Files
opencode/command/gitea-create-runner.md

771 lines
21 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.
---
description: Create and start a Gitea Actions runner (default host mode)
agent: general
subtask: true
---
# 创建并启动 Gitea Actions Runner
你的任务是创建并启动一个 Gitea Actions Runner默认使用 host 模式)。
## 工作目录
**macOS / Linux:**
```
~/.config/gitea/
```
**Windows:**
```
%USERPROFILE%\.config\gitea\
```
所有 Runner 配置、缓存、工作区都存储在该目录的 `runners/` 子目录下。
## 核心功能要求
请按照以下步骤执行:
1. **检查 act_runner 安装**
- 检查 act_runner 是否已安装(使用 `command -v act_runner`
- 如果未安装,使用 Homebrew 自动安装:`brew install act_runner`
- 如果 Homebrew 不存在,提示用户安装 Homebrew
- 验证安装成功后显示版本信息
2. **加载 Gitea 配置**
- 从配置文件加载配置:
- macOS/Linux: `~/.config/gitea/config.env`
- Windows: `%USERPROFILE%\.config\gitea\config.env`
- 如果配置文件不存在,提示用户运行 `/gitea-reset` 初始化
- 验证必需的配置项:`GITEA_URL``GITEA_TOKEN`
- 显示加载成功的配置信息
3. **生成 Runner 名称**
- 如果用户提供了参数 `$ARGUMENTS`,使用该名称
- 否则默认基于主机名生成:`runner-$(hostname -s)`
- 验证名称只包含字母、数字、下划线和连字符
4. **检查 Runner 是否已存在**
- 检查 Runner 目录:
- macOS/Linux: `~/.config/gitea/runners/$runner_name`
- Windows: `%USERPROFILE%\.config\gitea\runners\$runner_name`
- 如果已存在,提示用户可选操作:
- 使用其他名称
- 删除现有 runner使用 `/gitea-delete-runner`
- 查看所有 runners使用 `/gitea-list-runners`
5. **检测系统环境**
- 检测操作系统macOS/Linux
- 检测架构ARM64/x64
- 生成 host 模式的 labels
- `self-hosted:host`
- `{os_label}:host`(如 `macOS:host`
- `{arch_label}:host`(如 `ARM64:host`
- `{combined}:host`(如 `darwin-arm64:host`
6. **创建 Runner 目录结构**
- 创建目录结构:
- macOS/Linux: `~/.config/gitea/runners/$runner_name/{cache,workspace}`
- Windows: `%USERPROFILE%\.config\gitea\runners\$runner_name\{cache,workspace}`
- 验证目录创建成功
7. **生成配置文件**
- 创建 `config.yaml`,使用 host 模式配置
- 从环境变量读取可选配置:
- `GITEA_RUNNER_CAPACITY`(默认 2
- `GITEA_RUNNER_TIMEOUT`(默认 3h
- 配置要点:
- log level: info
- runner.capacity: 并发任务数
- runner.timeout: 任务超时
- cache: 启用缓存
- host.workdir_parent: 工作目录路径
- labels: 使用检测到的系统 labels
8. **获取注册 Token**
- 优先尝试创建全局 Runner需要管理员权限
- API: `GET ${GITEA_URL}/api/v1/admin/runners/registration-token`
- Header: `Authorization: token ${GITEA_TOKEN}`
- 如果返回 403/权限不足,自动降级到组织 Runner
- 使用 `GITEA_DEFAULT_ORG` 作为组织名
- API: `POST ${GITEA_URL}/api/v1/orgs/${org_name}/actions/runners/registration-token`
- 从响应中提取 tokenJSON 格式)
- 记录使用的 runner 级别global 或 organization
9. **注册 Runner**
- 执行命令:
```bash
act_runner register \
--config "$runner_dir/config.yaml" \
--instance "$GITEA_URL" \
--token "$registration_token" \
--name "$runner_name" \
--labels "$labels" \
--no-interactive
```
- 验证 `.runner` 文件是否创建
- 如果失败,提供诊断建议
10. **后台启动 Runner**
- 使用 nohup 后台启动:
```bash
nohup act_runner daemon --config "$runner_dir/config.yaml" \
> "$runner_dir/runner.log" 2>&1 &
```
- 记录进程 PID
- 等待 3 秒初始化
- 验证进程仍在运行
- 如果失败,显示日志的最后 20 行
11. **显示创建摘要**
- Runner 信息名称、级别、模式、状态、PID
- 如果是组织级别,显示组织名
- 配置信息容量、超时、labels
- 目录信息:配置文件、工作目录、缓存目录、日志文件
- 管理命令:查看日志、停止 Runner、查看所有、删除
- 使用示例workflow 中的 runs-on 配置
## 重要配置说明
- **默认模式**Host Mode直接在宿主机执行支持 Android SDK、iOS 构建等原生工具)
- **目录结构**
- macOS/Linux: 所有 runners 位于 `~/.config/gitea/runners/`
- Windows: 所有 runners 位于 `%USERPROFILE%\.config\gitea\runners\`
- **优雅降级**:全局 runner 权限不足时自动降级到组织 runner
- **后台运行**:使用 nohup 后台启动Unix或 Start-ProcessWindows日志输出到文件
- **进程管理**:需要手动管理进程(系统重启后需重新启动)
## 可选参数
- `$ARGUMENTS`: Runner 名称(可选,默认基于主机名生成)
使用示例:
```
/gitea-create-runner
/gitea-create-runner my-custom-runner
```
## 相关命令
- `/gitea-config`: 查看 Gitea 配置
- `/gitea-reset`: 重置/初始化 Gitea 配置
- `/gitea-list-runners`: 列出所有 runners
- `/gitea-delete-runner`: 删除指定 runner
---
## 详细实现步骤(供 AI 参考)
### 1. Check act_runner Installation
**AI 执行**:检查 act_runner 是否已安装,如果没有则自动安装。
```bash
echo "检查 act_runner 安装状态..."
if command -v act_runner &> /dev/null; then
version=$(act_runner --version 2>&1 | head -n1)
echo "✓ act_runner 已安装: $version"
else
echo "⚠️ act_runner 未安装"
echo "正在使用 Homebrew 安装..."
if ! command -v brew &> /dev/null; then
echo "❌ 需要先安装 Homebrew"
echo " 安装命令: /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
exit 1
fi
brew install act_runner
if [ $? -eq 0 ]; then
version=$(act_runner --version 2>&1 | head -n1)
echo "✓ act_runner 安装成功: $version"
else
echo "❌ act_runner 安装失败"
exit 1
fi
fi
echo ""
```
### 2. Load Gitea Configuration
**AI 执行**:加载 Gitea 配置,如果不存在则提示初始化。
```bash
config_file="$HOME/.config/gitea/config.env"
if [ ! -f "$config_file" ]; then
echo "❌ Gitea 配置不存在"
echo ""
echo "请先初始化 Gitea 配置:"
echo " /gitea-reset"
echo ""
echo "或使用以下命令查看配置:"
echo " /gitea-config"
exit 1
fi
source "$config_file"
if [ -z "$GITEA_URL" ] || [ -z "$GITEA_TOKEN" ]; then
echo "❌ Gitea 配置不完整"
echo " 需要 GITEA_URL 和 GITEA_TOKEN"
echo ""
echo "请重新初始化配置:"
echo " /gitea-reset"
exit 1
fi
echo "✓ 已加载 Gitea 配置"
echo " URL: $GITEA_URL"
echo ""
```
### 3. Generate Runner Name
**AI 执行**:生成 runner 名称(基于主机名或用户输入)。
```bash
# Check if runner name provided as argument
# 如果用户提供了名称参数,使用该参数;否则基于主机名生成
if [ -n "$1" ]; then
runner_name="$1"
echo "使用指定的 Runner 名称: $runner_name"
else
hostname=$(hostname -s 2>/dev/null || echo "unknown")
runner_name="runner-$hostname"
echo "生成 Runner 名称: $runner_name"
echo " (基于主机名: $hostname)"
fi
echo ""
# Validate runner name
if [[ ! "$runner_name" =~ ^[a-zA-Z0-9_-]+$ ]]; then
echo "❌ Runner 名称只能包含字母、数字、下划线和连字符"
exit 1
fi
```
### 4. Check Runner Existence
**AI 执行**:检查 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_dir"
echo ""
echo "选项:"
echo " 1. 使用其他名称: /gitea-create-runner <新名称>"
echo " 2. 删除现有 runner: /gitea-delete-runner"
echo " 3. 查看所有 runners: /gitea-list-runners"
exit 1
fi
```
### 5. Detect System Environment
**AI 执行**:智能检测系统环境并生成 labels。
```bash
echo "检测系统环境..."
# Detect OS
OS=$(uname -s)
case "$OS" in
Darwin) os_label="macOS" ;;
Linux) os_label="ubuntu" ;;
*) os_label="unknown" ;;
esac
# Detect architecture
ARCH=$(uname -m)
case "$ARCH" in
arm64|aarch64) arch_label="ARM64" ;;
x86_64) arch_label="x64" ;;
*) arch_label="unknown" ;;
esac
# Generate combined label
combined=$(echo "${OS}-${ARCH}" | tr '[:upper:]' '[:lower:]')
# Generate labels for host mode
labels="self-hosted:host,${os_label}:host,${arch_label}:host,${combined}:host"
echo "✓ 系统信息"
echo " 操作系统: $OS ($os_label)"
echo " 架构: $ARCH ($arch_label)"
echo " 组合标签: $combined"
echo ""
echo "✓ Runner Labels (Host Mode)"
echo " $labels"
echo ""
```
### 6. Create Runner Directory
**AI 执行**:创建 runner 目录结构。
```bash
echo "创建 Runner 目录..."
mkdir -p "$runner_dir"/{cache,workspace}
if [ ! -d "$runner_dir" ]; then
echo "❌ 创建目录失败"
exit 1
fi
echo "✓ 目录创建成功"
echo " 路径: $runner_dir"
echo " - cache/"
echo " - workspace/"
echo ""
```
### 7. Generate Configuration File
**AI 执行**:生成 host 模式配置文件。
```bash
echo "生成配置文件..."
# Get environment-specific settings (with defaults)
runner_capacity="${GITEA_RUNNER_CAPACITY:-2}"
runner_timeout="${GITEA_RUNNER_TIMEOUT:-3h}"
# Generate config.yaml for host mode
cat > "$runner_dir/config.yaml" << EOF
log:
level: info
runner:
file: $runner_dir/.runner
capacity: $runner_capacity
timeout: $runner_timeout
shutdown_timeout: 30s
insecure: false
fetch_timeout: 5s
fetch_interval: 2s
labels:
- "self-hosted:host"
- "${os_label}:host"
- "${arch_label}:host"
- "${combined}:host"
cache:
enabled: true
dir: "$runner_dir/cache"
host: "127.0.0.1"
port: 9000
host:
workdir_parent: "$runner_dir/workspace"
EOF
if [ ! -f "$runner_dir/config.yaml" ]; then
echo "❌ 配置文件生成失败"
exit 1
fi
echo "✓ 配置文件已生成"
echo " 文件: $runner_dir/config.yaml"
echo " 模式: Host Mode (原生执行)"
echo " 容量: $runner_capacity 并发任务"
echo " 超时: $runner_timeout"
echo ""
```
### 8. Get Registration Token
**AI 执行**:获取注册 token优先全局失败则降级到组织
```bash
echo "获取 Runner 注册 Token..."
echo ""
# Try global runner first (requires admin token)
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')
# Check for admin permission
if [ "$http_code" = "200" ]; then
echo "✓ 使用全局 Runner"
runner_level="global"
registration_token=$(echo "$body" | jq -r '.token')
else
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"
echo "使用默认组织: $org_name"
else
echo "❌ 未配置默认组织"
echo " 请在配置文件中设置 GITEA_DEFAULT_ORG"
echo " 或重新初始化配置: /gitea-reset"
exit 1
fi
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')
if [ "$http_code" != "200" ]; then
echo "❌ 获取注册 Token 失败 (HTTP $http_code)"
echo " 响应: $body"
echo ""
echo "可能的原因:"
echo " 1. 组织不存在"
echo " 2. Token 没有组织管理权限"
echo " 3. 网络连接问题"
exit 1
fi
registration_token=$(echo "$body" | jq -r '.token')
echo "✓ 组织 Runner Token 已获取"
fi
if [ -z "$registration_token" ] || [ "$registration_token" = "null" ]; then
echo "❌ 无法解析注册 Token"
exit 1
fi
echo "✓ 注册 Token 已准备"
echo ""
```
### 9. Register Runner
**AI 执行**:注册 runner 到 Gitea 服务器。
```bash
echo "注册 Runner 到 Gitea 服务器..."
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 注册失败"
echo ""
echo "请检查:"
echo " 1. Token 是否有效"
echo " 2. Gitea 服务器是否可访问"
echo " 3. 配置文件是否正确"
echo ""
echo "查看详细错误,可以手动运行:"
echo " act_runner register --config $runner_dir/config.yaml --instance $GITEA_URL --token <token> --name $runner_name --labels \"$labels\""
exit 1
fi
# Verify .runner file was created
if [ ! -f "$runner_dir/.runner" ]; then
echo "⚠️ 注册文件未创建,但注册可能成功"
echo " 请检查: $runner_dir/.runner"
fi
echo ""
```
### 10. Start Runner
**AI 执行**:后台启动 runner 并验证状态。
```bash
echo "启动 Runner..."
# Start runner in background
nohup act_runner daemon --config "$runner_dir/config.yaml" \
> "$runner_dir/runner.log" 2>&1 &
runner_pid=$!
echo " 进程已启动 (PID: $runner_pid)"
# Wait for runner to initialize
echo " 等待初始化..."
sleep 3
# Check if process is still running
if ps -p $runner_pid > /dev/null 2>&1; then
echo "✓ Runner 运行中"
else
echo "❌ Runner 启动失败"
echo ""
echo "查看日志以诊断问题:"
echo " tail -n 50 $runner_dir/runner.log"
echo ""
tail -n 20 "$runner_dir/runner.log"
exit 1
fi
echo ""
```
### 11. Display Summary
**AI 执行**:显示创建结果和管理命令。
```bash
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ Runner 创建完成!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "Runner 信息:"
echo " 名称: $runner_name"
echo " 级别: $runner_level"
if [ "$runner_level" = "organization" ]; then
echo " 组织: $org_name"
fi
echo " 模式: Host Mode (原生执行)"
echo " 状态: 🟢 运行中"
echo " PID: $runner_pid"
echo ""
echo "配置:"
echo " 容量: $runner_capacity 并发任务"
echo " 超时: $runner_timeout"
echo " Labels: $labels"
echo ""
echo "目录:"
echo " 配置文件: $runner_dir/config.yaml"
echo " 注册信息: $runner_dir/.runner"
echo " 工作目录: $runner_dir/workspace"
echo " 缓存目录: $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"
echo ""
echo "使用 Runner:"
echo " 在 workflow 中使用以下任一 runs-on 值:"
echo " - runs-on: $combined"
echo " - runs-on: $os_label"
echo " - runs-on: [self-hosted, $os_label, $arch_label]"
echo ""
```
## Output Example
### Example 1: Successful Creation (Global Runner)
```
检查 act_runner 安装状态...
✓ act_runner 已安装: act_runner version 0.2.13
✓ 已加载 Gitea 配置
URL: https://git.digitevents.com
生成 Runner 名称: runner-macbook-pro
(基于主机名: macbook-pro)
检测系统环境...
✓ 系统信息
操作系统: Darwin (macOS)
架构: arm64 (ARM64)
组合标签: darwin-arm64
✓ Runner Labels (Host Mode)
self-hosted:host,macOS:host,ARM64:host,darwin-arm64:host
创建 Runner 目录...
✓ 目录创建成功
路径: /Users/voson/.config/gitea/runners/runner-macbook-pro
- cache/
- workspace/
生成配置文件...
✓ 配置文件已生成
文件: /Users/voson/.config/gitea/runners/runner-macbook-pro/config.yaml
模式: Host Mode (原生执行)
容量: 2 并发任务
超时: 3h
获取 Runner 注册 Token...
尝试创建全局 Runner可用于所有组织和仓库...
✓ 使用全局 Runner
✓ 注册 Token 已准备
注册 Runner 到 Gitea 服务器...
✓ Runner 注册成功
启动 Runner...
进程已启动 (PID: 12345)
等待初始化...
✓ Runner 运行中
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Runner 创建完成!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Runner 信息:
名称: runner-macbook-pro
级别: global
模式: Host Mode (原生执行)
状态: 🟢 运行中
PID: 12345
配置:
容量: 2 并发任务
超时: 3h
Labels: self-hosted:host,macOS:host,ARM64:host,darwin-arm64:host
目录:
配置文件: /Users/voson/.config/gitea/runners/runner-macbook-pro/config.yaml
注册信息: /Users/voson/.config/gitea/runners/runner-macbook-pro/.runner
工作目录: /Users/voson/.config/gitea/runners/runner-macbook-pro/workspace
缓存目录: /Users/voson/.config/gitea/runners/runner-macbook-pro/cache
日志文件: /Users/voson/.config/gitea/runners/runner-macbook-pro/runner.log
管理命令:
查看日志: tail -f /Users/voson/.config/gitea/runners/runner-macbook-pro/runner.log
停止 Runner: pkill -f 'act_runner daemon --config.*runner-macbook-pro'
查看所有: /gitea-list-runners
删除 Runner: /gitea-delete-runner
使用 Runner:
在 workflow 中使用以下任一 runs-on 值:
- runs-on: darwin-arm64
- runs-on: macOS
- runs-on: [self-hosted, macOS, ARM64]
```
### Example 2: Auto-install act_runner
```
检查 act_runner 安装状态...
⚠️ act_runner 未安装
正在使用 Homebrew 安装...
==> Downloading act_runner...
==> Installing act_runner...
✓ act_runner 安装成功: act_runner version 0.2.13
[继续后续步骤...]
```
### Example 3: Downgrade to Organization Runner
```
获取 Runner 注册 Token...
尝试创建全局 Runner可用于所有组织和仓库...
⚠️ 全局 Runner 权限不足 (HTTP 403)
全局 Runner 需要管理员 Token
降级到组织 Runner...
使用默认组织: ai
✓ 组织 Runner Token 已获取
✓ 注册 Token 已准备
[继续后续步骤...]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Runner 创建完成!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Runner 信息:
名称: runner-macbook-pro
级别: organization
组织: ai
模式: Host Mode (原生执行)
[...]
```
### Example 4: Configuration Not Found
```
检查 act_runner 安装状态...
✓ act_runner 已安装: act_runner version 0.2.13
❌ Gitea 配置不存在
请先初始化 Gitea 配置:
/gitea-reset
或使用以下命令查看配置:
/gitea-config
```
### Example 5: Runner Already Exists
```
[前置检查...]
生成 Runner 名称: runner-macbook-pro
(基于主机名: macbook-pro)
❌ Runner 'runner-macbook-pro' 已存在
路径: /Users/voson/.config/gitea/runners/runner-macbook-pro
选项:
1. 使用其他名称: /gitea-create-runner <新名称>
2. 删除现有 runner: /gitea-delete-runner
3. 查看所有 runners: /gitea-list-runners
```
## Technical Notes
- **默认模式**Host Mode支持 Android SDK、iOS 等原生工具)
- **自动安装**:使用 Homebrew 安装 act_runner
- **智能检测**:自动检测 OS 和架构,生成合适的 labels
- **优雅降级**:全局 runner 权限不足时自动降级到组织 runner
- **后台运行**:自动后台启动,日志记录到文件
- **配置环境变量**
- `GITEA_RUNNER_CAPACITY`: 并发任务数(默认 2
- `GITEA_RUNNER_TIMEOUT`: 任务超时时间(默认 3h
- **目录权限**:自动创建,权限继承用户默认权限
- **进程管理**:使用 nohup 后台运行,支持系统重启后手动重启
## Related Commands
- `/gitea-config`: 查看 Gitea 配置
- `/gitea-reset`: 重置/初始化 Gitea 配置
- `/gitea-list-runners`: 列出所有 runners
- `/gitea-delete-runner`: 删除指定 runner
- `/create-gitea-repo`: 创建 Gitea 仓库
## Safety Features
- **配置验证**:检查必需的配置项
- **目录冲突检测**:避免覆盖现有 runner
- **启动验证**:等待并验证进程启动成功
- **错误提示**:清晰的错误信息和解决方案
- **日志记录**:所有输出记录到日志文件
## Version
- **Command Version**: 1.0
- **Last Updated**: 2026-01-12
- **Compatible with**: act_runner 0.2.13+, macOS/Linux