packaging: .deb/.rpm + apt.moq.dev / rpm.moq.dev workers#1457
Conversation
…rkers Ship native Linux packages for moq-relay, moq-cli, moq-token-cli, and the moq-gst plugin via apt.moq.dev (Debian/Ubuntu) and rpm.moq.dev (Fedora / RHEL / AlmaLinux). Each tagged release builds .deb/.rpm artifacts with nfpm, attaches them to the GitHub Release, and dispatches a follow-up workflow that regenerates the signed repository metadata on R2. Distribution-format packages link against the consumer's glibc, so the build matrix is pinned to ubuntu-22.04 (glibc 2.35) and almalinux:9 (glibc 2.34) instead of Nix, which would carry its own glibc. Nix still owns the existing reproducible tarball flow for moq-gst and the Cachix path; this is a parallel track with different compatibility tradeoffs. The apt and rpm workers follow the rom.moq.dev / vid.moq.dev pattern: a small TypeScript worker proxying GETs out of a per-domain R2 bucket with content-type and cache-control headers tuned for repo metadata versus content-addressed package blobs. A new infra/ folder collects infra-only workers; existing demo/pub, demo/boy, doc, cdn folders stay put since they are co-located with the content they serve. User-facing install one-liners live at doc/setup/linux.md; operator bootstrap (R2 buckets, GPG key, GitHub secrets) lives at infra/README.md.
|
Warning Review limit reached
Your plan currently allows 4 reviews/hour. Refill in 7 minutes and 19 seconds. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more review capacity refills, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (20)
WalkthroughThis PR implements complete Linux package distribution infrastructure for MoQ projects. It adds Cloudflare Workers-backed apt and rpm repositories (apt.moq.dev and rpm.moq.dev) served from R2 buckets, complete with publishing scripts that regenerate repository metadata and upload artifacts. New GitHub Actions workflows build and release packages for moq-cli, moq-token-cli, and updated workflows for moq-relay and moq-gst. The PR includes nfpm packaging definitions for all binaries and plugins, local packaging scripts, a systemd service unit for moq-relay with extensive hardening, comprehensive Linux installation documentation covering Debian/Ubuntu and Fedora-family distributions, and infrastructure deployment automation via justfile tasks. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Resolves conflicts in moq-relay.yml (kept new .deb/.rpm packaging steps, adopted main's SHA-pinned actions) and justfile (kept mod infra, dropped mod cdn since the cdn folder was removed on main). Also pinned actions in the new moq-cli.yml, moq-token-cli.yml, apt-repo.yml, rpm-repo.yml, and moq-gst.yml jobs to match main's pinning convention.
There was a problem hiding this comment.
Actionable comments posted: 16
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/scripts/install-nfpm.sh:
- Around line 21-27: Download the nfpm tarball into a temp file instead of
streaming to tar; also download the release checksums file for v${NFPM_VERSION},
verify the tarball with sha256sum -c, and only on successful verification
extract and install; update usage of TMP, URL, NFPM_VERSION and NFPM_ARCH to (1)
curl -fSL to save to "$TMP/nfpm_${NFPM_VERSION}_Linux_${NFPM_ARCH}.tar.gz", (2)
curl -fSL to fetch the corresponding checksums.txt, (3) run sha256sum -c against
the checksum entry for that tarball and exit non‑zero on failure, then (4) tar
-xz -C "$TMP" nfpm from the verified archive and sudo install -m 0755
"$TMP/nfpm" /usr/local/bin/nfpm.
In @.github/workflows/apt-repo.yml:
- Line 33: Replace the floating actions/checkout@v6 usage with a pinned commit
SHA and explicitly disable credential persistence: find the line using "uses:
actions/checkout@v6" and change it to the actions/checkout action pinned to a
specific commit SHA (instead of `@v6`) and add the input "persist-credentials:
false" under that step (optionally keep fetch-depth as needed); this hardens the
workflow by preventing supply-chain drift and avoids leaving repository
credentials in the runner.
In @.github/workflows/moq-cli.yml:
- Around line 30-33: The workflow uses floating refs for third-party GitHub
Actions and leaves checkout credentials persisted; update each uses entry (e.g.,
"actions/checkout@v6", "dtolnay/rust-toolchain@stable",
"actions/upload-artifact@v7", "actions/download-artifact@v8") to a pinned
immutable SHA (replace the tag with the specific commit SHA for that action) and
for every actions/checkout invocation add the input persist-credentials: false
so credentials are not persisted; apply these changes to all occurrences
referenced in the diff.
In @.github/workflows/moq-gst.yml:
- Around line 72-75: Update the workflow to harden actions: set actions/checkout
to include persist-credentials: false (so credentials are not retained), and
replace floating tags with pinned commit SHAs for uses of actions/checkout,
dtolnay/rust-toolchain, actions/upload-artifact,
DeterminateSystems/nix-installer-action, and
DeterminateSystems/magic-nix-cache-action (i.e., change
dtolnay/rust-toolchain@stable, actions/upload-artifact@v7,
DeterminateSystems/*`@main` to specific commit SHAs) so each action reference is
immutable and secure.
In @.github/workflows/moq-token-cli.yml:
- Around line 30-33: Update the workflow to pin all GitHub Actions to specific
commit SHAs and disable persisted checkout credentials: for each checkout step
using actions/checkout@v6 add with: persist-credentials: false (both
occurrences) and replace floating refs like dtolnay/rust-toolchain@stable,
actions/upload-artifact@v7, and actions/download-artifact@v8 with their
corresponding commit SHAs (use the latest known stable SHA for each action).
Ensure every action reference in the file is a SHA-pinned ref and that all
checkout steps include persist-credentials: false to avoid leaking tokens.
In @.github/workflows/rpm-repo.yml:
- Line 31: Replace the floating actions/checkout@v6 usage with an immutable
commit SHA and explicitly disable credential persistence: update the step that
uses actions/checkout@v6 to reference the action by its full commit SHA and add
persist-credentials: false to the checkout step; locate the checkout step by the
identifier actions/checkout@v6 in the workflow and modify it accordingly so the
action is pinned and credentials are not persisted.
In `@doc/setup/linux.md`:
- Around line 93-98: Rename the misleading subsection that currently shows the
commands "gpg --import moq-archive-keyring.gpg" and "gpg --verify Release.gpg
Release" so it clearly states that it verifies repository metadata (e.g.,
"Verify repository metadata / Release signature") instead of implying it
validates a downloaded `.deb` file; update any nearby text to reference
"Release.gpg" and the repository metadata verification flow rather than `.deb`
verification, and optionally add a short note suggesting the correct
approach/tool for verifying a `.deb` if needed.
- Line 57: The doc's copy command "sudo cp cert.pem key.pem root.jwk
/var/lib/moq-relay/" can fail if /var/lib/moq-relay doesn't exist; update the
instructions to create the state dir first (e.g., run a safe pre-step like "sudo
mkdir -p /var/lib/moq-relay" and set appropriate ownership/permissions) before
executing the cp, or suggest using an install/rsync command that creates the
destination; mention the exact path /var/lib/moq-relay and the copy command so
readers know where to add the mkdir step.
In `@infra/apt/publish.sh`:
- Around line 38-40: The temp GPG home (GNUPGHOME) isn't always removed on
error; update the cleanup to always remove both WORK and GNUPGHOME by replacing
the single trap with a robust cleanup function (e.g., cleanup() { rm -rf "$WORK"
"${GNUPGHOME:-}" ; } ) and register it for EXIT and ERR (trap 'cleanup' EXIT
ERR) or expand the existing trap to rm -rf "$WORK" "${GNUPGHOME:-}"; reference
the WORK and GNUPGHOME variables and the trap invocation so GNUPGHOME is removed
even when signing fails.
- Around line 41-43: The rclone sync call currently swallows failures with `||
mkdir -p "$WORK/pool"`, allowing the script to continue on auth/network errors;
change the flow so the local directory is created first (`mkdir -p
"$WORK/pool"`) and then run `rclone sync "r2:${BUCKET}/pool" "$WORK/pool"` and
if rclone exits non‑zero, log an error and exit the script (e.g., exit 1).
Update the block around the `rclone sync` invocation to remove the fallback that
masks failures and explicitly fail fast on rclone errors, referencing the
`rclone sync "r2:${BUCKET}/pool" "$WORK/pool"`, `$BUCKET`, and `$WORK/pool`
symbols.
In `@infra/apt/src/worker.ts`:
- Around line 35-39: The cacheControl function currently marks all ".gpg" files
immutable which wrongly pins mutable apt signatures like
"dists/.../Release.gpg"; update cacheControl so only .deb files and files in
"/pool/" get "public, max-age=2592000, immutable" and treat ".gpg" signatures as
short-lived (e.g., "public, max-age=300") unless they are located under "/pool/"
or another immutable path; change the logic in cacheControl to detect ".gpg"
filenames (e.g., "Release.gpg" or paths containing "/dists/") and return the
short-max-age value for those cases.
In `@infra/rpm/publish.sh`:
- Around line 45-56: When iterating new_rpms in the publish script, validate the
detected rpm arch (variable arch from rpm -qp) against the allowed ARCHES array
and fail fast (exit non-zero with an error message) if arch is not in ARCHES —
except allow "noarch" which should be expanded into every ARCHES entry; update
the same validation before the metadata/signing step so only supported arches
are processed. Locate the loop over new_rpms and the metadata/signing block (the
variables/arrays ARCHES, new_rpms, WORK, DIST and the arch variable) and add an
explicit membership check to reject unsupported architectures with a clear error
and non-zero exit.
In `@packaging/moq-relay/moq-relay.service`:
- Line 9: The systemd unit passes the wrong flag: update the ExecStart in
moq-relay.service to use --file instead of --config (change ExecStart to call
/usr/bin/moq-relay --file /etc/moq-relay/relay.toml) so it matches the
configuration struct (pub file: Option<String>) and Config::load() which expects
--file; also search and update any docs or example usages that currently use
--config to use --file for consistency.
In `@packaging/moq-relay/relay.toml`:
- Around line 36-40: Update the misleading comment above the [auth.public]
section so it accurately reflects the publish scope in the config: change the
text that currently says "Allow anonymous publish under anon/** only." to state
that anonymous publish includes both "anon/**" and "demo/viewer" (or
alternatively remove "only" if you prefer). Ensure the comment references the
publish key and values (publish = ["anon", "demo/viewer"]) so the comment and
the actual settings for subscribe and publish remain consistent.
In `@rs/justfile`:
- Around line 80-81: The Debian branch sets arch with a hardcoded fallback
"amd64" when dpkg is missing; change the fallback to derive the host
architecture instead of using amd64 by replacing the fallback in the deb) case
that calls dpkg --print-architecture (refer to the deb) arch=... assignment and
the dpkg --print-architecture command) so it uses uname -m (or a small mapping
from uname -m to Debian arch strings if needed) to produce a correct arch value
on non-debian systems.
In `@rs/moq-gst/package.sh`:
- Around line 37-43: The option parser in the while/case loop reads $2 directly
(for flags --packager, --version, --arch, --target, --output) which will trigger
an unbound-variable error if a flag is passed without a value; update each case
arm in the loop to validate that a non-empty value exists before shifting (e.g.,
check that "$2" is set and does not start with "-" or handle missing value) and
on failure print a clear usage/error message and exit non‑zero so missing flag
values produce a friendly error instead of an unbound-variable crash.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 794179a3-92a5-43c6-a333-66d2913e001c
📒 Files selected for processing (34)
.github/scripts/install-nfpm.sh.github/scripts/trigger-repo-publish.sh.github/workflows/apt-repo.yml.github/workflows/moq-cli.yml.github/workflows/moq-gst.yml.github/workflows/moq-relay.yml.github/workflows/moq-token-cli.yml.github/workflows/rpm-repo.ymlREADME.mddoc/.vitepress/config.tsdoc/setup/linux.mdinfra/README.mdinfra/apt/justfileinfra/apt/package.jsoninfra/apt/publish.shinfra/apt/src/worker.tsinfra/apt/wrangler.jsoncinfra/justfileinfra/rpm/justfileinfra/rpm/package.jsoninfra/rpm/publish.shinfra/rpm/src/worker.tsinfra/rpm/wrangler.jsoncjustfilepackaging/moq-cli/nfpm.yamlpackaging/moq-gst/nfpm.yamlpackaging/moq-relay/moq-relay.servicepackaging/moq-relay/nfpm.yamlpackaging/moq-relay/relay.tomlpackaging/moq-token-cli/nfpm.yamlrs/justfilers/moq-gst/README.mdrs/moq-gst/package.shrs/moq-relay/README.md
Soften the implicit "no comments" default toward "no comments when the code is self-explanatory." The non-obvious WHY (constraints, invariants, workarounds, surprising behavior) still warrants a comment.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (5)
.github/workflows/rpm-repo.yml (1)
31-31:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDisable persisted checkout credentials.
actions/checkout@v6still defaultspersist-credentialstotrue, so later steps in this job keep authenticated Git access unless you opt out. This workflow already usesGH_TOKENdirectly for the GitHub API call path, so persisting the checkout credential is unnecessary. (github.com)Suggested fix
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/rpm-repo.yml at line 31, The checkout step currently uses actions/checkout@de0fac2... which defaults persist-credentials to true; update the checkout step (the actions/checkout usage) to explicitly opt out by adding a with: persist-credentials: false entry so the job does not keep the repository authentication after checkout (since GH_TOKEN is used elsewhere)..github/workflows/moq-token-cli.yml (1)
30-30:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDisable persisted checkout credentials on both checkout steps.
actions/checkout@v6still defaultspersist-credentialstotrue, so later steps retain authenticated Git access unless you opt out. The release flow here already usesGH_TOKENexplicitly, so both checkout steps can disable credential persistence. (github.com)Suggested fix
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false ... - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 + persist-credentials: falseAlso applies to: 103-105
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/moq-token-cli.yml at line 30, Update both checkout steps that use "uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" to explicitly disable persisting credentials by adding a "with" block containing "persist-credentials: false"; ensure the same change is applied to the second checkout step (the other actions/checkout usage) so GH_TOKEN is used explicitly and no authenticated Git credentials are left in later steps..github/workflows/moq-gst.yml (1)
30-32:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDisable persisted checkout credentials on every checkout step.
actions/checkout@v6still defaultspersist-credentialstotrue, so later steps retain authenticated Git access unless you opt out. This workflow already passes explicit credentials where needed, so all four checkout steps can setpersist-credentials: false. (github.com)Suggested fix
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 + persist-credentials: false ... - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false ... - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false ... - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 + persist-credentials: falseAlso applies to: 72-72, 129-129, 188-190
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/moq-gst.yml around lines 30 - 32, In each actions/checkout@... step (the checkout steps currently showing e.g. the one using actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd and the other three checkout steps at the indicated locations), add the key persist-credentials: false to the step's with: block so the checkout does not retain authenticated Git credentials for later steps; leave other explicit credential usages unchanged and ensure the key is added under the existing with: mapping for each checkout step..github/workflows/apt-repo.yml (1)
33-33:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDisable persisted checkout credentials.
actions/checkout@v6still defaultspersist-credentialstotrue, so later steps in this job keep authenticated Git access unless you opt out. This workflow already passesGH_TOKENdirectly togh, so the checkout credential is unnecessary here. (github.com)Suggested fix
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/apt-repo.yml at line 33, The checkout step using actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd (v6) leaves persisted credentials enabled; update that checkout invocation to opt out by setting the persist-credentials input to false (persist-credentials: false) so later steps don’t retain the repo token (you can keep passing GH_TOKEN directly to gh as already done)..github/workflows/moq-cli.yml (1)
30-30:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDisable persisted checkout credentials on both checkout steps.
actions/checkout@v6still defaultspersist-credentialstotrue, so later steps retain authenticated Git access unless you opt out. In this workflow, release operations already useGH_TOKENexplicitly, so both checkouts can disable credential persistence. (github.com)Suggested fix
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false ... - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 + persist-credentials: falseAlso applies to: 103-105
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/moq-cli.yml at line 30, The checkout steps currently use actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd (v6) and leave persist-credentials at its default (true); update both checkout steps to explicitly set persist-credentials: false so later steps do not retain authenticated Git credentials (i.e., add with: persist-credentials: false to the actions/checkout uses lines referenced in the diff and the other occurrence around lines 103-105).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/moq-relay.yml:
- Line 33: The workflow's actions/checkout steps currently leave
persist-credentials at its default true; update both checkout steps in the
moq-relay workflow to set persist-credentials: false (the build checkout step
and the release checkout step where fetch-depth: 0 is set) so Git credentials
are not persisted to later steps; locate the steps that use actions/checkout@...
and add persist-credentials: false alongside their existing settings.
---
Duplicate comments:
In @.github/workflows/apt-repo.yml:
- Line 33: The checkout step using
actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd (v6) leaves persisted
credentials enabled; update that checkout invocation to opt out by setting the
persist-credentials input to false (persist-credentials: false) so later steps
don’t retain the repo token (you can keep passing GH_TOKEN directly to gh as
already done).
In @.github/workflows/moq-cli.yml:
- Line 30: The checkout steps currently use
actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd (v6) and leave
persist-credentials at its default (true); update both checkout steps to
explicitly set persist-credentials: false so later steps do not retain
authenticated Git credentials (i.e., add with: persist-credentials: false to the
actions/checkout uses lines referenced in the diff and the other occurrence
around lines 103-105).
In @.github/workflows/moq-gst.yml:
- Around line 30-32: In each actions/checkout@... step (the checkout steps
currently showing e.g. the one using
actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd and the other three
checkout steps at the indicated locations), add the key persist-credentials:
false to the step's with: block so the checkout does not retain authenticated
Git credentials for later steps; leave other explicit credential usages
unchanged and ensure the key is added under the existing with: mapping for each
checkout step.
In @.github/workflows/moq-token-cli.yml:
- Line 30: Update both checkout steps that use "uses:
actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd" to explicitly disable
persisting credentials by adding a "with" block containing "persist-credentials:
false"; ensure the same change is applied to the second checkout step (the other
actions/checkout usage) so GH_TOKEN is used explicitly and no authenticated Git
credentials are left in later steps.
In @.github/workflows/rpm-repo.yml:
- Line 31: The checkout step currently uses actions/checkout@de0fac2... which
defaults persist-credentials to true; update the checkout step (the
actions/checkout usage) to explicitly opt out by adding a with:
persist-credentials: false entry so the job does not keep the repository
authentication after checkout (since GH_TOKEN is used elsewhere).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e78838a0-2f71-4d6b-97c3-622cd10d510b
📒 Files selected for processing (9)
.github/workflows/apt-repo.yml.github/workflows/moq-cli.yml.github/workflows/moq-gst.yml.github/workflows/moq-relay.yml.github/workflows/moq-token-cli.yml.github/workflows/rpm-repo.ymlCLAUDE.mdinfra/README.mdjustfile
✅ Files skipped from review due to trivial changes (2)
- CLAUDE.md
- infra/README.md
nfpm and the apt/rpm repo tooling now come from the project flake (`packages.packaging`) instead of an ad-hoc `curl | tar` of a github release or `apt-get install`. Versions are pinned via flake.lock, the same binaries are available locally via `nix develop`, and there's no more unchecked tarball in the supply chain. The composite `setup-packaging` action installs Nix, builds the packaging bundle, and prepends its `bin/` to `$GITHUB_PATH` so the rest of the job sees a stable nfpm/rclone/gnupg/apt/dpkg/createrepo_c/rpm. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three independent bugs in the deb/rpm pipeline plus the bun lockfiles
that wrangler creates when the infra workers install their deps.
* infra/{apt,rpm}/publish.sh: the pull-from-R2 step was an `rclone sync`
with a fallback to `mkdir -p`. If the sync partially completed before
failing, the local mirror went stale, and the push step at the end of
the script either deleted .rpms from R2 (rpm side, `rclone sync` push)
or dropped them from the regenerated `Packages` indexes (apt side,
ftparchive only sees local files). Switch to `rclone copy` for the
pull so a partial fetch can never cause deletion; on the rpm push,
split the upload into an additive `copy` for the .rpms and a `sync`
for the regenerated repodata only.
* packaging/moq-gst: gstreamer-rs 0.23 requires GStreamer >= 1.22 at
compile time, but the previous workflow built on Ubuntu 22.04 which
ships 1.20. The build would have failed on the first tag. Move the
.deb build inside a debian:12 container, which pairs gst 1.22 with
glibc 2.36; update the libc6 dep accordingly and note in the install
docs that gstreamer1.0-moq drops Ubuntu 22.04.
* infra: rename APT_SIGNING_KEY{,_ID} -> REPO_SIGNING_KEY{,_ID}. The
same GPG key signs both repos; the apt-prefixed name was actively
misleading on the rpm side. Cheap to rename now before the secrets
are minted on the GitHub repo.
* infra/{apt,rpm}/bun.lock: the worker justfiles run `bun install`
before deploy. Commit the lockfiles so the wrangler version is
reproducibly pinned.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-distribution-cjAUm
…ish)
* packaging/moq-relay/moq-relay.service: ExecStart was passing --config
but moq-relay's clap parser exposes the TOML path as --file (see
rs/moq-relay/src/config.rs). The service would have failed to start
on every install.
* infra/apt/src/worker.ts: stop applying immutable Cache-Control to all
.gpg files. The only static one is moq-archive-keyring.gpg; Release.gpg
is rewritten every release and was getting pinned at the edge.
* infra/rpm/publish.sh: reject .rpms whose arch isn't in ARCHES (or
noarch). Previously an unsupported arch silently produced a directory
that never got indexed or signed.
* infra/{apt,rpm}/publish.sh: move GNUPGHOME removal into the EXIT trap
so key material is wiped even when signing fails.
* .github/workflows: set persist-credentials: false on every checkout in
the workflows this PR introduced (moq-cli, moq-token-cli, apt-repo,
rpm-repo, and the new moq-gst package-deb / package-rpm jobs). Brings
them in line with the convention from #1463.
* packaging/moq-relay/relay.toml: the comment claimed anonymous publish
was anon/** only; config also grants demo/viewer. Fixed.
* rs/justfile: drop the hardcoded amd64 fallback when dpkg isn't
installed. Map from uname -m so `just rs package` produces the right
arch label on arm64 hosts.
* rs/moq-gst/package.sh: validate that flag values are present before
reading $2, so a missing value produces a usage error instead of an
unbound-variable crash.
* doc/setup/linux.md: create /var/lib/moq-relay before the cp step (it
doesn't exist until the service starts and creates its StateDirectory)
and rename the misleading "verify a .deb directly" heading.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolves conflicts between this branch's nix-based tarball workflows for moq-cli/moq-relay/moq-token-cli and main's #1457 .deb/.rpm packaging flow added to the same files. The merged workflows now do both: main's linux cargo build + .deb + .rpm + apt/rpm repo publish trigger, plus this branch's macOS tarball build via nix for Homebrew. Per-crate workflow structure (moq-cli, moq-relay, moq-token-cli): - build job (main's): linux x86_64+aarch64, cargo, plus a new "Package tarball (Homebrew)" step that produces a .tar.gz alongside the bare binary and .deb/.rpm. Trigger paths cover the workflow, release.sh, package-binary.sh, the packaging/<crate>/ directory, and the setup-packaging composite action. - build-tarball-macos job (new): macOS x86_64+arm64 via nix, runs package-binary.sh to produce a .tar.gz for the Homebrew tap. - release job: needs [build, build-tarball-macos], gated to push events so PR dry-runs don't try to upload assets or trigger apt/rpm repo publish. moq-clock keeps the all-nix matrix from this branch (main didn't add .deb/.rpm packaging for it). moq-gst takes main's content verbatim (.deb/.rpm + nix tarball), with no PR dry-run. Dry-run versioning: each Parse version step has a pull_request fallback that reads from rs/<crate>/Cargo.toml instead of release.sh parse-version (which requires a GITHUB_REF tag). https://claude.ai/code/session_015J5tVAQ7ESjBhnzdeXfhgX
The merged-in workflow from #1457 references target/release/moq in the bare-binary copy, .deb BINARY_PATH, and the docker rpm rebuild, but cargo actually produces target/release/moq-cli (no [[bin]] override on the moq-cli crate). No moq-cli release has been cut yet so the bug hadn't been caught, but this PR's dry-run hits it: all four moq-cli matrix jobs fail at "Package bare binary" with cp: cannot stat 'moq'. Fix it the smallest way: after cargo build, copy target/release/moq-cli to target/release/moq on the runner, and inside the AlmaLinux docker (which does its own cargo build) cp from target/release/moq-cli straight to target/moq.rpm-build instead of through a nonexistent target/release/moq. The .deb nfpm BINARY_PATH keeps pointing at target/release/moq because the host-side rename makes that path exist. https://claude.ai/code/session_015J5tVAQ7ESjBhnzdeXfhgX
Summary
Wires up native Linux distribution for
moq-relay,moq-cli,moq-token-cli, and themoq-gstGStreamer plugin. Each tagged release now also produces signed.deband.rpmartifacts attached to the GitHub Release, and a follow-up workflow regenerates the apt/rpm repository metadata behind two new Cloudflare Workers.What ships to Linux users
moq-relaymoq-relaymoq-relay/etc/moq-relay/relay.toml(conffile)moq-climoq-climoq-cli/usr/bin/moqmoq-token-climoq-token-climoq-token-cli/usr/bin/moq-token-climoq-gstplugingstreamer1.0-moqgstreamer1-moqlibgstmoq.soin the right multiarch dirEnd-user one-liner (after the operator bootstrap below is done once):
Design decisions
nfpmis the packager. Single Go binary, produces both.deband.rpmfrom one YAML, no Ruby/Python runtime dep, no need to polluteCargo.tomlwith[package.metadata.deb]blocks. Configs live inpackaging/<crate>/nfpm.yaml..deb/.rpmdynamically link against the consumer's glibc; a Nix-pinned glibc wouldn't match. So.debbuilds onubuntu-22.04(glibc 2.35 → Ubuntu 22.04+ and Debian 12+) and.rpmbuilds inside analmalinux:9container (glibc 2.34 → RHEL/Rocky/Alma 9, Fedora 38+, openSUSE Leap 15.5+). Formoq-gstspecifically, this also means linking against the distro'slibgstreamer1.0-dev/gstreamer1-develso the.sois symbol-compatible with the GStreamer the user actually has. The existing Nix-built.tar.gzflow is preserved as the generic-Linux fallback.moq-relaysystemd unit usesDynamicUser=yes+StateDirectory=moq-relay. No postinstadduserscript, no chown dance. Dropcert.pem/key.pem/root.jwkinto/var/lib/moq-relay/andsystemctl enable --now moq-relay. The/etc/moq-relay/relay.tomlis registered as a conffile so operator edits survive package upgrades.rom.moq.dev(demo/boy/) andvid.moq.dev(demo/pub/) pattern. New infra-only workers go underinfra/{apt,rpm}/. Existing demo/cdn workers stay where they are since they're co-located with their content; consolidating them underinfra/would be a separate refactor.gh workflow run apt-repo.yml -f tag=...from each release job. Cannot rely onrelease:publishedcascade becauseGITHUB_TOKEN-created releases don't trigger downstream workflows.Layered distribution recommendation
The PR description in
doc/setup/linux.mddocuments the full set of options for "how should we distribute to Linux users in general":.deb/.rpmwith hosted repos (this PR)cargo installfrom crates.io (already shipping).deb, Flatpak is desktop-app oriented)One-time operator bootstrap
infra/README.mdis the runbook. TL;DR:apt-moq-devandrpm-moq-dev.just infra deployto bring up theapt.moq.devandrpm.moq.devcustom domains.R2_ACCESS_KEY_ID,R2_SECRET_ACCESS_KEY,R2_ACCOUNT_ID,APT_SIGNING_KEY,APT_SIGNING_KEY_ID.After that, every
moq-relay-v*/moq-cli-v*/moq-token-cli-v*/moq-gst-v*tag automatically populates both repositories.Test plan
These need to run after the operator bootstrap above, since CI talks to real R2 and GPG infrastructure.
just rs package moq-relay debproduces a valid.deb(Ubuntu host with nfpm installed). Confirmdpkg-deb -Ishows the right dependencies and conffile..debinstall in a clean container:docker run --rm -v $PWD/dist:/p ubuntu:22.04 bash -c "apt update && apt install -y /p/moq-relay_*.deb && moq-relay --help". Confirm/lib/systemd/system/moq-relay.servicelands anddpkg-query -W -f='${Conffiles}\n' moq-relaylists/etc/moq-relay/relay.toml..rpminstall in AlmaLinux 9:docker run --rm -v $PWD/dist:/p almalinux:9 bash -c "dnf install -y /p/moq-relay-*.rpm && moq-relay --help".docker run --rm -v $PWD/dist:/p ubuntu:22.04 bash -c "apt update && apt install -y gstreamer1.0-tools /p/gstreamer1.0-moq_*.deb && gst-inspect-1.0 moq". NoGST_PLUGIN_PATHoverrides needed./etc/moq-relay/relay.toml, install N+1, confirm the edit survives.bun wrangler deploy --dry-runininfra/apt/andinfra/rpm/validates the route+binding.infra/apt/publish.sh, thenapt updatefrom a clean Ubuntu container pointing at the test domain. Confirm signature verification passes and the advertised version matches the GitHub Release.moq-relay-v0.0.0-testagainst a fork. Confirm the workflow produces.deb/.rpmartifacts on the release page and thatapt-repo.yml/rpm-repo.ymlget dispatched and complete.https://claude.ai/code/session_013XdpQ4kZDWh7F94b8RwSwx
Generated by Claude Code