name: WAI operation catalogue # WAI's toolchain has one catalogue of operations, `noun.verb` (wai/wai-rs/src/catalogue.rs), # and every door names them by it. This workflow fails on drift: # # - the export, wai/catalogue/ops.json, is the table (`wai ops export --check`); # - the table keeps its naming rules (the library's catalogue tests); # - the command line reaches operations through the catalogue alone, and every operation # keeps the agent rules: its help, the exit codes, the JSON envelope, --dry-run on every # operation that is not read-only, --yes (tests/cli_ops.rs, and the binary's own tests); # - the other doors name operations as the catalogue does: MCP tool names, the services' # OpenAPI operationIds, the C header, and the Swift and Kotlin sinks # (scripts/check-wai-ops-doors.py, with its selftest). # # Push filters match the push's delta, so every path a door or a test reads is listed. concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true on: push: branches: [main] paths: - 'wai/wai-rs/**' - 'wai/catalogue/**' - 'wai/examples/**' - 'wai/http-conformance/**' - 'wai/score-conformance/**' - 'wai/live-conformance/fleet/**' # tests/cli_ops.rs builds the revenue share's --dry-run sample from this corpus. - 'wai/live-conformance/share/**' - 'wai/REGISTRY.md' - 'wai/LICENSE' - 'wai/wai-quantum/**' - 'wai/wai-ops/**' - 'wai/wai-app/**' - 'wai/wai-sink-swift/**' - 'wai/wai-sink-android/**' - 'joule-code/joule-code-rs/crates/*/openapi.json' - 'scripts/check-wai-ops-doors.py' - 'scripts/check-wai-ops-doors-selftest.sh' - 'rust-toolchain.toml' - '.github/workflows/wai-catalogue.yml' pull_request: paths: - 'wai/wai-rs/**' - 'wai/catalogue/**' - 'wai/examples/**' - 'wai/http-conformance/**' - 'wai/score-conformance/**' - 'wai/live-conformance/fleet/**' # tests/cli_ops.rs builds the revenue share's --dry-run sample from this corpus. - 'wai/live-conformance/share/**' - 'wai/REGISTRY.md' - 'wai/LICENSE' - 'wai/wai-quantum/**' - 'wai/wai-ops/**' - 'wai/wai-app/**' - 'wai/wai-sink-swift/**' - 'wai/wai-sink-android/**' - 'joule-code/joule-code-rs/crates/*/openapi.json' - 'scripts/check-wai-ops-doors.py' - 'scripts/check-wai-ops-doors-selftest.sh' - 'rust-toolchain.toml' - '.github/workflows/wai-catalogue.yml' jobs: # The path filters gate the trigger; this job gates the work from the pull request's own # diff (scripts/pr-touches-paths.py, reading the list above), as wai-pack.yml explains. 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-catalogue.yml \ "${{ github.event.pull_request.base.sha }}" \ "${{ github.event.pull_request.head.sha }}") echo "this change touches the operation catalogue: $r" echo "run=$r" >> "$GITHUB_OUTPUT" catalogue: name: the catalogue and every door ยท 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 rustup default 1.98.0 SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo" command -v python3 >/dev/null || { $SUDO apt-get update -qq; $SUDO apt-get install -y -qq python3; } echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" # The export other tools and this workflow's door check read is the table, byte for # byte; the message says how to regenerate it. - name: The catalogue's export is up to date working-directory: wai/wai-rs run: cargo run -q --locked --no-default-features --bin wai -- ops export --check ../catalogue/ops.json - name: Every door names its operations as the catalogue does shell: bash run: | set -euo pipefail bash scripts/check-wai-ops-doors-selftest.sh python3 -I scripts/check-wai-ops-doors.py # The library's catalogue tests: the naming rules, each broken in a copy of the table # and refused. The binary's own tests: every implementation names an operation of the # catalogue and every operation with a command line has one; help is the catalogue's. # tests/cli_ops.rs: wai ops, help, the exit codes, the envelope, --dry-run and --yes (and # --confirm, its deprecated spelling), # first in the archive's build (quickstart), then with every command-line feature that # needs no system library, so --dry-run is held on generate, score and stage too, with # Create's (app), so it is held on wai app export, with the revenue share's # (revenue_share), so it is held on wai contract create|accept and wai statement create, and # with the opportunity report's (opportunity_report), so it is held on wai opportunity # create and wai statement check. - name: The catalogue's rules, and the command line through it shell: bash working-directory: wai/wai-rs run: | set -euo pipefail ran() { grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$1" || { echo "::error::no test ran in $1"; exit 1; }; } cargo test --locked --no-default-features --lib catalogue 2>&1 | tee "$RUNNER_TEMP/lib.log" ran "$RUNNER_TEMP/lib.log" cargo test --locked --no-default-features --features quickstart --bin wai --test cli_ops 2>&1 | tee "$RUNNER_TEMP/cli.log" ran "$RUNNER_TEMP/cli.log" cargo test --locked --no-default-features --features quickstart,generate,score,staged,video_int,audio_int,splat_int --test cli_ops 2>&1 | tee "$RUNNER_TEMP/cli-full.log" ran "$RUNNER_TEMP/cli-full.log" cargo test --locked --no-default-features --features quickstart,app --test cli_ops 2>&1 | tee "$RUNNER_TEMP/cli-app.log" ran "$RUNNER_TEMP/cli-app.log" cargo test --locked --no-default-features --features quickstart,revenue_share --test cli_ops 2>&1 | tee "$RUNNER_TEMP/cli-share.log" ran "$RUNNER_TEMP/cli-share.log" cargo test --locked --no-default-features --features quickstart,opportunity_report --test cli_ops 2>&1 | tee "$RUNNER_TEMP/cli-opportunity.log" ran "$RUNNER_TEMP/cli-opportunity.log"