mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-07 00:39:00 +08:00
ci(release): 收敛 PAT 校验并归档迁移跟踪
- 新增复用的 PAT 校验 composite action,并统一 preview 与 release 的鉴权入口 - 修复 read-only PAT 会误过 API 探活的问题,提前校验 push 权限并清理临时文件 - 归档 semantic-release 迁移历史完成项,精简 active tracking 与 trace 恢复点
This commit is contained in:
parent
195658a217
commit
f777cdebd7
66
.github/actions/validate-pat/action.yml
vendored
Normal file
66
.github/actions/validate-pat/action.yml
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
name: Validate PAT
|
||||
description: Validate that the release PAT can access the repository and push tags.
|
||||
|
||||
inputs:
|
||||
pat-token:
|
||||
description: Personal access token used by semantic-release.
|
||||
required: true
|
||||
repo-api-url:
|
||||
description: GitHub repository API URL, for example https://api.github.com/repos/owner/repo.
|
||||
required: true
|
||||
repository:
|
||||
description: Repository slug used in error messages.
|
||||
required: true
|
||||
missing-token-message:
|
||||
description: Error message emitted when the PAT is absent.
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Validate PAT can push
|
||||
shell: bash
|
||||
env:
|
||||
PAT_TOKEN: ${{ inputs.pat-token }}
|
||||
REPO_API_URL: ${{ inputs.repo-api-url }}
|
||||
REPOSITORY: ${{ inputs.repository }}
|
||||
MISSING_TOKEN_MESSAGE: ${{ inputs.missing-token-message }}
|
||||
run: |
|
||||
if [ -z "${PAT_TOKEN}" ]; then
|
||||
echo "::error::${MISSING_TOKEN_MESSAGE}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
response_file="$(mktemp)"
|
||||
trap 'rm -f "${response_file}"' EXIT
|
||||
|
||||
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)
|
||||
# The repository endpoint returns 200 for read-only tokens as well.
|
||||
# semantic-release still performs a remote push probe, so require push permission here.
|
||||
push_ok="$(jq -r '.permissions.push // false' "${response_file}")"
|
||||
if [ "${push_ok}" != "true" ]; then
|
||||
echo "::error::PAT_TOKEN can read ${REPOSITORY} but lacks push permission. semantic-release requires contents:write."
|
||||
cat "${response_file}"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
401|403)
|
||||
echo "::error::PAT_TOKEN is invalid or lacks access to ${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
|
||||
76
.github/workflows/auto-tag.yml
vendored
76
.github/workflows/auto-tag.yml
vendored
@ -30,38 +30,12 @@ jobs:
|
||||
# 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
|
||||
uses: ./.github/actions/validate-pat
|
||||
with:
|
||||
pat-token: ${{ secrets.PAT_TOKEN }}
|
||||
repo-api-url: ${{ github.api_url }}/repos/${{ github.repository }}
|
||||
repository: ${{ github.repository }}
|
||||
missing-token-message: PAT_TOKEN is required because semantic-release preview performs a git push --dry-run permission check.
|
||||
|
||||
# preview 始终先运行,用于给当前 SHA 生成待发布版本预览。
|
||||
- name: Semantic release preview
|
||||
@ -130,38 +104,12 @@ jobs:
|
||||
ref: ${{ github.sha }}
|
||||
|
||||
- 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 a tag created with GITHUB_TOKEN will not trigger publish.yml."
|
||||
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
|
||||
uses: ./.github/actions/validate-pat
|
||||
with:
|
||||
pat-token: ${{ secrets.PAT_TOKEN }}
|
||||
repo-api-url: ${{ github.api_url }}/repos/${{ github.repository }}
|
||||
repository: ${{ github.repository }}
|
||||
missing-token-message: PAT_TOKEN is required because a tag created with GITHUB_TOKEN will not trigger publish.yml.
|
||||
|
||||
- name: Semantic release
|
||||
id: semantic_release
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
# Semantic Release 版本迁移归档(2026-04-26)
|
||||
|
||||
## 归档范围
|
||||
|
||||
- Phase 1 初始迁移结论
|
||||
- `SEMREL-RP-001` 到 `SEMREL-RP-003` 期间已稳定的 PR review 修复
|
||||
- active tracking 中已不需要继续占据默认恢复入口的历史验证明细
|
||||
|
||||
## 历史完成项
|
||||
|
||||
- 已确认当前版本入口为 `.github/workflows/auto-tag.yml`,现状始终执行 `PATCH + 1`
|
||||
- 已确认当前 `.github/workflows/publish.yml` 由 tag 触发,并负责 `.nupkg` 打包、发布和 GitHub Release
|
||||
- 已确认最新 tag 为 `v0.0.222`
|
||||
- 已确认 `v0.0.222..HEAD` 之间存在 `feat(...)` 提交,按目标规则首次 dry-run 预期版本应为 `v0.1.0`
|
||||
- 已新增 `.releaserc.json`,仅保留 `@semantic-release/commit-analyzer` 与
|
||||
`@semantic-release/release-notes-generator`,避免 `semantic-release` 直接创建 GitHub Release
|
||||
- 已将 `.releaserc.json` 的 `commit-analyzer` / `release-notes-generator` 同步切换到 `conventionalcommits`
|
||||
preset,并显式声明:
|
||||
- `breaking -> major`
|
||||
- `revert -> patch`
|
||||
- `feat -> minor`
|
||||
- `fix/perf/refactor -> patch`
|
||||
- `docs/test/chore/build/ci/style -> no release`
|
||||
- 已将 `.github/workflows/auto-tag.yml` 重写为:
|
||||
- `workflow_dispatch` 启动后总是先跑 `preview`
|
||||
- `preview` 只执行 dry-run,输出 `last_tag`、`next_version` 与 `next_tag`
|
||||
- `release` job 依赖 `preview` 输出,并通过 `release-approval` environment 暂停等待人工确认
|
||||
- 人工批准后,`release` 在同一 SHA 上执行真实打 tag,并把 preview / release 结果都写入 job summary
|
||||
- 已按上一轮 PR review 修复 `auto-tag.yml`:
|
||||
- 删除 preview job 中与 job 级 `if` 重复的运行时分支校验
|
||||
- 为 release job 增加 `needs.preview.result == 'success'` 守卫
|
||||
- 为 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`
|
||||
- `docs/test/chore/build/ci/style -> no release`
|
||||
- `BREAKING CHANGE` 或 `!` header -> major
|
||||
- 已移除基于 `workflow_run` 和 `[release ci]` 的自动发版门闸,后续版本预览与真实发版都由维护者手动触发
|
||||
- 已将 release 流程从“两次独立 workflow_dispatch”收敛为“同一次 run 里 preview + 审批 + release”的链路
|
||||
- 已精简 active trace,移除已废弃的 `release_mode=preview|release` 中间方案,保留当前有效恢复点
|
||||
|
||||
## 历史验证
|
||||
|
||||
- `git describe --tags --abbrev=0`
|
||||
- 结果:通过
|
||||
- 备注:当前最新 tag 为 `v0.0.222`
|
||||
- `git log --pretty=format:%h%x09%s v0.0.222..HEAD`
|
||||
- 结果:通过
|
||||
- 备注:最近版本窗口内存在多条 `feat(...)`,后续 dry-run 预期应提升 `minor`
|
||||
- `dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release -p:RestoreFallbackFolders=`
|
||||
- 结果:通过
|
||||
- 备注:`GFramework.Core.Abstractions` 与 `GFramework.Cqrs.Abstractions` Release 构建通过,`0 warning / 0 error`
|
||||
- `npx --yes semantic-release --dry-run --no-ci`
|
||||
- 结果:受阻
|
||||
- 备注:当前工作树的本地 tag 历史在 `git fetch --tags` 阶段出现 `would clobber existing tag` 冲突,不能直接作为 dry-run 环境
|
||||
- `git clone --branch main --single-branch git@github.com:GeWuYou/GFramework.git /tmp/gframework-semrel-dryrun`
|
||||
- 结果:通过
|
||||
- 备注:已建立干净临时克隆用于 dry-run 验证
|
||||
- `npx --yes semantic-release --dry-run --no-ci`(在 `/tmp/gframework-semrel-dryrun`)
|
||||
- 结果:通过
|
||||
- 备注:dry-run 成功识别 `v0.0.222` 为最新 release,并分析 `269` 个提交;按当前规则会提升到下一次 `minor` 发布,预期 tag 为 `v0.1.0`
|
||||
- `npx --yes -p semantic-release -p conventional-changelog-conventionalcommits@9.1.0 semantic-release --dry-run --no-ci`(在 `/tmp/gframework-semrel-dryrun`)
|
||||
- 结果:通过
|
||||
- 备注:成功加载 `@semantic-release/commit-analyzer` 与 `@semantic-release/release-notes-generator`,证明
|
||||
`conventionalcommits` preset 包可被解析;本次 dry-run 未继续出版本,是因为干净克隆的 `main` 已落后远端
|
||||
- `dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release -p:RestoreFallbackFolders=`(手动发版入口调整后复验)
|
||||
- 结果:通过
|
||||
- 备注:`0 warning / 0 error`
|
||||
- `dotnet build GFramework.sln -c Release`
|
||||
- 结果:通过
|
||||
- 备注:Release 构建通过,`639 warning / 0 error`;warning 为仓库既有基线;preview 鉴权修复后复验结果与基线一致
|
||||
@ -13,18 +13,18 @@
|
||||
|
||||
## 当前恢复点
|
||||
|
||||
- 恢复点编号:`SEMREL-RP-003`
|
||||
- 恢复点编号:`SEMREL-RP-004`
|
||||
- 当前阶段:`Phase 2`
|
||||
- 当前焦点:
|
||||
- 消除 `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 复验结果
|
||||
- 将 preview / release 的 PAT 校验收敛为同一个复用入口,避免后续修复在两段脚本间漂移
|
||||
- 在 PAT 校验阶段提前识别“仅有 read、没有 push”的 token,真正覆盖 `git push --dry-run` 的权限前提
|
||||
- 将 active tracking 中已稳定的历史完成项归档,恢复默认入口的可读性
|
||||
|
||||
### 已知风险
|
||||
|
||||
- `GITHUB_TOKEN` 推送 tag 不会再触发另一个 workflow,真实发布仍需要 `PAT_TOKEN`
|
||||
- `semantic-release` preview 虽然不会真实推送 tag,但仍会执行远端 `git push --dry-run` 权限探测;如果 preview 没有使用
|
||||
可写入仓库的令牌,仍然会先于版本分析阶段失败
|
||||
- `semantic-release` preview 虽然不会真实推送 tag,但仍会执行远端 `git push --dry-run` 权限探测;如果 PAT 仅具备
|
||||
read 权限、没有 `contents:write`,仍然会先于版本分析阶段失败
|
||||
- `semantic-release` 的版本判断完全依赖 Conventional Commits;不规范提交会直接影响版本计算
|
||||
- `cycjimmy/semantic-release-action@v6` 需要在 preview / release 两端都安装 `conventional-changelog-conventionalcommits`
|
||||
以保证 `conventionalcommits` preset 在 GitHub Actions 中可解析
|
||||
@ -32,79 +32,24 @@
|
||||
|
||||
## 已完成
|
||||
|
||||
- 已确认当前版本入口为 `.github/workflows/auto-tag.yml`,现状始终执行 `PATCH + 1`
|
||||
- 已确认当前 `.github/workflows/publish.yml` 由 tag 触发,并负责 `.nupkg` 打包、发布和 GitHub Release
|
||||
- 已确认最新 tag 为 `v0.0.222`
|
||||
- 已确认 `v0.0.222..HEAD` 之间存在 `feat(...)` 提交,按目标规则首次 dry-run 预期版本应为 `v0.1.0`
|
||||
- 已新增 `.releaserc.json`,仅保留 `@semantic-release/commit-analyzer` 与
|
||||
`@semantic-release/release-notes-generator`,避免 `semantic-release` 直接创建 GitHub Release
|
||||
- 已将 `.releaserc.json` 的 `commit-analyzer` / `release-notes-generator` 同步切换到 `conventionalcommits`
|
||||
preset,并显式声明:
|
||||
- `breaking -> major`
|
||||
- `revert -> patch`
|
||||
- `feat -> minor`
|
||||
- `fix/perf/refactor -> patch`
|
||||
- `docs/test/chore/build/ci/style -> no release`
|
||||
- 已将 `.github/workflows/auto-tag.yml` 重写为:
|
||||
- `workflow_dispatch` 启动后总是先跑 `preview`
|
||||
- `preview` 只执行 dry-run,输出 `last_tag`、`next_version` 与 `next_tag`
|
||||
- `release` job 依赖 `preview` 输出,并通过 `release-approval` environment 暂停等待人工确认
|
||||
- 人工批准后,`release` 在同一 SHA 上执行真实打 tag,并把 preview / release 结果都写入 job summary
|
||||
- 已按 PR review 修复 `auto-tag.yml`:
|
||||
- 删除 preview job 中与 job 级 `if` 重复的运行时分支校验
|
||||
- 为 release job 增加 `needs.preview.result == 'success'` 守卫
|
||||
- 为 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`
|
||||
- `docs/test/chore/build/ci/style -> no release`
|
||||
- `BREAKING CHANGE` 或 `!` header -> major
|
||||
- 已移除基于 `workflow_run` 和 `[release ci]` 的自动发版门闸,后续版本预览与真实发版都由维护者手动触发
|
||||
- 已将 release 流程从“两次独立 workflow_dispatch”收敛为“同一次 run 里 preview + 审批 + release”的链路
|
||||
- 已精简 active trace,移除已废弃的 `release_mode=preview|release` 中间方案,保留当前有效恢复点
|
||||
- 历史迁移结论与 `SEMREL-RP-001` 到 `SEMREL-RP-003` 的稳定完成项已归档到
|
||||
`ai-plan/public/semantic-release-versioning/archive/todos/semantic-release-versioning-2026-04-26.md`
|
||||
- 已将 preview / release 两段重复的 PAT 校验提取到 `.github/actions/validate-pat/action.yml`
|
||||
- 已在 PAT 校验中补充 `permissions.push` 断言,避免 read-only token 通过 API 探活却在
|
||||
`semantic-release` 的 `git push --dry-run` 阶段才失败
|
||||
- 已为 PAT 校验的 `mktemp` 文件补充 `trap` 清理,避免异常退出时遗留临时文件路径干扰日志
|
||||
- 已同步更新 active trace 到 `SEMREL-RP-004`,记录本轮 PR review 收敛结果
|
||||
|
||||
## 验证
|
||||
|
||||
- `git describe --tags --abbrev=0`
|
||||
- 结果:通过
|
||||
- 备注:当前最新 tag 为 `v0.0.222`
|
||||
- `git log --pretty=format:%h%x09%s v0.0.222..HEAD`
|
||||
- 结果:通过
|
||||
- 备注:最近版本窗口内存在多条 `feat(...)`,后续 dry-run 预期应提升 `minor`
|
||||
- `dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release -p:RestoreFallbackFolders=`
|
||||
- 结果:通过
|
||||
- 备注:`GFramework.Core.Abstractions` 与 `GFramework.Cqrs.Abstractions` Release 构建通过,`0 warning / 0 error`
|
||||
- `npx --yes semantic-release --dry-run --no-ci`
|
||||
- 结果:受阻
|
||||
- 备注:当前工作树的本地 tag 历史在 `git fetch --tags` 阶段出现 `would clobber existing tag` 冲突,不能直接作为 dry-run 环境
|
||||
- `git clone --branch main --single-branch git@github.com:GeWuYou/GFramework.git /tmp/gframework-semrel-dryrun`
|
||||
- 结果:通过
|
||||
- 备注:已建立干净临时克隆用于 dry-run 验证
|
||||
- `npx --yes semantic-release --dry-run --no-ci`(在 `/tmp/gframework-semrel-dryrun`)
|
||||
- 结果:通过
|
||||
- 备注:dry-run 成功识别 `v0.0.222` 为最新 release,并分析 `269` 个提交;按当前规则会提升到下一次 `minor` 发布,预期 tag 为 `v0.1.0`
|
||||
- `npx --yes -p semantic-release -p conventional-changelog-conventionalcommits@9.1.0 semantic-release --dry-run --no-ci`(在 `/tmp/gframework-semrel-dryrun`)
|
||||
- 结果:通过
|
||||
- 备注:成功加载 `@semantic-release/commit-analyzer` 与 `@semantic-release/release-notes-generator`,证明
|
||||
`conventionalcommits` preset 包可被解析;本次 dry-run 未继续出版本,是因为干净克隆的 `main` 已落后远端
|
||||
- `dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release -p:RestoreFallbackFolders=`(手动发版入口调整后复验)
|
||||
- 结果:通过
|
||||
- 备注:`0 warning / 0 error`
|
||||
- `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` 变更
|
||||
- 备注:Release 构建通过,`639 warning / 0 error`;warning 为仓库既有基线,preview 鉴权修复后与本轮 PAT 校验收敛后复验结果一致
|
||||
- 更早阶段的 dry-run / tag /抽象项目验证已归档到
|
||||
`ai-plan/public/semantic-release-versioning/archive/todos/semantic-release-versioning-2026-04-26.md`
|
||||
|
||||
## 下一步
|
||||
|
||||
1. 手动重跑 `Semantic Release Version and Tag` 的 preview job,确认不再出现 `git push --dry-run ... 403`
|
||||
2. 若 preview 通过,再复核当前 PR review 的 open threads 是否只剩等待 push 的已修复项
|
||||
3. 将本轮修复提交到当前分支,等待 GitHub reviewer 重新评估
|
||||
1. 手动重跑 `Semantic Release Version and Tag` 的 preview job,确认 read-only PAT 会在校验步骤提前失败、可写 PAT 不再进入 `git push --dry-run ... 403`
|
||||
2. 推送本轮修复后重新抓取 PR review,确认 CodeRabbit / Greptile 的 open threads 已转为过时或可关闭
|
||||
3. 如 CI 仍报告权限边界问题,再决定是否将 PAT 校验升级为更贴近真实链路的远端 git 探测
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
## 2026-04-26
|
||||
|
||||
### 当前恢复点(SEMREL-RP-003)
|
||||
### 当前恢复点(SEMREL-RP-004)
|
||||
|
||||
- 当前链路:
|
||||
- `workflow_dispatch` 手动启动
|
||||
@ -17,7 +17,8 @@
|
||||
- `breaking -> major`
|
||||
- 当前 workflow 加固:
|
||||
- `release` 额外要求 `needs.preview.result == 'success'`
|
||||
- `PAT_TOKEN` 在真实 release 前通过 GitHub API 做存活性校验
|
||||
- `PAT_TOKEN` 通过复用的 composite action 统一校验
|
||||
- GitHub API 校验额外断言 `.permissions.push == true`,避免 read-only PAT 混过 preview
|
||||
- preview / release summary 会展示 snapshot 语义与生成的 release notes
|
||||
- `preview` 改为先校验并使用 `PAT_TOKEN`,避免 `github-actions[bot]` 在 dry-run 的远端 push 权限探测中触发 403
|
||||
|
||||
@ -29,9 +30,12 @@
|
||||
- preview 与 release 共用 `PAT_TOKEN`:
|
||||
- `semantic-release` dry-run 仍会执行 `git push --dry-run`
|
||||
- preview 如果继续使用 `${{ github.token }}`,会先被 `github-actions[bot]` 的仓库写权限拦住,日志不再具有可读性
|
||||
- API 探活必须覆盖 push 权限:
|
||||
- 单纯 `GET /repos/{owner}/{repo}` 的 `200` 只能证明 read access
|
||||
- 本轮直接读取响应体里的 `permissions.push`,让 preview 在更接近真实失败原因的位置终止
|
||||
- 不保留已废弃的 `release_mode=preview|release` 中间方案:
|
||||
- active trace 只保留当前有效链路
|
||||
- 历史演进以 tracking 文档的已完成项为准
|
||||
- 历史演进以 tracking 归档文件为准,active tracking 仅保留当前恢复入口
|
||||
|
||||
### 验证结论
|
||||
|
||||
@ -40,10 +44,10 @@
|
||||
- 本次 dry-run 未继续出版本,因为干净克隆的 `main` 已落后远端
|
||||
2. `dotnet build GFramework.sln -c Release`
|
||||
- 通过,`639 warning / 0 error`
|
||||
- warning 为仓库既有基线,本轮未新增关联 warning
|
||||
- warning 为仓库既有基线,本轮 workflow / ai-plan 调整未新增关联 warning
|
||||
|
||||
### 下一步
|
||||
|
||||
1. 重跑 `auto-tag.yml` 的 preview,确认 `EGITNOPERMISSION` 已消失
|
||||
2. 复查当前 PR 的 open review threads 是否只剩等待 push 的已修复项
|
||||
1. 重跑 `auto-tag.yml` 的 preview,确认 read-only PAT 会在校验步骤提前失败、可写 PAT 不再落到 `EGITNOPERMISSION`
|
||||
2. 复查当前 PR 的 open review threads 是否已与本地修复对齐
|
||||
3. 创建提交并推送当前分支
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user