Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support deployment of same artifact to multiple group of an application #93

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 89 additions & 53 deletions src/main/java/com/amazonaws/codedeploy/AWSCodeDeployPublisher.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
import java.util.Date;
import java.util.Map;
import java.util.UUID;
import java.util.List;
import java.util.ArrayList;

import javax.annotation.Nonnull;
import javax.servlet.ServletException;
Expand Down Expand Up @@ -249,9 +251,9 @@ public void perform(@Nonnull Run<?,?> build, @Nonnull FilePath workspace, @Nonnu
success = true;
} else {

String deploymentId = createDeployment(aws, revisionLocation);
List<String> deploymentIds = createDeployment(aws, revisionLocation);

success = waitForDeployment(aws, deploymentId);
success = waitForDeployment(aws, deploymentIds);
}

} catch (Exception e) {
Expand Down Expand Up @@ -300,15 +302,37 @@ private void verifyCodeDeployApplication(AWSClients aws) throws IllegalArgumentE
throw new IllegalArgumentException("Cannot find application named '" + applicationName + "'");
}

// Check that the deployment group exists
ListDeploymentGroupsResult deploymentGroups = aws.codedeploy.listDeploymentGroups(
List<String> matchingGroups = getMatchingDeploymentGroup(aws, deploymentGroupName);

if (matchingGroups.isEmpty()) {
throw new IllegalArgumentException("Cannot find deployment group matching with '" + deploymentGroupName + "'");
}
}

private List<String> getMatchingDeploymentGroup(AWSClients aws, String deploymentGroupName) {
List<String> matchingGroups = new ArrayList<String>();
List<String> deploymentGroups = aws.codedeploy.listDeploymentGroups(
new ListDeploymentGroupsRequest()
.withApplicationName(applicationName)
);

if (!deploymentGroups.getDeploymentGroups().contains(deploymentGroupName)) {
throw new IllegalArgumentException("Cannot find deployment group named '" + deploymentGroupName + "'");
).getDeploymentGroups();
// all groups under application
if(deploymentGroupName.equals("*")) {
return deploymentGroups;
}
// Groups starting with specific word
if(deploymentGroupName.endsWith("*")) {
deploymentGroupName = deploymentGroupName.replace("*", "$");
}
// Groups ending with specific word
if(deploymentGroupName.startsWith("*")) {
deploymentGroupName = deploymentGroupName.replace("*", "^");
}
for(String eachGroupName : deploymentGroups) {
if(eachGroupName.matches(deploymentGroupName)) {
matchingGroups.add(eachGroupName);
}
}
return matchingGroups;
}

private RevisionLocation zipAndUpload(AWSClients aws, String projectName, FilePath sourceDirectory) throws IOException, InterruptedException, IllegalArgumentException {
Expand Down Expand Up @@ -435,73 +459,85 @@ private void registerRevision(AWSClients aws, RevisionLocation revisionLocation)
);
}

private String createDeployment(AWSClients aws, RevisionLocation revisionLocation) throws Exception {
private List<String> createDeployment(AWSClients aws, RevisionLocation revisionLocation) throws Exception {

this.logger.println("Creating deployment with revision at " + revisionLocation);
String deploymentGroupName = getDeploymentGroupNameFromEnv();
List<String> deploymnetIds = new ArrayList<String>();

List<String> deploymentGroups = getMatchingDeploymentGroup(aws, deploymentGroupName);

for(String eachGroup : deploymentGroups) {
CreateDeploymentResult createDeploymentResult = aws.codedeploy.createDeployment(
new CreateDeploymentRequest()
.withDeploymentConfigName(getDeploymentConfigFromEnv())
.withDeploymentGroupName(eachGroup)
.withApplicationName(getApplicationNameFromEnv())
.withRevision(revisionLocation)
.withDescription("Deployment created by Jenkins")
);
deploymnetIds.add(createDeploymentResult.getDeploymentId());
}

CreateDeploymentResult createDeploymentResult = aws.codedeploy.createDeployment(
new CreateDeploymentRequest()
.withDeploymentConfigName(getDeploymentConfigFromEnv())
.withDeploymentGroupName(getDeploymentGroupNameFromEnv())
.withApplicationName(getApplicationNameFromEnv())
.withRevision(revisionLocation)
.withDescription("Deployment created by Jenkins")
);

return createDeploymentResult.getDeploymentId();
return deploymnetIds;
}

private boolean waitForDeployment(AWSClients aws, String deploymentId) throws InterruptedException {
private boolean waitForDeployment(AWSClients aws, List<String> deploymentIds) throws InterruptedException {

if (!this.waitForCompletion) {
return true;
}

logger.println("Monitoring deployment with ID " + deploymentId + "...");
GetDeploymentRequest deployInfoRequest = new GetDeploymentRequest();
deployInfoRequest.setDeploymentId(deploymentId);
boolean success = true;

DeploymentInfo deployStatus = aws.codedeploy.getDeployment(deployInfoRequest).getDeploymentInfo();
for(String eachDeploymentId : deploymentIds) {
logger.println("Monitoring deployment with ID " + eachDeploymentId + "...");
GetDeploymentRequest deployInfoRequest = new GetDeploymentRequest();
deployInfoRequest.setDeploymentId(eachDeploymentId);

long startTimeMillis;
if (deployStatus == null || deployStatus.getStartTime() == null) {
startTimeMillis = new Date().getTime();
} else {
startTimeMillis = deployStatus.getStartTime().getTime();
}
DeploymentInfo deployStatus = aws.codedeploy.getDeployment(deployInfoRequest).getDeploymentInfo();

boolean success = true;
long pollingTimeoutMillis = this.pollingTimeoutSec * 1000L;
long pollingFreqMillis = this.pollingFreqSec * 1000L;
long startTimeMillis;
if (deployStatus == null || deployStatus.getStartTime() == null) {
startTimeMillis = new Date().getTime();
} else {
startTimeMillis = deployStatus.getStartTime().getTime();
}

while (deployStatus == null || deployStatus.getCompleteTime() == null) {
long pollingTimeoutMillis = this.pollingTimeoutSec * 1000L;
long pollingFreqMillis = this.pollingFreqSec * 1000L;

if (deployStatus == null) {
logger.println("Deployment status: unknown.");
} else {
DeploymentOverview overview = deployStatus.getDeploymentOverview();
logger.println("Deployment status: " + deployStatus.getStatus() + "; instances: " + overview);
while (deployStatus == null || deployStatus.getCompleteTime() == null) {

if (deployStatus == null) {
logger.println("Deployment status: unknown.");
} else {
DeploymentOverview overview = deployStatus.getDeploymentOverview();
logger.println("Deployment status: " + deployStatus.getStatus() + "; instances: " + overview);
}

deployStatus = aws.codedeploy.getDeployment(deployInfoRequest).getDeploymentInfo();
Date now = new Date();

if (now.getTime() - startTimeMillis >= pollingTimeoutMillis) {
this.logger.println("Exceeded maximum polling time of " + pollingTimeoutMillis + " milliseconds.");
success = false;
break;
}

Thread.sleep(pollingFreqMillis);
}

deployStatus = aws.codedeploy.getDeployment(deployInfoRequest).getDeploymentInfo();
Date now = new Date();
logger.println("Deployment status: " + deployStatus.getStatus() + "; instances: " + deployStatus.getDeploymentOverview());

if (now.getTime() - startTimeMillis >= pollingTimeoutMillis) {
this.logger.println("Exceeded maximum polling time of " + pollingTimeoutMillis + " milliseconds.");
if (!deployStatus.getStatus().equals(DeploymentStatus.Succeeded.toString())) {
this.logger.println("Deployment did not succeed. Final status: " + deployStatus.getStatus());
success = false;
}
if(!success){
break;
}

Thread.sleep(pollingFreqMillis);
}

logger.println("Deployment status: " + deployStatus.getStatus() + "; instances: " + deployStatus.getDeploymentOverview());

if (!deployStatus.getStatus().equals(DeploymentStatus.Succeeded.toString())) {
this.logger.println("Deployment did not succeed. Final status: " + deployStatus.getStatus());
success = false;
}

return success;
}

Expand Down