Merge pull request #10172 from electron/publish-prebuilt
publish to npm directly from electron repo
This commit is contained in:
commit
aac9ea1371
9 changed files with 360 additions and 25 deletions
76
README.md
76
README.md
|
@ -15,36 +15,71 @@ editor](https://github.com/atom/atom) and many other [apps](https://electron.ato
|
||||||
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
|
Follow [@ElectronJS](https://twitter.com/electronjs) on Twitter for important
|
||||||
announcements.
|
announcements.
|
||||||
|
|
||||||
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
|
This project adheres to the Contributor Covenant
|
||||||
|
[code of conduct](https://github.com/electron/electron/tree/master/CODE_OF_CONDUCT.md).
|
||||||
By participating, you are expected to uphold this code. Please report unacceptable
|
By participating, you are expected to uphold this code. Please report unacceptable
|
||||||
behavior to electron@github.com.
|
behavior to [electron@github.com](mailto:electron@github.com).
|
||||||
|
|
||||||
## Downloads
|
## Installation
|
||||||
|
|
||||||
To install prebuilt Electron binaries, use
|
To install prebuilt Electron binaries, use [`npm`](https://docs.npmjs.com/).
|
||||||
[`npm`](https://docs.npmjs.com/):
|
The preferred method is to install Electron as a development dependency in your
|
||||||
|
app:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# Install as a development dependency
|
npm install electron --save-dev --save-exact
|
||||||
npm install electron --save-dev
|
|
||||||
|
|
||||||
# Install the `electron` command globally in your $PATH
|
|
||||||
npm install electron -g
|
|
||||||
```
|
```
|
||||||
|
|
||||||
See the [releases page](https://github.com/electron/electron/releases) for
|
The `--save-exact` flag is recommended as Electron does not follow semantic
|
||||||
prebuilt binaries, debug symbols, and more.
|
versioning. For info on how to manage Electron versions in your apps, see
|
||||||
|
[Electron versioning](https://electron.atom.io/docs/tutorial/electron-versioning/).
|
||||||
|
|
||||||
|
For more installation options and troubleshooting tips, see
|
||||||
|
[installation](https://electron.atom.io/docs/tutorial/installation/).
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
Clone and run the
|
||||||
|
[electron/electron-quick-start](https://github.com/electron/electron-quick-start)
|
||||||
|
repository to see a minimal Electron app in action:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/electron/electron-quick-start
|
||||||
|
cd electron-quick-start
|
||||||
|
npm install
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
## Resources for Learning Electron
|
||||||
|
|
||||||
|
- [electron.atom.io/docs](http://electron.atom.io/docs) - all of Electron's documentation
|
||||||
|
- [electron/electron-quick-start](https://github.com/electron/electron-quick-start) - a very basic starter Electron app
|
||||||
|
- [electron.atom.io/community/#boilerplates](http://electron.atom.io/community/#boilerplates) - sample starter apps created by the community
|
||||||
|
- [electron/simple-samples](https://github.com/electron/simple-samples) - small applications with ideas for taking them further
|
||||||
|
- [electron/electron-api-demos](https://github.com/electron/electron-api-demos) - an Electron app that teaches you how to use Electron
|
||||||
|
- [hokein/electron-sample-apps](https://github.com/hokein/electron-sample-apps) - small demo apps for the various Electron APIs
|
||||||
|
|
||||||
|
## Programmatic usage
|
||||||
|
|
||||||
|
Most people use Electron from the command line, but if you require `electron` inside
|
||||||
|
your **Node app** (not your Electron app) it will return the file path to the
|
||||||
|
binary. Use this to spawn Electron from Node scripts:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const electron = require('electron')
|
||||||
|
const proc = require('child_process')
|
||||||
|
|
||||||
|
// will print something similar to /Users/maf/.../Electron
|
||||||
|
console.log(electron)
|
||||||
|
|
||||||
|
// spawn Electron
|
||||||
|
const child = proc.spawn(electron)
|
||||||
|
```
|
||||||
|
|
||||||
### Mirrors
|
### Mirrors
|
||||||
|
|
||||||
- [China](https://npm.taobao.org/mirrors/electron)
|
- [China](https://npm.taobao.org/mirrors/electron)
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
Guides and the API reference are located in the
|
|
||||||
[docs](https://github.com/electron/electron/tree/master/docs) directory. It also
|
|
||||||
contains documents describing how to build and contribute to Electron.
|
|
||||||
|
|
||||||
## Documentation Translations
|
## Documentation Translations
|
||||||
|
|
||||||
- [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR)
|
- [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR)
|
||||||
|
@ -60,11 +95,6 @@ contains documents describing how to build and contribute to Electron.
|
||||||
- [French](https://github.com/electron/electron/tree/master/docs-translations/fr-FR)
|
- [French](https://github.com/electron/electron/tree/master/docs-translations/fr-FR)
|
||||||
- [Indonesian](https://github.com/electron/electron/tree/master/docs-translations/id)
|
- [Indonesian](https://github.com/electron/electron/tree/master/docs-translations/id)
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
Clone and run the [`electron/electron-quick-start`](https://github.com/electron/electron-quick-start)
|
|
||||||
repository to see a minimal Electron app in action.
|
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
You can ask questions and interact with the community in the following
|
You can ask questions and interact with the community in the following
|
||||||
|
|
56
docs/tutorial/installation.md
Normal file
56
docs/tutorial/installation.md
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
> Tips for installing Electron
|
||||||
|
|
||||||
|
To install prebuilt Electron binaries, use [`npm`](https://docs.npmjs.com/).
|
||||||
|
The preferred method is to install Electron as a development dependency in your
|
||||||
|
app:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install electron --save-dev --save-exact
|
||||||
|
```
|
||||||
|
|
||||||
|
The `--save-exact` flag is recommended as Electron does not follow semantic
|
||||||
|
versioning. See the
|
||||||
|
[versioning doc](https://electron.atom.io/docs/tutorial/electron-versioning/)
|
||||||
|
for info on how to manage Electron versions in your apps.
|
||||||
|
|
||||||
|
## Global Installation
|
||||||
|
|
||||||
|
You can also install the `electron` command globally in your `$PATH`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install electron -g
|
||||||
|
```
|
||||||
|
|
||||||
|
## Customization
|
||||||
|
|
||||||
|
If you want to change the architecture that is downloaded (e.g., `ia32` on an
|
||||||
|
`x64` machine), you can use the `--arch` flag with npm install or set the
|
||||||
|
`npm_config_arch` environment variable:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
npm install --arch=ia32 electron
|
||||||
|
```
|
||||||
|
|
||||||
|
## Proxies
|
||||||
|
|
||||||
|
If you need to use an HTTP proxy you can [set these environment variables](https://github.com/request/request/tree/f0c4ec061141051988d1216c24936ad2e7d5c45d#controlling-proxy-behaviour-using-environment-variables).
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
When running `npm install electron`, some users occasionally encounter
|
||||||
|
installation errors.
|
||||||
|
|
||||||
|
In almost all cases, these errors are the result of network problems and not
|
||||||
|
actual issues with the `electron` npm package. Errors like `ELIFECYCLE`,
|
||||||
|
`EAI_AGAIN`, `ECONNRESET`, and `ETIMEDOUT` are all indications of such
|
||||||
|
network problems. The best resolution is to try switching networks, or
|
||||||
|
just wait a bit and try installing again.
|
||||||
|
|
||||||
|
You can also attempt to download Electron directly from
|
||||||
|
[electron/electron/releases](https://github.com/electron/electron/releases)
|
||||||
|
if installing via `npm` is failing.
|
||||||
|
|
||||||
|
If you need to force a re-download of the asset and the SHASUM file set the
|
||||||
|
`force_no_cache` enviroment variable to `true`.
|
10
npm/cli.js
Executable file
10
npm/cli.js
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var electron = require('./')
|
||||||
|
|
||||||
|
var proc = require('child_process')
|
||||||
|
|
||||||
|
var child = proc.spawn(electron, process.argv.slice(2), {stdio: 'inherit'})
|
||||||
|
child.on('close', function (code) {
|
||||||
|
process.exit(code)
|
||||||
|
})
|
10
npm/index.js
Normal file
10
npm/index.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
var fs = require('fs')
|
||||||
|
var path = require('path')
|
||||||
|
|
||||||
|
var pathFile = path.join(__dirname, 'path.txt')
|
||||||
|
|
||||||
|
if (fs.existsSync(pathFile)) {
|
||||||
|
module.exports = path.join(__dirname, fs.readFileSync(pathFile, 'utf-8'))
|
||||||
|
} else {
|
||||||
|
throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again')
|
||||||
|
}
|
65
npm/install.js
Executable file
65
npm/install.js
Executable file
|
@ -0,0 +1,65 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
// maintainer note - x.y.z-ab version in package.json -> x.y.z
|
||||||
|
var version = require('./package').version.replace(/-.*/, '')
|
||||||
|
|
||||||
|
var fs = require('fs')
|
||||||
|
var os = require('os')
|
||||||
|
var path = require('path')
|
||||||
|
var extract = require('extract-zip')
|
||||||
|
var download = require('electron-download')
|
||||||
|
|
||||||
|
var installedVersion = null
|
||||||
|
try {
|
||||||
|
installedVersion = fs.readFileSync(path.join(__dirname, 'dist', 'version'), 'utf-8').replace(/^v/, '')
|
||||||
|
} catch (ignored) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
var platformPath = getPlatformPath()
|
||||||
|
|
||||||
|
if (installedVersion === version && fs.existsSync(path.join(__dirname, platformPath))) {
|
||||||
|
process.exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// downloads if not cached
|
||||||
|
download({
|
||||||
|
cache: process.env.electron_config_cache,
|
||||||
|
version: version,
|
||||||
|
platform: process.env.npm_config_platform,
|
||||||
|
arch: process.env.npm_config_arch,
|
||||||
|
strictSSL: process.env.npm_config_strict_ssl === 'true',
|
||||||
|
force: process.env.force_no_cache === 'true',
|
||||||
|
quiet: ['info', 'verbose', 'silly', 'http'].indexOf(process.env.npm_config_loglevel) === -1
|
||||||
|
}, extractFile)
|
||||||
|
|
||||||
|
// unzips and makes path.txt point at the correct executable
|
||||||
|
function extractFile (err, zipPath) {
|
||||||
|
if (err) return onerror(err)
|
||||||
|
extract(zipPath, {dir: path.join(__dirname, 'dist')}, function (err) {
|
||||||
|
if (err) return onerror(err)
|
||||||
|
fs.writeFile(path.join(__dirname, 'path.txt'), platformPath, function (err) {
|
||||||
|
if (err) return onerror(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function onerror (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPlatformPath () {
|
||||||
|
var platform = process.env.npm_config_platform || os.platform()
|
||||||
|
|
||||||
|
switch (platform) {
|
||||||
|
case 'darwin':
|
||||||
|
return 'dist/Electron.app/Contents/MacOS/Electron'
|
||||||
|
case 'freebsd':
|
||||||
|
case 'linux':
|
||||||
|
return 'dist/electron'
|
||||||
|
case 'win32':
|
||||||
|
return 'dist/electron.exe'
|
||||||
|
default:
|
||||||
|
throw new Error('Electron builds are not available on platform: ' + platform)
|
||||||
|
}
|
||||||
|
}
|
26
npm/package.json
Normal file
26
npm/package.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"cache-clean": "rm -rf ~/.electron && rm -rf dist",
|
||||||
|
"postinstall": "node install.js",
|
||||||
|
"pretest": "npm run cache-clean",
|
||||||
|
"test": "standard"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"electron": "cli.js"
|
||||||
|
},
|
||||||
|
"main": "index.js",
|
||||||
|
"types": "electron.d.ts",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "^7.0.18",
|
||||||
|
"electron-download": "^3.0.1",
|
||||||
|
"extract-zip": "^1.0.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"home-path": "^0.1.1",
|
||||||
|
"path-exists": "^2.0.0",
|
||||||
|
"standard": "^5.4.1"
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"test": "test"
|
||||||
|
}
|
||||||
|
}
|
15
package.json
15
package.json
|
@ -1,17 +1,22 @@
|
||||||
{
|
{
|
||||||
"name": "electron",
|
"name": "electron",
|
||||||
"version": "1.7.5",
|
"version": "1.7.5",
|
||||||
|
"repository": "https://github.com/electron/electron",
|
||||||
|
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"asar": "^0.11.0",
|
"asar": "^0.11.0",
|
||||||
"browserify": "^13.1.0",
|
"browserify": "^13.1.0",
|
||||||
"check-for-leaks": "^1.0.2",
|
"check-for-leaks": "^1.0.2",
|
||||||
|
"dotenv-safe": "^4.0.4",
|
||||||
"electabul": "~0.0.4",
|
"electabul": "~0.0.4",
|
||||||
"electron-docs-linter": "^2.3.3",
|
"electron-docs-linter": "^2.3.3",
|
||||||
"electron-typescript-definitions": "^1.2.7",
|
"electron-typescript-definitions": "^1.2.7",
|
||||||
|
"github": "^9.2.0",
|
||||||
"husky": "^0.14.3",
|
"husky": "^0.14.3",
|
||||||
"request": "^2.68.0",
|
"request": "^2.68.0",
|
||||||
"standard": "^8.4.0",
|
"standard": "^8.4.0",
|
||||||
"standard-markdown": "^4.0.0"
|
"standard-markdown": "^4.0.0",
|
||||||
|
"temp": "^0.8.3"
|
||||||
},
|
},
|
||||||
"standard": {
|
"standard": {
|
||||||
"ignore": [
|
"ignore": [
|
||||||
|
@ -43,11 +48,17 @@
|
||||||
"create-api-json": "electron-docs-linter docs --outfile=out/electron-api.json --version=$npm_package_version",
|
"create-api-json": "electron-docs-linter docs --outfile=out/electron-api.json --version=$npm_package_version",
|
||||||
"create-typescript-definitions": "npm run create-api-json && electron-typescript-definitions --in=out/electron-api.json --out=out/electron.d.ts",
|
"create-typescript-definitions": "npm run create-api-json && electron-typescript-definitions --in=out/electron-api.json --out=out/electron.d.ts",
|
||||||
"preinstall": "node -e 'process.exit(0)'",
|
"preinstall": "node -e 'process.exit(0)'",
|
||||||
|
"publish-to-npm": "node ./script/publish-to-npm.js",
|
||||||
"prepack": "check-for-leaks",
|
"prepack": "check-for-leaks",
|
||||||
"prepush": "check-for-leaks",
|
"prepush": "check-for-leaks",
|
||||||
"release": "./script/upload.py -p",
|
"release": "./script/upload.py -p",
|
||||||
"repl": "python ./script/start.py --interactive",
|
"repl": "python ./script/start.py --interactive",
|
||||||
"start": "python ./script/start.py",
|
"start": "python ./script/start.py",
|
||||||
"test": "python ./script/test.py"
|
"test": "python ./script/test.py"
|
||||||
}
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"author": "Electron Community",
|
||||||
|
"keywords": [
|
||||||
|
"electron"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
125
script/publish-to-npm.js
Normal file
125
script/publish-to-npm.js
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
const temp = require('temp')
|
||||||
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
const childProcess = require('child_process')
|
||||||
|
const GitHubApi = require('github')
|
||||||
|
const request = require('request')
|
||||||
|
const assert = require('assert')
|
||||||
|
const rootPackageJson = require('../package.json')
|
||||||
|
|
||||||
|
const github = new GitHubApi({
|
||||||
|
// debug: true,
|
||||||
|
headers: { 'User-Agent': 'electron-npm-publisher' },
|
||||||
|
followRedirects: false
|
||||||
|
})
|
||||||
|
|
||||||
|
let tempDir
|
||||||
|
temp.track() // track and cleanup files at exit
|
||||||
|
|
||||||
|
const files = [
|
||||||
|
'cli.js',
|
||||||
|
'index.js',
|
||||||
|
'install.js',
|
||||||
|
'package.json',
|
||||||
|
'README.md'
|
||||||
|
]
|
||||||
|
|
||||||
|
const jsonFields = [
|
||||||
|
'name',
|
||||||
|
'version',
|
||||||
|
'repository',
|
||||||
|
'description',
|
||||||
|
'license',
|
||||||
|
'author',
|
||||||
|
'keywords'
|
||||||
|
]
|
||||||
|
|
||||||
|
let npmTag = ''
|
||||||
|
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
temp.mkdir('electron-npm', (err, dirPath) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err)
|
||||||
|
} else {
|
||||||
|
resolve(dirPath)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then((dirPath) => {
|
||||||
|
tempDir = dirPath
|
||||||
|
// copy files from `/npm` to temp directory
|
||||||
|
files.forEach((name) => {
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(tempDir, name),
|
||||||
|
fs.readFileSync(path.join(__dirname, '..', name === 'README.md' ? '' : 'npm', name))
|
||||||
|
)
|
||||||
|
})
|
||||||
|
// copy from root package.json to temp/package.json
|
||||||
|
const packageJson = require(path.join(tempDir, 'package.json'))
|
||||||
|
jsonFields.forEach((fieldName) => {
|
||||||
|
packageJson[fieldName] = rootPackageJson[fieldName]
|
||||||
|
})
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(tempDir, 'package.json'),
|
||||||
|
JSON.stringify(packageJson, null, 2)
|
||||||
|
)
|
||||||
|
|
||||||
|
return github.repos.getReleases({
|
||||||
|
owner: 'electron',
|
||||||
|
repo: 'electron'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then((releases) => {
|
||||||
|
// download electron.d.ts from release
|
||||||
|
const release = releases.data.find(
|
||||||
|
(release) => release.tag_name === `v${rootPackageJson.version}`
|
||||||
|
)
|
||||||
|
if (!release) {
|
||||||
|
throw new Error(`cannot find release with tag v${rootPackageJson.version}`)
|
||||||
|
}
|
||||||
|
return release
|
||||||
|
})
|
||||||
|
.then((release) => {
|
||||||
|
const tsdAsset = release.assets.find((asset) => asset.name === 'electron.d.ts')
|
||||||
|
if (!tsdAsset) {
|
||||||
|
throw new Error(`cannot find electron.d.ts from v${rootPackageJson.version} release assets`)
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
request.get({
|
||||||
|
url: tsdAsset.url,
|
||||||
|
headers: {
|
||||||
|
'accept': 'application/octet-stream',
|
||||||
|
'user-agent': 'electron-npm-publisher'
|
||||||
|
}
|
||||||
|
}, (err, response, body) => {
|
||||||
|
if (err || response.statusCode !== 200) {
|
||||||
|
reject(err || new Error('Cannot download electron.d.ts'))
|
||||||
|
} else {
|
||||||
|
fs.writeFileSync(path.join(tempDir, 'electron.d.ts'), body)
|
||||||
|
resolve(release)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then((release) => {
|
||||||
|
npmTag = release.prerelease ? 'beta' : 'latest'
|
||||||
|
})
|
||||||
|
.then(() => childProcess.execSync('npm pack', { cwd: tempDir }))
|
||||||
|
.then(() => {
|
||||||
|
// test that the package can install electron prebuilt from github release
|
||||||
|
const tarballPath = path.join(tempDir, `${rootPackageJson.name}-${rootPackageJson.version}.tgz`)
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
childProcess.execSync(`npm install ${tarballPath} --force --silent`, {
|
||||||
|
env: Object.assign({}, process.env, { electron_config_cache: tempDir }),
|
||||||
|
cwd: tempDir
|
||||||
|
})
|
||||||
|
const checkVersion = childProcess.execSync(`${path.join(tempDir, 'node_modules', '.bin', 'electron')} -v`)
|
||||||
|
assert.strictEqual(checkVersion.toString().trim(), `v${rootPackageJson.version}`)
|
||||||
|
resolve(tarballPath)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then((tarballPath) => childProcess.execSync(`npm publish ${tarballPath} --tag ${npmTag}`))
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(`Error: ${err}`)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
|
@ -72,6 +72,8 @@ def main():
|
||||||
# Press the publish button.
|
# Press the publish button.
|
||||||
publish_release(github, release['id'])
|
publish_release(github, release['id'])
|
||||||
|
|
||||||
|
# TODO: run publish-to-npm script here
|
||||||
|
|
||||||
# Do not upload other files when passed "-p".
|
# Do not upload other files when passed "-p".
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue