create-nx-workspace 22.4.2 → 22.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/bin/create-nx-workspace.d.ts.map +1 -1
- package/bin/create-nx-workspace.js +2 -10
- package/package.json +2 -2
- package/src/create-workspace.d.ts.map +1 -1
- package/src/create-workspace.js +17 -0
- package/src/internal-utils/prompts.d.ts.map +1 -1
- package/src/internal-utils/prompts.js +13 -30
- package/src/utils/nx/ab-testing.d.ts +20 -7
- package/src/utils/nx/ab-testing.d.ts.map +1 -1
- package/src/utils/nx/ab-testing.js +66 -29
- package/src/utils/nx/messages.d.ts +9 -5
- package/src/utils/nx/messages.d.ts.map +1 -1
- package/src/utils/nx/messages.js +57 -21
- package/src/utils/nx/nx-cloud.d.ts.map +1 -1
- package/src/utils/nx/nx-cloud.js +4 -1
- package/src/utils/template/update-readme.d.ts +31 -0
- package/src/utils/template/update-readme.d.ts.map +1 -0
- package/src/utils/template/update-readme.js +91 -0
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<p style="text-align: center;">
|
|
2
2
|
<picture>
|
|
3
3
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-dark.svg">
|
|
4
|
-
<img alt="Nx - Smart
|
|
4
|
+
<img alt="Nx - Smart Monorepos · Fast Builds" src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-light.svg" width="100%">
|
|
5
5
|
</picture>
|
|
6
6
|
</p>
|
|
7
7
|
|
|
@@ -66,5 +66,5 @@ npx nx@latest init
|
|
|
66
66
|
- [Blog Posts About Nx](https://nx.dev/blog)
|
|
67
67
|
|
|
68
68
|
<p style="text-align: center;"><a href="https://nx.dev/#learning-materials" target="_blank" rel="noreferrer"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-courses-and-videos.svg"
|
|
69
|
-
width="100%" alt="Nx - Smart
|
|
69
|
+
width="100%" alt="Nx - Smart Monorepos · Fast Builds"></a></p>
|
|
70
70
|
|
|
@@ -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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"}
|
|
@@ -300,20 +300,13 @@ async function normalizeArgsMiddleware(argv) {
|
|
|
300
300
|
const ghAvailable = (0, git_1.isGhCliAvailable)();
|
|
301
301
|
let nxCloud;
|
|
302
302
|
let completionMessageKey;
|
|
303
|
-
const flowVariant = (0, ab_testing_1.getFlowVariant)();
|
|
304
303
|
if (argv.skipGit === true) {
|
|
305
304
|
nxCloud = 'skip';
|
|
306
305
|
completionMessageKey = undefined;
|
|
307
306
|
}
|
|
308
|
-
else if (flowVariant === '2') {
|
|
309
|
-
// Variant 2: Skip cloud prompt, auto-connect
|
|
310
|
-
// Respect --nxCloud=skip if explicitly provided
|
|
311
|
-
nxCloud = argv.nxCloud === 'skip' ? 'skip' : 'yes';
|
|
312
|
-
completionMessageKey =
|
|
313
|
-
nxCloud === 'skip' ? undefined : (0, ab_testing_1.getCompletionMessageKeyForVariant)();
|
|
314
|
-
}
|
|
315
307
|
else {
|
|
316
|
-
//
|
|
308
|
+
// Always show cloud prompt with "full platform" message (CLOUD-4147)
|
|
309
|
+
// Flow variant only affects completion banners, not this prompt
|
|
317
310
|
nxCloud = await (0, prompts_1.determineNxCloudV2)(argv);
|
|
318
311
|
completionMessageKey =
|
|
319
312
|
nxCloud === 'skip' ? undefined : (0, ab_testing_1.getCompletionMessageKeyForVariant)();
|
|
@@ -327,7 +320,6 @@ async function normalizeArgsMiddleware(argv) {
|
|
|
327
320
|
defaultBase: 'main',
|
|
328
321
|
aiAgents,
|
|
329
322
|
ghAvailable,
|
|
330
|
-
skipCloudConnect: flowVariant === '2',
|
|
331
323
|
});
|
|
332
324
|
await (0, ab_testing_1.recordStat)({
|
|
333
325
|
nxVersion: nx_version_1.nxVersion,
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-nx-workspace",
|
|
3
|
-
"version": "22.4.
|
|
3
|
+
"version": "22.4.4",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "Smart
|
|
5
|
+
"description": "Smart Monorepos · Fast Builds",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/nrwl/nx.git",
|
|
@@ -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,EAGL,aAAa,EACd,MAAM,iBAAiB,CAAC;
|
|
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,EAGL,aAAa,EACd,MAAM,iBAAiB,CAAC;AA0BzB,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,EACd,OAAO,EAAE,CAAC,EACV,OAAO,CAAC,EAAE,CAAC;;;;;GA6MZ;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI7D"}
|
package/src/create-workspace.js
CHANGED
|
@@ -16,6 +16,7 @@ const output_1 = require("./utils/output");
|
|
|
16
16
|
const get_third_party_preset_1 = require("./utils/preset/get-third-party-preset");
|
|
17
17
|
const preset_1 = require("./utils/preset/preset");
|
|
18
18
|
const clone_template_1 = require("./utils/template/clone-template");
|
|
19
|
+
const update_readme_1 = require("./utils/template/update-readme");
|
|
19
20
|
const child_process_utils_1 = require("./utils/child-process-utils");
|
|
20
21
|
const package_manager_1 = require("./utils/package-manager");
|
|
21
22
|
// State for SIGINT handler - only set after workspace is fully installed
|
|
@@ -140,9 +141,25 @@ async function createWorkspace(preset, options, rawArgs) {
|
|
|
140
141
|
connectUrl = await (0, nx_cloud_1.createNxCloudOnboardingUrl)(nxCloud, token, directory, useGitHub);
|
|
141
142
|
// Store for SIGINT handler
|
|
142
143
|
cloudConnectUrl = connectUrl;
|
|
144
|
+
// Update README with connect URL (strips markers, adds connect section)
|
|
145
|
+
// Then commit the change - amend if not pushed, new commit if already pushed
|
|
146
|
+
if (isTemplate) {
|
|
147
|
+
const readmeUpdated = (0, update_readme_1.addConnectUrlToReadme)(directory, connectUrl);
|
|
148
|
+
if (readmeUpdated && !skipGit && commit) {
|
|
149
|
+
const alreadyPushed = pushedToVcs === git_1.VcsPushStatus.PushedToVcs;
|
|
150
|
+
await (0, update_readme_1.amendOrCommitReadme)(directory, alreadyPushed);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
143
153
|
nxCloudInfo = await (0, nx_cloud_1.getNxCloudInfo)(connectUrl, pushedToVcs, options.completionMessageKey, name);
|
|
144
154
|
}
|
|
145
155
|
else if (isTemplate && nxCloud === 'skip') {
|
|
156
|
+
// Strip marker comments from README even when cloud is skipped
|
|
157
|
+
// so users don't see raw <!-- BEGIN/END: nx-cloud --> markers
|
|
158
|
+
const readmeUpdated = (0, update_readme_1.addConnectUrlToReadme)(directory, undefined);
|
|
159
|
+
if (readmeUpdated && !skipGit && commit) {
|
|
160
|
+
const alreadyPushed = pushedToVcs === git_1.VcsPushStatus.PushedToVcs;
|
|
161
|
+
await (0, update_readme_1.amendOrCommitReadme)(directory, alreadyPushed);
|
|
162
|
+
}
|
|
146
163
|
// Show nx connect message when user skips cloud in template flow
|
|
147
164
|
nxCloudInfo = (0, nx_cloud_1.getSkippedNxCloudInfo)();
|
|
148
165
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../../../packages/create-nx-workspace/src/internal-utils/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../../../packages/create-nx-workspace/src/internal-utils/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,EAEL,cAAc,EAEf,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAE/C,OAAO,EACL,KAAK,EAGN,MAAM,6BAA6B,CAAC;AAGrC,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,GAChD,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GACvE,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,CAgC5B;AAED,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GACrE,OAAO,CAAC,OAAO,CAAC,CAelB;AA4BD,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC,GACD,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,CA4C5B;AAED,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GACzE,OAAO,CAAC,KAAK,EAAE,CAAC,CAElB;AAqBD,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GACpD,OAAO,CAAC,MAAM,CAAC,CAwBjB;AAED,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC,GACtD,OAAO,CAAC,cAAc,CAAC,CAiCzB"}
|
|
@@ -37,36 +37,19 @@ async function determineNxCloudV2(parsedArgs) {
|
|
|
37
37
|
if (!parsedArgs.interactive || (0, is_ci_1.isCI)()) {
|
|
38
38
|
return 'skip';
|
|
39
39
|
}
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
name: '
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
{ value: 'skip', name: 'Skip' },
|
|
54
|
-
],
|
|
55
|
-
initial: 0,
|
|
56
|
-
hint: () => chalk.dim('\n(can be disabled any time)'),
|
|
57
|
-
footer: () => chalk.dim('\nRead more about remote caching at https://nx.dev/ci/features/remote-cache'),
|
|
58
|
-
}
|
|
59
|
-
: {
|
|
60
|
-
name: 'nxCloud',
|
|
61
|
-
message: 'Try the full Nx platform?',
|
|
62
|
-
type: 'autocomplete',
|
|
63
|
-
choices: [
|
|
64
|
-
{ value: 'yes', name: 'Yes' },
|
|
65
|
-
{ value: 'skip', name: 'Skip' },
|
|
66
|
-
],
|
|
67
|
-
initial: 0,
|
|
68
|
-
footer: () => chalk.dim('\nAutomatically fix broken PRs, 70% faster CI: https://nx.dev/nx-cloud'),
|
|
69
|
-
};
|
|
40
|
+
// Locked to "full platform" messaging (CLOUD-4147)
|
|
41
|
+
// Flow variant only affects completion banners, not this prompt
|
|
42
|
+
const promptConfig = {
|
|
43
|
+
name: 'nxCloud',
|
|
44
|
+
message: 'Try the full Nx platform?',
|
|
45
|
+
type: 'autocomplete',
|
|
46
|
+
choices: [
|
|
47
|
+
{ value: 'yes', name: 'Yes' },
|
|
48
|
+
{ value: 'skip', name: 'Skip' },
|
|
49
|
+
],
|
|
50
|
+
initial: 0,
|
|
51
|
+
footer: () => chalk.dim('\nAutomatically fix broken PRs, 70% faster CI: https://nx.dev/nx-cloud'),
|
|
52
|
+
};
|
|
70
53
|
const result = await enquirer.prompt([
|
|
71
54
|
promptConfig,
|
|
72
55
|
]);
|
|
@@ -1,21 +1,34 @@
|
|
|
1
|
-
import type { CompletionMessageKey } from './messages';
|
|
1
|
+
import type { BannerVariant, CompletionMessageKey } from './messages';
|
|
2
2
|
/**
|
|
3
3
|
* Returns the flow variant for tracking (0 = preset, 1 = template).
|
|
4
4
|
*/
|
|
5
5
|
export declare function getFlowVariant(): string;
|
|
6
6
|
/**
|
|
7
|
-
* Returns the completion message key
|
|
8
|
-
*
|
|
9
|
-
* - Variant 1: 'cache-setup' (shows "Would you like remote caching..." prompt)
|
|
10
|
-
* - Variant 2: 'platform-promo' (skips prompt, auto-connects, shows promo message)
|
|
7
|
+
* Returns the completion message key.
|
|
8
|
+
* Now locked to 'platform-setup' after concluding the prompt A/B test.
|
|
11
9
|
*/
|
|
12
10
|
export declare function getCompletionMessageKeyForVariant(): CompletionMessageKey;
|
|
13
11
|
/**
|
|
14
12
|
* Returns whether the cloud prompt should be shown.
|
|
15
|
-
*
|
|
16
|
-
* Variant 2 skips the prompt and auto-connects.
|
|
13
|
+
* Now always returns true since we've locked in the prompt flow.
|
|
17
14
|
*/
|
|
18
15
|
export declare function shouldShowCloudPrompt(): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Check if the given cloud URL is an enterprise URL.
|
|
18
|
+
* Enterprise URLs are anything other than cloud.nx.app, eu.nx.app, staging.nx.app, or snapshot.nx.app.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isEnterpriseCloudUrl(cloudUrl?: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Get the banner variant for completion messages.
|
|
23
|
+
* Uses NX_CNW_FLOW_VARIANT to determine which banner to show.
|
|
24
|
+
* - Variant 0: Plain link (control) - always used for enterprise URLs
|
|
25
|
+
* - Variant 1: "Try the full Nx platform" banner
|
|
26
|
+
* - Variant 2: "Unlock 70% faster CI" banner
|
|
27
|
+
* - Variant 3: "Reclaim your team's focus" banner
|
|
28
|
+
*
|
|
29
|
+
* @param cloudUrl - The Nx Cloud URL. If enterprise, always returns '0'.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getBannerVariant(cloudUrl?: string): BannerVariant;
|
|
19
32
|
export declare const NxCloudChoices: string[];
|
|
20
33
|
declare const messageOptions: Record<string, MessageData[]>;
|
|
21
34
|
export type MessageKey = keyof typeof messageOptions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ab-testing.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/nx/ab-testing.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;
|
|
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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"}
|
|
@@ -4,13 +4,16 @@ exports.messages = exports.PromptMessages = exports.NxCloudChoices = void 0;
|
|
|
4
4
|
exports.getFlowVariant = getFlowVariant;
|
|
5
5
|
exports.getCompletionMessageKeyForVariant = getCompletionMessageKeyForVariant;
|
|
6
6
|
exports.shouldShowCloudPrompt = shouldShowCloudPrompt;
|
|
7
|
+
exports.isEnterpriseCloudUrl = isEnterpriseCloudUrl;
|
|
8
|
+
exports.getBannerVariant = getBannerVariant;
|
|
7
9
|
exports.recordStat = recordStat;
|
|
8
10
|
const node_child_process_1 = require("node:child_process");
|
|
9
11
|
const node_fs_1 = require("node:fs");
|
|
10
12
|
const node_path_1 = require("node:path");
|
|
11
13
|
const node_os_1 = require("node:os");
|
|
12
14
|
const is_ci_1 = require("../ci/is-ci");
|
|
13
|
-
//
|
|
15
|
+
// Flow variant controls both tracking and banner display (CLOUD-4147)
|
|
16
|
+
// Variants: 0 = plain link, 1-3 = decorative banners
|
|
14
17
|
const FLOW_VARIANT_CACHE_FILE = (0, node_path_1.join)((0, node_os_1.tmpdir)(), 'nx-cnw-flow-variant');
|
|
15
18
|
const FLOW_VARIANT_EXPIRY_MS = 7 * 24 * 60 * 60 * 1000; // 1 week
|
|
16
19
|
// In-memory cache to ensure consistency within a single run
|
|
@@ -31,7 +34,7 @@ function readCachedFlowVariant() {
|
|
|
31
34
|
return null;
|
|
32
35
|
}
|
|
33
36
|
const value = (0, node_fs_1.readFileSync)(FLOW_VARIANT_CACHE_FILE, 'utf-8').trim();
|
|
34
|
-
return
|
|
37
|
+
return ['0', '1', '2', '3'].includes(value) ? value : null;
|
|
35
38
|
}
|
|
36
39
|
catch {
|
|
37
40
|
return null;
|
|
@@ -47,11 +50,13 @@ function writeCachedFlowVariant(variant) {
|
|
|
47
50
|
}
|
|
48
51
|
function selectRandomVariant() {
|
|
49
52
|
const rand = Math.random();
|
|
50
|
-
if (rand < 0.
|
|
53
|
+
if (rand < 0.25)
|
|
51
54
|
return '0';
|
|
52
|
-
if (rand < 0.
|
|
55
|
+
if (rand < 0.5)
|
|
53
56
|
return '1';
|
|
54
|
-
|
|
57
|
+
if (rand < 0.75)
|
|
58
|
+
return '2';
|
|
59
|
+
return '3';
|
|
55
60
|
}
|
|
56
61
|
/**
|
|
57
62
|
* Internal function to determine and cache the flow variant.
|
|
@@ -81,29 +86,64 @@ function getFlowVariant() {
|
|
|
81
86
|
return flowVariantCache ?? getFlowVariantInternal();
|
|
82
87
|
}
|
|
83
88
|
/**
|
|
84
|
-
* Returns the completion message key
|
|
85
|
-
*
|
|
86
|
-
* - Variant 1: 'cache-setup' (shows "Would you like remote caching..." prompt)
|
|
87
|
-
* - Variant 2: 'platform-promo' (skips prompt, auto-connects, shows promo message)
|
|
89
|
+
* Returns the completion message key.
|
|
90
|
+
* Now locked to 'platform-setup' after concluding the prompt A/B test.
|
|
88
91
|
*/
|
|
89
92
|
function getCompletionMessageKeyForVariant() {
|
|
90
|
-
const variant = getFlowVariant();
|
|
91
|
-
if (variant === '1') {
|
|
92
|
-
return 'cache-setup';
|
|
93
|
-
}
|
|
94
|
-
if (variant === '2') {
|
|
95
|
-
return 'platform-promo';
|
|
96
|
-
}
|
|
97
93
|
return 'platform-setup';
|
|
98
94
|
}
|
|
99
95
|
/**
|
|
100
96
|
* Returns whether the cloud prompt should be shown.
|
|
101
|
-
*
|
|
102
|
-
* Variant 2 skips the prompt and auto-connects.
|
|
97
|
+
* Now always returns true since we've locked in the prompt flow.
|
|
103
98
|
*/
|
|
104
99
|
function shouldShowCloudPrompt() {
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
// ============================================================================
|
|
103
|
+
// Banner Variant A/B Testing (CLOUD-4147)
|
|
104
|
+
// ============================================================================
|
|
105
|
+
/**
|
|
106
|
+
* Standard Nx Cloud URLs that should participate in banner A/B testing.
|
|
107
|
+
* Enterprise URLs (any other URL) always get the plain link (variant 0).
|
|
108
|
+
*/
|
|
109
|
+
const STANDARD_NX_CLOUD_HOSTS = [
|
|
110
|
+
'cloud.nx.app',
|
|
111
|
+
'eu.nx.app',
|
|
112
|
+
'staging.nx.app',
|
|
113
|
+
'snapshot.nx.app',
|
|
114
|
+
];
|
|
115
|
+
/**
|
|
116
|
+
* Check if the given cloud URL is an enterprise URL.
|
|
117
|
+
* Enterprise URLs are anything other than cloud.nx.app, eu.nx.app, staging.nx.app, or snapshot.nx.app.
|
|
118
|
+
*/
|
|
119
|
+
function isEnterpriseCloudUrl(cloudUrl) {
|
|
120
|
+
if (!cloudUrl)
|
|
121
|
+
return false;
|
|
122
|
+
try {
|
|
123
|
+
const url = new URL(cloudUrl);
|
|
124
|
+
return !STANDARD_NX_CLOUD_HOSTS.includes(url.hostname);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get the banner variant for completion messages.
|
|
132
|
+
* Uses NX_CNW_FLOW_VARIANT to determine which banner to show.
|
|
133
|
+
* - Variant 0: Plain link (control) - always used for enterprise URLs
|
|
134
|
+
* - Variant 1: "Try the full Nx platform" banner
|
|
135
|
+
* - Variant 2: "Unlock 70% faster CI" banner
|
|
136
|
+
* - Variant 3: "Reclaim your team's focus" banner
|
|
137
|
+
*
|
|
138
|
+
* @param cloudUrl - The Nx Cloud URL. If enterprise, always returns '0'.
|
|
139
|
+
*/
|
|
140
|
+
function getBannerVariant(cloudUrl) {
|
|
141
|
+
// Enterprise URLs always get plain link (variant 0)
|
|
142
|
+
if (isEnterpriseCloudUrl(cloudUrl)) {
|
|
143
|
+
return '0';
|
|
144
|
+
}
|
|
145
|
+
// Use the flow variant (which handles docs generation, env var, and caching)
|
|
146
|
+
return getFlowVariant();
|
|
107
147
|
}
|
|
108
148
|
exports.NxCloudChoices = [
|
|
109
149
|
'github',
|
|
@@ -138,23 +178,20 @@ const messageOptions = {
|
|
|
138
178
|
],
|
|
139
179
|
/**
|
|
140
180
|
* These messages are a fallback for setting up CI as well as when migrating major versions
|
|
181
|
+
* Locked to "full platform" messaging (CLOUD-4147)
|
|
141
182
|
*/
|
|
142
183
|
setupNxCloud: [
|
|
143
184
|
{
|
|
144
|
-
code: '
|
|
145
|
-
message:
|
|
185
|
+
code: 'cloud-v2-full-platform-visit',
|
|
186
|
+
message: 'Try the full Nx platform?',
|
|
146
187
|
initial: 0,
|
|
147
188
|
choices: [
|
|
148
189
|
{ value: 'yes', name: 'Yes' },
|
|
149
|
-
{
|
|
150
|
-
value: 'skip',
|
|
151
|
-
name: 'No - I would not like remote caching',
|
|
152
|
-
},
|
|
190
|
+
{ value: 'skip', name: 'Skip' },
|
|
153
191
|
],
|
|
154
|
-
footer: '\
|
|
155
|
-
hint: `\n(can be disabled any time).`,
|
|
192
|
+
footer: '\nAutomatically fix broken PRs, 70% faster CI: https://nx.dev/nx-cloud',
|
|
156
193
|
fallback: undefined,
|
|
157
|
-
completionMessage: '
|
|
194
|
+
completionMessage: 'platform-setup',
|
|
158
195
|
},
|
|
159
196
|
],
|
|
160
197
|
/**
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { VcsPushStatus } from '../git/git';
|
|
2
|
+
/**
|
|
3
|
+
* Banner variants for the completion message experiment (CLOUD-4147).
|
|
4
|
+
* - '0': Plain link (control) - always used for enterprise URLs
|
|
5
|
+
* - '1': "Try the full Nx platform" decorative banner
|
|
6
|
+
* - '2': "Unlock 70% faster CI" decorative banner
|
|
7
|
+
* - '3': "Reclaim your team's focus" decorative banner
|
|
8
|
+
*/
|
|
9
|
+
export type BannerVariant = '0' | '1' | '2' | '3';
|
|
2
10
|
/**
|
|
3
11
|
* Completion messages shown after workspace creation.
|
|
4
12
|
* Keys are referenced by ab-testing.ts prompts via completionMessage field.
|
|
@@ -13,13 +21,9 @@ declare const completionMessages: {
|
|
|
13
21
|
readonly 'platform-setup': {
|
|
14
22
|
readonly title: "Your platform setup is almost complete.";
|
|
15
23
|
};
|
|
16
|
-
readonly 'platform-promo': {
|
|
17
|
-
readonly title: "Want faster builds?";
|
|
18
|
-
readonly subtext: "Remote caching · Self-healing CI · Task distribution";
|
|
19
|
-
};
|
|
20
24
|
};
|
|
21
25
|
export type CompletionMessageKey = keyof typeof completionMessages;
|
|
22
|
-
export declare function getCompletionMessage(completionMessageKey: CompletionMessageKey | undefined, url: string | null, pushedToVcs: VcsPushStatus, workspaceName?: string): {
|
|
26
|
+
export declare function getCompletionMessage(completionMessageKey: CompletionMessageKey | undefined, url: string | null, pushedToVcs: VcsPushStatus, workspaceName?: string, bannerVariant?: BannerVariant): {
|
|
23
27
|
title: string;
|
|
24
28
|
bodyLines: string[];
|
|
25
29
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/nx/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/nx/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAuFlD;;;GAGG;AACH,QAAA,MAAM,kBAAkB;;;;;;;;;;CAUd,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,kBAAkB,CAAC;AAEnE,wBAAgB,oBAAoB,CAClC,oBAAoB,EAAE,oBAAoB,GAAG,SAAS,EACtD,GAAG,EAAE,MAAM,GAAG,IAAI,EAClB,WAAW,EAAE,aAAa,EAC1B,aAAa,CAAC,EAAE,MAAM,EACtB,aAAa,CAAC,EAAE,aAAa,GAC5B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAuBxC;AAED,wBAAgB,sBAAsB,IAAI;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,CAUA"}
|
package/src/utils/nx/messages.js
CHANGED
|
@@ -3,20 +3,53 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getCompletionMessage = getCompletionMessage;
|
|
4
4
|
exports.getSkippedCloudMessage = getSkippedCloudMessage;
|
|
5
5
|
const git_1 = require("../git/git");
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Generates the decorative ASCII art banner for Nx Cloud.
|
|
8
|
+
* Line widths are carefully calculated to align properly.
|
|
9
|
+
*/
|
|
10
|
+
function generateDecorativeBanner(headline, url, subtext) {
|
|
11
|
+
// Fixed banner structure - pad content to fit within the box
|
|
12
|
+
// Total inner width is 60 characters
|
|
13
|
+
const innerWidth = 60;
|
|
14
|
+
const padCenter = (text, width) => {
|
|
15
|
+
const padding = width - text.length;
|
|
16
|
+
const leftPad = Math.floor(padding / 2);
|
|
17
|
+
const rightPad = padding - leftPad;
|
|
18
|
+
return ' '.repeat(leftPad) + text + ' '.repeat(rightPad);
|
|
19
|
+
};
|
|
20
|
+
const line1 = padCenter('', innerWidth);
|
|
21
|
+
const line2 = padCenter(`- ${headline} -`, innerWidth);
|
|
22
|
+
const line3 = padCenter(url, innerWidth);
|
|
23
|
+
const line4 = padCenter(subtext, innerWidth);
|
|
24
|
+
return [
|
|
25
|
+
` ${'_'.repeat(innerWidth + 1)} ____ ___ __ `,
|
|
26
|
+
` \\${line1}\\ \\ \\ \\ \\ \\ \\`,
|
|
27
|
+
` \\${line2}\\ \\ \\ \\ \\ \\ \\`,
|
|
28
|
+
` \\${line3}\\ \\ \\ \\ \\ \\ \\`,
|
|
29
|
+
` \\${line4}\\ \\ \\ \\ \\ \\ \\ `,
|
|
30
|
+
` \\${'_'.repeat(innerWidth)}\\ \\___\\ \\__\\ \\_\\`,
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get banner lines based on the variant.
|
|
35
|
+
* Returns empty array for variant 0 (plain link).
|
|
36
|
+
*/
|
|
37
|
+
function getBannerLines(variant, url) {
|
|
38
|
+
switch (variant) {
|
|
39
|
+
case '1':
|
|
40
|
+
return generateDecorativeBanner('Try the full Nx platform', url, 'Remote caching * Distribution * Self-healing CI');
|
|
41
|
+
case '2':
|
|
42
|
+
return generateDecorativeBanner('Unlock 70% faster CI', url, 'Remote caching & Distribution');
|
|
43
|
+
case '3':
|
|
44
|
+
return generateDecorativeBanner("Reclaim your team's focus", url, 'Self-healing CI + Remote caching');
|
|
45
|
+
default:
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function getSetupMessage(url, pushedToVcs, workspaceName) {
|
|
7
50
|
const githubUrl = workspaceName
|
|
8
51
|
? `https://github.com/new?name=${encodeURIComponent(workspaceName)}`
|
|
9
52
|
: 'https://github.com/new';
|
|
10
|
-
if (isPromo) {
|
|
11
|
-
if (pushedToVcs === git_1.VcsPushStatus.PushedToVcs) {
|
|
12
|
-
return url
|
|
13
|
-
? `Connect your repo to enable remote caching and self-healing CI at: ${url}`
|
|
14
|
-
: 'Connect your repo at https://cloud.nx.app to enable remote caching and self-healing CI.';
|
|
15
|
-
}
|
|
16
|
-
return url
|
|
17
|
-
? `Connect your repo (${githubUrl}) to enable remote caching and self-healing CI at: ${url}`
|
|
18
|
-
: `Connect your repo (${githubUrl}) to enable remote caching and self-healing CI at https://cloud.nx.app`;
|
|
19
|
-
}
|
|
20
53
|
if (pushedToVcs === git_1.VcsPushStatus.PushedToVcs) {
|
|
21
54
|
return url
|
|
22
55
|
? `Go to Nx Cloud and finish the setup: ${url}`
|
|
@@ -41,20 +74,23 @@ const completionMessages = {
|
|
|
41
74
|
'platform-setup': {
|
|
42
75
|
title: 'Your platform setup is almost complete.',
|
|
43
76
|
},
|
|
44
|
-
'platform-promo': {
|
|
45
|
-
title: 'Want faster builds?',
|
|
46
|
-
subtext: 'Remote caching \u00b7 Self-healing CI \u00b7 Task distribution',
|
|
47
|
-
},
|
|
48
77
|
};
|
|
49
|
-
function getCompletionMessage(completionMessageKey, url, pushedToVcs, workspaceName) {
|
|
78
|
+
function getCompletionMessage(completionMessageKey, url, pushedToVcs, workspaceName, bannerVariant) {
|
|
50
79
|
const key = completionMessageKey ?? 'ci-setup';
|
|
51
80
|
const messageConfig = completionMessages[key];
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
if ('
|
|
55
|
-
|
|
56
|
-
|
|
81
|
+
const variant = bannerVariant ?? '0';
|
|
82
|
+
// For decorative banner variants (1, 2, 3), show the banner instead of plain text
|
|
83
|
+
if (variant !== '0' && url) {
|
|
84
|
+
const bannerLines = getBannerLines(variant, url);
|
|
85
|
+
if (bannerLines.length > 0) {
|
|
86
|
+
return {
|
|
87
|
+
title: messageConfig.title,
|
|
88
|
+
bodyLines: [...bannerLines, ''],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
57
91
|
}
|
|
92
|
+
// Variant 0 (control) or fallback: plain link message
|
|
93
|
+
const bodyLines = [getSetupMessage(url, pushedToVcs, workspaceName)];
|
|
58
94
|
return {
|
|
59
95
|
title: messageConfig.title,
|
|
60
96
|
bodyLines,
|
|
@@ -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;AAE3C,OAAO,EAGL,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAIpB,MAAM,MAAM,OAAO,GACf,KAAK,GACL,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,qBAAqB,GACrB,UAAU,GACV,MAAM,CAAC;AAEX,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,CA6BjB;AAED,wBAAsB,cAAc,CAClC,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,aAAa,EAC1B,oBAAoB,CAAC,EAAE,oBAAoB,EAC3C,aAAa,CAAC,EAAE,MAAM,
|
|
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;AAE3C,OAAO,EAGL,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAIpB,MAAM,MAAM,OAAO,GACf,KAAK,GACL,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,qBAAqB,GACrB,UAAU,GACV,MAAM,CAAC;AAEX,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,CA6BjB;AAED,wBAAsB,cAAc,CAClC,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,aAAa,EAC1B,oBAAoB,CAAC,EAAE,oBAAoB,EAC3C,aAAa,CAAC,EAAE,MAAM,mBAevB;AAED,wBAAgB,qBAAqB,WAIpC"}
|
package/src/utils/nx/nx-cloud.js
CHANGED
|
@@ -60,7 +60,10 @@ async function createNxCloudOnboardingUrl(nxCloud, token, directory, useGitHub)
|
|
|
60
60
|
}
|
|
61
61
|
async function getNxCloudInfo(connectCloudUrl, pushedToVcs, completionMessageKey, workspaceName) {
|
|
62
62
|
const out = new output_1.CLIOutput(false);
|
|
63
|
-
|
|
63
|
+
// Get the banner variant based on the cloud URL
|
|
64
|
+
// Enterprise URLs automatically get variant 0 (plain link)
|
|
65
|
+
const bannerVariant = (0, ab_testing_1.getBannerVariant)(connectCloudUrl);
|
|
66
|
+
const message = (0, messages_1.getCompletionMessage)(completionMessageKey, connectCloudUrl, pushedToVcs, workspaceName, bannerVariant);
|
|
64
67
|
out.success(message);
|
|
65
68
|
return out.getOutput();
|
|
66
69
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Updates README content by processing the nx-cloud marker section.
|
|
3
|
+
* - If connectUrl is provided: replaces markers and content with the connect URL section
|
|
4
|
+
* - If connectUrl is undefined: removes markers and their content entirely
|
|
5
|
+
*
|
|
6
|
+
* This ensures users never see the raw <!-- BEGIN/END: nx-cloud --> markers in their README.
|
|
7
|
+
*
|
|
8
|
+
* @param readmeContent - The current README content
|
|
9
|
+
* @param connectUrl - The Nx Cloud connect URL (optional)
|
|
10
|
+
* @returns The updated README content with markers processed, or original if markers not found
|
|
11
|
+
*/
|
|
12
|
+
export declare function updateReadmeContent(readmeContent: string, connectUrl: string | undefined): string;
|
|
13
|
+
/**
|
|
14
|
+
* Updates the README.md file in the given directory with the Nx Cloud connect URL.
|
|
15
|
+
* This is a convenience wrapper around updateReadmeContent that handles file I/O.
|
|
16
|
+
*
|
|
17
|
+
* @param directory - The workspace directory containing README.md
|
|
18
|
+
* @param connectUrl - The Nx Cloud connect URL
|
|
19
|
+
* @returns true if the file was modified, false otherwise
|
|
20
|
+
*/
|
|
21
|
+
export declare function addConnectUrlToReadme(directory: string, connectUrl: string | undefined): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Commits README.md changes, either by amending the initial commit or creating a new one.
|
|
24
|
+
* - If already pushed to VCS: creates a new commit (to avoid requiring force push)
|
|
25
|
+
* - If not pushed: amends the initial commit (cleaner history)
|
|
26
|
+
*
|
|
27
|
+
* @param directory - The workspace directory
|
|
28
|
+
* @param alreadyPushed - Whether the repo was already pushed to VCS
|
|
29
|
+
*/
|
|
30
|
+
export declare function amendOrCommitReadme(directory: string, alreadyPushed: boolean): Promise<void>;
|
|
31
|
+
//# sourceMappingURL=update-readme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-readme.d.ts","sourceRoot":"","sources":["../../../../../../packages/create-nx-workspace/src/utils/template/update-readme.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,MAAM,CAuCR;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,OAAO,CAeT;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,OAAO,GACrB,OAAO,CAAC,IAAI,CAAC,CAWf"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateReadmeContent = updateReadmeContent;
|
|
4
|
+
exports.addConnectUrlToReadme = addConnectUrlToReadme;
|
|
5
|
+
exports.amendOrCommitReadme = amendOrCommitReadme;
|
|
6
|
+
const node_fs_1 = require("node:fs");
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const child_process_utils_1 = require("../child-process-utils");
|
|
9
|
+
const BEGIN_MARKER = '<!-- BEGIN: nx-cloud -->';
|
|
10
|
+
const END_MARKER = '<!-- END: nx-cloud -->';
|
|
11
|
+
const CLOUD_SETUP_SECTION = `## Finish your Nx platform setup
|
|
12
|
+
|
|
13
|
+
🚀 [Finish setting up your workspace]({{CONNECT_URL}}) to get faster builds with remote caching, distributed task execution, and self-healing CI. [Learn more about Nx Cloud](https://nx.dev/ci/intro/why-nx-cloud).
|
|
14
|
+
`;
|
|
15
|
+
/**
|
|
16
|
+
* Updates README content by processing the nx-cloud marker section.
|
|
17
|
+
* - If connectUrl is provided: replaces markers and content with the connect URL section
|
|
18
|
+
* - If connectUrl is undefined: removes markers and their content entirely
|
|
19
|
+
*
|
|
20
|
+
* This ensures users never see the raw <!-- BEGIN/END: nx-cloud --> markers in their README.
|
|
21
|
+
*
|
|
22
|
+
* @param readmeContent - The current README content
|
|
23
|
+
* @param connectUrl - The Nx Cloud connect URL (optional)
|
|
24
|
+
* @returns The updated README content with markers processed, or original if markers not found
|
|
25
|
+
*/
|
|
26
|
+
function updateReadmeContent(readmeContent, connectUrl) {
|
|
27
|
+
const beginIndex = readmeContent.indexOf(BEGIN_MARKER);
|
|
28
|
+
const endIndex = readmeContent.indexOf(END_MARKER);
|
|
29
|
+
if (beginIndex === -1 || endIndex === -1 || beginIndex >= endIndex) {
|
|
30
|
+
return readmeContent;
|
|
31
|
+
}
|
|
32
|
+
// If no connect URL, remove the markers and placeholder content entirely
|
|
33
|
+
if (!connectUrl) {
|
|
34
|
+
// Remove the marker section and surrounding newlines to avoid extra blank lines
|
|
35
|
+
// Skip one newline before BEGIN marker (if present)
|
|
36
|
+
const beforeBegin = beginIndex > 0 && readmeContent[beginIndex - 1] === '\n'
|
|
37
|
+
? beginIndex - 1
|
|
38
|
+
: beginIndex;
|
|
39
|
+
// Skip one newline after END marker (if present)
|
|
40
|
+
const afterEnd = endIndex + END_MARKER.length;
|
|
41
|
+
const skipTrailing = readmeContent[afterEnd] === '\n' ? afterEnd + 1 : afterEnd;
|
|
42
|
+
return (readmeContent.slice(0, beforeBegin) + readmeContent.slice(skipTrailing));
|
|
43
|
+
}
|
|
44
|
+
const section = CLOUD_SETUP_SECTION.replace('{{CONNECT_URL}}', connectUrl);
|
|
45
|
+
// Strip the markers - only include the section content
|
|
46
|
+
// Also skip one trailing newline after END marker since section already has one
|
|
47
|
+
const afterEnd = endIndex + END_MARKER.length;
|
|
48
|
+
const skipNewline = readmeContent[afterEnd] === '\n' ? afterEnd + 1 : afterEnd;
|
|
49
|
+
return (readmeContent.slice(0, beginIndex) +
|
|
50
|
+
section +
|
|
51
|
+
readmeContent.slice(skipNewline));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Updates the README.md file in the given directory with the Nx Cloud connect URL.
|
|
55
|
+
* This is a convenience wrapper around updateReadmeContent that handles file I/O.
|
|
56
|
+
*
|
|
57
|
+
* @param directory - The workspace directory containing README.md
|
|
58
|
+
* @param connectUrl - The Nx Cloud connect URL
|
|
59
|
+
* @returns true if the file was modified, false otherwise
|
|
60
|
+
*/
|
|
61
|
+
function addConnectUrlToReadme(directory, connectUrl) {
|
|
62
|
+
const readmePath = (0, path_1.join)(directory, 'README.md');
|
|
63
|
+
if (!(0, node_fs_1.existsSync)(readmePath)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const content = (0, node_fs_1.readFileSync)(readmePath, 'utf-8');
|
|
67
|
+
const updated = updateReadmeContent(content, connectUrl);
|
|
68
|
+
if (updated !== content) {
|
|
69
|
+
(0, node_fs_1.writeFileSync)(readmePath, updated);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Commits README.md changes, either by amending the initial commit or creating a new one.
|
|
76
|
+
* - If already pushed to VCS: creates a new commit (to avoid requiring force push)
|
|
77
|
+
* - If not pushed: amends the initial commit (cleaner history)
|
|
78
|
+
*
|
|
79
|
+
* @param directory - The workspace directory
|
|
80
|
+
* @param alreadyPushed - Whether the repo was already pushed to VCS
|
|
81
|
+
*/
|
|
82
|
+
async function amendOrCommitReadme(directory, alreadyPushed) {
|
|
83
|
+
await (0, child_process_utils_1.execAndWait)('git add README.md', directory);
|
|
84
|
+
if (alreadyPushed) {
|
|
85
|
+
await (0, child_process_utils_1.execAndWait)('git commit -m "chore: add Nx Cloud setup link to README"', directory);
|
|
86
|
+
await (0, child_process_utils_1.execAndWait)('git push', directory);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
await (0, child_process_utils_1.execAndWait)('git commit --amend --no-edit', directory);
|
|
90
|
+
}
|
|
91
|
+
}
|