Skip to content

mirror-chart

mirror-chart #26616

Workflow file for this run

name: Mirror External Helm Chart
# Mirrors a single upstream chart version into oci://ghcr.io/fredericrous/charts.
#
# Fired by repository_dispatch from fredericrous/homelab's mirror-discover
# workflow, which walks HelmRelease + HelmRepository CRDs and sends one
# event per (chart, version, upstream) tuple. workflow_dispatch is also
# kept for ad-hoc manual mirroring.
#
# Idempotent: if the chart@version already exists in the target OCI
# registry, the run skips the pull+push and exits successfully.
on:
repository_dispatch:
types: [mirror-chart]
workflow_dispatch:
inputs:
chart:
description: 'Chart name (e.g. tetragon)'
required: true
type: string
version:
description: 'Chart version (e.g. 1.7.0)'
required: true
type: string
upstream:
description: 'Upstream Helm repo URL (e.g. https://helm.cilium.io)'
required: true
type: string
permissions:
contents: read
packages: write
jobs:
mirror:
name: Pull from upstream, push to OCI
runs-on: ubuntu-latest
steps:
- name: Resolve inputs
id: in
run: |
if [ "${{ github.event_name }}" = "repository_dispatch" ]; then
chart='${{ github.event.client_payload.chart }}'
version='${{ github.event.client_payload.version }}'
upstream='${{ github.event.client_payload.upstream }}'
else
chart='${{ inputs.chart }}'
version='${{ inputs.version }}'
upstream='${{ inputs.upstream }}'
fi
for v in chart version upstream; do
if [ -z "${!v}" ]; then
echo "::error::missing input: $v"
exit 1
fi
done
echo "chart=$chart" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "upstream=$upstream" >> "$GITHUB_OUTPUT"
echo "Mirroring ${chart}@${version} from ${upstream}"
- name: Set up Helm
uses: azure/setup-helm@v4
with:
version: v3.13.3
- name: Log in to GHCR
run: echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Mirror chart
env:
CHART: ${{ steps.in.outputs.chart }}
VERSION: ${{ steps.in.outputs.version }}
UPSTREAM: ${{ steps.in.outputs.upstream }}
run: |
set -euo pipefail
target="oci://ghcr.io/${{ github.repository_owner }}/charts"
# Skip if this version already exists in the target OCI registry.
# `helm show chart` on the OCI ref succeeds only if the artifact
# is present.
if helm show chart "${target}/${CHART}" --version "${VERSION}" >/dev/null 2>&1; then
echo "${CHART}@${VERSION} already mirrored — skipping"
exit 0
fi
workdir=$(mktemp -d)
if ! helm pull "${CHART}" --repo "${UPSTREAM}" --version "${VERSION}" --destination "${workdir}"; then
echo "::error::helm pull failed for ${CHART}@${VERSION} from ${UPSTREAM}"
exit 1
fi
# Some charts publish versions as `v1.2.3` (leading `v`), which
# makes the tgz filename `<chart>-v1.2.3.tgz` rather than
# `<chart>-1.2.3.tgz`. Glob-match so both conventions work.
tgz=$(ls "${workdir}"/${CHART}-*.tgz 2>/dev/null | head -1 || true)
if [ -z "${tgz}" ] || [ ! -f "${tgz}" ]; then
echo "::error::no tgz found in ${workdir} after pull (expected ${CHART}-*.tgz)"
exit 1
fi
if ! helm push "${tgz}" "${target}"; then
echo "::error::helm push failed for ${CHART}@${VERSION}"
exit 1
fi
echo "mirrored → ${target}/${CHART}:${VERSION}"