Centralized reusable GitHub Actions workflows for all MorePET repositories.
File: .github/workflows/renovate-reusable.yml
A single reusable workflow for all Renovate use cases. Consuming repos create multiple workflows calling this with different config files.
MorePET uses three specialized Renovate workflows in each consuming repo:
| Workflow | Trigger | Purpose |
|---|---|---|
renovate-external-dependencies.yml |
Scheduled (weekly) | PyPI, pre-commit, GitHub Actions |
renovate-internal-dependencies.yml |
Triggered by releases | MorePET internal packages/tools |
renovate-internal-containers.yml |
Triggered by releases | MorePET container images |
All three call the same reusable workflow with different config files.
Purpose: Updates from PyPI, pre-commit, GitHub Actions
Create in your repo: .github/workflows/renovate-external-dependencies.yml
---
name: Renovate (External Dependencies)
on:
schedule:
- cron: '0 2 * * 1' # Weekly on Monday at 2 AM UTC
workflow_dispatch:
jobs:
renovate:
uses: MorePET/github-actions/.github/workflows/renovate-reusable.yml@main
with:
config_file: '.github/renovate-external-dependencies.json'
secrets:
token: ${{ secrets.RENOVATE_TOKEN }}Config: .github/renovate-external-dependencies.json (see templates below)
Purpose: Updates from MorePET internal packages/tools (triggered by package releases)
Create in your repo: .github/workflows/renovate-internal-dependencies.yml
---
name: Renovate (Internal Dependencies)
on:
workflow_dispatch: # Triggered by internal MorePET package releases
jobs:
renovate:
uses: MorePET/github-actions/.github/workflows/renovate-reusable.yml@main
with:
config_file: '.github/renovate-internal-dependencies.json'
secrets:
token: ${{ secrets.RENOVATE_TOKEN }}Config: .github/renovate-internal-dependencies.json (see templates below)
Purpose: Updates from MorePET container images (triggered by MorePET/containers releases)
Create in your repo: .github/workflows/renovate-internal-containers.yml
---
name: Renovate (Internal Containers)
on:
workflow_dispatch: # Triggered by MorePET/containers releases
jobs:
renovate:
uses: MorePET/github-actions/.github/workflows/renovate-reusable.yml@main
with:
config_file: '.github/renovate-internal-containers.json'
secrets:
token: ${{ secrets.RENOVATE_TOKEN }}Config: .github/renovate-internal-containers.json (see templates below)
Monitored Container Types:
- Devcontainers (
.devcontainer/devcontainer.json) - Docker/Podman (
Dockerfile,Containerfile) - Compose (
docker-compose.yml,podman-compose.yml)
File: .github/renovate-external-dependencies.json
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"],
"packageRules": [
{
"description": "Security patches - immediate",
"matchUpdateTypes": ["patch"],
"matchManagers": ["pep621"],
"vulnerabilityAlerts": { "enabled": true },
"automerge": true,
"automergeType": "pr",
"minimumReleaseAge": null,
"schedule": ["at any time"],
"labels": ["dependencies", "security", "patch", "automerge"]
},
{
"description": "Patch updates - 3 day soak time",
"matchUpdateTypes": ["patch"],
"matchManagers": ["pep621"],
"groupName": "Python patch updates",
"automerge": true,
"automergeType": "pr",
"minimumReleaseAge": "3 days",
"schedule": ["at any time"],
"labels": ["dependencies", "patch", "automerge"]
},
{
"description": "Minor updates - manual review",
"matchUpdateTypes": ["minor"],
"matchManagers": ["pep621"],
"groupName": "Python minor updates",
"automerge": false,
"schedule": ["every weekend"],
"labels": ["dependencies", "minor"]
},
{
"description": "Major updates - manual review",
"matchUpdateTypes": ["major"],
"matchManagers": ["pep621"],
"groupName": "Python major updates",
"automerge": false,
"schedule": ["every 2 weeks on Monday"],
"labels": ["dependencies", "major"]
},
{
"description": "Pre-commit hooks",
"matchManagers": ["pre-commit"],
"groupName": "Pre-commit hooks",
"automerge": false,
"schedule": ["every 2 weeks on Monday"],
"labels": ["dependencies", "pre-commit"]
},
{
"description": "GitHub Actions",
"matchManagers": ["github-actions"],
"groupName": "GitHub Actions",
"automerge": true,
"automergeType": "pr",
"schedule": ["every 2 weeks on Monday"],
"labels": ["dependencies", "github-actions", "automerge"]
}
],
"prConcurrentLimit": 5,
"prHourlyLimit": 2
}File: .github/renovate-internal-dependencies.json
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"],
"packageRules": [
{
"description": "Internal MorePET packages - security patches",
"matchUpdateTypes": ["patch"],
"matchManagers": ["pep621"],
"matchPackagePatterns": ["^morepet-", "^MorePET/"],
"vulnerabilityAlerts": { "enabled": true },
"automerge": true,
"automergeType": "pr",
"minimumReleaseAge": null,
"schedule": ["at any time"],
"labels": ["dependencies", "internal", "security", "patch", "automerge"]
},
{
"description": "Internal MorePET packages - patch updates",
"matchUpdateTypes": ["patch"],
"matchManagers": ["pep621"],
"matchPackagePatterns": ["^morepet-", "^MorePET/"],
"groupName": "MorePET internal patch updates",
"automerge": true,
"automergeType": "pr",
"minimumReleaseAge": "3 days",
"schedule": ["at any time"],
"labels": ["dependencies", "internal", "patch", "automerge"]
},
{
"description": "Internal MorePET packages - minor/major manual review",
"matchUpdateTypes": ["minor", "major"],
"matchManagers": ["pep621"],
"matchPackagePatterns": ["^morepet-", "^MorePET/"],
"automerge": false,
"schedule": ["at any time"],
"labels": ["dependencies", "internal"]
}
],
"hostRules": [
{
"matchHost": "https://github.com",
"hostType": "github-packages"
}
],
"prConcurrentLimit": 5,
"prHourlyLimit": 2
}File: .github/renovate-internal-containers.json
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"],
"packageRules": [
{
"description": "MorePET containers - all types (Docker, Podman, devcontainer, compose)",
"matchManagers": ["devcontainer", "docker", "docker-compose"],
"matchPackagePatterns": ["ghcr.io/morepet/containers/"],
"automerge": false,
"schedule": ["at any time"],
"labels": ["dependencies", "internal", "container"]
}
],
"prConcurrentLimit": 5,
"prHourlyLimit": 2
}Internal dependencies and containers use auto-discovery to trigger consuming repos:
- Producer repo releases (e.g., MorePET/containers tags new image)
- Search for consumers via GitHub Code Search API
- Find all repos with the corresponding workflow file
- Trigger workflows automatically in those repos
- Create PRs within minutes of release
Add to your release workflow (in MorePET/containers or internal package repos):
name: Release
on:
pull_request:
types: [closed]
branches: [main]
jobs:
release:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
# Your build/release steps here
- name: Trigger Renovate in consuming repos
run: |
# For containers: renovate-internal-containers.yml
# For packages: renovate-internal-dependencies.yml
WORKFLOW_FILE="renovate-internal-containers.yml"
echo "Finding repos with $WORKFLOW_FILE..."
gh api "/search/code?q=path:.github/workflows/${WORKFLOW_FILE}+org:MorePET" \
--jq '.items[].repository.name' | \
while read -r repo; do
echo "Triggering $WORKFLOW_FILE in MorePET/$repo..."
gh workflow run "$WORKFLOW_FILE" \
--repo "MorePET/$repo" \
--ref main || echo "Failed to trigger $repo"
done
env:
GH_TOKEN: ${{ secrets.ORG_PAT }}Required in Producer Repos:
- Organization-wide PAT with
actions:writepermission - Add as secret:
ORG_PAT - Use semantic versioning for releases
- Zero maintenance - No list of consuming repos to update
- Self-service - Repos opt-in by adding the workflow
- Automatic discovery - New consumers automatically included
- Loose coupling - Repos discover each other via workflow presence
| Update Type | Soak Time | Auto-merge? | Labels |
|---|---|---|---|
| Security Patch | Immediate | ✅ Yes | security, patch, automerge |
| Patch (x.x.N) | 3 days | ✅ Yes | patch, automerge |
| Minor (x.N.0) | - | ❌ No (manual review) | minor |
| Major (N.0.0) | - | ❌ No (manual review) | major |
Same strategy as external, applies to MorePET internal packages:
| Update Type | Soak Time | Auto-merge? | Labels |
|---|---|---|---|
| Security Patch | Immediate | ✅ Yes | internal, security, patch, automerge |
| Patch (x.x.N) | 3 days | ✅ Yes | internal, patch, automerge |
| Minor (x.N.0) | - | ❌ No (manual review) | internal, minor |
| Major (N.0.0) | - | ❌ No (manual review) | internal, major |
All container updates require manual review:
| Update Type | Auto-merge? | Labels |
|---|---|---|
| All updates | ❌ No (manual review) | internal, container |
File: .github/workflows/ci-python-reusable.yml
Usage in your repo:
Create .github/workflows/ci.yml:
---
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
uses: MorePET/github-actions/.github/workflows/ci-python-reusable.yml@mainWith custom Python version:
jobs:
test:
uses: MorePET/github-actions/.github/workflows/ci-python-reusable.yml@main
with:
python_version: '3.11'
run_tests: true- Copy
.github/workflows/ci.yml - Create fine-grained PAT with permissions:
- Contents: Read and write
- Pull requests: Read and write
- Workflows: Read and write
- Add PAT as repository secret:
RENOVATE_TOKEN - Enable auto-merge in repository settings (Settings → General → Pull Requests)
- Push to main branch
- Copy
.github/workflows/renovate-external-dependencies.yml - Copy
.github/renovate-external-dependencies.json - Manually trigger workflow to test
- Copy
.github/workflows/renovate-internal-dependencies.yml - Copy
.github/renovate-internal-dependencies.json - Ensure producer repos have trigger logic
- Copy
.github/workflows/renovate-internal-containers.yml - Copy
.github/renovate-internal-containers.json - Ensure MorePET/containers has trigger logic
- Add all above (internal dependencies or containers)
- Add release workflow with auto-discovery trigger
- Create organization PAT:
ORG_PAT - Use semantic versioning for releases (
v1.2.3)
For auto-discovery to work with internal packages:
- ✅ Use semantic versioning (
v1.2.3) - ✅ Create GitHub releases or tags
- ✅ Follow semver conventions (MAJOR.MINOR.PATCH)
- ✅ Add trigger logic to release workflow
| Secret | Purpose | Permissions |
|---|---|---|
RENOVATE_TOKEN |
Renovate automation | Contents, PRs, Workflows (Read + Write) |
| Secret | Purpose | Permissions |
|---|---|---|
ORG_PAT |
Trigger workflows in other repos | Actions (Write) |
→ Check workflow logs, may indicate:
- No updates available
- Configuration error
- Token permissions issue
→ Check producer repo has:
- Trigger logic in release workflow
- Organization PAT with correct permissions
- Correct workflow file name in search
→ Verify:
- Container image is from
ghcr.io/morepet/containers/* - Container file is in supported location
- Renovate config includes correct manager
→ Fine-grained PATs expire after 90 days, create new one
- Pin action versions - Let Renovate update them
- Enable branch protection - Require PR reviews and CI
- Monitor Actions tab - Check for failed workflows
- Review security PRs promptly - They auto-merge after CI