feat(nx-cloud): add 'generate-token' option to connect (#27678)

This update introduces a new 'genreate-token' option to force local
token creation. It ensures tokens are not created for GitHub-based
setups unless explicitly overridden. Adjustments include updated logic
in the generator function and schema to accommodate the new option.
This commit is contained in:
Benjamin Cabanes 2024-08-29 09:29:58 -04:00 committed by GitHub
parent a0cc0a9735
commit f95059917d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 96 additions and 37 deletions

View File

@ -17,12 +17,24 @@ Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`
## Options ## Options
### generateToken
Type: `boolean`
Explicitly asks for a token to be created, do not override existing tokens from Nx Cloud
### help ### help
Type: `boolean` Type: `boolean`
Show help Show help
### verbose
Type: `boolean`
Prints additional information about the commands (e.g., stack traces)
### version ### version
Type: `boolean` Type: `boolean`

View File

@ -17,12 +17,24 @@ Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`
## Options ## Options
### generateToken
Type: `boolean`
Explicitly asks for a token to be created, do not override existing tokens from Nx Cloud
### help ### help
Type: `boolean` Type: `boolean`
Show help Show help
### verbose
Type: `boolean`
Prints additional information about the commands (e.g., stack traces)
### version ### version
Type: `boolean` Type: `boolean`

View File

@ -24,6 +24,10 @@
"description": "Hide formatting logs", "description": "Hide formatting logs",
"x-priority": "internal" "x-priority": "internal"
}, },
"generateToken": {
"type": "boolean",
"description": "Explicitly asks for a token to be created, do not override existing tokens from Nx Cloud"
},
"github": { "github": {
"type": "boolean", "type": "boolean",
"description": "If the user will be using GitHub as their git hosting provider", "description": "If the user will be using GitHub as their git hosting provider",

View File

@ -1,14 +1,16 @@
import { CommandModule } from 'yargs'; import { Argv, CommandModule } from 'yargs';
import { linkToNxDevAndExamples } from '../yargs-utils/documentation'; import { linkToNxDevAndExamples } from '../yargs-utils/documentation';
import { nxVersion } from '../../utils/versions'; import { nxVersion } from '../../utils/versions';
import { withVerbose } from '../yargs-utils/shared-options';
export const yargsConnectCommand: CommandModule = { export const yargsConnectCommand: CommandModule = {
command: 'connect', command: 'connect',
aliases: ['connect-to-nx-cloud'], aliases: ['connect-to-nx-cloud'],
describe: `Connect workspace to Nx Cloud`, describe: `Connect workspace to Nx Cloud`,
builder: (yargs) => linkToNxDevAndExamples(yargs, 'connect-to-nx-cloud'), builder: (yargs) =>
handler: async () => { linkToNxDevAndExamples(withConnectOptions(yargs), 'connect-to-nx-cloud'),
await (await import('./connect-to-nx-cloud')).connectToNxCloudCommand(); handler: async (args: any) => {
await (await import('./connect-to-nx-cloud')).connectToNxCloudCommand(args);
await ( await (
await import('../../utils/ab-testing') await import('../../utils/ab-testing')
).recordStat({ ).recordStat({
@ -20,6 +22,14 @@ export const yargsConnectCommand: CommandModule = {
}, },
}; };
function withConnectOptions(yargs: Argv) {
return withVerbose(yargs).option('generateToken', {
type: 'boolean',
description:
'Explicitly asks for a token to be created, do not override existing tokens from Nx Cloud',
});
}
export const yargsViewLogsCommand: CommandModule = { export const yargsViewLogsCommand: CommandModule = {
command: 'view-logs', command: 'view-logs',
describe: describe:

View File

@ -70,6 +70,7 @@ export async function connectWorkspaceToCloud(
} }
export async function connectToNxCloudCommand( export async function connectToNxCloudCommand(
options: { generateToken?: boolean },
command?: string command?: string
): Promise<boolean> { ): Promise<boolean> {
const nxJson = readNxJson(); const nxJson = readNxJson();
@ -90,7 +91,8 @@ export async function connectToNxCloudCommand(
} }
const connectCloudUrl = await createNxCloudOnboardingURL( const connectCloudUrl = await createNxCloudOnboardingURL(
installationSource, installationSource,
token token,
options?.generateToken !== true
); );
output.log({ output.log({
title: '✔ This workspace already has Nx Cloud set up', title: '✔ This workspace already has Nx Cloud set up',
@ -104,10 +106,15 @@ export async function connectToNxCloudCommand(
return false; return false;
} }
const token = await connectWorkspaceToCloud({ const token = await connectWorkspaceToCloud({
generateToken: options?.generateToken,
installationSource: command ?? installationSource, installationSource: command ?? installationSource,
}); });
const connectCloudUrl = await createNxCloudOnboardingURL('nx-connect', token); const connectCloudUrl = await createNxCloudOnboardingURL(
'nx-connect',
token,
options?.generateToken !== true
);
try { try {
const cloudConnectSpinner = ora( const cloudConnectSpinner = ora(
`Opening Nx Cloud ${connectCloudUrl} in your browser to connect your workspace.` `Opening Nx Cloud ${connectCloudUrl} in your browser to connect your workspace.`
@ -153,7 +160,9 @@ export async function connectExistingRepoToNxCloudPrompt(
export async function connectToNxCloudWithPrompt(command: string) { export async function connectToNxCloudWithPrompt(command: string) {
const setNxCloud = await nxCloudPrompt('setupNxCloud'); const setNxCloud = await nxCloudPrompt('setupNxCloud');
const useCloud = const useCloud =
setNxCloud === 'yes' ? await connectToNxCloudCommand(command) : false; setNxCloud === 'yes'
? await connectToNxCloudCommand({ generateToken: false }, command)
: false;
await recordStat({ await recordStat({
command, command,
nxVersion, nxVersion,

View File

@ -100,6 +100,7 @@ export interface ConnectToNxCloudOptions {
hideFormatLogs?: boolean; hideFormatLogs?: boolean;
github?: boolean; github?: boolean;
directory?: string; directory?: string;
generateToken?: boolean;
} }
function addNxCloudIdToNxJson( function addNxCloudIdToNxJson(
@ -129,42 +130,49 @@ export async function connectToNxCloud(
tree: Tree, tree: Tree,
schema: ConnectToNxCloudOptions, schema: ConnectToNxCloudOptions,
nxJson = readNxJson(tree) nxJson = readNxJson(tree)
): Promise<string> { ): Promise<string | null> {
schema.installationSource ??= 'user'; schema.installationSource ??= 'user';
if (nxJson?.neverConnectToCloud) { if (nxJson?.neverConnectToCloud) {
printCloudConnectionDisabledMessage(); printCloudConnectionDisabledMessage();
return null; return null;
} else {
const usesGithub = schema.github ?? (await repoUsesGithub(schema.github));
let responseFromCreateNxCloudWorkspaceV2:
| {
nxCloudId: string;
}
| undefined;
// do NOT create Nx Cloud token (createNxCloudWorkspace)
// if user is using github and is running nx-connect
if (!(usesGithub && schema.installationSource === 'nx-connect')) {
responseFromCreateNxCloudWorkspaceV2 = await createNxCloudWorkspaceV2(
getRootPackageName(tree),
schema.installationSource,
getNxInitDate()
);
addNxCloudIdToNxJson(
tree,
responseFromCreateNxCloudWorkspaceV2?.nxCloudId,
schema.directory
);
await formatChangedFilesWithPrettierIfAvailable(tree, {
silent: schema.hideFormatLogs,
});
return responseFromCreateNxCloudWorkspaceV2.nxCloudId;
}
} }
const isGitHubDetected =
schema.github ?? (await repoUsesGithub(schema.github));
let responseFromCreateNxCloudWorkspaceV2:
| {
nxCloudId: string;
}
| undefined;
/**
* Do not create an Nx Cloud token if the user is using GitHub and
* is running `nx-connect` AND `token` is undefined (override)
*/
if (
!schema.generateToken &&
isGitHubDetected &&
schema.installationSource === 'nx-connect'
)
return null;
responseFromCreateNxCloudWorkspaceV2 = await createNxCloudWorkspaceV2(
getRootPackageName(tree),
schema.installationSource,
getNxInitDate()
);
addNxCloudIdToNxJson(
tree,
responseFromCreateNxCloudWorkspaceV2?.nxCloudId,
schema.directory
);
await formatChangedFilesWithPrettierIfAvailable(tree, {
silent: schema.hideFormatLogs,
});
return responseFromCreateNxCloudWorkspaceV2.nxCloudId;
} }
async function connectToNxCloudGenerator( async function connectToNxCloudGenerator(

View File

@ -21,6 +21,10 @@
"description": "Hide formatting logs", "description": "Hide formatting logs",
"x-priority": "internal" "x-priority": "internal"
}, },
"generateToken": {
"type": "boolean",
"description": "Explicitly asks for a token to be created, do not override existing tokens from Nx Cloud"
},
"github": { "github": {
"type": "boolean", "type": "boolean",
"description": "If the user will be using GitHub as their git hosting provider", "description": "If the user will be using GitHub as their git hosting provider",