Skip to content

Commit 75b7fa1

Browse files
mandariniFrozenPandaz
authored andcommitted
feat(nx-cloud): updates to the new onboarding flow
(cherry picked from commit d928558)
1 parent ef3d1e2 commit 75b7fa1

File tree

9 files changed

+254
-68
lines changed

9 files changed

+254
-68
lines changed

docs/generated/packages/nx/generators/connect-to-nx-cloud.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
"type": "boolean",
2929
"description": "If the user will be using GitHub as their git hosting provider",
3030
"default": false
31+
},
32+
"directory": {
33+
"type": "string",
34+
"description": "The directory where the workspace is located",
35+
"x-priority": "internal"
3136
}
3237
},
3338
"additionalProperties": false,

packages/create-nx-workspace/src/create-workspace.ts

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { createSandbox } from './create-sandbox';
55
import { createEmptyWorkspace } from './create-empty-workspace';
66
import { createPreset } from './create-preset';
77
import { setupCI } from './utils/ci/setup-ci';
8-
import { initializeGitRepo } from './utils/git/git';
8+
import { commitChanges, initializeGitRepo } from './utils/git/git';
99
import { getPackageNameFromThirdPartyPreset } from './utils/preset/get-third-party-preset';
1010
import { mapErrorToBodyLines } from './utils/error-utils';
1111

@@ -51,6 +51,23 @@ export async function createWorkspace<T extends CreateWorkspaceOptions>(
5151
);
5252
}
5353

54+
let gitSuccess = false;
55+
if (!skipGit && commit) {
56+
try {
57+
await initializeGitRepo(directory, { defaultBase, commit });
58+
gitSuccess = true;
59+
} catch (e) {
60+
if (e instanceof Error) {
61+
output.error({
62+
title: 'Could not initialize git repository',
63+
bodyLines: mapErrorToBodyLines(e),
64+
});
65+
} else {
66+
console.error(e);
67+
}
68+
}
69+
}
70+
5471
let nxCloudInstallRes;
5572
if (nxCloud !== 'skip') {
5673
nxCloudInstallRes = await setupNxCloud(
@@ -61,25 +78,14 @@ export async function createWorkspace<T extends CreateWorkspaceOptions>(
6178
);
6279

6380
if (nxCloud !== 'yes') {
64-
await setupCI(
81+
const nxCIsetupRes = await setupCI(
6582
directory,
6683
nxCloud,
6784
packageManager,
6885
nxCloudInstallRes?.code === 0
6986
);
70-
}
71-
}
72-
if (!skipGit && commit) {
73-
try {
74-
await initializeGitRepo(directory, { defaultBase, commit });
75-
} catch (e) {
76-
if (e instanceof Error) {
77-
output.error({
78-
title: 'Could not initialize git repository',
79-
bodyLines: mapErrorToBodyLines(e),
80-
});
81-
} else {
82-
console.error(e);
87+
if (nxCIsetupRes?.code === 0) {
88+
commitChanges(directory, `feat(nx): Generated CI workflow`);
8389
}
8490
}
8591
}

packages/create-nx-workspace/src/utils/git/git.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,19 @@ export async function initializeGitRepo(
8484
await execute(['commit', `-m "${message}"`]);
8585
}
8686
}
87+
88+
export function commitChanges(directory: string, message: string) {
89+
try {
90+
execSync('git add -A', { encoding: 'utf8', stdio: 'pipe', cwd: directory });
91+
execSync('git commit --no-verify -F -', {
92+
encoding: 'utf8',
93+
stdio: 'pipe',
94+
input: message,
95+
cwd: directory,
96+
});
97+
} catch (e) {
98+
console.error(`There was an error committing your Nx Cloud token.\n
99+
Please commit the changes manually and push to your new repository.\n
100+
\n${e}`);
101+
}
102+
}

packages/create-nx-workspace/src/utils/nx/nx-cloud.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export async function setupNxCloud(
1919
process.env.NX_NEW_CLOUD_ONBOARDING === 'true'
2020
? `${
2121
pmc.exec
22-
} nx g nx:connect-to-nx-cloud --installationSource=create-nx-workspace ${
22+
} nx g nx:connect-to-nx-cloud --installationSource=create-nx-workspace --directory=${directory} ${
2323
useGitHub ? '--github' : ''
2424
} --no-interactive`
2525
: `${pmc.exec} nx g nx:connect-to-nx-cloud --no-interactive --quiet`,

packages/nx/src/command-line/connect/connect-to-nx-cloud.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ export async function connectToNxCloudIfExplicitlyAsked(
5050
}
5151
}
5252

53-
export async function connectToNxCloudCommand(): Promise<boolean> {
53+
export async function connectToNxCloudCommand(
54+
command?: string
55+
): Promise<boolean> {
5456
const nxJson = readNxJson();
5557

5658
if (isNxCloudUsed(nxJson)) {
@@ -85,7 +87,9 @@ export async function connectToNxCloudCommand(): Promise<boolean> {
8587
}
8688

8789
const tree = new FsTree(workspaceRoot, false, 'connect-to-nx-cloud');
88-
const callback = await connectToNxCloud(tree, {});
90+
const callback = await connectToNxCloud(tree, {
91+
installationSource: command ?? 'nx-connect',
92+
});
8993
tree.lock();
9094
flushChanges(workspaceRoot, tree.listChanges());
9195
await callback();
@@ -96,7 +100,7 @@ export async function connectToNxCloudCommand(): Promise<boolean> {
96100
export async function connectToNxCloudWithPrompt(command: string) {
97101
const setNxCloud = await nxCloudPrompt('setupNxCloud');
98102
const useCloud =
99-
setNxCloud === 'yes' ? await connectToNxCloudCommand() : false;
103+
setNxCloud === 'yes' ? await connectToNxCloudCommand(command) : false;
100104
await recordStat({
101105
command,
102106
nxVersion,

packages/nx/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud.ts

Lines changed: 122 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import { readJson } from '../../../generators/utils/json';
66
import { NxJsonConfiguration } from '../../../config/nx-json';
77
import { readNxJson, updateNxJson } from '../../../generators/utils/nx-json';
88
import { formatChangedFilesWithPrettierIfAvailable } from '../../../generators/internal-utils/format-changed-files-with-prettier-if-available';
9-
import { shortenedCloudUrl } from '../../utilities/url-shorten';
9+
import { repoUsesGithub, shortenedCloudUrl } from '../../utilities/url-shorten';
10+
import { commitChanges } from '../../../utils/git-utils';
11+
import * as ora from 'ora';
12+
import * as open from 'open';
1013

1114
function printCloudConnectionDisabledMessage() {
1215
output.error({
@@ -75,9 +78,10 @@ async function createNxCloudWorkspace(
7578

7679
async function printSuccessMessage(
7780
url: string,
78-
token: string,
81+
token: string | undefined,
7982
installationSource: string,
80-
github: boolean
83+
usesGithub?: boolean,
84+
directory?: string
8185
) {
8286
if (process.env.NX_NEW_CLOUD_ONBOARDING !== 'true') {
8387
let origin = 'https://nx.app';
@@ -97,20 +101,63 @@ async function printSuccessMessage(
97101
const connectCloudUrl = await shortenedCloudUrl(
98102
installationSource,
99103
token,
100-
github
104+
usesGithub
101105
);
102106

103-
output.note({
104-
title: `Your Nx Cloud workspace is ready.`,
105-
bodyLines: [
106-
`To claim it, connect it to your Nx Cloud account:`,
107-
`- Commit and push your changes.`,
108-
`- Create a pull request for the changes.`,
109-
`- Go to the following URL to connect your workspace to Nx Cloud:
110-
111-
${connectCloudUrl}`,
112-
],
113-
});
107+
if (installationSource === 'nx-connect' && usesGithub) {
108+
try {
109+
const cloudConnectSpinner = ora(
110+
`Opening Nx Cloud ${connectCloudUrl} in your browser to connect your workspace.`
111+
).start();
112+
await sleep(2000);
113+
open(connectCloudUrl);
114+
cloudConnectSpinner.succeed();
115+
} catch (e) {
116+
output.note({
117+
title: `Your Nx Cloud workspace is ready.`,
118+
bodyLines: [
119+
`To claim it, connect it to your Nx Cloud account:`,
120+
`- Go to the following URL to connect your workspace to Nx Cloud:`,
121+
'',
122+
`${connectCloudUrl}`,
123+
],
124+
});
125+
}
126+
} else {
127+
if (installationSource === 'create-nx-workspace') {
128+
output.note({
129+
title: `Your Nx Cloud workspace is ready.`,
130+
bodyLines: [
131+
`To claim it, connect it to your Nx Cloud account:`,
132+
`- Push your repository to your git hosting provider.`,
133+
`- Go to the following URL to connect your workspace to Nx Cloud:`,
134+
'',
135+
`${connectCloudUrl}`,
136+
],
137+
});
138+
commitChanges(
139+
`feat(nx): Added Nx Cloud token to your nx.json
140+
141+
To connect your workspace to Nx Cloud, push your repository
142+
to your git hosting provider and go to the following URL:
143+
144+
${connectCloudUrl}`,
145+
directory
146+
);
147+
} else {
148+
output.note({
149+
title: `Your Nx Cloud workspace is ready.`,
150+
bodyLines: [
151+
`To claim it, connect it to your Nx Cloud account:`,
152+
`- Commit and push your changes.`,
153+
`- Create a pull request for the changes.`,
154+
`- Go to the following URL to connect your workspace to Nx Cloud:`,
155+
'',
156+
`${connectCloudUrl}`,
157+
],
158+
});
159+
}
160+
}
114161
}
115162
}
116163

@@ -119,6 +166,7 @@ interface ConnectToNxCloudOptions {
119166
installationSource?: string;
120167
hideFormatLogs?: boolean;
121168
github?: boolean;
169+
directory?: string;
122170
}
123171

124172
function addNxCloudOptionsToNxJson(
@@ -152,27 +200,70 @@ export async function connectToNxCloud(
152200
printCloudConnectionDisabledMessage();
153201
};
154202
} else {
155-
// TODO: Change to using loading light client when that is enabled by default
156-
const r = await createNxCloudWorkspace(
157-
getRootPackageName(tree),
158-
schema.installationSource,
159-
getNxInitDate()
160-
);
203+
if (process.env.NX_NEW_CLOUD_ONBOARDING !== 'true') {
204+
// TODO: Change to using loading light client when that is enabled by default
205+
const r = await createNxCloudWorkspace(
206+
getRootPackageName(tree),
207+
schema.installationSource,
208+
getNxInitDate()
209+
);
161210

162-
addNxCloudOptionsToNxJson(tree, nxJson, r.token);
211+
addNxCloudOptionsToNxJson(tree, nxJson, r.token);
163212

164-
await formatChangedFilesWithPrettierIfAvailable(tree, {
165-
silent: schema.hideFormatLogs,
166-
});
213+
await formatChangedFilesWithPrettierIfAvailable(tree, {
214+
silent: schema.hideFormatLogs,
215+
});
167216

168-
return async () =>
169-
await printSuccessMessage(
170-
r.url,
171-
r.token,
172-
schema.installationSource,
173-
schema.github
217+
return async () =>
218+
await printSuccessMessage(r.url, r.token, schema.installationSource);
219+
} else {
220+
const usesGithub = await repoUsesGithub(schema.github);
221+
222+
let responseFromCreateNxCloudWorkspace:
223+
| {
224+
token: string;
225+
url: string;
226+
}
227+
| undefined;
228+
229+
// do NOT create Nx Cloud token (createNxCloudWorkspace)
230+
// if user is using github and is running nx-connect
231+
if (!(usesGithub && schema.installationSource === 'nx-connect')) {
232+
responseFromCreateNxCloudWorkspace = await createNxCloudWorkspace(
233+
getRootPackageName(tree),
234+
schema.installationSource,
235+
getNxInitDate()
236+
);
237+
238+
addNxCloudOptionsToNxJson(
239+
tree,
240+
nxJson,
241+
responseFromCreateNxCloudWorkspace?.token
242+
);
243+
244+
await formatChangedFilesWithPrettierIfAvailable(tree, {
245+
silent: schema.hideFormatLogs,
246+
});
247+
}
248+
const apiUrl = removeTrailingSlash(
249+
process.env.NX_CLOUD_API ||
250+
process.env.NRWL_API ||
251+
`https://cloud.nx.app`
174252
);
253+
return async () =>
254+
await printSuccessMessage(
255+
responseFromCreateNxCloudWorkspace?.url ?? apiUrl,
256+
responseFromCreateNxCloudWorkspace?.token,
257+
schema.installationSource,
258+
usesGithub,
259+
schema.directory
260+
);
261+
}
175262
}
176263
}
177264

265+
function sleep(ms: number) {
266+
return new Promise((resolve) => setTimeout(resolve, ms));
267+
}
268+
178269
export default connectToNxCloud;

packages/nx/src/nx-cloud/generators/connect-to-nx-cloud/schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
"type": "boolean",
2626
"description": "If the user will be using GitHub as their git hosting provider",
2727
"default": false
28+
},
29+
"directory": {
30+
"type": "string",
31+
"description": "The directory where the workspace is located",
32+
"x-priority": "internal"
2833
}
2934
},
3035
"additionalProperties": false,

0 commit comments

Comments
 (0)