Files
BYW-VoiceHub/scripts/setup-runner.sh
T
Henry_Du a027816831
构建 & 部署 BYW VoiceHub / Preflight 语法 & 构建检查 (push) Canceled after 0s
构建 & 部署 BYW VoiceHub / 构建并推送镜像 (push) Canceled after 0s
构建 & 部署 BYW VoiceHub / 部署到生产服务器 (push) Canceled after 0s
fix: 修复 Gitea Runner 下载 404(v3+ 改名 gitea-runner,改为 assets 匹配 + 多源回退)
2026-09-06 09:13:06 +08:00

381 lines
17 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)
# --version 3.3.2 【可选】固定安装某版本,不写默认用 Gitea 官方 latest
# ============================================================================
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"
PINNED_VERSION="" # 空 = latest,否则比如 "3.3.2" 固定版本
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 ;;
--version) PINNED_VERSION="${2#v}"; 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 格式提示 ----------
# 不同版本 / 语言包的 Token 前缀不一样,兼容 4 种真实存在的格式:
# • 英文 1.21+ 仓库级 RGTxxxx / 组织级 RGOxxxx / 全局 RGxxxx
# • 中文语言包 / 某些二次分发版本:纯字母数字 20~64 位(如 LHLDAwsho7vVSukoEeKhft)
TOKEN_LEN="${#REG_TOKEN}"
ok "Token 长度 = ${TOKEN_LEN} 位"
case "${REG_TOKEN}" in
# 英文原版前缀
RG*) info "• Token 前缀 RG:全局/站点级(英文原版)✅" ;;
RGO*) info "• Token 前缀 RGO:组织级(英文原版)✅" ;;
RGT*) info "• Token 前缀 RGT:仓库级(英文原版)✅" ;;
# 纯字母数字(中文 UI / 二开版本常见)
[A-Za-z0-9]\{16,128\})
ok "• 纯字母数字 Token(中文 UI / 某些二开版本常见)✅,和截图里的「注册令牌」一致"
;;
# 其他
*)
warn "• Token 看起来不是 Gitea 常见格式。不过也可能是新版改动,继续尝试注册..."
warn " 如果注册报 401/403,建议回到页面点一次「重置注册令牌」重新复制。"
;;
esac
# 基本字符集校验(防止复制时粘了空格或换行)
if [[ ! "${REG_TOKEN}" =~ ^[A-Za-z0-9]+$ ]]; then
warn "⚠️ Token 里含有非字母数字的字符,很可能是复制时多带了空格/换行/标点!"
warn " 建议回到仓库页面点 📋 复制按钮(不要手选文字)。"
fi
# ---------- 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. 下载最新 Gitea Runner(act_runner 0.x → 3.x 改名 gitea-runner)
# 注意:官方从 v3 起,仓库从 gitea/act_runner 改到了 gitea/runner,且文件名前缀从 act_runner-* → gitea-runner-*。
# 为避免后续版本再改命名导致 404,这里**直接用 API 返回的 assets[].browser_download_url**,不再硬编码拼文件名。
# ----------
# 3.1 决定 release URL(固定版本 or latest)
if [[ -n "${PINNED_VERSION}" ]]; then
REL_URL="https://gitea.com/api/v1/repos/gitea/runner/releases/tags/v${PINNED_VERSION}"
info "⬇️ 你指定了固定版本:v${PINNED_VERSION}"
else
REL_URL="https://gitea.com/api/v1/repos/gitea/runner/releases/latest"
info "⬇️ 正在获取 Gitea Runner 最新 release 元数据..."
fi
LATEST_JSON="$(curl -fsSL "${REL_URL}" 2>/dev/null || true)"
# 3.2 如果 gitea.com 不通(纯内网),直接回退到一个我们已知可用的版本
if [[ -z "${LATEST_JSON}" ]]; then
if [[ -z "${PINNED_VERSION}" ]]; then
warn "gitea.com 访问不到(可能是内网环境),自动回退到已知稳定版本:v3.3.2"
PINNED_VERSION="3.3.2"
fi
TAG="v${PINNED_VERSION}"
FALLBACK_MODE=1
else
TAG="$(echo "${LATEST_JSON}" | grep -oE '"tag_name":\s*"[^"]+"' | head -1 | cut -d'"' -f4)"
FALLBACK_MODE=0
fi
[[ -n "${TAG}" ]] || TAG="v3.3.2"
VERSION="${TAG#v}"
# 3.3 优先从 assets 匹配正确 platform 的 browser_download_url
BIN_URL=""
ASSET_NAME=""
if [[ "${FALLBACK_MODE}" -eq 0 && -n "${LATEST_JSON}" ]]; then
# 用 awk 过滤:
# - 匹配 PLATFORM(例如 linux-amd64)
# - 排除 .xz / .sha256 / .exe 等校验和/压缩包
# - 两种前缀都兼容:gitea-runner-X.X.X- (新版) 或 act_runner-X.X.X- (旧版)
while IFS='|' read -r name url; do
[[ -z "${name}" ]] && continue
case "${name}" in
*"${PLATFORM}"* | *"${PLATFORM//-/_}"*) ;;
*) continue ;;
esac
case "${name}" in
*.xz|*.sha256|*.exe|*.tar.gz|*.zip|*checksums*) continue ;;
esac
ASSET_NAME="${name}"
BIN_URL="${url}"
break
done < <(echo "${LATEST_JSON}" | awk '
/"assets": *\[/ {inA=1; next}
inA && /"browser_download_url"/ { gsub(/[",]/,"",$2); url=$2 }
inA && /"name"/ {
gsub(/[",]/,"",$2)
if (url!="") { print $2 "|" url; url="" }
}
inA && /^\]/ {inA=0}
')
fi
# 3.4 如果 assets 匹配失败(老版本 JSON 格式特殊),手动拼 4 个候选 URL 顺序尝试
if [[ -z "${BIN_URL}" ]]; then
info "assets 自动匹配为空,改用手动候选列表(兼容新旧命名)..."
CANDIDATES=(
# 新版(v3+)gitea-runner
"https://gitea.com/gitea/runner/releases/download/v${VERSION}/gitea-runner-${VERSION}-${PLATFORM}"
# github 镜像(有时 gitea.com 慢或挂)
"https://github.com/go-gitea/runner/releases/download/v${VERSION}/gitea-runner-${VERSION}-${PLATFORM}"
# 旧版 act_runner(v0.2.x 遗留命名)
"https://dl.gitea.com/act_runner/${VERSION}/act_runner-${VERSION}-${PLATFORM}"
# 旧版 gitea.com
"https://gitea.com/gitea/act_runner/releases/download/v${VERSION}/act_runner-${VERSION}-${PLATFORM}"
)
for C in "${CANDIDATES[@]}"; do
info " → 尝试:${C}"
if curl -fsSI "${C}" >/dev/null 2>&1; then
BIN_URL="${C}"
ASSET_NAME="$(basename "${C}")"
break
fi
done
fi
# 3.5 还没拿到 URL → 打印手动下载指引(一定让用户能救回来)
if [[ -z "${BIN_URL}" ]]; then
{
echo ""
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${RED} ❌ 自动下载 Gitea Runner 失败${NC}"
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo " 你的架构:${PLATFORM} , 目标版本:${TAG}"
echo ""
echo " 请在能出网的机器上,手动打开下面 2 个 URL 之一,下载对应的二进制:"
echo " • https://gitea.com/gitea/runner/releases/tag/${TAG}"
echo " • https://github.com/go-gitea/runner/releases/tag/${TAG}"
echo " 找文件名类似:gitea-runner-${VERSION}-${PLATFORM}(不要下 .xz / .sha256)"
echo ""
echo " 下载完成后 scp 到本服务器并执行:"
echo " sudo cp ./gitea-runner-* /usr/local/bin/act_runner"
echo " sudo chmod +x /usr/local/bin/act_runner"
echo " # 然后重新跑本脚本(已有的用户/组/config 不会重复生成)"
echo ""
} >&2
exit 1
fi
# 3.6 真正下载
info "⬇️ 下载 Gitea Runner ${TAG}:${ASSET_NAME}"
info " URL:${BIN_URL}"
curl -fsSL "${BIN_URL}" -o /usr/local/bin/act_runner \
|| err "下载失败!可能是 DNS/网络/证书问题。可以手动把上面 URL 的文件下载下来 scp 到服务器放到 /usr/local/bin/act_runner,再重新跑本脚本。"
chmod +x /usr/local/bin/act_runner
INSTALLED_VER="$(act_runner --version 2>&1 || echo "${TAG}")"
ok "✅ 已安装到 /usr/local/bin/act_runner,版本:${INSTALLED_VER}"
# ---------- 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 ""