---
title: "Setting Up Release Infrastructure"
url: https://develop.sentry.dev/sdk/getting-started/playbooks/setup/setting-up-release-infrastructure/
---

# Setting Up Release Infrastructure

This document uses key words such as "MUST", "SHOULD", and "MAY" as defined in

<!-- -->

[RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) to indicate requirement levels.

Statusstable

Version`1.0.0`[(changelog)](https://develop.sentry.dev/sdk/getting-started/playbooks/setup/setting-up-release-infrastructure.md#changelog)

## [Overview](https://develop.sentry.dev/sdk/getting-started/playbooks/setup/setting-up-release-infrastructure.md#overview)

This playbook guides SDK maintainers through setting up automated release infrastructure for a new SDK repository using [Craft](https://craft.sentry.dev). It covers initial tagging, CI configuration, version management, and branch protection rules. By following these steps, the repository will support automated changelog generation, artifact publishing, and controlled releases via GitHub Actions.

Related resources:

* [Release Versioning Standard](https://develop.sentry.dev/sdk/getting-started/standards/release-versioning.md) — version format and tooling requirements
* [Craft Documentation](https://craft.sentry.dev) — release automation tool
* [Craft GitHub Actions](https://craft.sentry.dev/github-actions/) — workflow configuration options

***

## [Steps](https://develop.sentry.dev/sdk/getting-started/playbooks/setup/setting-up-release-infrastructure.md#steps)

#### [1. Create the Initial Tag](https://develop.sentry.dev/sdk/getting-started/playbooks/setup/setting-up-release-infrastructure.md#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). You **SHOULD** 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](https://develop.sentry.dev/sdk/getting-started/playbooks/setup/setting-up-release-infrastructure.md#2-set-up-ci-for-release-branches)

The repository's CI **MUST** respond to `release/**` branches and produce a named artifact.

#### [3. Configure Craft (`.craft.yml`)](https://develop.sentry.dev/sdk/getting-started/playbooks/setup/setting-up-release-infrastructure.md#3-configure-craft-craftyml)

You **MUST** 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`)](https://develop.sentry.dev/sdk/getting-started/playbooks/setup/setting-up-release-infrastructure.md#4-add-version-bump-script-scriptsbump-versionsh)

Craft invokes this script when bumping the version. The script **MUST** accept 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`)](https://develop.sentry.dev/sdk/getting-started/playbooks/setup/setting-up-release-infrastructure.md#5-add-release-workflow-githubworkflowsreleaseyml)

You **MUST** add a release workflow that triggers releases from the GitHub UI. The workflow **SHOULD** use `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](https://develop.sentry.dev/sdk/getting-started/playbooks/setup/setting-up-release-infrastructure.md#6-set-repository-permissions)

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

#### [7. Create Branch Ruleset](https://develop.sentry.dev/sdk/getting-started/playbooks/setup/setting-up-release-infrastructure.md#7-create-branch-ruleset)

Download the [default ruleset template](https://develop.sentry.dev/json/Default_ruleset.json). You **MUST** import it at `https://github.com/getsentry/REPONAME_HERE/settings/rules` via **New ruleset** > **Import a ruleset**. You **MAY** adjust settings but **MUST NOT** remove the App in the Bypass List.

#### [8. Cut Your First Release](https://develop.sentry.dev/sdk/getting-started/playbooks/setup/setting-up-release-infrastructure.md#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](https://develop.sentry.dev/sdk/getting-started/playbooks/setup/setting-up-release-infrastructure.md#referenced-standards)

* [Version format](https://develop.sentry.dev/sdk/getting-started/standards/release-versioning.md#versioning) — SemVer requirements
* [Release tooling](https://develop.sentry.dev/sdk/getting-started/standards/release-versioning.md#release-tooling) — Craft and publish setup
* [Release gating criteria](https://develop.sentry.dev/sdk/getting-started/standards/review-ci.md#release-gating) — Pre-release validation requirements
* [Rollback procedures](https://develop.sentry.dev/sdk/getting-started/standards/coordination-maintenance.md#releases) — Emergency release rollback process

***

## [Changelog](https://develop.sentry.dev/sdk/getting-started/playbooks/setup/setting-up-release-infrastructure.md#changelog)

| Version | Date       | Summary                                                                                               |
| ------- | ---------- | ----------------------------------------------------------------------------------------------------- |
| `1.0.0` | 2026-02-20 | Initial playbook — standardized release infrastructure setup with Craft, CI/CD, and branch protection |
