fix(renovate): run Renovate as the job container; the action needs a Docker daemon jobs do not get
renovatebot/github-action is a wrapper around `docker run`. On this runner a job has no Docker daemon by decision (decisions/2026-10-29-image-pipeline.md), so every run, including dispatch run 343, died before Renovate started: failed to connect to the docker API at unix:///var/run/docker.sock ... no such file or directory The pinned image ghcr.io/renovatebot/renovate:44.167.0 is now the job container, and a run step execs renovate-entrypoint.sh. actions/checkout is dropped, since Renovate clones the repo itself. An optional RENOVATE_GITHUB_COM_TOKEN secret feeds GITHUB_COM_TOKEN. Local dry run (--platform=local, uid 12021, the step body verbatim): 179 deps extracted, 42 updates, and all 4 own-image digest lookups against the Gitea registry succeed. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
dfc432c6ea
commit
365e43cdea
3 files changed
+167
-22
No files matched your search
@@ -116,15 +116,37 @@ concurrency:
|
||||
jobs:
|
||||
renovate:
|
||||
runs-on: ubuntu-latest
|
||||
# RENOVATE RUNS AS THE JOB CONTAINER, NOT THROUGH renovatebot/github-action. FIXED 2026-10-30.
|
||||
# That action does exactly one thing: `docker run ghcr.io/renovatebot/renovate:<version>`. On
|
||||
# this runner a job has NO Docker daemon, by decision (decisions/2026-10-29-image-pipeline.md:
|
||||
# act_runner sets container.docker_host to `-` when DOCKER_HOST is tcp://, and the DinD daemon
|
||||
# is privileged, so a job that could reach it would be root on the node). So every run of the
|
||||
# action died before Renovate started. Dispatch run 343 (2026-10-30), verbatim:
|
||||
# [command]/usr/bin/docker run --env LOG_LEVEL ... --env RENOVATE_TOKEN=*** ...
|
||||
# failed to connect to the docker API at unix:///var/run/docker.sock; ... no such file or directory
|
||||
# ::error::Error: The process '/usr/bin/docker' failed with exit code 1
|
||||
# No auth, scope, config or network question was ever reached. Making the Renovate image the
|
||||
# job container needs no daemon: act starts it through the runner's own DinD exactly as it
|
||||
# starts the default ubuntu image, then `exec`s each step inside it.
|
||||
#
|
||||
# PINNED here (was the action's `renovate-version: 44.167.0`). renovate.json5 is validated
|
||||
# against this exact tag — keep them in step. Renovate's github-actions manager reads
|
||||
# `.gitea/workflows` and extracts `container.image`, so this pin is still self-maintained.
|
||||
#
|
||||
# The image runs as uid 12021 (`ubuntu`), and that is fine under act: the step command files
|
||||
# ($GITHUB_STEP_SUMMARY etc.) are created mode 0666 (gitea/act v0.261.2 pkg/runner/step.go),
|
||||
# HOME comes from the image env, and no step writes the workspace. There is deliberately NO
|
||||
# actions/checkout: Renovate clones the repo itself from RENOVATE_ENDPOINT, and as uid 12021
|
||||
# checkout could not `git init` the root-owned workspace volume anyway.
|
||||
container:
|
||||
image: ghcr.io/renovatebot/renovate:44.167.0
|
||||
# Renovate scans every manager across the whole repo; 40m is generous for this repo's size and
|
||||
# well under a runner's patience. Without a timeout a wedged run holds the `renovate`
|
||||
# concurrency group and silently blocks every subsequent scheduled run.
|
||||
timeout-minutes: 40
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Preflight - the token must exist, and its absence must be LOUD
|
||||
shell: bash
|
||||
env:
|
||||
RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }}
|
||||
run: |
|
||||
@@ -147,25 +169,17 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
echo "RENOVATE_TOKEN is present (value not printed)."
|
||||
# Proves the step is running INSIDE the pinned Renovate image, not the default job image.
|
||||
echo "renovate $(renovate --version)"
|
||||
|
||||
- name: Run Renovate
|
||||
uses: renovatebot/[email protected]
|
||||
with:
|
||||
# Pinned, and Renovate maintains this pin itself: renovate.json's enabledManagers
|
||||
# includes `github-actions`, and `helpers:pinGitHubActionDigests` is in its `extends`.
|
||||
# This is the one dependency in the repo whose updater is its own updater.
|
||||
# MUST match the file's real name. #79 renamed it to renovate.json5 and left this line
|
||||
# saying `renovate.json`; every scheduled run from 2026-10-18 then died in ~1s with
|
||||
# ENOENT before Renovate started, and nothing in the gate noticed. ci/lint.sh now
|
||||
# asserts that every `configurationFile:` here names a file that exists.
|
||||
configurationFile: renovate.json5
|
||||
token: ${{ secrets.RENOVATE_TOKEN }}
|
||||
# PINNED 2026-10-29. Unset, this action version runs Renovate `39` (action.yml
|
||||
# `renovate-version` default at v41.0.9), i.e. 39.264.0, and renovate.json5 uses
|
||||
# `managerFilePatterns` (>= 40.2.0): under 39.x validation fails with five errors and
|
||||
# the run stops at CONFIG_VALIDATION. #79 validated against `latest`, not this.
|
||||
renovate-version: 44.167.0
|
||||
shell: bash
|
||||
# The repo config is discovered by Renovate from the cloned repo (renovate.json5,
|
||||
# RENOVATE_REQUIRE_CONFIG=required). The action used to ALSO load it as the global config
|
||||
# via RENOVATE_CONFIG_FILE; that double-loading is gone. ci/lint.sh's `configurationFile:`
|
||||
# check therefore has nothing to resolve in this file, and passes.
|
||||
env:
|
||||
RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }}
|
||||
# Self-hosted Gitea. `platform` + `endpoint` were the two values renovate.json's own
|
||||
# header said were "set at runtime by the operator's renovate runner" — this is that
|
||||
# runner, so they are set here rather than in the repo config, which keeps renovate.json
|
||||
@@ -189,6 +203,23 @@ jobs:
|
||||
# token; it therefore needs scope `read:package` in addition to the ones listed in the
|
||||
# preflight above. Gitea ignores the username for token auth (services/auth/basic.go).
|
||||
RENOVATE_HOST_RULES: '[{"hostType":"docker","matchHost":"gitea.home.keithjackson.dev","username":"renovate","password":"${{ secrets.RENOVATE_TOKEN }}"}]'
|
||||
# OPTIONAL, ADDED 2026-10-30. A github.com token (a fine-grained PAT with NO permissions,
|
||||
# public-repo read only) for lookups of GitHub-hosted dependencies. Without it Renovate
|
||||
# SKIPS them with `github-token-required` — measured in a local dry run: 17 deps, i.e.
|
||||
# every `uses: actions/*` here plus kubevirt/kubevirt, kubevirt/containerized-data-importer
|
||||
# and intel/intel-device-plugins-for-kubernetes. Unset is safe: the step below drops the
|
||||
# empty variable, and those deps simply stay unmaintained, with a WARN in the log.
|
||||
GITHUB_COM_TOKEN: ${{ secrets.RENOVATE_GITHUB_COM_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# An expression that evaluates to '' still EXPORTS the variable, as an empty string.
|
||||
# Drop those so an unset value means "Renovate's default", never "set to empty".
|
||||
for v in RENOVATE_DRY_RUN GITHUB_COM_TOKEN; do
|
||||
[ -n "${!v:-}" ] || unset "$v"
|
||||
done
|
||||
# Through the image's entrypoint, as `docker run` would have gone: it sources the
|
||||
# containerbase env and initialises the bundled tools before exec'ing Renovate.
|
||||
exec renovate-entrypoint.sh renovate
|
||||
|
||||
- name: Summary
|
||||
if: always()
|
||||
|
||||
Reference in new issue
Block a user