Files
opencode/skill/gitea-runner/SKILL.md
2026-01-12 17:39:49 +08:00

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

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 ...

Version

  • Skill Version: 1.0
  • Last Updated: 2026-01-12
  • Compatibility: act_runner 0.2.13+, macOS ARM64