Reusable GitHub Actions workflows for Helm chart repositories.
For individual chart repositories (e.g., chart-keycloak, chart-grafana):
| Workflow | Purpose |
|---|---|
| sync-upstream.yml | Sync from upstream submodules |
| release-please.yml | Automate releases with semantic versioning + π€ AI-enhanced changelogs |
| publish-chart.yml | Publish to OCI and trigger registry update |
| validate-licenses.yml | π License validation with AI compatibility analysis |
| scan-images.yml | Security scan with Trivy |
| replicate-images.yml | Mirror images to private registry |
| update-images.yml | Check for new container versions with Renovate + π€ AI-enhanced analysis |
| cleanup-releases.yml | Prune old releases and tags |
For the central registry repository (e.g., helm-charts):
| Workflow | Purpose |
|---|---|
| update-registry.yml | Pull charts from OCI, update index, deploy Pages |
GitHub App (Recommended):
- Organization variable:
APP_ID - Organization secret:
APP_PRIVATE_KEY - Permissions: Contents (RW), Packages (RW), Metadata (R)
- See ./docs/GITHUB_APP_SETUP.md
Repository Permissions:
- Settings β Actions β General β "Read and write permissions"
- β "Allow GitHub Actions to create and approve pull requests"
# .github/workflows/sync.yml
name: Sync
on:
schedule:
- cron: '0 0 * * 0'
workflow_dispatch:
jobs:
sync:
uses: chronolite-technologies/helm-workflows/.github/workflows/sync-upstream.yml@main
with:
upstream-path: upstream/source
chart-path: charts/chart-nameCreate .release-please-manifest.json:
{
".": "1.0.0"
}Create release-please-config.json:
{
"packages": {
".": {
"release-type": "simple",
"package-name": "chart-name",
"extra-files": [{
"type": "yaml",
"path": "charts/chart-name/Chart.yaml",
"jsonpath": "$.version"
}]
}
}
}Create .github/workflows/release-please.yml:
name: Release Please
on:
push:
branches: [main]
jobs:
release:
uses: chronolite-technologies/helm-workflows/.github/workflows/release-please.yml@main
with:
chart-path: charts/chart-name
chart-name: chart-name
secrets: inheritVersion bumps:
fix:β patch (1.0.0 β 1.0.1)feat:β minor (1.0.0 β 1.1.0)feat!:β major (1.0.0 β 2.0.0)
Create .images.yaml:
registry:
prefix: mirrors
images:
keycloak:
source: quay.io/keycloak/keycloak
versions: ["26.0.0"]Create .github/workflows/scan.yml:
name: Scan
on:
schedule:
- cron: '0 2 * * *'
workflow_dispatch:
jobs:
scan:
uses: chronolite-technologies/helm-workflows/.github/workflows/scan-images.yml@main
with:
severity: CRITICALCreate .github/workflows/update-images.yml:
name: Update Images
on:
schedule:
- cron: '0 1 * * 1' # Weekly
workflow_dispatch:
jobs:
update:
uses: chronolite-technologies/helm-workflows/.github/workflows/update-images.yml@main
secrets: inheritOptional - custom Renovate config (.github/renovate.json):
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:base"],
"packageRules": [
{
"matchDatasources": ["docker"],
"matchUpdateTypes": ["patch"],
"automerge": true
}
]
}How it works:
- Renovate scans
.images.yamlfor version updates - Queries container registries for new versions
- Creates PRs with updated versions
- Skips floating tags (latest, nightly)
Create .github/workflows/replicate.yml:
name: Replicate
on:
schedule:
- cron: '0 3 * * *'
workflow_dispatch:
jobs:
replicate:
uses: chronolite-technologies/helm-workflows/.github/workflows/replicate-images.yml@main
secrets: inheritCreate .github/workflows/cleanup.yml:
name: Cleanup
on:
schedule:
- cron: '0 4 * * 0'
workflow_dispatch:
jobs:
cleanup:
uses: chronolite-technologies/helm-workflows/.github/workflows/cleanup-releases.yml@main
with:
keep-count: 10Create .github/workflows/update-index.yml:
name: Update Index
on:
repository_dispatch:
types: [chart-published]
workflow_dispatch:
permissions:
contents: write
packages: read
jobs:
update:
uses: chronolite-technologies/helm-workflows/.github/workflows/update-registry.yml@main
with:
chart-name: ${{ github.event.client_payload.chart }}
chart-version: ${{ github.event.client_payload.version }}
oci-url: ${{ github.event.client_payload.oci_url }}
secrets: inheritHow it works:
- Chart repo creates release tag
publish-chart.ymlpublishes to GHCR- Sends
repository_dispatchto registry repo - Registry pulls from OCI, updates index.yaml, deploys to Pages
chart-keycloak (chart repo)
ββ Release tag created
ββ publish-chart.yml
ββ Push to OCI (ghcr.io)
ββ Dispatch event
ββ helm-charts (registry repo)
ββ update-registry.yml
ββ Pull from OCI
ββ Update index.yaml
ββ Deploy to Pages
Parallel Automation:
ββ update-images.yml β Check for new versions (weekly)
ββ scan-images.yml β Security scans (daily)
ββ replicate-images.yml β Mirror images (daily)
- HELM-OPS-CONCEPT.md - Architecture overview
- ./docs/GITHUB_APP_SETUP.md - GitHub App configuration
- docs/ai-changelog.md - π€ AI-Enhanced Changelogs setup and usage
- docs/license-validation.md - π License Validation with AI compatibility analysis
- docs/ai-image-updates.md - π AI-Enhanced Image Updates with Renovate
- docs/renovate-enhanced.md - Enhanced Renovate configuration guide
The release-please workflow automatically generates user-friendly, comprehensive release notes using OpenAI GPT-4o:
- β Transforms technical commits into user-friendly descriptions
- β Categorizes changes (Features, Bug Fixes, Security, etc.)
- β Explains impact and context
- β Highlights breaking changes with migration steps
- β Cost-effective (~$0.03 per release)
- β Automatic fallback if AI unavailable
Setup: Add OPENAI_API_KEY to repository secrets. See docs/ai-changelog.md for details.
The validate-licenses workflow validates license files with modular JavaScript architecture and optional AI-powered compatibility analysis:
- β
Validates all declared licenses in
.licenses.yaml - β Tracks upstream license changes (git history)
- β AI compatibility analysis with OpenAI GPT-4o
- β Automatic GitHub issue creation on failures
- β Comprehensive summary reports
- β Cost-effective (~$0.008 per validation)
- β Works without AI (validation + tracking only)
Setup: Create .licenses.yaml in repository root. Add OPENAI_API_KEY for AI analysis (optional). See docs/license-validation.md for details.
The update-images workflow uses Renovate Bot with AI-powered analysis to intelligently manage container image updates:
- β 50% fewer manual PR reviews - AI pre-screens updates for breaking changes
- β Faster security updates - Patch updates auto-merge safely after stabilization period
- β Better visibility - Clear risk levels (π’ Low, π‘ Medium, π΄ High) and actionable recommendations
- β Smart grouping - Separate PRs by risk (patch/minor/major)
- β Intelligent auto-merge - Safe automatic merging for low-risk patches
- β
Cost-effective -
$0.02 per image update ($2-5/month total)
How it works:
- Renovate detects updates β Creates PR for image version changes
- Fetches changelog data β Multiple sources (Docker Hub, GitHub Releases, CHANGELOG.md)
- AI analysis β OpenAI GPT-4o analyzes breaking changes, security impacts, migration requirements
- Enhances PR β Adds detailed analysis, risk labels, auto-merge recommendations
- Auto-merge β Low-risk patches merge automatically after stabilization period
Setup:
- Add
OPENAI_API_KEYto repository secrets (required for AI analysis) - Optional: Create
.github/renovate.jsonfor custom rules (uses enhanced config by default) - See docs/ai-image-updates.md and docs/renovate-enhanced.md for details.
License: Apache 2.0 β’ Maintainer: Chronolite Technologies