From d32504cccaf803ec8a3ec9cb6a38b37584f31fa5 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 10 Feb 2022 15:49:14 +0100 Subject: [PATCH 1/9] cli: include version info and upgrade helper link in bump output Signed-off-by: Patrik Oldsberg --- .../cli/src/commands/versions/bump.test.ts | 4 +-- packages/cli/src/commands/versions/bump.ts | 31 ++++++++++++++----- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index 73ecc0284e..776523742c 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -273,7 +273,7 @@ describe('bump', () => { 'unlocking @backstage/core-api@^1.0.6 ~> 1.0.7', 'unlocking @backstage/core-api@^1.0.3 ~> 1.0.7', 'bumping @backstage/theme in b to ^5.0.0', - 'Creating backstage.json', + 'Your project is now at version 0.0.1, which has been written to backstage.json', 'Running yarn install to install new versions', '⚠️ The following packages may have breaking changes:', ' @backstage/theme : 1.0.0 ~> 5.0.0', @@ -389,7 +389,7 @@ describe('bump', () => { 'Some packages are outdated, updating', 'bumping @backstage/core in a to ^5.0.0', 'bumping @backstage/core in b to ^5.0.0', - 'Creating backstage.json', + 'Your project is now at version 2.0.0, which has been written to backstage.json', 'Running yarn install to install new versions', '⚠️ The following packages may have breaking changes:', ' @backstage/core : 1.0.3 ~> 5.0.0', diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index 8c3c661996..ceb8dbc79e 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -420,17 +420,32 @@ export async function bumpBackstageJsonVersion(version: string) { throw e; }); - if (backstageJson?.version === version) { + const prevVersion = backstageJson?.version; + + if (prevVersion === version) { return; } - console.log( - chalk.yellow( - typeof backstageJson === 'undefined' - ? `Creating ${BACKSTAGE_JSON}` - : `Bumping version in ${BACKSTAGE_JSON}`, - ), - ); + const { yellow, cyan, green } = chalk; + if (prevVersion) { + const link = `https://backstage.github.io/upgrade-helper/?from=${prevVersion}&to=${version}`; + console.log( + yellow( + `Upgraded from release ${green(prevVersion)} to ${green( + version, + )}, please review the app changes:`, + ), + ); + console.log(); + console.log(` ${cyan(link)}`); + console.log(); + } else { + console.log( + yellow( + `Your project is now at version ${version}, which has been written to ${BACKSTAGE_JSON}`, + ), + ); + } await fs.writeJson( backstageJsonPath, From 409e99684e9b2cc6a2e3ef9938182be9b5775d52 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 10 Feb 2022 17:00:08 +0100 Subject: [PATCH 2/9] cli: filter out npm_ env vars when running yarn install inside bump Signed-off-by: Patrik Oldsberg --- packages/cli/src/commands/versions/bump.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index ceb8dbc79e..a0e8185920 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -264,7 +264,16 @@ export default async (cmd: Command) => { `Running ${chalk.blue('yarn install')} to install new versions`, ); console.log(); - await run('yarn', ['install']); + await run('yarn', ['install'], { + env: { + FORCE_COLOR: 'true', + ...Object.fromEntries( + Object.entries(process.env).map(([name, value]) => + name.startsWith('npm_') ? [name, undefined] : [name, value], + ), + ), + }, + }); if (breakingUpdates.size > 0) { console.log(); From 2c83545ddaeb4c743b2bb67997e14fa3c132dea2 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 10 Feb 2022 17:37:48 +0100 Subject: [PATCH 3/9] cli: clean up yarn install output in versions bump Signed-off-by: Patrik Oldsberg --- .../cli/src/commands/versions/bump.test.ts | 37 +++++++++++++-- packages/cli/src/commands/versions/bump.ts | 47 +++++++++++++------ packages/cli/src/lib/logging.ts | 2 +- 3 files changed, 66 insertions(+), 20 deletions(-) diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index 776523742c..bba349fa8e 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -31,6 +31,7 @@ import { rest } from 'msw'; // Remove log coloring to simplify log matching jest.mock('chalk', () => ({ + red: (str: string) => str, blue: (str: string) => str, cyan: (str: string) => str, green: (str: string) => str, @@ -38,6 +39,18 @@ jest.mock('chalk', () => ({ yellow: (str: string) => str, })); +jest.mock('ora', () => ({ + __esModule: true, + default({ prefixText }: any) { + console.log(prefixText); + return { + start: () => ({ + succeed: () => {}, + }), + }; + }, +})); + const REGISTRY_VERSIONS: { [name: string]: string } = { '@backstage/core': '1.0.6', '@backstage/core-api': '1.0.7', @@ -177,7 +190,11 @@ describe('bump', () => { ); expect(runObj.run).toHaveBeenCalledTimes(1); - expect(runObj.run).toHaveBeenCalledWith('yarn', ['install']); + expect(runObj.run).toHaveBeenCalledWith( + 'yarn', + ['install'], + expect.any(Object), + ); const lockfileContents = await fs.readFile('/yarn.lock', 'utf8'); expect(lockfileContents).toBe(lockfileMockResult); @@ -296,7 +313,11 @@ describe('bump', () => { ); expect(runObj.run).toHaveBeenCalledTimes(1); - expect(runObj.run).toHaveBeenCalledWith('yarn', ['install']); + expect(runObj.run).toHaveBeenCalledWith( + 'yarn', + ['install'], + expect.any(Object), + ); const lockfileContents = await fs.readFile('/yarn.lock', 'utf8'); expect(lockfileContents).toBe(lockfileMockResult); @@ -398,7 +419,11 @@ describe('bump', () => { ]); expect(runObj.run).toHaveBeenCalledTimes(1); - expect(runObj.run).toHaveBeenCalledWith('yarn', ['install']); + expect(runObj.run).toHaveBeenCalledWith( + 'yarn', + ['install'], + expect.any(Object), + ); const packageA = await fs.readJson('/packages/a/package.json'); expect(packageA).toEqual({ @@ -645,7 +670,11 @@ describe('bump', () => { ); expect(runObj.run).toHaveBeenCalledTimes(1); - expect(runObj.run).toHaveBeenCalledWith('yarn', ['install']); + expect(runObj.run).toHaveBeenCalledWith( + 'yarn', + ['install'], + expect.any(Object), + ); const lockfileContents = await fs.readFile('/yarn.lock', 'utf8'); expect(lockfileContents).toEqual(customLockfileMockResult); diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index a0e8185920..b292bcd435 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -16,6 +16,7 @@ import fs from 'fs-extra'; import chalk from 'chalk'; +import ora from 'ora'; import semver from 'semver'; import minimatch from 'minimatch'; import { Command } from 'commander'; @@ -259,21 +260,8 @@ export default async (cmd: Command) => { ), ); } - console.log(); - console.log( - `Running ${chalk.blue('yarn install')} to install new versions`, - ); - console.log(); - await run('yarn', ['install'], { - env: { - FORCE_COLOR: 'true', - ...Object.fromEntries( - Object.entries(process.env).map(([name, value]) => - name.startsWith('npm_') ? [name, undefined] : [name, value], - ), - ), - }, - }); + + await runYarnInstall(); if (breakingUpdates.size > 0) { console.log(); @@ -465,3 +453,32 @@ export async function bumpBackstageJsonVersion(version: string) { }, ); } + +async function runYarnInstall() { + const spinner = ora({ + prefixText: `Running ${chalk.blue('yarn install')} to install new versions`, + spinner: 'arc', + color: 'green', + }).start(); + + const installOutput = new Array(); + try { + await run('yarn', ['install'], { + env: { + FORCE_COLOR: 'true', + ...Object.fromEntries( + Object.entries(process.env).map(([name, value]) => + name.startsWith('npm_') ? [name, undefined] : [name, value], + ), + ), + }, + stdoutLogFunc: data => installOutput.push(data), + stderrLogFunc: data => installOutput.push(data), + }); + spinner.succeed(); + } catch (error) { + spinner.fail(); + process.stdout.write(Buffer.concat(installOutput)); + throw error; + } +} diff --git a/packages/cli/src/lib/logging.ts b/packages/cli/src/lib/logging.ts index 8745585d1e..59473d7f64 100644 --- a/packages/cli/src/lib/logging.ts +++ b/packages/cli/src/lib/logging.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -export type LogFunc = (data: Buffer | string) => void; +export type LogFunc = (data: Buffer) => void; export type LogPipe = (dst: NodeJS.WriteStream) => LogFunc; export type LogOptions = { From e9ee1f91e113d65cbe8a04d5b5cd0ccf64e080f0 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 10 Feb 2022 17:48:00 +0100 Subject: [PATCH 4/9] cli: include the root package in set of packages to upgrade Signed-off-by: Patrik Oldsberg --- packages/cli/src/lib/versioning/packages.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/lib/versioning/packages.ts b/packages/cli/src/lib/versioning/packages.ts index 9f2f2bdc65..ed7266a692 100644 --- a/packages/cli/src/lib/versioning/packages.ts +++ b/packages/cli/src/lib/versioning/packages.ts @@ -67,7 +67,10 @@ export async function mapDependencies( targetDir: string, pattern: string, ): Promise> { - const { packages } = await getPackages(targetDir); + const { packages, root } = await getPackages(targetDir); + + // Include root package.json too + packages.push(root); const dependencyMap = new Map(); for (const pkg of packages) { From d2927cb5dcc449f780c4023e204ac7a1ba038f54 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 10 Feb 2022 17:51:59 +0100 Subject: [PATCH 5/9] cli: document yarn install workaround and tweak upgrade helper messaging Signed-off-by: Patrik Oldsberg --- packages/cli/src/commands/versions/bump.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index b292bcd435..315155ccee 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -430,7 +430,7 @@ export async function bumpBackstageJsonVersion(version: string) { yellow( `Upgraded from release ${green(prevVersion)} to ${green( version, - )}, please review the app changes:`, + )}, please review these template changes:`, ), ); console.log(); @@ -466,6 +466,9 @@ async function runYarnInstall() { await run('yarn', ['install'], { env: { FORCE_COLOR: 'true', + // We filter out all of the npm_* environment variables that are added when + // executing through yarn. This works around an issue where these variables + // incorrectly override local yarn or npm config in the project directory. ...Object.fromEntries( Object.entries(process.env).map(([name, value]) => name.startsWith('npm_') ? [name, undefined] : [name, value], From 46cedf1d7d42acb8cdd296af7669e70100bd7363 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 10 Feb 2022 17:57:02 +0100 Subject: [PATCH 6/9] cli: capture logs in backstage.json bump tests Signed-off-by: Patrik Oldsberg --- packages/cli/src/commands/versions/bump.test.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index bba349fa8e..d5736add99 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -794,8 +794,16 @@ describe('bumpBackstageJsonVersion', () => { .spyOn(paths, 'resolveTargetRoot') .mockImplementation((...path) => resolvePath('/', ...path)); - await bumpBackstageJsonVersion('1.4.1'); + const { log } = await withLogCollector(async () => { + await bumpBackstageJsonVersion('1.4.1'); + }); expect(await fs.readJson('/backstage.json')).toEqual({ version: '1.4.1' }); + expect(log).toEqual([ + 'Upgraded from release 0.0.1 to 1.4.1, please review these template changes:', + undefined, + ' https://backstage.github.io/upgrade-helper/?from=0.0.1&to=1.4.1', + undefined, + ]); }); it("should create backstage.json if doesn't exist", async () => { @@ -806,8 +814,13 @@ describe('bumpBackstageJsonVersion', () => { .spyOn(paths, 'resolveTargetRoot') .mockImplementation((...path) => resolvePath('/', ...path)); - await bumpBackstageJsonVersion(latest); + const { log } = await withLogCollector(async () => { + await bumpBackstageJsonVersion(latest); + }); expect(await fs.readJson('/backstage.json')).toEqual({ version: latest }); + expect(log).toEqual([ + 'Your project is now at version 1.4.1, which has been written to backstage.json', + ]); }); }); From 22862486def499fb51efc778ee0676a179ffc87e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 10 Feb 2022 18:02:15 +0100 Subject: [PATCH 7/9] changesets: added changesets for CLI versions:bump improvements Signed-off-by: Patrik Oldsberg --- .changeset/flat-crabs-smash.md | 5 +++++ .changeset/little-ravens-kick.md | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/flat-crabs-smash.md create mode 100644 .changeset/little-ravens-kick.md diff --git a/.changeset/flat-crabs-smash.md b/.changeset/flat-crabs-smash.md new file mode 100644 index 0000000000..b56b340605 --- /dev/null +++ b/.changeset/flat-crabs-smash.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +The `versions:bump` command now filters out `npm_` environment configuration when running `yarn install`. This has the effect of allowing it to consider local configuration files within the repository, which is the behavior that one would expect. diff --git a/.changeset/little-ravens-kick.md b/.changeset/little-ravens-kick.md new file mode 100644 index 0000000000..1e14f2f37e --- /dev/null +++ b/.changeset/little-ravens-kick.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +The `versions:bump` command now also considers the root `package.json` when searching for updates. It has also received updates to its output, including a link the [Backstage upgrade helper](https://backstage.github.io/upgrade-helper) and silenced `yarn install` output. From 4c69686cb91d455414ea95306543ae582b361c2d Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 11 Feb 2022 11:32:35 +0100 Subject: [PATCH 8/9] cli: encode versions in upgrade helper URL Signed-off-by: Patrik Oldsberg --- packages/cli/src/commands/versions/bump.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index 315155ccee..b9d318bccc 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -425,7 +425,9 @@ export async function bumpBackstageJsonVersion(version: string) { const { yellow, cyan, green } = chalk; if (prevVersion) { - const link = `https://backstage.github.io/upgrade-helper/?from=${prevVersion}&to=${version}`; + const from = encodeURIComponent(prevVersion); + const to = encodeURIComponent(version); + const link = `https://backstage.github.io/upgrade-helper/?from=${from}&to=${to}`; console.log( yellow( `Upgraded from release ${green(prevVersion)} to ${green( From 9417be6fdd5503022365b59586f9a8f4f055e113 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 11 Feb 2022 12:59:51 +0100 Subject: [PATCH 9/9] cli: update new bump test to match new output Signed-off-by: Patrik Oldsberg --- packages/cli/src/commands/versions/bump.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index d5736add99..e7b3c858aa 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -537,7 +537,7 @@ describe('bump', () => { 'unlocking @backstage/core-api@^1.0.6 ~> 1.0.7', 'unlocking @backstage/core-api@^1.0.3 ~> 1.0.7', 'bumping @backstage/theme in b to ^5.0.0', - 'Creating backstage.json', + 'Your project is now at version 1.0.0, which has been written to backstage.json', 'Running yarn install to install new versions', '⚠️ The following packages may have breaking changes:', ' @backstage/theme : 1.0.0 ~> 5.0.0',