Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---
title: Setting Up Release Infrastructure
---

## Steps

#### 1. Create the Initial Tag

A tag must exist for the first commit of the repository due to a [craft limitation](https://github.com/getsentry/craft/issues/342). Tag the first commit before any meaningful history so the first changelog includes useful context.

```bash
git tag 0.0.0 "$(git log -1 --reverse --format=%h)"
git push origin --tags
```

#### 2. Set Up CI for Release Branches

Ensure the repository's CI responds to `release/**` branches and produces a named artifact. See [sentry-python's build workflow](https://github.com/getsentry/sentry-python/blob/master/.github/workflows/build.yml) for an example.

#### 3. Configure Craft (`.craft.yml`)

Create a `.craft.yml` with targets for your package registry and GitHub releases:

```yaml
minVersion: 0.28.1
targets:
- name: pypi
- name: github
```

See the [Craft configuration docs](https://craft.sentry.dev/configuration/) for all available targets and options.

#### 4. Add Version Bump Script (`scripts/bump-version.sh`)

Craft invokes this script when bumping the version. The script receives the old version as `$1` and the new version as `$2`:

```bash
#!/usr/bin/env bash
set -euxo pipefail

sed -i "s/^version =.*/version = $2/" setup.cfg
```

For a real-world example with multiple version locations, see [sentry-python's bump-version.sh](https://github.com/getsentry/sentry-python/blob/master/scripts/bump-version.sh).

#### 5. Add Release Workflow (`.github/workflows/release.yml`)

This workflow triggers releases from the GitHub UI. It uses `vars.SENTRY_RELEASE_BOT_CLIENT_ID` and `secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY` which are available to repositories in the `getsentry` org automatically. These are needed because [GitHub prevents `GITHUB_TOKEN` from triggering downstream workflows](https://docs.github.com/en/actions/reference/events-that-trigger-workflows).

```yaml
name: Release

on:
workflow_dispatch:
inputs:
version:
description: Version to release
required: false
force:
description: Force a release even when there are release-blockers (optional)
required: false

jobs:
release:
runs-on: ubuntu-latest
name: "Release a new version"
steps:
- name: Get auth token
id: token
uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
with:
app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }}
private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }}
- uses: actions/checkout@v6
with:
token: ${{ steps.token.outputs.token }}
fetch-depth: 0
- name: Prepare release
uses: getsentry/craft@v2
env:
GITHUB_TOKEN: ${{ steps.token.outputs.token }}
with:
version: ${{ github.event.inputs.version }}
force: ${{ github.event.inputs.force }}
```

For full details on all available options including auto-versioning, changelog preview, merge targets, and multiple craft configs, see [Craft's GitHub Actions documentation](https://craft.sentry.dev/github-actions/). Repositories outside the `getsentry` org can use the simpler [reusable workflow](https://craft.sentry.dev/github-actions/#option-1-reusable-workflow-recommended) which handles token management automatically via `secrets: inherit`.

#### 6. Set Repository Permissions

Give the `engineering` team write access via your repository's settings page: `https://github.com/getsentry/REPONAME_HERE/settings/access`

#### 7. Create Branch Ruleset

Download the [default ruleset template](/json/Default_ruleset.json). Import it at `https://github.com/getsentry/REPONAME_HERE/settings/rules` via **New ruleset** > **Import a ruleset**. You can adjust settings but do not remove the App in the Bypass List.

#### 8. Cut Your First Release

Navigate to the Actions tab, locate the Release workflow, and trigger it. This creates an [issue in `getsentry/publish`](https://github.com/getsentry/publish/issues) which requires an approver to add a label before artifacts are published.

For the ongoing release process after setup, see "Cutting a release" (wip).

## Referenced Standards

- [Version format](/sdk/getting-started/standards/release-versioning#version-format)
- [Release tooling](/sdk/getting-started/standards/release-versioning#release-tooling)
- Release gating criteria (wip)
- Rollback procedures (wip)
181 changes: 181 additions & 0 deletions develop-docs/sdk/getting-started/standards/release-versioning.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
---
title: Release and Versioning
sidebar_order: 99
---

## Version Format

#### Rule

All SDK versions follow [semantic versioning (SemVer)](https://semver.org/):

```
<major>.<minor>.<patch>(-<prerelease>)?(-<build>)?
```

Major, minor, and patch are required. Pre-release and build identifiers are optional and can be combined.

#### Enforcement

- [Craft](https://github.com/getsentry/craft) validates version format at release time.

#### Per-SDK Override

<StatusBadge type="no" /> Format is universal. Language-specific conventions around SemVer (if applicable) are allowed.

---

## Pre-Release Identifiers

#### Rule

Pre-release identifiers must be one of: `preview`, `pre`, `rc`, `dev`, `alpha`, `beta`, `unstable`, `a`, `b`. Arbitrary strings are not accepted.

Pre-releases:
- Do not receive a `latest` tag in package registries
- Are not inserted into the internal release-registry (used by Sentry product, docs, and tooling)

Valid examples:

```
1.0.0-preview
1.0.0-alpha.0
1.0.0-beta.1
1.0.0-rc.20
```

Invalid (treated as stable):

```
1.0.0-foo
1.0.0-canary.0
```

**Python post-releases:** Python has the concept of post-releases indicated by a numeric-only suffix (e.g. `1.0.0-1`). Since this doesn't match any valid pre-release identifier, craft treats post-releases as stable releases.

#### Enforcement

- Craft rejects unrecognized identifiers or treats them as stable releases.

#### Per-SDK Override

<StatusBadge type="no" />

---

## Build Identifiers

#### Rule

Build identifiers can be appended for platform or architecture variants. When combined with pre-release identifiers, the pre-release must come first.

Valid examples:

```
1.0.0+x86_64
1.0.0-rc.1+x86_64
```

Invalid:

```
1.0.0+rc.1+x86_64
1.0.0+x86_64-beta.0
```

#### Enforcement

- Craft validates format at release time.

#### Per-SDK Override

<StatusBadge type="yes" /> Usage depends on whether the SDK publishes platform-specific artifacts.

---

## Release Tooling

#### Rule

SDKs use [craft](https://github.com/getsentry/craft) for release preparation and [publish](https://github.com/getsentry/publish) for release approval. Every SDK repository must have:

- `.craft.yml` — release configuration
- `scripts/bump-version.sh` — version bump script invoked by craft
- `.github/workflows/release.yml` — GitHub Actions workflow to trigger releases

See the [setting up release infrastructure](/sdk/getting-started/playbooks/setting-up-release-infrastructure) playbook for setup instructions.

#### Enforcement

- Craft enforces configuration at release time.
- Publish requires approval label before artifacts are published.

#### Per-SDK Override

<StatusBadge type="yes" /> Craft targets and bump-version logic are SDK-specific. Toolchain is universal.

---

## Merge Target

#### Rule

By default, releases are merged to the repository's default branch (usually `main`). To override this, pass the `merge_target` input in the release workflow:

```yaml
- name: Prepare release
uses: getsentry/craft@v2
env:
GITHUB_TOKEN: ${{ steps.token.outputs.token }}
with:
version: ${{ github.event.inputs.version }}
merge_target: ${{ github.event.inputs.merge_target }}
```

Add a corresponding `merge_target` input to the workflow's `workflow_dispatch.inputs` block. The same input is available in the [reusable workflow](https://craft.sentry.dev/github-actions/#option-1-reusable-workflow-recommended).

#### Enforcement

- Craft handles branch targeting at release time.

#### Per-SDK Override

<StatusBadge type="yes" /> Depends on branching strategy.

---

## Multiple Craft Configs Per Repository

#### Rule

When a repository maintains multiple major versions (e.g. v7 and v8) with diverging publishing targets, it can opt into using the `.craft.yml` from the merge target branch instead of the default branch.

**Release preparation:** Add `craft_config_from_merge_target: true` when calling `getsentry/craft` in the release workflow:

```yaml
- name: Prepare release
uses: getsentry/craft@v2
with:
craft_config_from_merge_target: true
```

This input is also available in the [reusable workflow](https://craft.sentry.dev/github-actions/#option-1-reusable-workflow-recommended).

**Publish configuration:** Register the branch in the `publish.yml` workflow in `getsentry/publish`:

```yaml
- name: Set target repo checkout branch
if: |
fromJSON(steps.inputs.outputs.result).repo == 'sentry-javascript' && fromJSON(steps.inputs.outputs.result).merge_target == 'v7'
```

The registered branches **must be** protected in the target repository — disable direct pushing and require PR approvals before merging.

#### Enforcement

- Craft validates config from the specified branch.
- Publish workflow enforces branch protection requirement.

#### Per-SDK Override

<StatusBadge type="yes" /> Only needed for repos maintaining multiple major versions.
Loading
Loading