fix(update): убрать псевдо-версию latest, всё в commit-<sha7>
All checks were successful
CI / test (push) Successful in 59s
CI / build-and-package (amd64, darwin) (push) Successful in 42s
CI / build-and-package (amd64, linux) (push) Successful in 40s
CI / build-and-package (amd64, windows) (push) Successful in 42s
CI / build-and-package (arm64, darwin) (push) Successful in 45s
CI / build-and-package (arm64, linux) (push) Successful in 41s
All checks were successful
CI / test (push) Successful in 59s
CI / build-and-package (amd64, darwin) (push) Successful in 42s
CI / build-and-package (amd64, linux) (push) Successful in 40s
CI / build-and-package (amd64, windows) (push) Successful in 42s
CI / build-and-package (arm64, darwin) (push) Successful in 45s
CI / build-and-package (arm64, linux) (push) Successful in 41s
Gitea: при параллельных PUT матрицы (6 платформ) псевдо-версия 'latest'
переуказывается на каждый снимок, companion-файлы и бинарь разъезжаются
между версиями — checksum U4 ломался.
- CI: публикует бинарь+.version+.sha256 в (commit-<sha7>), latest не используется
- Updater.ResolveLatest: новейшая commit-* версия из листинга /api/v1/packages/{owner}/generic/{package},
берём макс id у которой есть бинарь текущей платформы
- Download/Verify/checksum читают ТУ ЖЕ version, а не latest
This commit is contained in:
@@ -2,6 +2,7 @@ package update
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -11,24 +12,53 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// mockGitea поднимает httptest-сервер с бинарём, <filename>.version и .sha256.
|
||||
// mockGitea поднимает httptest-сервер: листинг версий `/api/v1/packages/...`
|
||||
// и файлы конкретных версий `/api/packages/.../{version}/{filename}`.
|
||||
// version — имя новейшей версии (id бóльший), У которой есть бинарь+метаданные;
|
||||
// старые версии бинаря не содержат и отсеются ResolveLatest.
|
||||
func mockGitea(t *testing.T, bin []byte, version, checksum string) *httptest.Server {
|
||||
t.Helper()
|
||||
name := PlatformFilename()
|
||||
// старый commit, чтобы проверить, что Resolve берёт именно новейший.
|
||||
old := "commit-old" + version[len("commit-"):]
|
||||
fileSets := map[string]map[string][]byte{
|
||||
version: {
|
||||
name: bin,
|
||||
name + ".version": []byte(version),
|
||||
name + ".sha256": []byte(checksum),
|
||||
},
|
||||
}
|
||||
versions := []map[string]any{
|
||||
{"id": 1, "version": old},
|
||||
{"id": 2, "version": version},
|
||||
}
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/api/packages/", func(w http.ResponseWriter, r *http.Request) {
|
||||
base := name
|
||||
switch {
|
||||
case strings.HasSuffix(r.URL.Path, ".version"):
|
||||
base = name + ".version"
|
||||
_, _ = w.Write([]byte(version))
|
||||
case strings.HasSuffix(r.URL.Path, ".sha256"):
|
||||
base = name + ".sha256"
|
||||
_, _ = w.Write([]byte(checksum))
|
||||
default:
|
||||
_, _ = w.Write(bin) // сам бинарь
|
||||
mux.HandleFunc("/api/v1/packages/", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet || !strings.HasSuffix(r.URL.Path, "/generic/ratatoskr") {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
_ = base
|
||||
_ = json.NewEncoder(w).Encode(versions)
|
||||
})
|
||||
mux.HandleFunc("/api/packages/", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
http.Error(w, "method", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
// путь: /api/packages/{owner}/generic/{pkg}/{version}/{filename}
|
||||
parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
|
||||
if len(parts) < 6 {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
ver := parts[len(parts)-2]
|
||||
fileName := parts[len(parts)-1]
|
||||
body, ok := fileSets[ver][fileName]
|
||||
if !ok {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
_, _ = w.Write(body)
|
||||
})
|
||||
return httptest.NewServer(mux)
|
||||
}
|
||||
@@ -113,7 +143,7 @@ func TestDownload_And_Verify_Good(t *testing.T) {
|
||||
if !strings.Contains(file, ".new") {
|
||||
t.Errorf("temp file %q should end with .new", filepath.Base(file))
|
||||
}
|
||||
if err := u.Verify(context.Background(), file); err != nil {
|
||||
if err := u.Verify(context.Background(), "commit-new12345", file); err != nil {
|
||||
t.Fatalf("Verify err = %v", err)
|
||||
}
|
||||
// .new лежит в каталоге
|
||||
@@ -128,11 +158,11 @@ func TestVerify_ChecksumMismatch(t *testing.T) {
|
||||
srv := mockGitea(t, bin, "commit-x", sha256hex([]byte("differente-content")))
|
||||
t.Cleanup(srv.Close)
|
||||
u := &Updater{BaseURL: srv.URL, Owner: "k", Package: "p", Dir: t.TempDir()}
|
||||
file := filepath.Join(u.Dir, ".ratatoskr.x.new")
|
||||
file := filepath.Join(u.Dir, ".ratatoskr.commit-x.new")
|
||||
if err := os.WriteFile(file, []byte("A"), 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err := u.Verify(context.Background(), file)
|
||||
err := u.Verify(context.Background(), "commit-x", file)
|
||||
if err == nil {
|
||||
t.Fatal("expected checksum mismatch error")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user