mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-06 16:16:44 +08:00
build(release): 迁移语义化版本打标流程
- 新增 semantic-release 配置并固定 release rules 与 v 前缀 tag 格式 - 重构 auto-tag workflow 为 main 上的真实打标与 workflow_dispatch dry-run 双入口 - 保留现有 publish workflow 并补充 ai-plan 跟踪与验证记录
This commit is contained in:
parent
0c7552e629
commit
b194238385
100
.github/workflows/auto-tag.yml
vendored
100
.github/workflows/auto-tag.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: Auto Increment Version and Tag
|
||||
name: Semantic Release Version and Tag
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
@ -9,28 +9,17 @@ on:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
concurrency:
|
||||
group: auto-tag-main
|
||||
group: semantic-release-main
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
auto-tag:
|
||||
dry-run:
|
||||
if: >
|
||||
(
|
||||
github.event_name == 'workflow_run' &&
|
||||
github.event.workflow_run.conclusion == 'success' &&
|
||||
contains(github.event.workflow_run.head_commit.message, '[release ci]')
|
||||
)
|
||||
||
|
||||
(
|
||||
github.event_name == 'workflow_dispatch' &&
|
||||
github.ref == 'refs/heads/main'
|
||||
)
|
||||
|
||||
github.event_name == 'workflow_dispatch' &&
|
||||
github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
outputs:
|
||||
tagged: ${{ steps.create_tag.outcome == 'success' }}
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
@ -38,29 +27,64 @@ jobs:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Get next version
|
||||
id: version
|
||||
run: |
|
||||
LATEST_TAG=$(git tag --list "v*" --sort=-v:refname | head -n 1)
|
||||
LATEST_TAG=${LATEST_TAG:-v0.0.0}
|
||||
VERSION=${LATEST_TAG#v}
|
||||
IFS=. read MAJOR MINOR PATCH <<< "$VERSION"
|
||||
PATCH=$((PATCH+1))
|
||||
echo "new_tag=v$MAJOR.$MINOR.$PATCH" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create tag
|
||||
# 手动触发仅用于验证 semantic-release 的版本推导结果,不会真正推送 tag。
|
||||
- name: Semantic release dry-run
|
||||
id: semantic_release
|
||||
uses: cycjimmy/semantic-release-action@v6
|
||||
with:
|
||||
dry_run: true
|
||||
ci: false
|
||||
env:
|
||||
PAT: ${{ secrets.PAT_TOKEN }}
|
||||
TAG: ${{ steps.version.outputs.new_tag }}
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
- name: Show dry-run result
|
||||
run: |
|
||||
set -e
|
||||
git config user.name "GitHub Action"
|
||||
git config user.email "action@github.com"
|
||||
echo "published=${{ steps.semantic_release.outputs.new_release_published }}"
|
||||
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 }}"
|
||||
|
||||
if git show-ref --tags --verify --quiet "refs/tags/$TAG"; then
|
||||
echo "Tag $TAG already exists, skipping"
|
||||
exit 0
|
||||
release-tag:
|
||||
if: >
|
||||
github.event_name == 'workflow_run' &&
|
||||
github.event.workflow_run.conclusion == 'success' &&
|
||||
github.event.workflow_run.head_branch == 'main' &&
|
||||
contains(github.event.workflow_run.head_commit.message, '[release ci]')
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
ref: ${{ github.event.workflow_run.head_branch }}
|
||||
|
||||
- name: Validate PAT token
|
||||
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
|
||||
env:
|
||||
PAT_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||
|
||||
git tag -a "$TAG" -m "Auto tag $TAG"
|
||||
git push "https://x-access-token:${PAT}@github.com/${{ github.repository }}.git" "$TAG"
|
||||
# 真实 workflow_run 负责按 Conventional Commits 计算版本并推送 tag。
|
||||
- name: Semantic release
|
||||
id: semantic_release
|
||||
uses: cycjimmy/semantic-release-action@v6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||
|
||||
- name: Show release result
|
||||
env:
|
||||
PUBLISHED: ${{ steps.semantic_release.outputs.new_release_published }}
|
||||
LAST_TAG: ${{ steps.semantic_release.outputs.last_release_git_tag }}
|
||||
NEXT_VERSION: ${{ steps.semantic_release.outputs.new_release_version }}
|
||||
NEXT_TAG: ${{ steps.semantic_release.outputs.new_release_git_tag }}
|
||||
run: |
|
||||
echo "published=${PUBLISHED}"
|
||||
echo "last_tag=${LAST_TAG}"
|
||||
echo "next_version=${NEXT_VERSION}"
|
||||
echo "next_tag=${NEXT_TAG}"
|
||||
|
||||
72
.releaserc.json
Normal file
72
.releaserc.json
Normal file
@ -0,0 +1,72 @@
|
||||
{
|
||||
"branches": [
|
||||
"main"
|
||||
],
|
||||
"tagFormat": "v${version}",
|
||||
"plugins": [
|
||||
[
|
||||
"@semantic-release/commit-analyzer",
|
||||
{
|
||||
"releaseRules": [
|
||||
{
|
||||
"type": "feat",
|
||||
"release": "minor"
|
||||
},
|
||||
{
|
||||
"type": "fix",
|
||||
"release": "patch"
|
||||
},
|
||||
{
|
||||
"type": "perf",
|
||||
"release": "patch"
|
||||
},
|
||||
{
|
||||
"type": "refactor",
|
||||
"release": "patch"
|
||||
},
|
||||
{
|
||||
"type": "docs",
|
||||
"release": false
|
||||
},
|
||||
{
|
||||
"type": "test",
|
||||
"release": false
|
||||
},
|
||||
{
|
||||
"type": "chore",
|
||||
"release": false
|
||||
},
|
||||
{
|
||||
"type": "build",
|
||||
"release": false
|
||||
},
|
||||
{
|
||||
"type": "ci",
|
||||
"release": false
|
||||
},
|
||||
{
|
||||
"type": "style",
|
||||
"release": false
|
||||
}
|
||||
],
|
||||
"parserOpts": {
|
||||
"noteKeywords": [
|
||||
"BREAKING CHANGE",
|
||||
"BREAKING CHANGES"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
"@semantic-release/release-notes-generator",
|
||||
{
|
||||
"parserOpts": {
|
||||
"noteKeywords": [
|
||||
"BREAKING CHANGE",
|
||||
"BREAKING CHANGES"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -43,6 +43,10 @@ help the current worktree land on the right recovery documents without scanning
|
||||
- Purpose: continue the data repository persistence hardening plus the settings / serialization follow-up backlog.
|
||||
- Tracking: `ai-plan/public/data-repository-persistence/todos/data-repository-persistence-tracking.md`
|
||||
- Trace: `ai-plan/public/data-repository-persistence/traces/data-repository-persistence-trace.md`
|
||||
- `semantic-release-versioning`
|
||||
- Purpose: migrate release version calculation from fixed patch bumps to semantic-release while keeping the existing tag-driven NuGet publish flow.
|
||||
- Tracking: `ai-plan/public/semantic-release-versioning/todos/semantic-release-versioning-tracking.md`
|
||||
- Trace: `ai-plan/public/semantic-release-versioning/traces/semantic-release-versioning-trace.md`
|
||||
|
||||
## Worktree To Active Topic Map
|
||||
|
||||
@ -63,6 +67,9 @@ help the current worktree land on the right recovery documents without scanning
|
||||
- Branch: `feat/data-repository-persistence`
|
||||
- Worktree hint: `GFramework-data-repository-persistence`
|
||||
- Priority 1: `data-repository-persistence`
|
||||
- Branch: `feat/semantic-release-versioning`
|
||||
- Worktree hint: `GFramework`
|
||||
- Priority 1: `semantic-release-versioning`
|
||||
- Branch: `docs/sdk-update-documentation`
|
||||
- Worktree hint: `GFramework-update-documentation`
|
||||
- Priority 1: `documentation-full-coverage-governance`
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
# Semantic Release 版本迁移跟踪
|
||||
|
||||
## 目标
|
||||
|
||||
将版本管理从固定 `patch + 1` 的自动打 tag 迁移到 `semantic-release`,同时保留现有 `.github/workflows/publish.yml`
|
||||
的 tag 触发打包、NuGet 发布、GitHub Packages 发布和 GitHub Release 流程。
|
||||
|
||||
- 用 `cycjimmy/semantic-release-action` 替换 `auto-tag.yml` 的版本判断和打 tag 逻辑
|
||||
- 保留 `publish.yml` 的现有发布实现,不重写 NuGet 流程
|
||||
- 避免 `semantic-release` 与 `publish.yml` 重复创建 GitHub Release
|
||||
- 将版本规则固定为 `feat -> minor`、`fix/perf/refactor -> patch`、`BREAKING CHANGE` 或 `! -> major`
|
||||
- 为手动 `workflow_dispatch` 保留 dry-run 验证入口,先验证最近提交会算出什么版本
|
||||
|
||||
## 当前恢复点
|
||||
|
||||
- 恢复点编号:`SEMREL-RP-001`
|
||||
- 当前阶段:`Phase 1`
|
||||
- 当前焦点:
|
||||
- 增加 `.releaserc.json`,仅启用版本分析与 release notes 生成,不启用 GitHub Release 发布插件
|
||||
- 将 `auto-tag.yml` 改成 `workflow_run` 真正打 tag、`workflow_dispatch` 只做 dry-run 的双入口
|
||||
- 明确 `PAT_TOKEN` 与 `GITHUB_TOKEN` 的职责边界,确保 tag 继续触发 `publish.yml`
|
||||
|
||||
### 已知风险
|
||||
|
||||
- `GITHUB_TOKEN` 推送 tag 不会再触发另一个 workflow,真实发布仍需要 `PAT_TOKEN`
|
||||
- `semantic-release` 的版本判断完全依赖 Conventional Commits;不规范提交会直接影响版本计算
|
||||
- 当前仓库本地 `dotnet clean/build` 仍受 WSL fallback NuGet 路径影响,验证时需要继续采用已知可用的直接构建命令
|
||||
|
||||
## 已完成
|
||||
|
||||
- 已确认当前版本入口为 `.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
|
||||
- 已将 `.github/workflows/auto-tag.yml` 重写为:
|
||||
- `workflow_run` 在 `main` 上、CI 成功且提交消息包含 `[release ci]` 时执行真实打 tag
|
||||
- `workflow_dispatch` 只执行 dry-run,输出 `last_tag`、`next_version` 与 `next_tag`
|
||||
- 已明确真实打 tag 仍使用 `PAT_TOKEN`,因为 `GITHUB_TOKEN` 推送的 tag 不会继续触发 `publish.yml`
|
||||
|
||||
## 验证
|
||||
|
||||
- `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`
|
||||
|
||||
## 下一步
|
||||
|
||||
1. 复核 `workflow_dispatch` dry-run 输出格式是否还需要额外收窄或增加说明
|
||||
2. 评估是否要把 `workflow_run` 的 `[release ci]` 门闸改成更显式的 PR label 或 manual approval
|
||||
3. 若本轮验证通过,按仓库要求创建提交并等待你审阅发版流程细节
|
||||
@ -0,0 +1,39 @@
|
||||
# Semantic Release 版本迁移追踪
|
||||
|
||||
## 2026-04-26
|
||||
|
||||
### 阶段:方案落地准备(SEMREL-RP-001)
|
||||
|
||||
- 读取当前 `auto-tag.yml` 与 `publish.yml`,确认最小侵入改法应只替换版本判断与打 tag,保留 tag 触发发布链
|
||||
- 核对最近 tag 与提交历史:
|
||||
- 最新 tag 为 `v0.0.222`
|
||||
- `v0.0.222..HEAD` 含多条 `feat(...)`,按目标规则首次 dry-run 预期结果为 `v0.1.0`
|
||||
- 补建本主题的 active tracking / trace 入口,并在 `ai-plan/public/README.md` 中为
|
||||
`feat/semantic-release-versioning` 建立 worktree 映射
|
||||
|
||||
### 阶段:配置落地与验证(SEMREL-RP-001)
|
||||
|
||||
- 新增 `.releaserc.json`,显式固定:
|
||||
- `feat -> minor`
|
||||
- `fix/perf/refactor -> patch`
|
||||
- `docs/test/chore/build/ci/style -> no release`
|
||||
- `BREAKING CHANGE` / `BREAKING CHANGES` 作为 major 信号
|
||||
- 重写 `auto-tag.yml`:
|
||||
- 保留 `workflow_run` 监听 `CI - Build & Test`
|
||||
- `workflow_dispatch` 变为 dry-run 入口
|
||||
- 真实打 tag 改由 `semantic-release-action` 处理,并要求 `PAT_TOKEN`
|
||||
- 完成最小构建验证:
|
||||
- `dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release -p:RestoreFallbackFolders=`
|
||||
- 结果:通过,`0 warning / 0 error`
|
||||
- 直接在当前工作树执行 `semantic-release --dry-run` 时命中本地 tag 抓取冲突:
|
||||
- `git fetch --tags ... would clobber existing tag`
|
||||
- 结论:当前工作树不适合作为 dry-run 验证环境
|
||||
- 改用干净临时克隆 `/tmp/gframework-semrel-dryrun` 再跑 dry-run:
|
||||
- 成功识别 `v0.0.222` 为最新 release
|
||||
- 成功分析 `269` 个提交
|
||||
- 按当前规则得出下一次应为 `minor` 发布,预期版本窗口从 `0.0.222` 提升到 `0.1.0`
|
||||
|
||||
### 下一步
|
||||
|
||||
1. 复核变更 diff 并创建提交
|
||||
2. 向用户说明新的发版链路与可优化点
|
||||
Loading…
x
Reference in New Issue
Block a user