Files
halobestie-clone/.github/workflows/README.md
Ramadhan Sjamsani 816e037a9a ci: add parameterized build workflow (env x target x platform)
Manually-triggered, build-only GitHub Actions workflow on GitHub-hosted
runners. Inputs: environment (staging/prod), target (all/customer/mitra/
backend/control_center), platform (android/ios/both). Runner split: iOS app
jobs run on macos-latest, all else on ubuntu-latest. Apps build debug-signed
APKs; control_center bakes VITE_API_BASE_URL; backend exports a docker-save
tarball. iOS jobs await per-flavor Xcode schemes + signing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 15:10:59 +08:00

66 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CI Workflows
## `build.yml` — parameterized build
Manually-triggered, **build-only** pipeline (no push, no deploy). Produces downloadable artifacts.
### How to run
1. GitHub → **Actions** tab → **Build** (left sidebar) → **Run workflow**.
2. Pick:
- **environment** — `staging` or `prod`
- **target** — `all`, `customer`, `mitra`, `backend`, or `control_center`
- **platform** — `android`, `ios`, or `both` (only affects the customer/mitra apps; ignored for backend/control_center)
3. **Run workflow**. Open the run; artifacts appear at the bottom of the summary page when it finishes.
(You can also trigger it from the CLI: `gh workflow run build.yml -f environment=staging -f target=all -f platform=android`.)
### Runner split (Linux vs macOS)
iOS can only be built on macOS, so the workflow routes jobs accordingly:
| Job | Runner |
|---|---|
| `customer-ios`, `mitra-ios` | `macos-latest` |
| `customer-android`, `mitra-android`, `backend`, `control_center` | `ubuntu-latest` |
> ⚠️ **macOS runner minutes bill at ~10× Linux.** That's why `platform` defaults to `android`. Choose `ios`/`both` deliberately.
### What each target produces
| Target | Platform | Tool | Artifact | Notes |
|---|---|---|---|---|
| `customer` | android | Flutter | `customer-<env>-android-apk``app-<env>-release.apk` | Debug-signed (no keystore in repo). Fine for internal/Firebase App Distribution. |
| `customer` | ios | Flutter | `customer-<env>-ios-app` (`Runner.app`) | **Unsigned** (`--no-codesign`). See iOS prerequisites below. |
| `mitra` | android | Flutter | `mitra-<env>-android-apk` | Same as customer-android. |
| `mitra` | ios | Flutter | `mitra-<env>-ios-app` | Same caveats as customer-ios. |
| `control_center` | — | Vite | `control-center-<env>-dist` (the `dist/` folder) | `VITE_API_BASE_URL` baked in at build time — see below. |
| `backend` | — | Docker | `backend-<env>-image` (`*.tar.gz`) | Env-**agnostic** image (config is runtime env vars). Load with `docker load`. |
`all` runs every selected job in parallel; each is independent, so one failing doesn't block the others.
### ⚠️ iOS prerequisites (not satisfied yet)
The iOS jobs are wired but will **fail until two things are done**:
1. **Per-flavor Xcode schemes** (`staging`, `prod`) must exist in `ios/Runner.xcodeproj`. Today there's only the default `Runner` scheme, so `flutter build ios --flavor staging` errors with *"The Xcode project does not define custom schemes"*. This mirrors the Android flavor setup but on the iOS side (schemes + build configurations + per-config bundle IDs).
2. **Code signing** for a distributable `.ipa`: Apple Developer certificate + provisioning profiles stored as GitHub secrets. The current jobs use `--no-codesign`, which only validates that the app **compiles** and produces an unsigned `Runner.app` (not installable on devices).
Until then, `platform=ios`/`both` is useful only once the schemes land. `platform=android` works today.
### Environment specifics
- **Apps (customer/mitra):** `environment` selects the Flutter flavor + entrypoint + `env/<env>.json` (`--flavor`, `-t lib/main_<env>.dart`, `--dart-define-from-file`). Reminder: `env/staging.json` still has a **placeholder API URL** until the staging backend is deployed.
- **control_center:** `VITE_API_BASE_URL` is compiled in. Defaults: prod → `https://internal.halobestie.com`, staging → `https://staging-internal.halobestie.com`. Override without editing the workflow by setting repo **Variables** (Settings → Secrets and variables → Actions → Variables): `CC_API_BASE_URL_PROD`, `CC_API_BASE_URL_STAGING`.
- **backend:** the image is identical across environments; env/secrets are supplied at `docker run` time (see [backend/DEPLOY.md](../../backend/DEPLOY.md)). The `<env>` in the artifact name is just a label.
### Deploying a build artifact (manual, since we don't push yet)
- **Backend:** download `backend-<env>-image`, copy to the host, then:
```bash
gunzip -c halobestie-backend-<env>.tar.gz | docker load
# then run per backend/DEPLOY.md
```
- **control_center:** download `control-center-<env>-dist`, serve the `dist/` behind Nginx (internal-only).
- **Apps:** download the APK and install / upload to Firebase App Distribution.
### Pinned versions
Flutter `3.41.9`, JDK `17`, Node `20` (see `env:` block in [build.yml](build.yml)). Bump them there when the team upgrades.
### Not included yet (by design)
Pushing images to a registry and deploying are intentionally out of scope for this first iteration. When you're ready, the natural next step is a `release.yml` that pushes to GHCR and (optionally, via a self-hosted runner or SSH) deploys to the VPS.