|
name: CI |
|
|
|
on: |
|
push: |
|
branches: [main] |
|
pull_request: |
|
|
|
jobs: |
|
check-lockfile: |
|
name: Check backend lockfile is up to date |
|
if: github.event_name == 'pull_request' |
|
runs-on: ubuntu-latest |
|
steps: |
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 |
|
with: |
|
fetch-depth: 0 |
|
- name: Ensure lockfiles are updated when .in files change |
|
run: | |
|
BASE=${{ github.event.pull_request.base.sha }} |
|
HEAD=${{ github.event.pull_request.head.sha }} |
|
CHANGED=$(git diff --name-only "$BASE" "$HEAD") |
|
FAIL=0 |
|
if echo "$CHANGED" | grep -q 'backend/requirements\.in$'; then |
|
if ! echo "$CHANGED" | grep -q 'backend/requirements\.txt$'; then |
|
echo "::error::backend/requirements.in was modified but backend/requirements.txt was not." |
|
FAIL=1 |
|
fi |
|
if ! echo "$CHANGED" | grep -q 'backend/requirements-dev\.txt$'; then |
|
echo "::error::backend/requirements.in was modified but backend/requirements-dev.txt was not." |
|
FAIL=1 |
|
fi |
|
fi |
|
if echo "$CHANGED" | grep -q 'backend/requirements-dev\.in$'; then |
|
if ! echo "$CHANGED" | grep -q 'backend/requirements-dev\.txt$'; then |
|
echo "::error::backend/requirements-dev.in was modified but backend/requirements-dev.txt was not." |
|
FAIL=1 |
|
fi |
|
fi |
|
if [ "$FAIL" -eq 1 ]; then |
|
echo "::error::Please run pip-compile to regenerate lockfiles. See README for instructions." |
|
exit 1 |
|
fi |
|
|
|
backend-tests: |
|
name: Backend tests |
|
runs-on: ubuntu-latest |
|
steps: |
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 |
|
with: |
|
fetch-depth: 0 |
|
- name: Check for backend changes |
|
id: changes |
|
run: | |
|
if [ "${{ github.event_name }}" = "push" ]; then |
|
CHANGED=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }} 2>/dev/null \ |
|
|| git diff --name-only HEAD~1 HEAD 2>/dev/null \ |
|
|| echo "backend/") |
|
else |
|
CHANGED=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}) |
|
fi |
|
if echo "$CHANGED" | grep -Eq '^(backend/|\.github/workflows/ci\.yml$)'; then |
|
echo "backend=true" >> "$GITHUB_OUTPUT" |
|
fi |
|
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 |
|
if: steps.changes.outputs.backend == 'true' |
|
with: |
|
python-version: "3.13" |
|
cache: pip |
|
cache-dependency-path: backend/requirements-dev.txt |
|
- name: Install backend dependencies |
|
if: steps.changes.outputs.backend == 'true' |
|
working-directory: backend |
|
run: python -m pip install -r requirements-dev.txt |
|
- name: Run Ruff |
|
if: steps.changes.outputs.backend == 'true' |
|
working-directory: backend |
|
run: python -m ruff check . |
|
- name: Run tests |
|
if: steps.changes.outputs.backend == 'true' |
|
working-directory: backend |
|
run: python -m pytest tests/ -v --cov=app --cov-report=term-missing |
|
|
|
frontend-lint: |
|
name: Frontend Lint & Typecheck |
|
runs-on: ubuntu-latest |
|
defaults: |
|
run: |
|
working-directory: frontend |
|
steps: |
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 |
|
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 |
|
with: |
|
node-version: 20 |
|
cache: npm |
|
cache-dependency-path: frontend/package-lock.json |
|
- run: npm ci |
|
- run: npm run lint |
|
- run: npm run typecheck |