diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..ae2b8bc --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +# 每月一次,每个生态合成一个 PR(Refs ModAVD/ModAVD#127)。 +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly + cooldown: + default-days: 7 + groups: + github-actions: + patterns: + - "*" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b2cf7b..885fafb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,6 +2,9 @@ name: CI on: pull_request: + push: + branches: [main] + merge_group: workflow_dispatch: permissions: @@ -94,6 +97,32 @@ jobs: - name: Run repo checks unit tests shell: bash run: python3 -B -I -X utf8 scripts/test_repo_checks.py -v + # PR 里的提交在 pull_request 时已经查过。push 和 merge_group 下要查的只剩 GitHub 生成的 squash 提交, + # 它的作者邮箱取自贡献者 GitHub 账号的设置,不归作者检查管;查了会让合并队列和 main 无端变红。 - name: Check commit authors and trailers + if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' shell: bash run: python3 -B -I -X utf8 scripts/repo_checks.py + + zizmor: + name: Workflow security (zizmor) + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - name: Checkout without persistent credentials + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Install zizmor 1.32.0 (version and wheel hash pinned) + shell: bash + run: | + set -euo pipefail + python3 -m venv "$RUNNER_TEMP/zizmor" + printf '%s\n' 'zizmor==1.32.0 --hash=sha256:84a6acb975accc13408786a2bd274b572537ca19c933ebbc13e78f3988562071' > "$RUNNER_TEMP/zizmor-requirements.txt" + "$RUNNER_TEMP/zizmor/bin/pip" install --quiet --disable-pip-version-check --no-deps --only-binary=:all: \ + --require-hashes -r "$RUNNER_TEMP/zizmor-requirements.txt" + - name: Audit workflows and Dependabot config + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: '"$RUNNER_TEMP/zizmor/bin/zizmor" --format=github --no-progress .' diff --git a/scripts/test_repo_checks.py b/scripts/test_repo_checks.py index e854e16..965508a 100644 --- a/scripts/test_repo_checks.py +++ b/scripts/test_repo_checks.py @@ -11,6 +11,8 @@ class RepoChecksTest(unittest.TestCase): def test_allowed_identities(self): self.assertTrue(repo_checks.identity_allowed("qiyinxi", "qiyinxi@foxmail.com")) self.assertTrue(repo_checks.identity_allowed("Bot", "123+bot[bot]@users.noreply.github.com")) + # Dependabot 的提交作者,原样照 GitHub 写的抄。 + self.assertTrue(repo_checks.identity_allowed("dependabot[bot]", "49699333+dependabot[bot]@users.noreply.github.com")) self.assertTrue(repo_checks.identity_allowed("Old", "octocat@users.noreply.github.com")) def test_rejects_private_or_ai_identities(self):