Skip to content

Commit 63952cf

Browse files
authored
Merge pull request #46 from dennisme/dennisme/revamp-release
chore: reduce complexity
2 parents 59ae768 + 6b9e280 commit 63952cf

12 files changed

Lines changed: 174 additions & 70 deletions

File tree

.github/cr.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Config for helm/chart-releaser-action (cr) in
2+
# .github/workflows/helm-release.yaml.
3+
#
4+
# Custom release name so the chart's GitHub Release is unmistakably
5+
# separate from the app's own `vX.Y.Z` release that goreleaser.yaml
6+
# creates on the same tag.
7+
release-name-template: "helm-{{ .Name }}-{{ .Version }}"

.github/workflows/docs.yml

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ on:
2727
# Refresh docs/releases/changelog.md after GoReleaser publishes notes.
2828
release:
2929
types: [published]
30+
# helm-release.yaml (cr) publishes the chart's GitHub Release *before* it
31+
# finishes pushing the updated index.yaml to gh-pages, so the `release`
32+
# trigger above can fire while gh-pages is still stale. Wait for
33+
# helm-release.yaml to fully complete instead, so the chart index we fetch
34+
# below is current.
35+
workflow_run:
36+
workflows: ["helm-release"]
37+
types: [completed]
3038
workflow_dispatch:
3139

3240
permissions:
@@ -65,26 +73,37 @@ jobs:
6573
# Helm chart repository lives at /charts/ on the same GitHub Pages site
6674
# as the docs and demo. That keeps a single Pages deployment (one
6775
# concurrency group) and avoids a second repo or branch for charts.
76+
# The actual chart .tgz files are published as GitHub Release assets
77+
# by .github/workflows/helm-release.yaml (cr); this job only mirrors
78+
# the resulting index.yaml from the gh-pages branch, it never
79+
# packages the chart itself.
6880
- name: Set up Helm
6981
uses: azure/setup-helm@v4
7082
with:
7183
version: v3.16.2
72-
- name: Package Helm chart into site/charts
84+
- name: Fetch chart index from gh-pages
7385
run: |
7486
set -euo pipefail
7587
mkdir -p site/charts
76-
helm package deploy/charts/grex --destination site/charts
77-
helm repo index site/charts \
78-
--url https://dennisme.github.io/grex/charts
88+
if git ls-remote --exit-code --heads origin gh-pages >/dev/null 2>&1; then
89+
git fetch --depth 1 origin gh-pages
90+
git show origin/gh-pages:index.yaml > site/charts/index.yaml
91+
else
92+
echo "gh-pages branch not found yet (no chart release published); writing empty index"
93+
helm repo index site/charts --url https://dennisme.github.io/grex/charts
94+
fi
7995
# Keep a copy of the chart source README for humans browsing the path.
8096
cp deploy/charts/grex/README.md site/charts/README.md
8197
- name: Upload artifact
82-
# Deploy from main pushes, published releases (refresh changelog), and manual runs.
98+
# Deploy from main pushes, published releases (refresh changelog),
99+
# a completed helm-release run (refresh chart index), and manual runs.
83100
if: >-
84101
github.event_name != 'pull_request' &&
85102
(github.ref == 'refs/heads/main' ||
86103
github.event_name == 'release' ||
87-
github.event_name == 'workflow_dispatch')
104+
github.event_name == 'workflow_dispatch' ||
105+
(github.event_name == 'workflow_run' &&
106+
github.event.workflow_run.conclusion == 'success'))
88107
uses: actions/upload-pages-artifact@v3
89108
with:
90109
path: site
@@ -94,7 +113,9 @@ jobs:
94113
github.event_name != 'pull_request' &&
95114
(github.ref == 'refs/heads/main' ||
96115
github.event_name == 'release' ||
97-
github.event_name == 'workflow_dispatch')
116+
github.event_name == 'workflow_dispatch' ||
117+
(github.event_name == 'workflow_run' &&
118+
github.event.workflow_run.conclusion == 'success'))
98119
needs: build
99120
runs-on: ubuntu-latest
100121
environment:

.github/workflows/goreleaser.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ jobs:
4242
password: ${{ secrets.GITHUB_TOKEN }}
4343

4444
# Package outside dist/ so goreleaser --clean does not delete the chart.
45-
# Chart.yaml version/appVersion are bumped by `just release-tag` before the tag.
45+
# Only used for the OCI push below; Chart.yaml's version/appVersion
46+
# are a 0.0.0 placeholder, this override is the only real version.
4647
- name: Package Helm chart
4748
run: |
4849
set -euo pipefail
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: helm-release
2+
3+
# Publishes the Helm chart as its own GitHub Release + chart-repo index
4+
# entry on every app version tag. Runs independently of goreleaser.yaml
5+
# (which builds binaries/images/OCI chart push from the same tag) so a
6+
# failure in one doesn't block the other.
7+
#
8+
# Chart.yaml's version/appVersion are placeholders (0.0.0) — the real
9+
# version is always this explicit tag-derived override, never read from
10+
# the committed file. See docs/developer/releasing.md.
11+
on:
12+
push:
13+
tags:
14+
- "v*"
15+
16+
permissions:
17+
contents: write
18+
19+
jobs:
20+
chart-release:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v4
25+
26+
- name: Set up Helm
27+
uses: azure/setup-helm@v4
28+
with:
29+
version: v3.16.2
30+
31+
- name: Configure Git
32+
run: |
33+
git config user.name "$GITHUB_ACTOR"
34+
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
35+
36+
# cr expects pre-packaged charts in .cr-release-packages when
37+
# skip_packaging is set; package here with an explicit version
38+
# override so Chart.yaml's committed placeholder is never read.
39+
- name: Package chart
40+
run: |
41+
set -euo pipefail
42+
VER="${GITHUB_REF_NAME#v}"
43+
mkdir -p .cr-release-packages
44+
helm package deploy/charts/grex \
45+
--version "$VER" \
46+
--app-version "$VER" \
47+
--destination .cr-release-packages
48+
49+
- name: Run chart-releaser
50+
uses: helm/chart-releaser-action@v1.6.0
51+
with:
52+
config: .github/cr.yaml
53+
skip_packaging: true
54+
pages_branch: gh-pages
55+
env:
56+
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

.goreleaser.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,8 @@ changelog:
6262

6363
release:
6464
name_template: "v{{ .Version }}"
65-
# Packaged by the goreleaser workflow (outside dist/ so --clean is safe).
66-
extra_files:
67-
- glob: ./.chart-release/*.tgz
65+
# The chart .tgz is not attached here: it ships on its own GitHub Release
66+
# (helm-grex-VERSION), published by .github/workflows/helm-release.yaml (cr).
6867
# Appended after the generated changelog on the GitHub Release.
6968
footer: |
7069
---

deploy/charts/grex/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ apiVersion: v2
22
name: grex
33
description: OpAMP control plane for OpenTelemetry Collector fleets
44
type: application
5-
version: 0.2.0
6-
appVersion: "0.2.0"
5+
version: 0.0.0
6+
appVersion: "0.0.0"
77

88
keywords:
99
- opamp

deploy/charts/grex/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ helm install grex oci://ghcr.io/dennisme/charts/grex --version 0.1.0 \
2424
--namespace grex --create-namespace
2525
```
2626

27-
Chart `version` / `appVersion` are bumped with grex releases
28-
(`just release-tag`). Empty `image.tag` defaults to `appVersion`, which
29-
matches the published `ghcr.io/dennisme/grex` image tag.
27+
Chart `version` / `appVersion` in the packaged/published chart match each
28+
grex release tag (set via an explicit override at package time in CI, not
29+
stored in this file's `Chart.yaml`). Empty `image.tag` defaults to
30+
`appVersion`, which matches the published `ghcr.io/dennisme/grex` image tag.
3031

3132
## Install from a local checkout
3233

docs/admin/helm.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ collide:
3030
|------|---------|
3131
| `/` | MkDocs documentation |
3232
| `/demo/` | Static fleet UI demo |
33-
| `/charts/` | Helm repository (`index.yaml` + `.tgz`) |
33+
| `/charts/` | Helm repository index (`index.yaml`; each `.tgz` downloads from its own GitHub Release asset) |
3434

3535
```sh
3636
helm repo add grex https://dennisme.github.io/grex/charts/

docs/developer/releasing.md

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -63,45 +63,51 @@ svu next # what the next release tag would be
6363

6464
- Fetches remote tags so `svu` sees the latest release
6565
- Runs `svu next` (for example `v0.2.0`)
66-
- Bumps `deploy/charts/grex/Chart.yaml` `version` and `appVersion` to the
67-
SemVer **without** the leading `v` (for example `0.2.0`), and commits
68-
`chore(release): bump helm chart to …` when they change
69-
- Creates the git tag on that commit
70-
- Pushes the commit and the tag to `origin`
66+
- Creates the git tag on the current commit
67+
- Pushes the tag to `origin`
68+
69+
It does **not** touch `deploy/charts/grex/Chart.yaml`. That file's
70+
`version`/`appVersion` are a fixed `0.0.0` placeholder; every workflow that
71+
packages the chart overrides both with an explicit `--version`/
72+
`--app-version` flag derived from the tag, so the committed file is never
73+
read for a real release. See [Helm chart versioning](#helm-chart-versioning).
7174

7275
4. Watch CI:
7376

74-
- **GoReleaser** (tag) — binaries, container image, chart `.tgz` on the
75-
GitHub Release, chart OCI push to GHCR
76-
- **docs** (push to `main`, path-filtered) — rebuilds Pages, including
77-
packaging the chart into `https://dennisme.github.io/grex/charts/`
77+
- **goreleaser** (tag) — binaries, container image, chart OCI push to GHCR
78+
- **helm-release** (tag) — packages the chart, publishes it as its own
79+
GitHub Release (`helm-grex-VERSION`), pushes the updated repo index to
80+
the `gh-pages` branch
81+
- **docs** (runs after **helm-release** completes, plus push-to-`main` and
82+
`release: published`) — rebuilds Pages, mirroring the `gh-pages` index
83+
into `https://dennisme.github.io/grex/charts/`
7884

7985
Do **not** create release tags by hand unless you are fixing a one-off mistake;
80-
`just release-tag` keeps app, image, and chart versions aligned.
86+
`just release-tag` is just a thin wrapper around `svu next` + `git tag` +
87+
`git push`, but it also checks for a clean tree and refuses to retag.
8188

8289
### Manual equivalent
8390

8491
```sh
8592
git fetch --tags
8693
TAG=$(svu next)
87-
VER=${TAG#v}
88-
# bump deploy/charts/grex/Chart.yaml version + appVersion to $VER and commit
8994
git tag "$TAG"
90-
git push origin HEAD "$TAG"
95+
git push origin "$TAG"
9196
```
9297

9398
## What the release pipeline publishes
9499

95-
Configuration lives in `.goreleaser.yaml` at the repository root. On a
96-
version tag, GoReleaser (plus the workflow’s Helm steps) publishes:
100+
Configuration lives in `.goreleaser.yaml` at the repository root, plus
101+
`.github/workflows/helm-release.yaml` for the chart. On a version tag, these
102+
publish:
97103

98104
| Artifact | Destination |
99105
|----------|-------------|
100106
| Cross-compiled binaries (linux / darwin / windows × amd64 / arm64) | GitHub Release assets (archives + `checksums.txt`) |
101107
| Container images | GHCR (`ghcr.io/dennisme/grex`) multi-arch (amd64 + arm64) |
102-
| Helm chart package (`.tgz`) | GitHub Release asset |
108+
| Helm chart package (`.tgz`) | Its own GitHub Release (`helm-grex-VERSION`), published by `helm-release.yaml` (`cr`) |
103109
| Helm chart (OCI) | `oci://ghcr.io/dennisme/charts/grex` |
104-
| Helm chart (Pages index) | `https://dennisme.github.io/grex/charts/` via the **docs** workflow after the chart bump lands on `main` |
110+
| Helm chart (Pages index) | `https://dennisme.github.io/grex/charts/`, `cr` pushes `index.yaml` to `gh-pages`, the **docs** workflow mirrors it in on the next run |
105111
| Release notes (changelog) | GitHub Release body |
106112

107113
Image tags include `{{ .Version }}` (no `v`, matches chart `appVersion`),
@@ -118,18 +124,21 @@ local source builds and compose/Helm smoke tests.
118124

119125
| Field | Source | Meaning |
120126
|-------|--------|---------|
121-
| Chart `version` | bumped by `just release-tag` | Helm package / repo version |
122-
| Chart `appVersion` | same SemVer string | Default container image tag |
123-
| Git tag | `svu next` (with `v` prefix) | Triggers GoReleaser |
127+
| Chart `version` (in `Chart.yaml`) | fixed `0.0.0` placeholder, never edited | Not read for a real release |
128+
| Chart `version` (as packaged/published) | explicit `--version "$VER"` at package time, in `goreleaser.yaml` and `helm-release.yaml` | Helm package / repo version |
129+
| Chart `appVersion` (as packaged/published) | explicit `--app-version "$VER"`, same string | Default container image tag |
130+
| Git tag | `svu next` (with `v` prefix) | Triggers both `goreleaser.yaml` and `helm-release.yaml` |
124131

125132
For grex 1.0, **chart version and app version stay equal** to the grex release.
126133
Chart-only fixes still ship as a normal grex patch release (no separate chart
127-
version stream yet).
134+
version stream yet). Both workflows derive `$VER` the same way
135+
(`${GITHUB_REF_NAME#v}`), so they can't drift from each other even though
136+
they run independently.
128137

129138
**Install after a release:**
130139

131140
```sh
132-
# Chart repository on GitHub Pages (updated when main deploys docs)
141+
# Chart repository on GitHub Pages (index refreshed once helm-release + docs finish)
133142
helm repo add grex https://dennisme.github.io/grex/charts/
134143
helm repo update
135144
helm upgrade --install grex grex/grex --version 0.2.0 -n grex --create-namespace
@@ -139,8 +148,10 @@ helm upgrade --install grex oci://ghcr.io/dennisme/charts/grex --version 0.2.0 \
139148
-n grex --create-namespace
140149
```
141150

142-
Pages always packages the chart version currently on `main`. Historical
143-
`.tgz` files are kept on each GitHub Release and on GHCR (OCI).
151+
The Pages index reflects whatever `helm-release.yaml` last pushed to
152+
`gh-pages`, not whatever's on `main` (there's nothing chart-related to
153+
package from `main` anymore). Historical `.tgz` files are kept on each
154+
chart's own GitHub Release and on GHCR (OCI).
144155

145156
### Pretty release notes (changelog)
146157

@@ -185,13 +196,16 @@ gh api repos/dennisme/grex/releases/generate-notes \
185196
## After the release
186197

187198
- Confirm the [GitHub Releases](https://github.com/dennisme/grex/releases) page
188-
lists the new tag, binary archives, and `grex-<version>.tgz`
199+
lists the new app tag with its binary archives
200+
- Confirm a second GitHub Release `helm-grex-<version>` exists with the
201+
chart `.tgz` asset (published by `helm-release.yaml`)
189202
- Confirm the GHCR image `ghcr.io/dennisme/grex:<version>` exists
190203
- Confirm the OCI chart `oci://ghcr.io/dennisme/charts/grex` is pullable at
191204
that version
192-
- Confirm the docs workflow on `main` finished so
193-
[the chart repo](https://dennisme.github.io/grex/charts/) indexes the new
194-
chart (path-filtered; needs the chart bump commit on `main`)
205+
- Confirm `helm-release.yaml` finished (it pushes the updated index to
206+
`gh-pages`), then confirm the **docs** workflow's `workflow_run` trigger
207+
fired after it so [the chart repo](https://dennisme.github.io/grex/charts/)
208+
indexes the new chart
195209
- Confirm the docs workflow also ran on the **release published** event so
196210
[Releases → Changelog](../releases/changelog.md) includes the new notes
197211

@@ -214,6 +228,14 @@ Confirm the tag was pushed to the repo that owns
214228
`.github/workflows/goreleaser.yaml`, and that the workflow triggers on that
215229
tag pattern.
216230

231+
**Chart repo on Pages shows the old version**
232+
`cr` (in `helm-release.yaml`) publishes the chart's GitHub Release *before*
233+
it finishes pushing the updated `index.yaml` to `gh-pages`. The docs
234+
workflow's `workflow_run` trigger waits for `helm-release.yaml` to fully
235+
complete before mirroring the index, so this should self-correct once that
236+
run finishes. If `helm-release.yaml` failed outright, re-run it (or push a
237+
no-op tag fix) rather than editing `gh-pages` by hand.
238+
217239
## Related
218240

219241
- [Contributing](contributing.md) — conventional commits and PR CI

docs/releases/index.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,19 @@ Full operator install paths (Compose, from source, TLS, etc.):
6363
|----------|--------------|--------|
6464
| Cross-compiled binaries + checksums | GoReleaser → GitHub Release | linux / darwin / windows × amd64 / arm64 |
6565
| Multi-arch container image | GoReleaser → GHCR | Tags: `VERSION`, `vVERSION`, major/minor aliases, `latest` |
66-
| Helm chart `.tgz` | GoReleaser → GitHub Release asset | Same SemVer as `Chart.yaml` |
66+
| Helm chart `.tgz` | helm-release workflow (`cr`) → its own GitHub Release (`helm-grex-VERSION`) | Version comes from an explicit `--version` override at package time, not from `Chart.yaml` |
6767
| Helm chart OCI | GoReleaser workflow → GHCR | `oci://ghcr.io/dennisme/charts/grex` |
68-
| Helm chart on Pages | docs workflow on `main` | Repo index at `/charts/` |
68+
| Helm chart on Pages | helm-release workflow pushes `index.yaml` to `gh-pages`; docs workflow mirrors it into `/charts/` | Repo index only; the `.tgz` itself downloads from the chart's GitHub Release asset |
6969
| Release notes body | GoReleaser changelog | Grouped by commit type; PR links from `(#N)` squash subjects |
7070

7171
## Versioning
7272

7373
- **Git tags:** `vMAJOR.MINOR.PATCH` (via [`svu`](https://github.com/caarlos0/svu)
7474
/ `just release-tag`)
7575
- **Helm `version` / `appVersion` and default image tag:** `MAJOR.MINOR.PATCH`
76-
(no `v`)
76+
(no `v`), set via an explicit `--version`/`--app-version` override at
77+
package time in CI. `deploy/charts/grex/Chart.yaml` itself stays a fixed
78+
`0.0.0` placeholder and is never edited as part of a release.
7779
- **Breaking changes:** conventional `BREAKING CHANGE` / `type!:` → major bump
7880

7981
See the [Changelog](changelog.md) for notes per tag, or the

0 commit comments

Comments
 (0)