Skip to content

Create v0.9.7-rc1.yml (#463) #58

Create v0.9.7-rc1.yml (#463)

Create v0.9.7-rc1.yml (#463) #58

Workflow file for this run

name: Draft Release

Check failure on line 1 in .github/workflows/release.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/release.yml

Invalid workflow file

(Line: 406, Col: 9): Job 'cleanup-on-failure' depends on unknown job 'build-and-push-pbs-docker'., (Line: 407, Col: 9): Job 'cleanup-on-failure' depends on unknown job 'build-and-push-signer-docker'.
on:
workflow_dispatch:
inputs:
tag:
description: "Release tag (e.g. v1.2.3)"
required: true
type: string
permissions:
contents: read
packages: read
id-token: none
actions: read
attestations: read
checks: read
deployments: read
issues: read
discussions: read
pull-requests: read
repository-projects: read
security-events: read
statuses: read
models: read
# Job-level permissions grant write scopes only where required.
concurrency:
group: release-${{ inputs.tag }}
cancel-in-progress: false
jobs:
resolve-tag:
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
commit: ${{ steps.resolve.outputs.commit }}
steps:
- name: Checkout main
uses: actions/checkout@v6
with:
ref: main
fetch-depth: 0
- name: Resolve tag to commit
id: resolve
run: |
git cat-file -e "refs/tags/${{ inputs.tag }}" 2>/dev/null || {
echo "❌ Tag ${{ inputs.tag }} does not exist"
exit 1
}
COMMIT=$(git rev-parse "refs/tags/${{ inputs.tag }}^{}")
echo "commit=$COMMIT" >> $GITHUB_OUTPUT
echo "Resolved tag ${{ inputs.tag }} to commit $COMMIT"
# Determines whether this tag should update :latest on GHCR.
# Runs once; the Docker job consumes its output via matrix.
determine-latest:
runs-on: ubuntu-latest
timeout-minutes: 2
outputs:
value: ${{ steps.is_latest.outputs.value }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Check is-latest
id: is_latest
run: |
VALUE=$(python .github/workflows/release/release.py is-latest "${{ inputs.tag }}")
echo "value=$VALUE" >> $GITHUB_OUTPUT
# Builds the x64 and arm64 binaries for Linux, for all 3 crates, via the Docker builder
build-binaries-linux:
needs: [resolve-tag]
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
target:
- amd64
- arm64
name:
- commit-boost
include:
- target: amd64
package-suffix: x86-64
- target: arm64
package-suffix: arm64
- name: commit-boost
target-crate: commit-boost
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
ref: ${{ needs.resolve-tag.outputs.commit }}
fetch-depth: 0
submodules: true
- name: Log commit hash
run: |
echo "Releasing commit: $(git rev-parse HEAD)"
- name: Set lowercase owner
run: echo "OWNER=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build binary (Linux)
uses: docker/build-push-action@v6
with:
context: .
push: false
platforms: linux/${{ matrix.target }}
file: provisioning/build.Dockerfile
outputs: type=local,dest=build/linux_${{ matrix.target }}
build-args: |
TARGET_CRATE=${{ matrix.name }}
- name: Package binary (Linux)
run: |
cd build/linux_${{ matrix.target }}
tar -czvf ${{ matrix.name }}-${{ inputs.tag }}-linux_${{ matrix.package-suffix }}.tar.gz ${{ matrix.name }}
mv ${{ matrix.name }}-${{ inputs.tag }}-linux_${{ matrix.package-suffix }}.tar.gz ../../
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.name }}-${{ inputs.tag }}-linux_${{ matrix.package-suffix }}
path: |
${{ matrix.name }}-${{ inputs.tag }}-linux_${{ matrix.package-suffix }}.tar.gz
# Builds the arm64 binary for Darwin natively
build-binaries-darwin:
needs: [resolve-tag]
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
target:
# x64 requires macos-latest-large which is not available in the free tier
# - x86_64-apple-darwin
- aarch64-apple-darwin
name:
- commit-boost
include:
# - target: x86_64-apple-darwin
# os: macos-latest-large
# package-suffix: x86-64
- target: aarch64-apple-darwin
os: macos-latest
package-suffix: arm64
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
ref: ${{ needs.resolve-tag.outputs.commit }}
fetch-depth: 0
submodules: true
- name: Log commit hash
run: |
echo "Releasing commit: $(git rev-parse HEAD)"
- name: Install Protoc
run:
# Brew's version is much more up to date than the Linux ones, and installing the latest via script runs into curl issues so for now, brew's easier to use
# provisioning/protoc.sh
brew install protobuf
- name: Cache Cargo registry
uses: actions/cache@v4
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache Cargo index
uses: actions/cache@v4
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-git-${{ hashFiles('**/Cargo.lock') }}
- name: Cache Cargo build
uses: actions/cache@v4
with:
path: target
key: ${{ runner.os }}-cargo-build-${{ matrix.target }}-${{ matrix.name }}-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-build-${{ matrix.target }}-${{ matrix.name }}-
${{ runner.os }}-cargo-build-${{ matrix.target }}-
${{ runner.os }}-cargo-build-
- name: Build binary (Darwin)
run: cargo build --release --target ${{ matrix.target }} --bin ${{ matrix.name }}
- name: Package binary (Darwin)
run: |
cd target/${{ matrix.target }}/release
tar -czvf ${{ matrix.name }}-${{ inputs.tag }}-darwin_${{ matrix.package-suffix }}.tar.gz ${{ matrix.name }}
mv ${{ matrix.name }}-${{ inputs.tag }}-darwin_${{ matrix.package-suffix }}.tar.gz ../../../
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.name }}-${{ inputs.tag }}-darwin_${{ matrix.package-suffix }}
path: |
${{ matrix.name }}-${{ inputs.tag }}-darwin_${{ matrix.package-suffix }}.tar.gz
# Builds and pushes Docker images for both PBS and Signer
build-and-push-docker:
needs: [resolve-tag, build-binaries-linux, determine-latest]
permissions:
contents: read
packages: write
strategy:
matrix:
crate: [pbs, signer]
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
ref: ${{ needs.resolve-tag.outputs.commit }}
fetch-depth: 0
submodules: true
- name: Download binary archives
uses: actions/download-artifact@v4
with:
path: ./artifacts
pattern: "commit-boost*"
- name: Extract binaries
run: |
mkdir -p ./artifacts/bin/linux_amd64
mkdir -p ./artifacts/bin/linux_arm64
tar -xzf ./artifacts/commit-boost-${{ matrix.crate }}-${{ inputs.tag }}-linux_x86-64/commit-boost-${{ matrix.crate }}-${{ inputs.tag }}-linux_x86-64.tar.gz -C ./artifacts/bin
mv ./artifacts/bin/commit-boost-${{ matrix.crate }} ./artifacts/bin/linux_amd64/commit-boost-${{ matrix.crate }}
tar -xzf ./artifacts/commit-boost-${{ matrix.crate }}-${{ inputs.tag }}-linux_arm64/commit-boost-${{ matrix.crate }}-${{ inputs.tag }}-linux_arm64.tar.gz -C ./artifacts/bin
mv ./artifacts/bin/commit-boost-${{ matrix.crate }} ./artifacts/bin/linux_arm64/commit-boost-${{ matrix.crate }}
- name: Set lowercase owner
run: echo "OWNER=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
build-args: |
BINARIES_PATH=./artifacts/bin
tags: |
ghcr.io/${{ env.OWNER }}/${{ matrix.crate }}:${{ inputs.tag }}
${{ needs.determine-latest.outputs.value == 'true' && format('ghcr.io/{0}/{1}:latest', env.OWNER, matrix.crate) || '' }}
file: provisioning/${{ matrix.crate }}.Dockerfile
# Signs all binaries with Sigstore for provenance
sign-binaries:
needs: [build-binaries-linux, build-binaries-darwin]
permissions:
contents: read
id-token: write
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Download binary artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
pattern: "commit-boost*"
- name: Sign all binaries with Sigstore
uses: sigstore/gh-action-sigstore-python@v3.0.0
with:
inputs: ./artifacts/**/*.tar.gz
- name: Upload signed artifacts
uses: actions/upload-artifact@v4
with:
name: signed-${{ inputs.tag }}
path: ./artifacts/**/*.sigstore*
# Creates a release on GitHub with the binaries
finalize-release:
needs:
- build-binaries-linux
- build-binaries-darwin
- build-and-push-docker
- sign-binaries
permissions:
contents: write
packages: read
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Download binary artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
pattern: "commit-boost*"
- name: Download signatures
uses: actions/download-artifact@v4
with:
path: ./artifacts
pattern: "signatures-${{ github.ref_name }}*"
- name: Download signed artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
pattern: "signed-*"
- name: Finalize Release
uses: softprops/action-gh-release@v2
with:
files: ./artifacts/**/*
draft: true
prerelease: false
tag_name: ${{ inputs.tag }}
name: ${{ inputs.tag }}
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
# Fast-forwards stable (full release) or beta (RC) to the new tag.
# Runs after all artifacts are built and the draft release is created,
# so stable/beta are never touched if any part of the pipeline fails.
fast-forward-branch:
needs:
- finalize-release
runs-on: ubuntu-latest
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}
- name: Configure git
run: |
git config user.name "commit-boost-release-bot[bot]"
git config user.email "commit-boost-release-bot[bot]@users.noreply.github.com"
- name: Fast-forward beta branch (RC releases)
if: contains(github.ref_name, '-rc')
run: |
git checkout beta
git merge --ff-only "${{ github.ref_name }}"
git push origin beta
- name: Fast-forward stable branch (full releases)
if: "!contains(github.ref_name, '-rc')"
run: |
git checkout stable
git merge --ff-only "${{ github.ref_name }}"
git push origin stable
# Deletes the tag if any job in the release pipeline fails.
# This keeps the tag and release artifacts in sync — a tag should only
# exist if the full pipeline completed successfully.
# stable/beta are never touched on failure since fast-forward-branch
# only runs after finalize-release succeeds.
#
# Note: if finalize-release specifically fails, a draft release may already
# exist on GitHub pointing at the now-deleted tag and will need manual cleanup.
cleanup-on-failure:
needs:
- build-binaries-linux
- build-binaries-darwin
- sign-binaries
- build-and-push-pbs-docker
- build-and-push-signer-docker
- finalize-release
- fast-forward-branch
runs-on: ubuntu-latest
if: failure()
steps:
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: actions/checkout@v4
with:
token: ${{ steps.app-token.outputs.token }}
- name: Delete tag
run: git push origin --delete ${{ github.ref_name }}