Files
BYW-VoiceHub/scripts/setup-runner.sh
T
Henry_Du 08a6a66977
构建 & 部署 BYW VoiceHub / Preflight 语法 & 构建检查 (push) Canceled after 0s
构建 & 部署 BYW VoiceHub / 构建并推送镜像 (push) Canceled after 0s
构建 & 部署 BYW VoiceHub / 部署到生产服务器 (push) Canceled after 0s
ci: 适配 Gitea 1.27+ 的 Runner 注册 Token(RGT/RGO/RG 三种前缀)
2026-09-06 08:56:16 +08:00

269 lines
12 KiB
Bash
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.
#!/usr/bin/env bash
# ============================================================================
# setup-runner.sh —— 一键安装并注册 Gitea Actions Runner(act_runner)
#
# ✅ 兼容 Gitea 1.21 ~ 最新(含 1.27.x),新版没有 Platform 下拉菜单。
#
# 使用方法(两种模式任选其一,推荐 模式 A 最省事):
#
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 模式 A:仓库级 Runner(只给这个 VoiceHub 仓库用,最常用、权限最小)
# 路径:你的仓库 → Settings → Actions → Runners → 右上角
# → 新版(1.21+)这里没有 Platform 选择,直接有一个输入框
# 写着「Registration token」或「注册令牌」
# → 点右边的 📋 复制按钮,得到一串以 R 开头的 token
# 例: RGT8FZxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxV
#
# 机器上执行:
# sudo bash scripts/setup-runner.sh \
# --scope repo --gitea https://你的-gitea --token RGTxxxx...
#
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 模式 B:组织级 Runner(同一个 Gitea 组织下所有仓库都能用)
# 路径:组织主页 → Settings → Actions → Runners → 复制 Registration token
# (Token 开头一般是 RGOxxxx)
#
# 执行:
# sudo bash scripts/setup-runner.sh \
# --scope org --gitea https://你的-gitea --token RGOxxxx...
#
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 模式 C:全局/站点级 Runner(Gitea 全站所有仓库都能用,需站点管理员)
# 路径:站点管理后台(Site Administration)→ Actions → Runners
# → 复制 Registration token(开头一般是 RGxxxx)
#
# 执行:
# sudo bash scripts/setup-runner.sh \
# --scope global --gitea https://你的-gitea --token RGxxxx...
#
# 其他可选参数:
# --name "my-runner-01" 自定义 Runner 名字(默认是 runner-主机名)
# --user gitrunner 运行用户(默认 gitrunner)
# --dir /opt/act_runner 安装目录(默认 /opt/act_runner)
# ============================================================================
set -euo pipefail
# ---------- 颜色 ----------
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[1;36m'; NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
err() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; }
ok() { echo -e "${CYAN}[ OK ]${NC} $*"; }
# ---------- 解析参数 ----------
GITEA_URL=""
REG_TOKEN=""
SCOPE="repo" # repo | org | global(默认 repo,绝大多数人的场景)
RUNNER_NAME="runner-$(hostname | tr '[:upper:]' '[:lower:]')"
RUNNER_USER="gitrunner"
INSTALL_DIR="/opt/act_runner"
while [[ $# -gt 0 ]]; do
case "$1" in
--gitea) GITEA_URL="${2}"; shift 2 ;;
--token) REG_TOKEN="${2}"; shift 2 ;;
--scope) SCOPE="${2}"; shift 2 ;;
--name) RUNNER_NAME="${2}"; shift 2 ;;
--user) RUNNER_USER="${2}"; shift 2 ;;
--dir) INSTALL_DIR="${2}"; shift 2 ;;
-h|--help)
sed -n '2,60p' "$0" | sed 's/^# \{0,1\}//'
exit 0
;;
*) err "未知参数:$1(--help 查看帮助)" ;;
esac
done
[[ -n "${GITEA_URL}" ]] || err "必须传 --gitea https://你的-gitea-地址"
[[ -n "${REG_TOKEN}" ]] || err "必须传 --token(从 Gitea 页面的 Registration token 复制,Rxx 开头的一串)"
case "${SCOPE}" in
repo|org|global) ;;
*) err "--scope 必须是 repo | org | global 其中之一" ;;
esac
[[ $EUID -eq 0 ]] || err "请用 sudo 运行本脚本(需要写 /opt / /etc/systemd/system)"
# 去掉末尾 /
GITEA_URL="${GITEA_URL%/}"
echo ""
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${CYAN} 🚀 开始部署 Gitea Actions Runner (兼容 1.21 ~ 1.27+)${NC}"
echo -e "${CYAN} • 绑定 Gitea : ${GITEA_URL}${NC}"
echo -e "${CYAN} • 作用域 : ${SCOPE}${NC}"
echo -e "${CYAN} • Runner 名称 : ${RUNNER_NAME}${NC}"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
# ---------- 0. 架构检测 ----------
ARCH="$(uname -m)"
case "${ARCH}" in
x86_64|amd64) PLATFORM="linux-amd64" ;;
aarch64|arm64) PLATFORM="linux-arm64" ;;
armv7l) PLATFORM="linux-arm" ;;
*) err "暂不支持的架构:${ARCH}(需要 x86_64 / aarch64 / armv7)" ;;
esac
ok "检测到架构:${ARCH} → 下载版本:${PLATFORM}"
# ---------- 0.5 给新版 Gitea 用户的 Token 格式提示 ----------
case "${REG_TOKEN}" in
RG*) ok "Token 前缀 RG:全局/站点级 Runner Token ✅" ;;
RGO*) ok "Token 前缀 RGO:组织级 Runner Token ✅" ;;
RGT*) ok "Token 前缀 RGT:仓库级 Runner Token ✅(最常用)" ;;
R[0-9A-Za-z]*)
warn "Token 不是标准 RG/RGO/RGT 前缀。新版本 Gitea 里 Registration token 应该是 Rxx 开头。"
warn " 如果你是从旧文档里拿的 GFxxxxx(旧版),在 1.27 里已经不再用这种格式了!"
warn " → 请回到仓库/组织/站点的 Actions → Runners 页面,点击 「创建 Runner」或「Registration Token」"
;;
*)
warn "Token 前缀不匹配任何已知格式:$REG_TOKEN。请核对复制的内容是否少选。"
;;
esac
# ---------- 1. 安装依赖:docker(Runner 要用 Docker-in-Docker 执行 buildx 等)----------
if ! command -v docker >/dev/null 2>&1; then
info "检测到没装 Docker,现在用官方一键脚本安装(国内自动换清华源)..."
curl -fsSL https://get.docker.com -o /tmp/get-docker.sh || err "下载 docker-install 脚本失败"
if curl -sI https://mirrors.tuna.tsinghua.edu.cn >/dev/null; then
bash /tmp/get-docker.sh --mirror Aliyun || bash /tmp/get-docker.sh
else
bash /tmp/get-docker.sh
fi
systemctl enable --now docker
info "✅ Docker 安装完成:$(docker --version)"
else
info "✅ Docker 已存在:$(docker --version)"
fi
# ---------- 2. 建运行用户 gitrunner,加入 docker 组 ----------
if ! id -u "${RUNNER_USER}" >/dev/null 2>&1; then
useradd -r -s /usr/sbin/nologin -d "${INSTALL_DIR}" "${RUNNER_USER}"
info "✅ 新建系统用户 ${RUNNER_USER}"
else
info "ℹ️ 用户 ${RUNNER_USER} 已存在,跳过创建"
fi
usermod -aG docker "${RUNNER_USER}"
info "✅ 把 ${RUNNER_USER} 加入 docker 组(允许操作 Docker daemon)"
mkdir -p "${INSTALL_DIR}"
chown -R "${RUNNER_USER}:${RUNNER_USER}" "${INSTALL_DIR}"
# ---------- 3. 下载最新 act_runner ----------
info "⬇️ 正在拉取 act_runner 最新 release 元数据..."
LATEST_JSON="$(curl -fsSL https://gitea.com/api/v1/repos/gitea/act_runner/releases/latest || true)"
if [[ -z "${LATEST_JSON}" ]]; then
warn "gitea.com 不通,改用硬编码版本 0.2.10(你之后可手动升级)"
VERSION="0.2.10"
else
VERSION="$(echo "${LATEST_JSON}" | grep -oE '"tag_name":\s*"[^"]+"' | head -1 | cut -d'"' -f4 | sed 's/^v//')"
[[ -n "${VERSION}" ]] || VERSION="0.2.10"
fi
BIN_URL="https://dl.gitea.com/act_runner/${VERSION}/act_runner-${VERSION}-${PLATFORM}"
info "⬇️ 下载 act_runner v${VERSION}:${BIN_URL}"
curl -fsSL "${BIN_URL}" -o /usr/local/bin/act_runner \
|| err "下载失败。请手动打开 ${BIN_URL} 看是否 404,然后换个版本"
chmod +x /usr/local/bin/act_runner
info "✅ act_runner 已安装到 /usr/local/bin,版本:$(act_runner --version 2>&1 || true)"
# ---------- 4. 注册 Runner ----------
cd "${INSTALL_DIR}"
info "🔗 开始注册 Runner 到 ${GITEA_URL}(名称:${RUNNER_NAME})"
# 切到 gitrunner 用户注册,避免 root 跑(安全)
rm -f .runner 2>/dev/null || true
sudo -u "${RUNNER_USER}" env HOME="${INSTALL_DIR}" \
act_runner register \
--instance "${GITEA_URL}" \
--token "${REG_TOKEN}" \
--name "${RUNNER_NAME}" \
--labels "ubuntu-latest:docker://catthehacker/ubuntu:act-22.04" \
--no-interactive \
|| err "注册失败!常见原因:\n 1) token 不对(复制时别带空格)\n 2) Runner 机器出不了网到 ${GITEA_URL}\n 3) Gitea 站点时间和这台机器差太远(证书验证失败)"
chown "${RUNNER_USER}:${RUNNER_USER}" .runner 2>/dev/null || true
# ---------- 5. 生成配置文件(建议开启 docker.host 特权)----------
CONFIG_FILE="${INSTALL_DIR}/config.yaml"
if [[ ! -f "${CONFIG_FILE}" ]]; then
cat > "${CONFIG_FILE}" <<'YAML'
log:
level: info
runner:
file: .runner
capacity: 2 # 同一台 Runner 最多同时跑 2 个 Job
envs:
GOPROXY: https://goproxy.cn,direct
NPM_CONFIG_REGISTRY: https://registry.npmmirror.com
timeout: 3h
cache:
enabled: true
dir: /opt/act_runner/cache
container:
network: "bridge"
privileged: true # build-push-action 用到 Docker daemon
options: |
--add-host "host.docker.internal:host-gateway"
YAML
chown "${RUNNER_USER}:${RUNNER_USER}" "${CONFIG_FILE}"
mkdir -p "${INSTALL_DIR}/cache"
chown -R "${RUNNER_USER}:${RUNNER_USER}" "${INSTALL_DIR}/cache"
info "✅ 默认 config 写入 ${CONFIG_FILE}"
fi
# ---------- 6. 写 systemd 服务,开机自启 ----------
UNIT_FILE="/etc/systemd/system/gitea-act-runner.service"
cat > "${UNIT_FILE}" <<SYSTEMD
[Unit]
Description=Gitea Actions Runner (${RUNNER_NAME})
After=network.target docker.service
Requires=docker.service
[Service]
Type=simple
User=${RUNNER_USER}
Group=${RUNNER_USER}
WorkingDirectory=${INSTALL_DIR}
Environment=HOME=${INSTALL_DIR}
ExecStart=/usr/local/bin/act_runner daemon --config ${CONFIG_FILE}
Restart=always
RestartSec=5
KillMode=mixed
TimeoutStopSec=30
# 安全加固
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=${INSTALL_DIR} /var/run/docker.sock /tmp /var/tmp
[Install]
WantedBy=multi-user.target
SYSTEMD
systemctl daemon-reload
systemctl enable --now gitea-act-runner
info "✅ systemd 服务已写入并启动:${UNIT_FILE}"
sleep 3 # 给 daemon 点时间注册
info "📌 当前 Runner 状态:"
systemctl --no-pager status gitea-act-runner | head -15 || true
info "📌 最近 30 行日志(验证 OK):"
journalctl --no-pager -u gitea-act-runner --since "2 minutes ago" -n 30 || true
echo ""
echo -e "${GREEN}===========================================================================${NC}"
echo -e "${GREEN} 🎉 Gitea Actions Runner 安装 & 注册 & 开机自启 全部完成!${NC}"
echo -e "${GREEN}===========================================================================${NC}"
echo " ✅ Runner 名称 : ${RUNNER_NAME}"
echo " ✅ 运行用户 : ${RUNNER_USER}"
echo " ✅ 安装目录 : ${INSTALL_DIR}"
echo " ✅ 绑定 Gitea : ${GITEA_URL}"
echo ""
echo " 👉 下一步验证(建议立刻做):"
echo " 1. 浏览器打开:${GITEA_URL} → 仓库 → Settings → Actions → Runners"
echo " 应该能看到一个 Runner,状态 = Idle"
echo " 2. 回到终端,模拟跑一个 workflow 没问题就彻底大功告成!"
echo " 👉 常用命令:"
echo " systemctl {start|stop|restart|status} gitea-act-runner"
echo " journalctl -u gitea-act-runner -f # 实时看日志"
echo ""