diff --git a/.github/scripts/apply-branch-protection.sh b/.github/scripts/apply-branch-protection.sh index e64b466..67f1351 100755 --- a/.github/scripts/apply-branch-protection.sh +++ b/.github/scripts/apply-branch-protection.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# 在 GitHub 上启用 main / develop 分支保护(需仓库 admin + gh 已登录) -# Enable GitHub branch protection for main and develop (requires admin + gh auth) +# 在 GitHub 上启用 main / staging 分支保护(需仓库 admin + gh 已登录) +# Enable GitHub branch protection for main and staging (requires admin + gh auth) # # 用法 / Usage: # gh auth login @@ -20,7 +20,7 @@ if ! gh auth status >/dev/null 2>&1; then exit 1 fi -echo "🔒 配置 main:禁止直接 push,仅允许 PR(建议 base=develop 合入后再 PR 到 main)" +echo "🔒 配置 main:禁止直接 push,仅允许 staging PR 晋级" echo " Configure main: block direct pushes; merge via PR only" gh api "repos/${REPO}/branches/main/protection" -X PUT \ @@ -31,30 +31,35 @@ gh api "repos/${REPO}/branches/main/protection" -X PUT \ -f restrictions=null \ -f allow_force_pushes=false \ -f allow_deletions=false \ - -F 'required_status_checks[contexts][]=CI / test' \ + -F 'required_status_checks[contexts][]=CI / test (3.10)' \ + -F 'required_status_checks[contexts][]=CI / test (3.11)' \ + -F 'required_status_checks[contexts][]=CI / test (3.12)' \ -F 'required_status_checks[contexts][]=CI / lint' \ - -F 'required_status_checks[contexts][]=Branch Guard / block-direct-push-to-main' \ + -F 'required_status_checks[contexts][]=Branch Guard / require-staging-source' \ 2>/dev/null || { echo "⚠️ main 保护需 classic protection 或 Rulesets 权限;若失败请在 GitHub UI 手动设置:" echo " Settings → Branches → Add rule for main" echo " - Require a pull request before merging" + echo " - Require status check: Branch Guard / require-staging-source" echo " - Do not allow bypassing" echo " - Restrict pushes that create files (optional)" } echo "" -echo "🔒 配置 develop:禁止直接 push 到 main 的替代——develop 允许 PR 合并" -gh api "repos/${REPO}/branches/develop/protection" -X PUT \ +echo "🔒 配置 staging:禁止直接 push,仅允许 feature/fix 分支通过 PR 合入" +gh api "repos/${REPO}/branches/staging/protection" -X PUT \ -f required_status_checks[strict]=false \ -f enforce_admins=false \ -f required_pull_request_reviews[required_approving_review_count]=0 \ -f restrictions=null \ -f allow_force_pushes=false \ -f allow_deletions=false \ - -F 'required_status_checks[contexts][]=CI / test' \ + -F 'required_status_checks[contexts][]=CI / test (3.10)' \ + -F 'required_status_checks[contexts][]=CI / test (3.11)' \ + -F 'required_status_checks[contexts][]=CI / test (3.12)' \ -F 'required_status_checks[contexts][]=CI / lint' \ 2>/dev/null || { - echo "⚠️ develop 保护可选;建议在 UI 为 develop 启用 Require PR(feature → develop)" + echo "⚠️ staging 保护可选;建议在 UI 为 staging 启用 Require PR(feature/fix → staging)" } echo "" diff --git a/.github/workflows/branch-guard.yml b/.github/workflows/branch-guard.yml index a48ec48..d4de9b2 100644 --- a/.github/workflows/branch-guard.yml +++ b/.github/workflows/branch-guard.yml @@ -1,18 +1,37 @@ -# 分支策略守卫:禁止直接向 main 推送非合并提交 -# Branch guard: reject direct (non-merge) pushes to main +# 分支策略守卫:main 只能由 staging PR 晋级 +# Branch guard: main can only be promoted from staging PRs # -# 说明 / Note: 本地 pre-commit 的 no-commit-to-branch 防本地误提交; -# 本 workflow 在 push 已发生后标记 CI 失败,需配合 GitHub Branch protection 才能真正阻断。 -# Local pre-commit blocks local commits; this flags CI after push — use branch protection to block pushes. +# 说明 / Note: push 守卫是兜底;真正阻断直接更新依赖 GitHub Rulesets。 +# Push guard is a fallback; GitHub Rulesets are what block direct updates. name: Branch Guard on: push: branches: [main] + pull_request: + branches: [main] jobs: + require-staging-source: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: 检查 main PR 来源 / Check main PR source + env: + HEAD_REF: ${{ github.head_ref }} + run: | + set -euo pipefail + if [[ "${HEAD_REF}" == "staging" ]]; then + echo "Allowed: staging -> main" + exit 0 + fi + echo "::error::main 只能从 staging 分支通过 PR 晋级,当前来源:${HEAD_REF}" + echo "::error::PRs to main must come from staging. Current source: ${HEAD_REF}" + exit 1 + block-direct-push-to-main: + if: github.event_name == 'push' runs-on: ubuntu-latest steps: - name: 检查是否为合并提交 / Check merge commit @@ -29,6 +48,6 @@ jobs: echo "Allowed merge to main." exit 0 fi - echo "::error::禁止直接向 main 推送。请先合入 develop,再通过 PR 合入 main。" - echo "::error::Direct push to main is not allowed. Merge to develop first, then open a PR to main." + echo "::error::禁止直接向 main 推送。请先合入 staging,再通过 PR 合入 main。" + echo "::error::Direct push to main is not allowed. Merge to staging first, then open a PR to main." exit 1 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d430cac..197e16d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: CI on: push: - branches: [ main, develop ] + branches: [ main, staging ] pull_request: - branches: [ main, develop ] + branches: [ main, staging ] jobs: test: @@ -93,4 +93,3 @@ jobs: - name: 运行 Black run: poetry run black --check ogscope tests - diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e9fc5c1..7e37ef4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,11 +33,11 @@ cd OGScope ``` -2. **基于 develop 创建功能分支 / Branch from develop** +2. **基于 staging 创建功能分支 / Branch from staging** ```bash git fetch origin - git checkout develop - git pull origin develop + git checkout staging + git pull origin staging git checkout -b feature/your-feature-name ``` @@ -125,16 +125,16 @@ | 分支 | 用途 | |------|------| -| `main` | 稳定发布线;仅通过 PR 从 `develop` 合入 | -| `develop` | **唯一集成分支**;日常开发与板端联调基准 | -| `feature/*` | 功能/重构;从 `develop` 拉出,PR 合回后删除 | -| `fix/*` | 小修复;可合 `develop`,紧急时可 hotfix 合 `main` | +| `main` | 稳定发布线;仅通过 PR 从 `staging` 晋级 | +| `staging` | **长期测试集成分支**;日常开发、板端联调与社区测试基准 | +| `feature/*` | 功能/重构;从 `staging` 拉出,PR 合回后删除 | +| `fix/*` | 小修复;合入 `staging` 验证,紧急时可 hotfix 合 `main` | -流程:`feature/*` → PR → `develop` → 定期 PR → `main`。 +流程:`feature/*` / `fix/*` → PR → `staging` → 测试通过后 PR → `main`。 -**禁止直接向 `main` 提交或推送**(本地 pre-commit 会拦截;remote 需配置 Branch protection,见 [.github/scripts/apply-branch-protection.sh](../.github/scripts/apply-branch-protection.sh))。 +**禁止直接向 `main` 或 `staging` 提交或推送**(本地 pre-commit 会拦截;remote 需配置 GitHub Rulesets 或 Branch protection,见 [.github/scripts/apply-branch-protection.sh](../.github/scripts/apply-branch-protection.sh))。 -**已废弃**:不再使用 `dev`、`dev-latest` 双集成分支。 +**已废弃**:不再使用 `develop`、`dev`、`dev-latest` 集成分支。 ## 开发流程 @@ -142,7 +142,7 @@ 2. **开发**: 在本地开发和测试 3. **提交 PR**: 创建 Pull Request 4. **代码审查**: 等待维护者审查 -5. **合并**: 审查通过后合并到 `develop`(发版时再合 `main`) +5. **合并**: 审查通过后合并到 `staging`,测试通过后再通过 PR 晋级 `main` ## 代码审查标准 @@ -168,4 +168,3 @@ - 联系维护者 感谢你的贡献!🎉 - diff --git a/CONTRIBUTING_EN.md b/CONTRIBUTING_EN.md index 571cd44..08f1090 100644 --- a/CONTRIBUTING_EN.md +++ b/CONTRIBUTING_EN.md @@ -24,7 +24,7 @@ Thank you for your interest in OGScope. We welcome contributions of all kinds. ### Code contributions 1. **Fork** the repository and clone your fork. -2. **Branch from `develop`**: `git checkout develop && git pull && git checkout -b feature/your-feature-name` +2. **Branch from `staging`**: `git checkout staging && git pull && git checkout -b feature/your-feature-name` 3. **Dev dependencies**: ```bash poetry install @@ -80,16 +80,16 @@ Thank you for your interest in OGScope. We welcome contributions of all kinds. | Branch | Purpose | |--------|---------| -| `main` | Stable release; merge from `develop` via PR only | -| `develop` | **Single integration branch**; default for daily work and board sync | -| `feature/*` | Features/refactors; branch from `develop`, delete after merge | -| `fix/*` | Small fixes; merge to `develop`; hotfix to `main` when urgent | +| `main` | Stable release; promote from `staging` via PR only | +| `staging` | **Long-lived test integration branch**; default for daily work, board sync, and community validation | +| `feature/*` | Features/refactors; branch from `staging`, delete after merge | +| `fix/*` | Small fixes; validate through `staging`; hotfix to `main` when urgent | -Flow: `feature/*` → PR → `develop` → periodic PR → `main`. +Flow: `feature/*` / `fix/*` → PR → `staging` → validated PR → `main`. -**Do not commit or push directly to `main`.** Local pre-commit blocks this; configure GitHub branch protection via [.github/scripts/apply-branch-protection.sh](../.github/scripts/apply-branch-protection.sh). +**Do not commit or push directly to `main` or `staging`.** Local pre-commit blocks this; configure GitHub Rulesets or branch protection via [.github/scripts/apply-branch-protection.sh](../.github/scripts/apply-branch-protection.sh). -**Deprecated**: `dev` and `dev-latest` dual integration branches. +**Deprecated**: `develop`, `dev`, and `dev-latest` integration branches. ## Workflow @@ -97,7 +97,7 @@ Flow: `feature/*` → PR → `develop` → periodic PR → `main`. 2. Develop and test locally 3. Open a PR 4. Review -5. Merge into `develop` (and `main` for releases) +5. Merge into `staging`, then promote to `main` by PR after validation ## Review expectations