Skip to content

Commit 5c4fa57

Browse files
authored
git-tasks: add getshortsha action to github task (#206)
1 parent db89df4 commit 5c4fa57

File tree

16 files changed

+621
-84
lines changed

16 files changed

+621
-84
lines changed

tasks/git/src/main/java/com/walmartlabs/concord/plugins/git/GitHubTask.java

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import com.fasterxml.jackson.core.type.TypeReference;
2424
import com.fasterxml.jackson.databind.ObjectMapper;
25+
import com.walmartlabs.concord.plugins.git.actions.ShortCommitShaAction;
2526
import com.walmartlabs.concord.plugins.git.model.Auth;
2627
import com.walmartlabs.concord.plugins.git.model.GitHubApiInfo;
2728
import com.walmartlabs.concord.plugins.git.tokens.AccessTokenProvider;
@@ -43,6 +44,7 @@
4344

4445
import static com.walmartlabs.concord.plugins.git.Utils.getUrl;
4546
import static com.walmartlabs.concord.sdk.MapUtils.*;
47+
import static com.walmartlabs.concord.plugins.git.VariablesGithubTaskParams.Action;
4648

4749
public class GitHubTask {
4850

@@ -107,13 +109,15 @@ public class GitHubTask {
107109
private static final TypeReference<List<Map<String, Object>>> LIST_OF_OBJECT_TYPE = new TypeReference<>() {
108110
};
109111

112+
private final UUID txId;
110113
private final boolean dryRunMode;
111114

112-
public GitHubTask() {
113-
this(false);
115+
public GitHubTask(UUID txId) {
116+
this(txId, false);
114117
}
115118

116-
public GitHubTask(boolean dryRunMode) {
119+
public GitHubTask(UUID txId, boolean dryRunMode) {
120+
this.txId = txId;
117121
this.dryRunMode = dryRunMode;
118122
}
119123

@@ -140,6 +144,8 @@ public Map<String, Object> execute(Map<String, Object> in, Map<String, Object> d
140144

141145
log.info("Starting '{}' action on API URL: {}", action, apiInfo.baseUrl());
142146

147+
var input = VariablesGithubTaskParams.merge(defaults, in);
148+
143149
return switch (action) {
144150
case CREATEPR -> createPR(in, apiInfo);
145151
case COMMENTPR -> commentPR(in, apiInfo);
@@ -166,6 +172,7 @@ public Map<String, Object> execute(Map<String, Object> in, Map<String, Object> d
166172
case CREATEHOOK -> createHook(in, apiInfo);
167173
case GETPRFILES -> getPRFiles(in, apiInfo);
168174
case CREATEAPPTOKEN -> createAppToken(apiInfo);
175+
case GETSHORTSHA -> new ShortCommitShaAction().execute(txId, apiInfo, VariablesGithubTaskParams.getShortSha(input));
169176
};
170177
}
171178

@@ -1190,32 +1197,4 @@ protected IOException createException(InputStream response, int code, String sta
11901197
}
11911198
};
11921199
}
1193-
1194-
public enum Action {
1195-
CREATEPR,
1196-
COMMENTPR,
1197-
MERGEPR,
1198-
CLOSEPR,
1199-
GETPRCOMMITLIST,
1200-
MERGE,
1201-
CREATEISSUE,
1202-
CREATETAG,
1203-
CREATEHOOK,
1204-
DELETETAG,
1205-
DELETEBRANCH,
1206-
GETCOMMIT,
1207-
ADDSTATUS,
1208-
GETSTATUSES,
1209-
FORKREPO,
1210-
GETBRANCHLIST,
1211-
GETPR,
1212-
GETPRLIST,
1213-
GETPRFILES,
1214-
GETTAGLIST,
1215-
GETLATESTSHA,
1216-
CREATEREPO,
1217-
DELETEREPO,
1218-
GETCONTENT,
1219-
CREATEAPPTOKEN
1220-
}
12211200
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.walmartlabs.concord.plugins.git;
2+
3+
/*-
4+
* *****
5+
* Concord
6+
* -----
7+
* Copyright (C) 2017 - 2025 Walmart Inc., Concord Authors
8+
* -----
9+
* Licensed under the Apache License, Version 2.0 (the "License");
10+
* you may not use this file except in compliance with the License.
11+
* You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS,
17+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* See the License for the specific language governing permissions and
19+
* limitations under the License.
20+
* =====
21+
*/
22+
23+
import com.walmartlabs.concord.plugins.git.model.GitHubApiInfo;
24+
25+
import java.util.Map;
26+
import java.util.UUID;
27+
28+
public abstract class GitHubTaskAction<T extends GitHubTaskParams> {
29+
30+
public abstract Map<String, Object> execute(UUID txId, GitHubApiInfo apiInfo, T input) throws Exception;
31+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.walmartlabs.concord.plugins.git;
2+
3+
/*-
4+
* *****
5+
* Concord
6+
* -----
7+
* Copyright (C) 2017 - 2025 Walmart Inc., Concord Authors
8+
* -----
9+
* Licensed under the Apache License, Version 2.0 (the "License");
10+
* you may not use this file except in compliance with the License.
11+
* You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS,
17+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* See the License for the specific language governing permissions and
19+
* limitations under the License.
20+
* =====
21+
*/
22+
23+
public sealed interface GitHubTaskParams {
24+
25+
record GetShortCommitSha(
26+
String org,
27+
String repo,
28+
String sha,
29+
int minLength
30+
) implements GitHubTaskParams {
31+
}
32+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package com.walmartlabs.concord.plugins.git;
2+
3+
/*-
4+
* *****
5+
* Concord
6+
* -----
7+
* Copyright (C) 2017 - 2025 Walmart Inc., Concord Authors
8+
* -----
9+
* Licensed under the Apache License, Version 2.0 (the "License");
10+
* you may not use this file except in compliance with the License.
11+
* You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS,
17+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* See the License for the specific language governing permissions and
19+
* limitations under the License.
20+
* =====
21+
*/
22+
23+
import com.walmartlabs.concord.runtime.v2.sdk.MapBackedVariables;
24+
import com.walmartlabs.concord.runtime.v2.sdk.Variables;
25+
26+
import java.util.HashMap;
27+
import java.util.Map;
28+
import java.util.Objects;
29+
import java.util.stream.Stream;
30+
31+
import static com.walmartlabs.concord.plugins.git.GitHubTaskParams.*;
32+
33+
public final class VariablesGithubTaskParams {
34+
35+
public enum Action {
36+
CREATEPR,
37+
COMMENTPR,
38+
MERGEPR,
39+
CLOSEPR,
40+
GETPRCOMMITLIST,
41+
MERGE,
42+
CREATEISSUE,
43+
CREATETAG,
44+
CREATEHOOK,
45+
DELETETAG,
46+
DELETEBRANCH,
47+
GETCOMMIT,
48+
ADDSTATUS,
49+
GETSTATUSES,
50+
FORKREPO,
51+
GETBRANCHLIST,
52+
GETPR,
53+
GETPRLIST,
54+
GETPRFILES,
55+
GETTAGLIST,
56+
GETLATESTSHA,
57+
CREATEREPO,
58+
DELETEREPO,
59+
GETCONTENT,
60+
CREATEAPPTOKEN,
61+
GETSHORTSHA
62+
}
63+
64+
public static Variables merge(Map<String, Object> taskDefaults, Map<String, Object> input) {
65+
var merged = new HashMap<String, Object>();
66+
Stream.of(taskDefaults, input)
67+
.filter(Objects::nonNull)
68+
.forEach(merged::putAll);
69+
70+
return new MapBackedVariables(merged);
71+
}
72+
73+
public static GetShortCommitSha getShortSha(Variables variables) {
74+
return new GetShortCommitSha(
75+
assertOrg(variables),
76+
assertRepo(variables),
77+
variables.assertString("sha"),
78+
variables.getInt("minLength", 7));
79+
}
80+
81+
private static String assertOrg(Variables variables) {
82+
return variables.assertString("org");
83+
}
84+
85+
private static String assertRepo(Variables variables) {
86+
return variables.assertString("repo");
87+
}
88+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package com.walmartlabs.concord.plugins.git.actions;
2+
3+
/*-
4+
* *****
5+
* Concord
6+
* -----
7+
* Copyright (C) 2017 - 2025 Walmart Inc., Concord Authors
8+
* -----
9+
* Licensed under the Apache License, Version 2.0 (the "License");
10+
* you may not use this file except in compliance with the License.
11+
* You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS,
17+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* See the License for the specific language governing permissions and
19+
* limitations under the License.
20+
* =====
21+
*/
22+
23+
import com.walmartlabs.concord.plugins.git.GitHubTaskAction;
24+
import com.walmartlabs.concord.plugins.git.GitHubTaskParams;
25+
import com.walmartlabs.concord.plugins.git.client.GitHubApiException;
26+
import com.walmartlabs.concord.plugins.git.client.GitHubClient;
27+
import com.walmartlabs.concord.plugins.git.model.GitHubApiInfo;
28+
import com.walmartlabs.concord.runtime.v2.sdk.UserDefinedException;
29+
import org.slf4j.Logger;
30+
import org.slf4j.LoggerFactory;
31+
32+
import java.util.Map;
33+
import java.util.UUID;
34+
35+
public class ShortCommitShaAction extends GitHubTaskAction<GitHubTaskParams.GetShortCommitSha> {
36+
37+
private final static Logger log = LoggerFactory.getLogger(ShortCommitShaAction.class);
38+
39+
@Override
40+
public Map<String, Object> execute(UUID txId, GitHubApiInfo apiInfo, GitHubTaskParams.GetShortCommitSha input) {
41+
int minLen = input.minLength() > 0 ? input.minLength() : 7;
42+
43+
var client = new GitHubClient(txId, apiInfo);
44+
try {
45+
var commit = getCommit(client, input.org(), input.repo(), input.sha());
46+
if (commit == null) {
47+
log.error("❌ Commit '{}' not found in '{}/{}'", input.sha(), input.org(), input.repo());
48+
throw new UserDefinedException("Commit not found in '" + input.org() + "/" + input.repo() + "'");
49+
}
50+
51+
for (int len = minLen; len <= 40; len++) {
52+
var prefix = input.sha().substring(0, len);
53+
54+
commit = getCommit(client, input.org(), input.repo(), prefix);
55+
if (commit != null && input.sha().equals(commit.get("sha"))) {
56+
57+
log.info("✅ Short SHA for '{}' commit is '{}' in '{}/{}'",
58+
input.sha(), prefix, input.org(), input.repo());
59+
60+
return Map.of("shortSha", prefix);
61+
}
62+
}
63+
64+
log.error("❌ Could not derive unique short SHA for '{}' commit in '{}/{}'",
65+
input.sha(), input.org(), input.repo());
66+
67+
throw new UserDefinedException("Could not derive unique short SHA for '" + input.sha() + "' commit");
68+
} catch (UserDefinedException e) {
69+
throw e;
70+
} catch (Exception e) {
71+
log.error("❌ Error while getting short SHA for '{}' commit in '{}/{}'",
72+
input.sha(), input.org(), input.repo(), e);
73+
74+
throw new RuntimeException("Failed to get short SHA for '" + input.sha() + "' commit: " + e.getMessage());
75+
}
76+
}
77+
78+
private static Map<String, Object> getCommit(GitHubClient client, String owner, String repo, String sha) throws Exception{
79+
try {
80+
var c = client.singleObjectResult("GET", "/repos/" + owner + "/" + repo + "/commits/" + sha, null);
81+
return c == null || c.isEmpty() ? null : c;
82+
} catch (GitHubApiException e) {
83+
if (e.getStatusCode() == 404 || e.getStatusCode() == 422) {
84+
return null;
85+
}
86+
throw e;
87+
}
88+
}
89+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.walmartlabs.concord.plugins.git.client;
2+
3+
/*-
4+
* *****
5+
* Concord
6+
* -----
7+
* Copyright (C) 2017 - 2025 Walmart Inc., Concord Authors
8+
* -----
9+
* Licensed under the Apache License, Version 2.0 (the "License");
10+
* you may not use this file except in compliance with the License.
11+
* You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS,
17+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* See the License for the specific language governing permissions and
19+
* limitations under the License.
20+
* =====
21+
*/
22+
23+
import java.io.IOException;
24+
25+
public class GitHubApiException extends IOException {
26+
27+
private final int statusCode;
28+
29+
public GitHubApiException(String message, int statusCode) {
30+
super(message);
31+
this.statusCode = statusCode;
32+
}
33+
34+
public int getStatusCode() {
35+
return statusCode;
36+
}
37+
}

0 commit comments

Comments
 (0)