Skip to content

ci: build and push grid-wallet-prod image to ECR#747

Open
mariano-macri wants to merge 2 commits into
grid-wallet-prod-dockerfile-fixfrom
grid-wallet-prod-image-workflow
Open

ci: build and push grid-wallet-prod image to ECR#747
mariano-macri wants to merge 2 commits into
grid-wallet-prod-dockerfile-fixfrom
grid-wallet-prod-image-workflow

Conversation

@mariano-macri

Copy link
Copy Markdown

Stacked on #746 (which makes the image buildable at all).

Builds components/grid-wallet-prod and pushes it to the ECR repo vended by tooling-infra (terraform/apps/grid-wallet-prod), so the app can be deployed to the internal tooling EKS cluster behind Okta.

What it does

On pushes to main touching components/grid-wallet-prod/**: assume github-actions-grid-wallet-prod via GitHub OIDC, build linux/arm64, push an immutable sha-<gitsha> tag.

Three things worth reviewing

Landing order is mandatory. The path filter includes the workflow's own file, so merging this before the component stack reaches main triggers a run against a main with no components/grid-wallet-prod/ directory, and the build fails on a missing working directory. Land the component stack first, this second.

linux/arm64 because the tooling-prod cluster is Graviton (m8g). No other workflow in this repo uses an ARM label yet — if the first run sits in queued, GitHub-hosted ARM runners aren't enabled for the org and the fallback is setup-qemu + setup-buildx on ubuntu-latest (noted inline). ARC runners are not an option here: they have no Docker daemon.

The sandbox flag is a build arg, not config. NEXT_PUBLIC_* is inlined by Next at build time, so --build-arg NEXT_PUBLIC_GRID_SANDBOX=true is written literally in the workflow and has no default in the Dockerfile. A future production image would be a separate workflow against a separate ECR repo and cannot inherit the sandbox affordance by accident.

Idempotency

The ECR repo is IMMUTABLE-tagged, so re-pushing an existing tag is a hard failure. The build is guarded by a describe-images check that distinguishes "tag absent" from "the call failed" — a bare if aws ... >/dev/null 2>&1 is exempt from set -e and would treat an IAM error as a missing image, then die on the immutable push. Only ImageNotFoundException means "go build"; anything else fails loudly.

No workflow_dispatch: the IAM trust policy pins the sub claim to refs/heads/main, so a dispatch from any other ref could not authenticate.

Depends on

tooling-infra PR (ECR repo + github-actions-grid-wallet-prod role) must be applied before this runs, or the first push has nothing to authenticate against.

🤖 Generated with Claude Code

mariano-macri and others added 2 commits July 26, 2026 09:19
Triggers on pushes to main touching components/grid-wallet-prod/**, assumes
github-actions-grid-wallet-prod via OIDC, and pushes an immutable sha-<gitsha>
image to the ECR repo vended by tooling-infra.

Builds linux/arm64 because the tooling-prod cluster is Graviton. No other
workflow in this repo uses an ARM label yet, so if the first run sits in
`queued`, GitHub-hosted ARM runners are not enabled for the org; the fallback
is setup-qemu + setup-buildx on ubuntu-latest, noted inline.

--build-arg NEXT_PUBLIC_GRID_SANDBOX=true is written literally rather than
defaulted in the Dockerfile, so a future production image is a separate
workflow against a separate repo and cannot inherit the sandbox affordance.

The ECR repo is IMMUTABLE-tagged, so the build is guarded by a describe-images
check: a re-run for an already-pushed SHA exits 0 instead of failing on the
duplicate tag.

No workflow_dispatch: the IAM trust policy pins the sub claim to
refs/heads/main, so a dispatch from any other ref could not authenticate.

Co-Authored-By: Claude Opus 5 <[email protected]>
The idempotency guard was `if aws ecr describe-images ... >/dev/null 2>&1`.
Commands used as an `if` condition are exempt from `set -e`, so an IAM error,
a throttle, or a network blip was indistinguishable from "the tag isn't there"
— the job would fall through, build, and then die on the immutable push with a
misleading duplicate-tag error.

Now the exit code and stderr are captured separately: rc 0 means the image
exists and the job exits clean, ImageNotFoundException means build, and
anything else fails loudly with the underlying AWS error.

Co-Authored-By: Claude Opus 5 <[email protected]>
@vercel

vercel Bot commented Jul 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
grid-flow-builder Ignored Ignored Jul 26, 2026 5:08pm
grid-wallet-demo Ignored Ignored Jul 26, 2026 5:08pm

Request Review

@greptile-apps

greptile-apps Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds a GitHub Actions workflow that builds the Grid Wallet production component for ARM64 and publishes an immutable commit-tagged image to ECR.

  • Runs on pushes to main affecting the component or workflow.
  • Authenticates to AWS through GitHub OIDC.
  • Skips builds when the commit image already exists and distinguishes missing images from AWS command failures.

Confidence Score: 4/5

The PR is not yet safe to merge because the privileged publishing job still executes actions through mutable references.

The previously reported supply-chain path remains at HEAD: code selected by mutable action tags executes with OIDC permission and participates in assuming the ECR-publishing role.

Files Needing Attention: .github/workflows/grid-wallet-prod-image.yml

Important Files Changed

Filename Overview
.github/workflows/grid-wallet-prod-image.yml Adds the ARM64 ECR image build-and-publish workflow with immutable-tag idempotency handling.

Reviews (2): Last reviewed commit: "ci: don't treat a failed describe-images..." | Re-trigger Greptile

# docker/setup-qemu-action + docker/setup-buildx-action on ubuntu-latest.
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@v4

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.

P2 security Mutable privileged action reference

This image-publishing job references executable actions by mutable major-version tags while granting OIDC or inherited AWS credential access. Pinning these actions to full commit SHAs prevents an upstream tag change from altering the code that can assume the publishing role or modify and publish the image.

How this was verified: The referenced actions run in a job with id-token: write, and the workflow subsequently assumes the ECR-publishing role and pushes the checked-out workspace.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/grid-wallet-prod-image.yml
Line: 28

Comment:
**Mutable privileged action reference**

This image-publishing job references executable actions by mutable major-version tags while granting OIDC or inherited AWS credential access. Pinning these actions to full commit SHAs prevents an upstream tag change from altering the code that can assume the publishing role or modify and publish the image.

**How this was verified:** The referenced actions run in a job with `id-token: write`, and the workflow subsequently assumes the ECR-publishing role and pushes the checked-out workspace.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@mariano-macri

Copy link
Copy Markdown
Author

@greptileai review

No new commits since your last review — re-triggering for a fresh pass now that the sibling PRs have changed.

On the mutable action tags you flagged: keeping @v4/@v2 deliberately. All three are first-party (actions/checkout from GitHub; configure-aws-credentials and amazon-ecr-login from AWS), and this repo has no Dependabot config — so SHA pins would have no update path, freeze, and stop receiving upstream security fixes. That's a worse posture than tracking the major tag, not a better one. Pinning is right once there's a mechanism keeping pins current; that's a repo-wide change worth doing deliberately rather than inside a CI-wiring PR.

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