5.7 KiB
Procedure — Intentionally fork an upstream chart
Layer: Layer 1 — HIGH RISK. Blast radius: every cluster that consumes this chart will render against the forked templates on next sync. Approval: platform team — multi-reviewer.
Most charts in helm-templates/ are vanilla upstream, pulled via helm pull. The Chart.yaml is a thin wrapper declaring the upstream chart as a dependency; the actual templates come from the subchart in charts/. Editing a templates/*.yaml under the wrapper silently forks the chart, and the fork is clobbered the next time someone runs helm dependency update.
This procedure is the supported path when a fork is intentional.
When to use this procedure
- Upstream chart lacks a feature you need (e.g. a values key that doesn't exist).
- Upstream behaviour conflicts with Meesho's environment (e.g. probe path doesn't work behind Contour).
- Upstream chart has a bug awaiting an upstream fix.
This is not the right procedure for:
- Adding a values knob — file a PR upstream, or override behaviour through existing knobs.
- Pinning to an old version — use update-chart-version.md (or just don't bump).
- Style preferences — leave the upstream chart alone.
Pre-conditions
- You've confirmed the desired behaviour cannot be achieved via the chart's existing values.
- You've checked whether an upstream PR / issue already covers this.
- Platform team agrees the fork is justified.
- The fork's rationale will be documented in the chart's
README.md.
Steps
1. Vendor the chart's templates
If the chart is currently a thin wrapper (templates come from a subchart in charts/<sub>), you must first promote the subchart's templates into the wrapper.
cd helm-templates/<chart>
ls charts/ # find the subchart .tgz
helm dependency update # ensure it's resolved
# Extract templates from the subchart .tgz
tar -xzf charts/<sub>-<ver>.tgz -C /tmp/
cp -R /tmp/<sub>/templates ./templates
cp -R /tmp/<sub>/values.yaml ./values.yaml.upstream
Now the wrapper has its own templates/ — Helm will use those instead of the subchart's.
2. Edit Chart.yaml to reflect the fork
Remove the dependency (since the templates are now local), and bump version: (the chart's own version, not the subchart's):
apiVersion: v2
name: <chart>
-version: 0.1.0
+version: 0.1.0+fork.1
description: <description> — Meesho-forked from upstream <chart> <upstream-version>
-dependencies:
- - name: <sub>
- version: <upstream-version>
- repository: <upstream-repo>
3. Make the fork edits
Edit templates/*.yaml or values.yaml to apply the fix. Keep the diff minimal — every line away from upstream is technical debt.
4. Document the fork
Edit helm-templates/<chart>/README.md (create if missing). Use this template:
# <chart>
**Forked from upstream <chart> <upstream-version>** at <date>.
## Why
<one-paragraph rationale — what behaviour the fork changes and why we couldn't achieve
it through values alone>
## What's changed
- `templates/<file>.yaml` — <one-line diff summary>
- `values.yaml` — <one-line diff summary>
## Upstream tracking
- Upstream PR: <link, if you've sent one>
- Upstream issue: <link>
- When upstream merges: revert this fork via [unfork procedure].
5. Render and diff
sibling=$(find helm-overrides -maxdepth 2 -type d -name '<chart>' | head -1)
helm template <chart> helm-templates/<chart> -f "$sibling/custom-values.yaml" | head -120
# Spot-check helm diff against a live cluster
helm diff upgrade <release> helm-templates/<chart> \
-f helm-overrides/<cluster>/<app>/custom-values.yaml --kube-context=<context>
6. Commit and open the PR
git checkout -b fork/<chart>-<purpose>
git add helm-templates/<chart>/
git commit
git push origin fork/<chart>-<purpose>
gh pr create --base main --title "fork: <chart> — <one-line purpose>"
PR description must include:
- Procedure followed: this file.
- Why the fork is necessary (link to upstream issue/PR if any).
- What templates / values are changed and why.
- Platform team approver(s).
- Plan for unforking when upstream lands the fix.
Anti-patterns
- Editing
templates/without first vendoring (templates from a subchart). Your edits live inhelm-templates/<chart>/templates/but Helm renders fromcharts/<sub>/templates/— the edits do nothing, then get clobbered. - Forking a chart and not documenting why. Six months later nobody remembers; the fork looks like accidental drift.
- Forking instead of overriding via values. Always check the chart's existing values surface first.
- Forking and then bumping the upstream version. A bump runs
helm dependency update, which can clobber the fork. The fork must be re-applied or the bump must explicitly re-vendor. - Sweeping cleanup of upstream code alongside the fork edit. The diff should be exactly the change you intended; everything else is upstream.
Rollback / unforking
When upstream lands the fix and you want to return to vanilla:
- Restore
Chart.yamlto declare the upstream as a dependency (with the new upstream version that includes the fix). - Delete the local
templates/andvalues.yaml(or rename them as.upstreamfor reference). - Run
helm dependency update. - Update
helm-templates/<chart>/README.mdto remove the "forked" status. - Render against a sibling override and confirm the resulting manifests match what the fork was producing.
Related
- Procedure: update-chart-version.md.
- ADR: ADR-A1-cache-vs-upstream-charts.md.
- SANCTITY_RULES R7.