@otwld/workflow-cli 0.1.0

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 ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@otwld/workflow-cli",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./src/index.d.ts",
9
+ "default": "./src/index.js"
10
+ },
11
+ "./package.json": "./package.json"
12
+ },
13
+ "main": "./src/index.js",
14
+ "types": "./src/index.d.ts",
15
+ "bin": {
16
+ "workflow-cli": "./src/main.js"
17
+ },
18
+ "dependencies": {
19
+ "nx": "23.1.1"
20
+ },
21
+ "engines": {
22
+ "node": ">=24 <25"
23
+ },
24
+ "publishConfig": {
25
+ "access": "public"
26
+ }
27
+ }
package/src/cli.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export type CommandInput = {
2
+ command: 'stage' | 'release';
3
+ defaultBranch: string;
4
+ baseSha: string;
5
+ sourceSha: string;
6
+ projectsFile?: string;
7
+ };
8
+ export declare function parseCommand(argv: string[], environment: NodeJS.ProcessEnv): CommandInput;
9
+ export declare function parseProjectsFile(contents: string): string[];
package/src/cli.js ADDED
@@ -0,0 +1,88 @@
1
+ const flagToEnvironment = {
2
+ '--default-branch': 'DEFAULT_BRANCH',
3
+ '--base-sha': 'BASE_SHA',
4
+ '--source-sha': 'SOURCE_SHA',
5
+ '--projects-file': 'PROJECTS_FILE',
6
+ };
7
+ const shaPattern = /^[0-9a-f]{7,64}$/i;
8
+ const branchPattern = /^[A-Za-z0-9][A-Za-z0-9._/-]*$/;
9
+ export function parseCommand(argv, environment) {
10
+ const [command, ...flags] = argv;
11
+ if (command !== 'stage' && command !== 'release') {
12
+ throw new Error('Expected exactly one command: stage or release.');
13
+ }
14
+ const values = parseFlags(flags);
15
+ if (command === 'stage' && values['--projects-file'] !== undefined) {
16
+ throw new Error('stage does not accept --projects-file.');
17
+ }
18
+ const defaultBranch = resolve('--default-branch', values, environment);
19
+ const baseSha = resolve('--base-sha', values, environment);
20
+ const sourceSha = resolve('--source-sha', values, environment);
21
+ const projectsFile = command === 'release'
22
+ ? resolve('--projects-file', values, environment)
23
+ : undefined;
24
+ if (!branchPattern.test(defaultBranch) ||
25
+ defaultBranch.includes('..') ||
26
+ defaultBranch.endsWith('/')) {
27
+ throw new Error('default branch must be a valid branch name.');
28
+ }
29
+ if (!shaPattern.test(baseSha) || !shaPattern.test(sourceSha)) {
30
+ throw new Error('base SHA and source SHA must be hexadecimal Git object IDs.');
31
+ }
32
+ if (projectsFile !== undefined &&
33
+ (projectsFile.length === 0 || projectsFile.includes('\0'))) {
34
+ throw new Error('projects file must be a non-empty path.');
35
+ }
36
+ return projectsFile === undefined
37
+ ? { command, defaultBranch, baseSha, sourceSha }
38
+ : { command, defaultBranch, baseSha, sourceSha, projectsFile };
39
+ }
40
+ export function parseProjectsFile(contents) {
41
+ if (contents.length === 0) {
42
+ throw new Error('projects file must contain at least one project name.');
43
+ }
44
+ const lines = contents.split('\n');
45
+ if (lines.at(-1) === '') {
46
+ lines.pop();
47
+ }
48
+ const projects = lines.map((line) => line.endsWith('\r') ? line.slice(0, -1) : line);
49
+ const seen = new Set();
50
+ for (const project of projects) {
51
+ if (project.length === 0 ||
52
+ project.trim() !== project ||
53
+ project.includes(',') ||
54
+ project.includes('#') ||
55
+ /[\\$`;&|<>()[\]{}'"!]/.test(project) ||
56
+ seen.has(project)) {
57
+ throw new Error('projects file must contain one exact Nx project name per line.');
58
+ }
59
+ seen.add(project);
60
+ }
61
+ return projects;
62
+ }
63
+ function parseFlags(argv) {
64
+ const values = {};
65
+ for (let index = 0; index < argv.length; index += 2) {
66
+ const flag = argv[index];
67
+ const value = argv[index + 1];
68
+ if (!(flag in flagToEnvironment) ||
69
+ value === undefined ||
70
+ value.startsWith('--') ||
71
+ values[flag] !== undefined) {
72
+ throw new Error('Expected each supported flag exactly once with a non-empty value.');
73
+ }
74
+ if (value.length === 0) {
75
+ throw new Error(`Expected a value for ${flag}.`);
76
+ }
77
+ values[flag] = value;
78
+ }
79
+ return values;
80
+ }
81
+ function resolve(flag, values, environment) {
82
+ const value = values[flag] ?? environment[flagToEnvironment[flag]];
83
+ if (!value) {
84
+ throw new Error(`Missing ${flag} or ${flagToEnvironment[flag]}.`);
85
+ }
86
+ return value;
87
+ }
88
+ //# sourceMappingURL=cli.js.map
package/src/cli.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../../apps/workflow-cli/src/cli.ts"],"names":[],"mappings":"AAQA,MAAM,iBAAiB,GAAG;IACxB,kBAAkB,EAAE,gBAAgB;IACpC,YAAY,EAAE,UAAU;IACxB,cAAc,EAAE,YAAY;IAC5B,iBAAiB,EAAE,eAAe;CAC1B,CAAC;AAEX,MAAM,UAAU,GAAG,mBAAmB,CAAC;AACvC,MAAM,aAAa,GAAG,+BAA+B,CAAC;AAEtD,MAAM,UAAU,YAAY,CAC1B,IAAc,EACd,WAA8B;IAE9B,MAAM,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC;IACjC,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,OAAO,KAAK,OAAO,IAAI,MAAM,CAAC,iBAAiB,CAAC,KAAK,SAAS,EAAE,CAAC;QACnE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,kBAAkB,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IACvE,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,OAAO,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IAC/D,MAAM,YAAY,GAChB,OAAO,KAAK,SAAS;QACnB,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,MAAM,EAAE,WAAW,CAAC;QACjD,CAAC,CAAC,SAAS,CAAC;IAEhB,IACE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC;QAClC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC5B,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,EAC3B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IACD,IACE,YAAY,KAAK,SAAS;QAC1B,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAC1D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,YAAY,KAAK,SAAS;QAC/B,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE;QAChD,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QACxB,KAAK,CAAC,GAAG,EAAE,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAClC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAC/C,CAAC;IACF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IACE,OAAO,CAAC,MAAM,KAAK,CAAC;YACpB,OAAO,CAAC,IAAI,EAAE,KAAK,OAAO;YAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;YACrB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;YACrB,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC;YACrC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EACjB,CAAC;YACD,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,UAAU,CACjB,IAAc;IAEd,MAAM,MAAM,GAA4D,EAAE,CAAC;IAC3E,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAmC,CAAC;QAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC9B,IACE,CAAC,CAAC,IAAI,IAAI,iBAAiB,CAAC;YAC5B,KAAK,KAAK,SAAS;YACnB,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC,KAAK,SAAS,EAC1B,CAAC;YACD,MAAM,IAAI,KAAK,CACb,mEAAmE,CACpE,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,GAAG,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,OAAO,CACd,IAAoC,EACpC,MAA+D,EAC/D,WAA8B;IAE9B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;IACnE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,OAAO,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function isStableProjectTag(tag: string, family: string, project: string): boolean;
@@ -0,0 +1,8 @@
1
+ export function isStableProjectTag(tag, family, project) {
2
+ const parts = tag.split('/');
3
+ return (parts.length === 3 &&
4
+ parts[0] === family &&
5
+ parts[1] === project &&
6
+ /^\d+\.\d+\.\d+$/.test(parts[2] ?? ''));
7
+ }
8
+ //# sourceMappingURL=git-tags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-tags.js","sourceRoot":"","sources":["../../../../apps/workflow-cli/src/git-tags.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,kBAAkB,CAChC,GAAW,EACX,MAAc,EACd,OAAe;IAEf,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,CACL,KAAK,CAAC,MAAM,KAAK,CAAC;QAClB,KAAK,CAAC,CAAC,CAAC,KAAK,MAAM;QACnB,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO;QACpB,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CACvC,CAAC;AACJ,CAAC"}
package/src/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { parseCommand, parseProjectsFile } from './cli.js';
2
+ export { runWorkflow } from './workflow.js';
3
+ export type { WorkflowDependencies } from './workflow.js';
package/src/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { parseCommand, parseProjectsFile } from './cli.js';
2
+ export { runWorkflow } from './workflow.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../apps/workflow-cli/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
package/src/main.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/src/main.js ADDED
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+ import { execFile } from 'node:child_process';
3
+ import { readFile } from 'node:fs/promises';
4
+ import { createRequire } from 'node:module';
5
+ import { promisify } from 'node:util';
6
+ import { releaseChangelog, releasePublish, releaseVersion } from 'nx/release';
7
+ import { parseCommand } from './cli.js';
8
+ import { isStableProjectTag } from './git-tags.js';
9
+ import { isRequestedNxProject } from './project-shape.js';
10
+ import { runWorkflow } from './workflow.js';
11
+ const execute = promisify(execFile);
12
+ const require = createRequire(import.meta.url);
13
+ const nxCli = require.resolve('nx/bin/nx.js');
14
+ async function nxJson(arguments_) {
15
+ return JSON.parse(await command(process.execPath, [nxCli, ...arguments_]));
16
+ }
17
+ async function git(arguments_) {
18
+ return command('git', arguments_);
19
+ }
20
+ async function command(binary, arguments_) {
21
+ try {
22
+ const { stdout } = await execute(binary, arguments_, {
23
+ maxBuffer: 1024 * 1024,
24
+ });
25
+ return stdout.trim();
26
+ }
27
+ catch (error) {
28
+ const result = error;
29
+ const text = (value) => value?.toString().trim() || '(empty)';
30
+ throw new Error(`${binary} ${arguments_.join(' ')} failed (exit ${String(result.code)}). stdout: ${text(result.stdout)} stderr: ${text(result.stderr)}`, { cause: error });
31
+ }
32
+ }
33
+ const dependencies = {
34
+ async affectedProjects(baseSha, sourceSha) {
35
+ const result = await nxJson([
36
+ 'show',
37
+ 'projects',
38
+ '--affected',
39
+ `--base=${baseSha}`,
40
+ `--head=${sourceSha}`,
41
+ '--json',
42
+ ]);
43
+ if (!Array.isArray(result) ||
44
+ !result.every((project) => typeof project === 'string')) {
45
+ throw new Error('Nx returned an invalid affected-project response.');
46
+ }
47
+ return result;
48
+ },
49
+ async allProjects() {
50
+ const result = await nxJson(['show', 'projects', '--json']);
51
+ if (!Array.isArray(result) ||
52
+ !result.every((project) => typeof project === 'string')) {
53
+ throw new Error('Nx returned an invalid project response.');
54
+ }
55
+ return result;
56
+ },
57
+ async project(name) {
58
+ const result = await nxJson(['show', 'project', name, '--json']);
59
+ if (!isRequestedNxProject(result, name)) {
60
+ throw new Error(`Nx returned an invalid project response for ${name}.`);
61
+ }
62
+ return result;
63
+ },
64
+ async remoteHead(defaultBranch) {
65
+ const result = await git([
66
+ 'ls-remote',
67
+ '--exit-code',
68
+ 'origin',
69
+ `refs/heads/${defaultBranch}`,
70
+ ]);
71
+ const [head] = result.split(/\s+/);
72
+ if (!/^[0-9a-f]{40}$/i.test(head ?? '')) {
73
+ throw new Error(`origin/${defaultBranch} does not resolve to a commit.`);
74
+ }
75
+ return head;
76
+ },
77
+ head: () => git(['rev-parse', '--verify', 'HEAD^{commit}']),
78
+ readProjectsFile: (path) => readFile(path, 'utf8'),
79
+ async isInitialized(project, family) {
80
+ const tags = (await git(['tag', '--list'])).split('\n').filter(Boolean);
81
+ return tags.some((tag) => isStableProjectTag(tag, family, project));
82
+ },
83
+ release: {
84
+ version: releaseVersion,
85
+ changelog: releaseChangelog,
86
+ publish: releasePublish,
87
+ },
88
+ output: (line) => process.stdout.write(`${line}\n`),
89
+ };
90
+ try {
91
+ await runWorkflow(parseCommand(process.argv.slice(2), process.env), dependencies);
92
+ }
93
+ catch (error) {
94
+ const message = error instanceof Error ? error.message : String(error);
95
+ process.stderr.write(`workflow-cli: ${message}\n`);
96
+ process.exitCode = 1;
97
+ }
98
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../../../apps/workflow-cli/src/main.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAA6B,MAAM,eAAe,CAAC;AAEvE,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AACpC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;AAE9C,KAAK,UAAU,MAAM,CAAC,UAAoB;IACxC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,KAAK,UAAU,GAAG,CAAC,UAAoB;IACrC,OAAO,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,MAAc,EAAE,UAAoB;IACzD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE;YACnD,SAAS,EAAE,IAAI,GAAG,IAAI;SACvB,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,KAId,CAAC;QACF,MAAM,IAAI,GAAG,CAAC,KAAkC,EAAE,EAAE,CAClD,KAAK,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EACvI,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,YAAY,GAAyB;IACzC,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE,SAAS;QACvC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC;YAC1B,MAAM;YACN,UAAU;YACV,YAAY;YACZ,UAAU,OAAO,EAAE;YACnB,UAAU,SAAS,EAAE;YACrB,QAAQ;SACT,CAAC,CAAC;QACH,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YACtB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,EACvD,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,KAAK,CAAC,WAAW;QACf,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC5D,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YACtB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,EACvD,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,IAAI;QAChB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,+CAA+C,IAAI,GAAG,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,aAAa;QAC5B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;YACvB,WAAW;YACX,aAAa;YACb,QAAQ;YACR,cAAc,aAAa,EAAE;SAC9B,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,UAAU,aAAa,gCAAgC,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;IAC3D,gBAAgB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAClD,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM;QACjC,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxE,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,EAAE;QACP,OAAO,EACL,cAAuE;QACzE,SAAS,EACP,gBAA2E;QAC7E,OAAO,EACL,cAAuE;KAC1E;IACD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC;CACpD,CAAC;AAEF,IAAI,CAAC;IACH,MAAM,WAAW,CACf,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAChD,YAAY,CACb,CAAC;AACJ,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,OAAO,IAAI,CAAC,CAAC;IACnD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1,11 @@
1
+ export type NxShowProject = {
2
+ name: string;
3
+ targets?: Record<string, unknown>;
4
+ tags?: string[];
5
+ metadata?: {
6
+ js?: {
7
+ packageVersion?: string;
8
+ };
9
+ };
10
+ };
11
+ export declare function isRequestedNxProject(value: unknown, requestedName: string): value is NxShowProject;
@@ -0,0 +1,21 @@
1
+ export function isRequestedNxProject(value, requestedName) {
2
+ if (!isRecord(value) || value.name !== requestedName)
3
+ return false;
4
+ if (value.targets !== undefined && !isRecord(value.targets))
5
+ return false;
6
+ if (value.tags !== undefined &&
7
+ (!Array.isArray(value.tags) ||
8
+ !value.tags.every((tag) => typeof tag === 'string')))
9
+ return false;
10
+ if (value.metadata !== undefined && !isRecord(value.metadata))
11
+ return false;
12
+ const js = isRecord(value.metadata) ? value.metadata.js : undefined;
13
+ return (js === undefined ||
14
+ (isRecord(js) &&
15
+ (js.packageVersion === undefined ||
16
+ typeof js.packageVersion === 'string')));
17
+ }
18
+ function isRecord(value) {
19
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
20
+ }
21
+ //# sourceMappingURL=project-shape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-shape.js","sourceRoot":"","sources":["../../../../apps/workflow-cli/src/project-shape.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,oBAAoB,CAClC,KAAc,EACd,aAAqB;IAErB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa;QAAE,OAAO,KAAK,CAAC;IACnE,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1E,IACE,KAAK,CAAC,IAAI,KAAK,SAAS;QACxB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;YACzB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC;QAEtD,OAAO,KAAK,CAAC;IACf,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5E,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,OAAO,CACL,EAAE,KAAK,SAAS;QAChB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACX,CAAC,EAAE,CAAC,cAAc,KAAK,SAAS;gBAC9B,OAAO,EAAE,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAC5C,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { type CommandInput } from './cli.js';
2
+ type ArtifactFamily = 'docker' | 'helm' | 'npm';
3
+ type Project = {
4
+ name: string;
5
+ targets?: Record<string, unknown>;
6
+ tags?: string[];
7
+ metadata?: {
8
+ js?: {
9
+ packageVersion?: string;
10
+ };
11
+ };
12
+ };
13
+ type VersionData = Record<string, {
14
+ newVersion: string | null;
15
+ }>;
16
+ type VersionResult = {
17
+ projectsVersionData: VersionData;
18
+ releaseGraph: unknown;
19
+ };
20
+ type PublishResult = Record<string, {
21
+ code: number;
22
+ }>;
23
+ type ReleaseOptions = {
24
+ projects: string[];
25
+ specifier?: string;
26
+ preid?: string;
27
+ firstRelease?: boolean;
28
+ stageChanges?: boolean;
29
+ gitCommit?: boolean;
30
+ gitTag?: boolean;
31
+ gitPush?: boolean;
32
+ gitCommitArgs?: string[];
33
+ versionData?: VersionData;
34
+ releaseGraph?: unknown;
35
+ };
36
+ export type WorkflowDependencies = {
37
+ affectedProjects(baseSha: string, sourceSha: string): Promise<string[]>;
38
+ allProjects(): Promise<string[]>;
39
+ project(name: string): Promise<Project>;
40
+ remoteHead(defaultBranch: string): Promise<string>;
41
+ head(): Promise<string>;
42
+ readProjectsFile(path: string): Promise<string>;
43
+ isInitialized(project: string, family: ArtifactFamily): Promise<boolean>;
44
+ release: {
45
+ version(options: ReleaseOptions): Promise<VersionResult>;
46
+ changelog(options: ReleaseOptions): Promise<unknown>;
47
+ publish(options: ReleaseOptions): Promise<PublishResult>;
48
+ };
49
+ output(line: string): void;
50
+ };
51
+ export declare function runWorkflow(input: CommandInput, dependencies: WorkflowDependencies): Promise<void>;
52
+ export {};
@@ -0,0 +1,138 @@
1
+ import { parseProjectsFile } from './cli.js';
2
+ export async function runWorkflow(input, dependencies) {
3
+ if (input.command === 'stage') {
4
+ const affected = await dependencies.affectedProjects(input.baseSha, input.sourceSha);
5
+ const projects = await releaseable(affected, dependencies);
6
+ if (projects.length === 0) {
7
+ dependencies.output('stage: no publishable affected projects');
8
+ return;
9
+ }
10
+ await runStagingTransaction(projects.map((project) => project.name), input, dependencies);
11
+ return;
12
+ }
13
+ const requested = parseProjectsFile(await dependencies.readProjectsFile(input.projectsFile ?? ''));
14
+ const knownProjects = new Set(await dependencies.allProjects());
15
+ for (const project of requested) {
16
+ if (!knownProjects.has(project)) {
17
+ throw new Error(`Unknown Nx project: ${project}.`);
18
+ }
19
+ }
20
+ const projects = await releaseable(requested, dependencies);
21
+ if (projects.length !== requested.length) {
22
+ throw new Error('Every selected project must expose the nx-release-publish capability.');
23
+ }
24
+ const initialized = [];
25
+ const firstRelease = [];
26
+ for (const project of projects) {
27
+ ((await dependencies.isInitialized(project.name, artifactFamily(project)))
28
+ ? initialized
29
+ : firstRelease).push(project);
30
+ }
31
+ let expectedHead = input.sourceSha;
32
+ for (const project of firstRelease) {
33
+ expectedHead = await runStableTransaction([project.name], true, firstReleaseBaseline(project), input.defaultBranch, expectedHead, dependencies);
34
+ }
35
+ if (initialized.length > 0) {
36
+ await runStableTransaction(initialized.map((project) => project.name), false, undefined, input.defaultBranch, expectedHead, dependencies);
37
+ }
38
+ }
39
+ async function releaseable(projects, dependencies) {
40
+ const inspected = await Promise.all(projects.map(async (name) => dependencies.project(name)));
41
+ return inspected.filter((project) => project.targets?.['nx-release-publish'] !== undefined);
42
+ }
43
+ async function runStagingTransaction(projects, input, dependencies) {
44
+ await ensureCurrentSource(input.defaultBranch, input.sourceSha, dependencies);
45
+ const versioned = await dependencies.release.version({
46
+ projects,
47
+ preid: 'staging',
48
+ stageChanges: true,
49
+ gitCommit: true,
50
+ gitTag: true,
51
+ gitPush: true,
52
+ });
53
+ if (!hasVersionChanges(versioned.projectsVersionData, projects)) {
54
+ dependencies.output('stage: no releasable changes');
55
+ return;
56
+ }
57
+ await publish(projects, versioned, false, dependencies);
58
+ dependencies.output(`stage: published ${projects.join(',')}`);
59
+ }
60
+ async function runStableTransaction(projects, firstRelease, specifier, defaultBranch, expectedHead, dependencies) {
61
+ await ensureCurrentSource(defaultBranch, expectedHead, dependencies);
62
+ const versioned = await dependencies.release.version({
63
+ projects,
64
+ firstRelease,
65
+ specifier,
66
+ stageChanges: true,
67
+ gitCommit: false,
68
+ gitTag: false,
69
+ gitPush: false,
70
+ });
71
+ if (!hasVersionChanges(versioned.projectsVersionData, projects)) {
72
+ dependencies.output(`release: no releasable changes for ${projects.join(',')}`);
73
+ return expectedHead;
74
+ }
75
+ await dependencies.release.changelog({
76
+ projects,
77
+ firstRelease,
78
+ versionData: versioned.projectsVersionData,
79
+ releaseGraph: versioned.releaseGraph,
80
+ gitCommit: true,
81
+ gitTag: true,
82
+ gitPush: true,
83
+ });
84
+ const nextHead = await dependencies.head();
85
+ await publish(projects, versioned, firstRelease, dependencies);
86
+ dependencies.output(`release: published ${projects.join(',')}`);
87
+ return nextHead;
88
+ }
89
+ function artifactFamily(project) {
90
+ const artifactTags = project.tags?.filter((tag) => tag.startsWith('artifact:')) ?? [];
91
+ if (artifactTags.length !== 1) {
92
+ throw new Error(`Project ${project.name} must have exactly one artifact identity.`);
93
+ }
94
+ switch (artifactTags[0]) {
95
+ case 'artifact:oci-image':
96
+ return 'docker';
97
+ case 'artifact:oci-chart':
98
+ return 'helm';
99
+ case 'artifact:npm':
100
+ return 'npm';
101
+ default:
102
+ throw new Error(`Project ${project.name} has an unsupported artifact identity.`);
103
+ }
104
+ }
105
+ function firstReleaseBaseline(project) {
106
+ const baseline = project.metadata?.js?.packageVersion;
107
+ if (!baseline ||
108
+ !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/.test(baseline)) {
109
+ throw new Error(`First release project ${project.name} is missing a valid Nx package version baseline.`);
110
+ }
111
+ return baseline;
112
+ }
113
+ async function ensureCurrentSource(defaultBranch, expectedHead, dependencies) {
114
+ const [remoteHead, checkoutHead] = await Promise.all([
115
+ dependencies.remoteHead(defaultBranch),
116
+ dependencies.head(),
117
+ ]);
118
+ if (remoteHead !== expectedHead || checkoutHead !== expectedHead) {
119
+ throw new Error(`Stale release source: expected ${expectedHead}.`);
120
+ }
121
+ }
122
+ function hasVersionChanges(versionData, projects) {
123
+ return projects.some((project) => versionData[project]?.newVersion !== null &&
124
+ versionData[project]?.newVersion !== undefined);
125
+ }
126
+ async function publish(projects, versioned, firstRelease, dependencies) {
127
+ const results = await dependencies.release.publish({
128
+ projects,
129
+ firstRelease,
130
+ versionData: versioned.projectsVersionData,
131
+ releaseGraph: versioned.releaseGraph,
132
+ });
133
+ const failed = projects.filter((project) => results[project]?.code !== 0);
134
+ if (failed.length > 0) {
135
+ throw new Error(`incomplete publication: ${failed.join(',')}. Recover only by publishing from the exact Nx release tag.`);
136
+ }
137
+ }
138
+ //# sourceMappingURL=workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../../../apps/workflow-cli/src/workflow.ts"],"names":[],"mappings":"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"}