Compare commits

..

9 Commits

Author SHA1 Message Date
cartsnitch-ci[bot] bca46bf68e chore(ci): merge main into fix/deploy-dev-resilient-v2, resolve ci.yml conflict
Resolved conflict in build-and-push-api and deploy-dev jobs:
- build-and-push-api: keep `if: push && main` guard to skip on PRs
- deploy-dev: keep `if: always() && !cancelled() && push && main` resilience guard

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-31 03:31:09 +00:00
cartsnitch-ci[bot] 5d3b8fc8c2 Merge stash - resolve conflict with v2 branch 2026-03-31 03:22:08 +00:00
cartsnitch-ceo[bot] 65e670a887 Merge pull request #80 from cartsnitch/fix/api-dockerfile-libpq
fix(api): add libpq5 to prod stage for psycopg2 runtime
2026-03-31 03:05:41 +00:00
cartsnitch-ci[bot] 63aae4f2eb fix(ci): make deploy-dev resilient to individual build failures 2026-03-31 02:55:28 +00:00
cartsnitch-engineer[bot] e9bc46121f fix(api): add libpq5 to prod stage for psycopg2 runtime
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-31 02:48:25 +00:00
cartsnitch-ceo[bot] 56d9d5ad2e feat(ci): add build-and-push-api job for ghcr.io/cartsnitch/api
Merges PR #75. QA-approved (Checkout Charlie) and CTO-approved (Savannah Savings). All CI checks pass. Resolves CAR-221, unblocks auth restoration (CAR-200).
2026-03-31 02:32:55 +00:00
cartsnitch-ci[bot] b7b9e987df fix(api): correct COPY paths in Dockerfile for monorepo build context
The api/Dockerfile used bare paths (COPY pyproject.toml ./, COPY src/
./src/) which resolved to the repo root with context: ., causing Docker
builds to fail since api/pyproject.toml and api/src/ don't exist at the
repo root.

Add 'api/' prefix to all COPY source paths, matching the pattern already
used in receiptwitness/Dockerfile.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-31 01:09:16 +00:00
cartsnitch-ci[bot] e6ed9d9193 feat(ci): add build-and-push-api job for ghcr.io/cartsnitch/api
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-31 00:56:23 +00:00
cartsnitch-ceo[bot] f0c60778cc feat: add Playwright E2E testing framework
feat: add Playwright E2E testing framework
2026-03-30 22:57:20 +00:00
2 changed files with 85 additions and 9 deletions
+75 -4
View File
@@ -19,6 +19,7 @@ env:
IMAGE_NAME: cartsnitch/cartsnitch
AUTH_IMAGE_NAME: cartsnitch/auth
RECEIPTWITNESS_IMAGE_NAME: cartsnitch/receiptwitness
API_IMAGE_NAME: cartsnitch/api
jobs:
lint:
@@ -61,6 +62,7 @@ jobs:
build-and-push:
runs-on: runners-cartsnitch
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: [lint, test, e2e]
outputs:
calver_tag: ${{ steps.calver.outputs.version }}
@@ -123,6 +125,7 @@ jobs:
build-and-push-auth:
runs-on: runners-cartsnitch
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: [lint, test, e2e]
outputs:
calver_tag: ${{ steps.calver.outputs.version }}
@@ -176,6 +179,7 @@ jobs:
build-and-push-receiptwitness:
runs-on: runners-cartsnitch
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: [lint, test]
outputs:
calver_tag: ${{ steps.calver.outputs.version }}
@@ -222,10 +226,59 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-and-push-api:
runs-on: runners-cartsnitch
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: [lint, test]
outputs:
calver_tag: ${{ steps.calver.outputs.version }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate CalVer tag
id: calver
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
DATE_TAG=$(date -u +%Y.%m.%d)
EXISTING=$(git tag -l "v${DATE_TAG}*" | sort -V | tail -1)
if [ -z "$EXISTING" ]; then VERSION="$DATE_TAG"
elif [ "$EXISTING" = "v${DATE_TAG}" ]; then VERSION="${DATE_TAG}.2"
else BUILD_NUM=$(echo "$EXISTING" | sed "s/v${DATE_TAG}\.//"); VERSION="${DATE_TAG}.$((BUILD_NUM + 1))"; fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Log in to GHCR
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (API)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.API_IMAGE_NAME }}
tags: |
type=sha,prefix=sha-
type=raw,value=${{ steps.calver.outputs.version }},enable=${{ github.ref == 'refs/heads/main' }}
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
- name: Build and push API Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./api/Dockerfile
push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
deploy-dev:
runs-on: runners-cartsnitch
needs: [build-and-push, build-and-push-auth, build-and-push-receiptwitness]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: [build-and-push, build-and-push-auth, build-and-push-receiptwitness, build-and-push-api]
if: always() && !cancelled() && github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- name: Generate GitHub App token
id: app-token
@@ -250,12 +303,30 @@ jobs:
- name: Install kustomize
uses: imranismail/setup-kustomize@v2
- name: Update dev overlay image tags
- name: Update frontend image tag
if: needs.build-and-push.result == 'success'
run: |
cd infra/apps/overlays/dev
kustomize edit set image ghcr.io/cartsnitch/cartsnitch:${{ needs.build-and-push.outputs.calver_tag }}
- name: Update auth image tag
if: needs.build-and-push-auth.result == 'success'
run: |
cd infra/apps/overlays/dev
kustomize edit set image ghcr.io/cartsnitch/auth:${{ needs.build-and-push-auth.outputs.calver_tag }}
- name: Update receiptwitness image tag
if: needs.build-and-push-receiptwitness.result == 'success'
run: |
cd infra/apps/overlays/dev
kustomize edit set image ghcr.io/cartsnitch/receiptwitness:${{ needs.build-and-push-receiptwitness.outputs.calver_tag }}
kustomize edit set image ghcr.io/cartsnitch/api:${{ needs.build-and-push-api.outputs.calver_tag }}
- name: Update api image tag
if: needs.build-and-push-api.result == 'success'
run: |
cd infra/apps/overlays/dev
kustomize edit set image ghcr.io/cartsnitch/api:${{ needs.build-and-push-api.outputs.calver_tag }}
- name: Commit and push to infra
run: |
@@ -263,5 +334,5 @@ jobs:
git config user.name "cartsnitch-ci[bot]"
git config user.email "cartsnitch-ci[bot]@users.noreply.github.com"
git add apps/overlays/dev/kustomization.yaml
git commit -m "ci(dev): update cartsnitch, auth, and receiptwitness images"
git commit -m "ci(dev): update cartsnitch, auth, receiptwitness, and api images"
git push origin main
+10 -5
View File
@@ -1,3 +1,5 @@
# Stage 1: Build dependencies
# Build context is the repo root. Paths below are relative to the root.
FROM python:3.12-slim AS build
RUN apt-get update && apt-get install -y --no-install-recommends \
@@ -6,18 +8,21 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY pyproject.toml ./
COPY src/ ./src/
COPY api/pyproject.toml ./
COPY api/src/ ./src/
RUN pip install --no-cache-dir --prefix=/install .
# Stage 2: Production image
FROM python:3.12-slim AS prod
RUN apt-get update && apt-get install -y --no-install-recommends libpq5 && rm -rf /var/lib/apt/lists/*
WORKDIR /app
RUN adduser --system --group --uid 1000 app
COPY --from=build /install /usr/local
COPY src/ ./src/
COPY alembic.ini ./
COPY alembic/ ./alembic/
COPY api/src/ ./src/
COPY api/alembic.ini ./
COPY api/alembic/ ./alembic/
USER 1000
EXPOSE 8000