Skip to content

Commit

Permalink
Should make all the tests pass
Browse files Browse the repository at this point in the history
  • Loading branch information
marcingrzejszczak committed Feb 17, 2025
1 parent b5c5994 commit 2cbbd6e
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build & Deploy
name: Build

on:
push:
Expand Down
31 changes: 31 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ repositories {
group = 'io.micrometer.release'
println "I'm configuring $project.name with version $project.version"

sourceSets {
e2eTest {
java {
srcDir 'src/test/java'
include '**/*E2e*.java'
destinationDirectory = project.layout.buildDirectory.dir('classes/java/e2eTest')
}
compileClasspath = sourceSets.test.compileClasspath + sourceSets.test.output
runtimeClasspath = sourceSets.test.runtimeClasspath + sourceSets.test.output + files("${buildDir}/classes/java/e2eTest")
}

test {
java {
exclude '**/*E2e*.java'
}
}
}

dependencies {
checkstyle libs.javaFormatForPlugins

Expand Down Expand Up @@ -85,11 +103,21 @@ test {
}

tasks.register('e2e', Test) {
description = 'Runs E2E tests.'
group = 'verification'

dependsOn e2eTestClasses

testClassesDirs = sourceSets.e2eTest.output.classesDirs
classpath = sourceSets.e2eTest.runtimeClasspath

useJUnitPlatform() {
includeTags("e2e")
}
}

formatE2eTest.dependsOn("formatTest")

license {
header rootProject.file('gradle/licenseHeader.txt')
strictCheck true
Expand Down Expand Up @@ -124,12 +152,15 @@ tasks.check {

pitest {
junit5PluginVersion = libs.versions.pitestJunit5

threads = 4 // Parallel threads for mutation testing
outputFormats = ['HTML'] // Generate an HTML report
timestampedReports = false // Avoid timestamped reports for consistent file paths
testStrengthThreshold.set(90)
mutationThreshold.set(80)
setCoverageThreshold(80)

testSourceSets = [sourceSets.test] // Only use the main test source set
}

build.dependsOn("pitest")
Expand Down
57 changes: 29 additions & 28 deletions src/test/java/io/micrometer/release/common/GithubActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public interface GithubActions {
static void resetsMilestones() throws InterruptedException {
assertThat(System.getenv("GH_TOKEN")).as("GH_TOKEN env var must be set!").isNotBlank();
log.info(
"This test requires GH connection and will operate on [{}] repository. It's quite slow because it runs GH actions so please be patient...",
REPO);
"This test requires GH connection and will operate on [{}] repository. It's quite slow because it runs GH actions so please be patient...",
REPO);
resetMilestones();
}

Expand All @@ -64,7 +64,8 @@ static void runWorkflow(String workflowName, List<String> commands) {
processRunner.run(commands);
try {
waitForWorkflowCompletion(workflowName);
} catch (InterruptedException e) {
}
catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
Expand All @@ -77,19 +78,16 @@ private static void waitForWorkflowCompletion(String workflowFile) throws Interr
int maxAttempts = 30;
int attempts = 0;
while (!completed && attempts < maxAttempts) { // 5 minute timeout
List<String> status = processRunner.run("gh", "run", "list", "--workflow", workflowFile,
"--limit", "1");
log.info("Workflow [{}] not completed yet - attempt [{}]/[{}]", workflowFile,
attempts + 1, maxAttempts);
List<String> status = processRunner.run("gh", "run", "list", "--workflow", workflowFile, "--limit", "1");
log.info("Workflow [{}] not completed yet - attempt [{}]/[{}]", workflowFile, attempts + 1, maxAttempts);
completed = status.stream().anyMatch(line -> line.contains("completed"));
if (!completed) {
Thread.sleep(10_000);
attempts++;
}
}
if (!completed) {
throw new RuntimeException(
"Workflow " + workflowFile + " did not complete within timeout");
throw new RuntimeException("Workflow " + workflowFile + " did not complete within timeout");
}
log.info("Workflow [{}] completed successfully!", workflowFile);
}
Expand Down Expand Up @@ -117,35 +115,41 @@ class GithubClient {
GithubClient(String token, String repo) {
this.repo = repo;
this.processRunner = new ProcessRunner(repo).withEnvVars(
Map.of("JAVA_HOME", JavaHomeFinder.findJavaHomePath(), "GH_TOKEN",
token != null ? token : ""));
Map.of("JAVA_HOME", JavaHomeFinder.findJavaHomePath(), "GH_TOKEN", token != null ? token : ""));
this.objectMapper = new ObjectMapper().registerModule(new JavaTimeModule())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}

public Release getRelease(String tag) throws JsonProcessingException {
String output = String.join("\n",
processRunner.run("gh", "api", "/repos/" + repo + "/releases/tags/" + tag));
processRunner.run("gh", "api", "/repos/" + repo + "/releases/tags/" + tag));
return parseReleaseFromJson(output);
}

public void createReleaseAndTag(String tagName) {
log.info("Creating tag and release [{}]", tagName);

processRunner.run("gh", "release", "create", tagName, "--title", tagName.replace("v", ""), "--notes",
"Release " + tagName, "--target", "main");

log.info("Successfully created tag and release [{}]", tagName);
}

public Milestone getMilestoneByTitle(String title) throws JsonProcessingException {
String output = String.join("\n",
processRunner.run("gh", "api", "/repos/" + repo + "/milestones"));
processRunner.run("gh", "api", "/repos/" + repo + "/milestones?state=all"));
return parseMilestoneFromJson(output, title);
}

public List<Issue> getIssuesForMilestone(int milestoneNumber)
throws JsonProcessingException {
public List<Issue> getIssuesForMilestone(int milestoneNumber) throws JsonProcessingException {
String output = String.join("\n", processRunner.run("gh", "api",
"/repos/" + repo + "/issues?milestone=" + milestoneNumber));
"/repos/" + repo + "/issues?milestone=" + milestoneNumber + "&state=all"));
return parseIssuesFromJson(output);
}

public List<Issue> getClosedIssuesForMilestone(int milestoneNumber)
throws JsonProcessingException {
public List<Issue> getClosedIssuesForMilestone(int milestoneNumber) throws JsonProcessingException {
String output = String.join("\n", processRunner.run("gh", "api",
"/repos/" + repo + "/issues?milestone=" + milestoneNumber + "&state=closed"));
"/repos/" + repo + "/issues?milestone=" + milestoneNumber + "&state=closed"));
return parseIssuesFromJson(output);
}

Expand All @@ -154,17 +158,14 @@ private Release parseReleaseFromJson(String json) throws JsonProcessingException
return new Release(root.get("body").asText());
}

private Milestone parseMilestoneFromJson(String json, String title)
throws JsonProcessingException {
private Milestone parseMilestoneFromJson(String json, String title) throws JsonProcessingException {
JsonNode root = objectMapper.readTree(json);
for (JsonNode milestone : root) {
if (milestone.get("title").asText().equals(title)) {
return new Milestone(milestone.get("number").asInt(),
milestone.get("state").asText(),
milestone.get("title").asText(),
milestone.get("due_on") != null && !milestone.get("due_on").isNull()
? LocalDate.parse(milestone.get("due_on").asText().substring(0, 10))
: null);
return new Milestone(milestone.get("number").asInt(), milestone.get("state").asText(),
milestone.get("title").asText(),
milestone.get("due_on") != null && !milestone.get("due_on").isNull()
? LocalDate.parse(milestone.get("due_on").asText().substring(0, 10)) : null);
}
}
throw new RuntimeException("Milestone with title " + title + " not found");
Expand All @@ -175,7 +176,7 @@ private List<Issue> parseIssuesFromJson(String json) throws JsonProcessingExcept
List<Issue> issues = new ArrayList<>();
for (JsonNode issue : root) {
issues.add(new Issue(issue.get("number").asInt(), issue.get("state").asText(),
issue.get("title").asText()));
issue.get("title").asText()));
}
return issues;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class SingleProjectGithubActionsE2eTests implements GithubActions {

@BeforeAll
static void should_go_through_whole_flow() {
githubClient.createReleaseAndTag("v0.1.1");
runPostReleaseWorkflow();
}

Expand All @@ -41,13 +42,13 @@ void should_verify_release_notes_content() throws JsonProcessingException {
"""
## :star: New Features
- Closed enhancement in generic [#5](https://github.com/marcingrzejszczak/gh-actions-test/issues/5)
- Closed enhancement in generic 0.1.x [#8](https://github.com/marcingrzejszczak/gh-actions-test/issues/8)
- Foo [#2](https://github.com/micrometer-metrics/build-test/issues/2)
## :lady_beetle: Bug Fixes
- Closed bug in concrete [#3](https://github.com/marcingrzejszczak/gh-actions-test/issues/3)
- Closed bug in generic [#4](https://github.com/marcingrzejszczak/gh-actions-test/issues/4)
- Closed bug in concrete 0.1.1 [#12](https://github.com/marcingrzejszczak/gh-actions-test/issues/12)
- Closed bug in generic 0.1.x [#9](https://github.com/marcingrzejszczak/gh-actions-test/issues/9)
- Foo2 [#53](https://github.com/micrometer-metrics/build-test/issues/53)
## :hammer: Dependency Upgrades
Expand All @@ -71,8 +72,8 @@ void should_verify_current_milestone() throws JsonProcessingException {
List<Issue> issues = githubClient.getIssuesForMilestone(milestone.number());
assertThat(issues).extracting(Issue::state).containsOnly("closed");
assertThat(issues).extracting(Issue::title)
.containsOnly("Closed issue in generic", "Closed bug in concrete", "Closed bug in generic",
"Closed enhancement in generic");
.containsOnly("Closed issue in generic 0.1.x", "Closed bug in concrete 0.1.1",
"Closed bug in generic 0.1.x", "Closed enhancement in generic 0.1.x");
}

@Test
Expand All @@ -83,7 +84,7 @@ void should_verify_next_milestone() throws JsonProcessingException {
assertThat(milestone.dueOn()).isEqualTo(ReleaseDateCalculator.calculateDueDate(LocalDate.now()));
List<Issue> issues = githubClient.getIssuesForMilestone(milestone.number());
assertThat(issues).extracting(Issue::state).containsOnly("open");
assertThat(issues).extracting(Issue::title).containsOnly("Open issue in concrete");
assertThat(issues).extracting(Issue::title).containsOnly("Open issue in concrete 0.1.1");
}

@Test
Expand Down

0 comments on commit 2cbbd6e

Please sign in to comment.