WAI toolchain decision 11: joule-moq-relay builds wai-relay, joule-moq-room wai-room, and joule-moq-ingest wai-ingest. wai dev finds them by those names (WAI_RELAY_BIN, WAI_ROOM_BIN), and the quickstart archive, the release workflow, the examples' workflow, the browser tests, the interop scripts, the example host script, the Scoop manifest and the crates' READMEs and example configurations name them so. Wire and record identifiers that carry a crate's name (joule-moq-relay/session-summary/2, joule-moq-ingest/session/1, the relay's MOQT implementation string) and the log variables (JOULE_MOQ_*_LOG) are unchanged. Co-Authored-By: Claude Opus 5.5 <[email protected]>
245 lines
12 KiB
YAML
245 lines
12 KiB
YAML
name: wai command line release
|
|
|
|
# On a tag wai-v<version> (the version wai/wai-rs/Cargo.toml states), builds the quickstart
|
|
# archive (wai/quickstart/build.sh) on each runner and attaches it to the forge release of that
|
|
# tag, each archive with its SHA-256. An archive holds bin/ (wai with the feature quickstart,
|
|
# wai-relay, wai-room, wai-remote-host, wai-pack) and share/wai/web/ (the room
|
|
# client, built once, on the macOS host, which has the WebAssembly toolchain):
|
|
# macOS aarch64-apple-darwin and x86_64-apple-darwin;
|
|
# Linux x86_64- and aarch64-unknown-linux-musl, static, so any distribution runs it;
|
|
# Windows x86_64-pc-windows-msvc, as a zip.
|
|
# Each archive's own `wai` runs before it is attached (create --list, hello, verify, and on
|
|
# the hosts that run it, dev --check). A last job writes the Homebrew formula and the Scoop
|
|
# manifest for the archives attached and attaches them too; they go into the tap and the bucket
|
|
# by hand.
|
|
#
|
|
# Uploads go to the forge directly over the private network (FORGE_API), never through the
|
|
# public tunnel. A runner that is down leaves its platform's archive missing: the release lists
|
|
# what each build attached.
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
on:
|
|
push:
|
|
tags: ['wai-v*']
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
FORGE_API: http://100.64.224.0:3400/api/v1
|
|
FORGE_REPO: Transaction-Science/open-standards
|
|
PUBLIC: https://git.transaction.science/Transaction-Science/open-standards
|
|
|
|
jobs:
|
|
version:
|
|
name: the tag is the crate's version
|
|
runs-on: linux
|
|
outputs:
|
|
version: ${{ steps.v.outputs.version }}
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- id: v
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
v="${GITHUB_REF_NAME#wai-v}"
|
|
crate="$(sed -n 's/^version = "\(.*\)"$/\1/p' wai/wai-rs/Cargo.toml | head -1)"
|
|
[ "$v" = "$crate" ] || { echo "::error::the tag says $v, wai/wai-rs/Cargo.toml says $crate"; exit 1; }
|
|
grep -q "WAI_VERSION:-$v}" wai/quickstart/install.sh || { echo "::error::wai/quickstart/install.sh does not install $v"; exit 1; }
|
|
echo "version=$v" >> "$GITHUB_OUTPUT"
|
|
|
|
# The room client, once: the same files on every platform.
|
|
web:
|
|
name: the room client
|
|
needs: version
|
|
runs-on: macos
|
|
timeout-minutes: 60
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- name: Put cargo on PATH
|
|
shell: bash
|
|
run: echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
|
- name: Build and attach it
|
|
shell: bash
|
|
env:
|
|
FORGE_TOKEN: ${{ github.token }}
|
|
run: |
|
|
set -euo pipefail
|
|
rustup target add wasm32-unknown-unknown
|
|
command -v wasm-bindgen >/dev/null && wasm-bindgen --version | grep -q ' 0\.2\.127$' || cargo install --locked wasm-bindgen-cli --version 0.2.127
|
|
v="${{ needs.version.outputs.version }}"
|
|
bash wai/quickstart/build-web.sh "$RUNNER_TEMP/web"
|
|
mkdir -p "$RUNNER_TEMP/dist"
|
|
tar -C "$RUNNER_TEMP" -czf "$RUNNER_TEMP/dist/wai-web-$v.tar.gz" web
|
|
( cd "$RUNNER_TEMP/dist" && shasum -a 256 "wai-web-$v.tar.gz" > "wai-web-$v.tar.gz.sha256" )
|
|
bash wai/quickstart/publish.sh "$GITHUB_REF_NAME" "wai $v" "$RUNNER_TEMP"/dist/*
|
|
|
|
macos:
|
|
name: macOS · ${{ matrix.triple }}
|
|
needs: [version, web]
|
|
runs-on: macos
|
|
timeout-minutes: 120
|
|
strategy:
|
|
fail-fast: false
|
|
max-parallel: 1
|
|
matrix:
|
|
triple: [aarch64-apple-darwin, x86_64-apple-darwin]
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- name: Put cargo on PATH
|
|
shell: bash
|
|
run: echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
|
- name: Build, check and package
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
v="${{ needs.version.outputs.version }}"
|
|
rustup target add "${{ matrix.triple }}"
|
|
curl -fsS -o "$RUNNER_TEMP/web.tar.gz" "${FORGE_API%/api/v1}/$FORGE_REPO/releases/download/$GITHUB_REF_NAME/wai-web-$v.tar.gz"
|
|
tar -C "$RUNNER_TEMP" -xzf "$RUNNER_TEMP/web.tar.gz"
|
|
nice -n 10 bash wai/quickstart/build.sh "$RUNNER_TEMP/dist" --web "$RUNNER_TEMP/web" --target "${{ matrix.triple }}" --version "$v"
|
|
if [ "${{ matrix.triple }}" = "$(rustc -vV | sed -n 's/^host: //p')" ]; then
|
|
t="$RUNNER_TEMP/try"; mkdir -p "$t"; tar -C "$t" -xzf "$RUNNER_TEMP/dist/wai-$v-${{ matrix.triple }}.tar.gz"
|
|
b="$t/wai-$v-${{ matrix.triple }}/bin"
|
|
(cd "$t" && "$b/wai" hello h >/dev/null && "$b/wai" verify h >/dev/null && mkdir p && cd p && "$b/wai" dev --check --port 0)
|
|
fi
|
|
- name: Attach to the release
|
|
shell: bash
|
|
env:
|
|
FORGE_TOKEN: ${{ github.token }}
|
|
run: bash wai/quickstart/publish.sh "$GITHUB_REF_NAME" "wai ${{ needs.version.outputs.version }}" "$RUNNER_TEMP"/dist/*
|
|
|
|
linux:
|
|
name: Linux · ${{ matrix.triple }}
|
|
needs: [version, web]
|
|
runs-on: ${{ matrix.runner }}
|
|
timeout-minutes: 120
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- runner: linux
|
|
triple: x86_64-unknown-linux-musl
|
|
- runner: linux-arm64
|
|
triple: aarch64-unknown-linux-musl
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- name: Install Rust 1.98.0, the musl target and musl-gcc
|
|
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
|
|
rustup target add "${{ matrix.triple }}"
|
|
SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo"
|
|
$SUDO apt-get update -qq
|
|
$SUDO apt-get install -y -qq musl-tools python3 curl
|
|
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
|
- name: Build, check and package
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
v="${{ needs.version.outputs.version }}"
|
|
t="${{ matrix.triple }}"
|
|
T="$(echo "$t" | tr 'a-z-' 'A-Z_')"
|
|
# Static, as the quantum command line is built (wai-quantum-cli-release.yml).
|
|
export "CC_${t//-/_}=musl-gcc" "CARGO_TARGET_${T}_LINKER=musl-gcc"
|
|
export RUSTFLAGS="-C target-feature=+crt-static -C relocation-model=static"
|
|
curl -fsS -o "$RUNNER_TEMP/web.tar.gz" "${FORGE_API%/api/v1}/$FORGE_REPO/releases/download/$GITHUB_REF_NAME/wai-web-$v.tar.gz"
|
|
tar -C "$RUNNER_TEMP" -xzf "$RUNNER_TEMP/web.tar.gz"
|
|
bash wai/quickstart/build.sh "$RUNNER_TEMP/dist" --web "$RUNNER_TEMP/web" --target "$t" --version "$v"
|
|
d="$RUNNER_TEMP/try"; mkdir -p "$d"; tar -C "$d" -xzf "$RUNNER_TEMP/dist/wai-$v-$t.tar.gz"
|
|
b="$d/wai-$v-$t/bin"
|
|
(cd "$d" && "$b/wai" hello h >/dev/null && "$b/wai" verify h >/dev/null && mkdir p && cd p && "$b/wai" dev --check --port 0)
|
|
- name: Attach to the release
|
|
shell: bash
|
|
env:
|
|
FORGE_TOKEN: ${{ github.token }}
|
|
run: bash wai/quickstart/publish.sh "$GITHUB_REF_NAME" "wai ${{ needs.version.outputs.version }}" "$RUNNER_TEMP"/dist/*
|
|
|
|
windows:
|
|
name: Windows · x86_64-pc-windows-msvc
|
|
needs: [version, web]
|
|
runs-on: windows
|
|
timeout-minutes: 120
|
|
env:
|
|
CI: ""
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- name: Build, check and package
|
|
shell: pwsh
|
|
run: |
|
|
$ErrorActionPreference = 'Stop'
|
|
Remove-Item Env:CI -ErrorAction SilentlyContinue
|
|
$v = "${{ needs.version.outputs.version }}"
|
|
$t = "x86_64-pc-windows-msvc"
|
|
$web = Join-Path $env:RUNNER_TEMP 'web.tar.gz'
|
|
curl.exe -fsS -o $web "$($env:FORGE_API -replace '/api/v1$','')/$env:FORGE_REPO/releases/download/$env:GITHUB_REF_NAME/wai-web-$v.tar.gz"
|
|
tar -xzf $web -C $env:RUNNER_TEMP
|
|
$name = "wai-$v-$t"
|
|
$stage = Join-Path $env:RUNNER_TEMP $name
|
|
$dist = Join-Path $env:RUNNER_TEMP 'dist'
|
|
Remove-Item $stage, $dist -Recurse -Force -ErrorAction Ignore
|
|
New-Item -ItemType Directory -Force -Path (Join-Path $stage 'bin'), (Join-Path $stage 'share\wai'), $dist | Out-Null
|
|
$builds = @(
|
|
@{ dir = 'wai\wai-rs'; bin = 'wai'; args = @('--no-default-features', '--features', 'quickstart', '--bin', 'wai') },
|
|
@{ dir = 'joule-code\joule-code-rs'; bin = 'wai-relay'; args = @('-p', 'joule-moq-relay', '--bin', 'wai-relay') },
|
|
@{ dir = 'joule-code\joule-code-rs\crates\joule-moq-room'; bin = 'wai-room'; args = @('--bin', 'wai-room') },
|
|
@{ dir = 'joule-code\joule-code-rs\crates\joule-moq-remote'; bin = 'wai-remote-host'; args = @('--bin', 'wai-remote-host') },
|
|
@{ dir = 'wai\wai-pack'; bin = 'wai-pack'; args = @('--bin', 'wai-pack') }
|
|
)
|
|
foreach ($b in $builds) {
|
|
Push-Location $b.dir
|
|
cargo build --locked --release --target $t @($b.args)
|
|
if ($LASTEXITCODE -ne 0) { throw "the build of $($b.bin) failed" }
|
|
$target = (cargo metadata --format-version 1 --no-deps --locked | ConvertFrom-Json).target_directory
|
|
Copy-Item (Join-Path $target "$t\release\$($b.bin).exe") (Join-Path $stage 'bin')
|
|
Pop-Location
|
|
}
|
|
Copy-Item -Recurse (Join-Path $env:RUNNER_TEMP 'web') (Join-Path $stage 'share\wai\web')
|
|
Copy-Item wai\quickstart\README.md, wai\LICENSE $stage
|
|
& (Join-Path $stage 'bin\wai.exe') create --list
|
|
if ($LASTEXITCODE -ne 0) { throw "the packaged wai does not run" }
|
|
Compress-Archive -Path $stage -DestinationPath (Join-Path $dist "$name.zip") -Force
|
|
$h = (Get-FileHash (Join-Path $dist "$name.zip") -Algorithm SHA256).Hash.ToLower()
|
|
Set-Content -NoNewline -Path (Join-Path $dist "$name.zip.sha256") -Value "$h $name.zip`n"
|
|
- name: Attach to the release
|
|
shell: pwsh
|
|
env:
|
|
FORGE_TOKEN: ${{ github.token }}
|
|
run: |
|
|
$ErrorActionPreference = 'Stop'
|
|
$H = @{ Authorization = "token $env:FORGE_TOKEN" }
|
|
$base = "$env:FORGE_API/repos/$env:FORGE_REPO/releases"
|
|
$rel = Invoke-RestMethod -Headers $H -Uri "$base/tags/$env:GITHUB_REF_NAME"
|
|
foreach ($f in Get-ChildItem (Join-Path $env:RUNNER_TEMP 'dist')) {
|
|
foreach ($a in (Invoke-RestMethod -Headers $H -Uri "$base/$($rel.id)/assets" | Where-Object { $_.name -eq $f.Name })) {
|
|
Invoke-RestMethod -Headers $H -Method Delete -Uri "$base/$($rel.id)/assets/$($a.id)" | Out-Null
|
|
}
|
|
curl.exe -fsS -H "Authorization: token $env:FORGE_TOKEN" -X POST "$base/$($rel.id)/assets?name=$($f.Name)" -F "attachment=@$($f.FullName);type=application/octet-stream" -o NUL -w "uploaded $($f.Name): http %{http_code}`n"
|
|
if ($LASTEXITCODE -ne 0) { throw "the upload of $($f.Name) failed" }
|
|
}
|
|
|
|
formulae:
|
|
name: Homebrew formula and Scoop manifest
|
|
needs: [version, macos, linux, windows]
|
|
if: always() && needs.version.result == 'success'
|
|
runs-on: linux
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
- name: Write and attach them
|
|
shell: bash
|
|
env:
|
|
FORGE_TOKEN: ${{ github.token }}
|
|
run: |
|
|
set -euo pipefail
|
|
v="${{ needs.version.outputs.version }}"
|
|
out="$RUNNER_TEMP/formulae"; mkdir -p "$out"
|
|
python3 wai/quickstart/formulae.py "$v" "$GITHUB_REF_NAME" "$FORGE_API" "$FORGE_REPO" "$PUBLIC" "$out"
|
|
bash wai/quickstart/publish.sh "$GITHUB_REF_NAME" "wai $v" "$out"/*
|