Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 55 additions & 1 deletion src/main/java/com/ververica/Core.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ public class Core implements AutoCloseable {
"ci_(?<" + REGEX_GROUP_PULL_REQUEST_ID + ">[0-9]+)_(?<" + REGEX_GROUP_COMMIT_HASH + ">[0-9a-f]+)", Pattern.DOTALL);

private static final String REGEX_GROUP_COMMAND = "command";
private static final Pattern REGEX_PATTERN_COMMAND_MENTION = Pattern.compile("@flinkbot run (?<" + REGEX_GROUP_COMMAND + ">[\\w ]+)", Pattern.CASE_INSENSITIVE);

private static final Pattern REGEX_PATTERN_COMMAND_MENTION = Pattern.compile("@flinkbot run (?<" + REGEX_GROUP_COMMAND + ">[\\w .#]+)", Pattern.CASE_INSENSITIVE);
private static final DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

private final String observedRepository;
Expand Down Expand Up @@ -427,9 +427,11 @@ private Optional<Build> runManualBuild(Trigger trigger, CiReport ciReport) {
final String[] command = trigger.getCommand().get().split(" ");

final AzureCommand azureCommand = new AzureCommand();
final TestCommand testCommand = new TestCommand();

JCommander jCommander = new JCommander();
jCommander.addCommand(azureCommand);
jCommander.addCommand(testCommand);

try {
jCommander.parse(command);
Expand All @@ -441,6 +443,9 @@ private Optional<Build> runManualBuild(Trigger trigger, CiReport ciReport) {
switch (jCommander.getParsedCommand()) {
case AzureCommand.COMMAND_NAME:
return runManualBuild(CiProvider.Azure, ciReport, trigger, azureCommand.args);
case TestCommand.COMMAND_NAME:
runTestBuild(CiProvider.Azure, ciReport, testCommand.testPattern);
return Optional.empty();
default:
throw new RuntimeException("Unhandled valid command " + Arrays.toString(command) + " .");
}
Expand Down Expand Up @@ -480,6 +485,48 @@ private Optional<Build> runManualBuild(CiProvider ciProvider, CiReport ciReport,
return Optional.empty();
}

private void runTestBuild(
CiProvider ciProvider,
CiReport ciReport,
String testPattern) {
Optional<Build> lastBuildOptional = ciReport.getBuilds()
.filter(build -> build.status.map(s -> s.getCiProvider() == ciProvider).orElse(false))
.reduce((first, second) -> second);
if (!lastBuildOptional.isPresent()) {
LOG.debug("Ignoring {} run command since no build was triggered yet.", ciProvider.getName());
} else {
Build lastBuild = lastBuildOptional.get();
if (!lastBuild.status.isPresent()) {
LOG.debug("Ignoring {} run command since no build was triggered yet.", ciProvider.getName());
} else {
GitHubCheckerStatus gitHubCheckerStatus = lastBuild.status.get();

final Optional<String> buildUrl = ciActions.getActionsForProvider(gitHubCheckerStatus.getCiProvider())
.flatMap(ciAction -> ciAction.buildTest(
gitHubCheckerStatus.getDetailsUrl(),
lastBuild.commitHash,
testPattern)
);
buildUrl.ifPresent(
url -> {
try {
final int pullRequestID = lastBuild.pullRequestID;
LOG.debug(
"Submitting new test run comment for pull request {}",
formatPullRequestID(pullRequestID));
gitHubActions.submitComment(
observedRepository,
pullRequestID,
String.format("Submitted test run for pattern %s: %s", testPattern, url));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
);
}
}
}

public void mirrorPullRequest(int pullRequestID) throws GitException {
if (pendingMirrors.getIfPresent(pullRequestID) != null) {
LOG.debug("Ignoring mirroring for {} due to being cached.", formatPullRequestID(pullRequestID));
Expand Down Expand Up @@ -537,4 +584,11 @@ private static final class AzureCommand {
@Parameter
private List<String> args = Collections.emptyList();
}

@Parameters(commandNames = TestCommand.COMMAND_NAME)
private static final class TestCommand {
static final String COMMAND_NAME = "test";
@Parameter
private String testPattern = null;
}
}
3 changes: 2 additions & 1 deletion src/main/java/com/ververica/ci/CiActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import com.ververica.github.GitHubCheckerStatus;

import java.util.List;
import java.util.Optional;

public interface CiActions extends AutoCloseable {
Expand All @@ -31,6 +30,8 @@ public interface CiActions extends AutoCloseable {

void retryBuild(String detailsUrl, String branch);

Optional<String> buildTest(String detailsUrl, String branch, String testPattern);

default boolean supportsDirectBuildStatusRetrieval() {
return false;
}
Expand Down
42 changes: 41 additions & 1 deletion src/main/java/com/ververica/ci/azure/AzureActionsImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
import java.util.Optional;
Expand Down Expand Up @@ -131,6 +130,47 @@ public void retryBuild(String detailsUrl, String branch) {
RequestBody.create(MediaType.get("application/json"), "{}"));
}

@Override
public Optional<String> buildTest(String detailsUrl, String commitId, String testPattern) {
LOG.debug("Triggering build for test {}.", testPattern);

final String projectSlug = extractProjectSlug(detailsUrl);
final String buildId = extractBuildId(detailsUrl);

Optional<Integer> definitionId = getDefinitionId(projectSlug, buildId);
if (!definitionId.isPresent()) {
LOG.error("Failed to trigger build; could not retrieve definition id.");
return Optional.empty();
}
return submitRequest(
"https://dev.azure.com/" + projectSlug + "/_apis/pipelines/" + definitionId.get() +
"/runs?api-version=6.0-preview.1",
"POST",
RequestBody.create(
MediaType.get("application/json"),
"{" +
"\"stagesToSkip\":[]," +
"\"resources\":" +
"{\"repositories\":" +
"{\"self\":" +
"{\"version\":\"" + commitId + "\"}}}," +
"\"variables\":" +
"{\"MODE\":{\"value\":\"single-test\",\"isSecret\":false}," +
"\"TEST_PATTERN\":{\"value\":\"" + testPattern + "\",\"isSecret\":false}}}"))
.flatMap(
response -> {
try {
final JsonNode json = OBJECT_MAPPER.readTree(response);
final String url = json.get("_links").get("web").get("href").asText();
LOG.debug("Running tests for {} with pattern {}: {}", commitId, testPattern, url);
return Optional.ofNullable(url);
} catch (IOException e) {
return Optional.empty();
}
}
);
}

@Override
public boolean supportsDirectBuildStatusRetrieval() {
return true;
Expand Down