diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8118c2c5d..a28f19dd4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,27 +22,35 @@ jobs: # 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 + permissions: + contents: read runs-on: ubuntu-24.04 steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v4.2.2 + with: + persist-credentials: false - name: Install python - uses: actions/setup-python@v5 + uses: actions/setup-python@v5.6.0 with: python-version: ${{ env.DEFAULT_PYTHON_VERSION }} - name: Check files uses: pre-commit/action@v3.0.1 documentation: name: "Build & Deploy Documentation" + permissions: + contents: write runs-on: ubuntu-24.04 needs: - pre-commit steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v4.2.2 + with: + persist-credentials: false - name: Set up Python id: setup-python - uses: actions/setup-python@v5 + uses: actions/setup-python@v5.6.0 with: python-version: ${{ env.DEFAULT_PYTHON_VERSION }} - name: Install uv @@ -62,7 +70,7 @@ jobs: --frozen \ mkdocs build --config-file ./mkdocs.yml - name: Deploy documentation - if: github.event_name == 'push' && github.ref == 'refs/heads/main' + if: github.event_name == 'push' && github.ref_name == 'main' run: | echo "docs.paperless-ngx.com" > "${{ github.workspace }}/docs/CNAME" git config --global user.name "${{ github.actor }}" @@ -73,13 +81,15 @@ jobs: --frozen \ mkdocs gh-deploy --force --no-history - name: Upload artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v4.6.2 with: name: documentation path: site/ retention-days: 7 tests-backend: name: "Backend Tests (Python ${{ matrix.python-version }})" + permissions: + contents: read runs-on: ubuntu-24.04 needs: - pre-commit @@ -89,14 +99,16 @@ jobs: fail-fast: false steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v4.2.2 + with: + persist-credentials: false - 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 + uses: actions/setup-python@v5.6.0 with: python-version: "${{ matrix.python-version }}" - name: Install uv @@ -136,13 +148,13 @@ jobs: pytest - name: Upload backend test results to Codecov if: always() - uses: codecov/test-results-action@v1 + uses: codecov/test-results-action@v1.1.0 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 + uses: codecov/codecov-action@v5.4.2 with: token: ${{ secrets.CODECOV_TOKEN }} flags: backend-python-${{ matrix.python-version }} @@ -154,24 +166,28 @@ jobs: docker compose --file ${{ github.workspace }}/docker/compose/docker-compose.ci-test.yml down install-frontend-dependencies: name: "Install Frontend Dependencies" + permissions: + contents: read runs-on: ubuntu-24.04 needs: - pre-commit steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v4.2.2 + with: + persist-credentials: false - name: Install pnpm - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v4.1.0 with: version: 10 - name: Use Node.js 20 - uses: actions/setup-node@v4 + uses: actions/setup-node@v4.4.0 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 + uses: actions/cache@v4.2.3 with: path: | ~/.pnpm-store @@ -185,6 +201,8 @@ jobs: run: cd src-ui && pnpm playwright install --with-deps tests-frontend: name: "Frontend Tests (Node ${{ matrix.node-version }} - ${{ matrix.shard-index }}/${{ matrix.shard-count }})" + permissions: + contents: read runs-on: ubuntu-24.04 needs: - install-frontend-dependencies @@ -195,20 +213,22 @@ jobs: shard-index: [1, 2, 3, 4] shard-count: [4] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v4.2.2 + with: + persist-credentials: false - name: Install pnpm - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v4.1.0 with: version: 10 - name: Use Node.js 20 - uses: actions/setup-node@v4 + uses: actions/setup-node@v4.4.0 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 + uses: actions/cache@v4.2.3 with: path: | ~/.pnpm-store @@ -223,38 +243,42 @@ jobs: - name: Run Playwright e2e tests run: cd src-ui && pnpm exec playwright test --shard ${{ matrix.shard-index }}/${{ matrix.shard-count }} - name: Upload frontend test results to Codecov - uses: codecov/test-results-action@v1 + uses: codecov/test-results-action@v1.1.0 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 + uses: codecov/codecov-action@v5.4.2 with: token: ${{ secrets.CODECOV_TOKEN }} flags: frontend-node-${{ matrix.node-version }} directory: src-ui/coverage/ frontend-bundle-analysis: name: "Frontend Bundle Analysis" + permissions: + contents: read runs-on: ubuntu-24.04 needs: - tests-frontend steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v4.2.2 + with: + persist-credentials: false - name: Install pnpm - uses: pnpm/action-setup@v4 + uses: pnpm/action-setup@v4.1.0 with: version: 10 - name: Use Node.js 20 - uses: actions/setup-node@v4 + uses: actions/setup-node@v4.4.0 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 + uses: actions/cache@v4.2.3 with: path: | ~/.pnpm-store @@ -268,6 +292,9 @@ jobs: run: cd src-ui && pnpm run build --configuration=production build-docker-image: name: Build Docker image for ${{ github.ref_name }} + permissions: + contents: read + packages: write runs-on: ubuntu-24.04 if: github.event_name == 'push' && (startsWith(github.ref, 'refs/heads/feature-') || startsWith(github.ref, 'refs/heads/fix-') || github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/beta' || contains(github.ref, 'beta.rc') || startsWith(github.ref, 'refs/tags/v')) concurrency: @@ -301,7 +328,7 @@ jobs: echo "ghcr-repository=${ghcr_name}" >> $GITHUB_OUTPUT - name: Gather Docker metadata id: docker-meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@v5.7.0 with: images: | ghcr.io/${{ steps.set-ghcr-repository.outputs.ghcr-repository }} @@ -315,31 +342,33 @@ jobs: type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v4.2.2 + with: + persist-credentials: false # If https://github.com/docker/buildx/issues/1044 is resolved, # the append input with a native arm64 arch could be used to # significantly speed up building - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v3.10.0 - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v3.6.0 with: platforms: arm64 - name: Login to GitHub Container Registry - uses: docker/login-action@v3 + uses: docker/login-action@v3.4.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Login to Docker Hub - uses: docker/login-action@v3 + uses: docker/login-action@v3.4.0 # Don't attempt to login if not pushing to Docker Hub if: steps.push-other-places.outputs.enable == 'true' with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Login to Quay.io - uses: docker/login-action@v3 + uses: docker/login-action@v3.4.0 # Don't attempt to login if not pushing to Quay.io if: steps.push-other-places.outputs.enable == 'true' with: @@ -347,7 +376,7 @@ jobs: username: ${{ secrets.QUAY_USERNAME }} password: ${{ secrets.QUAY_ROBOT_TOKEN }} - name: Build and push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v6.16.0 with: context: . file: ./Dockerfile @@ -372,23 +401,27 @@ jobs: docker create --name frontend-extract ${{ fromJSON(steps.docker-meta.outputs.json).tags[0] }} docker cp frontend-extract:/usr/src/paperless/src/documents/static/frontend src/documents/static/frontend/ - name: Upload frontend artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v4.6.2 with: name: frontend-compiled path: src/documents/static/frontend/ retention-days: 7 build-release: name: "Build Release" + permissions: + contents: read needs: - build-docker-image - documentation runs-on: ubuntu-24.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v4.2.2 + with: + persist-credentials: false - name: Set up Python id: setup-python - uses: actions/setup-python@v5 + uses: actions/setup-python@v5.6.0 with: python-version: ${{ env.DEFAULT_PYTHON_VERSION }} - name: Install uv @@ -405,12 +438,12 @@ jobs: sudo apt-get update -qq sudo apt-get install -qq --no-install-recommends gettext liblept5 - name: Download frontend artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v4.3.0 with: name: frontend-compiled path: src/documents/static/frontend/ - name: Download documentation artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v4.3.0 with: name: documentation path: docs/_build/html/ @@ -473,13 +506,15 @@ jobs: sudo chown -R 1000:1000 paperless-ngx/ tar -cJf paperless-ngx.tar.xz paperless-ngx/ - name: Upload release artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v4.6.2 with: name: release path: dist/paperless-ngx.tar.xz retention-days: 7 publish-release: name: "Publish Release" + permissions: + contents: write runs-on: ubuntu-24.04 outputs: prerelease: ${{ steps.get_version.outputs.prerelease }} @@ -490,14 +525,16 @@ jobs: if: github.ref_type == 'tag' && (startsWith(github.ref_name, 'v') || contains(github.ref_name, '-beta.rc')) steps: - name: Download release artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v4.3.0 with: name: release path: ./ - name: Get version id: get_version + env: + REF_NAME: ${{ github.ref_name }} run: | - echo "version=${{ github.ref_name }}" >> $GITHUB_OUTPUT + echo "version=${REF_NAME}" >> $GITHUB_OUTPUT if [[ ${{ contains(github.ref_name, '-beta.rc') }} == 'true' ]]; then echo "prerelease=true" >> $GITHUB_OUTPUT else @@ -505,7 +542,7 @@ jobs: fi - name: Create Release and Changelog id: create-release - uses: release-drafter/release-drafter@v6 + uses: release-drafter/release-drafter@v6.1.0 with: name: Paperless-ngx ${{ steps.get_version.outputs.version }} tag: ${{ steps.get_version.outputs.version }} @@ -516,7 +553,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload release archive id: upload-release-asset - uses: shogo82148/actions-upload-release-asset@v1 + uses: shogo82148/actions-upload-release-asset@v1.8.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} upload_url: ${{ steps.create-release.outputs.upload_url }} @@ -525,18 +562,22 @@ jobs: asset_content_type: application/x-xz append-changelog: name: "Append Changelog" + permissions: + contents: write + pull-requests: write runs-on: ubuntu-24.04 needs: - publish-release if: needs.publish-release.outputs.prerelease == 'false' steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v4.2.2 with: ref: main + persist-credentials: false - name: Set up Python id: setup-python - uses: actions/setup-python@v5 + uses: actions/setup-python@v5.6.0 with: python-version: ${{ env.DEFAULT_PYTHON_VERSION }} - name: Install uv @@ -568,7 +609,7 @@ jobs: git commit -am "Changelog ${{ needs.publish-release.outputs.version }} - GHA" git push origin ${{ needs.publish-release.outputs.version }}-changelog - name: Create Pull Request - uses: actions/github-script@v7 + uses: actions/github-script@v7.0.1 with: script: | const { repo, owner } = context.repo; diff --git a/.github/workflows/translate-strings.yml b/.github/workflows/translate-strings.yml index a1e50d65d..e9e5ce02d 100644 --- a/.github/workflows/translate-strings.yml +++ b/.github/workflows/translate-strings.yml @@ -62,7 +62,7 @@ jobs: cd src-ui pnpm run ng extract-i18n - name: Commit changes - uses: stefanzweifel/git-auto-commit-action@b863ae1933cb653a53c021fe36dbb774e1fb9403 # v5.2.0 + uses: stefanzweifel/git-auto-commit-action@b863ae1933cb653a53c021fe36dbb774e1fb9403 # v5.2.0 with: file_pattern: 'src-ui/messages.xlf src/locale/en_US/LC_MESSAGES/django.po' commit_message: "Auto translate strings" diff --git a/.github/zizmor.yml b/.github/zizmor.yml index 95cb06bea..77524cab7 100644 --- a/.github/zizmor.yml +++ b/.github/zizmor.yml @@ -5,15 +5,38 @@ rules: # See https://woodruffw.github.io/zizmor/audits/#remediation_1 # we filter to the target branches to limit external users running their own code - pr-bot.yml:2:1 + # This workflow is manually disabled anyway + - project-actions.yml:2:1 + # See https://woodruffw.github.io/zizmor/audits/#cache-poisoning + cache-poisoning: + ignore: + # We don't publish a release or GitHub page from pull requests, only internal branches + # So I think this is safe + - ci.yml:2:1 + # See https://woodruffw.github.io/zizmor/audits/#template-injection + template-injection: + ignore: + # This location only checks the value of github.ref_name, and branch names can't contain + # executable code via injection + - ci.yml:307:9 + # Much the same here, the github.ref_name seems like it should be safe from injection + - ci.yml:72:9 unpinned-uses: config: policies: # We trust GitHub not to have a security incident actions/*: ref-pin github/codeql-action/*: ref-pin + # Going to trust Docker as well + docker/*: ref-pin + # And Codecov + codecov/*: ref-pin + release-drafter/release-drafter/*: ref-pin + shogo82148/actions-upload-release-asset/*: ref-pin crowdin/github-action: ref-pin astral-sh/setup-uv: ref-pin pnpm/action-setup: ref-pin dessant/lock-threads: ref-pin Gascon1/pr-size-labeler: ref-pin + pre-commit/action: ref-pin stumpylog/image-cleaner-action/*: ref-pin diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a16f703ba..347438cf6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -51,7 +51,11 @@ repos: - repo: https://github.com/woodruffw/zizmor-pre-commit rev: v1.6.0 hooks: - - id: zizmor + - id: zizmor + args: + - "--no-progress" + - "--quiet" + - "--min-severity=low" # Python hooks - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.9.9