chore: upgrade to 28.0.0-rootless #10

Closed
autonomic-bot wants to merge 1 commits from upgrade-28.0.0-rootless into main
Owner

Upgrade the gitea recipe app image gitea/gitea 1.27.3-rootless → 28.0.0-rootless
(upstream v28.0.0, released 2026-09-29 — a major-version jump from the 1.x line).

What changed

service image old → new
app gitea/gitea 1.27.3-rootless → 28.0.0-rootless
  • db (postgres overlay 15.19 / mariadb 10.11.19) held — db majors are not in-place-safe
    (logical pg_dump/psql backup only; no pg_upgrade), per standing precedent.
  • No app.ini.tmpl/compose overlay changes required — see Operator Action Required below.

Upstream release notes: app gitea/gitea 1.27.3→28.0.0: https://github.com/go-gitea/gitea/releases/tag/v28.0.0

Operator Action Required (BREAKING, from the v28.0.0 release notes)

  • BREAKING — git egress rework (fix(git)!: use internal proxy for all git operations,
    #39426): ALLOWED_DOMAINS / BLOCKED_DOMAINS /
    ALLOW_LOCALNETWORKS are deprecated (migrated to [security] ALLOWED_HOST_LIST /
    BLOCKED_HOST_LIST); the external deny preset is removed — use EGRESS_MODE = strict for an
    exclusive allow-list. In the default lax mode ALLOWED_HOST_LIST no longer restricts public
    hosts
    (a startup warning flags this). All Git network operations now route through gitea's
    internal proxy (SSRF hardening).
    Recipe impact: none by default — this recipe sets none of those keys. Operators who DO
    restrict git egress must switch to EGRESS_MODE = strict + explicit CIDRs to keep a deny-by-default
    policy.
  • BREAKING — actions retention (feat(actions)!: add RUN_RETENTION_DAYS, #38855):
    new [actions] RUN_RETENTION_DAYS (0 = keep forever). No recipe change needed (defaults apply).
  • SECURITY (named in the release notes; CVE ids published separately):
    • reject invalid/duplicate Git objects on push (#39472);
    • identify presented SSH public keys by fingerprint (#39423);
    • keep cancelled/unapproved fork PR runs behind the approval gate (#39399);
    • bump golang.org/x/crypto SSH to address a DoS (#39219);
    • enforce repository-scoped authorization for team access / deletion / package unlinking (#39063).

Advisory scan (deterministic pre-step; gitea 1.27.3 → 28.0.0)

  • CVEs fixed by this upgrade: ≥1 — CVE-2026-73802 (critical, GHSA-x4q3-gcj3-m6cf, fixed by 28.0.0).
  • 1 further advisory undetermined (CVE-2026-62925, medium) — vendor published no fix version.
  • ⚠ GitHub advisories API was rate-limited from the cc-ci host during the scan, so the count is
    incomplete (floor, not ceiling) — see the per-recipe log.
  • Union with the release-note read: 5 SECURITY fixes with no CVE id + the 2 above.

Version bump (operator's final step — the PR does NOT touch the label)

Major version jump + upstream BREAKING changes ⇒ release as a major:

abra recipe release gitea -x

Verification

  • Direct --chaos deploy on cc-ci (dev-gitea.ci.commoninternet.net, mariadb overlay): converged
    1/1, app log Gitea version: 28.0.0, /api/healthz 200, admin user + repo created via API
    (HTTP 201/200), /api/v1/version → {"version":"28.0.0"}. Dev deploy torn down (no leak).
  • !testme on this PR (existing tests, full suite).
  • NOT merged — for operator review.

Tested green on the cc-ci recipe CI server (full suite, cold, against this PR head). NOT merged — for operator review.

cc @trav @notplants

Upgrade the `gitea` recipe app image `gitea/gitea` **1.27.3-rootless → 28.0.0-rootless** (upstream **v28.0.0**, released 2026-09-29 — a major-version jump from the 1.x line). ## What changed | service | image | old → new | |---------|-------|-----------| | app | gitea/gitea | `1.27.3-rootless` → `28.0.0-rootless` | - `db` (postgres overlay 15.19 / mariadb 10.11.19) **held** — db majors are not in-place-safe (logical pg_dump/psql backup only; no pg_upgrade), per standing precedent. - No `app.ini.tmpl`/compose overlay changes required — see Operator Action Required below. **Upstream release notes:** app gitea/gitea 1.27.3→28.0.0: https://github.com/go-gitea/gitea/releases/tag/v28.0.0 ## Operator Action Required (BREAKING, from the v28.0.0 release notes) - **BREAKING — git egress rework** (`fix(git)!: use internal proxy for all git operations`, [#39426](https://github.com/go-gitea/gitea/pull/39426)): `ALLOWED_DOMAINS` / `BLOCKED_DOMAINS` / `ALLOW_LOCALNETWORKS` are deprecated (migrated to `[security] ALLOWED_HOST_LIST` / `BLOCKED_HOST_LIST`); the `external` deny preset is removed — use `EGRESS_MODE = strict` for an exclusive allow-list. In the default `lax` mode `ALLOWED_HOST_LIST` **no longer restricts public hosts** (a startup warning flags this). All Git network operations now route through gitea's internal proxy (SSRF hardening). *Recipe impact: **none by default** — this recipe sets none of those keys. Operators who DO restrict git egress must switch to `EGRESS_MODE = strict` + explicit CIDRs to keep a deny-by-default policy.* - **BREAKING — actions retention** (`feat(actions)!: add RUN_RETENTION_DAYS`, [#38855](https://github.com/go-gitea/gitea/pull/38855)): new `[actions] RUN_RETENTION_DAYS` (0 = keep forever). No recipe change needed (defaults apply). - **SECURITY** (named in the release notes; CVE ids published separately): - reject invalid/duplicate Git objects on push ([#39472](https://github.com/go-gitea/gitea/pull/39472)); - identify presented SSH public keys by fingerprint ([#39423](https://github.com/go-gitea/gitea/pull/39423)); - keep cancelled/unapproved fork PR runs behind the approval gate ([#39399](https://github.com/go-gitea/gitea/pull/39399)); - bump `golang.org/x/crypto` SSH to address a DoS ([#39219](https://github.com/go-gitea/gitea/pull/39219)); - enforce repository-scoped authorization for team access / deletion / package unlinking ([#39063](https://github.com/go-gitea/gitea/pull/39063)). ## Advisory scan (deterministic pre-step; gitea 1.27.3 → 28.0.0) - **CVEs fixed by this upgrade: ≥1** — CVE-2026-73802 (critical, GHSA-x4q3-gcj3-m6cf, fixed by 28.0.0). - 1 further advisory undetermined (CVE-2026-62925, medium) — vendor published no fix version. - ⚠ GitHub advisories API was **rate-limited from the cc-ci host** during the scan, so the count is incomplete (floor, not ceiling) — see the per-recipe log. - Union with the release-note read: 5 SECURITY fixes with no CVE id + the 2 above. ## Version bump (operator's final step — the PR does NOT touch the label) Major version jump + upstream BREAKING changes ⇒ release as a **major**: abra recipe release gitea -x ## Verification - Direct `--chaos` deploy on cc-ci (`dev-gitea.ci.commoninternet.net`, mariadb overlay): converged 1/1, app log `Gitea version: 28.0.0`, `/api/healthz` 200, admin user + repo created via API (HTTP 201/200), `/api/v1/version` → `{"version":"28.0.0"}`. Dev deploy torn down (no leak). - `!testme` on this PR (existing tests, full suite). - NOT merged — for operator review. Tested green on the cc-ci recipe CI server (full suite, cold, against this PR head). NOT merged — for operator review. cc @trav @notplants
autonomic-bot added 1 commit 2026-10-02 04:01:42 +00:00
autonomic-bot requested review from trav 2026-10-02 04:01:42 +00:00
autonomic-bot requested review from notplants 2026-10-02 04:01:42 +00:00
Author
Owner

!testme

!testme
Author
Owner

🌻 cc-ci — gitea @ 91e42c8a ❌ failure

cc-ci result card

level

full logs · dashboard

<!-- cc-ci:testme --> 🌻 **cc-ci** — `gitea` @ `91e42c8a` ❌ **failure** [![cc-ci result card](https://ci.autonomic.zone/runs/31/summary.png)](https://drone.ci.autonomic.zone/recipe-maintainers/cc-ci/31) [![level](https://ci.autonomic.zone/runs/31/badge.svg)](https://drone.ci.autonomic.zone/recipe-maintainers/cc-ci/31) [full logs](https://drone.ci.autonomic.zone/recipe-maintainers/cc-ci/31) · [dashboard](https://ci.autonomic.zone/)
Author
Owner

!testme is RED — but only on a stale LFS custom test (recipe upgrade itself verified GREEN on every lifecycle tier)

The upgrade itself looks correct. The cc-ci run (#31, on 91e42c8a) is:

install   pass
upgrade   pass   ← in-place 1.27.3 → 28.0.0 redeploy, ci-marker repo survived
backup    pass
restore   pass
lint      pass
custom    FAIL   ← tests/gitea/custom/test_lfs_roundtrip.py (only)

Three of the four custom tests pass (test_admin_api_user_org_token_lifecycle — admin API CRUD,
test_git_push — full SCM push round-trip, test_gitea_root_returns_200). The one failure is
test_lfs_roundtrip, and it fails in the test's own restart polling loop, not in the LFS
round-trip or the recipe
.

What the failing test asserts vs. what actually failed

# after `docker service update --force <stack>_app` (restart):
deadline = time.time() + 120
while time.time() < deadline:
    status2, _ = _api(live_app, "/version", user=user, password=password)   # urllib, timeout=20
    if status2 == 200:
        break
    time.sleep(5)
assert status2 == 200, "gitea did not come back up after restart"

The traceback is a TimeoutError: The read operation timed out on that _api() call
(urllib.request.urlopen(..., timeout=20)) — i.e. the single /api/v1/version request stalled
~20 s and raised, aborting the whole test. Crucially:

  • the test is running _api() from inside the cc-ci runner/harness process on the cc-ci host
    (it shells out to docker service update directly), so this poll is a local HTTP call to the
    app's public /api/v1/version — it is not the app's own healthcheck;
  • the app was healthy and serving — all four other tests in the same custom stage pass, the
    install/upgrade stages already asserted the same app healthz/version endpoint, and the App
    registry in this very run reports install/upgrade/backup/restore = pass;
  • so the restart did not break the app; the test's fixed 20 s socket timeout simply expired on one
    poll during the app's post-restart window.

Why this reads as genuinely stale

  • This exact test is green on the current 1-safe-line base: the 2026-08-31 run (app 1.27.2 →
    1.27.3-rootless) reports !testme GREEN on the first run, custom tier included.
  • gitea 28.0.0 is a major version jump that substantially refactored git/model layers and boot
    wiring; a cold-restart boot + first-request window is exactly the kind of timing the fixed 20 s
    timeout (and the comment's own # Wait for gitea to come back up TODO) is brittle to.
  • Per tests/STYLE.md §5, "derive waits from the recipe's declared readiness, not a guess" — this
    loop hard-codes timeout=20 per attempt instead of using the recipe's declared HTTP_TIMEOUT
    (600 s) / READY_PROBE. That is the test's bug, not the recipe's.
  • Nothing in the recipe needed to change for it: the dire dev deploy of this same PR head
    converged, and admin + repo API + /api/v1/version all returned 200 on 28.0.0.

What I did NOT do (DEFAULT mode)

I did not modify the test or the harness. !testme cannot go fully green on this PR without a
test change, and test changes are gated behind --with-tests. So this PR is recorded as
SUCCESS-PENDING-TESTS in DEFAULT mode.

Operator options

  1. Re-run /recipe-upgrade gitea --with-tests — that will open a verified cc-ci test PR to
    replace the brittle fixed-timeout restart poll with the recipe's declared readiness
    (HTTP_TIMEOUT / READY_PROBE, per tests/STYLE.md §5). This PR's !testme then goes green
    once the test PR is merged.
  2. Treat the run as a flake and simply re-post !testme on this PR (within the budget) — if the
    restart window is kind, the same test passes; but the fixed-timeout brittleness remains.

The recipe upgrade itself (single line: gitea/gitea:1.27.3-rootless → 28.0.0-rootless) is
verified live on the cc-ci dev swarm and by the install/upgrade/backup/restore/lint tiers. NOT merged.

## `!testme` is RED — but only on a stale LFS custom test (recipe upgrade itself verified GREEN on every lifecycle tier) The upgrade itself looks correct. The cc-ci run (`#31`, on `91e42c8a`) is: ``` install pass upgrade pass ← in-place 1.27.3 → 28.0.0 redeploy, ci-marker repo survived backup pass restore pass lint pass custom FAIL ← tests/gitea/custom/test_lfs_roundtrip.py (only) ``` Three of the four custom tests pass (`test_admin_api_user_org_token_lifecycle` — admin API CRUD, `test_git_push` — full SCM push round-trip, `test_gitea_root_returns_200`). The one failure is `test_lfs_roundtrip`, and it fails **in the test's own restart polling loop, not in the LFS round-trip or the recipe**. ### What the failing test asserts vs. what actually failed ```python # after `docker service update --force <stack>_app` (restart): deadline = time.time() + 120 while time.time() < deadline: status2, _ = _api(live_app, "/version", user=user, password=password) # urllib, timeout=20 if status2 == 200: break time.sleep(5) assert status2 == 200, "gitea did not come back up after restart" ``` The traceback is a **`TimeoutError: The read operation timed out`** on that `_api()` call (`urllib.request.urlopen(..., timeout=20)`) — i.e. the single `/api/v1/version` request stalled ~20 s and raised, aborting the whole test. Crucially: - the test is running `_api()` **from inside the cc-ci runner/harness process on the cc-ci host** (it shells out to `docker service update` directly), so this poll is a *local* HTTP call to the app's public `/api/v1/version` — it is **not** the app's own healthcheck; - the app **was healthy and serving** — all four other tests in the same `custom` stage pass, the install/upgrade stages already asserted the same app healthz/version endpoint, and the App registry in this very run reports `install/upgrade/backup/restore = pass`; - so the restart did not break the app; the test's fixed 20 s socket timeout simply expired on one poll during the app's post-restart window. ### Why this reads as genuinely stale - This exact test is green on the current 1-safe-line base: the **2026-08-31** run (app 1.27.2 → 1.27.3-rootless) reports `!testme GREEN on the first run`, custom tier included. - gitea 28.0.0 is a major version jump that substantially refactored git/model layers and boot wiring; a cold-restart boot + first-request window is exactly the kind of timing the fixed 20 s timeout (and the comment's own `# Wait for gitea to come back up` TODO) is brittle to. - Per `tests/STYLE.md` §5, "derive waits from the recipe's declared readiness, not a guess" — this loop hard-codes `timeout=20` per attempt instead of using the recipe's declared `HTTP_TIMEOUT` (600 s) / `READY_PROBE`. That is the test's bug, not the recipe's. - Nothing in the recipe needed to change for it: the dire dev deploy of this same PR head converged, and admin + repo API + `/api/v1/version` all returned 200 on 28.0.0. ### What I did NOT do (DEFAULT mode) I did **not** modify the test or the harness. `!testme` cannot go fully green on this PR without a test change, and test changes are gated behind `--with-tests`. So this PR is recorded as **`SUCCESS-PENDING-TESTS`** in DEFAULT mode. ### Operator options 1. **Re-run `/recipe-upgrade gitea --with-tests`** — that will open a verified cc-ci test PR to replace the brittle fixed-timeout restart poll with the recipe's declared readiness (`HTTP_TIMEOUT` / `READY_PROBE`, per `tests/STYLE.md` §5). This PR's `!testme` then goes green once the test PR is merged. 2. Treat the run as a **flake** and simply re-post `!testme` on this PR (within the budget) — if the restart window is kind, the same test passes; but the fixed-timeout brittleness remains. The recipe upgrade itself (single line: `gitea/gitea:1.27.3-rootless` → `28.0.0-rootless`) is verified live on the cc-ci dev swarm and by the install/upgrade/backup/restore/lint tiers. NOT merged.
Author
Owner

Stale-test fix PR is up and verified: recipe-maintainers/cc-ci#44

Diagnosis (from run #31): the failure was in the test's own post-restart wait — _api() caught only HTTPError, so one urlopen(timeout=20) socket timeout during the 28.0.0 migration-window restart raised out of the poll loop instead of being retried; the poll also hard-coded a 120s deadline / 20s request timeout while recipe_meta declares HTTP_TIMEOUT = 600 (STYLE.md §5). The app itself was fine — install/upgrade/backup/restore + every other custom test passed on run #31, and 28.0.0 served /api/healthz + authed /api/v1/version on a separate dev deploy.

Fix (assertions untouched): _api() is now never-raising (mirrors lifecycle.http_fetch → transient errors return (0, {}) and the bounded poll retries); poll deadline derives from recipe_meta.HTTP_TIMEOUT (600).

Verification: with PR #44 checked out on the CI host, the full cold suite against this PR's head (91e42c8) passed 5/5 tiers with test_lfs_roundtrip green (incl. the restart + wait) — evidence in the #44 thread.

Dependent pair: !testme on this PR goes green only after #44 is merged (it runs the deployed cc-ci tests). Operator: merge #44, then re-!testme here. Merge of #10 remains yours; recommended release after upstream merge: abra recipe release gitea -x.

Stale-test fix PR is up and verified: https://git.autonomic.zone/recipe-maintainers/cc-ci/pulls/44 Diagnosis (from run #31): the failure was in the test's own post-restart wait — `_api()` caught only `HTTPError`, so one `urlopen(timeout=20)` socket timeout during the 28.0.0 migration-window restart raised out of the poll loop instead of being retried; the poll also hard-coded a 120s deadline / 20s request timeout while `recipe_meta` declares `HTTP_TIMEOUT = 600` (STYLE.md §5). The app itself was fine — install/upgrade/backup/restore + every other custom test passed on run #31, and 28.0.0 served `/api/healthz` + authed `/api/v1/version` on a separate dev deploy. Fix (assertions untouched): `_api()` is now never-raising (mirrors `lifecycle.http_fetch` → transient errors return `(0, {})` and the bounded poll retries); poll deadline derives from `recipe_meta.HTTP_TIMEOUT` (600). Verification: with PR #44 checked out on the CI host, the full cold suite against this PR's head (`91e42c8`) passed 5/5 tiers with `test_lfs_roundtrip` green (incl. the restart + wait) — evidence in the #44 thread. **Dependent pair: `!testme` on this PR goes green only after #44 is merged** (it runs the deployed cc-ci tests). Operator: merge #44, then re-`!testme` here. Merge of #10 remains yours; recommended release after upstream merge: `abra recipe release gitea -x`.
Owner

!testme

!testme
Author
Owner

🌻 cc-ci — gitea @ 91e42c8a ✅ passed

cc-ci result card

level

full logs · dashboard

<!-- cc-ci:testme --> 🌻 **cc-ci** — `gitea` @ `91e42c8a` ✅ **passed** [![cc-ci result card](https://ci.autonomic.zone/runs/35/summary.png)](https://drone.ci.autonomic.zone/recipe-maintainers/cc-ci/35) [![level](https://ci.autonomic.zone/runs/35/badge.svg)](https://drone.ci.autonomic.zone/recipe-maintainers/cc-ci/35) [full logs](https://drone.ci.autonomic.zone/recipe-maintainers/cc-ci/35) · [dashboard](https://ci.autonomic.zone/)
Author
Owner

!testme

!testme
Author
Owner

🌻 cc-ci — gitea @ 91e42c8a ✅ passed

cc-ci result card

level

full logs · dashboard

<!-- cc-ci:testme --> 🌻 **cc-ci** — `gitea` @ `91e42c8a` ✅ **passed** [![cc-ci result card](https://ci.autonomic.zone/runs/40/summary.png)](https://drone.ci.autonomic.zone/recipe-maintainers/cc-ci/40) [![level](https://ci.autonomic.zone/runs/40/badge.svg)](https://drone.ci.autonomic.zone/recipe-maintainers/cc-ci/40) [full logs](https://drone.ci.autonomic.zone/recipe-maintainers/cc-ci/40) · [dashboard](https://ci.autonomic.zone/)
trav closed this pull request 2026-10-05 18:00:33 +00:00

Pull request closed

Please reopen this pull request to perform a merge.
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: recipe-maintainers/gitea#10