serverless-plugin-ci-build
Advanced tools
Comparing version 0.1.2 to 0.2.0
175
index.js
@@ -14,3 +14,7 @@ 'use strict'; | ||
this.uuidStage = uuidV4(); | ||
this.buildPlugin = this.serverless.service.custom ? this.serverless.service.custom.buildPlugin : {}; | ||
this.originalStage = this.options.stage || this.serverless.service.provider.stage; | ||
this.originalRegion = this.options.region || this.serverless.service.provider.region; | ||
this.buildPlugin = this.serverless.service.custom | ||
? this.serverless.service.custom.buildPlugin | ||
: {}; | ||
@@ -21,8 +25,8 @@ // @todo if deployment bucket is set it should be removed when deploying with noDeploy | ||
if (this.options.buildPlugin) { | ||
this.options = Object.assign(this.options, | ||
{ | ||
noDeploy: true, | ||
stage: this.buildPlugin.templateStage || this.uuidStage, | ||
region: this.buildPlugin.templateRegion || this.uuidRegion, | ||
}); | ||
delete this.serverless.service.provider.deploymentBucket; | ||
this.options = Object.assign(this.options, { | ||
noDeploy: true, | ||
stage: this.buildPlugin.templateStage || this.uuidStage, | ||
region: this.buildPlugin.templateRegion || this.uuidRegion, | ||
}); | ||
} | ||
@@ -37,12 +41,18 @@ this.commands = {}; | ||
if (this.options.buildPlugin) { | ||
const stack = | ||
JSON.parse(fse.readFileSync(path.join('.serverless', 'cloudformation-template-update-stack.json'), 'utf8')); | ||
const stack = JSON.parse( | ||
fse.readFileSync( | ||
path.join('.serverless', 'cloudformation-template-update-stack.json'), | ||
'utf8', | ||
), | ||
); | ||
// const state = JSON.parse( | ||
// fse.readFileSync( | ||
// path.join('.serverless', 'serverless-state.json'), | ||
// 'utf8', | ||
// ), | ||
// ); | ||
delete stack.Resources.ServerlessDeploymentBucket; | ||
const ServerlessDeploymentBucket = { | ||
Type: 'String', | ||
Description: 'Deployment Bucket Name', | ||
}; | ||
if (!stack.Parameters) { | ||
@@ -52,18 +62,65 @@ stack.Parameters = {}; | ||
Object.assign(stack.Parameters, { ServerlessDeploymentBucket }); | ||
// add ServerlessDeploymentBucket, Stage, and ArtifactPath path to Parameters | ||
if (!stack.Parameters.ServerlessDeploymentBucket) { | ||
Object.assign(stack.Parameters, { | ||
ServerlessDeploymentBucket: { | ||
Type: 'String', | ||
Description: 'Deployment Bucket Name', | ||
}, | ||
}); | ||
} | ||
if (!stack.Parameters.Stage) { | ||
Object.assign(stack.Parameters, { | ||
Stage: { | ||
Type: 'String', | ||
Description: 'Serverless Stage', | ||
}, | ||
}); | ||
} | ||
if (!stack.Parameters.ArtifactPath) { | ||
Object.assign(stack.Parameters, { | ||
ArtifactPath: { | ||
Type: 'String', | ||
Description: 'Artifact path', | ||
AllowedPattern: '.*/', | ||
}, | ||
}); | ||
} | ||
delete stack.Resources.ServerlessDeploymentBucketPolicy; | ||
const serviceName = this.serverless.service.service; | ||
const buildPluginCfTemplateFileName = this.buildPlugin.cfTemplateFileName || 'cloudformation-template-update-stack.json.j2'; | ||
let artifactPath; | ||
const replacer = (key, value) => { | ||
if (typeof (value) === 'string') { | ||
const buildPluginStage = this.buildPlugin.stage || '{{ stage }}'; | ||
const buildPluginRegion = this.buildPlugin.region || '{{ region }}'; | ||
const buildPluginArtifact = this.buildPlugin.artifactPath || '{{ artifact_path }}'; | ||
if (typeof value === 'string') { | ||
// eslint-disable-next-line no-template-curly-in-string | ||
const buildPluginStage = this.buildPlugin.stage || '${Stage}'; | ||
// eslint-disable-next-line no-template-curly-in-string | ||
const buildPluginRegion = this.buildPlugin.region || '${AWS::Region}'; | ||
// eslint-disable-next-line no-template-curly-in-string | ||
const buildPluginArtifact = this.buildPlugin.artifactPath || '${ArtifactPath}'; | ||
const regexRow = new RegExp( | ||
`(?:(?!").)*?(${this.options.stage}|${this.options.region}|serverless/${serviceName}/.+/[0-9-T:.Z]+/).*`, | ||
'g', | ||
); | ||
const regexStage = new RegExp(this.options.stage, 'g'); | ||
const regexRegion = new RegExp(this.options.region, 'g'); | ||
const regexArtifact = new RegExp(`serverless/${serviceName}/${buildPluginStage}/[0-9-T:.Z]+/`, 'g'); | ||
return value.replace(regexStage, buildPluginStage) | ||
.replace(regexRegion, buildPluginRegion) | ||
.replace(regexArtifact, `${buildPluginArtifact}/`); | ||
const regexArtifact = new RegExp( | ||
`serverless/${serviceName}/.+/[0-9-T:.Z]+/`, | ||
'g', | ||
); | ||
if (!artifactPath) { | ||
const testArtifactPath = regexArtifact.exec(value); | ||
artifactPath = testArtifactPath ? testArtifactPath[0] : undefined; | ||
} | ||
return value | ||
.replace(regexRow, (found) => (key !== 'Fn::Sub' ? `###SUB###${found}###/SUB###` : found)) | ||
.replace(regexArtifact, `${buildPluginArtifact}/`) | ||
.replace(regexStage, buildPluginStage) | ||
.replace(regexRegion, buildPluginRegion); | ||
} | ||
@@ -74,3 +131,2 @@ return value; | ||
const buildPluginDir = this.buildPlugin.buildDirectory || '.buildPlugin'; | ||
const templatePath = path.join(buildPluginDir, buildPluginCfTemplateFileName); | ||
@@ -81,26 +137,63 @@ // Create buildPlugin deployment directory | ||
// Save template | ||
const template = JSON.stringify(stack, replacer, 2); | ||
fse.writeFileSync(templatePath, template); | ||
this.log(`Created buildPlugin template ${templatePath}`); | ||
const templatePathJson = path.join( | ||
buildPluginDir, | ||
'cloudformation-template-update-stack.json', | ||
); | ||
const templatePathJinja = path.join( | ||
buildPluginDir, | ||
'cloudformation-template-update-stack.json.j2', | ||
); | ||
const parameterizedTemplate = JSON.stringify(stack, replacer, 2) | ||
.replace(/"(?:(?!").)*?###SUB###/g, '{ "Fn::Sub": "') | ||
.replace(/###\/SUB###"/g, '" }'); | ||
Object.keys(this.serverless.service.functions).reduce((result, key) => { | ||
const artifact = this.serverless.service.functions[key].package.artifact; | ||
if (result.indexOf(artifact) === -1) { | ||
result.push(artifact); | ||
} | ||
return result; | ||
}, []) | ||
const parameterizedTemplateJson = JSON.stringify( | ||
JSON.parse(parameterizedTemplate), | ||
); | ||
fse.writeFileSync(templatePathJson, parameterizedTemplateJson); | ||
fse.writeFileSync(templatePathJinja, parameterizedTemplateJson); | ||
this.log(`Created template ${templatePathJson} & ${templatePathJinja}`); | ||
// // Save state | ||
// const statePathJson = path.join(buildPluginDir, "serverless-state.json"); | ||
// const statePathJinja = path.join( | ||
// buildPluginDir, | ||
// "serverless-state.json.j2" | ||
// ); | ||
// const parameterizedState = JSON.stringify(state, replacer, 2) | ||
// .replace(/"(?:(?!").)*?###SUB###/g, '{ "Fn::Sub": "') | ||
// .replace(/###\/SUB###"/g, '" }'); | ||
// const parameterizedStateJson = JSON.stringify( | ||
// JSON.parse(parameterizedState) | ||
// ); | ||
// fse.writeFileSync(statePathJson, parameterizedStateJson); | ||
// fse.writeFileSync(statePathJinja, parameterizedStateJson); | ||
// this.log(`Created state ${statePathJson} & ${statePathJinja}`); | ||
Object.keys(this.serverless.service.functions) | ||
.reduce((result, key) => { | ||
const artifact = this.serverless.service.functions[key].package.artifact | ||
|| this.serverless.service.artifact; | ||
if (result.indexOf(artifact) === -1) { | ||
result.push(artifact); | ||
} | ||
return result; | ||
}, []) | ||
.forEach((zipfile) => { | ||
const zipfilename = path.parse(zipfile).base; | ||
// Copy zip | ||
fse.copySync( | ||
zipfile, | ||
path.join(buildPluginDir, zipfilename)); | ||
this.log(`Copied zip ${zipfilename} to ${buildPluginDir}/${zipfilename}`); | ||
fse.copySync(zipfile, path.join(buildPluginDir, zipfilename)); | ||
this.log( | ||
`Copied zip ${zipfilename} to ${buildPluginDir}/${zipfilename}`, | ||
); | ||
}); | ||
} | ||
this.options.stage = this.originalStage; | ||
this.options.region = this.originalRegion; | ||
} | ||
log(message) { | ||
this.serverless.cli.consoleLog(`Serverless Plugin CI Build: ${chalk.yellow(message)}`); | ||
this.serverless.cli.consoleLog( | ||
`Serverless Plugin CI Build: ${chalk.yellow(message)}`, | ||
); | ||
} | ||
@@ -107,0 +200,0 @@ } |
{ | ||
"name": "serverless-plugin-ci-build", | ||
"description": "Serverless Framework Plugin that creates Jinja2 template from CloudFormation templates", | ||
"version": "0.1.2", | ||
"version": "0.2.0", | ||
"main": "index.js", | ||
@@ -13,14 +13,14 @@ "author": "Eetu Tuomala", | ||
"dependencies": { | ||
"chalk": "^2.4.1", | ||
"fs-extra": "^7.0.0", | ||
"uuid": "^3.3.2" | ||
"chalk": "^2.4.2", | ||
"fs-extra": "^7.0.1", | ||
"uuid": "^3.3.3" | ||
}, | ||
"devDependencies": { | ||
"eslint": "^3.14.0", | ||
"eslint-config-airbnb": "^14.0.0", | ||
"eslint-config-airbnb-base": "^11.0.1", | ||
"eslint-plugin-import": "^2.2.0", | ||
"eslint-plugin-jsx-a11y": "^3.0.2", | ||
"eslint-plugin-react": "^6.9.0", | ||
"jest": "^23.5.0" | ||
"eslint": "^6.7.2", | ||
"eslint-config-airbnb": "^18.0.1", | ||
"eslint-config-airbnb-base": "^14.0.0", | ||
"eslint-plugin-import": "^2.19.1", | ||
"eslint-plugin-jsx-a11y": "^6.2.3", | ||
"eslint-plugin-react": "^7.17.0", | ||
"jest": "^24.9.0" | ||
}, | ||
@@ -27,0 +27,0 @@ "scripts": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
9061
190
Updatedchalk@^2.4.2
Updatedfs-extra@^7.0.1
Updateduuid@^3.3.3