@smoothbricks/cli 0.10.2 → 0.10.3
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/README.md +25 -13
- package/dist/cli.js +24 -0
- package/dist/github-ci/index.d.ts +17 -2
- package/dist/github-ci/index.d.ts.map +1 -1
- package/dist/github-ci/index.js +141 -11
- package/dist/github-ci/outputs.d.ts +22 -0
- package/dist/github-ci/outputs.d.ts.map +1 -0
- package/dist/github-ci/outputs.js +649 -0
- package/dist/monorepo/ci-workflow.js +1 -1
- package/dist/monorepo/managed-files.d.ts +1 -0
- package/dist/monorepo/managed-files.d.ts.map +1 -1
- package/dist/monorepo/managed-files.js +38 -0
- package/dist/monorepo/package-policy.d.ts.map +1 -1
- package/dist/monorepo/package-policy.js +26 -0
- package/dist/monorepo/packs/index.d.ts +3 -0
- package/dist/monorepo/packs/index.d.ts.map +1 -1
- package/dist/monorepo/packs/index.js +5 -2
- package/dist/monorepo/publish-workflow.d.ts +1 -0
- package/dist/monorepo/publish-workflow.d.ts.map +1 -1
- package/dist/monorepo/publish-workflow.js +239 -2
- package/dist/nx/index.d.ts +6 -0
- package/dist/nx/index.d.ts.map +1 -1
- package/dist/nx/index.js +55 -5
- package/dist/release/github-release.d.ts +3 -0
- package/dist/release/github-release.d.ts.map +1 -1
- package/dist/release/github-release.js +11 -0
- package/dist/release/index.d.ts +19 -1
- package/dist/release/index.d.ts.map +1 -1
- package/dist/release/index.js +140 -31
- package/dist/release/orchestration.d.ts +8 -1
- package/dist/release/orchestration.d.ts.map +1 -1
- package/dist/release/orchestration.js +38 -1
- package/managed/raw/tooling/direnv/github-actions-bootstrap.sh +5 -0
- package/managed/raw/tooling/direnv/setup-environment.ts +40 -3
- package/managed/templates/github/actions/cache-nix-devenv/action.yml +12 -10
- package/managed/templates/github/actions/cache-node-modules/action.yml +3 -2
- package/managed/templates/github/actions/cache-nx/action.yml +2 -2
- package/managed/templates/github/actions/save-nix-devenv/action.yml +11 -3
- package/package.json +7 -4
- package/src/cli.ts +30 -4
- package/src/github-ci/index.test.ts +486 -0
- package/src/github-ci/index.ts +172 -13
- package/src/github-ci/outputs.ts +506 -0
- package/src/monorepo/__tests__/ci-workflow.test.ts +11 -0
- package/src/monorepo/__tests__/publish-workflow.test.ts +222 -1
- package/src/monorepo/ci-workflow.ts +1 -1
- package/src/monorepo/managed-files.test.ts +62 -0
- package/src/monorepo/managed-files.ts +41 -0
- package/src/monorepo/package-policy.test.ts +50 -1
- package/src/monorepo/package-policy.ts +28 -0
- package/src/monorepo/packs/index.test.ts +18 -1
- package/src/monorepo/packs/index.ts +7 -3
- package/src/monorepo/publish-workflow.ts +479 -2
- package/src/nx/index.test.ts +39 -0
- package/src/nx/index.ts +65 -5
- package/src/release/__tests__/fixture-repo.test.ts +18 -16
- package/src/release/__tests__/github-release.test.ts +11 -0
- package/src/release/__tests__/orchestration.test.ts +57 -2
- package/src/release/__tests__/trust-publisher.test.ts +91 -2
- package/src/release/github-release.ts +12 -0
- package/src/release/index.ts +218 -40
- package/src/release/orchestration.ts +55 -3
|
@@ -2,6 +2,7 @@ import { execFileSync } from 'node:child_process';
|
|
|
2
2
|
import { existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { dirname, join, resolve } from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { PLATFORM_TARGET_GLOBS } from '@smoothbricks/nx-plugin/workspace-config-policy';
|
|
5
6
|
import { listReleasePackages, readPackageJson } from '../lib/workspace.js';
|
|
6
7
|
import { renderCiWorkflowYaml } from './ci-workflow.js';
|
|
7
8
|
import { renderPublishWorkflowYaml } from './publish-workflow.js';
|
|
@@ -234,6 +235,7 @@ function getManagedContent(file, context) {
|
|
|
234
235
|
deploy: context.hasProductionDeployTargets,
|
|
235
236
|
deployProvider: context.productionDeployProvider,
|
|
236
237
|
repoName: context.repoName,
|
|
238
|
+
platformTargetGlobs: context.platformTargetGlobs,
|
|
237
239
|
});
|
|
238
240
|
}
|
|
239
241
|
throw new Error(`Unknown generated managed file source ${file.source}`);
|
|
@@ -252,6 +254,7 @@ function getManagedFileContext(root) {
|
|
|
252
254
|
const ciPushBranches = getCiPushBranches(packageJson?.json);
|
|
253
255
|
const stagingDeploy = getDeployTargetInfo(root, 'staging');
|
|
254
256
|
const productionDeploy = getDeployTargetInfo(root, 'production');
|
|
257
|
+
const platformTargetGlobs = platformTargetGlobsForTest(readResolvedNxTargetNames(root));
|
|
255
258
|
const nodeModulesCacheKey = existsSync(join(root, 'bun.lock'))
|
|
256
259
|
? `$${"{{ hashFiles('bun.lock', 'package.json', 'packages/*/package.json') }}"}`
|
|
257
260
|
: `$${"{{ hashFiles('bun.lockb', 'package.json', 'packages/*/package.json') }}"}`;
|
|
@@ -264,8 +267,43 @@ function getManagedFileContext(root) {
|
|
|
264
267
|
ciPushBranches,
|
|
265
268
|
nodeModulesCacheKey,
|
|
266
269
|
repoName,
|
|
270
|
+
platformTargetGlobs,
|
|
267
271
|
};
|
|
268
272
|
}
|
|
273
|
+
export function platformTargetGlobsForTest(targetNames) {
|
|
274
|
+
const names = [...targetNames];
|
|
275
|
+
return PLATFORM_TARGET_GLOBS.filter((glob) => {
|
|
276
|
+
const suffix = glob.startsWith('*') ? glob.slice(1) : glob;
|
|
277
|
+
return names.some((name) => name.endsWith(suffix));
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
function readResolvedNxTargetNames(root) {
|
|
281
|
+
const output = execFileSync('nx', ['show', 'projects', '--json'], {
|
|
282
|
+
cwd: root,
|
|
283
|
+
encoding: 'utf8',
|
|
284
|
+
stdio: ['ignore', 'pipe', 'inherit'],
|
|
285
|
+
});
|
|
286
|
+
const projects = JSON.parse(output);
|
|
287
|
+
if (!Array.isArray(projects) || !projects.every((project) => typeof project === 'string')) {
|
|
288
|
+
return [];
|
|
289
|
+
}
|
|
290
|
+
const targetNames = new Set();
|
|
291
|
+
for (const project of projects) {
|
|
292
|
+
const projectOutput = execFileSync('nx', ['show', 'project', project, '--json'], {
|
|
293
|
+
cwd: root,
|
|
294
|
+
encoding: 'utf8',
|
|
295
|
+
stdio: ['ignore', 'pipe', 'inherit'],
|
|
296
|
+
});
|
|
297
|
+
const projectJson = JSON.parse(projectOutput);
|
|
298
|
+
const targets = recordValue(recordValue(projectJson)?.targets);
|
|
299
|
+
if (targets) {
|
|
300
|
+
for (const targetName of Object.keys(targets)) {
|
|
301
|
+
targetNames.add(targetName);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return [...targetNames];
|
|
306
|
+
}
|
|
269
307
|
function renderTemplate(context, template) {
|
|
270
308
|
return template
|
|
271
309
|
.replaceAll('{{REPO_NAME}}', context.repoName)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-policy.d.ts","sourceRoot":"","sources":["../../src/monorepo/package-policy.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC5B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAGL,2BAA2B,EAC3B,uBAAuB,EACxB,MAAM,+CAA+C,CAAC;AA6BvD,YAAY,EAAE,0BAA0B,IAAI,iCAAiC,EAAE,sBAAsB,EAAE,CAAC;AACxG,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,CAAC;AAYhE,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI/D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAuB1D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMxD;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAuC7D;AAED,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,0BAA+B,GAAG,IAAI,CAwB7G;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMzD;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAoB7D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAEvE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAezD;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAsC9D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAW5D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyB3D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAcvD;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA0DlE;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,0BAA+B,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"package-policy.d.ts","sourceRoot":"","sources":["../../src/monorepo/package-policy.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC5B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAGL,2BAA2B,EAC3B,uBAAuB,EACxB,MAAM,+CAA+C,CAAC;AA6BvD,YAAY,EAAE,0BAA0B,IAAI,iCAAiC,EAAE,sBAAsB,EAAE,CAAC;AACxG,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,CAAC;AAYhE,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI/D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAuB1D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMxD;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAuC7D;AAED,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,0BAA+B,GAAG,IAAI,CAwB7G;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMzD;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAoB7D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAEvE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAezD;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAsC9D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAW5D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyB3D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAcvD;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA0DlE;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,0BAA+B,GAAG,MAAM,CAkC5G"}
|
|
@@ -315,6 +315,7 @@ export function validatePublicPackageMetadata(root) {
|
|
|
315
315
|
}
|
|
316
316
|
export function validateWorkspaceDependencies(root, options = {}) {
|
|
317
317
|
let failures = 0;
|
|
318
|
+
failures += validateCiSkipTags(root, options);
|
|
318
319
|
const workspaceNames = new Set(getWorkspacePackages(root).map((pkg) => pkg.name));
|
|
319
320
|
for (const pkg of listPackageJsonRecords(root)) {
|
|
320
321
|
for (const field of workspaceDependencyFields) {
|
|
@@ -347,6 +348,31 @@ export function validateWorkspaceDependencies(root, options = {}) {
|
|
|
347
348
|
}
|
|
348
349
|
return failures;
|
|
349
350
|
}
|
|
351
|
+
const ciSkipTagPrefix = 'ci:skip:';
|
|
352
|
+
const invalidCiSkipTargetSyntax = /[,*?[\]{}]/;
|
|
353
|
+
function validateCiSkipTags(root, options) {
|
|
354
|
+
let failures = 0;
|
|
355
|
+
for (const pkg of getWorkspacePackages(root)) {
|
|
356
|
+
const resolved = options.resolvedTargetsByProject?.get(pkg.projectName);
|
|
357
|
+
const resolvedTargets = resolved && 'targets' in resolved ? resolved.targets : resolved;
|
|
358
|
+
for (const tag of pkg.tags) {
|
|
359
|
+
if (tag !== 'ci:skip' && !tag.startsWith(ciSkipTagPrefix)) {
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
const target = tag.startsWith(ciSkipTagPrefix) ? tag.slice(ciSkipTagPrefix.length) : '';
|
|
363
|
+
if (!target || invalidCiSkipTargetSyntax.test(target)) {
|
|
364
|
+
console.error(`${pkg.path}: nx tag ${tag} must use ci:skip:<target> with one exact Nx target name`);
|
|
365
|
+
failures++;
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
if (resolvedTargets && !resolvedTargets.has(target)) {
|
|
369
|
+
console.error(`${pkg.path}: nx tag ${tag} names missing Nx target ${target}`);
|
|
370
|
+
failures++;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return failures;
|
|
375
|
+
}
|
|
350
376
|
// ---------------------------------------------------------------------------
|
|
351
377
|
// Helpers kept in CLI (not Nx-specific)
|
|
352
378
|
// ---------------------------------------------------------------------------
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type ProjectTargets } from '../../nx/index.js';
|
|
2
|
+
import { type ResolvedProjectTargets } from '../package-policy.js';
|
|
1
3
|
export interface MonorepoContext {
|
|
2
4
|
root: string;
|
|
3
5
|
syncRuntime: boolean;
|
|
@@ -26,4 +28,5 @@ export interface ValidatePackResult {
|
|
|
26
28
|
}
|
|
27
29
|
export declare function runInitPacks(ctx: MonorepoContext): Promise<void>;
|
|
28
30
|
export declare function runValidatePacks(ctx: MonorepoContext, options?: ValidatePackOptions, hooks?: ValidatePackRunHooks): Promise<ValidatePackResult>;
|
|
31
|
+
export declare function resolvedTargetsByProject(projects: ProjectTargets[]): Map<string, ResolvedProjectTargets>;
|
|
29
32
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/monorepo/packs/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/monorepo/packs/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAAsB,MAAM,mBAAmB,CAAC;AAK5E,OAAO,EAKL,KAAK,sBAAsB,EAO5B,MAAM,sBAAsB,CAAC;AAU9B,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClD,WAAW,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACzD,YAAY,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,gBAAgB,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAClE,iBAAiB,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CACpE;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CAC9F;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AA4GD,wBAAsB,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAItE;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,eAAe,EACpB,OAAO,GAAE,mBAAwB,EACjC,KAAK,GAAE,oBAAyB,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CA0B7B;AAuMD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAaxG"}
|
|
@@ -302,18 +302,21 @@ function printCapturedOutput(output) {
|
|
|
302
302
|
console.log(line);
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
|
-
|
|
306
|
-
const projects = await readProjectTargets(ctx.root);
|
|
305
|
+
export function resolvedTargetsByProject(projects) {
|
|
307
306
|
return new Map(projects.map((project) => [
|
|
308
307
|
project.project,
|
|
309
308
|
{
|
|
310
309
|
targets: new Set(project.targets),
|
|
311
310
|
...(project.buildDependsOn ? { buildDependsOn: project.buildDependsOn } : {}),
|
|
311
|
+
...(project.targetDependencies ? { targetDependencies: project.targetDependencies } : {}),
|
|
312
312
|
...(project.targetExecutors ? { targetExecutors: project.targetExecutors } : {}),
|
|
313
313
|
...(project.targetScripts ? { targetScripts: project.targetScripts } : {}),
|
|
314
314
|
},
|
|
315
315
|
]));
|
|
316
316
|
}
|
|
317
|
+
async function readResolvedTargetsByProject(ctx) {
|
|
318
|
+
return resolvedTargetsByProject(await readProjectTargets(ctx.root));
|
|
319
|
+
}
|
|
317
320
|
function ensureLocalSmooShim(root) {
|
|
318
321
|
const shim = join(root, 'tooling', 'smoo');
|
|
319
322
|
if (!existsSync(shim)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish-workflow.d.ts","sourceRoot":"","sources":["../../src/monorepo/publish-workflow.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"publish-workflow.d.ts","sourceRoot":"","sources":["../../src/monorepo/publish-workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
/* biome-ignore-all lint/suspicious/noTemplateCurlyInString: GitHub Actions expressions are emitted literally. */
|
|
2
|
+
import synchronizedPrettier from '@prettier/sync';
|
|
3
|
+
import { LINUX_PLATFORM_TARGET_GLOBS, MACOS_PLATFORM_TARGET_GLOBS, } from '@smoothbricks/nx-plugin/workspace-config-policy';
|
|
2
4
|
import { isSmoothBricksCodebasePackageName } from '../lib/cli-package.js';
|
|
5
|
+
const PUBLISH_WORKFLOW_FORMAT_OPTIONS = Object.freeze({
|
|
6
|
+
parser: 'yaml',
|
|
7
|
+
printWidth: 120,
|
|
8
|
+
proseWrap: 'always',
|
|
9
|
+
});
|
|
3
10
|
export var PublishWorkflowStepKind;
|
|
4
11
|
(function (PublishWorkflowStepKind) {
|
|
5
12
|
PublishWorkflowStepKind["Checkout"] = "checkout";
|
|
@@ -175,8 +182,18 @@ function shouldRunStep(step, version, failed, inputs) {
|
|
|
175
182
|
return true;
|
|
176
183
|
}
|
|
177
184
|
export function renderPublishWorkflowYaml(options = {}) {
|
|
178
|
-
|
|
179
|
-
|
|
185
|
+
let workflow;
|
|
186
|
+
if (hasMacosPlatformTargets(options)) {
|
|
187
|
+
workflow = renderPlatformPublishWorkflowYaml(options);
|
|
188
|
+
}
|
|
189
|
+
else if (hasLinuxPlatformTargets(options)) {
|
|
190
|
+
workflow = `${renderPublishWorkflowHeader(options)}${renderSingleJobPublishWorkflowSteps(definePublishWorkflow(options).steps, options)}`;
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
const steps = definePublishWorkflow(options).steps;
|
|
194
|
+
workflow = `${renderPublishWorkflowHeader(options)}${renderPublishWorkflowSteps(steps, options)}`;
|
|
195
|
+
}
|
|
196
|
+
return synchronizedPrettier.format(workflow, PUBLISH_WORKFLOW_FORMAT_OPTIONS);
|
|
180
197
|
}
|
|
181
198
|
function renderPublishWorkflowHeader(options) {
|
|
182
199
|
const deployInput = options.deploy === true
|
|
@@ -375,6 +392,226 @@ function conditionalRunStep(step, run) {
|
|
|
375
392
|
const condition = "steps.version.outputs.mode != 'none'";
|
|
376
393
|
return [` - name: ${step.name}`, ` if: ${githubExpression(condition)}`, ` run: ${run}`];
|
|
377
394
|
}
|
|
395
|
+
function renderSingleJobPublishWorkflowSteps(steps, options) {
|
|
396
|
+
const lines = [];
|
|
397
|
+
for (const step of steps) {
|
|
398
|
+
lines.push(...sectionLinesBefore(step));
|
|
399
|
+
lines.push(...commentLinesForStep(step));
|
|
400
|
+
lines.push(...yamlLinesForStep(step, options));
|
|
401
|
+
lines.push('');
|
|
402
|
+
if (step.kind === PublishWorkflowStepKind.Build) {
|
|
403
|
+
lines.push(' - name: 🐧 Build supplemental Linux targets', ` if: ${githubExpression("steps.version.outputs.mode != 'none'")}`, ` run: smoo github-ci nx-run-many --targets "${LINUX_PLATFORM_TARGET_GLOBS.join(',')}" --projects "${githubExpression('steps.version.outputs.projects')}"`, '');
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return `${lines.join('\n').trimEnd()}\n`;
|
|
407
|
+
}
|
|
408
|
+
function renderPlatformPublishWorkflowYaml(options) {
|
|
409
|
+
const deployInput = options.deploy === true
|
|
410
|
+
? `
|
|
411
|
+
deploy_environment:
|
|
412
|
+
type: choice
|
|
413
|
+
description: Deploy live systems after a successful publish.
|
|
414
|
+
options: [none, production]
|
|
415
|
+
default: none`
|
|
416
|
+
: '';
|
|
417
|
+
const steps = definePublishWorkflow(options).steps;
|
|
418
|
+
return `name: Publish
|
|
419
|
+
|
|
420
|
+
on:
|
|
421
|
+
workflow_dispatch:
|
|
422
|
+
inputs:
|
|
423
|
+
bump:
|
|
424
|
+
type: choice
|
|
425
|
+
description:
|
|
426
|
+
Use auto for conventional commits, or force a semver bump. Prerelease publishes to next; all others publish to
|
|
427
|
+
latest.
|
|
428
|
+
options: [auto, patch, minor, major, prerelease]
|
|
429
|
+
default: auto
|
|
430
|
+
dry_run:
|
|
431
|
+
type: boolean
|
|
432
|
+
description: Run release commands without writing versions, tags, publishes, or GitHub Releases.
|
|
433
|
+
default: false${deployInput}
|
|
434
|
+
|
|
435
|
+
permissions:
|
|
436
|
+
contents: read
|
|
437
|
+
|
|
438
|
+
concurrency:
|
|
439
|
+
group: release-${githubExpression('github.ref')}
|
|
440
|
+
cancel-in-progress: false
|
|
441
|
+
|
|
442
|
+
defaults:
|
|
443
|
+
run:
|
|
444
|
+
working-directory: tooling/direnv
|
|
445
|
+
|
|
446
|
+
jobs:
|
|
447
|
+
linux-release-candidate:
|
|
448
|
+
runs-on: ubuntu-latest
|
|
449
|
+
permissions:
|
|
450
|
+
contents: write
|
|
451
|
+
id-token: none
|
|
452
|
+
outputs:
|
|
453
|
+
mode: ${githubExpression('steps.version.outputs.mode')}
|
|
454
|
+
release-sha: ${githubExpression('steps.release-state.outputs.sha')}
|
|
455
|
+
env:
|
|
456
|
+
NIX_STORE_NAR: ${githubExpression('github.workspace')}/nix-store.nar
|
|
457
|
+
GH_TOKEN: ${githubExpression('github.token')}
|
|
458
|
+
steps:
|
|
459
|
+
${renderLinuxReleaseCandidateSteps(steps, options)}
|
|
460
|
+
|
|
461
|
+
macos-platform:
|
|
462
|
+
runs-on: macos-latest
|
|
463
|
+
permissions:
|
|
464
|
+
contents: read
|
|
465
|
+
id-token: none
|
|
466
|
+
env:
|
|
467
|
+
NIX_STORE_NAR: ${githubExpression('github.workspace')}/nix-store.nar
|
|
468
|
+
GH_TOKEN: ${githubExpression('github.token')}
|
|
469
|
+
steps:
|
|
470
|
+
${renderMacosPlatformSteps(options)}
|
|
471
|
+
|
|
472
|
+
publish-on-linux:
|
|
473
|
+
needs: [linux-release-candidate, macos-platform]
|
|
474
|
+
runs-on: ubuntu-latest
|
|
475
|
+
permissions:
|
|
476
|
+
contents: write
|
|
477
|
+
id-token: write
|
|
478
|
+
env:
|
|
479
|
+
NIX_STORE_NAR: ${githubExpression('github.workspace')}/nix-store.nar
|
|
480
|
+
GH_TOKEN: ${githubExpression('github.token')}
|
|
481
|
+
steps:
|
|
482
|
+
${renderFinalLinuxPublishSteps(options)}
|
|
483
|
+
`;
|
|
484
|
+
}
|
|
485
|
+
function renderLinuxReleaseCandidateSteps(steps, options) {
|
|
486
|
+
const lines = [];
|
|
487
|
+
let stepNumber = 2;
|
|
488
|
+
for (const step of steps) {
|
|
489
|
+
if (step.kind === PublishWorkflowStepKind.RepairPendingReleases ||
|
|
490
|
+
step.kind === PublishWorkflowStepKind.PublishRelease ||
|
|
491
|
+
step.kind === PublishWorkflowStepKind.DeployProduction ||
|
|
492
|
+
step.kind === PublishWorkflowStepKind.SaveNixDevenv) {
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
lines.push(...sectionLinesBefore(step));
|
|
496
|
+
if (step.kind === PublishWorkflowStepKind.Checkout) {
|
|
497
|
+
lines.push(' # Step 1: GitHub adds "Set up job" automatically', ` # Step ${stepNumber}`);
|
|
498
|
+
}
|
|
499
|
+
else if (step.kind === PublishWorkflowStepKind.SetupDevenv) {
|
|
500
|
+
lines.push(` # Step ${stepNumber}. Composite action internals do not affect top-level job step`, ' # anchors; update these comments if top-level steps move.');
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
lines.push(` # Step ${stepNumber}`);
|
|
504
|
+
}
|
|
505
|
+
if (step.kind === PublishWorkflowStepKind.Checkout) {
|
|
506
|
+
lines.push(` - name: ${step.name}`, ' uses: actions/checkout@v6.0.2', ' with:', ` ref: ${githubExpression('github.sha')}`, ' filter: blob:none', ' fetch-depth: 0');
|
|
507
|
+
}
|
|
508
|
+
else if (step.kind === PublishWorkflowStepKind.Build) {
|
|
509
|
+
lines.push(` - name: ${step.name}`, ` if: ${githubExpression("steps.version.outputs.mode != 'none'")}`, ' run:', ` smoo github-ci nx-run-many --targets build --projects "${githubExpression('steps.version.outputs.projects')}" --collect-outputs "${githubExpression('runner.temp')}/release-build-outputs"`);
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
lines.push(...yamlLinesForStep(step, options));
|
|
513
|
+
}
|
|
514
|
+
stepNumber += 1;
|
|
515
|
+
if (step.kind === PublishWorkflowStepKind.VersionRelease) {
|
|
516
|
+
lines.push('', ` # Step ${stepNumber}`, ' - name: 🔒 Capture candidate release SHA', ' id: release-state', ' run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"');
|
|
517
|
+
stepNumber += 1;
|
|
518
|
+
}
|
|
519
|
+
if (step.kind === PublishWorkflowStepKind.Build && hasLinuxPlatformTargets(options)) {
|
|
520
|
+
lines.push('', ` # Step ${stepNumber}`, ' - name: 🐧 Build supplemental Linux targets', ` if: ${githubExpression("steps.version.outputs.mode != 'none'")}`, ' run:', ` smoo github-ci nx-run-many --targets "${LINUX_PLATFORM_TARGET_GLOBS.join(',')}" --projects "${githubExpression('steps.version.outputs.projects')}" --collect-outputs "${githubExpression('runner.temp')}/linux-platform-outputs"`);
|
|
521
|
+
stepNumber += 1;
|
|
522
|
+
}
|
|
523
|
+
lines.push('');
|
|
524
|
+
}
|
|
525
|
+
lines.push(' # --- Candidate transfer --------------------------------------------------', '', ` # Step ${stepNumber++}`, ' - name: 📦 Bundle validated release state', ' run:', ` mkdir -p "${githubExpression('runner.temp')}/publish-release-state" && git bundle create`, ` "${githubExpression('runner.temp')}/publish-release-state/release-state.bundle" HEAD --tags && git rev-parse HEAD >`, ` "${githubExpression('runner.temp')}/publish-release-state/release-head"`, '', ` # Step ${stepNumber++}`, ' - name: 📤 Upload validated release state', ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-release-state-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/publish-release-state`, ' if-no-files-found: error', ' retention-days: 1', '', ` # Step ${stepNumber++}`, ' - name: 📤 Upload validated build outputs', ` if: ${githubExpression("steps.version.outputs.mode != 'none'")}`, ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-release-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/release-build-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true');
|
|
526
|
+
if (hasLinuxPlatformTargets(options)) {
|
|
527
|
+
lines.push('', ` # Step ${stepNumber++}`, ' - name: 📤 Upload supplemental Linux outputs', ` if: ${githubExpression("steps.version.outputs.mode != 'none'")}`, ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-linux-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/linux-platform-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true');
|
|
528
|
+
}
|
|
529
|
+
lines.push('', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: 🧹 Cleanup and cache Nix/devenv', ` if: ${githubExpression('always()')}`, ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
|
|
530
|
+
return lines.join('\n').trimEnd();
|
|
531
|
+
}
|
|
532
|
+
function renderMacosPlatformSteps(options) {
|
|
533
|
+
let stepNumber = 4;
|
|
534
|
+
const lines = [
|
|
535
|
+
' # --- Setup --------------------------------------------------------------',
|
|
536
|
+
'',
|
|
537
|
+
' # Step 1: GitHub adds "Set up job" automatically',
|
|
538
|
+
' # Step 2',
|
|
539
|
+
' - name: 📥 Checkout dispatch commit',
|
|
540
|
+
' uses: actions/checkout@v6.0.2',
|
|
541
|
+
' with:',
|
|
542
|
+
` ref: ${githubExpression('github.sha')}`,
|
|
543
|
+
' filter: blob:none',
|
|
544
|
+
' fetch-depth: 0',
|
|
545
|
+
'',
|
|
546
|
+
' # Step 3. Composite action internals do not affect top-level job step',
|
|
547
|
+
' # anchors; update these comments if top-level steps move.',
|
|
548
|
+
' - name: 🧱 Setup Nix/devenv',
|
|
549
|
+
' id: setup',
|
|
550
|
+
' uses: ./.github/actions/setup-devenv',
|
|
551
|
+
];
|
|
552
|
+
if (isSmoothBricksCodebasePackageName(options.repoName)) {
|
|
553
|
+
lines.push('', ` # Step ${stepNumber++}`, ' - name: 🏗️ Build self-hosted smoo', ' # SmoothBricks self-hosts smoo from source for release commands.', ' run: nx build cli');
|
|
554
|
+
}
|
|
555
|
+
lines.push('', ` # Step ${stepNumber++}`, ' - name: 🍎 Build selected macOS and iOS release outputs', ' run:', ` smoo release build-platform-outputs --bump "${githubExpression('inputs.bump')}" --ref "${githubExpression('github.sha')}" --targets "${MACOS_PLATFORM_TARGET_GLOBS.join(',')}" --output`, ` "${githubExpression('runner.temp')}/macos-platform-outputs"`, '', ` # Step ${stepNumber++}`, ' - name: 📤 Upload macOS platform outputs', ' uses: actions/upload-artifact@v7.0.1', ' with:', ` name: publish-macos-outputs-${githubExpression('github.run_id')}`, ` path: ${githubExpression('runner.temp')}/macos-platform-outputs`, ' if-no-files-found: error', ' retention-days: 1', ' include-hidden-files: true', '', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: 🧹 Cleanup and cache Nix/devenv', ` if: ${githubExpression('always()')}`, ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
|
|
556
|
+
return lines.join('\n').trimEnd();
|
|
557
|
+
}
|
|
558
|
+
function renderFinalLinuxPublishSteps(options) {
|
|
559
|
+
const mode = 'needs.linux-release-candidate.outputs.mode';
|
|
560
|
+
let stepNumber = 2;
|
|
561
|
+
const lines = [
|
|
562
|
+
' # --- Setup --------------------------------------------------------------',
|
|
563
|
+
'',
|
|
564
|
+
' # Step 1: GitHub adds "Set up job" automatically',
|
|
565
|
+
` # Step ${stepNumber++}`,
|
|
566
|
+
' - name: 📥 Checkout dispatch commit',
|
|
567
|
+
' uses: actions/checkout@v6.0.2',
|
|
568
|
+
' with:',
|
|
569
|
+
` ref: ${githubExpression('github.sha')}`,
|
|
570
|
+
' filter: blob:none',
|
|
571
|
+
' fetch-depth: 0',
|
|
572
|
+
'',
|
|
573
|
+
` # Step ${stepNumber++}`,
|
|
574
|
+
' - name: 📥 Download candidate artifacts',
|
|
575
|
+
' uses: actions/download-artifact@v8.0.1',
|
|
576
|
+
' with:',
|
|
577
|
+
` pattern: publish-*-${githubExpression('github.run_id')}`,
|
|
578
|
+
` path: ${githubExpression('runner.temp')}/publish-artifacts`,
|
|
579
|
+
' merge-multiple: false',
|
|
580
|
+
'',
|
|
581
|
+
` # Step ${stepNumber}. Composite action internals do not affect top-level job step`,
|
|
582
|
+
' # anchors; update these comments if top-level steps move.',
|
|
583
|
+
' - name: 🧱 Setup Nix/devenv',
|
|
584
|
+
' id: setup',
|
|
585
|
+
' uses: ./.github/actions/setup-devenv',
|
|
586
|
+
'',
|
|
587
|
+
` # Step ${++stepNumber}`,
|
|
588
|
+
' - name: 🤖 Configure release author',
|
|
589
|
+
' run:',
|
|
590
|
+
' git config user.name "github-actions[bot]" && git config user.email',
|
|
591
|
+
' "41898282+github-actions[bot]@users.noreply.github.com"',
|
|
592
|
+
];
|
|
593
|
+
stepNumber += 1;
|
|
594
|
+
if (isSmoothBricksCodebasePackageName(options.repoName)) {
|
|
595
|
+
lines.push('', ` # Step ${stepNumber++}`, ' - name: 🏗️ Build self-hosted smoo', ' # SmoothBricks self-hosts smoo from source for release commands.', ' run: nx build cli');
|
|
596
|
+
}
|
|
597
|
+
lines.push('', ' # --- Repair -------------------------------------------------------------', '', ` # Step ${stepNumber++}`, ' - name: 🧯 Repair pending releases', ' run:', ` smoo release repair-pending --ref "${githubExpression('github.sha')}" --platform-outputs "${githubExpression('runner.temp')}/publish-artifacts/publish-macos-outputs-${githubExpression('github.run_id')}/repairs" --dry-run`, ` "${githubExpression('inputs.dry_run')}"`, '', ` # Step ${stepNumber++}`, ' - name: ♻️ Restore validated release state', ' run:', ` git fetch "${githubExpression('runner.temp')}/publish-artifacts/publish-release-state-${githubExpression('github.run_id')}/release-state.bundle" HEAD --tags && git reset`, ` --hard "$(cat "${githubExpression('runner.temp')}/publish-artifacts/publish-release-state-${githubExpression('github.run_id')}/release-head")"`);
|
|
598
|
+
lines.push('', ' # --- Validation ---------------------------------------------------------', '', ` # Step ${stepNumber++}`, ' - name: 📦 Apply verified Linux outputs', ` if: ${githubExpression(`${mode} != 'none'`)}`, ' run:', ` smoo github-ci apply-outputs --source-sha "${githubExpression('needs.linux-release-candidate.outputs.release-sha')}"`, ` "${githubExpression('runner.temp')}/publish-artifacts/publish-release-outputs-${githubExpression('github.run_id')}"`);
|
|
599
|
+
if (hasLinuxPlatformTargets(options)) {
|
|
600
|
+
lines.push(` "${githubExpression('runner.temp')}/publish-artifacts/publish-linux-outputs-${githubExpression('github.run_id')}"`);
|
|
601
|
+
}
|
|
602
|
+
lines.push('', ` # Step ${stepNumber++}`, ' - name: 🍎 Apply verified macOS outputs', ` if: ${githubExpression(`${mode} != 'none'`)}`, ' run:', ` smoo github-ci apply-outputs --source-sha "${githubExpression('github.sha')}"`, ` "${githubExpression('runner.temp')}/publish-artifacts/publish-macos-outputs-${githubExpression('github.run_id')}/current"`, '', ` # Step ${stepNumber++}`, ` - name: ✅ Validate restored release (${githubExpression(mode)})`, ` if: ${githubExpression(`${mode} != 'none'`)}`, ' run: smoo monorepo validate', '', ' # --- Release ------------------------------------------------------------', '', ` # Step ${stepNumber++}`, ` - name: 📦 Publish release (${githubExpression(mode)})`, ' # smoo packs with Bun, then publishes tarballs with npm. Existing', ' # packages must already exist on npm and use trusted publishing/OIDC.', ' # Missing package names are bootstrapped locally before trust setup.', ` run: smoo release publish --bump "${githubExpression('inputs.bump')}" --dry-run "${githubExpression('inputs.dry_run')}"`);
|
|
603
|
+
if (options.deploy === true) {
|
|
604
|
+
lines.push('', ` # Step ${stepNumber++}`, ' - name: 🚀 Deploy production', ' if:', " ${{ needs.linux-release-candidate.outputs.mode != 'none' && inputs.deploy_environment == 'production' &&", " inputs.dry_run != 'true' }}", ...deployEnvLines(options), ' run: smoo github-ci nx-deploy --configuration production --mode run-many --verify --name "Deploy Production"');
|
|
605
|
+
}
|
|
606
|
+
lines.push('', ' # --- Cleanup ------------------------------------------------------------', '', ` # Step ${stepNumber}`, ' - name: 🧹 Cleanup and cache Nix/devenv', ` if: ${githubExpression('always()')}`, ' uses: ./.github/actions/save-nix-devenv', ' with:', ` nix-cache-hit: ${githubExpression('steps.setup.outputs.nix-cache-hit')}`, ` devenv-cache-hit: ${githubExpression('steps.setup.outputs.devenv-cache-hit')}`);
|
|
607
|
+
return lines.join('\n').trimEnd();
|
|
608
|
+
}
|
|
609
|
+
function hasMacosPlatformTargets(options) {
|
|
610
|
+
return MACOS_PLATFORM_TARGET_GLOBS.some((glob) => options.platformTargetGlobs?.includes(glob) === true);
|
|
611
|
+
}
|
|
612
|
+
function hasLinuxPlatformTargets(options) {
|
|
613
|
+
return LINUX_PLATFORM_TARGET_GLOBS.some((glob) => options.platformTargetGlobs?.includes(glob) === true);
|
|
614
|
+
}
|
|
378
615
|
function githubExpression(expression) {
|
|
379
616
|
return ['$', '{{ ', expression, ' }}'].join('');
|
|
380
617
|
}
|
package/dist/nx/index.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
export interface ProjectTargets {
|
|
2
2
|
project: string;
|
|
3
|
+
root?: string;
|
|
3
4
|
targets: string[];
|
|
4
5
|
buildDependsOn?: string[];
|
|
6
|
+
targetDependencies?: Map<string, string[]>;
|
|
5
7
|
targetExecutors?: Map<string, string>;
|
|
8
|
+
targetOutputs?: Map<string, string[]>;
|
|
6
9
|
targetScripts?: Map<string, string>;
|
|
7
10
|
}
|
|
8
11
|
export interface CommandInvocation {
|
|
@@ -13,8 +16,11 @@ export declare function nxResetCommand(): CommandInvocation;
|
|
|
13
16
|
export declare function nxShowProjectCommand(project: string): CommandInvocation;
|
|
14
17
|
export declare function nxCacheDirectories(root: string): string[];
|
|
15
18
|
export declare function targetNamesFromNxProjectJson(value: unknown): string[];
|
|
19
|
+
export declare function projectRootFromNxProjectJson(value: unknown): string | undefined;
|
|
16
20
|
export declare function buildDependsOnFromNxProjectJson(value: unknown): string[] | undefined;
|
|
21
|
+
export declare function targetDependenciesFromNxProjectJson(value: unknown): Map<string, string[]>;
|
|
17
22
|
export declare function targetExecutorsFromNxProjectJson(value: unknown): Map<string, string>;
|
|
23
|
+
export declare function targetOutputsFromNxProjectJson(value: unknown): Map<string, string[]>;
|
|
18
24
|
export declare function targetScriptsFromNxProjectJson(value: unknown): Map<string, string>;
|
|
19
25
|
export declare function formatProjectTargetLines(projects: ProjectTargets[]): string;
|
|
20
26
|
export declare function projectNamesWithTarget(projects: ProjectTargets[], target: string): string[];
|
package/dist/nx/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nx/index.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,wBAAgB,cAAc,IAAI,iBAAiB,CAElD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAEvE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEzD;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAGrE;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nx/index.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3C,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,wBAAgB,cAAc,IAAI,iBAAiB,CAElD;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAEvE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEzD;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAGrE;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE/E;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,SAAS,CAEpF;AAED,wBAAgB,mCAAmC,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CA2BzF;AAED,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAYpF;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAEpF;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBlF;AAuBD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CAK3E;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAK3F;AAED,wBAAgB,oCAAoC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAsB7E;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7D;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhG;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5D;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa5D;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAGhF"}
|
package/dist/nx/index.js
CHANGED
|
@@ -17,13 +17,39 @@ export function targetNamesFromNxProjectJson(value) {
|
|
|
17
17
|
const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
|
|
18
18
|
return targets ? Object.keys(targets).sort((a, b) => a.localeCompare(b)) : [];
|
|
19
19
|
}
|
|
20
|
+
export function projectRootFromNxProjectJson(value) {
|
|
21
|
+
return isRecord(value) && typeof value.root === 'string' ? value.root : undefined;
|
|
22
|
+
}
|
|
20
23
|
export function buildDependsOnFromNxProjectJson(value) {
|
|
24
|
+
return targetDependenciesFromNxProjectJson(value).get('build');
|
|
25
|
+
}
|
|
26
|
+
export function targetDependenciesFromNxProjectJson(value) {
|
|
21
27
|
const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
|
|
22
|
-
const
|
|
23
|
-
if (!
|
|
24
|
-
return
|
|
28
|
+
const dependencies = new Map();
|
|
29
|
+
if (!targets) {
|
|
30
|
+
return dependencies;
|
|
31
|
+
}
|
|
32
|
+
for (const [targetName, target] of Object.entries(targets)) {
|
|
33
|
+
if (!isRecord(target) || !Array.isArray(target.dependsOn)) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const entries = [];
|
|
37
|
+
for (const dependency of target.dependsOn) {
|
|
38
|
+
if (typeof dependency === 'string') {
|
|
39
|
+
entries.push(dependency);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (!isRecord(dependency) || typeof dependency.target !== 'string') {
|
|
43
|
+
throw new Error(`Nx target ${targetName} has an invalid dependsOn entry.`);
|
|
44
|
+
}
|
|
45
|
+
if (dependency.projects !== undefined && dependency.projects !== 'self') {
|
|
46
|
+
throw new Error(`Nx target ${targetName} uses unsupported cross-project dependsOn for ${dependency.target}.`);
|
|
47
|
+
}
|
|
48
|
+
entries.push(dependency.target);
|
|
49
|
+
}
|
|
50
|
+
dependencies.set(targetName, entries);
|
|
25
51
|
}
|
|
26
|
-
return
|
|
52
|
+
return dependencies;
|
|
27
53
|
}
|
|
28
54
|
export function targetExecutorsFromNxProjectJson(value) {
|
|
29
55
|
const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
|
|
@@ -38,6 +64,9 @@ export function targetExecutorsFromNxProjectJson(value) {
|
|
|
38
64
|
}
|
|
39
65
|
return executors;
|
|
40
66
|
}
|
|
67
|
+
export function targetOutputsFromNxProjectJson(value) {
|
|
68
|
+
return targetStringArraysFromNxProjectJson(value, 'outputs');
|
|
69
|
+
}
|
|
41
70
|
export function targetScriptsFromNxProjectJson(value) {
|
|
42
71
|
const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
|
|
43
72
|
const scripts = new Map();
|
|
@@ -55,6 +84,23 @@ export function targetScriptsFromNxProjectJson(value) {
|
|
|
55
84
|
}
|
|
56
85
|
return scripts;
|
|
57
86
|
}
|
|
87
|
+
function targetStringArraysFromNxProjectJson(value, property) {
|
|
88
|
+
const targets = isRecord(value) ? recordProperty(value, 'targets') : null;
|
|
89
|
+
const values = new Map();
|
|
90
|
+
if (!targets) {
|
|
91
|
+
return values;
|
|
92
|
+
}
|
|
93
|
+
for (const [targetName, target] of Object.entries(targets)) {
|
|
94
|
+
if (!isRecord(target)) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const entries = target[property];
|
|
98
|
+
if (Array.isArray(entries)) {
|
|
99
|
+
values.set(targetName, entries.filter((entry) => typeof entry === 'string'));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return values;
|
|
103
|
+
}
|
|
58
104
|
export function formatProjectTargetLines(projects) {
|
|
59
105
|
return projects
|
|
60
106
|
.flatMap((project) => project.targets.map((target) => `${project.project}:${target}`))
|
|
@@ -134,11 +180,15 @@ async function readProjectTarget(root, project) {
|
|
|
134
180
|
const command = nxShowProjectCommand(project);
|
|
135
181
|
const result = await $ `${command.command} ${command.args}`.cwd(root).quiet();
|
|
136
182
|
const parsed = JSON.parse(decode(result.stdout));
|
|
183
|
+
const targetDependencies = targetDependenciesFromNxProjectJson(parsed);
|
|
137
184
|
return {
|
|
138
185
|
project,
|
|
186
|
+
root: projectRootFromNxProjectJson(parsed),
|
|
139
187
|
targets: targetNamesFromNxProjectJson(parsed),
|
|
140
|
-
buildDependsOn:
|
|
188
|
+
buildDependsOn: targetDependencies.get('build'),
|
|
189
|
+
targetDependencies,
|
|
141
190
|
targetExecutors: targetExecutorsFromNxProjectJson(parsed),
|
|
191
|
+
targetOutputs: targetOutputsFromNxProjectJson(parsed),
|
|
142
192
|
targetScripts: targetScriptsFromNxProjectJson(parsed),
|
|
143
193
|
};
|
|
144
194
|
}
|
|
@@ -25,6 +25,7 @@ export declare function nxProjectChangelogArgs(pkg: ReleasePackageInfo, previous
|
|
|
25
25
|
gitPush: false;
|
|
26
26
|
stageChanges: false;
|
|
27
27
|
createRelease: false;
|
|
28
|
+
forceChangelogGeneration: true;
|
|
28
29
|
deleteVersionPlans: false;
|
|
29
30
|
dryRun: boolean;
|
|
30
31
|
from: string;
|
|
@@ -36,11 +37,13 @@ export declare function nxProjectChangelogArgs(pkg: ReleasePackageInfo, previous
|
|
|
36
37
|
gitPush: false;
|
|
37
38
|
stageChanges: false;
|
|
38
39
|
createRelease: false;
|
|
40
|
+
forceChangelogGeneration: true;
|
|
39
41
|
deleteVersionPlans: false;
|
|
40
42
|
dryRun: boolean;
|
|
41
43
|
firstRelease: boolean;
|
|
42
44
|
};
|
|
43
45
|
export declare function projectChangelogContents(result: ProjectChangelogLookupResult, projectName: string): string;
|
|
46
|
+
export declare function githubReleaseLookupExists(tag: string, exitCode: number, stdout: string, stderr: string): boolean;
|
|
44
47
|
export declare function githubReleaseCommandArgs(tag: string, notesFile: string, releaseExists: boolean, version: string): string[];
|
|
45
48
|
export declare function withNxWorkspaceRoot<T>(root: string, run: () => Promise<T>): Promise<T>;
|
|
46
49
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-release.d.ts","sourceRoot":"","sources":["../../src/release/github-release.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,kBAAkB,EAAc,MAAM,WAAW,CAAC;AAYhE,UAAU,4BAA4B;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,6BAA6B,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IACpG,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,gCAAgC,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,CAS5G;AAED,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,kBAAkB,EACvB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO
|
|
1
|
+
{"version":3,"file":"github-release.d.ts","sourceRoot":"","sources":["../../src/release/github-release.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,kBAAkB,EAAc,MAAM,WAAW,CAAC;AAYhE,UAAU,4BAA4B;IACpC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,6BAA6B,CAAC,OAAO,SAAS,kBAAkB,GAAG,kBAAkB;IACpG,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAsB,gCAAgC,CAAC,KAAK,EAAE,6BAA6B,GAAG,OAAO,CAAC,MAAM,CAAC,CAS5G;AAED,wBAAsB,2BAA2B,CAC/C,GAAG,EAAE,kBAAkB,EACvB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;EAc1G;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,4BAA4B,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAM1G;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAShH;AAED,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,OAAO,EACtB,OAAO,EAAE,MAAM,GACd,MAAM,EAAE,CAgBV;AAMD,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAmB5F"}
|
|
@@ -41,6 +41,7 @@ export function nxProjectChangelogArgs(pkg, previousTag, dryRun) {
|
|
|
41
41
|
gitPush: false,
|
|
42
42
|
stageChanges: false,
|
|
43
43
|
createRelease: false,
|
|
44
|
+
forceChangelogGeneration: true,
|
|
44
45
|
deleteVersionPlans: false,
|
|
45
46
|
dryRun,
|
|
46
47
|
};
|
|
@@ -53,6 +54,16 @@ export function projectChangelogContents(result, projectName) {
|
|
|
53
54
|
}
|
|
54
55
|
return changelog.contents;
|
|
55
56
|
}
|
|
57
|
+
export function githubReleaseLookupExists(tag, exitCode, stdout, stderr) {
|
|
58
|
+
if (exitCode === 0) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
const details = [stderr.trim(), stdout.trim()].filter(Boolean).join('\n');
|
|
62
|
+
if (/\bHTTP 404\b|release not found/i.test(details)) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
throw new Error(`Unable to inspect GitHub Release ${tag}.${details ? `\n${details}` : ''}`);
|
|
66
|
+
}
|
|
56
67
|
export function githubReleaseCommandArgs(tag, notesFile, releaseExists, version) {
|
|
57
68
|
const args = [
|
|
58
69
|
'release',
|