Skip to content

renovate-self

A schedule-driven Renovate run that scans the project's tracked dependency manifests and opens MRs for available upgrades. Designed for a daily/weekly GitLab pipeline schedule that sets RENOVATE_TASK=scan (anything else is skipped, so one schedule can drive multiple tasks if a consumer ever needs that).

Pair this component with the bundled Renovate preset at the cicd repo root — in the consumer's renovate.json / renovate.json5:

{ "extends": ["gitlab>phpboyscout/cicd"] }

That preset ships a custom manager that tracks the gitlab.com/phpboyscout/cicd/<component>@vX.Y.Z pins in .gitlab-ci.yml — so this job opens MRs to keep itself (and every other component pin) current.

Image version floor

image_version must be ≥ 39: the bundled preset's custom managers use managerFilePatterns (introduced in Renovate 39, replacing fileMatch), which older images reject with a config error that halts MR creation.

On GitLab Free, project/group access tokens are Premium-only — use a fine-grained personal access token with api + write_repository scope on the target projects, in $RENOVATE_TOKEN.

The token is aliased internally to a non-colliding variable name before being handed to Renovate via --token. A job variable RENOVATE_TOKEN: "$RENOVATE_TOKEN" (same name on both sides) collides with a group variable of that name and resolves to a broken value, authenticating with junk — see Explanation: renovate automation.

Jobs

Job What it runs
renovate-self renovate --token="$RENOVATE_TOKEN_RUNTIME", with RENOVATE_PLATFORM=gitlab, RENOVATE_AUTODISCOVER=false, RENOVATE_REPOSITORIES=$[[ inputs.repositories ]].

Inputs

Input Type Default Description
image_version string "43" renovate/renovate image tag. Must be ≥ 39 (see note above).
stage string renovate GitLab CI stage. Consumers must declare it in stages:.
repositories string (required) Single project path or JSON array of paths Renovate should manage.
if string '$CI_PIPELINE_SOURCE == "schedule" && $RENOVATE_TASK == "scan"' Gating rules:if:.
token string "$RENOVATE_TOKEN" Token Renovate uses to clone, branch, and open MRs. Needs api + write_repository.
log_level string info Renovate log level — debug when triaging.
terraform_docs_version string "" Install this terraform-docs version into the Renovate image before the run (e.g. 0.24.0, no v). Empty = not installed. See terraform-docs regeneration.
allowed_commands string '["^terraform-docs --output-mode=inject --output-file=README\\.md markdown table [\\w./-]+$"]' JSON array of anchored regexes for RENOVATE_ALLOWED_COMMANDS — the commands postUpgradeTasks may run. [] allows nothing.

Usage

include:
  - component: gitlab.com/phpboyscout/cicd/[email protected]
    inputs:
      repositories: '["phpboyscout/my-project"]'

terraform-docs regeneration

Renovate bumps the version = constraint inside .tf files but does not know that a terraform-docs-managed table in README.md embeds that same version. So every Terraform module bump used to arrive with a stale docs table and fail tofu-lint's terraform-docs-drift job by construction.

A postUpgradeTasks hook fixes this by regenerating the tables inside Renovate's own commit. It needs three pieces, and any one alone is inert:

  1. The binary. Set terraform_docs_version. terraform-docs is not in the Renovate image, and Renovate's installTools cannot supply it — Containerbase has no Terraform track — so the job fetches the pinned release into /usr/local/bin before the run.
  2. The permission. allowed_commands (default already covers the preset's command). allowedCommands is a global-only Renovate option: it is rejected in repository config, so it cannot ride in the shared preset and must be set on this component.
  3. The hook. Extend the opt-in named preset alongside the default one:
{ "extends": ["gitlab>phpboyscout/cicd", "gitlab>phpboyscout/cicd:terraform-docs"] }
include:
  - component: gitlab.com/phpboyscout/cicd/[email protected]
    inputs:
      repositories: '["phpboyscout/iac/terraform-aws-signing-kms"]'
      terraform_docs_version: "0.24.0"

Repos with multiple module directories override commands with one entry per directory, mirroring their tofu-lint paths input:

{
  "extends": ["gitlab>phpboyscout/cicd", "gitlab>phpboyscout/cicd:terraform-docs"],
  "postUpgradeTasks": {
    "commands": [
      "terraform-docs --output-mode=inject --output-file=README.md markdown table bootstrap",
      "terraform-docs --output-mode=inject --output-file=README.md markdown table org",
      "terraform-docs --output-mode=inject --output-file=README.md markdown table src"
    ]
  }
}

The allowlist is a security boundary

allowed_commands is the list of commands the bot may execute against repository content. If you override the default:

  • Anchor every pattern with ^...$. Renovate matches with an unanchored test, so an unanchored pattern allows far more than it reads like it does.
  • Never allow a shell. ^bash -c .* would let the preset self-configure its directory list, but it grants arbitrary command execution and makes the allowlist decorative. That is why multi-directory repos spell out one command per directory instead.

A command that does not match is not silently dropped: Renovate logs a warning, records an artifact error in the MR body, and still opens the MR — so a misconfiguration degrades to the old behaviour rather than breaking the run.

The drift job is deliberately kept as the backstop — it still catches a regeneration that did not happen, whether because a repo has not adopted the preset, the allowlist rejected the command, or someone edited a table by hand.

See also