Skip to content
Permalink
Browse files

feat(publisher): add S3 publish target

ISSUES CLOSED: #116
  • Loading branch information
MarshallOfSound authored and malept committed Feb 6, 2017
1 parent bbc9c04 commit fa31902a6e94b6affd0ffa54fc534756633ca726
Showing with 82 additions and 1 deletion.
  1. +11 −0 README.md
  2. +2 −0 package.json
  3. +1 −1 src/electron-forge-publish.js
  4. +68 −0 src/publishers/s3.js
@@ -177,17 +177,28 @@ the JS file method mentioned above then you can use functions normally.
| Target Name | Description | Required Config |
|-------------|-------------|-----------------|
| github | Makes a new release for the current version (if required) and uploads the make artifacts as release assets | `process.env.GITHUB_TOKEN` - A personal access token with access to your releases <br />`forge.github_repository.owner` - The owner of the GitHub repository<br />`forge.github_repository.name` - The name of the GitHub repository <br />`forge.github_repository.draft` - Create the release as a draft, defaults to `true` <br />`forge.github_repository.prerelease` - Identify the release as a prerelease, defaults to `false` |
| Amazon S3 | Uploads your artifacts to the given S3 bucket | `process.env.S3_SECRET` - Your secret access token for your AWS account<br />`forge.s3.accessKey` - You access key for your AWS account<br />`forge.s3.bucket` - The name of the S3 bucket to upload to<br />`forge.s3.folder` - The folder path to upload to inside your bucket, defaults to your application version<br />`forge.s3.public` - Whether to make the S3 upload public, defaults to `false`

For example:

```javascript
// github
{
// Assume the GitHub repository is at https://github.com/username/repo
"github_repository": {
"owner": "username",
"name": "repo"
}
}
// s3
{
"s3": {
"accessKey": "<AWS_ACCESS_KEY>",
"bucket": "my_bucket_name",
"public": true
}
}
```

## Custom `make` and `publish` targets
@@ -95,6 +95,7 @@
"cache": true
},
"dependencies": {
"aws-sdk": "^2.9.0",
"babel-register": "^6.16.3",
"bluebird": "^3.4.6",
"colors": "^1.1.2",
@@ -123,6 +124,7 @@
"ora": "^1.1.0",
"pify": "^2.3.0",
"resolve-package": "^1.0.1",
"s3": "^4.4.0",
"semver": "^5.3.0",
"spawn-rx": "^2.0.7",
"sudo-prompt": "^6.2.1",
@@ -13,7 +13,7 @@ import { getMakeOptions } from './electron-forge-make';
.arguments('[cwd]')
.option('--auth-token', 'Authorization token for your publisher target (if required)')
.option('--tag', 'The tag to publish to on GitHub')
.option('--target', 'The deployment target, defaults to "github"')
.option('--target [target]', 'The deployment target, defaults to "github"')
.allowUnknownOption(true)
.action((cwd) => {
if (!cwd) return;
@@ -0,0 +1,68 @@
import AWS from 'aws-sdk';
import debug from 'debug';
import path from 'path';
import s3 from 's3';

import asyncOra from '../util/ora-handler';

const d = debug('electron-forge:publish:s3');

AWS.util.update(AWS.S3.prototype, {
addExpect100Continue: function addExpect100Continue() {
// Hack around large upload issue: https://github.com/andrewrk/node-s3-client/issues/74
},
});

export default async (artifacts, packageJSON, forgeConfig, authToken, tag) => {
const s3Config = forgeConfig.s3 || {};
s3Config.secret = authToken || process.env.S3_SECRET;
if (!(s3Config.accessKey && s3Config.secret && s3Config.bucket)) {
throw 'In order to publish to s3 you must set the "s3.accessKey", "process.env.S3_SECRET" and "s3.bucket" properties in your forge config. See the docs for more info'; // eslint-disable-line
}

d('creating s3 client with options:', s3Config);

const client = s3.createClient({
s3Client: new AWS.S3({
accessKeyId: s3Config.accessKey,
secretAccessKey: s3Config.secret,
}),
});
client.s3.addExpect100Continue = () => {};

const folder = s3Config.folder || tag || packageJSON.version;

let uploaded = 0;
await asyncOra(`Uploading Artifacts ${uploaded}/${artifacts.length}`, async (uploadSpinner) => {
const updateSpinner = () => {
uploadSpinner.text = `Uploading Artifacts ${uploaded}/${artifacts.length}`; // eslint-disable-line
};

await Promise.all(artifacts.map(artifactPath =>
new Promise(async (resolve, reject) => {
const done = (err) => {
if (err) return reject(err);
uploaded += 1;
updateSpinner();
resolve();
};

const uploader = client.uploadFile({
localFile: artifactPath,
s3Params: {
Bucket: s3Config.bucket,
Key: `${folder}/${path.basename(artifactPath)}`,
ACL: s3Config.public ? 'public-read' : 'private',
},
});
d('uploading:', artifactPath);

uploader.on('error', err => done(err));
uploader.on('progress', () => {
d(`Upload Progress (${path.basename(artifactPath)}) ${Math.round((uploader.progressAmount / uploader.progressTotal) * 100)}%`);
});
uploader.on('end', () => done());
})
));
});
};

0 comments on commit fa31902

Please sign in to comment.
You can’t perform that action at this time.