# Bitbucket Pipelines – macOS Self-Hosted Runner Setup

This guide helps you add a **self-hosted macOS runner** so the **develop** branch can run iOS build and TestFlight deploy steps. Without an online runner matching the required labels, you will see:

> **Currently no online runner available that matches the required labels.**

---

## Required labels in `bitbucket-pipelines.yml`

Our iOS steps use:

```yaml
runs-on:
  - self.hosted
  - macos
```

The runner you register **must** have both labels. Bitbucket adds them by default when you create a macOS runner; do not remove them.

---

## 1. Where to add the runner

**Option A – Repository runner (this repo only)**  
1. Open the repo: `overdrive/flutter_app` (or your repo).  
2. **Repository settings** (left sidebar) → **Pipelines** → **Runners**.  
3. **Add runner**.

**Option B – Workspace runner (all repos in workspace)**  
1. Click the **gear** (Settings) in the top bar.  
2. **Workspace settings** → **Pipelines** → **Workspace runners**.  
3. **Add runner**.

If you don’t see “Runners”, your plan or role may limit it; try workspace settings or ask an admin.

---

## 2. Create the macOS runner

1. **Add runner** → **System and architecture** → choose **MacOS (x86 / Apple Silicon)**.  
2. **Runner name**: e.g. `datafy-mac-ios`.  
3. **Runner labels**: Leave the defaults **self.hosted** and **macos** (they are added automatically). Add extra labels only if you need them.  
4. **Next** → Bitbucket shows the **Runner installation** dialog.

---

## 3. Install and start the runner on your Mac

**Prerequisites on the Mac:**

- 64-bit macOS, at least 8 GB RAM  
- [OpenJDK 11](https://openjdk.org/) (11.0.11 or newer)  
- [Git](https://git-scm.com/) 2.35.0 or newer  

**Steps:**

1. In the **Runner installation** dialog, **download the `.tar.gz`** from the **Run** step.  
2. On your Mac, untar to a directory, e.g.:
   ```bash
   mkdir -p ~/atlassian_runner && cd ~/atlassian_runner
   tar -xzf /path/to/downloaded-runner.tar.gz
   ```
3. In the same dialog, Bitbucket shows a **command** to start the runner (includes token). **Copy it** – it is shown only once.  
4. In Terminal, go to the **bin** directory under the runner folder and run the provided command, e.g.:
   ```bash
   cd ~/atlassian_runner/bin
   ./run.sh  # or the exact command Bitbucket gave you
   ```
5. Leave the terminal open so the runner stays running. The runner must be **online** for pipelines to use it.

**Optional – run as a service (keep runner online after logout):**  
Use macOS `launchd` (see [Apple: Scheduling Timed Jobs](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/ScheduledJobs.html)) or run the runner in a persistent terminal (e.g. `tmux`/`screen`).

---

## 4. Verify the runner is online

1. Go back to **Repository settings** (or **Workspace settings**) → **Pipelines** → **Runners**.  
2. Find your runner. Its status should be **Online** (green).  
3. If it stays **Unregistered** or **Offline**, the start command was not run successfully on the Mac; run it again and check for errors in the terminal.

---

## Troubleshooting

### “Currently no online runner available that matches the required labels”

| Check | Action |
|-------|--------|
| Runner status | In **Runners**, confirm the macOS runner is **Online**. If Offline/Unregistered, start it on the Mac (see step 3). |
| Labels | Runner must have **self.hosted** and **macos**. When creating the runner, do not remove the default labels. |
| Same scope | Repository pipeline uses **repository** runners first; if you added a **workspace** runner, ensure workspace runners are allowed for the repo. |
| One runner, many steps | Only one job runs per runner at a time. If the runner is busy, the step waits; if it’s offline, the step fails. |

### Runner goes offline

- The runner process must keep running on the Mac (terminal open or run as a service).  
- Sleep, shutdown, or closing the terminal stops the runner.  
- Restart the runner with the same `bin` command (you need a new token only if you delete and re-add the runner in Bitbucket).

### “The Size feature is not supported on this self-hosted runner’s platform”

- Do **not** use `size: 2x` (or any `size:`) in steps that use `runs-on: self.hosted`. Our iOS steps already omit `size`.

### CocoaPods: “specs repository is too out-of-date” or “ffi extensions are not built”

- The pipeline runs **`bundle exec pod repo update`** before **`bundle exec pod install`** so the CocoaPods specs are up to date. If you still see “specs repository is too out-of-date” locally, run: **`cd ios && pod repo update && pod install`** (or `bundle exec pod repo update && bundle exec pod install`).
- For “Ignoring ffi because its extensions are not built”, the pipeline runs **`gem pristine ffi`** before `pod install`. Locally you can run: **`gem pristine ffi --version 1.16.3`** (use the version shown in the message).

### macOS runner limitations (Bitbucket)

- **Pipes** and **service containers** are not supported on self-hosted macOS runners.  
- **Pre-defined Docker caches** are not supported; we use `flutter` and `cocoapods` caches, which are supported.  
- The machine is shared: installs or changes on the host affect later steps. Avoid global installs in pipeline scripts when possible.

---

## References

- [Set up runners for MacOS](https://support.atlassian.com/bitbucket-cloud/docs/set-up-runners-for-macos)  
- [Adding a new runner in Bitbucket](https://support.atlassian.com/bitbucket-cloud/docs/adding-a-new-runner-in-bitbucket)  
- [Configure your runner in bitbucket-pipelines.yml](https://support.atlassian.com/bitbucket-cloud/docs/configure-your-runner-in-bitbucket-pipelines-yml)
