release-manifests: allow overriding fetch implementation

This allows us to use yarn's built in HTTP request
utilities in the Backstage yarn plugin, thereby
benefiting from the built-in caching and proxy
configuration utilities.

Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>
This commit is contained in:
MT Lewis
2024-11-29 16:14:16 +00:00
parent c28afe5520
commit b29eaea119
4 changed files with 56 additions and 4 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/release-manifests': patch
---
Allow overriding the fetch function used inside getManifestByVersion
+6
View File
@@ -21,6 +21,12 @@ export function getManifestByVersion(
// @public
export type GetManifestByVersionOptions = {
version: string;
fetch?: (
url: string,
options?: {
signal?: AbortSignal;
},
) => Promise<Pick<Response, 'status' | 'json' | 'url'>>;
};
// @public
@@ -55,6 +55,37 @@ describe('Release Manifests', () => {
getManifestByVersion({ version: '999.0.1' }),
).rejects.toThrow('No release found for 999.0.1 version');
});
it('should allow overriding the fetch implementation', async () => {
const mockFetch = jest.fn().mockImplementation(async url => ({
status: 200,
url,
json: () => ({
packages: [{ name: '@backstage/core', version: '2.3.4' }],
}),
}));
const pkgs = await getManifestByVersion({
version: '0.0.0',
fetch: mockFetch,
});
expect(pkgs.packages).toEqual([
{
name: '@backstage/core',
version: '2.3.4',
},
]);
mockFetch.mockImplementation(async url => ({
status: 404,
url,
}));
await expect(
getManifestByVersion({ version: '0.0.0', fetch: mockFetch }),
).rejects.toThrow('No release found for 0.0.0 version');
});
});
describe('getManifestByReleaseLine', () => {
+14 -4
View File
@@ -33,6 +33,10 @@ export type ReleaseManifest = {
*/
export type GetManifestByVersionOptions = {
version: string;
fetch?: (
url: string,
options?: { signal?: AbortSignal },
) => Promise<Pick<Response, 'status' | 'json' | 'url'>>;
};
// Wait for waitMs, or until signal is aborted.
@@ -82,15 +86,21 @@ export async function getManifestByVersion(
options: GetManifestByVersionOptions,
): Promise<ReleaseManifest> {
const versionEnc = encodeURIComponent(options.version);
const fetchFn = options.fetch ?? fetch;
const res = await withFallback(
signal =>
fetch(`${VERSIONS_BASE_URL}/v1/releases/${versionEnc}/manifest.json`, {
fetchFn(`${VERSIONS_BASE_URL}/v1/releases/${versionEnc}/manifest.json`, {
signal,
}),
signal =>
fetch(`${GITHUB_RAW_BASE_URL}/v1/releases/${versionEnc}/manifest.json`, {
signal,
}),
fetchFn(
`${GITHUB_RAW_BASE_URL}/v1/releases/${versionEnc}/manifest.json`,
{
signal,
},
),
500,
);
if (res.status === 404) {