-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add support to chain deployment and aliasing in a single command
- Loading branch information
0 parents
commit 4d29b01
Showing
8 changed files
with
680 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"env": { | ||
"browser": true, | ||
"commonjs": true, | ||
"es6": true | ||
}, | ||
"extends": "eslint:recommended", | ||
"parserOptions": { | ||
"sourceType": "module" | ||
}, | ||
"rules": { | ||
"indent": [ | ||
"error", | ||
"tab" | ||
], | ||
"linebreak-style": [ | ||
"error", | ||
"unix" | ||
], | ||
"quotes": [ | ||
"error", | ||
"single" | ||
], | ||
"semi": [ | ||
"error", | ||
"never" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node_modules/ | ||
*.DS_Store | ||
blabla.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
BSD License | ||
|
||
For google-graphql-functions software | ||
|
||
Copyright (c) 2017, Neap pty ltd. All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without modification, | ||
are permitted provided that the following conditions are met: | ||
|
||
* Redistributions of source code must retain the above copyright notice, this | ||
list of conditions and the following disclaimer. | ||
|
||
* Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation | ||
and/or other materials provided with the distribution. | ||
|
||
* Neither the name Facebook nor the names of its contributors may be used to | ||
endorse or promote products derived from this software without specific | ||
prior written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | ||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
<a href="https://neap.co" target="_blank"><img src="https://neap.co/img/neap_black_small_logo.png" alt="Neap Pty Ltd logo" title="Neap" align="right" height="50" width="120"/></a> | ||
|
||
# NowFlow - Automate your Zeit Now Deployments | ||
[![NPM][1]][2] | ||
|
||
[1]: https://img.shields.io/npm/v/now-flow.svg?style=flat | ||
[2]: https://www.npmjs.com/package/now-flow | ||
|
||
Define your alias and all your environment variables inside your traditional __*now.json*__, and let __*now-flow*__ do the rest. | ||
|
||
_now.json_ | ||
```js | ||
{ | ||
"env": { | ||
"production": { | ||
"scripts": { | ||
"start": "NODE_ENV=production node index.js" | ||
}, | ||
"alias": "yourapp-prod" | ||
}, | ||
"test": { | ||
"scripts": { | ||
"start": "NODE_ENV=test node index.js" | ||
}, | ||
"alias": "yourapp-test" | ||
} | ||
} | ||
} | ||
``` | ||
|
||
``` | ||
nowflow production | ||
``` | ||
|
||
The above will make sure that the _package.json_ that is being deployed will contain the _start_ script `"NODE_ENV=production node index.js"` and that once the deployment to [Zeit](https://zeit.co/now) is finished, it is automatically aliased to `yourapp-prod`. | ||
|
||
No more deployment then aliasing steps. No more worries that some environment variables have been properly deployed to the right environment. | ||
|
||
|
||
# Install | ||
Either install it globally | ||
``` | ||
npm install now-flow -g | ||
``` | ||
|
||
Or embed it inside your project to run it through npm | ||
|
||
``` | ||
npm install now-flow --save | ||
``` | ||
|
||
# How To Use It | ||
## Basic | ||
You must first create a __*now.json*__ file in the root of your project's directory as follow: | ||
```js | ||
{ | ||
"env": { | ||
"production": { | ||
"alias": "yourapp-prod" | ||
}, | ||
"test": { | ||
"alias": "yourapp-test" | ||
} | ||
} | ||
} | ||
``` | ||
|
||
Make sure there is at least one environment defined under the _env_ property. Then simply run: | ||
|
||
``` | ||
nowflow production | ||
``` | ||
|
||
The above will: | ||
1. Deploy your project to [Zeit](https://zeit.co/now) using the _production_ config defined in the _now.json_. | ||
2. Will alias that deployment using the alias defined in the _production_ config defined in the _now.json_ (i.e. 'yourapp-prod'). | ||
|
||
## Skipping Aliasing | ||
If you do not want to alias your deployment, use the following: | ||
``` | ||
nowflow production --noalias | ||
``` | ||
|
||
## Modifying The package.json's "scripts" property For Each Environment | ||
As described in the intro, this is one of the key feature of _now-flow_. In the _now.json_, under each specific environment, you can add a __*"script"*__ property that will completely override the one defined inside the _package.json_ during the deployment. Once the deployment is completed, the _package.json_ is restored to its original state. | ||
|
||
```js | ||
{ | ||
"env": { | ||
"production": { | ||
"scripts": { | ||
"start": "NODE_ENV=production node index.js" | ||
}, | ||
"alias": "yourapp-prod" | ||
}, | ||
"test": { | ||
"scripts": { | ||
"start": "NODE_ENV=test node index.js" | ||
}, | ||
"alias": "yourapp-test" | ||
} | ||
} | ||
} | ||
``` | ||
|
||
``` | ||
nowflow production | ||
``` | ||
|
||
In the example above, we're making sure that the _package.json_ contains a _start_ script so that _now_ can, for example, correctly start an express server. | ||
|
||
# This Is What We re Up To | ||
We are Neap, an Australian Technology consultancy powering the startup ecosystem in Sydney. We simply love building Tech and also meeting new people, so don't hesitate to connect with us at [https://neap.co](https://neap.co). | ||
|
||
# License | ||
Copyright (c) 2017, Neap Pty Ltd. | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | ||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | ||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | ||
* Neither the name of Neap Pty Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL NEAP PTY LTD BE LIABLE FOR ANY | ||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/usr/bin/env node | ||
/** | ||
* Copyright (c) 2017, Neap Pty Ltd. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
'use strict' | ||
|
||
const program = require('commander') | ||
const { deploy } = require('./src/nowf') | ||
|
||
program | ||
.command('* <env>') | ||
.usage('Deploy to Zeit Now using a specific environment configuration that will configure the \'now.json\' and the \'package.json\' accordingly.') | ||
.option('-n, --noalias', 'When specified, prevent deployment to be aliased.') | ||
.action((env, options={}) => { | ||
deploy(env, ((options.parent || {}).rawArgs || []).some(x => (x == '--noalias' || x == '--noa'))) | ||
}) | ||
|
||
/*eslint-disable */ | ||
program.parse(process.argv) | ||
/*eslint-enable */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
{ | ||
"name": "now-flow", | ||
"version": "0.0.1", | ||
"description": "Add deployment workflows to Zeit now", | ||
"main": "index.js", | ||
"bin": { | ||
"nowflow": "./index.js" | ||
}, | ||
"scripts": { | ||
"eslint": "eslint ./src index.js --fix", | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/nicolasdao/now-workflow.git" | ||
}, | ||
"keywords": [ | ||
"Zeit", | ||
"now", | ||
"deploy", | ||
"deployment", | ||
"worflow" | ||
], | ||
"author": "Nicolas Dao", | ||
"license": "BSD-3-Clause", | ||
"bugs": { | ||
"url": "https://github.com/nicolasdao/now-workflow/issues" | ||
}, | ||
"homepage": "https://github.com/nicolasdao/now-workflow#readme", | ||
"dependencies": { | ||
"colors": "^1.1.2", | ||
"commander": "^2.12.2", | ||
"lodash": "^4.17.4", | ||
"rimraf": "^2.6.2", | ||
"shortid": "^2.2.8" | ||
}, | ||
"devDependencies": { | ||
"eslint": "^4.13.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
/** | ||
* Copyright (c) 2017, Neap Pty Ltd. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
const path = require('path') | ||
require('colors') | ||
const { writeToFile } = require('./utilities').files | ||
|
||
/*eslint-disable */ | ||
const getAbsPath = relativePath => path.join(process.cwd(), relativePath) | ||
const exit = msg => { | ||
if (msg) | ||
console.log(msg) | ||
process.exit() | ||
} | ||
/*eslint-enable */ | ||
|
||
const duplicate = obj => obj ? JSON.parse(JSON.stringify(obj)) : obj | ||
|
||
const updatePackageScripts = (env='default') => { | ||
let nowConfig | ||
nowConfig = require(getAbsPath('now.json')) || {} | ||
|
||
const envConfig = (nowConfig.env || {})[env] | ||
if (!envConfig) | ||
throw new Error(`No environment named '${env.bold}' in ${'now.json'.bold}`) | ||
|
||
const pkgPath = getAbsPath('package.json') | ||
if (envConfig.scripts != undefined) { | ||
const currentPkg = require(pkgPath) || {} | ||
const newPkg = duplicate(currentPkg) | ||
|
||
if (!currentPkg.scripts) | ||
newPkg.scripts = {} | ||
|
||
for (let script in envConfig.scripts) | ||
newPkg.scripts[script] = envConfig.scripts[script] | ||
|
||
return updateJsonFile(pkgPath, newPkg) | ||
.then(() => ({ path: pkgPath, current: currentPkg, new: newPkg })) | ||
// If updating the package.json fails, attempt to revert | ||
.catch(err => { | ||
return updateJsonFile(pkgPath, currentPkg) | ||
.catch(() => null) | ||
.then(() => { throw err }) | ||
}) | ||
} | ||
else | ||
return Promise.resolve({ path: pkgPath, current: null }) | ||
} | ||
|
||
const updateNowAlias = (env='default', toogle=true) => { | ||
const nowPath = getAbsPath('now.json') | ||
const currentNowConfig = require(nowPath) || {} | ||
const newNowConfig = duplicate(currentNowConfig) | ||
|
||
const envConfig = (currentNowConfig.env || {})[env] | ||
if (!envConfig) | ||
throw new Error(`No environment named '${env.bold}' in ${'now.json'.bold}`) | ||
|
||
if (envConfig.alias != undefined && toogle) { | ||
newNowConfig.alias = envConfig.alias | ||
|
||
return updateJsonFile(nowPath, newNowConfig) | ||
.then(() => ({ alias: toogle, path: nowPath, current: currentNowConfig, new: newNowConfig })) | ||
// If updating the now.json fails, attempt to revert | ||
.catch(err => { | ||
return updateJsonFile(nowPath, currentNowConfig) | ||
.catch(() => null) | ||
.then(() => { throw err }) | ||
}) | ||
} | ||
else | ||
return Promise.resolve({ alias: false, path: nowPath, current: null }) | ||
} | ||
|
||
const updateJsonFile = (filePath, jsonObj={}) => { | ||
const str = JSON.stringify(jsonObj, null, '\t') | ||
return writeToFile(filePath, str) | ||
} | ||
|
||
const deploy = (env='default', noalias=false) => updatePackageScripts(env) | ||
.catch(err => exit(err.message.italic.red)) | ||
.then(pkg => { | ||
try { | ||
require('child_process').execSync('now', { stdio: 'inherit' }) | ||
} | ||
catch(err) { | ||
return updateJsonFile(pkg.path, pkg.current) | ||
.then(() => exit()) | ||
.catch(() => exit()) | ||
} | ||
|
||
return updateJsonFile(pkg.path, pkg.current) | ||
}) | ||
.catch(err => exit(err.message.italic.red)) | ||
.then(() => { | ||
if (!noalias) | ||
return updateNowAlias(env).then(now => { | ||
if (now.alias) { | ||
try { | ||
require('child_process').execSync('now alias', { stdio: 'inherit' }) | ||
} | ||
catch(err) { | ||
return updateJsonFile(now.path, now.current) | ||
.then(() => exit()) | ||
.catch(() => exit()) | ||
} | ||
|
||
return updateJsonFile(now.path, now.current) | ||
} | ||
}) | ||
}) | ||
|
||
module.exports = { | ||
deploy | ||
} | ||
|
Oops, something went wrong.