From efc99a3c7c24ce6eb520a8506c8b1d8572cb9264 Mon Sep 17 00:00:00 2001 From: Mario Paulsen Date: Mon, 21 Nov 2022 16:47:33 -0300 Subject: [PATCH 1/9] Adds new param to use an existing s3 file and avoid to upload a file. --- README.md | 14 ++++ beanstalk-deploy.js | 160 ++++++++++++++++++++++++++++---------------- 2 files changed, 115 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index b10dd3b..fd5a11c 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,14 @@ the version but not deploy it anywhere. *It will prevent the action from (re)creating a bucket during deployment as well.* Omit this parameter to have the action create the bucket. The latter requires the API key used to have the applicable permissions. +`existing_file_name` *(since v21)*: Use this flag to indicate an existing file name on s3 and to avoid upload your deployment package to. +This can be set to `true`. Default is `false`. +The file to create the new version will be: +```.bash +s3:////.zip +``` + + ### AWS Permissions It should be enough for your AWS user to have the policies **AWSElasticBeanstalkWebTier** and **AWSElasticBeanstalkManagedUpdatesCustomerRolePolicy** attached @@ -111,6 +119,12 @@ defined. Pass the rest of the parameters in on the command line, like so: beanstalk-deploy.js MyApplicationName MyApplication-Environment 12345 us-west-2 deploy.zip ``` +If the file already exists in the S3 bucket: +```.bash +beanstalk-deploy true +``` +``: is going to be ignored. + Just like in the GitHub action you can skip the final file parameter and the program will attempt to deploy an existing version instead. diff --git a/beanstalk-deploy.js b/beanstalk-deploy.js index fae9a91..fdd4cf0 100755 --- a/beanstalk-deploy.js +++ b/beanstalk-deploy.js @@ -138,7 +138,7 @@ function expect(status, result, extraErrorMessage) { } //Uploads zip file, creates new version and deploys it -function deployNewVersion(application, environmentName, versionLabel, versionDescription, file, bucket, waitUntilDeploymentIsFinished, waitForRecoverySeconds) { +function deployNewVersion(application, environmentName, versionLabel, versionDescription, file, bucket, waitUntilDeploymentIsFinished, waitForRecoverySeconds, existingFileName) { //Lots of characters that will mess up an S3 filename, so only allow alphanumeric, - and _ in the actual file name. //The version label can still contain all that other stuff though. let s3filename = versionLabel.replace(/[^a-zA-Z0-9-_]/g, '-'); @@ -146,66 +146,104 @@ function deployNewVersion(application, environmentName, versionLabel, versionDes let s3Key = `/${application}/${s3filename}.zip`; let deployStart, fileBuffer; - readFile(file).then(result => { - fileBuffer = result; + if (existingFileName) { + createBeanstalkVersion(application, bucket, s3Key, versionLabel, versionDescription) + .then(result => { + expect(200, result); + console.log(`Created new application version ${versionLabel} in Beanstalk.`); + if (!environmentName) { + console.log(`No environment name given, so exiting now without deploying the new version ${versionLabel} anywhere.`); + process.exit(0); + } + deployStart = new Date(); + console.log(`Starting deployment of version ${versionLabel} to environment ${environmentName}`); + return deployBeanstalkVersion(application, environmentName, versionLabel, waitForRecoverySeconds); + }).then(result => { + expect(200, result); - if (bucket === null) { - console.log(`No existing bucket name given, creating/requesting storage location`); - return createStorageLocation(); - } - }).then(result => { - if (bucket === null) { - expect(200, result, 'Failed to create storage location'); - bucket = result.data.CreateStorageLocationResponse.CreateStorageLocationResult.S3Bucket; - } + if (waitUntilDeploymentIsFinished) { + console.log('Deployment started, "wait_for_deployment" was true...\n'); + return waitForDeployment(application, environmentName, versionLabel, deployStart, waitForRecoverySeconds); + } else { + console.log('Deployment started, parameter "wait_for_deployment" was false, so action is finished.'); + console.log('**** IMPORTANT: Please verify manually that the deployment succeeds!'); + process.exit(0); + } - console.log(`Uploading file to bucket ${bucket}`); + }).then(envAfterDeployment => { + if (envAfterDeployment.Health === 'Green') { + console.log('Environment update successful!'); + process.exit(0); + } else { + console.warn(`Environment update finished, but environment health is: ${envAfterDeployment.Health}, HealthStatus: ${envAfterDeployment.HealthStatus}`); + process.exit(1); + } + }).catch(err => { + console.error(`Deployment failed: ${err}`); + process.exit(2); + }); + } else { + readFile(file).then(result => { + fileBuffer = result; + + if (bucket === null) { + console.log(`No existing bucket name given, creating/requesting storage location`); + return createStorageLocation(); + } + }).then(result => { + if (bucket === null) { + expect(200, result, 'Failed to create storage location'); + bucket = result.data.CreateStorageLocationResponse.CreateStorageLocationResult.S3Bucket; + } - return checkIfFileExistsInS3(bucket, s3Key); - }).then(result => { - if (result.statusCode === 200) { - throw new Error(`Version ${versionLabel} already exists in S3!`); - } - expect(404, result); - return uploadFileToS3(bucket, s3Key, fileBuffer); - }).then(result => { - expect(200, result); - console.log(`New build successfully uploaded to S3, bucket=${bucket}, key=${s3Key}`); - return createBeanstalkVersion(application, bucket, s3Key, versionLabel, versionDescription); - }).then(result => { - expect(200, result); - console.log(`Created new application version ${versionLabel} in Beanstalk.`); - if (!environmentName) { - console.log(`No environment name given, so exiting now without deploying the new version ${versionLabel} anywhere.`); - process.exit(0); - } - deployStart = new Date(); - console.log(`Starting deployment of version ${versionLabel} to environment ${environmentName}`); - return deployBeanstalkVersion(application, environmentName, versionLabel, waitForRecoverySeconds); - }).then(result => { - expect(200, result); + console.log(`Uploading file to bucket ${bucket}`); - if (waitUntilDeploymentIsFinished) { - console.log('Deployment started, "wait_for_deployment" was true...\n'); - return waitForDeployment(application, environmentName, versionLabel, deployStart, waitForRecoverySeconds); - } else { - console.log('Deployment started, parameter "wait_for_deployment" was false, so action is finished.'); - console.log('**** IMPORTANT: Please verify manually that the deployment succeeds!'); - process.exit(0); - } + return checkIfFileExistsInS3(bucket, s3Key); + }).then(result => { + if (result.statusCode === 200) { + throw new Error(`Version ${versionLabel} already exists in S3!`); + } + expect(404, result); + return uploadFileToS3(bucket, s3Key, fileBuffer); + }).then(result => { + expect(200, result); + console.log(`New build successfully uploaded to S3, bucket=${bucket}, key=${s3Key}`); + return createBeanstalkVersion(application, bucket, s3Key, versionLabel, versionDescription); + }).then(result => { + expect(200, result); + console.log(`Created new application version ${versionLabel} in Beanstalk.`); + if (!environmentName) { + console.log(`No environment name given, so exiting now without deploying the new version ${versionLabel} anywhere.`); + process.exit(0); + } + deployStart = new Date(); + console.log(`Starting deployment of version ${versionLabel} to environment ${environmentName}`); + return deployBeanstalkVersion(application, environmentName, versionLabel, waitForRecoverySeconds); + }).then(result => { + expect(200, result); + + if (waitUntilDeploymentIsFinished) { + console.log('Deployment started, "wait_for_deployment" was true...\n'); + return waitForDeployment(application, environmentName, versionLabel, deployStart, waitForRecoverySeconds); + } else { + console.log('Deployment started, parameter "wait_for_deployment" was false, so action is finished.'); + console.log('**** IMPORTANT: Please verify manually that the deployment succeeds!'); + process.exit(0); + } - }).then(envAfterDeployment => { - if (envAfterDeployment.Health === 'Green') { - console.log('Environment update successful!'); - process.exit(0); - } else { - console.warn(`Environment update finished, but environment health is: ${envAfterDeployment.Health}, HealthStatus: ${envAfterDeployment.HealthStatus}`); - process.exit(1); - } - }).catch(err => { - console.error(`Deployment failed: ${err}`); - process.exit(2); - }); + }).then(envAfterDeployment => { + if (envAfterDeployment.Health === 'Green') { + console.log('Environment update successful!'); + process.exit(0); + } else { + console.warn(`Environment update finished, but environment health is: ${envAfterDeployment.Health}, HealthStatus: ${envAfterDeployment.HealthStatus}`); + process.exit(1); + } + }).catch(err => { + console.error(`Deployment failed: ${err}`); + process.exit(2); + }); + } } //Deploys existing version in EB @@ -256,7 +294,8 @@ function main() { existingBucketName = null, useExistingVersionIfAvailable, waitForRecoverySeconds = 30, - waitUntilDeploymentIsFinished = true; //Whether or not to wait for the deployment to complete... + waitUntilDeploymentIsFinished = false, //Whether or not to wait for the deployment to complete... + existingFileName; if (IS_GITHUB_ACTION) { //Running in GitHub Actions application = strip(process.env.INPUT_APPLICATION_NAME); @@ -282,6 +321,7 @@ function main() { waitForRecoverySeconds = parseInt(process.env.INPUT_WAIT_FOR_ENVIRONMENT_RECOVERY); } useExistingVersionIfAvailable = process.env.INPUT_USE_EXISTING_VERSION_IF_AVAILABLE == 'true' || process.env.INPUT_USE_EXISTING_VERSION_IF_AVAILABLE == 'True'; + existingFileName = (process.env.INPUT_EXISTING_FILE_NAME || '').toLowerCase() == 'true'; } else { //Running as command line script if (process.argv.length < 6) { @@ -293,7 +333,8 @@ function main() { process.exit(1); } - [application, environmentName, versionLabel, region, file] = process.argv.slice(2); + [application, environmentName, versionLabel, region, file, existingBucketName, existingFileName] = process.argv.slice(2); + existingFileName = (existingFileName || '').toLowerCase() == 'true'; versionDescription = ''; //Not available for this. useExistingVersionIfAvailable = false; //This option is not available in the console version @@ -336,6 +377,7 @@ function main() { console.log(' AWS Secret Key: ' + awsApiRequest.secretKey.length + ' characters long, starts with ' + awsApiRequest.secretKey.charAt(0)); console.log(' Wait for deployment: ' + waitUntilDeploymentIsFinished); console.log(' Recovery wait time: ' + waitForRecoverySeconds); + console.log(' Existing file Name: ' + existingFileName); console.log(''); getApplicationVersion(application, versionLabel).then(result => { @@ -368,7 +410,7 @@ function main() { } } else { if (file) { - deployNewVersion(application, environmentName, versionLabel, versionDescription, file, existingBucketName, waitUntilDeploymentIsFinished, waitForRecoverySeconds); + deployNewVersion(application, environmentName, versionLabel, versionDescription, file, existingBucketName, waitUntilDeploymentIsFinished, waitForRecoverySeconds, existingFileName); } else { console.error(`Deployment failed: No deployment package given but version ${versionLabel} doesn't exist, so nothing to deploy!`); process.exit(2); From 9d8a9485ffa7225ea23d0bb667c00af1892d6b33 Mon Sep 17 00:00:00 2001 From: Mario Paulsen Date: Mon, 21 Nov 2022 17:17:22 -0300 Subject: [PATCH 2/9] Updates version on README.md. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fd5a11c..8c9f341 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ the version but not deploy it anywhere. *It will prevent the action from (re)creating a bucket during deployment as well.* Omit this parameter to have the action create the bucket. The latter requires the API key used to have the applicable permissions. -`existing_file_name` *(since v21)*: Use this flag to indicate an existing file name on s3 and to avoid upload your deployment package to. +`existing_file_name` *(since v22)*: Use this flag to indicate an existing file name on s3 and to avoid upload your deployment package to. This can be set to `true`. Default is `false`. The file to create the new version will be: ```.bash From 26be6226c254862e7c140d391f8ed1e8d60dc8e9 Mon Sep 17 00:00:00 2001 From: Mario Paulsen Date: Wed, 23 Nov 2022 16:26:30 -0300 Subject: [PATCH 3/9] Accepts . character on s3 bucket file names. --- beanstalk-deploy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beanstalk-deploy.js b/beanstalk-deploy.js index fdd4cf0..8e00099 100755 --- a/beanstalk-deploy.js +++ b/beanstalk-deploy.js @@ -141,7 +141,7 @@ function expect(status, result, extraErrorMessage) { function deployNewVersion(application, environmentName, versionLabel, versionDescription, file, bucket, waitUntilDeploymentIsFinished, waitForRecoverySeconds, existingFileName) { //Lots of characters that will mess up an S3 filename, so only allow alphanumeric, - and _ in the actual file name. //The version label can still contain all that other stuff though. - let s3filename = versionLabel.replace(/[^a-zA-Z0-9-_]/g, '-'); + let s3filename = versionLabel.replace(/[^a-zA-Z0-9-_.]/g, '-'); let s3Key = `/${application}/${s3filename}.zip`; let deployStart, fileBuffer; From fa5dd6bfb267e9a16a401214c77dc4b93d7316fa Mon Sep 17 00:00:00 2001 From: Mario Paulsen Date: Wed, 23 Nov 2022 16:32:58 -0300 Subject: [PATCH 4/9] Updates version. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 805827a..ed31382 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "beanstalk-deploy", - "version": "20.0.0", + "version": "23.0.0", "description": "GitHub Action + command line tool to deploy to AWS Elastic Beanstalk.", "main": "beanstalk-deploy.js", "scripts": { From d1fe37530bfe9ba9b60513c236bba066767a66e6 Mon Sep 17 00:00:00 2001 From: Mario Paulsen Date: Mon, 5 Dec 2022 15:52:09 -0300 Subject: [PATCH 5/9] Adds 's3folder' parameter to set folder name of the deployment file. --- README.md | 6 ++++++ beanstalk-deploy.js | 10 ++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8c9f341..0dc59d6 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,12 @@ The file to create the new version will be: s3:////.zip ``` +`s3folder` *(since v24)*: Use this to set the name of the folder where the deployment package is. +The file to create the new version will be: +```.bash +s3:////.zip +``` + ### AWS Permissions diff --git a/beanstalk-deploy.js b/beanstalk-deploy.js index 8e00099..73618c2 100755 --- a/beanstalk-deploy.js +++ b/beanstalk-deploy.js @@ -138,12 +138,13 @@ function expect(status, result, extraErrorMessage) { } //Uploads zip file, creates new version and deploys it -function deployNewVersion(application, environmentName, versionLabel, versionDescription, file, bucket, waitUntilDeploymentIsFinished, waitForRecoverySeconds, existingFileName) { +function deployNewVersion(application, environmentName, versionLabel, versionDescription, file, bucket, waitUntilDeploymentIsFinished, waitForRecoverySeconds, existingFileName, s3folder) { //Lots of characters that will mess up an S3 filename, so only allow alphanumeric, - and _ in the actual file name. //The version label can still contain all that other stuff though. let s3filename = versionLabel.replace(/[^a-zA-Z0-9-_.]/g, '-'); - let s3Key = `/${application}/${s3filename}.zip`; + let s3Key = `/${s3folder || application}/${s3filename}.zip`; + let deployStart, fileBuffer; if (existingFileName) { @@ -333,7 +334,7 @@ function main() { process.exit(1); } - [application, environmentName, versionLabel, region, file, existingBucketName, existingFileName] = process.argv.slice(2); + [application, environmentName, versionLabel, region, file, existingBucketName, existingFileName, s3folder] = process.argv.slice(2); existingFileName = (existingFileName || '').toLowerCase() == 'true'; versionDescription = ''; //Not available for this. useExistingVersionIfAvailable = false; //This option is not available in the console version @@ -378,6 +379,7 @@ function main() { console.log(' Wait for deployment: ' + waitUntilDeploymentIsFinished); console.log(' Recovery wait time: ' + waitForRecoverySeconds); console.log(' Existing file Name: ' + existingFileName); + console.log(' s3 folder: ' + s3folder); console.log(''); getApplicationVersion(application, versionLabel).then(result => { @@ -410,7 +412,7 @@ function main() { } } else { if (file) { - deployNewVersion(application, environmentName, versionLabel, versionDescription, file, existingBucketName, waitUntilDeploymentIsFinished, waitForRecoverySeconds, existingFileName); + deployNewVersion(application, environmentName, versionLabel, versionDescription, file, existingBucketName, waitUntilDeploymentIsFinished, waitForRecoverySeconds, existingFileName, s3folder); } else { console.error(`Deployment failed: No deployment package given but version ${versionLabel} doesn't exist, so nothing to deploy!`); process.exit(2); From cdfd06bd086f21092118b7ff046d36f7258b0671 Mon Sep 17 00:00:00 2001 From: Mario Paulsen Date: Mon, 5 Dec 2022 16:20:40 -0300 Subject: [PATCH 6/9] Adds missing var declaration. --- README.md | 2 +- beanstalk-deploy.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0dc59d6..fa4f2e4 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ The file to create the new version will be: s3:////.zip ``` -`s3folder` *(since v24)*: Use this to set the name of the folder where the deployment package is. +`s3folder` *(since v24)*: Use this to set the name of the folder where the deployment package is. Default value is "application_name". The file to create the new version will be: ```.bash s3:////.zip diff --git a/beanstalk-deploy.js b/beanstalk-deploy.js index 73618c2..f439da9 100755 --- a/beanstalk-deploy.js +++ b/beanstalk-deploy.js @@ -296,7 +296,8 @@ function main() { useExistingVersionIfAvailable, waitForRecoverySeconds = 30, waitUntilDeploymentIsFinished = false, //Whether or not to wait for the deployment to complete... - existingFileName; + existingFileName, + s3folder; if (IS_GITHUB_ACTION) { //Running in GitHub Actions application = strip(process.env.INPUT_APPLICATION_NAME); From e6cfafb94b6635c5722faea5cb7a5de54fe528ba Mon Sep 17 00:00:00 2001 From: Mario Paulsen Date: Mon, 5 Dec 2022 16:48:10 -0300 Subject: [PATCH 7/9] Set s3folder when run gh action. --- beanstalk-deploy.js | 1 + 1 file changed, 1 insertion(+) diff --git a/beanstalk-deploy.js b/beanstalk-deploy.js index f439da9..cbe4ed5 100755 --- a/beanstalk-deploy.js +++ b/beanstalk-deploy.js @@ -324,6 +324,7 @@ function main() { } useExistingVersionIfAvailable = process.env.INPUT_USE_EXISTING_VERSION_IF_AVAILABLE == 'true' || process.env.INPUT_USE_EXISTING_VERSION_IF_AVAILABLE == 'True'; existingFileName = (process.env.INPUT_EXISTING_FILE_NAME || '').toLowerCase() == 'true'; + s3folder = process.env.INPUT_S3FOLDER; } else { //Running as command line script if (process.argv.length < 6) { From d089f76ac5f173cf3cccaf0c724666b4d37bd78c Mon Sep 17 00:00:00 2001 From: julillosamaral Date: Fri, 3 Feb 2023 17:23:11 -0300 Subject: [PATCH 8/9] Update beanstalk-deploy.js --- beanstalk-deploy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beanstalk-deploy.js b/beanstalk-deploy.js index cbe4ed5..4cc0823 100755 --- a/beanstalk-deploy.js +++ b/beanstalk-deploy.js @@ -143,7 +143,7 @@ function deployNewVersion(application, environmentName, versionLabel, versionDes //The version label can still contain all that other stuff though. let s3filename = versionLabel.replace(/[^a-zA-Z0-9-_.]/g, '-'); - let s3Key = `/${s3folder || application}/${s3filename}.zip`; + let s3Key = `/${s3folder || application}/${s3filename}.jar`; let deployStart, fileBuffer; From ef6335c349dd2d684f0ff71d7a819aee861776fd Mon Sep 17 00:00:00 2001 From: Mario Paulsen Date: Fri, 15 Mar 2024 15:00:01 -0300 Subject: [PATCH 9/9] Flag waitForDeployment, set as true by default. --- beanstalk-deploy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beanstalk-deploy.js b/beanstalk-deploy.js index 4cc0823..e96fc20 100755 --- a/beanstalk-deploy.js +++ b/beanstalk-deploy.js @@ -295,7 +295,7 @@ function main() { existingBucketName = null, useExistingVersionIfAvailable, waitForRecoverySeconds = 30, - waitUntilDeploymentIsFinished = false, //Whether or not to wait for the deployment to complete... + waitUntilDeploymentIsFinished = true, //Whether or not to wait for the deployment to complete... existingFileName, s3folder;