Dependency updates: sandbox
Every version in this repo and in pi-config is pinned, and a self-hosted
Renovate keeps them current by opening pull requests on
Codeberg. Each repo has its own, scoped Renovate run that processes only that repo. The
brain repos are not included.
What is updated#
| Dependency | Pinned in | Source Renovate checks |
|---|---|---|
Base image node:24-bookworm-slim (tag + digest) | Dockerfile FROM | Docker Hub |
pi (@earendil-works/pi-coding-agent) | Dockerfile ARG PI_VERSION | npm |
Hermit hermit (with the SHA-256 of its .gz) | Dockerfile ARG HERMIT_VERSION, HERMIT_SHA256_<ARCH> | GitHub releases (cashapp/hermit) |
Hermit package index cashapp/hermit-packages (archive at a fixed commit, with its SHA-256) | Dockerfile ARG HERMIT_PACKAGES_COMMIT, HERMIT_PACKAGES_SHA256 | by hand: no Renovate rule; compute the archive’s SHA-256 with the new commit |
AWS MCP proxy mcp-proxy-for-aws-cli (pins its Python dependencies exactly) | Dockerfile ARG MCP_PROXY_FOR_AWS_VERSION | PyPI |
STACKIT CLI stackit, Hetzner Cloud CLI hcloud, GitHub CLI gh, ghorg, RTK rtk, kubectl, talosctl (with checksums) | Dockerfile ARG <TOOL>_VERSION, <TOOL>_SHA256_<ARCH> | GitHub releases (kubectl: kubernetes/kubernetes, talosctl: siderolabs/talos) |
rtk build stage (compiles RTK for arm64; not in the image) | Dockerfile FROM rust (tag + digest); ARG RTK_COMMIT (tag commit, rewritten with the checksums) | Docker Hub; GitHub releases of rtk-ai/rtk |
uv build stage (installs the proxy; not in the image) | Dockerfile FROM ghcr.io/astral-sh/uv (tag + digest) | GitHub container registry |
| Debian packages of the image (git, ripgrep, fd-find, jq, curl, ca-certificates, less, python3, python3-yaml, python3-jsonschema, make, g++, yamllint, chromium) | Dockerfile ARG <PKG>_VERSION | Debian bookworm, bookworm-updates, bookworm-security |
| Release tooling (semantic-release + plugins) | package.json, package-lock.json | npm (+ weekly lockfile maintenance) |
| Forgejo actions (checkout, setup-node) | .forgejo/workflows/*.yml | code.forgejo.org tags |
| Node.js for CI jobs | .forgejo/workflows/*.yml node-version | Node.js releases |
| Renovate itself | .forgejo/workflows/renovate.yml | npm |
just, gitleaks (with checksums) | scripts/ci-install-tools.sh | GitHub releases |
| Docker CLI, compose, buildx | scripts/ci-install-tools.sh | Docker’s Debian repo |
| podman client | scripts/ci-install-tools.sh | Debian bookworm |
pi packages (npm:<name>@<x.y.z>) | pi-config/agent/settings.json + docs/config-reference.md | npm |
Versions that are not in a standard file format carry a # renovate: datasource=… depName=…
comment on the line above; the regex manager in renovate.json reads those.
How updates arrive#
- Commit types decide releases. Image contents (base image, pi, Debian packages) and pi
packages are committed as
build(deps): …→ patch release (and a new image here). CI and release tooling isci(deps): …→ no release. - Grouping: all Debian packages in one PR; semantic-release and its plugins in one PR.
- No minimum release age (bleeding edge): a new version is proposed in the first nightly run after it is published (owner decision 2026-10-04; the former 3-day wait is gone). Accepted risk: a compromised or withdrawn release can reach a PR the same night — the review before merging is the safeguard, and nothing is merged automatically.
- Checksums: when Renovate bumps
justorgitleaks, it runsscripts/update-ci-checksums.shin the PR branch, which fetches the new release’s published checksums and rewrites the pinned SHA-256 values; forstackit,hcloud,ghorg,gh,rtk,kubectlandtalosctlin the image it runsscripts/update-image-checksums.shthe same way. - Held back:
conventional-changelog-conventionalcommitsstays below 10 until semantic-release shipsconventional-changelog-writer9. - Dependency Dashboard: an issue in each repo lists every pending and open update.
- PR checks (
.forgejo/workflows/check.yml) run on every PR:just check, and here also an amd64 build of the image, so a Debian version that was superseded fails before merge. Both repos also validaterenovate.jsonwith the pinned Renovate version (renovate-config-validator --strict, same pin asrenovate.yml, bumped together), so a config error fails the PR instead of the nightly run. - Nothing is merged automatically. Review the PR, merge it, and the release pipeline does the rest.
The Renovate jobs#
Each repo runs its own .forgejo/workflows/renovate.yml on the runner pi
at night — workflow cron times are UTC: pi-docker-sandbox at 01:17 UTC (03:17 CEST / 02:17 CET),
pi-config at 01:47 UTC (03:47 CEST / 02:47 CET) — and on demand (Actions → renovate → Run
workflow in that repo). Each job runs npx renovate@<pinned> with platform forgejo against
https://codeberg.org/api/v1 and RENOVATE_REPOSITORIES set to ${{ github.repository }}, so
it can only work on its own repo; the concurrency group is per repo. The only post-upgrade
commands allowed are scripts/update-ci-checksums.sh and scripts/update-image-checksums.sh.
Keep both runs before 06:00 Berlin time: renovate.json’s weekly lockfile maintenance only
happens in its before 6am on monday window (timezone Europe/Berlin).
One-time setup#
- Bot account (recommended): a separate Codeberg user, e.g.
pi-renovate-bot, added to theblack0ut-pi-setuporganisation with write access to both repos. - Token of that account (Settings → Applications) with: repository read+write, issue
read+write, organisation read, user read. Store it as the Actions secret
RENOVATE_TOKEN— once at organisation level, or per repo (both repos need it). Per-repo secrets let you use a different token for each repo. - GitHub token —
RENOVATE_GITHUB_COM_TOKEN: a fine-grained GitHub token with no permissions (public read only). Needed for Node.js,justandgitleakslookups and release notes; without it those dependencies are skipped. - Issues must be enabled in both repos (for the Dependency Dashboard).
- Run the workflow once by hand in each repo. Because
renovate.jsonalready exists, there is no onboarding PR: Renovate creates the Dependency Dashboard issue and the first update PRs.