Overview
The self-hosted Debian repository (reprepro published to GitHub Pages, in release_ppa.yml) is currently release-only, serving a single stable suite. Prereleases go only to Launchpad's kolibri-proposed PPA, which has shown multi-hour publish latency (on a recent release the build finished in ~4 min but the binary wasn't installable for ~138 min). Add a prerelease suite to the self-hosted repo and publish prerelease .debs into it directly from the build artifact, so prereleases are installable from our own repo within minutes — independent of Launchpad. Releases reach stable by promoting (copying) a staged build out of prerelease. This requires the repo to persist its state across runs — which it currently doesn't — so both suites survive a publish and a staged build remains available to promote.
Complexity: Medium
Target branch: main
Context
kolibri is Architecture: all — a single .deb (built by build_deb.yml in minutes) installs on every Ubuntu/Debian series and arch. So the self-hosted repo needs no per-series builds; one repo serves all releases.
Current state of the self-hosted repo (release_ppa.yml, publish_github_pages_ppa job):
reprepro includedeb stable <deb> into a single Codename: stable / Suite: stable.
- Input is a finished
.deb (inputs.deb-file-name artifact or inputs.deb-url).
- Deployed via
git init + git checkout -b gh-pages + git push --force each run — so gh-pages only ever holds the one .deb from that run (no persistence).
The prerelease flow (prerelease.yml) currently publishes only to Launchpad kolibri-proposed (source upload → Launchpad builds), and never touches the self-hosted repo.
The Change
- Two suites. Add a
prerelease suite alongside stable in the reprepro distributions config; one published site serves both channels.
- Publish always targets
prerelease. Repurpose the existing self-hosted publisher (publish_github_pages_ppa) to publish the binary .deb (the build_deb.yml artifact) into the prerelease suite, and have the prerelease flow invoke it. New builds only ever enter via prerelease, so there's no suite flag.
- Promote via a separate, dispatchable workflow. A new reusable +
workflow_dispatch workflow promotes a staged package prerelease → stable with reprepro copy — reusing the exact tested .deb — decoupled from the Launchpad release flow. stable is populated only by promotion; this replaces release_ppa.yml's current direct-publish-to-stable.
- Persist, prune, flatten. Persist the repo state across runs so both suites and the staged package survive; retain only the most recent version per suite (older
.debs pruned from the pool); republish gh-pages as a flattened snapshot so old blobs don't accumulate in git history.
Acceptance Criteria
Out of Scope
AI usage
I developed this issue with Claude Code in an interactive session. Claude proposed options and surfaced tradeoffs (Launchpad publish latency, arch:all implications, git-history bloat), and drafted the sections; I made every design decision — suite naming, publish-always-to-prerelease with no flag, the separate dispatchable promote workflow, retention/flatten bounds, and replacing the release flow's direct stable publish — and reviewed and corrected each section.
Overview
The self-hosted Debian repository (reprepro published to GitHub Pages, in
release_ppa.yml) is currently release-only, serving a singlestablesuite. Prereleases go only to Launchpad'skolibri-proposedPPA, which has shown multi-hour publish latency (on a recent release the build finished in ~4 min but the binary wasn't installable for ~138 min). Add aprereleasesuite to the self-hosted repo and publish prerelease.debs into it directly from the build artifact, so prereleases are installable from our own repo within minutes — independent of Launchpad. Releases reachstableby promoting (copying) a staged build out ofprerelease. This requires the repo to persist its state across runs — which it currently doesn't — so both suites survive a publish and a staged build remains available to promote.Complexity: Medium
Target branch: main
Context
kolibriisArchitecture: all— a single.deb(built bybuild_deb.ymlin minutes) installs on every Ubuntu/Debian series and arch. So the self-hosted repo needs no per-series builds; one repo serves all releases.Current state of the self-hosted repo (
release_ppa.yml,publish_github_pages_ppajob):reprepro includedeb stable <deb>into a singleCodename: stable/Suite: stable..deb(inputs.deb-file-nameartifact orinputs.deb-url).git init+git checkout -b gh-pages+git push --forceeach run — sogh-pagesonly ever holds the one.debfrom that run (no persistence).The prerelease flow (
prerelease.yml) currently publishes only to Launchpadkolibri-proposed(source upload → Launchpad builds), and never touches the self-hosted repo.The Change
prereleasesuite alongsidestablein the repreprodistributionsconfig; one published site serves both channels.prerelease. Repurpose the existing self-hosted publisher (publish_github_pages_ppa) to publish the binary.deb(thebuild_deb.ymlartifact) into theprereleasesuite, and have the prerelease flow invoke it. New builds only ever enter viaprerelease, so there's no suite flag.workflow_dispatchworkflow promotes a staged packageprerelease → stablewithreprepro copy— reusing the exact tested.deb— decoupled from the Launchpad release flow.stableis populated only by promotion; this replacesrelease_ppa.yml's current direct-publish-to-stable..debs pruned from the pool); republishgh-pagesas a flattened snapshot so old blobs don't accumulate in git history.Acceptance Criteria
stableandprerelease, both published togh-pagesand signed with the existing repo key..deb(thebuild_deb.ymlartifact) to theprereleasesuite, installable from the self-hostedprereleasesuite viaapt. The publisher always targetsprerelease— no suite flag.workflow_dispatchpromote workflow promotes a staged packageprerelease → stable, runnable independently of the Launchpad release flow.stablesuite serves the same.debthat was staged inprerelease(areprepro copy, not a rebuild), installable viaapt.stableis populated only via promotion;release_ppa.yml's direct-publish-of-a-.deb-to-stableis removed/replaced.prereleasepublish doesn't dropstable; a promotion doesn't drop the currentprerelease)..debs are pruned from the reprepro pool.gh-pagesbranch is a single flattened commit (no old package blobs accumulating in git history).apt updateagainst either suite verifies signatures with the published public key (noNO_PUBKEY).stable/prerelease): sources entry +signed-bykey.Out of Scope
AI usage
I developed this issue with Claude Code in an interactive session. Claude proposed options and surfaced tradeoffs (Launchpad publish latency,
arch:allimplications, git-history bloat), and drafted the sections; I made every design decision — suite naming, publish-always-to-prereleasewith no flag, the separate dispatchable promote workflow, retention/flatten bounds, and replacing the release flow's directstablepublish — and reviewed and corrected each section.