0
# Build Operations
1
2
Build operation management, incremental builds, and change detection for efficient CI/CD workflows.
3
4
**Note**: All APIs in this document are re-exported from @microsoft/rush-lib through @rushstack/rush-sdk.
5
6
## Capabilities
7
8
### Operation Management
9
10
Core operation execution and dependency management for Rush build workflows.
11
12
```typescript { .api }
13
/**
14
* Represents a single build operation in the Rush workflow
15
*/
16
class Operation {
17
/** Operation name */
18
readonly name: string;
19
20
/** Current operation status */
21
readonly status: OperationStatus;
22
23
/** Operations that this operation depends on */
24
readonly dependencies: ReadonlySet<Operation>;
25
26
/** Operations that depend on this operation */
27
readonly consumers: ReadonlySet<Operation>;
28
29
/** Associated Rush project */
30
readonly associatedProject?: RushConfigurationProject;
31
32
/** Execute this operation */
33
executeAsync(): Promise<OperationStatus>;
34
35
/** Get weight for scheduling priority */
36
readonly weight: number;
37
}
38
39
/**
40
* Status values for operations
41
*/
42
enum OperationStatus {
43
/** Ready to execute */
44
Ready = "ready",
45
46
/** Currently executing */
47
Executing = "executing",
48
49
/** Completed successfully */
50
Success = "success",
51
52
/** Failed during execution */
53
Failure = "failure",
54
55
/** Blocked by failed dependency */
56
Blocked = "blocked",
57
58
/** Skipped (not needed) */
59
Skipped = "skipped"
60
}
61
```
62
63
**Usage Examples:**
64
65
```typescript
66
import { Operation, OperationStatus } from "@rushstack/rush-sdk";
67
68
// Execute operations (typically done by Rush internally)
69
async function executeOperation(operation: Operation): Promise<void> {
70
console.log(`Starting ${operation.name}`);
71
72
const result = await operation.executeAsync();
73
74
switch (result) {
75
case OperationStatus.Success:
76
console.log(`✅ ${operation.name} completed successfully`);
77
break;
78
case OperationStatus.Failure:
79
console.log(`❌ ${operation.name} failed`);
80
break;
81
default:
82
console.log(`⚠️ ${operation.name} finished with status: ${result}`);
83
}
84
}
85
86
// Check operation dependencies
87
function analyzeOperation(operation: Operation): void {
88
console.log(`Operation: ${operation.name}`);
89
console.log(`Status: ${operation.status}`);
90
console.log(`Dependencies: ${operation.dependencies.size}`);
91
console.log(`Consumers: ${operation.consumers.size}`);
92
93
if (operation.associatedProject) {
94
console.log(`Project: ${operation.associatedProject.packageName}`);
95
}
96
}
97
```
98
99
### Change Detection
100
101
Change detection system for incremental builds and selective testing.
102
103
```typescript { .api }
104
/**
105
* Manages change detection for incremental builds
106
*/
107
class ChangeManager {
108
/** Build all projects with change detection */
109
static buildAsync(terminal: ITerminal): Promise<void>;
110
111
/** Check if project has changes since last build */
112
static hasChanges(project: RushConfigurationProject): boolean;
113
114
/** Get list of changed projects */
115
static getChangedProjects(
116
rushConfiguration: RushConfiguration,
117
terminal: ITerminal
118
): ReadonlyArray<RushConfigurationProject>;
119
120
/** Clear change tracking state */
121
static clearChangeState(rushConfiguration: RushConfiguration): void;
122
}
123
124
/**
125
* Analyzes changes between project versions
126
*/
127
class ProjectChangeAnalyzer {
128
constructor(project: RushConfigurationProject);
129
130
/** Get files that have changed */
131
getChangedFiles(): ReadonlyArray<string>;
132
133
/** Check if specific file has changed */
134
hasFileChanged(relativePath: string): boolean;
135
136
/** Get change summary */
137
getChangeSummary(): IChangeSummary;
138
}
139
140
interface IChangeSummary {
141
/** Number of files changed */
142
filesChanged: number;
143
144
/** Number of files added */
145
filesAdded: number;
146
147
/** Number of files deleted */
148
filesDeleted: number;
149
150
/** Whether dependencies changed */
151
dependenciesChanged: boolean;
152
}
153
```
154
155
**Usage Examples:**
156
157
```typescript
158
import { ChangeManager, ProjectChangeAnalyzer, RushConfiguration } from "@rushstack/rush-sdk";
159
160
const config = RushConfiguration.loadFromDefaultLocation();
161
162
// Check for changes across workspace
163
const changedProjects = ChangeManager.getChangedProjects(config, terminal);
164
console.log(`${changedProjects.length} projects have changes`);
165
166
for (const project of changedProjects) {
167
console.log(`Changed: ${project.packageName}`);
168
169
// Analyze specific project changes
170
const analyzer = new ProjectChangeAnalyzer(project);
171
const summary = analyzer.getChangeSummary();
172
173
console.log(` Files changed: ${summary.filesChanged}`);
174
console.log(` Dependencies changed: ${summary.dependenciesChanged}`);
175
176
// Get specific changed files
177
const changedFiles = analyzer.getChangedFiles();
178
changedFiles.slice(0, 5).forEach(file => {
179
console.log(` ${file}`);
180
});
181
}
182
183
// Check individual project
184
const myProject = config.projectsByName.get("@mycompany/my-package");
185
if (myProject && ChangeManager.hasChanges(myProject)) {
186
console.log("My package has changes");
187
}
188
```
189
190
### Build Cache
191
192
Build cache configuration and management for faster builds.
193
194
```typescript { .api }
195
/**
196
* Build cache configuration and settings
197
*/
198
class BuildCacheConfiguration {
199
/** Whether build cache is disabled */
200
readonly disabled: boolean;
201
202
/** Cache entry name pattern */
203
readonly cacheEntryNamePattern?: string;
204
205
/** Build cache provider */
206
readonly buildCacheProvider?: IBuildCacheProvider;
207
208
/** Load configuration from rush.json */
209
static loadFromConfiguration(
210
rushConfiguration: RushConfiguration
211
): BuildCacheConfiguration | undefined;
212
}
213
214
/**
215
* File system build cache provider
216
*/
217
class FileSystemBuildCacheProvider implements IBuildCacheProvider {
218
/** Cache folder path */
219
readonly cacheFolder: string;
220
221
/** Get cache entry for operation */
222
tryGetCacheEntryAsync(
223
terminal: ITerminal,
224
cacheId: string
225
): Promise<ICacheEntry | undefined>;
226
227
/** Store cache entry */
228
trySetCacheEntryAsync(
229
terminal: ITerminal,
230
cacheId: string,
231
cacheEntry: ICacheEntry
232
): Promise<boolean>;
233
}
234
235
interface IBuildCacheProvider {
236
/** Try to get cached build result */
237
tryGetCacheEntryAsync(
238
terminal: ITerminal,
239
cacheId: string
240
): Promise<ICacheEntry | undefined>;
241
242
/** Try to store build result in cache */
243
trySetCacheEntryAsync(
244
terminal: ITerminal,
245
cacheId: string,
246
cacheEntry: ICacheEntry
247
): Promise<boolean>;
248
}
249
250
interface ICacheEntry {
251
/** Cached file contents */
252
readonly files: ReadonlyMap<string, Buffer>;
253
254
/** Metadata about the cache entry */
255
readonly metadata?: Record<string, string>;
256
}
257
```
258
259
**Usage Examples:**
260
261
```typescript
262
import { BuildCacheConfiguration, RushConfiguration } from "@rushstack/rush-sdk";
263
264
const config = RushConfiguration.loadFromDefaultLocation();
265
const buildCache = BuildCacheConfiguration.loadFromConfiguration(config);
266
267
if (buildCache && !buildCache.disabled) {
268
console.log("Build cache is enabled");
269
console.log(`Cache pattern: ${buildCache.cacheEntryNamePattern}`);
270
271
if (buildCache.buildCacheProvider) {
272
console.log("Build cache provider configured");
273
274
// Check for cached result (typically done by Rush internally)
275
const cacheEntry = await buildCache.buildCacheProvider.tryGetCacheEntryAsync(
276
terminal,
277
"my-cache-key"
278
);
279
280
if (cacheEntry) {
281
console.log(`Found cached entry with ${cacheEntry.files.size} files`);
282
}
283
}
284
} else {
285
console.log("Build cache is disabled");
286
}
287
```
288
289
### Cobuild Configuration
290
291
Distributed build configuration for scaling across multiple machines.
292
293
```typescript { .api }
294
/**
295
* Configuration for distributed (cobuild) builds
296
*/
297
class CobuildConfiguration {
298
/** Whether cobuild is disabled */
299
readonly disabled: boolean;
300
301
/** Cobuild context ID */
302
readonly cobuildContextId?: string;
303
304
/** Redis configuration for coordination */
305
readonly redisConfiguration?: IRedisConfiguration;
306
307
/** Load from rush.json configuration */
308
static loadFromConfiguration(
309
rushConfiguration: RushConfiguration
310
): CobuildConfiguration | undefined;
311
}
312
313
interface IRedisConfiguration {
314
/** Redis host */
315
readonly host: string;
316
317
/** Redis port */
318
readonly port: number;
319
320
/** Redis password */
321
readonly password?: string;
322
323
/** Redis database number */
324
readonly db?: number;
325
}
326
```
327
328
### Operation Metadata
329
330
Internal operation tracking and state management.
331
332
```typescript { .api }
333
/**
334
* Manages operation metadata and state
335
*/
336
class _OperationMetadataManager {
337
/** Get metadata for operation */
338
tryGetOperationMetadata(operationName: string): IOperationMetadata | undefined;
339
340
/** Save operation metadata */
341
saveOperationMetadata(operationName: string, metadata: IOperationMetadata): void;
342
}
343
344
/**
345
* Operation state file management
346
*/
347
class _OperationStateFile {
348
/** Load state from file */
349
static tryLoad(filePath: string): _OperationStateFile | undefined;
350
351
/** Operation status */
352
readonly status: OperationStatus;
353
354
/** Last modified time */
355
readonly lastModifiedTime: Date;
356
357
/** Save state to file */
358
save(): void;
359
}
360
361
interface IOperationMetadata {
362
/** Last execution status */
363
readonly lastStatus?: OperationStatus;
364
365
/** Last execution time */
366
readonly lastExecutionTime?: Date;
367
368
/** Execution duration in milliseconds */
369
readonly executionDurationMs?: number;
370
371
/** Cache hit/miss information */
372
readonly cacheHit?: boolean;
373
}
374
```