Commit 8b759616 authored by Greg Messner's avatar Greg Messner
Browse files

Added support for merge request approvals.

parent 133e6e17
......@@ -265,7 +265,7 @@ public class MergeRequestApi extends AbstractApi {
* @return the updated merge request
* @throws GitLabApiException if any exception occurs
*/
public MergeRequest acceptMergeRequest(Integer projectId, Integer mergeRequestId) throws GitLabApiException {
public MergeRequest cancelMergeRequest(Integer projectId, Integer mergeRequestId) throws GitLabApiException {
if (projectId == null) {
throw new RuntimeException("projectId cannot be null");
......@@ -278,4 +278,84 @@ public class MergeRequestApi extends AbstractApi {
Response response = put(Response.Status.OK, null, "projects", projectId, "merge_requests", mergeRequestId, "cancel_merge_when_pipeline_succeeds");
return (response.readEntity(MergeRequest.class));
}
/**
* Get the merge request with approval information.
*
* Note: This API endpoint is only available on 8.9 EE and above.
*
* GET /projects/:id/merge_requests/:merge_request_iid/approvals
*
* @param projectId the project ID of the merge request
* @param mergeRequestId the internal ID of the merge request
* @return a MergeRequest instance with approval information included
* @throws GitLabApiException if any exception occurs
*/
public MergeRequest getMergeRequestApprovals(Integer projectId, Integer mergeRequestId) throws GitLabApiException {
if (projectId == null) {
throw new RuntimeException("projectId cannot be null");
}
if (mergeRequestId == null) {
throw new RuntimeException("mergeRequestId cannot be null");
}
Response response = get(Response.Status.OK, null, "projects", projectId, "merge_requests", mergeRequestId, "approvals");
return (response.readEntity(MergeRequest.class));
}
/**
* Approve a merge request.
*
* Note: This API endpoint is only available on 8.9 EE and above.
*
* POST /projects/:id/merge_requests/:merge_request_iid/approve
*
* @param projectId the project ID of the merge request
* @param mergeRequestId the internal ID of the merge request
* @param sha the HEAD of the merge request, optional
* @return a MergeRequest instance with approval information included
* @throws GitLabApiException if any exception occurs
*/
public MergeRequest approveMergeRequest(Integer projectId, Integer mergeRequestId, String sha) throws GitLabApiException {
if (projectId == null) {
throw new RuntimeException("projectId cannot be null");
}
if (mergeRequestId == null) {
throw new RuntimeException("mergeRequestId cannot be null");
}
Form formData = new GitLabApiForm().withParam("sha", sha);
Response response = post(Response.Status.OK, formData, "projects", projectId, "merge_requests", mergeRequestId, "approve");
return (response.readEntity(MergeRequest.class));
}
/**
* Unapprove a merge request.
*
* Note: This API endpoint is only available on 8.9 EE and above.
*
* POST /projects/:id/merge_requests/:merge_request_iid/unapprove
*
* @param projectId the project ID of the merge request
* @param mergeRequestId the internal ID of the merge request
* @return a MergeRequest instance with approval information included
* @throws GitLabApiException if any exception occurs
*/
public MergeRequest unapproveMergeRequest(Integer projectId, Integer mergeRequestId) throws GitLabApiException {
if (projectId == null) {
throw new RuntimeException("projectId cannot be null");
}
if (mergeRequestId == null) {
throw new RuntimeException("mergeRequestId cannot be null");
}
Response response = post(Response.Status.OK, (Form)null, "projects", projectId, "merge_requests", mergeRequestId, "unapprove");
return (response.readEntity(MergeRequest.class));
}
}
......@@ -7,6 +7,11 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import org.gitlab4j.api.utils.JacksonJson;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class MergeRequest {
......@@ -43,6 +48,14 @@ public class MergeRequest {
private String webUrl;
private Boolean workInProgress;
// The approval fields will only be available when listing approvals, approving or unapproving a merge reuest.
private Integer approvalsRequired;
private Integer approvalsMissing;
@JsonSerialize(using = JacksonJson.UserListSerializer.class)
@JsonDeserialize(using = JacksonJson.UserListDeserializer.class)
private List<User> approvedBy;
public Integer getApprovalsBeforeMerge() {
return approvalsBeforeMerge;
}
......@@ -291,6 +304,72 @@ public class MergeRequest {
this.workInProgress = workInProgress;
}
/**
* Get the number of approvals required for the merge request.
*
* NOTE: This property will only be used when listing, approiving, or unapproving a merge request.
*
* @return the number of approvals required for the merge request
*/
public Integer getApprovalsRequired() {
return approvalsRequired;
}
/**
* Set the number of approvals required for the merge request.
*
* NOTE: This property will only be used when listing, approiving, or unapproving a merge request.
*
* @param approvalsRequired the number of approvals required for the merge request
*/
public void setApprovalsRequired(Integer approvalsRequired) {
this.approvalsRequired = approvalsRequired;
}
/**
* Get the number of approvals missing for the merge request.
*
* NOTE: This property will only be used when listing, approiving, or unapproving a merge request.
*
* @return the number of approvals missing for the merge request
*/
public Integer getApprovalsMissing() {
return approvalsMissing;
}
/**
* Set the number of approvals missing for the merge request.
*
* NOTE: This property will only be used when listing, approiving, or unapproving a merge request.
*
* @param approvalsMissing the number of approvals missing for the merge request
*/
public void setApprovalsMissing(Integer approvalsMissing) {
this.approvalsMissing = approvalsMissing;
}
/**
* Get the list of users that have approved the merge request.
*
* NOTE: This property will only be used when listing, approiving, or unapproving a merge request.
*
* @return the list of users that have approved the merge request
*/
public List<User> getApprovedBy() {
return approvedBy;
}
/**
* Set the list of users that have approved the merge request.
*
* NOTE: This property will only be used when listing, approiving, or unapproving a merge request.
*
* @param approvedBy the list of users that have approved the merge request
*/
public void setApprovedBy(List<User> approvedBy) {
this.approvedBy = approvedBy;
}
public static final boolean isValid(MergeRequest mergeRequest) {
return (mergeRequest != null && mergeRequest.getId() != null);
}
......
......@@ -5,7 +5,9 @@ import java.io.IOException;
import java.io.Reader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import javax.ws.rs.Produces;
......@@ -13,6 +15,8 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import org.gitlab4j.api.models.User;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
......@@ -23,6 +27,7 @@ import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
......@@ -168,4 +173,49 @@ public class JacksonJson extends JacksonJaxbJsonProvider implements ContextResol
}
}
}
}
\ No newline at end of file
/**
* Serializer for the odd User instances in the "approved_by" array in the merge_request JSON.
*/
public static class UserListSerializer extends JsonSerializer<List<User>> {
@Override
public void serialize(List<User> value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
jgen.writeStartArray();
for (User user : value) {
jgen.writeStartObject();
jgen.writeObjectField("user", user);
jgen.writeEndObject();
}
jgen.writeEndArray();
}
}
/**
* Deserializer for the odd User instances in the "approved_by" array in the merge_request JSON.
*/
public static class UserListDeserializer extends JsonDeserializer<List<User>> {
private static final ObjectMapper mapper = new JacksonJson().getObjectMapper();
@Override
public List<User> deserialize(JsonParser jsonParser, DeserializationContext context)
throws IOException, JsonProcessingException {
JsonNode tree = jsonParser.readValueAsTree();
int numUsers = tree.size();
List<User> users = new ArrayList<>(numUsers);
for (int i = 0; i < numUsers; i++) {
JsonNode node = tree.get(i);
JsonNode userNode = node.get("user");
User user = mapper.treeToValue(userNode, User.class);
users.add(user);
}
return (users);
}
}
}
......@@ -202,18 +202,18 @@ public class TestGitLabApiBeans {
e.printStackTrace();
}
}
/*
@Test
public void testMergeRequestComment() {
public void testMergeRequestApprovals() {
try {
MergeRequestComment mergeRequestComment = makeFakeApiCall(MergeRequestComment.class, "merge-request-comment");
assertTrue(compareJson(mergeRequestComment, "merge-request-comment"));
MergeRequest mergeRequestApprovals = makeFakeApiCall(MergeRequest.class, "approvals");
assertTrue(compareJson(mergeRequestApprovals, "approvals"));
} catch (Exception e) {
e.printStackTrace();
}
}
*/
@Test
public void testMergeRequest() {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment