From f1c17880481628d12a561b1b7c8739f5836bbec0 Mon Sep 17 00:00:00 2001 From: Isaac Guzman Date: Fri, 17 Jul 2026 15:49:06 -0400 Subject: [PATCH 1/2] Preserve existing code.json tags during metadata updates --- src/__tests__/unit/main.test.ts | 39 +++++++++++++++++++++++++++++++++ src/helper.ts | 9 ++++++++ src/main.ts | 13 +++++------ 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/__tests__/unit/main.test.ts b/src/__tests__/unit/main.test.ts index 475666be..f938377e 100644 --- a/src/__tests__/unit/main.test.ts +++ b/src/__tests__/unit/main.test.ts @@ -109,6 +109,45 @@ describe("getMetaData", () => { URL: "https://github.com/upstream-owner/upstream-repo", }); }); + + it("preserves existing tags that are not repository topics", async () => { + const deps = createMockDeps(); + const helpers = createHelpers(deps); + + const existing = { + ...validCodeJSON, + tags: ["featured"], + } as any; + + const result = await getMetaData(helpers, deps, existing); + + expect(result.tags).toEqual( + expect.arrayContaining(["test", "automation", "featured"]), + ); + }); + + it("does not duplicate tags that already exist as repository topics", async () => { + const deps = createMockDeps(); + const helpers = createHelpers(deps); + + const existing = { + ...validCodeJSON, + tags: ["test", "featured"], + } as any; + + const result = await getMetaData(helpers, deps, existing); + + expect(result.tags).toEqual(["test", "automation", "featured"]); + }); + + it("uses repository topics when no existing code.json is present", async () => { + const deps = createMockDeps(); + const helpers = createHelpers(deps); + + const result = await getMetaData(helpers, deps, null); + + expect(result.tags).toEqual(["test", "automation"]); + }); }); describe("runWithDeps", () => { diff --git a/src/helper.ts b/src/helper.ts index 57be7b12..39767d2c 100644 --- a/src/helper.ts +++ b/src/helper.ts @@ -334,6 +334,7 @@ export function createHelpers(deps: Dependencies) { readJSON, sendPR, pushDirectlyWithFallback, + mergeTags, }; } @@ -390,6 +391,14 @@ export function mergeReusedCode( return merged; } +// combines repository topics with existing manually added tags, de-duped +export function mergeTags( + repositoryTopics: string[] = [], + existingTags: string[] = [], +): string[] { + return Array.from(new Set([...repositoryTopics, ...existingTags])); +} + function bodyOfPR(): string { return ` ## Welcome to the Federal Open Source Community! diff --git a/src/main.ts b/src/main.ts index 496e5729..5ad790d1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -112,12 +112,11 @@ async function getMetaData( ? partialCodeJSON.description : existingCodeJSON?.description || ""; - // only update tags if we have new ones from GitHub Topics, otherwise keep existing - const shouldUpdateTags = - partialCodeJSON.tags && partialCodeJSON.tags.length > 0; - const tags = shouldUpdateTags - ? partialCodeJSON.tags - : existingCodeJSON?.tags || []; + // preserve existing tags and append repository topics, de-duped + const tags = helpers.mergeTags( + partialCodeJSON.tags ?? [], + existingCodeJSON?.tags ?? [], + ); // handling legacy contractNumber that turned from string to array which caused validation errors let contractNumber: string[] = []; @@ -135,7 +134,7 @@ async function getMetaData( if (deps.isArchived) { status = "Archival"; - tags?.push("archived"); + tags.push("archived"); } // detect the fork upstream and government-made dependencies, then merge with any existing reusedCode From bff836d9f811f352ddda29190223fd4fe3780aad Mon Sep 17 00:00:00 2001 From: Isaac Guzman Date: Fri, 17 Jul 2026 15:57:29 -0400 Subject: [PATCH 2/2] Fixed first test to pass without dupes --- src/__tests__/unit/main.test.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/__tests__/unit/main.test.ts b/src/__tests__/unit/main.test.ts index f938377e..2d8f872b 100644 --- a/src/__tests__/unit/main.test.ts +++ b/src/__tests__/unit/main.test.ts @@ -121,9 +121,7 @@ describe("getMetaData", () => { const result = await getMetaData(helpers, deps, existing); - expect(result.tags).toEqual( - expect.arrayContaining(["test", "automation", "featured"]), - ); + expect(result.tags).toEqual(["test", "automation", "featured"]); }); it("does not duplicate tags that already exist as repository topics", async () => {