--- description: 创建并启动 Gitea Actions Runner(默认使用 host 模式) 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` - 从响应中提取 token(JSON 格式) - 记录使用的 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-Process(Windows),日志输出到文件 - **进程管理**:需要手动管理进程(系统重启后需重新启动) ## 可选参数 - `$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 --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