From 81b17ee6790b5e61bdba1fd93b59b58f7a0d671a Mon Sep 17 00:00:00 2001 From: Cosmin Catalin Sanda Date: Thu, 21 May 2015 23:23:58 +0200 Subject: [PATCH 1/6] Add the posibility of zipping a specific subdirectory from the workspace --- .../codedeploy/AWSCodeDeployPublisher.java | 41 ++++++++++++++++--- .../AWSCodeDeployPublisher/config.jelly | 3 ++ .../help-subdirectory.html | 5 +++ 3 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 src/main/resources/com/amazonaws/codedeploy/AWSCodeDeployPublisher/help-subdirectory.html diff --git a/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java b/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java index 931dcc3..35e8b4e 100644 --- a/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java +++ b/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java @@ -91,6 +91,7 @@ public class AWSCodeDeployPublisher extends Publisher { private final String region; private final String includes; private final String excludes; + private final String subdirectory; private final String proxyHost; private final int proxyPort; @@ -118,7 +119,8 @@ public AWSCodeDeployPublisher( String includes, String proxyHost, int proxyPort, - String excludes) { + String excludes, + String subdirectory) { this.externalId = externalId; this.applicationName = applicationName; @@ -127,6 +129,7 @@ public AWSCodeDeployPublisher( this.region = region; this.includes = includes; this.excludes = excludes; + this.subdirectory = subdirectory; this.proxyHost = proxyHost; this.proxyPort = proxyPort; this.credentials = credentials; @@ -205,7 +208,7 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListener lis verifyCodeDeployApplication(aws); String projectName = build.getProject().getName(); - RevisionLocation revisionLocation = zipAndUpload(aws, projectName, build.getWorkspace()); + RevisionLocation revisionLocation = zipAndUpload(aws, projectName, getSourceDirectory(build.getWorkspace())); registerRevision(aws, revisionLocation); String deploymentId = createDeployment(aws, revisionLocation); @@ -224,6 +227,30 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListener lis return success; } + private FilePath getSourceDirectory(FilePath basePath) throws IOException, InterruptedException { + String subdirectory = this.subdirectory.trim().length() > 0 ? this.subdirectory.trim() : ""; + if (!subdirectory.isEmpty() && !subdirectory.startsWith("/")) { + subdirectory = "/" + subdirectory; + } + FilePath sourcePath = basePath.withSuffix(subdirectory).absolutize(); + File sourceDirectory = new File(sourcePath.getRemote()); + if (!sourceDirectory.isDirectory() || !isSubDirectory(basePath, sourcePath)) { + throw new IllegalArgumentException("Provided path is not a subdirectory of the workspace: " + sourcePath ); + } + return sourcePath; + } + + private boolean isSubDirectory(FilePath parent, FilePath child) { + FilePath parentFolder = child; + while (parentFolder!=null) { + if (parent.equals(parentFolder)) { + return true; + } + parentFolder = child.getParent(); + } + return false; + } + private void verifyCodeDeployApplication(AWSClients aws) throws IllegalArgumentException { // Check that the application exists ListApplicationsResult applications = aws.codedeploy.listApplications(); @@ -243,12 +270,12 @@ private void verifyCodeDeployApplication(AWSClients aws) throws IllegalArgumentE } } - private RevisionLocation zipAndUpload(AWSClients aws, String projectName, FilePath workspace) throws IOException, InterruptedException { + private RevisionLocation zipAndUpload(AWSClients aws, String projectName, FilePath sourceDirectory) throws IOException, InterruptedException { File zipFile = File.createTempFile(projectName + "-", ".zip"); - this.logger.println("Zipping workspace into " + zipFile.getAbsolutePath()); + this.logger.println("Zipping files into " + zipFile.getAbsolutePath()); - workspace.zip( + sourceDirectory.zip( new FileOutputStream(zipFile), new DirScanner.Glob(this.includes, this.excludes) ); @@ -583,6 +610,10 @@ public String getExcludes() { return excludes; } + public String getSubdirectory() { + return subdirectory; + } + public String getRegion() { return region; } diff --git a/src/main/resources/com/amazonaws/codedeploy/AWSCodeDeployPublisher/config.jelly b/src/main/resources/com/amazonaws/codedeploy/AWSCodeDeployPublisher/config.jelly index 04c860a..a1a69af 100644 --- a/src/main/resources/com/amazonaws/codedeploy/AWSCodeDeployPublisher/config.jelly +++ b/src/main/resources/com/amazonaws/codedeploy/AWSCodeDeployPublisher/config.jelly @@ -17,6 +17,9 @@ + + + diff --git a/src/main/resources/com/amazonaws/codedeploy/AWSCodeDeployPublisher/help-subdirectory.html b/src/main/resources/com/amazonaws/codedeploy/AWSCodeDeployPublisher/help-subdirectory.html new file mode 100644 index 0000000..c148bed --- /dev/null +++ b/src/main/resources/com/amazonaws/codedeploy/AWSCodeDeployPublisher/help-subdirectory.html @@ -0,0 +1,5 @@ +
+ A subdirectory inside the workspace to be packed instead of the whole workspace. Remember that the + appspec.yml must be placed at the top of the .zip archive. The excludes and includes will + be applied based on this path. +
From 6ce4bf39c44e0305974b2a2fa08abffd2e6b4586 Mon Sep 17 00:00:00 2001 From: Anthony Johnson Date: Thu, 30 Apr 2015 00:09:54 -0400 Subject: [PATCH 2/6] cleanup zip file after uploaded to S3 --- .../codedeploy/AWSCodeDeployPublisher.java | 67 ++++++++++--------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java b/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java index 35e8b4e..a4373fd 100644 --- a/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java +++ b/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java @@ -1,12 +1,12 @@ /* * Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * + * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at - * + * * http://aws.amazon.com/apache2.0 - * + * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing @@ -181,8 +181,8 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListener lis if ("awsAccessKey".equals(credentials)) { if (StringUtils.isEmpty(this.awsAccessKey) && StringUtils.isEmpty(this.awsSecretKey)) { aws = AWSClients.fromDefaultCredentialChain( - this.region, - this.proxyHost, + this.region, + this.proxyHost, this.proxyPort); } else { aws = AWSClients.fromBasicCredentials( @@ -273,40 +273,45 @@ private void verifyCodeDeployApplication(AWSClients aws) throws IllegalArgumentE private RevisionLocation zipAndUpload(AWSClients aws, String projectName, FilePath sourceDirectory) throws IOException, InterruptedException { File zipFile = File.createTempFile(projectName + "-", ".zip"); - this.logger.println("Zipping files into " + zipFile.getAbsolutePath()); + String key; - sourceDirectory.zip( - new FileOutputStream(zipFile), - new DirScanner.Glob(this.includes, this.excludes) - ); + try { - String key; - if (this.s3prefix.isEmpty()) { - key = zipFile.getName(); - } else { - key = this.s3prefix; - if (this.s3prefix.endsWith("/")) { - key += zipFile.getName(); + this.logger.println("Zipping workspace into " + zipFile.getAbsolutePath()); + sourceDirectory.zip( + new FileOutputStream(zipFile), + new DirScanner.Glob(this.includes, this.excludes) + ); + + if (this.s3prefix.isEmpty()) { + key = zipFile.getName(); } else { - key += "/" + zipFile.getName(); + key = this.s3prefix; + if (this.s3prefix.endsWith("/")) { + key += zipFile.getName(); + } else { + key += "/" + zipFile.getName(); + } } - } - logger.println("Uploading zip to s3://" + this.s3bucket + "/" + key); - PutObjectResult s3result = aws.s3.putObject(this.s3bucket, key, zipFile); + logger.println("Uploading zip to s3://" + this.s3bucket + "/" + key); + PutObjectResult s3result = aws.s3.putObject(this.s3bucket, key, zipFile); - S3Location s3Location = new S3Location(); - s3Location.setBucket(this.s3bucket); - s3Location.setKey(key); - s3Location.setBundleType(BundleType.Zip); - s3Location.setETag(s3result.getETag()); + S3Location s3Location = new S3Location(); + s3Location.setBucket(this.s3bucket); + s3Location.setKey(key); + s3Location.setBundleType(BundleType.Zip); + s3Location.setETag(s3result.getETag()); - RevisionLocation revisionLocation = new RevisionLocation(); - revisionLocation.setRevisionType(RevisionLocationType.S3); - revisionLocation.setS3Location(s3Location); + RevisionLocation revisionLocation = new RevisionLocation(); + revisionLocation.setRevisionType(RevisionLocationType.S3); + revisionLocation.setS3Location(s3Location); - return revisionLocation; + return revisionLocation; + } finally { + zipFile.delete(); + } } private void registerRevision(AWSClients aws, RevisionLocation revisionLocation) { @@ -440,7 +445,7 @@ public FormValidation doCheckName(@QueryParameter String value) } public boolean isApplicable(Class aClass) { - // Indicates that this builder can be used with all kinds of project types + // Indicates that this builder can be used with all kinds of project types return true; } From b9a70de79144172780adc69644a68b042d1b488a Mon Sep 17 00:00:00 2001 From: Anthony Johnson Date: Thu, 30 Apr 2015 00:13:38 -0400 Subject: [PATCH 3/6] Exchange tabs for spaces --- .../com/amazonaws/codedeploy/AWSCodeDeployPublisher.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java b/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java index a4373fd..f16c999 100644 --- a/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java +++ b/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java @@ -304,11 +304,11 @@ private RevisionLocation zipAndUpload(AWSClients aws, String projectName, FilePa s3Location.setBundleType(BundleType.Zip); s3Location.setETag(s3result.getETag()); - RevisionLocation revisionLocation = new RevisionLocation(); - revisionLocation.setRevisionType(RevisionLocationType.S3); - revisionLocation.setS3Location(s3Location); + RevisionLocation revisionLocation = new RevisionLocation(); + revisionLocation.setRevisionType(RevisionLocationType.S3); + revisionLocation.setS3Location(s3Location); - return revisionLocation; + return revisionLocation; } finally { zipFile.delete(); } From 500773df7cbbe5a246759ce55624f425eb589869 Mon Sep 17 00:00:00 2001 From: Cosmin Catalin Sanda Date: Thu, 21 May 2015 23:42:15 +0200 Subject: [PATCH 4/6] Remove the default slash from the S3 Prefix --- .../amazonaws/codedeploy/AWSCodeDeployPublisher/config.jelly | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/com/amazonaws/codedeploy/AWSCodeDeployPublisher/config.jelly b/src/main/resources/com/amazonaws/codedeploy/AWSCodeDeployPublisher/config.jelly index a1a69af..0bdd542 100644 --- a/src/main/resources/com/amazonaws/codedeploy/AWSCodeDeployPublisher/config.jelly +++ b/src/main/resources/com/amazonaws/codedeploy/AWSCodeDeployPublisher/config.jelly @@ -15,7 +15,7 @@ - + From c28c3989df0cb9eb03f15625aadf6da48d67d84a Mon Sep 17 00:00:00 2001 From: hollowdrutt Date: Tue, 2 Jun 2015 16:21:56 +0200 Subject: [PATCH 5/6] Add support for Ireland and Sydney Code Deploy --- .../java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java b/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java index f16c999..f9c9e9d 100644 --- a/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java +++ b/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java @@ -76,7 +76,7 @@ public class AWSCodeDeployPublisher extends Publisher { public static final long DEFAULT_TIMEOUT_SECONDS = 900; public static final long DEFAULT_POLLING_FREQUENCY_SECONDS = 15; public static final String ROLE_SESSION_NAME = "jenkins-codedeploy-plugin"; - public static final Regions[] AVAILABLE_REGIONS = {Regions.US_EAST_1, Regions.US_WEST_2}; + public static final Regions[] AVAILABLE_REGIONS = {Regions.AP_SOUTHEAST_2, Regions.EU_WEST_1, Regions.US_EAST_1, Regions.US_WEST_2}; private final String s3bucket; private final String s3prefix; From aea35877fcd23f3b7e2cd2e5f972541d942f2708 Mon Sep 17 00:00:00 2001 From: Cosmin Catalin Sanda Date: Thu, 21 May 2015 23:23:58 +0200 Subject: [PATCH 6/6] Add the posibility of zipping a specific subdirectory from the workspace --- .../java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java b/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java index f9c9e9d..b89153f 100644 --- a/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java +++ b/src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java @@ -276,8 +276,8 @@ private RevisionLocation zipAndUpload(AWSClients aws, String projectName, FilePa String key; try { + this.logger.println("Zipping files into " + zipFile.getAbsolutePath()); - this.logger.println("Zipping workspace into " + zipFile.getAbsolutePath()); sourceDirectory.zip( new FileOutputStream(zipFile), new DirScanner.Glob(this.includes, this.excludes)