Skip to content

Commit 0d0fe7f

Browse files
ci: switch chart release flow to release-please (FB-1938) (#20)
**Background** FB-1938: The chart release flow auto-bumps `helm/Chart.yaml` `version` from the merge-commit subject in a homegrown bash step and pushes the bump back to `main`; we want release-please as the source of truth instead, matching `firebolt-kubernetes-operator` (FB-1671). **Summary** Switches chart versioning and changelog generation to [release-please](https://github.com/googleapis/release-please), adapted for this single-chart repo (no app image / cosign / CRDs chart). What changes: - `release-please-config.json` + `.release-please-manifest.json` — one `helm` package (`release-type: helm`), tags `v<version>`, changelog sections mirroring the operator. - `helm-release-cd.yaml` rewritten: a `release-please` job opens/updates the release PR; a `release-chart` job (gated on `release_created`) regenerates the README, packages the chart, and pushes it to GHCR. `appVersion` stays owned by the upstream image-release automation. - `pr-title.yaml` added — validates conventional-commit PR titles (release-please derives versions from squash-merge titles), skipping dependabot/release-please branches. - `helm-test.yaml` — skips the kind e2e on release-please branches (the release PR only bumps the version + changelog over templates that already passed on the feature PR). - `AGENTS.md` / `helm/AGENTS.md` updated to describe the flow. Going forward, releasing is a two-step flow: merge a `feat:`/`fix:`/`chore(deps):` PR, then merge the release PR release-please opens. Only `feat`/`fix`/`perf`/`revert`/`chore(deps)` cut a release; plain `chore:`/`refactor:`/`docs:` merges no longer publish a chart. Do not hand-bump `Chart.yaml` `version` — release-please owns it. Breaking changes bump minor while pre-1.0. **Bootstrap (required before this takes effect):** no git tags exist, so anchor release-please at the current release before merging, or its first run scans all history. Tags are bare SemVer (no `v`), matching the chart version and OCI tag: ``` git tag 0.2.0 <main-HEAD> && git push origin 0.2.0 ``` **Test Plan** - `release-please-config.json` / `.release-please-manifest.json` validated as JSON. - Workflows reviewed for actionlint/zizmor: all actions pinned to SHAs (reusing existing repo pins), no `${{ }}` expansions inside `run:` blocks. - Traced trigger behavior on the release PR and on merge: `docs-sync`/`docs-validate` no-op, `helm-validate` lints the bumped chart, `helm-test` now skipped on release-please branches, and the README sync commit carries `[skip ci]` so it does not re-trigger the release run. - End-to-end release behavior will be confirmed on the first real run after the `v0.2.0` bootstrap tag is pushed. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes how every chart version reaches production (tags, GHCR, changelog) and tightens which merges trigger releases; misconfiguration or missing bootstrap tag could affect the first release run. > > **Overview** > Replaces the **homegrown bash auto-bump** on `main` with **[release-please](https://github.com/googleapis/release-please)** as the sole owner of `helm/Chart.yaml` `version` and changelog. > > **Release pipeline:** `helm-release-cd` now runs a `release-please` job on every push to `main` (no longer limited to `helm/**` paths). It opens/updates a release PR from conventional commits; merging that PR tags bare SemVer, cuts a GitHub release, and only then runs **`release-chart`** to regenerate `helm/README.md` (with `[skip ci]`), package, and push OCI to GHCR. The old logic that inferred patch/minor/major from the latest merge commit and pushed version/changelog bumps directly to `main` is removed. > > **New config:** `release-please-config.json` and `.release-please-manifest.json` (anchored at `0.2.0`) define a single `helm` package with operator-aligned changelog sections; only certain commit types are releasable. > > **CI gates:** **`pr-title.yaml`** enforces conventional PR titles (with issue refs) because squash-merge titles feed release-please. **`helm-test`** skips `release-please/*` branches so version-only release PRs do not rerun the long kind e2e. > > **Docs:** `AGENTS.md` / `helm/AGENTS.md` describe the two-step release (feature PR → release PR) and that hand-bumping chart `version` is no longer allowed; `appVersion` stays on separate image automation. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 03941b6. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent b9c0ee5 commit 0d0fe7f

7 files changed

Lines changed: 228 additions & 67 deletions

File tree

Lines changed: 82 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
---
2+
# Chart versioning is driven by release-please: conventional-commit pushes to
3+
# main accumulate on an automated release PR (opened/updated by the release-please
4+
# job); merging that PR bumps helm/Chart.yaml `version`, prepends helm/CHANGELOG.md,
5+
# tags `<version>` (bare SemVer, matching the chart version and OCI tag), and cuts
6+
# a GitHub release. Only then does release-chart package
7+
# and push the OCI chart to GHCR. Chart `appVersion` is NOT managed here -- it is
8+
# bumped independently by the upstream image-release automation (a chore(deps):
9+
# commit, which release-please still counts as releasable).
210
name: Helm - Release Chart
311

412
env:
@@ -8,8 +16,6 @@ env:
816
on:
917
push:
1018
branches: [main]
11-
paths:
12-
- "helm/**"
1319
workflow_dispatch:
1420

1521
permissions: {}
@@ -18,7 +24,44 @@ concurrency:
1824
group: ${{ github.workflow }}-${{ github.ref }}
1925

2026
jobs:
27+
release-please:
28+
runs-on: ubuntu-latest
29+
permissions:
30+
contents: write
31+
pull-requests: write
32+
outputs:
33+
# Single package at path `helm`, so release-please-action keys its outputs
34+
# by that path (`helm--<name>`) rather than the un-prefixed root aliases.
35+
release_created: ${{ steps.release.outputs['helm--release_created'] }}
36+
tag_name: ${{ steps.release.outputs['helm--tag_name'] }}
37+
version: ${{ steps.release.outputs['helm--version'] }}
38+
steps:
39+
- name: Checkout code
40+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
41+
with:
42+
show-progress: "false"
43+
fetch-depth: 0
44+
persist-credentials: false
45+
46+
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
47+
id: app-token
48+
with:
49+
client-id: ${{ secrets.GH_APP_FB_DB_CI_WRITER_CLIENT_ID }}
50+
private-key: ${{ secrets.GH_APP_FB_DB_CI_WRITER_APP_KEY_PEM }}
51+
permission-contents: write
52+
permission-pull-requests: write
53+
54+
- name: Release Please
55+
uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0
56+
id: release
57+
with:
58+
token: ${{ steps.app-token.outputs.token }}
59+
config-file: release-please-config.json
60+
manifest-file: .release-please-manifest.json
61+
2162
release-chart:
63+
needs: release-please
64+
if: needs.release-please.outputs.release_created == 'true'
2265
runs-on: ubuntu-latest
2366
permissions:
2467
contents: write
@@ -28,7 +71,6 @@ jobs:
2871
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
2972
with:
3073
show-progress: "false"
31-
fetch-depth: 2
3274
persist-credentials: false
3375

3476
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
@@ -49,65 +91,30 @@ jobs:
4991
sudo tar -xzf "${HELM_DOCS_ARCHIVE}" -C /usr/local/bin helm-docs
5092
rm -f "${HELM_DOCS_ARCHIVE}" checksums.txt
5193
52-
- name: Determine chart version
53-
id: chart
94+
- name: Sync generated chart README to released version
95+
# release-please bumps Chart.yaml `version` on the release PR but does not
96+
# run helm-docs, so the README version badge lags by one release. Regenerate
97+
# and commit it back. helm/README.md is cosmetic (the chart's .helmignore
98+
# excludes *.md, so it is never packaged). The commit carries `[skip ci]` so
99+
# this direct push to main does not trigger a second (no-op) release run;
100+
# its `docs:` type is non-releasable and it is still picked up (hidden) in
101+
# release-please's next commit-range scan.
54102
env:
55103
GH_APP_TOKEN: ${{ steps.app-token.outputs.token }}
104+
RELEASE_VERSION: ${{ needs.release-please.outputs.version }}
56105
run: |
57-
CURR_VERSION=$(yq '.version' helm/Chart.yaml)
58-
APP_VERSION=$(yq '.appVersion' helm/Chart.yaml)
59-
60-
# workflow_dispatch: publish the version already in Chart.yaml.
61-
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
62-
echo "chart_version=$CURR_VERSION" >> "$GITHUB_OUTPUT"
63-
echo "Releasing existing chart version $CURR_VERSION (appVersion: $APP_VERSION)"
64-
exit 0
65-
fi
66-
67-
# If the developer already bumped Chart.version in their commit, honour it.
68-
PREV_VERSION=$(git show HEAD~1:helm/Chart.yaml | yq '.version')
69-
if [ "$PREV_VERSION" != "$CURR_VERSION" ]; then
70-
echo "chart_version=$CURR_VERSION" >> "$GITHUB_OUTPUT"
71-
echo "Chart.version already bumped ($PREV_VERSION -> $CURR_VERSION); using as-is."
72-
exit 0
73-
fi
74-
75-
# ── Auto-bump based on conventional-commit message ────────────────
76-
COMMIT_MSG=$(git log --format='%s' -1)
77-
COMMIT_BODY=$(git log --format='%b' -1)
78-
79-
MAJOR=$(echo "$CURR_VERSION" | cut -d. -f1)
80-
MINOR=$(echo "$CURR_VERSION" | cut -d. -f2)
81-
PATCH=$(echo "$CURR_VERSION" | cut -d. -f3)
82-
83-
if echo "$COMMIT_BODY" | grep -qi 'BREAKING CHANGE'; then
84-
NEW_VERSION="$((MAJOR + 1)).0.0"
85-
BUMP_TYPE="major"
86-
elif echo "$COMMIT_MSG" | grep -qE '^feat(\(|:)'; then
87-
NEW_VERSION="$MAJOR.$((MINOR + 1)).0"
88-
BUMP_TYPE="minor"
89-
else
90-
NEW_VERSION="$MAJOR.$MINOR.$((PATCH + 1))"
91-
BUMP_TYPE="patch"
92-
fi
93-
94-
echo "Auto $BUMP_TYPE bump: $CURR_VERSION -> $NEW_VERSION (commit: $COMMIT_MSG)"
95-
96-
yq -i ".version = \"$NEW_VERSION\"" helm/Chart.yaml
97-
98-
printf "# %s\n\n%s\n\n" "$NEW_VERSION" "$COMMIT_MSG" \
99-
| cat - helm/CHANGELOG.md > /tmp/CHANGELOG.md
100-
mv /tmp/CHANGELOG.md helm/CHANGELOG.md
101-
102106
helm-docs --chart-search-root=helm
103107
104108
git config user.name "github-actions[bot]"
105109
git config user.email "github-actions[bot]@users.noreply.github.com"
106-
git add helm/Chart.yaml helm/CHANGELOG.md helm/README.md
107-
git commit -m "chore(helm): bump chart to $NEW_VERSION"
108-
git push "https://x-access-token:${GH_APP_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" HEAD:main
110+
git add helm/README.md
109111
110-
echo "chart_version=$NEW_VERSION" >> "$GITHUB_OUTPUT"
112+
if git diff --staged --quiet; then
113+
echo "Chart README already in sync; nothing to commit."
114+
else
115+
git commit -m "docs: regenerate chart README for ${RELEASE_VERSION} [skip ci]"
116+
git push "https://x-access-token:${GH_APP_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" HEAD:main
117+
fi
111118
112119
- name: Set up Helm
113120
uses: azure/setup-helm@dda3372f752e03dde6b3237bc9431cdc2f7a02a2 # v5.0.0
@@ -130,11 +137,28 @@ jobs:
130137
echo "Packaged: $(ls /tmp/helm-packages)"
131138
132139
- name: Push chart to GitHub Container Registry
140+
env:
141+
CHART_VERSION: ${{ needs.release-please.outputs.version }}
142+
REPO_OWNER: ${{ github.repository_owner }}
133143
run: |
134144
helm push \
135-
"/tmp/helm-packages/firebolt-instance-${STEPS_CHART_OUTPUTS_CHART_VERSION}.tgz" \
136-
"oci://${{ env.GHCR_REGISTRY }}/${{ github.repository_owner }}/${{ env.HELM_CHARTS_NAMESPACE }}"
137-
echo "Pushed firebolt-instance:${STEPS_CHART_OUTPUTS_CHART_VERSION} to GHCR"
145+
"/tmp/helm-packages/firebolt-instance-${CHART_VERSION}.tgz" \
146+
"oci://${GHCR_REGISTRY}/${REPO_OWNER}/${HELM_CHARTS_NAMESPACE}"
147+
echo "Pushed firebolt-instance:${CHART_VERSION} to GHCR"
138148
149+
- name: Job summary
139150
env:
140-
STEPS_CHART_OUTPUTS_CHART_VERSION: ${{ steps.chart.outputs.chart_version }}
151+
CHART_VERSION: ${{ needs.release-please.outputs.version }}
152+
TAG_NAME: ${{ needs.release-please.outputs.tag_name }}
153+
REPO_OWNER: ${{ github.repository_owner }}
154+
run: |
155+
{
156+
echo "### Helm chart published :rocket:"
157+
echo ""
158+
echo "| Field | Value |"
159+
echo "|-------|-------|"
160+
echo "| **Chart** | \`firebolt-instance\` |"
161+
echo "| **Version** | \`${CHART_VERSION}\` |"
162+
echo "| **Release tag** | \`${TAG_NAME}\` |"
163+
echo "| **Registry** | \`oci://${GHCR_REGISTRY}/${REPO_OWNER}/${HELM_CHARTS_NAMESPACE}\` |"
164+
} >> "$GITHUB_STEP_SUMMARY"

.github/workflows/helm-test.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ jobs:
6060
helm-test:
6161
name: helm-test (k8s ${{ matrix.k8s-version }})
6262
needs: detect
63-
if: needs.detect.outputs.docs_only != 'true'
63+
# Skip release-please's release PRs: they only bump Chart.yaml `version` +
64+
# CHANGELOG.md over templates that already passed e2e on the feature PR, so
65+
# re-running the 45-minute kind suite adds no coverage and a flake there
66+
# would needlessly block the release.
67+
if: needs.detect.outputs.docs_only != 'true' && !startsWith(github.head_ref, 'release-please')
6468
runs-on: ubuntu-latest
6569
timeout-minutes: 45
6670
permissions:

.github/workflows/pr-title.yaml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
# release-please derives the next chart version and CHANGELOG from the
3+
# conventional-commit subject of each squash-merged PR, so the PR title IS the
4+
# commit message that reaches main. This gate enforces that contract.
5+
name: PR Title
6+
7+
on:
8+
pull_request:
9+
# 'edited' is required so that fixing a failed title (which changes only the
10+
# title, not the commits) re-triggers validation. The default activity types
11+
# (opened, synchronize, reopened) do not cover title edits.
12+
types:
13+
- opened
14+
- reopened
15+
- synchronize
16+
- edited
17+
18+
permissions: {}
19+
20+
jobs:
21+
validate:
22+
name: PR Title
23+
runs-on: ubuntu-latest
24+
permissions:
25+
pull-requests: read
26+
if: ${{ !startsWith(github.head_ref, 'dependabot') && !startsWith(github.head_ref, 'release-please') }}
27+
steps:
28+
- name: Validate PR title
29+
uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1
30+
env:
31+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32+
with:
33+
# List of allowed commit types
34+
types: |
35+
build
36+
chore
37+
ci
38+
docs
39+
feat
40+
fix
41+
perf
42+
refactor
43+
revert
44+
style
45+
test
46+
47+
subjectPattern: ^[a-z0-9_].*\((#[0-9]+|[A-Z]+-[0-9]+)\)$
48+
requireScope: false
49+
validateSingleCommit: false
50+
subjectPatternError: |
51+
The subject "{subject}" found in the pull request title "{title}" didn't match the configured pattern.
52+
53+
We follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
54+
Our CI is configured to forbid PRs with titles that don't follow this standard.
55+
That's it, all commits landing in the `main` branch must be formatted in this way.
56+
Please make sure you read and understand this convention.
57+
58+
The subject must not start with a capital letter, and must end with an issue
59+
reference in parentheses: either a GitHub issue like "(#123)" or a tracker
60+
ticket like "(FB-1234)".

.release-please-manifest.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"helm": "0.2.0"
3+
}

AGENTS.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## What this project does
44

5-
Helm chart that runs a Firebolt instance on Kubernetes: an Envoy gateway that routes by `X-Firebolt-Engine` header, the Pensieve metadata service, a bundled or external PostgreSQL for metadata storage, and one or more `firebolt-core` query engines as StatefulSets. The chart is published as `firebolt-instance` to `oci://ghcr.io/firebolt-db/helm-charts` on every push to `main` that touches `helm/`.
5+
Helm chart that runs a Firebolt instance on Kubernetes: an Envoy gateway that routes by `X-Firebolt-Engine` header, the Pensieve metadata service, a bundled or external PostgreSQL for metadata storage, and one or more `firebolt-core` query engines as StatefulSets. The chart is published as `firebolt-instance` to `oci://ghcr.io/firebolt-db/helm-charts` when a release-please release PR is merged to `main` (see project-specific rules).
66

77
## Repo structure
88

@@ -28,7 +28,7 @@ Helm chart that runs a Firebolt instance on Kubernetes: an Envoy gateway that ro
2828
├── docs/ # user-facing docs, Mintlify MDX (docs.json drives nav; see docs/AGENTS.md for style)
2929
├── docs-internal/ # Firebolt-internal docs (e.g. the make dev / floci flow), plain Markdown
3030
├── .github/
31-
│ ├── workflows/ # helm-validate, helm-release-cd, gha-lint, helm-test
31+
│ ├── workflows/ # helm-validate, helm-release-cd (release-please), pr-title, gha-lint, helm-test
3232
│ └── ISSUE_TEMPLATE/
3333
├── static/ # chart icon
3434
├── .pre-commit-config.yaml # helm-docs, helm lint --strict, helm template dry-run
@@ -90,7 +90,7 @@ You MUST keep documentation in sync with code. When making changes:
9090

9191
- **AGENTS.md** — update the relevant `AGENTS.md` (root or `helm/AGENTS.md`) if you change structure, conventions, public surface, commands, or config formats. If your change makes existing AGENTS.md content wrong, fix it before finishing.
9292
- **`helm/values.yaml` annotations** — every value rendered into `helm/README.md` is documented inline via `# --` comments processed by `helm-docs`. When you add, rename, remove, or change the meaning of a value, update its annotation in the same change. Then regenerate `helm/README.md` via `make docs` (or let the pre-commit `helm-docs` hook do it on commit).
93-
- **`helm/CHANGELOG.md`**the `helm-release-cd` workflow prepends a new entry on each release based on the conventional-commit message of the merge commit. You do not normally hand-edit this file; you DO need to write a conventional-commit message (`feat:` / `fix:` / `chore:` / etc.) so the auto-bump and changelog entry are correct.
93+
- **`helm/CHANGELOG.md`** — release-please owns this file, prepending a section for each release from the conventional-commit history since the last release. You do not hand-edit it; you DO need conventional-commit PR titles (`feat:` / `fix:` / `chore(deps):` / etc.) so the version bump and changelog entry are correct.
9494
- **`README.md` (root)** — overview-only. Update when your change affects what a human reader needs to know about what the project is or how to run it. Implementation detail belongs in this file or `helm/AGENTS.md`, not the README.
9595
- **`helm/README.md`** — never hand-edit. It is regenerated.
9696

@@ -119,7 +119,7 @@ Code is not done until it is covered by tests where tests are reasonable.
119119
Every change is tracked and lands through a branch and a pull request — no exceptions.
120120

121121
- **A documented issue comes first.** Every task MUST have a corresponding issue before any work starts — a Linear ticket or a GitHub issue. If none exists, create one (GitHub issues use the templates under `.github/ISSUE_TEMPLATE/`). No issue, no work.
122-
- **Never touch `main` directly.** You MUST NEVER work in, commit to, or push to `main`. All work happens on a feature branch and merges via a reviewed PR. (`main` is only ever advanced by merging a PR or by the release workflow's automated version-bump commit — see project-specific rules.)
122+
- **Never touch `main` directly.** You MUST NEVER work in, commit to, or push to `main`. All work happens on a feature branch and merges via a reviewed PR. (`main` is only ever advanced by merging a PR — including release-please's automated release PR — see project-specific rules.)
123123
- **Branch names tie the branch to its issue**, so work is traceable. Prefix the branch with the tracker identifier:
124124
- Linear: `FB-<number>-<short-kebab-description>` (e.g. `FB-790-ci-testing`).
125125
- GitHub issue: `<issue-number>-<short-kebab-description>`.
@@ -139,7 +139,7 @@ Linear specifics:
139139

140140
## Project-specific rules
141141

142-
- **Conventional commits drive releases.** The `helm-release-cd` workflow on `main` parses the merge-commit subject. `feat:` bumps minor, `fix:`/`chore:`/anything-else bumps patch, and a body containing `BREAKING CHANGE` bumps major. Chart version in `helm/Chart.yaml` is auto-bumped and committed back to `main` by a GitHub App; `helm/CHANGELOG.md` is prepended; `helm/README.md` is regenerated; the chart is packaged and pushed to GHCR. If you bump `helm/Chart.yaml` `version` manually in your commit, the workflow honours it as-is and skips the auto-bump.
142+
- **Conventional commits drive releases via release-please.** The `helm-release-cd` workflow on `main` runs [release-please](https://github.com/googleapis/release-please) (config: `release-please-config.json`, state: `.release-please-manifest.json`), which accumulates conventional-commit merges onto an automated release PR. `feat:` bumps minor, `fix:`/`perf:`/`revert:`/`chore(deps):` bump patch, and `BREAKING CHANGE` bumps minor while pre-1.0 (`bump-minor-pre-major`). Merging that release PR bumps `helm/Chart.yaml` `version`, prepends `helm/CHANGELOG.md`, tags `<version>` (bare SemVer, no `v` — matching the chart version and OCI tag), and cuts a GitHub release; only then does the `release-chart` job regenerate `helm/README.md`, package the chart, and push it to GHCR. Do NOT hand-bump `helm/Chart.yaml` `version` — release-please owns it. `appVersion` is the exception: it is managed by the upstream image-release automation, not release-please.
143143
- **`appVersion` is the shared default image tag.** `helm/Chart.yaml`'s `appVersion` is the default for both `engineSpec.image.tag` and `metadata.image.tag`, and both image registries now publish matching `debug-` / `release-` prefixed tags. Override `metadata.image.tag` only when the metadata service must run a version other than the engine.
144144
- **GitHub Actions are pinned to commit SHAs.** All `uses:` references in `.github/workflows/*` use full 40-char SHAs with a version comment. `actionlint` and `zizmor` run on every push/PR that touches `.github/`. New actions you introduce MUST follow the same pinning convention.
145145
- **Pre-commit hook quirk: first-run helm-docs aborts the commit.** The `helm-docs` pre-commit hook regenerates `helm/README.md` and stages the result; if the regeneration changes the file, the commit aborts so you can re-run `git commit` with the now-staged README.md included. This is documented in `.pre-commit-config.yaml` and is intentional.

0 commit comments

Comments
 (0)