Skip to content

Release

Release #5

Workflow file for this run

name: Release
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
version:
description: "Release version without the leading v, for example 0.2.4"
required: true
type: string
permissions:
contents: write
env:
CARGO_TERM_COLOR: always
RELEASE_REF_NAME: ${{ github.event_name == 'workflow_dispatch' && format('v{0}', inputs.version) || github.ref_name }}
jobs:
build:
name: Build ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- name: windows-x64
os: windows-latest
archive: zip
binary: sivtr.exe
- name: linux-x64
os: ubuntu-latest
archive: tar.gz
binary: sivtr
- name: linux-x64-musl
os: ubuntu-latest
archive: tar.gz
binary: sivtr
musl: true
target: x86_64-unknown-linux-musl
- name: macos
os: macos-latest
archive: tar.gz
binary: sivtr
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.88.0
- name: Install musl target
if: matrix.musl
run: rustup target add x86_64-unknown-linux-musl
- name: Install musl tools
if: matrix.musl
run: sudo apt-get update && sudo apt-get install -y musl-tools
- name: Cache cargo
uses: Swatinem/rust-cache@v2
- name: Build
run: |
if [ -n "${{ matrix.target }}" ]; then
cargo build --release --locked --target ${{ matrix.target }}
else
cargo build --release --locked
fi
shell: bash
- name: Package Windows
if: matrix.archive == 'zip'
shell: pwsh
run: |
$name = "sivtr-${{ env.RELEASE_REF_NAME }}-${{ matrix.name }}"
New-Item -ItemType Directory -Path $name | Out-Null
if ("${{ matrix.target }}") {
Copy-Item "target/${{ matrix.target }}/release/${{ matrix.binary }}" $name
} else {
Copy-Item "target/release/${{ matrix.binary }}" $name
}
Copy-Item README.md $name
Copy-Item LICENSE $name
Compress-Archive -Path $name -DestinationPath "$name.zip"
- name: Package Unix
if: matrix.archive == 'tar.gz'
shell: bash
run: |
name="sivtr-${RELEASE_REF_NAME}-${{ matrix.name }}"
mkdir "$name"
if [ -n "${{ matrix.target }}" ]; then
cp "target/${{ matrix.target }}/release/${{ matrix.binary }}" "$name/"
else
cp "target/release/${{ matrix.binary }}" "$name/"
fi
cp README.md LICENSE "$name/"
tar -czf "$name.tar.gz" "$name"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: sivtr-${{ env.RELEASE_REF_NAME }}-${{ matrix.name }}
path: |
*.zip
*.tar.gz
publish-crates:
name: Publish crates.io
needs: build
runs-on: ubuntu-latest
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.88.0
- name: Cache cargo
uses: Swatinem/rust-cache@v2
- name: Publish crates
shell: bash
run: |
set -euo pipefail
if [ -z "${CARGO_REGISTRY_TOKEN:-}" ]; then
echo "::error::CARGO_REGISTRY_TOKEN secret is not configured."
exit 1
fi
version="${RELEASE_REF_NAME#v}"
manifest_version="$(cargo metadata --no-deps --format-version 1 \
| python3 -c 'import json,sys; data=json.load(sys.stdin); print(next(p["version"] for p in data["packages"] if p["name"] == "sivtr"))')"
if [ "$version" != "$manifest_version" ]; then
echo "Tag version ($version) does not match Cargo version ($manifest_version)."
exit 1
fi
crate_exists() {
local crate="$1"
curl -A "sivtr-release-ci" -fsSL "https://crates.io/api/v1/crates/${crate}/${version}" >/dev/null 2>&1
}
wait_for_crate() {
local crate="$1"
for attempt in {1..30}; do
if crate_exists "$crate"; then
return 0
fi
echo "Waiting for ${crate} ${version} to become visible on crates.io (${attempt}/30)..."
sleep 10
done
echo "::error::${crate} ${version} did not become visible on crates.io in time."
return 1
}
if crate_exists sivtr-core; then
echo "sivtr-core ${version} is already published."
else
cargo publish -p sivtr-core --locked --token "$CARGO_REGISTRY_TOKEN"
wait_for_crate sivtr-core
fi
if crate_exists sivtr; then
echo "sivtr ${version} is already published."
else
cargo publish -p sivtr --locked --token "$CARGO_REGISTRY_TOKEN"
fi
release:
name: Publish GitHub Release
needs:
- build
- publish-crates
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Resolve release notes
id: notes
shell: bash
run: |
set -euo pipefail
version="${RELEASE_REF_NAME#v}"
notes="changelogs/${version}.md"
if [ ! -f "$notes" ]; then
echo "::error::Missing release notes: ${notes}"
exit 1
fi
echo "path=${notes}" >> "$GITHUB_OUTPUT"
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Publish release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ env.RELEASE_REF_NAME }}
body_path: ${{ steps.notes.outputs.path }}
files: |
artifacts/**/*
install.sh