create-nx-workspace 22.6.1 → 22.6.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/bin/create-nx-workspace.d.ts.map +1 -1
- package/bin/create-nx-workspace.js +6 -5
- package/package.json +2 -1
- package/src/create-workspace.d.ts +2 -0
- package/src/create-workspace.d.ts.map +1 -1
- package/src/create-workspace.js +35 -2
- package/src/internal-utils/prompts.js +1 -1
- package/src/utils/child-process-utils.d.ts +2 -2
- package/src/utils/child-process-utils.d.ts.map +1 -1
- package/src/utils/child-process-utils.js +18 -3
- package/src/utils/git/git.d.ts +4 -4
- package/src/utils/git/git.d.ts.map +1 -1
- package/src/utils/git/git.js +77 -40
- package/src/utils/nx/ab-testing.d.ts +0 -1
- package/src/utils/nx/ab-testing.d.ts.map +1 -1
- package/src/utils/nx/ab-testing.js +31 -8
- package/src/utils/nx/nx-cloud.d.ts +1 -0
- package/src/utils/nx/nx-cloud.d.ts.map +1 -1
- package/src/utils/nx/nx-cloud.js +14 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-nx-workspace.d.ts","sourceRoot":"","sources":["../../../../packages/create-nx-workspace/bin/create-nx-workspace.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"create-nx-workspace.d.ts","sourceRoot":"","sources":["../../../../packages/create-nx-workspace/bin/create-nx-workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -169,13 +169,13 @@ exports.commandsObject = yargs
|
|
|
169
169
|
if ((0, ai_output_1.isAiAgent)()) {
|
|
170
170
|
exports.commandsObject
|
|
171
171
|
.example(chalk.green('AI AGENTS (RECOMMENDED):'), '')
|
|
172
|
-
.example(' npx create-nx-workspace@latest myorg --template=
|
|
172
|
+
.example(' npx create-nx-workspace@latest myorg --template=empty --nxCloud=yes --interactive=false', '')
|
|
173
173
|
.example('', '')
|
|
174
174
|
.example(chalk.green('AVAILABLE TEMPLATES:'), '')
|
|
175
|
-
.example(' --template=
|
|
176
|
-
.example(' --template=
|
|
177
|
-
.example(' --template=
|
|
178
|
-
.example(' --template=
|
|
175
|
+
.example(' --template=empty Empty monorepo', '')
|
|
176
|
+
.example(' --template=react React fullstack', '')
|
|
177
|
+
.example(' --template=angular Angular fullstack', '')
|
|
178
|
+
.example(' --template=typescript NPM packages', '')
|
|
179
179
|
.epilogue(`${chalk.cyan('AI Agent Mode:')}
|
|
180
180
|
Set CLAUDECODE=1 or OPENCODE=1 for JSON output and non-interactive mode.
|
|
181
181
|
In AI mode: auto non-interactive, NDJSON progress output, structured results.
|
|
@@ -252,6 +252,7 @@ async function main(parsedArgs) {
|
|
|
252
252
|
nxCloudArg: parsedArgs.nxCloud ?? '',
|
|
253
253
|
nxCloudArgRaw: rawArgs.nxCloud ?? '',
|
|
254
254
|
pushedToVcs: workspaceInfo.pushedToVcs ?? '',
|
|
255
|
+
pushFailReason: workspaceInfo.pushFailReason ?? '',
|
|
255
256
|
template: chosenTemplate ?? '',
|
|
256
257
|
preset: chosenPreset ?? '',
|
|
257
258
|
connectUrl: workspaceInfo.connectUrl ?? '',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-nx-workspace",
|
|
3
|
-
"version": "22.6.
|
|
3
|
+
"version": "22.6.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Smart Monorepos · Fast Builds",
|
|
6
6
|
"repository": {
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"chalk": "^4.1.0",
|
|
35
35
|
"enquirer": "~2.3.6",
|
|
36
36
|
"flat": "^5.0.2",
|
|
37
|
+
"open": "^8.4.0",
|
|
37
38
|
"ora": "5.3.0",
|
|
38
39
|
"tmp": "~0.2.1",
|
|
39
40
|
"tslib": "^2.3.0",
|
|
@@ -8,7 +8,9 @@ export declare function createWorkspace<T extends CreateWorkspaceOptions>(preset
|
|
|
8
8
|
nxCloudInfo: string;
|
|
9
9
|
directory: string;
|
|
10
10
|
pushedToVcs: VcsPushStatus;
|
|
11
|
+
pushFailReason: string;
|
|
11
12
|
connectUrl: string;
|
|
12
13
|
}>;
|
|
13
14
|
export declare function extractConnectUrl(text: string): string | null;
|
|
15
|
+
export declare function resolveTemplateShorthand(template: string): string;
|
|
14
16
|
//# sourceMappingURL=create-workspace.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-workspace.d.ts","sourceRoot":"","sources":["../../../../packages/create-nx-workspace/src/create-workspace.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,
|
|
1
|
+
{"version":3,"file":"create-workspace.d.ts","sourceRoot":"","sources":["../../../../packages/create-nx-workspace/src/create-workspace.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAIL,aAAa,EACd,MAAM,iBAAiB,CAAC;AA6BzB,wBAAgB,4BAA4B,IAAI;IAC9C,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,CAEA;AAED,wBAAsB,eAAe,CAAC,CAAC,SAAS,sBAAsB,EACpE,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,CAAC,EACV,OAAO,CAAC,EAAE,CAAC;;;;;;GA4RZ;AAUD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI7D;AASD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEjE"}
|
package/src/create-workspace.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getInterruptedWorkspaceState = getInterruptedWorkspaceState;
|
|
4
4
|
exports.createWorkspace = createWorkspace;
|
|
5
5
|
exports.extractConnectUrl = extractConnectUrl;
|
|
6
|
+
exports.resolveTemplateShorthand = resolveTemplateShorthand;
|
|
6
7
|
const node_fs_1 = require("node:fs");
|
|
7
8
|
const path_1 = require("path");
|
|
8
9
|
const create_empty_workspace_1 = require("./create-empty-workspace");
|
|
@@ -33,6 +34,8 @@ async function createWorkspace(preset, options, rawArgs) {
|
|
|
33
34
|
}
|
|
34
35
|
let directory;
|
|
35
36
|
if (options.template) {
|
|
37
|
+
// Resolve shorthand template names to full GitHub org/repo format
|
|
38
|
+
options.template = resolveTemplateShorthand(options.template);
|
|
36
39
|
if (!options.template.startsWith('nrwl/'))
|
|
37
40
|
throw new Error(`Invalid template. Only templates from the 'nrwl' GitHub org are supported.`);
|
|
38
41
|
const templateUrl = `https://github.com/${options.template}`;
|
|
@@ -131,6 +134,7 @@ async function createWorkspace(preset, options, rawArgs) {
|
|
|
131
134
|
await (0, setup_ci_1.setupCI)(directory, ciProvider, packageManager);
|
|
132
135
|
}
|
|
133
136
|
let pushedToVcs = git_1.VcsPushStatus.SkippedGit;
|
|
137
|
+
let pushFailReason;
|
|
134
138
|
if (!skipGit) {
|
|
135
139
|
const aiMode = (0, ai_output_1.isAiAgent)();
|
|
136
140
|
if (aiMode) {
|
|
@@ -153,14 +157,29 @@ async function createWorkspace(preset, options, rawArgs) {
|
|
|
153
157
|
}
|
|
154
158
|
}
|
|
155
159
|
catch (e) {
|
|
156
|
-
if (e instanceof
|
|
160
|
+
if (e instanceof git_1.GitHubPushError) {
|
|
161
|
+
// GitHub push issues are never fatal — CNW always succeeds.
|
|
162
|
+
// All reasons are logged in telemetry via pushFailReason.
|
|
163
|
+
pushedToVcs = git_1.VcsPushStatus.FailedToPushToVcs;
|
|
164
|
+
pushFailReason = e.reason;
|
|
165
|
+
// Only show the push hint when the user actually attempted a push
|
|
166
|
+
// and it failed. Pre-push issues (gh not installed, auth failed,
|
|
167
|
+
// timed out during auth) are silent — no point telling the user
|
|
168
|
+
// about a push they never asked for.
|
|
169
|
+
if (e.reason === 'push-failed' || e.reason === 'push-timeout') {
|
|
170
|
+
const githubNewUrl = `https://github.com/new?name=${encodeURIComponent(name)}`;
|
|
171
|
+
output_1.output.log({
|
|
172
|
+
title: `Push your repo to GitHub: ${githubNewUrl}`,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
else if (e instanceof Error) {
|
|
157
177
|
if (!aiMode) {
|
|
158
178
|
output_1.output.error({
|
|
159
179
|
title: 'Could not initialize git repository',
|
|
160
180
|
bodyLines: (0, error_utils_1.mapErrorToBodyLines)(e),
|
|
161
181
|
});
|
|
162
182
|
}
|
|
163
|
-
// In AI mode, error will be handled by the caller
|
|
164
183
|
}
|
|
165
184
|
else {
|
|
166
185
|
console.error(e);
|
|
@@ -194,6 +213,10 @@ async function createWorkspace(preset, options, rawArgs) {
|
|
|
194
213
|
}
|
|
195
214
|
}
|
|
196
215
|
nxCloudInfo = await (0, nx_cloud_1.getNxCloudInfo)(connectUrl, pushedToVcs, options.completionMessageKey, name);
|
|
216
|
+
// Auto-open the Cloud setup URL in the browser when user selected 'yes'
|
|
217
|
+
if (!options.skipCloudConnect) {
|
|
218
|
+
await (0, nx_cloud_1.openCloudSetupUrl)(connectUrl);
|
|
219
|
+
}
|
|
197
220
|
}
|
|
198
221
|
else if (isTemplate && (nxCloud === 'skip' || nxCloud === 'never')) {
|
|
199
222
|
// Strip marker comments from README
|
|
@@ -211,6 +234,7 @@ async function createWorkspace(preset, options, rawArgs) {
|
|
|
211
234
|
nxCloudInfo,
|
|
212
235
|
directory,
|
|
213
236
|
pushedToVcs,
|
|
237
|
+
pushFailReason,
|
|
214
238
|
connectUrl,
|
|
215
239
|
};
|
|
216
240
|
}
|
|
@@ -226,6 +250,15 @@ function extractConnectUrl(text) {
|
|
|
226
250
|
const match = text.match(urlPattern);
|
|
227
251
|
return match ? match[0] : null;
|
|
228
252
|
}
|
|
253
|
+
const templateShorthands = {
|
|
254
|
+
angular: 'nrwl/angular-template',
|
|
255
|
+
react: 'nrwl/react-template',
|
|
256
|
+
typescript: 'nrwl/typescript-template',
|
|
257
|
+
empty: 'nrwl/empty-template',
|
|
258
|
+
};
|
|
259
|
+
function resolveTemplateShorthand(template) {
|
|
260
|
+
return templateShorthands[template] ?? template;
|
|
261
|
+
}
|
|
229
262
|
function getWorkspaceGlobsFromPreset(preset) {
|
|
230
263
|
// Should match how apps are created in `packages/workspace/src/generators/preset/preset.ts`.
|
|
231
264
|
switch (preset) {
|
|
@@ -95,7 +95,7 @@ async function determineTemplate(parsedArgs) {
|
|
|
95
95
|
if (parsedArgs.preset)
|
|
96
96
|
return 'custom';
|
|
97
97
|
if (!parsedArgs.interactive || (0, is_ci_1.isCI)())
|
|
98
|
-
return '
|
|
98
|
+
return 'nrwl/empty-template';
|
|
99
99
|
// Docs generation needs preset flow to document all presets
|
|
100
100
|
if (process.env.NX_GENERATE_DOCS_PROCESS === 'true')
|
|
101
101
|
return 'custom';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Use spawn only for interactive shells
|
|
3
3
|
*/
|
|
4
|
-
export declare function spawnAndWait(command: string, args: string[], cwd: string): Promise<unknown>;
|
|
5
|
-
export declare function execAndWait(command: string, cwd: string, silenceErrors?: boolean): Promise<{
|
|
4
|
+
export declare function spawnAndWait(command: string, args: string[], cwd: string, timeout?: number): Promise<unknown>;
|
|
5
|
+
export declare function execAndWait(command: string, cwd: string, silenceErrors?: boolean, timeout?: number): Promise<{
|
|
6
6
|
code: number;
|
|
7
7
|
stdout: string;
|
|
8
8
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"child-process-utils.d.ts","sourceRoot":"","sources":["../../../../../packages/create-nx-workspace/src/utils/child-process-utils.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAgB,YAAY,
|
|
1
|
+
{"version":3,"file":"child-process-utils.d.ts","sourceRoot":"","sources":["../../../../../packages/create-nx-workspace/src/utils/child-process-utils.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,oBA8CjB;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,aAAa,UAAQ,EACrB,OAAO,CAAC,EAAE,MAAM;UAEW,MAAM;YAAU,MAAM;GAiClD"}
|
|
@@ -9,7 +9,7 @@ const error_utils_1 = require("./error-utils");
|
|
|
9
9
|
/**
|
|
10
10
|
* Use spawn only for interactive shells
|
|
11
11
|
*/
|
|
12
|
-
function spawnAndWait(command, args, cwd) {
|
|
12
|
+
function spawnAndWait(command, args, cwd, timeout) {
|
|
13
13
|
return new Promise((res, rej) => {
|
|
14
14
|
// Combine command and args into a single string to avoid DEP0190 warning
|
|
15
15
|
// (passing args with shell: true is deprecated)
|
|
@@ -29,7 +29,21 @@ function spawnAndWait(command, args, cwd) {
|
|
|
29
29
|
shell: true,
|
|
30
30
|
windowsHide: true,
|
|
31
31
|
});
|
|
32
|
+
let timedOut = false;
|
|
33
|
+
let timer;
|
|
34
|
+
if (timeout) {
|
|
35
|
+
timer = setTimeout(() => {
|
|
36
|
+
timedOut = true;
|
|
37
|
+
childProcess.kill('SIGTERM');
|
|
38
|
+
}, timeout);
|
|
39
|
+
}
|
|
32
40
|
childProcess.on('exit', (code, signal) => {
|
|
41
|
+
if (timer)
|
|
42
|
+
clearTimeout(timer);
|
|
43
|
+
if (timedOut) {
|
|
44
|
+
rej({ code: 1, timedOut: true });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
33
47
|
if (code === null)
|
|
34
48
|
code = signalToCode(signal);
|
|
35
49
|
if (code !== 0) {
|
|
@@ -41,17 +55,18 @@ function spawnAndWait(command, args, cwd) {
|
|
|
41
55
|
});
|
|
42
56
|
});
|
|
43
57
|
}
|
|
44
|
-
function execAndWait(command, cwd, silenceErrors = false) {
|
|
58
|
+
function execAndWait(command, cwd, silenceErrors = false, timeout) {
|
|
45
59
|
return new Promise((res, rej) => {
|
|
46
60
|
(0, child_process_1.exec)(command, {
|
|
47
61
|
cwd,
|
|
48
62
|
env: { ...process.env, NX_DAEMON: 'false' },
|
|
49
63
|
windowsHide: true,
|
|
50
64
|
maxBuffer: 1024 * 1024 * 10, // 10MB — default 1MB can be exceeded by verbose PM output
|
|
65
|
+
...(timeout ? { timeout } : {}),
|
|
51
66
|
}, (error, stdout, stderr) => {
|
|
52
67
|
if (error) {
|
|
53
68
|
if (silenceErrors) {
|
|
54
|
-
rej();
|
|
69
|
+
rej(error.killed ? { timedOut: true } : undefined);
|
|
55
70
|
}
|
|
56
71
|
else {
|
|
57
72
|
const logFile = (0, path_1.join)(cwd, 'error.log');
|
package/src/utils/git/git.d.ts
CHANGED
|
@@ -4,9 +4,9 @@ export declare enum VcsPushStatus {
|
|
|
4
4
|
FailedToPushToVcs = "FailedToPushToVcs",
|
|
5
5
|
SkippedGit = "SkippedGit"
|
|
6
6
|
}
|
|
7
|
-
export declare class
|
|
8
|
-
readonly
|
|
9
|
-
constructor(message: string);
|
|
7
|
+
export declare class GitHubPushError extends Error {
|
|
8
|
+
readonly reason: 'gh-not-installed' | 'gh-auth-failed' | 'push-timeout' | 'push-failed' | 'env-skip';
|
|
9
|
+
constructor(message: string, reason: 'gh-not-installed' | 'gh-auth-failed' | 'push-timeout' | 'push-failed' | 'env-skip');
|
|
10
10
|
}
|
|
11
11
|
export declare function checkGitVersion(): Promise<string | null | undefined>;
|
|
12
12
|
/**
|
|
@@ -16,7 +16,7 @@ export declare function checkGitVersion(): Promise<string | null | undefined>;
|
|
|
16
16
|
export declare function isGitAvailable(): boolean;
|
|
17
17
|
/**
|
|
18
18
|
* Synchronously checks if GitHub CLI (gh) is available on the system.
|
|
19
|
-
* Returns true if gh command can be executed, false otherwise.
|
|
19
|
+
* Returns true if gh command can be executed within 2 seconds, false otherwise.
|
|
20
20
|
*/
|
|
21
21
|
export declare function isGhCliAvailable(): boolean;
|
|
22
22
|
export declare function initializeGitRepo(directory: string, options: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/git/git.ts"],"names":[],"mappings":"AAMA,oBAAY,aAAa;IACvB,WAAW,gBAAgB;IAC3B,sBAAsB,2BAA2B;IACjD,iBAAiB,sBAAsB;IACvC,UAAU,eAAe;CAC1B;AAED,qBAAa,
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/git/git.ts"],"names":[],"mappings":"AAMA,oBAAY,aAAa;IACvB,WAAW,gBAAgB;IAC3B,sBAAsB,2BAA2B;IACjD,iBAAiB,sBAAsB;IACvC,UAAU,eAAe;CAC1B;AAED,qBAAa,eAAgB,SAAQ,KAAK;aAGtB,MAAM,EAClB,kBAAkB,GAClB,gBAAgB,GAChB,cAAc,GACd,aAAa,GACb,UAAU;gBANd,OAAO,EAAE,MAAM,EACC,MAAM,EAClB,kBAAkB,GAClB,gBAAgB,GAChB,cAAc,GACd,aAAa,GACb,UAAU;CAKjB;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAQ1E;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAOxC;AAYD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAW1C;AA0FD,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IACP,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,iBAsDF;AAED,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IACP,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GACA,OAAO,CAAC,aAAa,CAAC,CAkHxB"}
|
package/src/utils/git/git.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.GitHubPushError = exports.VcsPushStatus = void 0;
|
|
4
4
|
exports.checkGitVersion = checkGitVersion;
|
|
5
5
|
exports.isGitAvailable = isGitAvailable;
|
|
6
6
|
exports.isGhCliAvailable = isGhCliAvailable;
|
|
@@ -18,14 +18,14 @@ var VcsPushStatus;
|
|
|
18
18
|
VcsPushStatus["FailedToPushToVcs"] = "FailedToPushToVcs";
|
|
19
19
|
VcsPushStatus["SkippedGit"] = "SkippedGit";
|
|
20
20
|
})(VcsPushStatus || (exports.VcsPushStatus = VcsPushStatus = {}));
|
|
21
|
-
class
|
|
22
|
-
constructor(message) {
|
|
21
|
+
class GitHubPushError extends Error {
|
|
22
|
+
constructor(message, reason) {
|
|
23
23
|
super(message);
|
|
24
|
-
this.
|
|
25
|
-
this.name = '
|
|
24
|
+
this.reason = reason;
|
|
25
|
+
this.name = 'GitHubPushError';
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
exports.
|
|
28
|
+
exports.GitHubPushError = GitHubPushError;
|
|
29
29
|
async function checkGitVersion() {
|
|
30
30
|
try {
|
|
31
31
|
const result = await (0, child_process_utils_1.execAndWait)('git --version', process.cwd());
|
|
@@ -49,13 +49,26 @@ function isGitAvailable() {
|
|
|
49
49
|
return false;
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
+
// 1 second timeout for gh CLI pre-flight checks (version, auth). If gh is
|
|
53
|
+
// wrapped by 1Password, a credential manager, or corporate SSO the call can
|
|
54
|
+
// hang indefinitely. Better to skip the push than freeze the CLI.
|
|
55
|
+
const GH_CLI_TIMEOUT_MS = 1_000;
|
|
56
|
+
// 10 second timeout for repo listing (runs in background while user answers prompts).
|
|
57
|
+
const GH_LIST_TIMEOUT_MS = 10_000;
|
|
58
|
+
// 30 second timeout for the actual repo create + push operation.
|
|
59
|
+
// Longer than other gh commands to account for slow networks.
|
|
60
|
+
const GH_PUSH_TIMEOUT_MS = 30_000;
|
|
52
61
|
/**
|
|
53
62
|
* Synchronously checks if GitHub CLI (gh) is available on the system.
|
|
54
|
-
* Returns true if gh command can be executed, false otherwise.
|
|
63
|
+
* Returns true if gh command can be executed within 2 seconds, false otherwise.
|
|
55
64
|
*/
|
|
56
65
|
function isGhCliAvailable() {
|
|
57
66
|
try {
|
|
58
|
-
(0, child_process_1.execSync)('gh --version', {
|
|
67
|
+
(0, child_process_1.execSync)('gh --version', {
|
|
68
|
+
stdio: 'ignore',
|
|
69
|
+
windowsHide: true,
|
|
70
|
+
timeout: GH_CLI_TIMEOUT_MS,
|
|
71
|
+
});
|
|
59
72
|
return true;
|
|
60
73
|
}
|
|
61
74
|
catch {
|
|
@@ -63,12 +76,16 @@ function isGhCliAvailable() {
|
|
|
63
76
|
}
|
|
64
77
|
}
|
|
65
78
|
async function getGitHubUsername(directory) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
79
|
+
try {
|
|
80
|
+
const result = await (0, child_process_utils_1.execAndWait)('gh api user --jq .login', directory, true, // silenceErrors — gh failures should never write error.log (#34482)
|
|
81
|
+
GH_CLI_TIMEOUT_MS);
|
|
82
|
+
return result.stdout.trim() || null;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// gh is optional — auth failures, timeouts, or missing credentials
|
|
86
|
+
// are silently ignored. The push flow will be skipped.
|
|
87
|
+
return null;
|
|
70
88
|
}
|
|
71
|
-
return username;
|
|
72
89
|
}
|
|
73
90
|
// Module-level promise for background repo fetching
|
|
74
91
|
let existingReposPromise;
|
|
@@ -81,8 +98,9 @@ async function getUserRepositories(directory) {
|
|
|
81
98
|
// Get user's personal repos and organizations concurrently
|
|
82
99
|
// Limit to 100 repos for faster response (covers most use cases)
|
|
83
100
|
const [userRepos, orgsResult] = await Promise.all([
|
|
84
|
-
(0, child_process_utils_1.execAndWait)('gh repo list --limit 100 --json nameWithOwner --jq ".[].nameWithOwner"', directory
|
|
85
|
-
|
|
101
|
+
(0, child_process_utils_1.execAndWait)('gh repo list --limit 100 --json nameWithOwner --jq ".[].nameWithOwner"', directory, true, // silenceErrors — gh failures should never write error.log
|
|
102
|
+
GH_LIST_TIMEOUT_MS),
|
|
103
|
+
(0, child_process_utils_1.execAndWait)('gh api user/orgs --jq ".[].login"', directory, true, GH_LIST_TIMEOUT_MS),
|
|
86
104
|
]);
|
|
87
105
|
// Add user's personal repos
|
|
88
106
|
userRepos.stdout
|
|
@@ -98,7 +116,8 @@ async function getUserRepositories(directory) {
|
|
|
98
116
|
// Get repos from all organizations concurrently
|
|
99
117
|
const orgRepoPromises = orgs.map(async (org) => {
|
|
100
118
|
try {
|
|
101
|
-
const orgRepos = await (0, child_process_utils_1.execAndWait)(`gh repo list ${org} --limit 100 --json nameWithOwner --jq ".[].nameWithOwner"`, directory
|
|
119
|
+
const orgRepos = await (0, child_process_utils_1.execAndWait)(`gh repo list ${org} --limit 100 --json nameWithOwner --jq ".[].nameWithOwner"`, directory, true, // silenceErrors
|
|
120
|
+
GH_LIST_TIMEOUT_MS);
|
|
102
121
|
return orgRepos.stdout
|
|
103
122
|
.trim()
|
|
104
123
|
.split('\n')
|
|
@@ -166,13 +185,23 @@ ${options.connectUrl}
|
|
|
166
185
|
}
|
|
167
186
|
async function pushToGitHub(directory, options) {
|
|
168
187
|
try {
|
|
188
|
+
// Pre-flight gates — gh is optional, so any failure here throws
|
|
189
|
+
// GitHubPushError which the caller handles silently (no user output)
|
|
190
|
+
// while still recording the reason in telemetry.
|
|
169
191
|
if (process.env['NX_SKIP_GH_PUSH'] === 'true') {
|
|
170
|
-
throw new
|
|
192
|
+
throw new GitHubPushError('NX_SKIP_GH_PUSH is true', 'env-skip');
|
|
193
|
+
}
|
|
194
|
+
if (!isGhCliAvailable()) {
|
|
195
|
+
throw new GitHubPushError('gh CLI is not installed', 'gh-not-installed');
|
|
171
196
|
}
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
//
|
|
197
|
+
// Check gh authentication with a short timeout. If gh is wrapped by
|
|
198
|
+
// 1Password, a credential manager, or corporate SSO this call can hang
|
|
199
|
+
// indefinitely. A 2 s timeout catches that and skips the push gracefully
|
|
200
|
+
// instead of freezing the CLI.
|
|
175
201
|
const username = await getGitHubUsername(directory);
|
|
202
|
+
if (!username) {
|
|
203
|
+
throw new GitHubPushError('gh auth failed', 'gh-auth-failed');
|
|
204
|
+
}
|
|
176
205
|
// Start fetching existing repositories in the background immediately
|
|
177
206
|
// This runs while user is answering prompts, so validation is usually instant
|
|
178
207
|
populateExistingRepos(directory);
|
|
@@ -212,35 +241,43 @@ async function pushToGitHub(directory, options) {
|
|
|
212
241
|
},
|
|
213
242
|
},
|
|
214
243
|
]);
|
|
215
|
-
// Create GitHub repository using gh CLI
|
|
216
|
-
//
|
|
244
|
+
// Create GitHub repository and push using gh CLI.
|
|
245
|
+
// Uses execAndWait (not spawnAndWait) so output is captured rather than
|
|
246
|
+
// streamed to the terminal. This prevents git push output from bleeding
|
|
247
|
+
// into the terminal after CNW exits, and ensures the timeout properly
|
|
248
|
+
// kills the entire process tree.
|
|
217
249
|
output_1.output.log({
|
|
218
250
|
title: 'Creating GitHub repository and pushing (this may take a moment)...',
|
|
219
251
|
});
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
'create',
|
|
223
|
-
repoName,
|
|
224
|
-
'--private',
|
|
225
|
-
'--push',
|
|
226
|
-
'--source',
|
|
227
|
-
directory,
|
|
228
|
-
], directory);
|
|
252
|
+
const cmd = `gh repo create ${repoName} --private --push --source "${directory}"`;
|
|
253
|
+
await (0, child_process_utils_1.execAndWait)(cmd, directory, true, GH_PUSH_TIMEOUT_MS);
|
|
229
254
|
// Get the actual repository URL from GitHub CLI (it could be different from github.com)
|
|
230
|
-
|
|
231
|
-
|
|
255
|
+
let repoUrl = `https://github.com/${repoName}`;
|
|
256
|
+
try {
|
|
257
|
+
const repoResult = await (0, child_process_utils_1.execAndWait)('gh repo view --json url -q .url', directory, true, // silenceErrors
|
|
258
|
+
GH_CLI_TIMEOUT_MS);
|
|
259
|
+
if (repoResult.stdout.trim()) {
|
|
260
|
+
repoUrl = repoResult.stdout.trim();
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
// Fall back to constructed URL
|
|
265
|
+
}
|
|
232
266
|
output_1.output.success({
|
|
233
267
|
title: `Successfully pushed to GitHub repository: ${repoUrl}`,
|
|
234
268
|
});
|
|
235
269
|
return VcsPushStatus.PushedToVcs;
|
|
236
270
|
}
|
|
237
271
|
catch (e) {
|
|
238
|
-
//
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
272
|
+
// Re-throw GitHubPushError as-is (gh not installed, auth failed, env skip)
|
|
273
|
+
if (e instanceof GitHubPushError)
|
|
274
|
+
throw e;
|
|
275
|
+
// Wrap other failures (push timeout, push command failed) as GitHubPushError
|
|
276
|
+
const isTimedOut = e?.timedOut === true;
|
|
277
|
+
if (isTimedOut) {
|
|
278
|
+
throw new GitHubPushError('gh push timed out', 'push-timeout');
|
|
279
|
+
}
|
|
280
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
281
|
+
throw new GitHubPushError(msg.split('\n')[0].slice(0, 200), 'push-failed');
|
|
245
282
|
}
|
|
246
283
|
}
|
|
@@ -9,7 +9,6 @@ export declare function getFlowVariant(): string;
|
|
|
9
9
|
* Now locked to 'platform-setup' after concluding the prompt A/B test.
|
|
10
10
|
*/
|
|
11
11
|
export declare function getCompletionMessageKeyForVariant(): CompletionMessageKey;
|
|
12
|
-
export declare function shouldShowCloudPrompt(): boolean;
|
|
13
12
|
/**
|
|
14
13
|
* Check if the given cloud URL is an enterprise URL.
|
|
15
14
|
* Enterprise URLs are anything other than cloud.nx.app, eu.nx.app, staging.nx.app, or snapshot.nx.app.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ab-testing.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/nx/ab-testing.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ab-testing.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/nx/ab-testing.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.messages = exports.PromptMessages = exports.NxCloudChoices = void 0;
|
|
4
4
|
exports.getFlowVariant = getFlowVariant;
|
|
5
5
|
exports.getCompletionMessageKeyForVariant = getCompletionMessageKeyForVariant;
|
|
6
|
-
exports.shouldShowCloudPrompt = shouldShowCloudPrompt;
|
|
7
6
|
exports.isEnterpriseCloudUrl = isEnterpriseCloudUrl;
|
|
8
7
|
exports.getBannerVariant = getBannerVariant;
|
|
9
8
|
exports.recordStat = recordStat;
|
|
@@ -11,6 +10,7 @@ const node_child_process_1 = require("node:child_process");
|
|
|
11
10
|
const node_fs_1 = require("node:fs");
|
|
12
11
|
const node_path_1 = require("node:path");
|
|
13
12
|
const node_os_1 = require("node:os");
|
|
13
|
+
const chalk = require("chalk");
|
|
14
14
|
const is_ci_1 = require("../ci/is-ci");
|
|
15
15
|
// Flow variant controls both tracking and banner display (CLOUD-4235)
|
|
16
16
|
// Variants: 0 = control, 1 = updated prompt, 2 = no prompt (auto-connect)
|
|
@@ -91,11 +91,6 @@ function getFlowVariant() {
|
|
|
91
91
|
function getCompletionMessageKeyForVariant() {
|
|
92
92
|
return 'platform-setup';
|
|
93
93
|
}
|
|
94
|
-
function shouldShowCloudPrompt() {
|
|
95
|
-
// CLOUD-4255: Lock to variant 2 behavior (no prompt)
|
|
96
|
-
// To re-enable A/B testing: return getFlowVariant() !== '2';
|
|
97
|
-
return false;
|
|
98
|
-
}
|
|
99
94
|
// ============================================================================
|
|
100
95
|
// Banner Variant A/B Testing (CLOUD-4235)
|
|
101
96
|
// ============================================================================
|
|
@@ -205,12 +200,38 @@ const messageOptions = {
|
|
|
205
200
|
choices: [
|
|
206
201
|
{ value: 'yes', name: 'Yes' },
|
|
207
202
|
{ value: 'skip', name: 'Skip for now' },
|
|
208
|
-
{ value: 'never', name: "No, don't ask again" },
|
|
203
|
+
{ value: 'never', name: chalk.dim("No, don't ask again") },
|
|
209
204
|
],
|
|
210
205
|
footer: '\nAutomatically fix broken PRs, 70% faster CI: https://nx.dev/nx-cloud',
|
|
211
206
|
fallback: undefined,
|
|
212
207
|
completionMessage: 'platform-setup',
|
|
213
208
|
},
|
|
209
|
+
{
|
|
210
|
+
code: 'cloud-ab-remote-cache-speed',
|
|
211
|
+
message: 'Enable remote caching to speed up builds with Nx Cloud?',
|
|
212
|
+
initial: 0,
|
|
213
|
+
choices: [
|
|
214
|
+
{ value: 'yes', name: 'Yes' },
|
|
215
|
+
{ value: 'skip', name: 'Skip for now' },
|
|
216
|
+
{ value: 'never', name: chalk.dim("No, don't ask again") },
|
|
217
|
+
],
|
|
218
|
+
footer: '\nFree for small teams. 2-minute setup with GitHub — cache locally and in CI: https://nx.dev/nx-cloud',
|
|
219
|
+
fallback: undefined,
|
|
220
|
+
completionMessage: 'platform-setup',
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
code: 'cloud-ab-fast-ci-setup',
|
|
224
|
+
message: 'Speed up your CI with Nx Cloud?',
|
|
225
|
+
initial: 0,
|
|
226
|
+
choices: [
|
|
227
|
+
{ value: 'yes', name: 'Yes' },
|
|
228
|
+
{ value: 'skip', name: 'Skip for now' },
|
|
229
|
+
{ value: 'never', name: chalk.dim("No, don't ask again") },
|
|
230
|
+
],
|
|
231
|
+
footer: '\n70% faster CI on GitHub, GitLab, and more. Free tier, 2-minute setup: https://nx.dev/nx-cloud',
|
|
232
|
+
fallback: undefined,
|
|
233
|
+
completionMessage: 'platform-setup',
|
|
234
|
+
},
|
|
214
235
|
],
|
|
215
236
|
};
|
|
216
237
|
class PromptMessages {
|
|
@@ -223,7 +244,9 @@ class PromptMessages {
|
|
|
223
244
|
this.selectedMessages[key] = 0;
|
|
224
245
|
}
|
|
225
246
|
else {
|
|
226
|
-
|
|
247
|
+
const variant = Number(getFlowVariant());
|
|
248
|
+
this.selectedMessages[key] =
|
|
249
|
+
variant < messageOptions[key].length ? variant : 0;
|
|
227
250
|
}
|
|
228
251
|
}
|
|
229
252
|
return messageOptions[key][this.selectedMessages[key]];
|
|
@@ -6,5 +6,6 @@ export declare function readNxCloudToken(directory: string): string;
|
|
|
6
6
|
export declare function createNxCloudOnboardingUrl(nxCloud: NxCloud, token: string | undefined, directory: string, useGitHub?: boolean): Promise<string>;
|
|
7
7
|
export declare function getNxCloudInfo(connectCloudUrl: string, pushedToVcs: VcsPushStatus, completionMessageKey?: CompletionMessageKey, workspaceName?: string): Promise<string>;
|
|
8
8
|
export declare function getSkippedNxCloudInfo(): string;
|
|
9
|
+
export declare function openCloudSetupUrl(connectUrl: string): Promise<void>;
|
|
9
10
|
export declare function setNeverConnectToCloud(directory: string): void;
|
|
10
11
|
//# sourceMappingURL=nx-cloud.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nx-cloud.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/nx/nx-cloud.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"nx-cloud.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/nx/nx-cloud.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG3C,OAAO,EAGL,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAKpB,MAAM,MAAM,OAAO,GACf,KAAK,GACL,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,qBAAqB,GACrB,UAAU,GACV,MAAM,GACN,OAAO,CAAC;AAEZ,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,kBAAkB,EAAE,MAAM,EAC1B,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+BxB;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,UAgBjD;AAED,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED,wBAAsB,cAAc,CAClC,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,aAAa,EAC1B,oBAAoB,CAAC,EAAE,oBAAoB,EAC3C,aAAa,CAAC,EAAE,MAAM,mBAuBvB;AAED,wBAAgB,qBAAqB,WAIpC;AAED,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWzE;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAO9D"}
|
package/src/utils/nx/nx-cloud.js
CHANGED
|
@@ -5,7 +5,9 @@ exports.readNxCloudToken = readNxCloudToken;
|
|
|
5
5
|
exports.createNxCloudOnboardingUrl = createNxCloudOnboardingUrl;
|
|
6
6
|
exports.getNxCloudInfo = getNxCloudInfo;
|
|
7
7
|
exports.getSkippedNxCloudInfo = getSkippedNxCloudInfo;
|
|
8
|
+
exports.openCloudSetupUrl = openCloudSetupUrl;
|
|
8
9
|
exports.setNeverConnectToCloud = setNeverConnectToCloud;
|
|
10
|
+
const is_ci_1 = require("../ci/is-ci");
|
|
9
11
|
const output_1 = require("../output");
|
|
10
12
|
const messages_1 = require("./messages");
|
|
11
13
|
const ab_testing_1 = require("./ab-testing");
|
|
@@ -85,6 +87,18 @@ function getSkippedNxCloudInfo() {
|
|
|
85
87
|
out.success((0, messages_1.getSkippedCloudMessage)());
|
|
86
88
|
return out.getOutput();
|
|
87
89
|
}
|
|
90
|
+
async function openCloudSetupUrl(connectUrl) {
|
|
91
|
+
if ((0, is_ci_1.isCI)()) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const open = require('open');
|
|
96
|
+
await open(connectUrl);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Fail gracefully — the URL is already displayed in the terminal banner
|
|
100
|
+
}
|
|
101
|
+
}
|
|
88
102
|
function setNeverConnectToCloud(directory) {
|
|
89
103
|
const { readFileSync, writeFileSync } = require('fs');
|
|
90
104
|
const { join } = require('path');
|