Compare commits

...

9 Commits

Author SHA1 Message Date
Coupon Carl 309a837c77 Merge pull request 'Promote to Production: CAR-1318 frontend image-bump alignment + CAR-1216/CAR-1279 Phase 2' (#294) from uat into main
CI / lint (push) Successful in 14s
CI / test (push) Successful in 13s
CI / audit (push) Successful in 13s
CI / e2e (push) Successful in 48s
CI / lighthouse (push) Failing after 1m17s
CI / build-and-push-api (push) Successful in 2m31s
CI / build-and-push-receiptwitness (push) Successful in 3m16s
CI / build-and-push-auth (push) Successful in 1m15s
CI / build-and-push (push) Successful in 2m12s
CI / deploy-uat (push) Successful in 9s
CI / deploy-dev (push) Successful in 10s
Promote to Production: CAR-1318 frontend image-bump alignment + CAR-1216/CAR-1279 Phase 2

UAT PASS (Deal Dottie) + Security PASS (Stockboy Steve) on CAR-1320.
Merged by CEO (Coupon Carl) as production gate.

cc @cpfarhood
2026-06-07 15:50:29 +00:00
Savannah Savings a0f3eff2a4 Merge pull request 'promote(uat): frontend image-bump alignment (CAR-1318)' (#293) from dev into uat
CI / build-and-push (push) Successful in 29s
CI / lint (push) Successful in 18s
CI / test (push) Successful in 17s
CI / audit (push) Successful in 18s
CI / build-and-push-receiptwitness (push) Successful in 2m1s
CI / e2e (push) Successful in 58s
CI / lighthouse (push) Failing after 1m20s
CI / build-and-push-auth (push) Successful in 1m35s
CI / build-and-push-api (push) Failing after 2m21s
CI / deploy-dev (push) Has been skipped
CI / deploy-uat (push) Successful in 6s
CI / lint (pull_request) Successful in 19s
CI / test (pull_request) Successful in 52s
CI / audit (pull_request) Successful in 30s
CI / e2e (pull_request) Successful in 43s
CI / deploy-dev (pull_request) Has been skipped
CI / build-and-push-receiptwitness (pull_request) Has been skipped
CI / build-and-push-api (pull_request) Has been skipped
CI / build-and-push-auth (pull_request) Has been skipped
CI / lighthouse (pull_request) Failing after 1m21s
CI / build-and-push (pull_request) Has been skipped
CI / deploy-uat (pull_request) Has been skipped
2026-06-07 11:52:13 +00:00
Barcode Betty afe8f7b7f9 fix(ci): align deploy frontend image-bump to app entry name (CAR-1318)
CI / build-and-push-receiptwitness (pull_request) Has been skipped
CI / lint (push) Successful in 12s
CI / test (push) Successful in 12s
CI / audit (push) Successful in 12s
CI / e2e (push) Successful in 44s
CI / build-and-push-api (push) Successful in 1m47s
CI / e2e (pull_request) Successful in 39s
CI / lighthouse (push) Failing after 1m13s
CI / lint (pull_request) Successful in 10s
CI / test (pull_request) Successful in 10s
CI / audit (pull_request) Successful in 9s
CI / build-and-push-auth (push) Successful in 1m15s
CI / build-and-push-api (pull_request) Has been skipped
CI / build-and-push-auth (pull_request) Has been skipped
CI / build-and-push (push) Successful in 51s
CI / lighthouse (pull_request) Failing after 1m25s
CI / build-and-push (pull_request) Has been skipped
CI / deploy-dev (pull_request) Has been skipped
CI / deploy-uat (pull_request) Has been skipped
CI / build-and-push-receiptwitness (push) Failing after 22m44s
CI / deploy-uat (push) Has been skipped
CI / deploy-dev (push) Successful in 2m50s
Co-authored-by: Barcode Betty <betty@cartsnitch.com>
Co-committed-by: Barcode Betty <betty@cartsnitch.com>
2026-06-07 11:51:42 +00:00
Savannah Savings 292f428bc7 Merge pull request 'promote: CAR-1216 deploy never hard-fail on infra-PR merge (dev → uat)' (#290) from dev into uat
CI / build-and-push-api (push) Successful in 1m2s
CI / build-and-push-auth (push) Successful in 27s
CI / build-and-push-receiptwitness (push) Successful in 2m30s
CI / deploy-dev (push) Has been skipped
CI / audit (push) Successful in 9s
CI / lint (push) Successful in 14s
CI / test (push) Successful in 14s
CI / e2e (push) Successful in 40s
CI / lighthouse (push) Failing after 1m16s
CI / build-and-push (push) Successful in 55s
CI / deploy-uat (push) Successful in 6s
2026-06-07 10:26:22 +00:00
Savannah Savings 515631987b Merge pull request 'ci(deploy): never hard-fail on infra-PR merge outcome (CAR-1216)' (#284) from betty/car-1216-deploy-never-fail-merge into dev
CI / audit (push) Successful in 11s
CI / lint (push) Successful in 18s
CI / audit (pull_request) Successful in 9s
CI / test (pull_request) Successful in 21s
CI / build-and-push-api (push) Failing after 1m2s
CI / test (push) Successful in 45s
CI / lint (pull_request) Successful in 11s
CI / e2e (push) Successful in 40s
CI / e2e (pull_request) Successful in 40s
CI / lighthouse (push) Failing after 1m13s
CI / build-and-push-auth (push) Successful in 30s
CI / build-and-push-receiptwitness (pull_request) Has been skipped
CI / build-and-push-api (pull_request) Has been skipped
CI / build-and-push-auth (pull_request) Has been skipped
CI / build-and-push (pull_request) Has been skipped
CI / deploy-dev (pull_request) Has been skipped
CI / deploy-uat (pull_request) Has been skipped
CI / lighthouse (pull_request) Failing after 1m14s
CI / build-and-push (push) Successful in 2m59s
CI / build-and-push-receiptwitness (push) Successful in 4m35s
CI / deploy-uat (push) Has been skipped
CI / deploy-dev (push) Successful in 15s
2026-06-07 10:20:28 +00:00
Savannah Savings a3b6ba488f promote(uat): pin auth base image to node 22.22.2 digest (CAR-1287 / CAR-1279 Phase 2) (#288)
CI / lint (push) Successful in 13s
CI / test (push) Successful in 12s
CI / audit (push) Successful in 12s
CI / e2e (push) Successful in 41s
CI / lighthouse (push) Failing after 1m12s
CI / build-and-push-api (push) Successful in 1m6s
CI / build-and-push-receiptwitness (push) Successful in 1m55s
CI / build-and-push (push) Successful in 2m1s
CI / build-and-push-auth (push) Successful in 2m13s
CI / deploy-dev (push) Has been skipped
CI / deploy-uat (push) Failing after 8s
2026-06-06 06:23:12 +00:00
Savannah Savings 993302c72c fix(auth): pin base image to node 22.22.2 digest (CAR-1279 Phase 2) (#287)
CI / audit (push) Successful in 10s
CI / test (push) Successful in 14s
CI / e2e (push) Successful in 42s
CI / lighthouse (push) Failing after 1m16s
CI / test (pull_request) Successful in 12s
CI / lint (push) Successful in 14s
CI / lint (pull_request) Successful in 11s
CI / e2e (pull_request) Successful in 47s
CI / audit (pull_request) Successful in 10s
CI / build-and-push-auth (push) Successful in 2m20s
CI / build-and-push-api (push) Successful in 3m12s
CI / build-and-push-receiptwitness (pull_request) Has been skipped
CI / build-and-push-api (pull_request) Has been skipped
CI / build-and-push-auth (pull_request) Has been skipped
CI / build-and-push (pull_request) Has been skipped
CI / lighthouse (pull_request) Failing after 1m18s
CI / build-and-push-receiptwitness (push) Successful in 5m16s
CI / build-and-push (push) Successful in 2m21s
CI / deploy-dev (pull_request) Has been skipped
CI / deploy-uat (pull_request) Has been skipped
CI / deploy-dev (push) Failing after 14s
CI / deploy-uat (push) Has been skipped
2026-06-06 06:22:35 +00:00
Savannah Savings 7803d229eb fix(auth): pin base image to node 22.22.2 digest (CAR-1279 Phase 2)
CI / lint (pull_request) Successful in 40s
CI / test (pull_request) Successful in 1m15s
CI / build-and-push-receiptwitness (pull_request) Has been skipped
CI / build-and-push-api (pull_request) Has been skipped
CI / build-and-push-auth (pull_request) Has been skipped
CI / lighthouse (pull_request) Failing after 1m12s
CI / audit (pull_request) Successful in 2m47s
CI / e2e (pull_request) Successful in 3m18s
CI / build-and-push (pull_request) Has been skipped
CI / deploy-dev (pull_request) Has been skipped
CI / deploy-uat (pull_request) Has been skipped
Pin both build and runtime stages of auth/Dockerfile to
node:22-alpine@sha256:8ea2348b068a9544dae7317b4f3aafcdc032df1647bb7d768a05a5cad1a7683f
— the Docker Hub manifest digest for node:22.22.2-alpine (verified against
the registry by CTO).

This is the digest pulled in by the previously-healthy ghcr auth image, which
connects fine to the dev Postgres with the same pg 8.20.0 driver and
byte-identical source. The Gitea-built image, which bundles node 22.22.3
(via the floating 'node:22-alpine' tag), deterministically resets the
Postgres connection during the /health DB probe (read ECONNRESET →
Connection terminated unexpectedly).

Pinning both stages to the manifest digest restores the exact node runtime
that the healthy ghcr image used and fixes the dev auth crashloop. The
'RUN apk update && apk upgrade --no-cache' lines are kept as-is per task
spec.

Refs CAR-1279, CAR-1276 (CAR-1287)
2026-06-06 02:26:54 +00:00
Barcode Betty 81b19b9072 ci(deploy): never hard-fail on infra-PR merge outcome (CAR-1216)
CI / lint (pull_request) Successful in 12s
CI / test (pull_request) Successful in 12s
CI / build-and-push-receiptwitness (pull_request) Has been skipped
CI / build-and-push-api (pull_request) Has been skipped
CI / build-and-push-auth (pull_request) Has been skipped
CI / audit (pull_request) Successful in 18s
CI / e2e (pull_request) Successful in 43s
CI / build-and-push (pull_request) Has been skipped
CI / deploy-dev (pull_request) Has been skipped
CI / deploy-uat (pull_request) Has been skipped
CI / lighthouse (pull_request) Failing after 17m15s
The in-job merge attempt against `cartsnitch/infra` main is a best-effort
fast-path only. `infra` main requires a human approving review and the CI
bot (`CI_GITEA_TOKEN`) can never self-approve, so the merge call
structurally cannot succeed in the general case.

Replace the special-cased `does not have enough approvals` branch and the
final `else -> exit 1` branch in both `deploy-dev` and `deploy-uat` with a
single non-failing outcome: surface the Gitea response as a `::notice::`
and `exit 0`. The PR is already opened and `cs_savannah` is requested as
reviewer above, so the GitOps hand-off is intact.

The only hard-fail (`exit 1`) in this step remains the empty-`PR_NUM`
check (PR could not be created at all).

Related: CAR-1195 (PR-bump pattern), CAR-1194, CAR-1212.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-06-05 23:57:11 +00:00
2 changed files with 28 additions and 24 deletions
+26 -22
View File
@@ -495,7 +495,7 @@ jobs:
if: needs.build-and-push.result == 'success'
run: |
cd infra/apps/overlays/dev
kustomize edit set image ghcr.io/cartsnitch/cartsnitch=git.farh.net/cartsnitch/cartsnitch:${{ steps.frontend_tag.outputs.tag }}
kustomize edit set image ghcr.io/cartsnitch/app=git.farh.net/cartsnitch/cartsnitch:${{ steps.frontend_tag.outputs.tag }}
- name: Determine image tag for receiptwitness
id: receiptwitness_tag
@@ -577,6 +577,16 @@ jobs:
if [ "${REVIEW_HTTP}" -lt 200 ] || [ "${REVIEW_HTTP}" -ge 300 ]; then
echo "::notice::Failed to request reviewers for cartsnitch/infra PR #${PR_NUM} (HTTP ${REVIEW_HTTP}); continuing"
fi
# CAR-1216: the in-job merge attempt is a best-effort fast-path only.
# `cartsnitch/infra` main requires a human approving review (immutable
# branch protection); the CI bot (`CI_GITEA_TOKEN`) can never self-
# approve, so this merge call structurally cannot succeed in the
# general case. Any non-merged outcome (approvals pending, checks
# pending, any other Gitea message) is the GitOps approval gate, not
# a CI failure — the PR is already opened and `cs_savannah` is
# requested as reviewer above. Surface the response as a notice and
# exit success. The only hard-fail (`exit 1`) in this step remains
# the empty-`PR_NUM` check (PR could not be created at all).
MERGE_RESP=$(curl -sS -X POST \
-H "Authorization: token ${CI_GITEA_TOKEN}" \
-H "Content-Type: application/json" \
@@ -585,17 +595,9 @@ jobs:
MERGED=$(echo "$MERGE_RESP" | jq -r '.merged // false')
if [ "$MERGED" = "true" ]; then
echo "PR #${PR_NUM} merged into cartsnitch/infra main"
elif echo "$MERGE_RESP" | grep -qi 'does not have enough approvals'; then
# GitOps approval gate: the PR is correctly opened and surfaces in
# the CTO queue via the reviewers request above. Treat as success
# (exit 0) so the deploy job does not hard-fail on the approvals
# requirement that only a human maintainer can satisfy.
echo "::notice::infra PR #${PR_NUM} opened and awaiting CTO (cs_savannah) approve+merge — GitOps approval gate, not a failure"
exit 0
else
echo "::error::Auto-merge of cartsnitch/infra PR #${PR_NUM} failed: $MERGE_RESP"
echo "::error::Reassign to cs_savannah (authorized merger for cartsnitch/infra main) for backstop merge."
exit 1
echo "::notice::infra PR #${PR_NUM} opened and awaiting CTO (cs_savannah) approve+merge — GitOps approval gate, not a failure: $MERGE_RESP"
exit 0
fi
deploy-uat:
@@ -639,7 +641,7 @@ jobs:
if: needs.build-and-push.result == 'success'
run: |
cd infra/apps/overlays/uat
kustomize edit set image ghcr.io/cartsnitch/cartsnitch=git.farh.net/cartsnitch/cartsnitch:${{ steps.frontend_tag.outputs.tag }}
kustomize edit set image ghcr.io/cartsnitch/app=git.farh.net/cartsnitch/cartsnitch:${{ steps.frontend_tag.outputs.tag }}
- name: Determine image tag for receiptwitness
id: receiptwitness_tag
@@ -721,6 +723,16 @@ jobs:
if [ "${REVIEW_HTTP}" -lt 200 ] || [ "${REVIEW_HTTP}" -ge 300 ]; then
echo "::notice::Failed to request reviewers for cartsnitch/infra PR #${PR_NUM} (HTTP ${REVIEW_HTTP}); continuing"
fi
# CAR-1216: the in-job merge attempt is a best-effort fast-path only.
# `cartsnitch/infra` main requires a human approving review (immutable
# branch protection); the CI bot (`CI_GITEA_TOKEN`) can never self-
# approve, so this merge call structurally cannot succeed in the
# general case. Any non-merged outcome (approvals pending, checks
# pending, any other Gitea message) is the GitOps approval gate, not
# a CI failure — the PR is already opened and `cs_savannah` is
# requested as reviewer above. Surface the response as a notice and
# exit success. The only hard-fail (`exit 1`) in this step remains
# the empty-`PR_NUM` check (PR could not be created at all).
MERGE_RESP=$(curl -sS -X POST \
-H "Authorization: token ${CI_GITEA_TOKEN}" \
-H "Content-Type: application/json" \
@@ -729,15 +741,7 @@ jobs:
MERGED=$(echo "$MERGE_RESP" | jq -r '.merged // false')
if [ "$MERGED" = "true" ]; then
echo "PR #${PR_NUM} merged into cartsnitch/infra main"
elif echo "$MERGE_RESP" | grep -qi 'does not have enough approvals'; then
# GitOps approval gate: the PR is correctly opened and surfaces in
# the CTO queue via the reviewers request above. Treat as success
# (exit 0) so the deploy job does not hard-fail on the approvals
# requirement that only a human maintainer can satisfy.
echo "::notice::infra PR #${PR_NUM} opened and awaiting CTO (cs_savannah) approve+merge — GitOps approval gate, not a failure"
exit 0
else
echo "::error::Auto-merge of cartsnitch/infra PR #${PR_NUM} failed: $MERGE_RESP"
echo "::error::Reassign to cs_savannah (authorized merger for cartsnitch/infra main) for backstop merge."
exit 1
echo "::notice::infra PR #${PR_NUM} opened and awaiting CTO (cs_savannah) approve+merge — GitOps approval gate, not a failure: $MERGE_RESP"
exit 0
fi
+2 -2
View File
@@ -1,4 +1,4 @@
FROM node:22-alpine AS builder
FROM node:22-alpine@sha256:8ea2348b068a9544dae7317b4f3aafcdc032df1647bb7d768a05a5cad1a7683f AS builder
RUN apk update && apk upgrade --no-cache
WORKDIR /app
COPY package.json package-lock.json* ./
@@ -7,7 +7,7 @@ COPY tsconfig.json ./
COPY src/ src/
RUN npm run build
FROM node:22-alpine
FROM node:22-alpine@sha256:8ea2348b068a9544dae7317b4f3aafcdc032df1647bb7d768a05a5cad1a7683f
RUN apk update && apk upgrade --no-cache
WORKDIR /app
ENV NODE_ENV=production