Skip to content

ci: cut releases from a workflow that runs release.sh - #167

Merged
eddietejeda merged 1 commit into
mainfrom
ci/release-workflow
Oct 15, 2026
Merged

eddietejeda merged 1 commit into
mainfrom
ci/release-workflow

Conversation

@eddietejeda

Copy link
Copy Markdown
Contributor

Why

Releases still needed a laptop: run release.sh prepare, wait for the PR, then run release.sh publish from a clean main checkout. The Python SDK already cuts releases from CI; this brings the Rust crate to the same flow.

What

  • .github/workflows/cut-release.yml (mirrors sdk-python's workflow):
    • workflow_dispatch with a bump input runs the existing ./scripts/release.sh prepare, which bumps Cargo.toml, rolls [Unreleased] into a versioned changelog section, pushes release/vX.Y.Z, opens the PR, and then enables squash auto-merge on it.
    • When a release/v* PR merges, the Tag release job runs the existing ./scripts/release.sh publish, which tags main. The tag push triggers publish.yml (crates.io) and release.yml (GitHub Release) exactly as before.
    • Uses the hotdata-automation App token so the release PR gets CI and the tag triggers workflows (GITHUB_TOKEN events trigger nothing). All actions are SHA-pinned to the versions already used in this repo; cargo-edit is installed with a pinned taiki-e/install-action.
  • scripts/release.sh: only the usage text, PR body, and final echo now describe the CI path. No logic changes.
  • RELEASING.md: release steps now point at the workflow; adds a "Recover a missing tag" section; keeps the GitHub Release recovery section.

Releasing afterwards

gh workflow run cut-release.yml -f bump=minor   # or patch | major | X.Y.Z

@eddietejeda
eddietejeda requested a review from a team as a code owner October 15, 2026 19:34
@eddietejeda
eddietejeda requested review from rohan-hotdata and removed request for a team October 15, 2026 19:34
@eddietejeda
eddietejeda enabled auto-merge (squash) October 15, 2026 19:35
Comment on lines +34 to +36
concurrency:
group: cut-release
cancel-in-progress: false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Move concurrency from the workflow level to the publish and prepare jobs (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 with cancel-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-level concurrency only applies to jobs that pass their if, so unrelated PR closes never enter the group.

Comment on lines +78 to +80
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: ./scripts/release.sh prepare "${{ inputs.bump }}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Pass inputs.bump through env instead of ${{ }} in the script (not blocking).

The runner expands ${{ inputs.bump }} into the shell source before release.sh validates the value. A value with " or $(...) runs as shell code with the App token in the environment. GitHub's script-injection hardening guide recommends an intermediate environment variable.

Suggested change
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: ./scripts/release.sh prepare "${{ inputs.bump }}"
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
BUMP: ${{ inputs.bump }}
run: ./scripts/release.sh prepare "$BUMP"

@eddietejeda
eddietejeda merged commit 5bd4c83 into main Oct 15, 2026
3 checks passed
@eddietejeda
eddietejeda deleted the ci/release-workflow branch October 15, 2026 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant