From 5e542950cb52329a2071d126be3cce48022f7c45 Mon Sep 17 00:00:00 2001 From: wlthomson Date: Mon, 9 Feb 2026 17:43:53 +1300 Subject: [PATCH 1/3] Add support for GCS storage feeds --- src/features/feeds/feed.ts | 3 ++- src/features/feeds/feedType.ts | 1 + src/features/feeds/gcsStorageFeed.ts | 18 ++++++++++++++++++ src/features/feeds/index.ts | 1 + 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/features/feeds/gcsStorageFeed.ts diff --git a/src/features/feeds/feed.ts b/src/features/feeds/feed.ts index 0f04efa..68cb0d0 100644 --- a/src/features/feeds/feed.ts +++ b/src/features/feeds/feed.ts @@ -4,6 +4,7 @@ import type { AwsElasticContainerRegistryFeed } from "./awsElasticContainerRegis import type { BuiltInFeed } from "./builtInFeed"; import type { DockerFeed } from "./dockerFeed"; import { FeedType } from "./feedType"; +import type { GcsStorageFeed } from "./gcsStorageFeed"; import type { GitHubFeed } from "./gitHubFeed"; import type { HelmFeed } from "./helmFeed"; import type { MavenFeed } from "./mavenFeed"; @@ -12,7 +13,7 @@ import type { NugetFeed } from "./nugetFeed"; import type { OctopusProjectFeed } from "./octopusProjectFeed"; import { every } from "lodash"; -export type ExternalFeed = NugetFeed | DockerFeed | MavenFeed | GitHubFeed | HelmFeed | AwsElasticContainerRegistryFeed | NpmFeed; +export type ExternalFeed = NugetFeed | DockerFeed | MavenFeed | GitHubFeed | HelmFeed | AwsElasticContainerRegistryFeed | GcsStorageFeed | NpmFeed; export type Feed = ExternalFeed | BuiltInFeed | OctopusProjectFeed; diff --git a/src/features/feeds/feedType.ts b/src/features/feeds/feedType.ts index 08303c9..dfb0562 100644 --- a/src/features/feeds/feedType.ts +++ b/src/features/feeds/feedType.ts @@ -2,6 +2,7 @@ export enum FeedType { AwsElasticContainerRegistry = "AwsElasticContainerRegistry", BuiltIn = "BuiltIn", Docker = "Docker", + GcsStorage = "GcsStorage", GitHub = "GitHub", Helm = "Helm", Maven = "Maven", diff --git a/src/features/feeds/gcsStorageFeed.ts b/src/features/feeds/gcsStorageFeed.ts new file mode 100644 index 0000000..1f00b88 --- /dev/null +++ b/src/features/feeds/gcsStorageFeed.ts @@ -0,0 +1,18 @@ +import type { FeedType } from "./feedType"; +import type { SensitiveValue } from "../variables"; +import { SpaceScopedResource } from "../../spaceScopedResource"; +import { NamedResource } from "../../namedResource"; + +export interface GoogleOidcAuthentication { + Audience?: string; + SubjectKeys: string[]; +} + +export interface GcsStorageFeed extends SpaceScopedResource, NamedResource { + FeedType: FeedType.GcsStorage; + Name: string; + UseServiceAccountKey: boolean; + ServiceAccountJsonKey?: SensitiveValue; + Project?: string; + OidcAuthentication?: GoogleOidcAuthentication; +} diff --git a/src/features/feeds/index.ts b/src/features/feeds/index.ts index b1b033f..75128bf 100644 --- a/src/features/feeds/index.ts +++ b/src/features/feeds/index.ts @@ -4,6 +4,7 @@ export * from "./dockerFeed"; export * from "./feed"; export * from "./feedRepository"; export * from "./feedType"; +export * from "./gcsStorageFeed"; export * from "./gitHubFeed"; export * from "./helmFeed"; export * from "./mavenFeed"; From 42cdc4b530dee0dd4655e97b2973c508602e89b2 Mon Sep 17 00:00:00 2001 From: wlthomson Date: Tue, 10 Feb 2026 14:21:32 +1300 Subject: [PATCH 2/3] Update GCS storage feed to extend RetryFeed --- src/features/feeds/gcsStorageFeed.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/features/feeds/gcsStorageFeed.ts b/src/features/feeds/gcsStorageFeed.ts index 1f00b88..5ff1a0d 100644 --- a/src/features/feeds/gcsStorageFeed.ts +++ b/src/features/feeds/gcsStorageFeed.ts @@ -2,13 +2,14 @@ import type { FeedType } from "./feedType"; import type { SensitiveValue } from "../variables"; import { SpaceScopedResource } from "../../spaceScopedResource"; import { NamedResource } from "../../namedResource"; +import type { RetryFeed } from "./retryFeed"; export interface GoogleOidcAuthentication { Audience?: string; SubjectKeys: string[]; } -export interface GcsStorageFeed extends SpaceScopedResource, NamedResource { +export interface GcsStorageFeed extends SpaceScopedResource, NamedResource, RetryFeed { FeedType: FeedType.GcsStorage; Name: string; UseServiceAccountKey: boolean; From 84edf5b99cee129747189103f7da1e2b5b428521 Mon Sep 17 00:00:00 2001 From: wlthomson Date: Wed, 11 Feb 2026 15:47:51 +1300 Subject: [PATCH 3/3] Add test cases --- src/features/feeds/gcsStorageFeed.test.ts | 48 +++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/features/feeds/gcsStorageFeed.test.ts diff --git a/src/features/feeds/gcsStorageFeed.test.ts b/src/features/feeds/gcsStorageFeed.test.ts new file mode 100644 index 0000000..e9c958e --- /dev/null +++ b/src/features/feeds/gcsStorageFeed.test.ts @@ -0,0 +1,48 @@ +import type { GcsStorageFeed } from "./gcsStorageFeed"; +import { FeedType } from "./feedType"; + +describe("gcsStorageFeed", () => { + test("can create with service account key", () => { + const feed: GcsStorageFeed = { + Id: "feeds-123", + Name: "Test GCS Feed", + FeedType: FeedType.GcsStorage, + SpaceId: "Spaces-1", + UseServiceAccountKey: true, + ServiceAccountJsonKey: { + HasValue: true, + NewValue: '{"type":"service_account"}', + }, + Project: "my-project", + DownloadAttempts: 5, + DownloadRetryBackoffSeconds: 10, + }; + + expect(feed.Name).toBe("Test GCS Feed"); + expect(feed.UseServiceAccountKey).toBe(true); + expect(feed.DownloadAttempts).toBe(5); + expect(feed.DownloadRetryBackoffSeconds).toBe(10); + }); + + test("can create with OIDC authentication", () => { + const feed: GcsStorageFeed = { + Id: "feeds-456", + Name: "Test GCS Feed OIDC", + FeedType: FeedType.GcsStorage, + SpaceId: "Spaces-1", + UseServiceAccountKey: false, + OidcAuthentication: { + Audience: "api://AzureADTokenExchange", + SubjectKeys: ["space", "feed"], + }, + DownloadAttempts: 3, + DownloadRetryBackoffSeconds: 5, + }; + + expect(feed.Name).toBe("Test GCS Feed OIDC"); + expect(feed.UseServiceAccountKey).toBe(false); + expect(feed.OidcAuthentication?.Audience).toBe("api://AzureADTokenExchange"); + expect(feed.DownloadAttempts).toBe(3); + expect(feed.DownloadRetryBackoffSeconds).toBe(5); + }); +});