UNPKG

10.4 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.writeUpdateInfoFiles = exports.createUpdateInfoTasks = void 0;
4const bluebird_lst_1 = require("bluebird-lst");
5const builder_util_1 = require("builder-util");
6const fs_extra_1 = require("fs-extra");
7const lazy_val_1 = require("lazy-val");
8const path = require("path");
9const semver = require("semver");
10const core_1 = require("../core");
11const hash_1 = require("../util/hash");
12const PublishManager_1 = require("./PublishManager");
13async function getReleaseInfo(packager) {
14 const releaseInfo = { ...(packager.platformSpecificBuildOptions.releaseInfo || packager.config.releaseInfo) };
15 if (releaseInfo.releaseNotes == null) {
16 const releaseNotesFile = await packager.getResource(releaseInfo.releaseNotesFile, `release-notes-${packager.platform.buildConfigurationKey}.md`, `release-notes-${packager.platform.name}.md`, `release-notes-${packager.platform.nodeName}.md`, "release-notes.md");
17 const releaseNotes = releaseNotesFile == null ? null : await (0, fs_extra_1.readFile)(releaseNotesFile, "utf-8");
18 // to avoid undefined in the file, check for null
19 if (releaseNotes != null) {
20 releaseInfo.releaseNotes = releaseNotes;
21 }
22 }
23 delete releaseInfo.releaseNotesFile;
24 return releaseInfo;
25}
26function isGenerateUpdatesFilesForAllChannels(packager) {
27 const value = packager.platformSpecificBuildOptions.generateUpdatesFilesForAllChannels;
28 return value == null ? packager.config.generateUpdatesFilesForAllChannels : value;
29}
30/**
31 if this is an "alpha" version, we need to generate only the "alpha" .yml file
32 if this is a "beta" version, we need to generate both the "alpha" and "beta" .yml file
33 if this is a "stable" version, we need to generate all the "alpha", "beta" and "stable" .yml file
34 */
35function computeChannelNames(packager, publishConfig) {
36 const currentChannel = publishConfig.channel || "latest";
37 // for GitHub should be pre-release way be used
38 if (currentChannel === "alpha" || publishConfig.provider === "github" || !isGenerateUpdatesFilesForAllChannels(packager)) {
39 return [currentChannel];
40 }
41 switch (currentChannel) {
42 case "beta":
43 return [currentChannel, "alpha"];
44 case "latest":
45 return [currentChannel, "alpha", "beta"];
46 default:
47 return [currentChannel];
48 }
49}
50function getUpdateInfoFileName(channel, packager, arch) {
51 const osSuffix = packager.platform === core_1.Platform.WINDOWS ? "" : `-${packager.platform.buildConfigurationKey}`;
52 return `${channel}${osSuffix}${getArchPrefixForUpdateFile(arch, packager)}.yml`;
53}
54function getArchPrefixForUpdateFile(arch, packager) {
55 if (arch == null || arch === builder_util_1.Arch.x64 || packager.platform !== core_1.Platform.LINUX) {
56 return "";
57 }
58 return arch === builder_util_1.Arch.armv7l ? "-arm" : `-${builder_util_1.Arch[arch]}`;
59}
60function computeIsisElectronUpdater1xCompatibility(updaterCompatibility, publishConfiguration, packager) {
61 if (updaterCompatibility != null) {
62 return semver.satisfies("1.0.0", updaterCompatibility);
63 }
64 // spaces is a new publish provider, no need to keep backward compatibility
65 if (publishConfiguration.provider === "spaces") {
66 return false;
67 }
68 const updaterVersion = packager.metadata.dependencies == null ? null : packager.metadata.dependencies["electron-updater"];
69 return updaterVersion == null || semver.lt(updaterVersion, "4.0.0");
70}
71/** @internal */
72async function createUpdateInfoTasks(event, _publishConfigs) {
73 const packager = event.packager;
74 const publishConfigs = await (0, PublishManager_1.getPublishConfigsForUpdateInfo)(packager, _publishConfigs, event.arch);
75 if (publishConfigs == null || publishConfigs.length === 0) {
76 return [];
77 }
78 const outDir = event.target.outDir;
79 const version = packager.appInfo.version;
80 const sha2 = new lazy_val_1.Lazy(() => (0, hash_1.hashFile)(event.file, "sha256", "hex"));
81 const isMac = packager.platform === core_1.Platform.MAC;
82 const createdFiles = new Set();
83 const sharedInfo = await createUpdateInfo(version, event, await getReleaseInfo(packager));
84 const tasks = [];
85 const electronUpdaterCompatibility = packager.platformSpecificBuildOptions.electronUpdaterCompatibility || packager.config.electronUpdaterCompatibility || ">=2.15";
86 for (const publishConfiguration of publishConfigs) {
87 let dir = outDir;
88 if (publishConfigs.length > 1 && publishConfiguration !== publishConfigs[0]) {
89 dir = path.join(outDir, publishConfiguration.provider);
90 }
91 let isElectronUpdater1xCompatibility = computeIsisElectronUpdater1xCompatibility(electronUpdaterCompatibility, publishConfiguration, packager.info);
92 let info = sharedInfo;
93 // noinspection JSDeprecatedSymbols
94 if (isElectronUpdater1xCompatibility && packager.platform === core_1.Platform.WINDOWS) {
95 info = {
96 ...info,
97 };
98 info.sha2 = await sha2.value;
99 }
100 if (event.safeArtifactName != null && publishConfiguration.provider === "github") {
101 const newFiles = info.files.slice();
102 newFiles[0].url = event.safeArtifactName;
103 info = {
104 ...info,
105 files: newFiles,
106 path: event.safeArtifactName,
107 };
108 }
109 for (const channel of computeChannelNames(packager, publishConfiguration)) {
110 if (isMac && isElectronUpdater1xCompatibility && event.file.endsWith(".zip")) {
111 // write only for first channel (generateUpdatesFilesForAllChannels is a new functionality, no need to generate old mac update info file)
112 isElectronUpdater1xCompatibility = false;
113 await writeOldMacInfo(publishConfiguration, outDir, dir, channel, createdFiles, version, packager);
114 }
115 const updateInfoFile = path.join(dir, getUpdateInfoFileName(channel, packager, event.arch));
116 if (createdFiles.has(updateInfoFile)) {
117 continue;
118 }
119 createdFiles.add(updateInfoFile);
120 // artifact should be uploaded only to designated publish provider
121 tasks.push({
122 file: updateInfoFile,
123 info,
124 publishConfiguration,
125 packager,
126 });
127 }
128 }
129 return tasks;
130}
131exports.createUpdateInfoTasks = createUpdateInfoTasks;
132async function createUpdateInfo(version, event, releaseInfo) {
133 const customUpdateInfo = event.updateInfo;
134 const url = path.basename(event.file);
135 const sha512 = (customUpdateInfo == null ? null : customUpdateInfo.sha512) || (await (0, hash_1.hashFile)(event.file));
136 const files = [{ url, sha512 }];
137 const result = {
138 // @ts-ignore
139 version,
140 // @ts-ignore
141 files,
142 // @ts-ignore
143 path: url /* backward compatibility, electron-updater 1.x - electron-updater 2.15.0 */,
144 // @ts-ignore
145 sha512 /* backward compatibility, electron-updater 1.x - electron-updater 2.15.0 */,
146 ...releaseInfo,
147 };
148 if (customUpdateInfo != null) {
149 // file info or nsis web installer packages info
150 Object.assign("sha512" in customUpdateInfo ? files[0] : result, customUpdateInfo);
151 }
152 return result;
153}
154async function writeUpdateInfoFiles(updateInfoFileTasks, packager) {
155 // zip must be first and zip info must be used for old path/sha512 properties in the update info
156 updateInfoFileTasks.sort((a, b) => (a.info.files[0].url.endsWith(".zip") ? 0 : 100) - (b.info.files[0].url.endsWith(".zip") ? 0 : 100));
157 const updateChannelFileToInfo = new Map();
158 for (const task of updateInfoFileTasks) {
159 // https://github.com/electron-userland/electron-builder/pull/2994
160 const key = `${task.file}@${(0, builder_util_1.safeStringifyJson)(task.publishConfiguration, new Set(["releaseType"]))}`;
161 const existingTask = updateChannelFileToInfo.get(key);
162 if (existingTask == null) {
163 updateChannelFileToInfo.set(key, task);
164 continue;
165 }
166 existingTask.info.files.push(...task.info.files);
167 }
168 const releaseDate = new Date().toISOString();
169 await bluebird_lst_1.default.map(updateChannelFileToInfo.values(), async (task) => {
170 const publishConfig = task.publishConfiguration;
171 if (publishConfig.publishAutoUpdate === false) {
172 builder_util_1.log.debug({
173 provider: publishConfig.provider,
174 reason: "publishAutoUpdate is set to false",
175 }, "auto update metadata file not published");
176 return;
177 }
178 if (task.info.releaseDate == null) {
179 task.info.releaseDate = releaseDate;
180 }
181 const fileContent = Buffer.from((0, builder_util_1.serializeToYaml)(task.info, false, true));
182 await (0, fs_extra_1.outputFile)(task.file, fileContent);
183 packager.dispatchArtifactCreated({
184 file: task.file,
185 fileContent,
186 arch: null,
187 packager: task.packager,
188 target: null,
189 publishConfig,
190 });
191 }, { concurrency: 4 });
192}
193exports.writeUpdateInfoFiles = writeUpdateInfoFiles;
194// backward compatibility - write json file
195async function writeOldMacInfo(publishConfig, outDir, dir, channel, createdFiles, version, packager) {
196 const isGitHub = publishConfig.provider === "github";
197 const updateInfoFile = isGitHub && outDir === dir ? path.join(dir, "github", `${channel}-mac.json`) : path.join(dir, `${channel}-mac.json`);
198 if (!createdFiles.has(updateInfoFile)) {
199 createdFiles.add(updateInfoFile);
200 await (0, fs_extra_1.outputJson)(updateInfoFile, {
201 version,
202 releaseDate: new Date().toISOString(),
203 url: (0, PublishManager_1.computeDownloadUrl)(publishConfig, packager.generateName2("zip", "mac", isGitHub), packager),
204 }, { spaces: 2 });
205 packager.info.dispatchArtifactCreated({
206 file: updateInfoFile,
207 arch: null,
208 packager,
209 target: null,
210 publishConfig,
211 });
212 }
213}
214//# sourceMappingURL=updateInfoBuilder.js.map
\No newline at end of file