create-nx-workspace 22.6.1 → 22.6.2
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 +1 -0
- package/package.json +2 -1
- package/src/create-workspace.d.ts +1 -0
- package/src/create-workspace.d.ts.map +1 -1
- package/src/create-workspace.js +23 -2
- 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/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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"}
|
|
@@ -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.2",
|
|
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,6 +8,7 @@ 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;
|
|
@@ -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;;;;;;GAyRZ;AAUD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI7D"}
|
package/src/create-workspace.js
CHANGED
|
@@ -131,6 +131,7 @@ async function createWorkspace(preset, options, rawArgs) {
|
|
|
131
131
|
await (0, setup_ci_1.setupCI)(directory, ciProvider, packageManager);
|
|
132
132
|
}
|
|
133
133
|
let pushedToVcs = git_1.VcsPushStatus.SkippedGit;
|
|
134
|
+
let pushFailReason;
|
|
134
135
|
if (!skipGit) {
|
|
135
136
|
const aiMode = (0, ai_output_1.isAiAgent)();
|
|
136
137
|
if (aiMode) {
|
|
@@ -153,14 +154,29 @@ async function createWorkspace(preset, options, rawArgs) {
|
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
catch (e) {
|
|
156
|
-
if (e instanceof
|
|
157
|
+
if (e instanceof git_1.GitHubPushError) {
|
|
158
|
+
// GitHub push issues are never fatal — CNW always succeeds.
|
|
159
|
+
// All reasons are logged in telemetry via pushFailReason.
|
|
160
|
+
pushedToVcs = git_1.VcsPushStatus.FailedToPushToVcs;
|
|
161
|
+
pushFailReason = e.reason;
|
|
162
|
+
// Only show the push hint when the user actually attempted a push
|
|
163
|
+
// and it failed. Pre-push issues (gh not installed, auth failed,
|
|
164
|
+
// timed out during auth) are silent — no point telling the user
|
|
165
|
+
// about a push they never asked for.
|
|
166
|
+
if (e.reason === 'push-failed' || e.reason === 'push-timeout') {
|
|
167
|
+
const githubNewUrl = `https://github.com/new?name=${encodeURIComponent(name)}`;
|
|
168
|
+
output_1.output.log({
|
|
169
|
+
title: `Push your repo to GitHub: ${githubNewUrl}`,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else if (e instanceof Error) {
|
|
157
174
|
if (!aiMode) {
|
|
158
175
|
output_1.output.error({
|
|
159
176
|
title: 'Could not initialize git repository',
|
|
160
177
|
bodyLines: (0, error_utils_1.mapErrorToBodyLines)(e),
|
|
161
178
|
});
|
|
162
179
|
}
|
|
163
|
-
// In AI mode, error will be handled by the caller
|
|
164
180
|
}
|
|
165
181
|
else {
|
|
166
182
|
console.error(e);
|
|
@@ -194,6 +210,10 @@ async function createWorkspace(preset, options, rawArgs) {
|
|
|
194
210
|
}
|
|
195
211
|
}
|
|
196
212
|
nxCloudInfo = await (0, nx_cloud_1.getNxCloudInfo)(connectUrl, pushedToVcs, options.completionMessageKey, name);
|
|
213
|
+
// Auto-open the Cloud setup URL in the browser when user selected 'yes'
|
|
214
|
+
if (!options.skipCloudConnect) {
|
|
215
|
+
await (0, nx_cloud_1.openCloudSetupUrl)(connectUrl);
|
|
216
|
+
}
|
|
197
217
|
}
|
|
198
218
|
else if (isTemplate && (nxCloud === 'skip' || nxCloud === 'never')) {
|
|
199
219
|
// Strip marker comments from README
|
|
@@ -211,6 +231,7 @@ async function createWorkspace(preset, options, rawArgs) {
|
|
|
211
231
|
nxCloudInfo,
|
|
212
232
|
directory,
|
|
213
233
|
pushedToVcs,
|
|
234
|
+
pushFailReason,
|
|
214
235
|
connectUrl,
|
|
215
236
|
};
|
|
216
237
|
}
|
|
@@ -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
|
}
|
|
@@ -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');
|