diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4a8d49c06..7712f661c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,6 +1,8 @@ name: Release concurrency: ${{ github.workflow }}-${{ github.ref }} + on: + # For Craft's own releases (dogfooding) workflow_dispatch: inputs: version: @@ -11,35 +13,130 @@ on: description: Force a release even when there are release-blockers (optional) required: false + # For external repos to call this workflow + workflow_call: + inputs: + version: + description: Version to release (semver, bump type, or "auto") + type: string + required: false + force: + description: Force a release even when there are release-blockers + type: string + required: false + default: "false" + merge_target: + description: Target branch to merge into + type: string + required: false + blocker_label: + description: Label that blocks releases + type: string + required: false + default: "release-blocker" + publish_repo: + description: Repository for publish issues (owner/repo format) + type: string + required: false + git_user_name: + description: Git committer name + type: string + required: false + git_user_email: + description: Git committer email + type: string + required: false + path: + description: The path that Craft will run inside + type: string + required: false + default: "." + craft_config_from_merge_target: + description: Use the craft config from the merge target branch + type: string + required: false + default: "false" + outputs: + version: + description: The resolved version being released + value: ${{ jobs.release.outputs.version }} + branch: + description: The release branch name + value: ${{ jobs.release.outputs.branch }} + sha: + description: The commit SHA on the release branch + value: ${{ jobs.release.outputs.sha }} + previous_tag: + description: The tag before this release (for diff links) + value: ${{ jobs.release.outputs.previous_tag }} + changelog: + description: The changelog for this release + value: ${{ jobs.release.outputs.changelog }} + jobs: + # Build job only for Craft's own releases (dogfooding) build: + if: github.event_name == 'workflow_dispatch' name: Build uses: ./.github/workflows/build.yml permissions: contents: read release: - needs: build + needs: [build] + # Run if build succeeded OR was skipped (workflow_call case) + if: always() && (needs.build.result == 'success' || needs.build.result == 'skipped') runs-on: ubuntu-latest name: 'Release a new version' permissions: contents: write + outputs: + version: ${{ steps.craft-local.outputs.version || steps.craft-action.outputs.version }} + branch: ${{ steps.craft-local.outputs.branch || steps.craft-action.outputs.branch }} + sha: ${{ steps.craft-local.outputs.sha || steps.craft-action.outputs.sha }} + previous_tag: ${{ steps.craft-local.outputs.previous_tag || steps.craft-action.outputs.previous_tag }} + changelog: ${{ steps.craft-local.outputs.changelog || steps.craft-action.outputs.changelog }} steps: + # For Craft repo: use the release bot token - name: Get auth token id: token + if: github.event_name == 'workflow_dispatch' && github.repository == 'getsentry/craft' 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@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 + + - uses: actions/checkout@v4 with: - # Fetch all commits so we can determine previous version - token: ${{ steps.token.outputs.token }} + # Use release bot token for Craft repo, inherited token for external repos + token: ${{ steps.token.outputs.token || github.token }} fetch-depth: 0 - - name: Prepare release + + # For Craft's own releases: use local action (dogfooding) + - name: Prepare release (dogfooding) + if: github.event_name == 'workflow_dispatch' + id: craft-local uses: ./ env: GITHUB_TOKEN: ${{ steps.token.outputs.token }} with: version: ${{ github.event.inputs.version }} force: ${{ github.event.inputs.force }} + + # For external repos: use published action + - name: Prepare release + if: github.event_name == 'workflow_call' + id: craft-action + uses: getsentry/craft@v2 + env: + GITHUB_TOKEN: ${{ github.token }} + with: + version: ${{ inputs.version }} + force: ${{ inputs.force }} + merge_target: ${{ inputs.merge_target }} + blocker_label: ${{ inputs.blocker_label }} + publish_repo: ${{ inputs.publish_repo }} + git_user_name: ${{ inputs.git_user_name }} + git_user_email: ${{ inputs.git_user_email }} + path: ${{ inputs.path }} + craft_config_from_merge_target: ${{ inputs.craft_config_from_merge_target }} diff --git a/docs/src/content/docs/github-actions.md b/docs/src/content/docs/github-actions.md index 2cffed2b6..d05d9aa58 100644 --- a/docs/src/content/docs/github-actions.md +++ b/docs/src/content/docs/github-actions.md @@ -7,11 +7,18 @@ Craft provides GitHub Actions for automating releases and previewing changelog e For a real-world example of using Craft's GitHub Actions, see the [getsentry/publish](https://github.com/getsentry/publish) repository. -## Prepare Release Action +## Prepare Release -The main Craft action automates the `craft prepare` workflow in GitHub Actions. It creates a release branch, updates the changelog, and opens a publish request issue. +Craft offers two ways to automate releases in GitHub Actions: -### Basic Usage +| Option | Best For | Flexibility | +|--------|----------|-------------| +| **Reusable Workflow** | Quick setup, standard release flow | Low - runs as a complete job | +| **Composite Action** | Custom workflows, pre/post steps | High - composable with other steps | + +### Option 1: Reusable Workflow (Recommended) + +The simplest way to set up Craft releases. Call the workflow and let it handle everything: ```yaml name: Release @@ -24,19 +31,13 @@ on: jobs: release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: getsentry/craft@v2 - with: - version: ${{ github.event.inputs.version }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: getsentry/craft/.github/workflows/release.yml@v2 + with: + version: ${{ inputs.version }} + secrets: inherit ``` -### Inputs +#### Workflow Inputs | Input | Description | Default | |-------|-------------|---------| @@ -50,7 +51,7 @@ jobs: | `path` | The path that Craft will run inside. | `.` | | `craft_config_from_merge_target` | Use the craft config from the merge target branch. | `false` | -### Outputs +#### Workflow Outputs | Output | Description | |--------|-------------| @@ -60,15 +61,18 @@ jobs: | `previous_tag` | The tag before this release (for diff links) | | `changelog` | The changelog for this release | -### Auto-versioning Example +### Option 2: Composite Action -When using auto-versioning, Craft analyzes conventional commits to determine the version bump: +Use the action directly when you need to add custom steps before or after the release, or integrate Craft into a more complex workflow: ```yaml -name: Auto Release +name: Release on: - schedule: - - cron: '0 10 * * 1' # Every Monday at 10 AM + workflow_dispatch: + inputs: + version: + description: 'Version to release (or "auto")' + required: false jobs: release: @@ -77,11 +81,39 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 + + # Custom pre-release steps + - run: echo "Running pre-release checks..." + - uses: getsentry/craft@v2 with: - version: auto + version: ${{ github.event.inputs.version }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Custom post-release steps + - run: echo "Release prepared!" +``` + +The action accepts the same inputs and produces the same outputs as the reusable workflow. + +### Auto-versioning Example + +When using auto-versioning, Craft analyzes conventional commits to determine the version bump. This works with both the workflow and the action: + +```yaml +# Using the reusable workflow +name: Auto Release +on: + schedule: + - cron: '0 10 * * 1' # Every Monday at 10 AM + +jobs: + release: + uses: getsentry/craft/.github/workflows/release.yml@v2 + with: + version: auto + secrets: inherit ``` ## Changelog Preview (Reusable Workflow) @@ -208,9 +240,9 @@ PRs with the `skip-changelog` label or from excluded authors will not appear in ## Tips -### Combining Both Actions +### Combining Both Workflows -You can use both the changelog preview and release actions together for a complete release workflow. See the [getsentry/publish](https://github.com/getsentry/publish) repository for a real-world example. +You can use both the changelog preview and release workflows together for a complete release flow: ```yaml # .github/workflows/changelog-preview.yml @@ -237,14 +269,8 @@ on: jobs: release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: getsentry/craft@v2 - with: - version: ${{ github.event.inputs.version || 'auto' }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: getsentry/craft/.github/workflows/release.yml@v2 + with: + version: ${{ inputs.version || 'auto' }} + secrets: inherit ```