wishlist: retention cleanup for Forgejo package registries (deb/rpm) ai:claude-opus-5-5 #88

Closed
opened 2026-10-17 10:39:32 +02:00 by heiko · 1 comment
Owner

Wishlist: apply the release retention policy (cleanupOldReleases, see gogogo(7) RETENTION POLICY) to the Forgejo package registries (Debian, optionally RPM), without duplicating the policy code.

Idea

  • Extract the pure, API-free decision into e.g. internal/retention:
    Decide(newest string, items []Item) Plan{Prune, Delete} — keep the 2 newest of the same kind (semver order), prune the rest; on a full release delete older pre-releases.
  • Adapters:
    • releases: Prune = DeleteAttachments, Delete = DeleteRelease + DeleteTag (refactor existing code onto Decide)
    • deb/rpm registry: Prune = Delete = delete package version
  • Deb → semver inverse of debUpstream: strip -N revision, ~ → -, prefix v (unambiguous; semver has no ~). Group by upstream; also drop older revisions of the current upstream.

Forgejo API (verified on 17.0.0+gitea-1.22.0)

  • list: GET /api/v1/packages/{owner}?type=debian&q=<name> (paginated; name, version, repository)
  • delete version (all dists/comps/arches): DELETE /api/v1/packages/{owner}/{type}/{name}/{version}
  • delete single deb file: DELETE /api/packages/{owner}/debian/pool/{dist}/{comp}/{name}/{version}/{arch}
  • .../{version}/files does NOT expose distribution/component.
  • Server-side cleanup rules (incl. new last-download criterion, forgejo#14220) have no API.

Concerns / open points

  • Registry is per owner, not per repo: restrict to package names built by this project and linked to this repo.
  • Whole-version delete hits all suites (incl. manually copied ones); per-file delete must trust the configured suites.
  • Irreversible; breaks reinstall/downgrade of pruned versions. Must be opt-in and honour --dry-run.
  • Keep publish.API additions minimal (ListPackages, DeletePackageVersion); share only the policy, not a generic "versioned thing" interface.
  • Alternative without code: Forgejo server-side cleanup rules (keep pattern for stable ^[0-9.]+-[0-9]+$, keep count, last-download age). Cannot express "full release supersedes older pre-releases" by semver. Evaluate first.

(co)authored by ai:claude-opus-5-5

Wishlist: apply the release retention policy (`cleanupOldReleases`, see gogogo(7) RETENTION POLICY) to the Forgejo package registries (Debian, optionally RPM), without duplicating the policy code. ## Idea - Extract the pure, API-free decision into e.g. `internal/retention`: `Decide(newest string, items []Item) Plan{Prune, Delete}` — keep the 2 newest of the same kind (semver order), prune the rest; on a full release delete older pre-releases. - Adapters: - releases: Prune = `DeleteAttachments`, Delete = `DeleteRelease` + `DeleteTag` (refactor existing code onto `Decide`) - deb/rpm registry: Prune = Delete = delete package version - Deb → semver inverse of `debUpstream`: strip `-N` revision, `~` → `-`, prefix `v` (unambiguous; semver has no `~`). Group by upstream; also drop older revisions of the current upstream. ## Forgejo API (verified on 17.0.0+gitea-1.22.0) - list: `GET /api/v1/packages/{owner}?type=debian&q=<name>` (paginated; `name`, `version`, `repository`) - delete version (all dists/comps/arches): `DELETE /api/v1/packages/{owner}/{type}/{name}/{version}` - delete single deb file: `DELETE /api/packages/{owner}/debian/pool/{dist}/{comp}/{name}/{version}/{arch}` - `.../{version}/files` does NOT expose distribution/component. - Server-side cleanup rules (incl. new last-download criterion, forgejo#14220) have no API. ## Concerns / open points - Registry is per owner, not per repo: restrict to package names built by this project and linked to this repo. - Whole-version delete hits all suites (incl. manually copied ones); per-file delete must trust the configured suites. - Irreversible; breaks reinstall/downgrade of pruned versions. Must be opt-in and honour `--dry-run`. - Keep `publish.API` additions minimal (`ListPackages`, `DeletePackageVersion`); share only the policy, not a generic "versioned thing" interface. - Alternative without code: Forgejo server-side cleanup rules (keep pattern for stable `^[0-9.]+-[0-9]+$`, keep count, last-download age). Cannot express "full release supersedes older pre-releases" by semver. Evaluate first. (co)authored by ai:claude-opus-5-5
heiko added reference master 2026-10-17 11:04:04 +02:00
Author
Owner

Decisions:

  • Scope: only package names built and published by this project. No repository-link check.
  • Delete granularity: the whole version (DELETE /api/v1/packages/{owner}/{type}/{name}/{version}). gogogo is treated as the manager of the registry. Losing reinstall/downgrade of pruned versions is accepted.
  • Policy: the same as for releases (gogogo(7) RETENTION POLICY). It moves into a pure internal/retention.Decide, and cleanupOldReleases is refactored onto it. New guard: the version being published is never pruned.
  • Formats: deb and RPM.
    • deb → semver: a trailing all-digit -N is the revision, otherwise the version is native. Then ~ → - and prefix v.
    • RPM: the Forgejo version is <Version>-<Release> (no epoch, since gogogo uses NoEpoch). Release is N for full releases and 0.N.<pre> for pre-releases.
    • Only the newest revision of each upstream version is kept. Unparseable versions are never deleted.
  • Only forgejo-packages destinations; the dupload path is untouched.
  • Opt-out: publish.retention (default true), overridden by publish.destinations.<name>.retention. Setting it on a dupload destination is a validation error.
  • Server-side cleanup rules: evaluated, not flexible enough. Dropped.

Verified on forgejo.schlittermann.de (17.0.0+gitea-1.22.0): debian versions look like 0.28.0-1 and 0.0.2~0.20261014125915~c4924cc3feb8. The RPM version format comes from Forgejo v17.0.0 modules/packages/rpm/metadata.go; it has not been observed live because the RPM registry is still empty.

Work happens on branch feat/pkg-retention.

(co)authored by ai:claude-opus-5-5

Decisions: - **Scope:** only package names built and published by this project. No repository-link check. - **Delete granularity:** the whole version (`DELETE /api/v1/packages/{owner}/{type}/{name}/{version}`). gogogo is treated as the manager of the registry. Losing reinstall/downgrade of pruned versions is accepted. - **Policy:** the same as for releases (gogogo(7) RETENTION POLICY). It moves into a pure `internal/retention.Decide`, and `cleanupOldReleases` is refactored onto it. New guard: the version being published is never pruned. - **Formats:** deb and RPM. - deb → semver: a trailing all-digit `-N` is the revision, otherwise the version is native. Then `~` → `-` and prefix `v`. - RPM: the Forgejo version is `<Version>-<Release>` (no epoch, since gogogo uses NoEpoch). `Release` is `N` for full releases and `0.N.<pre>` for pre-releases. - Only the newest revision of each upstream version is kept. Unparseable versions are never deleted. - **Only `forgejo-packages` destinations;** the dupload path is untouched. - **Opt-out:** `publish.retention` (default `true`), overridden by `publish.destinations.<name>.retention`. Setting it on a dupload destination is a validation error. - **Server-side cleanup rules:** evaluated, not flexible enough. Dropped. Verified on forgejo.schlittermann.de (17.0.0+gitea-1.22.0): debian versions look like `0.28.0-1` and `0.0.2~0.20261014125915~c4924cc3feb8`. The RPM version format comes from Forgejo v17.0.0 `modules/packages/rpm/metadata.go`; it has not been observed live because the RPM registry is still empty. Work happens on branch `feat/pkg-retention`. (co)authored by ai:claude-opus-5-5
heiko closed this issue 2026-10-17 12:57:53 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
heiko/gogogo#88
No description provided.