Skip to content

release canaries

release canaries #2

name: release canaries
# Real projects built with the candidate mcpp before a release is tagged (the
# 2026-09-28 ecosystem design, WS10). release.yml calls this workflow first and
# its tag job needs it, so a canary that fails blocks the tag. It can also be
# dispatched by hand against any branch, to read a candidate early.
#
# The list is .github/release-canaries.toml. Each canary job builds the
# candidate from this commit, checks the project out, removes the project's own
# mcpp pin in that checkout (nothing is committed to the project), and runs the
# project's commands with `$MCPP` naming the candidate.
on:
workflow_call:
workflow_dispatch:
jobs:
list:
name: canaries (list)
runs-on: ubuntu-24.04
outputs:
matrix: ${{ steps.read.outputs.matrix }}
steps:
- uses: actions/checkout@v4
- id: read
run: python3 .github/tools/release_canaries.py matrix >> "$GITHUB_OUTPUT"
canary:
name: canary ${{ matrix.name }} (${{ matrix.os }})
needs: list
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.list.outputs.matrix) }}
runs-on: ${{ matrix.os }}
timeout-minutes: ${{ matrix.timeout }}
defaults:
run:
shell: bash
env:
XLINGS_NON_INTERACTIVE: '1'
PYTHONUTF8: '1'
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/bootstrap-mcpp
- name: Build the candidate mcpp from this commit
run: |
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
"$XLINGS_BIN" config --mirror GLOBAL 2>/dev/null || true
"$MCPP" self config --mirror GLOBAL 2>/dev/null || true
"$MCPP" build
exe=mcpp
[ "$RUNNER_OS" = Windows ] && exe=mcpp.exe
candidate=$(find target -type f -name "$exe" -path '*/bin/*' | head -1)
test -n "$candidate" || { echo "::error::no candidate $exe under target/"; exit 1; }
candidate=$(cd "$(dirname "$candidate")" && pwd)/$(basename "$candidate")
cp "$candidate" "$RUNNER_TEMP/$exe"
echo "CANDIDATE=$RUNNER_TEMP/$exe" >> "$GITHUB_ENV"
"$RUNNER_TEMP/$exe" --version
- name: Check out ${{ matrix.repo }}@${{ matrix.ref }}
run: |
sub=""
[ "${{ matrix.submodules }}" = true ] && sub="--recurse-submodules --shallow-submodules"
git clone --depth 1 --branch "${{ matrix.ref }}" $sub \
"https://github.com/${{ matrix.repo }}" "$RUNNER_TEMP/canary"
# A Windows runner has `python`, not `python3`.
py=python3; command -v python3 >/dev/null 2>&1 || py=python
"$py" .github/tools/release_canaries.py unpin "$RUNNER_TEMP/canary"
- name: Restore the canary's caches
if: matrix.cache != ''
uses: actions/cache@v4
with:
path: ${{ matrix.cache }}
key: canary-${{ matrix.name }}-${{ runner.os }}-${{ github.run_id }}
restore-keys: canary-${{ matrix.name }}-${{ runner.os }}-
- name: Build ${{ matrix.name }} with the candidate
run: |
export MCPP="$CANDIDATE"
export MCPP_VENDORED_XLINGS="$XLINGS_BIN"
# The bash running this step, by path (release_canaries.py says why).
if [ "$RUNNER_OS" = Windows ]; then
export CANARY_BASH="$(cygpath -w "$BASH")"
else
export CANARY_BASH="$BASH"
fi
"$MCPP" self config --mirror GLOBAL
tool="$GITHUB_WORKSPACE/.github/tools/release_canaries.py"
py=python3; command -v python3 >/dev/null 2>&1 || py=python
cd "$RUNNER_TEMP/canary"
"$py" "$tool" run "${{ matrix.name }}"