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, under a tariff of version 3 a job's work billed once and # its re-run billed, 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/wai-metrics/**' - '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/wai-metrics/**' - '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: gate 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.99.1 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.99.1 rustup toolchain install 1.99.1 --profile minimal --component clippy rustup default 1.99.1 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. It also checks the carousel and claim records # through claim_verify.py, which needs cryptography; a fresh 3.11 does not have it. - uses: actions/setup-python@v5 with: python-version: '3.11' - name: The independent verifier's one dependency run: python -m pip install cryptography - 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