diff --git a/codecov.yaml b/.codecov.yaml similarity index 100% rename from codecov.yaml rename to .codecov.yaml diff --git a/changelog.md b/changelog.md index 2f2059d9..6ef1addc 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,13 @@ # Architect Deploy changelog --- +## [1.3.0] 2019-12-14 + +### Added + +- Adding `--name` for creating a unique stack name. (Aliased to `-n` and `name`.) +- Adding `--tags` for adding tags to the CloudFormation stack. + ## [1.2.14] 2019-12-12 diff --git a/cli.js b/cli.js index dbb9407a..e283e725 100755 --- a/cli.js +++ b/cli.js @@ -3,45 +3,40 @@ let deploy = require('.') let {banner} = require('@architect/utils') let create = require('@architect/create') let validate = require('./src/validate') +let options = require('./src/options') let {version} = require('./package.json') /** * `arc deploy` * - * deploys the current .arc as a sam application to AppNameStaging stack + * deploys the current arcfile * * options * -p|--production|production ... deploys to AppNameProduction * -d|--dirty|dirty ............. *staging only* dirty deploy function code/config * -s|--static|static ........... dirty deploys /public to s3 bucket * -v|--verbose|verbose ......... prints all output to console + * -t|--tags|tags ............... add tags + * -n|--name|name ............... customize stack name */ -let isDirty = opt=> opt === 'dirty' || opt === '--dirty' || opt === '-d' -let isStatic = opt=> opt === 'static' || opt === '--static' || opt === '-s' -let isProd = opt=> opt === 'production' || opt === '--production' || opt === '-p' -let isPrune = opt=> opt === 'prune' || opt === '--prune' -let isVerbose = opt=> opt === 'verbose' || opt === '--verbose' || opt === '-v' - async function cmd(opts=[]) { + // validate the call for expected env and args validate(opts) + // create any missing local infra await create({}) - let args = { - prune: opts.some(isPrune), - verbose: opts.some(isVerbose), - production: opts.some(isProd) - } + // read args into {prune, verbose, production, tags, name, isFullDeploy} + let args = options(opts) - if (opts.some(isDirty)) + if (args.isDirty) return deploy.dirty() - if (opts.some(isStatic)) { - args.isFullDeploy = false + if (args.isStatic) return deploy.static(args) - } + // deploy with SAM by default.. return deploy.sam(args) } diff --git a/src/options.js b/src/options.js new file mode 100644 index 00000000..c89dc622 --- /dev/null +++ b/src/options.js @@ -0,0 +1,49 @@ +let isDirty = opt=> opt === 'dirty' || opt === '--dirty' || opt === '-d' +let isStatic = opt=> opt === 'static' || opt === '--static' || opt === '-s' +let isProd = opt=> opt === 'production' || opt === '--production' || opt === '-p' +let isPrune = opt=> opt === 'prune' || opt === '--prune' +let isVerbose = opt=> opt === 'verbose' || opt === '--verbose' || opt === '-v' + +let tags = arg=> arg === '--tags' || arg === '-t' || arg === 'tags' +let name = arg=> arg === '--name' || arg === '-n' || arg === 'name' || arg.startsWith('--name=') + +module.exports = function options(opts) { + return { + prune: opts.some(isPrune), + verbose: opts.some(isVerbose), + production: opts.some(isProd), + tags: getTags(opts), + name: getName(opts), + isDirty: opts.some(isDirty), + isStatic: opts.some(isStatic), + isFullDeploy: opts.some(isStatic)? false : true + } +} + +function getTags(list) { + let hasTags = process.argv.some(tags) + if (!hasTags) + return [] + let len = list.length + let index = list.findIndex(tags) + 1 + let left = list.slice(index, len) + return left.filter(arg=> /^[a-zA-Z0-9]+=[a-zA-Z0-9]+/.test(arg)) +} + +function getName(list) { + let hasName = process.argv.some(name) + if (!hasName) + return false + + let len = list.length + let index = list.findIndex(name) + let left = list.slice(index, len) + let operator = left.shift() + + if (operator.indexOf('=') === -1) { + return left.shift() + } + else { + return operator.split('=')[1] + } +} diff --git a/src/sam/01-deploy/index.js b/src/sam/01-deploy/index.js index f8e2ef28..0a450309 100644 --- a/src/sam/01-deploy/index.js +++ b/src/sam/01-deploy/index.js @@ -1,7 +1,7 @@ let spawn = require('../spawn') module.exports = function deploy(params, callback) { - let {stackname, nested, appname, bucket, pretty, region, update} = params + let {stackname, nested, appname, bucket, pretty, region, update, tags} = params update.done('Generated CloudFormation deployment') update.start('Deploying & building infrastructure...') let template = nested ? `${appname}-cfn.yaml` : 'sam.yaml' @@ -13,8 +13,9 @@ module.exports = function deploy(params, callback) { '--capabilities', 'CAPABILITY_IAM CAPABILITY_AUTO_EXPAND', '--region', region ] - // if (nested) { - // args.push('CAPABILITY_AUTO_EXPAND') - //} + if (tags.length > 0) { + args.push('--tags') + args = args.concat(tags) + } spawn('aws', args, pretty, callback) } diff --git a/src/sam/index.js b/src/sam/index.js index 961c082f..0cdee5f1 100644 --- a/src/sam/index.js +++ b/src/sam/index.js @@ -18,7 +18,7 @@ let after = require('./02-after') * @param {Function} callback - a node-style errback * @returns {Promise} - if not callback is supplied */ -module.exports = function samDeploy({verbose, production}, callback) { +module.exports = function samDeploy({verbose, production, tags, name}, callback) { let stage = production? 'production' : 'staging' let ts = Date.now() @@ -30,6 +30,9 @@ module.exports = function samDeploy({verbose, production}, callback) { let stackname = `${utils.toLogicalID(appname)}${production? 'Production' : 'Staging'}` let update = updater('Deploy') + if (name) + stackname += utils.toLogicalID(name) + // Assigned below let cloudformation let sam @@ -118,8 +121,16 @@ module.exports = function samDeploy({verbose, production}, callback) { * Deployment */ function theDeploy(callback) { - let params = {appname, stackname, nested, bucket, pretty, region, update} - deploy(params, callback) + deploy({ + appname, + stackname, + nested, + bucket, + pretty, + region, + update, + tags, + }, callback) }, /**