Repository navigation
Conversation
… to the last three versions Release-policy decision (spec D6): the poller now treats an upstream version as published only when an anchored ^svc-U-r(0|[1-9][0-9]*)$ release exists, matching scripts/plan-release-revision.sh, and no longer passes -f force=false to the release workflow (its force input is gone). Every polled service's release_floor moves to its third-newest stable upstream tag so the poller doesn't try to rebuild the whole legacy backlog once "published" excludes legacy tags. Chosen floors (previous -> new; three versions in the new window): - auth: v2.195.0 -> v2.195.0 (v2.195.0, v2.196.0, v2.197.0; unchanged) - postgrest: v14.16 -> v16.2 (v16.2, v16.3, v16.4) - realtime: v2.123.5 -> v2.138.6 (v2.138.6, v2.139.0, v2.139.1) - pooler: v2.9.10 -> v2.9.11 (v2.9.11, v2.9.12, v2.9.13) - analytics: v1.49.2 -> v1.50.13 (v1.50.13, v1.50.14, v1.50.15) - storage: v1.68.1 -> v1.79.21 (v1.79.21, v1.79.22, v1.79.23) - edge-runtime: v1.74.3 -> v1.76.2 (v1.76.2, v1.77.0, v1.77.1) - pgmeta: v0.96.6 -> v0.97.0 (v0.97.0, v0.98.0, v0.99.0) - studio: 2026.08.03-sha-022b374 -> 2026.09.14-sha-4dd8a95 (2026.09.14-sha-4dd8a95, 2026.09.21-sha-512201d, 2026.09.28-sha-5e59b60). services/studio/REPORT.md:60-64 flags 2026.09.21-sha-512201d and later as unbuildable (sharp traced into the Next standalone output); the chosen floor is the last documented slim-buildable tag, not that version. - postgres 15 line: 15.14.1.159 -> 15.14.1.177 (15.14.1.177, 15.14.1.178, 15.19.0.001) - postgres 17 line: 17.6.1.159 -> 17.6.1.177 (17.6.1.177, 17.6.1.178, 17.11.0.001) - imgproxy: no release_floor field; it continues to follow the storage compose pin unchanged. Floors were computed with a one-off query against the poller's own candidate sources (GitHub stable releases, Docker Hub tags, ordered by the poller's version_key) in scratch space, not committed here.
avallete
left a comment
There was a problem hiding this comment.
The overall design is solid. The planner is exactly anchored and paginated, runs are serialised per service and version, the release is created only if it doesn't already exist, publishing is limited to main, and old-style releases can't be mistaken for revisions. The host tests pass locally.
One path still breaks "published bytes are never replaced", though: re-running an old failed run can move the tags of a revision that another run has since published. Details are inline. Summary:
- Significant: re-running an old failed run can overwrite the GHCR, ECR and S3 tags of an already-published revision. Fix: add a release-exists guard at the start of each pushing job.
- Significant: draft releases count as taken revisions in the planner and the poller.
- DX: the
slim-release-publisheddispatch can't be retried once the release exists. - Minor regression: the ECR mirror's "latest" ordering sorts same-date Studio tags by the digits in their commit hash.
- DX: a few new workflow tests assert source text rather than behaviour, and there are some comments to tidy up.
Minor, non-blocking: $SERVICE-$VERSION.external-release.json and .oci-provenance.json are still named with the upstream version. They can't collide, since each release has its own assets. Rename them to the release version only if it's meant to cover every asset name.
…eleases - Guard publish-image, publish-natives, and mirror-ecr against pushing to an already-published revision, even on a re-run of failed jobs. - Treat draft GitHub releases as not taken in the revision planner, the poller, and the release create step, and clean up a stale draft before re-creating. - Move the CLI notification into its own retryable job and fail the plan early when the dispatch token is missing. - Order Studio releases in the mirror audit and results tables by publish time instead of the sha's hex digits. - Replace source-text workflow assertions with tests that execute the real run: blocks against fixtures. - Clean up comments that narrated task/plan history instead of stating the rule.
|
Thanks for the thorough review, @avallete. All five points are addressed in 5d0edad; each thread has the details.
On the non-blocking note, I've left |
avallete
left a comment
There was a problem hiding this comment.
Thanks for the quick turnaround. I re-checked 5d0edad, and all five points from the first round are addressed:
- The guards come before every push.
- Draft handling is safe, because runs of the same version take turns in the concurrency group.
notify-clican be retried on its own.- The TypeScript and Python comparators agree on every tricky version list I tried.
- The tests now run the real step scripts.
The host tests and actionlint pass locally.
Two things still need a change before this is safe:
notify-cliis skipped whenevermirror-ecrfails. The skip comes from the implicitsuccess()in itsif:. Adding!cancelled()fixes it (details inline).- The new guard fails open on some API errors.
gh release viewcan report "release not found" when the published-release lookup itself errored (details inline).
Non-blocking:
- The draft-filter test in the poller suite can't fail (inline).
- The token check is duplicated (inline).
- A few comments still describe history, or repeat another comment, rather than giving a reason:
- the "were dropped" / "Kept as the one structural check" comments in
test-external-workflows.sh; - the long comparator comment in
ecr-mirror.ts, which repeats the Python one; - the long comment in the notify step.
- the "were dropped" / "Kept as the one structural check" comments in
- For Studio tags from the same date, "latest" now means most recently published. So a hotfix
-r5of an older sha outranks a newer sha's-r0. That's probably intended, but worth a sentence indocs/design/ecr-mirror-dispatch.md.
…ation reachable - notify-cli no longer skips when an unrelated ancestor job (mirror-ecr) fails but publish-release still succeeds. - The published-release guard and the release-create step now query the REST releases-by-tag endpoint directly and fail closed on API errors, instead of gh release view's ambiguous REST+GraphQL lookup; stale drafts are deleted by id. - Test stubs for the draft-exclusion --jq filter now run the real filter through jq instead of a hand-written stand-in. - The CLI dispatch token check is now a single step after planning; mirror-ecr's and notify-cli's now-unreachable missing-token paths are removed.
|
Thanks @avallete. All four round-2 comments are addressed in 76120b5, with details in each thread:
After that I ran an independent review of the whole branch, going back and forth until we agreed. It raised two small issues, both fixed in ea4e189:
The follow-up review pass found nothing else actionable. CI is green. |
avallete
left a comment
There was a problem hiding this comment.
Approving. Thanks for working through all the rounds. I re-checked 76120b5 and ea4e189, and all four round-2 points are fixed:
-
notify-clinow has!cancelled(). No other job has the same implicit-success()problem. -
The release check now queries the tag directly and fails closed. I checked this against real GitHub with gh 2.97.0:
- a missing tag gets a 404, and the check lets the push continue;
- a published tag gets a 200, and the check stops with the immutability message;
- a 401 or any other error stops the run.
Stale drafts are found by listing releases and deleted by id, which is the right split.
-
The
--jq-honoring stubs now catch a regression: removingselect(.draft | not)from the planner or the poller makes their suites fail. -
The token check is a single step in
plan, and validation-only runs still work without the token. -
A whitespace-only
hotfix_reasonis rejected before any work starts.
The host tests and actionlint pass locally.
A few optional nits are inline. One more, not worth a thread: the check can't tell a missing tag from a repo that doesn't exist or can't be accessed (gh returns identical output for both). That's not reachable while GH_REPO is always set to github.repository, so it's just for awareness.
|
Thanks for the approval, @avallete. All four inline nits are addressed in 10caef8. I also cleaned up three small leftovers:
On the missing-repo versus missing-tag note: agreed. The check can't tell them apart, but that can't happen while |
…single version table (supabase#6883) ## Summary slim-services now publishes immutable `<upstream>-r<N>` releases (supabase/slim-services#326, supabase#328). This PR makes the CLI consume them safely and from one place: - **Pinning.** Every slim artifact is pinned by content: the image digest, plus an archive and manifest sha256 per target. Nothing is looked up at runtime. - **One version table.** The stack catalog (`packages/stack/src/Artifacts.ts`) is the only place slim-capable service versions are written down. The new stack, legacy `supabase start`, and legacy slim mode (`SUPABASE_USE_SLIM_IMAGES`) all derive from it. - **Updates.** Upgrades and packaging hotfixes arrive as automated PRs from slim-services releases. ### Pinning - **Catalog entries.** They are now `ArtifactPin`s: - `upstreamVersion` - `revision` - `image: …:<U>-r<N>@sha256:…` - `upstreamImage`: the upstream image slim-services built from or mirrored, as recorded in the release - `natives`: sha256s per target - **Native downloads.** - The runtime `SHA256SUMS` and GHCR checksum lookups are gone. The GitHub release and S3 serve bytes only. - The manifest is hash-checked before it is parsed. - A mirror that serves the wrong bytes falls through to the next one. - The cache key is `slim-services/<svc>/<R>/<target>`, so a hotfix revision gets its own cache entry. ### One version table - **Generated Dockerfile lines.** The slim-capable `FROM` lines of `apps/cli/src/shared/services/Dockerfile`, and its Go copy, are generated from the catalog by `apps/cli/scripts/render-service-dockerfile.ts`. - The generator rewrites only those 14 lines, in place, and takes each repository from the existing line. imgproxy stays on `darthsim/imgproxy`. - Kong, `pg14`, and the job images (migra, pg_prove, pgadmin-schema-diff) are still maintained by hand or by Dependabot. - A drift test in the required `apps/cli` unit project fails when the Dockerfile and the catalog disagree. - **Postgres 13/15 and 14.** New `pg15` (generated) and `pg14` (hand-pinned) stages replace the hardcoded constants, in both the TS and the Go CLI. - Non-slim PG13/15 moves from 15.8.1.085 to the pinned 15 line. - Slim mode translates `pg15` through the catalog, like every other alias. - **Slim mode.** It now always finds its pin for the default versions. A linked project's hosted version that the catalog doesn't pin still uses the upstream image. ### Updates - **`slim-release-published.yml`** reconciles the dispatched service against every committed slim-services release. For each release line it opens, or rewrites in place: - a **hotfix** PR (`slim-hotfix/<svc>[-<line>]`), when the pinned upstream has a newer revision; - an **upgrade** PR (`slim-bump/<svc>[-<line>]`), when a newer upstream exists on that line. - **Each PR:** - pins exactly the planned release; - regenerates both Dockerfiles; - is assigned to `jgoux`. - **Mirror timing.** Before planning, the run waits (bounded) for the dispatched release to appear in the release list. Before pinning, it waits (bounded) for the S3 mirror of a new release, and a digest mismatch fails immediately. - **Trust.** Plan and apply run from one checkout of the default branch, so a re-run recomputes the plan and never applies a stale one. Every `::error ::`/`::warning ::` line uses workflow-command data encoding. The app token reaches only `git push` and `gh`: it is never written to `.git/config`, and every `bun`/`pnpm` command (the formatter runs from the locked install) runs without it. The PR lookup ignores fork PRs. Payload and release-tag values are validated against anchored patterns, and recorded image references are validated and escaped before they are written into the catalog. - **Dependabot.** It now ignores every slim-capable image, and the Dependabot-to-catalog sync (`sync-artifacts-catalog.yml`) is deleted. - **Tests.** They derive versions from the catalog, so a bump PR touches only `Artifacts.ts` and the two Dockerfiles. ### Other changes needed by the new versions - **Vector 0.58** no longer expands `${VAR}` in its config. - The recipe writes real values into its own config instead. - In caller-supplied pipelines it fills in only `LOGFLARE_URL` and `LOGFLARE_PRIVATE_ACCESS_TOKEN`. - It never enables `--dangerously-allow-env-var-interpolation`. - **Vector on legacy `supabase start`.** Vector 0.58's images don't ship `/etc/vector`, so the entrypoint creates it before writing the config. A `start.lifecycle` e2e scenario starts Vector against a real Logflare. - **`pgdelta.seam.layer.ts`** compares slim images by revision or digest, so a container on `-r0` is reported stale once the catalog moves to `-r1`. - **Three integration tests that failed under load now have coherent time budgets:** - `upload-release-assets`: the retry that must succeed had to fit in the same 500ms as the attempt that hangs on purpose. - `stack-shadow`: a real-Docker test ran under vitest's 5s default timeout. - `sweep-live-projects`: a 10s hard kill inside the test's budget. ### Docs ADR 0026 is rewritten for this model, including the tradeoffs: - slim-capable upstream and security fixes arrive only via slim-services releases; - Dependabot's cooldown no longer applies to them; - kong and `pg14` are bumped by hand; - the Deno 1 edge-runtime override stays pinned separately. `infra/cli-artifacts/README.md` is updated to match. ## Release notes - Unlinked local projects on Postgres 13 or 15 now start `supabase/postgres:15.19.0.002` instead of `15.8.1.085`. Later catalog upgrades on the 15 line move them within the same major. - `supabase start` runs the catalog's upstream versions (table below), and Storage is pinned to the `v1.79.28-r1` hotfix. ## Versions Every catalog entry pins its newest committed revision. Legacy `supabase start` now runs the same upstream versions: | Service | Catalog before → after | Legacy Dockerfile before → after | |---|---|---| | postgres 17 | `17.6.1.173` → `17.11.0.002-r0` | `17.6.1.171` → `17.11.0.002` | | postgres 15 (PG13/15) | `15.14.1.173` → `15.19.0.002-r0` | `15.8.1.085` (constant) → `15.19.0.002` | | postgrest | `v16.2` → `v16.4-r0` | `v16.3` → `v16.4` | | auth | `v2.196.0` → `v2.197.0-r0` | `v2.197.0` (unchanged) | | realtime | `v2.134.5` → `v2.140.3-r0` | `v2.135.3` → `v2.140.3` | | storage | `v1.73.0` → `v1.79.28-r1` | `v1.77.0` → `v1.79.28` | | imgproxy | `v3.8.0` → `v3.26.0-r0` | `v3.8.0` → `v3.26.0` | | edge-runtime | `v1.77.1` → `v1.77.1-r0` | `v1.77.1` (unchanged) | | studio | `2026.09.04-sha-5a67366` → `2026.09.28-sha-5e59b60-r0` | `2026.09.14-sha-4dd8a95` → `2026.09.28-sha-5e59b60` | | pgmeta | `v0.99.0` → `v0.99.0-r0` | `v0.99.0` (unchanged) | | mailpit | `v1.30.2` → `v1.31.3-r0` | `v1.30.2` → `v1.31.3` | | analytics | `v1.50.9` → `v1.50.15-r0` | `1.50.12` → `1.50.15` | | vector | `0.53.0` → `0.58.0-r0` | `0.53.0-alpine` → `0.58.0-alpine` | | pooler | `v2.9.12` → `v2.9.13-r0` | `2.9.13` (unchanged) |
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [supabase](https://redirect.github.com/supabase/cli) ([source](https://redirect.github.com/supabase/cli/tree/HEAD/apps/cli)) | `2.118.0` → `2.119.0` |  |  | --- > [!WARNING] > Some dependencies could not be looked up. Check the [Dependency Dashboard](../issues/10) for more information. --- ### Release Notes <details> <summary>supabase/cli (supabase)</summary> ### [`v2.119.0`](https://redirect.github.com/supabase/cli/releases/tag/v2.119.0) [Compare Source](https://redirect.github.com/supabase/cli/compare/v2.118.0...v2.119.0) ##### Bug Fixes - **cli:** declare the [@​libpg-query/parser](https://redirect.github.com/libpg-query/parser) import plpgsql-deparser leaves undeclared ([#​6827](https://redirect.github.com/supabase/cli/issues/6827)) ([6e98622](https://redirect.github.com/supabase/cli/commit/6e98622c332eaedf99ea1cd0e45833252d9d87bf)), closes [supabase/cli#6822](https://redirect.github.com/supabase/cli/issues/6822) - **cli:** decline unrecognised yes/no prompt answers (CLI-2524) ([#​6910](https://redirect.github.com/supabase/cli/issues/6910)) ([b29e743](https://redirect.github.com/supabase/cli/commit/b29e7437b278ebe8102fd1334c7adb5a1d79f9ef)) - **cli:** keep migra session settings on reconnect (CLI-2522) ([#​6884](https://redirect.github.com/supabase/cli/issues/6884)) ([72b10f8](https://redirect.github.com/supabase/cli/commit/72b10f88c639b43f0f1937416c6d1b3adb54bb6b)) - **cli:** label non-stable builds in the root help description ([#​6868](https://redirect.github.com/supabase/cli/issues/6868)) ([04b1ce9](https://redirect.github.com/supabase/cli/commit/04b1ce9f14a5d46625c42670da158ea4ce792a70)) - **cli:** prefer Docker, then Podman, for automatic stack runtime selection ([#​6859](https://redirect.github.com/supabase/cli/issues/6859)) ([1ef5bc0](https://redirect.github.com/supabase/cli/commit/1ef5bc05a99829bfc60e1f48ff17b70458cedf14)) - **cli:** read request bodies before local functions respond ([#​6830](https://redirect.github.com/supabase/cli/issues/6830)) ([f70cda5](https://redirect.github.com/supabase/cli/commit/f70cda594448d35865549dcdc41ca16316bd8f37)), closes [#​6564](https://redirect.github.com/supabase/cli/issues/6564) - **cli:** reject `test new` names that escape supabase/tests (CLI-2480) ([#​6790](https://redirect.github.com/supabase/cli/issues/6790)) ([c877778](https://redirect.github.com/supabase/cli/commit/c877778f3394af39db88e75e1ed5225206e049ed)) - **cli:** show stack connection details on start and status (CLI-2546, CLI-2531, CLI-2530) ([#​6894](https://redirect.github.com/supabase/cli/issues/6894)) ([288edc2](https://redirect.github.com/supabase/cli/commit/288edc26628844b6a09c378a126a200bcd2adeae)) - **cli:** skip the contrib\_regression clone on pg-delta shadows ([#​6920](https://redirect.github.com/supabase/cli/issues/6920)) ([3704383](https://redirect.github.com/supabase/cli/commit/37043833af5d913ee233d76cd9fa63760c43063c)) - **cli:** state stack destroy --yes instead of self-answering prompt ([#​6903](https://redirect.github.com/supabase/cli/issues/6903)) ([63a2ff5](https://redirect.github.com/supabase/cli/commit/63a2ff5d8577df9a4625db6be251186eecd4abc7)), closes [supabase/cli#6889](https://redirect.github.com/supabase/cli/issues/6889) - **cli:** stop splitting escape strings on escaped quotes (CLI-2537) ([#​6906](https://redirect.github.com/supabase/cli/issues/6906)) ([233d145](https://redirect.github.com/supabase/cli/commit/233d1459e22ad14be9104ceb1254a7c3fe11b84d)) - **cli:** tidy stack start and non-TTY output friction ([#​6889](https://redirect.github.com/supabase/cli/issues/6889)) ([b8fae81](https://redirect.github.com/supabase/cli/commit/b8fae815ea95b5e298a02c2a97335f17a3652b03)) - **cli:** treat the stack database --db-url as local ([#​6904](https://redirect.github.com/supabase/cli/issues/6904)) ([2d7609d](https://redirect.github.com/supabase/cli/commit/2d7609dd9d655ad742be557819e923432b2e1244)) - **config:** ignore unset sms provider (CLI-2463) ([#​6685](https://redirect.github.com/supabase/cli/issues/6685)) ([eb0c3ff](https://redirect.github.com/supabase/cli/commit/eb0c3ff6a70e144e33173558130a900a81adc450)) - **stack:** clean up stacks when Docker is unavailable on start and destroy ([#​6825](https://redirect.github.com/supabase/cli/issues/6825)) ([e836519](https://redirect.github.com/supabase/cli/commit/e83651930de7f365b8e3d9e8800cf5f975a56177)) - **stack:** connect Studio to the database and restore its settings ([#​6865](https://redirect.github.com/supabase/cli/issues/6865)) ([a883019](https://redirect.github.com/supabase/cli/commit/a8830191962ac9de72accae701880b3bd537e012)) - **stack:** give each Mailpit instance its own database ([#​6901](https://redirect.github.com/supabase/cli/issues/6901)) ([2b13026](https://redirect.github.com/supabase/cli/commit/2b13026196177a2766bc8bca2fd4fd41435dca11)) - **stack:** group database helper containers with their stack ([#​6870](https://redirect.github.com/supabase/cli/issues/6870)) ([2547ce5](https://redirect.github.com/supabase/cli/commit/2547ce5d4b6d826c2199bf46a5217d8da38752a5)), closes [supabase/cli#6867](https://redirect.github.com/supabase/cli/issues/6867) [supabase/cli#6867](https://redirect.github.com/supabase/cli/issues/6867) - **stack:** harden readiness, port claims, and container storage ([#​6835](https://redirect.github.com/supabase/cli/issues/6835)) ([2c006dd](https://redirect.github.com/supabase/cli/commit/2c006dd11a22faf6530054da8885e08e5ce30a6d)), closes [#​6834](https://redirect.github.com/supabase/cli/issues/6834) [#​6836](https://redirect.github.com/supabase/cli/issues/6836) [#​6837](https://redirect.github.com/supabase/cli/issues/6837) [#​6838](https://redirect.github.com/supabase/cli/issues/6838) [#​6839](https://redirect.github.com/supabase/cli/issues/6839) [#​6840](https://redirect.github.com/supabase/cli/issues/6840) [#​6841](https://redirect.github.com/supabase/cli/issues/6841) - **stack:** keep in-progress artifact extractions safe from the leftover reaper ([#​6881](https://redirect.github.com/supabase/cli/issues/6881)) ([98cda96](https://redirect.github.com/supabase/cli/commit/98cda96f069fbceb2748beba11660bca61b4efe4)) - **stack:** keep in-use cached artifacts when a request needs more paths ([#​6882](https://redirect.github.com/supabase/cli/issues/6882)) ([e49b791](https://redirect.github.com/supabase/cli/commit/e49b7913be8b4b62ba8cefc86ce59c76c02b0678)) - **stack:** keep Storage uploads working on Docker Desktop for macOS ([#​6921](https://redirect.github.com/supabase/cli/issues/6921)) ([a0711c0](https://redirect.github.com/supabase/cli/commit/a0711c0c0872c4de7404eb47f0fd30175be7c67d)), closes [supabase/slim-services#329](https://redirect.github.com/supabase/slim-services/issues/329) [#​6900](https://redirect.github.com/supabase/cli/issues/6900) - **stack:** keep Studio awake for 5 minutes after its last request ([#​6866](https://redirect.github.com/supabase/cli/issues/6866)) ([66e92c7](https://redirect.github.com/supabase/cli/commit/66e92c71899da7b2cc1fdc53bae7d1fed972bf55)) - **stack:** load function deno.json files as Deno config ([#​6907](https://redirect.github.com/supabase/cli/issues/6907)) ([4371ed3](https://redirect.github.com/supabase/cli/commit/4371ed369d5f7f806e6905e0ec9ba79eb831c78b)) - **stack:** name containers by project and service ([#​6867](https://redirect.github.com/supabase/cli/issues/6867)) ([315dbcd](https://redirect.github.com/supabase/cli/commit/315dbcd13f810547a206b444ea3dcbad058e3357)) - **stack:** open a fresh upstream connection per proxied request ([#​6897](https://redirect.github.com/supabase/cli/issues/6897)) ([a1be13e](https://redirect.github.com/supabase/cli/commit/a1be13e80573a0eac2ce13713dc2501a1f27c2fd)) - **stack:** reach stack services from Windows and Docker Desktop containers ([#​6887](https://redirect.github.com/supabase/cli/issues/6887)) ([87d9efb](https://redirect.github.com/supabase/cli/commit/87d9efbb28f13a7093c82c2ced0a4ff5fc3090dd)) - **stack:** reduce native stack friction in agent sandboxes ([#​6856](https://redirect.github.com/supabase/cli/issues/6856)) ([ff14e91](https://redirect.github.com/supabase/cli/commit/ff14e91a715b0beb248a5119468ff5483f91f744)) - **stack:** release log followers on exit (CLI-2521) ([#​6861](https://redirect.github.com/supabase/cli/issues/6861)) ([621768f](https://redirect.github.com/supabase/cli/commit/621768f7918c3b04f467ce45bbb4d680af4aaf25)), closes [#​6594](https://redirect.github.com/supabase/cli/issues/6594) - **stack:** require passwords on the native database socket (CLI-2503) ([#​6833](https://redirect.github.com/supabase/cli/issues/6833)) ([b8026df](https://redirect.github.com/supabase/cli/commit/b8026df5ea50d49bc06dcfa8ab877e5f92c032a9)) - **stack:** retry image pulls after transient registry failures ([#​6879](https://redirect.github.com/supabase/cli/issues/6879)) ([ed05cb8](https://redirect.github.com/supabase/cli/commit/ed05cb84d7d340a1e38f3cda195f33d92a1c26d7)) - **stack:** reuse keep-alive upstream connections in the HTTP gateway ([#​6925](https://redirect.github.com/supabase/cli/issues/6925)) ([985e0ae](https://redirect.github.com/supabase/cli/commit/985e0ae9e9e9f364630a00dc45ea300f5f5019d8)), closes [#​6897](https://redirect.github.com/supabase/cli/issues/6897) [#​6922](https://redirect.github.com/supabase/cli/issues/6922) - **stack:** serve Storage S3 and resumable uploads behind the gateway ([#​6917](https://redirect.github.com/supabase/cli/issues/6917)) ([481cb3f](https://redirect.github.com/supabase/cli/commit/481cb3f43650c093be29147b32e685e5b4b0bf77)), closes [#​6900](https://redirect.github.com/supabase/cli/issues/6900) [#​6916](https://redirect.github.com/supabase/cli/issues/6916) - **stack:** start auth with zero session limits (CLI-2506) ([#​6848](https://redirect.github.com/supabase/cli/issues/6848)) ([643d648](https://redirect.github.com/supabase/cli/commit/643d648202ffcc71ed2fad95c17b92e822bcc205)) - **stack:** stop Postgres containers with a fast shutdown ([#​6834](https://redirect.github.com/supabase/cli/issues/6834)) ([e03ea7c](https://redirect.github.com/supabase/cli/commit/e03ea7c59335ac5979f3cf1926b8495f772ec642)), closes [#​6835](https://redirect.github.com/supabase/cli/issues/6835) [#​6836](https://redirect.github.com/supabase/cli/issues/6836) [#​6837](https://redirect.github.com/supabase/cli/issues/6837) [#​6838](https://redirect.github.com/supabase/cli/issues/6838) [#​6839](https://redirect.github.com/supabase/cli/issues/6839) [#​6840](https://redirect.github.com/supabase/cli/issues/6840) [#​6841](https://redirect.github.com/supabase/cli/issues/6841) - **stack:** upgrade edge-runtime to v1.77.1 ([#​6844](https://redirect.github.com/supabase/cli/issues/6844)) ([e29a712](https://redirect.github.com/supabase/cli/commit/e29a71245659d7b9bd5b27197cb8611704cd368a)) ##### Features - **cli:** drive gen types languages from the [@​supabase/typegen](https://redirect.github.com/supabase/typegen) registry (SDK-1956) ([#​6822](https://redirect.github.com/supabase/cli/issues/6822)) ([d021886](https://redirect.github.com/supabase/cli/commit/d021886ede50ff8b59b50950da4f7393e2d7fcef)), closes [supabase/sdk#231](https://redirect.github.com/supabase/sdk/issues/231) [supabase/sdk#233](https://redirect.github.com/supabase/sdk/issues/233) - **cli:** graduate OrioleDB configuration from experimental ([#​6828](https://redirect.github.com/supabase/cli/issues/6828)) ([48cabe3](https://redirect.github.com/supabase/cli/commit/48cabe354c16ce4c67199c4b46bbdca4265d17ae)) - **cli:** report stack MCP at the API URL and include connection env in JSON (CLI-2546) ([#​6914](https://redirect.github.com/supabase/cli/issues/6914)) ([26dc09a](https://redirect.github.com/supabase/cli/commit/26dc09a3245055d71352888d1d8f93beceedafc3)), closes [#​6894](https://redirect.github.com/supabase/cli/issues/6894) [#​6898](https://redirect.github.com/supabase/cli/issues/6898) - **cli:** upgrade pg-delta to 1.0.0-alpha.56 ([#​6913](https://redirect.github.com/supabase/cli/issues/6913)) ([8a7963e](https://redirect.github.com/supabase/cli/commit/8a7963e31241d7bc947c33a22cfac2459ddeb01d)) - **stack:** add a testing entrypoint and derive the Promise API ([#​6841](https://redirect.github.com/supabase/cli/issues/6841)) ([7894283](https://redirect.github.com/supabase/cli/commit/7894283333a1c706f43865cb516235779ceb50a2)), closes [#​6834](https://redirect.github.com/supabase/cli/issues/6834) [#​6835](https://redirect.github.com/supabase/cli/issues/6835) [#​6836](https://redirect.github.com/supabase/cli/issues/6836) [#​6837](https://redirect.github.com/supabase/cli/issues/6837) [#​6838](https://redirect.github.com/supabase/cli/issues/6838) [#​6839](https://redirect.github.com/supabase/cli/issues/6839) [#​6840](https://redirect.github.com/supabase/cli/issues/6840) - **stack:** lease owners with a lock and bind session stacks to creators ([#​6838](https://redirect.github.com/supabase/cli/issues/6838)) ([dfc52e6](https://redirect.github.com/supabase/cli/commit/dfc52e6ac7b67918bdc38e3b986e3b0a1568eb6f)), closes [#​6834](https://redirect.github.com/supabase/cli/issues/6834) [#​6835](https://redirect.github.com/supabase/cli/issues/6835) [#​6836](https://redirect.github.com/supabase/cli/issues/6836) [#​6837](https://redirect.github.com/supabase/cli/issues/6837) [#​6839](https://redirect.github.com/supabase/cli/issues/6839) [#​6840](https://redirect.github.com/supabase/cli/issues/6840) [#​6841](https://redirect.github.com/supabase/cli/issues/6841) - **stack:** pin slim artifacts by revision and make the catalog the single version table ([#​6883](https://redirect.github.com/supabase/cli/issues/6883)) ([62aac0f](https://redirect.github.com/supabase/cli/commit/62aac0ff87aac7651f2066ecd5da2fe8078ca591)), closes [supabase/slim-services#326](https://redirect.github.com/supabase/slim-services/issues/326) [#​328](https://redirect.github.com/supabase/cli/issues/328) - **stack:** serve Studio's MCP server at /mcp on the API listener (CLI-2546) ([#​6898](https://redirect.github.com/supabase/cli/issues/6898)) ([8ae22bc](https://redirect.github.com/supabase/cli/commit/8ae22bcba2fbe5b9e5de2c42c54bf332463f059a)), closes [#​6894](https://redirect.github.com/supabase/cli/issues/6894) - **stack:** ship the functions bootstrap with the package ([#​6839](https://redirect.github.com/supabase/cli/issues/6839)) ([7cd1a79](https://redirect.github.com/supabase/cli/commit/7cd1a79d0581f4160342913db94bfb0d8f1f3400)), closes [#​6834](https://redirect.github.com/supabase/cli/issues/6834) [#​6835](https://redirect.github.com/supabase/cli/issues/6835) [#​6836](https://redirect.github.com/supabase/cli/issues/6836) [#​6837](https://redirect.github.com/supabase/cli/issues/6837) [#​6838](https://redirect.github.com/supabase/cli/issues/6838) [#​6840](https://redirect.github.com/supabase/cli/issues/6840) [#​6841](https://redirect.github.com/supabase/cli/issues/6841) ##### Performance Improvements - **cli:** initialize catalog schemas without temporary servers ([#​6831](https://redirect.github.com/supabase/cli/issues/6831)) ([257bee9](https://redirect.github.com/supabase/cli/commit/257bee9bce93c096a6e7f9ba00fded141fd751ac)) </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/paulthvt/loomia). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMjUuMSIsInVwZGF0ZWRJblZlciI6IjQ0LjEyNS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Summary
Each build now gets its own immutable release version,
<upstream>-r<N>, instead of reusing the upstream version string and overwriting it withforce=true. A packaging fix becomes a new revision; published bytes are never replaced. This lets the CLI pin every artifact by content.Release version.
R = <upstream>-r<N>, whereNstarts at0.Rnames::R,:R-linux-*,:R-native-*), ECR Public and S3 paths;image.versionlabel and the local image tag.Everything that talks to upstream still uses the upstream version: source checkout, upstream image lookups, external snapshots, and version strings baked into binaries.
Commit point.
scripts/plan-release-revision.shallocatesNfrom the full paginated release list before anything is pushed.main. PR branches usevalidation_only.Workflow inputs.
forceis removed.hotfixandhotfix_reasonpublish the next revision of an already-published upstream version, and the reason goes into the release notes.Integrity.
SHA256SUMSnow also covers the finalmanifest.json.version(R),upstream_versionandrevision.CLI notification. After the release is created, the workflow sends
slim-release-published({service, upstream_version, revision, release_version}) to the CLI repo, so hotfixes can be picked up. The step fails loudly if it can't dispatch.Mirrors and results. The ECR/S3 audit and backfill, and the README results tables, only consider
-rNreleases, ordered by upstream version and then revision. Mirrors are reconciled against the committed GHCR digests.Legacy releases. Releases without
-rNare frozen and ignored. Nothing rewrites or deletes them, so already-released CLIs keep working.Poller. A version counts as published only when an
-rNrelease exists, andforceis no longer passed.Release floors (release-policy decision). Each polled service's
release_floormoves to its third-newest stable tag. The per-service values are in thefeat(poll)commit body.AGENTS.md: a floor must never be above a version the CLI catalog pins.2026.09.14-sha-4dd8a95, the last buildable tag;services/studio/REPORT.mdrecords newer tags as unreleasable.Docs. Updated
README.md,AGENTS.md,docs/design/ecr-mirror-dispatch.md,HOST_NATIVE_ARTIFACTS.md,IMAGE_CONTRACT.mdand the Nix playbook.The matching CLI change (pinned digests for image, archive and manifest, plus hotfix pickup) is in draft PR supabase/cli#6883. Its pins get filled in once the
-r0republish has run.After merge
authr0, then ahotfix=truer1, and check thatr0's release assets, GHCR digests and S3 objects are unchanged.-r0. Dispatch mailpit and vector by hand.Test plan
repository-checks.yml,bun testforecr-mirrorandpublish-native-oci,bash -n(including macOS bash 3.2), and shellcheckPOLL_DRY_RUN=1against this repo: it would dispatch only versions at or above the new floors, with noforcerepository-checksgreen on this PRservice-release.ymlvalidation_only=trueon this ref for auth (derived image), vector (mirrored image), studio (Docker Hub) and postgres 17: archive names end in-r0-<target>, manifests carry the new fields, andSHA256SUMSlists the manifests (auth, vector, studio, postgres). I downloaded the auth darwin-arm64 assets and checked them: the names end in-r0, the manifest hasversion: v2.197.0-r0,upstream_version: v2.197.0andrevision: 0, andshasum -cpasses on all three files inSHA256SUMS.