@rushstack/rush-http-build-cache-plugin 5.110.0 → 5.110.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/.rush/temp/operation/_phase_build/all.log +6 -6
  2. package/.rush/temp/operation/_phase_build/state.json +1 -1
  3. package/.rush/temp/operation/_phase_test/all.log +15 -15
  4. package/.rush/temp/operation/_phase_test/state.json +1 -1
  5. package/.rush/temp/{rushstack+rush-http-build-cache-plugin-_phase_build-6123140279635b4e69641307e04c82615d4a5778.tar.log → rushstack+rush-http-build-cache-plugin-_phase_build-7ded7328886512873bc98eadea233c2110896df5.tar.log} +2 -2
  6. package/.rush/temp/rushstack+rush-http-build-cache-plugin-_phase_build-7ded7328886512873bc98eadea233c2110896df5.untar.log +10 -0
  7. package/.rush/temp/{rushstack+rush-http-build-cache-plugin-_phase_test-78333a9310f75472822f70554dee637804eb3b97.tar.log → rushstack+rush-http-build-cache-plugin-_phase_test-d4e616d587d138917981fe75858bc749b9e2b9a2.tar.log} +2 -2
  8. package/.rush/temp/rushstack+rush-http-build-cache-plugin-_phase_test-d4e616d587d138917981fe75858bc749b9e2b9a2.untar.log +10 -0
  9. package/README.md +116 -116
  10. package/config/jest.config.json +14 -14
  11. package/config/rig.json +18 -18
  12. package/coverage/HttpBuildCacheProvider.ts.html +1 -1
  13. package/coverage/RushHttpBuildCachePlugin.ts.html +1 -1
  14. package/coverage/cobertura-coverage.xml +5 -5
  15. package/coverage/index.html +1 -1
  16. package/coverage/index.ts.html +1 -1
  17. package/coverage/junit.xml +4 -4
  18. package/lib/HttpBuildCacheProvider.js.map +1 -1
  19. package/lib/RushHttpBuildCachePlugin.js.map +1 -1
  20. package/lib/index.js.map +1 -1
  21. package/lib/schemas/plugin-config.schema.json +52 -52
  22. package/lib/test/HttpBuildCacheProvider.test.js.map +1 -1
  23. package/package.json +5 -5
  24. package/rush-logs/rush-http-build-cache-plugin._phase_build.cache.log +8 -8
  25. package/rush-logs/rush-http-build-cache-plugin._phase_build.log +6 -6
  26. package/rush-logs/rush-http-build-cache-plugin._phase_test.cache.log +17 -17
  27. package/rush-logs/rush-http-build-cache-plugin._phase_test.log +15 -15
  28. package/rush-plugin-manifest.json +11 -11
  29. package/src/HttpBuildCacheProvider.ts +424 -424
  30. package/src/RushHttpBuildCachePlugin.ts +81 -81
  31. package/src/index.ts +4 -4
  32. package/src/schemas/plugin-config.schema.json +52 -52
  33. package/src/test/HttpBuildCacheProvider.test.ts +115 -115
  34. package/temp/build/typescript/ts_l9Fw4VUO.json +1 -1
  35. package/tsconfig.json +3 -3
  36. package/.rush/temp/rushstack+rush-http-build-cache-plugin-_phase_build-6123140279635b4e69641307e04c82615d4a5778.untar.log +0 -10
  37. package/.rush/temp/rushstack+rush-http-build-cache-plugin-_phase_test-78333a9310f75472822f70554dee637804eb3b97.untar.log +0 -10
@@ -1,81 +1,81 @@
1
- // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
- // See LICENSE in the project root for license information.
3
-
4
- import type { IRushPlugin, RushSession, RushConfiguration } from '@rushstack/rush-sdk';
5
- import type { HttpBuildCacheProvider, IHttpBuildCacheProviderOptions } from './HttpBuildCacheProvider';
6
-
7
- const PLUGIN_NAME: string = 'HttpBuildCachePlugin';
8
-
9
- /**
10
- * @public
11
- */
12
- export interface IRushHttpBuildCachePluginConfig {
13
- /**
14
- * The URL of the server that stores the caches (e.g. "https://build-caches.example.com").
15
- */
16
- url: string;
17
-
18
- /**
19
- * The HTTP method to use when writing to the cache (defaults to PUT).
20
- */
21
- uploadMethod?: string;
22
-
23
- /**
24
- * An optional set of HTTP headers to pass to the cache server.
25
- */
26
- headers?: Record<string, string>;
27
-
28
- /**
29
- * An optional command that prints the endpoint's credentials to stdout. Provide the
30
- * command or script to execute and, optionally, any arguments to pass to the script.
31
- */
32
- tokenHandler?: {
33
- exec: string;
34
- args?: string[];
35
- };
36
-
37
- /**
38
- * Prefix for cache keys.
39
- */
40
- cacheKeyPrefix?: string;
41
-
42
- /**
43
- * If set to true, allow writing to the cache. Defaults to false.
44
- */
45
- isCacheWriteAllowed?: boolean;
46
- }
47
-
48
- /**
49
- * @public
50
- */
51
- export class RushHttpBuildCachePlugin implements IRushPlugin {
52
- public readonly pluginName: string = PLUGIN_NAME;
53
-
54
- public apply(rushSession: RushSession, rushConfig: RushConfiguration): void {
55
- rushSession.hooks.initialize.tap(this.pluginName, () => {
56
- rushSession.registerCloudBuildCacheProviderFactory('http', async (buildCacheConfig) => {
57
- const config: IRushHttpBuildCachePluginConfig = (
58
- buildCacheConfig as typeof buildCacheConfig & {
59
- httpConfiguration: IRushHttpBuildCachePluginConfig;
60
- }
61
- ).httpConfiguration;
62
-
63
- const { url, uploadMethod, headers, tokenHandler, cacheKeyPrefix, isCacheWriteAllowed } = config;
64
-
65
- const options: IHttpBuildCacheProviderOptions = {
66
- pluginName: this.pluginName,
67
- rushJsonFolder: rushConfig.rushJsonFolder,
68
- url: url,
69
- uploadMethod: uploadMethod,
70
- headers: headers,
71
- tokenHandler: tokenHandler,
72
- cacheKeyPrefix: cacheKeyPrefix,
73
- isCacheWriteAllowed: !!isCacheWriteAllowed
74
- };
75
-
76
- const { HttpBuildCacheProvider } = await import('./HttpBuildCacheProvider');
77
- return new HttpBuildCacheProvider(options, rushSession);
78
- });
79
- });
80
- }
81
- }
1
+ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
+ // See LICENSE in the project root for license information.
3
+
4
+ import type { IRushPlugin, RushSession, RushConfiguration } from '@rushstack/rush-sdk';
5
+ import type { HttpBuildCacheProvider, IHttpBuildCacheProviderOptions } from './HttpBuildCacheProvider';
6
+
7
+ const PLUGIN_NAME: string = 'HttpBuildCachePlugin';
8
+
9
+ /**
10
+ * @public
11
+ */
12
+ export interface IRushHttpBuildCachePluginConfig {
13
+ /**
14
+ * The URL of the server that stores the caches (e.g. "https://build-caches.example.com").
15
+ */
16
+ url: string;
17
+
18
+ /**
19
+ * The HTTP method to use when writing to the cache (defaults to PUT).
20
+ */
21
+ uploadMethod?: string;
22
+
23
+ /**
24
+ * An optional set of HTTP headers to pass to the cache server.
25
+ */
26
+ headers?: Record<string, string>;
27
+
28
+ /**
29
+ * An optional command that prints the endpoint's credentials to stdout. Provide the
30
+ * command or script to execute and, optionally, any arguments to pass to the script.
31
+ */
32
+ tokenHandler?: {
33
+ exec: string;
34
+ args?: string[];
35
+ };
36
+
37
+ /**
38
+ * Prefix for cache keys.
39
+ */
40
+ cacheKeyPrefix?: string;
41
+
42
+ /**
43
+ * If set to true, allow writing to the cache. Defaults to false.
44
+ */
45
+ isCacheWriteAllowed?: boolean;
46
+ }
47
+
48
+ /**
49
+ * @public
50
+ */
51
+ export class RushHttpBuildCachePlugin implements IRushPlugin {
52
+ public readonly pluginName: string = PLUGIN_NAME;
53
+
54
+ public apply(rushSession: RushSession, rushConfig: RushConfiguration): void {
55
+ rushSession.hooks.initialize.tap(this.pluginName, () => {
56
+ rushSession.registerCloudBuildCacheProviderFactory('http', async (buildCacheConfig) => {
57
+ const config: IRushHttpBuildCachePluginConfig = (
58
+ buildCacheConfig as typeof buildCacheConfig & {
59
+ httpConfiguration: IRushHttpBuildCachePluginConfig;
60
+ }
61
+ ).httpConfiguration;
62
+
63
+ const { url, uploadMethod, headers, tokenHandler, cacheKeyPrefix, isCacheWriteAllowed } = config;
64
+
65
+ const options: IHttpBuildCacheProviderOptions = {
66
+ pluginName: this.pluginName,
67
+ rushJsonFolder: rushConfig.rushJsonFolder,
68
+ url: url,
69
+ uploadMethod: uploadMethod,
70
+ headers: headers,
71
+ tokenHandler: tokenHandler,
72
+ cacheKeyPrefix: cacheKeyPrefix,
73
+ isCacheWriteAllowed: !!isCacheWriteAllowed
74
+ };
75
+
76
+ const { HttpBuildCacheProvider } = await import('./HttpBuildCacheProvider');
77
+ return new HttpBuildCacheProvider(options, rushSession);
78
+ });
79
+ });
80
+ }
81
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { RushHttpBuildCachePlugin } from './RushHttpBuildCachePlugin';
2
-
3
- export default RushHttpBuildCachePlugin;
4
- export { IHttpBuildCacheProviderOptions } from './HttpBuildCacheProvider';
1
+ import { RushHttpBuildCachePlugin } from './RushHttpBuildCachePlugin';
2
+
3
+ export default RushHttpBuildCachePlugin;
4
+ export { IHttpBuildCacheProviderOptions } from './HttpBuildCacheProvider';
@@ -1,52 +1,52 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-04/schema#",
3
- "title": "Configuration for build cache with HTTPS server",
4
- "type": "object",
5
- "required": ["url"],
6
- "properties": {
7
- "url": {
8
- "type": "string",
9
- "description": "(Required) The URL of the server that stores the caches (e.g. \"https://build-caches.example.com\").",
10
- "format": "uri"
11
- },
12
- "uploadMethod": {
13
- "type": "string",
14
- "description": "(Optional) The HTTP method to use when writing to the cache (defaults to PUT).",
15
- "enum": ["PUT", "POST", "PATCH"],
16
- "default": "PUT"
17
- },
18
- "headers": {
19
- "type": "object",
20
- "description": "(Optional) HTTP headers to pass to the cache server",
21
- "properties": {},
22
- "additionalProperties": {
23
- "type": "string"
24
- }
25
- },
26
- "tokenHandler": {
27
- "type": "object",
28
- "description": "(Optional) Shell command that prints the authorization token needed to communicate with the HTTPS server and exits with code 0. This command will be executed from the root of the monorepo.",
29
- "properties": {
30
- "exec": {
31
- "type": "string",
32
- "description": "(Required) The command or script to execute."
33
- },
34
- "args": {
35
- "type": "array",
36
- "description": "(Optional) Arguments to pass to the command or script.",
37
- "items": {
38
- "type": "string"
39
- }
40
- }
41
- }
42
- },
43
- "cacheKeyPrefix": {
44
- "type": "string",
45
- "description": "(Optional) prefix for cache keys."
46
- },
47
- "isCacheWriteAllowed": {
48
- "type": "boolean",
49
- "description": "(Optional) If set to true, allow writing to the cache. Defaults to false."
50
- }
51
- }
52
- }
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "title": "Configuration for build cache with HTTPS server",
4
+ "type": "object",
5
+ "required": ["url"],
6
+ "properties": {
7
+ "url": {
8
+ "type": "string",
9
+ "description": "(Required) The URL of the server that stores the caches (e.g. \"https://build-caches.example.com\").",
10
+ "format": "uri"
11
+ },
12
+ "uploadMethod": {
13
+ "type": "string",
14
+ "description": "(Optional) The HTTP method to use when writing to the cache (defaults to PUT).",
15
+ "enum": ["PUT", "POST", "PATCH"],
16
+ "default": "PUT"
17
+ },
18
+ "headers": {
19
+ "type": "object",
20
+ "description": "(Optional) HTTP headers to pass to the cache server",
21
+ "properties": {},
22
+ "additionalProperties": {
23
+ "type": "string"
24
+ }
25
+ },
26
+ "tokenHandler": {
27
+ "type": "object",
28
+ "description": "(Optional) Shell command that prints the authorization token needed to communicate with the HTTPS server and exits with code 0. This command will be executed from the root of the monorepo.",
29
+ "properties": {
30
+ "exec": {
31
+ "type": "string",
32
+ "description": "(Required) The command or script to execute."
33
+ },
34
+ "args": {
35
+ "type": "array",
36
+ "description": "(Optional) Arguments to pass to the command or script.",
37
+ "items": {
38
+ "type": "string"
39
+ }
40
+ }
41
+ }
42
+ },
43
+ "cacheKeyPrefix": {
44
+ "type": "string",
45
+ "description": "(Optional) prefix for cache keys."
46
+ },
47
+ "isCacheWriteAllowed": {
48
+ "type": "boolean",
49
+ "description": "(Optional) If set to true, allow writing to the cache. Defaults to false."
50
+ }
51
+ }
52
+ }
@@ -1,115 +1,115 @@
1
- // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
- // See LICENSE in the project root for license information.
3
-
4
- jest.mock('node-fetch', function () {
5
- return Object.assign(jest.fn(), jest.requireActual('node-fetch'));
6
- });
7
-
8
- import fetch, { Response } from 'node-fetch';
9
- import { RushSession, EnvironmentConfiguration } from '@rushstack/rush-sdk';
10
- import { StringBufferTerminalProvider, Terminal } from '@rushstack/node-core-library';
11
-
12
- import { HttpBuildCacheProvider, type IHttpBuildCacheProviderOptions } from '../HttpBuildCacheProvider';
13
-
14
- const EXAMPLE_OPTIONS: IHttpBuildCacheProviderOptions = {
15
- url: 'https://buildcache.example.acme.com',
16
- tokenHandler: {
17
- exec: 'node',
18
- args: ['tokenHandler.js']
19
- },
20
- uploadMethod: 'POST',
21
- isCacheWriteAllowed: false,
22
- pluginName: 'example-plugin',
23
- rushJsonFolder: '/repo',
24
- minHttpRetryDelayMs: 1
25
- };
26
-
27
- describe('HttpBuildCacheProvider', () => {
28
- let terminalBuffer: StringBufferTerminalProvider;
29
- let terminal!: Terminal;
30
-
31
- beforeEach(() => {
32
- terminalBuffer = new StringBufferTerminalProvider();
33
- terminal = new Terminal(terminalBuffer);
34
- });
35
-
36
- describe('tryGetCacheEntryBufferByIdAsync', () => {
37
- it('prints warning if read credentials are not available', async () => {
38
- jest.spyOn(EnvironmentConfiguration, 'buildCacheCredential', 'get').mockReturnValue(undefined);
39
-
40
- const session: RushSession = {} as RushSession;
41
- const provider = new HttpBuildCacheProvider(EXAMPLE_OPTIONS, session);
42
-
43
- mocked(fetch).mockResolvedValue(
44
- new Response('Unauthorized', {
45
- status: 401,
46
- statusText: 'Unauthorized'
47
- })
48
- );
49
-
50
- const result = await provider.tryGetCacheEntryBufferByIdAsync(terminal, 'some-key');
51
- expect(result).toBe(undefined);
52
- expect(fetch).toHaveBeenCalledTimes(1);
53
- expect(fetch).toHaveBeenNthCalledWith(1, 'https://buildcache.example.acme.com/some-key', {
54
- body: undefined,
55
- headers: {},
56
- method: 'GET',
57
- redirect: 'follow'
58
- });
59
- expect(terminalBuffer.getWarningOutput()).toMatchInlineSnapshot(
60
- `"Error getting cache entry: Error: Credentials for https://buildcache.example.acme.com/ have not been provided.[n]In CI, verify that RUSH_BUILD_CACHE_CREDENTIAL contains a valid Authorization header value.[n][n]For local developers, run:[n][n] rush update-cloud-credentials --interactive[n][n]"`
61
- );
62
- });
63
-
64
- it('attempts up to 3 times to download a cache entry', async () => {
65
- jest.spyOn(EnvironmentConfiguration, 'buildCacheCredential', 'get').mockReturnValue(undefined);
66
-
67
- const session: RushSession = {} as RushSession;
68
- const provider = new HttpBuildCacheProvider(EXAMPLE_OPTIONS, session);
69
-
70
- mocked(fetch).mockResolvedValueOnce(
71
- new Response('InternalServiceError', {
72
- status: 500,
73
- statusText: 'InternalServiceError'
74
- })
75
- );
76
- mocked(fetch).mockResolvedValueOnce(
77
- new Response('ServiceUnavailable', {
78
- status: 503,
79
- statusText: 'ServiceUnavailable'
80
- })
81
- );
82
- mocked(fetch).mockResolvedValueOnce(
83
- new Response('BadGateway', {
84
- status: 504,
85
- statusText: 'BadGateway'
86
- })
87
- );
88
-
89
- const result = await provider.tryGetCacheEntryBufferByIdAsync(terminal, 'some-key');
90
- expect(result).toBe(undefined);
91
- expect(fetch).toHaveBeenCalledTimes(3);
92
- expect(fetch).toHaveBeenNthCalledWith(1, 'https://buildcache.example.acme.com/some-key', {
93
- body: undefined,
94
- headers: {},
95
- method: 'GET',
96
- redirect: 'follow'
97
- });
98
- expect(fetch).toHaveBeenNthCalledWith(2, 'https://buildcache.example.acme.com/some-key', {
99
- body: undefined,
100
- headers: {},
101
- method: 'GET',
102
- redirect: 'follow'
103
- });
104
- expect(fetch).toHaveBeenNthCalledWith(3, 'https://buildcache.example.acme.com/some-key', {
105
- body: undefined,
106
- headers: {},
107
- method: 'GET',
108
- redirect: 'follow'
109
- });
110
- expect(terminalBuffer.getWarningOutput()).toMatchInlineSnapshot(
111
- `"Could not get cache entry: HTTP 504: BadGateway[n]"`
112
- );
113
- });
114
- });
115
- });
1
+ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
+ // See LICENSE in the project root for license information.
3
+
4
+ jest.mock('node-fetch', function () {
5
+ return Object.assign(jest.fn(), jest.requireActual('node-fetch'));
6
+ });
7
+
8
+ import fetch, { Response } from 'node-fetch';
9
+ import { RushSession, EnvironmentConfiguration } from '@rushstack/rush-sdk';
10
+ import { StringBufferTerminalProvider, Terminal } from '@rushstack/node-core-library';
11
+
12
+ import { HttpBuildCacheProvider, type IHttpBuildCacheProviderOptions } from '../HttpBuildCacheProvider';
13
+
14
+ const EXAMPLE_OPTIONS: IHttpBuildCacheProviderOptions = {
15
+ url: 'https://buildcache.example.acme.com',
16
+ tokenHandler: {
17
+ exec: 'node',
18
+ args: ['tokenHandler.js']
19
+ },
20
+ uploadMethod: 'POST',
21
+ isCacheWriteAllowed: false,
22
+ pluginName: 'example-plugin',
23
+ rushJsonFolder: '/repo',
24
+ minHttpRetryDelayMs: 1
25
+ };
26
+
27
+ describe('HttpBuildCacheProvider', () => {
28
+ let terminalBuffer: StringBufferTerminalProvider;
29
+ let terminal!: Terminal;
30
+
31
+ beforeEach(() => {
32
+ terminalBuffer = new StringBufferTerminalProvider();
33
+ terminal = new Terminal(terminalBuffer);
34
+ });
35
+
36
+ describe('tryGetCacheEntryBufferByIdAsync', () => {
37
+ it('prints warning if read credentials are not available', async () => {
38
+ jest.spyOn(EnvironmentConfiguration, 'buildCacheCredential', 'get').mockReturnValue(undefined);
39
+
40
+ const session: RushSession = {} as RushSession;
41
+ const provider = new HttpBuildCacheProvider(EXAMPLE_OPTIONS, session);
42
+
43
+ mocked(fetch).mockResolvedValue(
44
+ new Response('Unauthorized', {
45
+ status: 401,
46
+ statusText: 'Unauthorized'
47
+ })
48
+ );
49
+
50
+ const result = await provider.tryGetCacheEntryBufferByIdAsync(terminal, 'some-key');
51
+ expect(result).toBe(undefined);
52
+ expect(fetch).toHaveBeenCalledTimes(1);
53
+ expect(fetch).toHaveBeenNthCalledWith(1, 'https://buildcache.example.acme.com/some-key', {
54
+ body: undefined,
55
+ headers: {},
56
+ method: 'GET',
57
+ redirect: 'follow'
58
+ });
59
+ expect(terminalBuffer.getWarningOutput()).toMatchInlineSnapshot(
60
+ `"Error getting cache entry: Error: Credentials for https://buildcache.example.acme.com/ have not been provided.[n]In CI, verify that RUSH_BUILD_CACHE_CREDENTIAL contains a valid Authorization header value.[n][n]For local developers, run:[n][n] rush update-cloud-credentials --interactive[n][n]"`
61
+ );
62
+ });
63
+
64
+ it('attempts up to 3 times to download a cache entry', async () => {
65
+ jest.spyOn(EnvironmentConfiguration, 'buildCacheCredential', 'get').mockReturnValue(undefined);
66
+
67
+ const session: RushSession = {} as RushSession;
68
+ const provider = new HttpBuildCacheProvider(EXAMPLE_OPTIONS, session);
69
+
70
+ mocked(fetch).mockResolvedValueOnce(
71
+ new Response('InternalServiceError', {
72
+ status: 500,
73
+ statusText: 'InternalServiceError'
74
+ })
75
+ );
76
+ mocked(fetch).mockResolvedValueOnce(
77
+ new Response('ServiceUnavailable', {
78
+ status: 503,
79
+ statusText: 'ServiceUnavailable'
80
+ })
81
+ );
82
+ mocked(fetch).mockResolvedValueOnce(
83
+ new Response('BadGateway', {
84
+ status: 504,
85
+ statusText: 'BadGateway'
86
+ })
87
+ );
88
+
89
+ const result = await provider.tryGetCacheEntryBufferByIdAsync(terminal, 'some-key');
90
+ expect(result).toBe(undefined);
91
+ expect(fetch).toHaveBeenCalledTimes(3);
92
+ expect(fetch).toHaveBeenNthCalledWith(1, 'https://buildcache.example.acme.com/some-key', {
93
+ body: undefined,
94
+ headers: {},
95
+ method: 'GET',
96
+ redirect: 'follow'
97
+ });
98
+ expect(fetch).toHaveBeenNthCalledWith(2, 'https://buildcache.example.acme.com/some-key', {
99
+ body: undefined,
100
+ headers: {},
101
+ method: 'GET',
102
+ redirect: 'follow'
103
+ });
104
+ expect(fetch).toHaveBeenNthCalledWith(3, 'https://buildcache.example.acme.com/some-key', {
105
+ body: undefined,
106
+ headers: {},
107
+ method: 'GET',
108
+ redirect: 'follow'
109
+ });
110
+ expect(terminalBuffer.getWarningOutput()).toMatchInlineSnapshot(
111
+ `"Could not get cache entry: HTTP 504: BadGateway[n]"`
112
+ );
113
+ });
114
+ });
115
+ });