Skip to content

Commit 41b71eb

Browse files
committed
fix(helm): fail closed on registry lookup errors and pin documented installs
The publish guard treated every non-zero `helm show chart` exit as proof the version was unpublished, so a transient 5xx, an expired token, or a DNS blip would have enabled a push that moves an already-published version tag. Runs where the version already exists are routine — the path filter also fires on package.json and workflow edits — so this was reachable. Now only an explicit `: not found` counts as absent; anything else stops the job. Verified against the pinned Helm v3.16.4 that an absent version and an absent repository both report `: not found`, so a first publish still proceeds, while denied/unauthorized/dial-tcp failures abort instead. Also pins the two documented install paths that were still reproducible only by accident: the cloud-specific command paired a pinned chart with values fetched from the moving main branch, and the README quick start omitted --version while the same README warns against exactly that.
1 parent 1d064dc commit 41b71eb

3 files changed

Lines changed: 31 additions & 9 deletions

File tree

.github/workflows/helm.yml

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -239,20 +239,35 @@ jobs:
239239
echo "repository=ghcr.io/${GITHUB_REPOSITORY_OWNER}/charts/${name}" >> "$GITHUB_OUTPUT"
240240
241241
# Chart versions are immutable once published: whoever pinned a version
242-
# must keep resolving the same bytes forever. The PR gate above
243-
# already forces a version bump on every chart change, so a version that
244-
# is already in the registry means this commit changed something outside
245-
# `helm/sim/` — republishing would either fail or silently move a tag.
242+
# must keep resolving the same bytes forever. The PR gate above already
243+
# forces a version bump on every chart change, so a version that is
244+
# already in the registry means this commit changed something outside
245+
# `helm/sim/`.
246+
#
247+
# The lookup must fail CLOSED. Treating every non-zero exit as "absent"
248+
# would let a transient 5xx, an expired token, or a DNS blip re-push an
249+
# existing version and move a tag consumers have already pinned — and
250+
# same-version runs are routine, since the path filter also fires on
251+
# `package.json` and workflow edits.
252+
#
253+
# Verified against the pinned Helm (v3.16.4): an absent version AND an
254+
# absent repository both report `<ref>: not found`, so a first publish
255+
# still proceeds, while `denied`, `unauthorized`, and `dial tcp` failures
256+
# do not match and stop the job instead.
246257
- name: Skip if this version is already published
247258
id: exists
248259
run: |
249260
set -euo pipefail
250-
if helm show chart "oci://${{ steps.package.outputs.repository }}" \
251-
--version "${{ steps.package.outputs.version }}" > /dev/null 2>&1; then
261+
if err=$(helm show chart "oci://${{ steps.package.outputs.repository }}" \
262+
--version "${{ steps.package.outputs.version }}" 2>&1 >/dev/null); then
252263
echo "already=true" >> "$GITHUB_OUTPUT"
253264
echo "::notice::${{ steps.package.outputs.name }} ${{ steps.package.outputs.version }} is already published; skipping."
254-
else
265+
elif printf '%s\n' "$err" | grep -q ': not found'; then
255266
echo "already=false" >> "$GITHUB_OUTPUT"
267+
else
268+
printf '%s\n' "$err"
269+
echo "::error::Could not determine whether ${{ steps.package.outputs.name }} ${{ steps.package.outputs.version }} is already published. Refusing to push, because an unchecked push can overwrite a published version."
270+
exit 1
256271
fi
257272
258273
# `helm push` takes the namespace only — it derives the repository

apps/docs/content/docs/platform/self-hosting/kubernetes.mdx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,15 @@ Signing is Sigstore-only — there is no GPG `.prov` file, so `helm install --ve
7777
These are cloud-tuned **alternatives** to the generic install above — pick one path, don't run both. The commands reuse the `$BETTER_AUTH_SECRET`, `$ENCRYPTION_KEY`, `$INTERNAL_API_SECRET`, `$API_ENCRYPTION_KEY`, `$CRON_SECRET`, and `$POSTGRES_PASSWORD` variables generated in [Installation](#installation) above, so run that block's `openssl` lines first in the same shell. They use `helm upgrade --install`, so they work whether or not a release exists yet. Two caveats when converting an existing generic install rather than starting fresh: (1) **reuse the original secret values** — recover them with `helm get values sim -n simstudio` if your shell no longer has them; supplying a newly generated `ENCRYPTION_KEY` makes every previously encrypted value (workspace environment variables, stored provider keys, MCP OAuth credentials) undecryptable. (2) The cloud values rename the bundled PostgreSQL database to `simstudio`, but Postgres only applies that setting on first initialization — add `--set postgresql.auth.database=sim` to keep your existing database. If you'd rather start clean, `helm uninstall sim -n simstudio`, delete its PVCs, and run the cloud command fresh.
7878

7979
```bash
80+
# The example values files are not part of the packaged chart, so fetch the one
81+
# you want at a release tag — pinning the chart but reading values off a moving
82+
# branch would still make this command produce different deployments over time.
83+
SIM_RELEASE=v0.8.24
84+
curl -fsSLO "https://raw.githubusercontent.com/simstudioai/sim/$SIM_RELEASE/helm/sim/examples/values-aws.yaml"
85+
8086
helm upgrade --install sim oci://ghcr.io/simstudioai/charts/sim \
8187
--version 1.9.1 \
82-
--values https://raw.githubusercontent.com/simstudioai/sim/main/helm/sim/examples/values-aws.yaml \
88+
--values values-aws.yaml \
8389
--set app.env.BETTER_AUTH_SECRET="$BETTER_AUTH_SECRET" \
8490
--set app.env.ENCRYPTION_KEY="$ENCRYPTION_KEY" \
8591
--set app.env.INTERNAL_API_SECRET="$INTERNAL_API_SECRET" \
@@ -97,7 +103,7 @@ helm upgrade --install sim oci://ghcr.io/simstudioai/charts/sim \
97103

98104
Every one of those overrides is required. The cloud values files hardcode a placeholder domain in all six places, and overriding only `NEXT_PUBLIC_APP_URL` leaves sign-in pointed at the placeholder, realtime rejecting every socket upgrade, and the Ingress serving the wrong host.
99105

100-
Swap the `--values` file for your cloud: `values-aws.yaml` (EKS), `values-azure.yaml` (AKS), or `values-gcp.yaml` (GKE). Everything else is identical. Helm reads `--values` over HTTPS, so this works without a checkout; the example files are not part of the packaged chart. Download the file and edit it locally if you'd rather not fetch it at install time.
106+
Swap the `--values` file for your cloud: `values-aws.yaml` (EKS), `values-azure.yaml` (AKS), or `values-gcp.yaml` (GKE). Everything else is identical. Keep the downloaded file in your own config repo — the `--set` overrides above cover the six placeholder domains, but anything else you tune belongs in the file.
101107

102108
## Key Configuration
103109

helm/sim/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export POSTGRES_PASSWORD=$(openssl rand -base64 24 | tr -d '/+=')
2222

2323
# Install from the registry
2424
helm install sim oci://ghcr.io/simstudioai/charts/sim \
25+
--version 1.9.1 \
2526
--namespace sim --create-namespace \
2627
--set app.env.BETTER_AUTH_SECRET="$BETTER_AUTH_SECRET" \
2728
--set app.env.ENCRYPTION_KEY="$ENCRYPTION_KEY" \

0 commit comments

Comments
 (0)