From 0f706de124ef4de1333135915b2934338d355756 Mon Sep 17 00:00:00 2001 From: Jack Works Date: Tue, 24 Sep 2019 13:24:15 +0800 Subject: [PATCH] feat(ci): add real cond compilation --- .circleci/config.yml | 36 +------------ README.md | 15 ++++-- config-overrides/index.js | 13 +++-- config-overrides/manifest.overrides.js | 10 +--- package.json | 5 +- scripts/ci-build.js | 74 ++++++++++++++++++++++++++ scripts/spawn.js | 24 ++++++--- tsconfig_cjs.json | 3 +- 8 files changed, 118 insertions(+), 62 deletions(-) create mode 100644 scripts/ci-build.js diff --git a/.circleci/config.yml b/.circleci/config.yml index 809245b7b9a..0542dd4443d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,41 +17,7 @@ jobs: - v1-maskbook- - run: name: Build Maskbook - command: | - yarn install --link-duplicates --frozen-lockfile - yarn lint:report - yarn build - sudo apt-get install zip - # Build base version - cd build - zip -r ../Maskbook.zip ./* - cp manifest.json manifest.base.json - cd .. - # Build WKWebview version - node ./scripts/modify-manifest.js WKWebview - cd build - zip -r ../Maskbook.WKWebview.zip ./* - cd .. - # Build chromium version - node ./scripts/modify-manifest.js chromium - cd build - zip -r ../Maskbook.chromium.zip ./* - cd .. - # Build firefoxDesktop version - node ./scripts/modify-manifest.js firefoxDesktop - cd build - zip -r ../Maskbook.firefoxDesktop.zip ./* - cd .. - # Build firefoxGeckoview version - node ./scripts/modify-manifest.js firefoxGeckoview - cd build - zip -r ../Maskbook.firefoxGeckoview.zip ./* - cd .. - # Build firefoxAndroid version - node ./scripts/modify-manifest.js firefoxAndroid - cd build - zip -r ../Maskbook.firefoxAndroid.zip ./* - cd .. + command: node ./scripts/ci-build.js - save_cache: paths: - node_modules diff --git a/README.md b/README.md index 6df11aac5d2..ca25750f6c9 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ Encrypt your posts & chats on You-Know-Where. Allow only your friends to decrypt For general introductions, see https://Maskbook.com/ -* [Maskbook on Chrome Web Store][crext] -* [Maskbook on Firefox Addon Store][fxaddon] (Works on Android too!) +- [Maskbook on Chrome Web Store][crext] +- [Maskbook on Firefox Addon Store][fxaddon] (Works on Android too!) - [crext]: https://chrome.google.com/webstore/detail/maskbook/jkoeaghipilijlahjplgbfiocjhldnap/ - [fxaddon]: https://addons.mozilla.org/en-US/firefox/addon/maskbook/ + [crext]: https://chrome.google.com/webstore/detail/maskbook/jkoeaghipilijlahjplgbfiocjhldnap/ + [fxaddon]: https://addons.mozilla.org/en-US/firefox/addon/maskbook/ ## Documentation for developers @@ -32,6 +32,13 @@ For general introductions, see https://Maskbook.com/ - `yarn storybook` to start StoryBook. Used for UI only developing. - `yarn build` build a production version. Output files in `./build/` +#### Conditional compilation + +- If branch name contains `full`, CI will build for all targets +- If branch name contains `ios`, CI will build for target `iOS` +- If branch name contains `android` or `gecko`, CI will build for target `firefox` `gecko` +- For any other branches, CI will build for target `base` `chromium` `firefox` + #### Non-famous libraries we are using - `@holoflows/kit` - A toolkit for extension developing diff --git a/config-overrides/index.js b/config-overrides/index.js index 64d5c533564..c15f4c9548d 100644 --- a/config-overrides/index.js +++ b/config-overrides/index.js @@ -157,8 +157,8 @@ function override(config, env) { const manifest = require('../src/manifest.json') const modifiers = require('./manifest.overrides') if (target.Chromium) modifiers.chromium(manifest) - if (target.FirefoxDesktop) modifiers.firefoxDesktop(manifest) - if (target.FirefoxForAndroid) modifiers.firefoxAndroid(manifest) + if (target.FirefoxDesktop) modifiers.firefoxDesktopAndAndroid(manifest) + if (target.FirefoxForAndroid) modifiers.firefoxDesktopAndAndroid(manifest) if (target.StandaloneGeckoView) modifiers.firefoxGeckoview(manifest) if (target.WKWebview) modifiers.WKWebview(manifest) @@ -196,9 +196,12 @@ function override(config, env) { config.plugins.push(new SSRPlugin('index.html', src('./src/index.tsx'))) polyfills.map(x => void fs.copyFileSync(x, path.join(publicPolyfill, path.basename(x)))) } - - const tsCheckerPlugin = config.plugins.filter(x => x.constructor.name === 'ForkTsCheckerWebpackPlugin')[0] - tsCheckerPlugin.compilerOptions.isolatedModules = false + if (env === 'development') { + const tsCheckerPlugin = config.plugins.filter(x => x.constructor.name === 'ForkTsCheckerWebpackPlugin')[0] + tsCheckerPlugin.compilerOptions.isolatedModules = false + } else { + config.plugins = config.plugins.filter(x => x.constructor.name !== 'ForkTsCheckerWebpackPlugin') + } // Let webpack build to es2017 instead of es5 config.module.rules = [ diff --git a/config-overrides/manifest.overrides.js b/config-overrides/manifest.overrides.js index cd75537df3e..2e0b919154e 100644 --- a/config-overrides/manifest.overrides.js +++ b/config-overrides/manifest.overrides.js @@ -8,12 +8,6 @@ function firefox(manifest) { // TODO: Switch to browser.userScripts (Firefox only) API can resolve the problem. manifest.permissions.push('tabs') } -/** - * @param {typeof base} manifest - */ -function firefoxAndroid(manifest) { - firefox(manifest) -} /** * @param {typeof base} manifest */ @@ -24,7 +18,7 @@ function firefoxGeckoview(manifest) { /** * @param {typeof base} manifest */ -function firefoxDesktop(manifest) { +function firefoxDesktopAndAndroid(manifest) { firefox(manifest) } /** @@ -35,4 +29,4 @@ function chromium(manifest) {} * @param {typeof base} manifest */ function WKWebview(manifest) {} -module.exports = { firefox, firefoxAndroid, firefoxDesktop, firefoxGeckoview, chromium, WKWebview } +module.exports = { firefox, firefoxDesktopAndAndroid, firefoxGeckoview, chromium, WKWebview } diff --git a/package.json b/package.json index 2f8942f7400..d4d9fb68c24 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "start:android": "react-app-rewired start --firefox-android", "start:chromium": "react-app-rewired start --chromium", "start:gecko": "react-app-rewired start --firefox-gecko", - "start:wkwebview": "react-app-rewired start --wk-webview", + "start:ios": "react-app-rewired start --wk-webview", "prepare:firefox": "firefox -CreateProfile ./.firefox", @@ -21,9 +21,8 @@ "build:debugging": "node --inspect-brk node_modules/react-app-rewired/scripts/build.js", "build:gecko": "react-app-rewired build --firefox-gecko", "build:firefox": "react-app-rewired build --firefox", - "build:android": "react-app-rewired build --firefox-android", "build:chromium": "react-app-rewired build --chromium", - "build:wkwebview": "react-app-rewired start --wk-webview", + "build:ios": "react-app-rewired start --wk-webview", "test": "react-app-rewired test", diff --git a/scripts/ci-build.js b/scripts/ci-build.js new file mode 100644 index 00000000000..2bc07b94e90 --- /dev/null +++ b/scripts/ci-build.js @@ -0,0 +1,74 @@ +const { spawn } = require('./spawn') +const path = require('path') + +const base = path.join(__dirname, '../') +process.chdir(base) +async function main() { + const prepareCommands = getCommands(` + yarn install --link-duplicates --frozen-lockfile + yarn lint:report${ + /** + * Let's do a quick TypeScript check. + */ '' + } + yarn tsc -p tsconfig_cjs.json + sudo apt-get install zip + `) + for (const [commands, ...args] of prepareCommands) { + await spawn(commands, args) + } + const currentBranch = (await getCurrentGITBranchName()).toLowerCase() + for (const [first, ...args] of getCommands(buildTypes(currentBranch))) { + await spawn(first, args) + } +} +main().catch(e => { + console.error(e) + process.exit(1) +}) + +/** + * @param {string} branchName + */ +function buildTypes(branchName) { + if (branchName.match(/full/)) return getBuildCommand(['base', 'chromium', 'firefox', 'gecko', 'iOS']) + if (branchName.match(/ios/)) return getBuildCommand(['iOS']) + if (branchName.match(/android|gecko/)) return getBuildCommand(['firefox', 'gecko']) + return getBuildCommand(['base', 'chromium', 'firefox']) +} + +/** + * @param {('base' | 'iOS' | 'chromium' | 'firefox' | 'gecko')[]} platforms + */ +function getBuildCommand(platforms) { + return platforms + .map(x => x.toLowerCase()) + .map(generateCommand) + .join('\n') + function generateCommand(type) { + return ` + yarn build:${type} + cd build + zip -r ../Maskbook.${type}.zip ./* + cd .. + rm -rf build + ` + } +} + +async function getCurrentGITBranchName() { + const [git, ...args] = getCommands(`git rev-parse --abbrev-ref HEAD`)[0] + const branch = await spawn(git, args, { stdio: 'pipe' }) + return branch.split('\n')[0] +} + +/** + * @param {string} string + */ +function getCommands(string) { + return string + .split('\n') + .filter(x => x) + .map(x => x.split(' ').filter(x => x)) + .filter(x => x.length) +} diff --git a/scripts/spawn.js b/scripts/spawn.js index 411ebd63526..21b70233c37 100644 --- a/scripts/spawn.js +++ b/scripts/spawn.js @@ -3,18 +3,30 @@ const { spawn } = require('child_process') process.on('unhandledRejection', e => { process.exit(1) }) - -function spawnAsync(command, args, options) { +/** + * + * @param {string} command Command + * @param {string[]} args Arguments + * @param {import('child_process').SpawnOptionsWithoutStdio} options Options + */ +function spawnAsync(command, args, options = {}) { const child = spawn(command, args, { stdio: 'inherit', shell: true, ...options }) + let stdout = '' + if (child.stdout) { + child.stdout.addListener('data', data => (stdout += data.toString())) + } return new Promise(function(resolve, reject) { - const error = code => { - return reject(new Error('Child exited with code: ' + code)) - } child.addListener('error', e => { child.kill() reject(e) }) - child.addListener('exit', code => (code === 0 ? resolve : error)(code)) + child.addListener('exit', code => { + if (code === 0) return resolve(stdout) + const error = new Error('Child exited with code: ' + code) + // @ts-ignore + error.stdout = stdout + reject(error) + }) }) } diff --git a/tsconfig_cjs.json b/tsconfig_cjs.json index 1161604445b..aa88715e956 100644 --- a/tsconfig_cjs.json +++ b/tsconfig_cjs.json @@ -2,6 +2,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "module": "commonjs", - "jsx": "react" + "jsx": "react", + "isolatedModules": false } }