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

feat(gitlab): Add Gitlab SCM integration (spinnaker/spinnaker#2047) #197

Merged
merged 3 commits into from
Dec 19, 2017

Conversation

mdirkse
Copy link
Contributor

@mdirkse mdirkse commented Nov 20, 2017

Enables Igor scm functionality for GitLab (as per spinnaker/spinnaker#2047)

import javax.validation.constraints.NotNull

/**
* Helper class to map masters in properties file into a validated property map
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this comment is a bit misleading, what is masters in this context?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More nitpick: It's not really a map, it's just a standard type-safe Spring Boot config.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the GitLab implementation is pretty similar to the GitHub one we just copied this comment from https://github.com/spinnaker/igor/blob/master/igor-web/src/main/groovy/com/netflix/spinnaker/igor/config/GitHubProperties.groovy#L27
Should we omit it?

@@ -0,0 +1,22 @@
package com.netflix.spinnaker.igor.scm.gitlab.client
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing license.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

import retrofit.http.QueryMap

/**
* Interface for interacting with a Gitab REST API
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo Gitab -> GitLab.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Contributor

@gardleopard gardleopard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution! I have made some comments on small things that needs to be fixed.

import groovy.util.logging.Slf4j

/**
* Wrapper class for a collection of GitLab clients
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this ever be a collection? It looks like a single gitlab integration can be defined in the configuration. It looks more like Wrapper for the gitlab client.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also copied from the GitHub variant.

@@ -0,0 +1,19 @@
package com.netflix.spinnaker.igor.scm.gitlab.client.model
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing license.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

@@ -0,0 +1,8 @@
package com.netflix.spinnaker.igor.scm.gitlab.client.model
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing license.

import javax.validation.constraints.NotNull

/**
* Helper class to map masters in properties file into a validated property map
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More nitpick: It's not really a map, it's just a standard type-safe Spring Boot config.

try {
commitsResponse = master.gitLabClient.getCompareCommits(projectKey, repositorySlug, [to: requestParams.from, from: requestParams.to])
} catch (RetrofitError e) {
if(e.getKind() == RetrofitError.Kind.NETWORK) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after if

} catch (RetrofitError e) {
if(e.getKind() == RetrofitError.Kind.NETWORK) {
throw new RuntimeException("Could not find the server ${master.baseUrl}")
} else if(e.response.status == 404) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after if


commitsResponse.commits.each {
def commitUrl = getCommitUrl(gitLabProperties.baseUrl, projectKey, repositorySlug, it?.id)
result << [displayId: it?.id?.substring(0,gitLabProperties.commitDisplayLength), id: it?.id, authorDisplayName: it?.author_name,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after 0,

/**
* https://docs.gitlab.com/ce/api/repositories.html#compare-branches-tags-or-commits
*/
@GET('/api/v4/projects/{projectKey}%2F{repositorySlug}/repository/compare')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't use / instead of %2F?

Copy link
Contributor

@wheleph wheleph Nov 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, because Gitlab API expects a URL-encoded project id:

id (required) - The ID or URL-encoded path of the project owned by the authenticated user

(from https://docs.gitlab.com/ce/api/repositories.html#compare-branches-tags-or-commits)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK 👍

import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonProperty
import org.joda.time.DateTime
import org.joda.time.format.ISODateTimeFormat
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would strongly consider to use Java 8 Time & Date API (JSR 310) instead of Joda Time. I think Jackson converters are already included on the class path. If not, just include compile spinnaker.dependency('jacksonJsr310') in the gradle config.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JodaTime is also used in the code that talks to BitBucket. In the interest of consistency we decided to use it here as well. Perhaps we could do a separate PR to rid the project of JodaTime al together?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with that 👍

}

String getCompareCommitsResponse() {
return '{\n' +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lwander
Copy link
Member

lwander commented Nov 30, 2017

I don't know how necessary this is with the artifact support. I'm guessing we are just relying on webhooks?

@mdirkse mdirkse force-pushed the gitlab_ci_support branch 2 times, most recently from d422c33 to ca7cdf3 Compare November 30, 2017 22:43
@mdirkse
Copy link
Contributor Author

mdirkse commented Nov 30, 2017

Alright, fixed all review remarks and redid the whole thing in Java. Which mean that I also had to port the AbstractCommitController due to compilation ordering issues. So I ended up touching some other stuff that's not strictly gitlab related.

Copy link
Contributor

@jervi jervi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fixes! I have some minor comments, primarily regarding the Java conversion. Otherwise I think it looks good, disregarding the comment from @lwander.
Lars: you mean no more native SCM integrations should be created?
Edit: I just saw the discussion on Slack #dev.

public String privateToken;

@NotNull
public Integer commitDisplayLength;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ConfigurationProperties-classes should be standard POJO's, so make these three fields private and create getters

eMap.put("displayId", "NOT_FOUND");
eMap.put("id", "NOT_FOUND");
eMap.put("authorDisplayName", "UNKNOWN");
eMap.put("timestamp", new Date(0));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use JSR310 (or Joda Time, as discussed earlier). For instance Instant.now().

private final GitLabMaster gitLabMaster;
private final GitLabProperties gitLabProperties;

public CommitController(@Autowired GitLabMaster gitLabMaster, @Autowired GitLabProperties gitLabProperties) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just put the @Autowired annotation above the constructor, and remove the ones in front of the parameters.



@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "toCommit and fromCommit parameters are required in the query string")
@InheritConstructors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@InheritConstructors is groovy-stuff, so remove it


@RequestMapping(value = "/{projectKey}/{repositorySlug}/compareCommits")
public List<Map<String, Object>> compareCommits(@PathVariable(value = "projectKey") String projectKey,
@PathVariable(value = "repositorySlug") String repositorySlug,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove the annotation parameter, Spring will default to using the parameter name as the value. E.g.: @PathVariable String projectKey

public final String message;

@JsonCreator
public Commit(@JsonProperty("id") String id,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove the annotation value for id and message, as Jackson will default to the field name. Leave it for author_name and authored_date (if you rename the fields, that is).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jackson gets confused if I remove them.

@JsonCreator
public Commit(@JsonProperty("id") String id,
@JsonProperty("author_name") String author_name,
@JsonProperty("authored_date") Date authored_date,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

camelCase

public final List<Commit> commits;

@JsonCreator
public CompareCommitsResponse(@JsonProperty("commits") List<Commit> commits) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove the annotation value

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't, Jackson gets confused if I do

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you are correct. The JavaDoc on @JsonProperty seems to suggest that it's not needed, but the documentation on @JsonCreator is quite explicit on it being needed in plain Java code.

*/
public class GitLabMaster {
public final GitLabClient gitLabClient;
public final String baseUrl;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make these private and create getters.

protected ExecutorService executor;
protected ObjectMapper objectMapper;


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove one of the blank lines


@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "toCommit and fromCommit parameters are required in the query string")
@InheritConstructors
public static class MissingParametersException extends RuntimeException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be private, it's not used anywhere else. But it might make sense to keep it public for future use though.

@mdirkse
Copy link
Contributor Author

mdirkse commented Dec 4, 2017

@jervi fixed all things that could be fixed, thanks for the review!

Copy link
Contributor

@jervi jervi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -0,0 +1,133 @@
package com.netflix.spinnaker.igor.scm.gitlab.client
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing license

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@gardleopard
Copy link
Contributor

@lwander this is useful for doing the diff calculation in the deployment stages.

@gardleopard
Copy link
Contributor

We are running this in our test environment now and our deployments still gives us the change list, so this looks all good to me.

@gardleopard
Copy link
Contributor

@tomaslin can you take a look at this?

Copy link
Contributor

@jtk54 jtk54 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.


@Bean
public GitLabMaster gitLabMasters(@Valid GitLabProperties gitLabProperties) {
log.info("bootstrapping {} as gitlab", gitLabProperties.getBaseUrl());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/as gitlab/as gitlab master.

@jeyrschabu
Copy link
Contributor

LGTM

@gardleopard gardleopard merged commit 4297671 into spinnaker:master Dec 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
7 participants