fix(topdata): target git.westgate.pw and stub released parts manifest in tests
build-image / build-image (push) Failing after 3s
test / test (push) Failing after 6s

The reprovision retired gitea.westgate.pw in favour of git.westgate.pw, but
internal/topdata still defaulted to the old host and made a live API call
during the native buildability check, so once CI checkout was fixed the
parts tests failed (DNS, then HTTP 404).

- defaultGiteaBaseURL -> https://git.westgate.pw; normalize git-ssh. -> git.
- Add stubEmptyPartsManifest (stub_test.go) and call it from the 2 non-optional
  parts tests so they exercise the build offline. Per-test (t.Setenv) on
  purpose: a global TestMain SOW_ASSETS_SERVER_URL would override the
  git-remote-derived server other tests configure. VFX tests already pass
  (optional consumer ignores HTTP 404).

make check + make smoke green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-13 20:24:57 +02:00
co-authored by Claude Opus 4.8
parent 4892030643
commit 8ed706bbb0
4 changed files with 41 additions and 4 deletions
+2 -2
View File
@@ -18,7 +18,7 @@ import (
const ( const (
defaultSowAssetsRepoOwner = "ShadowsOverWestgate" defaultSowAssetsRepoOwner = "ShadowsOverWestgate"
defaultSowAssetsRepoName = "sow-assets" defaultSowAssetsRepoName = "sow-assets"
defaultGiteaBaseURL = "https://gitea.westgate.pw" defaultGiteaBaseURL = "https://git.westgate.pw"
partsManifestReleaseTag = "parts-manifest-current" partsManifestReleaseTag = "parts-manifest-current"
partsManifestAssetName = "sow-parts-manifest.json" partsManifestAssetName = "sow-parts-manifest.json"
partsManifestCacheFileName = "sow-parts-manifest.json" partsManifestCacheFileName = "sow-parts-manifest.json"
@@ -148,7 +148,7 @@ func parseRepoSpec(raw string) (giteaRepoSpec, bool) {
func normalizeGiteaHTTPHost(host string) string { func normalizeGiteaHTTPHost(host string) string {
host = strings.TrimSpace(host) host = strings.TrimSpace(host)
if strings.HasPrefix(host, "git-ssh.") { if strings.HasPrefix(host, "git-ssh.") {
return "gitea." + strings.TrimPrefix(host, "git-ssh.") return "git." + strings.TrimPrefix(host, "git-ssh.")
} }
return host return host
} }
+1 -1
View File
@@ -7,7 +7,7 @@ func TestParseRepoSpecNormalizesWestgateSSHHostToPublicGiteaHost(t *testing.T) {
if !ok { if !ok {
t.Fatal("expected SSH remote to parse") t.Fatal("expected SSH remote to parse")
} }
if spec.BaseURL != "https://gitea.westgate.pw" { if spec.BaseURL != "https://git.westgate.pw" {
t.Fatalf("expected public Gitea base URL, got %q", spec.BaseURL) t.Fatalf("expected public Gitea base URL, got %q", spec.BaseURL)
} }
if spec.Owner != "ShadowsOverWestgate" || spec.Repo != "sow-module" { if spec.Owner != "ShadowsOverWestgate" || spec.Repo != "sow-module" {
+35
View File
@@ -0,0 +1,35 @@
package topdata
import (
"net/http"
"net/http/httptest"
"testing"
)
// stubEmptyPartsManifest points the released-parts-manifest fetch at a local
// httptest server that serves an empty (but structurally valid) manifest, so a
// build/compare test exercises native build behaviour without reaching the live
// Gitea host. Use it in tests that build the non-optional `parts` consumer but
// do not depend on any released part rows.
//
// It is per-test (t.Setenv) on purpose: a package-global SOW_ASSETS_SERVER_URL
// would override the git-remote-derived server that other tests configure.
func stubEmptyPartsManifest(t *testing.T) {
t.Helper()
var srv *httptest.Server
srv = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/api/v1/repos/ShadowsOverWestgate/sow-assets/releases/tags/parts-manifest-current":
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"assets":[{"name":"sow-parts-manifest.json","browser_download_url":"` + srv.URL + `/dl/sow-parts-manifest.json"}]}`))
case "/dl/sow-parts-manifest.json":
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"repo":"ShadowsOverWestgate/sow-assets","ref":"main","categories":{"belt":[],"bicep":[],"chest":[],"foot":[],"forearm":[],"leg":[],"neck":[],"pelvis":[],"robe":[],"shin":[],"shoulder":[]}}`))
default:
http.NotFound(w, r)
}
}))
t.Cleanup(srv.Close)
t.Setenv("SOW_ASSETS_SERVER_URL", srv.URL)
t.Setenv("SOW_ASSETS_REPO", "ShadowsOverWestgate/sow-assets")
}
+3 -1
View File
@@ -2499,6 +2499,7 @@ func TestBuildReferenceAndCompareReference(t *testing.T) {
func TestCompareReferenceHandlesMixedModeOutputListMismatch(t *testing.T) { func TestCompareReferenceHandlesMixedModeOutputListMismatch(t *testing.T) {
root := testProjectRoot(t) root := testProjectRoot(t)
stubEmptyPartsManifest(t)
mkdirAll(t, filepath.Join(root, "topdata", "data", "parts")) mkdirAll(t, filepath.Join(root, "topdata", "data", "parts"))
writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n") writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n")
writeFile(t, filepath.Join(root, "topdata", "data", "parts", "belt.json"), `{ writeFile(t, filepath.Join(root, "topdata", "data", "parts", "belt.json"), `{
@@ -2834,6 +2835,7 @@ func TestBuildAppliesNonTLKOverrides(t *testing.T) {
func TestBuildFallsBackWhenProjectMigrationIsIncomplete(t *testing.T) { func TestBuildFallsBackWhenProjectMigrationIsIncomplete(t *testing.T) {
root := testProjectRoot(t) root := testProjectRoot(t)
stubEmptyPartsManifest(t)
mkdirAll(t, filepath.Join(root, "topdata", "data", "parts")) mkdirAll(t, filepath.Join(root, "topdata", "data", "parts"))
writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n") writeFile(t, filepath.Join(root, "topdata", "base_dialog.json"), "{}\n")
writeFile(t, filepath.Join(root, "topdata", "data", "parts", "belt.json"), `{ writeFile(t, filepath.Join(root, "topdata", "data", "parts", "belt.json"), `{
@@ -13470,7 +13472,7 @@ func TestBuildNativeRejectsGitRepoTopDataAssetsOverride(t *testing.T) {
writeFile(t, filepath.Join(root, "reference", "build.py"), "print('ok')\n") writeFile(t, filepath.Join(root, "reference", "build.py"), "print('ok')\n")
proj := testProject(root) proj := testProject(root)
proj.Config.TopData.Assets = "ssh://git@gitea.westgate.pw:2222/ShadowsOverWestgate/sow-assets.git" proj.Config.TopData.Assets = "ssh://git@git.westgate.pw:2222/ShadowsOverWestgate/sow-assets.git"
_, err := BuildNative(proj, nil) _, err := BuildNative(proj, nil)
if err == nil || !strings.Contains(err.Error(), "no longer supports git repo specs") { if err == nil || !strings.Contains(err.Error(), "no longer supports git repo specs") {