Last active
May 29, 2021 19:26
-
-
Save albanx/78fae254d2ea0cf601ff3d6359ffed99 to your computer and use it in GitHub Desktop.
Full Deploy.js script
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
const execSync = require('child_process').execSync; | |
const AWS = require('aws-sdk'); | |
const fs = require('fs'); | |
const mime = require('mime'); | |
const { version } = require('../package.json'); | |
const CLOUDFRONT_ID = 'YOUR_CF_ID'; | |
const S3_BUCKET_ID = 'BUCKET_NAME_IN_AWS_ACCOUNT'; | |
const walkSync = dir => { | |
let results = []; | |
fs.readdirSync(dir).forEach(function(file) { | |
const filePath = path.join(dir, file); | |
const stat = fs.statSync(filePath); | |
if (stat && stat.isDirectory()) { | |
results = results.concat(walkSync(filePath)); | |
} else { | |
results.push(filePath); | |
} | |
}); | |
return results; | |
}; | |
const build = (buildDir) => { | |
execSync(`ng build --configuration production --build-optimizer --output-path=${buildDir}`, { | |
stdio: 'inherit', | |
}); | |
}; | |
const deployVersionOnS3 = (srcDir, dstDir, bucketName) => { | |
const s3 = new AWS.S3(); | |
const filesToUpload = walkSync(srcDir); | |
return Promise.all( | |
filesToUpload.map((filePath) => { | |
return new Promise((resolve) => { | |
const bucketPath = filePath.split('\\').join('/').replace(srcDir, dstDir); | |
const params = { | |
Bucket: bucketName, | |
Key: bucketPath, | |
Body: fs.readFileSync(filePath), | |
ContentType: mime.getType(filePath), | |
// ACL: 'public-read' | |
}; | |
s3.putObject(params, (err, data) => { | |
if (err) { | |
resolve(err); | |
console.log(err); | |
} else { | |
resolve(); | |
console.log('Uploaded [' + filePath + '] => [' + bucketName + '/' + bucketPath + ']'); | |
} | |
}); | |
}); | |
}) | |
); | |
}; | |
const getCFDistribution = () => { | |
return new Promise((res, rej) => { | |
const cloudfront = new AWS.CloudFront(); | |
const params = { | |
Id: CLOUDFRONT_ID /* required */, | |
}; | |
cloudfront.getDistribution(params, function (err, data) { | |
if (!err) { | |
res(data); | |
} else { | |
rej(err); | |
} | |
}); | |
}); | |
}; | |
const updateOriginPathCF = async (OriginPath) => { | |
const { ETag, Distribution } = await getCFDistribution(); | |
return new Promise((res, rej) => { | |
Distribution.DistributionConfig.Origins.Items[0].OriginPath = OriginPath; | |
const updatedDistribution = { | |
DistributionConfig: Distribution.DistributionConfig, | |
IfMatch: ETag, | |
Id: Distribution.Id | |
} | |
const cloudfront = new AWS.CloudFront(); | |
cloudfront.updateDistribution(updatedDistribution, (err, data) => { | |
if (err) rej(err, err.stack); | |
// an error occurred | |
else res(data); // successful response | |
}); | |
}); | |
}; | |
const invalidateCloudFrontCache = () => { | |
return new Promise((res, rej) => { | |
const cloudfront = new AWS.CloudFront(); | |
const params = { | |
DistributionId: CLOUDFRONT_ID, | |
InvalidationBatch: { | |
CallerReference: Math.floor(Date.now() / 1000) + 't', | |
Paths: { | |
Quantity: 1, | |
Items: ['/*'], | |
}, | |
}, | |
}; | |
cloudfront.createInvalidation(params, (err, data) => { | |
if (err) rej(err, err.stack); | |
else res(data); | |
}); | |
}); | |
}; | |
const buildDir = `dist/prod/${version}`; | |
const destDir = `prod/${version}`; | |
const start = async () => { | |
console.log('Building...' + version); | |
build(buildDir, destDir + '/'); | |
console.log(`Deploy on S3 ${destDir}...`); | |
await deployVersionOnS3(buildDir, destDir, S3_BUCKET_ID); | |
console.log(`Switching cloudfront to new version ${destDir}`); | |
await updateOriginPathCF(`/${destDir}`); | |
console.log(`Invalidating cloudfront cache`); | |
await invalidateCloudFrontCache(); | |
console.log(`=========== VERSION ${version} successfully deplopyed online ===========`); | |
}; | |
AWS.config.loadFromPath('./ci/aws_key_s3_frontend_deploy.json'); | |
start(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment