# 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](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/`), you must first promote the subchart's templates into the wrapper. ```bash cd helm-templates/ ls charts/ # find the subchart .tgz helm dependency update # ensure it's resolved # Extract templates from the subchart .tgz tar -xzf charts/-.tgz -C /tmp/ cp -R /tmp//templates ./templates cp -R /tmp//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): ```diff apiVersion: v2 name: -version: 0.1.0 +version: 0.1.0+fork.1 description: — Meesho-forked from upstream -dependencies: - - name: - version: - repository: ``` ### 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//README.md` (create if missing). Use this template: ```markdown # **Forked from upstream ** at . ## Why ## What's changed - `templates/.yaml` — - `values.yaml` — ## Upstream tracking - Upstream PR: - Upstream issue: - When upstream merges: revert this fork via [unfork procedure]. ``` ### 5. Render and diff ```bash sibling=$(find helm-overrides -maxdepth 2 -type d -name '' | head -1) helm template helm-templates/ -f "$sibling/custom-values.yaml" | head -120 # Spot-check helm diff against a live cluster helm diff upgrade helm-templates/ \ -f helm-overrides///custom-values.yaml --kube-context= ``` ### 6. Commit and open the PR ```bash git checkout -b fork/- git add helm-templates// git commit git push origin fork/- gh pr create --base main --title "fork: " ``` 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//templates/` but Helm renders from `charts//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//README.md` to remove the "forked" status. 5. Render against a sibling override and confirm the resulting manifests match what the fork was producing. --- ## Related - Procedure: [update-chart-version.md](update-chart-version.md). - ADR: [ADR-A1-cache-vs-upstream-charts.md](../../../wiki/analyses/ADR-A1-cache-vs-upstream-charts.md). - [SANCTITY_RULES R7](../../global/SANCTITY_RULES.md).