Merge pull request #18116 from atom/dw-update-server-script

Add a simple server for testing Atom updates, enable Atom to use it via environment variable
This commit is contained in:
Jason Rudolph 2019-05-21 12:38:38 -04:00 committed by GitHub
commit 677a46de40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 588 additions and 3 deletions

View File

@ -21,6 +21,7 @@ const argv = yargs
.help('help')
.describe('existing-binaries', 'Use existing Atom binaries (skip clean/transpile/cache)')
.describe('code-sign', 'Code-sign executables (macOS and Windows only)')
.describe('test-sign', 'Test-sign executables (macOS only)')
.describe('create-windows-installer', 'Create installer (Windows only)')
.describe('create-debian-package', 'Create .deb package (Linux only)')
.describe('create-rpm-package', 'Create .rpm package (Linux only)')
@ -49,6 +50,7 @@ const generateStartupSnapshot = require('./lib/generate-startup-snapshot')
const installApplication = require('./lib/install-application')
const packageApplication = require('./lib/package-application')
const prebuildLessCache = require('./lib/prebuild-less-cache')
const testSignOnMac = require('./lib/test-sign-on-mac')
const transpileBabelPaths = require('./lib/transpile-babel-paths')
const transpileCoffeeScriptPaths = require('./lib/transpile-coffee-script-paths')
const transpileCsonPaths = require('./lib/transpile-cson-paths')
@ -92,12 +94,18 @@ if (!argv.generateApiDocs) {
case 'darwin': {
if (argv.codeSign) {
codeSignOnMac(packagedAppPath)
} else if (argv.testSign) {
testSignOnMac(packagedAppPath)
} else {
console.log('Skipping code-signing. Specify the --code-sign option to perform code-signing'.gray)
}
break
}
case 'win32': {
if (argv.testSign) {
console.log('Test signing is not supported on Windows, skipping.'.gray)
}
if (argv.codeSign) {
const executablesToSign = [ path.join(packagedAppPath, 'Atom.exe') ]
if (argv.createWindowsInstaller) {

View File

@ -9,6 +9,7 @@ const CONFIG = require('../config')
module.exports = (packagedAppPath) => {
const archSuffix = process.arch === 'ia32' ? '' : '-' + process.arch
const updateUrlPrefix = process.env.ATOM_UPDATE_URL_PREFIX || 'https://atom.io'
const options = {
appDirectory: packagedAppPath,
authors: 'GitHub Inc.',
@ -17,7 +18,7 @@ module.exports = (packagedAppPath) => {
outputDirectory: CONFIG.buildOutputPath,
noMsi: true,
noDelta: CONFIG.channel === 'nightly', // Delta packages are broken for nightly versions past nightly9 due to Squirrel/NuGet limitations
remoteReleases: `https://atom.io/api/updates${archSuffix}?version=${CONFIG.computedAppVersion}`,
remoteReleases: `${updateUrlPrefix}/api/updates${archSuffix}?version=${CONFIG.computedAppVersion}`,
setupExe: `AtomSetup${process.arch === 'x64' ? '-x64' : ''}.exe`,
setupIcon: path.join(CONFIG.repositoryRootPath, 'resources', 'app-icons', CONFIG.channel, 'atom.ico')
}

View File

@ -0,0 +1,23 @@
const spawnSync = require('./spawn-sync')
module.exports = function (packagedAppPath) {
const result =
spawnSync('security', [
'find-certificate', '-c', 'Mac Developer'
])
const certMatch = (result.stdout || '').toString().match(/\"(Mac Developer.*\))\"/)
if (!certMatch || !certMatch[1]) {
console.error('A "Mac Developer" certificate must be configured to perform test signing')
} else {
// This code-signs the application with a local certificate which won't be
// useful anywhere else but the current machine
// See this issue for more details: https://github.com/electron/electron/issues/7476#issuecomment-356084754
console.log(`Found development certificate '${certMatch[1]}'`)
console.log(`Test-signing application at ${packagedAppPath}`)
spawnSync('codesign', [
'--deep', '--force', '--verbose',
'--sign', certMatch[1], packagedAppPath
], {stdio: 'inherit'})
}
}

View File

@ -0,0 +1,61 @@
# Atom Update Test Server
This folder contains a simple implementation of Atom's update server to be used for testing the update process with local builds.
## Prerequisites
On macOS, you will need to configure a "Mac Development" certificate for your local machine so that the `script/build --test-sign` parameter will work. Here are the steps to set one up:
1. Install Xcode if it isn't already
1. Launch Xcode and open the Preferences dialog (<kbd>Cmd + ,</kbd>)
1. Switch to the Accounts tab
1. If you don't already see your Apple account in the leftmost column, click the `+` button at the bottom left of the window, select "Apple ID" and then click Continue. Sign in with your Apple account and then you'll be sent back to the Accounts tab.
1. Click the "Manage Certificates..." button in the lower right of the Accounts page
1. Click the `+` button in the lower left of the Signing Certificates popup and then select "Mac Development"
1. A new certificate should now be in the list of the Signing Certificates window with the name of your macOS machine. Click "Done"
1. In a Terminal, verify that your Mac Development certificate is set up by running
```
security find-certificate -c 'Mac Developer'
```
If it returns a lot of information with "Mac Developer: your@apple-id-email.com" inside of it, your certificate is configured correctly and you're now ready to run an Atom build with the `--test-sign` parameter.
## How to use it
1. Since you probably want to try upgrading an installed Atom release to a newer version, start your shell and set the `ATOM_RELEASE_VERSION` environment var to the version that you want the server to advertise as the latest version:
**Windows**
```
set ATOM_RELEASE_VERSION="1.32.0-beta1"
```
**macOS**
```
export ATOM_RELEASE_VERSION="1.32.0-beta1"
```
2. Run a full build of Atom such that the necessary release artifacts are in the `out` folder:
**Windows**
```
script/build --create-windows-installer
```
**macOS**
```
script/build --compress-artifacts --test-sign
```
3. Start up the server in this folder:
```
npm install
npm start
```
**NOTE:** You can customize the port by setting the `PORT` environment variable.
4. Start Atom from the command line with the `ATOM_UPDATE_URL_PREFIX` environment variable set to `http://localhost:3456` (change this to reflect any `PORT` override you might have used)
5. Open the About page and try to update Atom. The update server will write output to the console when requests are received.

378
script/update-server/package-lock.json generated Normal file
View File

@ -0,0 +1,378 @@
{
"name": "atom-test-update-server",
"version": "0.1.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"accepts": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
"integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
"requires": {
"mime-types": "~2.1.18",
"negotiator": "0.6.1"
}
},
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
},
"body-parser": {
"version": "1.18.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
"integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
"requires": {
"bytes": "3.0.0",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "~1.1.1",
"http-errors": "~1.6.2",
"iconv-lite": "0.4.19",
"on-finished": "~2.3.0",
"qs": "6.5.1",
"raw-body": "2.3.2",
"type-is": "~1.6.15"
}
},
"bytes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
},
"colors": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.2.tgz",
"integrity": "sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ=="
},
"content-disposition": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
"integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
},
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
},
"cookie": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"destroy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
},
"etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"express": {
"version": "4.16.3",
"resolved": "http://registry.npmjs.org/express/-/express-4.16.3.tgz",
"integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
"requires": {
"accepts": "~1.3.5",
"array-flatten": "1.1.1",
"body-parser": "1.18.2",
"content-disposition": "0.5.2",
"content-type": "~1.0.4",
"cookie": "0.3.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "~1.1.2",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "1.1.1",
"fresh": "0.5.2",
"merge-descriptors": "1.0.1",
"methods": "~1.1.2",
"on-finished": "~2.3.0",
"parseurl": "~1.3.2",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.3",
"qs": "6.5.1",
"range-parser": "~1.2.0",
"safe-buffer": "5.1.1",
"send": "0.16.2",
"serve-static": "1.13.2",
"setprototypeof": "1.1.0",
"statuses": "~1.4.0",
"type-is": "~1.6.16",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
}
},
"finalhandler": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
"requires": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "~2.3.0",
"parseurl": "~1.3.2",
"statuses": "~1.4.0",
"unpipe": "~1.0.0"
}
},
"forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
},
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"http-errors": {
"version": "1.6.3",
"resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.3",
"setprototypeof": "1.1.0",
"statuses": ">= 1.4.0 < 2"
}
},
"iconv-lite": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ipaddr.js": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz",
"integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4="
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
},
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"mime": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
},
"mime-db": {
"version": "1.36.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz",
"integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw=="
},
"mime-types": {
"version": "2.1.20",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz",
"integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==",
"requires": {
"mime-db": "~1.36.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"negotiator": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"requires": {
"ee-first": "1.1.1"
}
},
"parseurl": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
},
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"proxy-addr": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
"integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==",
"requires": {
"forwarded": "~0.1.2",
"ipaddr.js": "1.8.0"
}
},
"qs": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
"integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
},
"range-parser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
},
"raw-body": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
"integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
"requires": {
"bytes": "3.0.0",
"http-errors": "1.6.2",
"iconv-lite": "0.4.19",
"unpipe": "1.0.0"
},
"dependencies": {
"depd": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
"integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
},
"http-errors": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
"integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
"requires": {
"depd": "1.1.1",
"inherits": "2.0.3",
"setprototypeof": "1.0.3",
"statuses": ">= 1.3.1 < 2"
}
},
"setprototypeof": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
"integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
}
}
},
"safe-buffer": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
},
"send": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
"integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
"requires": {
"debug": "2.6.9",
"depd": "~1.1.2",
"destroy": "~1.0.4",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "~1.6.2",
"mime": "1.4.1",
"ms": "2.0.0",
"on-finished": "~2.3.0",
"range-parser": "~1.2.0",
"statuses": "~1.4.0"
}
},
"serve-static": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
"integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
"requires": {
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"parseurl": "~1.3.2",
"send": "0.16.2"
}
},
"setprototypeof": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
},
"statuses": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
},
"type-is": {
"version": "1.6.16",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
"integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
"requires": {
"media-typer": "0.3.0",
"mime-types": "~2.1.18"
}
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
"utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
}
}
}

View File

@ -0,0 +1,15 @@
{
"name": "atom-test-update-server",
"version": "0.1.0",
"private": true,
"description": "A test update server that replicates the one on atom.io",
"main": "run-server.js",
"scripts": {
"start": "node run-server.js"
},
"author": "David Wilson",
"dependencies": {
"colors": "^1.3.2",
"express": "^4.16.3"
}
}

View File

@ -0,0 +1,98 @@
require('colors')
const fs = require('fs')
const path = require('path')
const express = require('express')
const app = express()
const port = process.env.PORT || 3456
// Load the metadata for the local build of Atom
const buildPath = path.resolve(__dirname, '..', '..', 'out')
const packageJsonPath = path.join(buildPath, 'app', 'package.json')
if (!fs.existsSync(buildPath) || !fs.existsSync(packageJsonPath)) {
console.log(`This script requires a full Atom build with release packages for the current platform in the following path:\n ${buildPath}\n`)
if (process.platform === 'darwin') {
console.log(`Run this command before trying again:\n script/build --compress-artifacts --test-sign\n\n`)
} else if (process.platform === 'win32') {
console.log(`Run this command before trying again:\n script/build --create-windows-installer\n\n`)
}
process.exit(1)
}
const appMetadata = require(packageJsonPath)
const versionMatch = appMetadata.version.match(/-(beta|nightly)\d+$/)
const releaseChannel = versionMatch ? versionMatch[1] : 'stable'
console.log(`Serving ${appMetadata.productName} release assets (channel = ${releaseChannel})\n`.green)
function getMacZip (req, res) {
console.log(`Received request for atom-mac.zip, sending it`)
res.sendFile(path.join(buildPath, 'atom-mac.zip'))
}
function getMacUpdates (req, res) {
if (req.query.version !== appMetadata.version) {
const updateInfo = {
name: appMetadata.version,
pub_date: new Date().toISOString(),
url: `http://localhost:${port}/mac/atom-mac.zip`,
notes: '<p>No Details</p>'
}
console.log(`Received request for macOS updates (version = ${req.query.version}), sending\n`, updateInfo)
res.json(updateInfo)
} else {
console.log(`Received request for macOS updates, sending 204 as Atom is up to date (version = ${req.query.version})`)
res.sendStatus(204)
}
}
function getReleasesFile (fileName) {
return function (req, res) {
console.log(`Received request for ${fileName}, version: ${req.query.version}`)
if (req.query.version) {
const versionMatch = (req.query.version || '').match(/-(beta|nightly)\d+$/)
const versionChannel = (versionMatch && versionMatch[1]) || 'stable'
if (releaseChannel !== versionChannel) {
console.log(`Atom requested an update for version ${req.query.version} but the current release channel is ${releaseChannel}`)
res.sendStatus(404)
return
}
}
res.sendFile(path.join(buildPath, fileName))
}
}
function getNupkgFile (is64bit) {
return function (req, res) {
let nupkgFile = req.params.nupkg
if (is64bit) {
const nupkgMatch = nupkgFile.match(/atom-(.+)-(delta|full)\.nupkg/)
if (nupkgMatch) {
nupkgFile = `atom-x64-${nupkgMatch[1]}-${nupkgMatch[2]}.nupkg`
}
}
console.log(`Received request for ${req.params.nupkg}, sending ${nupkgFile}`)
res.sendFile(path.join(buildPath, nupkgFile))
}
}
if (process.platform === 'darwin') {
app.get('/mac/atom-mac.zip', getMacZip)
app.get('/api/updates', getMacUpdates)
} else if (process.platform === 'win32') {
app.get('/api/updates/RELEASES', getReleasesFile('RELEASES'))
app.get('/api/updates/:nupkg', getNupkgFile())
app.get('/api/updates-x64/RELEASES', getReleasesFile('RELEASES-x64'))
app.get('/api/updates-x64/:nupkg', getNupkgFile(true))
} else {
console.log(`The current platform '${process.platform}' doesn't support Squirrel updates, exiting.`.red)
process.exit(1)
}
app.listen(port, () => {
console.log(`Run Atom with ATOM_UPDATE_URL_PREFIX="http://localhost:${port}" set to test updates!\n`.yellow)
})

View File

@ -22,15 +22,16 @@ class AutoUpdateManager extends EventEmitter {
this.config = config
this.state = IdleState
this.iconPath = path.resolve(__dirname, '..', '..', 'resources', 'atom.png')
this.updateUrlPrefix = process.env.ATOM_UPDATE_URL_PREFIX || 'https://atom.io'
}
initialize () {
if (process.platform === 'win32') {
const archSuffix = process.arch === 'ia32' ? '' : `-${process.arch}`
this.feedUrl = `https://atom.io/api/updates${archSuffix}?version=${this.version}`
this.feedUrl = `${this.updateUrlPrefix}/api/updates${archSuffix}?version=${this.version}`
autoUpdater = require('./auto-updater-win32')
} else {
this.feedUrl = `https://atom.io/api/updates?version=${this.version}`;
this.feedUrl = `${this.updateUrlPrefix}/api/updates?version=${this.version}`;
({autoUpdater} = require('electron'))
}