refactor(update): владелец пакета — жёсткая константа packageOwner
All checks were successful
CI / test (push) Successful in 48s
CI / build-and-package (amd64, darwin) (push) Successful in 46s
CI / build-and-package (amd64, linux) (push) Successful in 44s
CI / build-and-package (amd64, windows) (push) Successful in 47s
CI / build-and-package (arm64, darwin) (push) Successful in 45s
CI / build-and-package (arm64, linux) (push) Successful in 47s
All checks were successful
CI / test (push) Successful in 48s
CI / build-and-package (amd64, darwin) (push) Successful in 46s
CI / build-and-package (amd64, linux) (push) Successful in 44s
CI / build-and-package (amd64, windows) (push) Successful in 47s
CI / build-and-package (arm64, darwin) (push) Successful in 45s
CI / build-and-package (arm64, linux) (push) Successful in 47s
- Убран update.owner из конфига, ldflag -X main.updateOwner, vars.TC_GITEA_OWNER и UPDATE_OWNER в Make. - Владелец пакета = packageOwner (kamelion), совпадает с владельцем репо и создателем токена. - app.New снова с 3 аргументами; тесты обновлены.
This commit is contained in:
@@ -58,7 +58,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
VERSION="commit-$(echo '${{ gitea.sha }}' | cut -c1-7)"
|
VERSION="commit-$(echo '${{ gitea.sha }}' | cut -c1-7)"
|
||||||
GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} \
|
GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} \
|
||||||
go build -ldflags="-s -w -X main.version=${VERSION} -X main.updateToken=${{ secrets.TC_UPDATE_TOKEN }} -X main.updateOwner=${{ vars.TC_GITEA_OWNER }}" -o "${FILENAME}" ./cmd/ratatoskr/
|
go build -ldflags="-s -w -X main.version=${VERSION} -X main.updateToken=${{ secrets.TC_UPDATE_TOKEN }}" -o "${FILENAME}" ./cmd/ratatoskr/
|
||||||
echo "FILENAME=${FILENAME}" >> "${GITEA_ENV}"
|
echo "FILENAME=${FILENAME}" >> "${GITEA_ENV}"
|
||||||
echo "VERSION=${VERSION}" >> "${GITEA_ENV}"
|
echo "VERSION=${VERSION}" >> "${GITEA_ENV}"
|
||||||
|
|
||||||
|
|||||||
3
Makefile
3
Makefile
@@ -6,8 +6,7 @@ GO ?= go
|
|||||||
GOPATH := $(shell $(GO) env GOPATH)
|
GOPATH := $(shell $(GO) env GOPATH)
|
||||||
GIT_SHA := $(shell git rev-parse --short HEAD 2>/dev/null || echo dev)
|
GIT_SHA := $(shell git rev-parse --short HEAD 2>/dev/null || echo dev)
|
||||||
UPDATE_TOKEN ?= ""
|
UPDATE_TOKEN ?= ""
|
||||||
UPDATE_OWNER ?= ""
|
GOFLAGS ?= -ldflags="-s -w -X main.version=commit-$(GIT_SHA) -X main.updateToken=$(UPDATE_TOKEN)"
|
||||||
GOFLAGS ?= -ldflags="-s -w -X main.version=commit-$(GIT_SHA) -X main.updateToken=$(UPDATE_TOKEN) -X main.updateOwner=$(UPDATE_OWNER)"
|
|
||||||
|
|
||||||
all: test build
|
all: test build
|
||||||
|
|
||||||
|
|||||||
@@ -24,11 +24,6 @@ var version = "dev"
|
|||||||
// Без ldflags — пустой; тогда используется update.token из конфига (если задан).
|
// Без ldflags — пустой; тогда используется update.token из конфига (если задан).
|
||||||
var updateToken = ""
|
var updateToken = ""
|
||||||
|
|
||||||
// updateOwner — владелец Gitea-пакета (обычно git-юзер), вшивается при сборке:
|
|
||||||
// go build -ldflags "-X main.updateOwner=kamelion"
|
|
||||||
// Без ldflags — пустой; тогда используется update.owner из конфига (если задан).
|
|
||||||
var updateOwner = ""
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cfg := flag.String("config", "", "путь к config.yaml (по умолчанию — CWD/config.yaml)")
|
cfg := flag.String("config", "", "путь к config.yaml (по умолчанию — CWD/config.yaml)")
|
||||||
versionFlag := flag.Bool("version", false, "показать версию и выйти")
|
versionFlag := flag.Bool("version", false, "показать версию и выйти")
|
||||||
@@ -39,7 +34,7 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
a, err := app.New(*cfg, version, updateToken, updateOwner)
|
a, err := app.New(*cfg, version, updateToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("app init: %v", err)
|
log.Fatalf("app init: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ telegram:
|
|||||||
# update (авто-обновление бинаря из Gitea Packages)
|
# update (авто-обновление бинаря из Gitea Packages)
|
||||||
# Авто-режим только проверяет и уведомляет владельца; замена — по команде /update.
|
# Авто-режим только проверяет и уведомляет владельца; замена — по команде /update.
|
||||||
# Если base_url не задан — обновление отключено (фоллбэк на git.base_url НЕ используется).
|
# Если base_url не задан — обновление отключено (фоллбэк на git.base_url НЕ используется).
|
||||||
|
# Владелец пакета — жёсткая константа в коде (packageOwner), настраивать не нужно.
|
||||||
# enabled: false # включить фоновую проверку обновления
|
# enabled: false # включить фоновую проверку обновления
|
||||||
# base_url: "http://gitea.hal9000.home" # хост Gitea для обновления (UPDATE_BASE_URL)
|
# base_url: "http://gitea.hal9000.home" # хост Gitea для обновления (UPDATE_BASE_URL)
|
||||||
# token: "${UPDATE_TOKEN}" # токен read:package (UPDATE_TOKEN) — опционально, если не вшит
|
# token: "${UPDATE_TOKEN}" # токен read:package (UPDATE_TOKEN) — опционально, если не вшит
|
||||||
# owner: "kamelion" # владелец пакета в Gitea (UPDATE_OWNER)
|
|
||||||
# package: "ratatoskr" # имя пакета-хранилища (generic)
|
# package: "ratatoskr" # имя пакета-хранилища (generic)
|
||||||
# check_interval: "24h" # как часто проверять наличие обновления
|
# check_interval: "24h" # как часто проверять наличие обновления
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,11 @@ import (
|
|||||||
"github.com/kamelion/ratatoskr-go/internal/worker"
|
"github.com/kamelion/ratatoskr-go/internal/worker"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// packageOwner — владелец Gitea-пакета, из которого берутся обновления.
|
||||||
|
// Жёсткая константа: владелец пакета совпадает с владельцем репозитория и
|
||||||
|
// создателем токена read:package (kamelion). Не требует конфигурации.
|
||||||
|
const packageOwner = "kamelion"
|
||||||
|
|
||||||
// App — собранный конвейер.
|
// App — собранный конвейер.
|
||||||
type App struct {
|
type App struct {
|
||||||
Config *config.Config
|
Config *config.Config
|
||||||
@@ -41,9 +46,7 @@ type App struct {
|
|||||||
// version — вшитая версия бинаря (ldflag -X main.version).
|
// version — вшитая версия бинаря (ldflag -X main.version).
|
||||||
// updateToken — вшитый токен read:package для авто-обновления
|
// updateToken — вшитый токен read:package для авто-обновления
|
||||||
// (ldflag -X main.updateToken); имеет приоритет над update.token из конфига.
|
// (ldflag -X main.updateToken); имеет приоритет над update.token из конфига.
|
||||||
// updateOwner — вшитый владелец Gitea-пакета (ldflag -X main.updateOwner);
|
func New(configPath, version, updateToken string) (*App, error) {
|
||||||
// имеет приоритет над update.owner из конфига.
|
|
||||||
func New(configPath, version, updateToken, updateOwner string) (*App, error) {
|
|
||||||
cfg, err := config.Load(configPath)
|
cfg, err := config.Load(configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%w: %v", ErrConfig, err)
|
return nil, fmt.Errorf("%w: %v", ErrConfig, err)
|
||||||
@@ -124,14 +127,9 @@ func New(configPath, version, updateToken, updateOwner string) (*App, error) {
|
|||||||
if udToken == "" {
|
if udToken == "" {
|
||||||
udToken = cfg.Update.Token
|
udToken = cfg.Update.Token
|
||||||
}
|
}
|
||||||
// Владелец пакета: вшитый updateOwner приоритетнее update.owner из конфига.
|
|
||||||
udOwner := updateOwner
|
|
||||||
if udOwner == "" {
|
|
||||||
udOwner = cfg.Update.Owner
|
|
||||||
}
|
|
||||||
ud := &update.Updater{
|
ud := &update.Updater{
|
||||||
BaseURL: cfg.Update.BaseURL,
|
BaseURL: cfg.Update.BaseURL,
|
||||||
Owner: udOwner,
|
Owner: packageOwner,
|
||||||
Package: cfg.Update.Package,
|
Package: cfg.Update.Package,
|
||||||
Token: udToken,
|
Token: udToken,
|
||||||
CurrentVersion: version,
|
CurrentVersion: version,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func TestNew(t *testing.T) {
|
|||||||
t.Setenv("RATATOSKR_DB", dbPath)
|
t.Setenv("RATATOSKR_DB", dbPath)
|
||||||
|
|
||||||
// Загружаем без config-файла (дефолты + env)
|
// Загружаем без config-файла (дефолты + env)
|
||||||
a, err := New("", "dev", "", "")
|
a, err := New("", "dev", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("New() err = %v", err)
|
t.Fatalf("New() err = %v", err)
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ func TestNew_MissingToken(t *testing.T) {
|
|||||||
t.Setenv("TG_CHAT_ID", "12345")
|
t.Setenv("TG_CHAT_ID", "12345")
|
||||||
t.Setenv("RATATOSKR_DB", dbPath)
|
t.Setenv("RATATOSKR_DB", dbPath)
|
||||||
|
|
||||||
_, err := New("", "dev", "", "")
|
_, err := New("", "dev", "")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error for missing token")
|
t.Fatal("expected error for missing token")
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ func TestNew_BadDB(t *testing.T) {
|
|||||||
t.Setenv("TG_CHAT_ID", "12345")
|
t.Setenv("TG_CHAT_ID", "12345")
|
||||||
t.Setenv("RATATOSKR_DB", dbPath)
|
t.Setenv("RATATOSKR_DB", dbPath)
|
||||||
|
|
||||||
_, err := New("", "dev", "", "")
|
_, err := New("", "dev", "")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error for invalid db path")
|
t.Fatal("expected error for invalid db path")
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ func TestNew_RunCtxCancel(t *testing.T) {
|
|||||||
t.Setenv("TG_CHAT_ID", "12345")
|
t.Setenv("TG_CHAT_ID", "12345")
|
||||||
t.Setenv("RATATOSKR_DB", dbPath)
|
t.Setenv("RATATOSKR_DB", dbPath)
|
||||||
|
|
||||||
a, err := New("", "dev", "", "")
|
a, err := New("", "dev", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("New() err = %v", err)
|
t.Fatalf("New() err = %v", err)
|
||||||
}
|
}
|
||||||
@@ -109,8 +109,7 @@ func TestMain(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TestNew_UpdateWiring проверяет: 1) update.base_url берётся из update-блока
|
// TestNew_UpdateWiring проверяет: 1) update.base_url берётся из update-блока
|
||||||
// (не git.base_url); 2) приоритет токена: вшитый updateToken > update.token;
|
// (не git.base_url); 2) приоритет токена: вшитый updateToken > update.token.
|
||||||
// 3) приоритет владельца: вшитый updateOwner > update.owner.
|
|
||||||
func TestNew_UpdateWiring(t *testing.T) {
|
func TestNew_UpdateWiring(t *testing.T) {
|
||||||
tmp := t.TempDir()
|
tmp := t.TempDir()
|
||||||
dbPath := filepath.Join(tmp, "test.db")
|
dbPath := filepath.Join(tmp, "test.db")
|
||||||
@@ -127,7 +126,6 @@ func TestNew_UpdateWiring(t *testing.T) {
|
|||||||
" enabled: true",
|
" enabled: true",
|
||||||
" base_url: \"https://hub.example.com\"",
|
" base_url: \"https://hub.example.com\"",
|
||||||
" token: \"cfg-update-token\"",
|
" token: \"cfg-update-token\"",
|
||||||
" owner: \"cfg-owner\"",
|
|
||||||
"paths:",
|
"paths:",
|
||||||
" db: \"" + dbPath + "\"",
|
" db: \"" + dbPath + "\"",
|
||||||
"", // пустая строка в конце
|
"", // пустая строка в конце
|
||||||
@@ -137,7 +135,7 @@ func TestNew_UpdateWiring(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 1) base_url из update-блока, а НЕ git
|
// 1) base_url из update-блока, а НЕ git
|
||||||
a, err := New(configPath, "dev", "", "")
|
a, err := New(configPath, "dev", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("New() err = %v", err)
|
t.Fatalf("New() err = %v", err)
|
||||||
}
|
}
|
||||||
@@ -147,24 +145,21 @@ func TestNew_UpdateWiring(t *testing.T) {
|
|||||||
if want := "https://hub.example.com"; a.Updater.BaseURL != want {
|
if want := "https://hub.example.com"; a.Updater.BaseURL != want {
|
||||||
t.Errorf("BaseURL = %q, want %q (должен быть update.base_url, не git.base_url)", a.Updater.BaseURL, want)
|
t.Errorf("BaseURL = %q, want %q (должен быть update.base_url, не git.base_url)", a.Updater.BaseURL, want)
|
||||||
}
|
}
|
||||||
// без вшитого токена и владельца берём их из конфига
|
// владелец пакета — жёсткая константа
|
||||||
|
if a.Updater.Owner != packageOwner {
|
||||||
|
t.Errorf("Owner = %q, want %q (константа)", a.Updater.Owner, packageOwner)
|
||||||
|
}
|
||||||
|
// без вшитого токена берём update.token из конфига
|
||||||
if a.Updater.Token != "cfg-update-token" {
|
if a.Updater.Token != "cfg-update-token" {
|
||||||
t.Errorf("Token = %q, want cfg-update-token (при пустом вшитом)", a.Updater.Token)
|
t.Errorf("Token = %q, want cfg-update-token (при пустом вшитом)", a.Updater.Token)
|
||||||
}
|
}
|
||||||
if a.Updater.Owner != "cfg-owner" {
|
|
||||||
t.Errorf("Owner = %q, want cfg-owner (при пустом вшитом)", a.Updater.Owner)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2) вшитый updateToken перекрывает конфиг
|
// 2) вшитый updateToken перекрывает конфиг
|
||||||
a2, err := New(configPath, "dev", "embedded-update-token", "embedded-owner")
|
a2, err := New(configPath, "dev", "embedded-update-token")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("New() err = %v", err)
|
t.Fatalf("New() err = %v", err)
|
||||||
}
|
}
|
||||||
if a2.Updater.Token != "embedded-update-token" {
|
if a2.Updater.Token != "embedded-update-token" {
|
||||||
t.Errorf("Token = %q, want embedded-update-token (вшитый приоритетнее)", a2.Updater.Token)
|
t.Errorf("Token = %q, want embedded-update-token (вшитый приоритетнее)", a2.Updater.Token)
|
||||||
}
|
}
|
||||||
// 3) вшитый updateOwner перекрывает конфиг
|
|
||||||
if a2.Updater.Owner != "embedded-owner" {
|
|
||||||
t.Errorf("Owner = %q, want embedded-owner (вшитый приоритетнее)", a2.Updater.Owner)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -53,15 +53,14 @@ type GitCfg struct {
|
|||||||
// BaseURL — хост Gitea для обновления (обязателен: без него update отключён,
|
// BaseURL — хост Gitea для обновления (обязателен: без него update отключён,
|
||||||
// фоллбэк на git.base_url НЕ используется).
|
// фоллбэк на git.base_url НЕ используется).
|
||||||
// Token — токен read:package. Приоритет: вшитый -X main.updateToken > этот.
|
// Token — токен read:package. Приоритет: вшитый -X main.updateToken > этот.
|
||||||
// Owner — владелец Gitea-пакета (обязателен для работы обновления).
|
// Package — имя пакета-хранилища (по умолчанию ratatoskr). Владелец пакета —
|
||||||
// Package — имя пакета-хранилища (по умолчанию ratatoskr).
|
// жёсткая константа (packageOwner в app).
|
||||||
// CheckInterval — как часто авто-проверять наличие обновления
|
// CheckInterval — как часто авто-проверять наличие обновления
|
||||||
// (по умолчанию 24h). Авто-режим ТОЛЬКО уведомляет; замена — по /update.
|
// (по умолчанию 24h). Авто-режим ТОЛЬКО уведомляет; замена — по /update.
|
||||||
type UpdateCfg struct {
|
type UpdateCfg struct {
|
||||||
Enabled bool `yaml:"enabled" default:"false"`
|
Enabled bool `yaml:"enabled" default:"false"`
|
||||||
BaseURL string `yaml:"base_url" env:"UPDATE_BASE_URL"`
|
BaseURL string `yaml:"base_url" env:"UPDATE_BASE_URL"`
|
||||||
Token string `yaml:"token" env:"UPDATE_TOKEN"`
|
Token string `yaml:"token" env:"UPDATE_TOKEN"`
|
||||||
Owner string `yaml:"owner" env:"UPDATE_OWNER"`
|
|
||||||
Package string `yaml:"package" default:"ratatoskr"`
|
Package string `yaml:"package" default:"ratatoskr"`
|
||||||
CheckInterval Duration `yaml:"check_interval" default:"24h"`
|
CheckInterval Duration `yaml:"check_interval" default:"24h"`
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user