Skip to content

Self-hosted PPA: add prerelease suite and prerelease→stable promotion #165

@rtibbles

Description

@rtibbles

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

  • The self-hosted reprepro repo defines two suites, stable and prerelease, both published to gh-pages and signed with the existing repo key.
  • A prerelease build publishes its binary .deb (the build_deb.yml artifact) to the prerelease suite, installable from the self-hosted prerelease suite via apt. The publisher always targets prerelease — no suite flag.
  • A separate reusable + workflow_dispatch promote workflow promotes a staged package prerelease → stable, runnable independently of the Launchpad release flow.
  • After promotion, the stable suite serves the same .deb that was staged in prerelease (a reprepro copy, not a rebuild), installable via apt.
  • stable is populated only via promotion; release_ppa.yml's direct-publish-of-a-.deb-to-stable is removed/replaced.
  • Publishing or promoting into one suite preserves the other (a prerelease publish doesn't drop stable; a promotion doesn't drop the current prerelease).
  • Each suite retains only the most recent version; older .debs are pruned from the reprepro pool.
  • After any publish or promotion, the gh-pages branch is a single flattened commit (no old package blobs accumulating in git history).
  • apt update against either suite verifies signatures with the published public key (no NO_PUBKEY).
  • Repo-setup docs cover adding the self-hosted repo and enabling either suite (stable / prerelease): sources entry + signed-by key.

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.

Metadata

Metadata

Assignees

Type

No fields configured for Task.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions