Files
opencode/skill/gitea/runner-management.md
Voson 5a05d5ab53 chore: 重构 OpenCode 命令和技能文档体系
- 新增:统一的 git 命令文档(add/commit/push/pull 等)
- 新增:整合的 Gitea 技能文档(API、运行器、工作流等)
- 新增:工作流模板(Android、Go、Node.js 等)
- 移除:已弃用的旧命令脚本和发布脚本
- 改进:.gitignore 添加敏感文件保护规则
- 改进:AGENTS.md 完善了开发规范和示例

此次重组统一了命令和技能的文档结构,便于后续维护和扩展。
2026-01-13 00:27:21 +08:00

809 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Gitea Runner 管理
完整的 Gitea Act Runner 创建、注册、配置和管理指南。
## 概述
Gitea Act Runner 是 Gitea Actions 的 CI/CD 执行器,兼容 GitHub Actions workflow 语法。
### Runner 级别
| 级别 | 作用域 | 权限要求 | 适用场景 |
|------|--------|---------|---------|
| **全局 Runner** | 所有组织和仓库 | 管理员 Token | 共享资源、统一管理 |
| **组织 Runner** | 特定组织 | 组织管理权限 | 组织内项目共享 |
| **仓库 Runner** | 特定仓库 | 仓库管理权限 | 独立项目使用 |
**推荐**
- 小团队或个人使用:**全局 Runner**(统一管理,配置简单)
- 企业多组织:**组织 Runner**(隔离资源,权限分离)
### 执行模式
| 模式 | 环境 | 适用场景 | Android SDK |
|------|------|---------|-------------|
| **Host Mode** | Native macOS/Linux | Android/iOS 构建、原生工具链 | macOS ARM64 支持 |
| Docker Mode | Linux 容器 | 跨平台构建 | Linux ARM64 不支持 |
**推荐**macOS ARM64 使用 **Host Mode** 以支持 Android SDK。
## Runner 目录结构
所有 Runner 配置统一管理在:
```
~/.config/gitea/runners/
├── runner-macbook-pro/ # Runner 1
│ ├── .runner # 注册信息JSON
│ ├── config.yaml # Runner 配置
│ ├── cache/ # Cache 目录
│ └── workspace/ # 工作目录
└── runner-mac-mini/ # Runner 2
└── ...
```
## 前置要求
### 1. 安装 act_runner
```bash
# 使用 Homebrew推荐
brew install act_runner
# 或手动下载
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
# 验证安装
act_runner --version
```
### 2. 安装开发工具(可选,根据需要)
```bash
# GoGo 项目构建)
brew install go
# Node.js前端项目构建
brew install node@22
npm install -g pnpm
# JDK 17Android 项目构建)
brew install openjdk@17
# Docker容器构建
# 从 https://docker.com 安装 Docker Desktop
```
### 3. 安装 Android SDKAndroid 项目构建)
```bash
# 使用 Homebrew
brew install --cask android-commandlinetools
# 或手动安装
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
# 接受许可并安装组件
yes | sdkmanager --licenses
sdkmanager "platform-tools" "platforms;android-36" "build-tools;36.0.0"
```
### 4. 配置环境变量
添加到 `~/.zshrc``~/.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
```
重新加载配置:
```bash
source ~/.zshrc # 或 source ~/.bashrc
```
### 5. 验证环境
```bash
go version # Go 1.23+
node --version # v22.x
pnpm --version # Latest
java -version # 17+
echo $ANDROID_HOME # SDK 路径
docker --version # Latest
act_runner --version
```
## 创建 Runner
### 使用命令快速创建
```bash
/gitea-create-runner
```
此命令会自动:
1. 检查并安装 act_runner如未安装
2. 加载 Gitea 配置(如不存在则提示初始化)
3. 生成 runner 名称(基于主机名)
4. 检测系统环境并生成 labels
5. 创建 runner 目录结构
6. 生成 host 模式配置文件
7. 获取注册 token优先全局
8. 注册并启动 runner
### 详细创建流程
当运行 `/gitea-create-runner` 命令时,会执行以下步骤:
#### 步骤 1: 检查 act_runner 安装
```bash
if command -v act_runner &> /dev/null; then
echo "✓ act_runner 已安装"
else
echo "⚠️ act_runner 未安装,正在安装..."
brew install act_runner
fi
```
#### 步骤 2: 加载 Gitea 配置
```bash
config_file="$HOME/.config/gitea/config.env"
if [ ! -f "$config_file" ]; then
echo "❌ Gitea 配置不存在,请先初始化: /gitea-reset"
exit 1
fi
source "$config_file"
```
#### 步骤 3: 生成 Runner 名称
```bash
# 基于主机名自动生成
hostname=$(hostname -s)
runner_name="runner-$hostname"
# 或使用命令参数
# /gitea-create-runner my-custom-name
```
#### 步骤 4: 智能检测系统环境和 Labels
```bash
# 检测操作系统
OS=$(uname -s)
case "$OS" in
Darwin) os_label="macOS" ;;
Linux) os_label="ubuntu" ;;
*) os_label="unknown" ;;
esac
# 检测架构
ARCH=$(uname -m)
case "$ARCH" in
arm64|aarch64) arch_label="ARM64" ;;
x86_64) arch_label="x64" ;;
*) arch_label="unknown" ;;
esac
# 生成组合 label
combined=$(echo "${OS}-${ARCH}" | tr '[:upper:]' '[:lower:]')
# 生成建议的 labels
suggested_labels="self-hosted:host,${os_label}:host,${arch_label}:host,${combined}:host"
echo ""
echo "检测到系统环境:"
echo " 操作系统: $OS ($os_label)"
echo " 架构: $ARCH ($arch_label)"
echo ""
echo "建议的 Runner Labels:"
echo " $suggested_labels"
echo ""
```
**输出示例**
```
检测到系统环境:
操作系统: Darwin (macOS)
架构: arm64 (ARM64)
建议的 Runner Labels:
self-hosted:host,macOS:host,ARM64:host,darwin-arm64:host
```
#### 步骤 5: 创建 Runner 目录
```bash
runners_dir="$HOME/.config/gitea/runners"
runner_dir="$runners_dir/$runner_name"
# 检查是否已存在
if [ -d "$runner_dir" ]; then
echo "❌ Runner '$runner_name' 已存在"
echo "请使用其他名称或先删除现有 runner: /gitea-delete-runner $runner_name"
exit 1
fi
# 创建目录结构
mkdir -p "$runner_dir"/{cache,workspace}
echo "✓ 创建目录: $runner_dir"
```
#### 步骤 6: 生成配置文件
**默认生成 Host Mode 配置**
```yaml
log:
level: info
runner:
file: $HOME/.config/gitea/runners/$runner_name/.runner
capacity: ${GITEA_RUNNER_CAPACITY:-2}
timeout: ${GITEA_RUNNER_TIMEOUT:-3h}
shutdown_timeout: 30s
insecure: false
fetch_timeout: 5s
fetch_interval: 2s
labels:
- "self-hosted:host"
- "macOS:host"
- "ARM64:host"
- "darwin-arm64:host"
cache:
enabled: true
dir: "$HOME/.config/gitea/runners/$runner_name/cache"
host: "127.0.0.1"
port: 9000
host:
workdir_parent: "$HOME/.config/gitea/runners/$runner_name/workspace"
```
**说明**
- 默认使用 Host Mode支持 Android SDK、iOS 等原生工具)
- 自动填充系统检测的 labels
- 容量和超时可通过环境变量配置
#### 步骤 7: 获取注册 Token
```bash
echo ""
echo "正在获取 Runner 注册 Token..."
# 默认尝试全局 Runner管理员权限
echo "尝试创建全局 Runner可用于所有组织和仓库..."
response=$(curl -s -w "\n%{http_code}" \
-H "Authorization: token $GITEA_TOKEN" \
"${GITEA_URL}/api/v1/admin/runners/registration-token")
http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')
# 如果全局 Runner 失败(权限不足),降级到组织 Runner
if [ "$http_code" != "200" ]; then
echo "⚠️ 全局 Runner 权限不足 (HTTP $http_code)"
echo " 全局 Runner 需要管理员 Token"
echo ""
echo "降级到组织 Runner..."
runner_level="organization"
if [ -n "$GITEA_DEFAULT_ORG" ]; then
org_name="$GITEA_DEFAULT_ORG"
else
read -p "请输入组织名称: " org_input
if [ -z "$org_input" ]; then
echo "❌ 必须指定组织名称"
exit 1
fi
org_name="$org_input"
fi
echo "使用组织: $org_name"
response=$(curl -s -w "\n%{http_code}" -X POST \
-H "Authorization: token $GITEA_TOKEN" \
"${GITEA_URL}/api/v1/orgs/$org_name/actions/runners/registration-token")
http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | sed '$d')
else
echo "✓ 使用全局 Runner"
runner_level="global"
fi
if [ "$http_code" != "200" ]; then
echo "❌ 获取注册 Token 失败 (HTTP $http_code)"
echo "$body"
exit 1
fi
registration_token=$(echo "$body" | jq -r '.token')
echo "✓ 注册 Token 已获取"
```
#### 步骤 8: 注册 Runner
```bash
echo ""
echo "正在注册 Runner..."
act_runner register \
--config "$runner_dir/config.yaml" \
--instance "$GITEA_URL" \
--token "$registration_token" \
--name "$runner_name" \
--labels "$labels" \
--no-interactive
if [ $? -eq 0 ]; then
echo "✓ Runner 注册成功"
else
echo "❌ Runner 注册失败"
exit 1
fi
```
#### 步骤 9: 自动启动 Runner
```bash
echo ""
echo "正在启动 Runner..."
# 后台启动 Runner
nohup act_runner daemon --config "$runner_dir/config.yaml" \
> "$runner_dir/runner.log" 2>&1 &
runner_pid=$!
# 等待 2 秒让 runner 启动
sleep 2
# 检查进程是否存在
if ps -p $runner_pid > /dev/null 2>&1; then
echo "✓ Runner 已启动 (PID: $runner_pid)"
else
echo "⚠️ Runner 启动失败,请查看日志:"
echo " tail -f $runner_dir/runner.log"
exit 1
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Runner 创建完成!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "Runner 名称: $runner_name"
echo "Runner 级别: ${runner_level}"
if [ "$runner_level" = "organization" ]; then
echo "所属组织: ${org_name}"
fi
echo "PID: $runner_pid"
echo "配置文件: $runner_dir/config.yaml"
echo "工作目录: $runner_dir/workspace"
echo "Cache 目录: $runner_dir/cache"
echo "日志文件: $runner_dir/runner.log"
echo ""
echo "管理命令:"
echo " 查看日志: tail -f $runner_dir/runner.log"
echo " 停止 Runner: pkill -f 'act_runner daemon --config.*$runner_name'"
echo " 查看所有: /gitea-list-runners"
echo " 删除 Runner: /gitea-delete-runner $runner_name"
echo ""
```
## Label 设计指南
### Label 格式
```
label-name:mode
```
**Mode 类型**
- `host`: Host Mode原生执行
- `docker://image`: Docker Mode容器执行
### 推荐 Labels
#### macOS ARM64
```yaml
labels:
- "self-hosted:host"
- "macOS:host"
- "ARM64:host"
- "darwin-arm64:host"
```
#### Linux x64
```yaml
labels:
- "self-hosted:host"
- "ubuntu:host"
- "x64:host"
- "linux-x64:host"
```
#### Docker Mode
```yaml
labels:
- "ubuntu-latest:docker://catthehacker/ubuntu:act-latest"
- "ubuntu-22.04:docker://catthehacker/ubuntu:act-latest"
```
### Workflow 匹配
**方法 1: 组合 label推荐最精确**
```yaml
jobs:
build:
runs-on: darwin-arm64
```
**方法 2: Label 数组(匹配多个条件)**
```yaml
jobs:
build:
runs-on: [self-hosted, macOS, ARM64]
```
**方法 3: 仅操作系统**
```yaml
jobs:
build:
runs-on: macOS
```
## Runner 配置详解
### Host Mode 配置
```yaml
log:
level: info # 日志级别debug/info/warn/error
runner:
file: /path/to/.runner # 注册信息文件
capacity: 2 # 并发任务数
timeout: 3h # 任务超时时间
shutdown_timeout: 30s # 关闭超时时间
insecure: false # 是否允许不安全连接
fetch_timeout: 5s # 获取任务超时
fetch_interval: 2s # 获取任务间隔
labels:
- "label-name:host" # Runner labels
cache:
enabled: true # 启用缓存
dir: "/path/to/cache" # 缓存目录
host: "127.0.0.1" # 监听地址(仅本地)
port: 9000 # 缓存服务端口
host:
workdir_parent: "/path/to/workspace" # 工作目录父路径
```
### Docker Mode 配置
```yaml
log:
level: info
runner:
file: /path/to/.runner
capacity: 2
timeout: 3h
labels:
- "ubuntu-latest:docker://catthehacker/ubuntu:act-latest"
cache:
enabled: true
dir: "/path/to/cache"
host: "192.168.0.103" # 主机 IP非 127.0.0.1
port: 9000
container:
options: "--platform=linux/amd64" # 容器选项
network: "host" # 网络模式
```
## 多 Runner 缓存共享
### 方案 A: Master-Slave 模式(推荐 2-3 个 runner
**主 Runnercache server**
```yaml
cache:
enabled: true
dir: "$HOME/.config/gitea/runners/runner-primary/cache"
host: "0.0.0.0" # 监听所有接口
port: 9000
```
**从 Runnercache client**
```yaml
cache:
enabled: true
server: "http://192.168.0.103:9000" # 主 runner IP
dir: "$HOME/.config/gitea/runners/runner-secondary/cache" # 本地备份
host: "192.168.0.104" # 本 runner IP
port: 9000
```
### 方案 B: NFS 共享存储(企业级)
**1. 在主 Runner 上设置 NFS server**
```bash
# /etc/exports
/Users/voson/.config/gitea/cache -alldirs -mapall=$(id -u):$(id -g) 192.168.0.0/24
sudo nfsd restart
```
**2. 在从 Runner 上挂载**
```bash
sudo mkdir -p /mnt/runner-cache
sudo mount -t nfs 192.168.0.103:/Users/voson/.config/gitea/cache /mnt/runner-cache
```
### 方案 C: 独立缓存(默认)
每个 runner 维护自己的缓存。首次构建下载依赖,后续构建使用本地缓存。
## 缓存管理
### Host Mode 缓存位置
| 缓存类型 | 位置 | 行为 |
|---------|------|------|
| Runner cache service | `config.cache.dir` | act_runner 管理 |
| Gradle | `~/.gradle/` | 跨构建持久化 |
| npm/pnpm | `~/.npm/`, `~/.pnpm-store/` | 跨构建持久化 |
| Go modules | `~/go/pkg/mod/` | 跨构建持久化 |
### 缓存清理脚本
创建 `~/.config/gitea/cleanup-cache.sh`
```bash
#!/bin/bash
set -e
echo "清理 Gitea Runner 缓存..."
runners_dir="$HOME/.config/gitea/runners"
# 1. Runner cache超过 7 天)
find "$runners_dir"/*/cache -type f -mtime +7 -delete 2>/dev/null || true
echo "✓ Runner cache 已清理"
# 2. Gradle cache超过 30 天)
find ~/.gradle/caches -type f -mtime +30 -delete 2>/dev/null || true
find ~/.gradle/caches -type d -empty -delete 2>/dev/null || true
echo "✓ Gradle cache 已清理"
# 3. npm cache 验证
npm cache verify
echo "✓ npm cache 已验证"
# 4. Workspace 清理(超过 7 天)
find "$runners_dir"/*/workspace -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \; 2>/dev/null || true
echo "✓ Workspace 已清理"
# 显示缓存大小
echo ""
echo "当前缓存大小:"
for runner in "$runners_dir"/*; do
if [ -d "$runner" ]; then
name=$(basename "$runner")
size=$(du -sh "$runner/cache" 2>/dev/null | awk '{print $1}')
echo " $name: ${size:-0B}"
fi
done
echo ""
echo "✓ 清理完成"
```
### 定时清理
```bash
# 添加到 crontab
chmod +x ~/.config/gitea/cleanup-cache.sh
crontab -e
# 每周日凌晨 3 点清理
0 3 * * 0 ~/.config/gitea/cleanup-cache.sh >> ~/.config/gitea/cleanup.log 2>&1
```
## Runner 管理命令
### 列出所有 Runners
```bash
/gitea-list-runners
```
### 启动 Runner
```bash
# 前台运行(调试用)
act_runner daemon --config ~/.config/gitea/runners/runner-macbook-pro/config.yaml
# 后台运行
nohup act_runner daemon --config ~/.config/gitea/runners/runner-macbook-pro/config.yaml \
> ~/.config/gitea/runners/runner-macbook-pro/runner.log 2>&1 &
```
### 停止 Runner
```bash
# 查找进程
ps aux | grep "act_runner daemon"
# 停止特定 runner
pkill -f "act_runner daemon --config.*runner-macbook-pro"
# 停止所有 runners
pkill -f "act_runner daemon"
```
### 查看 Runner 日志
```bash
# 实时查看
tail -f ~/.config/gitea/runners/runner-macbook-pro/runner.log
# 查看最近 100 行
tail -n 100 ~/.config/gitea/runners/runner-macbook-pro/runner.log
```
### 删除 Runner
```bash
/gitea-delete-runner runner-macbook-pro
```
## 故障排查
### 1. Android SDK 未找到
```bash
# 验证 ANDROID_HOME
echo $ANDROID_HOME
ls $ANDROID_HOME
# 确保 runner 以安装 SDK 的用户身份运行
whoami
```
### 2. JDK 版本错误
Android Gradle Plugin 8.x 需要 JDK 17+
```bash
java -version
# 应显示: openjdk version "17.x.x"
# 如果版本错误,更新 JAVA_HOME
export JAVA_HOME=/opt/homebrew/opt/openjdk@17
```
### 3. 权限问题
```bash
# 确保 runner 用户拥有工作目录
chown -R $(whoami) ~/.config/gitea/runners
chmod -R 755 ~/.config/gitea/runners
```
### 4. Label 不匹配
```bash
# 检查注册的 labels
cat ~/.config/gitea/runners/runner-macbook-pro/.runner | jq '.labels'
# 确保 workflow runs-on 匹配
# Workflow: runs-on: darwin-arm64
# Runner: "darwin-arm64:host" label
```
### 5. 缓存服务端口冲突
```bash
# 检查端口占用
lsof -i :9000
# 如果冲突,修改配置使用其他端口
vim ~/.config/gitea/runners/runner-macbook-pro/config.yaml
# 修改: port: 9001
```
### 6. Runner 无法连接 Gitea
```bash
# 测试 Gitea 连接
source ~/.config/gitea/config.env
curl -s "$GITEA_URL/api/v1/version" | jq .
# 检查防火墙设置
# 检查网络连接
```
### 7. Runner 已注册但不在线
```bash
# 检查 runner 进程
ps aux | grep "act_runner daemon"
# 如果未运行,后台启动 runner创建时会自动启动
nohup act_runner daemon --config ~/.config/gitea/runners/runner-macbook-pro/config.yaml \
> ~/.config/gitea/runners/runner-macbook-pro/runner.log 2>&1 &
# 查看日志诊断问题
tail -f ~/.config/gitea/runners/runner-macbook-pro/runner.log
```
## Quick Reference
| 任务 | 命令 |
|------|------|
| 安装 runner | `brew install act_runner` |
| 创建 runner | `/gitea-create-runner`(自动安装、配置、启动)|
| 列出 runners | `/gitea-list-runners` |
| 删除 runner | `/gitea-delete-runner` |
| 手动启动 | `nohup act_runner daemon --config <config.yaml> > <log> 2>&1 &` |
| 停止 runner | `pkill -f "act_runner daemon --config.*<name>"` |
| 查看状态 | `ps aux \| grep act_runner` |
| 查看日志 | `tail -f <runner-dir>/runner.log` |
| 清理缓存 | `~/.config/gitea/cleanup-cache.sh` |
## 相关资源
- [Gitea Actions 文档](https://docs.gitea.com/usage/actions/overview)
- [Act Runner 文档](https://docs.gitea.com/usage/actions/act-runner)
- [Android SDK 命令行工具](https://developer.android.com/studio/command-line)
- [GitHub Actions Workflow 语法](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions)
## 版本
- **文档版本**: 1.0
- **最后更新**: 2026-01-12
- **兼容性**: act_runner 0.2.13+, macOS ARM64, Linux