iso-init-repo

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

iso-init-repo

iso-init-repo

Set up GitHub repo governance. Run from inside the target repo.
All templates live in
templates/
next to this file.
搭建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"
fi
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"
fi

gh 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
fi

Remote 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
package.json
exists. Warns rather than fails — repo/branch steps still run.
bash
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
All checks pass → proceed to Step 1.
仅当存在
package.json
时相关。仅发出警告而非终止——仓库/分支相关步骤仍会执行。
bash
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 --push

Remote exists → verify

已存在远程仓库→验证

bash
gh repo view
Confirm accessible, then continue.
bash
gh repo view
确认可访问后继续。

Step 2 — Branch structure

步骤2——分支结构

Target:
dev
(default, daily work) ←
test
(staging) ←
prod
(release)
bash
ORIGIN=$(git symbolic-ref --short HEAD)   # current default, likely 'main'
目标结构:
dev
(默认分支,日常开发)←
test
(预发布)←
prod
(正式发布)
bash
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
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

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
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

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

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

分支保护无法限制PR的源分支——这由`ci-prod-gate.yml`负责处理。

Step 4 — GitHub files

步骤4——GitHub配置文件

Read
templates/ci-prod-gate.yml
→ write to
.github/workflows/ci-prod-gate.yml
.
bash
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.yml
bash
git checkout dev
git add .github/
git commit -m "chore(repo): add prod-gate workflow"
git push origin dev

Step 5 — Commitlint

步骤5——Commitlint配置

Skip if no
package.json
.
若不存在
package.json
则跳过。

5a — 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"; fi
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"; fi

5b — Init Husky (only if
.husky/
missing)

5b——初始化Husky(仅当
.husky/
目录不存在时)

bash
[ -d .husky ] || npx husky init
bash
[ -d .husky ] || npx husky init

5c — Install deps

5c——安装依赖

Only install packages not already in
package.json
. Skip any already present.
bash
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
Also ensure
"prepare": "husky"
is in
package.json
scripts if missing.
仅安装
package.json
中未包含的包。已存在的包将跳过。
bash
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
同时确保
package.json
的scripts中包含
"prepare": "husky"
,若缺失则添加。

5d — commit-msg hook

5d——commit-msg钩子

Read
templates/commit-msg.sh
→ write to
.husky/commit-msg
, chmod +x.
Guard:
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; }
读取
templates/commit-msg.sh
文件→写入到
.husky/commit-msg
,并赋予执行权限(chmod +x)。
检查:
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.js
Before enabling
scope-enum
, audit all scopes in git history:
bash
git log --oneline | sed -n 's/[^(]*(\([^)]*\)).*/\1/p' | sort -u
Only uncomment
scope-enum
if the repo has clean, consistent scopes. Populate from:
  • scopes found above
  • names from
    ls apps/ packages/
  • cross-cutting:
    ci
    ,
    deps
    ,
    docs
    ,
    repo
If history has free-text scopes — leave
scope-enum
commented.
scope-empty
alone is sufficient.
Commit:
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
启用
scope-enum
之前
,审核git历史中的所有scope:
bash
git log --oneline | sed -n 's/[^(]*(\([^)]*\)).*/\1/p' | sort -u
仅当仓库拥有清晰、一致的scope时才取消
scope-enum
的注释。可从以下来源填充:
  • 上述找到的scope
  • ls apps/ packages/
    命令返回的名称
  • 跨领域:
    ci
    deps
    docs
    repo
若历史记录中存在自由文本格式的scope——请保持
scope-enum
的注释状态。仅启用
scope-empty
即可。
提交变更:
bash
git add .husky/ commitlint.config.js package.json
git commit -m "chore(repo): add commitlint"
git push origin dev

Step 6 — Version bump hook

步骤6——版本更新钩子

Skip if no
package.json
.
Read
templates/post-commit-version-bump.sh
→ write to
.husky/post-commit-version-bump.sh
, chmod +x.
If
.husky/post-commit
exists, append; otherwise create:
bash
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
则跳过。
读取
templates/post-commit-version-bump.sh
文件→写入到
.husky/post-commit-version-bump.sh
,并赋予执行权限(chmod +x)。
.husky/post-commit
已存在,则追加内容;否则创建该文件:
bash
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 dev

Step 8 — Deploy cascade command

步骤8——部署级联命令

Read
templates/deploy-cascade-command.md
→ write to
.claude/commands/deploy-cascade.md
.
This gives the repo a
/deploy-cascade
command. Uses caveman skill for all output. Starting point is auto-detected from current branch — runnable from any branch except
prod
.
bash
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
这将为仓库添加
/deploy-cascade
命令。所有输出使用caveman skill。起始分支会从当前分支自动检测——可在除
prod
外的任何分支运行。
bash
mkdir -p .claude/commands
git add .claude/commands/deploy-cascade.md
git commit -m "chore(repo): add /deploy-cascade command"
git push origin dev

Step 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 command
Cascade:
<any branch> → dev → test → prod
/deploy-cascade
auto-detects starting point — run from any branch except
prod
. Uses caveman skill. Prod-gate: PRs to
prod
from any branch other than
test
fail CI automatically.
✓ 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命令
级联流程:
<任意分支> → dev → test → prod
/deploy-cascade
会自动检测起始分支——可在除
prod
外的任何分支运行。使用caveman skill。 Prod-gate:来自test以外分支的prod PR会自动导致CI失败。