Skip to content

Commit

Permalink
Merge pull request #604 from cosmos/NodeGuy/#304
Browse files Browse the repository at this point in the history
Allow bundling of network in production build. #304
  • Loading branch information
NodeGuy authored Apr 16, 2018
2 parents 4543058 + 608768c commit e4622f1
Show file tree
Hide file tree
Showing 21 changed files with 154 additions and 233 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,12 @@ A list of all environment variables and their purpose:
| NODE_ENV | 'production', 'development' | | |
| LOGGING | 'true', 'false' | 'true' | Disable logging |
| COSMOS_NETWORK | {path to network configuration folder} | '../networks/gaia-1' | Network to connect to |
| COSMOS_HOME | {path to config persistence folder} | '$HOME/voyager[-dev]' | |
| COSMOS_HOME | {path to config persistence folder} | '$HOME/.cosmos-voyager[-dev]' | |
| COSMOS_NODE | {ip of a certain node} | | Node to connect to |
| COSMOS_DEVTOOLS | 'true', 'false' | 'false' | Open the debug panel in the electron view |
| COSMOS_E2E_KEEP_OPEN | 'true', 'false' | 'false' | Keep the Window open in local E2E test to see the state in which the application broke. |
| ELECTRON_ENABLE_LOGGING | 'true', 'false' | 'false' | Redirect the browser view console output to the console |
| PREVIEW | 'true', 'false' | 'true' if NODE_ENV 'development' | Show/Hide features that are in development |
| COSMOS_E2E_KEEP_OPEN | 'true', 'false' | 'false' | Keep the Window open in local E2E test to see the state in which the application broke. |

### FAQ

Expand Down
15 changes: 15 additions & 0 deletions app/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Name of electron app
# Will be used in production builds
name = "Cosmos Voyager"

# webpack-dev-server port
wds_port = 9080
lcd_port = 9070
lcd_port_prod = 9071
relay_port = 9060
relay_port_prod = 9061

default_network = "gaia-2"
google_analytics_uid = "UA-51029217-3"
sentry_dsn = "https://4dee9f70a7d94cc0959a265c45902d84:[email protected]/288169"
sentry_dsn_public = "https://[email protected]/288169"
11 changes: 11 additions & 0 deletions app/src/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use strict"

const fs = require(`fs`)
const path = require(`path`)
const toml = require(`toml`)

module.exports = toml.parse(
fs.readFileSync(path.join(__dirname, `../config.toml`), {
encoding: `utf8`
})
)
4 changes: 3 additions & 1 deletion app/src/main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ let Raven = require("raven")

let pkg = require("../../../package.json")
let addMenu = require("./menu.js")
let config = require("../../../config.js")
let config = require("../config.js")
global.config = config // to make the config accessable from renderer

let shuttingDown = false
let mainWindow
Expand All @@ -24,6 +25,7 @@ let seeds = null
let booted = false

const root = require("../root.js")
global.root = root // to make the root accessable from renderer
const networkPath = require("../network.js").path

const lcdHome = join(root, "lcd")
Expand Down
2 changes: 1 addition & 1 deletion app/src/network.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
let { join } = require("path")
let { readFileSync } = require("fs")
let config = require("../../config.js")
let config = require("./config.js")

// this network gets used if none is specified via the
// COSMOS_NETWORK env var
Expand Down
4 changes: 2 additions & 2 deletions app/src/renderer/vuex/modules/user.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import enableGoogleAnalytics from "../../google-analytics.js"
import Raven from "raven-js"
const { ipcRenderer } = require("electron")
const config = require("../../../../../config")
const { ipcRenderer, remote } = require("electron")
const config = remote.getGlobal("config")

export default ({ commit, node }) => {
const ERROR_COLLECTION_KEY = "voyager_error_collection"
Expand Down
3 changes: 2 additions & 1 deletion app/src/renderer/vuex/modules/wallet.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
let fs = require("fs-extra")
let { join } = require("path")
let root = require("../../../root.js")
const { remote } = require("electron")
const root = remote.getGlobal("root")

export default ({ commit, node }) => {
let state = {
Expand Down
44 changes: 0 additions & 44 deletions config.js

This file was deleted.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -173,15 +173,15 @@
"/build/",
"/dist/",
"/test/",
"/config.js"
"/app/src/config.js"
],
"testURL": "http://localhost",
"setupFiles": [
"./test/unit/helpers/fixed_time.js",
"./test/unit/helpers/setup.js",
"./test/unit/helpers/console_error_throw.js",
"./test/unit/helpers/genesis_mock.js",
"./test/unit/helpers/ipc_mock.js",
"./test/unit/helpers/electron_mock.js",
"jest-localstorage-mock"
]
},
Expand Down
58 changes: 42 additions & 16 deletions tasks/build/index.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,62 @@
"use strict"

const { cli } = require(`@nodeguy/cli`)
const options = require(`./options.json`)
const fp = require(`lodash/fp`)
const optionsSpecification = require(`./optionsSpecification.json`)
const path = require(`path`)
const shell = require(`shelljs`)
const untildify = require(`untildify`)

cli(options, async ({ commit, gaia, platform, "skip-pack": skipPack }) => {
shell.exec(`docker build --tag cosmos/voyager-builder .`, {
// Show the exec commands for easier debugging if something goes wrong.
const exec = (command, ...args) => {
console.log(command)
return shell.exec(command, ...args)
}

cli(optionsSpecification, options => {
const { commit, gaia, network } = options

exec(`docker build --tag cosmos/voyager-builder .`, {
cwd: __dirname
})

const builds = path.resolve(__dirname, "../../builds")
shell.mkdir(`-p`, builds)
// Expand '~' if preset and resolve to absolute pathnames for Docker.
const resolved = fp.mapValues(fp.pipe(untildify, path.resolve), {
gaia,
git: path.join(__dirname, "../../.git"),
network,
builds: path.join(__dirname, "../../builds")
})

// Make the 'builds' directory if not present.
shell.mkdir(`-p`, resolved.builds)

const resolved = {
gaia: parsePath(path.resolve(untildify(gaia))),
git: parsePath(path.resolve(__dirname, "../../.git")),
builds: parsePath(builds)
}
// Override the gaia option before passing the options into the container.
const nextOptions = Object.assign({}, options, {
gaia: `/mnt/gaia`
})

const nextOptionsString = Object.entries(nextOptions)
.map(([key, value]) => `--${key}=${value}`)
.join(` `)

shell.exec(`docker run \
// inputs: The Gaia binary and the .git directory.
// inputs:
// gaia
// .git/
// default network
//
// output: the builds directory
exec(`docker run \
--interactive \
--mount type=bind,readonly,source=${resolved.gaia},target=/mnt/gaia \
--mount type=bind,readonly,source=${resolved.git},target=/mnt/.git \
--mount type=bind,readonly,source=${
resolved.network
},target=/mnt/network \
--mount type=bind,source=${resolved.builds},target=/mnt/builds \
--rm \
cosmos/voyager-builder \
"${commit}" \
--gaia=/mnt/gaia \
--platform=${platform} \
--skip-pack=${skipPack}
cosmos/voyager-builder "${commit}" ${nextOptionsString}
`)
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"commit": ["commit from which to build", "HEAD"],
"gaia": ["path to the gaia binary"],
"network": ["path to the default network to use", "app/networks/gaia-2"],
"platform": ["the target platform {darwin|linux|win32}"],
"skip-pack": ["skip the repackaging of the JS files", false]
}
56 changes: 42 additions & 14 deletions tasks/build/release.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
"use strict"

const { cli } = require(`@nodeguy/cli`)
const config = require(`../../config`)
const { createHash } = require("crypto")
const optionsSpecification = require(`./options.json`)
const optionsSpecification = require(`./optionsSpecification.json`)
const path = require("path")
const packager = require("electron-packager")
const shell = require(`shelljs`)
Expand All @@ -15,13 +14,31 @@ var tar = require("tar-stream")
var duplexer = require("duplexer")
const packageJson = require("../../package.json")

/**
* Build webpack in production
*/
const pack = async options => {
console.log("\x1b[33mBuilding webpack in production mode...\n\x1b[0m")
shell.exec("npm run pack")
build(options)
const rewriteConfig = ({ network }) => {
const file = path.join(__dirname, `../../app`, `config.toml`)
const config = fs.readFileSync(file, { encoding: `utf8` })
const networkName = path.basename(network)

const newConfig = config.replace(
/default_network = ".*"/,
`default_network = "${networkName}"`
)

console.log(`Changed default network to "${networkName}".`)
fs.writeFileSync(file, newConfig)
}

// electron-packager options
// Docs: https://simulatedgreg.gitbooks.io/electron-vue/content/docs/building_your_app.html
const building = {
arch: "x64",
asar: false,
dir: path.join(__dirname, "../../app"),
icon: path.join(__dirname, "../../app/icons/icon"),
ignore: /^\/(src|index\.ejs|icons)/,
out: path.join(__dirname, "../../builds"),
overwrite: true,
packageManager: "yarn"
}

/**
Expand All @@ -30,7 +47,7 @@ const pack = async options => {
function build({ platform, gaia }) {
console.log("Using prebuilt binary", gaia)

const options = Object.assign({}, config.building, {
const options = Object.assign({}, building, {
afterCopy: [copyBinary("gaia", gaia)],
platform
})
Expand Down Expand Up @@ -63,6 +80,14 @@ function build({ platform, gaia }) {
})
}

/**
* Build webpack in production
*/
const pack = () => {
console.log("\x1b[33mBuilding webpack in production mode...\n\x1b[0m")
shell.exec("npm run pack")
}

function copyBinary(name, binaryLocation) {
return function(buildPath, electronVersion, platform, arch, cb) {
let binPath = path.join(buildPath, "bin", name)
Expand Down Expand Up @@ -204,20 +229,23 @@ function deterministicTar() {
return duplexer(extract, pack)
}

cli(optionsSpecification, async options => {
const { platform, "skip-pack": skipPack } = options
cli(optionsSpecification, options => {
const { network, platform, "skip-pack": skipPack } = options

if (platform === "clean") {
require("del").sync(["builds/*", "!.gitkeep"])
console.log("\x1b[33m`builds` directory cleaned.\n\x1b[0m")
} else {
console.log(`Building for platform "${platform}".`)
rewriteConfig(options)
shell.cp(`-r`, `/mnt/network`, `app/networks/${path.basename(network)}`)

if (skipPack) {
console.log("Skipping packaging")
build(options)
} else {
await pack(options)
pack()
}

build(options)
}
})
2 changes: 1 addition & 1 deletion tasks/runner.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict"

const config = require("../config")
const config = require("../app/src/config")
const spawn = require("child_process").spawn
const path = require("path")
const { cleanExitChild } = require("./common.js")
Expand Down
20 changes: 20 additions & 0 deletions test/unit/helpers/electron_mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// this mocks the IPC layer and isolates the mainthread from the renderer thread in tests
jest.mock("electron", () => ({
clipboard: { writeText: jest.fn() },
ipcRenderer: { send: jest.fn() },
ipcMain: { on: jest.fn() },
remote: {
getGlobal(name) {
if (name === "config")
return {
default_network: "mock-net",
google_analytics_uid: "UA-TEST",
sentry_dsn:
"https://4dee9f70a7d94cc0959a265c45902d84:[email protected]/288169",
sentry_dsn_public:
"https://[email protected]/288169"
}
if (name === "root") return "./test/unit/tmp/test_root/"
}
}
}))
5 changes: 0 additions & 5 deletions test/unit/helpers/ipc_mock.js

This file was deleted.

2 changes: 1 addition & 1 deletion test/unit/specs/App.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jest.mock("renderer/connectors/node.js", () => () =>
)

describe("App without analytics", () => {
jest.mock("../../../config", () => ({
jest.mock("../../../app/src/config", () => ({
google_analytics_uid: "123",
sentry_dsn_public: "456"
}))
Expand Down
3 changes: 0 additions & 3 deletions test/unit/specs/components/common/NiBtnCopy.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import setup from "../../../helpers/vuex-setup"

jest.mock("electron", () => ({ clipboard: { writeText: jest.fn() } }))

import NiBtnCopy from "renderer/components/common/NiBtnCopy"

describe("NiBtnCopy", () => {
Expand Down
Loading

0 comments on commit e4622f1

Please sign in to comment.