diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e2f0e55..a23b975 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,7 @@ env: REGISTRY: ghcr.io IMAGE_NAME: cartsnitch/cartsnitch AUTH_IMAGE_NAME: cartsnitch/auth + RECEIPTWITNESS_IMAGE_NAME: cartsnitch/receiptwitness jobs: lint: @@ -161,9 +162,57 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + build-and-push-receiptwitness: + runs-on: runners-cartsnitch + 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 + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.RECEIPTWITNESS_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 receiptwitness image + uses: docker/build-push-action@v6 + with: + context: . + file: ./receiptwitness/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] + needs: [build-and-push, build-and-push-auth, build-and-push-receiptwitness] if: github.event_name == 'push' && github.ref == 'refs/heads/main' steps: - name: Generate GitHub App token @@ -189,11 +238,12 @@ jobs: - name: Install kustomize uses: imranismail/setup-kustomize@v2 - - name: Update dev overlay image tag + - name: Update dev overlay image tags run: | cd infra/apps/overlays/dev kustomize edit set image ghcr.io/cartsnitch/cartsnitch:${{ needs.build-and-push.outputs.calver_tag }} kustomize edit set image ghcr.io/cartsnitch/auth:${{ needs.build-and-push-auth.outputs.calver_tag }} + kustomize edit set image ghcr.io/cartsnitch/receiptwitness:${{ needs.build-and-push-receiptwitness.outputs.calver_tag }} - name: Commit and push to infra run: | @@ -201,5 +251,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 and auth images to ${{ needs.build-and-push.outputs.calver_tag }}" + git commit -m "ci(dev): update cartsnitch, auth, and receiptwitness images" git push origin main diff --git a/receiptwitness/Dockerfile b/receiptwitness/Dockerfile index bb6300d..8fead61 100644 --- a/receiptwitness/Dockerfile +++ b/receiptwitness/Dockerfile @@ -3,24 +3,21 @@ FROM python:3.12-slim AS build WORKDIR /app -# git is required to install cartsnitch-common from GitHub; build-essential and -# libpq-dev are needed to compile any C-extension wheels (e.g. psycopg2 fallback) +# build-essential and libpq-dev are needed to compile any C-extension wheels +# (e.g. psycopg2 fallback). No git needed — common/ is copied from the repo root. RUN apt-get update && apt-get install -y --no-install-recommends \ - git \ libpq-dev \ build-essential \ && rm -rf /var/lib/apt/lists/* -COPY pyproject.toml ./ -COPY src/ ./src/ +# Build context is the repo root. These paths are relative to the root. +COPY receiptwitness/pyproject.toml ./ +COPY receiptwitness/src/ ./src/ +COPY common/ ./common/ -# cartsnitch-common is not on PyPI — install it directly from GitHub, then -# install the rest of the package dependencies in a single resolver pass so -# pip can satisfy the cartsnitch-common>=0.1.0 constraint declared in -# pyproject.toml without hitting PyPI for it. -RUN pip install --no-cache-dir --prefix=/install \ - "cartsnitch-common @ git+https://github.com/cartsnitch/common.git@76685ed0384103228cd670b477b967e7752ebe6b" \ - . +# Install from the local common/ (cartsnitch-common>=0.1.0 in pyproject.toml +# will be satisfied by the local package) then install receiptwitness itself. +RUN pip install --no-cache-dir --prefix=/install ./common/ . # Stage 2: Production image with Playwright + Chromium FROM python:3.12-slim AS prod @@ -51,7 +48,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ RUN adduser --system --group --uid 1000 app COPY --from=build /install /usr/local -COPY src/ ./src/ +COPY receiptwitness/src/ ./src/ # Install Playwright Chromium browser (runs as root; /opt/playwright is world-readable) RUN PLAYWRIGHT_BROWSERS_PATH=/opt/playwright playwright install chromium