diff --git a/.github/workflows/sync-readme.yml b/.github/workflows/sync-readme.yml index df83f80..7847d42 100644 --- a/.github/workflows/sync-readme.yml +++ b/.github/workflows/sync-readme.yml @@ -2,8 +2,11 @@ name: Sync README # Regenerates the plugin overview in README.md from lithe-plugin-index.json # after every change lands on main, so contributors and the release bot only -# edit the index. Commits made with GITHUB_TOKEN do not trigger workflows, -# so the sync commit cannot loop. +# edit the index. `main` is protected (owners merge), so the workflow cannot +# push to it: it commits to the bot/sync-readme branch and opens or updates one +# pull request, like Track plugin releases does. Merging that pull request +# re-runs this workflow, finds README.md already in sync and stops, so it +# cannot loop. on: push: branches: [main] @@ -16,6 +19,7 @@ on: permissions: contents: write + pull-requests: write concurrency: group: sync-readme @@ -23,25 +27,46 @@ concurrency: jobs: sync: + # The overview must be rendered from main, never from a feature branch. + if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest timeout-minutes: 5 + env: + BRANCH: bot/sync-readme + # A PR opened with GITHUB_TOKEN does not trigger other workflows. Set the + # STORE_BOT_TOKEN secret (fine-grained PAT: contents + pull requests) so + # `Validate index` runs on the bot PR as well. + GH_TOKEN: ${{ secrets.STORE_BOT_TOKEN || github.token }} steps: - uses: actions/checkout@v7 + with: + token: ${{ secrets.STORE_BOT_TOKEN || github.token }} - uses: actions/setup-node@v7 with: node-version: 22 - - name: Render the plugin overview run: node scripts/render-readme.mjs - - - name: Commit when README changed + - name: Open or update the pull request when README changed run: | if git diff --quiet -- README.md; then echo "README.md is already in sync." + # An earlier sync pull request that nobody merged is now obsolete. + if gh pr view "$BRANCH" --json state -q .state 2>/dev/null | grep -q OPEN; then + gh pr close "$BRANCH" --delete-branch \ + --comment "main 上的 README 总览已经与索引一致,这个同步 PR 不再需要。" + fi exit 0 fi git config user.name "lithe-store-bot" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git switch -C "$BRANCH" git add README.md git commit -m "docs(readme): 同步插件总览" - git push origin HEAD:main + git push --force origin "$BRANCH" + title="docs(readme): 同步插件总览" + body="README 的插件总览由 \`scripts/render-readme.mjs\` 根据 \`lithe-plugin-index.json\` 生成。main 上的索引或渲染脚本有更新,这个 PR 只包含重新生成的 \`README.md\`,合并即可。" + if gh pr view "$BRANCH" --json state -q .state 2>/dev/null | grep -q OPEN; then + gh pr edit "$BRANCH" --title "$title" --body "$body" + else + gh pr create --base main --head "$BRANCH" --title "$title" --body "$body" + fi diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 422a1af..10f432b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,7 +13,7 @@ - 一个 PR 只改一个插件,便于审查和回退。 - `plugins` 按 `id` 字母序排列;每个插件的 `versions` 新版本在前。 - 不修改已发布版本的 `downloadURL` 与 `sha256`;不删除历史版本(撤回问题版本除外)。 -- README 的插件总览由 `scripts/render-readme.mjs` 根据索引生成,合并到 main 后由 `Sync README` 工作流自动提交,PR 中不需要手动更新。 +- README 的插件总览由 `scripts/render-readme.mjs` 根据索引生成,合并到 main 后由 `Sync README` 工作流开一个 `bot/sync-readme` PR 同步(`main` 受保护,不能直接推送),PR 中不需要手动更新。 - 插件图标填在条目的 `icon` 字段,指向插件仓库内固定到提交的 SVG/PNG(`raw.githubusercontent.com////…`);没有填写时 README 使用默认图标。 - 插件的 bug 与功能请求请提到插件自己的仓库,本仓库只处理收录相关事务。 @@ -61,7 +61,7 @@ scripts/track-releases.mjs # 追踪已收录插件的新 Release 并生成 scripts/render-readme.mjs # 根据索引生成 README 的插件总览 scripts/store.test.mjs # 校验脚本的测试(fixtures 复制自插件契约) assets/ # README 用到的图片(无图标插件的默认图标) -.github/workflows/ # validate(PR/推送/每周)、track-releases(每 6 小时)、sync-readme(main 更新后同步 README) +.github/workflows/ # validate(PR/推送/每周)、track-releases(每 6 小时)、sync-readme(main 更新后开 PR 同步 README) ``` ## 本地校验 diff --git a/docs/maintainers.md b/docs/maintainers.md index a248adc..c48fb14 100644 --- a/docs/maintainers.md +++ b/docs/maintainers.md @@ -31,6 +31,17 @@ CI(`Validate index`)已经自动保证: `Validate index`;工作流已在开 PR 前完成同样的校验,但合并前需要手动运行一次检查才能满足分支保护。 3. 分支保护:`main` 要求 `Validate index / validate` 通过,要求 CODEOWNERS 审查。 +## 自动同步 README 总览 + +README 的插件总览由 `scripts/render-readme.mjs` 根据索引生成。`main` 上的索引、渲染脚本或图片更新后, +`Sync README` 工作流重新生成它;`main` 受保护,工作流不能直接推送,所以和追踪新版本一样, +把结果提交到 `bot/sync-readme` 分支并开一个 PR,下一次运行会覆盖这个分支并更新描述。 +合并这个 PR 后工作流会再运行一次,发现总览已经一致就结束。总览已经一致时,上一轮没人合并的同步 PR 会被自动关闭。 + +仓库设置与追踪新版本相同(“Allow GitHub Actions to create and approve pull requests”, +可选的 `STORE_BOT_TOKEN`)。没有配置 `STORE_BOT_TOKEN` 时,这个 PR 也不会触发 `Validate index`, +需要手动运行一次检查才能满足分支保护。同步 PR 只应该包含 `README.md`;如果还改了别的文件,不要合并。 + ## 下架与撤回 | 情况 | 处理 |