From 250c197f7b7f0a7349c99c5019fe6a643d7140df Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Tue, 7 Feb 2017 17:48:10 +1100 Subject: [PATCH] feat(generic): allow config options to be automagically pulled in from process.env --- README.md | 2 +- src/publishers/s3.js | 12 ++++++------ src/util/forge-config.js | 28 +++++++++++++++++++++++++++- test/fast/forge-config_spec.js | 11 +++++++++++ 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a609f873b0..bb069d004d 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,7 @@ 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
`forge.github_repository.owner` - The owner of the GitHub repository
`forge.github_repository.name` - The name of the GitHub repository
`forge.github_repository.draft` - Create the release as a draft, defaults to `true`
`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
`forge.s3.accessKey` - You access key for your AWS account
`forge.s3.bucket` - The name of the S3 bucket to upload to
`forge.s3.folder` - The folder path to upload to inside your bucket, defaults to your application version
`forge.s3.public` - Whether to make the S3 upload public, defaults to `false` +| Amazon S3 | Uploads your artifacts to the given S3 bucket | `process.env.ELECTRON_FORGE_S3_SECRET_ACCESS_KEY` - Your secret access token for your AWS account
`forge.s3.accessKey` - Your access key for your AWS account
`forge.s3.bucket` - The name of the S3 bucket to upload to
`forge.s3.folder` - The folder path to upload to inside your bucket, defaults to your application version
`forge.s3.public` - Whether to make the S3 upload public, defaults to `false` For example: diff --git a/src/publishers/s3.js b/src/publishers/s3.js index 6aee2fea94..3a061ac774 100644 --- a/src/publishers/s3.js +++ b/src/publishers/s3.js @@ -14,18 +14,18 @@ AWS.util.update(AWS.S3.prototype, { }); 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 + const s3Config = forgeConfig.s3; + s3Config.secretAccessKey = s3Config.secretAccessKey || authToken; + if (!(s3Config.accessKeyId && s3Config.secret && s3Config.bucket)) { + throw 'In order to publish to s3 you must set the "s3.accessKeyId", "process.env.ELECTRON_FORGE_S3_SECRET_ACCESS_KEY" 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, + accessKeyId: s3Config.accessKeyId, + secretAccessKey: s3Config.secretAccessKey, }), }); client.s3.addExpect100Continue = () => {}; diff --git a/src/util/forge-config.js b/src/util/forge-config.js index ee96732f0d..a2e67fc848 100644 --- a/src/util/forge-config.js +++ b/src/util/forge-config.js @@ -3,6 +3,30 @@ import path from 'path'; import _template from 'lodash.template'; import readPackageJSON from './read-package-json'; +const underscoreCase = str => str.replace(/(.)([A-Z][a-z]+)/g, '$1_$2').replace(/([a-z0-9])([A-Z])/g, '$1_$2').toUpperCase(); + +const proxify = (object, envPrefix) => { + const newObject = {}; + + Object.keys(object).forEach((key) => { + if (typeof object[key] === 'object' && !Array.isArray(object[key])) { + newObject[key] = proxify(object[key], `${envPrefix}_${underscoreCase(key)}`); + } else { + newObject[key] = object[key]; + } + }); + + return new Proxy(newObject, { + get(target, name) { + if (target.hasOwnProperty(name)) return target[name]; // eslint-disable-line no-prototype-builtins + if (typeof name === 'string') { + const envValue = process.env[`${envPrefix}_${underscoreCase(name)}`]; + if (envValue) return envValue; + } + }, + }); +}; + export default async (dir) => { const packageJSON = await readPackageJSON(dir); let forgeConfig = packageJSON.config.forge; @@ -24,6 +48,8 @@ export default async (dir) => { electronInstallerDebian: {}, electronInstallerDMG: {}, electronInstallerRedhat: {}, + s3: {}, + github_repository: {}, }, forgeConfig); forgeConfig.make_targets = Object.assign({ win32: ['squirrel'], @@ -54,5 +80,5 @@ export default async (dir) => { template(forgeConfig); - return forgeConfig; + return proxify(forgeConfig, 'ELECTRON_FORGE'); }; diff --git a/test/fast/forge-config_spec.js b/test/fast/forge-config_spec.js index d039d36104..f120b4d0b6 100644 --- a/test/fast/forge-config_spec.js +++ b/test/fast/forge-config_spec.js @@ -21,6 +21,8 @@ const defaults = { linux: ['github'], mas: ['github'], }, + github_repository: {}, + s3: {}, }; describe('forge-config', () => { @@ -46,4 +48,13 @@ describe('forge-config', () => { expect(conf.magicFn).to.be.a('function'); expect(conf.magicFn()).to.be.equal('magic result'); }); + + it('should magically map properties to environment variables', async () => { + const conf = await findConfig(path.resolve(__dirname, '../fixture/dummy_js_conf')); + expect(conf.s3.secretAccessKey).to.equal(undefined); + + process.env.ELECTRON_FORGE_S3_SECRET_ACCESS_KEY = 'SecretyThing'; + expect(conf.s3.secretAccessKey).to.equal('SecretyThing'); + delete process.env.ELECTRON_FORGE_S3_SECRET_ACCESS_KEY; + }); });