766f43931c
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.