.github/workflows/wai-examples.yml runs each example through wai create and wai dev: the portable ones on linux, the archive as the release builds it, the quickstart's readiness check (wai dev --check from the unpacked archive), the browser examples and apple-app on macos, android-app on linux-arm64. wai-conformance.yml runs tests/floor.rs and tests/cli_dx.rs, and fires on wai/examples/ (the templates are compiled into wai). wai-release.yml, on a tag wai-v<version>, builds the room client once and the archive on each runner, attaches them with their SHA-256, and writes the Homebrew formula and the Scoop manifest; wai/quickstart/install.sh installs a release. Two clippy notes of the new code fixed (a type alias for a template's files; hex only where hello and verify are built). Co-Authored-By: Claude Opus 5.5 <[email protected]>
101 lines
3.5 KiB
Python
101 lines
3.5 KiB
Python
"""The package managers' entries for a release of the WAI command line, from the SHA-256 files
|
|
attached to it:
|
|
|
|
python3 wai/quickstart/formulae.py <version> <tag> <forge-api> <owner/repo> <public-url> <out-dir>
|
|
|
|
Writes <out-dir>/wai.rb (a Homebrew formula for macOS and Linux) and <out-dir>/wai.json (a
|
|
Scoop manifest for Windows). A platform whose archive is not attached is left out, and stderr
|
|
says so; with none at all, it fails. Each archive holds bin/ and share/wai/web/, kept side by
|
|
side as `wai dev` expects them.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import pathlib
|
|
import sys
|
|
import urllib.request
|
|
|
|
version, tag, api, repo, public, out = sys.argv[1:7]
|
|
token = os.environ.get("FORGE_TOKEN", "")
|
|
headers = {"User-Agent": "wai-release"}
|
|
if token:
|
|
headers["Authorization"] = f"token {token}"
|
|
web = api.rsplit("/api/v1", 1)[0]
|
|
|
|
|
|
def get(url):
|
|
with urllib.request.urlopen(urllib.request.Request(url, headers=headers), timeout=60) as r:
|
|
return r.read()
|
|
|
|
|
|
release = json.loads(get(f"{api}/repos/{repo}/releases/tags/{tag}"))
|
|
assets = {a["name"]: a for a in release.get("assets", [])}
|
|
|
|
|
|
def digest(archive):
|
|
if archive not in assets or archive + ".sha256" not in assets:
|
|
print(f"note: {archive} is not attached; left out", file=sys.stderr)
|
|
return None
|
|
return get(f"{web}/{repo}/releases/download/{tag}/{archive}.sha256").decode().split()[0]
|
|
|
|
|
|
def url(archive):
|
|
return f"{public}/releases/download/{tag}/{archive}"
|
|
|
|
|
|
DESC = "WAI, an open media standard: its command line, and a local relay and room service"
|
|
HOME = "https://wai.transaction.science/docs/quickstart/"
|
|
targets = {
|
|
("macos", "arm"): "aarch64-apple-darwin",
|
|
("macos", "intel"): "x86_64-apple-darwin",
|
|
("linux", "arm"): "aarch64-unknown-linux-musl",
|
|
("linux", "intel"): "x86_64-unknown-linux-musl",
|
|
}
|
|
blocks = {}
|
|
for (os_name, cpu), triple in targets.items():
|
|
archive = f"wai-{version}-{triple}.tar.gz"
|
|
sha = digest(archive)
|
|
if sha:
|
|
blocks.setdefault(os_name, []).append(f' on_{cpu} do\n url "{url(archive)}"\n sha256 "{sha}"\n end\n')
|
|
win = f"wai-{version}-x86_64-pc-windows-msvc"
|
|
win_sha = digest(win + ".zip")
|
|
if not blocks and not win_sha:
|
|
sys.exit("no archive is attached to the release")
|
|
|
|
formula = f'''class Wai < Formula
|
|
desc "{DESC}"
|
|
homepage "{HOME}"
|
|
version "{version}"
|
|
license "Apache-2.0"
|
|
'''
|
|
for os_name in ("macos", "linux"):
|
|
if os_name in blocks:
|
|
formula += f" on_{os_name} do\n" + "".join(blocks[os_name]) + " end\n"
|
|
formula += '''
|
|
def install
|
|
# bin/ and share/wai/web/ side by side: `wai dev` finds the relay, the room service and the
|
|
# room client beside its own binary.
|
|
bin.install Dir["bin/*"]
|
|
(share/"wai").install "share/wai/web"
|
|
end
|
|
|
|
test do
|
|
assert_match "video-room", shell_output("#{bin}/wai create --list")
|
|
assert_match "delivered-verified", shell_output("#{bin}/wai hello #{testpath}/hello")
|
|
assert_match "verified", shell_output("#{bin}/wai verify #{testpath}/hello")
|
|
end
|
|
end
|
|
'''
|
|
pathlib.Path(out, "wai.rb").write_text(formula)
|
|
|
|
if win_sha:
|
|
manifest = {
|
|
"version": version,
|
|
"description": DESC,
|
|
"homepage": HOME,
|
|
"license": "Apache-2.0",
|
|
"architecture": {"64bit": {"url": url(win + ".zip"), "hash": win_sha, "extract_dir": win}},
|
|
"bin": ["bin\\wai.exe", "bin\\joule-moq-relay.exe", "bin\\joule-moq-room.exe", "bin\\wai-remote-host.exe", "bin\\wai-pack.exe"],
|
|
}
|
|
pathlib.Path(out, "wai.json").write_text(json.dumps(manifest, indent=2) + "\n")
|
|
print(f"wrote the formula{' and the manifest' if win_sha else ''} for wai {version}")
|