Repository navigation
ci: cut releases from a workflow that runs release.sh #167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,133 @@ | ||||||||||||||||
| # Cut a release entirely from CI, using the same scripts/release.sh a human | ||||||||||||||||
| # would run locally. Three steps: | ||||||||||||||||
| # | ||||||||||||||||
| # 1. `gh workflow run cut-release.yml -f bump=<patch|minor|major|X.Y.Z>` | ||||||||||||||||
| # runs `release.sh prepare`: bumps Cargo.toml, rolls [Unreleased] into a | ||||||||||||||||
| # versioned CHANGELOG section, pushes release/vX.Y.Z and opens the PR, | ||||||||||||||||
| # then enables auto-merge on it. | ||||||||||||||||
| # 2. The PR merges on its own once CI and the review gate pass. | ||||||||||||||||
| # 3. The merge of a release/v* branch triggers the `publish` job below, which | ||||||||||||||||
| # runs `release.sh publish`: tags main with vX.Y.Z and pushes the tag. | ||||||||||||||||
| # The tag push then triggers publish.yml (crates.io) and release.yml | ||||||||||||||||
| # (GitHub Release) as it always has. | ||||||||||||||||
| # | ||||||||||||||||
| # Every git/gh call uses a GitHub App token instead of GITHUB_TOKEN. PRs opened | ||||||||||||||||
| # and tags pushed with GITHUB_TOKEN never trigger other workflows, so with it | ||||||||||||||||
| # the release PR would get no CI checks and the tag would never publish. | ||||||||||||||||
|
|
||||||||||||||||
| name: Cut Release | ||||||||||||||||
|
|
||||||||||||||||
| on: | ||||||||||||||||
| workflow_dispatch: | ||||||||||||||||
| inputs: | ||||||||||||||||
| bump: | ||||||||||||||||
| description: 'patch | minor | major | explicit X.Y.Z' | ||||||||||||||||
| required: true | ||||||||||||||||
| default: patch | ||||||||||||||||
| type: string | ||||||||||||||||
| pull_request: | ||||||||||||||||
| types: [closed] | ||||||||||||||||
| branches: [main] | ||||||||||||||||
|
|
||||||||||||||||
| permissions: {} | ||||||||||||||||
|
|
||||||||||||||||
| concurrency: | ||||||||||||||||
| group: cut-release | ||||||||||||||||
| cancel-in-progress: false | ||||||||||||||||
|
|
||||||||||||||||
| jobs: | ||||||||||||||||
| prepare: | ||||||||||||||||
| name: Open release PR | ||||||||||||||||
| if: github.event_name == 'workflow_dispatch' | ||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||
| steps: | ||||||||||||||||
| - name: Generate GitHub App token | ||||||||||||||||
| id: app-token | ||||||||||||||||
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 | ||||||||||||||||
| with: | ||||||||||||||||
| client-id: Iv23liKBX2RYMoZIYuKa | ||||||||||||||||
| private-key: ${{ secrets.HOTDATA_AUTOMATION_PRIVATE_KEY }} | ||||||||||||||||
| owner: hotdata-dev | ||||||||||||||||
|
|
||||||||||||||||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||||||||||||||||
| with: | ||||||||||||||||
| token: ${{ steps.app-token.outputs.token }} | ||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||
| fetch-tags: true | ||||||||||||||||
|
|
||||||||||||||||
| - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable | ||||||||||||||||
| with: | ||||||||||||||||
| toolchain: stable | ||||||||||||||||
|
|
||||||||||||||||
| # release.sh bumps Cargo.toml with `cargo set-version` (cargo-edit). | ||||||||||||||||
| - name: Install cargo-edit | ||||||||||||||||
| uses: taiki-e/install-action@1168f6810a3cb30a3514bf5756a3b7f0422c6df8 # v2.87.28 | ||||||||||||||||
| with: | ||||||||||||||||
| tool: cargo-edit | ||||||||||||||||
|
|
||||||||||||||||
| - name: Configure git identity | ||||||||||||||||
| env: | ||||||||||||||||
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | ||||||||||||||||
| run: | | ||||||||||||||||
| slug="${{ steps.app-token.outputs.app-slug }}[bot]" | ||||||||||||||||
| id="$(gh api "/users/${slug}" --jq .id)" | ||||||||||||||||
| git config user.name "$slug" | ||||||||||||||||
| git config user.email "${id}+${slug}@users.noreply.github.com" | ||||||||||||||||
|
|
||||||||||||||||
| - name: Prepare release | ||||||||||||||||
| env: | ||||||||||||||||
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | ||||||||||||||||
| run: ./scripts/release.sh prepare "${{ inputs.bump }}" | ||||||||||||||||
|
Comment on lines
+78
to
+80
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Pass The runner expands
Suggested change
|
||||||||||||||||
|
|
||||||||||||||||
| # Branch protection on main gates the merge on CI plus the review gate, | ||||||||||||||||
| # so this only merges once everything is green. | ||||||||||||||||
| - name: Enable auto-merge on the release PR | ||||||||||||||||
| env: | ||||||||||||||||
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | ||||||||||||||||
| run: | | ||||||||||||||||
| branch="$(git rev-parse --abbrev-ref HEAD)" | ||||||||||||||||
| number="$(gh pr list --head "$branch" --state open --json number --jq '.[0].number')" | ||||||||||||||||
| [[ -n "$number" ]] || { echo "::error::no open PR for $branch"; exit 1; } | ||||||||||||||||
| gh pr merge "$number" --squash --auto | ||||||||||||||||
|
|
||||||||||||||||
| publish: | ||||||||||||||||
| name: Tag release | ||||||||||||||||
| if: >- | ||||||||||||||||
| github.event_name == 'pull_request' && | ||||||||||||||||
| github.event.pull_request.merged == true && | ||||||||||||||||
| startsWith(github.event.pull_request.head.ref, 'release/v') | ||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||
| steps: | ||||||||||||||||
| - name: Generate GitHub App token | ||||||||||||||||
| id: app-token | ||||||||||||||||
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 | ||||||||||||||||
| with: | ||||||||||||||||
| client-id: Iv23liKBX2RYMoZIYuKa | ||||||||||||||||
| private-key: ${{ secrets.HOTDATA_AUTOMATION_PRIVATE_KEY }} | ||||||||||||||||
| owner: hotdata-dev | ||||||||||||||||
|
|
||||||||||||||||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||||||||||||||||
| with: | ||||||||||||||||
| ref: main | ||||||||||||||||
| token: ${{ steps.app-token.outputs.token }} | ||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||
| fetch-tags: true | ||||||||||||||||
|
|
||||||||||||||||
| # release.sh reads the version with `cargo metadata`. | ||||||||||||||||
| - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable | ||||||||||||||||
| with: | ||||||||||||||||
| toolchain: stable | ||||||||||||||||
|
|
||||||||||||||||
| - name: Configure git identity | ||||||||||||||||
| env: | ||||||||||||||||
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | ||||||||||||||||
| run: | | ||||||||||||||||
| slug="${{ steps.app-token.outputs.app-slug }}[bot]" | ||||||||||||||||
| id="$(gh api "/users/${slug}" --jq .id)" | ||||||||||||||||
| git config user.name "$slug" | ||||||||||||||||
| git config user.email "${id}+${slug}@users.noreply.github.com" | ||||||||||||||||
|
|
||||||||||||||||
| - name: Tag and push | ||||||||||||||||
| env: | ||||||||||||||||
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | ||||||||||||||||
| run: ./scripts/release.sh publish | ||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Move
concurrencyfrom the workflow level to thepublishandpreparejobs (not blocking).The workflow-level group applies to every closed PR on
main, including runs where both jobs skip. GitHub keeps one running and one pending run per group. A newer pending run cancels the older pending run, even withcancel-in-progress: false. A release-PR merge run can wait behind another close event. A third close event then cancels the release run, and no tag is pushed. Job-levelconcurrencyonly applies to jobs that pass theirif, so unrelated PR closes never enter the group.