# GitHub Self-Hosted Runner Management Guide

## SSH Connection

### Connection Details
- **Host:** 100.126.148.125
- **User:** githubrunner
- **SSH Key:** ~/.ssh/id_rsa_remarkable (passwordless)
- **Connection Command:** `ssh -i ~/.ssh/id_rsa_remarkable githubrunner@100.126.148.125`

### User Configuration
- **User:** githubrunner
- **Groups:** staff, everyone, localaccounts, com.apple.access_ssh, etc.
- **Home Directory:** /Users/githubrunner
- **Shell:** zsh (default)
- **Sudo Access:** Configured for passwordless sudo (NOPASSWD: ALL)

## Runner Configuration

### Runner Installation
- **Location:** ~/actions-runner
- **Version:** 2.331.0
- **Organization:** coredevices
- **Runner Name:** mac-mini-github-runner
- **Labels:** self-hosted, macOS, ARM64
- **Working Directory:** ~/actions-runner/_work

### Runner Files Structure
```
~/actions-runner/
├── .credentials          # Runner registration credentials
├── .credentials_rsaparams
├── .env                  # Environment variables for runner
├── .path                 # PATH configuration for runner
├── .runner               # Runner configuration (JSON)
├── .service              # Service configuration marker
├── bin/                  # Runner binaries
├── config.sh             # Configuration script
├── run.sh                # Start runner script
├── runsvc.sh            # Service wrapper script
├── svc.sh               # Service management script
├── _work/               # Job working directory
└── _diag/               # Diagnostic logs
```

### Important Configuration Files

#### .env File
Contains environment variables used by the runner:
```bash
LANG=en_US.UTF-8
JAVA_HOME=/opt/homebrew/opt/openjdk@17
DEVELOPER_DIR=/Applications/Xcode_26.2.app/Contents/Developer
```

#### .path File
PATH entries for the runner (one per line, order matters):
```
/opt/homebrew/opt/openjdk@17/bin
/opt/homebrew/opt/ruby/bin
/opt/homebrew/lib/ruby/gems/4.0.0/bin
/opt/homebrew/bin
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
```

**Critical:** The runner uses `.env` and `.path` files, NOT ~/.zshrc. Always update these files when adding new tools or environment variables.

#### .runner File
JSON configuration showing:
```json
{
  "agentId": 64,
  "agentName": "mac-mini-github-runner",
  "poolId": 1,
  "poolName": "Default",
  "serverUrl": "https://pipelinesghubeus24.actions.githubusercontent.com/...",
  "gitHubUrl": "https://github.com/coredevices",
  "workFolder": "_work"
}
```

## Running the Runner

### Manual Start (Current Method)
```bash
cd ~/actions-runner
nohup ./run.sh > runner.log 2>&1 &
```

**Check if running:**
```bash
ps aux | grep "Runner.Listener" | grep -v grep
```

**View logs:**
```bash
tail -f ~/actions-runner/runner.log
```

**Stop runner:**
```bash
pkill -f "Runner.Listener"
```

### Service Management (Auto-Start)

#### Using Built-in Service Script
```bash
cd ~/actions-runner

# Install service (creates LaunchAgent)
./svc.sh install githubrunner

# Start service
./svc.sh start

# Stop service
./svc.sh stop

# Check status
./svc.sh status

# Uninstall service
./svc.sh uninstall
```

#### LaunchAgent Location
- **User LaunchAgent:** `~/Library/LaunchAgents/actions.runner.coredevices.mac-mini-github-runner.plist`
- **Logs:** `~/Library/Logs/actions.runner.coredevices.mac-mini-github-runner/`

#### Important LaunchAgent Limitations

**SSH Session Limitations:**
When connected via SSH without a GUI session, LaunchAgent commands may fail with errors like:
- `Bootstrap failed: 125: Domain does not support specified action`
- `Could not enable service: 125: Domain does not support specified action`

**This is because:**
1. User LaunchAgents require an active GUI session
2. SSH connections don't create GUI sessions by default
3. `launchctl bootstrap gui/$(id -u)` and `launchctl enable gui/$(id -u)/...` require GUI context

**Workarounds:**
1. **Manual start via SSH:** Use `nohup ./run.sh &` (currently implemented)
2. **GUI login:** Have the user log in via VNC/console, then service will auto-start
3. **System Service:** Convert to system-level LaunchDaemon (requires running as root/system)

**Auto-Start Behavior:**
- LaunchAgent is configured with `<key>RunAtLoad</key><true/>`
- Will automatically start when githubrunner user logs in via GUI
- Will NOT auto-start from SSH-only sessions
- Will auto-start after system reboot IF user has auto-login enabled

## Environment Configuration

### Shell Configuration (~/.zshrc)
The shell configuration is set up but NOT used by the runner directly:
```bash
# Homebrew environment
eval "$(/opt/homebrew/bin/brew shellenv)"

# Ruby from Homebrew
export PATH="/opt/homebrew/opt/ruby/bin:$PATH"
export PATH="/opt/homebrew/lib/ruby/gems/4.0.0/bin:$PATH"

# Java 17
export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH"
export JAVA_HOME="/opt/homebrew/opt/openjdk@17"

# Xcode
export DEVELOPER_DIR="/Applications/Xcode_26.2.app/Contents/Developer"
```

**Important:** This is for interactive shell sessions only. The runner uses `.env` and `.path` files instead.

### Installed Software

| Component | Version | Location |
|-----------|---------|----------|
| Homebrew | 5.0.12 | /opt/homebrew |
| Xcode | 26.2 (17C52) | /Applications/Xcode_26.2.app |
| Java (OpenJDK) | 17.0.18 | /opt/homebrew/opt/openjdk@17 |
| Gradle | 9.3.1 | /opt/homebrew/bin/gradle |
| Ruby | 4.0.1 | /opt/homebrew/opt/ruby |
| Bundler | 4.0.4 & 4.0.5 | /opt/homebrew/lib/ruby/gems/4.0.0/bin |
| CocoaPods | 1.16.2 | /opt/homebrew/lib/ruby/gems/4.0.0/bin |
| xcpretty | 0.4.1 | /opt/homebrew/lib/ruby/gems/4.0.0/bin |
| Git | 2.52.0 | /opt/homebrew/bin/git |
| Git LFS | 3.7.1 | /opt/homebrew/bin/git-lfs |
| xcodes CLI | 1.6.2 | /opt/homebrew/bin/xcodes |

### Tool Verification Commands
```bash
# Via SSH
ssh -i ~/.ssh/id_rsa_remarkable githubrunner@100.126.148.125 '
  echo "=== Xcode ===" && xcodebuild -version
  echo "=== Java ===" && /opt/homebrew/opt/openjdk@17/bin/java -version 2>&1 | head -2
  echo "=== Gradle ===" && /opt/homebrew/bin/gradle --version | grep Gradle | head -1
  echo "=== Ruby ===" && /opt/homebrew/opt/ruby/bin/ruby --version
  echo "=== CocoaPods ===" && /opt/homebrew/lib/ruby/gems/4.0.0/bin/pod --version
  echo "=== xcpretty ===" && /opt/homebrew/lib/ruby/gems/4.0.0/bin/xcpretty --version
  echo "=== Git ===" && /opt/homebrew/bin/git --version
  echo "=== Git LFS ===" && /opt/homebrew/bin/git-lfs version
'
```

## Workflow Configuration

### Workflow File: .github/workflows/build-ios.yml
- **Runner:** `runs-on: [self-hosted, macOS, ARM64]`
- **Xcode Setup:** Uses `sudo xcode-select` (requires passwordless sudo)
- **Removed Steps:** JDK setup, Swift setup, xcpretty installation (pre-installed)

### Workflow Requirements Met
- Git 2.52.0 with Git LFS
- Xcode 26.2 (Build 17C52)
- Java 17 (Temurin)
- Gradle 9.3+
- Ruby 4.0+
- CocoaPods 1.16.2
- xcpretty
- Passwordless sudo
- Keychain access for code signing

## Quick Reference Commands

```bash
# Connect to runner
ssh -i ~/.ssh/id_rsa_remarkable githubrunner@100.126.148.125

# Check runner status
ps aux | grep "Runner.Listener" | grep -v grep

# Start runner
cd ~/actions-runner && nohup ./run.sh > runner.log 2>&1 &

# Stop runner
pkill -f "Runner.Listener"

# View logs
tail -f ~/actions-runner/runner.log

# Check tool versions
xcodebuild -version
java -version
gradle --version
ruby --version
pod --version

# Update PATH
echo "/new/path" >> ~/actions-runner/.path

# Update environment
echo "VAR=value" >> ~/actions-runner/.env

# Verify sudo
sudo -n xcode-select -p

# Service management (may not work over SSH)
cd ~/actions-runner
./svc.sh status
./svc.sh start
./svc.sh stop
```

## System Information

- **Hostname:** Mac Mini
- **IP:** 100.126.148.125
- **OS:** macOS 15.7.1 (24G231) Sequoia
- **Architecture:** arm64 (Apple M4)
- **Memory:** 16GB
- **Disk:** 228GB total, ~111GB available after setup
- **Xcode Developer Directory:** /Applications/Xcode_26.2.app/Contents/Developer

---

*Last Updated: 2026-02-02*
*Runner Version: 2.331.0*
*Xcode Version: 26.2 (17C52)*
