Skip to content

Commit 0385b36

Browse files
committed
write commit status to gitlab
1 parent 7cefbfe commit 0385b36

File tree

10 files changed

+115
-29
lines changed

10 files changed

+115
-29
lines changed

core/src/main/java/com/flowci/core/common/domain/Variables.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,11 @@ public abstract static class Git {
148148
* Push / Tag variables
149149
*/
150150
public static final String PUSH_AUTHOR = "FLOWCI_GIT_AUTHOR";
151-
public static final String PUSH_BRANCH = "FLOWCI_GIT_BRANCH";
152151
public static final String PUSH_MESSAGE = "FLOWCI_GIT_COMMIT_MESSAGE";
153152
public static final String PUSH_COMMIT_TOTAL = "FLOWCI_GIT_COMMIT_TOTAL";
154153
public static final String PUSH_COMMIT_LIST = "FLOWCI_GIT_COMMIT_LIST"; // b64 json
155154
public static final Collection<String> PUSH_TAG_VARS = ImmutableSet.<String>builder()
156155
.add(PUSH_AUTHOR)
157-
.add(PUSH_BRANCH)
158156
.add(PUSH_MESSAGE)
159157
.add(PUSH_COMMIT_TOTAL)
160158
.add(PUSH_COMMIT_LIST)

core/src/main/java/com/flowci/core/git/client/GerritApiClient.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ public GerritApiClient(HttpClient httpClient, ObjectMapper objectMapper) {
4242
@Override
4343
public void writeCommitStatus(GitCommitStatus commit, GitConfigWithHost config) {
4444
var secret = config.getSecretObj();
45-
if (!(secret instanceof AuthSecret)) {
46-
throw new ArgumentException("AuthSecret is required for Gerrit");
47-
}
48-
4945
var changeId = CommitHelper.getChangeId(commit);
5046
if (changeId.isEmpty()) {
5147
throw new NotFoundException("Change-Id not found from commit message");

core/src/main/java/com/flowci/core/git/client/GitHubApiClient.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,6 @@ public GitHubApiClient(HttpClient httpClient, ObjectMapper objectMapper) {
4545
@Override
4646
public void writeCommitStatus(GitCommitStatus commit, GitConfig config) {
4747
var secret = config.getSecretObj();
48-
49-
if (!(secret instanceof TokenSecret)) {
50-
throw new ArgumentException("Token secret is required Github");
51-
}
52-
5348
var tokenSecret = (TokenSecret) secret;
5449
var repo = getRepo(commit);
5550

core/src/main/java/com/flowci/core/git/client/GitLabV4ApiClient.java

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,83 @@
33
import com.fasterxml.jackson.databind.ObjectMapper;
44
import com.flowci.core.git.domain.GitCommitStatus;
55
import com.flowci.core.git.domain.GitConfigWithHost;
6+
import com.flowci.core.secret.domain.AuthSecret;
67
import com.flowci.core.secret.domain.TokenSecret;
78
import com.flowci.exception.ArgumentException;
9+
import com.flowci.util.StringHelper;
10+
import com.google.common.collect.ImmutableMap;
811
import lombok.extern.log4j.Log4j2;
12+
import org.springframework.http.HttpHeaders;
13+
import org.springframework.http.HttpStatus;
14+
import org.springframework.http.MediaType;
15+
import org.springframework.web.util.UriComponentsBuilder;
916

17+
import java.net.URI;
18+
import java.net.URLEncoder;
1019
import java.net.http.HttpClient;
20+
import java.net.http.HttpRequest;
21+
import java.net.http.HttpResponse;
22+
import java.nio.charset.StandardCharsets;
23+
import java.util.Map;
1124

1225
@Log4j2
1326
public class GitLabV4ApiClient implements GitApiClient<GitConfigWithHost> {
1427

1528
private final HttpClient httpClient;
1629

17-
private final ObjectMapper objectMapper;
18-
19-
public GitLabV4ApiClient(HttpClient httpClient, ObjectMapper objectMapper) {
30+
public GitLabV4ApiClient(HttpClient httpClient) {
2031
this.httpClient = httpClient;
21-
this.objectMapper = objectMapper;
2232
}
2333

2434
@Override
2535
public void writeCommitStatus(GitCommitStatus commit, GitConfigWithHost config) {
26-
var secret = config.getSecretObj();
27-
if (!(secret instanceof TokenSecret)) {
28-
throw new ArgumentException("TokenSecret is required for Gerrit");
36+
if (!StringHelper.hasValue(commit.getRepoId())) {
37+
throw new ArgumentException("GitLab repo id is missing");
2938
}
3039

40+
var url = UriComponentsBuilder.fromHttpUrl(config.getHost())
41+
.path("/api/v4/projects/")
42+
.path(commit.getRepoId())
43+
.path("/statuses/")
44+
.path(commit.getId())
45+
.build()
46+
.toUriString();
47+
48+
var request = getRequestBuilder(url, (TokenSecret) config.getSecretObj())
49+
.POST(buildFormData(ImmutableMap.builder()
50+
.put("state", commit.getStatus())
51+
.put("ref", commit.getBranch())
52+
.put("context", "flow.ci")
53+
.put("target_url", commit.getTargetUrl())
54+
.put("description", commit.getDesc())
55+
.build()))
56+
.build();
57+
58+
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString())
59+
.thenAccept(r -> {
60+
log.info("Update commit status on {} is {}", commit.getUrl(), r.statusCode());
61+
if (r.statusCode() != HttpStatus.OK.value()) {
62+
log.debug(r.body());
63+
}
64+
});
65+
}
3166

67+
private HttpRequest.Builder getRequestBuilder(String url, TokenSecret secret) {
68+
return HttpRequest.newBuilder(URI.create(url))
69+
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
70+
.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + secret.getTokenData());
71+
}
72+
73+
public static HttpRequest.BodyPublisher buildFormData(Map<Object, Object> data) {
74+
var builder = new StringBuilder();
75+
for (Map.Entry<Object, Object> entry : data.entrySet()) {
76+
if (builder.length() > 0) {
77+
builder.append("&");
78+
}
79+
builder.append(URLEncoder.encode(entry.getKey().toString(), StandardCharsets.UTF_8));
80+
builder.append("=");
81+
builder.append(URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8));
82+
}
83+
return HttpRequest.BodyPublishers.ofString(builder.toString());
3284
}
3385
}

core/src/main/java/com/flowci/core/git/domain/GitCommitStatus.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,8 @@ public class GitCommitStatus extends GitCommit {
1212
private String targetUrl;
1313

1414
private String desc;
15+
16+
private String repoId;
17+
18+
private String branch;
1519
}

core/src/main/java/com/flowci/core/git/domain/GitPushTrigger.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public StringVars toVariableMap() {
5959
// ignore
6060
}
6161

62-
map.put(PUSH_BRANCH, ref);
62+
map.put(BRANCH, ref);
6363
map.put(PUSH_MESSAGE, message);
6464
map.put(PUSH_AUTHOR, sender.getEmail());
6565
map.put(PUSH_COMMIT_TOTAL, String.valueOf(numOfCommit));

core/src/main/java/com/flowci/core/git/service/GitConfigServiceImpl.java

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.flowci.core.git.client.GerritApiClient;
77
import com.flowci.core.git.client.GitApiClient;
88
import com.flowci.core.git.client.GitHubApiClient;
9+
import com.flowci.core.git.client.GitLabV4ApiClient;
910
import com.flowci.core.git.dao.GitConfigDao;
1011
import com.flowci.core.git.domain.GitCommitStatus;
1112
import com.flowci.core.git.domain.GitConfig;
@@ -52,6 +53,7 @@ public class GitConfigServiceImpl implements GitConfigService {
5253
public void init() {
5354
handlers.put(GitSource.GITHUB, new GitHubOperationHandler());
5455
handlers.put(GitSource.GERRIT, new GerritOperationHandler());
56+
handlers.put(GitSource.GITLAB, new GitLabOperationHandler());
5557
}
5658

5759
@Override
@@ -95,6 +97,8 @@ public void onJobFinishEvent(JobFinishedEvent event) {
9597

9698
var commit = new GitCommitStatus();
9799
commit.setId(JobContextHelper.getCommitId(job));
100+
commit.setRepoId(JobContextHelper.getRepoId(job));
101+
commit.setBranch(JobContextHelper.getGitBranch(job));
98102
commit.setMessage(JobContextHelper.getGitMessage(job));
99103
commit.setUrl(JobContextHelper.getGitUrl(job));
100104
commit.setTargetUrl(JobContextHelper.getJobUrl(job));
@@ -138,7 +142,7 @@ private class GitHubOperationHandler extends OperationHandler {
138142
private final GitApiClient<GitConfig> client = new GitHubApiClient(httpClient, objectMapper);
139143

140144
@Override
141-
public GitConfig save(GitConfig config) {
145+
GitConfig save(GitConfig config) {
142146
Secret secret = fetch(config.getSecret(), TokenSecret.class);
143147

144148
var optional = gitConfigDao.findBySource(GitSource.GITHUB);
@@ -152,7 +156,7 @@ public GitConfig save(GitConfig config) {
152156
}
153157

154158
@Override
155-
public void writeCommit(GitCommitStatus commit, GitConfig config) {
159+
void writeCommit(GitCommitStatus commit, GitConfig config) {
156160
Secret secret = fetch(config.getSecret(), TokenSecret.class);
157161
config.setSecretObj(secret);
158162
client.writeCommitStatus(commit, config);
@@ -164,7 +168,7 @@ private class GerritOperationHandler extends OperationHandler {
164168
private final GitApiClient<GitConfigWithHost> client = new GerritApiClient(httpClient, objectMapper);
165169

166170
@Override
167-
public GitConfig save(GitConfig config) {
171+
GitConfig save(GitConfig config) {
168172
var c = castConfig(config);
169173
Secret secret = fetch(config.getSecret(), AuthSecret.class);
170174

@@ -180,18 +184,46 @@ public GitConfig save(GitConfig config) {
180184
}
181185

182186
@Override
183-
public void writeCommit(GitCommitStatus commit, GitConfig config) {
187+
void writeCommit(GitCommitStatus commit, GitConfig config) {
184188
Secret secret = fetch(config.getSecret(), AuthSecret.class);
185189
config.setSecretObj(secret);
186190
client.writeCommitStatus(commit, castConfig(config));
187191
}
192+
}
193+
194+
private class GitLabOperationHandler extends OperationHandler {
195+
196+
private final GitApiClient<GitConfigWithHost> client = new GitLabV4ApiClient(httpClient);
197+
198+
@Override
199+
GitConfig save(GitConfig config) {
200+
var c = castConfig(config);
201+
Secret secret = fetch(config.getSecret(), TokenSecret.class);
188202

189-
private GitConfigWithHost castConfig(GitConfig config) {
190-
if (!(config instanceof GitConfigWithHost)) {
191-
throw new ArgumentException("GitConfigWithHost is required");
203+
var optional = gitConfigDao.findBySource(GitSource.GITLAB);
204+
if (optional.isEmpty()) {
205+
return gitConfigDao.save(c);
192206
}
193207

194-
return (GitConfigWithHost) config;
208+
var exist = (GitConfigWithHost) optional.get();
209+
exist.setSecret(secret.getName());
210+
exist.setHost(c.getHost());
211+
return gitConfigDao.save(exist);
195212
}
213+
214+
@Override
215+
void writeCommit(GitCommitStatus commit, GitConfig config) {
216+
Secret secret = fetch(config.getSecret(), TokenSecret.class);
217+
config.setSecretObj(secret);
218+
client.writeCommitStatus(commit, castConfig(config));
219+
}
220+
}
221+
222+
private static GitConfigWithHost castConfig(GitConfig config) {
223+
if (!(config instanceof GitConfigWithHost)) {
224+
throw new ArgumentException("GitConfigWithHost is required");
225+
}
226+
227+
return (GitConfigWithHost) config;
196228
}
197229
}

core/src/main/java/com/flowci/core/job/domain/JobItem.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public Context convert(org.bson.Document source) {
7474
context.putIfNotEmpty(EVENT);
7575

7676
// git push / tag
77-
context.putIfNotEmpty(PUSH_BRANCH);
77+
context.putIfNotEmpty(BRANCH);
7878
context.putIfNotEmpty(PUSH_MESSAGE);
7979
context.putIfNotEmpty(PUSH_AUTHOR);
8080
context.putIfNotEmpty(PUSH_COMMIT_LIST);

core/src/main/java/com/flowci/core/job/util/JobContextHelper.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.flowci.core.job.domain.Job;
66
import com.flowci.util.StringHelper;
77

8+
import static com.flowci.core.common.domain.Variables.Git.BRANCH;
89
import static com.flowci.core.job.domain.Job.Trigger.PUSH;
910

1011
public abstract class JobContextHelper {
@@ -96,4 +97,12 @@ public static String getGitMessage(Job job) {
9697

9798
return job.getContext().get(variable, StringHelper.EMPTY);
9899
}
100+
101+
public static String getGitBranch(Job job) {
102+
return job.getContext().get(BRANCH);
103+
}
104+
105+
public static String getRepoId(Job job) {
106+
return job.getContext().get(Variables.Git.REPO_ID, StringHelper.EMPTY);
107+
}
99108
}

core/src/test/java/com/flowci/core/test/trigger/TriggerServiceTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public void should_send_email_with_condition() throws JsonProcessingException {
9999
commits.add(GitCommit.of("1", "first message", "2021-01-01", "https://xxx.xxx/xx/1", new GitUser().setEmail("[email protected]")));
100100
commits.add(GitCommit.of("2", "second message", "2021-01-02", "https://xxx.xxx/xx/2", new GitUser().setEmail("[email protected]")));
101101

102-
context.put(Variables.Git.PUSH_BRANCH, "master");
102+
context.put(Variables.Git.BRANCH, "master");
103103
context.put(Variables.Git.PUSH_MESSAGE, "hello test");
104104
context.put(Variables.Git.PUSH_COMMIT_LIST, StringHelper.toBase64(objectMapper.writeValueAsString(commits)));
105105
context.put(Variables.Git.PUSH_COMMIT_TOTAL, String.valueOf(2));

0 commit comments

Comments
 (0)