Skip to content

Commit d9513cd

Browse files
Merge pull request #8 from alirezarezvani/dev
2 parents 6cc4681 + a451691 commit d9513cd

25 files changed

Lines changed: 2083 additions & 1900 deletions

.github/BRANCH_PROTECTION.md

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# Branch Protection & Branching Strategy
2+
3+
This repository follows a strict **three-tier branching strategy**. Working
4+
branches always flow into `dev`, and `dev` is the **only** branch allowed to
5+
merge into `main`. The GitHub Actions workflows in this repo enforce parts of
6+
this automatically; the remaining enforcement is done via GitHub branch
7+
protection rules (configured once in the repository settings).
8+
9+
```
10+
working branch ── PR ──► dev ── PR ──► main ── release.yml ──► GitHub Release
11+
(feature-*, │
12+
fix-*, docs-*, │
13+
refactor-*, chore-*) └── wiki-sync.yml ──► Wiki
14+
```
15+
16+
## Working branches
17+
18+
Naming convention (enforced by `auto-pr-dev.yml`):
19+
20+
| Prefix | Used for | Auto labels |
21+
|--------------|--------------------------------|-------------------------|
22+
| `feature-*` | New features / enhancements | `feature`, `enhancement`|
23+
| `fix-*` | Bug fixes | `bug`, `fix` |
24+
| `docs-*` | Documentation only | `documentation` |
25+
| `refactor-*` | Refactors (no behavior change) | `refactoring` |
26+
| `chore-*` | Maintenance, CI, tooling | `chore` |
27+
28+
When linked to an issue, use `{prefix}-{issue-number}-{slug}`
29+
(e.g. `feature-42-trending-keywords`). The `branch-lifecycle.yml` workflow
30+
creates these branches automatically when an issue is labelled `ready`.
31+
32+
## Workflow map
33+
34+
| Workflow | Trigger | Purpose |
35+
|---------------------------|--------------------------------------------------|----------------------------------------|
36+
| `auto-pr-dev.yml` | Push to `feature-*`/`fix-*`/`docs-*`/`refactor-*`/`chore-*` | Auto-create PR into `dev` |
37+
| `auto-pr-main.yml` | Manual (`workflow_dispatch`) | Create release PR from `dev` to `main` |
38+
| `branch-lifecycle.yml` | Issue labelled `ready`, PR sync/close | Create branch / rebase / delete |
39+
| `python-quality.yml` | PR + push to `dev`/`main` (python paths) | Ruff lint/format + syntax matrix |
40+
| `security.yml` | PR + push to `dev`/`main` + weekly cron | CodeQL, TruffleHog, dependency audit |
41+
| `claude-code-review.yml` | PR to `dev`/`main` | Size labels + AI review on dev PRs |
42+
| `claude-main-check.yml` | PR to `main` | Enforce `dev`-only source + final AI gate |
43+
| `claude.yml` | `@claude` mention | On-demand assistant |
44+
| `wiki-sync.yml` | Push to `main` (docs paths) | Mirror docs to GitHub Wiki |
45+
| `release.yml` | Push to `main` | Build skill ZIP + tag + GitHub Release |
46+
| `labels.yml` | Push to `main`/`dev` touching label manifest | Sync `.github/labels.yml` |
47+
48+
## Required branch protection rules
49+
50+
Configure these once in **Settings → Branches** (or via `gh api`). The CI status
51+
check names below match the workflow job names exactly.
52+
53+
## One-time repository settings
54+
55+
Before the automation can work end-to-end, two repository-level toggles must
56+
be flipped (these cannot be set from a workflow):
57+
58+
1. **Settings → Actions → General → Workflow permissions**
59+
- Set to **"Read and write permissions"**
60+
- Tick **"Allow GitHub Actions to create and approve pull requests"**
61+
62+
Without this, `auto-pr-dev.yml` and `auto-pr-main.yml` will fail with
63+
`GitHub Actions is not permitted to create or approve pull requests`,
64+
even though the workflows themselves declare `pull-requests: write`.
65+
66+
2. **Settings → Actions → General → Fork pull request workflows from outside
67+
collaborators** — set to **"Require approval for first-time contributors"**
68+
(default is fine). Workflows that need a write token (auto-rebase,
69+
auto-PR) intentionally skip fork branches in `branch-lifecycle.yml`, so
70+
this is mainly belt-and-braces.
71+
72+
### `main` (protected, release branch)
73+
74+
- Require a pull request before merging
75+
- Required approvals: **1**
76+
- Dismiss stale approvals when new commits are pushed
77+
- Require review from Code Owners
78+
- Require status checks to pass before merging
79+
- Require branches to be up to date before merging: **enabled**
80+
- Required status checks:
81+
- `Quality Summary` (from `python-quality.yml`)
82+
- `Security Summary` (from `security.yml`)
83+
- `Enforce dev to main rule` (from `claude-main-check.yml`)
84+
- `Claude Release Validation` (from `claude-main-check.yml`)
85+
- Require conversation resolution before merging
86+
- Require linear history
87+
- Restrict who can push to matching branches (admins only)
88+
- Do not allow bypassing the above settings
89+
- Allow force pushes: **off**
90+
- Allow deletions: **off**
91+
- Restrict pushes that create files larger than 100 MB
92+
93+
### `dev` (protected, integration branch)
94+
95+
- Require a pull request before merging
96+
- Required approvals: **1**
97+
- Dismiss stale approvals when new commits are pushed
98+
- Require review from Code Owners
99+
- Require status checks to pass before merging
100+
- Require branches to be up to date before merging: **enabled**
101+
- Required status checks:
102+
- `Quality Summary` (from `python-quality.yml`)
103+
- `Security Summary` (from `security.yml`)
104+
- `Claude Code Review` (from `claude-code-review.yml`)
105+
- Require conversation resolution before merging
106+
- Require linear history
107+
- Allow force pushes: **off**
108+
- Allow deletions: **off**
109+
110+
### Working branches (`feature-*`, `fix-*`, `docs-*`, `refactor-*`, `chore-*`)
111+
112+
- Allow force pushes (with lease) so the auto-rebase step can keep the branch
113+
current with `dev`.
114+
- No required reviews (review happens on the resulting PR to `dev`).
115+
- Will be auto-deleted by `branch-lifecycle.yml` after the PR merges.
116+
117+
## One-shot setup with `gh`
118+
119+
The block below applies the recommended protection to `main` and `dev`. Adjust
120+
the required check names if you rename a workflow.
121+
122+
```bash
123+
# main
124+
gh api -X PUT "repos/${OWNER}/${REPO}/branches/main/protection" \
125+
-H "Accept: application/vnd.github+json" \
126+
-f required_status_checks.strict=true \
127+
-F required_status_checks.contexts[]='Quality Summary' \
128+
-F required_status_checks.contexts[]='Security Summary' \
129+
-F required_status_checks.contexts[]='Enforce dev to main rule' \
130+
-F required_status_checks.contexts[]='Claude Release Validation' \
131+
-f enforce_admins=true \
132+
-F required_pull_request_reviews.required_approving_review_count=1 \
133+
-F required_pull_request_reviews.dismiss_stale_reviews=true \
134+
-F required_pull_request_reviews.require_code_owner_reviews=true \
135+
-f required_linear_history=true \
136+
-f allow_force_pushes=false \
137+
-f allow_deletions=false \
138+
-f restrictions=null
139+
140+
# dev
141+
gh api -X PUT "repos/${OWNER}/${REPO}/branches/dev/protection" \
142+
-H "Accept: application/vnd.github+json" \
143+
-f required_status_checks.strict=true \
144+
-F required_status_checks.contexts[]='Quality Summary' \
145+
-F required_status_checks.contexts[]='Security Summary' \
146+
-F required_status_checks.contexts[]='Claude Code Review' \
147+
-f enforce_admins=false \
148+
-F required_pull_request_reviews.required_approving_review_count=1 \
149+
-F required_pull_request_reviews.dismiss_stale_reviews=true \
150+
-F required_pull_request_reviews.require_code_owner_reviews=true \
151+
-f required_linear_history=true \
152+
-f allow_force_pushes=false \
153+
-f allow_deletions=false \
154+
-f restrictions=null
155+
```
156+
157+
## Release flow
158+
159+
1. Open a PR from a working branch to `dev` (auto-created on first push).
160+
2. Quality + security + AI review run. Address feedback, get 1 approval, merge.
161+
3. When ready to release, run **Actions → Auto-Create Release PR (dev to main)**
162+
and pick `patch`/`minor`/`major`.
163+
4. The release PR is reviewed; `claude-main-check.yml` enforces that the PR
164+
came from `dev` and runs a minimal final gate.
165+
5. On merge, `release.yml` reads the version from `pyproject.toml`, builds
166+
`app-store-optimization-<version>.zip`, tags `v<version>`, and creates the
167+
GitHub Release with notes from `CHANGELOG.md`.
168+
6. `wiki-sync.yml` updates the wiki from the new `main`.
169+
170+
## Secrets and variables required
171+
172+
| Name | Type | Used by |
173+
|----------------------------|---------|---------------------------------------------------------|
174+
| `CLAUDE_CODE_OAUTH_TOKEN` | Secret | `claude.yml`, `claude-code-review.yml`, `claude-main-check.yml` |
175+
| `GITHUB_TOKEN` (built-in) | Secret | all workflows |
176+
| `PROJECT_VERSION` | Var (optional) | `wiki-sync.yml` (defaults to `1.0.0`) |

.github/labels.yml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Labels managed declaratively by .github/workflows/labels.yml
2+
# Adding/removing/editing a label here updates the repository on the next push.
3+
#
4+
# Note: color values are quoted strings so that hex codes containing only
5+
# digits (for example 000000) are not silently coerced to numbers by the
6+
# YAML parser - EndBug/label-sync rejects non-string colors.
7+
8+
# --- Type / category ---
9+
- name: feature
10+
color: 'a2eeef'
11+
description: New feature or capability
12+
- name: enhancement
13+
color: '84b6eb'
14+
description: Improvement to an existing feature
15+
- name: bug
16+
color: 'd73a4a'
17+
description: Something is not working
18+
- name: fix
19+
color: 'e99695'
20+
description: Bug fix
21+
- name: documentation
22+
color: '0075ca'
23+
description: Documentation changes
24+
- name: refactoring
25+
color: 'c2e0c6'
26+
description: Code refactoring (no behavior change)
27+
- name: chore
28+
color: 'cfd3d7'
29+
description: Maintenance and tooling work
30+
- name: security
31+
color: 'ee0701'
32+
description: Security-related change
33+
- name: performance
34+
color: 'fbca04'
35+
description: Performance improvement
36+
- name: dependencies
37+
color: '0366d6'
38+
description: Dependency update
39+
- name: github-actions
40+
color: '000000'
41+
description: GitHub Actions workflow change
42+
- name: python
43+
color: '3572A5'
44+
description: Python language related
45+
46+
# --- Lifecycle ---
47+
- name: ready
48+
color: '0e8a16'
49+
description: Issue is ready to be picked up (triggers branch automation)
50+
- name: in-progress
51+
color: 'fbca04'
52+
description: Work is actively in progress
53+
- name: completed
54+
color: '6f42c1'
55+
description: Work has been merged and the issue is closed
56+
- name: release
57+
color: '5319e7'
58+
description: Release PR (dev to main)
59+
- name: blocked
60+
color: 'b60205'
61+
description: Blocked by another item
62+
63+
# --- PR size ---
64+
- name: 'size: XS'
65+
color: '00ff7f'
66+
description: Tiny PR (<50 changes)
67+
- name: 'size: S'
68+
color: '7fff00'
69+
description: Small PR (50-199 changes)
70+
- name: 'size: M'
71+
color: 'ffff00'
72+
description: Medium PR (200-499 changes)
73+
- name: 'size: L'
74+
color: 'ffa500'
75+
description: Large PR (500-999 changes)
76+
- name: 'size: XL'
77+
color: 'ff0000'
78+
description: Extra large PR (>=1000 changes)

0 commit comments

Comments
 (0)