mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-07 00:39:00 +08:00
Merge pull request #294 from GeWuYou/feat/semantic-release-versioning
ci(release): 修复 semantic-release 预览鉴权
This commit is contained in:
commit
617e0bffd2
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
|
||||||
51
.github/workflows/auto-tag.yml
vendored
51
.github/workflows/auto-tag.yml
vendored
@ -27,6 +27,16 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
ref: ${{ github.sha }}
|
ref: ${{ github.sha }}
|
||||||
|
|
||||||
|
# semantic-release 在 dry-run 中仍会执行一次 git push --dry-run 权限探测。
|
||||||
|
# 这里提前要求与正式 release 相同的 PAT,避免 github-actions[bot] 因只读上下文触发误导性的 403。
|
||||||
|
- name: Validate PAT token
|
||||||
|
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 生成待发布版本预览。
|
# preview 始终先运行,用于给当前 SHA 生成待发布版本预览。
|
||||||
- name: Semantic release preview
|
- name: Semantic release preview
|
||||||
id: semantic_release
|
id: semantic_release
|
||||||
@ -37,7 +47,7 @@ jobs:
|
|||||||
extra_plugins: |
|
extra_plugins: |
|
||||||
conventional-changelog-conventionalcommits@9.1.0
|
conventional-changelog-conventionalcommits@9.1.0
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||||
|
|
||||||
- name: Show preview result
|
- name: Show preview result
|
||||||
run: |
|
run: |
|
||||||
@ -59,6 +69,7 @@ jobs:
|
|||||||
echo "- Last tag: \`${{ steps.semantic_release.outputs.last_release_git_tag }}\`"
|
echo "- Last tag: \`${{ steps.semantic_release.outputs.last_release_git_tag }}\`"
|
||||||
echo "- Next version: \`${{ steps.semantic_release.outputs.new_release_version }}\`"
|
echo "- Next version: \`${{ steps.semantic_release.outputs.new_release_version }}\`"
|
||||||
echo "- Next tag: \`${{ steps.semantic_release.outputs.new_release_git_tag }}\`"
|
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."
|
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
|
if [ "${RELEASE_PUBLISHED}" = "true" ] && [ -n "${RELEASE_NOTES}" ]; then
|
||||||
echo
|
echo
|
||||||
@ -93,38 +104,12 @@ jobs:
|
|||||||
ref: ${{ github.sha }}
|
ref: ${{ github.sha }}
|
||||||
|
|
||||||
- name: Validate PAT token
|
- name: Validate PAT token
|
||||||
env:
|
uses: ./.github/actions/validate-pat
|
||||||
PAT_TOKEN: ${{ secrets.PAT_TOKEN }}
|
with:
|
||||||
REPO_API_URL: ${{ github.api_url }}/repos/${{ github.repository }}
|
pat-token: ${{ secrets.PAT_TOKEN }}
|
||||||
run: |
|
repo-api-url: ${{ github.api_url }}/repos/${{ github.repository }}
|
||||||
if [ -z "${PAT_TOKEN}" ]; then
|
repository: ${{ github.repository }}
|
||||||
echo "::error::PAT_TOKEN is required because a tag created with GITHUB_TOKEN will not trigger publish.yml."
|
missing-token-message: 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
|
|
||||||
|
|
||||||
- name: Semantic release
|
- name: Semantic release
|
||||||
id: 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,16 +13,18 @@
|
|||||||
|
|
||||||
## 当前恢复点
|
## 当前恢复点
|
||||||
|
|
||||||
- 恢复点编号:`SEMREL-RP-002`
|
- 恢复点编号:`SEMREL-RP-004`
|
||||||
- 当前阶段:`Phase 2`
|
- 当前阶段:`Phase 2`
|
||||||
- 当前焦点:
|
- 当前焦点:
|
||||||
- 让 `.releaserc.json` 对 `BREAKING CHANGE` 与 `feat!:` / `feat(scope)!:` 的 `major` 语义与文档保持一致
|
- 将 preview / release 的 PAT 校验收敛为同一个复用入口,避免后续修复在两段脚本间漂移
|
||||||
- 将 `auto-tag.yml` 的 preview / release 输出与 PR review 建议对齐,避免 release notes 被静默丢弃
|
- 在 PAT 校验阶段提前识别“仅有 read、没有 push”的 token,真正覆盖 `git push --dry-run` 的权限前提
|
||||||
- 提前校验 `PAT_TOKEN` 的真实可用性,并把当前 PR review 修复结果同步回 `AGENTS.md` 与 active trace
|
- 将 active tracking 中已稳定的历史完成项归档,恢复默认入口的可读性
|
||||||
|
|
||||||
### 已知风险
|
### 已知风险
|
||||||
|
|
||||||
- `GITHUB_TOKEN` 推送 tag 不会再触发另一个 workflow,真实发布仍需要 `PAT_TOKEN`
|
- `GITHUB_TOKEN` 推送 tag 不会再触发另一个 workflow,真实发布仍需要 `PAT_TOKEN`
|
||||||
|
- `semantic-release` preview 虽然不会真实推送 tag,但仍会执行远端 `git push --dry-run` 权限探测;如果 PAT 仅具备
|
||||||
|
read 权限、没有 `contents:write`,仍然会先于版本分析阶段失败
|
||||||
- `semantic-release` 的版本判断完全依赖 Conventional Commits;不规范提交会直接影响版本计算
|
- `semantic-release` 的版本判断完全依赖 Conventional Commits;不规范提交会直接影响版本计算
|
||||||
- `cycjimmy/semantic-release-action@v6` 需要在 preview / release 两端都安装 `conventional-changelog-conventionalcommits`
|
- `cycjimmy/semantic-release-action@v6` 需要在 preview / release 两端都安装 `conventional-changelog-conventionalcommits`
|
||||||
以保证 `conventionalcommits` preset 在 GitHub Actions 中可解析
|
以保证 `conventionalcommits` preset 在 GitHub Actions 中可解析
|
||||||
@ -30,72 +32,24 @@
|
|||||||
|
|
||||||
## 已完成
|
## 已完成
|
||||||
|
|
||||||
- 已确认当前版本入口为 `.github/workflows/auto-tag.yml`,现状始终执行 `PATCH + 1`
|
- 历史迁移结论与 `SEMREL-RP-001` 到 `SEMREL-RP-003` 的稳定完成项已归档到
|
||||||
- 已确认当前 `.github/workflows/publish.yml` 由 tag 触发,并负责 `.nupkg` 打包、发布和 GitHub Release
|
`ai-plan/public/semantic-release-versioning/archive/todos/semantic-release-versioning-2026-04-26.md`
|
||||||
- 已确认最新 tag 为 `v0.0.222`
|
- 已将 preview / release 两段重复的 PAT 校验提取到 `.github/actions/validate-pat/action.yml`
|
||||||
- 已确认 `v0.0.222..HEAD` 之间存在 `feat(...)` 提交,按目标规则首次 dry-run 预期版本应为 `v0.1.0`
|
- 已在 PAT 校验中补充 `permissions.push` 断言,避免 read-only token 通过 API 探活却在
|
||||||
- 已新增 `.releaserc.json`,仅保留 `@semantic-release/commit-analyzer` 与
|
`semantic-release` 的 `git push --dry-run` 阶段才失败
|
||||||
`@semantic-release/release-notes-generator`,避免 `semantic-release` 直接创建 GitHub Release
|
- 已为 PAT 校验的 `mktemp` 文件补充 `trap` 清理,避免异常退出时遗留临时文件路径干扰日志
|
||||||
- 已将 `.releaserc.json` 的 `commit-analyzer` / `release-notes-generator` 同步切换到 `conventionalcommits`
|
- 已同步更新 active trace 到 `SEMREL-RP-004`,记录本轮 PR review 收敛结果
|
||||||
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
|
|
||||||
- 已明确真实打 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`
|
- `dotnet build GFramework.sln -c Release`
|
||||||
- 结果:通过
|
- 结果:通过
|
||||||
- 备注:Release 构建完成,`639 warning / 0 error`;warning 为仓库既有基线,与本轮 workflow / doc 改动无新增关联项
|
- 备注: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. 复核当前 PR review 的 open threads 是否只剩等待 push 的已修复项
|
1. 手动重跑 `Semantic Release Version and Tag` 的 preview job,确认 read-only PAT 会在校验步骤提前失败、可写 PAT 不再进入 `git push --dry-run ... 403`
|
||||||
2. 将本轮修复提交到当前分支,等待 GitHub reviewer 重新评估
|
2. 推送本轮修复后重新抓取 PR review,确认 CodeRabbit / Greptile 的 open threads 已转为过时或可关闭
|
||||||
3. 若后续需要,再在真实仓库主线最新快照上复验一次 `semantic-release` dry-run 结果展示
|
3. 如 CI 仍报告权限边界问题,再决定是否将 PAT 校验升级为更贴近真实链路的远端 git 探测
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## 2026-04-26
|
## 2026-04-26
|
||||||
|
|
||||||
### 当前恢复点(SEMREL-RP-002)
|
### 当前恢复点(SEMREL-RP-004)
|
||||||
|
|
||||||
- 当前链路:
|
- 当前链路:
|
||||||
- `workflow_dispatch` 手动启动
|
- `workflow_dispatch` 手动启动
|
||||||
@ -17,17 +17,25 @@
|
|||||||
- `breaking -> major`
|
- `breaking -> major`
|
||||||
- 当前 workflow 加固:
|
- 当前 workflow 加固:
|
||||||
- `release` 额外要求 `needs.preview.result == 'success'`
|
- `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 / release summary 会展示 snapshot 语义与生成的 release notes
|
||||||
|
- `preview` 改为先校验并使用 `PAT_TOKEN`,避免 `github-actions[bot]` 在 dry-run 的远端 push 权限探测中触发 403
|
||||||
|
|
||||||
### 本轮关键决策
|
### 本轮关键决策
|
||||||
|
|
||||||
- 保留 `@semantic-release/release-notes-generator`,但不再让它白跑:
|
- 保留 `@semantic-release/release-notes-generator`,但不再让它白跑:
|
||||||
- 继续生成 notes
|
- 继续生成 notes
|
||||||
- 将 notes 写入 GitHub Actions summary
|
- 将 notes 写入 GitHub Actions summary
|
||||||
|
- 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` 中间方案:
|
- 不保留已废弃的 `release_mode=preview|release` 中间方案:
|
||||||
- active trace 只保留当前有效链路
|
- active trace 只保留当前有效链路
|
||||||
- 历史演进以 tracking 文档的已完成项为准
|
- 历史演进以 tracking 归档文件为准,active tracking 仅保留当前恢复入口
|
||||||
|
|
||||||
### 验证结论
|
### 验证结论
|
||||||
|
|
||||||
@ -36,9 +44,10 @@
|
|||||||
- 本次 dry-run 未继续出版本,因为干净克隆的 `main` 已落后远端
|
- 本次 dry-run 未继续出版本,因为干净克隆的 `main` 已落后远端
|
||||||
2. `dotnet build GFramework.sln -c Release`
|
2. `dotnet build GFramework.sln -c Release`
|
||||||
- 通过,`639 warning / 0 error`
|
- 通过,`639 warning / 0 error`
|
||||||
- warning 为仓库既有基线,本轮未新增关联 warning
|
- warning 为仓库既有基线,本轮 workflow / ai-plan 调整未新增关联 warning
|
||||||
|
|
||||||
### 下一步
|
### 下一步
|
||||||
|
|
||||||
1. 复查当前 PR 的 open review threads 是否只剩等待 push 的已修复项
|
1. 重跑 `auto-tag.yml` 的 preview,确认 read-only PAT 会在校验步骤提前失败、可写 PAT 不再落到 `EGITNOPERMISSION`
|
||||||
2. 创建提交并推送当前分支
|
2. 复查当前 PR 的 open review threads 是否已与本地修复对齐
|
||||||
|
3. 创建提交并推送当前分支
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user