Skip to content

Commit 2fe791b

Browse files
Should work with train versions
1 parent 98c512b commit 2fe791b

24 files changed

+724
-202
lines changed

.github/workflows/train-release-workflow.yml

+16-6
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,22 @@ name: Release Train (for a single project)
33
on:
44
workflow_dispatch:
55
inputs:
6-
train_versions:
7-
description: "Comma separated list of versions (e.g. 1.13.2,1.14.8,1.15.9-M2)"
8-
required: true
9-
artifact_to_check:
10-
description: "What's the artifact id (io.micrometer:artifactId) to check in Maven Central if the sync after the release was successful (e.g. micrometer-bom)"
11-
required: true
6+
context_propagation_versions:
7+
description: "[TRAIN] Comma separated list of context propagation versions (e.g. 1.0.0,1.1.0,1.1.0)"
8+
required: false
9+
default: ""
10+
micrometer_versions:
11+
description: "[TRAIN] Comma separated list of micrometer versions (e.g. 1.13.2,1.14.8,1.15.9)"
12+
required: false
13+
default: ""
14+
tracing_versions:
15+
description: "[TRAIN] Comma separated list of micrometer tracing versions (e.g. 1.5.0,1.6.0,1.7.0)"
16+
required: false
17+
default: ""
18+
docs_gen_versions:
19+
description: "[TRAIN] Comma separated list of micrometer docs generator versions (e.g. 1.0.0,1.1.0,1.2.0)"
20+
required: false
21+
default: ""
1222

1323
jobs:
1424
post_release:

action.yml

+16-6
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,20 @@ inputs:
1818
description: "[SINGLE PROJECT] Previous release version in this train (e.g.v1.14.8)"
1919
required: false
2020
default: ""
21-
train_versions:
22-
description: "[TRAIN] Comma separated list of versions (e.g. 1.13.2,1.14.8,1.15.9)"
21+
context_propagation_versions:
22+
description: "[TRAIN] Comma separated list of context propagation versions (e.g. 1.0.0,1.1.0,1.1.0)"
2323
required: false
2424
default: ""
25-
artifact_to_check:
26-
description: "[TRAIN] What's the artifact id (io.micrometer:artifactId) to check in Maven Central if the sync after the release was successful (e.g. micrometer-bom)"
25+
micrometer_versions:
26+
description: "[TRAIN] Comma separated list of micrometer versions (e.g. 1.13.2,1.14.8,1.15.9)"
27+
required: false
28+
default: ""
29+
tracing_versions:
30+
description: "[TRAIN] Comma separated list of context micrometer tracing versions (e.g. 1.5.0,1.6.0,1.7.0)"
31+
required: false
32+
default: ""
33+
docs_gen_versions:
34+
description: "[TRAIN] Comma separated list of context micrometer docs generator versions (e.g. 1.0.0,1.1.0,1.2.0)"
2735
required: false
2836
default: ""
2937
spring_release_gchat_webhook_url:
@@ -52,9 +60,11 @@ runs:
5260
SPRING_RELEASE_GCHAT_WEBHOOK_URL: ${{ inputs.spring_release_gchat_webhook_url }}
5361
BLUESKY_HANDLE: ${{ inputs.bluesky_handle }}
5462
BLUESKY_PASSWORD: ${{ inputs.bluesky_password }}
55-
TRAIN_VERSIONS: ${{ inputs.train_versions }}
56-
ARTIFACT_TO_CHECK: ${{ inputs.artifact_to_check }}
5763
CIRCLE_CI_TOKEN: ${{ inputs.circle_ci_token }}
64+
CONTEXT_PROPAGATION_VERSIONS: ${{ inputs.context_propagation_versions }}
65+
MICROMETER_VERSIONS: ${{ inputs.micrometer_versions }}
66+
TRACING_VERSIONS: ${{ inputs.tracing_versions }}
67+
DOCS_GEN_VERSIONS: ${{ inputs.docs_gen_versions }}
5868

5969
branding:
6070
icon: "activity"

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ pitest {
155155
threads = 4 // Parallel threads for mutation testing
156156
outputFormats = ['HTML'] // Generate an HTML report
157157
timestampedReports = false // Avoid timestamped reports for consistent file paths
158-
testStrengthThreshold.set(85)
158+
testStrengthThreshold.set(80)
159159
mutationThreshold.set(75)
160160
setCoverageThreshold(80)
161161
excludedClasses.set(["io.micrometer.release.Main"])

src/main/java/io/micrometer/release/Main.java

+53-14
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import io.micrometer.release.common.ProcessRunner;
2020
import io.micrometer.release.single.PostReleaseWorkflow;
2121
import io.micrometer.release.train.ProjectTrainReleaseWorkflow;
22+
import io.micrometer.release.train.TrainOptions;
23+
import io.micrometer.release.train.TrainOptions.ProjectSetup;
2224
import org.slf4j.Logger;
2325
import org.slf4j.LoggerFactory;
2426

@@ -51,8 +53,11 @@ void run() {
5153
String githubOrgRepo = getGithubOrgRepository();
5254
String githubRefName = getGithubRefName();
5355
String previousRefName = getPreviousRefName();
54-
String trainVersions = getTrainVersions();
55-
String artifactToCheck = System.getenv("ARTIFACT_TO_CHECK");
56+
// TRAIN OPTIONS
57+
String contextPropVersions = getContextPropVersions();
58+
String micrometerVersions = getMicrometerVersions();
59+
String tracingVersions = getTracingVersions();
60+
String docsGenVersions = getDocsGenVersions();
5661

5762
log.info("""
5863
!!!
@@ -64,22 +69,60 @@ void run() {
6469
GITHUB_REPOSITORY [%s]
6570
GITHUB_REF_NAME [%s]
6671
PREVIOUS_REF_NAME [%s]
67-
TRAIN_VERSIONS [%s]
68-
ARTIFACT_TO_CHECK [%s]
72+
73+
TRAIN OPTIONS:
74+
CONTEXT_PROPAGATION_VERSIONS [%s]
75+
MICROMETER_VERSIONS [%s]
76+
TRACING_VERSIONS [%s]
77+
DOCS_GEN_VERSIONS [%s]
6978
7079
!!!
71-
""".formatted(githubOrgRepo, githubRefName, previousRefName, trainVersions, artifactToCheck));
80+
""".formatted(githubOrgRepo, githubRefName, previousRefName, contextPropVersions, micrometerVersions,
81+
tracingVersions, docsGenVersions));
7282

73-
if (trainVersions != null && !trainVersions.isBlank()) {
83+
if (isTrainRelease(githubOrgRepo, contextPropVersions, micrometerVersions, tracingVersions, docsGenVersions)) {
7484
log.info("Will proceed with train release...");
75-
trainReleaseWorkflow(githubOrgRepo, artifactToCheck, postReleaseWorkflow, processRunner).run(trainVersions);
85+
ProjectSetup projectSetup = new TrainOptions().parse(githubOrgRepo, contextPropVersions, micrometerVersions,
86+
tracingVersions, docsGenVersions);
87+
trainReleaseWorkflow(githubOrgRepo, postReleaseWorkflow, processRunner).run(projectSetup);
7688
}
7789
else {
7890
log.info("Will proceed with single project post release workflow...");
7991
postReleaseWorkflow.run(githubOrgRepo, githubRefName, previousRefName);
8092
}
8193
}
8294

95+
private boolean isTrainRelease(String githubOrgRepo, String contextPropVersions, String micrometerVersions,
96+
String tracingVersions, String docsGenVersions) {
97+
return switch (githubOrgRepo) {
98+
case "micrometer-metrics/context-propagation" -> hasText(contextPropVersions);
99+
case "micrometer-metrics/micrometer" -> hasText(micrometerVersions);
100+
case "micrometer-metrics/tracing" -> hasText(tracingVersions);
101+
case "micrometer-metrics/micrometer-docs-generator" -> hasText(docsGenVersions);
102+
default -> false;
103+
};
104+
}
105+
106+
private boolean hasText(String text) {
107+
return text != null && !text.isBlank();
108+
}
109+
110+
String getDocsGenVersions() {
111+
return Input.getDocsGenVersions();
112+
}
113+
114+
String getTracingVersions() {
115+
return Input.getTracingVersions();
116+
}
117+
118+
String getMicrometerVersions() {
119+
return Input.getMicrometerVersions();
120+
}
121+
122+
String getContextPropVersions() {
123+
return Input.getContextPropagationVersions();
124+
}
125+
83126
String getGithubOrgRepository() {
84127
return Input.getGithubOrgRepository();
85128
}
@@ -92,13 +135,9 @@ String getGithubRefName() {
92135
return Input.getGithubRefName();
93136
}
94137

95-
String getTrainVersions() {
96-
return Input.getTrainVersions();
97-
}
98-
99-
ProjectTrainReleaseWorkflow trainReleaseWorkflow(String githubOrgRepo, String artifactToCheck,
100-
PostReleaseWorkflow postReleaseWorkflow, ProcessRunner processRunner) {
101-
return new ProjectTrainReleaseWorkflow(githubOrgRepo, artifactToCheck, processRunner, postReleaseWorkflow);
138+
ProjectTrainReleaseWorkflow trainReleaseWorkflow(String githubOrgRepo, PostReleaseWorkflow postReleaseWorkflow,
139+
ProcessRunner processRunner) {
140+
return new ProjectTrainReleaseWorkflow(githubOrgRepo, processRunner, postReleaseWorkflow);
102141
}
103142

104143
PostReleaseWorkflow newPostReleaseWorkflow(ProcessRunner processRunner) {

src/main/java/io/micrometer/release/common/Input.java

+20
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,24 @@ public static String getTrainVersions() {
4949
return System.getenv("TRAIN_VERSIONS");
5050
}
5151

52+
public static String getContextPropagationVersions() {
53+
return System.getenv("CONTEXT_PROPAGATION_VERSIONS");
54+
}
55+
56+
public static String getMicrometerVersions() {
57+
return System.getenv("MICROMETER_VERSIONS");
58+
}
59+
60+
public static String getTracingVersions() {
61+
return System.getenv("TRACING_VERSIONS");
62+
}
63+
64+
public static String getDocsGenVersions() {
65+
return System.getenv("DOCS_GEN_VERSIONS");
66+
}
67+
68+
public static String getGhToken() {
69+
return System.getenv("GH_TOKEN");
70+
}
71+
5272
}

src/main/java/io/micrometer/release/train/DependencyVerifier.java

+29-31
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717

1818
import io.micrometer.release.common.Dependency;
1919
import io.micrometer.release.common.GradleParser;
20+
import io.micrometer.release.common.Input;
2021
import io.micrometer.release.common.ProcessRunner;
22+
import io.micrometer.release.train.TrainOptions.ProjectSetup;
2123
import org.slf4j.Logger;
2224
import org.slf4j.LoggerFactory;
2325

@@ -62,18 +64,24 @@ class DependencyVerifier {
6264
this.timeUnit = timeUnit;
6365
}
6466

65-
void verifyDependencies(String branch, String orgRepository) {
67+
void verifyDependencies(String branch, String orgRepository, ProjectSetup projectSetup) {
6668
File clonedRepo = cloneRepo(branch, orgRepository);
6769
GradleParser gradleParser = getGradleParser(clonedRepo);
6870
log.info("Fetching all dependencies before dependabot...");
6971
Set<Dependency> dependenciesBeforeDependabot = micrometerOnly(gradleParser.fetchAllDependencies());
70-
Status status = dependabotUpdateStatus(clonedRepo, orgRepository);
72+
log.info("Micrometer dependencies before running dependabot {}", dependenciesBeforeDependabot);
73+
dependabotUpdateStatus(clonedRepo, orgRepository);
7174
pullTheLatestRepoChanges(clonedRepo);
7275
Set<Dependency> dependenciesAfterDependabot = micrometerOnly(gradleParser.fetchAllDependencies());
76+
log.info("Micrometer dependencies after running dependabot {}", dependenciesBeforeDependabot);
77+
printDiff(dependenciesAfterDependabot, dependenciesBeforeDependabot);
78+
assertDependencyDiff(dependenciesAfterDependabot, projectSetup);
79+
}
80+
81+
private void printDiff(Set<Dependency> dependenciesAfterDependabot, Set<Dependency> dependenciesBeforeDependabot) {
7382
Set<Dependency> diff = new HashSet<>(dependenciesAfterDependabot);
7483
diff.removeAll(dependenciesBeforeDependabot);
75-
log.info("Dependency diff {}", diff);
76-
assertDependencyDiff(status, diff);
84+
log.info("Dependency diff after running dependabot {}", diff);
7785
}
7886

7987
private Set<Dependency> micrometerOnly(Set<Dependency> dependencies) {
@@ -82,29 +90,25 @@ private Set<Dependency> micrometerOnly(Set<Dependency> dependencies) {
8290
.collect(Collectors.toSet());
8391
}
8492

85-
private void assertDependencyDiff(Status status, Set<Dependency> diff) {
86-
if (status == Status.NO_PRS) {
87-
log.info("There were no dependabot PRs, the dependency diff should have no differences");
88-
if (!diff.isEmpty()) {
89-
log.error("Dependency diff was not empty!");
90-
throw new IllegalStateException(
91-
"There were open PRs however the dependencies differ. Different dependencies: [" + diff + "]");
92-
}
93-
}
94-
else {
95-
log.info("There were open PRs. The dependency diff should contain new library versions");
96-
// TODO: Take from env vars micrometer / tracing / context propagation library
97-
// versions and assert that they were updated in the diff
98-
// check what this project is (e.g. micrometer) and what it should check for
99-
// (e.g. context-propagation)
93+
private void assertDependencyDiff(Set<Dependency> diff, ProjectSetup projectSetup) {
94+
List<Dependency> dependencies = projectSetup.expectedDependencies();
95+
log.info("Expected dependencies from the project setup {}", dependencies);
96+
Set<Dependency> diffBetweenExpectedAndActual = new HashSet<>(dependencies);
97+
diffBetweenExpectedAndActual.removeAll(diff);
98+
if (!diffBetweenExpectedAndActual.isEmpty()) {
99+
throw new IllegalStateException(
100+
"There's a difference between expected dependencies from project setup and the one after running dependabot ["
101+
+ diffBetweenExpectedAndActual + "]");
100102
}
103+
log.info(
104+
"Project after running dependabot has all project dependencies in required versions! Proceeding with the release...");
101105
}
102106

103-
private Status dependabotUpdateStatus(File clonedRepo, String orgRepository) {
107+
private void dependabotUpdateStatus(File clonedRepo, String orgRepository) {
104108
String githubServerTime = getGitHubServerTime(orgRepository);
105109
triggerDependabotCheck(orgRepository, clonedRepo);
106110
waitForDependabotJobsToFinish(orgRepository, githubServerTime);
107-
return waitForDependabotPrsToFinish(githubServerTime);
111+
waitForDependabotPrsToFinish(githubServerTime);
108112
}
109113

110114
private GradleParser getGradleParser(File branch) {
@@ -194,7 +198,7 @@ private void triggerDependabotCheck(String orgRepository, File clonedRepo) {
194198
}
195199

196200
String ghToken() {
197-
return System.getenv("GH_TOKEN");
201+
return Input.getGhToken();
198202
}
199203

200204
ProcessRunner processRunnerForBranch(File clonedRepo) {
@@ -246,7 +250,7 @@ private String getDependabotupdatesWorkflowId(String orgRepository) {
246250
return ids.get(0);
247251
}
248252

249-
private Status waitForDependabotPrsToFinish(String githubServerTime) {
253+
private void waitForDependabotPrsToFinish(String githubServerTime) {
250254
log.info("Waiting {} {} for Dependabot PRs to be created...", initialWait, timeUnit);
251255
sleep(initialWait);
252256
long startTime = System.currentTimeMillis();
@@ -255,7 +259,7 @@ private Status waitForDependabotPrsToFinish(String githubServerTime) {
255259
List<String> openPRs = getOpenMicrometerDependabotPRs(githubServerTime);
256260
if (openPRs.isEmpty()) {
257261
log.info("No pending Micrometer updates");
258-
return Status.NO_PRS;
262+
return;
259263
}
260264
boolean allProcessed = true;
261265
for (String pr : openPRs) {
@@ -265,7 +269,7 @@ private Status waitForDependabotPrsToFinish(String githubServerTime) {
265269
}
266270
if (allProcessed) {
267271
log.info("All Dependabot PRs processed");
268-
return Status.ALL_PRS_COMPLETED;
272+
return;
269273
}
270274
log.info("Not all PRs processed, will try again...");
271275
sleep(waitBetweenRuns);
@@ -310,10 +314,4 @@ private boolean checkPRStatus(String prNumber) {
310314
return isCompleted;
311315
}
312316

313-
enum Status {
314-
315-
NO_PRS, ALL_PRS_COMPLETED
316-
317-
}
318-
319317
}

0 commit comments

Comments
 (0)