name: ci on: push: tags: # https://semver.org/#spec-item-2 - 'v[0-9]+.[0-9]+.[0-9]+' # https://semver.org/#spec-item-9 - 'v[0-9]+.[0-9]+.[0-9]+-beta.rc[0-9]+' branches-ignore: - 'translations**' pull_request: branches-ignore: - 'translations**' env: DEFAULT_UV_VERSION: "0.8.x" # This is the default version of Python to use in most steps which aren't specific DEFAULT_PYTHON_VERSION: "3.11" NLTK_DATA: "/usr/share/nltk_data" jobs: pre-commit: # We want to run on external PRs, but not on our own internal PRs as they'll be run # by the push to the branch. Without this if check, checks are duplicated since # internal PRs match both the push and pull_request events. if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository name: Linting Checks runs-on: ubuntu-24.04 steps: - name: Checkout repository uses: actions/checkout@v5 - name: Install python uses: actions/setup-python@v5 with: python-version: ${{ env.DEFAULT_PYTHON_VERSION }} - name: Check files uses: pre-commit/action@v3.0.1 documentation: name: "Build & Deploy Documentation" runs-on: ubuntu-24.04 needs: - pre-commit steps: - name: Checkout uses: actions/checkout@v5 - name: Set up Python id: setup-python uses: actions/setup-python@v5 with: python-version: ${{ env.DEFAULT_PYTHON_VERSION }} - name: Install uv uses: astral-sh/setup-uv@v6 with: version: ${{ env.DEFAULT_UV_VERSION }} enable-cache: true python-version: ${{ env.DEFAULT_PYTHON_VERSION }} - name: Install Python dependencies run: | uv sync --python ${{ steps.setup-python.outputs.python-version }} --dev --frozen - name: Make documentation run: | uv run \ --python ${{ steps.setup-python.outputs.python-version }} \ --dev \ --frozen \ mkdocs build --config-file ./mkdocs.yml - name: Deploy documentation if: github.event_name == 'push' && github.ref == 'refs/heads/main' run: | echo "docs.paperless-ngx.com" > "${{ github.workspace }}/docs/CNAME" git config --global user.name "${{ github.actor }}" git config --global user.email "${{ github.actor }}@users.noreply.github.com" uv run \ --python ${{ steps.setup-python.outputs.python-version }} \ --dev \ --frozen \ mkdocs gh-deploy --force --no-history - name: Upload artifact uses: actions/upload-artifact@v4 with: name: documentation path: site/ retention-days: 7 tests-backend: name: "Backend Tests (Python ${{ matrix.python-version }})" runs-on: ubuntu-24.04 needs: - pre-commit strategy: matrix: python-version: ['3.10', '3.11', '3.12'] fail-fast: false steps: - name: Checkout uses: actions/checkout@v5 - name: Start containers run: | docker compose --file ${{ github.workspace }}/docker/compose/docker-compose.ci-test.yml pull --quiet docker compose --file ${{ github.workspace }}/docker/compose/docker-compose.ci-test.yml up --detach - name: Set up Python id: setup-python uses: actions/setup-python@v5 with: python-version: "${{ matrix.python-version }}" - name: Install uv uses: astral-sh/setup-uv@v6 with: version: ${{ env.DEFAULT_UV_VERSION }} enable-cache: true python-version: ${{ steps.setup-python.outputs.python-version }} - name: Install system dependencies run: | sudo apt-get update -qq sudo apt-get install -qq --no-install-recommends unpaper tesseract-ocr imagemagick ghostscript libzbar0 poppler-utils - name: Configure ImageMagick run: | sudo cp docker/rootfs/etc/ImageMagick-6/paperless-policy.xml /etc/ImageMagick-6/policy.xml - name: Install Python dependencies run: | uv sync \ --python ${{ steps.setup-python.outputs.python-version }} \ --group testing \ --frozen - name: List installed Python dependencies run: | uv pip list - name: Install or update NLTK dependencies run: uv run python -m nltk.downloader punkt punkt_tab snowball_data stopwords -d ${{ env.NLTK_DATA }} - name: Tests env: NLTK_DATA: ${{ env.NLTK_DATA }} PAPERLESS_CI_TEST: 1 # Enable paperless_mail testing against real server PAPERLESS_MAIL_TEST_HOST: ${{ secrets.TEST_MAIL_HOST }} PAPERLESS_MAIL_TEST_USER: ${{ secrets.TEST_MAIL_USER }} PAPERLESS_MAIL_TEST_PASSWD: ${{ secrets.TEST_MAIL_PASSWD }} run: | uv run \ --python ${{ steps.setup-python.outputs.python-version }} \ --dev \ --frozen \ pytest - name: Upload backend test results to Codecov if: always() uses: codecov/test-results-action@v1 with: token: ${{ secrets.CODECOV_TOKEN }} flags: backend-python-${{ matrix.python-version }} files: junit.xml - name: Upload backend coverage to Codecov uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} flags: backend-python-${{ matrix.python-version }} files: coverage.xml - name: Stop containers if: always() run: | docker compose --file ${{ github.workspace }}/docker/compose/docker-compose.ci-test.yml logs docker compose --file ${{ github.workspace }}/docker/compose/docker-compose.ci-test.yml down install-frontend-dependencies: name: "Install Frontend Dependencies" runs-on: ubuntu-24.04 needs: - pre-commit steps: - uses: actions/checkout@v5 - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 10 - name: Use Node.js 20 uses: actions/setup-node@v4 with: node-version: 20.x cache: 'pnpm' cache-dependency-path: 'src-ui/pnpm-lock.yaml' - name: Cache frontend dependencies id: cache-frontend-deps uses: actions/cache@v4 with: path: | ~/.pnpm-store ~/.cache key: ${{ runner.os }}-frontenddeps-${{ hashFiles('src-ui/pnpm-lock.yaml') }} - name: Install dependencies run: cd src-ui && pnpm install tests-frontend: name: "Frontend Unit Tests (Node ${{ matrix.node-version }} - ${{ matrix.shard-index }}/${{ matrix.shard-count }})" runs-on: ubuntu-24.04 needs: - install-frontend-dependencies strategy: fail-fast: false matrix: node-version: [20.x] shard-index: [1, 2, 3, 4] shard-count: [4] steps: - uses: actions/checkout@v5 - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 10 - name: Use Node.js 20 uses: actions/setup-node@v4 with: node-version: 20.x cache: 'pnpm' cache-dependency-path: 'src-ui/pnpm-lock.yaml' - name: Cache frontend dependencies id: cache-frontend-deps uses: actions/cache@v4 with: path: | ~/.pnpm-store ~/.cache key: ${{ runner.os }}-frontenddeps-${{ hashFiles('src-ui/pnpm-lock.yaml') }} - name: Re-link Angular cli run: cd src-ui && pnpm link @angular/cli - name: Linting checks run: cd src-ui && pnpm run lint - name: Run Jest unit tests run: cd src-ui && pnpm run test --max-workers=2 --shard=${{ matrix.shard-index }}/${{ matrix.shard-count }} - name: Upload frontend test results to Codecov uses: codecov/test-results-action@v1 if: always() with: token: ${{ secrets.CODECOV_TOKEN }} flags: frontend-node-${{ matrix.node-version }} directory: src-ui/ - name: Upload frontend coverage to Codecov uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} flags: frontend-node-${{ matrix.node-version }} directory: src-ui/coverage/ tests-frontend-e2e: name: "Frontend E2E Tests (Node ${{ matrix.node-version }} - ${{ matrix.shard-index }}/${{ matrix.shard-count }})" runs-on: ubuntu-24.04 needs: - install-frontend-dependencies strategy: fail-fast: false matrix: node-version: [20.x] shard-index: [1, 2] shard-count: [2] steps: - uses: actions/checkout@v5 - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 10 - name: Use Node.js 20 uses: actions/setup-node@v4 with: node-version: 20.x cache: 'pnpm' cache-dependency-path: 'src-ui/pnpm-lock.yaml' - name: Cache frontend dependencies id: cache-frontend-deps uses: actions/cache@v4 with: path: | ~/.pnpm-store ~/.cache key: ${{ runner.os }}-frontenddeps-${{ hashFiles('src-ui/pnpm-lock.yaml') }} - name: Re-link Angular cli run: cd src-ui && pnpm link @angular/cli - name: Cache Playwright browsers uses: actions/cache@v4 with: path: ~/.cache/ms-playwright key: ${{ runner.os }}-playwright-${{ hashFiles('src-ui/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-playwright- - name: Install Playwright system dependencies run: npx playwright install-deps - name: Install dependencies run: cd src-ui && pnpm install --no-frozen-lockfile - name: Install Playwright run: cd src-ui && pnpm exec playwright install - name: Run Playwright e2e tests run: cd src-ui && pnpm exec playwright test --shard ${{ matrix.shard-index }}/${{ matrix.shard-count }} frontend-bundle-analysis: name: "Frontend Bundle Analysis" runs-on: ubuntu-24.04 needs: - tests-frontend - tests-frontend-e2e steps: - uses: actions/checkout@v5 - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 10 - name: Use Node.js 20 uses: actions/setup-node@v4 with: node-version: 20.x cache: 'pnpm' cache-dependency-path: 'src-ui/pnpm-lock.yaml' - name: Cache frontend dependencies id: cache-frontend-deps uses: actions/cache@v4 with: path: | ~/.pnpm-store ~/.cache key: ${{ runner.os }}-frontenddeps-${{ hashFiles('src-ui/package-lock.json') }} - name: Re-link Angular cli run: cd src-ui && pnpm link @angular/cli - name: Build frontend and upload analysis env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} run: cd src-ui && pnpm run build --configuration=production