From 7fd414d13180ebfee56f0070e88cd743b41f3fd7 Mon Sep 17 00:00:00 2001 From: Arek Sredzki Date: Thu, 26 Jan 2023 13:31:30 -1000 Subject: [PATCH] fix(publisher-ers): Update ERS API usage for v2.0 Recently, v2.0 of electron-release-server was released. This version updated many of the underlying packages and should be adopted by all users of the server. In the process, the API changed due to an change with SailsJS. This corrects the API usage within the ERS publisher plugin to allow users to continue using it. Note that this issue was reported here: https://github.com/ArekSredzki/electron-release-server/issues/314 --- .../src/PublisherERS.ts | 36 +++++++++++-------- .../test/PublisherERS_spec.ts | 15 ++++---- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/packages/publisher/electron-release-server/src/PublisherERS.ts b/packages/publisher/electron-release-server/src/PublisherERS.ts index fd46396542..891801e11d 100644 --- a/packages/publisher/electron-release-server/src/PublisherERS.ts +++ b/packages/publisher/electron-release-server/src/PublisherERS.ts @@ -11,10 +11,19 @@ import { PublisherERSConfig } from './Config'; const d = debug('electron-forge:publish:ers'); +interface ERSAsset { + name: string; + platform: string; +} + +interface ERSFlavor { + name: string; +} + interface ERSVersion { name: string; - assets: { name: string }[]; - flavor?: string; + assets: ERSAsset[]; + flavor: ERSFlavor; } const fetchAndCheckStatus = async (url: RequestInfo, init?: RequestInit): Promise => { @@ -71,16 +80,15 @@ export default class PublisherERS extends PublisherBase { const authFetch = (apiPath: string, options?: RequestInit) => fetchAndCheckStatus(api(apiPath), { ...(options || {}), headers: { ...(options || {}).headers, Authorization: `Bearer ${token}` } }); - const versions: ERSVersion[] = await (await authFetch('api/version')).json(); const flavor = config.flavor || 'default'; for (const makeResult of makeResults) { const { packageJSON } = makeResult; const artifacts = makeResult.artifacts.filter((artifactPath) => path.basename(artifactPath).toLowerCase() !== 'releases'); - const existingVersion = versions.find((version) => { - return version.name === packageJSON.version && (!version.flavor || version.flavor === flavor); - }); + const versions: ERSVersion[] = await (await authFetch('api/version')).json(); + // Find the version with the same name and flavor + const existingVersion = versions.find((version) => version.name === packageJSON.version && version.flavor.name === flavor); let channel = 'stable'; if (config.channel) { @@ -97,12 +105,11 @@ export default class PublisherERS extends PublisherBase { await authFetch('api/version', { method: 'POST', body: JSON.stringify({ - channel: { - name: channel, - }, - flavor: config.flavor, + channel: channel, + flavor: flavor, name: packageJSON.version, notes: '', + id: packageJSON.version + '_' + channel, }), headers: { 'Content-Type': 'application/json', @@ -115,10 +122,10 @@ export default class PublisherERS extends PublisherBase { updateStatusLine(); await Promise.all( - artifacts.map(async (artifactPath) => { + artifacts.map(async (artifactPath: string) => { + const platform = ersPlatform(makeResult.platform, makeResult.arch); if (existingVersion) { - const existingAsset = existingVersion.assets.find((asset) => asset.name === path.basename(artifactPath)); - + const existingAsset = existingVersion.assets.find((asset) => asset.name === path.basename(artifactPath) && asset.platform === platform); if (existingAsset) { d('asset at path:', artifactPath, 'already exists on server'); uploaded += 1; @@ -130,8 +137,7 @@ export default class PublisherERS extends PublisherBase { const artifactForm = new FormData(); artifactForm.append('token', token); artifactForm.append('version', `${packageJSON.version}_${flavor}`); - artifactForm.append('platform', ersPlatform(makeResult.platform, makeResult.arch)); - + artifactForm.append('platform', platform); // see https://github.com/form-data/form-data/issues/426 const fileOptions = { knownLength: fs.statSync(artifactPath).size, diff --git a/packages/publisher/electron-release-server/test/PublisherERS_spec.ts b/packages/publisher/electron-release-server/test/PublisherERS_spec.ts index ccc36d3f5e..52a79d4c2c 100644 --- a/packages/publisher/electron-release-server/test/PublisherERS_spec.ts +++ b/packages/publisher/electron-release-server/test/PublisherERS_spec.ts @@ -35,7 +35,7 @@ describe('PublisherERS', () => { // mock login fetch.postOnce('path:/api/auth/login', { body: { token }, status: 200 }); // mock fetch all existing versions - fetch.getOnce('path:/api/version', { body: [{ name: '2.0.0', assets: [], flavor: 'default' }], status: 200 }); + fetch.getOnce('path:/api/version', { body: [{ name: '2.0.0', assets: [], flavor: { name: 'default' } }], status: 200 }); // mock creating a new version fetch.postOnce('path:/api/version', { status: 200 }); // mock asset upload @@ -65,7 +65,7 @@ describe('PublisherERS', () => { // creates a new version with the correct flavor, name, and channel expect(calls[2][0]).to.equal(`${baseUrl}/api/version`); - expect(calls[2][1]?.body).to.equal(`{"channel":{"name":"stable"},"flavor":"${flavor}","name":"${version}","notes":""}`); + expect(calls[2][1]?.body).to.equal(`{"channel":"stable","flavor":"${flavor}","name":"${version}","notes":"","id":"${version}_stable"}`); // uploads asset successfully expect(calls[3][0]).to.equal(`${baseUrl}/api/asset`); @@ -83,7 +83,7 @@ describe('PublisherERS', () => { // mock login fetch.postOnce('path:/api/auth/login', { body: { token }, status: 200 }); // mock fetch all existing versions - fetch.getOnce('path:/api/version', { body: [{ name: '2.0.0', assets: [], flavor: 'lite' }], status: 200 }); + fetch.getOnce('path:/api/version', { body: [{ name: '2.0.0', assets: [], flavor: { name: 'lite' } }], status: 200 }); // mock asset upload fetch.post('path:/api/asset', { status: 200 }); @@ -123,7 +123,10 @@ describe('PublisherERS', () => { // mock login fetch.postOnce('path:/api/auth/login', { body: { token }, status: 200 }); // mock fetch all existing versions - fetch.getOnce('path:/api/version', { body: [{ name: '2.0.0', assets: [{ name: 'existing-artifact' }], flavor: 'default' }], status: 200 }); + fetch.getOnce('path:/api/version', { + body: [{ name: '2.0.0', assets: [{ name: 'existing-artifact', platform: 'linux_64' }], flavor: { name: 'default' } }], + status: 200, + }); const publisher = new PublisherERS({ baseUrl, @@ -158,7 +161,7 @@ describe('PublisherERS', () => { // mock login fetch.postOnce('path:/api/auth/login', { body: { token }, status: 200 }); // mock fetch all existing versions - fetch.getOnce('path:/api/version', { body: [{ name: '2.0.0', assets: [{ name: 'existing-artifact' }], flavor: 'default' }], status: 200 }); + fetch.getOnce('path:/api/version', { body: [{ name: '2.0.0', assets: [{ name: 'existing-artifact' }], flavor: { name: 'default' } }], status: 200 }); // mock creating a new version fetch.postOnce('path:/api/version', { status: 200 }); // mock asset upload @@ -188,7 +191,7 @@ describe('PublisherERS', () => { // creates a new version with the correct flavor, name, and channel expect(calls[2][0]).to.equal(`${baseUrl}/api/version`); - expect(calls[2][1]?.body).to.equal(`{"channel":{"name":"stable"},"flavor":"${flavor}","name":"${version}","notes":""}`); + expect(calls[2][1]?.body).to.equal(`{"channel":"stable","flavor":"${flavor}","name":"${version}","notes":"","id":"${version}_stable"}`); // uploads asset successfully expect(calls[3][0]).to.equal(`${baseUrl}/api/asset`);