iso-init-repo
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseiso-init-repo
iso-init-repo
Set up GitHub repo governance. Run from inside the target repo.
All templates live in next to this file.
templates/搭建GitHub仓库治理体系。需在目标仓库内运行。
所有模板存放在当前文件旁的目录中。
templates/Pre-flight
前置检查
Run these checks before any step.
在执行任何步骤前先运行以下检查。
git
git
bash
command -v git &>/dev/null \
|| { echo "✗ git not found. Install Xcode CLI tools: xcode-select --install"; exit 1; }bash
command -v git &>/dev/null \
|| { echo "✗ git not found. Install Xcode CLI tools: xcode-select --install"; exit 1; }gh (GitHub CLI)
gh (GitHub CLI)
bash
if ! command -v gh &>/dev/null; then
echo "⚠ gh not found — installing..."
brew install gh
command -v gh &>/dev/null \
|| { echo "✗ gh install failed. Run manually: brew install gh"; exit 1; }
echo "✓ gh installed"
fibash
if ! command -v gh &>/dev/null; then
echo "⚠ gh not found — installing..."
brew install gh
command -v gh &>/dev/null \
|| { echo "✗ gh install failed. Run manually: brew install gh"; exit 1; }
echo "✓ gh installed"
figh authentication
gh认证
Authentication is interactive — cannot be automated. If not authenticated, stop and run the login command manually.
bash
if ! gh auth status &>/dev/null; then
echo "⚠ gh not authenticated."
echo " Run: gh auth login"
echo " Then re-run /iso-init-repo"
exit 1
fi认证为交互式操作——无法自动化。若未认证,请停止操作并手动运行登录命令。
bash
if ! gh auth status &>/dev/null; then
echo "⚠ gh not authenticated."
echo " Run: gh auth login"
echo " Then re-run /iso-init-repo"
exit 1
fiRemote detection
远程仓库检测
bash
git remote get-url origin 2>/dev/null || echo "no remote"bash
git remote get-url origin 2>/dev/null || echo "no remote"node / npx (Node repos — commitlint + version-bump)
node / npx(Node仓库——commitlint + 版本更新)
Only relevant when exists. Warns rather than fails — repo/branch steps still run.
package.jsonbash
if [ -f package.json ] && ! command -v npx &>/dev/null; then
echo "⚠ node/npx not found — Steps 5–6 (commitlint, version-bump) will be skipped."
echo " Install Node.js: https://nodejs.org or via nvm/fnm"
fiAll checks pass → proceed to Step 1.
仅当存在时相关。仅发出警告而非终止——仓库/分支相关步骤仍会执行。
package.jsonbash
if [ -f package.json ] && ! command -v npx &>/dev/null; then
echo "⚠ node/npx not found — Steps 5–6 (commitlint, version-bump) will be skipped."
echo " Install Node.js: https://nodejs.org or via nvm/fnm"
fi所有检查通过 → 执行步骤1。
Step 1 — GitHub repo
步骤1——GitHub仓库
No remote → create
无远程仓库→创建
Ask user for repo name (default: current directory name) and visibility (private/public).
bash
gh repo create <name> --private --source=. --remote=origin --push询问用户仓库名称(默认:当前目录名称)和可见性(私有/公开)。
bash
gh repo create <name> --private --source=. --remote=origin --pushRemote exists → verify
已存在远程仓库→验证
bash
gh repo viewConfirm accessible, then continue.
bash
gh repo view确认可访问后继续。
Step 2 — Branch structure
步骤2——分支结构
Target: (default, daily work) ← (staging) ← (release)
devtestprodbash
ORIGIN=$(git symbolic-ref --short HEAD) # current default, likely 'main'目标结构:(默认分支,日常开发)← (预发布)← (正式发布)
devtestprodbash
ORIGIN=$(git symbolic-ref --short HEAD) # current default, likely 'main'Create prod from current default
Create prod from current default
git checkout -b prod 2>/dev/null || git checkout prod
git push -u origin prod
git checkout -b prod 2>/dev/null || git checkout prod
git push -u origin prod
Create test and dev from prod
Create test and dev from prod
git checkout -b test prod && git push -u origin test
git checkout -b dev prod && git push -u origin dev
git checkout -b test prod && git push -u origin test
git checkout -b dev prod && git push -u origin dev
Set dev as GitHub default branch
Set dev as GitHub default branch
gh repo edit --default-branch dev
gh repo edit --default-branch dev
Delete original default (main) if it was the starting point
Delete original default (main) if it was the starting point
if [ "$ORIGIN" = "main" ]; then
git push origin --delete main
git branch -d main
fi
Only delete `main` if `prod` was successfully created with full history.if [ "$ORIGIN" = "main" ]; then
git push origin --delete main
git branch -d main
fi
仅当`prod`分支成功创建且包含完整历史记录时,才删除`main`分支。Step 3 — Branch protection
步骤3——分支保护
Requires the branches from Step 2 to exist on origin.
bash
REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)要求步骤2中的分支已存在于远程仓库origin中。
bash
REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)prod — PR required, no force push. ci-prod-gate enforces source=test.
prod — PR required, no force push. ci-prod-gate enforces source=test.
gh api "repos/$REPO/branches/prod/protection" --method PUT
--input - <<'EOF' { "required_status_checks": null, "enforce_admins": false, "required_pull_request_reviews": { "required_approving_review_count": 0 }, "restrictions": null } EOF
--input - <<'EOF' { "required_status_checks": null, "enforce_admins": false, "required_pull_request_reviews": { "required_approving_review_count": 0 }, "restrictions": null } EOF
gh api "repos/$REPO/branches/prod/protection" --method PUT
--input - <<'EOF' { "required_status_checks": null, "enforce_admins": false, "required_pull_request_reviews": { "required_approving_review_count": 0 }, "restrictions": null } EOF
--input - <<'EOF' { "required_status_checks": null, "enforce_admins": false, "required_pull_request_reviews": { "required_approving_review_count": 0 }, "restrictions": null } EOF
test — PR required, no force push
test — PR required, no force push
gh api "repos/$REPO/branches/test/protection" --method PUT
--input - <<'EOF' { "required_status_checks": null, "enforce_admins": false, "required_pull_request_reviews": { "required_approving_review_count": 0 }, "restrictions": null } EOF
--input - <<'EOF' { "required_status_checks": null, "enforce_admins": false, "required_pull_request_reviews": { "required_approving_review_count": 0 }, "restrictions": null } EOF
gh api "repos/$REPO/branches/test/protection" --method PUT
--input - <<'EOF' { "required_status_checks": null, "enforce_admins": false, "required_pull_request_reviews": { "required_approving_review_count": 0 }, "restrictions": null } EOF
--input - <<'EOF' { "required_status_checks": null, "enforce_admins": false, "required_pull_request_reviews": { "required_approving_review_count": 0 }, "restrictions": null } EOF
dev — PR required, no force push
dev — PR required, no force push
gh api "repos/$REPO/branches/dev/protection" --method PUT
--input - <<'EOF' { "required_status_checks": null, "enforce_admins": false, "required_pull_request_reviews": { "required_approving_review_count": 0 }, "restrictions": null } EOF
--input - <<'EOF' { "required_status_checks": null, "enforce_admins": false, "required_pull_request_reviews": { "required_approving_review_count": 0 }, "restrictions": null } EOF
Branch protection can't restrict PR source branch — that's what `ci-prod-gate.yml` handles.gh api "repos/$REPO/branches/dev/protection" --method PUT
--input - <<'EOF' { "required_status_checks": null, "enforce_admins": false, "required_pull_request_reviews": { "required_approving_review_count": 0 }, "restrictions": null } EOF
--input - <<'EOF' { "required_status_checks": null, "enforce_admins": false, "required_pull_request_reviews": { "required_approving_review_count": 0 }, "restrictions": null } EOF
分支保护无法限制PR的源分支——这由`ci-prod-gate.yml`负责处理。Step 4 — GitHub files
步骤4——GitHub配置文件
Read → write to .
templates/ci-prod-gate.yml.github/workflows/ci-prod-gate.ymlbash
git checkout dev
git add .github/
git commit -m "chore(repo): add prod-gate workflow"
git push origin dev读取文件→写入到。
templates/ci-prod-gate.yml.github/workflows/ci-prod-gate.ymlbash
git checkout dev
git add .github/
git commit -m "chore(repo): add prod-gate workflow"
git push origin devStep 5 — Commitlint
步骤5——Commitlint配置
Skip if no .
package.json若不存在则跳过。
package.json5a — Package manager
5a——包管理器
bash
if [ -f pnpm-lock.yaml ]; then echo "pnpm"
elif [ -f yarn.lock ]; then echo "yarn"
elif [ -f bun.lockb ] || [ -f bun.lock ]; then echo "bun"
else echo "npm"; fibash
if [ -f pnpm-lock.yaml ]; then echo "pnpm"
elif [ -f yarn.lock ]; then echo "yarn"
elif [ -f bun.lockb ] || [ -f bun.lock ]; then echo "bun"
else echo "npm"; fi5b — Init Husky (only if .husky/
missing)
.husky/5b——初始化Husky(仅当.husky/
目录不存在时)
.husky/bash
[ -d .husky ] || npx husky initbash
[ -d .husky ] || npx husky init5c — Install deps
5c——安装依赖
Only install packages not already in . Skip any already present.
package.jsonbash
pnpm add -D -w @commitlint/cli @commitlint/config-conventional # pnpm
yarn add -D -W @commitlint/cli @commitlint/config-conventional # yarn
bun add -d @commitlint/cli @commitlint/config-conventional # bun
npm install --save-dev @commitlint/cli @commitlint/config-conventional # npmAlso ensure is in scripts if missing.
"prepare": "husky"package.json仅安装中未包含的包。已存在的包将跳过。
package.jsonbash
pnpm add -D -w @commitlint/cli @commitlint/config-conventional # pnpm
yarn add -D -W @commitlint/cli @commitlint/config-conventional # yarn
bun add -d @commitlint/cli @commitlint/config-conventional # bun
npm install --save-dev @commitlint/cli @commitlint/config-conventional # npm同时确保的scripts中包含,若缺失则添加。
package.json"prepare": "husky"5d — commit-msg hook
5d——commit-msg钩子
Read → write to , chmod +x.
templates/commit-msg.sh.husky/commit-msgGuard:
bash
grep -q "commitlint" .husky/commit-msg 2>/dev/null \
&& echo "commit-msg: already configured, skipping" \
|| { cat templates/commit-msg.sh > .husky/commit-msg && chmod +x .husky/commit-msg; }读取文件→写入到,并赋予执行权限(chmod +x)。
templates/commit-msg.sh.husky/commit-msg检查:
bash
grep -q "commitlint" .husky/commit-msg 2>/dev/null \
&& echo "commit-msg: already configured, skipping" \
|| { cat templates/commit-msg.sh > .husky/commit-msg && chmod +x .husky/commit-msg; }5e — commitlint.config.js
5e——commitlint.config.js配置文件
Check before writing:
bash
[ -f commitlint.config.js ] \
&& echo "commitlint.config.js: already exists, skipping — review manually if needed" \
|| cp templates/commitlint.config.js commitlint.config.jsBefore enabling , audit all scopes in git history:
scope-enumbash
git log --oneline | sed -n 's/[^(]*(\([^)]*\)).*/\1/p' | sort -uOnly uncomment if the repo has clean, consistent scopes. Populate from:
scope-enum- scopes found above
- names from
ls apps/ packages/ - cross-cutting: ,
ci,deps,docsrepo
If history has free-text scopes — leave commented. alone is sufficient.
scope-enumscope-emptyCommit:
bash
git add .husky/ commitlint.config.js package.json
git commit -m "chore(repo): add commitlint"
git push origin dev写入前检查:
bash
[ -f commitlint.config.js ] \
&& echo "commitlint.config.js: already exists, skipping — review manually if needed" \
|| cp templates/commitlint.config.js commitlint.config.js启用之前,审核git历史中的所有scope:
scope-enumbash
git log --oneline | sed -n 's/[^(]*(\([^)]*\)).*/\1/p' | sort -u仅当仓库拥有清晰、一致的scope时才取消的注释。可从以下来源填充:
scope-enum- 上述找到的scope
- 命令返回的名称
ls apps/ packages/ - 跨领域:、
ci、deps、docsrepo
若历史记录中存在自由文本格式的scope——请保持的注释状态。仅启用即可。
scope-enumscope-empty提交变更:
bash
git add .husky/ commitlint.config.js package.json
git commit -m "chore(repo): add commitlint"
git push origin devStep 6 — Version bump hook
步骤6——版本更新钩子
Skip if no .
package.jsonRead → write to , chmod +x.
templates/post-commit-version-bump.sh.husky/post-commit-version-bump.shIf exists, append; otherwise create:
.husky/post-commitbash
bash "$(dirname "$0")/post-commit-version-bump.sh"Commit:
bash
git add .husky/
git commit -m "chore(repo): add version-bump post-commit hook"
git push origin dev若不存在则跳过。
package.json读取文件→写入到,并赋予执行权限(chmod +x)。
templates/post-commit-version-bump.sh.husky/post-commit-version-bump.sh若已存在,则追加内容;否则创建该文件:
.husky/post-commitbash
bash "$(dirname "$0")/post-commit-version-bump.sh"提交变更:
bash
git add .husky/
git commit -m "chore(repo): add version-bump post-commit hook"
git push origin devStep 8 — Deploy cascade command
步骤8——部署级联命令
Read → write to .
templates/deploy-cascade-command.md.claude/commands/deploy-cascade.mdThis gives the repo a command. Uses caveman skill for all output. Starting point is auto-detected from current branch — runnable from any branch except .
/deploy-cascadeprodbash
mkdir -p .claude/commands
git add .claude/commands/deploy-cascade.md
git commit -m "chore(repo): add /deploy-cascade command"
git push origin dev读取文件→写入到。
templates/deploy-cascade-command.md.claude/commands/deploy-cascade.md这将为仓库添加命令。所有输出使用caveman skill。起始分支会从当前分支自动检测——可在除外的任何分支运行。
/deploy-cascadeprodbash
mkdir -p .claude/commands
git add .claude/commands/deploy-cascade.md
git commit -m "chore(repo): add /deploy-cascade command"
git push origin devStep 9 — Summary
步骤9——总结
✓ GitHub repo created/configured
✓ Branches: dev (default) ← test ← prod
✓ Protection: PR required on dev, test, prod (no direct push)
✓ .github/workflows/ci-prod-gate.yml — prod accepts PRs from test only
✓ .husky/commit-msg + commitlint.config.js [or: skipped — no package.json]
✓ .husky/post-commit-version-bump.sh [or: skipped — no package.json]
✓ .claude/commands/deploy-cascade.md — /deploy-cascade commandCascade:
auto-detects starting point — run from any branch except . Uses caveman skill.
Prod-gate: PRs to from any branch other than fail CI automatically.
<any branch> → dev → test → prod/deploy-cascadeprodprodtest✓ GitHub仓库已创建/配置完成
✓ 分支结构:dev(默认)← test ← prod
✓ 分支保护:dev、test、prod分支需要PR(禁止直接推送)
✓ .github/workflows/ci-prod-gate.yml — prod仅接受来自test的PR
✓ .husky/commit-msg + commitlint.config.js [或:已跳过——无package.json]
✓ .husky/post-commit-version-bump.sh [或:已跳过——无package.json]
✓ .claude/commands/deploy-cascade.md — /deploy-cascade命令级联流程:
会自动检测起始分支——可在除外的任何分支运行。使用caveman skill。
Prod-gate:来自test以外分支的prod PR会自动导致CI失败。
<任意分支> → dev → test → prod/deploy-cascadeprod