2018-05-27 17:45:26 +00:00
|
|
|
/* eslint-disable no-console */
|
|
|
|
|
|
|
|
const path = require('path');
|
|
|
|
const fs = require('fs');
|
|
|
|
const colors = require('colors/safe');
|
|
|
|
const readdir = require('recursive-readdir');
|
|
|
|
const AWS = require('aws-sdk');
|
|
|
|
const mime = require('mime-types');
|
|
|
|
|
|
|
|
const s3 = new AWS.S3();
|
2018-05-29 21:08:22 +00:00
|
|
|
const cloudFront = new AWS.CloudFront();
|
2018-05-27 17:45:26 +00:00
|
|
|
const config = require(path.resolve(process.argv[2]));
|
|
|
|
|
|
|
|
const configFor = path => {
|
|
|
|
const { match, ...conf } = config.paths.find(conf => conf.match.test(path)); // eslint-disable-line no-unused-vars
|
|
|
|
return {
|
2018-05-27 17:49:55 +00:00
|
|
|
ContentType: mime.lookup(path) || 'application/octet-stream',
|
2018-05-27 17:45:26 +00:00
|
|
|
...conf
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
const bucketContents = s3.listObjectsV2({
|
2018-05-29 21:11:20 +00:00
|
|
|
Bucket: config.s3Bucket
|
2018-05-27 17:45:26 +00:00
|
|
|
}).promise()
|
|
|
|
.then(result => {
|
|
|
|
return result.Contents.map(item => item.Key);
|
|
|
|
})
|
|
|
|
.catch(err => {
|
|
|
|
console.error(colors.red.bold('Failed to fetch bucket contents:'), err);
|
|
|
|
process.exit(1);
|
|
|
|
});
|
|
|
|
|
|
|
|
const uploadDetails = readdir(config.deployFrom)
|
|
|
|
.then(paths => paths.map(p => {
|
|
|
|
const key = path.relative(config.deployFrom, p);
|
|
|
|
return {
|
|
|
|
Key: key,
|
|
|
|
Body: fs.createReadStream(p),
|
|
|
|
...configFor(key)
|
|
|
|
};
|
|
|
|
}))
|
|
|
|
.catch(err => {
|
|
|
|
console.error(colors.red.bold('Error:'), err);
|
|
|
|
process.exit(1);
|
|
|
|
});
|
|
|
|
|
|
|
|
Promise.all([bucketContents, uploadDetails]).then(([bucket, upload]) => {
|
|
|
|
const deleteKeys = bucket.filter(key => !upload.find(conf => key === conf.Key));
|
|
|
|
|
|
|
|
const uploadPromises = upload.map(params => {
|
|
|
|
console.log(`Starting upload for ${ params.Key }`);
|
|
|
|
return s3.upload({
|
2018-05-29 21:08:22 +00:00
|
|
|
Bucket: config.s3Bucket,
|
2018-05-27 17:45:26 +00:00
|
|
|
...params
|
|
|
|
}).promise()
|
|
|
|
.then(() => console.log(colors.green(`${ params.Key } successful`)))
|
|
|
|
.catch(err => {
|
|
|
|
console.error(colors.red.bold(`${ params.Key } failed`));
|
|
|
|
return Promise.reject(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-05-29 21:08:22 +00:00
|
|
|
return Promise.all(uploadPromises)
|
|
|
|
.then(() => {
|
2018-05-31 21:26:32 +00:00
|
|
|
if (deleteKeys.length === 0) {
|
|
|
|
console.log('No files to delete');
|
|
|
|
return Promise.resolve();
|
|
|
|
}
|
|
|
|
|
2018-05-29 21:08:22 +00:00
|
|
|
console.log(`Deleting ${ deleteKeys.length } stale files`);
|
|
|
|
return s3.deleteObjects({
|
|
|
|
Bucket: config.s3Bucket,
|
|
|
|
Delete: {
|
|
|
|
Objects: deleteKeys.map(key => ({ Key: key }))
|
|
|
|
}
|
|
|
|
}).promise()
|
|
|
|
.then(() => console.log(colors.green('Delete successful')))
|
|
|
|
.catch(err => {
|
|
|
|
console.error(colors.red.bold('Delete failed'));
|
|
|
|
return Promise.reject(err);
|
|
|
|
});
|
|
|
|
})
|
|
|
|
.then(() => {
|
|
|
|
return cloudFront.createInvalidation({
|
|
|
|
DistributionId: config.cloudFrontId,
|
|
|
|
InvalidationBatch: {
|
2018-06-06 05:33:31 +00:00
|
|
|
CallerReference: `deploy-${ process.env.CI_COMMIT_REF_SLUG }-${ process.env.CI_COMMIT_SHA }`,
|
2018-05-29 21:08:22 +00:00
|
|
|
Paths: {
|
2018-05-29 21:13:38 +00:00
|
|
|
Quantity: 1,
|
2018-05-29 21:08:22 +00:00
|
|
|
Items: [
|
|
|
|
'/*'
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).promise();
|
|
|
|
});
|
2018-05-27 17:45:26 +00:00
|
|
|
})
|
|
|
|
.catch(err => {
|
|
|
|
console.error(colors.red.bold('Error:'), err);
|
|
|
|
process.exit(1);
|
|
|
|
});
|