Drop the Renovate workflow: the Gitea side already has a shared instance

A measurement overtook this part of the change. A shared `jlab-renovate-bot`
instance already runs on the Gitea side and already has this repository
enrolled - its first run there opened PRs for searxng and gotenberg plus the
dependency dashboard. A second runner in this repo would produce duplicate
PRs and two schedulers rewriting each other's branches, so
.github/workflows/renovate.yml is removed again.

Two things fall out of that run, and both were open risks:

- The instance reads our renovate.json5. searxng and gotenberg are
  customManagers targets of ours - no built-in manager finds an appVersion
  in a Chart.yaml - so the config is demonstrably in effect.

- allowedCommands is already granted there. The searxng PR's diff carries
  `version: 1.0.4+up2026.9.11.ffe96f8a6 -> 1.0.5+up2026.9.13.96479fff6`
  next to the appVersion, and nothing but ci/renovate-bump-chart.sh writes
  `version:`. Had that allow-list been missing, postUpgradeTasks would have
  been skipped SILENTLY and every chart PR on Gitea would have been red on
  the version check with nothing naming the cause.

With the workflow gone there is no container image to pin either; verified
by dry run that the ghcr.io/renovatebot/renovate dependency is no longer
extracted, while TRIVY_VERSION still is - that one belongs to the Trivy
replacement and stays.

README and CLAUDE.md now say Renovate runs on Gitea as an existing shared
instance and that no workflow belongs here, so the next reader who finds
none knows why instead of building one.
This commit is contained in:
jklein committed 2026-09-16 15:49:36 +02:00
1 parent a6c27ebef3
commit c3889a66b6
4 files changed
+17 -117

No files matched your search

-108
View File
@@ -1,108 +0,0 @@
# Renovate, self-hosted (issue #225).
#
# On github.com Renovate arrived as the `jlab-renovate` GitHub App and this
# repo only ever carried renovate.json5. Gitea has no app model and no hosted
# Renovate, so after the move the bot has to be *run* by this repo: a scheduled
# job with its own token. That is the only change to how dependencies are
# updated - renovate.json5 stays the single source of what gets updated, and
# everything in it works unchanged on the Gitea platform.
#
# What the maintainer has to create once on the instance (the token this
# workflow cannot create for itself):
#
# RENOVATE_TOKEN Gitea access token of the bot account, scopes
# read:user, write:issue, write:repository. Renovate opens
# the PRs and the dependency dashboard issue with it, so
# the PRs will be authored by whoever owns the token.
# GITHUB_COM_TOKEN Read-only github.com PAT (public_repo / no scopes at all
# is enough). NOT optional here: every `github-releases` and
# `github-tags` lookup in renovate.json5 - and the whole
# built-in github-actions manager, which resolves
# actions/checkout and friends on github.com - hits
# github.com's unauthenticated rate limit within one run
# otherwise. On the App this came for free; here it does not.
# README already names this for the `no-result` symptom.
#
# There is deliberately no `allowedCommands` to set up by hand any more: the
# postUpgradeTasks hook renovate.json5 needs (ci/renovate-bump-chart.sh, which
# recomputes `version:` after an appVersion change) is allow-listed by the
# RENOVATE_ALLOWED_COMMANDS env below, because this workflow *is* the instance
# config now. Without it Renovate skips the task silently and every chart PR
# stays red on the version-bump check - see README, "The version-bump hook".
name: Renovate
on:
schedule:
# 03:40 UTC, once a day. Renovate's own `timezone` in renovate.json5
# (Europe/Berlin) governs the PR schedules; this cron is plain UTC.
- cron: "40 3 * * *"
workflow_dispatch:
inputs:
dryRun:
description: "Dry run: 'full' looks up and renders everything but writes nothing"
type: choice
default: "full"
options: ["full", "lookup", "extract", "disabled"]
logLevel:
description: "Renovate log level"
type: choice
default: "info"
options: ["info", "debug"]
jobs:
renovate:
name: Renovate
# The guard that keeps this workflow inert on github.com. The file reaches
# GitHub as well (that is where the migration PR is merged), and a
# scheduled run there would authenticate a *Gitea* token against a Gitea
# endpoint from a runner that has neither - failing nightly for a reason
# nobody is watching for. GITHUB_SERVER_URL is the one context value that
# differs between the two platforms without naming our instance: Gitea
# sets it to its own base URL. Delete this line once github.com is a
# push mirror without Actions.
if: github.server_url != 'https://github.com'
# No Docker socket needed: the Gitea runner starts every job in a container
# itself, and `container:` is the runner's job to create, not the job's.
# Measured on the probe PR of #225 - the same distinction that puts
# install-test on ubuntu-docker leaves this job on ubuntu-latest.
runs-on: ubuntu-latest
# The official image rather than `npx renovate`: it ships the git, node and
# package-manager versions Renovate expects, and pulling ~200 MB from npm
# on every scheduled run is the alternative. Renovate's built-in
# github-actions manager keeps this tag current (proved by dry run, see the
# migration PR) - it reads `container:` images, not only `uses:`.
container: ghcr.io/renovatebot/renovate:44.87.1
steps:
- name: "Checkout Repository"
uses: actions/checkout@v7
- name: "Run Renovate"
env:
# Platform. The endpoint is derived from the run itself so the
# instance address stays out of this repository, the same rule the
# publish workflow follows for the registry URL.
RENOVATE_PLATFORM: gitea
RENOVATE_ENDPOINT: ${{ github.server_url }}/api/v1
RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }}
GITHUB_COM_TOKEN: ${{ secrets.GITHUB_COM_TOKEN }}
# Exactly this repository. Autodiscovery would enrol every repo the
# token can see, and the token is an account token, not an app
# installation scoped to one repo.
RENOVATE_AUTODISCOVER: "false"
RENOVATE_REPOSITORIES: ${{ github.repository }}
# Who the commits are by. The e-mail must not be a real address of a
# person - Gitea attributes a commit to the account whose verified
# address matches, and these commits are the bot's.
RENOVATE_GIT_AUTHOR: "Renovate Bot <renovate-bot@noreply.invalid>"
# The instance-level half of renovate.json5's postUpgradeTasks. A
# command not listed here is skipped WITHOUT an error message.
RENOVATE_ALLOWED_COMMANDS: '["^ci/renovate-bump-chart\\.sh"]'
# Manual runs default to a dry run; the schedule is the only thing
# that writes on its own.
RENOVATE_DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && inputs.dryRun || 'null' }}
LOG_LEVEL: ${{ github.event_name == 'workflow_dispatch' && inputs.logLevel || 'info' }}
run: renovate
+1
View File
@@ -28,6 +28,7 @@ The repository is moving from github.com to the Gitea instance JLab-Git (#225).
- **`gh` only as `op plugin run -- gh`**, `tea` only as `op plugin run -- tea`. A bare `gh` falls back to the wrong identity. Every call costs a 1Password confirmation, so bundle them and never poll.
- **After the move: no merge queue.** Gitea has none. Its place is taken by **auto-merge on green checks** — the PR is armed once and merges itself when the required checks pass. The manager still decides *whether* to arm it; rule 6 above is unchanged: the user merges, and an agent never merges its own PR.
- **Issue numbers will not survive the move.** Gitea renumbers, and issues and PRs share one counter. A `#n` written today keeps pointing at the GitHub issue; `ci/migrate-issues-to-gitea.sh` writes the old→new mapping but deliberately rewrites nothing.
- **Renovate is already running on the Gitea side, and not from this repo.** A shared `jlab-renovate-bot` instance serves the other repositories there and has this one enrolled; it reads our `renovate.json5` and its `postUpgradeTasks` hook is allow-listed (both verified on its first run). **Do not add a Renovate workflow here** — a second runner against the same repo means duplicate PRs and two schedulers rewriting each other's branches. README, "Renovate on Gitea", has the evidence.
## Keep the docs current
+7 -6
View File
@@ -108,7 +108,7 @@ Fixture images avoid Docker Hub where possible (`public.ecr.aws`/`ghcr.io`) to d
## Dependency updates (Renovate)
Renovate runs as the self-hosted `jlab-renovate` GitHub App while the repo is on github.com, and as a scheduled job of its own (`.github/workflows/renovate.yml`) on Gitea, where no app model exists — see "Renovate on Gitea" below. Which of the two runs it changes nothing about *what* gets updated: its config is **`renovate.json5`** in the repo root (JSON5 for the inline reasoning; requires Renovate >= 41 for `managerFilePatterns`/`customType`). There must be exactly one config file — do not add a second `renovate.json` or `.github/renovate.json`.
Renovate runs as the self-hosted `jlab-renovate` GitHub App while the repo is on github.com, and on Gitea as the shared `jlab-renovate-bot` instance that already serves the other repositories there — see "Renovate on Gitea" below. **There is no Renovate workflow in this repo, and none should be added.** Which of the two runs it changes nothing about *what* gets updated: its config is **`renovate.json5`** in the repo root (JSON5 for the inline reasoning; requires Renovate >= 41 for `managerFilePatterns`/`customType`). There must be exactly one config file — do not add a second `renovate.json` or `.github/renovate.json`.
What Renovate keeps current:
@@ -154,13 +154,14 @@ If the dependency dashboard reports `Failed to look up github-releases package
### Renovate on Gitea
There is no Renovate app for Gitea, so after the move the bot is run by this repository: `.github/workflows/renovate.yml`, a daily schedule plus a manual dispatch that defaults to a dry run. It executes the official `ghcr.io/renovatebot/renovate` image; no Docker socket is involved, because starting a job's `container:` is the runner's own work — the job only lives in it. The file carries an `if: github.server_url != 'https://github.com'` guard so the same workflow stays inert on github.com, where a Gitea token and a Gitea endpoint would fail nightly for a reason nobody is watching for.
**Do not add a Renovate workflow to this repository.** It is the obvious thing to reach for — Gitea has no app model, so a scheduled job in the repo looks like the only way to run the bot — and it is wrong here: a **shared `jlab-renovate-bot` instance already runs on the Gitea side** and already has this repository enrolled. A second runner against the same repo produces duplicate PRs and two schedulers rewriting each other's branches, which is not a safety net but a fault. This paragraph exists so the next reader who finds no workflow knows why instead of building one.
Three things about it are easy to get wrong and cost nothing to get right:
The instance is outside this repository, which has two consequences worth writing down:
- **`GITHUB_COM_TOKEN` is not optional here.** Every `github-releases`/`github-tags` lookup and the whole built-in `github-actions` manager resolve against github.com. Under the App those calls rode on the installation token; a Gitea token is worth nothing there, and unauthenticated github.com runs into the rate limit inside a single pass. The symptom is the `no-result` line on the dependency dashboard, not an error.
- **`allowedCommands` moved into the workflow.** `postUpgradeTasks` only runs when the command is allow-listed in the *instance* config, which this workflow now is: `RENOVATE_ALLOWED_COMMANDS='["^ci/renovate-bump-chart\.sh"]'`. Without it Renovate skips the version-bump hook **silently** and every chart PR stays red on the version check.
- **Renovate keeps its own image current.** The built-in `github-actions` manager reads `container:` images, not only `uses:`. Proved by dry run rather than assumed: pinned to `44.80.0`, the lookup returns `44.87.1` as a `minor` update on branch `renovate/ghcr.io-renovatebot-renovate-44.x`, with `pendingChecks: true` from the 3-day `minimumReleaseAge`. The `ubuntu-docker` runner label is **not** touched by the `github-runners` manager — it is not extracted at all, so nothing will quietly "fix" it back to a version label.
- **It reads our `renovate.json5` and the per-chart rules do fire.** Measured, not assumed: its first run on the migrated repo opened PRs for `searxng` and `gotenberg` plus the dependency dashboard. Those two are `customManagers` targets of ours — no built-in manager finds an `appVersion:` in a `Chart.yaml` — so the config is demonstrably in effect.
- **`allowedCommands` is already granted there, and the version-bump hook runs.** This was the expensive unknown: `postUpgradeTasks` only executes when the command is allow-listed in the *instance* config, and a missing entry is skipped **silently**, leaving every chart PR red on the version check. The proof is in that searxng PR's diff, which carries `version: 1.0.4+up2026.9.11.ffe96f8a6` → `1.0.5+up2026.9.13.96479fff6` alongside the `appVersion` change. Nothing but `ci/renovate-bump-chart.sh` writes `version:`. Nothing has to be configured for the move — but the allow-list is not visible from this repo either, so if it is ever dropped, the symptom here will be red chart PRs with no explanation.
One item does not come for free on either side and is named in "The version-bump hook" above: a `GITHUB_COM_TOKEN` for github.com datasource lookups. Under the GitHub App those rode on the installation token; a Gitea token is worth nothing at github.com, and unauthenticated lookups hit the rate limit inside a single pass. The symptom is a `no-result` line on the dependency dashboard, not an error.
### PR policy
+9 -3
View File
@@ -49,9 +49,15 @@
// allowedCommands: ["^ci/renovate-bump-chart\\.sh"]
//
// Without that entry Renovate skips the task silently and every chart PR
// stays red on the version-bump check. On Gitea, where this repo runs
// Renovate itself, "the instance config" is .github/workflows/renovate.yml -
// it sets RENOVATE_ALLOWED_COMMANDS to exactly that value.
// stays red on the version-bump check.
//
// On the Gitea side (#225) that entry EXISTS and was verified rather than
// hoped for: the shared instance's first run on the migrated repo produced
// a searxng PR whose diff carries `version: 1.0.4+up... -> 1.0.5+up...`
// next to the appVersion. No built-in manager touches `version:`, so that
// line can only come from this hook. Nothing has to be configured for the
// move - but the allow-list lives on that instance, not in this repo, so it
// is also not visible from here if it is ever removed.
postUpgradeTasks: {
commands: ["ci/renovate-bump-chart.sh {{{packageFileDir}}}"],
fileFilters: ["**/Chart.yaml"],