The workflow keeps both new steps and both sets of paths: the corpus's CI tier and main's job receipts by two verifiers. Co-Authored-By: Claude Opus 5.5 <[email protected]>
148 lines
8.4 KiB
YAML
148 lines
8.4 KiB
YAML
name: wai-quantum on every processor
|
|
|
|
# The crate promises the same bits on every processor. Native legs run elsewhere
|
|
# (x86_64 Linux, aarch64 macOS, the arm64 Linux VM, wasm32, wasip2); this
|
|
# workflow runs the crate's byte-pinning tests under user-mode QEMU on the
|
|
# instruction sets no runner has, the big-endian ones among them:
|
|
#
|
|
# bit_identity 23 digests across every numeric layer, taken natively and
|
|
# confirmed under wasip2;
|
|
# frame_reference the noisy-Clifford fixtures written by an independent tool;
|
|
# the library the modules that pin exact bytes: the core and its corpora,
|
|
# the fabric and its certificates, the strict JSON reader,
|
|
# receipts, energy labels and the bill of materials.
|
|
#
|
|
# These are emulator results: they prove what each target's binary computes
|
|
# under QEMU, not what that silicon does. i686 is the exception: it runs
|
|
# directly on the x86_64 host in 32-bit mode, so that leg is silicon.
|
|
#
|
|
# Each leg's job container is that target's cross image (linker, sysroot and
|
|
# QEMU, the runner preset in its environment), pinned by digest, capped at
|
|
# 6 GiB: an uncapped emulated run once took the 15 GiB host down. The job
|
|
# installs the pinned Rust into the runner's persistent cache, builds in a
|
|
# target directory of its own there (a build script compiled in one image fails
|
|
# in another with an older glibc), and holds a host-wide lock, so one leg runs
|
|
# at a time across every run of this workflow.
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
on:
|
|
pull_request:
|
|
paths:
|
|
- 'wai/wai-quantum/**'
|
|
- 'rust-toolchain.toml'
|
|
- '.github/workflows/wai-quantum-processors.yml'
|
|
schedule:
|
|
- cron: '48 6 * * *'
|
|
|
|
jobs:
|
|
emulated:
|
|
name: emulated · ${{ matrix.target }}
|
|
runs-on: linux
|
|
timeout-minutes: 120
|
|
container:
|
|
image: ${{ matrix.image }}
|
|
options: --memory=6g --memory-swap=6g ${{ matrix.options }}
|
|
strategy:
|
|
fail-fast: false
|
|
max-parallel: 1
|
|
matrix:
|
|
include:
|
|
- target: s390x-unknown-linux-gnu
|
|
image: ghcr.io/cross-rs/s390x-unknown-linux-gnu@sha256:0d8edc92c39158abe211fddfc9617bf5b7865c2ae0f58873f9cf0c58bb315271
|
|
how: emulated, qemu-user
|
|
- target: sparc64-unknown-linux-gnu
|
|
image: ghcr.io/cross-rs/sparc64-unknown-linux-gnu@sha256:2d04e507ee8bbb1ba61d483d22cf5839a0f138678f71facb40a08a9dffecf316
|
|
how: emulated, qemu-user
|
|
- target: powerpc64-unknown-linux-gnu
|
|
image: ghcr.io/cross-rs/powerpc64-unknown-linux-gnu@sha256:db02ecb2429912a6e939cc3d5cfe00aa20d7423ff484980f1fbfee4a3f2683cf
|
|
how: emulated, qemu-user
|
|
- target: powerpc64le-unknown-linux-gnu
|
|
image: ghcr.io/cross-rs/powerpc64le-unknown-linux-gnu@sha256:de5114adcd786f6a41eb07379459aaae94de73670303e202ea3603d250c19091
|
|
how: emulated, qemu-user
|
|
- target: riscv64gc-unknown-linux-gnu
|
|
image: ghcr.io/cross-rs/riscv64gc-unknown-linux-gnu@sha256:67ee97dd4719390d299edfcf39f226360ccfb1539e08b078ec187d4848415794
|
|
how: emulated, qemu-user
|
|
# QEMU 5.1's 32-bit ARM guest grows the emulator's own memory with the
|
|
# guest's thread count: with all 20 host CPUs, bit_identity's threaded
|
|
# state-vector run took qemu-arm past 6 GiB (a 32-bit guest addresses at
|
|
# most 4 GiB, so the excess is the emulator's). Four CPUs keep it under
|
|
# 1 GiB and still take the threaded paths.
|
|
- target: armv7-unknown-linux-gnueabihf
|
|
image: ghcr.io/cross-rs/armv7-unknown-linux-gnueabihf@sha256:4a08bebb60f08d52c1885b643a768f163c7318c05f91cf119f6c02855ea52699
|
|
options: --cpuset-cpus=0-3
|
|
how: emulated, qemu-user
|
|
# Runs directly on the x86_64 host in 32-bit mode.
|
|
- target: i686-unknown-linux-gnu
|
|
image: ghcr.io/cross-rs/i686-unknown-linux-gnu@sha256:2647400f884dd399a3ce6f6d918fec0776d43e73f471f52e310cbe664ac1671f
|
|
how: silicon, x86_64 host in 32-bit mode
|
|
- target: aarch64-unknown-linux-gnu
|
|
image: ghcr.io/cross-rs/aarch64-unknown-linux-gnu@sha256:7f8308a8734d9fcd2ebbe9a3e4bdea74af293f0799d80c3cc341e340cda49a4c
|
|
how: emulated, qemu-user
|
|
# cross 0.2.5 has no LoongArch image; this is cross's development image.
|
|
- target: loongarch64-unknown-linux-gnu
|
|
image: ghcr.io/cross-rs/loongarch64-unknown-linux-gnu@sha256:8968bd3b2c3b7b6d73c48e10faa605e14b40ce0080579a06402ea9fdfbc2a5c0
|
|
how: emulated, qemu-user
|
|
steps:
|
|
- name: Fetch the source
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
want="${{ github.event.pull_request.head.sha || github.sha }}"
|
|
# The commit itself, not the ref: a later commit on the ref that this
|
|
# workflow's paths do not match would otherwise be tested instead. The
|
|
# archive carries its commit id, checked before anything is built.
|
|
rm -rf src src.tar.gz src.tar && mkdir src
|
|
curl -sSf -o src.tar.gz "http://100.64.224.0:3400/Transaction-Science/open-standards/archive/$want.tar.gz"
|
|
# Decompressed to a file, not a pipe: get-tar-commit-id stops reading at the
|
|
# header, and the writer's broken pipe would fail the step under pipefail.
|
|
gzip -dc src.tar.gz > src.tar
|
|
got="$(git get-tar-commit-id < src.tar)"
|
|
[ "$got" = "$want" ] || { echo "::error::the archive is of $got, not $want"; exit 1; }
|
|
# -m: every file gets the time it was extracted, not its commit's. The build
|
|
# reuses a target directory kept between runs, and cargo takes a crate as
|
|
# built when no source file is newer than its last build: with the commit's
|
|
# times, an older commit ran the binary another commit had built there.
|
|
tar -xmf src.tar -C src --strip-components=1
|
|
rm src.tar.gz src.tar
|
|
- name: The byte-pinning tests
|
|
shell: bash
|
|
working-directory: src/wai/wai-quantum
|
|
run: |
|
|
set -euo pipefail
|
|
t="${{ matrix.target }}"
|
|
cache=/ci-cache/wai-quantum-processors
|
|
mkdir -p "$cache"
|
|
# One leg at a time on this host, across every run of this workflow: the
|
|
# emulated tests are heavy, and the toolchain cache is shared.
|
|
exec 9>"$cache/.lock"
|
|
flock 9
|
|
# Every source file newer than every build in the cache, now that the lock is
|
|
# held: another run may have built here while this one waited for it, after
|
|
# this one's extraction. (../.. is the extracted tree.)
|
|
find ../.. -type f -exec touch {} +
|
|
export RUSTUP_HOME="$cache/rustup" CARGO_HOME="$cache/cargo"
|
|
export PATH="$CARGO_HOME/bin:$PATH"
|
|
if ! command -v rustup >/dev/null; then
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path --profile minimal --default-toolchain none
|
|
fi
|
|
rustup toolchain install
|
|
rustup target add "$t"
|
|
export CARGO_TARGET_DIR="$cache/target/$t"
|
|
logs="$(mktemp -d)"
|
|
run() {
|
|
local name="$1"; shift
|
|
timeout 2700 cargo test --locked --release -j 6 --target "$t" --features full "$@" 2>&1 | tee "$logs/$name.log"
|
|
}
|
|
run bit_identity --test bit_identity
|
|
# The first build after the refresh compiles wai-quantum; one that compiled
|
|
# none ran a binary another commit left in the cache.
|
|
grep -qE '^ *Compiling wai-quantum v[0-9]' "$logs/bit_identity.log" || { echo "::error::$t: the build compiled no wai-quantum: its tests ran a binary already in the cache"; exit 1; }
|
|
grep -qE '^test result: ok\. 23 passed; 0 failed' "$logs/bit_identity.log" || { echo "::error::$t: the 23 bit-identity digests did not all pass"; exit 1; }
|
|
run frame --test frame_reference
|
|
grep -qE '^test result: ok\. 3 passed; 0 failed' "$logs/frame.log" || { echo "::error::$t: the fixtures did not pass"; exit 1; }
|
|
run lib --lib -- quantum:: quantum_fabric:: ijson:: quantum_receipt quantum_energy quantum_qbom merkle
|
|
grep -qE '^test result: ok\. [1-9][0-9]+ passed; 0 failed' "$logs/lib.log" || { echo "::error::$t: the byte-pinning library tests did not pass"; exit 1; }
|
|
echo "processor: $t (${{ matrix.how }}) bit_identity 23/23, fixtures 3/3, $(grep -E '^test result' "$logs/lib.log" | tail -1)"
|