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
|
||||
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
|
||||
behavior to electron@github.com.
|
||||
behavior to [electron@github.com](mailto:electron@github.com).
|
||||
|
||||
## Downloads
|
||||
## Installation
|
||||
|
||||
To install prebuilt Electron binaries, use
|
||||
[`npm`](https://docs.npmjs.com/):
|
||||
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
|
||||
# Install as a development dependency
|
||||
npm install electron --save-dev
|
||||
|
||||
# Install the `electron` command globally in your $PATH
|
||||
npm install electron -g
|
||||
npm install electron --save-dev --save-exact
|
||||
```
|
||||
|
||||
See the [releases page](https://github.com/electron/electron/releases) for
|
||||
prebuilt binaries, debug symbols, and more.
|
||||
The `--save-exact` flag is recommended as Electron does not follow semantic
|
||||
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
|
||||
|
||||
- [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
|
||||
|
||||
- [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)
|
||||
- [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
|
||||
|
||||
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",
|
||||
"version": "1.7.5",
|
||||
"repository": "https://github.com/electron/electron",
|
||||
"description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
|
||||
"devDependencies": {
|
||||
"asar": "^0.11.0",
|
||||
"browserify": "^13.1.0",
|
||||
"check-for-leaks": "^1.0.2",
|
||||
"dotenv-safe": "^4.0.4",
|
||||
"electabul": "~0.0.4",
|
||||
"electron-docs-linter": "^2.3.3",
|
||||
"electron-typescript-definitions": "^1.2.7",
|
||||
"github": "^9.2.0",
|
||||
"husky": "^0.14.3",
|
||||
"request": "^2.68.0",
|
||||
"standard": "^8.4.0",
|
||||
"standard-markdown": "^4.0.0"
|
||||
"standard-markdown": "^4.0.0",
|
||||
"temp": "^0.8.3"
|
||||
},
|
||||
"standard": {
|
||||
"ignore": [
|
||||
|
@ -43,11 +48,17 @@
|
|||
"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",
|
||||
"preinstall": "node -e 'process.exit(0)'",
|
||||
"publish-to-npm": "node ./script/publish-to-npm.js",
|
||||
"prepack": "check-for-leaks",
|
||||
"prepush": "check-for-leaks",
|
||||
"release": "./script/upload.py -p",
|
||||
"repl": "python ./script/start.py --interactive",
|
||||
"start": "python ./script/start.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.
|
||||
publish_release(github, release['id'])
|
||||
|
||||
# TODO: run publish-to-npm script here
|
||||
|
||||
# Do not upload other files when passed "-p".
|
||||
return
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue