per1234 fe19e0ef26 Use Apple Silicon build artifact name required by electron-updater
The Arduino IDE update check uses a "channel update info file" on Arduino's download server. This file specifies the
latest version of Arduino IDE available from the Arduino download server as well as the download URLs for the release
archives.

There is a separate channel file for each host operating system:

- Windows
- Linux
- macOS

Two macOS host architectures are now supported:

- x86 (AKA "Intel")
- ARM64 (AKA "Apple Silicon")

These each have their own release archive files. The macOS channel file contains data on both. So the updater must be
able to identify the appropriate archive to use for the update based on the host architecture. This is based on the
archive filename.

Arduino IDE's auto-update feature is built on the electron-updater package. The release archive selection is handled by
the electron-updater codebase and the filename pattern is hardcoded there. It selects the archive file that contains
`arm64` in its name (case sensitive), if present, to use for updates on macOS hosts with ARM64 architecture.

Previously, the build system produced archive files with the name format arduino-ide_<version>_macOS_ARM64.zip,
consistent with the established naming in other Arduino tooling projects. Unfortunately this naming would cause either
(depending on the order of the entries in the channel file) the x86 build to be used to update ARM64 macOS hosts
(resulting in lesser performance due to Rosetta 2 overhead) or the ARM64 build to be used to update x86 hosts (resulting
in the IDE failing to start).

So it is necessary to change the build artifact name to follow the format dictated by the electron-updater package.
Although it is not required (because electron-updater uses separate channel files for the x86 and ARM hosts), the Linux
archive filename format was also changed for the sake of consistency.
2023-02-27 01:05:36 -08:00

156 lines
3.7 KiB
JavaScript

//@ts-check
const fs = require('fs');
const path = require('path');
const semver = require('semver');
const merge = require('deepmerge');
const dateFormat = require('dateformat');
const { isNightly, isRelease, git } = require('./utils');
function artifactName() {
const { platform, arch } = process;
const id = (() => {
if (isRelease) {
return getVersion();
} else if (isNightly) {
return `nightly-${timestamp()}`;
} else {
return getVersion();
}
})();
const name = 'arduino-ide';
switch (platform) {
case 'win32': {
if (arch === 'x64') {
return `${name}_${id}_Windows_64bit.\$\{ext}`;
}
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
}
case 'darwin': {
if (arch === 'arm64') {
return `${name}_${id}_macOS_arm64.\$\{ext}`;
}
return `${name}_${id}_macOS_64bit.\$\{ext}`;
}
case 'linux': {
switch (arch) {
case 'arm': {
return `${name}_${id}_Linux_armv7.\$\{ext}`;
}
case 'arm64': {
return `${name}_${id}_Linux_arm64.\$\{ext}`;
}
case 'x64': {
return `${name}_${id}_Linux_64bit.\$\{ext}`;
}
default: {
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
}
}
}
default:
throw new Error(`Unsupported platform, arch: ${platform}, ${arch}`);
}
}
function electronPlatform() {
switch (process.platform) {
case 'win32': {
return 'win';
}
case 'darwin': {
return 'mac';
}
case 'linux': {
return 'linux';
}
default:
throw new Error(`Unsupported platform: ${process.platform}.`);
}
}
function getVersion() {
const repositoryRootPath = git('rev-parse --show-toplevel');
let version = JSON.parse(
fs.readFileSync(path.join(repositoryRootPath, 'package.json'), {
encoding: 'utf8',
})
).version;
if (!semver.valid(version)) {
throw new Error(
`Could not read version from root package.json. Version was: '${version}'.`
);
}
if (!isRelease) {
if (isNightly) {
version = `${version}-nightly-${timestamp()}`;
} else {
version = `${version}-snapshot-${currentCommitish()}`;
}
if (!semver.valid(version)) {
throw new Error(`Invalid patched version: '${version}'.`);
}
}
return version;
}
function getChannel() {
if (isRelease) {
return 'stable';
}
if (isNightly) {
return 'nightly';
}
return '';
}
function timestamp() {
return dateFormat(new Date(), 'yyyymmdd');
}
function currentCommitish() {
return git('rev-parse --short HEAD');
}
// function currentBranch() {
// return git('rev-parse --abbrev-ref HEAD');
// }
function generateTemplate(buildDate) {
// do `export PUBLISH=true yarn package` if you want to mimic CI build locally.
// const electronPublish = release || (isCI && currentBranch() === 'main') || process.env.PUBLISH === 'true';
const version = getVersion();
const productName = 'Arduino IDE';
const name = 'arduino-ide';
const updateChannel = getChannel();
let customizations = {
name,
description: productName,
version,
theia: {
frontend: {
config: {
'arduino.ide.updateChannel': updateChannel,
},
},
},
build: {
productName,
appId: 'cc.arduino.IDE2',
[electronPlatform()]: {
artifactName: artifactName(),
},
},
};
if (buildDate) {
customizations = merge(customizations, {
theia: { frontend: { config: { buildDate } } },
});
}
const template = require('../build/template-package.json');
return merge(template, customizations);
}
module.exports = { generateTemplate };