name: Continuous Deployment
on:
push:
branches:
- main
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
jobs:
release-plz:
name: Release-plz
if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }}
runs-on: ubuntu-latest
permissions:
actions: write
contents: write
pull-requests: write
packages: write
env:
EFFECTIVE_GITHUB_TOKEN: ${{ secrets.RELEASE_PLZ_TOKEN != '' && secrets.RELEASE_PLZ_TOKEN || github.token }}
RELEASE_PLZ_TOKEN_CONFIGURED: ${{ secrets.RELEASE_PLZ_TOKEN != '' }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ env.EFFECTIVE_GITHUB_TOKEN }}
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Install cargo-audit
uses: taiki-e/install-action@v2
with:
tool: cargo-audit
- name: Install system dependencies
run: |
sudo apt-get update -y
sudo apt-get --assume-yes install \
nasm ffmpeg autoconf autoconf-archive automake libtool
- name: Cache cargo-vcpkg binary
id: cargo-vcpkg-cache
uses: actions/cache@v4
with:
path: ~/.cargo/bin/cargo-vcpkg
key: cargo-vcpkg-linux-v1
- name: Install cargo-vcpkg
if: steps.cargo-vcpkg-cache.outputs.cache-hit != 'true'
run: cargo install cargo-vcpkg --locked
- name: Cache vcpkg workspace
id: vcpkg-cache
uses: actions/cache@v4
with:
path: |
target/vcpkg/.vcpkg-root
target/vcpkg/.git
target/vcpkg/downloads
target/vcpkg/installed
target/vcpkg/packages
target/vcpkg/ports
target/vcpkg/scripts
target/vcpkg/triplets
target/vcpkg/vcpkg
key: vcpkg-root-linux-v2-${{ hashFiles('Cargo.toml') }}
restore-keys: |
vcpkg-root-linux-v2-
- name: Validate vcpkg cache origin
run: |
cache_invalid=0
expected_rev="$(grep -E '^rev = "' Cargo.toml | head -n1 | awk -F'"' '{print $2}')"
if [ -e "target/vcpkg" ] && [ ! -e "target/vcpkg/.git" ]; then
echo "vcpkg root missing .git; clearing cache entry"
rm -rf target/vcpkg
cache_invalid=1
fi
for dir in target/vcpkg target/vcpkg/.vcpkg-root target/vcpkg/vcpkg; do
if [ -e "$dir/.git" ]; then
origin=$(git -C "$dir" remote get-url origin 2>/dev/null || true)
if [ -z "$origin" ]; then
echo "Failed to read vcpkg origin in $dir; clearing cache entry"
rm -rf "$dir"
cache_invalid=1
continue
fi
if [ "$origin" != "https://github.com/microsoft/vcpkg.git" ] && [ "$origin" != "https://github.com/microsoft/vcpkg" ]; then
echo "Unexpected vcpkg origin in $dir: $origin"
rm -rf "$dir"
cache_invalid=1
continue
fi
if [ -n "$expected_rev" ]; then
if ! git -C "$dir" cat-file -e "${expected_rev}^{tree}" 2>/dev/null; then
echo "Missing vcpkg rev $expected_rev in $dir; clearing cache entry"
rm -rf "$dir"
cache_invalid=1
fi
fi
fi
done
if [ "$cache_invalid" -eq 1 ]; then
echo "VCPKG_CACHE_INVALID=1" >> "$GITHUB_ENV"
fi
- name: Use cached vcpkg workspace
if: steps.vcpkg-cache.outputs.cache-hit == 'true' && env.VCPKG_CACHE_INVALID != '1'
run: echo "vcpkg workspace cache hit; skipping dependency rebuild."
- name: Build vcpkg dependencies
if: steps.vcpkg-cache.outputs.cache-hit != 'true' || env.VCPKG_CACHE_INVALID == '1'
env:
VCPKG_FEATURE_FLAGS: manifests,binarycaching
VCPKG_BINARY_SOURCES: clear;x-gha,readwrite
VCPKG_CMAKE_CONFIGURE_OPTIONS: -Wno-dev -DCMAKE_POLICY_DEFAULT_CMP0174=NEW
VCPKG_MAX_CONCURRENCY: 2
CMAKE_BUILD_PARALLEL_LEVEL: 2
run: |
cargo vcpkg --verbose build
- name: Export VCPKG_ROOT
run: echo "VCPKG_ROOT=$(pwd)/target/vcpkg" >> $GITHUB_ENV
- name: Clippy strict
env:
VCPKG_ROOT: ${{ env.VCPKG_ROOT }}
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Cargo audit
run: cargo audit
- name: Install git-cliff
uses: taiki-e/install-action@v2
with:
tool: git-cliff
- name: Generate release notes preview
run: |
bash ./scripts/generate_release_notes.sh RELEASE_NOTES.md
- name: Upload release notes artifact
uses: actions/upload-artifact@v4
with:
name: release-notes-preview
path: RELEASE_NOTES.md
- name: Clean release notes preview file
run: rm -f RELEASE_NOTES.md
- name: Run release-plz (update)
uses: MarcoIeni/release-plz-action@v0.5
with:
command: update
env:
GITHUB_TOKEN: ${{ env.EFFECTIVE_GITHUB_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Commit version and changelog updates
run: |
if git diff --quiet; then
echo "No release metadata changes detected."
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add Cargo.toml Cargo.lock CHANGELOG.md
git commit -m "chore(release): update versions and changelog [skip ci]"
git push origin HEAD:main
- name: Capture release tags before release-plz
if: ${{ env.RELEASE_PLZ_TOKEN_CONFIGURED != 'true' }}
shell: bash
run: |
set -euo pipefail
git fetch --tags --force
git tag --list | sort > "$RUNNER_TEMP/release-tags-before.txt"
- name: Run release-plz (release)
id: release-plz-release
uses: MarcoIeni/release-plz-action@v0.5
with:
command: release
env:
GITHUB_TOKEN: ${{ env.EFFECTIVE_GITHUB_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Dispatch binary release workflow
if: ${{ env.RELEASE_PLZ_TOKEN_CONFIGURED != 'true' }}
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
before="$RUNNER_TEMP/release-tags-before.txt"
after="$RUNNER_TEMP/release-tags-after.txt"
git fetch --tags --force
git tag --list | sort > "$after"
new_tags="$(comm -13 "$before" "$after" | grep -E '(^|/|v)[0-9]+\.[0-9]+\.[0-9]+' || true)"
if [[ -z "$new_tags" ]]; then
echo "No new release tags created; skipping binary release dispatch."
exit 0
fi
while IFS= read -r release_tag; do
[[ -n "$release_tag" ]] || continue
echo "Dispatching binary release workflow for ${release_tag}."
gh workflow run release.yml --ref "$release_tag" -f tag="$release_tag"
done <<< "$new_tags"