From 476bb9411595cda8337353d0dbd6ffd17a95190a Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 19 Jan 2022 10:30:12 +0100 Subject: [PATCH 01/33] Initial release manifest package Signed-off-by: Johan Haals --- .changeset/config.json | 4 +- packages/cli/src/commands/index.ts | 5 + packages/cli/src/commands/versions/bump.ts | 27 ++-- packages/cli/src/lib/versioning/packages.ts | 2 +- packages/release-manifest/.eslintrc.js | 5 + packages/release-manifest/CHANGELOG.md | 1 + packages/release-manifest/README.md | 3 + packages/release-manifest/api-report.md | 12 ++ packages/release-manifest/package.json | 41 +++++++ packages/release-manifest/releases/1.0.0 | 115 ++++++++++++++++++ packages/release-manifest/src/index.ts | 21 ++++ .../release-manifest/src/manifest.test.ts | 9 ++ packages/release-manifest/src/manifest.ts | 57 +++++++++ 13 files changed, 293 insertions(+), 9 deletions(-) create mode 100644 packages/release-manifest/.eslintrc.js create mode 100644 packages/release-manifest/CHANGELOG.md create mode 100644 packages/release-manifest/README.md create mode 100644 packages/release-manifest/api-report.md create mode 100644 packages/release-manifest/package.json create mode 100644 packages/release-manifest/releases/1.0.0 create mode 100644 packages/release-manifest/src/index.ts create mode 100644 packages/release-manifest/src/manifest.test.ts create mode 100644 packages/release-manifest/src/manifest.ts diff --git a/.changeset/config.json b/.changeset/config.json index 283caa6ac4..33b69f3f1e 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -6,7 +6,9 @@ "access": "public", "baseBranch": "master", "updateInternalDependencies": "patch", - "ignore": [], + "ignore": [ + "@backstage/release-manifest" + ], "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { "onlyUpdatePeerDependentsWhenOutOfRange": true } diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 2211af1dda..280c90ece8 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -341,6 +341,11 @@ export function registerCommands(program: CommanderStatic) { '--pattern ', 'Override glob for matching packages to upgrade', ) + .option( + '--release-line ', + 'Bump to the latest version of a specific release line', + 'main', + ) .description('Bump Backstage packages to the latest versions') .action(lazy(() => import('./versions/bump').then(m => m.default))); diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index 0d7c1cdfae..bb719e7e48 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -60,7 +60,7 @@ export default async (cmd: Command) => { console.log(`Using custom pattern glob ${pattern}`); } - const findTargetVersion = createVersionFinder(); + const findTargetVersion = createVersionFinder(cmd.releaseLine); // First we discover all Backstage dependencies within our own repo const dependencyMap = await mapDependencies(paths.targetDir, pattern); @@ -284,7 +284,9 @@ export default async (cmd: Command) => { } }; -function createVersionFinder() { +function createVersionFinder(releaseLine = 'latest') { + // The main release line is just an alias for latest + const distTag = releaseLine === 'main' ? 'latest' : releaseLine; const found = new Map(); return async function findTargetVersion(name: string) { @@ -295,12 +297,23 @@ function createVersionFinder() { console.log(`Checking for updates of ${name}`); const info = await fetchPackageInfo(name); - const latest = info['dist-tags'].latest; - if (!latest) { - throw new Error(`No latest version found for ${name}`); + const latestVersion = info['dist-tags'].latest; + if (!latestVersion) { + throw new Error(`No target 'latest' version found for ${name}`); } - found.set(name, latest); - return latest; + if (distTag === 'latest') { + found.set(name, latestVersion); + return latestVersion; + } + const taggedVersion = info['dist-tags'][distTag]; + if (!taggedVersion) { + found.set(name, latestVersion); + return latestVersion; + } + + // Take release from latest of next release is older + found.set(name, targetVersion); + return targetVersion; }; } diff --git a/packages/cli/src/lib/versioning/packages.ts b/packages/cli/src/lib/versioning/packages.ts index 1dabec6032..9f2f2bdc65 100644 --- a/packages/cli/src/lib/versioning/packages.ts +++ b/packages/cli/src/lib/versioning/packages.ts @@ -28,7 +28,7 @@ const DEP_TYPES = [ // Package data as returned by `yarn info` export type YarnInfoInspectData = { name: string; - 'dist-tags': { latest: string }; + 'dist-tags': Record; versions: string[]; time: { [version: string]: string }; }; diff --git a/packages/release-manifest/.eslintrc.js b/packages/release-manifest/.eslintrc.js new file mode 100644 index 0000000000..a86d9806ad --- /dev/null +++ b/packages/release-manifest/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = { + extends: [ + require.resolve('@backstage/release-manifest/config/eslint.backend'), + ], +}; diff --git a/packages/release-manifest/CHANGELOG.md b/packages/release-manifest/CHANGELOG.md new file mode 100644 index 0000000000..28f83c41cd --- /dev/null +++ b/packages/release-manifest/CHANGELOG.md @@ -0,0 +1 @@ +# @backstage/release-manifest diff --git a/packages/release-manifest/README.md b/packages/release-manifest/README.md new file mode 100644 index 0000000000..ddbeed7dd0 --- /dev/null +++ b/packages/release-manifest/README.md @@ -0,0 +1,3 @@ +# @backstage/release-manifest + +This package provides a mapping between a Backstage release and the packages included in that release. diff --git a/packages/release-manifest/api-report.md b/packages/release-manifest/api-report.md new file mode 100644 index 0000000000..0837e05763 --- /dev/null +++ b/packages/release-manifest/api-report.md @@ -0,0 +1,12 @@ +## API Report File for "@backstage/release-manifest" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +// Warning: (ae-missing-release-tag) "releaseManifest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const releaseManifest: { + '@backstage/cli': string; +}; +``` diff --git a/packages/release-manifest/package.json b/packages/release-manifest/package.json new file mode 100644 index 0000000000..d530ac4df0 --- /dev/null +++ b/packages/release-manifest/package.json @@ -0,0 +1,41 @@ +{ + "name": "@backstage/release-manifest", + "description": "Package information for ", + "version": "0.0.0", + "private": false, + "main": "src/index.ts", + "types": "src/index.ts", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "packages/release-manifest" + }, + "keywords": [ + "backstage" + ], + "license": "Apache-2.0", + "scripts": { + "build": "backstage-cli build --outputs cjs,types", + "lint": "backstage-cli lint", + "test": "backstage-cli test", + "prepack": "backstage-cli prepack", + "postpack": "backstage-cli postpack", + "clean": "backstage-cli clean" + }, + "dependencies": { + "fs-extra": "^10.0.0" + }, + "devDependencies": { + "@types/jest": "^26.0.7", + "@types/node": "^14.14.32" + }, + "files": [ + "dist" + ] +} diff --git a/packages/release-manifest/releases/1.0.0 b/packages/release-manifest/releases/1.0.0 new file mode 100644 index 0000000000..9480d17aef --- /dev/null +++ b/packages/release-manifest/releases/1.0.0 @@ -0,0 +1,115 @@ +app-defaults=1.0.0 +backend-common=1.0.0 +backend-tasks=1.0.0 +backend-test-utils=1.0.0 +catalog-client=1.0.0 +catalog-model=1.0.0 +cli-common=1.0.0 +cli=1.0.0 +codemods=1.0.0 +config-loader=1.0.0 +config=1.0.0 +core-app-api=1.0.0 +core-components=1.0.0 +core-plugin-api=1.0.0 +create-app=1.0.0 +dev-utils=1.0.0 +errors=1.0.0 +integration-react=1.0.0 +integration=1.0.0 +plugin-airbrake=1.0.0 +plugin-allure=1.0.0 +plugin-analytics-module-ga=1.0.0 +plugin-apache-airflow=1.0.0 +plugin-api-docs=1.0.0 +plugin-app-backend=1.0.0 +plugin-auth-backend=1.0.0 +plugin-azure-devops-backend=1.0.0 +plugin-azure-devops-common=1.0.0 +plugin-azure-devops=1.0.0 +plugin-badges-backend=1.0.0 +plugin-badges=1.0.0 +plugin-bazaar-backend=1.0.0 +plugin-bazaar=1.0.0 +plugin-bitrise=1.0.0 +plugin-catalog-backend-module-ldap=1.0.0 +plugin-catalog-backend-module-msgraph=1.0.0 +plugin-catalog-backend=1.0.0 +plugin-catalog-common=1.0.0 +plugin-catalog-graph=1.0.0 +plugin-catalog-graphql=1.0.0 +plugin-catalog-import=1.0.0 +plugin-catalog-react=1.0.0 +plugin-catalog=1.0.0 +plugin-circleci=1.0.0 +plugin-cloudbuild=1.0.0 +plugin-code-coverage-backend=1.0.0 +plugin-code-coverage=1.0.0 +plugin-config-schema=1.0.0 +plugin-cost-insights=1.0.0 +plugin-explore-react=1.0.0 +plugin-explore=1.0.0 +plugin-firehydrant=1.0.0 +plugin-fossa=1.0.0 +plugin-gcp-projects=1.0.0 +plugin-git-release-manager=1.0.0 +plugin-github-actions=1.0.0 +plugin-github-deployments=1.0.0 +plugin-gitops-profiles=1.0.0 +plugin-gocd=1.0.0 +plugin-graphiql=1.0.0 +plugin-graphql-backend=1.0.0 +plugin-home=1.0.0 +plugin-ilert=1.0.0 +plugin-jenkins-backend=1.0.0 +plugin-jenkins=1.0.0 +plugin-kafka-backend=1.0.0 +plugin-kafka=1.0.0 +plugin-kubernetes-backend=1.0.0 +plugin-kubernetes-common=1.0.0 +plugin-kubernetes=1.0.0 +plugin-lighthouse=1.0.0 +plugin-newrelic-dashboard=1.0.0 +plugin-newrelic=1.0.0 +plugin-org=1.0.0 +plugin-pagerduty=1.0.0 +plugin-permission-backend=1.0.0 +plugin-permission-common=1.0.0 +plugin-permission-node=1.0.0 +plugin-permission-react=1.0.0 +plugin-proxy-backend=1.0.0 +plugin-rollbar-backend=1.0.0 +plugin-rollbar=1.0.0 +plugin-scaffolder-backend-module-cookiecutter=1.0.0 +plugin-scaffolder-backend-module-rails=1.0.0 +plugin-scaffolder-backend-module-yeoman=1.0.0 +plugin-scaffolder-backend=1.0.0 +plugin-scaffolder-common=1.0.0 +plugin-scaffolder=1.0.0 +plugin-search-backend-module-elasticsearch=1.0.0 +plugin-search-backend-module-pg=1.0.0 +plugin-search-backend-node=1.0.0 +plugin-search-backend=1.0.0 +plugin-search=1.0.0 +plugin-sentry=1.0.0 +plugin-shortcuts=1.0.0 +plugin-sonarqube=1.0.0 +plugin-splunk-on-call=1.0.0 +plugin-tech-insights-backend-module-jsonfc=1.0.0 +plugin-tech-insights-backend=1.0.0 +plugin-tech-insights-common=1.0.0 +plugin-tech-insights-node=1.0.0 +plugin-tech-insights=1.0.0 +plugin-tech-radar=1.0.0 +plugin-techdocs-backend=1.0.0 +plugin-techdocs=1.0.0 +plugin-todo-backend=1.0.0 +plugin-todo=1.0.0 +plugin-user-settings=1.0.0 +plugin-xcmetrics=1.0.0 +search-common=1.0.0 +techdocs-common=1.0.0 +test-utils=1.0.0 +theme=1.0.0 +types=1.0.0 +version-bridge=1.0.0 diff --git a/packages/release-manifest/src/index.ts b/packages/release-manifest/src/index.ts new file mode 100644 index 0000000000..099b146e78 --- /dev/null +++ b/packages/release-manifest/src/index.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Contains mapping between Backstage release and package versions. + * + * @packageDocumentation + */ diff --git a/packages/release-manifest/src/manifest.test.ts b/packages/release-manifest/src/manifest.test.ts new file mode 100644 index 0000000000..0c2005d1a8 --- /dev/null +++ b/packages/release-manifest/src/manifest.test.ts @@ -0,0 +1,9 @@ +import { getRelease } from './manifest'; + +describe('Get Packages', () => { + it('should return a list of packages in a release', async () => { + const pkgs = await getRelease('1.0.0'); + console.log(pkgs); + expect(pkgs.size).toBe(2); + }); +}); diff --git a/packages/release-manifest/src/manifest.ts b/packages/release-manifest/src/manifest.ts new file mode 100644 index 0000000000..07e3ec7cb7 --- /dev/null +++ b/packages/release-manifest/src/manifest.ts @@ -0,0 +1,57 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Mapping between a Backstage release and individual package versions. + * @public + */ +import { resolvePackagePath } from '@backstage/backend-common'; +import fs from 'fs-extra'; +import path from 'path'; + +const RELEASE_DIR = resolvePackagePath( + '@backstage/release-manifest', + 'releases', +); + +export type ReleaseManifest = { + packages: Map; +}; + +export async function getRelease(version: string): Promise { + const pkgs = new Map(); + try { + const content = await fs.readFile(path.resolve(RELEASE_DIR, `${version}`)); + for (const line of content.toString().split('\n')) { + const [pkg, version] = line.split('='); + pkgs.set(pkg, version); + } + } catch (e) { + throw new Error(`No release found for ${version} version`); + } + return { packages: pkgs }; +} + +export type ReleaseList = { + items: { + version: string; + }[]; +}; + +export async function listReleases(): Promise { + const files = await fs.readdir(RELEASE_DIR); + return { items: files.map(file => ({ version: file })) }; +} From 36cca38c61fdd71b76edc4a08aa1d2bceda788a1 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 19 Jan 2022 13:48:15 +0100 Subject: [PATCH 02/33] date compare release tracks, prefer latest Signed-off-by: Johan Haals --- packages/cli/src/commands/versions/bump.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index bb719e7e48..2371011be3 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -310,10 +310,18 @@ function createVersionFinder(releaseLine = 'latest') { found.set(name, latestVersion); return latestVersion; } + const latestVersionRelease = new Date(info.time[latestVersion]); + const taggedVersionRelease = new Date(info.time[taggedVersion]); + if (latestVersionRelease > taggedVersionRelease) { + console.log( + `using 'latest' dist tag for ${name} as its newer than '${distTag}'`, + ); + found.set(name, latestVersion); + return latestVersion; + } - // Take release from latest of next release is older - found.set(name, targetVersion); - return targetVersion; + found.set(name, taggedVersion); + return taggedVersion; }; } From 7c4e7b707c285cfe56ddb73b0e3235713f9e9da6 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Thu, 20 Jan 2022 11:13:55 +0100 Subject: [PATCH 03/33] cli/bump: Add tests for versionfinder Co-authored-by: Patrik Oldsberg Signed-off-by: Johan Haals --- .../cli/src/commands/versions/bump.test.ts | 92 ++++++++++++++++++- packages/cli/src/commands/versions/bump.ts | 36 +++++--- 2 files changed, 115 insertions(+), 13 deletions(-) diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index ae1a4c4627..a5c867fccd 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -20,8 +20,9 @@ import { Command } from 'commander'; import { resolve as resolvePath } from 'path'; import { paths } from '../../lib/paths'; import * as runObj from '../../lib/run'; -import bump, { bumpBackstageJsonVersion } from './bump'; +import bump, { bumpBackstageJsonVersion, createVersionFinder } from './bump'; import { withLogCollector } from '@backstage/test-utils'; +import { YarnInfoInspectData } from '../../lib/versioning/packages'; // Remove log coloring to simplify log matching jest.mock('chalk', () => ({ @@ -442,3 +443,92 @@ describe('bumpBackstageJsonVersion', () => { expect(json).toEqual({ version: '1.4.1' }); }); }); + +describe('createVersionFinder', () => { + async function findVersion(tag: string, data: Partial) { + const fetcher = () => + Promise.resolve({ + name: '@backstage/core', + 'dist-tags': {}, + versions: [], + time: {}, + ...data, + }); + + const versionFinder = createVersionFinder(tag, fetcher); + let result; + await withLogCollector(async () => { + result = await versionFinder('@backstage/core'); + }); + return result; + } + + it('should create version finder', async () => { + await expect( + findVersion('latest', { + time: { '1.0.0': '2020-01-01T00:00:00.000Z' }, + 'dist-tags': { latest: '1.0.0' }, + }), + ).resolves.toBe('1.0.0'); + + await expect( + findVersion('main', { + time: { '1.0.0': '2020-01-01T00:00:00.000Z' }, + 'dist-tags': { latest: '1.0.0' }, + }), + ).resolves.toBe('1.0.0'); + + await expect( + findVersion('next', { + time: { '1.0.0': '2020-01-01T00:00:00.000Z' }, + 'dist-tags': { latest: '1.0.0' }, + }), + ).resolves.toBe('1.0.0'); + + await expect( + findVersion('next', { + time: { + '1.0.0': '2020-01-01T00:00:00.000Z', + '0.9.0': '2010-01-01T00:00:00.000Z', + }, + 'dist-tags': { latest: '1.0.0', next: '0.9.0' }, + }), + ).resolves.toBe('1.0.0'); + + await expect( + findVersion('next', { + time: { + '1.0.0': '2020-01-01T00:00:00.000Z', + '0.9.0': '2020-02-01T00:00:00.000Z', + }, + 'dist-tags': { latest: '1.0.0', next: '0.9.0' }, + }), + ).resolves.toBe('0.9.0'); + + await expect(findVersion('next', {})).rejects.toThrow( + "No target 'latest' version found for @backstage/core", + ); + + await expect( + findVersion('next', { + time: { + '0.9.0': '2020-02-01T00:00:00.000Z', + }, + 'dist-tags': { latest: '1.0.0', next: '0.9.0' }, + }), + ).rejects.toThrow( + "No time available for version '1.0.0' of @backstage/core", + ); + + await expect( + findVersion('next', { + time: { + '1.0.0': '2020-01-01T00:00:00.000Z', + }, + 'dist-tags': { latest: '1.0.0', next: '0.9.0' }, + }), + ).rejects.toThrow( + "No time available for version '0.9.0' of @backstage/core", + ); + }); +}); diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index 2371011be3..af188cd472 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -284,7 +284,10 @@ export default async (cmd: Command) => { } }; -function createVersionFinder(releaseLine = 'latest') { +export function createVersionFinder( + releaseLine = 'latest', + packageInfoFetcher = fetchPackageInfo, +) { // The main release line is just an alias for latest const distTag = releaseLine === 'main' ? 'latest' : releaseLine; const found = new Map(); @@ -296,26 +299,35 @@ function createVersionFinder(releaseLine = 'latest') { } console.log(`Checking for updates of ${name}`); - const info = await fetchPackageInfo(name); + const info = await packageInfoFetcher(name); const latestVersion = info['dist-tags'].latest; if (!latestVersion) { throw new Error(`No target 'latest' version found for ${name}`); } - if (distTag === 'latest') { - found.set(name, latestVersion); - return latestVersion; - } + const taggedVersion = info['dist-tags'][distTag]; - if (!taggedVersion) { + if (distTag === 'latest' || !taggedVersion) { found.set(name, latestVersion); return latestVersion; } - const latestVersionRelease = new Date(info.time[latestVersion]); - const taggedVersionRelease = new Date(info.time[taggedVersion]); - if (latestVersionRelease > taggedVersionRelease) { - console.log( - `using 'latest' dist tag for ${name} as its newer than '${distTag}'`, + + const latestVersionDateStr = info.time[latestVersion]; + const taggedVersionDateStr = info.time[taggedVersion]; + if (!latestVersionDateStr) { + throw new Error( + `No time available for version '${latestVersion}' of ${name}`, ); + } + if (!taggedVersionDateStr) { + throw new Error( + `No time available for version '${taggedVersion}' of ${name}`, + ); + } + + const latestVersionRelease = new Date(latestVersionDateStr).getTime(); + const taggedVersionRelease = new Date(taggedVersionDateStr).getTime(); + if (latestVersionRelease > taggedVersionRelease) { + // Prefer latest version if it's newer. found.set(name, latestVersion); return latestVersion; } From 5cd75ebbea503e1cdb8b1264a1f3ee4adab93910 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 21 Jan 2022 14:14:58 +0100 Subject: [PATCH 04/33] fix eslint error Signed-off-by: Johan Haals --- packages/release-manifest/.eslintrc.js | 4 +--- packages/release-manifest/package.json | 7 +++++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/release-manifest/.eslintrc.js b/packages/release-manifest/.eslintrc.js index a86d9806ad..16a033dbc6 100644 --- a/packages/release-manifest/.eslintrc.js +++ b/packages/release-manifest/.eslintrc.js @@ -1,5 +1,3 @@ module.exports = { - extends: [ - require.resolve('@backstage/release-manifest/config/eslint.backend'), - ], + extends: [require.resolve('@backstage/cli/config/eslint.backend')], }; diff --git a/packages/release-manifest/package.json b/packages/release-manifest/package.json index d530ac4df0..4f2a25aa33 100644 --- a/packages/release-manifest/package.json +++ b/packages/release-manifest/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/release-manifest", "description": "Package information for ", - "version": "0.0.0", + "version": "0.0.1", "private": false, "main": "src/index.ts", "types": "src/index.ts", @@ -29,9 +29,12 @@ "clean": "backstage-cli clean" }, "dependencies": { - "fs-extra": "^10.0.0" + "fs-extra": "^10.0.0", + "node-fetch": "^2.6.1" }, "devDependencies": { + "@backstage/test-utils": "^0.2.3", + "msw": "^0.36.5", "@types/jest": "^26.0.7", "@types/node": "^14.14.32" }, From c2930c3b2cf88e62cdc83de246d7700954a277e7 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 21 Jan 2022 14:15:58 +0100 Subject: [PATCH 05/33] manifest: add getReleaseBy methods Signed-off-by: Johan Haals --- packages/release-manifest/src/index.ts | 3 + .../release-manifest/src/manifest.test.ts | 52 +++++++++++- packages/release-manifest/src/manifest.ts | 82 ++++++++++++------- 3 files changed, 104 insertions(+), 33 deletions(-) diff --git a/packages/release-manifest/src/index.ts b/packages/release-manifest/src/index.ts index 099b146e78..fa05520855 100644 --- a/packages/release-manifest/src/index.ts +++ b/packages/release-manifest/src/index.ts @@ -19,3 +19,6 @@ * * @packageDocumentation */ + +export { getByVersion, getByReleaseLine } from './manifest'; +export type { ReleaseManifest } from './manifest'; diff --git a/packages/release-manifest/src/manifest.test.ts b/packages/release-manifest/src/manifest.test.ts index 0c2005d1a8..a5c7235036 100644 --- a/packages/release-manifest/src/manifest.test.ts +++ b/packages/release-manifest/src/manifest.test.ts @@ -1,9 +1,53 @@ -import { getRelease } from './manifest'; +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { setupRequestMockHandlers } from '@backstage/test-utils'; +import { getByVersion } from './manifest'; +import { setupServer } from 'msw/node'; +import { rest } from 'msw'; describe('Get Packages', () => { + const worker = setupServer(); + setupRequestMockHandlers(worker); + it('should return a list of packages in a release', async () => { - const pkgs = await getRelease('1.0.0'); - console.log(pkgs); - expect(pkgs.size).toBe(2); + worker.use( + rest.get('*/v1/releases/0.0.0', (_, res, ctx) => + res( + ctx.status(200), + ctx.json({ + packages: [{ name: '@backstage/core', version: '1.2.3' }], + }), + ), + ), + rest.get('*/v1/releases/999.0.1', (_, res, ctx) => + res(ctx.status(404), ctx.json({})), + ), + ); + + const pkgs = await getByVersion({ version: '0.0.0' }); + expect(pkgs.packages).toEqual([ + { + name: '@backstage/core', + version: '1.2.3', + }, + ]); + + await expect(getByVersion({ version: '999.0.1' })).rejects.toThrow( + 'No release found for 999.0.1 version', + ); }); }); diff --git a/packages/release-manifest/src/manifest.ts b/packages/release-manifest/src/manifest.ts index 07e3ec7cb7..378ff41b7a 100644 --- a/packages/release-manifest/src/manifest.ts +++ b/packages/release-manifest/src/manifest.ts @@ -14,44 +14,68 @@ * limitations under the License. */ +import fetch from 'node-fetch'; + +const VERSIONS_DOMAIN = 'https://versions.backstage.io'; + /** - * Mapping between a Backstage release and individual package versions. + * Contains mapping between Backstage release and package versions. * @public */ -import { resolvePackagePath } from '@backstage/backend-common'; -import fs from 'fs-extra'; -import path from 'path'; - -const RELEASE_DIR = resolvePackagePath( - '@backstage/release-manifest', - 'releases', -); - export type ReleaseManifest = { - packages: Map; + packages: { name: string; version: string }[]; }; -export async function getRelease(version: string): Promise { - const pkgs = new Map(); - try { - const content = await fs.readFile(path.resolve(RELEASE_DIR, `${version}`)); - for (const line of content.toString().split('\n')) { - const [pkg, version] = line.split('='); - pkgs.set(pkg, version); - } - } catch (e) { - throw new Error(`No release found for ${version} version`); +/** + * Options for getByVersion. + */ +export type GetByVersionOptions = { + version: string; +}; + +/** + * Returns a release manifest based on supplied version. + * @public + */ +export async function getByVersion( + options: GetByVersionOptions, +): Promise { + const url = `${VERSIONS_DOMAIN}/v1/releases/${options.version}`; + const response = await fetch(url); + if (response.status === 404) { + throw new Error(`No release found for ${options.version} version`); } - return { packages: pkgs }; + if (response.status !== 200) { + throw new Error( + `Unexpected response status ${response.status} when fetching release from ${url}.`, + ); + } + return await response.json(); } -export type ReleaseList = { - items: { - version: string; - }[]; +/** + * Options for getByReleaseLine. + */ +export type GetByReleaseLineOptions = { + releaseLine: string; }; -export async function listReleases(): Promise { - const files = await fs.readdir(RELEASE_DIR); - return { items: files.map(file => ({ version: file })) }; +/** + * Returns a release manifest based on supplied release line. + * @public + */ +export async function getByReleaseLine( + options: GetByReleaseLineOptions, +): Promise { + const url = `${VERSIONS_DOMAIN}/v1/tags/${options.releaseLine}`; + const response = await fetch(url); + if (response.status === 404) { + throw new Error(`No '${options.releaseLine}' release line found`); + } + if (response.status !== 200) { + throw new Error( + `Unexpected response status ${response.status} when fetching release from ${url}.`, + ); + } + return await response.json(); } From 061393a964a018cdbd4909070d7b71664cb4cc50 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 21 Jan 2022 14:17:50 +0100 Subject: [PATCH 06/33] Pass releaseManifest to versionFinder Signed-off-by: Johan Haals --- packages/cli/package.json | 1 + packages/cli/src/commands/index.ts | 5 +- packages/cli/src/commands/versions/bump.ts | 46 +++++++-- packages/release-manifest/releases/1.0.0 | 115 --------------------- 4 files changed, 45 insertions(+), 122 deletions(-) delete mode 100644 packages/release-manifest/releases/1.0.0 diff --git a/packages/cli/package.json b/packages/cli/package.json index 0f6c521ec4..cf0f79720c 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -32,6 +32,7 @@ "@backstage/config": "^0.1.13", "@backstage/config-loader": "^0.9.3", "@backstage/errors": "^0.2.0", + "@backstage/release-manifest": "^0.0.1", "@backstage/types": "^0.1.1", "@hot-loader/react-dom": "^16.13.0", "@manypkg/get-packages": "^1.1.3", diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 280c90ece8..b1fce377f5 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -344,7 +344,10 @@ export function registerCommands(program: CommanderStatic) { .option( '--release-line ', 'Bump to the latest version of a specific release line', - 'main', + ) + .option( + '--backstage-release ', + 'Bump to a specific Backstage release', ) .description('Bump Backstage packages to the latest versions') .action(lazy(() => import('./versions/bump').then(m => m.default))); diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index af188cd472..31e424dd6d 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -27,10 +27,16 @@ import { mapDependencies, fetchPackageInfo, Lockfile, + YarnInfoInspectData, } from '../../lib/versioning'; import { forbiddenDuplicatesFilter } from './lint'; import { BACKSTAGE_JSON } from '@backstage/cli-common'; import { runParallelWorkers } from '../../lib/parallel'; +import { + getByReleaseLine, + getByVersion, + ReleaseManifest, +} from '@backstage/release-manifest'; const DEP_TYPES = [ 'dependencies', @@ -60,7 +66,22 @@ export default async (cmd: Command) => { console.log(`Using custom pattern glob ${pattern}`); } - const findTargetVersion = createVersionFinder(cmd.releaseLine); + if (cmd.releaseLine && cmd.backstageRelease) { + throw new Error( + 'Cannot specify both --release-line and --backstage-release', + ); + } + + let releaseManifest; + if (cmd.backstageRelease) { + releaseManifest = await getByVersion({ version: cmd.backstageRelease }); + } else if (cmd.releaseLine) { + releaseManifest = await getByReleaseLine({ releaseLine: cmd.releaseLine }); + } + const findTargetVersion = createVersionFinder({ + releaseLine: cmd.releaseLine, + releaseManifest, + }); // First we discover all Backstage dependencies within our own repo const dependencyMap = await mapDependencies(paths.targetDir, pattern); @@ -284,14 +305,22 @@ export default async (cmd: Command) => { } }; -export function createVersionFinder( - releaseLine = 'latest', - packageInfoFetcher = fetchPackageInfo, -) { +export function createVersionFinder(options: { + releaseLine?: string; + packageInfoFetcher?: () => Promise; + releaseManifest?: ReleaseManifest; +}) { + const { + releaseLine = 'latest', + packageInfoFetcher = fetchPackageInfo, + releaseManifest, + } = options; // The main release line is just an alias for latest const distTag = releaseLine === 'main' ? 'latest' : releaseLine; const found = new Map(); - + const releasePackages = new Map( + releaseManifest?.packages.map(p => [p.name, p.version]), + ); return async function findTargetVersion(name: string) { const existing = found.get(name); if (existing) { @@ -299,6 +328,11 @@ export function createVersionFinder( } console.log(`Checking for updates of ${name}`); + const manifestVersion = releasePackages.get(name); + if (manifestVersion) { + return manifestVersion; + } + const info = await packageInfoFetcher(name); const latestVersion = info['dist-tags'].latest; if (!latestVersion) { diff --git a/packages/release-manifest/releases/1.0.0 b/packages/release-manifest/releases/1.0.0 deleted file mode 100644 index 9480d17aef..0000000000 --- a/packages/release-manifest/releases/1.0.0 +++ /dev/null @@ -1,115 +0,0 @@ -app-defaults=1.0.0 -backend-common=1.0.0 -backend-tasks=1.0.0 -backend-test-utils=1.0.0 -catalog-client=1.0.0 -catalog-model=1.0.0 -cli-common=1.0.0 -cli=1.0.0 -codemods=1.0.0 -config-loader=1.0.0 -config=1.0.0 -core-app-api=1.0.0 -core-components=1.0.0 -core-plugin-api=1.0.0 -create-app=1.0.0 -dev-utils=1.0.0 -errors=1.0.0 -integration-react=1.0.0 -integration=1.0.0 -plugin-airbrake=1.0.0 -plugin-allure=1.0.0 -plugin-analytics-module-ga=1.0.0 -plugin-apache-airflow=1.0.0 -plugin-api-docs=1.0.0 -plugin-app-backend=1.0.0 -plugin-auth-backend=1.0.0 -plugin-azure-devops-backend=1.0.0 -plugin-azure-devops-common=1.0.0 -plugin-azure-devops=1.0.0 -plugin-badges-backend=1.0.0 -plugin-badges=1.0.0 -plugin-bazaar-backend=1.0.0 -plugin-bazaar=1.0.0 -plugin-bitrise=1.0.0 -plugin-catalog-backend-module-ldap=1.0.0 -plugin-catalog-backend-module-msgraph=1.0.0 -plugin-catalog-backend=1.0.0 -plugin-catalog-common=1.0.0 -plugin-catalog-graph=1.0.0 -plugin-catalog-graphql=1.0.0 -plugin-catalog-import=1.0.0 -plugin-catalog-react=1.0.0 -plugin-catalog=1.0.0 -plugin-circleci=1.0.0 -plugin-cloudbuild=1.0.0 -plugin-code-coverage-backend=1.0.0 -plugin-code-coverage=1.0.0 -plugin-config-schema=1.0.0 -plugin-cost-insights=1.0.0 -plugin-explore-react=1.0.0 -plugin-explore=1.0.0 -plugin-firehydrant=1.0.0 -plugin-fossa=1.0.0 -plugin-gcp-projects=1.0.0 -plugin-git-release-manager=1.0.0 -plugin-github-actions=1.0.0 -plugin-github-deployments=1.0.0 -plugin-gitops-profiles=1.0.0 -plugin-gocd=1.0.0 -plugin-graphiql=1.0.0 -plugin-graphql-backend=1.0.0 -plugin-home=1.0.0 -plugin-ilert=1.0.0 -plugin-jenkins-backend=1.0.0 -plugin-jenkins=1.0.0 -plugin-kafka-backend=1.0.0 -plugin-kafka=1.0.0 -plugin-kubernetes-backend=1.0.0 -plugin-kubernetes-common=1.0.0 -plugin-kubernetes=1.0.0 -plugin-lighthouse=1.0.0 -plugin-newrelic-dashboard=1.0.0 -plugin-newrelic=1.0.0 -plugin-org=1.0.0 -plugin-pagerduty=1.0.0 -plugin-permission-backend=1.0.0 -plugin-permission-common=1.0.0 -plugin-permission-node=1.0.0 -plugin-permission-react=1.0.0 -plugin-proxy-backend=1.0.0 -plugin-rollbar-backend=1.0.0 -plugin-rollbar=1.0.0 -plugin-scaffolder-backend-module-cookiecutter=1.0.0 -plugin-scaffolder-backend-module-rails=1.0.0 -plugin-scaffolder-backend-module-yeoman=1.0.0 -plugin-scaffolder-backend=1.0.0 -plugin-scaffolder-common=1.0.0 -plugin-scaffolder=1.0.0 -plugin-search-backend-module-elasticsearch=1.0.0 -plugin-search-backend-module-pg=1.0.0 -plugin-search-backend-node=1.0.0 -plugin-search-backend=1.0.0 -plugin-search=1.0.0 -plugin-sentry=1.0.0 -plugin-shortcuts=1.0.0 -plugin-sonarqube=1.0.0 -plugin-splunk-on-call=1.0.0 -plugin-tech-insights-backend-module-jsonfc=1.0.0 -plugin-tech-insights-backend=1.0.0 -plugin-tech-insights-common=1.0.0 -plugin-tech-insights-node=1.0.0 -plugin-tech-insights=1.0.0 -plugin-tech-radar=1.0.0 -plugin-techdocs-backend=1.0.0 -plugin-techdocs=1.0.0 -plugin-todo-backend=1.0.0 -plugin-todo=1.0.0 -plugin-user-settings=1.0.0 -plugin-xcmetrics=1.0.0 -search-common=1.0.0 -techdocs-common=1.0.0 -test-utils=1.0.0 -theme=1.0.0 -types=1.0.0 -version-bridge=1.0.0 From 415316302bac5450380ea80ce7f59a067ea37e45 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 21 Jan 2022 14:52:15 +0100 Subject: [PATCH 07/33] Update paths, remove exclude Signed-off-by: Johan Haals --- .changeset/config.json | 4 +--- packages/release-manifest/package.json | 2 +- packages/release-manifest/src/manifest.ts | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.changeset/config.json b/.changeset/config.json index 33b69f3f1e..283caa6ac4 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -6,9 +6,7 @@ "access": "public", "baseBranch": "master", "updateInternalDependencies": "patch", - "ignore": [ - "@backstage/release-manifest" - ], + "ignore": [], "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { "onlyUpdatePeerDependentsWhenOutOfRange": true } diff --git a/packages/release-manifest/package.json b/packages/release-manifest/package.json index 4f2a25aa33..896f226612 100644 --- a/packages/release-manifest/package.json +++ b/packages/release-manifest/package.json @@ -34,7 +34,7 @@ }, "devDependencies": { "@backstage/test-utils": "^0.2.3", - "msw": "^0.36.5", + "msw": "^0.35.0", "@types/jest": "^26.0.7", "@types/node": "^14.14.32" }, diff --git a/packages/release-manifest/src/manifest.ts b/packages/release-manifest/src/manifest.ts index 378ff41b7a..3123f99808 100644 --- a/packages/release-manifest/src/manifest.ts +++ b/packages/release-manifest/src/manifest.ts @@ -40,7 +40,7 @@ export type GetByVersionOptions = { export async function getByVersion( options: GetByVersionOptions, ): Promise { - const url = `${VERSIONS_DOMAIN}/v1/releases/${options.version}`; + const url = `${VERSIONS_DOMAIN}/v1/releases/${options.version}/manifest.json`; const response = await fetch(url); if (response.status === 404) { throw new Error(`No release found for ${options.version} version`); @@ -67,7 +67,7 @@ export type GetByReleaseLineOptions = { export async function getByReleaseLine( options: GetByReleaseLineOptions, ): Promise { - const url = `${VERSIONS_DOMAIN}/v1/tags/${options.releaseLine}`; + const url = `${VERSIONS_DOMAIN}/v1/tags/${options.releaseLine}/manifest.json`; const response = await fetch(url); if (response.status === 404) { throw new Error(`No '${options.releaseLine}' release line found`); From 2b92120edb4ce3cadd9f808a1e288ef2b029e132 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 21 Jan 2022 15:07:03 +0100 Subject: [PATCH 08/33] Add missing export Signed-off-by: Johan Haals --- packages/release-manifest/api-report.md | 33 ++++++++++++++++++++++--- packages/release-manifest/src/index.ts | 6 ++++- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/packages/release-manifest/api-report.md b/packages/release-manifest/api-report.md index 0837e05763..4f1840403f 100644 --- a/packages/release-manifest/api-report.md +++ b/packages/release-manifest/api-report.md @@ -3,10 +3,35 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -// Warning: (ae-missing-release-tag) "releaseManifest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// @public +export function getByReleaseLine( + options: GetByReleaseLineOptions, +): Promise; + +// Warning: (ae-missing-release-tag) "GetByReleaseLineOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) -export const releaseManifest: { - '@backstage/cli': string; +// @public +export type GetByReleaseLineOptions = { + releaseLine: string; +}; + +// @public +export function getByVersion( + options: GetByVersionOptions, +): Promise; + +// Warning: (ae-missing-release-tag) "GetByVersionOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type GetByVersionOptions = { + version: string; +}; + +// @public +export type ReleaseManifest = { + packages: { + name: string; + version: string; + }[]; }; ``` diff --git a/packages/release-manifest/src/index.ts b/packages/release-manifest/src/index.ts index fa05520855..25101d4cbf 100644 --- a/packages/release-manifest/src/index.ts +++ b/packages/release-manifest/src/index.ts @@ -21,4 +21,8 @@ */ export { getByVersion, getByReleaseLine } from './manifest'; -export type { ReleaseManifest } from './manifest'; +export type { + ReleaseManifest, + GetByReleaseLineOptions, + GetByVersionOptions, +} from './manifest'; From 0e09335809e17d64dbcf4f9831ebd826d1660900 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 21 Jan 2022 15:08:57 +0100 Subject: [PATCH 09/33] fix missing annotations Signed-off-by: Johan Haals --- packages/release-manifest/api-report.md | 4 ---- packages/release-manifest/src/manifest.ts | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/release-manifest/api-report.md b/packages/release-manifest/api-report.md index 4f1840403f..6cafdaf2a2 100644 --- a/packages/release-manifest/api-report.md +++ b/packages/release-manifest/api-report.md @@ -8,8 +8,6 @@ export function getByReleaseLine( options: GetByReleaseLineOptions, ): Promise; -// Warning: (ae-missing-release-tag) "GetByReleaseLineOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type GetByReleaseLineOptions = { releaseLine: string; @@ -20,8 +18,6 @@ export function getByVersion( options: GetByVersionOptions, ): Promise; -// Warning: (ae-missing-release-tag) "GetByVersionOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type GetByVersionOptions = { version: string; diff --git a/packages/release-manifest/src/manifest.ts b/packages/release-manifest/src/manifest.ts index 3123f99808..1120073afb 100644 --- a/packages/release-manifest/src/manifest.ts +++ b/packages/release-manifest/src/manifest.ts @@ -28,6 +28,7 @@ export type ReleaseManifest = { /** * Options for getByVersion. + * @public */ export type GetByVersionOptions = { version: string; @@ -55,6 +56,7 @@ export async function getByVersion( /** * Options for getByReleaseLine. + * @public */ export type GetByReleaseLineOptions = { releaseLine: string; From cbf43cee68d24a1892e534b81cc7971c2593b755 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 21 Jan 2022 15:12:55 +0100 Subject: [PATCH 10/33] Remove unused dependencies Signed-off-by: Johan Haals --- packages/release-manifest/package.json | 1 - yarn.lock | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/release-manifest/package.json b/packages/release-manifest/package.json index 896f226612..7ba37f121d 100644 --- a/packages/release-manifest/package.json +++ b/packages/release-manifest/package.json @@ -29,7 +29,6 @@ "clean": "backstage-cli clean" }, "dependencies": { - "fs-extra": "^10.0.0", "node-fetch": "^2.6.1" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 3f7b855e74..1d768dcb66 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12304,7 +12304,7 @@ fs-constants@^1.0.0: resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@10.0.0, fs-extra@^10.0.0: +fs-extra@10.0.0: version "10.0.0" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== From aeb5c69abb75e6bd1519bfddc3f7aa76e0f8fa82 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 21 Jan 2022 15:27:12 +0100 Subject: [PATCH 11/33] Add changesets Signed-off-by: Johan Haals --- .changeset/cold-houses-type.md | 7 +++++++ .changeset/green-peaches-explode.md | 6 ++++++ packages/release-manifest/package.json | 4 ++-- 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 .changeset/cold-houses-type.md create mode 100644 .changeset/green-peaches-explode.md diff --git a/.changeset/cold-houses-type.md b/.changeset/cold-houses-type.md new file mode 100644 index 0000000000..6aa466755d --- /dev/null +++ b/.changeset/cold-houses-type.md @@ -0,0 +1,7 @@ +--- +'@backstage/cli': patch +--- + +Introduces two new parameters to the `backstage-cli versions:bump` command. +The first one is `--release-line ` bump packages to the latest `main` or `next` release. +`--backstage-release ` is used to bump packages to a specific backstage release. diff --git a/.changeset/green-peaches-explode.md b/.changeset/green-peaches-explode.md new file mode 100644 index 0000000000..c28c9f6e75 --- /dev/null +++ b/.changeset/green-peaches-explode.md @@ -0,0 +1,6 @@ +--- +'@backstage/release-manifest': patch +--- + +Introduces a new release-manifest package with utilities for fetching release manifests. +This package will primarily be used by the `@backstage/cli` package. diff --git a/packages/release-manifest/package.json b/packages/release-manifest/package.json index 7ba37f121d..ffa201ae4a 100644 --- a/packages/release-manifest/package.json +++ b/packages/release-manifest/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/release-manifest", - "description": "Package information for ", - "version": "0.0.1", + "description": "Helper library for receiving release manifests", + "version": "0.0.0", "private": false, "main": "src/index.ts", "types": "src/index.ts", From 79b08b5fe3173bb2ca0c53e7e21f7f6b6f949596 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 24 Jan 2022 09:17:50 +0100 Subject: [PATCH 12/33] Use correct package version Signed-off-by: Johan Haals --- packages/cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index cf0f79720c..dbcab6fbc7 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -32,7 +32,7 @@ "@backstage/config": "^0.1.13", "@backstage/config-loader": "^0.9.3", "@backstage/errors": "^0.2.0", - "@backstage/release-manifest": "^0.0.1", + "@backstage/release-manifest": "^0.0.0", "@backstage/types": "^0.1.1", "@hot-loader/react-dom": "^16.13.0", "@manypkg/get-packages": "^1.1.3", From d9327ae0783d601aa18e51260360a99937c8c362 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 24 Jan 2022 10:40:33 +0100 Subject: [PATCH 13/33] cli: fix tests Signed-off-by: Johan Haals --- packages/cli/src/commands/versions/bump.test.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index a5c867fccd..ed1fc62380 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -455,7 +455,10 @@ describe('createVersionFinder', () => { ...data, }); - const versionFinder = createVersionFinder(tag, fetcher); + const versionFinder = createVersionFinder({ + releaseLine: tag, + packageInfoFetcher: fetcher, + }); let result; await withLogCollector(async () => { result = await versionFinder('@backstage/core'); From 714895e91bcf5813c2d34d8eaa1a8f7458f11622 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 24 Jan 2022 14:36:43 +0100 Subject: [PATCH 14/33] fix tests Signed-off-by: Johan Haals --- packages/release-manifest/src/manifest.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/release-manifest/src/manifest.test.ts b/packages/release-manifest/src/manifest.test.ts index a5c7235036..3ae71fe05b 100644 --- a/packages/release-manifest/src/manifest.test.ts +++ b/packages/release-manifest/src/manifest.test.ts @@ -25,7 +25,7 @@ describe('Get Packages', () => { it('should return a list of packages in a release', async () => { worker.use( - rest.get('*/v1/releases/0.0.0', (_, res, ctx) => + rest.get('*/v1/releases/0.0.0/manifest.json', (_, res, ctx) => res( ctx.status(200), ctx.json({ @@ -33,7 +33,7 @@ describe('Get Packages', () => { }), ), ), - rest.get('*/v1/releases/999.0.1', (_, res, ctx) => + rest.get('*/v1/releases/999.0.1/manifest.json', (_, res, ctx) => res(ctx.status(404), ctx.json({})), ), ); From dc4b7d4778beb184521d99e89644375bc4172f4d Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 24 Jan 2022 14:40:22 +0100 Subject: [PATCH 15/33] Add more tests Signed-off-by: Johan Haals --- .../release-manifest/src/manifest.test.ts | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/packages/release-manifest/src/manifest.test.ts b/packages/release-manifest/src/manifest.test.ts index 3ae71fe05b..e6f353f912 100644 --- a/packages/release-manifest/src/manifest.test.ts +++ b/packages/release-manifest/src/manifest.test.ts @@ -18,8 +18,9 @@ import { setupRequestMockHandlers } from '@backstage/test-utils'; import { getByVersion } from './manifest'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; +import { getByReleaseLine } from '.'; -describe('Get Packages', () => { +describe('getByVersion', () => { const worker = setupServer(); setupRequestMockHandlers(worker); @@ -51,3 +52,36 @@ describe('Get Packages', () => { ); }); }); + +describe('getByReleaseLine', () => { + const worker = setupServer(); + setupRequestMockHandlers(worker); + + it('should return a list of packages in a release', async () => { + worker.use( + rest.get('*/v1/tags/main/manifest.json', (_, res, ctx) => + res( + ctx.status(200), + ctx.json({ + packages: [{ name: '@backstage/core', version: '1.2.3' }], + }), + ), + ), + rest.get('*/v1/tags/foo/manifest.json', (_, res, ctx) => + res(ctx.status(404), ctx.json({})), + ), + ); + + const pkgs = await getByReleaseLine({ releaseLine: 'main' }); + expect(pkgs.packages).toEqual([ + { + name: '@backstage/core', + version: '1.2.3', + }, + ]); + + await expect(getByReleaseLine({ releaseLine: 'foo' })).rejects.toThrow( + "No 'foo' release line found", + ); + }); +}); From 1ecfb1614ba0e09b6006fa022d358e8c646ecf50 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 25 Jan 2022 08:57:57 +0100 Subject: [PATCH 16/33] update yarn.lock Signed-off-by: Johan Haals --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 1d768dcb66..3f7b855e74 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12304,7 +12304,7 @@ fs-constants@^1.0.0: resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@10.0.0: +fs-extra@10.0.0, fs-extra@^10.0.0: version "10.0.0" resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== From aa15e9ae2bac8ad5b307f46c24e562740050f52c Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 25 Jan 2022 16:06:54 +0100 Subject: [PATCH 17/33] Add releaseVersion to manifest Signed-off-by: Johan Haals --- packages/release-manifest/src/manifest.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/release-manifest/src/manifest.ts b/packages/release-manifest/src/manifest.ts index 1120073afb..564809fdee 100644 --- a/packages/release-manifest/src/manifest.ts +++ b/packages/release-manifest/src/manifest.ts @@ -23,6 +23,7 @@ const VERSIONS_DOMAIN = 'https://versions.backstage.io'; * @public */ export type ReleaseManifest = { + releaseVersion: string; packages: { name: string; version: string }[]; }; @@ -41,7 +42,9 @@ export type GetByVersionOptions = { export async function getByVersion( options: GetByVersionOptions, ): Promise { - const url = `${VERSIONS_DOMAIN}/v1/releases/${options.version}/manifest.json`; + const url = `${VERSIONS_DOMAIN}/v1/releases/${encodeURIComponent( + options.version, + )}/manifest.json`; const response = await fetch(url); if (response.status === 404) { throw new Error(`No release found for ${options.version} version`); @@ -69,7 +72,9 @@ export type GetByReleaseLineOptions = { export async function getByReleaseLine( options: GetByReleaseLineOptions, ): Promise { - const url = `${VERSIONS_DOMAIN}/v1/tags/${options.releaseLine}/manifest.json`; + const url = `${VERSIONS_DOMAIN}/v1/tags/${encodeURIComponent( + options.releaseLine, + )}/manifest.json`; const response = await fetch(url); if (response.status === 404) { throw new Error(`No '${options.releaseLine}' release line found`); From ba6c626d09e3d439f5b6e788d00a2ea57328582e Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 25 Jan 2022 16:20:35 +0100 Subject: [PATCH 18/33] combine bump arguments Signed-off-by: Johan Haals --- packages/cli/src/commands/index.ts | 9 ++-- packages/cli/src/commands/versions/bump.ts | 49 ++++++++++++++-------- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index b1fce377f5..770d216ba2 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -342,12 +342,9 @@ export function registerCommands(program: CommanderStatic) { 'Override glob for matching packages to upgrade', ) .option( - '--release-line ', - 'Bump to the latest version of a specific release line', - ) - .option( - '--backstage-release ', - 'Bump to a specific Backstage release', + '--release ', + 'Bump to a specific Backstage release line or version', + 'main', ) .description('Bump Backstage packages to the latest versions') .action(lazy(() => import('./versions/bump').then(m => m.default))); diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index 31e424dd6d..a7ce942af7 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -19,7 +19,7 @@ import chalk from 'chalk'; import semver from 'semver'; import minimatch from 'minimatch'; import { Command } from 'commander'; -import { isError } from '@backstage/errors'; +import { isError, NotFoundError } from '@backstage/errors'; import { resolve as resolvePath } from 'path'; import { run } from '../../lib/run'; import { paths } from '../../lib/paths'; @@ -66,23 +66,20 @@ export default async (cmd: Command) => { console.log(`Using custom pattern glob ${pattern}`); } - if (cmd.releaseLine && cmd.backstageRelease) { - throw new Error( - 'Cannot specify both --release-line and --backstage-release', - ); + let findTargetVersion: (name: string) => Promise; + if (semver.valid(cmd.release)) { + findTargetVersion = createStrictVersionFinder({ + releaseManifest: await getByVersion({ version: cmd.release }), + }); + } else { + findTargetVersion = createVersionFinder({ + releaseLine: cmd.releaseLine, + releaseManifest: await getByReleaseLine({ + releaseLine: cmd.release, + }), + }); } - let releaseManifest; - if (cmd.backstageRelease) { - releaseManifest = await getByVersion({ version: cmd.backstageRelease }); - } else if (cmd.releaseLine) { - releaseManifest = await getByReleaseLine({ releaseLine: cmd.releaseLine }); - } - const findTargetVersion = createVersionFinder({ - releaseLine: cmd.releaseLine, - releaseManifest, - }); - // First we discover all Backstage dependencies within our own repo const dependencyMap = await mapDependencies(paths.targetDir, pattern); @@ -305,10 +302,26 @@ export default async (cmd: Command) => { } }; +export function createStrictVersionFinder(options: { + releaseManifest: ReleaseManifest; +}) { + const releasePackages = new Map( + options.releaseManifest.packages.map(p => [p.name, p.version]), + ); + return async function findTargetVersion(name: string) { + console.log(`Checking for updates of ${name}`); + const manifestVersion = releasePackages.get(name); + if (manifestVersion) { + return manifestVersion; + } + throw new NotFoundError(`Package ${name} not found in release manifest`); + }; +} + export function createVersionFinder(options: { releaseLine?: string; packageInfoFetcher?: () => Promise; - releaseManifest?: ReleaseManifest; + releaseManifest: ReleaseManifest; }) { const { releaseLine = 'latest', @@ -319,7 +332,7 @@ export function createVersionFinder(options: { const distTag = releaseLine === 'main' ? 'latest' : releaseLine; const found = new Map(); const releasePackages = new Map( - releaseManifest?.packages.map(p => [p.name, p.version]), + releaseManifest.packages.map(p => [p.name, p.version]), ); return async function findTargetVersion(name: string) { const existing = found.get(name); From fc65c6cd9eef760b0a9838866e060d2065f2e80e Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 25 Jan 2022 16:39:50 +0100 Subject: [PATCH 19/33] Rename pkg, make isomorphic Signed-off-by: Johan Haals --- packages/cli/package.json | 2 +- packages/cli/src/commands/versions/bump.ts | 6 +++--- packages/release-manifest/CHANGELOG.md | 1 - .../{release-manifest => release-manifests}/.eslintrc.js | 0 packages/release-manifests/CHANGELOG.md | 1 + .../{release-manifest => release-manifests}/README.md | 0 .../api-report.md | 0 .../{release-manifest => release-manifests}/package.json | 9 +++++---- .../{release-manifest => release-manifests}/src/index.ts | 0 .../src/manifest.test.ts | 0 .../src/manifest.ts | 2 +- 11 files changed, 11 insertions(+), 10 deletions(-) delete mode 100644 packages/release-manifest/CHANGELOG.md rename packages/{release-manifest => release-manifests}/.eslintrc.js (100%) create mode 100644 packages/release-manifests/CHANGELOG.md rename packages/{release-manifest => release-manifests}/README.md (100%) rename packages/{release-manifest => release-manifests}/api-report.md (100%) rename packages/{release-manifest => release-manifests}/package.json (82%) rename packages/{release-manifest => release-manifests}/src/index.ts (100%) rename packages/{release-manifest => release-manifests}/src/manifest.test.ts (100%) rename packages/{release-manifest => release-manifests}/src/manifest.ts (98%) diff --git a/packages/cli/package.json b/packages/cli/package.json index dbcab6fbc7..9911c427a0 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -32,7 +32,7 @@ "@backstage/config": "^0.1.13", "@backstage/config-loader": "^0.9.3", "@backstage/errors": "^0.2.0", - "@backstage/release-manifest": "^0.0.0", + "@backstage/release-manifests": "^0.0.0", "@backstage/types": "^0.1.1", "@hot-loader/react-dom": "^16.13.0", "@manypkg/get-packages": "^1.1.3", diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index a7ce942af7..46044bcca1 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -36,7 +36,7 @@ import { getByReleaseLine, getByVersion, ReleaseManifest, -} from '@backstage/release-manifest'; +} from '@backstage/release-manifests'; const DEP_TYPES = [ 'dependencies', @@ -321,7 +321,7 @@ export function createStrictVersionFinder(options: { export function createVersionFinder(options: { releaseLine?: string; packageInfoFetcher?: () => Promise; - releaseManifest: ReleaseManifest; + releaseManifest?: ReleaseManifest; }) { const { releaseLine = 'latest', @@ -332,7 +332,7 @@ export function createVersionFinder(options: { const distTag = releaseLine === 'main' ? 'latest' : releaseLine; const found = new Map(); const releasePackages = new Map( - releaseManifest.packages.map(p => [p.name, p.version]), + releaseManifest?.packages.map(p => [p.name, p.version]), ); return async function findTargetVersion(name: string) { const existing = found.get(name); diff --git a/packages/release-manifest/CHANGELOG.md b/packages/release-manifest/CHANGELOG.md deleted file mode 100644 index 28f83c41cd..0000000000 --- a/packages/release-manifest/CHANGELOG.md +++ /dev/null @@ -1 +0,0 @@ -# @backstage/release-manifest diff --git a/packages/release-manifest/.eslintrc.js b/packages/release-manifests/.eslintrc.js similarity index 100% rename from packages/release-manifest/.eslintrc.js rename to packages/release-manifests/.eslintrc.js diff --git a/packages/release-manifests/CHANGELOG.md b/packages/release-manifests/CHANGELOG.md new file mode 100644 index 0000000000..3aac6c8e6a --- /dev/null +++ b/packages/release-manifests/CHANGELOG.md @@ -0,0 +1 @@ +# @backstage/release-manifests diff --git a/packages/release-manifest/README.md b/packages/release-manifests/README.md similarity index 100% rename from packages/release-manifest/README.md rename to packages/release-manifests/README.md diff --git a/packages/release-manifest/api-report.md b/packages/release-manifests/api-report.md similarity index 100% rename from packages/release-manifest/api-report.md rename to packages/release-manifests/api-report.md diff --git a/packages/release-manifest/package.json b/packages/release-manifests/package.json similarity index 82% rename from packages/release-manifest/package.json rename to packages/release-manifests/package.json index ffa201ae4a..405896f50b 100644 --- a/packages/release-manifest/package.json +++ b/packages/release-manifests/package.json @@ -1,5 +1,5 @@ { - "name": "@backstage/release-manifest", + "name": "@backstage/release-manifests", "description": "Helper library for receiving release manifests", "version": "0.0.0", "private": false, @@ -8,20 +8,21 @@ "publishConfig": { "access": "public", "main": "dist/index.cjs.js", + "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, "homepage": "https://backstage.io", "repository": { "type": "git", "url": "https://github.com/backstage/backstage", - "directory": "packages/release-manifest" + "directory": "packages/release-manifests" }, "keywords": [ "backstage" ], "license": "Apache-2.0", "scripts": { - "build": "backstage-cli build --outputs cjs,types", + "build": "backstage-cli build", "lint": "backstage-cli lint", "test": "backstage-cli test", "prepack": "backstage-cli prepack", @@ -29,7 +30,7 @@ "clean": "backstage-cli clean" }, "dependencies": { - "node-fetch": "^2.6.1" + "cross-fetch": "^3.0.6" }, "devDependencies": { "@backstage/test-utils": "^0.2.3", diff --git a/packages/release-manifest/src/index.ts b/packages/release-manifests/src/index.ts similarity index 100% rename from packages/release-manifest/src/index.ts rename to packages/release-manifests/src/index.ts diff --git a/packages/release-manifest/src/manifest.test.ts b/packages/release-manifests/src/manifest.test.ts similarity index 100% rename from packages/release-manifest/src/manifest.test.ts rename to packages/release-manifests/src/manifest.test.ts diff --git a/packages/release-manifest/src/manifest.ts b/packages/release-manifests/src/manifest.ts similarity index 98% rename from packages/release-manifest/src/manifest.ts rename to packages/release-manifests/src/manifest.ts index 564809fdee..ab2fa6c9fa 100644 --- a/packages/release-manifest/src/manifest.ts +++ b/packages/release-manifests/src/manifest.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import fetch from 'node-fetch'; +import fetch from 'cross-fetch'; const VERSIONS_DOMAIN = 'https://versions.backstage.io'; From 25c6c2fd747503f72f176979b1fc5e91dcbf288c Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 26 Jan 2022 09:16:05 +0100 Subject: [PATCH 20/33] update api report Signed-off-by: Johan Haals --- packages/release-manifests/api-report.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/release-manifests/api-report.md b/packages/release-manifests/api-report.md index 6cafdaf2a2..6dc3dde258 100644 --- a/packages/release-manifests/api-report.md +++ b/packages/release-manifests/api-report.md @@ -1,4 +1,4 @@ -## API Report File for "@backstage/release-manifest" +## API Report File for "@backstage/release-manifests" > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). @@ -25,6 +25,7 @@ export type GetByVersionOptions = { // @public export type ReleaseManifest = { + releaseVersion: string; packages: { name: string; version: string; From 59f31a631552490ada609d60db7e959193f82d07 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 26 Jan 2022 11:37:49 +0100 Subject: [PATCH 21/33] chore: fix test, add additonal tests Signed-off-by: Johan Haals --- packages/cli/package.json | 3 +- .../cli/src/commands/versions/bump.test.ts | 165 +++++++++++++++++- 2 files changed, 160 insertions(+), 8 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 9911c427a0..3786b7d3e5 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -144,7 +144,8 @@ "del": "^6.0.0", "mock-fs": "^5.1.0", "nodemon": "^2.0.2", - "ts-node": "^10.0.0" + "ts-node": "^10.0.0", + "msw": "^0.35.0" }, "peerDependencies": { "@microsoft/api-extractor": "^7.19.2" diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index ed1fc62380..1b9e0aa7cc 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -21,8 +21,13 @@ import { resolve as resolvePath } from 'path'; import { paths } from '../../lib/paths'; import * as runObj from '../../lib/run'; import bump, { bumpBackstageJsonVersion, createVersionFinder } from './bump'; -import { withLogCollector } from '@backstage/test-utils'; +import { + setupRequestMockHandlers, + withLogCollector, +} from '@backstage/test-utils'; import { YarnInfoInspectData } from '../../lib/versioning/packages'; +import { setupServer } from 'msw/node'; +import { rest } from 'msw'; // Remove log coloring to simplify log matching jest.mock('chalk', () => ({ @@ -83,6 +88,8 @@ describe('bump', () => { mockFs.restore(); jest.resetAllMocks(); }); + const worker = setupServer(); + setupRequestMockHandlers(worker); it('should bump backstage dependencies', async () => { mockFs({ @@ -122,9 +129,20 @@ describe('bump', () => { }), ); jest.spyOn(runObj, 'run').mockResolvedValue(undefined); - + worker.use( + rest.get( + 'https://versions.backstage.io/v1/tags/main/manifest.json', + (_, res, ctx) => + res( + ctx.status(200), + ctx.json({ + packages: [], + }), + ), + ), + ); const { log: logs } = await withLogCollector(['log'], async () => { - await bump({ pattern: null } as unknown as Command); + await bump({ pattern: null, release: 'main' } as unknown as Command); }); expect(logs.filter(Boolean)).toEqual([ 'Using default pattern glob @backstage/*', @@ -180,6 +198,114 @@ describe('bump', () => { }); }); + it('should prefer dependency versions from release manifest', async () => { + mockFs({ + '/yarn.lock': lockfileMock, + '/package.json': JSON.stringify({ + workspaces: { + packages: ['packages/*'], + }, + }), + '/packages/a/package.json': JSON.stringify({ + name: 'a', + dependencies: { + '@backstage/core': '^1.0.5', + }, + }), + '/packages/b/package.json': JSON.stringify({ + name: 'b', + dependencies: { + '@backstage/core': '^1.0.3', + '@backstage/theme': '^1.0.0', + }, + }), + }); + + jest + .spyOn(paths, 'resolveTargetRoot') + .mockImplementation((...path) => resolvePath('/', ...path)); + jest.spyOn(runObj, 'runPlain').mockImplementation(async (...[, , , name]) => + JSON.stringify({ + type: 'inspect', + data: { + name: name, + 'dist-tags': { + latest: REGISTRY_VERSIONS[name], + }, + }, + }), + ); + jest.spyOn(runObj, 'run').mockResolvedValue(undefined); + worker.use( + rest.get( + 'https://versions.backstage.io/v1/tags/main/manifest.json', + (_, res, ctx) => + res( + ctx.status(200), + ctx.json({ + packages: [{ name: '@backstage/theme', version: '5.0.0' }], + }), + ), + ), + ); + const { log: logs } = await withLogCollector(['log'], async () => { + await bump({ pattern: null, release: 'main' } as unknown as Command); + }); + expect(logs.filter(Boolean)).toEqual([ + 'Using default pattern glob @backstage/*', + 'Checking for updates of @backstage/core', + 'Checking for updates of @backstage/theme', + 'Checking for updates of @backstage/theme', + 'Checking for updates of @backstage/core-api', + 'Some packages are outdated, updating', + 'unlocking @backstage/core@^1.0.3 ~> 1.0.6', + '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', + 'Running yarn install to install new versions', + '⚠️ The following packages may have breaking changes:', + ' @backstage/theme : 1.0.0 ~> 5.0.0', + ' https://github.com/backstage/backstage/blob/master/packages/theme/CHANGELOG.md', + 'Version bump complete!', + ]); + + expect(runObj.runPlain).toHaveBeenCalledTimes(3); + expect(runObj.runPlain).toHaveBeenCalledWith( + 'yarn', + 'info', + '--json', + '@backstage/core', + ); + expect(runObj.runPlain).not.toHaveBeenCalledWith( + 'yarn', + 'info', + '--json', + '@backstage/theme', + ); + + expect(runObj.run).toHaveBeenCalledTimes(1); + expect(runObj.run).toHaveBeenCalledWith('yarn', ['install']); + + const lockfileContents = await fs.readFile('/yarn.lock', 'utf8'); + expect(lockfileContents).toBe(lockfileMockResult); + + const packageA = await fs.readJson('/packages/a/package.json'); + expect(packageA).toEqual({ + name: 'a', + dependencies: { + '@backstage/core': '^1.0.5', // not bumped since new version is within range + }, + }); + const packageB = await fs.readJson('/packages/b/package.json'); + expect(packageB).toEqual({ + name: 'b', + dependencies: { + '@backstage/core': '^1.0.3', // not bumped + '@backstage/theme': '^5.0.0', // bumped since newer + }, + }); + }); + it('should bump backstage dependencies and dependencies matching pattern glob', async () => { const customLockfileMock = `${lockfileMock} "@backstage-extra/custom@^1.1.0": @@ -247,9 +373,23 @@ describe('bump', () => { }), ); jest.spyOn(runObj, 'run').mockResolvedValue(undefined); - + worker.use( + rest.get( + 'https://versions.backstage.io/v1/tags/main/manifest.json', + (_, res, ctx) => + res( + ctx.status(200), + ctx.json({ + packages: [], + }), + ), + ), + ); const { log: logs } = await withLogCollector(['log'], async () => { - await bump({ pattern: '@{backstage,backstage-extra}/*' } as any); + await bump({ + pattern: '@{backstage,backstage-extra}/*', + release: 'main', + } as any); }); expect(logs.filter(Boolean)).toEqual([ 'Using custom pattern glob @{backstage,backstage-extra}/*', @@ -343,9 +483,20 @@ describe('bump', () => { .mockImplementation((...path) => resolvePath('/', ...path)); jest.spyOn(runObj, 'runPlain').mockImplementation(async () => ''); jest.spyOn(runObj, 'run').mockResolvedValue(undefined); - + worker.use( + rest.get( + 'https://versions.backstage.io/v1/tags/main/manifest.json', + (_, res, ctx) => + res( + ctx.status(200), + ctx.json({ + packages: [], + }), + ), + ), + ); const { log: logs } = await withLogCollector(['log'], async () => { - await bump({ pattern: null } as unknown as Command); + await bump({ pattern: null, release: 'main' } as unknown as Command); }); expect(logs.filter(Boolean)).toEqual([ 'Using default pattern glob @backstage/*', From 788ffa78e28f039f52683b7f933f934af79fb85d Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 26 Jan 2022 14:45:24 +0100 Subject: [PATCH 22/33] Skip backstage.json update for custom patterns. Add more tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Patrik Oldsberg Co-authored-by: Fredrik Adelöw Signed-off-by: Johan Haals --- .../cli/src/commands/versions/bump.test.ts | 158 ++++++++++++++---- packages/cli/src/commands/versions/bump.ts | 17 +- 2 files changed, 131 insertions(+), 44 deletions(-) diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index 1b9e0aa7cc..ce37181b72 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -44,6 +44,7 @@ const REGISTRY_VERSIONS: { [name: string]: string } = { '@backstage/theme': '2.0.0', '@backstage-extra/custom': '1.1.0', '@backstage-extra/custom-two': '2.0.0', + '@backstage/create-app': '1.0.0', }; const HEADER = `# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. @@ -154,6 +155,8 @@ 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 ^2.0.0', + 'Checking for updates of @backstage/create-app', + 'Creating backstage.json', 'Running yarn install to install new versions', '⚠️ The following packages may have breaking changes:', ' @backstage/theme : 1.0.0 ~> 2.0.0', @@ -243,7 +246,16 @@ describe('bump', () => { res( ctx.status(200), ctx.json({ - packages: [{ name: '@backstage/theme', version: '5.0.0' }], + packages: [ + { + name: '@backstage/theme', + version: '5.0.0', + }, + { + name: '@backstage/create-app', + version: '3.0.0', + }, + ], }), ), ), @@ -262,6 +274,8 @@ 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', + 'Checking for updates of @backstage/create-app', + 'Creating backstage.json', 'Running yarn install to install new versions', '⚠️ The following packages may have breaking changes:', ' @backstage/theme : 1.0.0 ~> 5.0.0', @@ -269,7 +283,7 @@ describe('bump', () => { 'Version bump complete!', ]); - expect(runObj.runPlain).toHaveBeenCalledTimes(3); + expect(runObj.runPlain).toHaveBeenCalledTimes(2); expect(runObj.runPlain).toHaveBeenCalledWith( 'yarn', 'info', @@ -306,6 +320,107 @@ describe('bump', () => { }); }); + it('should only bump packages in the manifest when a specific release is specified', async () => { + mockFs({ + '/yarn.lock': lockfileMock, + '/package.json': JSON.stringify({ + workspaces: { + packages: ['packages/*'], + }, + }), + '/packages/a/package.json': JSON.stringify({ + name: 'a', + dependencies: { + '@backstage/core': '^1.0.5', + }, + }), + '/packages/b/package.json': JSON.stringify({ + name: 'b', + dependencies: { + '@backstage/core': '^1.0.3', + '@backstage/theme': '^1.0.0', + }, + }), + }); + jest.spyOn(runObj, 'runPlain').mockImplementation(async (...[, , , name]) => + JSON.stringify({ + type: 'inspect', + data: { + name: name, + 'dist-tags': { + latest: REGISTRY_VERSIONS[name], + }, + }, + }), + ); + jest + .spyOn(paths, 'resolveTargetRoot') + .mockImplementation((...path) => resolvePath('/', ...path)); + + jest.spyOn(runObj, 'run').mockResolvedValue(undefined); + worker.use( + rest.get( + 'https://versions.backstage.io/v1/releases/1.0.0/manifest.json', + (_, res, ctx) => + res( + ctx.status(200), + ctx.json({ + packages: [ + { name: '@backstage/core', version: '5.0.0' }, + { name: '@backstage/core-api', version: '5.0.0' }, + { name: '@backstage/create-app', version: '2.0.0' }, + ], + }), + ), + ), + ); + const { log: logs } = await withLogCollector(['log'], async () => { + await expect( + bump({ pattern: null, release: '1.0.0' } as unknown as Command), + ).rejects.toThrow('Duplicate versions present after package bump'); + }); + expect(logs.filter(Boolean)).toEqual([ + 'Using default pattern glob @backstage/*', + 'Checking for updates of @backstage/theme', + 'Checking for updates of @backstage/core', + 'Package @backstage/theme not found in release manifest, skipping', + 'Checking for updates of @backstage/core-api', + 'Checking for updates of @backstage/theme', + 'Checking for updates of @backstage/core', + 'Package @backstage/theme not found in release manifest, skipping', + 'Some packages are outdated, updating', + 'bumping @backstage/core in b to ^5.0.0', + 'bumping @backstage/core in a to ^5.0.0', + 'Checking for updates of @backstage/create-app', + 'Creating backstage.json', + 'Running yarn install to install new versions', + '⚠️ The following packages may have breaking changes:', + ' @backstage/core : 1.0.6 ~> 5.0.0', + ' https://github.com/backstage/backstage/blob/master/packages/core/CHANGELOG.md', + 'Version bump complete!', + ]); + + expect(runObj.run).toHaveBeenCalledTimes(1); + expect(runObj.run).toHaveBeenCalledWith('yarn', ['install']); + + const packageA = await fs.readJson('/packages/a/package.json'); + expect(packageA).toEqual({ + name: 'a', + dependencies: { + '@backstage/core': '^5.0.0', + }, + }); + const packageB = await fs.readJson('/packages/b/package.json'); + expect(packageB).toEqual({ + name: 'b', + dependencies: { + '@backstage/core': '^5.0.0', + '@backstage/theme': '^1.0.0', + }, + }); + expect(await fs.readJson('/backstage.json')).toEqual({ version: '2.0.0' }); + }); + it('should bump backstage dependencies and dependencies matching pattern glob', async () => { const customLockfileMock = `${lockfileMock} "@backstage-extra/custom@^1.1.0": @@ -414,7 +529,7 @@ describe('bump', () => { 'Version bump complete!', ]); - expect(runObj.runPlain).toHaveBeenCalledTimes(6); + expect(runObj.runPlain).toHaveBeenCalledTimes(5); expect(runObj.runPlain).toHaveBeenCalledWith( 'yarn', 'info', @@ -545,27 +660,12 @@ describe('bumpBackstageJsonVersion', () => { '/backstage.json': JSON.stringify({ version: '0.0.1' }), }); paths.targetDir = '/'; - const latest = '1.4.1'; jest .spyOn(paths, 'resolveTargetRoot') .mockImplementation((...path) => resolvePath('/', ...path)); - jest.spyOn(runObj, 'runPlain').mockImplementation(async (...[, , , name]) => - JSON.stringify({ - type: 'inspect', - data: { - name, - 'dist-tags': { - latest, - }, - }, - }), - ); - jest.spyOn(runObj, 'run').mockResolvedValue(undefined); - await bumpBackstageJsonVersion(); - - const json = await fs.readJson('/backstage.json'); - expect(json).toEqual({ version: '1.4.1' }); + await bumpBackstageJsonVersion('1.4.1'); + expect(await fs.readJson('/backstage.json')).toEqual({ version: '1.4.1' }); }); it("should create backstage.json if doesn't exist", async () => { @@ -575,23 +675,9 @@ describe('bumpBackstageJsonVersion', () => { jest .spyOn(paths, 'resolveTargetRoot') .mockImplementation((...path) => resolvePath('/', ...path)); - jest.spyOn(runObj, 'runPlain').mockImplementation(async (...[, , , name]) => - JSON.stringify({ - type: 'inspect', - data: { - name, - 'dist-tags': { - latest, - }, - }, - }), - ); - jest.spyOn(runObj, 'run').mockResolvedValue(undefined); - await bumpBackstageJsonVersion(); - - const json = await fs.readJson('/backstage.json'); - expect(json).toEqual({ version: '1.4.1' }); + await bumpBackstageJsonVersion(latest); + expect(await fs.readJson('/backstage.json')).toEqual({ version: latest }); }); }); diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index 46044bcca1..6e602c726c 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -231,8 +231,12 @@ export default async (cmd: Command) => { console.log(); - await bumpBackstageJsonVersion(); - + // Do not update backstage.json when upgrade patterns are used. + if (pattern === DEFAULT_PATTERN_GLOB) { + await bumpBackstageJsonVersion( + await findTargetVersion('@backstage/create-app'), + ); + } console.log(); console.log( `Running ${chalk.blue('yarn install')} to install new versions`, @@ -384,7 +388,7 @@ export function createVersionFinder(options: { }; } -export async function bumpBackstageJsonVersion() { +export async function bumpBackstageJsonVersion(createAppVersion: string) { const backstageJsonPath = paths.resolveTargetRoot(BACKSTAGE_JSON); const backstageJson = await fs.readJSON(backstageJsonPath).catch(e => { if (e.code === 'ENOENT') { @@ -394,10 +398,7 @@ export async function bumpBackstageJsonVersion() { throw e; }); - const info = await fetchPackageInfo('@backstage/create-app'); - const { latest } = info['dist-tags']; - - if (backstageJson?.version === latest) { + if (backstageJson?.version === createAppVersion) { return; } @@ -411,7 +412,7 @@ export async function bumpBackstageJsonVersion() { await fs.writeJson( backstageJsonPath, - { ...backstageJson, version: latest }, + { ...backstageJson, version: createAppVersion }, { spaces: 2, encoding: 'utf8', From cbb3aa231bc564320bb8c38a7a940dfdcd0bcfeb Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Mon, 7 Feb 2022 11:20:08 +0100 Subject: [PATCH 23/33] Update changeset Signed-off-by: Johan Haals --- .changeset/cold-houses-type.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.changeset/cold-houses-type.md b/.changeset/cold-houses-type.md index 6aa466755d..a4dee63dd9 100644 --- a/.changeset/cold-houses-type.md +++ b/.changeset/cold-houses-type.md @@ -2,6 +2,6 @@ '@backstage/cli': patch --- -Introduces two new parameters to the `backstage-cli versions:bump` command. -The first one is `--release-line ` bump packages to the latest `main` or `next` release. -`--backstage-release ` is used to bump packages to a specific backstage release. +Introduces a new `--release` parameters to the `backstage-cli versions:bump` command. +The release can be either a specific version for example `0.99.1`, or the latest `main` or `next` release. +The default behavior is to bump the latest `main` release. From c22bcaafddbccb4ddc45732aacef2a897d8b66af Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 8 Feb 2022 10:22:19 +0100 Subject: [PATCH 24/33] update tests Signed-off-by: Johan Haals --- packages/cli/src/commands/versions/bump.test.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index ce37181b72..ca940e204d 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -381,21 +381,21 @@ describe('bump', () => { }); expect(logs.filter(Boolean)).toEqual([ 'Using default pattern glob @backstage/*', - 'Checking for updates of @backstage/theme', 'Checking for updates of @backstage/core', - 'Package @backstage/theme not found in release manifest, skipping', + 'Checking for updates of @backstage/theme', + 'Package info not found, ignoring package @backstage/theme', + 'Checking for updates of @backstage/core', + 'Checking for updates of @backstage/theme', 'Checking for updates of @backstage/core-api', - 'Checking for updates of @backstage/theme', - 'Checking for updates of @backstage/core', - 'Package @backstage/theme not found in release manifest, skipping', + 'Package info not found, ignoring package @backstage/theme', 'Some packages are outdated, updating', - 'bumping @backstage/core in b to ^5.0.0', 'bumping @backstage/core in a to ^5.0.0', + 'bumping @backstage/core in b to ^5.0.0', 'Checking for updates of @backstage/create-app', 'Creating backstage.json', 'Running yarn install to install new versions', '⚠️ The following packages may have breaking changes:', - ' @backstage/core : 1.0.6 ~> 5.0.0', + ' @backstage/core : 1.0.3 ~> 5.0.0', ' https://github.com/backstage/backstage/blob/master/packages/core/CHANGELOG.md', 'Version bump complete!', ]); From d77c32fd48477a1d1d6d2e2de77f7b57d781a7c2 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 8 Feb 2022 11:33:59 +0100 Subject: [PATCH 25/33] Use release version from manifest Signed-off-by: Johan Haals --- .../cli/src/commands/versions/bump.test.ts | 10 ++++---- packages/cli/src/commands/versions/bump.ts | 23 +++++++++++-------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/packages/cli/src/commands/versions/bump.test.ts b/packages/cli/src/commands/versions/bump.test.ts index ca940e204d..d2d3cf1573 100644 --- a/packages/cli/src/commands/versions/bump.test.ts +++ b/packages/cli/src/commands/versions/bump.test.ts @@ -155,8 +155,6 @@ 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 ^2.0.0', - 'Checking for updates of @backstage/create-app', - 'Creating backstage.json', 'Running yarn install to install new versions', '⚠️ The following packages may have breaking changes:', ' @backstage/theme : 1.0.0 ~> 2.0.0', @@ -164,7 +162,7 @@ describe('bump', () => { 'Version bump complete!', ]); - expect(runObj.runPlain).toHaveBeenCalledTimes(4); + expect(runObj.runPlain).toHaveBeenCalledTimes(3); expect(runObj.runPlain).toHaveBeenCalledWith( 'yarn', 'info', @@ -246,6 +244,7 @@ describe('bump', () => { res( ctx.status(200), ctx.json({ + releaseVersion: '0.0.1', packages: [ { name: '@backstage/theme', @@ -274,7 +273,6 @@ 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', - 'Checking for updates of @backstage/create-app', 'Creating backstage.json', 'Running yarn install to install new versions', '⚠️ The following packages may have breaking changes:', @@ -365,10 +363,10 @@ describe('bump', () => { res( ctx.status(200), ctx.json({ + releaseVersion: '2.0.0', packages: [ { name: '@backstage/core', version: '5.0.0' }, { name: '@backstage/core-api', version: '5.0.0' }, - { name: '@backstage/create-app', version: '2.0.0' }, ], }), ), @@ -391,7 +389,6 @@ 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', - 'Checking for updates of @backstage/create-app', 'Creating backstage.json', 'Running yarn install to install new versions', '⚠️ The following packages may have breaking changes:', @@ -521,6 +518,7 @@ describe('bump', () => { 'bumping @backstage-extra/custom-two in a to ^2.0.0', 'bumping @backstage-extra/custom-two in b to ^2.0.0', 'bumping @backstage/theme in b to ^2.0.0', + 'Skipping backstage.json update as custom pattern is used', 'Running yarn install to install new versions', '⚠️ The following packages may have breaking changes:', ' @backstage-extra/custom-two : 1.0.0 ~> 2.0.0', diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index 6e602c726c..85385616c9 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -67,16 +67,17 @@ export default async (cmd: Command) => { } let findTargetVersion: (name: string) => Promise; + let releaseManifest: ReleaseManifest; if (semver.valid(cmd.release)) { + releaseManifest = await getByVersion({ version: cmd.release }); findTargetVersion = createStrictVersionFinder({ - releaseManifest: await getByVersion({ version: cmd.release }), + releaseManifest, }); } else { + releaseManifest = await getByReleaseLine({ releaseLine: cmd.release }); findTargetVersion = createVersionFinder({ releaseLine: cmd.releaseLine, - releaseManifest: await getByReleaseLine({ - releaseLine: cmd.release, - }), + releaseManifest, }); } @@ -233,8 +234,12 @@ export default async (cmd: Command) => { // Do not update backstage.json when upgrade patterns are used. if (pattern === DEFAULT_PATTERN_GLOB) { - await bumpBackstageJsonVersion( - await findTargetVersion('@backstage/create-app'), + await bumpBackstageJsonVersion(releaseManifest.releaseVersion); + } else { + console.log( + chalk.yellow( + `Skipping backstage.json update as custom pattern is used`, + ), ); } console.log(); @@ -388,7 +393,7 @@ export function createVersionFinder(options: { }; } -export async function bumpBackstageJsonVersion(createAppVersion: string) { +export async function bumpBackstageJsonVersion(version: string) { const backstageJsonPath = paths.resolveTargetRoot(BACKSTAGE_JSON); const backstageJson = await fs.readJSON(backstageJsonPath).catch(e => { if (e.code === 'ENOENT') { @@ -398,7 +403,7 @@ export async function bumpBackstageJsonVersion(createAppVersion: string) { throw e; }); - if (backstageJson?.version === createAppVersion) { + if (backstageJson?.version === version) { return; } @@ -412,7 +417,7 @@ export async function bumpBackstageJsonVersion(createAppVersion: string) { await fs.writeJson( backstageJsonPath, - { ...backstageJson, version: createAppVersion }, + { ...backstageJson, version }, { spaces: 2, encoding: 'utf8', From b25e1d23c7042a9461520da78c3f041e69bf0d57 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 8 Feb 2022 14:41:12 +0100 Subject: [PATCH 26/33] Fix incorrect package name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Johan Haals Co-authored-by: Fredrik Adelöw --- .changeset/green-peaches-explode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/green-peaches-explode.md b/.changeset/green-peaches-explode.md index c28c9f6e75..e81771f1c3 100644 --- a/.changeset/green-peaches-explode.md +++ b/.changeset/green-peaches-explode.md @@ -1,5 +1,5 @@ --- -'@backstage/release-manifest': patch +'@backstage/release-manifests': patch --- Introduces a new release-manifest package with utilities for fetching release manifests. From 1b58473c4bb2504fd1ee57a62a870784aa7dae0a Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 8 Feb 2022 14:41:25 +0100 Subject: [PATCH 27/33] Update .changeset/green-peaches-explode.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Johan Haals Co-authored-by: Fredrik Adelöw --- .changeset/green-peaches-explode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/green-peaches-explode.md b/.changeset/green-peaches-explode.md index e81771f1c3..cfebebffc3 100644 --- a/.changeset/green-peaches-explode.md +++ b/.changeset/green-peaches-explode.md @@ -2,5 +2,5 @@ '@backstage/release-manifests': patch --- -Introduces a new release-manifest package with utilities for fetching release manifests. +Introduces a new package with utilities for fetching release manifests. This package will primarily be used by the `@backstage/cli` package. From 259929af4e745da266254bdffd3007e9eb8ba21f Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 8 Feb 2022 14:41:40 +0100 Subject: [PATCH 28/33] Update package header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Johan Haals Co-authored-by: Fredrik Adelöw --- packages/release-manifests/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/release-manifests/README.md b/packages/release-manifests/README.md index ddbeed7dd0..6111173f15 100644 --- a/packages/release-manifests/README.md +++ b/packages/release-manifests/README.md @@ -1,3 +1,3 @@ -# @backstage/release-manifest +# @backstage/release-manifests This package provides a mapping between a Backstage release and the packages included in that release. From bf78c72b16b37a875ed76e931ff1be69cbb535a7 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 8 Feb 2022 14:46:39 +0100 Subject: [PATCH 29/33] fix typos in .changeset/cold-houses-type.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Johan Haals Co-authored-by: Fredrik Adelöw --- .changeset/cold-houses-type.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.changeset/cold-houses-type.md b/.changeset/cold-houses-type.md index a4dee63dd9..05155c96c0 100644 --- a/.changeset/cold-houses-type.md +++ b/.changeset/cold-houses-type.md @@ -2,6 +2,6 @@ '@backstage/cli': patch --- -Introduces a new `--release` parameters to the `backstage-cli versions:bump` command. -The release can be either a specific version for example `0.99.1`, or the latest `main` or `next` release. -The default behavior is to bump the latest `main` release. +Introduces a new `--release` parameter to the `backstage-cli versions:bump` command. +The release can be either a specific version, for example `0.99.1`, or the latest `main` or `next` release. +The default behavior is to bump to the latest `main` release. From 494e1914cdf6522f2f0273556ab3b54ce28cab0b Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 8 Feb 2022 14:48:31 +0100 Subject: [PATCH 30/33] chore: Remove accidental dot import Signed-off-by: Johan Haals --- packages/release-manifests/src/manifest.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/release-manifests/src/manifest.test.ts b/packages/release-manifests/src/manifest.test.ts index e6f353f912..efd5728fbc 100644 --- a/packages/release-manifests/src/manifest.test.ts +++ b/packages/release-manifests/src/manifest.test.ts @@ -15,10 +15,9 @@ */ import { setupRequestMockHandlers } from '@backstage/test-utils'; -import { getByVersion } from './manifest'; +import { getByReleaseLine, getByVersion } from './manifest'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; -import { getByReleaseLine } from '.'; describe('getByVersion', () => { const worker = setupServer(); From 0af2670e45d43bcc29599c2c7d65eb1e0729d9e1 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 8 Feb 2022 14:44:05 +0100 Subject: [PATCH 31/33] scripts: Do not allow warnings in packages/release-manifests Signed-off-by: Johan Haals --- scripts/api-extractor.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index 1ac43d242d..808af8754d 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -216,6 +216,7 @@ const NO_WARNING_PACKAGES = [ 'packages/test-utils', 'packages/theme', 'packages/types', + 'packages/release-manifests', 'packages/version-bridge', 'plugins/catalog-backend-module-ldap', 'plugins/catalog-backend-module-msgraph', From db1066eec96294abbc9da34817c7afe973a0dae1 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 8 Feb 2022 15:00:12 +0100 Subject: [PATCH 32/33] chore: clarify function names Signed-off-by: Johan Haals --- packages/cli/src/commands/versions/bump.ts | 10 ++++++---- packages/release-manifests/api-report.md | 12 ++++++------ packages/release-manifests/src/index.ts | 6 +++--- .../release-manifests/src/manifest.test.ts | 18 +++++++++--------- packages/release-manifests/src/manifest.ts | 12 ++++++------ 5 files changed, 30 insertions(+), 28 deletions(-) diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index 85385616c9..fc455b9fbd 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -33,8 +33,8 @@ import { forbiddenDuplicatesFilter } from './lint'; import { BACKSTAGE_JSON } from '@backstage/cli-common'; import { runParallelWorkers } from '../../lib/parallel'; import { - getByReleaseLine, - getByVersion, + getManifestByReleaseLine, + getManifestByVersion, ReleaseManifest, } from '@backstage/release-manifests'; @@ -69,12 +69,14 @@ export default async (cmd: Command) => { let findTargetVersion: (name: string) => Promise; let releaseManifest: ReleaseManifest; if (semver.valid(cmd.release)) { - releaseManifest = await getByVersion({ version: cmd.release }); + releaseManifest = await getManifestByVersion({ version: cmd.release }); findTargetVersion = createStrictVersionFinder({ releaseManifest, }); } else { - releaseManifest = await getByReleaseLine({ releaseLine: cmd.release }); + releaseManifest = await getManifestByReleaseLine({ + releaseLine: cmd.release, + }); findTargetVersion = createVersionFinder({ releaseLine: cmd.releaseLine, releaseManifest, diff --git a/packages/release-manifests/api-report.md b/packages/release-manifests/api-report.md index 6dc3dde258..1ffa35838b 100644 --- a/packages/release-manifests/api-report.md +++ b/packages/release-manifests/api-report.md @@ -4,22 +4,22 @@ ```ts // @public -export function getByReleaseLine( - options: GetByReleaseLineOptions, +export function getManifestByReleaseLine( + options: GetManifestByReleaseLineOptions, ): Promise; // @public -export type GetByReleaseLineOptions = { +export type GetManifestByReleaseLineOptions = { releaseLine: string; }; // @public -export function getByVersion( - options: GetByVersionOptions, +export function getManifestByVersion( + options: GetManifestByVersionOptions, ): Promise; // @public -export type GetByVersionOptions = { +export type GetManifestByVersionOptions = { version: string; }; diff --git a/packages/release-manifests/src/index.ts b/packages/release-manifests/src/index.ts index 25101d4cbf..f8ea22a3cb 100644 --- a/packages/release-manifests/src/index.ts +++ b/packages/release-manifests/src/index.ts @@ -20,9 +20,9 @@ * @packageDocumentation */ -export { getByVersion, getByReleaseLine } from './manifest'; +export { getManifestByVersion, getManifestByReleaseLine } from './manifest'; export type { ReleaseManifest, - GetByReleaseLineOptions, - GetByVersionOptions, + GetManifestByReleaseLineOptions, + GetManifestByVersionOptions, } from './manifest'; diff --git a/packages/release-manifests/src/manifest.test.ts b/packages/release-manifests/src/manifest.test.ts index efd5728fbc..70894e5431 100644 --- a/packages/release-manifests/src/manifest.test.ts +++ b/packages/release-manifests/src/manifest.test.ts @@ -15,11 +15,11 @@ */ import { setupRequestMockHandlers } from '@backstage/test-utils'; -import { getByReleaseLine, getByVersion } from './manifest'; +import { getManifestByReleaseLine, getManifestByVersion } from './manifest'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; -describe('getByVersion', () => { +describe('getManifestByVersion', () => { const worker = setupServer(); setupRequestMockHandlers(worker); @@ -38,7 +38,7 @@ describe('getByVersion', () => { ), ); - const pkgs = await getByVersion({ version: '0.0.0' }); + const pkgs = await getManifestByVersion({ version: '0.0.0' }); expect(pkgs.packages).toEqual([ { name: '@backstage/core', @@ -46,13 +46,13 @@ describe('getByVersion', () => { }, ]); - await expect(getByVersion({ version: '999.0.1' })).rejects.toThrow( + await expect(getManifestByVersion({ version: '999.0.1' })).rejects.toThrow( 'No release found for 999.0.1 version', ); }); }); -describe('getByReleaseLine', () => { +describe('getManifestByReleaseLine', () => { const worker = setupServer(); setupRequestMockHandlers(worker); @@ -71,7 +71,7 @@ describe('getByReleaseLine', () => { ), ); - const pkgs = await getByReleaseLine({ releaseLine: 'main' }); + const pkgs = await getManifestByReleaseLine({ releaseLine: 'main' }); expect(pkgs.packages).toEqual([ { name: '@backstage/core', @@ -79,8 +79,8 @@ describe('getByReleaseLine', () => { }, ]); - await expect(getByReleaseLine({ releaseLine: 'foo' })).rejects.toThrow( - "No 'foo' release line found", - ); + await expect( + getManifestByReleaseLine({ releaseLine: 'foo' }), + ).rejects.toThrow("No 'foo' release line found"); }); }); diff --git a/packages/release-manifests/src/manifest.ts b/packages/release-manifests/src/manifest.ts index ab2fa6c9fa..4068f4c963 100644 --- a/packages/release-manifests/src/manifest.ts +++ b/packages/release-manifests/src/manifest.ts @@ -31,7 +31,7 @@ export type ReleaseManifest = { * Options for getByVersion. * @public */ -export type GetByVersionOptions = { +export type GetManifestByVersionOptions = { version: string; }; @@ -39,8 +39,8 @@ export type GetByVersionOptions = { * Returns a release manifest based on supplied version. * @public */ -export async function getByVersion( - options: GetByVersionOptions, +export async function getManifestByVersion( + options: GetManifestByVersionOptions, ): Promise { const url = `${VERSIONS_DOMAIN}/v1/releases/${encodeURIComponent( options.version, @@ -61,7 +61,7 @@ export async function getByVersion( * Options for getByReleaseLine. * @public */ -export type GetByReleaseLineOptions = { +export type GetManifestByReleaseLineOptions = { releaseLine: string; }; @@ -69,8 +69,8 @@ export type GetByReleaseLineOptions = { * Returns a release manifest based on supplied release line. * @public */ -export async function getByReleaseLine( - options: GetByReleaseLineOptions, +export async function getManifestByReleaseLine( + options: GetManifestByReleaseLineOptions, ): Promise { const url = `${VERSIONS_DOMAIN}/v1/tags/${encodeURIComponent( options.releaseLine, From 89a2d00de73d9e810adc0fcf7538e859bc41b04e Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Tue, 8 Feb 2022 16:43:04 +0100 Subject: [PATCH 33/33] chore: add links to options doc strings Signed-off-by: Johan Haals --- packages/release-manifests/src/manifest.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/release-manifests/src/manifest.ts b/packages/release-manifests/src/manifest.ts index 4068f4c963..955cf7308c 100644 --- a/packages/release-manifests/src/manifest.ts +++ b/packages/release-manifests/src/manifest.ts @@ -28,7 +28,7 @@ export type ReleaseManifest = { }; /** - * Options for getByVersion. + * Options for {@link getManifestByVersion}. * @public */ export type GetManifestByVersionOptions = { @@ -58,7 +58,7 @@ export async function getManifestByVersion( } /** - * Options for getByReleaseLine. + * Options for {@link getManifestByReleaseLine}. * @public */ export type GetManifestByReleaseLineOptions = {