Skip to content

Commit

Permalink
feat(jenkins): Automatically set a build description that links back …
Browse files Browse the repository at this point in the history
…to Spinnaker (spinnaker#4055)

Requires that `spinnaker.wwwHost` be set in your `orca` configuration.

```
spinnaker:
  wwwHost: https://www.spinnaker.net
```
  • Loading branch information
ajordens authored Jan 29, 2021
1 parent 7848ea6 commit 0c29cdf
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,9 @@ public List<Artifact> getArtifacts(
Integer buildNumber, String fileName, String master, String job) {
return igorService.getArtifacts(buildNumber, fileName, master, encode(job));
}

public Response updateBuild(
String master, String jobName, Integer buildNumber, IgorService.UpdatedBuild updatedBuild) {
return igorService.update(master, jobName, buildNumber, updatedBuild);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import lombok.Data;
import retrofit.client.Response;
import retrofit.http.*;

Expand All @@ -41,6 +42,13 @@ String stop(
@Path(encode = false, value = "buildNumber") Integer buildNumber,
@Body String ignored);

@PATCH("/masters/{name}/jobs/{jobName}/update/{buildNumber}")
Response update(
@Path("name") String master,
@Path(encode = false, value = "jobName") String jobName,
@Path(encode = false, value = "buildNumber") Integer buildNumber,
@Body UpdatedBuild updatedBuild);

@GET("/builds/queue/{master}/{item}")
Map queuedBuild(@Path("master") String master, @Path("item") String item);

Expand Down Expand Up @@ -113,4 +121,13 @@ Map<String, Object> getDeliveryConfigManifest(
@Query("directory") @Nullable String directory,
@Query("manifest") @Nullable String manifest,
@Query("ref") @Nullable String ref);

@Data
class UpdatedBuild {
private final String description;

public UpdatedBuild(String description) {
this.description = description;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package com.netflix.spinnaker.orca.igor.tasks

import com.netflix.spinnaker.orca.api.pipeline.models.StageExecution
import com.netflix.spinnaker.orca.igor.IgorService
import org.springframework.beans.factory.annotation.Value

import java.util.concurrent.TimeUnit
import com.netflix.spinnaker.orca.api.pipeline.models.ExecutionStatus
Expand All @@ -31,24 +33,27 @@ import retrofit.RetrofitError
@Slf4j
@Component
class MonitorQueuedJenkinsJobTask implements OverridableTimeoutRetryableTask {

long backoffPeriod = 10000
long timeout = TimeUnit.HOURS.toMillis(2)
private final BuildService buildService
private final String wwwHost

@Autowired
BuildService buildService
MonitorQueuedJenkinsJobTask(BuildService buildService, @Value("\${spinnaker.www-host}") String wwwHost) {
this.buildService = buildService
this.wwwHost = wwwHost
}

@Override
TaskResult execute(StageExecution stage) {
String master = stage.context.master
String job = stage.context.job
String jenkinsController = stage.context.master
String jobName = stage.context.job
String queuedBuild = stage.context.queuedBuild

try {
Map<String, Object> build = buildService.queuedBuild(master, queuedBuild)
Map<String, Object> build = buildService.queuedBuild(jenkinsController, queuedBuild)
if (build?.number == null) {
return TaskResult.ofStatus(ExecutionStatus.RUNNING)
} else {
updateBuildDescription(stage, jenkinsController, jobName, build.number as Integer)
return TaskResult.builder(ExecutionStatus.SUCCEEDED).context([buildNumber: build.number]).build()
}
} catch (RetrofitError e) {
Expand All @@ -59,4 +64,48 @@ class MonitorQueuedJenkinsJobTask implements OverridableTimeoutRetryableTask {
throw e
}
}

@Override
long getBackoffPeriod() {
return 10000
}

@Override
long getTimeout() {
return TimeUnit.HOURS.toMillis(2)
}

/**
* Update the description of a running Jenkins build and provide a deep link back to the particular execution in
* Spinnaker.
*
* Requires that `wwwHost` be specified _and_ that the build is running (vs. queued).
*/
private void updateBuildDescription(StageExecution stageExecution,
String jenkinsController,
String jobName,
Integer buildNumber) {
if (wwwHost == null) {
return
}

try {
buildService.updateBuild(
jenkinsController,
jobName,
buildNumber,
new IgorService.UpdatedBuild(
String.format(
"This build was triggered by '<a href=\"%s/#/applications/%s/executions/details/%s\">%s</a>' in Spinnaker.",
wwwHost,
stageExecution.execution.application,
stageExecution.execution.id,
Optional.ofNullable(stageExecution.execution.name).orElse("Unknown Pipeline")
)
)
)
} catch (Exception e) {
log.warn("Unable to update build description on {}:{}:{}", jenkinsController, jobName, buildNumber, e)
}
}
}

0 comments on commit 0c29cdf

Please sign in to comment.