Research-Stack/4-Infrastructure/servo-fetch/.github/workflows/release.yml

216 lines
7.2 KiB
YAML

name: Release
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
permissions:
contents: read
jobs:
create-release:
name: Create Release
runs-on: ubuntu-24.04
timeout-minutes: 10
permissions:
contents: write
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
TAG: ${{ github.ref_name }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Validate tag matches Cargo.toml version
id: version
run: |
VERSION="${TAG#v}"
CARGO_VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
if [ "$VERSION" != "$CARGO_VERSION" ]; then
echo "::error::Tag $TAG does not match Cargo.toml version $CARGO_VERSION"
exit 1
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Generate release notes
run: gh api "repos/$REPO/releases/generate-notes" -f tag_name="$TAG" --jq .body > RELEASE_NOTES.md
- name: Create GitHub release
run: gh release create "$TAG" --draft --verify-tag --title "$TAG" --notes-file RELEASE_NOTES.md
outputs:
version: ${{ steps.version.outputs.version }}
build-release:
name: Build ${{ matrix.target }}
needs: [create-release]
runs-on: ${{ matrix.os }}
timeout-minutes: 90
permissions:
contents: write
id-token: write
attestations: write
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-24.04
- target: aarch64-unknown-linux-gnu
os: ubuntu-24.04-arm
- target: aarch64-apple-darwin
os: macos-latest
- target: x86_64-apple-darwin
os: macos-15-intel
- target: x86_64-pc-windows-msvc
os: windows-2022
env:
RUST_BACKTRACE: 1
CARGO_INCREMENTAL: 0
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: sccache
CCACHE: sccache
TARGET: ${{ matrix.target }}
VERSION: ${{ needs.create-release.outputs.version }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.ref_name }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1
with:
toolchain: "1.95.0"
targets: ${{ matrix.target }}
- uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
- name: Install system dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y cmake clang llvm pkg-config libfontconfig-dev libfreetype-dev \
libssl-dev libglib2.0-dev libegl1-mesa-dev \
xvfb libegl1 libgles2 libgl1-mesa-dri mesa-utils \
libfontconfig1 libfreetype6 libharfbuzz0b libx11-6 libxcb1 libxcb-render0 libxcb-shape0 libxcb-xfixes0
- name: Set LIBCLANG_PATH (Windows)
if: runner.os == 'Windows'
shell: bash
run: printf 'LIBCLANG_PATH=C:\\Program Files\\LLVM\\bin\n' >> "$GITHUB_ENV"
- name: Build release binary
shell: bash
run: cargo build --release --locked --target "$TARGET"
- name: Bundle Windows ANGLE DLLs
if: runner.os == 'Windows'
shell: bash
run: |
set -eu
shopt -s failglob
BIN_DIR="target/$TARGET/release"
cp "$BIN_DIR"/build/mozangle-*/out/libEGL.dll "$BIN_DIR"/
cp "$BIN_DIR"/build/mozangle-*/out/libGLESv2.dll "$BIN_DIR"/
- name: Smoke test (CLI only, no network)
shell: bash
run: |
set -euo pipefail
BIN="target/$TARGET/release/servo-fetch"
[[ "${{ runner.os }}" == "Windows" ]] && BIN="$BIN.exe"
"$BIN" --version | grep -q '^servo-fetch '
"$BIN" --help >/dev/null
- name: Strip binary (Unix)
if: runner.os != 'Windows'
shell: bash
run: strip "target/$TARGET/release/servo-fetch"
- name: Determine archive name
shell: bash
run: echo "ARCHIVE=servo-fetch-v${VERSION}-${TARGET}" >> "$GITHUB_ENV"
- name: Build archive (Unix)
if: runner.os != 'Windows'
shell: bash
run: |
set -eu
mkdir "$ARCHIVE"
cp "target/$TARGET/release/servo-fetch" "$ARCHIVE"/
cp README.md LICENSE "$ARCHIVE"/
tar czf "$ARCHIVE.tar.gz" "$ARCHIVE"
shasum -a 256 "$ARCHIVE.tar.gz" > "$ARCHIVE.tar.gz.sha256"
- name: Build archive (Windows)
if: runner.os == 'Windows'
shell: bash
run: |
set -eu
mkdir "$ARCHIVE"
cp "target/$TARGET/release/servo-fetch.exe" "$ARCHIVE"/
cp "target/$TARGET/release/libEGL.dll" "$ARCHIVE"/
cp "target/$TARGET/release/libGLESv2.dll" "$ARCHIVE"/
cp README.md LICENSE "$ARCHIVE"/
7z a "$ARCHIVE.zip" "$ARCHIVE"
certutil -hashfile "$ARCHIVE.zip" SHA256 > "$ARCHIVE.zip.sha256"
- name: Attest build provenance (Unix)
if: runner.os != 'Windows'
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
with:
subject-path: ${{ env.ARCHIVE }}.tar.gz
- name: Attest build provenance (Windows)
if: runner.os == 'Windows'
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
with:
subject-path: ${{ env.ARCHIVE }}.zip
- name: Upload release archive
shell: bash
run: |
set -eu
if [[ "${{ runner.os }}" == "Windows" ]]; then
gh release upload "$TAG" "$ARCHIVE.zip" "$ARCHIVE.zip.sha256"
else
gh release upload "$TAG" "$ARCHIVE.tar.gz" "$ARCHIVE.tar.gz.sha256"
fi
publish-crate:
name: Publish to crates.io
needs: [create-release, build-release]
runs-on: ubuntu-24.04
timeout-minutes: 15
permissions:
id-token: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1
with:
toolchain: "1.95.0"
- name: Dry-run package (gate for --no-verify below)
run: cargo package --locked --list >/dev/null
- uses: rust-lang/crates-io-auth-action@bbd81622f20ce9e2dd9622e3218b975523e45bbe # v1.0.4
id: auth
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
run: cargo publish --locked --no-verify
publish-release:
name: Publish Release
needs: [create-release, build-release, publish-crate]
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions:
contents: write
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
TAG: ${{ github.ref_name }}
steps:
- name: Mark release as non-draft
run: gh release edit "$TAG" --repo "$REPO" --draft=false