feat(ci): document the mirrored-chart convention and its home repository #205

Merged
grachevko merged 2 commits from feat/charts-mirror into main 2026-09-24 17:59:32 +00:00
Collaborator

What was

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 the cluster, curl -4 https://helm.goharbor.io/index.yaml answers 200 with Content-Length: 95085 and then stalls after 11203 bytes (90 s timeout), and HashiCorp's index answers 403. A HelmRepository source cannot be built from either, so both apps take their chart from a GitRepository, which is also why the cluster-level chart check cannot inflate those two releases.

What this PR does

  • AGENTS.md: the cluster-side convention only. A chart whose upstream is unreachable is taken from our own Harbor as an OCI artifact; the mirror itself is a separate repository, grachevko/charts (https://git.grachevko.ru/grachevko/charts), which holds the scheduled workflow, the robot-account secrets and the instruction for adding a chart. Also recorded there: the OCI tag of such an artifact is the CHART version, not the release tag with its v prefix.

An earlier revision of this branch carried the workflow itself; it moved to grachevko/charts (PR #1 there) because that repository already holds the Harbor robot secrets.

Verified

  • Forgejo ambiguous-unicode checker on AGENTS.md: clean.
  • Nothing in the cluster reads this file set, so the PR has no cluster effect and needs no run of its own.

Next, in order

  1. grachevko/charts PR #1 merges, then Mirror Charts runs once with chart: all. Expected: harbor:1.19.2 and vault:0.34.1 in Harbor, pullable anonymously.
  2. A follow-up PR here switches harbor and vault from their GitRepository sources to an OCIRepository of the mirror (oci://harbor.grachevko.ru/charts/<name>) and brings the flux-local gate (test + rendered diff) plus the Renovate configuration for the chart tags. Until that PR, this one is documentation only.

Rollback

Revert the commit: the note disappears together with it.

## What was 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 the cluster, `curl -4 https://helm.goharbor.io/index.yaml` answers 200 with `Content-Length: 95085` and then stalls after 11203 bytes (90 s timeout), and HashiCorp's index answers 403. A HelmRepository source cannot be built from either, so both apps take their chart from a GitRepository, which is also why the cluster-level chart check cannot inflate those two releases. ## What this PR does - `AGENTS.md`: the cluster-side convention only. A chart whose upstream is unreachable is taken from our own Harbor as an OCI artifact; the mirror itself is a separate repository, `grachevko/charts` (https://git.grachevko.ru/grachevko/charts), which holds the scheduled workflow, the robot-account secrets and the instruction for adding a chart. Also recorded there: the OCI tag of such an artifact is the CHART version, not the release tag with its `v` prefix. An earlier revision of this branch carried the workflow itself; it moved to `grachevko/charts` (PR #1 there) because that repository already holds the Harbor robot secrets. ## Verified - Forgejo ambiguous-unicode checker on `AGENTS.md`: clean. - Nothing in the cluster reads this file set, so the PR has no cluster effect and needs no run of its own. ## Next, in order 1. `grachevko/charts` PR #1 merges, then `Mirror Charts` runs once with `chart: all`. Expected: `harbor:1.19.2` and `vault:0.34.1` in Harbor, pullable anonymously. 2. A follow-up PR here switches `harbor` and `vault` from their GitRepository sources to an `OCIRepository` of the mirror (`oci://harbor.grachevko.ru/charts/<name>`) and brings the `flux-local` gate (test + rendered diff) plus the Renovate configuration for the chart tags. Until that PR, this one is documentation only. ## Rollback Revert the commit: the note disappears together with it.
feat(ci): mirror CloudFront-only charts into Harbor
All checks were successful
Flate / Flate - Filter (pull_request) Successful in 4s
Flate / Flate (pull_request) Has been skipped
Flate / Flate - Success (pull_request) Successful in 4s
c924d04288
## What was

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 the
cluster, `curl -4 https://helm.goharbor.io/index.yaml` answers 200 with `Content-Length: 95085`
and then stalls after 11203 bytes (90 s timeout), and HashiCorp's index answers 403. A
HelmRepository source cannot be built from either, so both apps take their chart from a
GitRepository, which is also the reason the CI checks cannot inflate those two releases.

## What this PR does

- `.github/workflows/mirror-charts.yaml`: packages the chart from the upstream release tag
  (`codeload.github.com/<repo>/tar.gz/refs/tags/<tag>`) and pushes it to
  `oci://harbor.grachevko.ru/charts` with `helm push`. Daily schedule plus `workflow_dispatch`
  with `chart` and `version` inputs; idempotent, because a chart version that is already mirrored
  is skipped before packaging. Credentials come from the repository secrets
  `HARBOR_ROBOT_USER` / `HARBOR_ROBOT_TOKEN` (robot account of the `charts` project with push
  rights).
- `AGENTS.md`: the convention and the tag rule, that the OCI tag of such an artifact is the
  CHART version rather than the release tag with its `v` prefix.

## 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 .github/workflows/mirror-charts.yaml` — no findings. Inputs and secrets are
  passed into the script through `env:`; interpolating them into `run:` was a template-injection
  finding, which is why the script reads `INPUT_CHART` and `INPUT_VERSION`.
- Forgejo ambiguous-unicode checker — clean.

## Owner steps before the first run

1. Harbor: create a public project `charts`.
2. Harbor: create a robot account of that project with push and pull rights, expiry never.
3. Forgejo: add the robot name and secret as repository secrets `HARBOR_ROBOT_USER` and
   `HARBOR_ROBOT_TOKEN`. The values do not belong in chat.

Then run `Mirror Charts` once with `chart: all`: the run must end with `helm show chart`
answering for both `oci://harbor.grachevko.ru/charts/harbor` and
`oci://harbor.grachevko.ru/charts/vault`, and both must be pullable anonymously.

## Next

A follow-up PR switches `harbor` and `vault` from their GitRepository sources to an
`OCIRepository` of this mirror and brings the `flux-local` gate (test + rendered diff), which is
blocked until these artifacts exist.

## Rollback

Revert the commit: the workflow disappears. Nothing in the cluster reads the mirror yet, so no
cluster state is involved.
feat(ci): point the chart mirror at the grachevko/charts repository
All checks were successful
Flate / Flate - Filter (pull_request) Successful in 3s
Flate / Flate (pull_request) Has been skipped
Flate / Flate - Success (pull_request) Successful in 3s
69ac236c32
The mirror does not belong in this repository: the scheduled workflow that packages the upstream
chart and pushes it to `oci://harbor.grachevko.ru/charts` lives in `grachevko/charts`
(https://git.grachevko.ru/grachevko/charts), together with the robot-account secrets it needs.

Here only the cluster-side convention stays documented: why a chart is mirrored, that the mirror
is a separate repository, and that the OCI tag of such an artifact is the CHART version rather
than the release tag with its `v` prefix.

No cluster state changes in this PR.
hermes changed title from feat(ci): mirror CloudFront-only charts into Harbor to feat(ci): document the mirrored-chart convention and its home repository 2026-09-24 17:39:17 +00:00
grachevko deleted branch feat/charts-mirror 2026-09-24 17:59:32 +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/home-ops!205
No description provided.