9.9 KiB
9.9 KiB
name, description
| name | description |
|---|---|
| gitea-runner | 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
# 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
# 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)
# 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:
# 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
# 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:
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
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
# 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
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
# 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):
cache:
enabled: true
dir: "/Users/voson/work/gitea/cache"
host: "0.0.0.0" # Listen on all interfaces
port: 9000
Secondary Runner (cache client):
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:
# /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:
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:
#!/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
# 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
# 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
# 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+:
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
# Ensure runner user owns work directories
chown -R $(whoami) /path/to/work/dir
chmod -R 755 /path/to/work/dir
4. Label Mismatch
# 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
# 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:
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
Version
- Skill Version: 1.0
- Last Updated: 2026-01-12
- Compatibility: act_runner 0.2.13+, macOS ARM64