From 195658a2176f8e33595c0d1cf676a7889a8e5755 Mon Sep 17 00:00:00 2001 From: gewuyou <95328647+GeWuYou@users.noreply.github.com> Date: Sun, 26 Apr 2026 11:27:41 +0800 Subject: [PATCH] =?UTF-8?q?ci(release):=20=E4=BF=AE=E5=A4=8D=20semantic-re?= =?UTF-8?q?lease=20=E9=A2=84=E8=A7=88=E9=89=B4=E6=9D=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复 preview job 在 dry-run 中改用 PAT_TOKEN 并提前校验仓库访问权限 - 补充 preview summary 对远端 push 权限探测行为的说明 - 更新 semantic-release versioning 的 tracking 与 trace 恢复点和验证记录 --- .github/workflows/auto-tag.yml | 39 ++++++++++++++++++- .../semantic-release-versioning-tracking.md | 23 +++++++---- .../semantic-release-versioning-trace.md | 11 ++++-- 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/.github/workflows/auto-tag.yml b/.github/workflows/auto-tag.yml index d502bd64..51e51095 100644 --- a/.github/workflows/auto-tag.yml +++ b/.github/workflows/auto-tag.yml @@ -27,6 +27,42 @@ jobs: persist-credentials: false ref: ${{ github.sha }} + # semantic-release 在 dry-run 中仍会执行一次 git push --dry-run 权限探测。 + # 这里提前要求与正式 release 相同的 PAT,避免 github-actions[bot] 因只读上下文触发误导性的 403。 + - name: Validate PAT token + env: + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} + REPO_API_URL: ${{ github.api_url }}/repos/${{ github.repository }} + run: | + if [ -z "${PAT_TOKEN}" ]; then + echo "::error::PAT_TOKEN is required because semantic-release preview performs a git push --dry-run permission check." + exit 1 + fi + + response_file="$(mktemp)" + status_code="$( + curl -sS -o "${response_file}" -w "%{http_code}" \ + -H "Authorization: Bearer ${PAT_TOKEN}" \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "${REPO_API_URL}" + )" + + case "${status_code}" in + 200) + ;; + 401|403) + echo "::error::PAT_TOKEN is invalid or lacks access to ${GITHUB_REPOSITORY} (HTTP ${status_code})." + cat "${response_file}" + exit 1 + ;; + *) + echo "::error::Failed to validate PAT_TOKEN against ${REPO_API_URL} (HTTP ${status_code})." + cat "${response_file}" + exit 1 + ;; + esac + # preview 始终先运行,用于给当前 SHA 生成待发布版本预览。 - name: Semantic release preview id: semantic_release @@ -37,7 +73,7 @@ jobs: extra_plugins: | conventional-changelog-conventionalcommits@9.1.0 env: - GITHUB_TOKEN: ${{ github.token }} + GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }} - name: Show preview result run: | @@ -59,6 +95,7 @@ jobs: echo "- Last tag: \`${{ steps.semantic_release.outputs.last_release_git_tag }}\`" echo "- Next version: \`${{ steps.semantic_release.outputs.new_release_version }}\`" echo "- Next tag: \`${{ steps.semantic_release.outputs.new_release_git_tag }}\`" + echo "- Preview auth: uses \`PAT_TOKEN\` because semantic-release dry-run still performs a remote push permission probe." echo "- Snapshot semantics: this preview is pinned to dispatch SHA \`${{ github.sha }}\`; commits added to \`main\` after the run starts are not included." if [ "${RELEASE_PUBLISHED}" = "true" ] && [ -n "${RELEASE_NOTES}" ]; then echo diff --git a/ai-plan/public/semantic-release-versioning/todos/semantic-release-versioning-tracking.md b/ai-plan/public/semantic-release-versioning/todos/semantic-release-versioning-tracking.md index ba8ebb56..e71a79e2 100644 --- a/ai-plan/public/semantic-release-versioning/todos/semantic-release-versioning-tracking.md +++ b/ai-plan/public/semantic-release-versioning/todos/semantic-release-versioning-tracking.md @@ -13,16 +13,18 @@ ## 当前恢复点 -- 恢复点编号:`SEMREL-RP-002` +- 恢复点编号:`SEMREL-RP-003` - 当前阶段:`Phase 2` - 当前焦点: - - 让 `.releaserc.json` 对 `BREAKING CHANGE` 与 `feat!:` / `feat(scope)!:` 的 `major` 语义与文档保持一致 - - 将 `auto-tag.yml` 的 preview / release 输出与 PR review 建议对齐,避免 release notes 被静默丢弃 - - 提前校验 `PAT_TOKEN` 的真实可用性,并把当前 PR review 修复结果同步回 `AGENTS.md` 与 active trace + - 消除 `auto-tag.yml` preview job 中由 `github-actions[bot]` 触发的 `EGITNOPERMISSION` / `git push --dry-run` 403 + - 让 preview 与 release 共用同一条 `PAT_TOKEN` 身份验证链路,避免 dry-run 与真实 release 的权限前提不一致 + - 将本轮 preview 身份验证修复同步回 active trace,并等待 CI 复验结果 ### 已知风险 - `GITHUB_TOKEN` 推送 tag 不会再触发另一个 workflow,真实发布仍需要 `PAT_TOKEN` +- `semantic-release` preview 虽然不会真实推送 tag,但仍会执行远端 `git push --dry-run` 权限探测;如果 preview 没有使用 + 可写入仓库的令牌,仍然会先于版本分析阶段失败 - `semantic-release` 的版本判断完全依赖 Conventional Commits;不规范提交会直接影响版本计算 - `cycjimmy/semantic-release-action@v6` 需要在 preview / release 两端都安装 `conventional-changelog-conventionalcommits` 以保证 `conventionalcommits` preset 在 GitHub Actions 中可解析 @@ -54,6 +56,10 @@ - 为 preview / release 的 semantic-release action 显式安装 `conventional-changelog-conventionalcommits@9.1.0` - 在 release 前通过 GitHub API 校验 `PAT_TOKEN` 是否真实可访问当前仓库 - 在 preview / release summary 中补充 snapshot 语义与生成的 release notes +- 已修复 preview 链路的鉴权前提: + - 在 preview 开始前通过 GitHub API 校验 `PAT_TOKEN` + - 将 preview 的 `semantic-release` 令牌从 `${{ github.token }}` 切换为 `${{ secrets.PAT_TOKEN }}` + - 在 preview summary 中明确说明 dry-run 仍会执行远端 push 权限探测,避免将 403 误判为版本计算失败 - 已明确真实打 tag 仍使用 `PAT_TOKEN`,因为 `GITHUB_TOKEN` 推送的 tag 不会继续触发 `publish.yml` - 已更新 `AGENTS.md` 的 Conventional Commit 规则,显式补充: - `fix/perf/refactor -> patch` @@ -93,9 +99,12 @@ - `dotnet build GFramework.sln -c Release` - 结果:通过 - 备注:Release 构建完成,`639 warning / 0 error`;warning 为仓库既有基线,与本轮 workflow / doc 改动无新增关联项 +- `dotnet build GFramework.sln -c Release`(preview 鉴权修复后复验) + - 结果:通过 + - 备注:Release 构建完成,`639 warning / 0 error`;warning 基线与修复前一致,本轮仅涉及 workflow / `ai-plan` 变更 ## 下一步 -1. 复核当前 PR review 的 open threads 是否只剩等待 push 的已修复项 -2. 将本轮修复提交到当前分支,等待 GitHub reviewer 重新评估 -3. 若后续需要,再在真实仓库主线最新快照上复验一次 `semantic-release` dry-run 结果展示 +1. 手动重跑 `Semantic Release Version and Tag` 的 preview job,确认不再出现 `git push --dry-run ... 403` +2. 若 preview 通过,再复核当前 PR review 的 open threads 是否只剩等待 push 的已修复项 +3. 将本轮修复提交到当前分支,等待 GitHub reviewer 重新评估 diff --git a/ai-plan/public/semantic-release-versioning/traces/semantic-release-versioning-trace.md b/ai-plan/public/semantic-release-versioning/traces/semantic-release-versioning-trace.md index 5aba262a..25885702 100644 --- a/ai-plan/public/semantic-release-versioning/traces/semantic-release-versioning-trace.md +++ b/ai-plan/public/semantic-release-versioning/traces/semantic-release-versioning-trace.md @@ -2,7 +2,7 @@ ## 2026-04-26 -### 当前恢复点(SEMREL-RP-002) +### 当前恢复点(SEMREL-RP-003) - 当前链路: - `workflow_dispatch` 手动启动 @@ -19,12 +19,16 @@ - `release` 额外要求 `needs.preview.result == 'success'` - `PAT_TOKEN` 在真实 release 前通过 GitHub API 做存活性校验 - preview / release summary 会展示 snapshot 语义与生成的 release notes + - `preview` 改为先校验并使用 `PAT_TOKEN`,避免 `github-actions[bot]` 在 dry-run 的远端 push 权限探测中触发 403 ### 本轮关键决策 - 保留 `@semantic-release/release-notes-generator`,但不再让它白跑: - 继续生成 notes - 将 notes 写入 GitHub Actions summary +- preview 与 release 共用 `PAT_TOKEN`: + - `semantic-release` dry-run 仍会执行 `git push --dry-run` + - preview 如果继续使用 `${{ github.token }}`,会先被 `github-actions[bot]` 的仓库写权限拦住,日志不再具有可读性 - 不保留已废弃的 `release_mode=preview|release` 中间方案: - active trace 只保留当前有效链路 - 历史演进以 tracking 文档的已完成项为准 @@ -40,5 +44,6 @@ ### 下一步 -1. 复查当前 PR 的 open review threads 是否只剩等待 push 的已修复项 -2. 创建提交并推送当前分支 +1. 重跑 `auto-tag.yml` 的 preview,确认 `EGITNOPERMISSION` 已消失 +2. 复查当前 PR 的 open review threads 是否只剩等待 push 的已修复项 +3. 创建提交并推送当前分支