CI/CD в Gitea Actions и установка одной командой
CI / test (push) Successful in 56s

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>
This commit is contained in:
2026-09-04 19:27:30 +03:00
co-authored by Claude Opus 5
parent 29782dcce9
commit 49d549463a
9 changed files with 356 additions and 23 deletions
+13 -1
View File
@@ -29,6 +29,10 @@ import (
"github.com/mrleo1nid/pzmanager/web"
)
// version подставляется при сборке: -ldflags "-X main.version=v1.2.3".
// В сборке из рабочей копии остаётся "dev".
var version = "dev"
const usage = `pzmanager — панель управления сервером Project Zomboid.
Использование:
@@ -36,6 +40,7 @@ const usage = `pzmanager — панель управления сервером
pzmanager useradd <логин> создать пользователя панели
pzmanager passwd <логин> сменить пароль
pzmanager users показать список пользователей
pzmanager version показать версию
Флаги:
`
@@ -56,6 +61,12 @@ func main() {
if len(args) > 0 && !strings.HasPrefix(args[0], "-") {
command, args = args[0], args[1:]
}
// Версию печатаем до загрузки конфига: она должна работать всегда,
// в том числе на сломанной конфигурации.
if command == "version" || command == "--version" {
fmt.Println("pzmanager", version)
return
}
if err := fs.Parse(args); err != nil {
os.Exit(2)
}
@@ -123,6 +134,7 @@ func serve(cfg *config.Config, users *auth.Store, secureCookies bool) error {
}
apiServer := api.New(api.Options{
Version: version,
Config: cfg,
Users: users,
Supervisor: supervisor,
@@ -155,7 +167,7 @@ func serve(cfg *config.Config, users *auth.Store, secureCookies bool) error {
if err != nil {
return fmt.Errorf("не удалось занять адрес %s: %w", cfg.Listen, err)
}
fmt.Printf("pzmanager слушает http://%s\n", cfg.Listen)
fmt.Printf("pzmanager %s слушает http://%s\n", version, cfg.Listen)
if cfg.AutoStart {
if err := supervisor.Start(); err != nil {