✨ 新增 act_runner 自动升级脚本并同步最新版本探测
Ubuntu System Information / show-system-info (push) Waiting to run
Details
Ubuntu System Information / show-system-info (push) Waiting to run
Details
This commit is contained in:
parent
1a52ee08a2
commit
9d4c4a1f73
|
|
@ -29,6 +29,7 @@ docker-runner/
|
|||
│ ├── check_crlf.sh # Windows 换行符检查工具
|
||||
│ ├── entrypoint.sh # 容器启动脚本
|
||||
│ ├── setup.sh # Runner 安装脚本
|
||||
│ ├── upgrade.sh # Runner 升级脚本
|
||||
│ ├── register.sh # Runner 注册脚本
|
||||
│ └── manage.sh # Runner 管理脚本
|
||||
│
|
||||
|
|
@ -128,7 +129,7 @@ docker-compose up -d
|
|||
docker-compose exec gitea-runner /data/setup.sh
|
||||
```
|
||||
|
||||
按照提示选择版本(默认 0.2.13)和架构(自动检测)。
|
||||
脚本会自动探测最新 `act_runner` 版本作为默认值,然后提示你确认架构。
|
||||
|
||||
#### 5. 注册 Runner
|
||||
|
||||
|
|
@ -250,6 +251,21 @@ docker-compose exec gitea-runner /data/manage.sh restart <runner-name>
|
|||
docker-compose exec gitea-runner /data/manage.sh delete <runner-name>
|
||||
```
|
||||
|
||||
### 升级 act_runner
|
||||
|
||||
```bash
|
||||
# 自动检查最新稳定版本,下载后重启所有已注册 runners
|
||||
docker-compose exec gitea-runner /data/upgrade.sh
|
||||
|
||||
# 指定版本
|
||||
docker-compose exec gitea-runner /data/upgrade.sh --version 0.6.1
|
||||
|
||||
# 仅重启指定 runner
|
||||
docker-compose exec gitea-runner /data/upgrade.sh --runner <runner-name>
|
||||
```
|
||||
|
||||
`upgrade.sh` 只替换 `/data/bin/act_runner` 并重启 runner 进程,不会重新注册,也不需要重新输入 token。
|
||||
|
||||
### 添加多个 Runners
|
||||
|
||||
```bash
|
||||
|
|
@ -389,8 +405,14 @@ CMD ["/app"]
|
|||
### Q1: 如何更新 Runner 版本?
|
||||
|
||||
```bash
|
||||
docker-compose exec gitea-runner /data/setup.sh
|
||||
# 脚本会检测到已安装并询问是否升级
|
||||
docker-compose exec gitea-runner /data/upgrade.sh
|
||||
# 脚本会自动从官方目录页检测最新 act_runner 版本
|
||||
```
|
||||
|
||||
如需固定版本:
|
||||
|
||||
```bash
|
||||
docker-compose exec gitea-runner /data/upgrade.sh --version 0.6.1
|
||||
```
|
||||
|
||||
### Q2: 如何添加多个 Runners?
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ NC='\033[0m'
|
|||
SCRIPT_FILES=(
|
||||
"entrypoint.sh"
|
||||
"setup.sh"
|
||||
"upgrade.sh"
|
||||
"register.sh"
|
||||
"manage.sh"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
# 共享升级脚本中的版本探测逻辑
|
||||
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
UPGRADE_HELPER="${SCRIPT_DIR}/upgrade.sh"
|
||||
DEFAULT_RUNNER_VERSION_FALLBACK="${DEFAULT_RUNNER_VERSION_FALLBACK:-0.2.13}"
|
||||
|
||||
if [ -f "${UPGRADE_HELPER}" ]; then
|
||||
# shellcheck source=/dev/null
|
||||
source "${UPGRADE_HELPER}"
|
||||
fi
|
||||
|
||||
echo "=========================================="
|
||||
echo " Gitea Runner Installation Script "
|
||||
echo "=========================================="
|
||||
|
|
@ -30,8 +40,20 @@ fi
|
|||
# 获取要安装的版本
|
||||
echo "Available versions: https://dl.gitea.com/act_runner/"
|
||||
echo ""
|
||||
read -p "Enter version to install (default: 0.2.13): " RUNNER_VERSION
|
||||
RUNNER_VERSION=${RUNNER_VERSION:-0.2.13}
|
||||
|
||||
DEFAULT_RUNNER_VERSION="${DEFAULT_RUNNER_VERSION_FALLBACK}"
|
||||
if declare -F resolve_latest_version_or_fallback >/dev/null 2>&1; then
|
||||
DEFAULT_RUNNER_VERSION=$(resolve_latest_version_or_fallback "${DEFAULT_RUNNER_VERSION_FALLBACK}")
|
||||
fi
|
||||
|
||||
echo "Default install version: ${DEFAULT_RUNNER_VERSION}"
|
||||
read -p "Enter version to install (default: ${DEFAULT_RUNNER_VERSION}): " RUNNER_VERSION
|
||||
RUNNER_VERSION=${RUNNER_VERSION:-$DEFAULT_RUNNER_VERSION}
|
||||
|
||||
if declare -F validate_version >/dev/null 2>&1 && ! validate_version "${RUNNER_VERSION}"; then
|
||||
echo "✗ Invalid version format: ${RUNNER_VERSION}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ARCH=$(uname -m)
|
||||
case "$ARCH" in
|
||||
|
|
@ -114,8 +136,7 @@ if curl -L "$DOWNLOAD_URL" -o "$INSTALL_PATH"; then
|
|||
echo "1. Register the runner:"
|
||||
echo " docker-compose exec gitea-runner /data/register.sh"
|
||||
echo ""
|
||||
echo "2. Restart the container:"
|
||||
echo " docker-compose restart"
|
||||
echo "2. Start using the runner after registration."
|
||||
echo ""
|
||||
echo "Note: act_runner is saved in persistent storage"
|
||||
echo " and will survive container restarts."
|
||||
|
|
|
|||
|
|
@ -0,0 +1,284 @@
|
|||
#!/bin/bash
|
||||
|
||||
INSTALL_PATH="/data/bin/act_runner"
|
||||
SYSTEM_PATH="/usr/local/bin/act_runner"
|
||||
RUNNER_INDEX_URL="${RUNNER_INDEX_URL:-https://dl.gitea.com/act_runner/}"
|
||||
|
||||
print_usage() {
|
||||
cat <<'EOF'
|
||||
Usage: /data/upgrade.sh [options]
|
||||
|
||||
Upgrade act_runner without re-registering existing runners.
|
||||
|
||||
Options:
|
||||
--version <version> Upgrade to a specific version instead of auto-detecting latest
|
||||
--arch <arch> Override detected architecture: amd64, arm64, arm-7
|
||||
--runner <name> Restart only the specified runner (can be used multiple times)
|
||||
-y, --yes Skip confirmation prompt
|
||||
-h, --help Show this help message
|
||||
EOF
|
||||
}
|
||||
|
||||
log() {
|
||||
echo "$@"
|
||||
}
|
||||
|
||||
fail() {
|
||||
echo "✗ $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
extract_version_number() {
|
||||
sed -nE 's/.*version[[:space:]]+([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' | head -n 1
|
||||
}
|
||||
|
||||
extract_versions_from_listing() {
|
||||
grep -oE '/act_runner/[0-9]+\.[0-9]+\.[0-9]+/' | \
|
||||
sed -E 's#^/act_runner/([0-9]+\.[0-9]+\.[0-9]+)/$#\1#' | \
|
||||
awk '!seen[$0]++'
|
||||
}
|
||||
|
||||
pick_latest_version() {
|
||||
awk 'NF' | sort -V | tail -n 1
|
||||
}
|
||||
|
||||
fetch_latest_version() {
|
||||
curl -fsSL "${RUNNER_INDEX_URL}" | extract_versions_from_listing | pick_latest_version
|
||||
}
|
||||
|
||||
resolve_latest_version_or_fallback() {
|
||||
local fallback_version=$1
|
||||
local fetcher_cmd=${2:-fetch_latest_version}
|
||||
local detected_version=""
|
||||
|
||||
if command -v "${fetcher_cmd}" >/dev/null 2>&1; then
|
||||
detected_version=$("${fetcher_cmd}" 2>/dev/null || true)
|
||||
fi
|
||||
|
||||
if [ -n "${detected_version}" ] && validate_version "${detected_version}"; then
|
||||
echo "${detected_version}"
|
||||
else
|
||||
echo "${fallback_version}"
|
||||
fi
|
||||
}
|
||||
|
||||
validate_version() {
|
||||
local version=$1
|
||||
|
||||
[[ "${version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]
|
||||
}
|
||||
|
||||
detect_runner_arch() {
|
||||
local arch
|
||||
arch=$(uname -m)
|
||||
|
||||
case "${arch}" in
|
||||
x86_64)
|
||||
echo "amd64"
|
||||
;;
|
||||
aarch64|arm64)
|
||||
echo "arm64"
|
||||
;;
|
||||
armv7l)
|
||||
echo "arm-7"
|
||||
;;
|
||||
*)
|
||||
fail "Unsupported architecture: ${arch}"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_installed_version() {
|
||||
local output=""
|
||||
|
||||
if [ -x "${INSTALL_PATH}" ]; then
|
||||
output=$("${INSTALL_PATH}" --version 2>/dev/null || true)
|
||||
elif command -v act_runner >/dev/null 2>&1; then
|
||||
output=$(act_runner --version 2>/dev/null || true)
|
||||
fi
|
||||
|
||||
if [ -n "${output}" ]; then
|
||||
extract_version_number <<<"${output}"
|
||||
fi
|
||||
}
|
||||
|
||||
list_registered_runners() {
|
||||
local runner_dir
|
||||
|
||||
if [ ! -d "/data/runners" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
for runner_dir in /data/runners/*/; do
|
||||
if [ -d "${runner_dir}" ] && [ -f "${runner_dir}/.runner" ]; then
|
||||
basename "${runner_dir}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
build_download_url() {
|
||||
local version=$1
|
||||
local arch=$2
|
||||
|
||||
echo "https://dl.gitea.com/act_runner/${version}/act_runner-${version}-linux-${arch}"
|
||||
}
|
||||
|
||||
confirm_or_exit() {
|
||||
local auto_confirm=$1
|
||||
|
||||
if [ "${auto_confirm}" = "true" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
read -p "Proceed with upgrade? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! "${REPLY}" =~ ^[Yy]$ ]]; then
|
||||
echo "Upgrade cancelled."
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
download_and_install() {
|
||||
local version=$1
|
||||
local arch=$2
|
||||
local url
|
||||
local tmp_path
|
||||
local downloaded_version
|
||||
|
||||
mkdir -p "$(dirname "${INSTALL_PATH}")"
|
||||
url=$(build_download_url "${version}" "${arch}")
|
||||
tmp_path=$(mktemp "${INSTALL_PATH}.tmp.XXXXXX")
|
||||
|
||||
trap 'rm -f "${tmp_path}"' EXIT
|
||||
|
||||
log "Downloading ${url}"
|
||||
curl -fL "${url}" -o "${tmp_path}"
|
||||
chmod +x "${tmp_path}"
|
||||
|
||||
downloaded_version=$("${tmp_path}" --version 2>/dev/null | extract_version_number)
|
||||
if [ "${downloaded_version}" != "${version}" ]; then
|
||||
fail "Downloaded binary version mismatch: expected ${version}, got ${downloaded_version:-unknown}"
|
||||
fi
|
||||
|
||||
mv "${tmp_path}" "${INSTALL_PATH}"
|
||||
ln -sf "${INSTALL_PATH}" "${SYSTEM_PATH}"
|
||||
trap - EXIT
|
||||
}
|
||||
|
||||
restart_runner_process() {
|
||||
local runner_name=$1
|
||||
|
||||
if ! command -v supervisorctl >/dev/null 2>&1; then
|
||||
log "⚠ supervisorctl not found, please restart the container manually."
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "Restarting runner '${runner_name}'..."
|
||||
supervisorctl restart "runner-${runner_name}"
|
||||
}
|
||||
|
||||
restart_selected_runners() {
|
||||
local requested_runners=("$@")
|
||||
local runner_names=()
|
||||
local runner_name
|
||||
|
||||
if [ "${#requested_runners[@]}" -gt 0 ]; then
|
||||
runner_names=("${requested_runners[@]}")
|
||||
else
|
||||
while IFS= read -r runner_name; do
|
||||
[ -n "${runner_name}" ] && runner_names+=("${runner_name}")
|
||||
done < <(list_registered_runners)
|
||||
fi
|
||||
|
||||
if [ "${#runner_names[@]}" -eq 0 ]; then
|
||||
log "No registered runners found. Binary upgraded, no process restart needed."
|
||||
return 0
|
||||
fi
|
||||
|
||||
for runner_name in "${runner_names[@]}"; do
|
||||
restart_runner_process "${runner_name}"
|
||||
done
|
||||
}
|
||||
|
||||
main() {
|
||||
local target_version=""
|
||||
local target_arch=""
|
||||
local auto_confirm="false"
|
||||
local current_version=""
|
||||
local runner_names=()
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--version)
|
||||
[ $# -ge 2 ] || fail "--version requires a value"
|
||||
target_version=$2
|
||||
shift 2
|
||||
;;
|
||||
--arch)
|
||||
[ $# -ge 2 ] || fail "--arch requires a value"
|
||||
target_arch=$2
|
||||
shift 2
|
||||
;;
|
||||
--runner)
|
||||
[ $# -ge 2 ] || fail "--runner requires a value"
|
||||
runner_names+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
-y|--yes)
|
||||
auto_confirm="true"
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
print_usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
fail "Unknown option: $1"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
current_version=$(get_installed_version || true)
|
||||
|
||||
if [ -z "${target_version}" ]; then
|
||||
log "Fetching latest act_runner version from ${RUNNER_INDEX_URL}"
|
||||
target_version=$(fetch_latest_version)
|
||||
[ -n "${target_version}" ] || fail "Unable to detect the latest act_runner version"
|
||||
fi
|
||||
|
||||
validate_version "${target_version}" || fail "Invalid version: ${target_version}"
|
||||
|
||||
if [ -z "${target_arch}" ]; then
|
||||
target_arch=$(detect_runner_arch)
|
||||
fi
|
||||
|
||||
if [ -n "${current_version}" ] && [ "${current_version}" = "${target_version}" ]; then
|
||||
log "act_runner is already at the latest version: ${current_version}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "Upgrade summary:"
|
||||
log " Current version: ${current_version:-not installed}"
|
||||
log " Target version: ${target_version}"
|
||||
log " Architecture: ${target_arch}"
|
||||
log " Install path: ${INSTALL_PATH}"
|
||||
if [ "${#runner_names[@]}" -gt 0 ]; then
|
||||
log " Restart target: ${runner_names[*]}"
|
||||
else
|
||||
log " Restart target: all registered runners"
|
||||
fi
|
||||
echo
|
||||
|
||||
confirm_or_exit "${auto_confirm}"
|
||||
download_and_install "${target_version}" "${target_arch}"
|
||||
restart_selected_runners "${runner_names[@]}"
|
||||
|
||||
log
|
||||
log "✓ act_runner upgraded successfully"
|
||||
log " Installed version: $(get_installed_version || echo unknown)"
|
||||
}
|
||||
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
set -euo pipefail
|
||||
main "$@"
|
||||
fi
|
||||
|
|
@ -8,6 +8,7 @@ services:
|
|||
volumes:
|
||||
- ./runner-data:/data
|
||||
- ../../common/setup.sh:/data/setup.sh:ro
|
||||
- ../../common/upgrade.sh:/data/upgrade.sh:ro
|
||||
- ../../common/register.sh:/data/register.sh:ro
|
||||
- ../../common/manage.sh:/data/manage.sh:ro
|
||||
- ../../common/check_crlf.sh:/data/check_crlf.sh:ro
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ services:
|
|||
volumes:
|
||||
- ./runner-data:/data
|
||||
- ../../common/setup.sh:/data/setup.sh:ro
|
||||
- ../../common/upgrade.sh:/data/upgrade.sh:ro
|
||||
- ../../common/register.sh:/data/register.sh:ro
|
||||
- ../../common/manage.sh:/data/manage.sh:ro
|
||||
- ../../common/check_crlf.sh:/data/check_crlf.sh:ro
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ services:
|
|||
volumes:
|
||||
- ./runner-data:/data
|
||||
- ../../common/setup.sh:/data/setup.sh:ro
|
||||
- ../../common/upgrade.sh:/data/upgrade.sh:ro
|
||||
- ../../common/register.sh:/data/register.sh:ro
|
||||
- ../../common/manage.sh:/data/manage.sh:ro
|
||||
- ../../common/entrypoint.sh:/data/entrypoint.sh:ro
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
REPO_ROOT=$(cd "${SCRIPT_DIR}/.." && pwd)
|
||||
|
||||
# shellcheck source=/dev/null
|
||||
source "${REPO_ROOT}/docker-runner/common/upgrade.sh"
|
||||
|
||||
assert_eq() {
|
||||
local expected=$1
|
||||
local actual=$2
|
||||
local message=$3
|
||||
|
||||
if [ "${expected}" != "${actual}" ]; then
|
||||
echo "FAIL: ${message}" >&2
|
||||
echo " expected: ${expected}" >&2
|
||||
echo " actual: ${actual}" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_extract_versions_from_listing() {
|
||||
local html
|
||||
html=$(cat <<'EOF'
|
||||
<tr class="file ">
|
||||
<td class="name"><a href="/act_runner/0.6.1/"><span class="name">0.6.1</span></a></td>
|
||||
</tr>
|
||||
<tr class="file ">
|
||||
<td class="name"><a href="/act_runner/0.5.0/"><span class="name">0.5.0</span></a></td>
|
||||
</tr>
|
||||
<tr class="file ">
|
||||
<td class="name"><a href="/act_runner/0.4.1/"><span class="name">0.4.1</span></a></td>
|
||||
</tr>
|
||||
EOF
|
||||
)
|
||||
|
||||
local actual
|
||||
actual=$(extract_versions_from_listing <<<"${html}")
|
||||
|
||||
assert_eq $'0.6.1\n0.5.0\n0.4.1' "${actual}" \
|
||||
"extract_versions_from_listing should return every version in listing order"
|
||||
}
|
||||
|
||||
test_pick_latest_version() {
|
||||
local actual
|
||||
actual=$(pick_latest_version <<'EOF'
|
||||
0.5.0
|
||||
0.6.1
|
||||
0.4.9
|
||||
EOF
|
||||
)
|
||||
|
||||
assert_eq "0.6.1" "${actual}" \
|
||||
"pick_latest_version should return the highest semantic version"
|
||||
}
|
||||
|
||||
fake_latest_version() {
|
||||
echo "0.6.2"
|
||||
}
|
||||
|
||||
fake_invalid_version() {
|
||||
echo "latest"
|
||||
}
|
||||
|
||||
test_resolve_latest_version_or_fallback_prefers_latest() {
|
||||
local actual
|
||||
actual=$(resolve_latest_version_or_fallback "0.2.13" fake_latest_version)
|
||||
|
||||
assert_eq "0.6.2" "${actual}" \
|
||||
"resolve_latest_version_or_fallback should prefer the detected latest version"
|
||||
}
|
||||
|
||||
test_resolve_latest_version_or_fallback_uses_fallback() {
|
||||
local actual
|
||||
actual=$(resolve_latest_version_or_fallback "0.2.13" fake_invalid_version)
|
||||
|
||||
assert_eq "0.2.13" "${actual}" \
|
||||
"resolve_latest_version_or_fallback should fall back when detected version is invalid"
|
||||
}
|
||||
|
||||
test_extract_versions_from_listing
|
||||
test_pick_latest_version
|
||||
test_resolve_latest_version_or_fallback_prefers_latest
|
||||
test_resolve_latest_version_or_fallback_uses_fallback
|
||||
|
||||
echo "upgrade_test.sh: PASS"
|
||||
Loading…
Reference in New Issue