mirror of
https://github.com/coder/coder.git
synced 2026-10-16 14:48:56 +08:00
The `Publish Helm Chart` step does an unguarded read-modify-write of `gs://helm.coder.com/v2/index.yaml`: download, `helm repo index --merge` with only this run's three charts, upload. The workflow `concurrency` group is keyed on `github.ref`, so releases for different tags run in parallel. When two of them reach this step at about the same time, both merge into the same old index and the second upload silently drops the first release's entries. This is how 2.36.6 (and, going by the current index, probably 2.36.2) went missing from the `coder-v2` chart repo after back-to-back manual re-runs. ## Fix Treat the index like a compare-and-swap: - Read the object's GCS `generation` before and after downloading `index.yaml`, and fail if it changed underneath us. - Upload with `x-goog-if-generation-match:<generation>` so a concurrent writer causes a `412` instead of a clobber. - On either failure, exit with a `::error::` telling the operator to re-run the job. No automatic retry; a re-run merges against the fresh index. Chart tarballs are still uploaded before the index, so an index entry is never published ahead of its tarball. The OCI pushes to `ghcr.io/coder/chart` are unchanged; they have no shared index and were never affected. Serializing all release runs through a single `concurrency` group was considered and rejected: GitHub keeps only the newest pending run per group, so a third dispatch would silently cancel a queued release. ## Verification - `actionlint` and `shellcheck` on the step script pass. - Exercised the step locally with a fake `gsutil`: the happy path uploads and bumps the generation; bumping the generation between read and upload makes the precondition fail and the step exit 1 with the re-run message. - Not exercised against the real bucket. The `x-goog-if-generation-match` header and `gsutil stat` `Generation:` field are standard GCS behaviour, but a dry-run cannot cover this because the step is skipped when `dry_run` is set. This does not repair the already-missing entries; #29794 adds a one-off workflow for that. --- _Generated by Coder Agents on behalf of @f0ssel._ --------- Co-authored-by: McKayla はな <kayla@tree.camp>