ci(release): 修复 semantic-release 预览鉴权

- 修复 preview job 在 dry-run 中改用 PAT_TOKEN 并提前校验仓库访问权限
- 补充 preview summary 对远端 push 权限探测行为的说明
- 更新 semantic-release versioning 的 tracking 与 trace 恢复点和验证记录
This commit is contained in:
gewuyou 2026-04-26 11:27:41 +08:00
parent 524d54d3de
commit 195658a217
3 changed files with 62 additions and 11 deletions

View File

@ -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

View File

@ -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 重新评估

View File

@ -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. 创建提交并推送当前分支