@uipath/packager-tool-workflowcompiler 1.202.0-preview.141 → 1.202.0-preview.142
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.
- package/package.json +4 -8
- package/src/i18n/index.ts +0 -45
- package/src/i18n/locales/de.json +0 -41
- package/src/i18n/locales/en.ts +0 -62
- package/src/i18n/locales/es-MX.json +0 -41
- package/src/i18n/locales/es.json +0 -41
- package/src/i18n/locales/fr.json +0 -41
- package/src/i18n/locales/ja.json +0 -41
- package/src/i18n/locales/ko.json +0 -41
- package/src/i18n/locales/pt-BR.json +0 -41
- package/src/i18n/locales/pt.json +0 -41
- package/src/i18n/locales/ro.json +0 -41
- package/src/i18n/locales/ru.json +0 -41
- package/src/i18n/locales/tr.json +0 -41
- package/src/i18n/locales/zh-CN.json +0 -41
- package/src/i18n/locales/zh-TW.json +0 -41
- package/src/i18n/locales/zu.json +0 -41
- package/src/index.ts +0 -28
- package/src/output-entry.ts +0 -53
- package/src/workflow-cleanup-details.ts +0 -4
- package/src/workflow-compiler-config.ts +0 -57
- package/src/workflow-compiler-executor.ts +0 -530
- package/src/workflow-compiler-path-resolver.ts +0 -302
- package/src/workflow-compiler-tool-factory.ts +0 -82
- package/src/workflow-compiler-tool.ts +0 -519
|
@@ -1,519 +0,0 @@
|
|
|
1
|
-
import { OrchestratorFeedComposer } from "@uipath/packager-orchestrator-client";
|
|
2
|
-
import {
|
|
3
|
-
type FileSystemStats,
|
|
4
|
-
type IFileSystem,
|
|
5
|
-
type IProjectBuildOptions,
|
|
6
|
-
type IProjectCleanupOptions,
|
|
7
|
-
type IProjectOptions,
|
|
8
|
-
type IProjectPackOptions,
|
|
9
|
-
type IProjectRestoreOptions,
|
|
10
|
-
type IProjectValidateOptions,
|
|
11
|
-
type IToolLogger,
|
|
12
|
-
LogLevel,
|
|
13
|
-
type ProjectOperationContext,
|
|
14
|
-
ProjectTool,
|
|
15
|
-
type ToolResult,
|
|
16
|
-
toProjectCleanupInfo,
|
|
17
|
-
type WorkflowCompilerCleanupPayload,
|
|
18
|
-
} from "@uipath/solutionpackager-tool-core";
|
|
19
|
-
import { WorkflowCompilerExecutor } from "./workflow-compiler-executor.js";
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Raw `remove-unused-dependencies` payload the WorkflowCompiler emits on
|
|
23
|
-
* `details.removeUnusedDependencies` (PascalCase on the wire, camelCased by the
|
|
24
|
-
* executor). Owned by this tool; mapped to the generic {@link ProjectCleanupInfo}
|
|
25
|
-
* before it leaves `cleanupAsync` so nothing downstream depends on this shape.
|
|
26
|
-
*/
|
|
27
|
-
type RawRemoveUnusedDependenciesResult = WorkflowCompilerCleanupPayload;
|
|
28
|
-
|
|
29
|
-
const NO_CLEANUP_SOURCE_FILES_MESSAGE =
|
|
30
|
-
"no workflow xamls or coded source files";
|
|
31
|
-
const CLEANUP_SOURCE_FILE_EXTENSIONS = [".xaml", ".cs", ".vb"];
|
|
32
|
-
const CLEANUP_SOURCE_SCAN_SKIP_DIRS = new Set([
|
|
33
|
-
".git",
|
|
34
|
-
".local",
|
|
35
|
-
".project",
|
|
36
|
-
"bin",
|
|
37
|
-
"dist",
|
|
38
|
-
"node_modules",
|
|
39
|
-
"obj",
|
|
40
|
-
]);
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* The two NuGet-source channels the WorkflowCompiler accepts, kept apart on
|
|
44
|
-
* purpose:
|
|
45
|
-
* - `orchestratorFeedsJsonPath` — Orchestrator tenant feeds composed internally into a
|
|
46
|
-
* JSON file, passed on the hidden `--nuget-config-file` option. Never
|
|
47
|
-
* user-supplied.
|
|
48
|
-
* - `userNugetConfigPath` — the user's own NuGet.config (XML), passed verbatim on
|
|
49
|
-
* `--nuget-config`.
|
|
50
|
-
*/
|
|
51
|
-
interface FeedPaths {
|
|
52
|
-
orchestratorFeedsJsonPath?: string;
|
|
53
|
-
userNugetConfigPath?: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Workflow compiler tool implementation.
|
|
58
|
-
* Builds commands and delegates execution to WorkflowCompilerExecutor.
|
|
59
|
-
*/
|
|
60
|
-
export class WorkflowCompilerTool extends ProjectTool {
|
|
61
|
-
private readonly executor: WorkflowCompilerExecutor;
|
|
62
|
-
|
|
63
|
-
constructor(
|
|
64
|
-
fileSystem: IFileSystem,
|
|
65
|
-
logger: IToolLogger,
|
|
66
|
-
private readonly context?: ProjectOperationContext,
|
|
67
|
-
) {
|
|
68
|
-
super(fileSystem, logger);
|
|
69
|
-
this.executor = new WorkflowCompilerExecutor(logger, fileSystem);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
private async withFeedPaths(
|
|
73
|
-
options: IProjectOptions,
|
|
74
|
-
run: (paths: FeedPaths) => Promise<ToolResult>,
|
|
75
|
-
): Promise<ToolResult> {
|
|
76
|
-
// The user's own NuGet.config (XML) always rides the --nuget-config
|
|
77
|
-
// channel; it is never mixed into the internal feeds file.
|
|
78
|
-
const userNugetConfigPath = options.nuGetSourcesConfigPath;
|
|
79
|
-
const connection = this.context?.connection;
|
|
80
|
-
// A named folder must fail closed. Skipping composition here would let
|
|
81
|
-
// the build fall back to whatever other sources are configured, which is
|
|
82
|
-
// precisely what --feed-folder exists to prevent — so hand it to the
|
|
83
|
-
// composer even without a session and let it raise.
|
|
84
|
-
if (!connection && !options.feedFolder) {
|
|
85
|
-
return run({ userNugetConfigPath });
|
|
86
|
-
}
|
|
87
|
-
// Orchestrator tenant feeds are composed into a JSON file that only ever
|
|
88
|
-
// goes on the hidden --nuget-config-file option.
|
|
89
|
-
const composed = await new OrchestratorFeedComposer(
|
|
90
|
-
this.fileSystem,
|
|
91
|
-
this.logger,
|
|
92
|
-
).composeAsync({ connection, feedFolder: options.feedFolder });
|
|
93
|
-
try {
|
|
94
|
-
return await run({
|
|
95
|
-
orchestratorFeedsJsonPath: composed.configPath,
|
|
96
|
-
userNugetConfigPath,
|
|
97
|
-
});
|
|
98
|
-
} finally {
|
|
99
|
-
await composed.dispose();
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async restoreAsync(
|
|
104
|
-
options: IProjectRestoreOptions,
|
|
105
|
-
cancellationToken?: AbortSignal,
|
|
106
|
-
): Promise<ToolResult> {
|
|
107
|
-
return this.withFeedPaths(options, (paths) => {
|
|
108
|
-
const args = [
|
|
109
|
-
`-p`,
|
|
110
|
-
options.projectPath,
|
|
111
|
-
`--log-level`,
|
|
112
|
-
String(options.logLevel ?? LogLevel.Info),
|
|
113
|
-
`--destination`,
|
|
114
|
-
options.outputPath ?? "",
|
|
115
|
-
`--format-logs`,
|
|
116
|
-
`true`,
|
|
117
|
-
`--exclude-configured-sources`,
|
|
118
|
-
`${options.excludeConfiguredSources}`,
|
|
119
|
-
];
|
|
120
|
-
|
|
121
|
-
if (paths.orchestratorFeedsJsonPath) {
|
|
122
|
-
args.push(
|
|
123
|
-
`--nuget-config-file`,
|
|
124
|
-
paths.orchestratorFeedsJsonPath,
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
if (paths.userNugetConfigPath) {
|
|
128
|
-
args.push(`--nuget-config`, paths.userNugetConfigPath);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return this.executor.executeAsync(
|
|
132
|
-
"restore",
|
|
133
|
-
args,
|
|
134
|
-
cancellationToken,
|
|
135
|
-
);
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
async validateAsync(
|
|
140
|
-
options: IProjectValidateOptions,
|
|
141
|
-
cancellationToken?: AbortSignal,
|
|
142
|
-
): Promise<ToolResult> {
|
|
143
|
-
return this.withFeedPaths(options, (paths) => {
|
|
144
|
-
const args = [
|
|
145
|
-
`-p`,
|
|
146
|
-
options.projectPath,
|
|
147
|
-
`--log-level`,
|
|
148
|
-
String(options.logLevel ?? LogLevel.Info),
|
|
149
|
-
`--format-logs`,
|
|
150
|
-
`true`,
|
|
151
|
-
`--skip-analyze`,
|
|
152
|
-
`${options.skipAnalyze}`,
|
|
153
|
-
`--skip-validate`,
|
|
154
|
-
`${options.skipValidate}`,
|
|
155
|
-
`--exclude-configured-sources`,
|
|
156
|
-
`${options.excludeConfiguredSources}`,
|
|
157
|
-
];
|
|
158
|
-
|
|
159
|
-
if (options.detailedLogPath) {
|
|
160
|
-
args.push(`--detailed`, options.detailedLogPath);
|
|
161
|
-
}
|
|
162
|
-
if (options.defaultSeverity) {
|
|
163
|
-
args.push(`--default-severity`, options.defaultSeverity);
|
|
164
|
-
}
|
|
165
|
-
if (options.policyFilePath) {
|
|
166
|
-
args.push(`--policy-file`, options.policyFilePath);
|
|
167
|
-
}
|
|
168
|
-
if (options.policyFileType) {
|
|
169
|
-
args.push(`--policy-file-type`, `${options.policyFileType}`);
|
|
170
|
-
}
|
|
171
|
-
if (paths.orchestratorFeedsJsonPath) {
|
|
172
|
-
args.push(
|
|
173
|
-
`--nuget-config-file`,
|
|
174
|
-
paths.orchestratorFeedsJsonPath,
|
|
175
|
-
);
|
|
176
|
-
}
|
|
177
|
-
if (paths.userNugetConfigPath) {
|
|
178
|
-
args.push(`--nuget-config`, paths.userNugetConfigPath);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return this.executor.executeAsync(
|
|
182
|
-
"validate",
|
|
183
|
-
args,
|
|
184
|
-
cancellationToken,
|
|
185
|
-
);
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
async buildAsync(
|
|
190
|
-
options: IProjectBuildOptions,
|
|
191
|
-
cancellationToken?: AbortSignal,
|
|
192
|
-
): Promise<ToolResult> {
|
|
193
|
-
return this.withFeedPaths(options, (paths) => {
|
|
194
|
-
const args = [
|
|
195
|
-
`-p`,
|
|
196
|
-
options.projectPath,
|
|
197
|
-
`-o`,
|
|
198
|
-
options.outputPath,
|
|
199
|
-
`--log-level`,
|
|
200
|
-
String(options.logLevel ?? LogLevel.Info),
|
|
201
|
-
`--format-logs`,
|
|
202
|
-
`true`,
|
|
203
|
-
`--skip-analyze`,
|
|
204
|
-
`${options.skipAnalyze}`,
|
|
205
|
-
`--skip-validate`,
|
|
206
|
-
`${options.skipValidate}`,
|
|
207
|
-
`--exclude-configured-sources`,
|
|
208
|
-
`${options.excludeConfiguredSources}`,
|
|
209
|
-
];
|
|
210
|
-
|
|
211
|
-
if (options.detailedLogPath) {
|
|
212
|
-
args.push(`--detailed`, options.detailedLogPath);
|
|
213
|
-
}
|
|
214
|
-
if (options.policyFilePath) {
|
|
215
|
-
args.push(`--policy-file`, options.policyFilePath);
|
|
216
|
-
}
|
|
217
|
-
if (options.policyFileType) {
|
|
218
|
-
args.push(`--policy-file-type`, `${options.policyFileType}`);
|
|
219
|
-
}
|
|
220
|
-
if (options.outputType) {
|
|
221
|
-
const outputType = this.mapOutputType(options.outputType);
|
|
222
|
-
args.push(`--output-type`, outputType);
|
|
223
|
-
}
|
|
224
|
-
if (paths.orchestratorFeedsJsonPath) {
|
|
225
|
-
args.push(
|
|
226
|
-
`--nuget-config-file`,
|
|
227
|
-
paths.orchestratorFeedsJsonPath,
|
|
228
|
-
);
|
|
229
|
-
}
|
|
230
|
-
if (paths.userNugetConfigPath) {
|
|
231
|
-
args.push(`--nuget-config`, paths.userNugetConfigPath);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return this.executor.executeAsync("build", args, cancellationToken);
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
async packAsync(
|
|
239
|
-
options: IProjectPackOptions,
|
|
240
|
-
cancellationToken?: AbortSignal,
|
|
241
|
-
): Promise<ToolResult> {
|
|
242
|
-
return this.withFeedPaths(options, async (paths) => {
|
|
243
|
-
const args: string[] = [
|
|
244
|
-
`-p`,
|
|
245
|
-
options.projectPath,
|
|
246
|
-
`-o`,
|
|
247
|
-
options.outputPath,
|
|
248
|
-
`--build-version`,
|
|
249
|
-
options.package.version,
|
|
250
|
-
`--log-level`,
|
|
251
|
-
String(options.logLevel ?? LogLevel.Info),
|
|
252
|
-
`--format-logs`,
|
|
253
|
-
`true`,
|
|
254
|
-
`--skip-analyze`,
|
|
255
|
-
`${options.skipAnalyze}`,
|
|
256
|
-
`--skip-validate`,
|
|
257
|
-
`${options.skipValidate}`,
|
|
258
|
-
`--no-optimize-deps`,
|
|
259
|
-
`${options.skipDependencyOptimization}`,
|
|
260
|
-
`--include-sources`,
|
|
261
|
-
`${options.includeSources}`,
|
|
262
|
-
`--split-packages`,
|
|
263
|
-
`${options.splitPackages}`,
|
|
264
|
-
`--exclude-configured-sources`,
|
|
265
|
-
`${options.excludeConfiguredSources}`,
|
|
266
|
-
`--pack-options`,
|
|
267
|
-
JSON.stringify(options.package),
|
|
268
|
-
];
|
|
269
|
-
|
|
270
|
-
if (options.package.id) {
|
|
271
|
-
args.push(`--package-name`, options.package.id);
|
|
272
|
-
}
|
|
273
|
-
if (options.detailedLogPath) {
|
|
274
|
-
args.push(`--detailed`, options.detailedLogPath);
|
|
275
|
-
}
|
|
276
|
-
if (options.policyFilePath) {
|
|
277
|
-
args.push(`--policy-file`, options.policyFilePath);
|
|
278
|
-
}
|
|
279
|
-
if (options.policyFileType) {
|
|
280
|
-
args.push(`--policy-file-type`, options.policyFileType);
|
|
281
|
-
}
|
|
282
|
-
if (options.outputType) {
|
|
283
|
-
const outputType = this.mapOutputType(options.outputType);
|
|
284
|
-
args.push(`--output-type`, outputType);
|
|
285
|
-
}
|
|
286
|
-
if (paths.orchestratorFeedsJsonPath) {
|
|
287
|
-
args.push(
|
|
288
|
-
`--nuget-config-file`,
|
|
289
|
-
paths.orchestratorFeedsJsonPath,
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
if (paths.userNugetConfigPath) {
|
|
293
|
-
args.push(`--nuget-config`, paths.userNugetConfigPath);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
const result = await this.executor.executeAsync(
|
|
297
|
-
"build",
|
|
298
|
-
args,
|
|
299
|
-
cancellationToken,
|
|
300
|
-
);
|
|
301
|
-
return this.recoverPackagePathsAsync(result, options.outputPath);
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
async cleanupAsync(
|
|
306
|
-
options: IProjectCleanupOptions,
|
|
307
|
-
cancellationToken?: AbortSignal,
|
|
308
|
-
): Promise<ToolResult> {
|
|
309
|
-
return this.withFeedPaths(options, async (paths) => {
|
|
310
|
-
const args = [
|
|
311
|
-
`-p`,
|
|
312
|
-
options.projectPath,
|
|
313
|
-
`--log-level`,
|
|
314
|
-
String(options.logLevel ?? LogLevel.Info),
|
|
315
|
-
`--format-logs`,
|
|
316
|
-
`true`,
|
|
317
|
-
`--exclude-configured-sources`,
|
|
318
|
-
`${options.excludeConfiguredSources}`,
|
|
319
|
-
];
|
|
320
|
-
|
|
321
|
-
// --dry-run and --skip-imports are boolean switches on the compiler CLI:
|
|
322
|
-
// present means true, absent means false. They take no value — passing
|
|
323
|
-
// one (`--dry-run false`) leaves a stray token and still enables the flag.
|
|
324
|
-
if (options.dryRun) {
|
|
325
|
-
args.push(`--dry-run`);
|
|
326
|
-
}
|
|
327
|
-
if (options.skipImports) {
|
|
328
|
-
args.push(`--skip-imports`);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
if (paths.orchestratorFeedsJsonPath) {
|
|
332
|
-
args.push(
|
|
333
|
-
`--nuget-config-file`,
|
|
334
|
-
paths.orchestratorFeedsJsonPath,
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
if (paths.userNugetConfigPath) {
|
|
338
|
-
args.push(`--nuget-config`, paths.userNugetConfigPath);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
const result = await this.executor.executeAsync(
|
|
342
|
-
"remove-unused-dependencies",
|
|
343
|
-
args,
|
|
344
|
-
cancellationToken,
|
|
345
|
-
);
|
|
346
|
-
if (
|
|
347
|
-
await this.shouldRetryCleanupNoSourceFalseNegativeAsync(
|
|
348
|
-
result,
|
|
349
|
-
options.projectPath,
|
|
350
|
-
)
|
|
351
|
-
) {
|
|
352
|
-
this.logger.warn(
|
|
353
|
-
"[WorkflowCompiler] remove-unused-dependencies reported no workflow/source files even though the project contains source files; retrying once.",
|
|
354
|
-
);
|
|
355
|
-
const retryResult = await this.executor.executeAsync(
|
|
356
|
-
"remove-unused-dependencies",
|
|
357
|
-
args,
|
|
358
|
-
cancellationToken,
|
|
359
|
-
);
|
|
360
|
-
return this.toProjectCleanupResult(retryResult);
|
|
361
|
-
}
|
|
362
|
-
return this.toProjectCleanupResult(result);
|
|
363
|
-
});
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
private async shouldRetryCleanupNoSourceFalseNegativeAsync(
|
|
367
|
-
result: ToolResult,
|
|
368
|
-
projectPath: string,
|
|
369
|
-
): Promise<boolean> {
|
|
370
|
-
if (result.isSuccess) {
|
|
371
|
-
return false;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
const message = result.message?.toLowerCase();
|
|
375
|
-
if (!message?.includes(NO_CLEANUP_SOURCE_FILES_MESSAGE)) {
|
|
376
|
-
return false;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
return await this.hasCleanupSourceFilesAsync(projectPath);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
private async hasCleanupSourceFilesAsync(
|
|
383
|
-
projectPath: string,
|
|
384
|
-
): Promise<boolean> {
|
|
385
|
-
let entries: string[];
|
|
386
|
-
try {
|
|
387
|
-
entries = await this.fileSystem.readdir(projectPath);
|
|
388
|
-
} catch {
|
|
389
|
-
return false;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
for (const entry of entries) {
|
|
393
|
-
const lowerEntry = entry.toLowerCase();
|
|
394
|
-
const fullPath = this.fileSystem.path.join(projectPath, entry);
|
|
395
|
-
let stats: FileSystemStats | null;
|
|
396
|
-
try {
|
|
397
|
-
stats = await this.fileSystem.stat(fullPath);
|
|
398
|
-
} catch {
|
|
399
|
-
continue;
|
|
400
|
-
}
|
|
401
|
-
if (!stats) {
|
|
402
|
-
continue;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
if (
|
|
406
|
-
stats.isFile() &&
|
|
407
|
-
CLEANUP_SOURCE_FILE_EXTENSIONS.some((extension) =>
|
|
408
|
-
lowerEntry.endsWith(extension),
|
|
409
|
-
)
|
|
410
|
-
) {
|
|
411
|
-
return true;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
if (
|
|
415
|
-
stats.isDirectory() &&
|
|
416
|
-
!CLEANUP_SOURCE_SCAN_SKIP_DIRS.has(lowerEntry) &&
|
|
417
|
-
(await this.hasCleanupSourceFilesAsync(fullPath))
|
|
418
|
-
) {
|
|
419
|
-
return true;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
return false;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
/**
|
|
427
|
-
* Convert the WorkflowCompiler's raw `remove-unused-dependencies` payload
|
|
428
|
-
* into the generic {@link ProjectCleanupInfo} the cleanup pipeline expects,
|
|
429
|
-
* exposed under the generic `details.projectCleanup` key. The
|
|
430
|
-
* workflow-specific bits (per-file removed namespaces) are preserved under
|
|
431
|
-
* `toolDetails` with this tool's own type; callers that only want the general
|
|
432
|
-
* result ignore it. Leaves the result untouched when the tool reported no
|
|
433
|
-
* cleanup payload (e.g. a failure, or an older compiler build).
|
|
434
|
-
*/
|
|
435
|
-
private toProjectCleanupResult(result: ToolResult): ToolResult {
|
|
436
|
-
const raw = result.details?.removeUnusedDependencies as
|
|
437
|
-
| RawRemoveUnusedDependenciesResult
|
|
438
|
-
| undefined;
|
|
439
|
-
if (!raw) {
|
|
440
|
-
return result;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
// Re-key the wire-named payload under the generic `projectCleanup` so
|
|
444
|
-
// nothing downstream sees this tool's domain naming.
|
|
445
|
-
const details = { ...result.details };
|
|
446
|
-
delete details.removeUnusedDependencies;
|
|
447
|
-
details.projectCleanup = toProjectCleanupInfo(raw);
|
|
448
|
-
result.details = details;
|
|
449
|
-
return result;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Maps output type for workflow compiler.
|
|
454
|
-
*/
|
|
455
|
-
private mapOutputType(outputType: string): string {
|
|
456
|
-
return outputType === "WebApp" ? "Process" : outputType;
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
/**
|
|
460
|
-
* WORKAROUND (UV-15007): older WorkflowCompiler builds report the staging
|
|
461
|
-
* content folder in their pack result instead of the produced `.nupkg` path,
|
|
462
|
-
* so downstream consumers (package signing, solution compression) cannot rely
|
|
463
|
-
* on `packages`. When the result does not already carry `.nupkg` paths, recover
|
|
464
|
-
* them by scanning the output folder.
|
|
465
|
-
*
|
|
466
|
-
* Remove this fallback after UV-15007 lands and the bundled WorkflowCompiler
|
|
467
|
-
* surfaces the produced `.nupkg` path in its result
|
|
468
|
-
* (see scripts/Download-WorkflowCompiler.ps1).
|
|
469
|
-
*/
|
|
470
|
-
private async recoverPackagePathsAsync(
|
|
471
|
-
result: ToolResult,
|
|
472
|
-
outputPath: string,
|
|
473
|
-
): Promise<ToolResult> {
|
|
474
|
-
if (!result.isSuccess) {
|
|
475
|
-
return result;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
const alreadyHasNupkgPaths =
|
|
479
|
-
result.packages.length > 0 &&
|
|
480
|
-
result.packages.every((p) => p.toLowerCase().endsWith(".nupkg"));
|
|
481
|
-
if (alreadyHasNupkgPaths) {
|
|
482
|
-
return result;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
const recovered = await this.findNupkgFilesAsync(outputPath);
|
|
486
|
-
if (recovered.length > 0) {
|
|
487
|
-
this.logger.warn(
|
|
488
|
-
`[WorkflowCompiler] pack result did not include .nupkg paths; recovered ${recovered.length} package(s) by scanning the output folder (UV-15007 workaround).`,
|
|
489
|
-
);
|
|
490
|
-
result.packages = recovered;
|
|
491
|
-
}
|
|
492
|
-
return result;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
/**
|
|
496
|
-
* Recursively collect `.nupkg` files under `dir` (cross-platform). Returns an
|
|
497
|
-
* empty list if the folder cannot be read.
|
|
498
|
-
*/
|
|
499
|
-
private async findNupkgFilesAsync(dir: string): Promise<string[]> {
|
|
500
|
-
const results: string[] = [];
|
|
501
|
-
let entries: string[];
|
|
502
|
-
try {
|
|
503
|
-
entries = await this.fileSystem.readdir(dir);
|
|
504
|
-
} catch {
|
|
505
|
-
return results;
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
for (const entry of entries) {
|
|
509
|
-
const fullPath = this.fileSystem.path.join(dir, entry);
|
|
510
|
-
const stats = await this.fileSystem.stat(fullPath);
|
|
511
|
-
if (stats?.isDirectory()) {
|
|
512
|
-
results.push(...(await this.findNupkgFilesAsync(fullPath)));
|
|
513
|
-
} else if (entry.toLowerCase().endsWith(".nupkg")) {
|
|
514
|
-
results.push(fullPath);
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
return results;
|
|
518
|
-
}
|
|
519
|
-
}
|