name: Release
on:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false
permissions: {}
defaults:
run:
shell: bash -xeuo pipefail {0}
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
runs-on: ubuntu-latest
- target: aarch64-unknown-linux-gnu
runs-on: ubuntu-24.04-arm
- target: x86_64-apple-darwin
runs-on: macos-26-intel
- target: aarch64-apple-darwin
runs-on: macos-26
- target: x86_64-pc-windows-msvc
runs-on: windows-latest
- target: aarch64-pc-windows-msvc
runs-on: windows-11-arm
runs-on: ${{ matrix.runs-on }}
permissions:
contents: read
id-token: write
attestations: write
artifact-metadata: write
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with:
persist-credentials: false
- &version
name: Determine version
id: version
run: |
version="$(
cargo metadata --format-version=1 --no-deps |
jq --raw-output \
--arg package shortener \
'.packages[] | select(.name == $package) | .version'
)"
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Run build
run: |
cargo build --locked --bins --all-features --release \
--target "$TARGET"
env:
TARGET: ${{ matrix.target }}
- name: Package
id: package
run: |
cargo install --locked --bins --all-features --no-track \
--target "$TARGET" \
--path . \
--root "$ARTIFACT"
tar czvf "$ARTIFACT.tar.gz" "$ARTIFACT"
echo "artifact=$ARTIFACT.tar.gz" >> "$GITHUB_OUTPUT"
env:
ARTIFACT: shortener-${{ steps.version.outputs.version }}-${{ matrix.target }}
TARGET: ${{ matrix.target }}
- name: Generate build provenance
uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 with:
subject-path: ${{ steps.package.outputs.artifact }}
- name: Upload artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with:
name: ${{ steps.package.outputs.artifact }}
path: ${{ steps.package.outputs.artifact }}
release:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with:
persist-credentials: false
- *version
- name: Create bot token
id: token
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 with:
client-id: ${{ vars.APP_CLIENT_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Create tag
run: |
gh api "/repos/$GITHUB_REPOSITORY/git/refs" \
-f "ref=refs/tags/v$VERSION" \
-f "sha=$GITHUB_SHA"
env:
GH_TOKEN: ${{ steps.token.outputs.token }}
VERSION: ${{ steps.version.outputs.version }}
- name: Download artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c with:
path: artifacts
- name: Create release
env:
GH_TOKEN: ${{ github.token }}
VERSION: ${{ steps.version.outputs.version }}
run: |
gh release create "v$VERSION" \
--draft \
--title "$VERSION" \
--generate-notes \
artifacts/**/*.tar.gz
publish-crate:
needs: release
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with:
persist-credentials: false
- name: Perform release checks
run: cargo publish --dry-run
- name: Authenticate to crates.io
id: auth
uses: rust-lang/crates-io-auth-action@bbd81622f20ce9e2dd9622e3218b975523e45bbe - name: Publish crate
run: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}