name: CI on: pull_request: push: branches: [master] concurrency: group: ci-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} env: PYTHONDONTWRITEBYTECODE: 1 jobs: lint: name: Lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install system dependencies run: sudo apt-get update && sudo apt-get install -y libcairo2-dev - uses: astral-sh/setup-uv@v6 with: python-version-file: ".python-version" enable-cache: true - run: uv sync --locked - name: Pre-commit hooks (ruff, formatting, file hygiene) run: uv run prek run --all-files --show-diff-on-failure - name: Django system checks run: uv run python manage.py check - name: Check for missing migrations run: uv run python manage.py makemigrations --check --dry-run test: name: Test runs-on: ubuntu-latest env: DATABASE_ENGINE: sqlite3 DATABASE_NAME: db.sqlite3 steps: - uses: actions/checkout@v4 - name: Install system dependencies run: sudo apt-get update && sudo apt-get install -y libcairo2-dev - uses: astral-sh/setup-uv@v6 with: python-version-file: ".python-version" enable-cache: true - uses: actions/setup-node@v4 with: node-version: 24 cache: npm - run: uv sync --locked - name: Build frontend assets run: | npm ci npm run build - run: uv run python manage.py collectstatic --noinput - name: Run tests run: uv run pytest -n auto --cov - name: Coveralls run: uv run coveralls --service=github env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} docker: name: Docker image runs-on: ubuntu-latest needs: [lint, test] permissions: contents: read packages: write steps: - uses: actions/checkout@v4 - uses: docker/setup-qemu-action@v3 - uses: docker/setup-buildx-action@v3 # Only authenticate when we are actually going to push (never for PRs, which may come from forks) - name: Log in to GHCR if: github.event_name == 'push' uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - id: meta uses: docker/metadata-action@v5 with: images: ghcr.io/${{ github.repository }} tags: | type=raw,value=latest type=sha - name: Build (and push on master) uses: docker/build-push-action@v6 with: context: . platforms: linux/amd64,linux/arm64 push: ${{ github.event_name == 'push' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max