Versions and Renovate Management

SkillDev tools

Managing platform versions and Renovate annotations in the homelab.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Versions and Renovate Management skill

What this skill tells your AI

The instructions your AI receives, as published by ionfury/homelab in .claude/skills/versions-renovate/SKILL.md and read by ahel’s review.

Versions live in kubernetes/platform/versions.env. Renovate's custom regex manager in .github/renovate.json5 parses # renovate: annotations on the line above each entry. Flux substitutes ${var} references into HelmRelease specs at reconcile time.

Choosing the Initial Version

Always verify the latest stable tag from the source — never guess from memory. Training data lags reality by months to years, so a remembered tag is almost always stale. Before writing any *_version= entry or hardcoded image tag, look it up:

# Docker/OCI registry (GHCR shown; anonymous pull token)
TOKEN=$(curl -s "https://ghcr.io/token?scope=repository:<org>/<image>:pull&service=ghcr.io" | jq -r .token)
curl -s -H "Authorization: Bearer $TOKEN" "https://ghcr.io/v2/<org>/<image>/tags/list" | jq -r '.tags[]' | sort -V | tail

skopeo list-tags docker://ghcr.io/<org>/<image>          # if skopeo available
git ls-remote --tags --refs https://github.com/<org>/<repo>.git | sort -V | tail   # github-releases/tags

Match the tag format the registry actually uses (v2.7.1 vs 2.7.1). Pick the newest stable semver; skip beta/rc/nightly/latest unless the user asks. Renovate keeps it current afterward, but a fresh deploy must start on the current release, not an ancient one.

Annotation Syntax

# renovate: datasource=<source> depName=<name> [packageName=<pkg>] [extractVersion=<regex>] [registryUrl=<url>] [versioning=<scheme>]
variable_name=<value>

Key ordering is fixed: datasource, depName, packageName, extractVersion, registryUrl, versioning. Rearranging keys causes Renovate to silently skip the entry.

FieldRequiredPurpose
datasourceYesWhere Renovate looks (helm, docker, github-releases, github-tags)
depNameYesHuman-readable name shown in Renovate PRs
packageNameNoRegistry-specific lookup path (OCI registries, GitHub repos)
extractVersionNoRegex to transform upstream version (e.g., strip v prefix)
registryUrlNoHTTP Helm repository URL (not for OCI)
versioningNoVersion scheme override for non-semver (e.g., loose)

Datasource Selection

HTTP Helm registry    --> datasource=helm + registryUrl=<url>
OCI Helm registry     --> datasource=docker + packageName=<full-path>   (no oci:// prefix)
GitHub release        --> datasource=github-releases + packageName=<org/repo>
GitHub tag            --> datasource=github-tags + packageName=<org/repo>

Examples

# HTTP Helm registry
# renovate: datasource=helm depName=grafana registryUrl=https://grafana.github.io/helm-charts
grafana_version=10.5.15

# OCI Helm registry
# renovate: datasource=docker depName=app-template packageName=ghcr.io/bjw-s-labs/helm/app-template
app_template_version=4.6.2

# GitHub releases (keep v prefix)
# renovate: datasource=github-releases depName=talos packageName=siderolabs/talos
talos_version=v1.12.2

# GitHub tags (strip v prefix with extractVersion)
# renovate: datasource=github-tags depName=kubernetes packageName=kubernetes/kubernetes extractVersion=^v(?<version>.*)$
kubernetes_version=1.35.0

# Strip v from Helm chart releases
# renovate: datasource=helm depName=cert-manager extractVersion=^v(?<version>.*)$ registryUrl=https://charts.jetstack.io
cert_manager_version=1.19.3

# Non-semver versions
# renovate: datasource=docker depName=cloudnative-vectorchord packageName=ghcr.io/tensorchord/cloudnative-vectorchord versioning=loose
vectorchord_version=18.1-1.0.0

YAML Container Image Annotations

For image tags hardcoded in Helm values files (sidecars, init containers):

image:
  repository: ghcr.io/kashalls/kromgo
  # renovate: datasource=docker depName=ghcr.io/kashalls/kromgo
  tag: v0.7.5
initContainers:
  # renovate: datasource=docker depName=ghcr.io/home-operations/postgres-init
  image: ghcr.io/home-operations/postgres-init:18

Package Rules

Add to .github/renovate.json5 to group related charts or block automerge:

{
  "matchDepNames": ["my-chart", "related-chart"],
  "groupName": "my stack"
}

matchDepNames values must match the depName in the annotation. By default, minor/patch updates automerge after 3 days (.renovate/automerge.json5). Infrastructure-critical groups (talos, kubernetes, cilium, gateway-api, flux) have automerge disabled.

After changes, run task renovate:validate.

Debugging

SymptomCauseFix
Silently ignoredWrong key orderFollow exact order above
Can't find packageoci:// prefix in packageNameRemove oci:// prefix
Version has unwanted vMissing extractVersionAdd extractVersion=^v(?<version>.*)$
Can't find OCI chartdatasource=helm for OCIUse datasource=docker
Skips non-semverMissing versioning=looseAdd versioning=loose
Regex doesn't matchAnnotation not on line aboveMust be immediately above key=value

Also check: dependency dashboard in the Renovate GitHub issue, ignorePaths in renovate.json5.

Signals

GitHub stars
25
Forks
3
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
versions-renovate
Source
github.com/ionfury/homelab