feat: mirror CloudFront-only charts into Harbor #1

Merged
hermes merged 1 commit from feat/mirror-workflow into main 2026-09-24 17:39:40 +00:00
Collaborator

What this repo is

Charts our cluster cannot take from their upstream location. The workflow packages a chart from its upstream release tag and pushes it to oci://harbor.grachevko.ru/charts, and the cluster takes it from there with an OCIRepository.

Why

Harbor and Vault publish their chart from a git repository, and both chart repositories (helm.goharbor.io, helm.releases.hashicorp.com) are served by CloudFront: measured from our network, curl -4 https://helm.goharbor.io/index.yaml answers 200 with Content-Length: 95085 and then stalls after 11203 bytes (90 s timeout), while HashiCorp's index answers 403. A HelmRepository source cannot be built from either, so both apps in grachevko/home-ops take their chart from a GitRepository today, and a chart in a git repository is what no cluster-level check can inflate.

What lands here

  • .github/workflows/mirror-charts.yaml: daily schedule plus workflow_dispatch with chart and version inputs; idempotent, a chart version already present in Harbor is skipped before packaging; the push is verified with helm show chart against the registry.
  • README.md: what the repo is for, how to add a chart, the tag rule and which secrets it needs.

Verified

  • The packaging half ran locally with the same tools the job pod has: release-tag resolution through the release redirect (goharbor/harbor-helm -> v1.19.2, hashicorp/vault-helm -> v0.34.1), archive directory naming (harbor-helm-1.19.2, vault-helm-0.34.1) and helm package output names (harbor-1.19.2.tgz, vault-0.34.1.tgz).
  • zizmor --offline reports no findings: inputs and secrets reach the script through env:, because interpolating them into run: is a template-injection finding.
  • The Harbor project charts exists and is public (checked anonymously through its API) and is empty, so the first run has both charts to push. The repository secrets HARBOR_ROBOT_USER and HARBOR_ROBOT_TOKEN are already set here and are not read by the workflow at rest.

After merge

Run Mirror Charts once with chart: all. Expected: two artifacts (harbor:1.19.2, vault:0.34.1), pullable anonymously, after which grachevko/home-ops can switch both apps to an OCIRepository of this mirror and bring the cluster-level chart check.

Rollback

Revert the commit: the workflow disappears, nothing else depends on it yet.

## What this repo is Charts our cluster cannot take from their upstream location. The workflow packages a chart from its upstream release tag and pushes it to `oci://harbor.grachevko.ru/charts`, and the cluster takes it from there with an `OCIRepository`. ## Why Harbor and Vault publish their chart from a git repository, and both chart repositories (`helm.goharbor.io`, `helm.releases.hashicorp.com`) are served by CloudFront: measured from our network, `curl -4 https://helm.goharbor.io/index.yaml` answers 200 with `Content-Length: 95085` and then stalls after 11203 bytes (90 s timeout), while HashiCorp's index answers 403. A HelmRepository source cannot be built from either, so both apps in grachevko/home-ops take their chart from a GitRepository today, and a chart in a git repository is what no cluster-level check can inflate. ## What lands here - `.github/workflows/mirror-charts.yaml`: daily schedule plus `workflow_dispatch` with `chart` and `version` inputs; idempotent, a chart version already present in Harbor is skipped before packaging; the push is verified with `helm show chart` against the registry. - `README.md`: what the repo is for, how to add a chart, the tag rule and which secrets it needs. ## Verified - The packaging half ran locally with the same tools the job pod has: release-tag resolution through the release redirect (goharbor/harbor-helm -> v1.19.2, hashicorp/vault-helm -> v0.34.1), archive directory naming (harbor-helm-1.19.2, vault-helm-0.34.1) and `helm package` output names (harbor-1.19.2.tgz, vault-0.34.1.tgz). - `zizmor --offline` reports no findings: inputs and secrets reach the script through `env:`, because interpolating them into `run:` is a template-injection finding. - The Harbor project `charts` exists and is public (checked anonymously through its API) and is empty, so the first run has both charts to push. The repository secrets `HARBOR_ROBOT_USER` and `HARBOR_ROBOT_TOKEN` are already set here and are not read by the workflow at rest. ## After merge Run `Mirror Charts` once with `chart: all`. Expected: two artifacts (`harbor:1.19.2`, `vault:0.34.1`), pullable anonymously, after which grachevko/home-ops can switch both apps to an `OCIRepository` of this mirror and bring the cluster-level chart check. ## Rollback Revert the commit: the workflow disappears, nothing else depends on it yet.
## What this repo is

Charts our cluster cannot take from their upstream location. The workflow packages a chart from
its upstream release tag and pushes it to `oci://harbor.grachevko.ru/charts`, and the cluster
takes it from there with an `OCIRepository`.

## Why

Harbor and Vault publish their chart from a git repository, and both chart repositories
(`helm.goharbor.io`, `helm.releases.hashicorp.com`) are served by CloudFront: measured from our
network, `curl -4 https://helm.goharbor.io/index.yaml` answers 200 with `Content-Length: 95085`
and then stalls after 11203 bytes (90 s timeout), while HashiCorp's index answers 403. A
HelmRepository source cannot be built from either, so both apps in `grachevko/home-ops` take
their chart from a `GitRepository` today, and a chart in a git repository is what no cluster-level
check can inflate.

## What lands here

- `.github/workflows/mirror-charts.yaml`: daily schedule plus `workflow_dispatch` with `chart`
  and `version` inputs; idempotent, a chart version already present in Harbor is skipped before
  packaging; the push is verified with `helm show chart` from the registry.
- `README.md`: what the repo is for, how to add a chart, the tag rule and which secrets it needs.

## Verified

- The packaging half ran locally with the same tools the job pod has: release-tag resolution
  through the release redirect (`goharbor/harbor-helm` -> `v1.19.2`, `hashicorp/vault-helm` ->
  `v0.34.1`), archive directory naming (`harbor-helm-1.19.2`, `vault-helm-0.34.1`) and
  `helm package` output names (`harbor-1.19.2.tgz`, `vault-0.34.1.tgz`).
- `zizmor --offline` reports no findings: inputs and secrets reach the script through `env:`,
  because interpolating them into `run:` is a template-injection finding.
- The Harbor project `charts` exists and is public (checked anonymously through its API); it is
  empty, so the first run has both charts to push.

## After merge

Run `Mirror Charts` once with `chart: all`. Expected: two pushed artifacts
(`harbor:1.19.2`, `vault:0.34.1`), pullable anonymously, after which `grachevko/home-ops` can
switch both apps to an `OCIRepository` of this mirror.
hermes merged commit c6811a8955 into main 2026-09-24 17:39:40 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
grachevko/charts!1
No description provided.