- docs/spec/release-packaging.md: decision-complete spec — compat matrix, Gitea 1.27.1 registry channel, nfpm toolchain, signing/key policy, release mechanics, package layout/ownership, maintainer-script contracts, initial config, make-install migration runbook. - docs/adr/0007: package delivery amends ADR 0004 (delivery/ownership only; runtime semantics inherited verbatim). 0004 status updated. - docs/research/: toolchain, gitea-registry, obs findings merged from research branches (assets of map tickets #34/#35/#36). - CONTEXT.md: Release + Rollback glossary terms (ticket #43).
8.3 KiB
Research: Gitea 1.27 Debian + RPM package registry feasibility
Issue: Fenris deb + rpm release plan →
Research: Gitea 1.27 Debian + RPM package registry feasibility
Verified 2026-09-03 against live instance https://git.bongbetic.com (reports 1.27.1 via /api/v1/version)
and primary sources: docs.gitea.com 1.27 Debian/RPM registry pages and Gitea v1.27.1 source (go-gitea/gitea tag).
Verdict: feasible. Every publish/consume path tested live with throwaway packages fenris-regtest (all deleted afterward; package list verified empty).
1. Publish paths (verified live, HTTP 201)
Debian (.deb)
curl --user xavierk:$TOKEN --upload-file fenris_0.3.0_amd64.deb \
"https://git.bongbetic.com/api/packages/xavierk/debian/pool/{distribution}/{component}/upload"
distributionandcomponentare free-form path segments chosen at upload time (e.g.bookworm/main,noble/main). Gitea derives apt suites from what was uploaded — verified: same .deb published topool/bookworm/mainandpool/noble/main(both 201), both then served indists/bookworm/anddists/noble/with correctSuite:/Codename:headers.- Republish of identical name+version+distribution+component+architecture → 409 Conflict (verified). Must delete first.
RPM (.rpm)
# no group (flat repo)
curl --user xavierk:$TOKEN --upload-file fenris-0.3.0-1.el9.x86_64.rpm \
"https://git.bongbetic.com/api/packages/xavierk/rpm/upload"
# with group (distro tag, nestable)
curl --user xavierk:$TOKEN --upload-file fenris-0.3.0-1.fc40.x86_64.rpm \
"https://git.bongbetic.com/api/packages/xavierk/rpm/el9/upload" # e.g. el9, rocky/el9, fc40
- Group = free-form nesting used to partition repos per distro/track. Verified: publish to root group and
el9group (both 201), duplicate → 409. - Owner can be the user (
xavierk) or an org; packages under a public owner are readable anonymously (verified: metadata fetches without auth succeeded).
2. Consumer setup (exact commands)
apt clients
sudo mkdir -p /etc/apt/keyrings
sudo curl -o /etc/apt/keyrings/gitea-xavierk.asc \
https://git.bongbetic.com/api/packages/xavierk/debian/repository.key
echo "deb [signed-by=/etc/apt/keyrings/gitea-xavierk.asc] https://git.bongbetic.com/api/packages/xavierk/debian bookworm main" \
| sudo tee /etc/apt/sources.list.d/gitea.list # one line per distribution
sudo apt update
apt install fenris # or fenris=0.3.0
# private owner variant: https://{user}:{token}@git.bongbetic.com/api/packages/... in the URL
dnf clients
sudo dnf config-manager --add-repo https://git.bongbetic.com/api/packages/xavierk/rpm/el9.repo
# private owner: add user:token into the baseurl inside /etc/yum.repos.d/gitea-xavierk-el9.repo afterwards
sudo dnf install fenris # or fenris-0.3.0
The served .repo (verified live) sets gpgcheck=1 and points gpgkey at …/rpm/repository.key, so dnf auto-imports on first use.
3. Metadata signing: native, not passthrough
Gitea signs generated metadata itself with per-instance auto-generated PGP keys. Client-side signing config is limited to trusting the served keys.
- Debian:
dists/{suite}/InReleaseis clearsigned;Release.gpgdetached sig also served. Key (RSA) fetched from…/debian/repository.key, uid literally(Automatically generated Debian Registry Key; created …). - RPM:
repodata/repomd.xml.ascdetached ASCII-armored signature, uid(RPM Registry). Key from…/rpm/repository.key. - Both verified with
gpg --verify→ Good signature (keys are self-generated; the "not certified" warning is expected and handled by the signed-by/keyring flow above). - The apt
Releasealso advertisesAcquire-By-Hash: yeswith MD5/SHA1/SHA256/SHA512 indexes ofPackages/.gz/.xz(verified live). RPM repomd carries sha256 checksums forprimary/filelists/other.xml.gz.
There is no bring-your-own-signing-key config for these registries in 1.27 — trust anchor is the instance's auto keys. For Fenris this is acceptable; TOFU over TLS via the key URLs above.
4. Multi-distro metadata
- Debian: distributions/suites are implicit — whatever
{distribution}path segments appear on upload becomedists/{distribution}/trees withSuite:/Codename:set to the segment. No server-side list to maintain; adding a new distro = upload with new segment + one moredeb …sources line. Components likewise (main, etc.). Architectures come from each.deb's control stanza (index served asdists/{dist}/{component}/binary-{arch}/Packages). - RPM: same via
{group}path segments (el9,rocky/el9, …); each group gets its ownrepodata/. Nobasearchfiltering — clients pick the group; Gitea publishes whatever RPM arch was uploaded.
5. Version retention
- Default: all versions retained indefinitely; nothing auto-deletes. Old versions stay installable (
apt install fenris=0.2.9,dnf install fenris-0.2.9). - Republishing an existing name+version (deb: same dist/component/arch; rpm: same file name in group) → 409; overwrite requires delete-then-upload.
- Optional cleanup rules exist (per owner + package type):
KeepCount,KeepPattern,RemoveDays,RemovePattern,MatchFullName(source:models/packages/package_cleanup_rule.go, executed by scheduledCleanupTaskinservices/packages/cleanup/cleanup.go). In 1.27.1 they are configurable only in the web UI (owner → Packages → Cleanup Rules); no v1 REST route (verified by route table grep ofrouters/api/v1/api.go— probes of/api/v1/packages/{owner}/cleanuprules…return 404/409-style errors). - Deletes: format-specific
DELETE …/debian/pool/{dist}/{component}/{name}/{version}/{arch}andDELETE …/rpm/{group}/package/{name}/{version}/{arch}(both verified, 204). Deleting last file removes the version. Generic fallback:DELETE /api/v1/packages/{owner}/{type}/{name}/{version}.
6. Release attachment: not supported
Gitea 1.27.1 has no package↔release linkage. Release assets (…/releases/{id}/assets) are standalone file uploads; the package model has no release field and no route links them (verified against v1.27.1 source: routers/api/v1/repo/release_attachment.go, models/packages/). Options for Fenris releases:
- Publish
.deb/.rpmto the registry (real apt/dnf install UX) and reference the registry URLs in release notes. - Additionally upload tarballs/SHA256SUMS as plain release attachments.
- Generic registry (
PUT /api/packages/{owner}/generic/{name}/{version}/{filename}) if an untyped artifact store is needed.
7. Caveats for the release plan
- Owner choice matters: publish under an org (e.g.
fenris) if multiple maintainers need write;xavierkuser owner works today (token owner is admin). - Metadata access follows owner visibility — public owner → anonymous consumers, no token in URLs (current state, verified). Keep owner public for frictionless installs, or embed
user:tokenin sources/baseurl. - apt distro naming should match OS release names (
bookworm,trixie,noble) purely for client convention; server accepts anything. - RPM groups should mirror
$distver(e.g.el9,fc40) so.reposelection is obvious per target.
8. Test log (live, 2026-09-03)
| Step | Result |
|---|---|
PUT debian/pool/bookworm/main/upload |
201 |
PUT debian/pool/noble/main/upload (multi-dist) |
201 |
PUT debian duplicate |
409 (expected) |
PUT rpm/upload (no group) |
201 |
PUT rpm/el9/upload (group) |
201 |
PUT rpm duplicate |
409 (expected) |
GET debian/repository.key / rpm/repository.key |
PGP public keys (200) |
GET dists/bookworm/{Release,InRelease,Packages} |
correct; gpg --verify Good signature |
GET rpm{,/el9}/repodata/repomd.xml{,.asc} |
200; Good signature |
GET rpm{,/el9}.repo |
generated repo files with gpgcheck=1 |
| Cleanup-rules REST probes | 404 (not in v1 API — UI only) |
DELETE all four test entries |
204 ×4; package list then empty |
Sources: docs.gitea.com 1.27 Debian registry, docs.gitea.com 1.27 RPM registry, Gitea source tag v1.27.1 (routers/api/v1/api.go, models/packages/package_cleanup_rule.go, services/packages/cleanup/cleanup.go), live instance git.bongbetic.com.