Files
pzmanager/deploy/get.sh
T
mrleo1nidandClaude Opus 5 49d549463a
CI / test (push) Successful in 56s
CI/CD в Gitea Actions и установка одной командой
Workflow CI гоняет gofmt, vet, тесты и сборку на каждый push в main;
workflow Release по тегу v* собирает бинарники под linux/amd64 и arm64,
считает контрольные суммы и публикует релиз через API Gitea.

Оба workflow забирают код через git, а не actions/checkout: это
JS-действие, которому нужен Node внутри контейнера, а в образе golang его
нет. Заодно сборка перестала зависеть от доступности github.com, что для
self-hosted инстанса существенно.

Скрипт deploy/get.sh ставит последний релиз одной командой: определяет
архитектуру, забирает файлы релиза, сверяет sha256 (бинарник ставится с
правами root) и передаёт управление install.sh. Обновление — та же
команда.

Версия сборки попадает в бинарник через ldflags, доступна как
`pzmanager version` и видна в панели на вкладке «Настройки»: без неё
нельзя понять, какой релиз стоит на сервере.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 19:27:30 +03:00

108 lines
4.2 KiB
Bash

#!/usr/bin/env bash
# Установка или обновление pzmanager до последнего релиза одной командой:
#
# curl -fsSL https://gitea.hsrv.site/mrleo1nid/pzmanager/raw/branch/main/deploy/get.sh | sudo bash
#
# Панель в локальной сети (подставьте адрес своего сервера):
#
# curl -fsSL .../get.sh | sudo PZ_LISTEN=10.10.1.142:8080 bash
#
# Переменные окружения:
# PZ_VERSION какой тег ставить (по умолчанию последний релиз)
# PZ_HOME куда ставить (по умолчанию /opt/pzmanager)
# PZ_USER системный пользователь (по умолчанию pzserver)
# PZ_LISTEN адрес веб-панели (по умолчанию 127.0.0.1:8080)
# PZ_REPO адрес репозитория (по умолчанию этот)
set -euo pipefail
PZ_REPO="${PZ_REPO:-https://gitea.hsrv.site/mrleo1nid/pzmanager}"
PZ_VERSION="${PZ_VERSION:-latest}"
API="${PZ_REPO%/}"
API="${API%.git}"
# Из https://host/owner/repo делаем https://host/api/v1/repos/owner/repo
HOST="$(printf '%s' "$API" | cut -d/ -f1-3)"
PATH_PART="${API#"$HOST"/}"
API="${HOST}/api/v1/repos/${PATH_PART}"
die() { echo "Ошибка: $*" >&2; exit 1; }
[[ $EUID -eq 0 ]] || die "запустите с правами root (sudo)"
for tool in curl sha256sum; do
command -v "$tool" >/dev/null 2>&1 || die "не найдена утилита $tool"
done
case "$(uname -m)" in
x86_64 | amd64) ARCH=amd64 ;;
aarch64 | arm64) ARCH=arm64 ;;
*) die "архитектура $(uname -m) не поддерживается: есть сборки только под amd64 и arm64" ;;
esac
if [[ "$PZ_VERSION" == "latest" ]]; then
RELEASE_URL="${API}/releases/latest"
else
RELEASE_URL="${API}/releases/tags/${PZ_VERSION}"
fi
echo "==> Спрашиваю у Gitea последний релиз"
RELEASE_JSON="$(curl -fsSL "$RELEASE_URL")" \
|| die "не удалось получить релиз с ${RELEASE_URL}"
TAG="$(printf '%s' "$RELEASE_JSON" | grep -o '"tag_name" *: *"[^"]*"' | head -1 | cut -d'"' -f4)"
[[ -n "$TAG" ]] || die "в ответе нет тега — возможно, релизов ещё нет"
# Ссылки на файлы релиза достаём без jq: он есть далеко не на всякой машине.
# Имя файла сравниваем целиком, а не шаблоном: точка в "install.sh" в регулярке
# совпала бы с любым символом.
asset_url() {
printf '%s' "$RELEASE_JSON" \
| grep -o '"browser_download_url" *: *"[^"]*"' \
| cut -d'"' -f4 \
| while read -r url; do
if [[ "${url##*/}" == "$1" ]]; then
printf '%s' "$url"
return
fi
done
}
BIN_NAME="pzmanager-linux-${ARCH}"
BIN_URL="$(asset_url "$BIN_NAME")"
[[ -n "$BIN_URL" ]] || die "в релизе ${TAG} нет файла ${BIN_NAME}"
echo "==> Ставлю ${TAG} (${ARCH})"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
cd "$TMP"
download() {
local name="$1" url required="${2:-required}"
url="$(asset_url "$name")"
if [[ -z "$url" ]]; then
[[ "$required" == "optional" ]] && return 1
die "в релизе ${TAG} нет файла ${name}"
fi
curl -fsSL -o "$name" "$url" || die "не удалось скачать ${name}"
}
download "$BIN_NAME"
download install.sh
download pzmanager.service
# Контрольные суммы обязательны: бинарник ставится с правами root.
download checksums.txt
echo "==> Проверяю контрольные суммы"
grep -E " (${BIN_NAME}|install\.sh|pzmanager\.service)\$" checksums.txt > expected.txt \
|| die "в checksums.txt нет нужных строк"
sha256sum -c expected.txt || die "контрольные суммы не сошлись — файлы повреждены"
mkdir -p deploy
mv install.sh pzmanager.service deploy/
mv "$BIN_NAME" pzmanager
chmod +x pzmanager deploy/install.sh
echo "==> Запускаю установщик"
BINARY="$TMP/pzmanager" bash deploy/install.sh