Skip to content

Commit

Permalink
fix(core): move token generation into new (#27266)
Browse files Browse the repository at this point in the history
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

The Nx Cloud token is generated after the workspace and preset have been
generated. This makes it hard to use the Nx Cloud token for generating
the workspace and preset.

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

The Nx Cloud token is generated in the workspace creation. This makes it
easier to use the Nx Cloud token during the workspace creation process.

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

(cherry picked from commit 2ec2564)
  • Loading branch information
FrozenPandaz committed Aug 7, 2024
1 parent b12043d commit 964558d
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 70 deletions.
9 changes: 9 additions & 0 deletions docs/generated/devkit/NxJsonConfiguration.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Nx.json configuration
- [implicitDependencies](../../devkit/documents/NxJsonConfiguration#implicitdependencies): ImplicitDependencyEntry<T>
- [installation](../../devkit/documents/NxJsonConfiguration#installation): NxInstallationConfiguration
- [namedInputs](../../devkit/documents/NxJsonConfiguration#namedinputs): Object
- [neverConnectToCloud](../../devkit/documents/NxJsonConfiguration#neverconnecttocloud): boolean
- [nxCloudAccessToken](../../devkit/documents/NxJsonConfiguration#nxcloudaccesstoken): string
- [nxCloudEncryptionKey](../../devkit/documents/NxJsonConfiguration#nxcloudencryptionkey): string
- [nxCloudUrl](../../devkit/documents/NxJsonConfiguration#nxcloudurl): string
Expand Down Expand Up @@ -163,6 +164,14 @@ Named inputs targets can refer to reduce duplication

---

### neverConnectToCloud

`Optional` **neverConnectToCloud**: `boolean`

Set this to false to disable connection to Nx Cloud

---

### nxCloudAccessToken

`Optional` **nxCloudAccessToken**: `string`
Expand Down
13 changes: 13 additions & 0 deletions docs/generated/devkit/Workspace.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use ProjectsConfigurations or NxJsonConfiguration
- [implicitDependencies](../../devkit/documents/Workspace#implicitdependencies): ImplicitDependencyEntry<string[] | "\*">
- [installation](../../devkit/documents/Workspace#installation): NxInstallationConfiguration
- [namedInputs](../../devkit/documents/Workspace#namedinputs): Object
- [neverConnectToCloud](../../devkit/documents/Workspace#neverconnecttocloud): boolean
- [nxCloudAccessToken](../../devkit/documents/Workspace#nxcloudaccesstoken): string
- [nxCloudEncryptionKey](../../devkit/documents/Workspace#nxcloudencryptionkey): string
- [nxCloudUrl](../../devkit/documents/Workspace#nxcloudurl): string
Expand Down Expand Up @@ -203,6 +204,18 @@ Named inputs targets can refer to reduce duplication

---

### neverConnectToCloud

`Optional` **neverConnectToCloud**: `boolean`

Set this to false to disable connection to Nx Cloud

#### Inherited from

[NxJsonConfiguration](../../devkit/documents/NxJsonConfiguration).[neverConnectToCloud](../../devkit/documents/NxJsonConfiguration#neverconnecttocloud)

---

### nxCloudAccessToken

`Optional` **nxCloudAccessToken**: `string`
Expand Down
4 changes: 2 additions & 2 deletions packages/create-nx-workspace/src/create-workspace.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CreateWorkspaceOptions } from './create-workspace-options';
import { output } from './utils/output';
import { getOnboardingInfo, setupNxCloud } from './utils/nx/nx-cloud';
import { getOnboardingInfo, readNxCloudToken } from './utils/nx/nx-cloud';
import { createSandbox } from './create-sandbox';
import { createEmptyWorkspace } from './create-empty-workspace';
import { createPreset } from './create-preset';
Expand Down Expand Up @@ -54,7 +54,7 @@ export async function createWorkspace<T extends CreateWorkspaceOptions>(
let connectUrl: string | undefined;
let nxCloudInfo: string | undefined;
if (nxCloud !== 'skip') {
const token = await setupNxCloud(directory, nxCloud, useGitHub);
const token = readNxCloudToken(directory) as string;

if (nxCloud !== 'yes') {
await setupCI(directory, nxCloud, packageManager);
Expand Down
58 changes: 14 additions & 44 deletions packages/create-nx-workspace/src/utils/nx/nx-cloud.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,23 @@
import * as ora from 'ora';
import { CLIOutput, output } from '../output';
import { mapErrorToBodyLines } from '../error-utils';
import { CLIOutput } from '../output';
import { getMessageFactory } from './messages';
import * as ora from 'ora';

export type NxCloud = 'yes' | 'github' | 'circleci' | 'skip';

export async function setupNxCloud(
directory: string,
nxCloud: NxCloud,
useGitHub?: boolean
) {
const nxCloudSpinner = ora(`Setting up Nx Cloud`).start();
try {
// nx-ignore-next-line
const { connectWorkspaceToCloud } = require(require.resolve(
'nx/src/command-line/connect/connect-to-nx-cloud',
{
paths: [directory],
}
// nx-ignore-next-line
)) as typeof import('nx/src/command-line/connect/connect-to-nx-cloud');

const accessToken = await connectWorkspaceToCloud(
{
installationSource: 'create-nx-workspace',
directory,
github: useGitHub,
},
directory
);

nxCloudSpinner.succeed('Nx Cloud has been set up successfully');
return accessToken;
} catch (e) {
nxCloudSpinner.fail();

if (e instanceof Error) {
output.error({
title: `Failed to setup Nx Cloud`,
bodyLines: mapErrorToBodyLines(e),
});
} else {
console.error(e);
export function readNxCloudToken(directory: string) {
const nxCloudSpinner = ora(`Checking Nx Cloud setup`).start();
// nx-ignore-next-line
const { getCloudOptions } = require(require.resolve(
'nx/src/nx-cloud/utilities/get-cloud-options',
{
paths: [directory],
}
// nx-ignore-next-line
)) as typeof import('nx/src/nx-cloud/utilities/get-cloud-options');

process.exit(1);
} finally {
nxCloudSpinner.stop();
}
const { accessToken } = getCloudOptions(directory);
nxCloudSpinner.succeed('Nx Cloud has been set up successfully');
return accessToken;
}

export async function getOnboardingInfo(
Expand Down
1 change: 1 addition & 0 deletions packages/nx/src/adapter/compat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export const allowedWorkspaceExtensions = [
'cacheDirectory',
'useDaemonProcess',
'useInferencePlugins',
'neverConnectToCloud',
] as const;

if (!patched) {
Expand Down
5 changes: 5 additions & 0 deletions packages/nx/src/config/nx-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,11 @@ export interface NxJsonConfiguration<T = '*' | string[]> {
* Set this to false to disable adding inference plugins when generating new projects
*/
useInferencePlugins?: boolean;

/**
* Set this to false to disable connection to Nx Cloud
*/
neverConnectToCloud?: boolean;
}

export type PluginConfiguration = string | ExpandedPluginConfiguration;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { execSync } from 'child_process';
import { output } from '../../../utils/output';
import { Tree } from '../../../generators/tree';
import { readJson } from '../../../generators/utils/json';
import { readJson, updateJson } from '../../../generators/utils/json';
import { NxJsonConfiguration } from '../../../config/nx-json';
import { readNxJson, updateNxJson } from '../../../generators/utils/nx-json';
import { readNxJson } from '../../../generators/utils/nx-json';
import { formatChangedFilesWithPrettierIfAvailable } from '../../../generators/internal-utils/format-changed-files-with-prettier-if-available';
import {
repoUsesGithub,
createNxCloudOnboardingURL,
} from '../../utilities/url-shorten';
import { getCloudUrl } from '../../utilities/get-cloud-options';
import { join } from 'path';

function printCloudConnectionDisabledMessage() {
output.error({
Expand Down Expand Up @@ -103,30 +104,34 @@ export interface ConnectToNxCloudOptions {

function addNxCloudOptionsToNxJson(
tree: Tree,
nxJson: NxJsonConfiguration,
token: string
token: string,
directory: string = tree.root
) {
nxJson ??= {
extends: 'nx/presets/npm.json',
};
nxJson.nxCloudAccessToken = token;
const overrideUrl = process.env.NX_CLOUD_API || process.env.NRWL_API;
if (overrideUrl) {
(nxJson as any).nxCloudUrl = overrideUrl;
const nxJsonPath = join(directory, 'nx.json');
if (tree.exists(nxJsonPath)) {
updateJson<NxJsonConfiguration>(
tree,
join(directory, 'nx.json'),
(nxJson) => {
const overrideUrl = process.env.NX_CLOUD_API || process.env.NRWL_API;
if (overrideUrl) {
nxJson.nxCloudUrl = overrideUrl;
}
nxJson.nxCloudAccessToken = token;

return nxJson;
}
);
}
updateNxJson(tree, nxJson);
}

export async function connectToNxCloud(
tree: Tree,
schema: ConnectToNxCloudOptions
schema: ConnectToNxCloudOptions,
nxJson = readNxJson(tree)
): Promise<string> {
schema.installationSource ??= 'user';

const nxJson = readNxJson(tree) as
| null
| (NxJsonConfiguration & { neverConnectToCloud: boolean });

if (nxJson?.neverConnectToCloud) {
printCloudConnectionDisabledMessage();
return null;
Expand All @@ -150,8 +155,8 @@ export async function connectToNxCloud(

addNxCloudOptionsToNxJson(
tree,
nxJson,
responseFromCreateNxCloudWorkspace?.token
responseFromCreateNxCloudWorkspace?.token,
schema.directory
);

await formatChangedFilesWithPrettierIfAvailable(tree, {
Expand Down
7 changes: 5 additions & 2 deletions packages/nx/src/nx-cloud/utilities/get-cloud-options.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { CloudTaskRunnerOptions } from '../nx-cloud-tasks-runner-shell';
import { readNxJson } from '../../config/nx-json';
import { getRunnerOptions } from '../../tasks-runner/run-command';
import { workspaceRoot } from '../../utils/workspace-root';

export function getCloudOptions(): CloudTaskRunnerOptions {
const nxJson = readNxJson();
export function getCloudOptions(
directory = workspaceRoot
): CloudTaskRunnerOptions {
const nxJson = readNxJson(directory);

// TODO: The default is not always cloud? But it's not handled at the moment
return getRunnerOptions('default', nxJson, {}, true);
Expand Down
22 changes: 19 additions & 3 deletions packages/workspace/src/generators/new/generate-workspace-files.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
formatFiles,
generateFiles,
getPackageManagerVersion,
names,
Expand All @@ -14,6 +13,7 @@ import { join } from 'path';
import { Preset } from '../utils/presets';
import { deduceDefaultBase } from '../../utilities/default-base';
import { NormalizedSchema } from './new';
import { connectToNxCloud } from 'nx/src/nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud';

export async function generateWorkspaceFiles(
tree: Tree,
Expand All @@ -31,7 +31,20 @@ export async function generateWorkspaceFiles(
options = normalizeOptions(options);
createReadme(tree, options);
createFiles(tree, options);
createNxJson(tree, options);
const nxJson = createNxJson(tree, options);

const token =
options.nxCloud !== 'skip'
? await connectToNxCloud(
tree,
{
installationSource: 'create-nx-workspace',
directory: options.directory,
github: options.useGitHub,
},
nxJson
)
: null;

const [packageMajor] = packageManagerVersion.split('.');
if (options.packageManager === 'pnpm' && +packageMajor >= 7) {
Expand All @@ -47,7 +60,7 @@ export async function generateWorkspaceFiles(
addNpmScripts(tree, options);
setUpWorkspacesInPackageJson(tree, options);

await formatFiles(tree);
return token;
}

function setPresetProperty(tree: Tree, options: NormalizedSchema) {
Expand Down Expand Up @@ -96,6 +109,8 @@ function createNxJson(
}

writeJson<NxJsonConfiguration>(tree, join(directory, 'nx.json'), nxJson);

return nxJson;
}

function createFiles(tree: Tree, options: NormalizedSchema) {
Expand Down Expand Up @@ -217,6 +232,7 @@ function normalizeOptions(options: NormalizedSchema) {
name,
...options,
defaultBase,
nxCloud: options.nxCloud ?? 'skip',
};
}

Expand Down
5 changes: 5 additions & 0 deletions packages/workspace/src/generators/new/new.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
formatFiles,
getPackageManagerCommand,
installPackagesTask,
joinPathFragments,
Expand Down Expand Up @@ -34,6 +35,8 @@ interface Schema {
e2eTestRunner?: 'cypress' | 'playwright' | 'detox' | 'jest' | 'none';
ssr?: boolean;
prefix?: string;
useGitHub?: boolean;
nxCloud?: 'yes' | 'skip' | 'circleci' | 'github';
}

export interface NormalizedSchema extends Schema {
Expand All @@ -49,6 +52,8 @@ export async function newGenerator(tree: Tree, opts: Schema) {

addPresetDependencies(tree, options);

await formatFiles(tree);

return async () => {
if (!options.skipInstall) {
const pmc = getPackageManagerCommand(options.packageManager);
Expand Down

0 comments on commit 964558d

Please sign in to comment.