Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions .github/workflows/bump-and-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ on:
jobs:
bump:
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
actions: write
contents: write
pull-requests: write
steps:
Expand Down Expand Up @@ -44,16 +46,26 @@ jobs:
git config user.email "github-actions[bot]@users.noreply.github.com"
git add charts/lunar/Chart.yaml charts/lunar/values.yaml
if git diff --cached --quiet; then
echo "No changes to commit"
echo "No changes to commit; dispatching release reconciliation"
gh workflow run release.yml --ref main
exit 0
fi
BRANCH="release/${VERSION}"
git checkout -b "${BRANCH}"
git commit -m "Release ${VERSION}"
git push -u origin "${BRANCH}"
gh pr create \
PR_URL=$(gh pr create \
--base main \
--head "${BRANCH}" \
--title "Release ${VERSION}" \
--body "Automated bump from the \`lunar-hub-v${VERSION}\` release. Sets \`Chart.yaml\` version and the hub/operator/init/sidecar image tags in \`charts/lunar/values.yaml\` to \`${VERSION}\` (chart and hub versions stay in lockstep). Grafana runs stock \`grafana/grafana\` and is not retagged. The chart release is published by \`release.yml\` on merge to \`main\`."
gh pr merge --auto --squash "${BRANCH}"
--body "Automated bump from the \`lunar-hub-v${VERSION}\` release. Sets \`Chart.yaml\` version and the hub/operator/init/sidecar image tags in \`charts/lunar/values.yaml\` to \`${VERSION}\` (chart and hub versions stay in lockstep). Grafana runs stock \`grafana/grafana\` and is not retagged. The chart release is published by \`release.yml\` on merge to \`main\`.")
gh pr merge --auto --squash "$PR_URL"
for attempt in $(seq 1 90); do
MERGED_AT=$(gh pr view "$PR_URL" --json mergedAt --jq '.mergedAt // ""')
if [ -n "$MERGED_AT" ]; then
gh workflow run release.yml --ref main
exit 0
fi
sleep 10
done
echo "::warning::release PR did not merge within 15 minutes; auto-merge remains enabled and the scheduled release reconciliation will publish it"
69 changes: 63 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ on:
# Manual lever: a release-PR merged by GITHUB_TOKEN (e.g. bump-and-pr's
# auto-merge) does NOT fire the push trigger, so dispatch this to publish.
workflow_dispatch: {}
schedule:
- cron: '17 5 * * *'

concurrency:
group: release-charts
cancel-in-progress: false

jobs:
release:
Expand Down Expand Up @@ -38,11 +44,62 @@ jobs:
env:
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

# chart-releaser seeds every release body with the chart description.
# Replace it with the matching CHANGELOG.md section. Runs in the same job
# (a separate `on: release` workflow would not fire — releases created
# with GITHUB_TOKEN don't trigger downstream workflow runs).
- name: Sync release notes from changelog
- name: Link canonical Self-hosted release notes and notify Lunar
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./scripts/sync-release-notes.sh
LUNAR_REPO_DISPATCH_TOKEN: ${{ secrets.LUNAR_REPO_DISPATCH_TOKEN }}
EVENT_NAME: ${{ github.event_name }}
run: |-
set -euo pipefail
chart_version=$(yq -r '.version' charts/lunar/Chart.yaml)
chart_tag="lunar-${chart_version}"
chart_asset_name="${chart_tag}.tgz"
release_json=$(gh release view "$chart_tag" --repo "$GITHUB_REPOSITORY" --json tagName,publishedAt,url,assets,body)
if [[ "$(jq -r '.tagName' <<<"$release_json")" != "$chart_tag" ]]; then
echo "::error::published chart tag does not match $chart_tag" >&2
exit 1
fi
if ! jq -e --arg name "$chart_asset_name" '.assets | any(.name == $name)' <<<"$release_json" >/dev/null; then
echo "::error::$chart_tag has no $chart_asset_name asset" >&2
exit 1
fi
rm -f "$RUNNER_TEMP/$chart_asset_name"
gh release download "$chart_tag" --repo "$GITHUB_REPOSITORY" --pattern "$chart_asset_name" --dir "$RUNNER_TEMP"
lunar_images_version=$(tar -xOzf "$RUNNER_TEMP/$chart_asset_name" lunar/values.yaml | yq -r '.hub.image.tag')
if [[ ! "$lunar_images_version" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error::published chart contains invalid hub.image.tag '$lunar_images_version'" >&2
exit 1
fi
released=$(jq -r '.publishedAt | split("T")[0]' <<<"$release_json")
chart_release_url=$(jq -r '.url' <<<"$release_json")
git fetch --force --tags origin
chart_sha=$(git rev-list -n 1 "$chart_tag")
canonical_url='https://docs-lunar.earthly.dev/release-notes/self-hosted'
canonical_body=$(printf '%s\n\n%s' \
'Earthly Lunar Self-hosted release notes are maintained in the Lunar documentation.' \
"$canonical_url")
if [[ "$EVENT_NAME" != workflow_dispatch && "$(jq -r '.body // ""' <<<"$release_json")" == "$canonical_body" ]]; then
echo "$chart_tag already records the canonical release-note link; no callback is required."
exit 0
fi
notes_file=$(mktemp)
printf '%s\n' "$canonical_body" > "$notes_file"
jq -n \
--arg event_type lunar-chart-released \
--arg chart_version "$chart_version" \
--arg released "$released" \
--arg lunar_images_version "$lunar_images_version" \
--arg chart_tag "$chart_tag" \
--arg chart_sha "$chart_sha" \
--arg chart_release_url "$chart_release_url" \
--arg chart_asset_name "$chart_asset_name" \
'{event_type: $event_type, client_payload: {chart_version: $chart_version, released: $released, lunar_images_version: $lunar_images_version, chart_tag: $chart_tag, chart_sha: $chart_sha, chart_release_url: $chart_release_url, chart_asset_name: $chart_asset_name}}' \
> "$RUNNER_TEMP/lunar-chart-released.json"
curl -fsSL \
--request POST \
--header "Authorization: Bearer $LUNAR_REPO_DISPATCH_TOKEN" \
--header 'Accept: application/vnd.github+json' \
--header 'X-GitHub-Api-Version: 2022-11-28' \
--data-binary "@$RUNNER_TEMP/lunar-chart-released.json" \
https://api.github.com/repos/earthly/lunar/dispatches
gh release edit "$chart_tag" --repo "$GITHUB_REPOSITORY" --notes-file "$notes_file"
102 changes: 50 additions & 52 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,81 +21,80 @@ User-facing install/values docs live in `README.md`.
```text
charts/lunar/ # the lunar chart
Chart.yaml # chart metadata (name, version, kubeVersion)
CHANGELOG.md # per-chart release notes (canonical for chart history)
README.md # values reference + install guide (publicly rendered)
values.yaml # default values for the chart
templates/ # k8s manifest templates (hub, operator, grafana, etc.)
scripts/ # helper scripts shipped with the chart (e.g. create-github-app.sh)
scripts/ # repo tooling, NOT shipped with the chart
sync-release-notes.sh # mirror CHANGELOG.md sections into GitHub release notes
.github/workflows/ # CI: chart-releaser on main, bump-and-pr on dispatch
.github/workflows/ # chart publication, version bump, and Lunar completion callback
.github/CODEOWNERS # @dchw owns everything by default
CHANGELOG.md # repo-level index pointing at per-chart changelogs
lunar.yml # lunar-config: domain + codeowners + description
README.md # repo-level README
```

## Release flow

1. A new Lunar version (`lunar-hub-vX.Y.Z`) is released from `earthly/lunar`.
2. The `bump-and-pr.yml` workflow here is triggered (`workflow_dispatch`) with
`version=X.Y.Z`.
1. A human release signer reviews an exact Lunar `main` SHA and dispatches
Lunar's `release.yml` for `lunar-hub` with that reviewed SHA and `X.Y.Z`.
2. Lunar's workflow validates the authorization, runs its release gate, creates
`lunar-hub-vX.Y.Z` on the signer's behalf, publishes the images, then triggers
this repository's `bump-and-pr.yml` with `version=X.Y.Z`.
3. `bump-and-pr.yml` bumps `charts/lunar/Chart.yaml` `version` plus all the
`*.image.tag` fields in `values.yaml`, pushes a `release/X.Y.Z` branch,
opens a PR, and enables auto-merge (squash).
4. On merge to `main`, `release.yml` (the `Release Charts` workflow) runs
`chart-releaser-action`, which packages the chart and publishes the tag
(`lunar-X.Y.Z`) + GitHub Release.
5. Still in the same `release.yml` job, `scripts/sync-release-notes.sh` runs
and copies the matching `## [X.Y.Z]` section from
`charts/lunar/CHANGELOG.md` into that release's notes (see below).

So: **the changelog entry IS the release notes.** Write the
`charts/lunar/CHANGELOG.md` section for the new version — usually as part of the
release PR or a follow-up on the same `release/X.Y.Z` branch before the bump PR
merges — and the release body is populated for you.

## Release notes are derived from the changelog

`chart-releaser` seeds every release body with the chart `description`, so
without help every release reads `A Helm chart for Earthly Lunar 🌙`.
`scripts/sync-release-notes.sh` fixes that: for each
`charts/<chart>/CHANGELOG.md`, it maps every `## [X.Y.Z]` section to the
`<chart>-X.Y.Z` release tag and sets the release body to that section.

- Runs automatically as the last step of `release.yml`. It's deliberately in
the same job as `chart-releaser` rather than a separate `on: release`
workflow, because releases created with `GITHUB_TOKEN` don't trigger
downstream workflow runs.
- Idempotent and self-healing — it reconciles every run, so fixing a typo in a
past changelog entry repairs that release's notes on the next release.
- Skips releases with no matching changelog section (e.g. pre-1.0 history the
changelog intentionally omits).

Run it by hand against the live repo when needed:

```bash
scripts/sync-release-notes.sh --dry-run # preview, no writes
scripts/sync-release-notes.sh # reconcile all releases
scripts/sync-release-notes.sh --version 2.4.0 # just one release
```

Needs an authenticated `gh` and `awk`. Defaults to `$GITHUB_REPOSITORY`
(falls back to `earthly/charts`).
`chart-releaser-action`, which packages the chart and publishes the Helm
chart tag (`lunar-X.Y.Z`) + chart GitHub Release in this repository. The
prefix is the chart name; it is unrelated to the CLI's `lunar-vX.Y.Z` tag
and does not release the CLI. `bump-and-pr.yml` explicitly dispatches
it after auto-merge because merges performed with `GITHUB_TOKEN` do not
emit a downstream `push` workflow. A daily scheduled reconciliation is the
fallback for a delayed merge or missed dispatch.
5. Still in the same `release.yml` job, the workflow verifies the public tag
and `.tgz`, sends a metadata-only `lunar-chart-released` repository dispatch
to `earthly/lunar`, and then replaces the chart GitHub Release body with a link
to the canonical Self-hosted GitBook page. That link is the durable completion
marker: push and scheduled reconciliation skip an already-marked release, while
a manual workflow dispatch forces the callback for repair.
6. Lunar independently verifies the public release and chart package, resolves
the packaged Lunar SHA and charts tag SHA, promotes eligible Self-hosted
fragments from both repositories, and publishes the canonical notes.

## Release-note source flow

Structured fragments in `earthly/lunar/release-notes.d/` are the only canonical
source for future release-note prose. This repository has no maintained
changelog. Existing historical release bodies and Git history preserve the old
record.

- Lunar's weekday drafting workflow checks out Charts `main` and scans it with
an independent `earthly/charts` watermark. Charts sends no per-merge source
notification.
- Version-only/image-tag-only release PRs are expected to become `no-note`.
User-visible values, templates, compatibility, installation, and upgrade
changes can produce `source_repo: earthly/charts` Self-hosted fragments.
- `release.yml` sends chart metadata only after the chart is public: version/date,
chart tag and SHA, release URL, package name, and packaged Lunar image version.
It never sends release-note prose.
- Chart GitHub Release bodies point to
<https://docs-lunar.earthly.dev/release-notes/self-hosted>. GitBook is the
canonical release-note surface.

Only the completion callback requires the `LUNAR_REPO_DISPATCH_TOKEN` Actions
secret. A failed run before the completion marker is retried by reconciliation;
accepted callbacks are marked once, and explicit manual callbacks remain idempotent.

## Editing checklist

- **Bumping the chart**: don't edit `Chart.yaml` / `values.yaml` image tags by
hand. Trigger the `bump-and-pr.yml` workflow via `workflow_dispatch`.
- **Changing template behavior**: update `charts/lunar/templates/*.yaml` and
`values.yaml`. Bump the chart minor (`X.Y+1.0`) for additions, major
(`X+1.0.0`) for breaking values-shape changes, patch for fixes. Add a
`charts/lunar/CHANGELOG.md` entry — it becomes the release notes.
(`X+1.0.0`) for breaking values-shape changes, patch for fixes. Do not write a
separate changelog entry; Lunar drafts source-aware fragments after merge.
- **Editing the README**: keep the values table in sync with `values.yaml`.
The README is the doc surface users see when they browse the chart.
- **Workflow / tooling changes**: anything under `.github/workflows/` or
`scripts/` — these aren't chart-versioned; track them in git history (the
repo-level `CHANGELOG.md` is just an index, not a per-commit log).
`scripts/` — these aren't chart-versioned; track them in git history.

## Conventions

Expand All @@ -108,7 +107,6 @@ Needs an authenticated `gh` and `awk`. Defaults to `$GITHUB_REPOSITORY`

## Pointers

- Per-chart release notes: [`charts/lunar/CHANGELOG.md`](charts/lunar/CHANGELOG.md)
- Repo-level changelog index: [`CHANGELOG.md`](CHANGELOG.md)
- Canonical Self-hosted release notes: <https://docs-lunar.earthly.dev/release-notes/self-hosted>
- Public docs site: <https://docs-lunar.earthly.dev/>
- Lunar source: <https://github.com/earthly/lunar>
9 changes: 0 additions & 9 deletions CHANGELOG.md

This file was deleted.

5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -406,10 +406,7 @@ helm upgrade lunar earthly/lunar \
-f values.yaml
```

Per-release changes (breaking changes, new values, behaviour shifts)
are recorded in the [chart CHANGELOG](charts/lunar/CHANGELOG.md). Read
the entries between your current version and the one you're upgrading
to before running `helm upgrade`.
Before upgrading, review the [Self-hosted release notes](https://docs-lunar.earthly.dev/release-notes/self-hosted) for breaking changes, new values, behavior changes, and required upgrade actions between your current and target chart versions.

## Uninstalling

Expand Down
Loading