Skip to content

Commit daab290

Browse files
committed
Add Rush reporter repository configuration
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
1 parent 4a97962 commit daab290

11 files changed

Lines changed: 224 additions & 2 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@microsoft/rush",
5+
"comment": "Add repository configuration for opting into and configuring the experimental Rush reporter.",
6+
"type": "patch"
7+
}
8+
],
9+
"packageName": "@microsoft/rush",
10+
"email": "TheLarkInn@users.noreply.github.com"
11+
}

common/reviews/api/rush-lib.api.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,7 @@ export interface IExperimentsJson {
497497
usePnpmLockfileOnlyThenFrozenLockfileForRushUpdate?: boolean;
498498
usePnpmPreferFrozenLockfileForRushUpdate?: boolean;
499499
usePnpmSyncForInjectedDependencies?: boolean;
500+
useRushReporter?: boolean;
500501
}
501502

502503
// @beta
@@ -971,6 +972,11 @@ export interface _IRushProjectJson {
971972
operationSettings?: IOperationSettings[];
972973
}
973974

975+
// @beta
976+
export interface IRushReportingConfiguration {
977+
readonly agentEnvironmentVariables: readonly string[];
978+
}
979+
974980
// @beta (undocumented)
975981
export interface IRushSessionOptions {
976982
// (undocumented)
@@ -1471,6 +1477,8 @@ export class RushConfiguration {
14711477
get projectsByName(): ReadonlyMap<string, RushConfigurationProject>;
14721478
// @beta
14731479
get projectsByTag(): ReadonlyMap<string, ReadonlySet<RushConfigurationProject>>;
1480+
// @beta
1481+
readonly reportingConfiguration: IRushReportingConfiguration;
14741482
readonly repositoryDefaultBranch: string;
14751483
get repositoryDefaultFullyQualifiedRemoteBranch(): string;
14761484
readonly repositoryDefaultRemote: string;

libraries/rush-lib/assets/rush-init/common/config/rush/experiments.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,5 +141,11 @@
141141
* must implement the optional file-based methods for this to take effect; otherwise it falls back to the
142142
* buffer-based approach.
143143
*/
144-
/*[LINE "HYPOTHETICAL"]*/ "useDirectFileTransfersForBuildCache": true
144+
/*[LINE "HYPOTHETICAL"]*/ "useDirectFileTransfersForBuildCache": true,
145+
146+
/**
147+
* If true, Rush may use the experimental Rush reporter system. If omitted or false,
148+
* Rush preserves the legacy reporting behavior.
149+
*/
150+
/*[LINE "HYPOTHETICAL"]*/ "useRushReporter": true
145151
}

libraries/rush-lib/assets/rush-init/rush.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,19 @@
316316
*/
317317
/*[LINE "HYPOTHETICAL"]*/ "telemetryEnabled": false,
318318

319+
/**
320+
* Configures repository settings used by the experimental Rush reporter system.
321+
*/
322+
/*[BEGIN "HYPOTHETICAL"]*/
323+
"reporting": {
324+
/**
325+
* Additional environment variable names that identify an agent environment.
326+
* The built-in COPILOT_CLI variable does not need to be listed here.
327+
*/
328+
"agentEnvironmentVariables": ["MY_AGENT_CLI", "ANOTHER_AGENT"]
329+
},
330+
/*[END "HYPOTHETICAL"]*/
331+
319332
/**
320333
* Allows creation of hotfix changes. This feature is experimental so it is disabled by default.
321334
* If this is set, 'rush change' only allows a 'hotfix' change type to be specified. This change type

libraries/rush-lib/src/api/ExperimentsConfiguration.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@ export interface IExperimentsJson {
153153
* effect; otherwise it falls back to the buffer-based approach.
154154
*/
155155
useDirectFileTransfersForBuildCache?: boolean;
156+
157+
/**
158+
* If true, Rush may use the experimental Rush reporter system. If omitted or false,
159+
* Rush preserves the legacy reporting behavior.
160+
*/
161+
useRushReporter?: boolean;
156162
}
157163

158164
const _EXPERIMENTS_JSON_SCHEMA: JsonSchema = JsonSchema.fromLoadedObject(schemaJson);

libraries/rush-lib/src/api/RushConfiguration.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,21 @@ export interface IRushVariantOptionsJson {
154154
description: string;
155155
}
156156

157+
interface IRushReportingConfigurationJson {
158+
agentEnvironmentVariables?: string[];
159+
}
160+
161+
/**
162+
* Repository settings used by the Rush reporter system.
163+
* @beta
164+
*/
165+
export interface IRushReportingConfiguration {
166+
/**
167+
* Additional environment variable names that identify an agent environment.
168+
*/
169+
readonly agentEnvironmentVariables: readonly string[];
170+
}
171+
157172
/**
158173
* This represents the JSON data structure for the "rush.json" configuration file.
159174
* See rush.schema.json for documentation.
@@ -184,6 +199,7 @@ export interface IRushConfigurationJson {
184199
yarnOptions?: IYarnOptionsJson;
185200
ensureConsistentVersions?: boolean;
186201
variants?: IRushVariantOptionsJson[];
202+
reporting?: IRushReportingConfigurationJson;
187203
}
188204

189205
/**
@@ -523,6 +539,12 @@ export class RushConfiguration {
523539
*/
524540
public readonly telemetryEnabled: boolean;
525541

542+
/**
543+
* Repository settings used by the Rush reporter system.
544+
* @beta
545+
*/
546+
public readonly reportingConfiguration: IRushReportingConfiguration;
547+
526548
/**
527549
* {@inheritDoc NpmOptionsConfiguration}
528550
*/
@@ -853,6 +875,9 @@ export class RushConfiguration {
853875
}
854876

855877
this.telemetryEnabled = !!rushConfigurationJson.telemetryEnabled;
878+
this.reportingConfiguration = {
879+
agentEnvironmentVariables: rushConfigurationJson.reporting?.agentEnvironmentVariables || []
880+
};
856881
this.eventHooks = new EventHooks(rushConfigurationJson.eventHooks || {});
857882

858883
this.versionPolicyConfigurationFilePath = path.join(
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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 * as path from 'node:path';
5+
6+
import { FileSystem, JsonFile } from '@rushstack/node-core-library';
7+
8+
import { ExperimentsConfiguration } from '../ExperimentsConfiguration';
9+
10+
const TEMP_FOLDER: string = path.join(__dirname, 'temp', ExperimentsConfiguration.name);
11+
const EXPERIMENTS_JSON_PATH: string = path.join(TEMP_FOLDER, 'experiments.json');
12+
13+
describe(ExperimentsConfiguration.name, () => {
14+
beforeEach(() => {
15+
FileSystem.ensureEmptyFolder(TEMP_FOLDER);
16+
});
17+
18+
afterEach(() => {
19+
FileSystem.ensureEmptyFolder(TEMP_FOLDER);
20+
});
21+
22+
it('preserves legacy reporting behavior when the experiment file is absent', () => {
23+
const experimentsConfiguration: ExperimentsConfiguration = new ExperimentsConfiguration(
24+
EXPERIMENTS_JSON_PATH
25+
);
26+
27+
expect(experimentsConfiguration.configuration.useRushReporter).toBeUndefined();
28+
});
29+
30+
it('loads the Rush reporter opt-in', () => {
31+
JsonFile.save({ useRushReporter: true }, EXPERIMENTS_JSON_PATH);
32+
33+
const experimentsConfiguration: ExperimentsConfiguration = new ExperimentsConfiguration(
34+
EXPERIMENTS_JSON_PATH
35+
);
36+
37+
expect(experimentsConfiguration.configuration.useRushReporter).toBe(true);
38+
});
39+
40+
it('keeps an explicit false value disabled', () => {
41+
JsonFile.save({ useRushReporter: false }, EXPERIMENTS_JSON_PATH);
42+
43+
const experimentsConfiguration: ExperimentsConfiguration = new ExperimentsConfiguration(
44+
EXPERIMENTS_JSON_PATH
45+
);
46+
47+
expect(experimentsConfiguration.configuration.useRushReporter).toBe(false);
48+
});
49+
50+
it('rejects a non-boolean Rush reporter opt-in', () => {
51+
JsonFile.save({ useRushReporter: 'yes' }, EXPERIMENTS_JSON_PATH);
52+
53+
expect(() => new ExperimentsConfiguration(EXPERIMENTS_JSON_PATH)).toThrow(/useRushReporter/);
54+
});
55+
});
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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 * as path from 'node:path';
5+
6+
import { FileSystem, JsonFile } from '@rushstack/node-core-library';
7+
8+
import { Rush } from '../Rush';
9+
import { RushConfiguration } from '../RushConfiguration';
10+
11+
const TEMP_FOLDER: string = path.join(__dirname, 'temp', 'RushConfigurationReporting');
12+
const RUSH_JSON_PATH: string = path.join(TEMP_FOLDER, 'rush.json');
13+
14+
function writeRushJson(reporting?: unknown): void {
15+
JsonFile.save(
16+
{
17+
rushVersion: Rush.version,
18+
pnpmVersion: '10.0.0',
19+
projects: [],
20+
...(reporting === undefined ? {} : { reporting })
21+
},
22+
RUSH_JSON_PATH
23+
);
24+
}
25+
26+
describe('RushConfiguration reporting configuration', () => {
27+
beforeEach(() => {
28+
FileSystem.ensureEmptyFolder(TEMP_FOLDER);
29+
});
30+
31+
afterEach(() => {
32+
FileSystem.ensureEmptyFolder(TEMP_FOLDER);
33+
});
34+
35+
it('defaults agent environment variables to an empty array', () => {
36+
writeRushJson();
37+
38+
const rushConfiguration: RushConfiguration = RushConfiguration.loadFromConfigurationFile(RUSH_JSON_PATH);
39+
40+
expect(rushConfiguration.reportingConfiguration.agentEnvironmentVariables).toEqual([]);
41+
});
42+
43+
it('loads configured agent environment variables', () => {
44+
writeRushJson({
45+
agentEnvironmentVariables: ['MY_AGENT_CLI', 'ANOTHER_AGENT']
46+
});
47+
48+
const rushConfiguration: RushConfiguration = RushConfiguration.loadFromConfigurationFile(RUSH_JSON_PATH);
49+
50+
expect(rushConfiguration.reportingConfiguration.agentEnvironmentVariables).toEqual([
51+
'MY_AGENT_CLI',
52+
'ANOTHER_AGENT'
53+
]);
54+
});
55+
56+
it('rejects invalid agent environment variables', () => {
57+
writeRushJson({
58+
agentEnvironmentVariables: ['MY_AGENT_CLI', 123]
59+
});
60+
61+
expect(() => RushConfiguration.loadFromConfigurationFile(RUSH_JSON_PATH)).toThrow(
62+
/agentEnvironmentVariables/
63+
);
64+
});
65+
66+
it('rejects unsupported reporting settings', () => {
67+
writeRushJson({
68+
agentEnvironmentVariables: [],
69+
defaultReporter: 'ai'
70+
});
71+
72+
expect(() => RushConfiguration.loadFromConfigurationFile(RUSH_JSON_PATH)).toThrow(/defaultReporter/);
73+
});
74+
});

libraries/rush-lib/src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ export {
2020

2121
export { ApprovedPackagesPolicy } from './api/ApprovedPackagesPolicy';
2222

23-
export { RushConfiguration, type ITryFindRushJsonLocationOptions } from './api/RushConfiguration';
23+
export {
24+
RushConfiguration,
25+
type IRushReportingConfiguration,
26+
type ITryFindRushJsonLocationOptions
27+
} from './api/RushConfiguration';
2428

2529
export { Subspace } from './api/Subspace';
2630
export { SubspacesConfiguration } from './api/SubspacesConfiguration';

libraries/rush-lib/src/schemas/experiments.schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@
9393
"useDirectFileTransfersForBuildCache": {
9494
"description": "If true, the build cache will use file-based APIs to transfer cache entries to and from cloud storage. This avoids loading the entire cache entry into memory, which can prevent out-of-memory errors for large build outputs and allow cache entries to exceed the limit of a single Buffer. The cloud cache provider plugin must implement the optional file-based methods for this to take effect; otherwise it falls back to the buffer-based approach.",
9595
"type": "boolean"
96+
},
97+
"useRushReporter": {
98+
"description": "If true, Rush may use the experimental Rush reporter system. If omitted or false, Rush preserves the legacy reporting behavior.",
99+
"type": "boolean"
96100
}
97101
},
98102
"additionalProperties": false

0 commit comments

Comments
 (0)