Merge pull request 'docs: add CICD.md (pipeline flow)' (#27) from docs/cicd-flow into develop
Some checks failed
CI / build-and-test (push) Has been cancelled
Some checks failed
CI / build-and-test (push) Has been cancelled
This commit is contained in:
75
docs/CICD.md
Normal file
75
docs/CICD.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# CI/CD Flow
|
||||||
|
|
||||||
|
How a change travels from a local branch to TestFlight, and where the gates are.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
A["feature/* branch · local<br/><i>pre-push hook blocks main</i>"]
|
||||||
|
B["Pull request → develop<br/><i>develop is the default branch</i>"]
|
||||||
|
C["CI · ci.yml (macOS runner)<br/><i>xcodebuild build + test</i>"]
|
||||||
|
D{"Merge gate<br/>CI green + 1 approval"}
|
||||||
|
E["Pull request develop → main<br/><i>same gate</i>"]
|
||||||
|
F["Release · release.yml<br/><i>archive → IPA → TestFlight</i>"]
|
||||||
|
|
||||||
|
A -->|git push · open PR| B
|
||||||
|
B -->|PR triggers CI| C
|
||||||
|
C -->|status check: build-and-test| D
|
||||||
|
D -->|promote when ready| E
|
||||||
|
E -->|on merge to main| F
|
||||||
|
```
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
|
1. **`feature/*` branch (local).** Branch off `develop`. A local
|
||||||
|
`.git/hooks/pre-push` hook rejects any direct push to `main`, so nothing
|
||||||
|
reaches the protected branch outside a PR.
|
||||||
|
|
||||||
|
2. **PR → `develop`.** `develop` is the default branch and the integration
|
||||||
|
target for all feature work.
|
||||||
|
|
||||||
|
3. **CI runs** — [`.gitea/workflows/ci.yml`](../.gitea/workflows/ci.yml) on the
|
||||||
|
self-hosted **macOS runner**. It runs `xcodebuild build` then
|
||||||
|
`xcodebuild test` (the `KisaniCalTests` target on an iOS simulator). The
|
||||||
|
result is published as a commit status named **`build-and-test`**.
|
||||||
|
|
||||||
|
4. **Merge gate.** Gitea branch protection blocks the merge until:
|
||||||
|
- the `build-and-test` status check is **green**,
|
||||||
|
- there is **≥ 1 approval**,
|
||||||
|
- there are no rejected reviews, and
|
||||||
|
- the branch is up to date with its base.
|
||||||
|
|
||||||
|
The same gate guards both `develop` and `main`.
|
||||||
|
|
||||||
|
5. **Promote `develop` → `main`** via a second PR when a release is ready. It
|
||||||
|
passes through the identical gate.
|
||||||
|
|
||||||
|
6. **Release runs** — [`.gitea/workflows/release.yml`](../.gitea/workflows/release.yml)
|
||||||
|
fires **only** on push to `main` (i.e. after a PR merges). It archives,
|
||||||
|
exports an IPA via [`ExportOptions.plist`](../ExportOptions.plist), and
|
||||||
|
uploads to **TestFlight** (currently a commented-out placeholder awaiting the
|
||||||
|
App Store Connect API-key secrets).
|
||||||
|
|
||||||
|
## Two automation halves
|
||||||
|
|
||||||
|
- **CI** (steps 3–4) gates **every** PR into `main`/`develop`.
|
||||||
|
- **Release** (step 6) runs **only** on `main`.
|
||||||
|
|
||||||
|
Blue/manual steps are actions you take; CI and Release run unattended on the
|
||||||
|
runner.
|
||||||
|
|
||||||
|
## Requirements & gotchas
|
||||||
|
|
||||||
|
- **Runner labels.** Both workflows use `runs-on: [self-hosted, macOS]`. The
|
||||||
|
registered runner must carry **both** labels or jobs queue forever. Check at
|
||||||
|
Settings → Actions → Runners.
|
||||||
|
- **Status-check name.** Branch protection requires a check literally named
|
||||||
|
`build-and-test` (the CI job name). If the rendered context differs, update
|
||||||
|
the rule (`scripts/gitea-setup.sh`, `STATUS_CONTEXT`).
|
||||||
|
- **Simulator.** The runner needs an installed iOS runtime (Xcode → Settings →
|
||||||
|
Components) — CI auto-selects the first available iPhone simulator.
|
||||||
|
- **Signing.** CI builds with `CODE_SIGNING_ALLOWED=NO`. The Release job needs a
|
||||||
|
distribution cert + profile in the runner's login keychain.
|
||||||
|
- **Build number.** `CURRENT_PROJECT_VERSION` in `project.yml` must increase for
|
||||||
|
every TestFlight upload — App Store Connect rejects a repeated build number.
|
||||||
|
|
||||||
|
See also [CONTRIBUTING.md](../CONTRIBUTING.md) for the branch workflow.
|
||||||
Reference in New Issue
Block a user