Publish a package repository from GitHub Pages - #95
Merged
Merged
Conversation
Every install was by URL, so every consumer encoded the release filename convention, the architecture segment did not match the fact it came from, ensure => latest could not work, and the lab and the Puppet module both had to pin a raw asset. Hosting a repository looked like a standing commitment: a server, createrepo, an apt indexer, a key to generate, distribute, and rotate. It is a build step after all. The repository is static files: a directory with repodata in it is a yum repository, and one with Packages and Release files is an apt repository, and GitHub Pages serves both. The Repository workflow rebuilds it in full from GitHub Releases whenever a release is published — every rpm and deb ever released, indexed and signed — so there is no branch to maintain and nothing to get out of step with the releases page, which stays the source of truth. What is signed is the metadata, not the packages. repomd.xml and Release each name every package's SHA-256, so a signed index vouches for every file below it; apt has always worked this way and dnf verifies it with repo_gpgcheck. That keeps the packages byte-for-byte the release assets, including releases made before this existed, so checksums.txt still describes them. The key's secret half lives only in the repository secrets; its public half is exported into the site beside the packages. Verified locally with a throwaway key: dnf on Rocky 9 and apt on Debian 12 each imported the key, verified the metadata, installed a pinned older version, and upgraded to the latest. apt-ftparchive's Tree mode indexed nothing from the pool, so the builder scans per architecture directly. The README installs from the repository and needs no version; only the install-by-URL fallback in installation.md carries one, so the release workflow's version check now covers that file alone. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Michael Harp <mike@mikeharp.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #42 once the first deploy lands.
What this is
A yum and apt repository as static files on GitHub Pages, at https://mikeharp.com/codavox (the github.io address redirects there). The
Repositoryworkflow rebuilds it in full from GitHub Releases whenever a release is published, and on demand: every rpm and deb ever released, indexed withcreaterepo_candapt-ftparchive, metadata signed, deployed withdeploy-pages. No branch to maintain; the releases page stays the source of truth and this is a view of it.What is signed
The metadata, not the packages:
repomd.xmlandReleaseeach carry every package's SHA-256, so a signed index vouches for every file below it. That is how apt has always worked, and dnf verifies it withrepo_gpgcheck=1, which the shipped.repofile sets. It keeps the packages byte-for-byte the release assets, including releases made before this existed, sochecksums.txtstill describes them. The key's secret half is in the repository secrets (REPO_GPG_PRIVATE_KEY,REPO_GPG_PASSPHRASE, already set); the public half is exported into the site ascodavox.asc.Verified
Locally with a throwaway key, against the eight rpm and eight deb files of the four releases: dnf on Rocky 9 and apt on Debian 12 each imported the key, verified the metadata, installed a pinned
0.7.0, and upgraded to0.8.0. One finding on the way:apt-ftparchive's Tree mode indexed nothing from the pool, so the builder runs the per-architecture scan directly.Docs
README and installation.md install from the repository; installation.md keeps install-by-URL as the fallback for a host that cannot reach it, which is now the only place a
VERSION=line lives, so the release workflow's version check covers that file alone. CONTRIBUTING's release steps mention the Repository workflow.After merging
Run the Repository workflow once by hand (
gh workflow run repository.yml); Pages is already enabled for workflow deploys. Then the Puppet module can manage the repository instead of apackage_sourceURL, and the lab can drop its pinned asset.Assisted by Claude.