mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
Remove the errant (but understandable) distributed usage of region and stage settings. This otherwise locks in a multitude of bugs around the improper algorithm for selecting (given all context) the proper region or stage setting. Instead, all code should use the centralized algorithm for determining such values. This creates a strange first and second class configuration concept but these two are sufficiently varied and complex in their creation and use that this seems appropriate.
116 lines
3.5 KiB
JavaScript
116 lines
3.5 KiB
JavaScript
'use strict';
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const crypto = require('crypto');
|
|
const globby = require('globby');
|
|
const BbPromise = require('bluebird');
|
|
const _ = require('lodash');
|
|
const normalizeFiles = require('../../lib/normalizeFiles');
|
|
|
|
module.exports = {
|
|
checkForChanges() {
|
|
this.serverless.service.provider.shouldNotDeploy = false;
|
|
|
|
if (this.options.force) {
|
|
return BbPromise.resolve();
|
|
}
|
|
|
|
return BbPromise.bind(this)
|
|
.then(this.getMostRecentObjects)
|
|
.then(this.getObjectMetadata)
|
|
.then(this.checkIfDeploymentIsNecessary);
|
|
},
|
|
|
|
getMostRecentObjects() {
|
|
const service = this.serverless.service.service;
|
|
|
|
const params = {
|
|
Bucket: this.bucketName,
|
|
Prefix: `serverless/${service}/${this.provider.getStage()}`,
|
|
};
|
|
|
|
return this.provider.request('S3',
|
|
'listObjectsV2',
|
|
params
|
|
).then((result) => {
|
|
if (result && result.Contents && result.Contents.length) {
|
|
const objects = result.Contents;
|
|
|
|
const ordered = _.orderBy(objects, ['Key'], ['desc']);
|
|
|
|
const firstKey = ordered[0].Key;
|
|
const directory = firstKey.substring(0, firstKey.lastIndexOf('/'));
|
|
|
|
const mostRecentObjects = ordered.filter((obj) => {
|
|
const objKey = obj.Key;
|
|
const objDirectory = objKey.substring(0, objKey.lastIndexOf('/'));
|
|
|
|
return directory === objDirectory;
|
|
});
|
|
|
|
return BbPromise.resolve(mostRecentObjects);
|
|
}
|
|
|
|
return BbPromise.resolve([]);
|
|
});
|
|
},
|
|
|
|
getObjectMetadata(objects) {
|
|
if (objects && objects.length) {
|
|
const headObjectObjects = objects
|
|
.map((obj) => this.provider.request('S3',
|
|
'headObject',
|
|
{
|
|
Bucket: this.bucketName,
|
|
Key: obj.Key,
|
|
}
|
|
));
|
|
|
|
return BbPromise.all(headObjectObjects)
|
|
.then((result) => result);
|
|
}
|
|
|
|
return BbPromise.resolve([]);
|
|
},
|
|
|
|
checkIfDeploymentIsNecessary(objects) {
|
|
if (objects && objects.length) {
|
|
const remoteHashes = objects.map((object) => object.Metadata.filesha256 || '');
|
|
|
|
const serverlessDirPath = path.join(this.serverless.config.servicePath, '.serverless');
|
|
|
|
// create a hash of the CloudFormation body
|
|
const compiledCfTemplate = this.serverless.service.provider.compiledCloudFormationTemplate;
|
|
const normCfTemplate = normalizeFiles.normalizeCloudFormationTemplate(compiledCfTemplate);
|
|
const localCfHash = crypto
|
|
.createHash('sha256')
|
|
.update(JSON.stringify(normCfTemplate))
|
|
.digest('base64');
|
|
|
|
// create hashes for all the zip files
|
|
const zipFiles = globby.sync(['**.zip'], { cwd: serverlessDirPath, dot: true, silent: true });
|
|
const zipFilePaths = zipFiles.map((zipFile) => path.join(serverlessDirPath, zipFile));
|
|
const zipFileHashes = zipFilePaths.map((zipFilePath) => {
|
|
// TODO refactor to be async (use util function to compute checksum async)
|
|
const zipFile = fs.readFileSync(zipFilePath);
|
|
return crypto.createHash('sha256').update(zipFile).digest('base64');
|
|
});
|
|
|
|
const localHashes = zipFileHashes;
|
|
localHashes.push(localCfHash);
|
|
|
|
if (_.isEqual(remoteHashes.sort(), localHashes.sort())) {
|
|
this.serverless.service.provider.shouldNotDeploy = true;
|
|
|
|
const message = [
|
|
'Service files not changed. Skipping deployment...',
|
|
].join('');
|
|
this.serverless.cli.log(message);
|
|
}
|
|
}
|
|
|
|
return BbPromise.resolve();
|
|
},
|
|
};
|