-
Notifications
You must be signed in to change notification settings - Fork 657
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
Conversation
afce9c3
to
3bdfdb3
Compare
b7a6862
to
488e571
Compare
769e9dc
to
691371a
Compare
import javax.validation.constraints.NotNull | ||
|
||
/** | ||
* Helper class to map masters in properties file into a validated property map |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing license.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo Gitab -> GitLab
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
There was a problem hiding this 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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing license.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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') |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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' + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Groovy has multiline support. See http://groovy-lang.org/syntax.html#_triple_single_quoted_string
I don't know how necessary this is with the artifact support. I'm guessing we are just relying on webhooks? |
d422c33
to
ca7cdf3
Compare
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. |
There was a problem hiding this 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; |
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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; | ||
|
||
|
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
ca7cdf3
to
7878b21
Compare
@jervi fixed all things that could be fixed, thanks for the review! |
There was a problem hiding this 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing license
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@lwander this is useful for doing the diff calculation in the deployment stages. |
7878b21
to
37fff8c
Compare
37fff8c
to
a2840ff
Compare
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. |
@tomaslin can you take a look at this? |
There was a problem hiding this 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()); |
There was a problem hiding this comment.
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.
LGTM |
Enables Igor scm functionality for GitLab (as per spinnaker/spinnaker#2047)