Skip to content

Commit

Permalink
feat(misc): a/b different messages during migration to next major
Browse files Browse the repository at this point in the history
(cherry picked from commit 77b57b7)
  • Loading branch information
vsavkin authored and FrozenPandaz committed Oct 3, 2022
1 parent f54dd1a commit ce0fe45
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 73 deletions.
83 changes: 83 additions & 0 deletions packages/create-nx-workspace/bin/ab-testing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import axios from 'axios';
import { isCI } from './output';

export class PromptMessages {
private messages = {
nxCloudCreation: [
{
code: 'set-up-distributed-caching-ci',
message: `Enable distributed caching to make your CI faster`,
},
],
nxCloudMigration: [
{
code: 'we-noticed',
message: `We noticed you are migrating to a new major version, but are not taking advantage of Nx Cloud. Nx Cloud can make your CI up to 10 times faster. Learn more about it here: nx.app. Would you like to add it?`,
},
{
code: 'not-leveraging-caching',
message: `You're not leveraging distributed caching yet. Do you want to enable it and speed up your CI?`,
},
{
code: 'make-ci-faster',
message: `Enable distributed caching to make your CI faster?`,
},
],
};

private selectedMessages = {};

getPromptMessage(key: string): string {
if (this.selectedMessages[key] === undefined) {
if (process.env.NX_GENERATE_DOCS_PROCESS === 'true') {
this.selectedMessages[key] = 0;
} else {
this.selectedMessages[key] = Math.floor(
Math.random() * this.messages[key].length
);
}
}
return this.messages[key][this.selectedMessages[key]].message;
}

codeOfSelectedPromptMessage(key: string): string {
if (this.selectedMessages[key] === undefined) return null;
return this.messages[key][this.selectedMessages[key]].code;
}
}

export const messages = new PromptMessages();

/**
* We are incrementing a counter to track how often create-nx-workspace is used in CI
* vs dev environments. No personal information is collected.
*/
export async function recordStat(opts: {
command: string;
nxVersion: string;
useCloud: boolean;
meta: string;
}) {
try {
const major = Number(opts.nxVersion.split('.')[0]);
if (process.env.NX_VERBOSE_LOGGING === 'true') {
console.log(`Record stat. Major: ${major}`);
}
if (major < 10 || major > 14) return; // test version, skip it
await axios
.create({
baseURL: 'https://cloud.nx.app',
timeout: 400,
})
.post('/nx-cloud/stats', {
command: opts.command,
isCI: isCI(),
useCloud: opts.useCloud,
meta: opts.meta,
});
} catch (e) {
if (process.env.NX_VERBOSE_LOGGING === 'true') {
console.error(e);
}
}
}
77 changes: 10 additions & 67 deletions packages/create-nx-workspace/bin/create-nx-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as path from 'path';
import { dirSync } from 'tmp';
import * as yargs from 'yargs';
import { showNxWarning, unparse } from './shared';
import { isCI, output } from './output';
import { output } from './output';
import * as ora from 'ora';
import {
detectInvokedPackageManager,
Expand All @@ -23,7 +23,7 @@ import chalk = require('chalk');
import { ciList } from './ci';
import { join } from 'path';
import { initializeGitRepo } from './git';
import axios from 'axios';
import { messages, recordStat } from './ab-testing';

type Arguments = {
name: string;
Expand Down Expand Up @@ -62,37 +62,6 @@ enum Preset {
Express = 'express',
}

class PromptMessages {
private messages = {
nxCloud: [
{
code: 'set-up-distributed-caching-ci',
message: `Enable distributed caching to make your CI faster`,
},
],
};

private selectedMessages = {};

getPromptMessage(key: string): string {
if (this.selectedMessages[key] === undefined) {
if (process.env.NX_GENERATE_DOCS_PROCESS === 'true') {
this.selectedMessages[key] = 0;
} else {
this.selectedMessages[key] = Math.floor(
Math.random() * this.messages[key].length
);
}
}
return this.messages[key][this.selectedMessages[key]].message;
}

codeOfSelectedPromptMessage(key: string): string {
if (this.selectedMessages[key] === undefined) return null;
return this.messages[key][this.selectedMessages[key]].code;
}
}

const presetOptions: { name: Preset; message: string }[] = [
{
name: Preset.Apps,
Expand Down Expand Up @@ -162,8 +131,6 @@ const nxVersion = require('../package.json').version;
const tsVersion = 'TYPESCRIPT_VERSION'; // This gets replaced with the typescript version in the root package.json during build
const prettierVersion = 'PRETTIER_VERSION'; // This gets replaced with the prettier version in the root package.json during build

const messages = new PromptMessages();

export const commandsObject: yargs.Argv<Arguments> = yargs
.wrap(yargs.terminalWidth())
.parserConfiguration({
Expand Down Expand Up @@ -208,7 +175,7 @@ export const commandsObject: yargs.Argv<Arguments> = yargs
type: 'string',
})
.option('nxCloud', {
describe: chalk.dim(messages.getPromptMessage('nxCloud')),
describe: chalk.dim(messages.getPromptMessage('nxCloudCreation')),
type: 'boolean',
})
.option('ci', {
Expand Down Expand Up @@ -346,7 +313,12 @@ async function main(parsedArgs: yargs.Arguments<Arguments>) {
printNxCloudSuccessMessage(nxCloudInstallRes.stdout);
}

await recordWorkspaceCreationStats(nxCloud);
await recordStat({
nxVersion,
command: 'create-nx-workspace',
useCloud: nxCloud,
meta: messages.codeOfSelectedPromptMessage('nxCloudCreation'),
});
}

async function getConfiguration(
Expand Down Expand Up @@ -718,7 +690,7 @@ async function determineNxCloud(
.prompt([
{
name: 'NxCloud',
message: messages.getPromptMessage('nxCloud'),
message: messages.getPromptMessage('nxCloudCreation'),
type: 'autocomplete',
choices: [
{
Expand Down Expand Up @@ -1039,32 +1011,3 @@ function pointToTutorialAndCourse(preset: Preset) {
break;
}
}

/**
* We are incrementing a counter to track how often create-nx-workspace is used in CI
* vs dev environments. No personal information is collected.
*/
async function recordWorkspaceCreationStats(useCloud: boolean) {
try {
const major = Number(nxVersion.split('.')[0]);
if (process.env.NX_VERBOSE_LOGGING === 'true') {
console.log(`Record stat. Major: ${major}`);
}
if (major < 10 || major > 14) return; // test version, skip it
await axios
.create({
baseURL: 'https://cloud.nx.app',
timeout: 400,
})
.post('/nx-cloud/stats', {
command: 'create-nx-workspace',
isCI: isCI(),
useCloud,
meta: messages.codeOfSelectedPromptMessage('nxCloud'),
});
} catch (e) {
if (process.env.NX_VERBOSE_LOGGING === 'true') {
console.error(e);
}
}
}
3 changes: 2 additions & 1 deletion packages/nx/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
"v8-compile-cache": "2.3.0",
"yargs": "^17.4.0",
"yargs-parser": "21.0.1",
"js-yaml": "4.1.0"
"js-yaml": "4.1.0",
"axios": "0.21.1"
},
"peerDependencies": {
"@swc-node/register": "^1.4.2",
Expand Down
7 changes: 4 additions & 3 deletions packages/nx/src/command-line/connect-to-nx-cloud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export async function connectToNxCloudIfExplicitlyAsked(opts: {

export async function connectToNxCloudCommand(
promptOverride?: string
): Promise<void> {
): Promise<boolean> {
const nxJson = readNxJson();
const nxCloudUsed = Object.values(nxJson.tasksRunnerOptions).find(
(r) => r.runner == '@nrwl/nx-cloud'
Expand All @@ -38,16 +38,17 @@ export async function connectToNxCloudCommand(
output.log({
title: 'This workspace is already connected to Nx Cloud.',
});
return;
return false;
}

const res = await connectToNxCloudPrompt(promptOverride);
if (!res) return;
if (!res) return false;
const pmc = getPackageManagerCommand();
execSync(`${pmc.addDev} @nrwl/nx-cloud@latest`);
execSync(`${pmc.exec} nx g @nrwl/nx-cloud:init`, {
stdio: [0, 1, 2],
});
return true;
}

async function connectToNxCloudPrompt(prompt?: string) {
Expand Down
12 changes: 10 additions & 2 deletions packages/nx/src/command-line/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import {
import { handleErrors } from '../utils/params';
import { connectToNxCloudCommand } from './connect-to-nx-cloud';
import { output } from '../utils/output';
import { messages, recordStat } from 'nx/src/utils/ab-testing';
import { nxVersion } from '../utils/versions';

export interface ResolvedMigrationConfiguration extends MigrationsJson {
packageGroup?: NxMigrationsConfiguration['packageGroup'];
Expand Down Expand Up @@ -815,9 +817,15 @@ async function generateMigrationsJsonAndUpdatePackageJson(
opts.targetVersion
))
) {
await connectToNxCloudCommand(
'We noticed you are migrating to a new major version, but are not taking advantage of Nx Cloud. Nx Cloud can make your CI up to 10 times faster. Learn more about it here: nx.app. Would you like to add it?'
const useCloud = await connectToNxCloudCommand(
messages.getPromptMessage('nxCloudMigration')
);
await recordStat({
command: 'migrate',
nxVersion,
useCloud,
meta: messages.codeOfSelectedPromptMessage('nxCloudMigration'),
});
originalPackageJson = readJsonFile<PackageJson>(
join(root, 'package.json')
);
Expand Down
83 changes: 83 additions & 0 deletions packages/nx/src/utils/ab-testing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import axios from 'axios';
import { isCI } from './is-ci';

export class PromptMessages {
private messages = {
nxCloudCreation: [
{
code: 'set-up-distributed-caching-ci',
message: `Enable distributed caching to make your CI faster`,
},
],
nxCloudMigration: [
{
code: 'we-noticed',
message: `We noticed you are migrating to a new major version, but are not taking advantage of Nx Cloud. Nx Cloud can make your CI up to 10 times faster. Learn more about it here: nx.app. Would you like to add it?`,
},
{
code: 'not-leveraging-caching',
message: `You're not leveraging distributed caching yet. Do you want to enable it and speed up your CI?`,
},
{
code: 'make-ci-faster',
message: `Enable distributed caching to make your CI faster?`,
},
],
};

private selectedMessages = {};

getPromptMessage(key: string): string {
if (this.selectedMessages[key] === undefined) {
if (process.env.NX_GENERATE_DOCS_PROCESS === 'true') {
this.selectedMessages[key] = 0;
} else {
this.selectedMessages[key] = Math.floor(
Math.random() * this.messages[key].length
);
}
}
return this.messages[key][this.selectedMessages[key]].message;
}

codeOfSelectedPromptMessage(key: string): string {
if (this.selectedMessages[key] === undefined) return null;
return this.messages[key][this.selectedMessages[key]].code;
}
}

export const messages = new PromptMessages();

/**
* We are incrementing a counter to track how often create-nx-workspace is used in CI
* vs dev environments. No personal information is collected.
*/
export async function recordStat(opts: {
command: string;
nxVersion: string;
useCloud: boolean;
meta: string;
}) {
try {
const major = Number(opts.nxVersion.split('.')[0]);
if (process.env.NX_VERBOSE_LOGGING === 'true') {
console.log(`Record stat. Major: ${major}`);
}
if (major < 10 || major > 14) return; // test version, skip it
await axios
.create({
baseURL: 'https://cloud.nx.app',
timeout: 400,
})
.post('/nx-cloud/stats', {
command: opts.command,
isCI: isCI(),
useCloud: opts.useCloud,
meta: opts.meta,
});
} catch (e) {
if (process.env.NX_VERBOSE_LOGGING === 'true') {
console.error(e);
}
}
}

0 comments on commit ce0fe45

Please sign in to comment.