Compare commits

..

1 Commits

Author SHA1 Message Date
Barcode Betty 499c1c4488 fix: migrate CI from ghcr.io to Gitea built-in registry
CI / typecheck (pull_request) Failing after 56s
CI / lint (pull_request) Failing after 57s
CI / test (pull_request) Failing after 2m18s
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
- Change REGISTRY from ghcr.io to git.farh.net
- Replace Docker Hub + GHCR login with single Gitea Container Registry login
- Remove credentials from postgres and redis service containers

Refs: CAR-995
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-23 21:24:44 +00:00
5 changed files with 295 additions and 5 deletions
+3 -2
View File
@@ -26,6 +26,7 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- run: pip install ruff
- name: Ruff lint
run: ruff check .
@@ -40,6 +41,7 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y libpq-dev build-essential
- run: pip install -e ".[dev]" mypy
@@ -81,13 +83,12 @@ jobs:
CARTSNITCH_DATABASE_URL: postgresql+asyncpg://cartsnitch:cartsnitch_test@localhost:5432/cartsnitch_test
CARTSNITCH_REDIS_URL: redis://localhost:6379/0
CARTSNITCH_JWT_SECRET_KEY: test-secret-do-not-use-in-prod
CARTSNITCH_SERVICE_KEY: test-service-key-do-not-use-in-prod
CARTSNITCH_FERNET_KEY: wXWQsC0FZlhSz2t_tfVQjNUSP8vgAGG3o3pkjrX8Bw0=
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y libpq-dev build-essential
- run: pip install -e ".[dev]"
+287
View File
@@ -0,0 +1,287 @@
name: CI
on:
push:
branches: [main, dev]
pull_request:
branches: [main, dev]
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: write
packages: write
env:
REGISTRY: git.farh.net
IMAGE_NAME: cartsnitch/api
jobs:
lint:
runs-on: runners-cartsnitch
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- run: pip install ruff
- name: Ruff lint
run: ruff check .
- name: Ruff format check
run: ruff format --check .
typecheck:
runs-on: runners-cartsnitch
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y libpq-dev build-essential
- run: pip install -e ".[dev]" mypy
- name: Type check
run: mypy src/cartsnitch_api
test:
runs-on: runners-cartsnitch
services:
postgres:
image: postgres:15-alpine
env:
POSTGRES_USER: cartsnitch
POSTGRES_PASSWORD: cartsnitch_test
POSTGRES_DB: cartsnitch_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
CARTSNITCH_DATABASE_URL: postgresql+asyncpg://cartsnitch:cartsnitch_test@localhost:5432/cartsnitch_test
CARTSNITCH_REDIS_URL: redis://localhost:6379/0
CARTSNITCH_JWT_SECRET_KEY: test-secret-do-not-use-in-prod
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y libpq-dev build-essential
- run: pip install -e ".[dev]"
- name: Run tests
run: pytest --tb=short -q
build-and-push:
runs-on: runners-cartsnitch
needs: [lint, test]
outputs:
calver_tag: ${{ steps.calver.outputs.version }}
sha_tag: sha-${{ github.sha }}
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"
echo "CalVer tag: $VERSION"
- name: Log in to Gitea Container Registry
run: echo "${{ github.token }}" | docker login git.farh.net -u ${{ github.actor }} --password-stdin
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=sha,prefix=sha-,format=long
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 Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
load: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
APT_CACHE_BUST=${{ github.run_id }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Scan api image for vulnerabilities
uses: anchore/scan-action@v5
id: scan
env:
GRYPE_CONFIG: .grype.yaml
with:
image: "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:sha-${{ github.sha }}"
fail-build: true
severity-cutoff: high
only-fixed: "true"
output-format: sarif
- name: Upload api scan results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: ${{ steps.scan.outputs.sarif }}
- name: Push Docker image
if: github.event_name == 'push'
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
APT_CACHE_BUST=${{ github.run_id }}
cache-from: type=gha
- name: Create git tag
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
git tag "v${{ steps.calver.outputs.version }}"
git push origin "v${{ steps.calver.outputs.version }}"
deploy-dev:
runs-on: runners-cartsnitch
needs: [build-and-push]
if: always() && !cancelled() && github.event_name == 'push' && (github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main')
steps:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.CARTSNITCH_APP_ID }}
private-key: ${{ secrets.CARTSNITCH_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: infra
- name: Checkout infra repo
uses: actions/checkout@v4
with:
repository: cartsnitch/infra
token: ${{ steps.app-token.outputs.token }}
ref: main
path: infra
- name: Install kubectl
uses: azure/setup-kubectl@v4
- name: Install kustomize
uses: imranismail/setup-kustomize@v2
- name: Determine image tag
id: api_tag
run: |
if [ "${{ github.ref }}" == "refs/heads/main" ]; then
echo "tag=${{ needs.build-and-push.outputs.calver_tag }}" >> "$GITHUB_OUTPUT"
else
echo "tag=${{ needs.build-and-push.outputs.sha_tag }}" >> "$GITHUB_OUTPUT"
fi
- name: Update api image tag
if: needs.build-and-push.result == 'success'
run: |
cd infra/apps/overlays/dev
kustomize edit set image ghcr.io/cartsnitch/api:${{ steps.api_tag.outputs.tag }}
- name: Commit and push to infra
run: |
cd infra
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 api image"
git pull --rebase origin main
git push origin main
deploy-uat:
runs-on: runners-cartsnitch
needs: [build-and-push]
if: always() && !cancelled() && github.event_name == 'push' && (github.ref == 'refs/heads/uat' || github.ref == 'refs/heads/main')
steps:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.CARTSNITCH_APP_ID }}
private-key: ${{ secrets.CARTSNITCH_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: infra
- name: Checkout infra repo
uses: actions/checkout@v4
with:
repository: cartsnitch/infra
token: ${{ steps.app-token.outputs.token }}
ref: main
path: infra
- name: Install kubectl
uses: azure/setup-kubectl@v4
- name: Install kustomize
uses: imranismail/setup-kustomize@v2
- name: Determine image tag
id: api_tag
run: |
if [ "${{ github.ref }}" == "refs/heads/main" ]; then
echo "tag=${{ needs.build-and-push.outputs.calver_tag }}" >> "$GITHUB_OUTPUT"
else
echo "tag=${{ needs.build-and-push.outputs.sha_tag }}" >> "$GITHUB_OUTPUT"
fi
- name: Update api image tag
if: needs.build-and-push.result == 'success'
run: |
cd infra/apps/overlays/uat
kustomize edit set image ghcr.io/cartsnitch/api:${{ steps.api_tag.outputs.tag }}
- name: Commit and push to infra
run: |
cd infra
git config user.name "cartsnitch-ci[bot]"
git config user.email "cartsnitch-ci[bot]@users.noreply.github.com"
git add apps/overlays/uat/kustomization.yaml
git commit -m "ci(uat): update api image"
git pull --rebase origin main
git push origin main
+1 -2
View File
@@ -5,8 +5,7 @@ Sessions are verified by querying the shared sessions table directly.
"""
from datetime import UTC, datetime
from fastapi import Depends, Header, HTTPException, Request, status
from fastapi import Cookie, Depends, Header, HTTPException, Request, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession
+3
View File
@@ -6,10 +6,13 @@ endpoints that query our own user data from the shared database.
"""
from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from cartsnitch_api.auth.dependencies import get_current_user
from cartsnitch_api.database import get_db
from cartsnitch_api.models import User
from cartsnitch_api.schemas import (
UpdateUserRequest,
UserResponse,
+1 -1
View File
@@ -7,10 +7,10 @@ from fastapi import APIRouter, FastAPI
from cartsnitch_api.auth.routes import router as auth_router
from cartsnitch_api.cache import cache_client
from cartsnitch_api.database import dispose_engine
from cartsnitch_api.middleware.audit import add_audit_middleware
from cartsnitch_api.middleware.cors import add_cors_middleware
from cartsnitch_api.middleware.error_handler import add_error_handlers, add_error_monitor_middleware
from cartsnitch_api.middleware.rate_limit import add_rate_limit_middleware
from cartsnitch_api.middleware.audit import add_audit_middleware
from cartsnitch_api.routes.alerts import router as alerts_router
from cartsnitch_api.routes.coupons import router as coupons_router
from cartsnitch_api.routes.health import router as health_router