关于 arc-conventional-commits
arc-conventional-commits 是一项技能,用于在仓库中配置 Conventional Commits 和 semantic-release。它指导版本管理、可选的提交校验与 CI 设置,并先检查现有工具,破坏性修改须经确认。
主要功能
- 01检测现有发布工具
- 02配置 semantic-release
- 03可选设置 commitlint 和 husky
- 04可选创建 GitHub Actions 工作流
- 05通过试运行验证
适用场景
- 01为仓库添加自动版本管理
- 02迁移现有发布工具
- 03强制遵循提交消息规范
- 04准备 CI 检查和发布工作流
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ andysolomon/ arc-skills --skill arc-conventional-commits安装后在 Claude Code 中输入/arc-conventional-commits确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/evals.jsonevals/files/clean-repo/package.jsonevals/files/monorepo/package.jsonevals/files/monorepo/packages/.gitkeepevals/files/standard-version/.versionrc.jsonpackage.jsonreferences/conventional-commits-spec.mdscripts/pre-commitprotect-main.sh详细介绍
Conventional Commits + Semantic Release
此技能使用 Conventional Commits v1.0.0 规范和 semantic-release,设置由 CI 驱动的自动版本管理。
整个工作流采用对话方式进行——在执行删除现有工具等破坏性更改前,务必先向用户确认。
请按顺序完成以下五个阶段。
阶段 1 — 检测现有版本管理工具
在安装任何内容之前,扫描代码仓库中现有的版本管理基础设施。 这可以避免冲突,并让用户有机会顺利迁移。
使用 Glob 和 Read 检查以下工具:
| 工具 | 文件 / 模式 |
|---|---|
| semantic-release | .releaserc、.releaserc.json、.releaserc.yml、.releaserc.yaml、release.config.js、release.config.cjs |
| standard-version | .versionrc、.versionrc.json、.versionrc.js |
| changesets | .changeset/ 目录 |
| lerna | lerna.json |
| release-please | release-please-config.json、.release-please-manifest.json |
同时读取 package.json 并检查:
- devDependencies 中是否包含:
semantic-release、standard-version、@changesets/cli、@changesets/changelog-github、lerna、release-please、conventional-changelog-cli、np、publish-please - scripts 中是否有键或值包含
version、release或publish(忽略dev、start、build)
向用户汇报检查结果,以摘要列表的形式呈现。例如:
我在此代码仓库中发现以下版本管理工具:
- standard-version —
.versionrc.json、devDependencies 中的standard-version- 发布脚本 — package.json scripts 中的
"release": "standard-version"是否要先删除这些工具,再设置 semantic-release?
如果没有发现任何内容,告知用户代码仓库中没有现有工具,然后跳到阶段 3。
阶段 2 — 移除现有工具(按需执行)
只有在阶段 1 检测到现有工具且用户确认移除后,才执行此阶段。
针对每个检测到的工具:
- 删除配置文件 — 移除阶段 1 中识别出的所有配置文件
- 卸载软件包 — 对 devDependencies 中检测到的每个软件包运行
npm uninstall <package> - 清理脚本 — 从
package.json中移除与版本管理或发布相关的脚本 - 移除目录 — 如果检测到 changesets,则删除
.changeset/
移除完成后,确认已清理的内容:
已移除:
- 已删除
.versionrc.json- 已卸载
standard-version- 已从 package.json 中移除
"release"脚本
阶段 3 — 安装 semantic-release
步骤 1:安装核心软件包
npm install --save-dev semantic-release \
@semantic-release/commit-analyzer \
@semantic-release/release-notes-generator \
@semantic-release/changelog \
@semantic-release/npm \
@semantic-release/github \
@semantic-release/git \
conventional-changelog-conventionalcommits
步骤 2:确定发布分支
检查代码仓库的默认分支:
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null || git branch --show-current
将结果(通常为 main 或 master)作为发布分支。如不确定,请与用户确认。
步骤 3:创建 .releaserc.json
插件顺序很重要——每个插件都会依次运行,后续插件依赖前面的插件。
{
"branches": ["main"],
"plugins": [
["@semantic-release/commit-analyzer", {
"preset": "conventionalcommits"
}],
["@semantic-release/release-notes-generator", {
"preset": "conventionalcommits"
}],
["@semantic-release/changelog", {
"changelogFile": "CHANGELOG.md"
}],
["@semantic-release/npm", {
"npmPublish": false
}],
"@semantic-release/github",
["@semantic-release/git", {
"assets": ["CHANGELOG.md", "package.json", "package-lock.json"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}]
]
}
调整配置:
- 如果
package.json中有"private": true,则保留npmPublish: false(上面的默认设置) - 如果此软件包应发布到 npm,则设置
npmPublish: true - 将 branches 中的
"main"替换为实际的默认分支名称
步骤 4:添加发布脚本
添加到 package.json 的 scripts 中:
"release": "semantic-release"
步骤 5:询问是否启用提交规范检查
询问用户:
是否要安装 commitlint 和 husky,以强制每次提交都符合 Conventional Commits 格式? 这样可以防止格式错误的提交消息被推送。
如果用户同意:
npm install --save-dev @commitlint/cli @commitlint/config-conventional husky
npx husky init
创建 commitlint.config.js:
export default { extends: ['@commitlint/config-conventional'] };
创建 husky 钩子:
echo 'npx --no -- commitlint --edit $1' > .husky/commit-msg
如果 .husky/ 已存在(由之前的 husky 设置创建),不要运行 npx husky init —
只需在现有钩子旁添加 commit-msg 钩子文件。
第 6 步:询问是否集成 CI
询问用户:
你希望我创建 GitHub Actions 工作流,用于 PR 检查、合并门禁和自动发布吗?
如果是,创建三个工作流文件。将这三个文件中的 main 替换为实际的默认分支。
.github/workflows/release.yml — 合并到 main 后运行 semantic-release
name: Release
on:
push:
branches: [main]
permissions:
contents: write
issues: write
pull-requests: write
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- name: Install dependencies
run: npm ci
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release
.github/workflows/pr.yml — PR 创建或更新时运行检查
name: PR Checks
on:
pull_request:
branches: [main]
jobs:
commitlint:
name: Validate Commits
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- run: npm ci
- name: Validate commit messages
run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- run: npm ci
- run: npm run lint --if-present
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- run: npm ci
- run: npm test --if-present
.github/workflows/merge.yml — 合并门禁(用于分支保护的单一状态检查)
此工作流运行与 pr.yml 相同的检查,但将其作为单个任务运行,生成一个状态检查名称(Merge Gate),可在 GitHub 分支保护设置中将其设为必需项。
name: Merge Gate
on:
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
jobs:
merge-gate:
name: Merge Gate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- run: npm ci
- name: Validate commits
run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose
- name: Lint
run: npm run lint --if-present
- name: Test
run: npm test --if-present
提醒用户:
- GitHub Actions 会自动提供
GITHUB_TOKEN - 仅在发布到 npm 时才需要
NPM_TOKEN——用户可以在仓库的 Settings > Secrets 中设置 Merge Gate任务名称就是用户要在分支保护中设为必需状态检查的名称
第 7 步:检查是否为 monorepo
如果 package.json 中包含 workspaces 字段,或存在 lerna.json,请提醒用户:
此仓库似乎是一个 monorepo。semantic-release 开箱即用的 monorepo 支持有限。可以考虑使用
semantic-release-monorepo或multi-semantic-release来为各个包分别管理版本。
第 4 阶段 — 验证
安装后:
-
试运行(如果仓库有提交):
npx semantic-release --dry-run --no-ci此操作会验证配置,但不会发布任何内容。将输出内容分享给用户。
-
总结 — 告知用户已完成的设置:
- 使用 Conventional Commits 预设的 semantic-release
- 启用的插件
- 是否添加了 commitlint/husky 强制校验
- 是否创建了 CI 工作流
-
提交示例 — 向用户展示如何立即使用该系统:
fix: resolve null pointer in user lookup → triggers PATCH bump (e.g., 1.0.0 → 1.0.1) feat(auth): add OAuth2 support → triggers MINOR bump (e.g., 1.0.1 → 1.1.0) feat!: redesign the public API → triggers MAJOR bump (e.g., 1.1.0 → 2.0.0) chore: update dev dependencies → no version bump, appears in changelog
第 5 阶段 — 分支保护
采用 Conventional Commits 时,最好通过分支和 PR 提交所有更改。 此阶段会设置三层保护,防止直接向 main 提交。
第 1 步:安装 husky 提交前钩子
此钩子会阻止在终端中向 main 执行 git commit。
npm install --save-dev husky
npx husky init
将 .husky/pre-commit 的内容替换为:
#!/bin/sh
branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$branch" = "main" ] || [ "$branch" = "master" ]; then
echo ""
echo " Direct commits to $branch are not allowed."
echo " Create a feature branch and open a PR instead:"
echo ""
echo " git checkout -b feat/your-feature"
echo ""
exit 1
fi
如果 .husky/ 已存在,请勿运行 npx husky init——只需替换 pre-commit 文件。
如果存在 .husky/commit-msg 钩子(来自第 3 阶段第 5 步),请保留该文件。
第 2 步:安装 Claude Code PreToolUse 钩子
这会阻止 Claude 在 main 上暂存或提交更改。它会提示用户批准,因此用户确有需要时可以覆盖限制。
在目标仓库中创建 .claude/hooks/protect-main.sh:
#!/bin/bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
if ! echo "$COMMAND" | grep -qE "^git (add|commit)"; then
exit 0
fi
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
if [ "$CURRENT_BRANCH" = "main" ] || [ "$CURRENT_BRANCH" = "master" ]; then
if echo "$COMMAND" | grep -qE "^git add"; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "ask",
permissionDecisionReason: "You are about to stage files on main. Create a feature branch instead."
}
}'
else
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "ask",
permissionDecisionReason: "You are about to commit directly to main. Create a feature branch instead."
}
}'
fi
exit 0
fi
exit 0
将其设为可执行文件:
chmod +x .claude/hooks/protect-main.sh
然后创建或更新 .claude/settings.json,以注册此钩子。如果该文件已存在,请将 hooks 键合并到现有配置中——不要覆盖其他设置。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/protect-main.sh"
}
]
}
]
}
}
第 3 步:配置 GitHub 分支保护
询问用户:
你希望我在 main 上设置 GitHub 分支保护规则吗? 这需要管理员权限,并会在服务器层面强制要求使用 PR。
如果是,使用 GitHub CLI:
gh api repos/{owner}/{repo}/branches/main/protection \
-X PUT \
-H "Accept: application/vnd.github+json" \
-f "required_pull_request_reviews[dismiss_stale_reviews]=false" \
-f "required_pull_request_reviews[require_code_owner_reviews]=false" \
-F "required_pull_request_reviews[required_approving_review_count]=1" \
-F "enforce_admins=true" \
-f "restrictions=null" \
-f "required_status_checks=null"
将 {owner}/{repo} 替换为 gh repo view --json owner,name 返回的实际值。
如果仓库有 CI 工作流(来自第 3 阶段第 6 步),请将 Merge Gate 任务设为必需状态检查,这样只有所有检查都通过后 PR 才能合并:
gh api repos/{owner}/{repo}/branches/main/protection \
-X PUT \
-H "Accept: application/vnd.github+json" \
-f "required_pull_request_reviews[dismiss_stale_reviews]=false" \
-F "required_pull_request_reviews[required_approving_review_count]=1" \
-F "enforce_admins=true" \
-f "restrictions=null" \
-f "required_status_checks[strict]=true" \
-f "required_status_checks[contexts][]=Merge Gate"
提醒用户:
enforce_admins: true表示即使仓库管理员也无法绕过这些规则Merge Gate是merge.yml中的任务名称——它会验证提交、运行 lint 并运行测试- 用户之后可以在 GitHub 仓库的 Settings > Branches 中调整这些设置
快速参考 — 提交格式
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
| 前缀 | 版本升级 | 示例 |
|---|---|---|
fix: | PATCH (0.0.x) | fix: prevent race condition in auth flow |
feat: | MINOR (0.x.0) | feat(api): add pagination to /users endpoint |
feat!: | MAJOR (x.0.0) | feat!: drop support for Node 14 |
BREAKING CHANGE: 页脚 | MAJOR (x.0.0) | 在页脚中包含 BREAKING CHANGE: <desc> 的任意类型 |
有效类型: feat、fix、build、chore、ci、docs、style、refactor、perf、test
默认情况下,只有 feat 和 fix 会触发版本升级。其他类型会出现在变更日志中,但不会升级版本。
回答规范相关问题
有关 Conventional Commits 规范的详细问题——作用域规则、多行正文、页脚语法和边缘情况——请阅读此技能目录中的 references/conventional-commits-spec.md。其中包含完整的 v1.0.0 规范,包括全部 16 条规则和示例。