From: Steve Myers Date: Wed, 23 Sep 2026 15:23:32 +0000 (-0500) Subject: ci: add release-plz workflow and update release docs X-Git-Url: http://internal-gitweb-vhost/tx_graph/%22https:/encode/struct.SegwitCodeLengthError.html?a=commitdiff_plain;h=886f4c13ebbf1680b71d068ed9ff31d368ab1476;p=bdk-cli ci: add release-plz workflow and update release docs Add a GitHub Actions workflow that uses release-plz to automate creating release PRs, publishing to crates.io, tagging, and creating GitHub releases via OIDC trusted publishing and environment-gated approvals. Update DEVELOPMENT_CYCLE.md with the new release process. --- diff --git a/.github/workflows/release-plz.yml b/.github/workflows/release-plz.yml new file mode 100644 index 0000000..8c9fa47 --- /dev/null +++ b/.github/workflows/release-plz.yml @@ -0,0 +1,116 @@ +name: Release-plz + +# How this works (see https://release-plz.dev/docs/github/quickstart): +# +# This workflow is triggered manually only (Actions -> "Release-plz" -> "Run +# workflow"). Select the branch to release from in the "Use workflow from" +# dropdown (e.g. the default branch or `release/1.x`) and click "Run workflow". +# Both jobs below run on every dispatch: +# +# 1. The `release-pr` job opens/updates a release PR (branch prefix `release-plz-`) +# with the version bump and changelog for updated crates, targeting the +# selected branch, authored by the `bitcoindevkit-release-plz` GitHub App. +# The version bump for each crate is computed from that branch's Cargo.toml. +# Re-run it to refresh the release PR after new commits land on the branch. +# 2. The `release` job checks whether the release PR has been merged. If so, it +# publishes the crate to crates.io (via trusted publishing / OIDC, no token +# secret) and creates the `-vX.Y.Z` git tag and GitHub release. +# The job runs in the `release` GitHub environment, whose required reviewers +# are defined in the GitHub repository config; publishing waits until an +# authorized GitHub user approves it in the Actions UI. +# +# Notes: +# - release-plz supports only one open release PR per repository, so don't +# prepare releases on two branches concurrently. + +on: + workflow_dispatch: + +permissions: {} + +jobs: + # Create or update the PR with the new version and changelog. + release-pr: + name: Create/Update Rust Release PR + runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'bitcoindevkit' }} + permissions: + contents: write # push the release PR branch + pull-requests: write # open and update the release PR + concurrency: + group: release-plz-${{ github.ref_name }} + cancel-in-progress: false + steps: + - name: Validate selected branch + env: + BRANCH: ${{ github.ref_name }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + run: | + case "$BRANCH" in + "$DEFAULT_BRANCH"|release/*) ;; + *) echo "Refusing to release from '$BRANCH' (expected '$DEFAULT_BRANCH' or 'release/*')"; exit 1 ;; + esac + - name: Generate GitHub App token + id: app-token + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ secrets.RELEASE_PLZ_APP_ID }} + private-key: ${{ secrets.RELEASE_PLZ_PRIVATE_KEY }} + - name: Checkout repository + uses: actions/checkout@v7 + with: + ref: ${{ github.ref_name }} + fetch-depth: 0 + persist-credentials: false + - name: Install Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@v2 + - name: Run release-plz + uses: release-plz/action@v0.5 + with: + command: release-pr + env: + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} + + # If the release PR was merged, publish to crates.io, tag, and create the + # GitHub release. Gated by the `release` environment (team approval). + release: + name: Publish Rust Release + runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'bitcoindevkit' }} + environment: release + permissions: + contents: write # push tags and create GitHub releases + pull-requests: read # detect the merged release PR + id-token: write # crates.io trusted publishing (OIDC) + steps: + - name: Validate selected branch + env: + BRANCH: ${{ github.ref_name }} + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + run: | + case "$BRANCH" in + "$DEFAULT_BRANCH"|release/*) ;; + *) echo "Refusing to release from '$BRANCH' (expected '$DEFAULT_BRANCH' or 'release/*')"; exit 1 ;; + esac + - name: Generate GitHub App token + id: app-token + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ secrets.RELEASE_PLZ_APP_ID }} + private-key: ${{ secrets.RELEASE_PLZ_PRIVATE_KEY }} + - name: Checkout repository + uses: actions/checkout@v7 + with: + ref: ${{ github.ref_name }} + fetch-depth: 0 + persist-credentials: false + - name: Install Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@v2 + - name: Run release-plz + uses: release-plz/action@v0.5 + with: + command: release + env: + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} + # No CARGO_REGISTRY_TOKEN on purpose: crates.io trusted publishing is + # configured for this repo + workflow + the `release` environment. diff --git a/DEVELOPMENT_CYCLE.md b/DEVELOPMENT_CYCLE.md index 11e7a26..c394068 100644 --- a/DEVELOPMENT_CYCLE.md +++ b/DEVELOPMENT_CYCLE.md @@ -10,7 +10,7 @@ Once the project reaches a more mature state (>= `1.0.0`), we will very likely s The "feature freeze" will happen **one week before the release date**. This means a new branch will be created originating from the `master` tip at that time, and in that branch we will stop adding new features and only focus on ensuring the ones we've added are working properly. -To create a new release a release manager will create a new issue using the `Release` template and follow the template instructions. +To create a new release a release manager will trigger the `release-plz` workflow to create a new release PR, review and approve it, and then trigger the `release-plz` workflow again to publish it to `crates.io`. [used by the Rust language]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html [Semantic Versioning]: https://semver.org/