A composite GitHub Action that packages Helm charts, publishes them to a gh-pages branch as a Helm repo, and pushes them to an OCI registry — all in one step. Internally delegates OCI push to somaz94/helm-oci-push-action.
- One action for the full release pipeline:
helm package→ gh-pages index merge + publish → OCI registry push - Two modes:
single(one chart_path) andmulti(scan every subdirectory ofcharts_dir) - Independent toggles:
enable_gh_pages,enable_oci_push dry_runfor PR validation (no gh-pages commit, no OCI push)- Automatic
appVersionbump from the release tag (single mode) - Ships with
azure/setup-helm@v5(latest stable helm by default, pin viahelm_versionif needed)
name: Helm Chart Release
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
workflow_dispatch:
permissions:
contents: write
packages: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.PAT_TOKEN }}
- uses: somaz94/helm-chart-release-action@v1
with:
mode: single
chart_path: ./helm/my-app
gh_pages_url: https://somaz94.github.io/my-app/helm-repo
registry_password: ${{ secrets.GITHUB_TOKEN }}- uses: somaz94/helm-chart-release-action@v1
with:
mode: multi
charts_dir: charts
gh_pages_url: https://somaz94.github.io/my-charts/helm-repo
registry_password: ${{ secrets.GITHUB_TOKEN }}- uses: somaz94/helm-chart-release-action@v1
with:
mode: single
chart_path: ./helm/my-app
enable_gh_pages: false
registry_password: ${{ secrets.GITHUB_TOKEN }}- uses: somaz94/helm-chart-release-action@v1
with:
mode: single
chart_path: ./helm/my-app
gh_pages_url: https://somaz94.github.io/my-app/helm-repo
enable_oci_push: false- uses: somaz94/helm-chart-release-action@v1
with:
mode: single
chart_path: ./helm/my-app
gh_pages_url: https://somaz94.github.io/my-app/helm-repo
dry_run: true
registry_password: ${{ secrets.GITHUB_TOKEN }}- uses: somaz94/helm-chart-release-action@v1
with:
mode: multi
charts_dir: charts
gh_pages_url: https://somaz94.github.io/my-charts/helm-repo
skip_existing: true
registry_password: ${{ secrets.GITHUB_TOKEN }}- uses: somaz94/helm-chart-release-action@v1
with:
mode: single
chart_path: ./helm/my-app
update_dependencies: true # runs `helm dependency update` first
gh_pages_url: https://somaz94.github.io/my-app/helm-repo
registry_password: ${{ secrets.GITHUB_TOKEN }}- uses: somaz94/helm-chart-release-action@v1
with:
mode: single
chart_path: ./helm/my-app
helm_package_args: --version 1.2.3 --app-version 1.2.3
gh_pages_url: https://somaz94.github.io/my-app/helm-repo
registry_password: ${{ secrets.GITHUB_TOKEN }}Pass a full OCI URL. If you've already authenticated via a provider-specific action, set registry_password empty and toggle login off via the underlying action — or use helm-oci-push-action directly for more control.
- uses: somaz94/helm-chart-release-action@v1
with:
mode: multi
charts_dir: charts
enable_gh_pages: false
registry: oci://harbor.example.com/charts
registry_username: ${{ secrets.HARBOR_USER }}
registry_password: ${{ secrets.HARBOR_TOKEN }}| Input | Description | Required | Default |
|---|---|---|---|
mode |
single or multi |
Yes | — |
chart_path |
Chart directory (mode=single) | single | '' |
charts_dir |
Directory with chart subdirectories (mode=multi) | multi | '' |
update_appversion |
Bump Chart.yaml appVersion from GITHUB_REF_NAME |
No | true |
update_dependencies |
Run helm dependency update before packaging (for charts with subchart dependencies) |
No | false |
helm_package_args |
Extra CLI args forwarded to helm package (e.g., --version 1.2.3 --app-version 1.2.3) |
No | '' |
enable_gh_pages |
Publish to gh-pages branch | No | true |
enable_oci_push |
Push to OCI registry | No | true |
gh_pages_url |
Helm repo base URL (required when enable_gh_pages=true) |
conditional | '' |
gh_pages_branch |
gh-pages branch name | No | gh-pages |
commit_message |
gh-pages commit message | No | chore: update helm chart repository |
git_user_name |
gh-pages commit author name | No | GitHub Actions |
git_user_email |
gh-pages commit author email | No | [email protected] |
registry |
Target OCI registry URL | No | oci://ghcr.io/${{ github.repository_owner }}/charts |
registry_login |
Forwarded to helm-oci-push-action: log in inside the action | No | true |
registry_username |
OCI username | No | ${{ github.actor }} |
registry_password |
OCI token (typically secrets.GITHUB_TOKEN for GHCR) |
No | '' |
skip_existing |
Forwarded to helm-oci-push-action: skip chart@version already in registry (idempotent) | No | false |
helm_version |
Helm CLI version for azure/setup-helm (latest or pin like v3.16.4) |
No | latest |
dry_run |
Skip actual commit/push (both gh-pages and OCI) | No | false |
oci_continue_on_error |
Forwarded to helm-oci-push-action: keep pushing the other charts and publish gh-pages when one push fails |
No | true |
fail_on_oci_error |
Fail the step at the very end, after gh-pages is published, when any OCI push failed. false keeps a failed push green |
No | true |
| Output | Description |
|---|---|
pushed_charts |
Comma-separated name:version pairs pushed to OCI |
skipped_charts |
Comma-separated name:version pairs skipped (dry-run or already exists) |
failed_charts |
Comma-separated name:version pairs whose OCI push failed (non-empty only with oci_continue_on_error) |
With the defaults, a chart whose push still fails after its retries does not stop the other charts or gh-pages, and the step then fails with the list of failed charts. Set fail_on_oci_error: false to keep the step green and handle failed_charts yourself.
Caller workflow needs:
permissions:
contents: write # for gh-pages commit
packages: write # for GHCR pushAnd actions/checkout with fetch-depth: 0 + a PAT token (so the action can push to gh-pages):
- uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.PAT_TOKEN }}azure/setup-helminstalls Helm (helm_versionempty = latest stable; pin a specific version if reproducibility matters).update_appversion(single + flag): rewritesChart.yamlappVersionfromGITHUB_REF_NAME.update_dependencies(optional): runshelm dependency updateon the chart(s).helm packageproduces.tgz(s) inhelm-repo/(extra args viahelm_package_args).- OCI push (
enable_oci_push=true): delegates tosomaz94/helm-oci-push-action@v1withtarballs: helm-repo/*.tgz. Runs before gh-pages because that step rewrites the working tree, and the underlying Docker action can only see${{ github.workspace }}. - gh-pages (
enable_gh_pages=true): merges existingindex.yaml, stasheshelm-repo/to/tmp, switches to thegh-pagesbranch, adds the staged files next to the charts already published there (older versions stay downloadable), commits, and pushes. - OCI failure check (
fail_on_oci_error=true): fails the step whenfailed_chartsis non-empty, last so nothing else is skipped.
This project is licensed under the MIT License — see the LICENSE file for details.