lockfile update #2
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| target_branch: | |
| description: Release branch | |
| required: true | |
| type: choice | |
| options: | |
| - develop | |
| - main | |
| version: | |
| description: Release version (X.Y.Z) | |
| required: true | |
| type: string | |
| pull_request: | |
| types: [closed] | |
| branches: | |
| - develop | |
| - main | |
| permissions: | |
| actions: write | |
| contents: write | |
| pull-requests: read | |
| concurrency: | |
| group: release-${{ github.event_name == 'workflow_dispatch' && inputs.target_branch || github.event.pull_request.base.ref }} | |
| cancel-in-progress: false | |
| env: | |
| CARGO_TERM_COLOR: always | |
| MAIN_BASE_VERSION: ${{ vars.MAIN_BASE_VERSION }} | |
| DEVELOP_BASE_VERSION: ${{ vars.DEVELOP_BASE_VERSION }} | |
| jobs: | |
| plan: | |
| if: github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should_release: ${{ steps.plan.outputs.should_release }} | |
| reason: ${{ steps.plan.outputs.reason }} | |
| bump: ${{ steps.plan.outputs.bump }} | |
| base_version: ${{ steps.plan.outputs.base_version }} | |
| previous_version: ${{ steps.plan.outputs.previous_version }} | |
| version: ${{ steps.plan.outputs.version }} | |
| target_branch: ${{ steps.plan.outputs.target_branch }} | |
| source_branch: ${{ steps.plan.outputs.source_branch }} | |
| merge_sha: ${{ steps.context.outputs.merge_sha }} | |
| steps: | |
| - name: Checkout selected branch | |
| if: github.event_name == 'workflow_dispatch' | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ inputs.target_branch }} | |
| fetch-depth: 0 | |
| - name: Checkout merge commit | |
| if: github.event_name == 'pull_request' | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.pull_request.merge_commit_sha }} | |
| fetch-depth: 0 | |
| - name: Fetch tags | |
| run: git fetch --force --tags | |
| - name: Resolve base versions | |
| id: bases | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| current_version="$( | |
| sed -nE 's/^version = "([0-9]+\.[0-9]+\.[0-9]+)"/\1/p' Cargo.toml | head -n1 | |
| )" | |
| if [[ -z "${current_version}" ]]; then | |
| echo "Could not determine the current Cargo version." >&2 | |
| exit 1 | |
| fi | |
| echo "main_base_version=${MAIN_BASE_VERSION:-$current_version}" >> "$GITHUB_OUTPUT" | |
| echo "develop_base_version=${DEVELOP_BASE_VERSION:-$current_version}" >> "$GITHUB_OUTPUT" | |
| - name: Resolve release context | |
| id: context | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | |
| echo "target_branch=${{ inputs.target_branch }}" >> "$GITHUB_OUTPUT" | |
| echo "source_branch=workflow_dispatch" >> "$GITHUB_OUTPUT" | |
| echo "release_version=${{ inputs.version }}" >> "$GITHUB_OUTPUT" | |
| echo "merge_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "target_branch=${{ github.event.pull_request.base.ref }}" >> "$GITHUB_OUTPUT" | |
| echo "source_branch=${{ github.event.pull_request.head.ref }}" >> "$GITHUB_OUTPUT" | |
| echo "release_version=" >> "$GITHUB_OUTPUT" | |
| echo "merge_sha=${{ github.event.pull_request.merge_commit_sha }}" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Plan release | |
| id: plan | |
| env: | |
| TARGET_BRANCH: ${{ steps.context.outputs.target_branch }} | |
| SOURCE_BRANCH: ${{ steps.context.outputs.source_branch }} | |
| RELEASE_VERSION: ${{ steps.context.outputs.release_version }} | |
| MAIN_BASE_VERSION: ${{ steps.bases.outputs.main_base_version }} | |
| DEVELOP_BASE_VERSION: ${{ steps.bases.outputs.develop_base_version }} | |
| run: devops/ga-release-plan.sh | |
| - name: Stop on non-release branches | |
| if: steps.plan.outputs.should_release != 'true' | |
| shell: bash | |
| run: | | |
| echo "Skipping release: ${{ steps.plan.outputs.reason }}" | |
| prepare_release: | |
| needs: plan | |
| if: needs.plan.outputs.should_release == 'true' | |
| runs-on: ubuntu-latest | |
| outputs: | |
| release_sha: ${{ steps.release_commit.outputs.release_sha }} | |
| steps: | |
| - name: Checkout target branch | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ needs.plan.outputs.target_branch }} | |
| fetch-depth: 0 | |
| - name: Fetch tags | |
| run: git fetch --force --tags | |
| - name: Verify tag does not already exist | |
| shell: bash | |
| run: | | |
| if git rev-parse "refs/tags/${{ needs.plan.outputs.version }}" >/dev/null 2>&1; then | |
| echo "Tag ${{ needs.plan.outputs.version }} already exists." | |
| exit 1 | |
| fi | |
| - name: Ensure release commit includes merged change | |
| if: github.event_name == 'pull_request' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if ! git merge-base --is-ancestor "${{ needs.plan.outputs.merge_sha }}" HEAD; then | |
| echo "The target branch no longer contains merge commit ${{ needs.plan.outputs.merge_sha }}." >&2 | |
| exit 1 | |
| fi | |
| - name: Configure git author | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| - name: Create release commit | |
| id: release_commit | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| version="${{ needs.plan.outputs.version }}" | |
| perl -pi -e 's/^version = "[0-9]+\.[0-9]+\.[0-9]+"/version = "'"$version"'"/' Cargo.toml | |
| perl -0pi -e 's/name = "commitbot"\nversion = "[0-9]+\.[0-9]+\.[0-9]+"/name = "commitbot"\nversion = "'"$version"'"/m' Cargo.lock | |
| if git diff --quiet -- Cargo.toml Cargo.lock; then | |
| echo "Release version ${version} is already present in Cargo metadata." >&2 | |
| exit 1 | |
| fi | |
| git add Cargo.toml Cargo.lock | |
| git commit -m "Release ${version}" | |
| git tag "${version}" | |
| echo "release_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" | |
| - name: Push release commit and tag | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| git push origin "HEAD:${{ needs.plan.outputs.target_branch }}" | |
| git push origin "refs/tags/${{ needs.plan.outputs.version }}" | |
| create_release: | |
| needs: [plan, prepare_release] | |
| if: needs.plan.outputs.should_release == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out release commit | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ needs.prepare_release.outputs.release_sha }} | |
| - name: Generate release notes | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| NOTES_ARGS=() | |
| if [[ "${{ needs.plan.outputs.previous_version }}" != "${{ needs.plan.outputs.base_version }}" ]]; then | |
| NOTES_ARGS+=(-f previous_tag_name="${{ needs.plan.outputs.previous_version }}") | |
| fi | |
| gh api \ | |
| -H "Accept: application/vnd.github+json" \ | |
| "/repos/${{ github.repository }}/releases/generate-notes" \ | |
| -f tag_name="${{ needs.plan.outputs.version }}" \ | |
| -f target_commitish="${{ needs.prepare_release.outputs.release_sha }}" \ | |
| "${NOTES_ARGS[@]}" \ | |
| --jq .body > generated-release-notes.md | |
| bash devops/render-release-notes.sh \ | |
| "${{ needs.plan.outputs.version }}" \ | |
| "${{ github.repository }}" \ | |
| generated-release-notes.md > release-notes.md | |
| - name: Create GitHub release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| gh release create "${{ needs.plan.outputs.version }}" \ | |
| --draft \ | |
| --verify-tag \ | |
| --target "${{ needs.prepare_release.outputs.release_sha }}" \ | |
| --title "${{ needs.plan.outputs.version }}" \ | |
| --notes-file release-notes.md | |
| - name: Dispatch release-assets workflow | |
| id: dispatch_assets | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| dispatch_started_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)" | |
| source_run_url="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| gh workflow run release-assets.yml \ | |
| --ref "${{ needs.plan.outputs.target_branch }}" \ | |
| -f tag="${{ needs.plan.outputs.version }}" \ | |
| -f source_run_id="${{ github.run_id }}" \ | |
| -f source_run_url="${source_run_url}" | |
| assets_run_url="" | |
| for _ in {1..12}; do | |
| sleep 5 | |
| assets_run_url="$( | |
| gh api "/repos/${{ github.repository }}/actions/workflows/release-assets.yml/runs?event=workflow_dispatch&branch=${{ needs.plan.outputs.target_branch }}&per_page=20" \ | |
| --jq '.workflow_runs | |
| | map(select(.head_sha == "${{ needs.prepare_release.outputs.release_sha }}" and .status != null)) | |
| | sort_by(.created_at) | |
| | reverse | |
| | .[0].html_url // ""' | |
| )" | |
| if [[ -n "${assets_run_url}" ]]; then | |
| break | |
| fi | |
| done | |
| echo "dispatch_started_at=${dispatch_started_at}" >> "$GITHUB_OUTPUT" | |
| echo "assets_run_url=${assets_run_url}" >> "$GITHUB_OUTPUT" | |
| - name: Add release summary | |
| shell: bash | |
| run: | | |
| release_url="https://github.com/${{ github.repository }}/releases/tag/${{ needs.plan.outputs.version }}" | |
| assets_url="${{ steps.dispatch_assets.outputs.assets_run_url }}" | |
| { | |
| echo "## Release" | |
| echo | |
| echo "- Version: \`${{ needs.plan.outputs.version }}\`" | |
| echo "- Release: [${{ needs.plan.outputs.version }}](${release_url})" | |
| if [[ -n "${assets_url}" ]]; then | |
| echo "- Release assets workflow: [Open run](${assets_url})" | |
| else | |
| echo "- Release assets workflow: dispatched, but the run URL was not discovered yet." | |
| echo "- Release assets workflow page: [Open workflow](https://github.com/${{ github.repository }}/actions/workflows/release-assets.yml)" | |
| fi | |
| } >> "$GITHUB_STEP_SUMMARY" |