Some checks failed
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 10s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Successful in 1m1s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Failing after 4m20s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Successful in 4m57s
The WAI site's list of conforming implementations (/conformance/) admits a record only when it verifies, names the pinned commit and toolchain, is admitted against that commit's corpus, is not signed by a published test key and names no local path. CI made no such record: the conformance runner job of wai-breaking.yml wrote its per-suite records to the runner's temporary folder, signed with keys made for their runs and naming the runner's paths, and uploaded none; wai-conformance.yml's independent-verifiers artefact holds whole-corpus records, which §4.1 rule 4 refuses. wai/quickstart/conformance-records.sh runs WAI's own implementations as that job does (the five independent verifiers, the reference packager, the native sink through its module and its C interface, the score renderer, the browser sink, the integer-synthesis decoder, a cache in front of the reference origin, and the reference relay at drafts 22, 18 and 16), each record naming <wai version>+<commit>, signed with the seed in WAI_CONFORMANCE_SEED and admitted by `wai verify --conformant`, and packs the 15 as wai-conformance-<label>.tar.gz (with MANIFEST.json: commit, standard, signer, each record's SHA-256) and its .sha256. The runs are made from a folder holding bin/ and a link to wai/, programs found through PATH's relative `bin`, so a record names bin/<program> and wai/<path>; a record holding a path under /Users/, /Volumes/, /home/, /private/ or /tmp/, or such a python3, stops it. The seed goes to a file only the script reads, removed on exit, and the variable is unset before anything runs. Without the seed: one notice, nothing written, exit 0. A seed that is not one, or a key conform-result-conformance publishes, stops it with nothing written. - wai-breaking.yml, runner job: the three refusals planted on every change; on a push to main the pack at the commit, kept as the artefact wai-conformance-records when the secret is set. - wai-release.yml: job conformance builds the programs at a wai-v* tag, runs and signs them (the seed in that step alone) and attaches wai-conformance-<version>.tar.gz and its .sha256 through publish.sh, to FORGE_API directly. Job setup reports whether WAI_CONFORMANCE_SEED is set, as for WAI_PACKAGES_TOKEN (cc1849097): without it one notice, and the job is skipped. - publish.sh: the release's description names the pack. Checked: PyYAML parses both workflows; check-workflow-concurrency.sh and its selftest, check-tests-in-ci.py and its selftest, check-wai-release-quickstart.py and its selftest, the changelog check, the public-name check with the private list and the other light checks of repo-checks.yml pass under bash. Proved end to end at this change (as f5038ea40, before the rebase onto8da651a54, which touches none of these files), with a throwaway key made on the Framework build host and deleted there: the script, run as the release job runs it, wrote 15 records, every one conformant, admitted against the corpus (areas trust 5, media 2, delivery 2, live 6), path-neutral (bin/<program>, wai/<path>, /usr/bin/python3) and signed by the key, packed with its SHA-256. The WAI site's sync (scripts/sync-conform.mjs, on the M3 Ultra) admitted all 15 as WAI's own by --records with --signer, and the same 15 by --release from a server laid out as the forge's release downloads; the built page held each (check-conform, and the page's e2e: 102 checks). Planted and caught: the script with no seed (one notice, nothing written, exit 0) and with the published test key (exit 1, nothing written); at the sync, a record naming a local path (check f), a record signed by the test key (check e, also with that key named as WAI's) and a pack whose .sha256 does not match (refused by --release). Co-Authored-By: Claude Opus 5.5 <[email protected]>
34 lines
2.7 KiB
Shell
Executable file
34 lines
2.7 KiB
Shell
Executable file
#!/usr/bin/env bash
|
|
# Attach files to the forge release for a tag, creating the release if there is
|
|
# none, and replacing an asset of the same name:
|
|
#
|
|
# FORGE_API=http://host:3400/api/v1 FORGE_REPO=owner/repo FORGE_TOKEN=... \
|
|
# bash wai/quickstart/publish.sh <tag> <title> <file>...
|
|
#
|
|
# Uploads go to FORGE_API directly (over the private network), never through the
|
|
# public tunnel, whose request size cap a large asset would hit.
|
|
set -euo pipefail
|
|
if [ $# -lt 3 ]; then
|
|
echo "usage: bash wai/quickstart/publish.sh <tag> <title> <file>..." >&2
|
|
exit 2
|
|
fi
|
|
TAG="$1"; TITLE="$2"; shift 2
|
|
: "${FORGE_API:?}" "${FORGE_REPO:?}" "${FORGE_TOKEN:?}"
|
|
AUTH="Authorization: token $FORGE_TOKEN"
|
|
BASE="$FORGE_API/repos/$FORGE_REPO/releases"
|
|
release_id() { curl -fsS -H "$AUTH" "$BASE/tags/$TAG" 2>/dev/null | python3 -c 'import json,sys; print(json.load(sys.stdin).get("id", ""))' 2>/dev/null || true; }
|
|
ID="$(release_id)"
|
|
if [ -z "$ID" ]; then
|
|
BODY="$(python3 -c 'import json,sys; print(json.dumps({"tag_name": sys.argv[1], "name": sys.argv[2], "body": "The WAI command line and what `wai dev` runs, for macOS, Linux and Windows: each wai-<version>-<triple> archive holds bin/ (wai, wai-relay, wai-room, wai-ingest, wai-remote-host, wai-pack, wai-quantum), share/wai/web/ (the room client), share/wai/studio/ (WAI Studio), a README and the licence. For C on Linux, libwai-<version>-<triple>.tar.gz: lib/libwai.a, include/wai.h and lib/pkgconfig/wai.pc. For Swift, wai-sink-swift-<version>.zip, the package whose Package.swift names WaiFFI-<version>.xcframework.zip by URL and checksum. For Android, wai-sink-<version>.aar, also science.transaction.wai:wai-sink in the forge\u2019s Maven registry. WAI\u2019s own conformance results, wai-conformance-<version>.tar.gz: each suite\u2019s record (conform-result/1) of WAI\u2019s implementations run at this tag, signed with WAI\u2019s key. Each .sha256 file checks its file (`shasum -a 256 -c`)."}))' "$TAG" "$TITLE")"
|
|
curl -fsS -H "$AUTH" -H 'content-type: application/json' -X POST "$BASE" -d "$BODY" > /dev/null 2>&1 || true
|
|
# Builds run side by side; one of them created it if this did not.
|
|
for _ in 1 2 3 4 5 6; do ID="$(release_id)"; [ -n "$ID" ] && break; sleep 3; done
|
|
fi
|
|
[ -n "$ID" ] || { echo "::error::no release for $TAG"; exit 1; }
|
|
for f in "$@"; do
|
|
name="$(basename "$f")"
|
|
for old in $(curl -fsS -H "$AUTH" "$BASE/$ID/assets" | NAME="$name" python3 -c 'import json,os,sys; print(" ".join(str(a["id"]) for a in json.load(sys.stdin) if a["name"] == os.environ["NAME"]))'); do
|
|
curl -fsS -H "$AUTH" -X DELETE "$BASE/$ID/assets/$old" > /dev/null
|
|
done
|
|
curl -fsS -H "$AUTH" -X POST "$BASE/$ID/assets?name=$name" -F "attachment=@$f;type=application/octet-stream" -o /dev/null -w "uploaded $name: http %{http_code}\n"
|
|
done
|