--- name: gitea-runner description: Gitea Act Runner configuration guide for macOS ARM64 with host mode, cache optimization, and multi-runner setup --- # Gitea Act Runner Configuration Skill Complete guide for configuring and deploying Gitea Act Runner, optimized for macOS ARM64 (Apple Silicon) host mode. ## Overview Gitea Act Runner is the CI/CD executor for Gitea Actions, compatible with GitHub Actions workflow syntax. ### Execution Modes | Mode | Environment | Use Case | Android SDK | |------|-------------|----------|-------------| | **Host Mode** | Native macOS/Linux | Android/iOS builds, native toolchains | macOS ARM64 supported | | Docker Mode | Linux containers | Cross-platform builds | Linux ARM64 NOT supported | **Recommendation**: Use **host mode** for macOS ARM64 runners to leverage native Android SDK support. ## Prerequisites ### 1. Install act_runner ```bash # Using Homebrew (recommended) brew install act_runner # Or manual download curl -sL https://gitea.com/gitea/act_runner/releases/download/v0.2.13/act_runner-0.2.13-darwin-arm64 \ -o /usr/local/bin/act_runner chmod +x /usr/local/bin/act_runner ``` ### 2. Install Development Tools ```bash # Go (for Go backend builds) brew install go # Node.js (for frontend/miniprogram builds) brew install node@22 # pnpm (package manager) npm install -g pnpm # JDK 17 (for Android builds) brew install openjdk@17 # Docker (for container builds) # Install Docker Desktop from https://docker.com ``` ### 3. Install Android SDK (for Android builds) ```bash # Using Homebrew brew install --cask android-commandlinetools # Or manual installation mkdir -p ~/android-sdk/cmdline-tools cd ~/android-sdk/cmdline-tools curl -sL https://dl.google.com/android/repository/commandlinetools-mac-11076708_latest.zip -o cmdline-tools.zip unzip cmdline-tools.zip mv cmdline-tools latest rm cmdline-tools.zip # Accept licenses and install components yes | sdkmanager --licenses sdkmanager "platform-tools" "platforms;android-36" "build-tools;36.0.0" ``` ### 4. Configure Environment Variables Add to `~/.zshrc` or `~/.bashrc`: ```bash # Go export GOPATH=$HOME/go export PATH=$PATH:$GOPATH/bin # Java export JAVA_HOME=/opt/homebrew/opt/openjdk@17 export PATH=$PATH:$JAVA_HOME/bin # Android SDK export ANDROID_HOME=~/android-sdk export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin export PATH=$PATH:$ANDROID_HOME/platform-tools ``` ### 5. Verify Environment ```bash # Verify all tools go version # Go 1.23+ node --version # v22.x pnpm --version # Latest java -version # 17+ echo $ANDROID_HOME # SDK path docker --version # Latest act_runner --version ``` ## Runner Configuration ### Host Mode Configuration Template Create `act_runner_host.yaml`: ```yaml log: level: info runner: file: /path/to/work/dir/.runner capacity: 2 # Concurrent jobs timeout: 3h # Job timeout shutdown_timeout: 30s insecure: false fetch_timeout: 5s fetch_interval: 2s # Labels reflect actual system info for precise workflow matching labels: - "self-hosted:host" # Self-hosted runner - "macOS:host" # Operating system - "ARM64:host" # Architecture - "darwin-arm64:host" # Combined label (recommended for matching) cache: enabled: true dir: "/path/to/work/dir/cache" host: "127.0.0.1" # Local only (use 0.0.0.0 for multi-runner) port: 9000 host: workdir_parent: "/path/to/work/dir/workspace" ``` ### Label Design Guidelines | Label | Meaning | Usage | |-------|---------|-------| | `self-hosted` | Self-hosted runner | Distinguish from Gitea-hosted runners | | `macOS` | Operating system | Friendly name for Darwin | | `ARM64` | CPU architecture | Apple Silicon (M1/M2/M3/M4) | | `darwin-arm64` | Combined label | Most precise matching | ### Workflow Matching Examples ```yaml jobs: build: # Method 1: Combined label (recommended, most precise) runs-on: darwin-arm64 # Method 2: Label array (matches multiple conditions) # runs-on: [self-hosted, macOS, ARM64] # Method 3: OS only # runs-on: macOS ``` ## Registration & Startup ### 1. Get Registration Token ```bash # Organization level (global runner, recommended) curl -H "Authorization: token YOUR_GITEA_TOKEN" \ "https://your-gitea.com/api/v1/orgs/ORG_NAME/actions/runners/registration-token" # Or repository level curl -H "Authorization: token YOUR_GITEA_TOKEN" \ "https://your-gitea.com/api/v1/repos/OWNER/REPO/actions/runners/registration-token" ``` ### 2. Register Runner ```bash act_runner register \ --config act_runner_host.yaml \ --instance https://your-gitea.com/ \ --token YOUR_REGISTRATION_TOKEN \ --name "your-runner-name" \ --labels "self-hosted:host,macOS:host,ARM64:host,darwin-arm64:host" \ --no-interactive ``` ### 3. Start Runner ```bash # Foreground (for debugging) act_runner daemon --config act_runner_host.yaml # Background nohup act_runner daemon --config act_runner_host.yaml > runner.log 2>&1 & # Using brew services (recommended for persistence) brew services start act_runner ``` ## Multi-Runner Cache Sharing ### Option A: Master-Slave Mode (Recommended for 2-3 runners) **Primary Runner (cache server)**: ```yaml cache: enabled: true dir: "/Users/voson/work/gitea/cache" host: "0.0.0.0" # Listen on all interfaces port: 9000 ``` **Secondary Runner (cache client)**: ```yaml cache: enabled: true server: "http://192.168.0.103:9000" # Primary runner IP dir: "/Users/user/work/gitea/cache" # Local fallback host: "192.168.0.104" # This runner's IP port: 9000 ``` ### Option B: NFS Shared Storage (Enterprise) **1. Setup NFS server on primary runner:** ```bash # /etc/exports /Users/voson/work/gitea/cache -alldirs -mapall=$(id -u):$(id -g) 192.168.0.0/24 sudo nfsd restart ``` **2. Mount on secondary runner:** ```bash sudo mkdir -p /mnt/runner-cache sudo mount -t nfs 192.168.0.103:/Users/voson/work/gitea/cache /mnt/runner-cache ``` ### Option C: Independent Cache (Default) Each runner maintains its own cache. First build downloads dependencies, subsequent builds use local cache. ## Cache Management ### Host Mode Cache Locations | Cache Type | Location | Behavior | |------------|----------|----------| | Runner cache service | `config.cache.dir` | Managed by act_runner | | Gradle | `~/.gradle/` | Persistent across builds | | npm/pnpm | `~/.npm/`, `~/.pnpm-store/` | Persistent across builds | | Go modules | `~/go/pkg/mod/` | Persistent across builds | ### Cache Cleanup Script Create `cleanup-cache.sh`: ```bash #!/bin/bash set -e echo "Cleaning up caches..." # 1. Runner cache (older than 7 days) find /path/to/cache/cache -type f -mtime +7 -delete 2>/dev/null || true # 2. Gradle cache (older than 30 days) find ~/.gradle/caches -type f -mtime +30 -delete 2>/dev/null || true find ~/.gradle/caches -type d -empty -delete 2>/dev/null || true # 3. npm cache verification npm cache verify # 4. Workspace cleanup find /path/to/workspace -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \; 2>/dev/null || true echo "Cleanup complete!" echo "Runner cache: $(du -sh /path/to/cache/ | awk '{print $1}')" echo "Gradle cache: $(du -sh ~/.gradle/ | awk '{print $1}')" ``` ### Schedule Cleanup ```bash # Add to crontab for weekly cleanup crontab -e # Add: 0 3 * * 0 /path/to/cleanup-cache.sh >> /path/to/cleanup.log 2>&1 ``` ## Management Commands ```bash # Check runner status ps aux | grep act_runner # View logs tail -f /path/to/runner.log # Stop runner pkill -f "act_runner daemon" # Re-register (stop first, delete .runner file) rm /path/to/.runner act_runner register --config act_runner_host.yaml ... # Check Gitea connection curl -s https://your-gitea.com/api/v1/version ``` ## Troubleshooting ### 1. Android SDK Not Found ```bash # Verify ANDROID_HOME echo $ANDROID_HOME ls $ANDROID_HOME # Check if runner can access SDK # Ensure runner runs as the same user who installed SDK ``` ### 2. JDK Version Error Android Gradle Plugin 8.x requires JDK 17+: ```bash java -version # Should show: openjdk version "17.x.x" # If wrong version, update JAVA_HOME export JAVA_HOME=/opt/homebrew/opt/openjdk@17 ``` ### 3. Permission Issues ```bash # Ensure runner user owns work directories chown -R $(whoami) /path/to/work/dir chmod -R 755 /path/to/work/dir ``` ### 4. Label Mismatch ```bash # Check registered labels cat /path/to/.runner | jq '.labels' # Ensure workflow runs-on matches # Workflow: runs-on: darwin-arm64 # Runner: "darwin-arm64:host" label ``` ### 5. Cache Service Port Conflict ```bash # Check if port 9000 is in use lsof -i :9000 # Use different port if needed # In config: port: 9001 ``` ## Docker Mode Configuration (Alternative) For container-based builds: ```yaml log: level: info runner: file: /path/to/.runner capacity: 2 timeout: 3h labels: - "ubuntu-latest:docker://catthehacker/ubuntu:act-latest" - "ubuntu-22.04:docker://catthehacker/ubuntu:act-latest" cache: enabled: true dir: "/path/to/cache" host: "192.168.0.103" # Host IP (not 127.0.0.1 for containers) port: 9000 container: options: "--platform=linux/amd64" # For ARM64 host running x86 images network: "host" ``` ## Quick Reference | Task | Command | |------|---------| | Install runner | `brew install act_runner` | | Register | `act_runner register --config ... --instance ... --token ...` | | Start | `act_runner daemon --config act_runner_host.yaml` | | Stop | `pkill -f "act_runner daemon"` | | Check status | `ps aux \| grep act_runner` | | View logs | `tail -f runner.log` | | Re-register | `rm .runner && act_runner register ...` | ## Related Resources - [Gitea Act Runner Documentation](https://docs.gitea.com/usage/actions/act-runner) - [Android SDK Command Line Tools](https://developer.android.com/studio/command-line) - [GitHub Actions Workflow Syntax](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions) ## Version - **Skill Version**: 1.0 - **Last Updated**: 2026-01-12 - **Compatibility**: act_runner 0.2.13+, macOS ARM64