Skip to content

Commit

Permalink
"!label" and "!action"; paths instead of path
Browse files Browse the repository at this point in the history
  • Loading branch information
ebullient committed Feb 6, 2024
1 parent 386ec5d commit f6d6d93
Show file tree
Hide file tree
Showing 13 changed files with 1,234 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,6 @@ public Response execRepoQuerySync(String query, Map<String, Object> variables) {
public Collection<DataLabel> getCachedLabels(String itemId) {
@SuppressWarnings("unchecked")
Set<DataLabel> labels = QueryHelper.QueryCache.LABELS.getCachedValue(itemId, Set.class);

if (labels != null) {
return labels;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ public Action deserialize(JsonParser jp, DeserializationContext ctxt) throws IOE
return labelsAction;
} else if (root.has("address")) {
return mapper.convertValue(root, EmailAction.class);
} else if (root.has("repo")) {
return mapper.convertValue(root, DispatchAction.class);
} else if (root.has("channel")) {
return mapper.convertValue(root, DiscordAction.class);
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@

import org.commonhaus.automation.github.QueryHelper.QueryContext;

import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

@JsonDeserialize(as = DispatchAction.class)
public class DispatchAction extends Action {
String repo;
@JsonDeserialize(as = DiscordAction.class)
public class DiscordAction extends Action {

@JsonAlias("name")
String workflowName;
String channel;

@Override
public void apply(QueryContext queryContext) {

// TODO: stuff
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

@JsonDeserialize(as = EmailAction.class)
public class EmailAction extends Action {

String address;
String template;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,35 @@
package org.commonhaus.automation.github.rules;

import java.util.ArrayList;
import java.util.List;

import org.commonhaus.automation.github.EventData;
import org.commonhaus.automation.github.QueryHelper.QueryContext;

public class MatchAction {

public List<String> actions;
public List<String> include = new ArrayList<>(1);
public List<String> exclude = new ArrayList<>(1);

public MatchAction(List<String> actions) {
actions.forEach(x -> {
if (x.startsWith("!")) {
exclude.add(x.substring(1));
} else {
include.add(x);
}
});
}

public boolean matches(QueryContext queryContext) {
EventData eventData = queryContext.getEventData();
if (eventData == null) {
return false;
}
return actions.stream().anyMatch(x -> x.equalsIgnoreCase(eventData.getAction()));
String action = eventData.getAction();
if (!exclude.isEmpty() && exclude.stream().anyMatch(x -> x.equalsIgnoreCase(action))) {
return false;
}
return include.isEmpty() || include.stream().anyMatch(x -> x.equalsIgnoreCase(action));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.commonhaus.automation.github.rules;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

Expand All @@ -8,7 +9,19 @@
import org.commonhaus.automation.github.model.DataLabel;

public class MatchLabel {
List<String> labels;

public List<String> include = new ArrayList<>(1);
public List<String> exclude = new ArrayList<>(1);

public MatchLabel(List<String> actions) {
actions.forEach(x -> {
if (x.startsWith("!")) {
exclude.add(x.substring(1));
} else {
include.add(x);
}
});
}

public boolean matches(QueryContext queryContext) {
EventData eventData = queryContext.getEventData();
Expand All @@ -22,6 +35,9 @@ public boolean matches(QueryContext queryContext) {
return false;
}

return eventLabels.stream().anyMatch(x -> labels.contains(x.name) || labels.contains(x.id));
if (!exclude.isEmpty() && eventLabels.stream().anyMatch(x -> exclude.contains(x.name) || exclude.contains(x.id))) {
return false;
}
return include.isEmpty() || eventLabels.stream().anyMatch(x -> include.contains(x.name) || include.contains(x.id));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
/**
* Only applies to GitHub Pull Requests
*/
public class MatchFilePath {
public class MatchPaths {
List<String> paths;

public boolean matches(QueryContext queryContext) {
Expand All @@ -35,7 +35,6 @@ public boolean matches(QueryContext queryContext) {
if (prFiles != null) {
for (GHPullRequestFileDetail changedFile : prFiles) {
for (String p : paths) {

if (!p.contains("*")) {
if (changedFile.getFilename().startsWith(p)) {
return true;
Expand Down
52 changes: 36 additions & 16 deletions src/main/java/org/commonhaus/automation/github/rules/Rule.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class Rule {

MatchAction action;
MatchCategory category;
MatchFilePath path;
MatchPaths paths;
MatchLabel label;

public List<String> then;
Expand All @@ -31,8 +31,8 @@ public boolean matches(QueryContext queryContext) {
if (matches && category != null) {
matches &= category.matches(queryContext);
}
if (matches && path != null) {
matches &= path.matches(queryContext);
if (matches && paths != null) {
matches &= paths.matches(queryContext);
}
if (matches && label != null) {
matches &= label.matches(queryContext);
Expand All @@ -56,26 +56,46 @@ public Rule deserialize(com.fasterxml.jackson.core.JsonParser p,
ObjectMapper mapper = (ObjectMapper) p.getCodec();
JsonNode node = mapper.readTree(p);
Rule rule = new Rule();
if (node.has("action")) {
rule.action = new MatchAction();
rule.action.actions = mapper.convertValue(node.get("action"), LIST_STRING);
if (RuleType.action.existsIn(node)) {
rule.action = new MatchAction(mapper.convertValue(RuleType.action.getFrom(node), LIST_STRING));
}
if (node.has("category")) {
if (RuleType.category.existsIn(node)) {
rule.category = new MatchCategory();
rule.category.category = mapper.convertValue(node.get("category"), LIST_STRING);
rule.category.category = mapper.convertValue(RuleType.category.getFrom(node), LIST_STRING);
}
if (node.has("label")) {
rule.label = new MatchLabel();
rule.label.labels = mapper.convertValue(node.get("label"), LIST_STRING);
if (RuleType.label.existsIn(node)) {
rule.label = new MatchLabel(mapper.convertValue(RuleType.label.getFrom(node), LIST_STRING));
}
if (node.has("path")) {
rule.path = new MatchFilePath();
rule.path.paths = mapper.convertValue(node.get("path"), LIST_STRING);
if (RuleType.paths.existsIn(node)) {
rule.paths = new MatchPaths();
rule.paths.paths = mapper.convertValue(RuleType.paths.getFrom(node), LIST_STRING);
}
if (node.has("then")) {
rule.then = mapper.convertValue(node.get("then"), LIST_STRING);
if (RuleType.then.existsIn(node)) {
rule.then = mapper.convertValue(RuleType.then.getFrom(node), LIST_STRING);
}
return rule;
}
}

enum RuleType {
action,
category,
label,
paths,
then;

boolean existsIn(JsonNode source) {
if (source == null) {
return false;
}
return source.has(this.name());
}

JsonNode getFrom(JsonNode source) {
if (source == null) {
return null;
}
return source.get(this.name());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
@GitHubAppTest
public class NotifyLabelsTest {
final String repoFullName = "commonhaus/automation-test";
final String repositoryId = "R_kgDOLDuJqg";
final long repoId = 742099370;
final long installationId = 46053716;
static final DataLabel bug = new DataLabel.Builder().name("bug").id("LA_kwDOLDuJqs8AAAABfqsdNQ").build();
Expand All @@ -62,16 +63,17 @@ Response mockResponse(Path filename) {
@BeforeEach
void beforeEach() {
QueryHelper.QueryCache.LABELS.invalidateAll();
verifyNoLabelCache(repositoryId);
}

@Test
void discussionCreated() throws Exception {
// When a general, not-interesting, discussion is created,
// - labels are still fetched (label rule)
// - no other rules or actions are triggered
// - no rules or actions are triggered

// from src/test/resources/github/eventDiscussionCreated.json
String discussionId = "D_kwDOLDuJqs4AXaZU";
verifyNoLabelCache(discussionId);

Response noLabels = mockResponse(Path.of("src/test/resources/github/queryLabelEmpty.json"));
given()
Expand All @@ -98,11 +100,10 @@ void discussionCreatedAnnouncements() throws Exception {
// When a discussion is created in announcements
// - labels are fetched (label rule)
// - the notice label is added
// - email is sent
// - a workflow is dispatched

// from src/test/resources/github/eventDiscussionCreatedAnnouncements.json
String discussionId = "D_kwDOLDuJqs4AXaZM";
verifyNoLabelCache(discussionId);

Response repoLabels = mockResponse(Path.of("src/test/resources/github/queryRepositoryLabelsNotice.json"));
Response noLabels = mockResponse(Path.of("src/test/resources/github/queryLabelEmpty.json"));
Expand Down Expand Up @@ -136,7 +137,6 @@ void discussionCreatedReviewsLabeled() throws Exception {

// from src/test/resources/github/eventDiscussionCreatedReviewsLabel.json
String discussionId = "D_kwDOLDuJqs4AXaZQ";
String repositoryId = "R_kgDOLDuJqg";

// preload the cache: no request to fetch repo labels (and check our work)
Set<DataLabel> existing = new HashSet<>();
Expand Down Expand Up @@ -196,6 +196,7 @@ void discussionUnlabeledUnknown() throws Exception {
// When a discussion is unlabeled, ...
// from src/test/resources/github/eventDiscussionUnlabeled.json
String discussionId = "D_kwDOLDuJqs4AXNhB";
verifyNoLabelCache(discussionId);

given()
.github(mocks -> {
Expand All @@ -209,8 +210,7 @@ void discussionUnlabeledUnknown() throws Exception {
verifyNoMoreInteractions(mocks.ghObjects());
});

Assertions.assertNull(QueryHelper.QueryCache.LABELS.getCachedValue(discussionId, Set.class),
"Discussion labels cache should not exist");
verifyNoLabelCache(discussionId);
}

@Test
Expand Down Expand Up @@ -243,8 +243,9 @@ void discussionUnlabeled() throws Exception {
@Test
void testRelevantPr() throws Exception {
String prNodeId = "PR_kwDOLDuJqs5lPq17";
long id = 1698606459;
verifyNoLabelCache(prNodeId);

long id = 1698606459;
Response repoLabels = mockResponse(Path.of("src/test/resources/github/queryRepositoryLabelsNotice.json"));
Response bugLabel = mockResponse(Path.of("src/test/resources/github/queryLabelBug.json"));
Response modifiedLabel = mockResponse(Path.of("src/test/resources/github/addLabelsToLabelableResponse.json"));
Expand Down Expand Up @@ -299,6 +300,11 @@ public void testLabelChanged() throws Exception {
verifyLabelCache(repoId, 2, List.of("bug", "notice"));
}

private void verifyNoLabelCache(String labelId) {
Assertions.assertNull(QueryHelper.QueryCache.LABELS.getCachedValue(labelId, Set.class),
"Label cache for " + labelId + " should not exist");
}

private void verifyLabelCache(String labeledId, int size, List<String> expectedLabels) {
@SuppressWarnings("unchecked")
Set<DataLabel> labels = QueryHelper.QueryCache.LABELS.getCachedValue(labeledId, Set.class);
Expand Down
Loading

0 comments on commit f6d6d93

Please sign in to comment.