smoke.sh ends with receipt_ledger_verify.py, which imports pack_verify.py, which reads TOML with the standard library's tomllib (3.11). The linux runner's image has Python 3.10, so the step failed on the import. The job now sets up Python 3.11 as wai-key-proxy's does, and the step says so first if the python3 it finds has no tomllib. Co-Authored-By: Claude Opus 5.5 <[email protected]>
137 lines
5.8 KiB
YAML
137 lines
5.8 KiB
YAML
name: wai-ledger service
|
|
|
|
# The WAI receipt ledger as a service (wai/wai-ledger, extensions/receipt-ledger.md §9): its
|
|
# tests (the corpus's invoices issued byte for byte, the chain recovered from the directory
|
|
# after a restart, a source billed once, one process per directory), clippy with warnings as
|
|
# errors, and its smoke checks over HTTP against an instance started here with the corpus's
|
|
# seller key, the invoice's verification document checked by receipt_ledger_verify.py; on
|
|
# Linux and on the macOS runner (the host the service would be deployed to).
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
paths:
|
|
- 'wai/wai-rs/**'
|
|
- 'wai/wai-ledger/**'
|
|
- 'wai/live-conformance/**'
|
|
- 'wai/pack-conformance/**'
|
|
- 'wai/claim-conformance/**'
|
|
- 'wai/extensions/receipt-ledger.md'
|
|
- 'rust-toolchain.toml'
|
|
- '.github/workflows/wai-ledger.yml'
|
|
pull_request:
|
|
paths:
|
|
- 'wai/wai-rs/**'
|
|
- 'wai/wai-ledger/**'
|
|
- 'wai/live-conformance/**'
|
|
- 'wai/pack-conformance/**'
|
|
- 'wai/claim-conformance/**'
|
|
- 'wai/extensions/receipt-ledger.md'
|
|
- 'rust-toolchain.toml'
|
|
- '.github/workflows/wai-ledger.yml'
|
|
|
|
jobs:
|
|
relevant:
|
|
name: does this change touch it
|
|
runs-on: linux-arm64
|
|
outputs:
|
|
run: ${{ steps.gate.outputs.run }}
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
with:
|
|
fetch-depth: 0
|
|
- id: gate
|
|
run: |
|
|
set -euo pipefail
|
|
r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-ledger.yml \
|
|
"${{ github.event.pull_request.base.sha }}" \
|
|
"${{ github.event.pull_request.head.sha }}")
|
|
echo "this change touches wai-ledger: $r"
|
|
echo "run=$r" >> "$GITHUB_OUTPUT"
|
|
|
|
service-linux:
|
|
name: service · linux
|
|
needs: relevant
|
|
if: needs.relevant.outputs.run == 'true'
|
|
runs-on: linux
|
|
timeout-minutes: 60
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- name: Install Rust 1.98.0
|
|
shell: bash
|
|
run: |
|
|
export PATH="$HOME/.cargo/bin:$PATH"
|
|
command -v rustup >/dev/null 2>&1 || \
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.98.0
|
|
rustup toolchain install 1.98.0 --profile minimal --component clippy
|
|
rustup default 1.98.0
|
|
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
|
- name: Tests and clippy
|
|
shell: bash
|
|
working-directory: wai/wai-ledger
|
|
run: |
|
|
set -euo pipefail
|
|
cargo test --locked --release 2>&1 | tee "$RUNNER_TEMP/test.log"
|
|
grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$RUNNER_TEMP/test.log" || { echo "::error::no test ran"; exit 1; }
|
|
cargo clippy --locked --release --all-targets -- -D warnings
|
|
# smoke.sh ends with the independent verifier, receipt_ledger_verify.py, which reads
|
|
# packages with pack_verify.py and so needs the standard library's tomllib (Python 3.11):
|
|
# the runner image's own Python is older.
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.11'
|
|
- name: The smoke checks over HTTP
|
|
shell: bash
|
|
working-directory: wai/wai-ledger
|
|
run: |
|
|
set -euo pipefail
|
|
python3 -c 'import sys, tomllib; print(sys.version.split()[0])' \
|
|
|| { echo "::error::python3 here has no tomllib (Python 3.11 or later), which the independent verifier needs"; exit 1; }
|
|
cargo build --locked --release
|
|
dir="$RUNNER_TEMP/ledger"; key="$RUNNER_TEMP/ledger.key"; rm -rf "$dir" "$key"
|
|
# The corpus's seller key, from its fixed seed (a test key, never a deployment's).
|
|
python3 -I -c 'import hashlib,sys; sys.stdout.buffer.write(hashlib.sha256(b"wai:ledger-corpus\x01seller").digest())' > "$key"
|
|
WAI_LEDGER_KEY="$key" WAI_LEDGER_DIR="$dir" WAI_LEDGER_ADDR=127.0.0.1:18251 \
|
|
./target/release/wai-ledger serve 2> "$RUNNER_TEMP/service.log" &
|
|
pid=$!
|
|
trap 'kill $pid 2>/dev/null || true; cat "$RUNNER_TEMP/service.log"' EXIT
|
|
for _ in $(seq 1 50); do curl -s -o /dev/null http://127.0.0.1:18251/v1/health && break; sleep 0.2; done
|
|
bash smoke.sh http://127.0.0.1:18251
|
|
|
|
service-macos:
|
|
name: service · macos
|
|
needs: relevant
|
|
if: needs.relevant.outputs.run == 'true'
|
|
runs-on: macos
|
|
timeout-minutes: 60
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
# launchd's PATH omits cargo on the macOS host runner.
|
|
- name: Put cargo on PATH
|
|
shell: bash
|
|
run: echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
|
- name: Tests
|
|
shell: bash
|
|
working-directory: wai/wai-ledger
|
|
run: |
|
|
set -euo pipefail
|
|
nice -n 10 cargo test --locked --release 2>&1 | tee "$RUNNER_TEMP/test.log"
|
|
grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$RUNNER_TEMP/test.log" || { echo "::error::no test ran"; exit 1; }
|
|
- name: The smoke checks over HTTP
|
|
shell: bash
|
|
working-directory: wai/wai-ledger
|
|
run: |
|
|
set -euo pipefail
|
|
nice -n 10 cargo build --locked --release
|
|
dir="$RUNNER_TEMP/ledger"; key="$RUNNER_TEMP/ledger.key"; rm -rf "$dir" "$key"
|
|
python3 -I -c 'import hashlib,sys; sys.stdout.buffer.write(hashlib.sha256(b"wai:ledger-corpus\x01seller").digest())' > "$key"
|
|
WAI_LEDGER_KEY="$key" WAI_LEDGER_DIR="$dir" WAI_LEDGER_ADDR=127.0.0.1:18251 \
|
|
./target/release/wai-ledger serve 2> "$RUNNER_TEMP/service.log" &
|
|
pid=$!
|
|
trap 'kill $pid 2>/dev/null || true; cat "$RUNNER_TEMP/service.log"' EXIT
|
|
for _ in $(seq 1 50); do curl -s -o /dev/null http://127.0.0.1:18251/v1/health && break; sleep 0.2; done
|
|
bash smoke.sh http://127.0.0.1:18251
|