Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ check:

# Tests of repository tooling; every `just check` and `just ci` runs them.
test:
python3 test/smoke/runner.test.py
python3 sh/coverage.test.py
python3 sh/size/report.test.py
python3 sh/size/release.test.py
Expand Down
109 changes: 108 additions & 1 deletion .github/workflows/smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,8 @@ jobs:
cancel-in-progress: false
queue: max
permissions:
# Delete a Pages artifact left by an earlier run attempt.
# Delete a Pages artifact left by an earlier run attempt or by this run's
# upstream runner report.
actions: write
contents: write
pages: write
Expand Down Expand Up @@ -521,3 +522,109 @@ jobs:
# failing the job; remove this once that protocol mismatch is fixed.
continue-on-error: true
run: just moxygen

interop-runner:
name: Upstream Docker interoperability
runs-on: ubuntu-latest
timeout-minutes: 90
permissions:
contents: read
outputs:
report: ${{ steps.upload.outcome }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- uses: ./.github/actions/just

- uses: docker/setup-buildx-action@594f3bf4285d9ea8dc53c9a0c9c4092420091003 # v4.4.0

- name: Build this checkout's relay image
run: just runner-build

# Upstream follows its default branch. This job has no secrets and neither
# checkout persists credentials; its report is the only publishing input.
- name: Checkout upstream runner HEAD
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: englishm/moq-interop-runner
path: runner-upstream
persist-credentials: false

# Any failed pair or setup step fails the job. A complete run still writes
# its report first, since a failing run is the one worth looking at.
- name: Run upstream Docker matrices
run: just runner "$GITHUB_WORKSPACE/runner-upstream" "$GITHUB_WORKSPACE/interop-runner-report"

- name: Upload upstream report
id: upload
if: ${{ !cancelled() && hashFiles('interop-runner-report/index.html') != '' }}
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: interop-runner-report
path: interop-runner-report/
if-no-files-found: error

- name: Upload runner diagnostics
if: failure()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: interop-runner-diagnostics
path: runner-upstream/results
if-no-files-found: ignore

interop-runner-report:
name: Publish upstream runner report
needs: interop-runner
if: ${{ !cancelled() && github.ref == 'refs/heads/main' && github.event_name != 'pull_request' && needs.interop-runner.outputs.report == 'success' }}
runs-on: ubuntu-latest
timeout-minutes: 15
concurrency:
group: benchmark-pages
cancel-in-progress: false
queue: max
permissions:
# Delete a Pages artifact left by an earlier run attempt or by this run's
# relay report.
actions: write
contents: write
pages: write
id-token: write
defaults:
run:
working-directory: .
environment:
name: github-pages
url: ${{ steps.deploy.outputs.page_url }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: true

- uses: ./.github/actions/just

- name: Download upstream report
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8
with:
name: interop-runner-report
path: ${{ runner.temp }}/interop-runner-report

- name: Commit upstream report
run: just gh pages-publish interop-runner "$RUNNER_TEMP/interop-runner-report" "$RUNNER_TEMP/pages"

- name: Drop a stale Pages artifact
run: just gh pages-clean
env:
GH_TOKEN: ${{ github.token }}

- name: Upload site
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
with:
path: ${{ runner.temp }}/pages

- name: Deploy to GitHub Pages
id: deploy
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
1 change: 0 additions & 1 deletion quest/m1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@ tracks, so per-group stats stop costing cluster announces.
- [Generated JS API reference](/quest/m1/js-api-reference.md) - the doc site renders an API reference for every `@moq/*` package from API Extractor's doc model
- [IETF lazy discovery](/quest/m1/ietf-lazy-discovery.md) - moq-transport sessions ask for announcements only under watched prefixes, starting with UNSUBSCRIBE_NAMESPACE on d14/15
- [Interop coverage](/quest/m1/interop-coverage/README.md) - the riskiest moq-transport features moq-net exposes get cross-implementation tests over the even drafts 14 to 22
- [Runner nightly](/quest/m1/interop-runner-nightly.md) - a nightly job runs the upstream interop runner against our relay and clients, so newly registered implementations with a published image are tested without a change here
- [One Annex-B exporter](/quest/m1/annexb-export.md) - H.264 and H.265 Annex-B export share one private lifecycle, which also follows a rebound rendition
- [One CLI duration type](/quest/m1/cli-duration.md) - moq-cli, moq-bench and moq-relay reuse moq-tokio's public `cli::Duration` instead of their own copies
- [Shared watch and publish UI](/quest/m1/js-ui.md) - a new `@moq/ui` package holds the graph, buttons, and support banner that watch and publish duplicate
Expand Down
9 changes: 4 additions & 5 deletions quest/m1/audit-interop.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ Decided with the maintainer on 2026-10-21:
through every registered public relay), plus every cell of the runner's
report with a moq.dev side: our clients, our docker relay, or
`cdn.moq.dev`, including third-party clients failing against our relay.
- Sync new registry entries. Once the [runner nightly](/quest/m1/interop-runner-nightly.md)
lands, it runs the runner's HEAD, so check that newly registered clients
and docker-only relays show up in its report, and ask upstream for a
published image for any it lists as not run. The relays page reads every
- Sync new registry entries. The smoke workflow's upstream runner job runs
the runner's HEAD, so check that newly registered clients and docker-only
relays show up in its [report](https://git.moq.dev/interop-runner/),
and ask upstream for a published image for any it lists as not run. The relays page reads every
remote relay from the registry; give new relays the per-relay config they
need (`publish_path`, `WEBSOCKET_KEYS` in `test/smoke/relays.sh`).
- Standing approval to open PRs on englishm/moq-interop-runner that touch only
Expand Down Expand Up @@ -120,7 +120,6 @@ waits on [JavaScript FETCH](/quest/m1/js-fetch.md).

## Related

- [Runner nightly](/quest/m1/interop-runner-nightly.md) - runs every registered client and docker relay with a published image against us
- [Runner teardown](/quest/m3/interop-runner-approval.md) - the runner's moq.dev clients move to the withdrawing `close()` once it ships
- [Moxygen minimal interop](/quest/m1/smoke-moxygen.md) - Moxygen's filter type, waiting upstream
- [JavaScript FETCH](/quest/m1/js-fetch.md) - the JS publisher serves FETCH, which most red `js-web` publisher cells need
Expand Down
51 changes: 0 additions & 51 deletions quest/m1/interop-runner-nightly.md

This file was deleted.

3 changes: 2 additions & 1 deletion sh/gh/pages-clean.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail

# deploy-pages refuses to choose between artifacts from different run attempts.
# deploy-pages refuses to choose between a run's Pages artifacts, left by earlier
# attempts or by another publishing job in the same workflow.
# Scope deletion to this run so other Pages publishers keep their artifacts.
: "${GITHUB_REPOSITORY:?}" "${GITHUB_RUN_ID:?}"
artifacts=$(gh api --paginate "repos/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID/artifacts?name=github-pages" --jq '.artifacts[].id')
Expand Down
1 change: 1 addition & 0 deletions test/smoke/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ This suite installs the published moq packages and checks that they exchange med
| --- | --- | --- |
| Packages | `just smoke`, `just full` | Published clients through a local `moq-relay`. `smoke` is Rust only. `full` is the cross-language matrix. |
| Public relays | `just relays` | Rust publisher and subscriber through every relay in the [moq-interop-runner](https://github.com/englishm/moq-interop-runner) registry. CI publishes with Rust and the browser (`js-web`) and subscribes with Rust, `js-web`, and `js-bun`. On those relays `js-web` and `js-bun` run only on WebTransport (`@moq/web-transport` has no raw QUIC mode); a client that does not belong is omitted. WebSocket is its own column for the relays in `WEBSOCKET_KEYS` (`moq-dev-rs`): each of their `http(s)` endpoints also runs as `ws(s)`, and every other relay keeps that fallback off. A relay that refuses anonymous root broadcasts is dialed on the path `publish_path` names (`stitcher-moq` publishes under `/moq-test`). That run is what the [results page](https://moq-dev.github.io/moq/relays/) shows. Only `--required` relays fail the run; the default is moq-dev's `cdn.moq.dev`, including its WebSocket endpoint. |
| Upstream Docker runner | `just runner-build`, `just runner UPSTREAM OUTPUT` | Every published registry client against this checkout's relay, and the moq-dev clients against published Docker relays. Uses unpinned upstream HEAD and its HTML report. Local-build-only adapters appear as not run. Any failed pair or setup step fails the run, after the report is written. CI publishes it to [interop-runner/](https://git.moq.dev/interop-runner/). |
| Cloudflare | `just cloudflare` | Relays built from the default branches of [cloudflare/moq-rs](https://github.com/cloudflare/moq-rs) and moq-dev/moq, driven by a Cloudflare client over WebTransport and raw QUIC. |
| moxygen | `just moxygen` | Meta's [`moxygen`](https://github.com/facebookexperimental/moxygen) interop client through the latest moq-dev relay. Needs Linux Docker. |
| Tokens | `just token`, `just token-full` | `moq auth` and npm [`@moq/auth`](https://www.npmjs.com/package/@moq/auth) mint and verify each other's JWTs, and each verifier rejects a tampered token. |
Expand Down
13 changes: 13 additions & 0 deletions test/smoke/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,16 @@ check-toolchain:
nix develop --command just freshness
cd clients/js && nix develop --command bun install
cd clients/js && nix develop --command bun -e 'import {chromium} from "playwright"; const browser = await chromium.launch({channel: "chromium", headless: true}); await browser.close();'

# Build this checkout's relay image and its upstream interop adapter.
runner-build:
docker build --build-arg package=moq-relay -t moq-interop-relay-base:local ../..
docker build -f runner.Dockerfile -t moq-interop-relay:local .

# Run the upstream Docker matrices touching moq-dev and render upstream HTML.
runner upstream output:
python3 runner.py {{ quote(upstream) }} {{ quote(output) }}

# Check dynamic matrix selection and fail-closed coverage validation.
runner-check:
python3 runner.test.py
10 changes: 10 additions & 0 deletions test/smoke/runner.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# The source-built relay follows the runner's /certs convention. Its scratch
# image needs a shell and grep for Docker Compose's UDP healthcheck; the musl
# busybox is static, since the image has no system loader.
FROM moq-interop-relay-base:local
COPY --from=docker.io/library/busybox:stable-musl /bin /bin
ENV MOQ_LISTEN=[::]:4443 \
MOQ_LISTEN_TLS_CERT=/certs/cert.pem \
MOQ_LISTEN_TLS_KEY=/certs/priv.key \
MOQ_AUTH_PUBLIC=**
EXPOSE 4443/udp
Loading
Loading