Latest stable releases of developer tools, packaged for Debian and Ubuntu and
served over apt.
- Debian: Bullseye (11), Bookworm (12), Trixie (13), Forky (14/testing), Sid (unstable)
- Ubuntu: Jammy (22.04 LTS), Noble (24.04 LTS), Questing (25.10), Resolute
(26.04 LTS) — native builds wherever the builder produced an
+<ubuntu-suite>package; packages without a native build fall back to an alias of a Debian suite with older-or-equal glibc (Jammy from Bullseye; Noble/Questing/Resolute from Trixie) — seesuites.json'saliasesmap and the per-package fallback inscripts/build-repo.sh - Architectures: amd64, arm64, armhf, ppc64el, s390x, riscv64, loong64 (plus i386 and armel on bullseye/bookworm/trixie)
- Updates: near-instant — publishing a release in a
*-debianrepo triggers an immediate rebuild via webhook, with a ~6h scheduled run as the fallback. Best-effort, no SLA (see Support & expectations)
All packages are built from upstream releases using the debian-multiarch-builder GitHub Action. Each tool's packaging lives in its own repo under this organization.
Every release is gated by lintian (Debian's package policy checker) and a smoke test that runs the packaged binaries in a container and verifies they report the expected version before the release is published — so the channel only ever carries packages that both pass policy and actually run.
An auditable, signed, test-gated latest channel — that's the differentiator. It sits between two unsatisfying extremes: Debian's frozen cadence and ad-hoc "download the tarball from GitHub" installs.
vs. Debian stable — Debian freezes versions for years; you wait for
backports or the next release. Here, the moment a *-debian repo publishes a
release, a webhook (repository_dispatch) fires an immediate apt-repo
rebuild — with a ~6h scheduled run as the catch-up backstop — so you get
current tools on a stable base, through the same apt you already trust.
vs. Debian itself — when a live Debian suite (most often sid/unstable,
but sometimes trixie too — common for tools with a Debian Developer
upstream, e.g. bat, fd) already tracks a tool's latest upstream release,
it's already offering exactly what this channel would add, on a much larger
base of packages. We don't duplicate that — see
Debian parity below.
vs. ad-hoc release downloads — a raw GitHub binary is trust-on-download: no policy check, no run test, no signature chain, no record of what you got. Every package in this channel instead carries:
- Signed — the apt indexes are GPG-signed on every rebuild
(
scripts/sign-repo.sh) andaptverifies them viasigned-by=, so the metadata describing every package is authentic, not just the download. - Test-gated — lintian (Debian's packaging policy checker) plus a smoke test that actually runs the packaged binaries in a container and confirms they report the expected version. Nothing is released that fails policy or doesn't run.
- Auditable — each package carries a provenance pin (upstream release identity + SHA-256, cross-checked against the vendor's published checksum at vet time), every build lands as a draft that a maintainer reviews before promotion, and the whole chain — packaging repos, builder action, rebuild pipeline — runs in public repos with full history (see Supply chain & provenance).
That combination is what ad-hoc downloads can't offer (no signing, no policy, no audit trail) and what Debian's cadence can't offer (currency).
And we retire ourselves when Debian catches up. Most third-party
repositories have a structural reason to keep you on them; this one does not.
When a tool reaches its latest upstream version in a released suite, we drop
our package — when it reaches parity in a rolling suite, we drop that suite
from our build and leave the rest. It is applied automatically by
scripts/build-repo.sh from a daily parity report, not left to good
intentions, and every hand-off is recorded in
graduated.json with where to go instead. The
dashboard counts suites handed
back as wins rather than to-do items. A vendor apt repo or a Homebrew tap has
no equivalent — nothing in either shrinks its own scope when the distribution
catches up. Full mechanics in
Debian parity.
Have a project that publishes a Linux binary on GitHub? We can package it for
Debian the same way the tools above are — signed, test-gated, provenance-pinned,
and kept current automatically. The <tool>-debian repo is yours: public,
forkable, and maintained via the feature channel (a template change rolls out
to every package repo in one operation, so improvements land everywhere at
once).
What you get, concretely:
- A public packaging repo scaffolded from one template, with CI and full history.
- Auto-watch: new upstream releases are built automatically, no per-version work.
- All five Debian suites × every architecture your release actually publishes a Linux binary for (verified precisely at vet time), plus source packages. A suite drops out automatically once its Debian LTS window ends.
- GPG-signed apt indexes, lintian + smoke-test gates, a vet-time SHA-256 provenance pin, and automated license/SPDX + asset pre-checks at intake.
- Near-instant updates via webhook-triggered rebuilds.
It's volunteer-run and best-effort (no SLA), but the packaging is yours to fork and take anywhere. See SERVICE.md for the full pitch, the offer, and how to get started (or just open a package request).
This is a volunteer-run project, not a commercial service. Everything runs on free GitHub Actions and manual review, so treat the channel as best-effort with no SLA:
- Rebuild cadence. Publishing a release normally rebuilds the apt index
within minutes (a webhook from the
*-debianrepo triggers it). If that webhook is missed — lost dispatch, a missingTRIGGER_TOKEN, a runner outage, or GitHub deferring scheduled/dispatch events under load — the ~6h scheduled run is the guaranteed catch-up. A freshly published upstream release can therefore appear within minutes or take longer, and if an upstream archive becomes unavailable, that version may be skipped entirely. Don't build a pipeline that depends on a package appearing by a deadline. - Draft release promotion. Packages are never auto-published. Every build
lands as a draft GitHub release that a maintainer reviews and publishes by
hand (see Supply chain & provenance). That
human gate is deliberate — it keeps tampered or broken releases out of the
channel — but it means promotion lags the build, and if a maintainer is
away, newer versions wait.
scripts/promote-drafts.shmakes catching up a single reviewed command (list, then publish, across every*-debianrepo). - Upstream dependency. We repackage upstream GitHub releases as they
publish them. If an upstream changes its release layout, removes old
archives, or goes away, the corresponding tool stops updating until someone
fixes the packaging. The staleness watchdog
catches that automatically — a tool whose upstream release outlives the
rebuild + promotion grace window lands on the
stale-packagetracking issue — but the fix itself still needs a human.
What we do guarantee: the channel stays internally consistent. Indexes are always GPG-signed, every package is lintian-checked, smoke-tested, and checksum-verified before publication, and nothing ships that a human hasn't reviewed. Rely on it for convenience — not for security-critical or time-critical patch delivery.
Via extrepo (Debian, and Ubuntu except 22.04):
sudo extrepo enable latest-debs
sudo apt update
sudo apt install uv eza lazygitImportant
extrepo enable latest-debs is currently broken — use the manual snippet
below instead. The policy published in
extrepo-data
still carries the old https://latest-debs.github.io/apt-repo/ base URI.
That origin still serves dists/, so apt update succeeds and the packages
appear — but pool/ is no longer published there (it exceeded GitHub Pages'
1GB published-site limit), so every apt install 404s on download. The
manual snippet below points at the redirector, which serves both. This
clears once the extrepo-data MR in
extrepo/latest-debs.yaml is merged upstream.
On Ubuntu 22.04 (jammy), use the manual snippet below instead. extrepo takes its suite from
/etc/extrepo/config.yaml— a static file shipped in the package, not read fromos-release— and jammy's extrepo 0.9 pinsbookworm, whose glibc (2.36) is newer than jammy's (2.35). The manual snippet uses jammy's own codename, which we serve as an alias of bullseye (glibc 2.31). Noble and later pintrixie, the same alias target this repo already maps them to, so extrepo and the manual snippet install identical packages there.
Manually:
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://raw.githubusercontent.com/latest-debs/apt-repo/main/latest-debs.asc | sudo gpg --dearmor --yes -o /etc/apt/keyrings/latest-debs.gpg
echo "deb [signed-by=/etc/apt/keyrings/latest-debs.gpg] https://latest-debs.ranjithraj.workers.dev/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/latest-debs.list
sudo apt updateNote: The repository indexes are GPG-signed (
scripts/sign-repo.shruns automatically on every rebuild).aptverifies signatures against the key imported above viasigned-by=.
If you're installing these tools in a build image, a CI runner, or across a
fleet, the usual options are curl | sh inside the Dockerfile or a version
manager (mise, asdf) resolving a plugin at build time — neither gives you
a signature, a pinned checksum, or a record of what actually got installed.
This channel gives a CI/fleet pipeline something to point at instead:
-
Pin an exact version, and verify the pin cryptographically. Every release carries a Sigstore-signed SLSA build-provenance attestation and a signed SPDX SBOM, both bound to the exact artifact bytes. That turns "trust our
provenance.json" into something your pipeline can check itself, with no appeal to us:# Fails loudly if the .deb was not built by the workflow it claims. gh attestation verify uv_0.12.3-1+trixie_amd64.deb --repo latest-debs/uv-debian # Same artifact, its SPDX SBOM. gh attestation verify uv_0.12.3-1+trixie_amd64.deb --repo latest-debs/uv-debian \ --predicate-type https://spdx.dev/Document
Run it as a gate in the build that consumes the package, and a substituted or re-uploaded artifact fails the step instead of shipping. Alongside those, each release still carries the human-readable
provenance.json(source commit, builder run URL, SHA-256 of every shipped artifact) andsbom.spdx.json, and was built against a vet-time upstream checksum pin. See Supply chain & provenance.What the SBOM does and does not cover, since an overstated SBOM is worse than none: it documents the shipped artifacts and the upstream release they were packaged from — names, versions, licenses, SHA-256s, and the CI run that produced them. It does not enumerate the upstream's transitive dependency graph. The document says so in its own
commentfield. -
Signed, not just downloaded.
apt's ownsigned-by=verification replaces "trust the TLS connection to a raw GitHub URL" with a GPG chain you control the keyring for — the same trust model as every other package on the box, not a special case for your dev tools. -
A
Dockerfileline, not a shell script to audit. Nocurl | sh, no third-party install script to review on every version bump:RUN sudo install -d -m 0755 /etc/apt/keyrings \ && curl -fsSL https://raw.githubusercontent.com/latest-debs/apt-repo/main/latest-debs.asc \ | gpg --dearmor -o /etc/apt/keyrings/latest-debs.gpg \ && echo "deb [signed-by=/etc/apt/keyrings/latest-debs.gpg] https://latest-debs.ranjithraj.workers.dev/ trixie main" \ > /etc/apt/sources.list.d/latest-debs.list \ && apt-get update && apt-get install -y ripgrep=<version> fd-find=<version>
-
Check our work before you depend on it. The pipeline status dashboard publishes, daily and unedited, exactly which tools are behind upstream and by how long, and which are at parity in a Debian suite. It's rendered straight from
dists/staleness.jsonanddists/parity.json— machine-readable, so a procurement review (or a scheduled check in your own CI) can assess the channel's actual operating record rather than take this README's word for it.Both reports are served from two independent origins — the redirector (
https://latest-debs.ranjithraj.workers.dev/dists/…) and the GitHub Pages site it proxies — and the dashboard reads whichever answers first. Point your own check at either. The record is the basis on which this channel asks to be judged, so it deliberately does not depend on any single host staying available.
Read Support & expectations first, though: this is volunteer-run with no SLA — and the dashboard above is deliberately the place to verify that claim rather than dispute it. Fine for a build image where a missed rebuild window just means "not on the latest patch release yet" — not a fit for a deploy gate with a hard deadline on a specific version landing.
- Request a package: open a
package request
— tool name, upstream URL, and license is all we need. Valid requests are
validated and scaffolded automatically by the
Process package requestworkflow; open requests are tracked under thepackage-requestlabel. - Do it yourself:
- Add an entry to
tools.yamlpointing at the tool's package repo (e.g.https://github.com/latest-debs/uv-debian). - The scheduled workflow picks it up automatically on the next run.
- Add an entry to
Policy: we step aside exactly as far as Debian actually covers the user — per suite, not per package. Where a live Debian suite already carries a tool at its latest upstream version, our copy for that suite is a second, lower-trust duplicate of what Debian already ships. But how far that goes depends on whether the user can actually reach that suite:
| Parity in | What we do | Why |
|---|---|---|
| A released suite (bullseye, bookworm, trixie) | Retire the package (human-gated) | The user already runs that suite: plain apt install <tool> gets them the current version. We're fully redundant. |
| A rolling suite (forky, sid) | Drop just that suite from our build. Keep the package. | A sid user gets it from sid — so we stop publishing our sid copy. But a bookworm/trixie user can't reach sid without pinning, and may not want to at all, so our package stays for every other suite. |
So a tool at parity in sid keeps shipping here for bullseye/bookworm/trixie — we simply stop building it for sid, and point sid users at Debian's own copy. Nobody loses a route to the current version; we just stop duplicating the one route that already exists.
Parity exceptions. parity-exceptions.json lists packages that
deliberately override the released-suite RETIRE stop, each with a reason,
a review date, and an expiry. check-suite-parity.sh reports them as
EXCEPT (and writes gate: except) instead of failing vetting, and
build-repo.sh's is_parity_drop skips them so the per-suite hand-back
does not remove them either. Exceptions are time-boxed on purpose: once
expiry passes, the package reverts to ordinary parity handling. The
current entry is the quickshell source-build pilot (below).
Every other package here repacks an upstream binary. quickshell has no
upstream binaries, so its repo carries build_mode: source and compiles the
Forgejo source tag per suite (see BUILD-SOURCE.md in that repo). Two
consequences for the shared tooling:
rollout-autowatch.shskips any repo whosepackage.yamlsetsbuild_mode: source— itsrelease.ymlis bespoke and must not be clobbered by the binary template.- Intake supports Forgejo-first upstreams via
add-package.sh --source --upstream-url <repo-url>, which vets the source tarball (scripts/vet-source.sh) instead of a release asset.tools.yamlmay then carrygithub_repo:to point version detection, parity, and staleness at the GitHub mirror whenhomepageis not GitHub.
Policy: if an upstream already publishes .deb packages itself, we don't
package that tool. Upstream is the highest-trust source for its own
software; a repack of its artifacts through our pipeline would be a second,
lower-trust copy of exactly the same bytes — the same redundancy Debian
parity removes, one level down. The gap we fill is packaging, not
distribution: a tool whose releases ship no Linux artifact we can build
from (bare binaries or binary archives) is out of scope for the same reason
we don't repackage upstream .debs.
What we do instead:
- Point users upstream. If the upstream
.debs are downloadable and maintained, that's the honest answer — the package request gets closed with a link, not a duplicate. - Pitch the builder, not a repack. If upstream wants an apt index or
wider architecture coverage around the artifacts it already builds, the
offer is SERVICE.md's: run our builder upstream and publish your own
signed channel — which is a graduation (
reason: own-repoingraduated.json), never a copy here.
This is the intake analogue of Debian parity, and it applies at
scaffolding time: an upstream release whose only Linux artifacts are
.deb/AppImage doesn't get scaffolded, and a tracked tool that starts
shipping its own .debs gets flagged for the same step-aside review.
For tools already in the catalogue, upstream parity graduates through the
same handoff ledger as every other step-aside. When a tracked tool's
latest upstream release ships its own .deb packages, we open a handoff:
append an entry to graduated.json with reason: own-deb, destination pointing at the upstream release/download page,
drop the tool from tools.yaml, and let the coverage table and status page
show users where to go. Same human-gated review as an own-repo
graduation — one entry per tool, dated, in the PR that removes it. The
count of these entries is the count of packaging gaps that no longer exist,
which is the metric this channel is actually optimizing.
Two flags before any individual handoff lands (review them per tool):
- Does upstream cover the user's bases? An upstream
.debthat exists only for amd64 handsoffs a user holding an arm64 board. Check the arch spread and say so in the ledger entry'snote. - Is upstream's channel actually installable and current? A
.debattachment on a release is a download, not a distribution channel. If upstream's release cadence or asset naming looks unmaintained, say that instead and keep the entry off the ledger until it's real.
The per-suite drop is applied at build time by scripts/build-repo.sh from
the daily parity.json. It runs after the Ubuntu alias fallback on purpose:
an alias-filled package (noble←trixie, jammy←bullseye) keeps shipping even
when the Debian suite it was copied from is handed back, because an Ubuntu
user gains nothing from Debian trixie reaching parity. If the report is
missing or unreadable the build fails open and publishes everything —
shipping a redundant package is cheaper than silently withholding one.
These drops are wins, and the dashboard counts them as such. Every suite handed back is one this channel no longer has to carry, reached by the outcome the project wants: Debian caught up. They appear under Handed back to Debian rather than on any to-do list — no maintainer action is needed, and no user loses a route to the current version.
- New requests:
scripts/add-package.sh scaffoldchecks the requested tool's version in every live suite against the upstream release being vetted (scripts/check-suite-parity.sh, same madison lookupfetch-debian-versions.shuses for the stable-version column). Parity in a released suite fails vetting (verdictRETIRE) — the requester already has it. Parity in forky/sid only is advisory (verdictPIN-ADVISED): the request still proceeds, and the comment recommends pinning from that suite for anyone willing. - Tracked tools: run
scripts/check-suite-parity.shagainsttools.yamlto list current packages that have since caught up in any suite (upstream reaching parity after a tool was added is expected — Debian keeps moving). Only released-suite parity is flagged for retirement, and even then it is reviewed by a maintainer rather than auto-removed: removing a package a user already depends on is a real breaking change, so it goes through the same human-gate as everything else here. Rolling-suite parity shows aspin:<suites>and needs no action — the build already drops those suites on its own. A retirement that does go ahead is appended tograduated.jsonin the same PR that drops thetools.yamlentry — see Graduated tools below. Narrow the check with--suite trixie,--suite trixie,sid, etc. when you just want to preview one suite rather than all five. - What we tell users instead: depends on which suite matched.
-
If it's the suite they already run (trixie or bookworm, if that's their
aptconfig) — nothing extra needed, plainapt install <tool>already gets the latest version straight from Debian. -
If it's a suite they don't run (typically sid or forky) — enabling it wholesale on a stable/testing box is a good way to break that box (dependency escalation, aka "Frankendebian"). The safe version is pinning just the one package:
SUITE=sid # whichever suite matched — see the check's output echo "deb http://deb.debian.org/debian $SUITE main" | sudo tee /etc/apt/sources.list.d/$SUITE.list printf 'Package: *\nPin: release a=%s\nPin-Priority: 100\n\nPackage: %s\nPin: release a=%s\nPin-Priority: 500\n' \ "$SUITE" "<tool>" "$SUITE" | sudo tee /etc/apt/preferences.d/$SUITE-pin-<tool> sudo apt update sudo apt install <tool>
Everything else on the system stays on its current suite (priority 100 — won't install from
$SUITE); only the pinned package (priority 500) is allowed to come from there.
-
This only applies to Debian-suite parity — it doesn't change the hand-off policy for a project shipping its own official repo, which is a separate, unrelated case.
The Process package request workflow
runs on every package-request issue. With no extra setup it validates the
request (upstream exists, publishes a Linux .tar.gz/.tgz/.tar.xz/.zip
release asset) and leaves a comment on the issue.
To let it fully deploy, create a fine-grained PAT restricted to the
latest-debs org with Administration: write, Contents: write, and
Workflows: write (never a classic PAT with admin:org), set a short
expiry, and store it as the ORG_ADMIN_TOKEN secret in this repo. It is
only ever used to create org repos and dispatch their first build; everything
else in the workflow (issue comments, tools.yaml pushes) runs on the
repo-scoped GITHUB_TOKEN. Rotate it periodically. Once set, the workflow
will:
- scaffold a
<tool>-debianrepo fromtemplates/package-scaffold, - create and push it, dispatch the first auto build,
- register the package in
tools.yaml, and - comment on the issue.
All package repos use the auto-watching workflow: a scheduled job compares the
latest upstream release against what's already built and rebuilds new versions
automatically (see scripts/detect-version.sh in any *-debian repo).
When a *-debian release is published, its
notify-apt-repo workflow
dispatches an immediate apt-repo rebuild via repository_dispatch — so a new
package version lands in the apt index within minutes, not at the next ~6h
schedule. This needs a TRIGGER_TOKEN Actions secret on the package repo:
a fine-grained PAT scoped to apt-repo only with Contents: write (the
minimum for repository_dispatch). New repos get it copied at deploy time
(best-effort); run scripts/set-trigger-secret.sh to backfill existing repos
and to rotate. A repo without the secret falls back to the scheduled rebuild —
the webhook is an optimization, never a correctness dependency.
Package repo releases must be named so the suite is embedded, e.g.:
uv_0.12.3-1.bookworm_amd64.deb
uv_0.12.3-1.bookworm.dsc
uv_0.12.3-1.trixie_amd64.deb
See tools.yaml and scripts/build-repo.sh.
templates/package-scaffold is the single source of truth for every
*-debian repo's packaging workflow. To ship a change — a new
debian-multiarch-builder
version pin, a glob fix, a smoke-test improvement — edit the template,
commit it, then run:
scripts/rollout-autowatch.sh --dry-run # preview: what would change per repo
scripts/rollout-autowatch.sh # real run: 1 commit pushed per repoIt regenerates .github/workflows/release.yml, .github/workflows/notify-apt-repo.yml,
and .github/scripts/detect-version.sh in every repo (placeholders
substituted from each repo's package.yaml) and pushes one commit per repo
to main. Idempotent: repos already at the template are skipped. Use
--repo owner/repo to target a single repo. README.md is intentionally
not rolled out — child READMEs carry per-repo customizations.
A daily scheduled workflow (staleness.yml) compares each tool's upstream
latest release against what the apt channel actually carries (from
dists/pkg-repo-map.json, the same data the freshness badges use). A tool is
flagged only once the upstream release has outlived the grace window
(STALE_AFTER_HOURS, default 48) — shorter gaps are the normal rebuild +
draft-promotion lag, not a broken pipeline. Flagged tools land on a single
stale-package tracking issue, which the watchdog updates in place and
closes on its own when everything is current again. Run it by hand with
scripts/check-upstream-staleness.sh (add --update-issue to sync the
tracking issue; local runs print the report).
Promoting the backlog of already-built drafts is a separate one-liner —
scripts/promote-drafts.sh lists every pending draft across all
*-debian repos (--publish promotes them after review; publishing fires
the webhook, so the apt index rebuilds within minutes).
The pipeline defends against upstream supply-chain attacks in layers:
-
Draft-before-publish — every
*-debianbuild produces a draft GitHub release. Only a human publishing the draft makes the packages visible to the apt repo's rebuild, so nothing we ship was ever auto-published. -
Vet-time provenance pin — when a package request is vetted (
scripts/vet-release.sh, viaadd-package.sh scaffold), the upstream asset is downloaded, its SHA-256 is cross-checked against the release's published checksum file, and the release identity plus digest are captured in.github/release-metadata.jsoninside the scaffolded repo. The debian-multiarch-builder re-verifies the exact bytes it downloads against that pin when building the vetted version, so a release altered after vetting fails the build instead of being silently packaged. Releases that appear later (via the auto-watch) have no pin yet, so they are verified against the release's own checksum file and still gated by draft-before-publish until a maintainer vets them. -
Build provenance — every release also ships a
provenance.jsonasset (.github/scripts/generate-provenance.sh) recording the exact builder action ref, workflow run URL, and source commit that produced it, a SHA-256 of every shipped artifact, and the vet-time upstream pin it was built from. The input pin proves what upstream bytes were verified; this proves what build produced the .deb — so a package traces back to an inspectable CI run, not just a checksum on faith. -
Signed attestations —
provenance.jsonandsbom.spdx.jsonare our own documents, and on their own they are exactly as trustworthy as whoever serves them. Every release therefore also publishes a Sigstore-signed SLSA build-provenance attestation and a signed SPDX SBOM attestation (actions/attest-build-provenance,actions/attest-sbom), each bound to the artifact digests. Anyone can check one without trusting this README, the apt origin, or us:gh attestation verify <file>.deb --repo latest-debs/<tool>-debian
This is the layer that survives the rest being wrong: if the origin were compromised and a
.debswapped, its attestation would not verify. See For CI pipelines & fleets for using it as a gate. The SBOM covers the shipped artifacts and their upstream release, not the upstream's transitive dependency graph — it says so in its owncommentfield.
Access is scoped to the minimum: repo-scoped GITHUB_TOKEN wherever possible
(issue handling, tools.yaml), and a fine-grained, org-restricted
ORG_ADMIN_TOKEN only for creating org repos and dispatching their first
build. GitHub API calls are authenticated everywhere to avoid the shared
60/hour anonymous rate limit silently starving every fetch.
RUNBOOK.md covers the two dependencies that can't be recreated from this repo if their holder is unavailable — the Cloudflare Worker that serves every apt client, and the GPG signing key — plus what maintainers would need to take the channel over. The tokens above are deliberately out of scope there: any org owner can re-issue them in minutes.
licenses.json is the published, per-package SPDX record —
one declared license identifier per tracked tool, sourced straight from each
<tool>-debian repo's package.yaml (the same field the vet-time license
scan and every release's license-recheck gate both read). It's regenerated
from tools.yaml with scripts/fetch-licenses.sh and committed rather than
generated on the fly, so anyone auditing the channel — before depending on it
in CI, an image, or a fleet — can check exactly what's declared for every
package without re-running the pipeline themselves. licenses.json is the
machine-readable form of the same data shown in the License column of the
status dashboard.
graduated.json records every tool that has left this
channel and why — either because upstream shipped its own signed apt repo
(the hand-off policy)
or because a Debian suite caught up (the
parity policy).
This channel exists to fill a gap, so a tool leaving because that gap closed
is the intended outcome, not attrition — and the ledger is what makes that
countable instead of invisible. It also gives anyone hunting for a package
that used to be here a place to land: each entry names where the tool lives
now. Append an entry in the same PR that drops the tools.yaml entry; the
list renders on the
status dashboard.
The current list of published packages — with versions, licenses, and install
commands — is served dynamically on the
status dashboard, generated live from the
apt indexes on every rebuild, so it can never drift from what the channel
actually serves. The per-package SPDX declarations behind the dashboard's
License column are also available as machine-readable
licenses.json.
tools.yaml registry of tracked tools
templates/package-scaffold template for new <tool>-debian repos
scripts/add-package.sh validate + vet (checksum) + scaffold + deploy + register tool
scripts/vet-release.sh vet-time checksum verification + release metadata capture
scripts/vet-source.sh source-only upstream vetting (tarball SHA-256 pin)
scripts/build-repo.sh fetch releases + generate pool/ and dists/
scripts/run-in-debian.sh run build-repo.sh in a Debian container
scripts/sign-repo.sh GPG-sign dists (run on a Debian machine)
scripts/set-trigger-secret.sh backfill TRIGGER_TOKEN onto *-debian repos
scripts/rollout-autowatch.sh one-command template rollout to all *-debian repos (skips build_mode: source)
scripts/fetch-licenses.sh regenerate licenses.json from tools.yaml
scripts/check-upstream-staleness.sh flag tools whose upstream release outran the channel (--update-issue syncs the tracking issue)
scripts/promote-drafts.sh list/publish pending draft releases across all *-debian repos (dry-run by default)
scripts/check-suite-parity.sh flag tools already at latest-upstream parity in any Debian suite (default: all)
parity-exceptions.json time-boxed overrides of the released-suite parity RETIRE stop
extrepo/latest-debs.yaml extrepo metadata (contributed upstream)
latest-debs.asc public signing key
licenses.json per-package SPDX license audit (generated, committed)
pool/ downloaded .deb + source files (generated)
dists/ apt indexes (generated)
