enrolment.create, enrolment.list, report.create and report.export join the catalogue as the other operations are: placed on the client against a fleet service, with their effect, toolset, input and output schemas, receipt and the features they need (fleet for the two that sign or verify). wai enrolment|report run through the door, and the fleet's command module keeps the agent rules of dx/envelope.rs instead of its own copy of them: the envelope with --json, every file through out.rs and every request to the service named in a dry run's plan and not sent (out::would_send), and --yes before the service is changed or a file replaced, exit 4 off a terminal with the proposal and the confirming command. A catalogue entry now says when it waits for confirmation (Op::confirms: never, a file the command line did not name, any file, the target or a file, always), and the rules refuse a change to a target that does not wait and a read that does. The export carries it and the agent flags (AGENT_FLAGS), from which wai --help is written: --yes is the one confirmation flag, and --confirm, which wai conform, wai setup-agent and the fleet took, is its deprecated spelling, still accepted, so named in help, in every confirming operation's help and in the export. wai conform confirms through the same module. wai verify's entry names the conformance results and fleet bundles it reads. Co-Authored-By: Claude Opus 5.5 <[email protected]>
136 lines
6 KiB
YAML
136 lines
6 KiB
YAML
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/**'
|
|
- '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/**'
|
|
- '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, and with
|
|
# Create's (app), so it is held on wai app export.
|
|
- 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"
|