From 152a9c2eada7b9ad362f19c9444c49aece901fcb Mon Sep 17 00:00:00 2001 From: lutangar Date: Fri, 24 Jan 2020 14:01:48 +0100 Subject: [PATCH] feat(environment) add proding environment (staging on production API) - introduce dedicated staging and production deploy process - create a manifest file per env/platform --- .env.proding | 20 +++++ .env.production | 1 + .env.staging | 1 + bin/web-ext-sign.mjs | 11 ++- manifest/{dev.js => development/chromium.js} | 4 +- .../{firefoxDev.js => development/firefox.js} | 4 +- manifest/getManifest.js | 23 ----- manifest/index.js | 17 ++-- manifest/proding/chromium.js | 22 +++++ manifest/proding/firefox.js | 6 ++ manifest/{ => production}/chromium.js | 8 +- manifest/{ => production}/firefox.js | 2 +- manifest/staging.js | 32 ------- manifest/staging/chromium.js | 22 +++++ manifest/staging/firefox.js | 6 ++ package.json | 12 ++- release.config.js | 83 +++---------------- release.config.production.js | 34 ++++++++ release.config.staging.js | 83 +++++++++++++++++++ webpack/config.plugins.js | 2 +- 20 files changed, 243 insertions(+), 150 deletions(-) create mode 100644 .env.proding rename manifest/{dev.js => development/chromium.js} (85%) rename manifest/{firefoxDev.js => development/firefox.js} (81%) delete mode 100644 manifest/getManifest.js create mode 100644 manifest/proding/chromium.js create mode 100644 manifest/proding/firefox.js rename manifest/{ => production}/chromium.js (73%) rename manifest/{ => production}/firefox.js (70%) delete mode 100644 manifest/staging.js create mode 100644 manifest/staging/chromium.js create mode 100644 manifest/staging/firefox.js create mode 100644 release.config.production.js create mode 100644 release.config.staging.js diff --git a/.env.proding b/.env.proding new file mode 100644 index 000000000..4a52344e1 --- /dev/null +++ b/.env.proding @@ -0,0 +1,20 @@ +BACKEND_ORIGIN=https://notices.bulles.fr/api/v3/ + +# Refresh intervals in minutes +REFRESH_MC_INTERVAL=300 +REFRESH_CONTRIBUTORS_INTERVAL=300 + +UNINSTALL_ORIGIN=https://www.bulles.fr/desinstallation + +# Tracking +TRACKING_URL=https://stats.lmem.net/matomo.php +TRACKING_SITE_ID=5 + +# Email +SEND_CONTRIBUTION_FROM=contribution@bulles.fr +SEND_CONTRIBUTION_TO=contribution@bulles.fr + +#SENTRY_ENABLED=true +CHROME_EXTENSION_ID=mepoelfgpameiagpkgpjphnbgampgffm +FIREFOX_EXTENSION_ID={72aad822-62f5-4663-a8f0-025b2f9a3dd5} +BABEL_ENV=production diff --git a/.env.production b/.env.production index 88db8c20e..ae8b15aea 100644 --- a/.env.production +++ b/.env.production @@ -16,3 +16,4 @@ SEND_CONTRIBUTION_TO=contribution@bulles.fr SENTRY_ENABLED=true CHROME_EXTENSION_ID=fpjlnlnbacohacebkadbbjebbipcknbg +FIREFOX_EXTENSION_ID=@lmem diff --git a/.env.staging b/.env.staging index f360e52f3..5c5198218 100644 --- a/.env.staging +++ b/.env.staging @@ -16,4 +16,5 @@ SEND_CONTRIBUTION_TO=contribution@bulles.fr #SENTRY_ENABLED=true CHROME_EXTENSION_ID=nfabbfkbbbcebdmnocndhdombaffkaog +FIREFOX_EXTENSION_ID={7d0d2553-c311-4acd-a170-f9a4714eb2c0} BABEL_ENV=production diff --git a/bin/web-ext-sign.mjs b/bin/web-ext-sign.mjs index 3daebe86b..b5684a935 100644 --- a/bin/web-ext-sign.mjs +++ b/bin/web-ext-sign.mjs @@ -9,7 +9,12 @@ const { getPackageDir, getPackagePath } = packageNaming; loadEnv({ path: path.resolve() }); -const { FIREFOX_API_KEY, FIREFOX_API_SECRET, NODE_ENV } = process.env; +const { + FIREFOX_API_KEY, + FIREFOX_API_SECRET, + NODE_ENV, + FIREFOX_EXTENSION_ID +} = process.env; const { version } = pjson; const packageDir = path.resolve(getPackageDir('firefox', NODE_ENV)); @@ -28,11 +33,11 @@ signAddon // The explicit extension ID. // WebExtensions do not require an ID. // See the notes below about dealing with IDs. - // id: 'your-addon-id@somewhere', + id: FIREFOX_EXTENSION_ID, // The release channel (listed or unlisted). // Ignored for new add-ons, which are always unlisted. // Default: most recently used channel. - channel: 'unlisted', + channel: NODE_ENV === 'production' ? 'listed' : 'unlisted', // Save downloaded files to this directory. // Default: current working directory. downloadDir: packageDir, diff --git a/manifest/dev.js b/manifest/development/chromium.js similarity index 85% rename from manifest/dev.js rename to manifest/development/chromium.js index f9441aea5..eec655b0d 100644 --- a/manifest/dev.js +++ b/manifest/development/chromium.js @@ -1,9 +1,9 @@ const csp = require('content-security-policy-builder'); -const base = require('./base'); +const base = require('../base'); module.exports = { ...base, - name: 'Bulles - DEV', + name: 'Bulles - development', options_page: 'options.html', content_security_policy: csp({ directives: { diff --git a/manifest/firefoxDev.js b/manifest/development/firefox.js similarity index 81% rename from manifest/firefoxDev.js rename to manifest/development/firefox.js index 05eb0b4a5..e2490b89d 100644 --- a/manifest/firefoxDev.js +++ b/manifest/development/firefox.js @@ -1,9 +1,9 @@ const csp = require('content-security-policy-builder'); -const base = require('./base'); +const base = require('../base'); module.exports = { ...base, - name: 'Bulles - DEV', + name: 'Bulles - development', permissions: ['storage', 'tabs', '*://*/*', ''], content_security_policy: csp({ directives: { diff --git a/manifest/getManifest.js b/manifest/getManifest.js deleted file mode 100644 index c00c402b8..000000000 --- a/manifest/getManifest.js +++ /dev/null @@ -1,23 +0,0 @@ -const manifests = require('../manifest'); - -const getManifestFilename = (env, platform) => { - if (env === 'development') { - if (platform === 'firefox') { - return 'firefoxDev'; - } - return 'dev'; - } else if (env === 'production') { - return platform; - } else if (env === 'staging') { - if (platform === 'firefox') { - return 'firefox'; - } - } - - return env; -}; - -const getManifest = (env, platform) => - JSON.stringify(manifests[getManifestFilename(env, platform)], null, 2); - -module.exports = getManifest; diff --git a/manifest/index.js b/manifest/index.js index 0cceeb490..80276ea4d 100644 --- a/manifest/index.js +++ b/manifest/index.js @@ -1,13 +1,8 @@ -const dev = require('./dev'); -const firefoxDev = require('./firefoxDev'); -const staging = require('./staging'); -const chromium = require('./chromium'); -const firefox = require('./firefox'); +const getManifestFilepath = (env, platform) => `./${env}/${platform}.js`; -module.exports = { - dev, - staging, - chromium, - firefox, - firefoxDev +const getManifest = (env, platform) => { + console.log(getManifestFilepath(env, platform)); + return JSON.stringify(require(getManifestFilepath(env, platform)), null, 2); }; + +module.exports = getManifest; diff --git a/manifest/proding/chromium.js b/manifest/proding/chromium.js new file mode 100644 index 000000000..aaf5f2117 --- /dev/null +++ b/manifest/proding/chromium.js @@ -0,0 +1,22 @@ +const csp = require('content-security-policy-builder'); +const production = require('../production/chromium'); + +module.exports = { + ...production, + name: 'Bulles - proding', + content_security_policy: csp({ + directives: { + 'default-src': ['https://notices.bulles.fr'], + 'connect-src': [ + 'https://notices.bulles.fr', + 'https://sentry.io', + 'https://stats.lmem.net' + ], + 'script-src': ["'self'", "'unsafe-eval'"], + 'object-src': ["'self'"], + 'img-src': ["'self'", 'https://notices.bulles.fr', 'data:'], + 'font-src': ["'self'", 'data:'], + 'style-src': ["'unsafe-inline'"] + } + }) +}; diff --git a/manifest/proding/firefox.js b/manifest/proding/firefox.js new file mode 100644 index 000000000..36aa411a6 --- /dev/null +++ b/manifest/proding/firefox.js @@ -0,0 +1,6 @@ +const production = require('../production/firefox'); + +module.exports = { + ...production, + name: 'Bulles - proding' +}; diff --git a/manifest/chromium.js b/manifest/production/chromium.js similarity index 73% rename from manifest/chromium.js rename to manifest/production/chromium.js index 32fc056b1..0be396d4a 100644 --- a/manifest/chromium.js +++ b/manifest/production/chromium.js @@ -1,5 +1,5 @@ const csp = require('content-security-policy-builder'); -const base = require('./base'); +const base = require('../base'); module.exports = { ...base, @@ -7,7 +7,11 @@ module.exports = { content_security_policy: csp({ directives: { 'default-src': ['https://notices.bulles.fr'], - 'connect-src': ['https://notices.bulles.fr', 'https://sentry.io', 'https://stats.lmem.net'], + 'connect-src': [ + 'https://notices.bulles.fr', + 'https://sentry.io', + 'https://stats.lmem.net' + ], 'script-src': ["'self'"], 'object-src': ["'self'"], 'img-src': ["'self'", 'https://notices.bulles.fr', 'data:'], diff --git a/manifest/firefox.js b/manifest/production/firefox.js similarity index 70% rename from manifest/firefox.js rename to manifest/production/firefox.js index 007cd7137..f5a882a46 100644 --- a/manifest/firefox.js +++ b/manifest/production/firefox.js @@ -1,4 +1,4 @@ -const base = require('./base'); +const base = require('../base'); module.exports = { ...base, diff --git a/manifest/staging.js b/manifest/staging.js deleted file mode 100644 index 13142ad43..000000000 --- a/manifest/staging.js +++ /dev/null @@ -1,32 +0,0 @@ -const csp = require('content-security-policy-builder'); -const base = require('./base'); - -module.exports = { - ...base, - name: 'Bulles - STAGING', - options_page: 'options.html', - content_security_policy: csp({ - directives: { - 'default-src': [ - 'https://staging-notices.bulles.fr', - 'https://notices.bulles.fr' - ], - 'connect-src': [ - 'https://staging-notices.bulles.fr', - 'https://notices.bulles.fr', - 'https://sentry.io', - 'https://stats.lmem.net/matomo.php' - ], - 'script-src': ["'self'", "'unsafe-eval'"], - 'object-src': ["'self'"], - 'img-src': [ - "'self'", - 'https://staging-notices.bulles.fr', - 'https://notices.bulles.fr', - 'data:' - ], - 'font-src': ["'self'", 'data:'], - 'style-src': ["'unsafe-inline'"] - } - }) -}; diff --git a/manifest/staging/chromium.js b/manifest/staging/chromium.js new file mode 100644 index 000000000..b5b732e2c --- /dev/null +++ b/manifest/staging/chromium.js @@ -0,0 +1,22 @@ +const csp = require('content-security-policy-builder'); +const proding = require('../proding/chromium'); + +module.exports = { + ...proding, + name: 'Bulles - staging', + content_security_policy: csp({ + directives: { + 'default-src': ['https://staging-notices.bulles.fr'], + 'connect-src': [ + 'https://staging-notices.bulles.fr', + 'https://sentry.io', + 'https://stats.lmem.net' + ], + 'script-src': ["'self'", "'unsafe-eval'"], + 'object-src': ["'self'"], + 'img-src': ["'self'", 'https://staging-notices.bulles.fr', 'data:'], + 'font-src': ["'self'", 'data:'], + 'style-src': ["'unsafe-inline'"] + } + }) +}; diff --git a/manifest/staging/firefox.js b/manifest/staging/firefox.js new file mode 100644 index 000000000..552d2629c --- /dev/null +++ b/manifest/staging/firefox.js @@ -0,0 +1,6 @@ +const proding = require('../proding/firefox'); + +module.exports = { + ...proding, + name: 'Bulles - staging' +}; diff --git a/package.json b/package.json index 1bb734740..a5df3b140 100644 --- a/package.json +++ b/package.json @@ -9,16 +9,20 @@ "start": "webpack --watch --progress --mode=development", "build:staging": "yarn build:chromium --env.NODE_ENV=staging && yarn build:firefox --env.NODE_ENV=staging", "release:staging": "yarn build:chromium --env.NODE_ENV=staging --env.SENTRY_ENABLED && yarn build:firefox --env.NODE_ENV=staging --env.SENTRY_ENABLED", + "build:proding": "yarn build:chromium --env.NODE_ENV=proding && yarn build:firefox --env.NODE_ENV=proding", + "release:proding": "yarn build:chromium --env.NODE_ENV=proding --env.SENTRY_ENABLED && yarn build:firefox --env.NODE_ENV=proding --env.SENTRY_ENABLED", "build:firefox": "webpack --mode=production --env.PLATFORM=firefox", "sign:firefox": "node --experimental-modules bin/web-ext-sign.mjs", "sign:firefox:staging": "NODE_ENV=staging yarn sign:firefox", + "sign:firefox:proding": "NODE_ENV=proding yarn sign:firefox", "upload:chrome": "node --experimental-modules bin/chrome-webstore-upload", "upload:chrome:staging": "NODE_ENV=staging node --experimental-modules bin/chrome-webstore-upload.mjs", + "upload:chrome:proding": "NODE_ENV=proding node --experimental-modules bin/chrome-webstore-upload.mjs", "build:chromium": "webpack --mode=production --env.PLATFORM=chromium", "build:production": "yarn build:chromium --env.NODE_ENV=production && yarn build:firefox --env.NODE_ENV=production", "release:production": "yarn build:chromium --env.NODE_ENV=production --env.SENTRY_ENABLED && yarn build:firefox --env.NODE_ENV=production --env.SENTRY_ENABLED", - "build": "yarn build:staging && yarn build:production", - "release": "yarn release:staging && yarn release:production", + "build": "yarn build:staging && yarn build:production && yarn build:proding", + "release": "yarn release:staging && yarn release:production && yarn build:proding", "clean": "rm -rf build", "test": "BACKEND_ORIGIN='' mocha -r ts-node/register -r tsconfig-paths/register -r jsdom-global/register 'src/**/*.spec.ts' 'test/app/*.ts' 'test/app/**/*.ts'", "typecheck": "tsc --noEmit", @@ -28,7 +32,9 @@ "verify": "yarn test && yarn typecheck && yarn lint", "analyze": "webpack --mode=production --env.NODE_ENV=production --env.PLATFORM=chromium --env.ANALYZE", "storybook": "start-storybook --ci -p 6007 -c .storybook", - "build-storybook": "build-storybook" + "build-storybook": "build-storybook", + "deploy": "DEPLOY=staging yarn semantic-release --dry-run", + "deploy:production": "DEPLOY=production yarn semantic-release --dry-run" }, "husky": { "hooks": { diff --git a/release.config.js b/release.config.js index 4a0d3e1e7..bedd14bf6 100644 --- a/release.config.js +++ b/release.config.js @@ -1,73 +1,16 @@ -const { getPackagePath } = require('./webpack/packageNaming'); +const { DEPLOY } = process.env; -const release = Object.freeze({ - verifyConditions: [ - '@semantic-release/changelog', - '@semantic-release/git', - '@semantic-release/github', - 'semantic-release-chrome' - ], - analyzeCommits: { - preset: 'angular', - parserOpts: { - noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES', 'MAJOR RELEASE'] - } - }, - prepare: [ - '@semantic-release/changelog', - { - path: '@semantic-release/exec', - cmd: - 'sed -i -r \'s/"version":\\s*"[^"]+"/"version": "${nextRelease.version}"/\' package.json' - }, - { - path: '@semantic-release/git', - assets: ['package.json', 'yarn.lock', 'CHANGELOG.md'], - message: - 'chore: release ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}' - } - ], - publish: [ - { - path: '@semantic-release/exec', - cmd: 'yarn run release' - }, - { - path: '@semantic-release/exec', - cmd: 'yarn run sign:firefox:staging' - }, - { - path: '@semantic-release/exec', - cmd: 'yarn run upload:chrome:staging' - }, - { - path: '@semantic-release/github', - assets: [ - { - path: getPackagePath('*', 'firefox', 'staging'), - label: 'Firefox Package - staging' - }, - { - path: getPackagePath('*', 'firefox', 'production'), - label: 'Firefox Package' - }, - { - path: getPackagePath('*', 'chromium', 'staging'), - label: 'Chromium Package - staging' - }, - { - path: getPackagePath('*', 'chromium', 'production'), - label: 'Chromium Package' - } - ] - } - //FIXME: semantic-release-chrome does not take globs on assets pathnames - //{ - // path: 'semantic-release-chrome', - // asset: 'build/bulles-v*-chromium.zip', - // extensionId: 'fpjlnlnbacohacebkadbbjebbipcknbg', - //}, - ] +const getLogger = require('semantic-release/lib/get-logger'); + +const logger = getLogger({ + cwd: process.cwd(), + env: process.env, + stdout: process.stdout, + stderr: process.stderr }); -module.exports = release; +const configFilePath = `./release.config.${DEPLOY}.js`; + +logger.log(`Loading config file ${configFilePath}`); + +module.exports = require(configFilePath); diff --git a/release.config.production.js b/release.config.production.js new file mode 100644 index 000000000..ce908d5bd --- /dev/null +++ b/release.config.production.js @@ -0,0 +1,34 @@ +const { getPackagePath } = require('./webpack/packageNaming'); + +const release = Object.freeze({ + verifyConditions: ['@semantic-release/github'], + publish: [ + { + path: '@semantic-release/exec', + cmd: 'yarn run release:production"' + }, + { + path: '@semantic-release/exec', + cmd: 'yarn run sign:firefox:production' + }, + { + path: '@semantic-release/exec', + cmd: 'yarn run upload:chrome:production' + }, + { + path: '@semantic-release/github', + assets: [ + { + path: getPackagePath('*', 'firefox', 'production'), + label: 'Firefox Package' + }, + { + path: getPackagePath('*', 'chromium', 'production'), + label: 'Chromium Package' + } + ] + } + ] +}); + +module.exports = release; diff --git a/release.config.staging.js b/release.config.staging.js new file mode 100644 index 000000000..5646e0d52 --- /dev/null +++ b/release.config.staging.js @@ -0,0 +1,83 @@ +const { getPackagePath } = require('./webpack/packageNaming'); + +const release = Object.freeze({ + verifyConditions: [ + '@semantic-release/changelog', + '@semantic-release/git', + '@semantic-release/github', + 'semantic-release-chrome' + ], + analyzeCommits: { + preset: 'angular', + parserOpts: { + noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES', 'MAJOR RELEASE'] + } + }, + prepare: [ + '@semantic-release/changelog', + { + path: '@semantic-release/exec', + cmd: + 'sed -i -r \'s/"version":\\s*"[^"]+"/"version": "${nextRelease.version}"/\' package.json' + }, + { + path: '@semantic-release/git', + assets: ['package.json', 'yarn.lock', 'CHANGELOG.md'], + message: + 'chore: release ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}' + } + ], + publish: [ + // staging + { + path: '@semantic-release/exec', + cmd: 'yarn run release:staging' + }, + { + path: '@semantic-release/exec', + cmd: 'yarn run sign:firefox:staging' + }, + { + path: '@semantic-release/exec', + cmd: 'yarn run upload:chrome:staging' + }, + + // proding + { + path: '@semantic-release/exec', + cmd: 'yarn run release:proding' + }, + { + path: '@semantic-release/exec', + cmd: 'yarn run sign:firefox:proding' + }, + { + path: '@semantic-release/exec', + cmd: 'yarn run upload:chrome:proding' + }, + + { + path: '@semantic-release/github', + assets: [ + { + path: getPackagePath('*', 'firefox', 'staging'), + label: 'Firefox Package - staging' + }, + { + path: getPackagePath('*', 'firefox', 'proding'), + label: 'Firefox Package - proding' + }, + { + path: getPackagePath('*', 'chromium', 'staging'), + label: 'Chromium Package - staging' + }, + { + path: getPackagePath('*', 'chromium', 'proding'), + label: 'Chromium Package - proding' + }, + ] + } + ] +}); + +module.exports = release; diff --git a/webpack/config.plugins.js b/webpack/config.plugins.js index 6f34d05e4..75ccc60a3 100644 --- a/webpack/config.plugins.js +++ b/webpack/config.plugins.js @@ -7,7 +7,7 @@ const ZipPlugin = require('zip-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const SentryWebpackPlugin = require('@sentry/webpack-plugin'); const R = require('ramda'); -const getManifest = require('../manifest/getManifest'); +const getManifest = require('../manifest'); const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin'); const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');