Skip to content

fix(stack): pin catalog images that ECR Public mirrors and report every mirror failure - #6804

Closed
avallete wants to merge 2 commits into
developfrom
avallete/stack-ecr-cold-fallback
Closed

avallete wants to merge 2 commits into
developfrom
avallete/stack-ecr-cold-fallback

Conversation

@avallete

Copy link
Copy Markdown
Member

With GHCR unreachable and an empty Docker cache, the local stack does try the ECR Public image fallback. But ECR Public never received the digests the catalog pinned for studio, pgmeta, and pooler. The mirror pull then failed, and the error only showed the GHCR failure, so it looked as if the fallback never ran. Postgres 15/17 had the same problem and are already re-pinned on develop.

  • Re-pin studio, pgmeta, and pooler to their current tag digests. Both GHCR and ECR Public serve these as multi-arch indexes.
  • When every source fails, image and native-archive errors lead with the primary failure and then list each fallback's. The primary cause is kept. Because the pull retry matches rate limits on the message, a rate-limited mirror now also retries the chain.
  • The catalog sync refuses a pin until public.ecr.aws/supabase/cli/<service>:<version> resolves to the GHCR digest. A Dependabot bump whose image is not mirrored yet fails its sync with a blocking reason, the same as an unpublished image.
  • supabase stack without the experimental flag now names SUPABASE_EXPERIMENTAL_STACK=1 and [experimental] stack = true, instead of reporting an unknown subcommand. Completion is unchanged.

🤖 Generated with Claude Code

avallete and others added 2 commits September 24, 2026 17:38
…ry mirror failure

The catalog pinned postgres 15/17, pgmeta, pooler, and studio to digests that
GHCR still serves but ECR Public never received, so a cold start with GHCR
unreachable tried the mirror, failed, and showed only the GHCR error.

- Re-pin those images to their current tag digests, which both registries serve.
- When every source fails, image and native-archive errors lead with the
  primary failure and list each fallback's.
- The catalog sync refuses a pin until ECR Public serves the GHCR digest.
- `supabase stack` without the experimental flag explains how to enable it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e stack hint

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@avallete
avallete requested a review from a team as a code owner September 24, 2026 15:44

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Review

Three small issues were confirmed: a misleading missing-mirror message, incorrect telemetry classification for a disabled command, and missing test coverage for the new registry probe. Two digest-related findings were refuted by the code and the trusted mirror policy. No blocking issue was verified.

Findings

Severity Location Category Sources Claim
🟡 MINOR .github/scripts/sync-artifacts-catalog.test.ts:100 test-coverage codex The added test does not exercise the new ECR registry probe or digest comparison.
⚪ NIT .github/scripts/sync-artifacts-catalog.ts:273 error-messages claude A missing ECR tag is reported as a digest mismatch, obscuring that the image has not been mirrored.
⚪ NIT apps/cli/src/command-internal/stack-backend.ts:48 telemetry claude Invoking the disabled stack namespace is now classified as invalid configuration, although it is a command usage error.

Findings outside the diff

  • ⚪ NIT apps/cli/src/command-internal/stack-backend.ts:48 — Invoking the disabled stack namespace is now classified as invalid configuration, although it is a command usage error.
Refuted findings (kept for transparency, not posted as review comments)
  • .github/scripts/sync-artifacts-catalog.ts:365 (correctness): The catalog sync requires matching GHCR and ECR digests even for tag-only entries, unnecessarily blocking their version bumps when the digests differ.
    Refuted: The digest-preserving requirement applies to every slim image, including tag-only catalog entries. A mismatched ECR tag violates that documented mirror contract, so blocking the catalog update is intentional.
  • .github/scripts/sync-artifacts-catalog.ts:365 (correctness): A missing ECR mirror can be treated as published if the GHCR probe also has no digest.
    Refuted: The alleged two-undefined-digest path cannot reach the comparison: a GHCR probe without a digest is missing or lookup-failed and returns earlier. A published GHCR probe always has a valid digest, which differs from a missing mirror's undefined digest.

Stats

Claude findings: 3 · Codex findings: 2 · Confirmed: 3 · Refuted: 2 · Uncertain: 0


Models: claude-opus-5-5 + gpt-6-sol · Trigger: auto · Workflow run

This review runs once per PR. A maintainer can request another with a /ai-review comment.

Comment on lines +273 to +274
: release.status === "unmirrored"
? `${pin.service}:${pin.version} on ${DEST_REGISTRY} does not match the GHCR digest.`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚪ NIT · error-messages · source: claude

A missing ECR tag is reported as a digest mismatch, obscuring that the image has not been mirrored.

Evidence: .github/scripts/sync-artifacts-catalog.ts:324 returns a missing mirror with no digest; lines 365 and 273-274 turn that into the message that ECR does not match the GHCR digest.

Suggested fix: Distinguish a missing ECR tag from an existing tag with a different digest in the blocking reason.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworded the blocking reason to "is not on public.ecr.aws/supabase/cli under the GHCR digest", which is accurate for both a missing tag and a mismatched digest.

🤖 Addressed by Claude Code

baseDockerfile: "FROM supabase/postgres:17.6.1.168 AS pg\n",
dockerfile: "FROM supabase/postgres:17.6.1.171 AS pg\n",
catalog: fixture,
publication: async () => ({ status: "unmirrored" }),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MINOR · test-coverage · source: codex

The added test does not exercise the new ECR registry probe or digest comparison.

Evidence: .github/scripts/sync-artifacts-catalog.test.ts:95-111 supplies a publication callback that directly returns unmirrored. The probe and comparison are in .github/scripts/sync-artifacts-catalog.ts:354-366, outside the tested planner.

Suggested fix: Add a focused test of the publication lookup with controlled GHCR and ECR probe responses, covering missing and mismatched mirrors.

@avallete avallete closed this Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant