mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
fix: abort ShipIt installation attempt at the final mile if the app is running (#36130)
* fix: abort ShipIt installation attempt at the final mile if the app is running * chore: remove only * Update patches/squirrel.mac/fix_abort_installation_attempt_at_the_final_mile_if_the_app_is.patch Co-authored-by: Jeremy Rose <jeremya@chromium.org> * chore: update patches * spec: make the ShipIt process lister helper more resilient Co-authored-by: Jeremy Rose <jeremya@chromium.org> Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import * as express from 'express';
|
||||
import * as fs from 'fs-extra';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import * as psList from 'ps-list';
|
||||
import { AddressInfo } from 'net';
|
||||
import { ifdescribe, ifit } from './spec-helpers';
|
||||
import * as uuid from 'uuid';
|
||||
@@ -95,6 +96,16 @@ ifdescribe(process.platform === 'darwin' && !(process.env.CI && process.arch ===
|
||||
return spawn(path.resolve(appPath, 'Contents/MacOS/Electron'), args);
|
||||
};
|
||||
|
||||
const spawnAppWithHandle = (appPath: string, args: string[] = []) => {
|
||||
return cp.spawn(path.resolve(appPath, 'Contents/MacOS/Electron'), args);
|
||||
};
|
||||
|
||||
const getRunningShipIts = async (appPath: string) => {
|
||||
const processes = await psList();
|
||||
const activeShipIts = processes.filter(p => p.cmd?.includes('Squirrel.framework/Resources/ShipIt com.github.Electron.ShipIt') && p.cmd!.startsWith(appPath));
|
||||
return activeShipIts;
|
||||
};
|
||||
|
||||
const withTempDirectory = async (fn: (dir: string) => Promise<void>, autoCleanUp = true) => {
|
||||
const dir = await fs.mkdtemp(path.resolve(os.tmpdir(), 'electron-update-spec-'));
|
||||
try {
|
||||
@@ -323,6 +334,71 @@ ifdescribe(process.platform === 'darwin' && !(process.env.CI && process.arch ===
|
||||
});
|
||||
});
|
||||
|
||||
it('should abort the update if the application is still running when ShipIt kicks off', async () => {
|
||||
await withUpdatableApp({
|
||||
nextVersion: '2.0.0',
|
||||
startFixture: 'update',
|
||||
endFixture: 'update'
|
||||
}, async (appPath, updateZipPath) => {
|
||||
server.get('/update-file', (req, res) => {
|
||||
res.download(updateZipPath);
|
||||
});
|
||||
server.get('/update-check', (req, res) => {
|
||||
res.json({
|
||||
url: `http://localhost:${port}/update-file`,
|
||||
name: 'My Release Name',
|
||||
notes: 'Theses are some release notes innit',
|
||||
pub_date: (new Date()).toString()
|
||||
});
|
||||
});
|
||||
|
||||
enum FlipFlop {
|
||||
INITIAL,
|
||||
FLIPPED,
|
||||
FLOPPED,
|
||||
}
|
||||
|
||||
const shipItFlipFlopPromise = new Promise<void>((resolve) => {
|
||||
let state = FlipFlop.INITIAL;
|
||||
const checker = setInterval(async () => {
|
||||
const running = await getRunningShipIts(appPath);
|
||||
switch (state) {
|
||||
case FlipFlop.INITIAL: {
|
||||
if (running.length) state = FlipFlop.FLIPPED;
|
||||
break;
|
||||
}
|
||||
case FlipFlop.FLIPPED: {
|
||||
if (!running.length) state = FlipFlop.FLOPPED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (state === FlipFlop.FLOPPED) {
|
||||
clearInterval(checker);
|
||||
resolve();
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
|
||||
const launchResult = await launchApp(appPath, [`http://localhost:${port}/update-check`]);
|
||||
const retainerHandle = spawnAppWithHandle(appPath, ['remain-open']);
|
||||
logOnError(launchResult, () => {
|
||||
expect(launchResult).to.have.property('code', 0);
|
||||
expect(launchResult.out).to.include('Update Downloaded');
|
||||
expect(requests).to.have.lengthOf(2);
|
||||
expect(requests[0]).to.have.property('url', '/update-check');
|
||||
expect(requests[1]).to.have.property('url', '/update-file');
|
||||
expect(requests[0].header('user-agent')).to.include('Electron/');
|
||||
expect(requests[1].header('user-agent')).to.include('Electron/');
|
||||
});
|
||||
|
||||
await shipItFlipFlopPromise;
|
||||
expect(requests).to.have.lengthOf(2, 'should not have relaunched the updated app');
|
||||
expect(JSON.parse(await fs.readFile(path.resolve(appPath, 'Contents/Resources/app/package.json'), 'utf8')).version).to.equal('1.0.0', 'should still be the old version on disk');
|
||||
|
||||
retainerHandle.kill('SIGINT');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with SquirrelMacEnableDirectContentsWrite enabled', () => {
|
||||
let previousValue: any;
|
||||
|
||||
|
||||
52
spec/fixtures/auto-update/update/index.js
vendored
52
spec/fixtures/auto-update/update/index.js
vendored
@@ -15,28 +15,34 @@ autoUpdater.on('error', (err) => {
|
||||
|
||||
const urlPath = path.resolve(__dirname, '../../../../url.txt');
|
||||
let feedUrl = process.argv[1];
|
||||
if (!feedUrl || !feedUrl.startsWith('http')) {
|
||||
feedUrl = `${fs.readFileSync(urlPath, 'utf8')}/${app.getVersion()}`;
|
||||
|
||||
if (feedUrl === 'remain-open') {
|
||||
// Hold the event loop
|
||||
setInterval(() => {});
|
||||
} else {
|
||||
fs.writeFileSync(urlPath, `${feedUrl}/updated`);
|
||||
if (!feedUrl || !feedUrl.startsWith('http')) {
|
||||
feedUrl = `${fs.readFileSync(urlPath, 'utf8')}/${app.getVersion()}`;
|
||||
} else {
|
||||
fs.writeFileSync(urlPath, `${feedUrl}/updated`);
|
||||
}
|
||||
|
||||
autoUpdater.setFeedURL({
|
||||
url: feedUrl
|
||||
});
|
||||
|
||||
autoUpdater.checkForUpdates();
|
||||
|
||||
autoUpdater.on('update-available', () => {
|
||||
console.log('Update Available');
|
||||
});
|
||||
|
||||
autoUpdater.on('update-downloaded', () => {
|
||||
console.log('Update Downloaded');
|
||||
autoUpdater.quitAndInstall();
|
||||
});
|
||||
|
||||
autoUpdater.on('update-not-available', () => {
|
||||
console.error('No update available');
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
autoUpdater.setFeedURL({
|
||||
url: feedUrl
|
||||
});
|
||||
|
||||
autoUpdater.checkForUpdates();
|
||||
|
||||
autoUpdater.on('update-available', () => {
|
||||
console.log('Update Available');
|
||||
});
|
||||
|
||||
autoUpdater.on('update-downloaded', () => {
|
||||
console.log('Update Downloaded');
|
||||
autoUpdater.quitAndInstall();
|
||||
});
|
||||
|
||||
autoUpdater.on('update-not-available', () => {
|
||||
console.error('No update available');
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"mocha-junit-reporter": "^1.18.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"pdfjs-dist": "^2.2.228",
|
||||
"ps-list": "^7.0.0",
|
||||
"q": "^1.5.1",
|
||||
"send": "^0.16.2",
|
||||
"sinon": "^9.0.1",
|
||||
|
||||
@@ -73,10 +73,9 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
abstract-socket@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/abstract-socket/-/abstract-socket-2.1.1.tgz#243a7e6e6ff65bb9eab16a22fa90699b91e528f7"
|
||||
integrity sha512-YZJizsvS1aBua5Gd01woe4zuyYBGgSMeqDOB6/ChwdTI904KP6QGtJswXl4hcqWxbz86hQBe++HWV0hF1aGUtA==
|
||||
"abstract-socket@github:saghul/node-abstractsocket#35b1b1491fabc04899bde5be3428abf5cf9cd528":
|
||||
version "2.1.0"
|
||||
resolved "https://codeload.github.com/saghul/node-abstractsocket/tar.gz/35b1b1491fabc04899bde5be3428abf5cf9cd528"
|
||||
dependencies:
|
||||
bindings "^1.2.1"
|
||||
nan "^2.12.1"
|
||||
@@ -303,7 +302,7 @@ dashdash@^1.12.0:
|
||||
safe-buffer "^5.1.1"
|
||||
xml2js "^0.4.17"
|
||||
optionalDependencies:
|
||||
abstract-socket "^2.0.0"
|
||||
abstract-socket "github:saghul/node-abstractsocket#35b1b1491fabc04899bde5be3428abf5cf9cd528"
|
||||
|
||||
debug@2.6.9, debug@^2.2.0:
|
||||
version "2.6.9"
|
||||
@@ -937,6 +936,11 @@ performance-now@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
||||
|
||||
ps-list@^7.0.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ps-list/-/ps-list-7.2.0.tgz#3d110e1de8249a4b178c9b1cf2a215d1e4e42fc0"
|
||||
integrity sha512-v4Bl6I3f2kJfr5o80ShABNHAokIgY+wFDTQfE+X3zWYgSGQOCBeYptLZUpoOALBqO5EawmDN/tjTldJesd0ujQ==
|
||||
|
||||
psl@^1.1.24:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
|
||||
|
||||
Reference in New Issue
Block a user