From 1483679db2869bd35620d165e3f7197363dcedf0 Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Fri, 18 Aug 2023 15:05:33 +0100 Subject: [PATCH] Add a GitHub Actions workflow for preparing a libcnb.rs release Libcnb.rs uses a two stage release process. Until now both of those stages required a maintainer to perform the steps manually: https://github.com/heroku/libcnb.rs/blob/main/RELEASING.md This new GitHub Actions workflow replaces the manual steps in the first half of the release process, leading up to the creation of the "Prepare release" PR. In the future, the second stage of the release process will be automated too, but that will require sorting out a service account (which will also have to be backed by a GitHub account, since currently crates.io only supports login via GitHub oauth). See also: https://github.com/killercup/cargo-edit#cargo-set-version https://github.com/heroku/languages-github-actions/blob/main/.github/workflows/_buildpacks-release.yml First part of #595. GUS-W-13977983. --- .github/workflows/prepare-release.yml | 99 +++++++++++++++++++++++++++ RELEASING.md | 14 +--- 2 files changed, 101 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/prepare-release.yml diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml new file mode 100644 index 00000000..581ee571 --- /dev/null +++ b/.github/workflows/prepare-release.yml @@ -0,0 +1,99 @@ +name: Prepare release + +on: + workflow_dispatch: + inputs: + bump: + description: "Which component of the version to increment" + required: true + default: "patch" + type: choice + options: + - major + - minor + - patch + +env: + CARGO_TERM_COLOR: always + +jobs: + prepare-release: + name: Prepare Release + runs-on: pub-hk-ubuntu-22.04-small + steps: + - name: Get token for GH application (Linguist) + uses: heroku/use-app-token-action@main + id: generate-token + with: + app_id: ${{ vars.LINGUIST_GH_APP_ID }} + private_key: ${{ secrets.LINGUIST_GH_PRIVATE_KEY }} + + - name: Checkout + uses: actions/checkout@v4 + with: + # We always want the version bump/changelog and resultant PR to target main, not the branch of the workflow_dispatch. + ref: main + # Using the GH application token here will configure the local git config for this repo with credentials + # that can be used to make signed commits that are attributed to the GH application user + token: ${{ steps.generate-token.outputs.app_token }} + + - name: Update Rust toolchain + run: rustup update + + - name: Rust Cache + uses: Swatinem/rust-cache@v2.7.0 + + - name: Install cargo-edit + run: cargo install cargo-edit + + - name: Record old crate version + id: old-version + run: echo "version=$(yq '.workspace.package.version' Cargo.toml)" >> "${GITHUB_OUTPUT}" + + - name: Bump crate versions + # We use `--package libcnb` here to prevent the example and test buildpack crates from + # having their versions bumped too. Since the libcnb package's version is set via the + # root Cargo.toml's `workspace.package.version` field, all other publishable crates will + # still have their versions bumped, even though they are not explicitly listed here. + run: cargo set-version --package libcnb --bump '${{ inputs.bump }}' + + - name: Record new crate version + id: new-version + run: echo "version=$(yq '.workspace.package.version' Cargo.toml)" >> "${GITHUB_OUTPUT}" + + - name: Update changelog + run: | + OLD_VERSION='${{ steps.old-version.outputs.version }}' + NEW_VERSION='${{ steps.new-version.outputs.version }}' + DATE_TODAY="$(date --utc --iso-8601)" + UNRELEASED_URL="https://github.com/${{ github.repository }}/compare/v${NEW_VERSION}...HEAD" + NEW_VERSION_URL="https://github.com/${{ github.repository }}/compare/v${OLD_VERSION}...v${NEW_VERSION}" + + sed --in-place --regexp-extended \ + --expression "s~(^## \[Unreleased\])$~\1\n\n\n## [${NEW_VERSION}] - ${DATE_TODAY}~" \ + --expression "s~(^\[unreleased\]:) .*$~\1 ${UNRELEASED_URL}\n[${NEW_VERSION}]: ${NEW_VERSION_URL}~" \ + CHANGELOG.md + + - name: Upgrade in-range dependency versions + run: cargo upgrade + + - name: Create pull request + id: pr + uses: peter-evans/create-pull-request@v5.0.2 + with: + token: ${{ steps.generate-token.outputs.app_token }} + title: Prepare release v${{ steps.new-version.outputs.version }} + body: | + Changes: + https://github.com/${{ github.repository }}/compare/v${{ steps.old-version.outputs.version }}...main + commit-message: Prepare release v${{ steps.new-version.outputs.version }} + branch: prepare-release + delete-branch: true + committer: ${{ vars.LINGUIST_GH_APP_USERNAME }} <${{ vars.LINGUIST_GH_APP_EMAIL }}> + author: ${{ vars.LINGUIST_GH_APP_USERNAME }} <${{ vars.LINGUIST_GH_APP_EMAIL }}> + + - name: Configure pull request + if: steps.pr.outputs.pull-request-operation == 'created' + run: gh pr merge --auto --squash "${{ steps.pr.outputs.pull-request-number }}" + env: + GH_TOKEN: ${{ steps.generate-token.outputs.app_token }} diff --git a/RELEASING.md b/RELEASING.md index 70b0e7dd..64d0ad57 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -5,21 +5,11 @@ easier to gauge cross-crate compatibility. ## Prepare Release -1. Create a new branch for the upcoming release -2. Update [Cargo.toml](./Cargo.toml) in the root of the repository: - 1. In the `workspace.package` table, update `version` to the new version - 2. In the `workspace.dependencies` table, update the `version` of each of the repository-local dependencies to the new version -3. Update [CHANGELOG.md](./CHANGELOG.md) - 1. Move all content under `## [Unreleased]` to a new section that follows this pattern: `## [VERSION] - YYYY-MM-DD` - 2. If appropriate, add a high-level summary of changes at the beginning of the new section - 3. Update the version compare links at the bottom of the file to both add the new version, and update the "unreleased" link's "from" version. -4. Install the latest version of [cargo-edit](https://github.com/killercup/cargo-edit): `cargo install cargo-edit` -5. Bump in-range dependency versions using: `cargo upgrade` -6. Commit the changes, push them and open a PR targeting `main` +1. Trigger the [Prepare release](https://github.com/heroku/libcnb.rs/actions/workflows/prepare-release.yml) GitHub Actions workflow with a suitable `{patch,minor,major}` version bump. ## Release -1. After peer-review, merge the release preparation PR +1. Once the release preparation PR has been opened, review it (including ensuring the changelog is accurate) and then merge. 2. On your local machine, run `git switch main && git pull` to ensure you're on the `main` branch with the latest changes 3. Create a (lightweight) Git tag for the release and push it: (i.e. for version `1.1.38`: `git tag v1.1.38 && git push origin v1.1.38`) 4. Use `cargo` to release all crates, making sure to release dependencies of other crates first: