From c2930c3b2cf88e62cdc83de246d7700954a277e7 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Fri, 21 Jan 2022 14:15:58 +0100 Subject: [PATCH] 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(); }