From 5f38e05201df2f06112f787b22467791ebe1d1d3 Mon Sep 17 00:00:00 2001 From: Ming Date: Sat, 11 Jul 2026 08:04:43 +0800 Subject: [PATCH 1/6] ci: isolate label apply credentials --- .github/workflows/sync-labels.yml | 70 ++++++++----------------------- 1 file changed, 17 insertions(+), 53 deletions(-) diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml index 326c244..0fe74ec 100644 --- a/.github/workflows/sync-labels.yml +++ b/.github/workflows/sync-labels.yml @@ -1,83 +1,47 @@ -name: Sync organization labels +name: Apply organization labels on: workflow_dispatch: inputs: - dry_run: - description: "仅预览变更;关闭后才会实际修改标签" - required: true - type: boolean - default: true - repository: description: "只同步指定仓库;留空同步全部仓库" required: false type: string default: "" - push: - branches: - - main - paths: - - ".github/labels.yml" - - ".github/actions/sync-labels/**" - - ".github/workflows/sync-labels.yml" - - schedule: - # 每周一 UTC 03:17 预览标签漂移,不自动写入仓库。 - - cron: "17 3 * * 1" + confirm_apply: + description: "确认执行真实标签变更" + required: true + type: boolean + default: false permissions: contents: read concurrency: - group: sync-organization-labels + group: apply-organization-labels cancel-in-progress: false jobs: - sync-labels: - name: Preview or synchronize organization labels + apply-labels: + name: Apply organization label changes + if: ${{ github.ref == 'refs/heads/main' && inputs.confirm_apply }} runs-on: ubuntu-latest timeout-minutes: 30 + environment: + name: label-governance-production steps: - name: Checkout governance repository - uses: actions/checkout@v7 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: persist-credentials: false - - name: Diagnose label sync token - shell: bash - env: - GH_TOKEN: ${{ secrets.LABEL_SYNC_TOKEN }} - run: | - set -euo pipefail - - echo "Testing repository access..." - gh api \ - -H "Accept: application/vnd.github+json" \ - /repos/matharts/.github \ - --jq '{full_name, private, archived, permissions}' - - echo "Testing label read access..." - gh api \ - -H "Accept: application/vnd.github+json" \ - "/repos/matharts/.github/labels?per_page=1" \ - --include - - - name: Run MathArts label sync + - name: Apply MathArts label synchronization uses: ./.github/actions/sync-labels with: - token: ${{ secrets.LABEL_SYNC_TOKEN }} + token: ${{ secrets.LABEL_SYNC_WRITE_TOKEN }} owner: ${{ github.repository_owner }} config_file: ".github/labels.yml" - - # Push 和定时任务只做预览。只有手动触发并关闭 dry_run 才实际写入。 - dry_run: >- - ${{ github.event_name != 'workflow_dispatch' - || inputs.dry_run }} - - repository: >- - ${{ github.event_name == 'workflow_dispatch' - && inputs.repository - || '' }} + dry_run: "false" + repository: ${{ inputs.repository }} From 7c4ac2add85a641b75daea7f422ff3cc072f109e Mon Sep 17 00:00:00 2001 From: Ming Date: Sat, 11 Jul 2026 08:04:51 +0800 Subject: [PATCH 2/6] ci: add read-only label preview --- .github/workflows/preview-labels.yml | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 .github/workflows/preview-labels.yml diff --git a/.github/workflows/preview-labels.yml b/.github/workflows/preview-labels.yml new file mode 100644 index 0000000..9f11a17 --- /dev/null +++ b/.github/workflows/preview-labels.yml @@ -0,0 +1,55 @@ +name: Preview organization labels + +on: + workflow_dispatch: + inputs: + repository: + description: "只预览指定仓库;留空预览全部可见仓库" + required: false + type: string + default: "" + + push: + branches: + - main + paths: + - ".github/labels.yml" + - ".github/actions/sync-labels/**" + - ".github/workflows/preview-labels.yml" + - ".github/workflows/sync-labels.yml" + + schedule: + # 每周一 UTC 03:17 检查公开可见仓库的标签漂移。 + - cron: "17 3 * * 1" + +permissions: + contents: read + issues: read + +concurrency: + group: preview-organization-labels + cancel-in-progress: true + +jobs: + preview-labels: + name: Preview organization label changes + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout governance repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + with: + persist-credentials: false + + - name: Preview MathArts label synchronization + uses: ./.github/actions/sync-labels + with: + token: ${{ github.token }} + owner: ${{ github.repository_owner }} + config_file: ".github/labels.yml" + dry_run: "true" + repository: >- + ${{ github.event_name == 'workflow_dispatch' + && inputs.repository + || '' }} From 9282e9cef2bc517d2d4d93e98f9fc7f57350bb8d Mon Sep 17 00:00:00 2001 From: Ming Date: Sat, 11 Jul 2026 08:05:04 +0800 Subject: [PATCH 3/6] ci: pin third-party actions by SHA --- .github/workflows/validate-documentation.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/validate-documentation.yml b/.github/workflows/validate-documentation.yml index 8cbd5b9..43a95ab 100644 --- a/.github/workflows/validate-documentation.yml +++ b/.github/workflows/validate-documentation.yml @@ -42,7 +42,7 @@ jobs: timeout-minutes: 5 steps: - name: Checkout repository - uses: actions/checkout@v7 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: persist-credentials: false @@ -68,10 +68,10 @@ jobs: name: Lint Markdown runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: persist-credentials: false - - uses: DavidAnson/markdownlint-cli2-action@v24 + - uses: DavidAnson/markdownlint-cli2-action@8de2aa07cae85fd17c0b35642db70cf5495f1d25 # v24 with: config: ".markdownlint-cli2.jsonc" globs: "**/*.md" @@ -81,7 +81,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: persist-credentials: false @@ -99,10 +99,10 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: persist-credentials: false - - uses: lycheeverse/lychee-action@v2 + - uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2 with: args: >- --config lychee.toml From aff264884c2ffcdd746ae39f38b076b6bc0cd98a Mon Sep 17 00:00:00 2001 From: Ming Date: Sat, 11 Jul 2026 08:05:09 +0800 Subject: [PATCH 4/6] ci: maintain pinned GitHub Actions --- .github/dependabot.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..8890c37 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 + +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + open-pull-requests-limit: 5 + labels: + - "type: dependencies" + commit-message: + prefix: "ci" From 6b957ab480f428ead9575cab0b1234e9d0c69434 Mon Sep 17 00:00:00 2001 From: Ming Date: Sat, 11 Jul 2026 08:05:24 +0800 Subject: [PATCH 5/6] docs: document protected label apply flow --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 996d42f..0e8f2ca 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,12 @@ MathArts 的组织级标签由两个权威来源共同维护: 标签同步只管理组织保留的 `type:*`、`status:*`、`priority:*`、`impact:*`、`process:*`、`resolution:*` 系列、贡献入口标签及其历史别名。项目仓库可以增加 `area:*`、`package:*`、`platform:*` 或其他项目特定标签,自动化会保留这些扩展标签。 -推送和定时任务只预览标签漂移。实际修改必须通过手动触发标签同步工作流,并明确关闭 Dry Run。 +标签自动化分为两个权限边界: + +* [`preview-labels.yml`](.github/workflows/preview-labels.yml) 在推送、定时任务或手动触发时使用只读 `github.token` 预览公开可见仓库的标签漂移,不读取跨仓库写令牌; +* [`sync-labels.yml`](.github/workflows/sync-labels.yml) 只允许从 `main` 手动触发真实变更,并绑定 `label-governance-production` Environment。 + +真实同步所需的 `LABEL_SYNC_WRITE_TOKEN` 必须配置为 `label-governance-production` 的 Environment Secret,而不是普通仓库 Secret。该 Environment 应在仓库设置中启用 Required reviewers,并禁止发起者自行批准。 ## 维护原则 From 144ba4e691be9d77a07b4e877e7a4fbcde0b6ab3 Mon Sep 17 00:00:00 2001 From: Ming Date: Sat, 11 Jul 2026 08:07:01 +0800 Subject: [PATCH 6/6] ci: preview label changes on pull requests --- .github/workflows/preview-labels.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/preview-labels.yml b/.github/workflows/preview-labels.yml index 9f11a17..e9ed549 100644 --- a/.github/workflows/preview-labels.yml +++ b/.github/workflows/preview-labels.yml @@ -9,6 +9,13 @@ on: type: string default: "" + pull_request: + paths: + - ".github/labels.yml" + - ".github/actions/sync-labels/**" + - ".github/workflows/preview-labels.yml" + - ".github/workflows/sync-labels.yml" + push: branches: - main @@ -27,7 +34,7 @@ permissions: issues: read concurrency: - group: preview-organization-labels + group: preview-organization-labels-${{ github.ref }} cancel-in-progress: true jobs: