diff --git a/.github/workflows/renovate.yml b/.github/workflows/renovate.yml deleted file mode 100644 index 2d967f0..0000000 --- a/.github/workflows/renovate.yml +++ /dev/null @@ -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 " - - # 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 diff --git a/CLAUDE.md b/CLAUDE.md index 2e6b88b..23aa80f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 diff --git a/README.md b/README.md index 3cb6b63..93d756b 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/renovate.json5 b/renovate.json5 index e8d8754..b68fd34 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -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"],