# Contributing to Jarvis ## Branch workflow ``` feature/* ──→ develop ──→ main ``` - **`main`** — protected. No direct pushes. Every change arrives via PR from `develop`. - **`develop`** — integration branch. All feature work merges here first. CI runs on every push. - **`feature/*`** — short-lived branches cut from `develop`. ## Starting work ```bash git checkout develop git pull origin develop git checkout -b feature/your-description ``` ## Opening a PR 1. Push your feature branch and open a PR targeting **`develop`**. 2. CI must pass (Debug + Release builds succeed). 3. At least 1 approval required before merge. ## Releasing to TestFlight A maintainer opens a PR from `develop → main`. Merging triggers the release workflow: archive → export IPA → upload to TestFlight. --- ## Runner setup (one-time, on your Mac) Gitea Actions requires a self-hosted runner. The CI workflows target `[self-hosted, macos]`. ### 1. Enable Gitea Actions (admin, once per instance) In `app.ini` on the Gitea server, add: ```ini [actions] ENABLED = true ``` Then restart Gitea. ### 2. Install act_runner on the Mac There is no Homebrew formula — download the official binary: ```bash curl -sL -o /usr/local/bin/act_runner \ https://dl.gitea.com/act_runner/0.6.1/act_runner-0.6.1-darwin-arm64 chmod +x /usr/local/bin/act_runner ``` ### 3. Register the runner Get a registration token from: **Repository Settings → Actions → Runners → Create Runner** (or via API: `GET /api/v1/repos/kutesir/jarvis/actions/runners/registration-token`) The `:host` label suffix is required — it makes jobs run directly on the Mac instead of in Docker (which xcodebuild needs, and the Mac has no Docker): ```bash mkdir -p ~/.act_runner && cd ~/.act_runner act_runner register --no-interactive \ --instance http://10.10.1.21:3002 \ --token \ --name "mac-mini" \ --labels "self-hosted:host,macos:host" ``` ### 4. Configure and start the runner Generate the config, then fix two defaults that break Docker-less Macs (the generated config ships Docker-based ubuntu labels that make the daemon refuse to start without a Docker socket): ```bash cd ~/.act_runner act_runner generate-config > config.yaml # 1. labels: [] — empty falls back to the :host labels in .runner # 2. docker_host: "-" — never look for a Docker daemon ``` In `config.yaml`, set: - `labels: []` (replace the default ubuntu docker labels) - `docker_host: "-"` (under `container:`) Then start it: ```bash act_runner daemon --config ~/.act_runner/config.yaml ``` To keep it running across reboots, load it as a LaunchAgent (`~/Library/LaunchAgents/com.gitea.act-runner.plist`, see repo scripts). The runner must have **Xcode 16+** installed and accepted the license: ```bash sudo xcodebuild -license accept ``` --- ## Signing and TestFlight secrets For the release workflow to archive and upload, the runner Mac needs: 1. The **iOS Distribution certificate** installed in its keychain (set up once in Xcode → Settings → Accounts → Manage Certificates). 2. Three **Gitea secrets** set under: **Repository Settings → Actions → Secrets** | Secret | Where to get it | |---|---| | `ASC_KEY_ID` | App Store Connect → Users & Access → API Keys | | `ASC_ISSUER_ID` | Same page, above the key list | | `ASC_PRIVATE_KEY` | The `.p8` file downloaded when you created the key (only downloadable once) | --- ## Branch protection (manual setup in Gitea UI) Go to **Repository Settings → Branches → Add Branch Rule**: | Setting | Value | |---|---| | Branch name pattern | `main` | | Require pull request before merging | ✅ | | Required approvals | 1 | | Require status checks to pass | ✅ — select `Build · Debug` and `Build · Release` | | Block force push | ✅ | | Block deletion | ✅ | Repeat with `develop` but set required approvals to 0 (CI gate only).