diff --git a/ui/desktop/README.md b/ui/desktop/README.md index bd8215112..f3f57ee29 100644 --- a/ui/desktop/README.md +++ b/ui/desktop/README.md @@ -62,6 +62,9 @@ List of available project commands. `yarn run ` To run as a desktop app: * `yarn start:desktop` +The Boundary CLI is downloaded and extracted to `electron-app/cli/` folder as part of +build. CLI version is defined in `electron-app/config/cli.js`. + ### Building for Production Before executing a build, be sure to set any environment variables necessary @@ -77,6 +80,8 @@ yarn build to codesign in production. The static production assets are saved into the `dist/` folder. +The Boundary CLI is downloaded and extracted to `electron-app/cli/` folder as part of +packaging. CLI version is defined in `electron-app/config/cli.js`. #### Environment Variables diff --git a/ui/desktop/electron-app/.gitignore b/ui/desktop/electron-app/.gitignore index b215f5133..9fde06842 100644 --- a/ui/desktop/electron-app/.gitignore +++ b/ui/desktop/electron-app/.gitignore @@ -91,3 +91,6 @@ out/ # Ember build ember-dist/ ember-test/ + +# CLI +cli/ \ No newline at end of file diff --git a/ui/desktop/electron-app/config/cli.js b/ui/desktop/electron-app/config/cli.js new file mode 100644 index 000000000..6f80e957a --- /dev/null +++ b/ui/desktop/electron-app/config/cli.js @@ -0,0 +1,40 @@ +const fs = require('fs'); +const path = require('path'); +const https = require('https'); +const decompress = require('decompress'); +const os = require('os'); + +const artifactVersion = '0.1.4'; +const artifactDestination = path.resolve(__dirname, '..', 'cli'); + +const downloadArtifact = (version) => { + const url = `https://releases.hashicorp.com/boundary/${version}/boundary_${version}_darwin_amd64.zip`; + return new Promise((resolve, reject) => { + const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'boundary-desktop-artifact-')) + console.log('Create tmp artifact directory: ', tmpDir); + + const artifactFileName = url.split('/').pop(); + if(!artifactFileName) reject('Could not find artifact filename in: ', url); + + const artifactPath = path.resolve(tmpDir, artifactFileName); + console.log('Download artifact url: ', url); + https.get(url, (response) => { + const stream = response.pipe(fs.createWriteStream(artifactPath)) + stream.on('close', () => resolve(artifactPath)); + stream.on('error', reject); + }); + }); +}; + +const extract = (artifactPath, destination) => { + if (!fs.existsSync(destination)) fs.mkdirSync(destination); + console.log('Extract artifact to: ', destination); + return decompress(artifactPath, destination); +}; + +module.exports = { + setup: async () => { + const artifactPath = await downloadArtifact(artifactVersion); + await extract(artifactPath, artifactDestination); + } +} \ No newline at end of file diff --git a/ui/desktop/electron-app/config/forge.config.js b/ui/desktop/electron-app/config/forge.config.js index e8cde84b0..0e9faa53c 100644 --- a/ui/desktop/electron-app/config/forge.config.js +++ b/ui/desktop/electron-app/config/forge.config.js @@ -1,42 +1,7 @@ const process = require('process'); -const fs = require('fs'); -const path = require('path'); -const https = require('https'); -const decompress = require('decompress'); -const os = require('os'); module.exports = { hooks: { - prePackage: async () => { - const downloadArtifact = (url) => { - return new Promise((resolve, reject) => { - const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'boundary-desktop-artifact-')) - console.log('\nCreate tmp artifact directory: ', tmpDir); - - const artifactFileName = url.split('/').pop(); - if(!artifactFileName) reject('Could not find artifact filename in: ', url); - - const artifactPath = path.resolve(tmpDir, artifactFileName); - console.log('\nDownload artifact url: ', url); - https.get(url, (response) => { - const stream = response.pipe(fs.createWriteStream(artifactPath)) - stream.on('close', () => resolve(artifactPath)); - stream.on('error', reject); - }); - }); - } - - // Download boundary - const artifactVersion = '0.1.4'; - const url = `https://releases.hashicorp.com/boundary/${artifactVersion}/boundary_${artifactVersion}_darwin_amd64.zip`; - const artifactPath = await downloadArtifact(url); - - // Extract artifact content - const binaryPath = path.resolve(__dirname, '..', 'src', 'binary'); - if (!fs.existsSync(binaryPath)) fs.mkdirSync(binaryPath); - console.log('\nExtract artifact to: ', binaryPath); - await decompress(artifactPath, binaryPath); - }, preMake: (forgeConfig) => { if (process.env.BOUNDARY_DESKTOP_SIGNING_IDENTITY) { forgeConfig.osxSign = { @@ -48,7 +13,7 @@ module.exports = { "signature-flags": "library" } } else { - console.warn('Could not find signing identity. Skipping signing.'); + console.warn('WARNING: Could not find signing identity. Skipping signing.'); } } }, diff --git a/ui/desktop/electron-app/package.json b/ui/desktop/electron-app/package.json index 971052c68..b8bb5ebae 100644 --- a/ui/desktop/electron-app/package.json +++ b/ui/desktop/electron-app/package.json @@ -8,8 +8,10 @@ "author": "HashiCorp", "main": "src/index.js", "scripts": { + "build:cli": "node -e 'require(\"./config/cli.js\").setup()'", "start": "electron-forge start", "package": "electron-forge package", + "premake": "yarn build:cli", "make": "electron-forge make", "publish": "electron-forge publish", "lint": "echo \"No linting configured\"" diff --git a/ui/desktop/electron-app/src/boundary-cli.js b/ui/desktop/electron-app/src/boundary-cli.js index ce740d87c..d3f0fd332 100644 --- a/ui/desktop/electron-app/src/boundary-cli.js +++ b/ui/desktop/electron-app/src/boundary-cli.js @@ -1,7 +1,7 @@ const path = require('path'); const spawnPromise = require('./spawn-promise'); -const cliPath = async () => path.resolve(__dirname, 'binary', 'boundary'); +const cliPath = async () => path.resolve(__dirname, '..', 'cli', 'boundary'); module.exports = { // Find boundary cli path diff --git a/ui/desktop/electron-app/src/spawn-promise.js b/ui/desktop/electron-app/src/spawn-promise.js index 1dabe4fea..2638f653c 100644 --- a/ui/desktop/electron-app/src/spawn-promise.js +++ b/ui/desktop/electron-app/src/spawn-promise.js @@ -27,7 +27,7 @@ const jsonify = (data) => { // POJO representation and throw it or promise->reject it. module.exports = function spawnPromise (command) { return new Promise((resolve, reject) => { - const boundaryPath = path.resolve(__dirname, 'binary', 'boundary'); + const boundaryPath = path.resolve(__dirname, '..', 'cli', 'boundary'); // TODO: remove path logging console.log(boundaryPath); const childProcess = spawn(boundaryPath, command); diff --git a/ui/desktop/package.json b/ui/desktop/package.json index 6056db791..06056a0df 100644 --- a/ui/desktop/package.json +++ b/ui/desktop/package.json @@ -24,6 +24,7 @@ "format:js": "prettier --write '{app,config,stories,tests,electron-app/src}/**/*.js' *.js", "format:sass": "prettier --write app/**/*.scss", "start": "ember serve", + "prestart:desktop": "cd electron-app && yarn build:cli", "start:desktop": "ember electron", "clean:coverage": "rm -rf coverage_*", "pretest": "yarn clean:coverage",