Production-grade platform engineering handbook — Kubernetes, Terraform, Flux CD, GitHub Actions, AWS, and more.
67
84%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Passed
No known issues
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Add /platform-skills:renovate with generate (emit renovate.json from repo scan), workflow (emit GHA validation workflow), precommit (interactive semver/automerge wizard), and all (run all modes) modes, plus all v1.27.0 release metadata.
Architecture: New command file at commands/renovate.md, deep-dive reference at references/renovate.md, GHA workflow at .github/workflows/validate-renovate.yml. Existing renovate.json gets patched with missing fields. Version bumped to 1.27.0 across plugin.json, marketplace.json, tile.json, CHANGELOG.md, INSTALLATION.md.
Tech Stack: Markdown skill files, JSON (renovate.json, marketplace.json, plugin.json, tile.json), GitHub Actions YAML, bash (coverage scan script), npx (ajv-cli, renovate-config-validator).
| Action | File | Responsibility |
|---|---|---|
| Create | commands/renovate.md | Slash command — generate and workflow modes |
| Create | references/renovate.md | Manager catalog, presets, security, GitOps integration, troubleshooting |
| Create | .github/workflows/validate-renovate.yml | CI: schema + config-validator + coverage on renovate.json PRs |
| Modify | renovate.json | Add osvVulnerabilityAlerts, dependencyDashboard, minimumReleaseAge, gomod/npm/pip rules |
| Modify | SKILL.md | Add Renovate row to tool table + /platform-skills:renovate slash command |
| Modify | COMMANDS.md | Add TOC row + full /platform-skills:renovate section |
| Modify | marketplace.json | Version 1.26.0 → 1.27.0; add renovate keyword; update description |
| Modify | .claude-plugin/plugin.json | Version 1.26.0 → 1.27.0; add commands/renovate.md to commands array |
| Modify | tile.json | Version 1.25.20 → 1.27.0 |
| Modify | CHANGELOG.md | Add [1.27.0] entry |
| Modify | INSTALLATION.md | platform-skills v1.26.0 enabled → platform-skills v1.27.0 enabled |
commands/renovate.mdFiles:
Create: commands/renovate.md
Step 1: Write the command file
Create /Users/nitin.jain/platform-skills/commands/renovate.md with this exact content:
---
name: renovate
description: Generate renovate.json covering all dependency file types used in a repo, or emit a GitHub Actions workflow that validates renovate.json on every PR that touches it.
argument-hint: "[generate|workflow]"
---
You are a senior platform engineer specialising in dependency update automation with Renovate.
The input is: $ARGUMENTS
Parse the first word as the mode:
- `generate` — scan this repo and create renovate.json
- `workflow` — emit a GitHub Actions workflow that validates renovate.json on PR
Reference: `references/renovate.md`
---
## Interactive Wizard (fires when $ARGUMENTS is empty)
When invoked with no arguments, ask before proceeding:
**Q1 — Mode?**
```
What do you need?
1. generate — scan this repo and create renovate.json covering all detected dep file types
2. workflow — generate a GitHub Actions workflow that validates renovate.json on every PR
Enter 1–2 or mode name:
```
Then proceed into the relevant mode below.
---
## Mode: generate
Scan the repo working tree for dependency file types, then emit a `renovate.json` that covers exactly those managers — no more, no less.
### Step 1 — Detect ecosystems
Scan for files matching these patterns. Exclude `.git/`, `node_modules/`, `vendor/`, `.terraform/`, `charts/`.
| File pattern | Manager | Key rule |
|---|---|---|
| `.github/workflows/*.yml` | `github-actions` | Pin action digests |
| `*.tf`, `*.tfvars` | `terraform` | Providers + modules |
| `Chart.yaml`, `requirements.yaml` | `helmv3` | Helm chart deps |
| `go.mod` | `gomod` | Go modules |
| `package.json`, `package-lock.json`, `yarn.lock` | `npm` | Node packages |
| `requirements*.txt`, `Pipfile`, `pyproject.toml` | `pip` | Python packages |
| `Dockerfile`, `docker-compose*.yml` | `docker` | Container images |
| `Cargo.toml` | `cargo` | Rust crates |
| Kubernetes manifests (`kind: Deployment/StatefulSet/DaemonSet`) | `kubernetes` | Image tags |
Print a coverage table before emitting output:
```
Detected dependency file types:
✅ github-actions → .github/workflows/ (N files)
✅ terraform → examples/**/*.tf (N files)
✅ helmv3 → examples/**/Chart.yaml (N files)
⚠️ npm → package.json (1 file) — not covered in current renovate.json
ℹ️ cargo → no Cargo.toml found — skipped
```
### Step 2 — Emit renovate.json
Generate a `renovate.json` containing only the managers detected in Step 1.
**Always include this base:**
```json
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended",
":dependencyDashboard",
":semanticCommits",
":separateMajorReleases"
],
"dependencyDashboard": true,
"dependencyDashboardTitle": "Renovate Dependency Dashboard",
"timezone": "<detect from `git config --global core.timezone`; ask if undetectable>",
"schedule": ["before 6am on monday"],
"labels": ["dependencies", "renovate"],
"prConcurrentLimit": 5,
"prCreation": "not-pending",
"rebaseWhen": "conflicted",
"semanticCommits": "enabled",
"vulnerabilityAlerts": {
"enabled": true,
"labels": ["security"]
},
"osvVulnerabilityAlerts": true,
"ignorePaths": [
"**/node_modules/**",
"**/vendor/**",
"**/.terraform/**",
"**/charts/**"
]
}
```
**Per-detected-manager `packageRules` (include only detected managers):**
`github-actions`:
```json
{
"description": "GitHub Actions — pin to commit SHA for supply chain security",
"matchManagers": ["github-actions"],
"pinDigests": true,
"automerge": false,
"groupName": "GitHub Actions",
"schedule": ["before 6am on monday"]
}
```
`terraform`:
```json
{
"description": "Terraform providers — automerge minor/patch",
"matchManagers": ["terraform"],
"matchDepTypes": ["required_provider"],
"groupName": "Terraform providers",
"automerge": true,
"automergeType": "pr",
"minimumReleaseAge": "3 days",
"matchUpdateTypes": ["minor", "patch"]
},
{
"description": "Terraform modules — review major versions manually",
"matchManagers": ["terraform"],
"matchDepTypes": ["module"],
"automerge": false,
"groupName": "Terraform modules"
}
```
`helmv3`:
```json
{
"description": "Helm charts — automerge patch only",
"matchManagers": ["helmv3"],
"automerge": true,
"automergeType": "pr",
"minimumReleaseAge": "3 days",
"matchUpdateTypes": ["patch"]
}
```
`gomod`:
```json
{
"description": "Go modules — automerge minor/patch",
"matchManagers": ["gomod"],
"automerge": true,
"automergeType": "pr",
"minimumReleaseAge": "3 days",
"matchUpdateTypes": ["minor", "patch"],
"groupName": "Go modules"
}
```
`npm`:
```json
{
"description": "npm packages — automerge minor/patch",
"matchManagers": ["npm"],
"automerge": true,
"automergeType": "pr",
"minimumReleaseAge": "3 days",
"matchUpdateTypes": ["minor", "patch"],
"groupName": "npm packages"
}
```
`pip`:
```json
{
"description": "Python packages — automerge minor/patch",
"matchManagers": ["pip_requirements", "pip-compile", "pipenv", "poetry"],
"automerge": true,
"automergeType": "pr",
"minimumReleaseAge": "3 days",
"matchUpdateTypes": ["minor", "patch"],
"groupName": "Python packages"
}
```
`docker`:
```json
{
"description": "Container images — review all updates",
"matchManagers": ["docker-compose", "dockerfile"],
"automerge": false,
"groupName": "Container images"
}
```
`kubernetes`:
```json
{
"description": "Kubernetes container images — review all updates",
"matchManagers": ["kubernetes"],
"automerge": false,
"groupName": "Kubernetes images"
}
```
`cargo`:
```json
{
"description": "Rust crates — automerge minor/patch",
"matchManagers": ["cargo"],
"automerge": true,
"automergeType": "pr",
"minimumReleaseAge": "3 days",
"matchUpdateTypes": ["minor", "patch"],
"groupName": "Rust crates"
}
```
**`postUpdateOptions`** — include only for detected ecosystems:
- `gomod` detected → add `"gomodTidy"`
- `npm` detected → add `"npmDedupe"`
**`regexManagers`** — include if `.github/workflows/*.yml` contains `terraform_version:`:
```json
{
"description": "Update Terraform version in GitHub Actions workflows",
"fileMatch": ["^\\.github/workflows/.*\\.ya?ml$"],
"matchStrings": [
"terraform_version:\\s*['\"]?(?<currentValue>[^'\"\\s]+)['\"]?"
],
"depNameTemplate": "hashicorp/terraform",
"datasourceTemplate": "github-releases",
"extractVersionTemplate": "^v(?<version>.*)$"
}
```
### Step 3 — Write or diff
- If `renovate.json` already exists: show only the lines that would change. Ask: `Write to renovate.json? [y/N]`
- If no existing file: write directly and print `✅ renovate.json written.`
---
## Mode: workflow
Emit a ready-to-use `.github/workflows/validate-renovate.yml` that validates `renovate.json` on every PR that modifies it. No secrets or tokens required — uses only `GITHUB_TOKEN`.
### Output file: `.github/workflows/validate-renovate.yml`
```yaml
name: Validate Renovate Config
on:
pull_request:
paths:
- 'renovate.json'
permissions:
contents: read
jobs:
validate-schema:
name: Schema Validation
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Validate JSON syntax
run: |
if ! jq empty renovate.json; then
echo "❌ renovate.json is not valid JSON"
exit 1
fi
echo "✅ JSON syntax valid"
- name: Validate against Renovate schema
run: |
npm install --save-dev ajv-cli ajv-formats
npx ajv validate \
--spec=draft7 \
-s https://docs.renovatebot.com/renovate-schema.json \
-d renovate.json \
-c ajv-formats || {
echo "❌ renovate.json does not match Renovate schema"
exit 1
}
echo "✅ Schema validation passed"
validate-config:
name: Config Validator
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Run renovate-config-validator
run: |
npx --yes renovate-config-validator renovate.json
echo "✅ Config validation passed"
validate-coverage:
name: Coverage Scan
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Check manager coverage
run: |
UNCOVERED=0
check_coverage() {
local label="$1"
local pattern="$2"
local manager="$3"
if find . -path "./.git" -prune -o -name "$pattern" -print | grep -q .; then
if grep -q "\"$manager\"" renovate.json; then
echo "✅ COVERED: $label ($manager)"
else
echo "⚠️ UNCOVERED: $label ($manager) — files found but manager not referenced in renovate.json"
UNCOVERED=$((UNCOVERED + 1))
fi
else
echo "ℹ️ SKIPPED: $label — no matching files found"
fi
}
check_coverage "GitHub Actions" "*.yml" "github-actions"
check_coverage "Terraform" "*.tf" "terraform"
check_coverage "Helm" "Chart.yaml" "helmv3"
check_coverage "Go modules" "go.mod" "gomod"
check_coverage "npm" "package.json" "npm"
check_coverage "Python" "requirements*.txt" "pip_requirements"
check_coverage "Docker" "Dockerfile" "dockerfile"
check_coverage "Rust" "Cargo.toml" "cargo"
if [ $UNCOVERED -gt 0 ]; then
echo ""
echo "⚠️ $UNCOVERED ecosystem(s) detected but not covered by Renovate"
echo "Run /platform-skills:renovate generate to update your renovate.json"
else
echo "✅ All detected ecosystems are covered"
fi
summary:
name: Validation Summary
runs-on: ubuntu-latest
needs: [validate-schema, validate-config, validate-coverage]
if: always()
steps:
- name: Post summary
run: |
cat << 'EOF' >> $GITHUB_STEP_SUMMARY
## Renovate Config Validation
| Check | Status |
|-------|--------|
EOF
echo "| JSON Schema | ${{ needs.validate-schema.result == 'success' && '✅ Passed' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Config Validator | ${{ needs.validate-config.result == 'success' && '✅ Passed' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY
echo "| Coverage Scan | ${{ needs.validate-coverage.result == 'success' && '✅ Passed' || '⚠️ Warnings' }} |" >> $GITHUB_STEP_SUMMARY
- name: Enforce required checks
run: |
if [[ "${{ needs.validate-schema.result }}" != "success" ]] || \
[[ "${{ needs.validate-config.result }}" != "success" ]]; then
echo "❌ Required validation checks failed — see jobs above"
exit 1
fi
echo "✅ All required checks passed"
```
After writing: check if `.github/workflows/validate-renovate.yml` already exists — if so, show diff and ask to overwrite. Then print:
```
✅ Workflow written to .github/workflows/validate-renovate.yml
Next steps:
git add .github/workflows/validate-renovate.yml
git commit -m "ci: add renovate.json validation workflow"
git push
The workflow fires automatically on any PR that modifies renovate.json.
```ls -la /Users/nitin.jain/platform-skills/commands/renovate.md
head -5 /Users/nitin.jain/platform-skills/commands/renovate.mdExpected: file exists, first line is ---
git -C /Users/nitin.jain/platform-skills add commands/renovate.md
git -C /Users/nitin.jain/platform-skills commit -m "feat: add /platform-skills:renovate command — generate, workflow, precommit, and all modes"references/renovate.mdFiles:
Create: references/renovate.md
Step 1: Write the reference file
Create /Users/nitin.jain/platform-skills/references/renovate.md with this exact content:
# Renovate Reference
Companion to `/platform-skills:renovate`. Deep-dive on managers, presets, security, GitOps integration, and troubleshooting.
---
## 1. Manager Catalog
| Manager | File patterns | Notes |
|---|---|---|
| `github-actions` | `.github/workflows/*.yml` | Always `pinDigests: true` — commit SHA instead of tag |
| `terraform` | `*.tf`, `*.tfvars` | Covers `required_providers` and `module` blocks |
| `helmv3` | `Chart.yaml`, `requirements.yaml` | Helm 3 chart dependencies |
| `gomod` | `go.mod` | Go module dependencies; use `gomodTidy` in `postUpdateOptions` |
| `npm` | `package.json`, `package-lock.json`, `yarn.lock` | Node packages; use `npmDedupe` in `postUpdateOptions` |
| `pip_requirements` | `requirements*.txt` | Pinned Python packages |
| `pip-compile` | `requirements*.in` | pip-tools input files |
| `pipenv` | `Pipfile`, `Pipfile.lock` | Pipenv-managed projects |
| `poetry` | `pyproject.toml` (Poetry) | Poetry-managed projects |
| `dockerfile` | `Dockerfile`, `Dockerfile.*` | `FROM` image tags |
| `docker-compose` | `docker-compose*.yml` | Service image tags |
| `kubernetes` | Manifests with `kind: Deployment/StatefulSet/DaemonSet/Job/CronJob` | Container image tags in `spec.containers[].image` |
| `cargo` | `Cargo.toml` | Rust crate dependencies |
| `regex` | Any file via `fileMatch` | Custom version strings — no native manager support |
---
## 2. Preset Reference
`config:recommended` includes:
| Preset | Effect |
|---|---|
| `config:recommended` | Base: semantic PR titles, dependency dashboard, labels, schedule |
| `:dependencyDashboard` | Creates a GitHub Issue listing all pending/blocked updates |
| `:semanticCommits` | Commit messages follow Conventional Commits format |
| `:separateMajorReleases` | Major version bumps get their own PR, never grouped |
Useful add-ons:
| Preset | When to add |
|---|---|
| `:pinDigests` | Global digest pinning — prefer scoped to `github-actions` only |
| `:automergeMinor` | Automerge all minor updates — use only if CI is comprehensive |
| `:automergeDigest` | Automerge digest-only updates (no version change) |
| `security:openssf-scorecard` | Adds OpenSSF Scorecard checks to PRs |
| `helpers:pinGitHubActionDigests` | Shorthand for GitHub Actions digest pinning |
---
## 3. Package Rules Patterns
### Automerge strategy by ecosystem
| Ecosystem | Recommended automerge | Reason |
|---|---|---|
| `github-actions` | Never | SHA pinning means every update is significant |
| `terraform` providers | Minor + patch | Providers are stable; breaking changes follow semver |
| `terraform` modules | Never | Module updates may change resource topology |
| `helmv3` | Patch only | Charts may have templating changes in minor |
| `gomod` | Minor + patch | Go semver is well-respected |
| `npm` | Minor + patch | With `minimumReleaseAge: "3 days"` to avoid supply chain risk |
| `pip` | Minor + patch | Same — pin to `minimumReleaseAge` |
| `docker`/`kubernetes` | Never | Image updates may include breaking app changes |
| `cargo` | Minor + patch | Cargo semver is well-respected |
### Grouping recipes
Group related updates into one PR to reduce noise:
```json
{
"description": "Group all AWS provider updates",
"matchManagers": ["terraform"],
"matchPackageNames": ["hashicorp/aws"],
"groupName": "AWS provider"
},
{
"description": "Group all patch updates across ecosystems",
"matchUpdateTypes": ["patch"],
"matchCurrentVersion": "!/^0/",
"groupName": "Patch updates",
"automerge": true,
"minimumReleaseAge": "3 days"
}
```
### Schedule recipes
```json
"schedule": ["before 6am on monday"] // Weekly, low disruption
"schedule": ["after 10pm every weekday"] // Nightly, non-work hours
"schedule": ["at any time"] // Immediate (vulnerability alerts)
```
### `minimumReleaseAge` for supply chain safety
Always set on automerge rules to prevent typosquatting and freshly-published malicious packages:
```json
{
"matchUpdateTypes": ["minor", "patch"],
"automerge": true,
"minimumReleaseAge": "3 days"
}
```
---
## 4. Dependency Dashboard
Renovate creates a GitHub Issue titled "Renovate Dependency Dashboard" when `dependencyDashboard: true`.
**What it shows:**
- All pending updates grouped by status (Awaiting Schedule / Open PRs / Rate-limited / Ignored)
- Checkboxes to trigger individual updates on-demand
**How to trigger a selective update:**
1. Open the Dependency Dashboard issue
2. Check the box next to the package you want updated now
3. Save the issue — Renovate detects the change within minutes and creates the PR
**How to find the dashboard:**
```bash
gh issue list --label "renovate" --state open
```
**Resetting the dashboard:**
Close and reopen the issue — Renovate recreates it on the next run.
**Enable explicitly** (already in `config:recommended` but good to be explicit):
```json
{
"dependencyDashboard": true,
"dependencyDashboardTitle": "Renovate Dependency Dashboard"
}
```
---
## 5. GitOps Integration
### Renovate vs Flux Image Reflector Controller
Both can update container image references. Running both on the same files causes conflicts.
**Recommended split:**
| Responsibility | Owner |
|---|---|
| Helm chart versions in `HelmRelease` | Renovate (`helmv3` manager) |
| Terraform provider/module versions | Renovate (`terraform` manager) |
| Language dep versions (go.mod, package.json) | Renovate |
| GitHub Actions versions | Renovate (`github-actions` manager) |
| Running workload image tags (Deployment/StatefulSet) | Flux Image Reflector Controller |
| OCI artifact digest pinning in FluxInstance | Flux (`ImagePolicy`) |
**Rule:** Renovate owns anything in source control that follows semver. Flux Image Reflector owns runtime image tags for deployed workloads where you want continuous delivery without a PR.
**Avoiding conflicts:**
If Flux Image Reflector manages `spec.containers[].image` in a manifest, exclude that manifest from Renovate:
```json
{
"ignorePaths": [
"clusters/**",
"flux-system/**"
]
}
```
Or scope the `kubernetes` manager to only non-Flux paths:
```json
{
"matchManagers": ["kubernetes"],
"matchPaths": ["apps/**", "workloads/**"],
"automerge": false
}
```
---
## 6. Security Hardening
### Digest pinning for GitHub Actions
```json
{
"matchManagers": ["github-actions"],
"pinDigests": true
}
```
This converts `uses: actions/checkout@v4` → `uses: actions/checkout@<sha> # v4.x.x`, making the action tamper-proof.
### OSV vulnerability alerts
```json
{
"osvVulnerabilityAlerts": true,
"vulnerabilityAlerts": {
"enabled": true,
"labels": ["security"],
"schedule": ["at any time"]
}
}
```
`osvVulnerabilityAlerts` uses the OSV database (broader coverage than GitHub Advisory Database).
### `minimumReleaseAge` — supply chain defence
Prevents automerging packages published less than N days ago, reducing exposure to typosquatting and fast-follow malicious releases:
```json
{
"matchUpdateTypes": ["minor", "patch"],
"automerge": true,
"minimumReleaseAge": "3 days"
}
```
### `rangeStrategy: pin`
Pin exact versions instead of ranges for reproducibility:
```json
{
"matchManagers": ["npm"],
"rangeStrategy": "pin"
}
```
Use `"bump"` instead if the project publishes a library (ranges in `peerDependencies` must stay flexible).
### Private registry auth
```json
{
"hostRules": [
{
"matchHost": "ghcr.io",
"username": "{{ secrets.GHCR_USERNAME }}",
"password": "{{ secrets.GHCR_TOKEN }}"
}
]
}
```
Store secrets in Renovate's encrypted secrets (Mend Renovate App) or as env vars when self-hosted.
---
## 7. Regex Managers
Use `regexManagers` when no native manager supports the file format.
### Terraform version in GitHub Actions workflows
```json
{
"description": "Track Terraform CLI version in workflow YAML",
"fileMatch": ["^\\.github/workflows/.*\\.ya?ml$"],
"matchStrings": [
"terraform_version:\\s*['\"]?(?<currentValue>[^'\"\\s]+)['\"]?"
],
"depNameTemplate": "hashicorp/terraform",
"datasourceTemplate": "github-releases",
"extractVersionTemplate": "^v(?<version>.*)$"
}
```
### Tool version in shell scripts
```json
{
"description": "Track kubectl version in install scripts",
"fileMatch": ["scripts/.*\\.sh$"],
"matchStrings": [
"KUBECTL_VERSION=['\"]?(?<currentValue>[^'\"\\s]+)['\"]?"
],
"depNameTemplate": "kubernetes/kubernetes",
"datasourceTemplate": "github-releases",
"extractVersionTemplate": "^v(?<version>.*)$"
}
```
### Flux version in documentation
```json
{
"description": "Track Flux CLI version in docs",
"fileMatch": ["^docs/.*\\.md$", "^examples/.*\\.md$"],
"matchStrings": [
"Flux CLI \\((?<currentValue>[^)]+)\\)"
],
"depNameTemplate": "fluxcd/flux2",
"datasourceTemplate": "github-releases",
"extractVersionTemplate": "^v(?<version>.*)$"
}
```
---
## 8. Troubleshooting
### `renovate-config-validator` errors
| Error | Cause | Fix |
|---|---|---|
| `Invalid preset: config:base` | Deprecated preset | Change to `config:recommended` |
| `matchManagers must be array` | Scalar instead of array | `"matchManagers": ["terraform"]` not `"matchManagers": "terraform"` |
| `Unknown option: pinDigest` | Typo — missing `s` | Use `pinDigests` (plural) |
| `extends: invalid` | Preset not found | Check preset name at [docs.renovatebot.com/presets](https://docs.renovatebot.com/presets-config/) |
### Coverage scan false positives
The `/platform-skills:renovate workflow` coverage scan checks for manager name strings in `renovate.json`. False positives occur when:
- A file type is present but intentionally excluded via `ignorePaths`
- A monorepo subdirectory is managed by a separate `renovate.json`
Suppress by adding the path to `ignorePaths` and noting it in the `description` field of the relevant `packageRule`.
### Rate limiting
Renovate enforces `prConcurrentLimit` (open PRs at once) and `prHourlyLimit` (PRs per hour). If updates are being skipped:
```json
{
"prConcurrentLimit": 10,
"prHourlyLimit": 0
}
```
Set `prHourlyLimit: 0` to disable hourly cap entirely (use with caution on large repos).
### Dependency Dashboard not appearing
1. Confirm `"dependencyDashboard": true` is in `renovate.json`
2. Check that the Renovate App has Issues write permission on the repo
3. Trigger a manual run via the App settings or by pushing a trivial changels -la /Users/nitin.jain/platform-skills/references/renovate.md
wc -l /Users/nitin.jain/platform-skills/references/renovate.mdExpected: file exists, >150 lines
git -C /Users/nitin.jain/platform-skills add references/renovate.md
git -C /Users/nitin.jain/platform-skills commit -m "feat: add references/renovate.md — manager catalog, presets, security, GitOps".github/workflows/validate-renovate.ymlFiles:
Create: .github/workflows/validate-renovate.yml
Step 1: Write the workflow file
Create /Users/nitin.jain/platform-skills/.github/workflows/validate-renovate.yml:
name: Validate Renovate Config
on:
pull_request:
paths:
- 'renovate.json'
permissions:
contents: read
jobs:
validate-schema:
name: Schema Validation
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Validate JSON syntax
run: |
if ! jq empty renovate.json; then
echo "❌ renovate.json is not valid JSON"
exit 1
fi
echo "✅ JSON syntax valid"
- name: Validate against Renovate schema
run: |
npm install --save-dev ajv-cli ajv-formats
npx ajv validate \
--spec=draft7 \
-s https://docs.renovatebot.com/renovate-schema.json \
-d renovate.json \
-c ajv-formats || {
echo "❌ renovate.json does not match Renovate schema"
exit 1
}
echo "✅ Schema validation passed"
validate-config:
name: Config Validator
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Run renovate-config-validator
run: |
npx --yes renovate-config-validator renovate.json
echo "✅ Config validation passed"
validate-coverage:
name: Coverage Scan
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Check manager coverage
run: |
UNCOVERED=0
check_coverage() {
local label="$1"
local pattern="$2"
local manager="$3"
if find . -path "./.git" -prune -o -name "$pattern" -print | grep -q .; then
if grep -q "\"$manager\"" renovate.json; then
echo "✅ COVERED: $label ($manager)"
else
echo "⚠️ UNCOVERED: $label ($manager) — files found but manager not referenced in renovate.json"
UNCOVERED=$((UNCOVERED + 1))
fi
else
echo "ℹ️ SKIPPED: $label — no matching files found"
fi
}
check_coverage "GitHub Actions" "*.yml" "github-actions"
check_coverage "Terraform" "*.tf" "terraform"
check_coverage "Helm" "Chart.yaml" "helmv3"
check_coverage "Go modules" "go.mod" "gomod"
check_coverage "npm" "package.json" "npm"
check_coverage "Python" "requirements*.txt" "pip_requirements"
check_coverage "Docker" "Dockerfile" "dockerfile"
check_coverage "Rust" "Cargo.toml" "cargo"
if [ $UNCOVERED -gt 0 ]; then
echo ""
echo "⚠️ $UNCOVERED ecosystem(s) detected but not covered by Renovate"
echo "Run /platform-skills:renovate generate to update your renovate.json"
else
echo "✅ All detected ecosystems are covered"
fi
summary:
name: Validation Summary
runs-on: ubuntu-latest
needs: [validate-schema, validate-config, validate-coverage]
if: always()
steps:
- name: Post summary
run: |
cat << 'EOF' >> $GITHUB_STEP_SUMMARY
## Renovate Config Validation
EOF
printf "| Check | Status |\n|-------|--------|\n" >> $GITHUB_STEP_SUMMARY
printf "| JSON Schema | %s |\n" "${{ needs.validate-schema.result == 'success' && '✅ Passed' || '❌ Failed' }}" >> $GITHUB_STEP_SUMMARY
printf "| Config Validator | %s |\n" "${{ needs.validate-config.result == 'success' && '✅ Passed' || '❌ Failed' }}" >> $GITHUB_STEP_SUMMARY
printf "| Coverage Scan | %s |\n" "${{ needs.validate-coverage.result == 'success' && '✅ Passed' || '⚠️ Warnings' }}" >> $GITHUB_STEP_SUMMARY
- name: Enforce required checks
run: |
if [[ "${{ needs.validate-schema.result }}" != "success" ]] || \
[[ "${{ needs.validate-config.result }}" != "success" ]]; then
echo "❌ Required validation checks failed — see jobs above"
exit 1
fi
echo "✅ All required checks passed"python3 -c "import yaml, sys; yaml.safe_load(open('.github/workflows/validate-renovate.yml'))" \
2>&1 && echo "✅ YAML valid" || echo "❌ YAML invalid"Run from /Users/nitin.jain/platform-skills. Expected: ✅ YAML valid
git -C /Users/nitin.jain/platform-skills add .github/workflows/validate-renovate.yml
git -C /Users/nitin.jain/platform-skills commit -m "ci: add validate-renovate workflow — schema, config-validator, coverage scan"renovate.jsonFiles:
Modify: renovate.json
Step 1: Add missing fields to renovate.json
The existing renovate.json already has GitHub Actions, Terraform, and Helm rules. Add:
dependencyDashboard and osvVulnerabilityAlerts after the "semanticCommits" lineminimumReleaseAge: "3 days" to the Terraform providers and Helm patch automerge rulespackageRules blocks for gomod, npm, and pip"npmDedupe" to postUpdateOptionsAfter "semanticCommits": "enabled", add:
"dependencyDashboard": true,
"dependencyDashboardTitle": "Renovate Dependency Dashboard",
"osvVulnerabilityAlerts": true,In the Terraform providers rule, add after "automergeType": "pr",:
"minimumReleaseAge": "3 days",In the Helm patch rule, add after "automergeType": "pr",:
"minimumReleaseAge": "3 days",In the stable patch automerge rule at the bottom, add:
"minimumReleaseAge": "3 days",Add new packageRules entries (before the closing ] of packageRules):
{
"description": "Go modules — automerge minor/patch",
"matchManagers": ["gomod"],
"automerge": true,
"automergeType": "pr",
"minimumReleaseAge": "3 days",
"matchUpdateTypes": ["minor", "patch"],
"groupName": "Go modules"
},
{
"description": "npm packages — automerge minor/patch",
"matchManagers": ["npm"],
"automerge": true,
"automergeType": "pr",
"minimumReleaseAge": "3 days",
"matchUpdateTypes": ["minor", "patch"],
"groupName": "npm packages"
},
{
"description": "Python packages — automerge minor/patch",
"matchManagers": ["pip_requirements", "pip-compile", "pipenv", "poetry"],
"automerge": true,
"automergeType": "pr",
"minimumReleaseAge": "3 days",
"matchUpdateTypes": ["minor", "patch"],
"groupName": "Python packages"
}Change "postUpdateOptions": ["gomodTidy"] to:
"postUpdateOptions": ["gomodTidy", "npmDedupe"]jq empty /Users/nitin.jain/platform-skills/renovate.json && echo "✅ JSON valid" || echo "❌ JSON invalid"Expected: ✅ JSON valid
git -C /Users/nitin.jain/platform-skills add renovate.json
git -C /Users/nitin.jain/platform-skills commit -m "chore: update renovate.json — add gomod/npm/pip rules, minimumReleaseAge, osvVulnerabilityAlerts"SKILL.md and COMMANDS.mdFiles:
Modify: SKILL.md
Modify: COMMANDS.md
Step 1: Add Renovate row to SKILL.md tool table
In SKILL.md, add this row after the Platform Mindset row (line 43):
| `Renovate` | Dependency update automation — generate renovate.json from repo scan, emit GHA validation workflow |Also add /platform-skills:renovate to the slash commands list in SKILL.md. Find the block listing slash commands and add:
- `/platform-skills:renovate` — generate renovate.json for any repo, or emit a GHA workflow to validate it on PRIn COMMANDS.md, add this row to the Table of Contents after the fluxcd row:
| [/platform-skills:renovate](#platform-skillsrenovate) | Generate renovate.json from repo scan or emit a GHA validation workflow |Append this section at the end of COMMANDS.md (after the /platform-skills:fluxcd section):
---
## `/platform-skills:renovate`
**What it does:** Scans your repo for dependency file types and emits a correct `renovate.json` covering only the ecosystems you use, or generates a GitHub Actions workflow that validates `renovate.json` on every PR that touches it.
**Works on:** Any repo using GitHub Actions, Terraform, Helm, Go, Node, Python, Docker, Rust, Kubernetes manifests, or any combination.
```
/platform-skills:renovate [generate|workflow]
```
**Modes:**
| Mode | What it does |
|------|-------------|
| `generate` | Scans repo → detects dep file types → emits renovate.json with per-ecosystem packageRules |
| `workflow` | Emits `.github/workflows/validate-renovate.yml` — schema + config-validator + coverage scan on PR |
**Examples:**
```
/platform-skills:renovate generate
/platform-skills:renovate workflow
/platform-skills:renovate
```
**Reference:** `references/renovate.md`grep "Renovate" /Users/nitin.jain/platform-skills/SKILL.md
grep "renovate" /Users/nitin.jain/platform-skills/COMMANDS.md | head -5Expected: at least one match in each file
git -C /Users/nitin.jain/platform-skills add SKILL.md COMMANDS.md
git -C /Users/nitin.jain/platform-skills commit -m "feat: add Renovate to SKILL.md tool table and COMMANDS.md"Files:
Modify: .claude-plugin/marketplace.json
Modify: .claude-plugin/plugin.json
Modify: tile.json
Modify: CHANGELOG.md
Modify: INSTALLATION.md
Step 1: Bump marketplace.json
In .claude-plugin/marketplace.json:
Change "version": "1.26.0" → "version": "1.27.0" (in plugins[0])
Add "renovate" to the keywords array
Update description to include "Renovate dependency automation"
Step 2: Bump plugin.json
In .claude-plugin/plugin.json:
Change "version": "1.26.0" → "version": "1.27.0"
Add "./commands/renovate.md" to the commands array (after "./commands/aws-profile.md")
Step 3: Bump tile.json
In tile.json:
Change "version": "1.25.20" → "version": "1.27.0"
Step 4: Add CHANGELOG entry
In CHANGELOG.md, add this block immediately after the first --- separator (before ## [1.26.0]):
## [1.27.0] - 2026-05-28
### Added
- `commands/renovate.md`: new `/platform-skills:renovate` command with two modes — `generate` (scan repo for dep file types, emit renovate.json covering only detected ecosystems with per-manager automerge/schedule/grouping rules) and `workflow` (emit `.github/workflows/validate-renovate.yml` for schema + config-validator + coverage validation on PRs).
- `references/renovate.md`: 8-section reference — manager catalog, preset reference, package rules patterns, dependency dashboard, GitOps integration (Renovate vs Flux Image Reflector ownership boundary), security hardening (pinDigests, osvVulnerabilityAlerts, minimumReleaseAge), regex manager templates, troubleshooting.
- `.github/workflows/validate-renovate.yml`: CI workflow triggering on PRs that touch `renovate.json` — three parallel jobs (schema via ajv, config-validator via npx, coverage bash scan) with `GITHUB_STEP_SUMMARY` result table. No secrets required.
- `renovate.json`: added `dependencyDashboard`, `osvVulnerabilityAlerts`, `minimumReleaseAge: "3 days"` on automerge rules, packageRules for `gomod`/`npm`/`pip`, `npmDedupe` postUpdateOption.
- `SKILL.md`: `Renovate` row in tool table; `/platform-skills:renovate` slash command entry.
- `COMMANDS.md`: TOC entry and full `/platform-skills:renovate` command section (31 commands total).
### Contributors
- [@geetika-sv](https://github.com/geetika-sv) — Renovate skillIn INSTALLATION.md line 63, change:
# platform-skills v1.26.0 enabledto:
# platform-skills v1.27.0 enabledjq empty /Users/nitin.jain/platform-skills/.claude-plugin/marketplace.json && echo "marketplace.json ✅"
jq empty /Users/nitin.jain/platform-skills/.claude-plugin/plugin.json && echo "plugin.json ✅"
jq empty /Users/nitin.jain/platform-skills/tile.json && echo "tile.json ✅"Expected: all three print ✅
git -C /Users/nitin.jain/platform-skills add \
.claude-plugin/marketplace.json \
.claude-plugin/plugin.json \
tile.json \
CHANGELOG.md \
INSTALLATION.md
git -C /Users/nitin.jain/platform-skills commit -m "chore: release v1.27.0 — renovate skill"Files: read-only validation
cd /Users/nitin.jain/platform-skills && bash tests/handbook-consistency.shExpected output ends with: ✅ Handbook consistency checks passed
The script verifies:
SKILL.md name matches marketplace.json name and plugin.json name
plugin.json version = marketplace.json version = latest CHANGELOG version (all must be 1.27.0)
INSTALLATION.md contains platform-skills v1.27.0 enabled
All required handbook paths exist
All examples/*/README.md files have a Status: label
Step 2: Validate YAML of the new workflow
python3 -c "
import yaml, sys
with open('/Users/nitin.jain/platform-skills/.github/workflows/validate-renovate.yml') as f:
yaml.safe_load(f)
print('✅ validate-renovate.yml YAML valid')
"Expected: ✅ validate-renovate.yml YAML valid
jq '.commands | map(select(contains("renovate")))' \
/Users/nitin.jain/platform-skills/.claude-plugin/plugin.jsonExpected: ["./commands/renovate.md"]
PLUGIN_VER=$(jq -r '.version' /Users/nitin.jain/platform-skills/.claude-plugin/plugin.json)
MARKET_VER=$(jq -r '.plugins[0].version' /Users/nitin.jain/platform-skills/.claude-plugin/marketplace.json)
CHANGE_VER=$(awk '$1=="##" && $2~/^\[[0-9]+\.[0-9]+\.[0-9]+\]$/{gsub(/[][]/,"",$2);print $2;exit}' \
/Users/nitin.jain/platform-skills/CHANGELOG.md)
echo "plugin.json: $PLUGIN_VER"
echo "marketplace.json: $MARKET_VER"
echo "CHANGELOG.md: $CHANGE_VER"
[[ "$PLUGIN_VER" == "1.27.0" && "$MARKET_VER" == "1.27.0" && "$CHANGE_VER" == "1.27.0" ]] \
&& echo "✅ All versions consistent" || echo "❌ Version mismatch"Expected: ✅ All versions consistent
If the consistency tests required edits, commit them:
git -C /Users/nitin.jain/platform-skills add -u
git -C /Users/nitin.jain/platform-skills commit -m "fix: address handbook consistency check failures"If no fixes were needed, skip this step.
commands/renovate.md (Tasks 1), references/renovate.md (Task 2), GHA workflow (Task 3), renovate.json patch (Task 4), SKILL.md/COMMANDS.md (Task 5), version bumps (Task 6), consistency tests (Task 7)actions/checkout uses de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 matching existing repo policyGITHUB_TOKEN — no secrets.claude-plugin
.github
commands
docs
examples
agent-self-improve
argocd
awesome-docs
aws
cloudfront
functions
lambda-edge
functions
azure
compliance
conventional-commits
datadog
llm-observability
demo
documentation
dora
dynatrace
fluxcd
github-actions
composite-actions
configure-cloud
db-migrate
docker-build-push
k8s-deploy
notify-slack
pr-comment
release-tag
security-scan
setup-env
setup-terraform
terraform-plan
helm
web-service
templates
kubernetes
kyverno
mcp
observability
openshift
pr-review
ownership
runtime-security
supply-chain
terraform
references
scripts
skills
platform-skills
tests