mirror of
https://github.com/cfal/shoes.git
synced 2026-11-07 00:13:35 +00:00
* Refresh dependencies and CI tooling while preserving fork pins * Make privileged test fixtures compatible with Ubuntu 26
224 lines
7.6 KiB
YAML
224 lines
7.6 KiB
YAML
name: Build Binaries
|
|
|
|
on:
|
|
push:
|
|
branches: [ master ]
|
|
tags: [ 'v*' ]
|
|
pull_request:
|
|
branches: [ master ]
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: binaries-${{ github.ref }}
|
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
CARGO_BUILD_JOBS: 1
|
|
CROSS_VERSION: 0.2.5
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
|
|
jobs:
|
|
version:
|
|
name: Validate release version
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 5
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Check manifest, lockfile, and tag
|
|
run: |
|
|
python3 - <<'PY'
|
|
import os
|
|
import tomllib
|
|
from pathlib import Path
|
|
|
|
manifest = tomllib.loads(Path("Cargo.toml").read_text())["package"]
|
|
packages = tomllib.loads(Path("Cargo.lock").read_text())["package"]
|
|
locked = [p["version"] for p in packages if p["name"] == manifest["name"] and "source" not in p]
|
|
assert locked == [manifest["version"]], "Manifest and lockfile versions differ"
|
|
if os.environ["GITHUB_REF_TYPE"] == "tag":
|
|
assert os.environ["GITHUB_REF_NAME"] == f'v{manifest["version"]}', "Tag does not match package version"
|
|
PY
|
|
|
|
- name: Test release smoke checks
|
|
run: python3 scripts/test-smoke-release.py
|
|
|
|
build:
|
|
name: Build ${{ matrix.target }}
|
|
needs: version
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 90
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- target: x86_64-unknown-linux-gnu
|
|
os: ubuntu-24.04
|
|
use_cross: false
|
|
- target: x86_64-unknown-linux-musl
|
|
os: ubuntu-24.04
|
|
use_cross: true
|
|
- target: aarch64-unknown-linux-gnu
|
|
os: ubuntu-24.04
|
|
use_cross: true
|
|
- target: aarch64-unknown-linux-musl
|
|
os: ubuntu-24.04
|
|
use_cross: true
|
|
- target: armv7-unknown-linux-gnueabihf
|
|
os: ubuntu-24.04
|
|
use_cross: true
|
|
- target: armv7-unknown-linux-musleabihf
|
|
os: ubuntu-24.04
|
|
use_cross: true
|
|
- target: x86_64-apple-darwin
|
|
os: macos-15-intel
|
|
use_cross: false
|
|
- target: aarch64-apple-darwin
|
|
os: macos-15
|
|
use_cross: false
|
|
env:
|
|
TARGET: ${{ matrix.target }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@b725eda525362e7cf34af9a7243cac1e3f01a7ec
|
|
with:
|
|
toolchain: 1.99.1
|
|
targets: ${{ matrix.target }}
|
|
|
|
- name: Install pinned cross binary
|
|
if: matrix.use_cross
|
|
run: |
|
|
curl --fail --location --retry 3 \
|
|
"https://github.com/cross-rs/cross/releases/download/v${CROSS_VERSION}/cross-x86_64-unknown-linux-gnu.tar.gz" \
|
|
--output "$RUNNER_TEMP/cross.tar.gz"
|
|
echo "642375d1bcf3bd88272c32ba90e999f3d983050adf45e66bd2d3887e8e838bad $RUNNER_TEMP/cross.tar.gz" | sha256sum --check --strict
|
|
tar -xzf "$RUNNER_TEMP/cross.tar.gz" -C "$HOME/.cargo/bin" cross
|
|
|
|
- name: Setup cache
|
|
uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2
|
|
with:
|
|
key: release-${{ matrix.target }}
|
|
save-if: ${{ github.ref == 'refs/heads/master' }}
|
|
|
|
- name: Build binary (cross)
|
|
if: matrix.use_cross
|
|
run: cross build --release --locked --target "$TARGET" --bin shoes
|
|
|
|
- name: Build binary (native)
|
|
if: ${{ !matrix.use_cross }}
|
|
run: cargo build --release --locked --target "$TARGET" --bin shoes
|
|
|
|
- name: Verify lockfile unchanged
|
|
run: git diff --exit-code -- Cargo.lock
|
|
|
|
# Cargo's release profile strips with the target toolchain before packaging.
|
|
- name: Package binary and notices
|
|
run: |
|
|
test -x "target/$TARGET/release/shoes"
|
|
file "target/$TARGET/release/shoes"
|
|
case "$TARGET" in
|
|
*musl*) file "target/$TARGET/release/shoes" | grep -E 'static.*linked' ;;
|
|
esac
|
|
mkdir -p package artifacts smoke
|
|
cp "target/$TARGET/release/shoes" THIRD_PARTY_NOTICES.md package/
|
|
cp -R licenses package/
|
|
tar -czf "artifacts/shoes-$TARGET.tar.gz" -C package shoes THIRD_PARTY_NOTICES.md licenses
|
|
python3 scripts/check-release-notices.py "artifacts/shoes-$TARGET.tar.gz"
|
|
tar -xzf "artifacts/shoes-$TARGET.tar.gz" -C smoke
|
|
|
|
- name: Smoke-test packaged binary (cross/QEMU)
|
|
if: matrix.use_cross
|
|
timeout-minutes: 5
|
|
run: |
|
|
image="$(python3 -c 'import sys, tomllib; print(tomllib.load(open("Cross.toml", "rb"))["target"][sys.argv[1]]["image"])' "$TARGET")"
|
|
runner=/linux-runner
|
|
case "$TARGET" in
|
|
*musl*) runner=/qemu-runner ;;
|
|
esac
|
|
python3 scripts/smoke-release.py docker run --rm \
|
|
--volume "$PWD:/work:ro" --workdir /work \
|
|
"$image" "$runner" "${TARGET%%-*}" ./smoke/shoes
|
|
|
|
- name: Smoke-test packaged binary (native)
|
|
if: ${{ !matrix.use_cross }}
|
|
timeout-minutes: 5
|
|
run: python3 scripts/smoke-release.py ./smoke/shoes
|
|
|
|
- name: Upload verified archive
|
|
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
|
|
with:
|
|
name: shoes-${{ matrix.target }}
|
|
path: artifacts/shoes-${{ matrix.target }}.tar.gz
|
|
if-no-files-found: error
|
|
|
|
release:
|
|
name: Create Draft Release
|
|
needs: build
|
|
if: startsWith(github.ref, 'refs/tags/')
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 10
|
|
permissions:
|
|
contents: write
|
|
id-token: write
|
|
attestations: write
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Verify tag still targets this commit and release is unpublished
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
git fetch --no-tags origin "refs/tags/$GITHUB_REF_NAME"
|
|
test "$(git rev-parse 'FETCH_HEAD^{commit}')" = "$GITHUB_SHA"
|
|
gh api --paginate "repos/$GITHUB_REPOSITORY/releases" \
|
|
--jq '.[] | {tag_name, draft}' > "$RUNNER_TEMP/releases.jsonl"
|
|
jq --slurp --exit-status --arg tag "$GITHUB_REF_NAME" \
|
|
'[.[] | select(.tag_name == $tag)] | all(.draft)' "$RUNNER_TEMP/releases.jsonl"
|
|
|
|
- name: Download verified archives
|
|
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8
|
|
with:
|
|
pattern: shoes-*
|
|
path: release-artifacts
|
|
merge-multiple: true
|
|
|
|
- name: Verify notices and checksum final archives
|
|
run: |
|
|
archives=(release-artifacts/shoes-*.tar.gz)
|
|
test "${#archives[@]}" -eq 8
|
|
for archive in "${archives[@]}"; do
|
|
python3 scripts/check-release-notices.py "$archive"
|
|
done
|
|
cd release-artifacts
|
|
sha256sum shoes-*.tar.gz > SHA256SUMS
|
|
sha256sum --check --strict SHA256SUMS
|
|
|
|
- name: Attest final release artifacts
|
|
uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2
|
|
with:
|
|
subject-path: release-artifacts/*
|
|
|
|
- name: Create Draft Release
|
|
uses: softprops/action-gh-release@8a0cd651e5b2365bd640854a3fa5dfc70e4875f3 # v3.0.4
|
|
with:
|
|
files: release-artifacts/*
|
|
fail_on_unmatched_files: true
|
|
draft: true
|
|
generate_release_notes: true
|