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

- Убран update.owner из конфига, ldflag -X main.updateOwner, vars.TC_GITEA_OWNER и UPDATE_OWNER в Make.
- Владелец пакета = packageOwner (kamelion), совпадает с владельцем репо и создателем токена.
- app.New снова с 3 аргументами; тесты обновлены.
This commit is contained in:
Hermes
2026-08-16 12:37:53 +05:00
parent 8fcafcdffd
commit 05c17ed1f7
7 changed files with 25 additions and 39 deletions

View File

@@ -25,6 +25,11 @@ import (
"github.com/kamelion/ratatoskr-go/internal/worker"
)
// packageOwner — владелец Gitea-пакета, из которого берутся обновления.
// Жёсткая константа: владелец пакета совпадает с владельцем репозитория и
// создателем токена read:package (kamelion). Не требует конфигурации.
const packageOwner = "kamelion"
// App — собранный конвейер.
type App struct {
Config *config.Config
@@ -41,9 +46,7 @@ type App struct {
// version — вшитая версия бинаря (ldflag -X main.version).
// updateToken — вшитый токен read:package для авто-обновления
// (ldflag -X main.updateToken); имеет приоритет над update.token из конфига.
// updateOwner — вшитый владелец Gitea-пакета (ldflag -X main.updateOwner);
// имеет приоритет над update.owner из конфига.
func New(configPath, version, updateToken, updateOwner string) (*App, error) {
func New(configPath, version, updateToken string) (*App, error) {
cfg, err := config.Load(configPath)
if err != nil {
return nil, fmt.Errorf("%w: %v", ErrConfig, err)
@@ -124,14 +127,9 @@ func New(configPath, version, updateToken, updateOwner string) (*App, error) {
if udToken == "" {
udToken = cfg.Update.Token
}
// Владелец пакета: вшитый updateOwner приоритетнее update.owner из конфига.
udOwner := updateOwner
if udOwner == "" {
udOwner = cfg.Update.Owner
}
ud := &update.Updater{
BaseURL: cfg.Update.BaseURL,
Owner: udOwner,
Owner: packageOwner,
Package: cfg.Update.Package,
Token: udToken,
CurrentVersion: version,

View File

@@ -20,7 +20,7 @@ func TestNew(t *testing.T) {
t.Setenv("RATATOSKR_DB", dbPath)
// Загружаем без config-файла (дефолты + env)
a, err := New("", "dev", "", "")
a, err := New("", "dev", "")
if err != nil {
t.Fatalf("New() err = %v", err)
}
@@ -50,7 +50,7 @@ func TestNew_MissingToken(t *testing.T) {
t.Setenv("TG_CHAT_ID", "12345")
t.Setenv("RATATOSKR_DB", dbPath)
_, err := New("", "dev", "", "")
_, err := New("", "dev", "")
if err == nil {
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("RATATOSKR_DB", dbPath)
_, err := New("", "dev", "", "")
_, err := New("", "dev", "")
if err == nil {
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("RATATOSKR_DB", dbPath)
a, err := New("", "dev", "", "")
a, err := New("", "dev", "")
if err != nil {
t.Fatalf("New() err = %v", err)
}
@@ -109,8 +109,7 @@ func TestMain(t *testing.T) {
}
// TestNew_UpdateWiring проверяет: 1) update.base_url берётся из update-блока
// (не git.base_url); 2) приоритет токена: вшитый updateToken > update.token;
// 3) приоритет владельца: вшитый updateOwner > update.owner.
// (не git.base_url); 2) приоритет токена: вшитый updateToken > update.token.
func TestNew_UpdateWiring(t *testing.T) {
tmp := t.TempDir()
dbPath := filepath.Join(tmp, "test.db")
@@ -127,7 +126,6 @@ func TestNew_UpdateWiring(t *testing.T) {
" enabled: true",
" base_url: \"https://hub.example.com\"",
" token: \"cfg-update-token\"",
" owner: \"cfg-owner\"",
"paths:",
" db: \"" + dbPath + "\"",
"", // пустая строка в конце
@@ -137,7 +135,7 @@ func TestNew_UpdateWiring(t *testing.T) {
}
// 1) base_url из update-блока, а НЕ git
a, err := New(configPath, "dev", "", "")
a, err := New(configPath, "dev", "")
if err != nil {
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 {
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" {
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 перекрывает конфиг
a2, err := New(configPath, "dev", "embedded-update-token", "embedded-owner")
a2, err := New(configPath, "dev", "embedded-update-token")
if err != nil {
t.Fatalf("New() err = %v", err)
}
if a2.Updater.Token != "embedded-update-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)
}
}

View File

@@ -53,15 +53,14 @@ type GitCfg struct {
// BaseURL — хост Gitea для обновления (обязателен: без него update отключён,
// фоллбэк на git.base_url НЕ используется).
// Token — токен read:package. Приоритет: вшитый -X main.updateToken > этот.
// Owner — владелец Gitea-пакета (обязателен для работы обновления).
// Package — имя пакета-хранилища (по умолчанию ratatoskr).
// Package — имя пакета-хранилища (по умолчанию ratatoskr). Владелец пакета —
// жёсткая константа (packageOwner в app).
// CheckInterval — как часто авто-проверять наличие обновления
// (по умолчанию 24h). Авто-режим ТОЛЬКО уведомляет; замена — по /update.
type UpdateCfg struct {
Enabled bool `yaml:"enabled" default:"false"`
BaseURL string `yaml:"base_url" env:"UPDATE_BASE_URL"`
Token string `yaml:"token" env:"UPDATE_TOKEN"`
Owner string `yaml:"owner" env:"UPDATE_OWNER"`
Package string `yaml:"package" default:"ratatoskr"`
CheckInterval Duration `yaml:"check_interval" default:"24h"`
}