Skip to content

Commit

Permalink
Lookup previous build using build id and re-use any parameters (#236)
Browse files Browse the repository at this point in the history
  • Loading branch information
acormier1 committed Feb 15, 2022
1 parent 3d152cf commit c686ef4
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
Expand All @@ -22,10 +24,13 @@
import org.jenkinsci.plugins.github.extension.GHEventsSubscriber;
import org.jenkinsci.plugins.github.extension.GHSubscriberEvent;
import hudson.Extension;
import hudson.model.Action;
import hudson.model.Cause;
import hudson.model.CauseAction;
import hudson.model.Item;
import hudson.model.Job;
import hudson.model.ParametersAction;
import hudson.model.Run;
import hudson.security.ACL;
import hudson.security.ACLContext;
import jenkins.model.ParameterizedJobMixIn;
Expand Down Expand Up @@ -78,14 +83,14 @@ protected void onEvent(final GHSubscriberEvent event) {
final String payload = event.getPayload();
try {
GHEventPayload.CheckRun checkRun = GitHub.offline().parseEventPayload(new StringReader(payload), GHEventPayload.CheckRun.class);
JSONObject payloadJSON = new JSONObject(payload);

if (!RERUN_ACTION.equals(checkRun.getAction())) {
LOGGER.log(Level.FINE,
"Unsupported check run action: " + checkRun.getAction().replaceAll("[\r\n]", ""));
return;
}

JSONObject payloadJSON = new JSONObject(payload);

LOGGER.log(Level.INFO, "Received rerun request through GitHub checks API.");
try (ACLContext ignored = ACL.as(ACL.SYSTEM)) {
String branchName = payloadJSON.getJSONObject("check_run").getJSONObject("check_suite").optString("head_branch");
Expand All @@ -100,18 +105,29 @@ protected void onEvent(final GHSubscriberEvent event) {
private void scheduleRerun(final GHEventPayload.CheckRun checkRun, final String branchName) {
final GHRepository repository = checkRun.getRepository();

Optional<Job<?, ?>> optionalJob = jenkinsFacade.getJob(checkRun.getCheckRun().getExternalId());
if (optionalJob.isPresent()) {
Job<?, ?> job = optionalJob.get();
Optional<Run<?, ?>> optionalRun = jenkinsFacade.getBuild(checkRun.getCheckRun().getExternalId());
if (optionalRun.isPresent()) {
Run<?, ?> run = optionalRun.get();
Job<?, ?> job = run.getParent();

Cause cause = new GitHubChecksRerunActionCause(checkRun.getSender().getLogin(), branchName);
ParameterizedJobMixIn.scheduleBuild2(job, 0, new CauseAction(cause));

List<Action> actions = new ArrayList<>();
actions.add(new CauseAction(cause));

ParametersAction paramAction = run.getAction(ParametersAction.class);
if (paramAction != null) {
actions.add(paramAction);
}

ParameterizedJobMixIn.scheduleBuild2(job, 0, actions.toArray(new Action[0]));

LOGGER.log(Level.INFO, String.format("Scheduled rerun (build #%d) for job %s, requested by %s",
job.getNextBuildNumber(), jenkinsFacade.getFullNameOf(job),
checkRun.getSender().getLogin()).replaceAll("[\r\n]", ""));
}
else {
LOGGER.log(Level.WARNING, String.format("No job found for rerun request from repository: %s and job: %s",
LOGGER.log(Level.WARNING, String.format("No build found for rerun request from repository: %s and id: %s",
repository.getFullName(), checkRun.getCheckRun().getExternalId()).replaceAll("[\r\n]", ""));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,13 @@ GHCheckRunBuilder getCreator(final GitHub gitHub, final GitHubChecksDetails deta
private GHCheckRunBuilder applyDetails(final GHCheckRunBuilder builder, final GitHubChecksDetails details) {
builder
.withStatus(details.getStatus())
.withExternalID(context.getJob().getFullName())
.withDetailsURL(details.getDetailsURL().orElse(context.getURL()));

if (context.getRun().isPresent()) {
final String externalId = context.getRun().get().getExternalizableId();
builder.withExternalID(externalId);
}

if (details.getConclusion().isPresent()) {
builder.withConclusion(details.getConclusion().get())
.withCompletedAt(details.getCompletedAt().orElse(Date.from(Instant.now())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Optional;
import java.util.logging.Level;

Expand Down Expand Up @@ -101,12 +100,17 @@ void shouldIgnoreCheckRunEventWithoutRerequestedAction() throws IOException {

@Test
void shouldScheduleRerunForPR() throws IOException {
Job<?, ?> job = mock(Job.class);
Job job = mock(Job.class);
Run run = mock(Run.class);
JenkinsFacade jenkinsFacade = mock(JenkinsFacade.class);
SCMFacade scmFacade = mock(SCMFacade.class);

when(jenkinsFacade.getJob("XiongKezhi/codingstyle/PR-1")).thenReturn(Optional.of(job));
when(jenkinsFacade.getBuild("codingstyle/PR-1#2")).thenReturn(Optional.of(run));
when(jenkinsFacade.getFullNameOf(job)).thenReturn("codingstyle/PR-1");
when(run.getParent()).thenReturn(job);
when(run.getAction(ParametersAction.class)).thenReturn(
new ParametersAction(new StringParameterValue("test_key", "test_value"))
);
when(job.getNextBuildNumber()).thenReturn(1);
when(job.getName()).thenReturn("PR-1");

Expand All @@ -119,12 +123,15 @@ void shouldScheduleRerunForPR() throws IOException {

@Test
void shouldScheduleRerunForMaster() throws IOException {
Job<?, ?> job = mock(Job.class);
Job job = mock(Job.class);
Run run = mock(Run.class);
JenkinsFacade jenkinsFacade = mock(JenkinsFacade.class);
SCMFacade scmFacade = mock(SCMFacade.class);

when(jenkinsFacade.getJob("XiongKezhi/codingstyle/master")).thenReturn(Optional.of(job));
when(jenkinsFacade.getBuild("codingstyle/master#8")).thenReturn(Optional.of(run));
when(jenkinsFacade.getFullNameOf(job)).thenReturn("codingstyle/master");
when(run.getParent()).thenReturn(job);
when(run.getAction(ParametersAction.class)).thenReturn(null);
when(job.getNextBuildNumber()).thenReturn(1);
when(job.getName()).thenReturn("master");

Expand All @@ -136,9 +143,9 @@ void shouldScheduleRerunForMaster() throws IOException {
}

@Test
void shouldNotScheduleRerunWhenNoProperJobFound() throws IOException {
void shouldNotScheduleRerunWhenNoProperBuildFound() throws IOException {
JenkinsFacade jenkinsFacade = mock(JenkinsFacade.class);
when(jenkinsFacade.getAllJobs()).thenReturn(Collections.emptyList());
when(jenkinsFacade.getBuild("codingstyle/PR-1#2")).thenReturn(Optional.empty());

assertNoBuildIsScheduled(jenkinsFacade, mock(SCMFacade.class),
createEventWithRerunRequest(RERUN_REQUEST_JSON_FOR_PR));
Expand All @@ -165,7 +172,7 @@ private void assertNoBuildIsScheduled(final JenkinsFacade jenkinsFacade, final S
loggerRule.record(CheckRunGHEventSubscriber.class.getName(), Level.WARNING).capture(1);
new CheckRunGHEventSubscriber(jenkinsFacade, scmFacade).onEvent(event);
assertThat(loggerRule.getMessages())
.contains("No job found for rerun request from repository: XiongKezhi/codingstyle and job: XiongKezhi/codingstyle/PR-1");
.contains("No build found for rerun request from repository: XiongKezhi/codingstyle and id: codingstyle/PR-1#2");
}

private GHSubscriberEvent createEventWithRerunRequest(final String jsonFile) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"id": 993663296,
"node_id": "MDg6Q2hlY2tSdW45OTM2NjMyOTY=",
"head_sha": "b22fdfec1127073e509224a99a7704eeebdebe11",
"external_id": "XiongKezhi/codingstyle/master",
"external_id": "codingstyle/master#8",
"url": "https://api.github.com/repos/XiongKezhi/codingstyle/check-runs/993663296",
"html_url": "https://github.com/XiongKezhi/codingstyle/runs/993663296",
"details_url": "http://127.0.0.1:8080/job/free-coding-style/8/display/redirect",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"id": 993923912,
"node_id": "MDg6Q2hlY2tSdW45OTM5MjM5MTI=",
"head_sha": "3c0ea12c02129ff4919afe087616d84547d93539",
"external_id": "XiongKezhi/codingstyle/PR-1",
"external_id": "codingstyle/PR-1#2",
"url": "https://api.github.com/repos/XiongKezhi/codingstyle/check-runs/993923912",
"html_url": "https://github.com/XiongKezhi/codingstyle/runs/993923912",
"details_url": "http://127.0.0.1:8080/job/pipeline-coding-style/job/PR-1/2/display/redirect",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"id": 993923912,
"node_id": "MDg6Q2hlY2tSdW45OTM5MjM5MTI=",
"head_sha": "3c0ea12c02129ff4919afe087616d84547d93539",
"external_id": "XiongKezhi/codingstyle/PR-1",
"external_id": "codingstyle/PR-1#2",
"url": "https://api.github.com/repos/XiongKezhi/codingstyle/check-runs/993923912",
"html_url": "https://github.com/XiongKezhi/codingstyle/runs/993923912",
"details_url": "http://127.0.0.1:8080/job/pipeline-coding-style/job/PR-1/2/display/redirect",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"id": 993923912,
"node_id": "MDg6Q2hlY2tSdW45OTM5MjM5MTI=",
"head_sha": "3c0ea12c02129ff4919afe087616d84547d93539",
"external_id": "XiongKezhi/codingstyle/PR-1",
"external_id": "codingstyle/PR-1#2",
"url": "https://api.github.com/repos/XiongKezhi/codingstyle/check-runs/993923912",
"html_url": "https://github.com/XiongKezhi/codingstyle/runs/993923912",
"details_url": "http://127.0.0.1:8080/job/pipeline-coding-style/job/PR-1/2/display/redirect",
Expand Down

0 comments on commit c686ef4

Please sign in to comment.