name: Finalize release
on:
push:
tags: ['v*']
workflow_dispatch:
inputs:
tag:
description: Release tag, for example v1.0.0
required: true
type: string
permissions:
actions: write
contents: write
jobs:
package:
name: Package release assets
runs-on: ubuntu-latest
steps:
- name: Select the release tag
env:
INPUT_TAG: ${{ inputs.tag }}
run: |
set -euo pipefail
if [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ]; then
tag="$INPUT_TAG"
else
tag="$GITHUB_REF_NAME"
fi
[[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] || { echo "invalid release tag: $tag" >&2; exit 1; }
echo "TAG=$tag" >> "$GITHUB_ENV"
- uses: actions/checkout@v4
with:
ref: refs/tags/${{ env.TAG }}
- name: Install Rust toolchain
run: rustup show
- name: Cache cargo registry and build artifacts
uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- name: Install wasm32 target
run: rustup target add wasm32-unknown-unknown
- name: Install native audio dependencies
timeout-minutes: 15
run: python3 .github/scripts/apt_install.py libasound2-dev
- name: Install wasm-pack
env:
WASM_PACK_VERSION: '0.15.0'
run: |
target="wasm-pack-v${WASM_PACK_VERSION}-x86_64-unknown-linux-musl"
mkdir -p "$RUNNER_TEMP/wasm-pack"
curl -sSfL "https://github.com/rustwasm/wasm-pack/releases/download/v${WASM_PACK_VERSION}/${target}.tar.gz" \
| tar -xz --strip-components=1 -C "$RUNNER_TEMP/wasm-pack" "${target}/wasm-pack"
echo "$RUNNER_TEMP/wasm-pack" >> "$GITHUB_PATH"
- name: Verify every package version matches the release tag
run: |
mismatched="$(cargo metadata --no-deps --format-version 1 \
| jq -r --arg version "${TAG#v}" '.packages[] | select(.version != $version) | .name')"
if [ -n "$mismatched" ]; then
echo "these packages are not at ${TAG#v}: $mismatched"
exit 1
fi
- name: Build release assets
run: |
mkdir release
# `zvidlib` and every crate it is built from, verified together so
# each one builds against the others as they will be published.
# The benchmark helpers are development-only and never published.
cargo package --workspace --exclude zvidlib-bench-support --locked
cp target/package/*.crate release/
wasm-pack build --release --target web --out-dir pkg --features web
(cd pkg && npm pack --pack-destination ../release)
mv release/zvidlib-*.tgz "release/zvidlib-web-${TAG}.tgz"
- name: Extract the release notes
run: |
set -euo pipefail
extract_section() {
awk -v heading="$1" '
index($0, heading) == 1 { in_section = 1; next }
in_section && /^## / { exit }
in_section { print }
' CHANGELOG.md | sed -e '/./,$!d' | sed -e :a -e '/^\n*$/{$d;N;ba' -e '}'
}
notes="$RUNNER_TEMP/release-notes.md"
extract_section "## ${TAG#v} - " > "$notes"
if [ ! -s "$notes" ]; then
extract_section "## Unreleased" > "$notes"
fi
[ -s "$notes" ] || { echo "CHANGELOG.md has no entry for $TAG" >&2; exit 1; }
echo "NOTES_FILE=$notes" >> "$GITHUB_ENV"
- name: Create the GitHub release with its assets
env:
GH_TOKEN: ${{ github.token }}
run: |
if gh release view "$TAG" > /dev/null 2>&1; then
gh release upload "$TAG" release/* --clobber
else
gh release create "$TAG" release/* --verify-tag --title "zvidlib ${TAG}" --notes-file "$NOTES_FILE"
fi
- name: Start Publish crates
env:
GH_TOKEN: ${{ github.token }}
run: gh workflow run publish-crates.yml --repo "$GITHUB_REPOSITORY" --ref "$TAG" -f tag="$TAG"