name: Release
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*'
permissions: {}
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
env:
SQLX_OFFLINE: "true"
jobs:
verify:
name: Verify tag + green tree
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Tag matches Cargo.toml version
run: |
tag="${GITHUB_REF_NAME#v}"
crate="$(grep -m1 -E '^version[[:space:]]*=' Cargo.toml \
| sed -E 's/^version[[:space:]]*=[[:space:]]*"([^"]+)".*/\1/')"
echo "tag version: $tag"
echo "crate version: $crate"
if [ "$tag" != "$crate" ]; then
echo "::error::pushed tag v$tag does not match Cargo.toml version $crate"
exit 1
fi
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Cache dependencies
uses: Swatinem/rust-cache@v2
- name: Check formatting
run: cargo fmt --all --check
- name: Clippy
run: cargo clippy --all-targets -- -D warnings
- name: Tests
run: cargo test
build:
name: Build ${{ matrix.target }}
needs: verify
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
runner: ubuntu-latest
- target: aarch64-unknown-linux-gnu
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Cache dependencies
uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}
- name: Build
run: cargo build --release --locked --target ${{ matrix.target }}
- name: Package
run: |
version="${GITHUB_REF_NAME#v}"
pkg="sagittarius-${version}-${{ matrix.target }}"
stage="dist/${pkg}"
mkdir -p "${stage}"
cp "target/${{ matrix.target }}/release/sagittarius" "${stage}/"
strip "${stage}/sagittarius"
cp README.md CHANGELOG.md LICENSE-MIT LICENSE-APACHE "${stage}/"
tar -C dist -czf "dist/${pkg}.tar.gz" "${pkg}"
(cd dist && sha256sum "${pkg}.tar.gz" > "${pkg}.tar.gz.sha256")
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}
path: |
dist/*.tar.gz
dist/*.sha256
github-release:
name: GitHub Release
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate release notes
id: cliff
uses: orhun/git-cliff-action@v4
with:
config: cliff.toml
args: --latest --strip header
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: Detect pre-release
id: prerelease
run: |
if [[ "${GITHUB_REF_NAME}" == *-* ]]; then
echo "value=true" >> "${GITHUB_OUTPUT}"
else
echo "value=false" >> "${GITHUB_OUTPUT}"
fi
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
body: ${{ steps.cliff.outputs.content }}
prerelease: ${{ steps.prerelease.outputs.value }}
fail_on_unmatched_files: true
files: |
dist/*.tar.gz
dist/*.sha256
publish-crate:
name: Publish to crates.io
needs: [build, github-release, docker]
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache dependencies
uses: Swatinem/rust-cache@v2
- name: Publish
run: cargo publish --locked
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
docker:
name: Docker image
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Stage binaries per architecture
run: |
version="${GITHUB_REF_NAME#v}"
mkdir -p binaries/amd64 binaries/arm64
tar -xzf "artifacts/x86_64-unknown-linux-gnu/sagittarius-${version}-x86_64-unknown-linux-gnu.tar.gz" -C /tmp
cp "/tmp/sagittarius-${version}-x86_64-unknown-linux-gnu/sagittarius" binaries/amd64/sagittarius
tar -xzf "artifacts/aarch64-unknown-linux-gnu/sagittarius-${version}-aarch64-unknown-linux-gnu.tar.gz" -C /tmp
cp "/tmp/sagittarius-${version}-aarch64-unknown-linux-gnu/sagittarius" binaries/arm64/sagittarius
- name: Set up Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Image metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/lhelge/sagittarius
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable=${{ !contains(github.ref_name, '-') }}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}