diff --git a/.github/release-please-config.json b/.github/release-please-config.json index e9fbda4b..e7ecc230 100644 --- a/.github/release-please-config.json +++ b/.github/release-please-config.json @@ -1,5 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "last-release-sha": "9f7d5b3f1476234e552b783415527cc4bac55b39", "packages": { ".": { "release-type": "python", diff --git a/.github/workflows/release-cherry-pick.yml b/.github/workflows/release-cherry-pick.yml index fd25f734..bf2247c4 100644 --- a/.github/workflows/release-cherry-pick.yml +++ b/.github/workflows/release-cherry-pick.yml @@ -1,5 +1,5 @@ -# Cherry-picks a commit from main to the release/candidate branch. -# Use this to include bug fixes in an in-progress release. +# Step 3 (optional): Cherry-picks a commit from main to the release/candidate branch. +# Use between step 1 and step 4 to include bug fixes in an in-progress release. name: "Release: Cherry-pick" on: @@ -42,5 +42,5 @@ jobs: env: GH_TOKEN: ${{ github.token }} run: | - gh workflow run release-please.yml --repo ${{ github.repository }} + gh workflow run release-please.yml --repo ${{ github.repository }} --ref release/candidate echo "Triggered Release Please workflow" diff --git a/.github/workflows/release-cut.yml b/.github/workflows/release-cut.yml index 3e8643b6..8dbed404 100644 --- a/.github/workflows/release-cut.yml +++ b/.github/workflows/release-cut.yml @@ -1,5 +1,5 @@ -# Starts the release process by creating a release/candidate branch. -# Triggers release-please to generate a changelog PR. +# Step 1: Starts the release process by creating a release/candidate branch. +# Generates a changelog PR for review (step 2). name: "Release: Cut" on: @@ -42,5 +42,5 @@ jobs: env: GH_TOKEN: ${{ github.token }} run: | - gh workflow run release-please.yml --repo ${{ github.repository }} + gh workflow run release-please.yml --repo ${{ github.repository }} --ref release/candidate echo "Triggered Release Please workflow" diff --git a/.github/workflows/release-finalize.yml b/.github/workflows/release-finalize.yml index 9864aaab..ade58ec2 100644 --- a/.github/workflows/release-finalize.yml +++ b/.github/workflows/release-finalize.yml @@ -1,5 +1,5 @@ -# Triggers when release-please PR is merged to release/candidate. -# Creates the final release/v{version} branch and deletes the candidate branch. +# Step 4: Triggers when the changelog PR is merged to release/candidate. +# Records last-release-sha and renames release/candidate to release/v{version}. name: "Release: Finalize" on: @@ -33,6 +33,8 @@ jobs: if: steps.check.outputs.is_release_pr == 'true' with: ref: release/candidate + token: ${{ secrets.RELEASE_PAT }} + fetch-depth: 0 - name: Extract version from manifest if: steps.check.outputs.is_release_pr == 'true' @@ -42,18 +44,33 @@ jobs: echo "version=$VERSION" >> $GITHUB_OUTPUT echo "Extracted version: $VERSION" - - name: Create release branch + - name: Configure git identity from RELEASE_PAT if: steps.check.outputs.is_release_pr == 'true' + env: + GH_TOKEN: ${{ secrets.RELEASE_PAT }} run: | - git checkout -b "release/v${{ steps.version.outputs.version }}" - git push origin "release/v${{ steps.version.outputs.version }}" - echo "Created branch: release/v${{ steps.version.outputs.version }}" + USER_JSON=$(gh api user) + git config user.name "$(echo "$USER_JSON" | jq -r '.login')" + git config user.email "$(echo "$USER_JSON" | jq -r '.id')+$(echo "$USER_JSON" | jq -r '.login')@users.noreply.github.com" - - name: Delete release/candidate branch + - name: Record last-release-sha for release-please if: steps.check.outputs.is_release_pr == 'true' run: | - git push origin --delete release/candidate - echo "Deleted branch: release/candidate" + git fetch origin main + CUT_SHA=$(git merge-base origin/main HEAD) + echo "Release was cut from main at: $CUT_SHA" + jq --arg sha "$CUT_SHA" '. + {"last-release-sha": $sha}' \ + .github/release-please-config.json > tmp.json && mv tmp.json .github/release-please-config.json + git add .github/release-please-config.json + git commit -m "chore: update last-release-sha for next release" + git push origin release/candidate + + - name: Rename release/candidate to release/v{version} + if: steps.check.outputs.is_release_pr == 'true' + run: | + VERSION="v${{ steps.version.outputs.version }}" + git push origin "release/candidate:refs/heads/release/$VERSION" ":release/candidate" + echo "Renamed release/candidate to release/$VERSION" - name: Update PR label to tagged if: steps.check.outputs.is_release_pr == 'true' diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index b2540e9f..791d84a5 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -1,5 +1,5 @@ # Runs release-please to create/update a PR with version bump and changelog. -# Triggered by pushes to release/candidate or manually. +# Triggered automatically by step 1 (cut) or step 3 (cherry-pick). name: "Release: Please" on: @@ -18,11 +18,25 @@ jobs: if: "!startsWith(github.event.head_commit.message, 'chore(release')" runs-on: ubuntu-latest steps: + - name: Check if release/candidate still exists + id: check + env: + GH_TOKEN: ${{ github.token }} + run: | + if gh api repos/${{ github.repository }}/branches/release/candidate --silent 2>/dev/null; then + echo "exists=true" >> $GITHUB_OUTPUT + else + echo "release/candidate branch no longer exists, skipping" + echo "exists=false" >> $GITHUB_OUTPUT + fi + - uses: actions/checkout@v4 + if: steps.check.outputs.exists == 'true' with: ref: release/candidate - uses: googleapis/release-please-action@v4 + if: steps.check.outputs.exists == 'true' with: token: ${{ secrets.RELEASE_PAT }} config-file: .github/release-please-config.json diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index 51623d57..5979cd9c 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -1,5 +1,5 @@ -# Builds and publishes the package to PyPI from a release branch. -# Creates a merge-back PR to sync release changes to main. +# Step 6: Builds and publishes the package to PyPI from a release/v{version} branch. +# Creates a merge-back PR (step 7) to sync release changes to main. name: "Release: Publish to PyPi" on: