diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9ecc51dc..50dc7f0a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,6 +5,8 @@ updates: directory: "/" schedule: interval: "daily" + cooldown: + default-days: 7 groups: actions: patterns: diff --git a/.github/workflows/bump.yml b/.github/workflows/bump.yml index 1616c0ef..7200b37f 100644 --- a/.github/workflows/bump.yml +++ b/.github/workflows/bump.yml @@ -18,7 +18,12 @@ jobs: with: app-id: ${{ secrets.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} + # Scope the token to only what the PR creation needs + permission-contents: write + permission-pull-requests: write - uses: actions/checkout@v6 + with: + persist-credentials: false - uses: astral-sh/setup-uv@v8.2.0 - run: uvx nox -s pc_bump env: diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index a3e6c3c6..fb5389de 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -6,14 +6,19 @@ on: types: - published +permissions: {} + jobs: dist: name: Distribution build runs-on: ubuntu-latest + permissions: + contents: read steps: - uses: actions/checkout@v6 with: + persist-credentials: false fetch-depth: 0 - uses: hynek/build-and-inspect-python-package@v2 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 843e4033..73131db3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,23 +11,34 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: {} + jobs: change-detection: + permissions: + contents: read + pull-requests: read uses: ./.github/workflows/reusable-change-detection.yml cookie: needs: change-detection if: fromJSON(needs.change-detection.outputs.run-cookie) + permissions: + contents: read uses: ./.github/workflows/reusable-cookie.yml rr-tests: needs: change-detection if: fromJSON(needs.change-detection.outputs.run-rr) + permissions: + contents: read uses: ./.github/workflows/reusable-rr-tests.yml docs: needs: change-detection if: fromJSON(needs.change-detection.outputs.run-docs) + permissions: + contents: read uses: ./.github/workflows/reusable-docs.yml pass: diff --git a/.github/workflows/docs-link.yml b/.github/workflows/docs-link.yml index 1b62af3c..faaaa291 100644 --- a/.github/workflows/docs-link.yml +++ b/.github/workflows/docs-link.yml @@ -1,6 +1,9 @@ name: Read the Docs PR preview on: + # zizmor: ignore[dangerous-triggers] + # pull_request_target is required so the RTD preview can comment on PRs from + # forks; no untrusted code is checked out, and it is gated on `fork == false`. pull_request_target: types: - opened diff --git a/.github/workflows/reusable-change-detection.yml b/.github/workflows/reusable-change-detection.yml index 8a7c9bac..b27597b6 100644 --- a/.github/workflows/reusable-change-detection.yml +++ b/.github/workflows/reusable-change-detection.yml @@ -23,6 +23,8 @@ jobs: run-docs: ${{ steps.docs-changes.outputs.run-docs || false }} steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Changed cookie-related files if: github.event_name == 'pull_request' diff --git a/.github/workflows/reusable-cookie.yml b/.github/workflows/reusable-cookie.yml index 985de892..db614e44 100644 --- a/.github/workflows/reusable-cookie.yml +++ b/.github/workflows/reusable-cookie.yml @@ -14,6 +14,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Lint all run: pipx run nox -s 'lint' @@ -33,6 +35,8 @@ jobs: steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - uses: actions/setup-python@v6 with: @@ -105,6 +109,8 @@ jobs: steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - uses: actions/setup-python@v6 with: @@ -172,6 +178,8 @@ jobs: steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Build sdist and wheel run: pipx run nox -s dist diff --git a/.github/workflows/reusable-docs.yml b/.github/workflows/reusable-docs.yml index 347a9809..e8f2d75c 100644 --- a/.github/workflows/reusable-docs.yml +++ b/.github/workflows/reusable-docs.yml @@ -10,6 +10,8 @@ jobs: timeout-minutes: 10 steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - uses: oven-sh/setup-bun@v2 diff --git a/.github/workflows/reusable-rr-tests.yml b/.github/workflows/reusable-rr-tests.yml index 07ac22ce..05fb69da 100644 --- a/.github/workflows/reusable-rr-tests.yml +++ b/.github/workflows/reusable-rr-tests.yml @@ -21,6 +21,7 @@ jobs: steps: - uses: actions/checkout@v6 with: + persist-credentials: false fetch-depth: 0 - uses: actions/setup-python@v6 @@ -41,6 +42,7 @@ jobs: steps: - uses: actions/checkout@v6 with: + persist-credentials: false fetch-depth: 0 - name: Run sp-repo-review action @@ -52,6 +54,7 @@ jobs: steps: - uses: actions/checkout@v6 with: + persist-credentials: false fetch-depth: 0 - uses: actions/setup-python@v6 @@ -71,6 +74,7 @@ jobs: steps: - uses: actions/checkout@v6 with: + persist-credentials: false fetch-depth: 0 - uses: actions/setup-python@v6 diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 00000000..5aae9aaf --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,8 @@ +# Configuration for zizmor (https://docs.zizmor.sh) +rules: + unpinned-uses: + config: + # Actions are kept up to date with Dependabot, so a ref (tag) pin is + # sufficient; hash pinning is not required. + policies: + "*": ref-pin diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9519f684..a9f4f007 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -77,6 +77,11 @@ repos: - id: typos exclude: ^Gemfile\.lock$ + - repo: https://github.com/zizmorcore/zizmor-pre-commit + rev: "v1.25.2" + hooks: + - id: zizmor + - repo: local hooks: - id: disallow-caps diff --git a/action.yml b/action.yml index 007365a7..f78c8b55 100644 --- a/action.yml +++ b/action.yml @@ -28,14 +28,21 @@ runs: - name: Run repo-review shell: bash + # Pass expansions through the environment to avoid template injection + env: + PYTHON_PATH: ${{ steps.python.outputs.python-path }} + ACTION_PATH: ${{ github.action_path }} + SELECT: ${{ inputs.select }} + IGNORE: ${{ inputs.ignore }} + PACKAGE_DIR: ${{ inputs.package-dir }} run: > pipx run - --python '${{ steps.python.outputs.python-path }}' - --spec '${{ github.action_path }}[cli]' + --python "$PYTHON_PATH" + --spec "$ACTION_PATH[cli]" repo-review . --format html --stderr rich - --select "${{ inputs.select }}" - --ignore "${{ inputs.ignore }}" - --package-dir "${{ inputs.package-dir }}" - >> $GITHUB_STEP_SUMMARY + --select "$SELECT" + --ignore "$IGNORE" + --package-dir "$PACKAGE_DIR" + >> "$GITHUB_STEP_SUMMARY"