Fix #583 : Commit status fail on push events
This commit is contained in:
parent
7063999fee
commit
8d7a8c807e
|
@ -26,6 +26,7 @@ import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
|
|||
import hudson.EnvVars;
|
||||
import hudson.model.Run;
|
||||
import hudson.model.TaskListener;
|
||||
import hudson.plugins.git.Revision;
|
||||
import hudson.plugins.git.util.Build;
|
||||
import hudson.plugins.git.util.BuildData;
|
||||
import jenkins.model.Jenkins;
|
||||
|
@ -100,64 +101,93 @@ public class CommitStatusUpdater {
|
|||
return Jenkins.getInstance().getRootUrl() + build.getUrl();
|
||||
}
|
||||
|
||||
private static List<GitLabBranchBuild> retrieveGitlabProjectIds(Run<?, ?> build, EnvVars environment) {
|
||||
LOGGER.log(Level.INFO, "Retrieving gitlab project ids");
|
||||
final List<GitLabBranchBuild> result = new ArrayList<>();
|
||||
|
||||
GitLabWebHookCause cause = build.getCause(GitLabWebHookCause.class);
|
||||
if (cause != null) {
|
||||
return Collections.singletonList(new GitLabBranchBuild(cause.getData().getSourceProjectId().toString(), cause.getData().getLastCommit()));
|
||||
}
|
||||
private static List<GitLabBranchBuild> retrieveGitlabProjectIds(Run<?, ?> build, EnvVars environment) {
|
||||
LOGGER.log(Level.INFO, "Retrieving gitlab project ids");
|
||||
final List<GitLabBranchBuild> result = new ArrayList<>();
|
||||
|
||||
final GitLabApi gitLabClient = getClient(build);
|
||||
if (gitLabClient == null) {
|
||||
LOGGER.log(Level.WARNING, "No gitlab client found.");
|
||||
return result;
|
||||
}
|
||||
GitLabWebHookCause cause = build.getCause(GitLabWebHookCause.class);
|
||||
if (cause != null) {
|
||||
return Collections.singletonList(new GitLabBranchBuild(cause.getData().getSourceProjectId().toString(),
|
||||
cause.getData().getLastCommit()));
|
||||
}
|
||||
|
||||
final SCMRevisionAction scmRevisionAction = build.getAction(SCMRevisionAction.class);
|
||||
final GitLabApi gitLabClient = getClient(build);
|
||||
if (gitLabClient == null) {
|
||||
LOGGER.log(Level.WARNING, "No gitlab client found.");
|
||||
return result;
|
||||
}
|
||||
|
||||
final SCMRevision scmRevision = scmRevisionAction.getRevision();
|
||||
final List<BuildData> buildDatas = build.getActions(BuildData.class);
|
||||
if (CollectionUtils.isEmpty(buildDatas)) {
|
||||
LOGGER.log(Level.INFO, "Build does not contain build data.");
|
||||
return result;
|
||||
}
|
||||
|
||||
String scmRevisionHash = null;
|
||||
if (scmRevision instanceof AbstractGitSCMSource.SCMRevisionImpl) {
|
||||
scmRevisionHash = ((AbstractGitSCMSource.SCMRevisionImpl) scmRevision).getHash();
|
||||
}
|
||||
|
||||
final List<BuildData> buildDatas = build.getActions(BuildData.class);
|
||||
if(CollectionUtils.isEmpty(buildDatas)) {
|
||||
LOGGER.log(Level.INFO, "Build does not contain build data.");
|
||||
return result;
|
||||
}
|
||||
if (buildDatas.size() == 1) {
|
||||
addGitLabBranchBuild(result, getBuildRevision(build), buildDatas.get(0).getRemoteUrls(), environment, gitLabClient);
|
||||
} else {
|
||||
final SCMRevisionAction scmRevisionAction = build.getAction(SCMRevisionAction.class);
|
||||
|
||||
for(final BuildData buildData : buildDatas) {
|
||||
for(final Entry<String, Build> buildByBranchName : buildData.getBuildsByBranchName().entrySet()) {
|
||||
if(buildByBranchName.getValue().getSHA1().equals(ObjectId.fromString(scmRevisionHash))) {
|
||||
final Set<String> remoteUrls = buildData.getRemoteUrls();
|
||||
for (String remoteUrl : remoteUrls) {
|
||||
try {
|
||||
LOGGER.log(Level.INFO, "Retrieving the gitlab project id from remote url {0}", remoteUrl);
|
||||
final String projectNameWithNameSpace = ProjectIdUtil.retrieveProjectId(environment.expand(remoteUrl));
|
||||
if (StringUtils.isNotBlank(projectNameWithNameSpace)) {
|
||||
String projectId = projectNameWithNameSpace;
|
||||
if (projectNameWithNameSpace.contains(".")) {
|
||||
try {
|
||||
projectId = gitLabClient.getProject(projectNameWithNameSpace).getId().toString();
|
||||
} catch (WebApplicationException | ProcessingException e) {
|
||||
LOGGER.log(Level.SEVERE, String.format("Failed to retrieve projectId for project '%s'", projectNameWithNameSpace), e);
|
||||
}
|
||||
}
|
||||
result.add(new GitLabBranchBuild(projectId, scmRevisionHash));
|
||||
}
|
||||
} catch (ProjectIdUtil.ProjectIdResolutionException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final SCMRevision scmRevision = scmRevisionAction.getRevision();
|
||||
|
||||
return result;
|
||||
}
|
||||
String scmRevisionHash = null;
|
||||
if (scmRevision instanceof AbstractGitSCMSource.SCMRevisionImpl) {
|
||||
scmRevisionHash = ((AbstractGitSCMSource.SCMRevisionImpl) scmRevision).getHash();
|
||||
}
|
||||
|
||||
for (final BuildData buildData : buildDatas) {
|
||||
for (final Entry<String, Build> buildByBranchName : buildData.getBuildsByBranchName().entrySet()) {
|
||||
if (buildByBranchName.getValue().getSHA1().equals(ObjectId.fromString(scmRevisionHash))) {
|
||||
addGitLabBranchBuild(result, scmRevisionHash, buildData.getRemoteUrls(), environment, gitLabClient);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String getBuildRevision(Run<?, ?> build) {
|
||||
GitLabWebHookCause cause = build.getCause(GitLabWebHookCause.class);
|
||||
if (cause != null) {
|
||||
return cause.getData().getLastCommit();
|
||||
}
|
||||
|
||||
BuildData action = build.getAction(BuildData.class);
|
||||
if (action == null) {
|
||||
throw new IllegalStateException("No (git-plugin) BuildData associated to current build");
|
||||
}
|
||||
Revision lastBuiltRevision = action.getLastBuiltRevision();
|
||||
|
||||
if (lastBuiltRevision == null) {
|
||||
throw new IllegalStateException("Last build has no associated commit");
|
||||
}
|
||||
|
||||
return action.getLastBuild(lastBuiltRevision.getSha1()).getMarked().getSha1String();
|
||||
}
|
||||
|
||||
private static void addGitLabBranchBuild(List<GitLabBranchBuild> result, String scmRevisionHash,
|
||||
Set<String> remoteUrls, EnvVars environment, GitLabApi gitLabClient) {
|
||||
for (String remoteUrl : remoteUrls) {
|
||||
try {
|
||||
LOGGER.log(Level.INFO, "Retrieving the gitlab project id from remote url {0}", remoteUrl);
|
||||
final String projectNameWithNameSpace = ProjectIdUtil.retrieveProjectId(environment.expand(remoteUrl));
|
||||
if (StringUtils.isNotBlank(projectNameWithNameSpace)) {
|
||||
String projectId = projectNameWithNameSpace;
|
||||
if (projectNameWithNameSpace.contains(".")) {
|
||||
try {
|
||||
projectId = gitLabClient.getProject(projectNameWithNameSpace).getId().toString();
|
||||
} catch (WebApplicationException | ProcessingException e) {
|
||||
LOGGER.log(Level.SEVERE, String.format("Failed to retrieve projectId for project '%s'",
|
||||
projectNameWithNameSpace), e);
|
||||
}
|
||||
}
|
||||
result.add(new GitLabBranchBuild(projectId, scmRevisionHash));
|
||||
}
|
||||
} catch (ProjectIdUtil.ProjectIdResolutionException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class GitLabBranchBuild {
|
||||
private final String projectId;
|
||||
|
|
|
@ -143,6 +143,20 @@ public class GitLabCommitStatusPublisherTest {
|
|||
mockServerClient.verify(requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runningWithLibrary() throws UnsupportedEncodingException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running)
|
||||
};
|
||||
AbstractBuild build = mockBuildWithLibrary(SHA1, "/build/123", GIT_LAB_CONNECTION, null, "test/project.git");
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.prebuild(build, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runningWithDotInProjectId() throws IOException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
|
@ -172,6 +186,20 @@ public class GitLabCommitStatusPublisherTest {
|
|||
mockServerClient.verify(requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canceledWithLibrary() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.canceled)
|
||||
};
|
||||
AbstractBuild build = mockBuildWithLibrary(SHA1, "/build/123", GIT_LAB_CONNECTION, Result.ABORTED, "test/project.git");
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void success() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
|
@ -186,6 +214,20 @@ public class GitLabCommitStatusPublisherTest {
|
|||
mockServerClient.verify(requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successWithLibrary() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.success)
|
||||
};
|
||||
AbstractBuild build = mockBuildWithLibrary(SHA1, "/build/123", GIT_LAB_CONNECTION, Result.SUCCESS, "test/project.git");
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failed() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
|
@ -200,6 +242,20 @@ public class GitLabCommitStatusPublisherTest {
|
|||
mockServerClient.verify(requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failedWithLibrary() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.failed)
|
||||
};
|
||||
AbstractBuild build = mockBuildWithLibrary(SHA1, "/build/123", GIT_LAB_CONNECTION, Result.FAILURE, "test/project.git");
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unstable() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
|
@ -214,6 +270,20 @@ public class GitLabCommitStatusPublisherTest {
|
|||
mockServerClient.verify(requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unstableWithLibrary() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", SHA1),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", SHA1, jenkins.getInstance().getRootUrl() + "/build/123", BuildState.failed)
|
||||
};
|
||||
AbstractBuild build = mockBuildWithLibrary(SHA1, "/build/123", GIT_LAB_CONNECTION, Result.UNSTABLE, "test/project.git");
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher("jenkins", false);
|
||||
publisher.perform(build, null, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unstableAsSuccess() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
|
@ -315,6 +385,40 @@ public class GitLabCommitStatusPublisherTest {
|
|||
}
|
||||
|
||||
private AbstractBuild mockBuild(String sha, String buildUrl, String gitLabConnection, Result result, String... remoteUrls) {
|
||||
AbstractBuild build = mock(AbstractBuild.class);
|
||||
List<BuildData> buildDatas = new ArrayList<BuildData>();
|
||||
BuildData buildData = mock(BuildData.class);
|
||||
Revision revision = mock(Revision.class);
|
||||
when(revision.getSha1String()).thenReturn(sha);
|
||||
when(buildData.getLastBuiltRevision()).thenReturn(revision);
|
||||
when(buildData.getRemoteUrls()).thenReturn(new HashSet<>(Arrays.asList(remoteUrls)));
|
||||
Build gitBuild = mock(Build.class);
|
||||
when(gitBuild.getMarked()).thenReturn(revision);
|
||||
when(buildData.getLastBuild(any(ObjectId.class))).thenReturn(gitBuild);
|
||||
buildDatas.add(buildData);
|
||||
when(build.getActions(BuildData.class)).thenReturn(buildDatas);
|
||||
when(build.getAction(BuildData.class)).thenReturn(buildData);
|
||||
when(build.getResult()).thenReturn(result);
|
||||
when(build.getUrl()).thenReturn(buildUrl);
|
||||
AbstractProject<?, ?> project = mock(AbstractProject.class);
|
||||
when(project.getProperty(GitLabConnectionProperty.class)).thenReturn(new GitLabConnectionProperty(gitLabConnection));
|
||||
when(build.getProject()).thenReturn(project);
|
||||
EnvVars environment = mock(EnvVars.class);
|
||||
when(environment.expand(anyString())).thenAnswer(new Answer<String>() {
|
||||
@Override
|
||||
public String answer(InvocationOnMock invocation) throws Throwable {
|
||||
return (String) invocation.getArguments()[0];
|
||||
}
|
||||
});
|
||||
try {
|
||||
when(build.getEnvironment(any(TaskListener.class))).thenReturn(environment);
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return build;
|
||||
}
|
||||
|
||||
private AbstractBuild mockBuildWithLibrary(String sha, String buildUrl, String gitLabConnection, Result result, String... remoteUrls) {
|
||||
AbstractBuild build = mock(AbstractBuild.class);
|
||||
List<BuildData> buildDatas = new ArrayList<BuildData>();
|
||||
BuildData buildData = mock(BuildData.class);
|
||||
|
@ -339,6 +443,17 @@ public class GitLabCommitStatusPublisherTest {
|
|||
buildsByBranchName.put("develop", gitBuild);
|
||||
when(buildData.getBuildsByBranchName()).thenReturn(buildsByBranchName);
|
||||
buildDatas.add(buildData);
|
||||
|
||||
//Second build data (@librabry)
|
||||
BuildData buildDataLib = mock(BuildData.class);
|
||||
Revision revisionLib = mock(Revision.class);
|
||||
when(revisionLib.getSha1String()).thenReturn("SHALIB");
|
||||
when(buildDataLib.getLastBuiltRevision()).thenReturn(revisionLib);
|
||||
Build gitBuildLib = mock(Build.class);
|
||||
when(gitBuildLib.getMarked()).thenReturn(revisionLib);
|
||||
when(buildDataLib.getLastBuild(any(ObjectId.class))).thenReturn(gitBuildLib);
|
||||
buildDatas.add(buildDataLib);
|
||||
|
||||
when(build.getActions(BuildData.class)).thenReturn(buildDatas);
|
||||
when(build.getResult()).thenReturn(result);
|
||||
when(build.getUrl()).thenReturn(buildUrl);
|
||||
|
@ -360,6 +475,7 @@ public class GitLabCommitStatusPublisherTest {
|
|||
}
|
||||
return build;
|
||||
}
|
||||
|
||||
private String getSingleProjectJson(String name,String projectNameWithNamespace, int porjectId) throws IOException {
|
||||
String nameSpace = projectNameWithNamespace.split("/")[0];
|
||||
String projectName = projectNameWithNamespace.split("/")[1];
|
||||
|
|
Loading…
Reference in New Issue