package delivery import ( "crypto/sha256" "encoding/hex" "os" "path/filepath" "strings" "testing" "gitea.maximumdirect.net/eric/ReleaseKit/internal/artifact" internalbuild "gitea.maximumdirect.net/eric/ReleaseKit/internal/build" "gitea.maximumdirect.net/eric/ReleaseKit/internal/gitea" ) func TestDeclaredBuildAssetsGenerateManifestFromBuildResult(t *testing.T) { output := t.TempDir() first := []byte("first artifact") second := []byte("second artifact") firstPath := filepath.Join(output, "app-v1.2.3-linux-amd64") secondPath := filepath.Join(output, "app-v1.2.3-darwin-arm64") if err := os.WriteFile(firstPath, first, 0o600); err != nil { t.Fatal(err) } if err := os.WriteFile(secondPath, second, 0o600); err != nil { t.Fatal(err) } result, err := declaredBuildAssets(internalbuild.Result{ Version: "v1.2.3", Settings: artifact.NormalizeSettings("./cmd/app", "app", []artifact.Target{ {OS: "linux", Arch: "amd64"}, {OS: "darwin", Arch: "arm64"}, }), Artifacts: []internalbuild.Artifact{ {Path: firstPath, Filename: filepath.Base(firstPath), Target: internalbuild.Target{OS: "linux", Arch: "amd64"}, SHA256: assetDigest(first)}, {Path: secondPath, Filename: filepath.Base(secondPath), Target: internalbuild.Target{OS: "darwin", Arch: "arm64"}, SHA256: assetDigest(second)}, }, }) if err != nil { t.Fatal(err) } if len(result) != 3 || result[0].Filename != filepath.Base(firstPath) || result[1].Filename != filepath.Base(secondPath) || result[2].Filename != gitea.ManifestFilename { t.Fatalf("assets = %#v", result) } want := assetDigest(second) + " app-v1.2.3-darwin-arm64\n" + assetDigest(first) + " app-v1.2.3-linux-amd64\n" if string(result[2].Content) != want { t.Fatalf("manifest = %q, want %q", result[2].Content, want) } if result[0].Size != int64(len(first)) || result[1].Size != int64(len(second)) { t.Fatalf("sizes = %d, %d", result[0].Size, result[1].Size) } } func TestDeclaredBuildAssetsRejectsArtifactDeclarationMismatch(t *testing.T) { path := filepath.Join(t.TempDir(), "app-v1.2.3-linux-arm64") contents := []byte("built application") if err := os.WriteFile(path, contents, 0o600); err != nil { t.Fatal(err) } _, err := declaredBuildAssets(internalbuild.Result{ Version: "v1.2.3", Settings: artifact.NormalizeSettings("./cmd/app", "app", []artifact.Target{{OS: "linux", Arch: "amd64"}}), Artifacts: []internalbuild.Artifact{{ Path: path, Filename: filepath.Base(path), Target: internalbuild.Target{OS: "linux", Arch: "amd64"}, SHA256: assetDigest(contents), }}, }) if err == nil || !strings.Contains(err.Error(), "does not match a selected target") { t.Fatalf("declaredBuildAssets() error = %v, want declaration mismatch", err) } } func TestDeclaredBuildAssetsKeepsSourceOnlyBuildManifestFree(t *testing.T) { assets, err := declaredBuildAssets(internalbuild.Result{}) if err != nil || len(assets) != 0 { t.Fatalf("assets = %#v, error = %v", assets, err) } } func assetDigest(content []byte) string { sum := sha256.Sum256(content) return hex.EncodeToString(sum[:]) }