fix(publisher-ers): Update ERS API usage for v2.0 (#3149)

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 a 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
This commit is contained in:
Arek Sredzki 2023-02-06 16:28:11 -08:00 коммит произвёл GitHub
Родитель 8ed43ee7c7
Коммит 3d5c87c817
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 30 добавлений и 21 удалений

Просмотреть файл

@ -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<Response> => {
@ -71,16 +80,15 @@ export default class PublisherERS extends PublisherBase<PublisherERSConfig> {
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<PublisherERSConfig> {
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<PublisherERSConfig> {
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<PublisherERSConfig> {
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,

Просмотреть файл

@ -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`);