mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-12 05:08:58 +08:00
build(release): 收紧手动发版入口与提交语义约束
- 重构 semantic-release workflow 为 preview 与 release 两种手动触发模式 - 更新 AGENTS 中的 Conventional Commit 规则并禁止 feat(docs) 这类文档提交类型 - 补充 semantic-release 迁移跟踪与二次验证记录
This commit is contained in:
parent
b194238385
commit
d7ddff9f53
103
.github/workflows/auto-tag.yml
vendored
103
.github/workflows/auto-tag.yml
vendored
@ -1,56 +1,26 @@
|
|||||||
name: Semantic Release Version and Tag
|
name: Semantic Release Version and Tag
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_run:
|
|
||||||
workflows: ["CI - Build & Test"]
|
|
||||||
types:
|
|
||||||
- completed
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
release_mode:
|
||||||
|
description: Choose preview to inspect the next version, or release to create and push the next tag.
|
||||||
|
required: true
|
||||||
|
default: preview
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- preview
|
||||||
|
- release
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: semantic-release-main
|
group: semantic-release-main
|
||||||
cancel-in-progress: false
|
cancel-in-progress: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
dry-run:
|
semantic-release:
|
||||||
if: >
|
if: >
|
||||||
github.event_name == 'workflow_dispatch' &&
|
|
||||||
github.ref == 'refs/heads/main'
|
github.ref == 'refs/heads/main'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
# 手动触发仅用于验证 semantic-release 的版本推导结果,不会真正推送 tag。
|
|
||||||
- name: Semantic release dry-run
|
|
||||||
id: semantic_release
|
|
||||||
uses: cycjimmy/semantic-release-action@v6
|
|
||||||
with:
|
|
||||||
dry_run: true
|
|
||||||
ci: false
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
|
||||||
|
|
||||||
- name: Show dry-run result
|
|
||||||
run: |
|
|
||||||
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 }}"
|
|
||||||
|
|
||||||
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:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
@ -59,9 +29,16 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
ref: ${{ github.event.workflow_run.head_branch }}
|
|
||||||
|
- name: Validate release branch
|
||||||
|
run: |
|
||||||
|
if [ "${GITHUB_REF}" != "refs/heads/main" ]; then
|
||||||
|
echo "::error::Semantic Release Version and Tag only supports workflow_dispatch on main."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Validate PAT token
|
- name: Validate PAT token
|
||||||
|
if: inputs.release_mode == 'release'
|
||||||
run: |
|
run: |
|
||||||
if [ -z "${PAT_TOKEN}" ]; then
|
if [ -z "${PAT_TOKEN}" ]; then
|
||||||
echo "::error::PAT_TOKEN is required because a tag created with GITHUB_TOKEN will not trigger publish.yml."
|
echo "::error::PAT_TOKEN is required because a tag created with GITHUB_TOKEN will not trigger publish.yml."
|
||||||
@ -70,21 +47,41 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
PAT_TOKEN: ${{ secrets.PAT_TOKEN }}
|
PAT_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||||
|
|
||||||
# 真实 workflow_run 负责按 Conventional Commits 计算版本并推送 tag。
|
# preview 模式只输出版本推导结果,不会真正推送 tag。
|
||||||
|
- name: Semantic release preview
|
||||||
|
if: inputs.release_mode == 'preview'
|
||||||
|
id: semantic_release
|
||||||
|
uses: cycjimmy/semantic-release-action@v6
|
||||||
|
with:
|
||||||
|
dry_run: true
|
||||||
|
ci: false
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
|
||||||
|
# release 模式由维护者手动触发,直接创建并推送下一个 tag。
|
||||||
- name: Semantic release
|
- name: Semantic release
|
||||||
|
if: inputs.release_mode == 'release'
|
||||||
id: semantic_release
|
id: semantic_release
|
||||||
uses: cycjimmy/semantic-release-action@v6
|
uses: cycjimmy/semantic-release-action@v6
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||||
|
|
||||||
- name: Show release result
|
- name: Show 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: |
|
run: |
|
||||||
echo "published=${PUBLISHED}"
|
echo "mode=${{ inputs.release_mode }}"
|
||||||
echo "last_tag=${LAST_TAG}"
|
echo "published=${{ steps.semantic_release.outputs.new_release_published }}"
|
||||||
echo "next_version=${NEXT_VERSION}"
|
echo "last_tag=${{ steps.semantic_release.outputs.last_release_git_tag }}"
|
||||||
echo "next_tag=${NEXT_TAG}"
|
echo "next_version=${{ steps.semantic_release.outputs.new_release_version }}"
|
||||||
|
echo "next_tag=${{ steps.semantic_release.outputs.new_release_git_tag }}"
|
||||||
|
|
||||||
|
- name: Write summary
|
||||||
|
run: |
|
||||||
|
{
|
||||||
|
echo "## Semantic Release"
|
||||||
|
echo
|
||||||
|
echo "- Mode: \`${{ inputs.release_mode }}\`"
|
||||||
|
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 }}\`"
|
||||||
|
} >> "${GITHUB_STEP_SUMMARY}"
|
||||||
|
|||||||
13
AGENTS.md
13
AGENTS.md
@ -55,6 +55,19 @@ All AI agents and contributors must follow these rules when writing, reviewing,
|
|||||||
- The commit `body` MUST use unordered list items, and each item MUST start with a verb such as `新增`、`修复`、`优化`、
|
- The commit `body` MUST use unordered list items, and each item MUST start with a verb such as `新增`、`修复`、`优化`、
|
||||||
`更新`、`补充`、`重构`.
|
`更新`、`补充`、`重构`.
|
||||||
- Each commit body bullet MUST describe one independent change point; avoid repeated or redundant descriptions.
|
- Each commit body bullet MUST describe one independent change point; avoid repeated or redundant descriptions.
|
||||||
|
- Commit `type` MUST reflect release semantics instead of author intent:
|
||||||
|
- Use `feat` only for user-facing or consumer-facing capability additions that should raise the next released version's
|
||||||
|
`minor` segment.
|
||||||
|
- Use `fix` for behavior corrections, `perf` for observable performance improvements, and `refactor` only for
|
||||||
|
non-feature code restructuring.
|
||||||
|
- Use `docs`、`test`、`chore`、`build`、`ci`、`style` for their literal categories; do not encode these changes as
|
||||||
|
`feat` just because they feel important.
|
||||||
|
- Documentation-only changes MUST NOT use `feat`, including new guides, refreshed examples, navigation updates, and
|
||||||
|
adoption notes for existing capabilities. If a commit changes both product behavior and related docs, either split the
|
||||||
|
commit or use `feat` only when the code/package behavior is the primary released change.
|
||||||
|
- Contributors MUST avoid ambiguous scopes such as `feat(docs)` for documentation work. If the change only affects docs,
|
||||||
|
prefer `docs(<module-or-area>)`; if it adds a real capability in a docs-related toolchain, use the scope of that
|
||||||
|
actual subsystem instead of `docs`.
|
||||||
- Keep technical terms in English when they are established project terms, such as `API`、`Model`、`System`.
|
- Keep technical terms in English when they are established project terms, such as `API`、`Model`、`System`.
|
||||||
- When composing a multi-line commit body from shell commands, contributors MUST NOT rely on Bash `$"..."` quoting for
|
- When composing a multi-line commit body from shell commands, contributors MUST NOT rely on Bash `$"..."` quoting for
|
||||||
newline escapes, because it passes literal `\n` sequences to Git. Use multiple `-m` flags or ANSI-C `$'...'`
|
newline escapes, because it passes literal `\n` sequences to Git. Use multiple `-m` flags or ANSI-C `$'...'`
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
- 当前阶段:`Phase 1`
|
- 当前阶段:`Phase 1`
|
||||||
- 当前焦点:
|
- 当前焦点:
|
||||||
- 增加 `.releaserc.json`,仅启用版本分析与 release notes 生成,不启用 GitHub Release 发布插件
|
- 增加 `.releaserc.json`,仅启用版本分析与 release notes 生成,不启用 GitHub Release 发布插件
|
||||||
- 将 `auto-tag.yml` 改成 `workflow_run` 真正打 tag、`workflow_dispatch` 只做 dry-run 的双入口
|
- 将 `auto-tag.yml` 改成纯 `workflow_dispatch` 双模式入口,由维护者手动选择 `preview` 或 `release`
|
||||||
- 明确 `PAT_TOKEN` 与 `GITHUB_TOKEN` 的职责边界,确保 tag 继续触发 `publish.yml`
|
- 明确 `PAT_TOKEN` 与 `GITHUB_TOKEN` 的职责边界,确保 tag 继续触发 `publish.yml`
|
||||||
|
|
||||||
### 已知风险
|
### 已知风险
|
||||||
@ -35,9 +35,12 @@
|
|||||||
- 已新增 `.releaserc.json`,仅保留 `@semantic-release/commit-analyzer` 与
|
- 已新增 `.releaserc.json`,仅保留 `@semantic-release/commit-analyzer` 与
|
||||||
`@semantic-release/release-notes-generator`,避免 `semantic-release` 直接创建 GitHub Release
|
`@semantic-release/release-notes-generator`,避免 `semantic-release` 直接创建 GitHub Release
|
||||||
- 已将 `.github/workflows/auto-tag.yml` 重写为:
|
- 已将 `.github/workflows/auto-tag.yml` 重写为:
|
||||||
- `workflow_run` 在 `main` 上、CI 成功且提交消息包含 `[release ci]` 时执行真实打 tag
|
- `workflow_dispatch` 由维护者手动选择 `preview` 或 `release`
|
||||||
- `workflow_dispatch` 只执行 dry-run,输出 `last_tag`、`next_version` 与 `next_tag`
|
- `preview` 只执行 dry-run,输出 `last_tag`、`next_version` 与 `next_tag`
|
||||||
|
- `release` 由维护者手动触发真实打 tag,并把结果写入 job summary
|
||||||
- 已明确真实打 tag 仍使用 `PAT_TOKEN`,因为 `GITHUB_TOKEN` 推送的 tag 不会继续触发 `publish.yml`
|
- 已明确真实打 tag 仍使用 `PAT_TOKEN`,因为 `GITHUB_TOKEN` 推送的 tag 不会继续触发 `publish.yml`
|
||||||
|
- 已更新 `AGENTS.md` 的 Conventional Commit 规则,显式禁止把纯文档变更写成 `feat(...)` 或 `feat(docs)`
|
||||||
|
- 已移除基于 `workflow_run` 和 `[release ci]` 的自动发版门闸,后续版本预览与真实发版都由维护者手动触发
|
||||||
|
|
||||||
## 验证
|
## 验证
|
||||||
|
|
||||||
@ -59,9 +62,12 @@
|
|||||||
- `npx --yes semantic-release --dry-run --no-ci`(在 `/tmp/gframework-semrel-dryrun`)
|
- `npx --yes semantic-release --dry-run --no-ci`(在 `/tmp/gframework-semrel-dryrun`)
|
||||||
- 结果:通过
|
- 结果:通过
|
||||||
- 备注:dry-run 成功识别 `v0.0.222` 为最新 release,并分析 `269` 个提交;按当前规则会提升到下一次 `minor` 发布,预期 tag 为 `v0.1.0`
|
- 备注:dry-run 成功识别 `v0.0.222` 为最新 release,并分析 `269` 个提交;按当前规则会提升到下一次 `minor` 发布,预期 tag 为 `v0.1.0`
|
||||||
|
- `dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release -p:RestoreFallbackFolders=`(手动发版入口调整后复验)
|
||||||
|
- 结果:通过
|
||||||
|
- 备注:`0 warning / 0 error`
|
||||||
|
|
||||||
## 下一步
|
## 下一步
|
||||||
|
|
||||||
1. 复核 `workflow_dispatch` dry-run 输出格式是否还需要额外收窄或增加说明
|
1. 复核 `workflow_dispatch` 的 `preview` / `release` 两种模式命名是否还要进一步收紧
|
||||||
2. 评估是否要把 `workflow_run` 的 `[release ci]` 门闸改成更显式的 PR label 或 manual approval
|
2. 评估是否要在 release 模式中补充额外输入,例如预期 tag 确认或二次确认文本
|
||||||
3. 若本轮验证通过,按仓库要求创建提交并等待你审阅发版流程细节
|
3. 若本轮验证通过,按仓库要求创建补充提交并等待你审阅手动发版流程细节
|
||||||
|
|||||||
@ -19,9 +19,18 @@
|
|||||||
- `docs/test/chore/build/ci/style -> no release`
|
- `docs/test/chore/build/ci/style -> no release`
|
||||||
- `BREAKING CHANGE` / `BREAKING CHANGES` 作为 major 信号
|
- `BREAKING CHANGE` / `BREAKING CHANGES` 作为 major 信号
|
||||||
- 重写 `auto-tag.yml`:
|
- 重写 `auto-tag.yml`:
|
||||||
- 保留 `workflow_run` 监听 `CI - Build & Test`
|
- 改为纯 `workflow_dispatch` 手动入口
|
||||||
- `workflow_dispatch` 变为 dry-run 入口
|
- 增加 `release_mode=preview|release` 输入
|
||||||
- 真实打 tag 改由 `semantic-release-action` 处理,并要求 `PAT_TOKEN`
|
- `preview` 只跑 dry-run 并输出 `last_tag`、`next_version`、`next_tag`
|
||||||
|
- `release` 由维护者手动触发真实打 tag,并要求 `PAT_TOKEN`
|
||||||
|
- 收紧 `AGENTS.md` 的提交信息约束,明确提交类型必须反映 release semantics,纯文档变更禁止写成 `feat(...)`
|
||||||
|
- 按用户反馈继续调整发版入口:
|
||||||
|
- 删除基于 `workflow_run` 的自动发版路径
|
||||||
|
- 统一改为 `workflow_dispatch` 手动触发
|
||||||
|
- 通过 `release_mode=preview|release` 区分“查看下个版本”和“真实打 tag”
|
||||||
|
- 复验最小构建命令:
|
||||||
|
- `dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release -p:RestoreFallbackFolders=`
|
||||||
|
- 结果:通过,`0 warning / 0 error`
|
||||||
- 完成最小构建验证:
|
- 完成最小构建验证:
|
||||||
- `dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release -p:RestoreFallbackFolders=`
|
- `dotnet build GFramework.Core.Abstractions/GFramework.Core.Abstractions.csproj -c Release -p:RestoreFallbackFolders=`
|
||||||
- 结果:通过,`0 warning / 0 error`
|
- 结果:通过,`0 warning / 0 error`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user