Files
devops-infra-helm-charts-gcp/docs/platform/procedures/fork-upstream-chart.md
T
2026-08-26 03:39:42 +05:30

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

  1. Editing templates/ without first vendoring (templates from a subchart). Your edits live in helm-templates/<chart>/templates/ but Helm renders from charts/<sub>/templates/ — the edits do nothing, then get clobbered.
  2. Forking a chart and not documenting why. Six months later nobody remembers; the fork looks like accidental drift.
  3. Forking instead of overriding via values. Always check the chart's existing values surface first.
  4. 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.
  5. 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:

  1. Restore Chart.yaml to declare the upstream as a dependency (with the new upstream version that includes the fix).
  2. Delete the local templates/ and values.yaml (or rename them as .upstream for reference).
  3. Run helm dependency update.
  4. Update helm-templates/<chart>/README.md to remove the "forked" status.
  5. Render against a sibling override and confirm the resulting manifests match what the fork was producing.