const archiver = require('archiver'); const fs = require('fs'); const AWS = require('aws-sdk'); const mime = require('mime'); const { version } = require('../package.json'); const VERSION_FILE_NAME = `build_v${version}.zip`; const EB_S3_BUCKET = 'elasticbeanstalk___BUCKET_NAME'; const EB_APP_NAME = 'APPLICATION_NAME'; const EB_VERSION_LABEL = `api_v${version}_${Math.floor(Date.now() /1000)}`; const EN_ENV_NAME = 'ENVIRONMENT_NAAME'; let progressOutputText = ''; let throttleProgressOutput = ''; const startProgressOutput = () => { throttleProgressOutput = setInterval(() => { console.log(progressOutputText); }, 2000); }; const createApiZip = (apiPath) => { return new Promise((resolve) => { const deployZipFile = `${apiPath}/builds/${VERSION_FILE_NAME}`; if (fs.existsSync(deployZipFile)) { fs.unlinkSync(deployZipFile); } const output = fs.createWriteStream(deployZipFile); const archive = archiver('zip', { zlib: { level: 3 }, // Sets the compression level. }); // =========== ElasticBenstalk =====================================================================// archive.directory(apiPath + '/.platform', '.platform'); // ======================== APPLICATION CODE COPY ===============================================// archive.directory(apiPath + '/data', 'data'); archive.directory(apiPath + '/fixtures', 'fixtures'); archive.directory(apiPath + '/module', 'module'); archive.directory(apiPath + '/public', 'public'); archive.directory(apiPath + '/templates', 'templates'); archive.directory(apiPath + '/vendor', 'vendor'); archive.on('progress', function (obj) { progressOutputText = 'Zipping...' + obj.entries.processed + ' - ' + obj.fs.processedBytes; }); output.on('close', function () { console.log(archive.pointer() + ' total bytes'); console.log('Zip to deploy is ready.'); clearInterval(throttleProgressOutput); resolve(deployZipFile); }); archive.on('warning', function (err) { if (err.code === 'ENOENT') { // log warning } else { // throw error throw err; } }); archive.on('error', function (err) { throw err; }); archive.pipe(output); archive.finalize(); startProgressOutput(); }); }; const updateEbEnvironment = (envName, versionLabel) => { return new Promise((resolve) => { AWS.config.loadFromPath('./ci/aws_key_eb_api_deploy.json'); const elasticbeanstalk = new AWS.ElasticBeanstalk(); const params = { EnvironmentName: envName, VersionLabel: versionLabel, }; elasticbeanstalk.updateEnvironment(params, (err, data) => { if (err) { resolve(err); console.log(err); } else { resolve(); console.log(`EB Environment update started. Application will be live in a short`); } }); }); }; const createAppVersionOnElastichBeanstalk = (appName, s3Bucket, fileNameInBucket, versionLabel) => { return new Promise((resolve, reject) => { AWS.config.loadFromPath('./ci/aws_key_eb_api_deploy.json'); const elasticbeanstalk = new AWS.ElasticBeanstalk(); const params = { ApplicationName: appName, AutoCreateApplication: true, Description: 'uploaded from deploy_api script', Process: true, SourceBundle: { S3Bucket: s3Bucket, S3Key: fileNameInBucket, }, VersionLabel: versionLabel, }; elasticbeanstalk.createApplicationVersion(params, (err, data) => { if (err) { reject(err); console.log(err); } else { resolve(); console.log(`Application version created`); } }); }); }; const uploadFileOnS3 = (filePath, bucketName, fileToCopy) => { return new Promise((resolve) => { AWS.config.loadFromPath('./ci/aws_key_eb_api_deploy.json'); const s3 = new AWS.S3(); const params = { Bucket: bucketName, Key: fileToCopy, 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(`File ${fileToCopy} copied to root`); } }); }); }; const start = async () => { const apiPath = __dirname + '/../api'; console.log('Zipping PHP app: ' + apiPath); const deployZipFile = await createApiZip(apiPath); if (fs.existsSync(deployZipFile)) { console.log('Uploading on S3: ' + deployZipFile); await uploadFileOnS3(deployZipFile, EB_S3_BUCKET, VERSION_FILE_NAME); console.log('Set version on EB'); await createAppVersionOnElastichBeanstalk(EB_APP_NAME, EB_S3_BUCKET, VERSION_FILE_NAME, EB_VERSION_LABEL); console.log('Activate version on EB'); await updateEbEnvironment(EN_ENV_NAME, EB_VERSION_LABEL); } }; start();