Skip to content

Commit 6457718

Browse files
rycegiclanton
andauthored
[rush-azure-storage-build-cache-plugin] Add custom endpoint support via storageEndpoint (#5664)
* add optional storageEndpoint config * add change * Update common/changes/@microsoft/rush/feat-custom-endpoint-azure-blob-storage_2026-02-23-03-40.json Co-authored-by: Ian Clanton-Thuon <iclanton@users.noreply.github.com> --------- Co-authored-by: Ian Clanton-Thuon <iclanton@users.noreply.github.com>
1 parent 3cc6d1b commit 6457718

6 files changed

Lines changed: 66 additions & 1 deletion

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@microsoft/rush",
5+
"comment": "Add custom endpoint support via a `storageEndpoint` configuration option for the Azure Storage build cache plugin.",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@microsoft/rush"
10+
}

common/reviews/api/rush-azure-storage-build-cache-plugin.api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ export interface IAzureStorageAuthenticationOptions extends IAzureAuthentication
9898
storageAccountName: string;
9999
// (undocumented)
100100
storageContainerName: string;
101+
// (undocumented)
102+
storageEndpoint?: string;
101103
}
102104

103105
// @public (undocumented)

rush-plugins/rush-azure-storage-build-cache-plugin/src/AzureStorageAuthentication.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
export interface IAzureStorageAuthenticationOptions extends IAzureAuthenticationBaseOptions {
2525
storageContainerName: string;
2626
storageAccountName: string;
27+
storageEndpoint?: string;
2728
isCacheWriteAllowed: boolean;
2829
}
2930

@@ -46,7 +47,11 @@ export class AzureStorageAuthentication extends AzureAuthenticationBase {
4647
this._storageAccountName = options.storageAccountName;
4748
this._storageContainerName = options.storageContainerName;
4849
this._isCacheWriteAllowedByConfiguration = options.isCacheWriteAllowed;
49-
this._storageAccountUrl = `https://${this._storageAccountName}.blob.core.windows.net/`;
50+
this._storageAccountUrl = options.storageEndpoint
51+
? options.storageEndpoint.endsWith('/')
52+
? options.storageEndpoint
53+
: options.storageEndpoint + '/'
54+
: `https://${this._storageAccountName}.blob.core.windows.net/`;
5055
}
5156

5257
protected _getCacheIdParts(): string[] {

rush-plugins/rush-azure-storage-build-cache-plugin/src/RushAzureStorageBuildCachePlugin.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ interface IAzureBlobStorageConfigurationJson {
3737
*/
3838
readonly loginFlowFailover?: LoginFlowFailoverMap;
3939

40+
/**
41+
* An optional custom endpoint URL for the Azure Blob Storage account.
42+
* Use this to connect to Azurite, private endpoints, or storage emulators.
43+
* Overrides the default endpoint derived from storageAccountName.
44+
*/
45+
readonly storageEndpoint?: string;
46+
4047
/**
4148
* An optional prefix for cache item blob names.
4249
*/
@@ -70,6 +77,7 @@ export class RushAzureStorageBuildCachePlugin implements IRushPlugin {
7077
return new AzureStorageBuildCacheProvider({
7178
storageAccountName: azureBlobStorageConfiguration.storageAccountName,
7279
storageContainerName: azureBlobStorageConfiguration.storageContainerName,
80+
storageEndpoint: azureBlobStorageConfiguration.storageEndpoint,
7381
azureEnvironment: azureBlobStorageConfiguration.azureEnvironment,
7482
blobPrefix: azureBlobStorageConfiguration.blobPrefix,
7583
loginFlow: azureBlobStorageConfiguration.loginFlow,

rush-plugins/rush-azure-storage-build-cache-plugin/src/schemas/azure-blob-storage-config.schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@
9595
"description": "An optional prefix for cache item blob names."
9696
},
9797

98+
"storageEndpoint": {
99+
"type": "string",
100+
"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\"",
101+
"format": "uri"
102+
},
103+
98104
"isCacheWriteAllowed": {
99105
"type": "boolean",
100106
"description": "If set to true, allow writing to the cache. Defaults to false."

rush-plugins/rush-azure-storage-build-cache-plugin/src/test/AzureStorageBuildCacheProvider.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,40 @@ describe(AzureStorageBuildCacheProvider.name, () => {
3131
).toThrowErrorMatchingSnapshot();
3232
});
3333

34+
describe('storageEndpoint', () => {
35+
it('uses the default endpoint when storageEndpoint is not provided', () => {
36+
const subject: AzureStorageBuildCacheProvider = new AzureStorageBuildCacheProvider({
37+
storageAccountName: 'storage-account',
38+
storageContainerName: 'container-name',
39+
isCacheWriteAllowed: false
40+
});
41+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
42+
expect((subject as any)._storageAccountUrl).toBe('https://storage-account.blob.core.windows.net/');
43+
});
44+
45+
it('uses the custom endpoint when storageEndpoint is provided', () => {
46+
const subject: AzureStorageBuildCacheProvider = new AzureStorageBuildCacheProvider({
47+
storageAccountName: 'devstoreaccount1',
48+
storageContainerName: 'container-name',
49+
storageEndpoint: 'http://127.0.0.1:10000/devstoreaccount1',
50+
isCacheWriteAllowed: false
51+
});
52+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
53+
expect((subject as any)._storageAccountUrl).toBe('http://127.0.0.1:10000/devstoreaccount1/');
54+
});
55+
56+
it('preserves a trailing slash on the custom endpoint', () => {
57+
const subject: AzureStorageBuildCacheProvider = new AzureStorageBuildCacheProvider({
58+
storageAccountName: 'devstoreaccount1',
59+
storageContainerName: 'container-name',
60+
storageEndpoint: 'https://my-proxy.example.com/devstoreaccount1/',
61+
isCacheWriteAllowed: false
62+
});
63+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
64+
expect((subject as any)._storageAccountUrl).toBe('https://my-proxy.example.com/devstoreaccount1/');
65+
});
66+
});
67+
3468
describe('isCacheWriteAllowed', () => {
3569
function prepareSubject(
3670
optionValue: boolean,

0 commit comments

Comments
 (0)