Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Commit

Permalink
feat(gitlab): Add Gitlab SCM integration (spinnaker/spinnaker#2047)
Browse files Browse the repository at this point in the history
  • Loading branch information
Maarten Dirkse committed Nov 21, 2017
1 parent 8f9504e commit 691371a
Show file tree
Hide file tree
Showing 10 changed files with 515 additions and 1 deletion.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ default may be configured using the `regexes` list.
```
github:
baseUrl: "https://api.github.com"
accessToken: '<your token>'
accessToken: '<your github token>'
commitDisplayLength: 8
stash:
Expand All @@ -73,6 +73,11 @@ bitbucket:
username: '<bitbucket username>'
password: '<bitbucket password>'
commitDisplayLength: 7
gitlab:
baseUrl: "https://gitlab.com"
privateToken: '<your gitlab token>'
commitDisplayLength: 8
```

Currently git credentials are used in Spinnaker pipelines to retrieve commit changes across different build versions.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright 2017 bol.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.netflix.spinnaker.igor.config

import com.netflix.spinnaker.igor.scm.gitlab.client.GitLabClient
import com.netflix.spinnaker.igor.scm.gitlab.client.GitLabMaster
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import retrofit.Endpoints
import retrofit.RequestInterceptor
import retrofit.RestAdapter
import retrofit.client.OkClient
import retrofit.converter.JacksonConverter

import javax.validation.Valid

@Configuration
@ConditionalOnProperty('gitlab.baseUrl')
@Slf4j
@CompileStatic
@EnableConfigurationProperties(GitLabProperties)
class GitLabConfig {
@Bean
GitLabMaster gitLabMasters(@Valid GitLabProperties gitLabProperties) {
log.info "bootstrapping ${gitLabProperties.baseUrl} as gitlab"
new GitLabMaster(gitLabClient: gitLabClient(gitLabProperties.baseUrl, gitLabProperties.privateToken), baseUrl: gitLabProperties.baseUrl)
}

GitLabClient gitLabClient(String address, String privateToken) {
new RestAdapter.Builder()
.setEndpoint(Endpoints.newFixedEndpoint(address))
.setRequestInterceptor(new PrivateTokenRequestInterceptor(privateToken))
.setClient(new OkClient())
.setConverter(new JacksonConverter())
.build()
.create(GitLabClient)
}


static class PrivateTokenRequestInterceptor implements RequestInterceptor {
private final String privateToken

PrivateTokenRequestInterceptor(String privateToken) {
this.privateToken = privateToken
}

@Override
void intercept(RequestInterceptor.RequestFacade request) {
request.addHeader("Private-Token", privateToken)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2017 bol.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.netflix.spinnaker.igor.config

import groovy.transform.CompileStatic
import org.hibernate.validator.constraints.NotEmpty
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.boot.context.properties.ConfigurationProperties

import javax.validation.constraints.NotNull

/**
* Helper class to map masters in properties file into a validated property map
*/
@ConditionalOnProperty('gitlab.baseUrl')
@CompileStatic
@ConfigurationProperties(prefix = 'gitlab')
class GitLabProperties {
@NotEmpty
String baseUrl

@NotEmpty
String privateToken

@NotNull
Integer commitDisplayLength
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2017 bol.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.netflix.spinnaker.igor.scm.gitlab

import com.netflix.spinnaker.igor.config.GitLabProperties
import com.netflix.spinnaker.igor.scm.AbstractCommitController
import com.netflix.spinnaker.igor.scm.gitlab.client.model.CompareCommitsResponse
import com.netflix.spinnaker.igor.scm.gitlab.client.GitLabMaster
import groovy.util.logging.Slf4j
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import retrofit.RetrofitError

@Slf4j
@RestController(value = "GitLabCommitController")
@ConditionalOnProperty('gitlab.baseUrl')
@RequestMapping("/gitlab")
class CommitController extends AbstractCommitController {
@Autowired
GitLabMaster master

@Autowired
GitLabProperties gitLabProperties

@RequestMapping(value = '/{projectKey}/{repositorySlug}/compareCommits')
List compareCommits(@PathVariable(value = 'projectKey') String projectKey, @PathVariable(value='repositorySlug') repositorySlug, @RequestParam Map<String, String> requestParams) {
super.compareCommits(projectKey, repositorySlug, requestParams)
CompareCommitsResponse commitsResponse
List result = []

try {
commitsResponse = master.gitLabClient.getCompareCommits(projectKey, repositorySlug, [to: requestParams.from, from: requestParams.to])
} 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) {
return getNotFoundCommitsResponse(projectKey, repositorySlug, requestParams.to, requestParams.from, master.baseUrl)
}
log.error("Unhandled error response, acting like commit response was not found", e)
return getNotFoundCommitsResponse(projectKey, repositorySlug, requestParams.to, requestParams.from, master.baseUrl)
}

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,
timestamp: it?.authored_date, message : it?.message, commitUrl: commitUrl]
}
return result
}

static String getCommitUrl(String baseUrl, String projectKey, String repositorySlug, String commitId) {
return "${baseUrl}/${projectKey}/${repositorySlug}/commit/${commitId}"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.netflix.spinnaker.igor.scm.gitlab.client

import com.netflix.spinnaker.igor.scm.gitlab.client.model.CompareCommitsResponse
import retrofit.http.GET
import retrofit.http.Path
import retrofit.http.QueryMap

/**
* Interface for interacting with a Gitab REST API
* https://docs.gitlab.com/ce/api/README.html
*/
interface GitLabClient {

/**
* https://docs.gitlab.com/ce/api/repositories.html#compare-branches-tags-or-commits
*/
@GET('/api/v4/projects/{projectKey}%2F{repositorySlug}/repository/compare')
CompareCommitsResponse getCompareCommits(
@Path('projectKey') String projectKey,
@Path('repositorySlug') String repositorySlug,
@QueryMap Map queryMap)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2017 bol.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.netflix.spinnaker.igor.scm.gitlab.client

import groovy.util.logging.Slf4j

/**
* Wrapper class for a collection of GitLab clients
*/
@Slf4j
class GitLabMaster {
GitLabClient gitLabClient
String baseUrl
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.netflix.spinnaker.igor.scm.gitlab.client.model

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

@JsonIgnoreProperties(ignoreUnknown = true)
class Commit {
String id
String author_name
Date authored_date
String message

@JsonProperty(value = "authored_date")
void setDate(String utcTimestamp) {
authored_date = DateTime.parse(utcTimestamp, ISODateTimeFormat.dateTime()).toDate()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.netflix.spinnaker.igor.scm.gitlab.client.model

import com.fasterxml.jackson.annotation.JsonIgnoreProperties

@JsonIgnoreProperties(ignoreUnknown = true)
class CompareCommitsResponse {
List<Commit> commits
}

0 comments on commit 691371a

Please sign in to comment.