chart: publish from the tag only, not from both workflows
Two workflows published the chart and disagreed about its metadata. release.yml stamps version and appVersion from the git tag; chart-release.yml, triggered by any charts/** push to main, took Chart.yaml verbatim, where appVersion is the hardcoded "latest". Both fired for the same commit, both tried to publish the same chart version, and skip_existing turned whichever lost into a no-op — so what a release said about itself came down to which runner was quicker. Chart 0.9.0 went out that way, reading appVersion "latest". Every earlier release got the right answer by accident: Chart.yaml's version lagged the published set, so chart-release.yml always collided with an existing version and skipped, leaving release.yml to win uncontested. Bumping Chart.yaml to match the tag before cutting 0.9.0 removed that accident and the race showed itself. Making the two agree is not possible. The tag is pushed after the branch, so a workflow triggered by the main push cannot know the version it is about to be tagged with — no amount of deriving from git describe fixes that ordering. The fix is one publisher, triggered by the tag, so chart-release.yml is deleted. The chart now only ships with an app release. Nothing is lost: the sed in release.yml ties the chart version to the app version, so a chart-only change never had a version of its own to be released under. Chart fixes ride the next tag. Chart.yaml's version and appVersion are documented as the placeholders they now are, so the next person does not helpfully bump them and reintroduce this. skip_existing stays, for idempotent re-runs of a failed release rather than for the race, and a non-version tag now fails the job instead of silently publishing unstamped metadata.
This commit is contained in:
@@ -1,38 +0,0 @@
|
||||
name: Release Helm Chart
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- charts/**
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pages: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config user.name "$GITHUB_ACTOR"
|
||||
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
|
||||
|
||||
- name: Install Helm
|
||||
uses: azure/setup-helm@v4
|
||||
|
||||
- name: Run chart-releaser
|
||||
uses: helm/chart-releaser-action@v1.6.0
|
||||
with:
|
||||
# A charts/** push without a Chart.yaml version bump would otherwise
|
||||
# fail trying to re-release the current version. Tagged releases also
|
||||
# publish the chart from release.yml, so the two can race.
|
||||
skip_existing: true
|
||||
env:
|
||||
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
@@ -112,18 +112,41 @@ jobs:
|
||||
- name: Install Helm
|
||||
uses: azure/setup-helm@v4
|
||||
|
||||
# This job is the only thing that publishes the chart, which is what keeps
|
||||
# the published metadata honest. There used to be a second publisher --
|
||||
# chart-release.yml, on every charts/** push to main -- and the two raced
|
||||
# for the same chart version with different answers: this one stamps
|
||||
# version and appVersion from the tag, that one took Chart.yaml verbatim,
|
||||
# where appVersion is the hardcoded "latest". Whichever landed first won
|
||||
# and skip_existing turned the loser into a no-op, so the metadata of a
|
||||
# release depended on which runner was quicker. Chart 0.9.0 went out on
|
||||
# 2026-08-08 reading appVersion "latest" that way.
|
||||
#
|
||||
# It could not be fixed by making both agree: the tag is pushed after the
|
||||
# branch, so a workflow triggered by the main push cannot know the version
|
||||
# it is about to be tagged with. One publisher, triggered by the tag.
|
||||
#
|
||||
# The cost is that the chart only ships with an app release. That is no
|
||||
# real loss -- the sed below ties the chart version to the app version, so
|
||||
# a chart-only change has no version of its own to be released under
|
||||
# anyway. Chart fixes ride the next tag.
|
||||
- name: Update chart versions
|
||||
run: |
|
||||
VERSION="${{ github.ref_name }}"
|
||||
if [[ "$VERSION" =~ ^v[0-9] ]]; then
|
||||
if [[ ! "$VERSION" =~ ^v[0-9] ]]; then
|
||||
echo "::error::refusing to publish a chart for non-version tag ${VERSION}"
|
||||
exit 1
|
||||
fi
|
||||
CHART_VERSION="${VERSION#v}"
|
||||
sed -i "s/^version:.*/version: ${CHART_VERSION}/" charts/terdut-server/Chart.yaml
|
||||
sed -i "s/^appVersion:.*/appVersion: \"${VERSION}\"/" charts/terdut-server/Chart.yaml
|
||||
fi
|
||||
|
||||
- name: Run chart-releaser
|
||||
uses: helm/chart-releaser-action@v1.6.0
|
||||
with:
|
||||
# Keeps a re-run of a failed release idempotent rather than failing on
|
||||
# the chart that already went out. It is no longer papering over a
|
||||
# race -- see above.
|
||||
skip_existing: true
|
||||
env:
|
||||
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
@@ -2,5 +2,10 @@ apiVersion: v2
|
||||
name: terdut-server
|
||||
description: A Helm chart for Terminal Duty — on-call alert management server
|
||||
type: application
|
||||
# These two are placeholders for a local `helm install ./charts/terdut-server`,
|
||||
# not the released values. release.yml rewrites both from the git tag when it
|
||||
# publishes, so the chart version always equals the app version. Bumping them by
|
||||
# hand does nothing for a release and is not needed before tagging.
|
||||
# "latest" is honest here: it matches image.tag in values.yaml.
|
||||
version: 0.9.0
|
||||
appVersion: "latest"
|
||||
|
||||
Reference in New Issue
Block a user