name: Release
on:
workflow_dispatch:
inputs:
version:
description: "Version to release, e.g. 0.2.0 (no leading v)"
required: true
permissions:
contents: read
jobs:
bump:
runs-on: ubuntu-latest
permissions:
contents: write env:
VERSION: ${{ inputs.version }}
steps:
- name: Validate version
run: |
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
echo "::error::'$VERSION' is not a valid semver (e.g. 0.2.0)"
exit 1
fi
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
- name: Install Rust
uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30
- name: Bump Cargo.toml version
run: |
sed -i "0,/^version = \".*\"/{s/^version = \".*\"/version = \"$VERSION\"/}" Cargo.toml
cargo check --quiet # refreshes Cargo.lock's own version entry
- name: Commit and tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Cargo.toml Cargo.lock
# Cargo.toml may already be at the requested version (e.g. the
# very first release) — that's not an error, just nothing to bump.
if git diff --cached --quiet; then
echo "Cargo.toml is already at v$VERSION — nothing to bump."
else
git commit -m "chore(release): v$VERSION"
git push origin HEAD:main
fi
# Re-running after a later job failed shouldn't choke on a tag
# that's already there from the earlier attempt.
if git ls-remote --exit-code --tags origin "refs/tags/v$VERSION" > /dev/null; then
echo "Tag v$VERSION already exists on origin — reusing it."
else
git tag "v$VERSION"
git push origin "v$VERSION"
fi
build:
needs: bump
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
- os: ubuntu-24.04-arm
target: aarch64-unknown-linux-gnu
- os: macos-latest
target: aarch64-apple-darwin
- os: macos-15-intel
target: x86_64-apple-darwin
runs-on: ${{ matrix.os }}
env:
VERSION: ${{ inputs.version }}
steps:
- name: Checkout release tag
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 with:
ref: v${{ inputs.version }}
persist-credentials: false
- name: Install Rust
uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 with:
targets: ${{ matrix.target }}
- name: Cache cargo registry/build
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 with:
key: ${{ matrix.target }}
- name: Build
run: cargo build --release --target ${{ matrix.target }}
- name: Package
run: |
bin="target/${{ matrix.target }}/release/sofka"
strip "$bin"
out="sofka-v$VERSION-${{ matrix.target }}.tar.gz"
tar -czf "$out" -C "$(dirname "$bin")" sofka
echo "ASSET=$out" >> "$GITHUB_ENV"
- name: Upload artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 with:
name: ${{ matrix.target }}
path: ${{ env.ASSET }}
github-release:
needs: [bump, build]
runs-on: ubuntu-latest
permissions:
contents: write env:
VERSION: ${{ inputs.version }}
steps:
- name: Checkout release tag
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 with:
ref: v${{ inputs.version }}
persist-credentials: false
- name: Download all artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 with:
path: dist
merge-multiple: true
- name: Create release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "v$VERSION" dist/*.tar.gz \
--title "v$VERSION" \
--generate-notes
crates-publish:
needs: bump
runs-on: ubuntu-latest
steps:
- name: Checkout release tag
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 with:
ref: v${{ inputs.version }}
persist-credentials: false
- name: Install Rust
uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: cargo publish
nix-cache:
needs: bump
strategy:
matrix:
include:
- os: ubuntu-latest
- os: ubuntu-24.04-arm
- os: macos-latest
- os: macos-15-intel
runs-on: ${{ matrix.os }}
env:
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
steps:
- name: Checkout release tag
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 with:
ref: v${{ inputs.version }}
persist-credentials: false
- name: Setup Nix
uses: ./.github/actions/setup-nix
- name: Build and cache
run: nix build .#sofka --print-build-logs