From 67f4be8149757424151b9bb97daf1e595ab6830d Mon Sep 17 00:00:00 2001 From: naveensrinivasan <172697+naveensrinivasan@users.noreply.github.com> Date: Wed, 6 May 2026 09:36:45 -0500 Subject: [PATCH] Fix RPM audit files not appearing in index.json The root cause was that the toPlatformArtifact function in the promotion flow only set the Binary field but not the Audit field for RPM packages. When package promotion ran, it would upload the RPM and its audit file to GitHub, but the database artifacts JSON only recorded the Binary, not the Audit. This caused the audit to be null in the database and missing from the generated index.json. Changes: - Modified toPlatformArtifact in internal/promotion/promote.go to set the Audit field for RPM targets with the audit filename and URL - Added tests for RPM audit file handling in release and promotion Fixes the issue where OSPO-nodejs-*.rpm.audit.json files were uploaded to GitHub releases but not reflected in index.json. --- internal/cli/release_test.go | 98 ++++++++++++++++++++++++++++++ internal/promotion/promote.go | 16 ++++- internal/promotion/promote_test.go | 8 +++ 3 files changed, 120 insertions(+), 2 deletions(-) diff --git a/internal/cli/release_test.go b/internal/cli/release_test.go index 6f2b1d3..2e93bed 100644 --- a/internal/cli/release_test.go +++ b/internal/cli/release_test.go @@ -415,6 +415,24 @@ func TestGetFileInfo(t *testing.T) { wantIsCommonFile: true, wantType: "package_test_results", }, + { + name: "RPM package file", + filename: "OSPO-nodejs-24.15.0-1.amzn2023.x86_64.rpm", + url: "https://example.com/OSPO-nodejs-24.15.0-1.amzn2023.x86_64.rpm", + wantIsCommonFile: false, + wantOS: "linux", + wantArch: "x64", + wantType: "binary", + }, + { + name: "RPM package audit file", + filename: "OSPO-nodejs-24.15.0-1.amzn2023.x86_64.rpm.audit.json", + url: "https://example.com/OSPO-nodejs-24.15.0-1.amzn2023.x86_64.rpm.audit.json", + wantIsCommonFile: false, + wantOS: "linux", + wantArch: "x64", + wantType: "artifact", + }, } for _, tt := range tests { @@ -666,6 +684,86 @@ func TestBuildArtifactsJSON(t *testing.T) { } } +func TestBuildArtifactsJSON_RPMPackageWithAudit(t *testing.T) { + stdout := slog.New(slog.NewJSONHandler(os.Stdout, nil)) + stderr := slog.New(slog.NewJSONHandler(os.Stderr, nil)) + + rm := &ReleaseManager{ + db: &mockDatabaseStore{}, + github: &mockGitHubReleaser{}, + stdout: stdout, + stderr: stderr, + } + + // Test that RPM binary and RPM audit file are properly paired + uploadedArtifacts := map[string]artifactInfo{ + "OSPO-nodejs-24.15.0-1.amzn2023.x86_64.rpm": { + URL: "https://github.com/owner/repo/releases/download/tag/OSPO-nodejs-24.15.0-1.amzn2023.x86_64.rpm", + SHA256: "7e8e74ea70d14f4cf1f405938349f225e1536263b970615bc7e4e73ba6f2d8d5", + OriginalFilename: "OSPO-nodejs-24.15.0-1.amzn2023.x86_64.rpm", + }, + "OSPO-nodejs-24.15.0-1.amzn2023.x86_64.rpm.audit.json": { + URL: "https://github.com/owner/repo/releases/download/tag/OSPO-nodejs-24.15.0-1.amzn2023.x86_64.rpm.audit.json", + SHA256: "fc373ea7f1c925c286544bc026d092a3bfc782b7ef8a2bd7d7bfdc8397bb3c17", + OriginalFilename: "OSPO-nodejs-24.15.0-1.amzn2023.x86_64.rpm.audit.json", + }, + } + + downloadResults := []runtime.DownloadResult{ + { + LocalPath: "/tmp/node-v24.15.0-linux-x64.tar.xz", + FileSize: 31164460, + Platform: platform.Platform{ + OS: "linux", + Arch: "x64", + }, + }, + } + + jsonStr, err := rm.buildArtifactsJSON(uploadedArtifacts, downloadResults) + if err != nil { + t.Fatalf("buildArtifactsJSON() error: %v", err) + } + + if jsonStr == "" { + t.Fatal("buildArtifactsJSON() returned empty string") + } + + // Verify it's valid JSON + var artifacts storage.ReleaseArtifacts + if err := json.Unmarshal([]byte(jsonStr), &artifacts); err != nil { + t.Fatalf("buildArtifactsJSON() produced invalid JSON: %v", err) + } + + // Find the RPM platform + var rpmPlatform *storage.PlatformArtifact + for i := range artifacts.Platforms { + if artifacts.Platforms[i].Platform == "linux-x64" && artifacts.Platforms[i].Binary != nil && + strings.HasSuffix(artifacts.Platforms[i].Binary.Filename, ".rpm") { + rpmPlatform = &artifacts.Platforms[i] + break + } + } + + if rpmPlatform == nil { + t.Fatal("buildArtifactsJSON() did not create RPM platform artifact") + } + + // Verify the binary is set + if rpmPlatform.Binary == nil { + t.Error("RPM platform has no Binary set") + } else if rpmPlatform.Binary.Filename != "OSPO-nodejs-24.15.0-1.amzn2023.x86_64.rpm" { + t.Errorf("RPM Binary.Filename = %q, want %q", rpmPlatform.Binary.Filename, "OSPO-nodejs-24.15.0-1.amzn2023.x86_64.rpm") + } + + // Verify the audit is set - THIS IS THE KEY TEST FOR THE BUG + if rpmPlatform.Audit == nil { + t.Error("RPM platform has no Audit set - RPM audit file was not properly paired with RPM binary") + } else if rpmPlatform.Audit.Filename != "OSPO-nodejs-24.15.0-1.amzn2023.x86_64.rpm.audit.json" { + t.Errorf("RPM Audit.Filename = %q, want %q", rpmPlatform.Audit.Filename, "OSPO-nodejs-24.15.0-1.amzn2023.x86_64.rpm.audit.json") + } +} + func TestUploadArtifacts_DuplicateBasenameGetsPlatformQualifiedName(t *testing.T) { tempDir := t.TempDir() linuxDir := filepath.Join(tempDir, "linux-x64") diff --git a/internal/promotion/promote.go b/internal/promotion/promote.go index bed7cd3..9885320 100644 --- a/internal/promotion/promote.go +++ b/internal/promotion/promote.go @@ -352,7 +352,7 @@ func toPlatformArtifact(target Target, result TestResult) (storage.PlatformArtif } platform := fmt.Sprintf("%s-%s-%s", target.InputPlatform, target.InputArch, strings.ToLower(strings.TrimSpace(target.Target))) - return storage.PlatformArtifact{ + artifact := storage.PlatformArtifact{ Platform: platform, PlatformOS: target.InputPlatform, PlatformArch: target.InputArch, @@ -363,5 +363,17 @@ func toPlatformArtifact(target Target, result TestResult) (storage.PlatformArtif URL: url, UploadedAt: time.Now().UTC(), }, - }, nil + } + + // Include audit file info for RPM packages (audit file is uploaded alongside the RPM) + if strings.ToLower(strings.TrimSpace(target.Target)) == "rpm" { + auditFilename := filename + ".audit.json" + artifact.Audit = &storage.AuditArtifact{ + Filename: auditFilename, + URL: url + ".audit.json", // Same URL pattern as the RPM with .audit.json suffix + UploadedAt: time.Now().UTC(), + } + } + + return artifact, nil } diff --git a/internal/promotion/promote_test.go b/internal/promotion/promote_test.go index 7be20f1..550b92f 100644 --- a/internal/promotion/promote_test.go +++ b/internal/promotion/promote_test.go @@ -81,6 +81,14 @@ func TestPromoteTestedPackages_SuccessAndIdempotent(t *testing.T) { t.Fatalf("unexpected promoted artifact: %+v", artifacts.Platforms[0].Binary) } + // Verify RPM audit file is included in the platform artifact + if artifacts.Platforms[0].Audit == nil { + t.Fatal("RPM platform artifact has no Audit field set") + } + if artifacts.Platforms[0].Audit.Filename != "OSPO-nodejs-22.22.0-1.x86_64.rpm.audit.json" { + t.Fatalf("unexpected audit filename: %q, want %q", artifacts.Platforms[0].Audit.Filename, "OSPO-nodejs-22.22.0-1.x86_64.rpm.audit.json") + } + record, err := db.GetPackageRecord( "nodejs", "22.22.0", "rpm", "linux", "x64", "in-sha-1", "OSPO-nodejs", "/export/apps/citools/OSPO-nodejs/22.22.0", )