- Add native Windows service detection and signal handling - Implement configurable shutdown timeout for graceful job completion - Improve HTTP client with connection pooling and timeouts - Propagate context through poller for proper shutdown coordination - Add documentation for Windows service installation (NSSM and sc.exe) - Add *.exe to .gitignore for Windows builds
13 KiB
GitCaddy Runner
A Gitea Actions runner with enhanced capability detection and reporting for AI-friendly workflow generation.
GitCaddy Runner is a hard fork of Gitea's act_runner, rebranded and enhanced with automated capability detection to enable AI tools to generate compatible workflows based on available resources.
Features
- Automated Capability Detection: Automatically identifies OS, architecture, installed tools, and available resources
- Concurrent Job Execution: Configure runner capacity to handle multiple jobs simultaneously
- Docker Support: Full support for Docker and Docker Compose workflows
- Xcode Integration: Detects Xcode installations, SDKs, and simulators on macOS
- Tool Detection: Identifies installed tools (Node.js, Python, .NET, Go, Ruby, Swift, etc.)
- AI-Friendly API: Exposes capabilities through Gitea's API for automated workflow generation
- Cache Support: Built-in workflow cache support for faster builds
Installation
Pre-built Binaries
Download the latest release for your platform from the releases page:
macOS:
# Apple Silicon (M1/M2/M3/M4)
curl -L -o gitcaddy-runner https://git.marketally.com/gitcaddy/gitcaddy-runner/releases/download/v1.0.0/gitcaddy-runner-1.0.0-darwin-arm64
chmod +x gitcaddy-runner
# Intel
curl -L -o gitcaddy-runner https://git.marketally.com/gitcaddy/gitcaddy-runner/releases/download/v1.0.0/gitcaddy-runner-1.0.0-darwin-amd64
chmod +x gitcaddy-runner
Linux:
# x86_64
curl -L -o gitcaddy-runner https://git.marketally.com/gitcaddy/gitcaddy-runner/releases/download/v1.0.0/gitcaddy-runner-1.0.0-linux-amd64
chmod +x gitcaddy-runner
# ARM64
curl -L -o gitcaddy-runner https://git.marketally.com/gitcaddy/gitcaddy-runner/releases/download/v1.0.0/gitcaddy-runner-1.0.0-linux-arm64
chmod +x gitcaddy-runner
Windows:
# Download the Windows executable
# https://git.marketally.com/gitcaddy/gitcaddy-runner/releases/download/v1.0.0/gitcaddy-runner-1.0.0-windows-amd64.exe
Build from Source
git clone https://git.marketally.com/gitcaddy/gitcaddy-runner.git
cd gitcaddy-runner
make build
Quick Start
1. Enable Gitea Actions
In your Gitea app.ini:
[actions]
ENABLED = true
2. Generate Configuration
./gitcaddy-runner generate-config > config.yaml
3. Configure the Runner
Edit config.yaml to customize settings. Important configuration options:
log:
level: info
runner:
file: .runner
capacity: 2 # Number of concurrent jobs (default: 1)
timeout: 3h
shutdown_timeout: 3m # Grace period for running jobs on shutdown
insecure: false
fetch_timeout: 5s
fetch_interval: 2s
labels:
- "ubuntu-latest:docker://node:16-bullseye"
- "ubuntu-22.04:docker://node:16-bullseye"
cache:
enabled: true
dir: ""
container:
network: ""
privileged: false
options: ""
valid_volumes: []
docker_host: ""
force_pull: false
host:
workdir_parent: ""
Capacity Configuration
The capacity setting controls how many jobs the runner can execute simultaneously:
- Default: 1 (one job at a time)
- Recommended: 2-4 for multi-core systems
- Considerations:
- Each job consumes CPU, memory, and disk I/O
- iOS/macOS builds are resource-intensive (start with 2)
- Lighter builds (Node.js, Go) can handle higher capacity (4-6)
- Monitor system load and adjust accordingly
Example for different workloads:
# Light builds (web apps, APIs)
runner:
capacity: 4
# Mixed builds
runner:
capacity: 2
# Heavy builds (iOS/macOS, large containers)
runner:
capacity: 1
4. Register the Runner
./gitcaddy-runner register \
--instance https://your-gitea-instance.com \
--token YOUR_REGISTRATION_TOKEN \
--name my-runner \
--labels ubuntu-latest:docker://node:16-bullseye
The registration token can be obtained from:
- Gitea Admin Panel > Actions > Runners
- Or repository Settings > Actions > Runners
5. Start the Runner
Important: Always specify the config file path with -c flag:
./gitcaddy-runner daemon -c config.yaml
Without the -c flag, the runner will use default settings and ignore your config.yaml!
Running as a Service
macOS (launchd)
Create ~/Library/LaunchAgents/com.gitcaddy.runner.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.gitcaddy.runner</string>
<key>ProgramArguments</key>
<array>
<string>/path/to/gitcaddy-runner</string>
<string>daemon</string>
<string>-c</string>
<string>/path/to/config.yaml</string>
</array>
<key>WorkingDirectory</key>
<string>/path/to/runner/directory</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/path/to/runner.log</string>
<key>StandardErrorPath</key>
<string>/path/to/runner.err</string>
</dict>
</plist>
Load the service:
launchctl load ~/Library/LaunchAgents/com.gitcaddy.runner.plist
Linux (systemd)
Create /etc/systemd/system/gitcaddy-runner.service:
[Unit]
Description=GitCaddy Actions Runner
After=network.target
[Service]
Type=simple
User=runner
WorkingDirectory=/home/runner/gitcaddy-runner
ExecStart=/home/runner/gitcaddy-runner/gitcaddy-runner daemon -c /home/runner/gitcaddy-runner/config.yaml
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable gitcaddy-runner
sudo systemctl start gitcaddy-runner
Windows (NSSM or Native Service)
GitCaddy Runner has native Windows service support. When running as a service, it automatically detects the Windows Service Control Manager (SCM) and handles stop/shutdown signals properly.
Option 1: Using NSSM (Recommended)
Install NSSM via Chocolatey:
choco install nssm -y
Create the service:
# Install the service
nssm install GiteaRunnerSvc C:\gitea-runner\gitcaddy-runner.exe daemon --config C:\gitea-runner\config.yaml
# Set working directory
nssm set GiteaRunnerSvc AppDirectory C:\gitea-runner
# Set environment variables
nssm set GiteaRunnerSvc AppEnvironmentExtra HOME=C:\gitea-runner USERPROFILE=C:\gitea-runner
# Configure auto-restart on failure
sc failure GiteaRunnerSvc reset=86400 actions=restart/60000/restart/60000/restart/60000
# Start the service
sc start GiteaRunnerSvc
Option 2: Native sc.exe (requires wrapper)
Create a wrapper batch file C:\gitea-runner\start-runner.bat:
@echo off
set HOME=C:\gitea-runner
set USERPROFILE=C:\gitea-runner
cd /d C:\gitea-runner
C:\gitea-runner\gitcaddy-runner.exe daemon --config C:\gitea-runner\config.yaml
Service Management:
# Check service status
sc query GiteaRunnerSvc
# Start service
sc start GiteaRunnerSvc
# Stop service
sc stop GiteaRunnerSvc
# View service logs (if using NSSM with log rotation)
Get-Content C:\gitea-runner\logs\runner.log -Tail 50
Environment Variables for Windows Services:
| Variable | Description | Example |
|---|---|---|
GITEA_RUNNER_SERVICE_NAME |
Override service name detection | GiteaRunnerSvc |
Capability Detection
GitCaddy Runner automatically detects and reports system capabilities:
Platform Information
- Operating system (darwin, linux, windows)
- Architecture (amd64, arm64)
Container Runtime
- Docker availability and version
- Docker Compose support
- Container runtime type
Development Tools
- Node.js, npm, yarn
- Python, pip
- Go
- .NET
- Ruby
- Rust
- Java
- Swift (macOS)
- Git, Make
macOS-Specific
- Xcode version and build
- Available SDKs (iOS, macOS, tvOS, watchOS, visionOS)
- Simulators
- Code signing tools (codesign, pkgbuild)
- Package managers (Homebrew, CocoaPods, Fastlane)
System Resources
- CPU cores
- Load average
- Disk space and usage
- Network bandwidth
Example Capabilities Output
{
"os": "darwin",
"arch": "arm64",
"capacity": 2,
"docker": true,
"docker_compose": true,
"container_runtime": "docker",
"xcode": {
"version": "15.2",
"build": "15C500b",
"sdks": ["iOS 17.2", "macOS 14.2"]
},
"tools": {
"node": ["20.11"],
"python": ["3.11"],
"swift": ["5.9"]
},
"build_tools": ["fastlane", "cocoapods", "codesign"],
"cpu": {
"num_cpu": 10,
"load_percent": 25.5
},
"disk": {
"free_bytes": 54199226368,
"used_percent": 77.89
}
}
Configuration Reference
Runner Section
| Option | Type | Default | Description |
|---|---|---|---|
capacity |
int | 1 | Maximum concurrent jobs |
timeout |
duration | 3h | Maximum job execution time |
shutdown_timeout |
duration | 3m | Grace period for jobs to complete on shutdown |
insecure |
bool | false | Allow insecure HTTPS |
fetch_timeout |
duration | 5s | Timeout for fetching tasks |
fetch_interval |
duration | 2s | Interval between task fetches |
labels |
[]string | [] | Runner labels for job matching |
env_file |
string | .env | Environment variables file |
Cache Section
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
bool | true | Enable cache support |
dir |
string | "" | Cache directory path |
host |
string | "" | External cache server host |
port |
int | 0 | External cache server port |
Container Section
| Option | Type | Default | Description |
|---|---|---|---|
network |
string | "" | Docker network for containers |
privileged |
bool | false | Run containers in privileged mode |
docker_host |
string | "" | Custom Docker host |
force_pull |
bool | false | Always pull latest images |
Troubleshooting
Capacity Not Being Applied
Problem: Runner shows "capacity":1 even though config.yaml has capacity: 2
Solution: Ensure you're using the -c flag when starting the daemon:
# ✅ Correct
./gitcaddy-runner daemon -c /path/to/config.yaml
# ❌ Wrong - uses defaults
./gitcaddy-runner daemon
Verify the config is being loaded:
# Check runner process
ps aux | grep gitcaddy-runner
# Should show: gitcaddy-runner daemon -c /path/to/config.yaml
Docker Not Detected
Problem: Capabilities show "docker":false but Docker is installed
Solution:
-
Ensure Docker Desktop/daemon is running:
docker ps -
Restart the runner after starting Docker:
./gitcaddy-runner daemon -c config.yaml -
Check Docker socket permissions:
ls -l /var/run/docker.sock
Jobs Not Running Concurrently
Problem: Jobs queue instead of running in parallel
Checklist:
- Verify capacity in capabilities output (check runner logs)
- Confirm config.yaml has
capacity > 1 - Ensure runner was started with
-c config.yamlflag - Check system resources aren't maxed out
- Restart runner after config changes
Runner Not Starting
Problem: Runner exits immediately or fails to start
Common causes:
- Invalid config.yaml syntax
.runnerfile missing (runregisterfirst)- Permission issues on working directory
- Invalid Gitea instance URL or token
Debug steps:
# Check config syntax
./gitcaddy-runner generate-config > test-config.yaml
diff config.yaml test-config.yaml
# Test with verbose logging
./gitcaddy-runner daemon -c config.yaml --log-level debug
# Verify registration
cat .runner
Environment Variables
GitCaddy Runner supports environment variable configuration:
| Variable | Description | Example |
|---|---|---|
GITEA_RUNNER_CAPACITY |
Override capacity setting | GITEA_RUNNER_CAPACITY=2 |
GITEA_RUNNER_ENV_FILE |
Custom env file path | GITEA_RUNNER_ENV_FILE=.env.prod |
API Integration
Query runner capabilities via Gitea API:
curl -H "Authorization: token YOUR_TOKEN" \
https://your-gitea.com/api/v1/runners
Use capabilities to generate compatible workflows:
# Example: Use capabilities to select appropriate runner
name: Build
on: [push]
jobs:
build:
runs-on: ${{ capabilities.os == 'darwin' && 'macos-latest' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v3
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
License
MIT License - see LICENSE for details.
Support
- Issues: https://git.marketally.com/gitcaddy/gitcaddy-runner/issues
- Discussions: https://git.marketally.com/gitcaddy/gitcaddy-runner/discussions
Acknowledgments
GitCaddy Runner is a hard fork of Gitea's act_runner, rebranded and enhanced with automated capability detection and reporting features for AI-friendly workflow generation.