Upgrade Forgejo from 15 LTS to 16.0.1 #620
Labels
No labels
burndown-2026-06
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/infrastructure#620
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Infrastructure upgrades the Forgejo deployment from the pinned
15.0.2-rootlessimage to16.0.1-rootless. The upgrade unlocks native Actions run cancellation, Authorized Integrations, workflow and job log APIs, and Actions artifact APIs.Decision boundary
Forgejo 16 is a non-LTS release supported through 2026-10-29. Forgejo 15 LTS is supported through 2027-07-15. Kai accepts the shorter upgrade cadence, or the operator records a decision to remain on 15 and defers the linked adoption work. Infrastructure pins an exact patch release rather than a floating major tag.
Work
Done
The rollback path this upgrade depends on is now tested for the database.
A restore drill ran on ser8 today against snapshot
0db62842: the Forgejopg_dumpextracts in 1 second and loads into a clean PostgreSQL 17 in 8 seconds, producing 128 tables whose row counts match the live database exactly on stable tables and differ only by ordinary activity on growing ones. Full method, timing, and fidelity table are recorded on #599.That closes the specific risk raised on #790: Forgejo 16 runs irreversible schema migrations, so rolling the image back does not roll the database back, and the only real rollback is restoring the snapshot. That restore is no longer untested.
Still true and worth stating plainly: the drill covered the database only. The PVC payload, about 95.8 GiB across
forgejo-data,forgejo-db-data,registry-data, andcode-fleet-watch-state, has still never been restore-tested.Recommended sequence before applying #790 remains: take a fresh backup rather than relying on the nightly, then apply, then validate.
Applied 2026-08-12, verified
16.0.2-rootlessis live. Applied 04:32:01Z, pod Ready 04:33:08Z, so 43seconds of downtime on the
Recreatestrategy.Migrations
Clean.
v16b_add-login-source-id-to-forgejo-auth-token,v16b_add_comment_line_count,v16b_authorized_integration_name_description,v16c_action_run_priority,v16c_add_team_invite_invited_id,v16c_authorized_integration_ui,v16c_cleanup_package_blob_indexes,v16d_action_run_warnings, andv16e_add-granular-watchall applied, followedby a dangling
sha256:*image cleanup. No error, fatal, or panic in thestartup log.
Verified
16.0.2+gitea-1.22.0.completed successfully since the upgrade.
synced=31with nofailures.
OAuth login was not verified. Kai confirms it is no longer used, so it is not a
gap.
The reason for the upgrade works
Both endpoints that 15 had no route for now answer:
CI failures are diagnosable from the API. That resolves issue 786 and unblocks
issues 621 and 622.
Trusted proxy
FORGEJO__security__REVERSE_PROXY_TRUSTED_PROXIESwas set to the pod CIDR inthe same change, so the removal of the image default
REVERSE_PROXY_TRUSTED_PROXIES = *in Forgejo 16 did not silently dropTraefik's forwarded headers.
Backup deviation, stated plainly
The planned pre-upgrade restic run did not happen. The agent has no
passwordless sudo on kai-server, so
systemctl start restic-backup.servicewasnot available.
Substituted: a fresh
pg_dump -Fctaken throughkubectl exec, 30 seconds,65 MiB, copied off-host to ser8 at
/var/tmp/forgejo-preupgrade-20260812.pgdumpand verified to parse to 128TABLE DATAentries, matching the restore drill recorded on issue 599.That is the material a schema-migration rollback needs, since migrations touch
the database and not the PVC payload, which last night's snapshot still covers.
It is a narrower safety net than planned and the deviation is recorded rather
than absorbed.
Residual, non-blocking
Five peripheral errors in the first thirty minutes, none migration or
data-related:
GetDiffbroken pipe onward.git, a render aborted by a closedconnection
Failed to create commit status for job 27537: head commit is missing in event payloadThe commit-status one is the only one with functional effect, and only for that
job. Worth a glance if it recurs on ordinary push events.
Follow-up found during verification
aosguard ops forgejo action-job logsfails withinvalid character '-' after top-level value. It JSON-parses a plaintext response. Forgejo serves theendpoint correctly, so this is a client-side fix in the guardfile or its
response handling.