From 9af77e98d3c479a65e96c40a1c07c2d4f952bab1 Mon Sep 17 00:00:00 2001 From: Rhys Date: Mon, 23 Feb 2026 14:35:32 +1100 Subject: [PATCH 1/3] add optional storageEndpoint config --- ...sh-azure-storage-build-cache-plugin.api.md | 2 ++ .../src/AzureStorageAuthentication.ts | 7 +++- .../src/RushAzureStorageBuildCachePlugin.ts | 8 +++++ .../azure-blob-storage-config.schema.json | 6 ++++ .../AzureStorageBuildCacheProvider.test.ts | 34 +++++++++++++++++++ 5 files changed, 56 insertions(+), 1 deletion(-) diff --git a/common/reviews/api/rush-azure-storage-build-cache-plugin.api.md b/common/reviews/api/rush-azure-storage-build-cache-plugin.api.md index 26f39c4993a..f093e5a8a62 100644 --- a/common/reviews/api/rush-azure-storage-build-cache-plugin.api.md +++ b/common/reviews/api/rush-azure-storage-build-cache-plugin.api.md @@ -98,6 +98,8 @@ export interface IAzureStorageAuthenticationOptions extends IAzureAuthentication storageAccountName: string; // (undocumented) storageContainerName: string; + // (undocumented) + storageEndpoint?: string; } // @public (undocumented) diff --git a/rush-plugins/rush-azure-storage-build-cache-plugin/src/AzureStorageAuthentication.ts b/rush-plugins/rush-azure-storage-build-cache-plugin/src/AzureStorageAuthentication.ts index 982eb9f51fd..fdd1ecf80a4 100644 --- a/rush-plugins/rush-azure-storage-build-cache-plugin/src/AzureStorageAuthentication.ts +++ b/rush-plugins/rush-azure-storage-build-cache-plugin/src/AzureStorageAuthentication.ts @@ -24,6 +24,7 @@ import { export interface IAzureStorageAuthenticationOptions extends IAzureAuthenticationBaseOptions { storageContainerName: string; storageAccountName: string; + storageEndpoint?: string; isCacheWriteAllowed: boolean; } @@ -46,7 +47,11 @@ export class AzureStorageAuthentication extends AzureAuthenticationBase { this._storageAccountName = options.storageAccountName; this._storageContainerName = options.storageContainerName; this._isCacheWriteAllowedByConfiguration = options.isCacheWriteAllowed; - this._storageAccountUrl = `https://${this._storageAccountName}.blob.core.windows.net/`; + this._storageAccountUrl = options.storageEndpoint + ? options.storageEndpoint.endsWith('/') + ? options.storageEndpoint + : options.storageEndpoint + '/' + : `https://${this._storageAccountName}.blob.core.windows.net/`; } protected _getCacheIdParts(): string[] { diff --git a/rush-plugins/rush-azure-storage-build-cache-plugin/src/RushAzureStorageBuildCachePlugin.ts b/rush-plugins/rush-azure-storage-build-cache-plugin/src/RushAzureStorageBuildCachePlugin.ts index 4f3f440c5f7..4955f96f27b 100644 --- a/rush-plugins/rush-azure-storage-build-cache-plugin/src/RushAzureStorageBuildCachePlugin.ts +++ b/rush-plugins/rush-azure-storage-build-cache-plugin/src/RushAzureStorageBuildCachePlugin.ts @@ -37,6 +37,13 @@ interface IAzureBlobStorageConfigurationJson { */ readonly loginFlowFailover?: LoginFlowFailoverMap; + /** + * An optional custom endpoint URL for the Azure Blob Storage account. + * Use this to connect to Azurite, private endpoints, or storage emulators. + * Overrides the default endpoint derived from storageAccountName. + */ + readonly storageEndpoint?: string; + /** * An optional prefix for cache item blob names. */ @@ -70,6 +77,7 @@ export class RushAzureStorageBuildCachePlugin implements IRushPlugin { return new AzureStorageBuildCacheProvider({ storageAccountName: azureBlobStorageConfiguration.storageAccountName, storageContainerName: azureBlobStorageConfiguration.storageContainerName, + storageEndpoint: azureBlobStorageConfiguration.storageEndpoint, azureEnvironment: azureBlobStorageConfiguration.azureEnvironment, blobPrefix: azureBlobStorageConfiguration.blobPrefix, loginFlow: azureBlobStorageConfiguration.loginFlow, diff --git a/rush-plugins/rush-azure-storage-build-cache-plugin/src/schemas/azure-blob-storage-config.schema.json b/rush-plugins/rush-azure-storage-build-cache-plugin/src/schemas/azure-blob-storage-config.schema.json index 3a5173a26fd..2ffcd58e4ba 100644 --- a/rush-plugins/rush-azure-storage-build-cache-plugin/src/schemas/azure-blob-storage-config.schema.json +++ b/rush-plugins/rush-azure-storage-build-cache-plugin/src/schemas/azure-blob-storage-config.schema.json @@ -95,6 +95,12 @@ "description": "An optional prefix for cache item blob names." }, + "storageEndpoint": { + "type": "string", + "description": "An optional custom endpoint URL for the Azure Blob Storage account. Use this to connect to Azurite, private endpoints, or storage emulators. When specified, this overrides the default endpoint derived from storageAccountName. Example: \"http://127.0.0.1:10000/devstoreaccount1\" or \"https://my-proxy.example.com/devstoreaccount1\"", + "format": "uri" + }, + "isCacheWriteAllowed": { "type": "boolean", "description": "If set to true, allow writing to the cache. Defaults to false." diff --git a/rush-plugins/rush-azure-storage-build-cache-plugin/src/test/AzureStorageBuildCacheProvider.test.ts b/rush-plugins/rush-azure-storage-build-cache-plugin/src/test/AzureStorageBuildCacheProvider.test.ts index 23bb0ead55b..25cb7d50bc1 100644 --- a/rush-plugins/rush-azure-storage-build-cache-plugin/src/test/AzureStorageBuildCacheProvider.test.ts +++ b/rush-plugins/rush-azure-storage-build-cache-plugin/src/test/AzureStorageBuildCacheProvider.test.ts @@ -31,6 +31,40 @@ describe(AzureStorageBuildCacheProvider.name, () => { ).toThrowErrorMatchingSnapshot(); }); + describe('storageEndpoint', () => { + it('uses the default endpoint when storageEndpoint is not provided', () => { + const subject: AzureStorageBuildCacheProvider = new AzureStorageBuildCacheProvider({ + storageAccountName: 'storage-account', + storageContainerName: 'container-name', + isCacheWriteAllowed: false + }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + expect((subject as any)._storageAccountUrl).toBe('https://storage-account.blob.core.windows.net/'); + }); + + it('uses the custom endpoint when storageEndpoint is provided', () => { + const subject: AzureStorageBuildCacheProvider = new AzureStorageBuildCacheProvider({ + storageAccountName: 'devstoreaccount1', + storageContainerName: 'container-name', + storageEndpoint: 'http://127.0.0.1:10000/devstoreaccount1', + isCacheWriteAllowed: false + }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + expect((subject as any)._storageAccountUrl).toBe('http://127.0.0.1:10000/devstoreaccount1/'); + }); + + it('preserves a trailing slash on the custom endpoint', () => { + const subject: AzureStorageBuildCacheProvider = new AzureStorageBuildCacheProvider({ + storageAccountName: 'devstoreaccount1', + storageContainerName: 'container-name', + storageEndpoint: 'https://my-proxy.example.com/devstoreaccount1/', + isCacheWriteAllowed: false + }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + expect((subject as any)._storageAccountUrl).toBe('https://my-proxy.example.com/devstoreaccount1/'); + }); + }); + describe('isCacheWriteAllowed', () => { function prepareSubject( optionValue: boolean, From b384fb82e8b0ec02bc4514a7bb66091732add899 Mon Sep 17 00:00:00 2001 From: Rhys Date: Mon, 23 Feb 2026 14:41:16 +1100 Subject: [PATCH 2/3] add change --- ...m-endpoint-azure-blob-storage_2026-02-23-03-40.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 common/changes/@microsoft/rush/feat-custom-endpoint-azure-blob-storage_2026-02-23-03-40.json diff --git a/common/changes/@microsoft/rush/feat-custom-endpoint-azure-blob-storage_2026-02-23-03-40.json b/common/changes/@microsoft/rush/feat-custom-endpoint-azure-blob-storage_2026-02-23-03-40.json new file mode 100644 index 00000000000..4379ccf849b --- /dev/null +++ b/common/changes/@microsoft/rush/feat-custom-endpoint-azure-blob-storage_2026-02-23-03-40.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@microsoft/rush", + "comment": "Add custom endpoint support via storageEndpoint for azure storage build cache plugin", + "type": "none" + } + ], + "packageName": "@microsoft/rush" +} \ No newline at end of file From 52949def0a5d8b31419eb5c704b6e2a5d7fa53ed Mon Sep 17 00:00:00 2001 From: Rhys <36913739+ryceg@users.noreply.github.com> Date: Tue, 24 Feb 2026 09:08:08 +1100 Subject: [PATCH 3/3] Update common/changes/@microsoft/rush/feat-custom-endpoint-azure-blob-storage_2026-02-23-03-40.json Co-authored-by: Ian Clanton-Thuon --- ...eat-custom-endpoint-azure-blob-storage_2026-02-23-03-40.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/changes/@microsoft/rush/feat-custom-endpoint-azure-blob-storage_2026-02-23-03-40.json b/common/changes/@microsoft/rush/feat-custom-endpoint-azure-blob-storage_2026-02-23-03-40.json index 4379ccf849b..27740282c27 100644 --- a/common/changes/@microsoft/rush/feat-custom-endpoint-azure-blob-storage_2026-02-23-03-40.json +++ b/common/changes/@microsoft/rush/feat-custom-endpoint-azure-blob-storage_2026-02-23-03-40.json @@ -2,7 +2,7 @@ "changes": [ { "packageName": "@microsoft/rush", - "comment": "Add custom endpoint support via storageEndpoint for azure storage build cache plugin", + "comment": "Add custom endpoint support via a `storageEndpoint` configuration option for the Azure Storage build cache plugin.", "type": "none" } ],