Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions .github/scripts/apply-branch-protection.sh
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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 \
Expand All @@ -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/fixstaging)"
}

echo ""
Expand Down
33 changes: 26 additions & 7 deletions .github/workflows/branch-guard.yml
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
5 changes: 2 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: CI

on:
push:
branches: [ main, develop ]
branches: [ main, staging ]
pull_request:
branches: [ main, develop ]
branches: [ main, staging ]

jobs:
test:
Expand Down Expand Up @@ -93,4 +93,3 @@ jobs:

- name: 运行 Black
run: poetry run black --check ogscope tests

23 changes: 11 additions & 12 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```

Expand Down Expand Up @@ -125,24 +125,24 @@

| 分支 | 用途 |
|------|------|
| `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` 集成分支

## 开发流程

1. **选择 Issue**: 从 Issues 列表中选择要解决的问题
2. **开发**: 在本地开发和测试
3. **提交 PR**: 创建 Pull Request
4. **代码审查**: 等待维护者审查
5. **合并**: 审查通过后合并到 `develop`(发版时再合 `main`
5. **合并**: 审查通过后合并到 `staging`,测试通过后再通过 PR 晋级 `main`

## 代码审查标准

Expand All @@ -168,4 +168,3 @@
- 联系维护者

感谢你的贡献!🎉

18 changes: 9 additions & 9 deletions CONTRIBUTING_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -80,24 +80,24 @@ 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

1. Pick or file an issue
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

Expand Down
Loading