Skip to content

Commit 1103078

Browse files
committed
Add links to the web search in Develocity reports
For now it's not very useful given the query is just a list of CI runs we found, but it might still help with debugging, and also if we build the query differently in the future (e.g. match by PR tag + commit SHA).
1 parent 8deab47 commit 1103078

File tree

5 files changed

+126
-5
lines changed

5 files changed

+126
-5
lines changed

src/main/java/org/hibernate/infra/bot/ExtractDevelocityBuildScans.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,10 @@ private void extractCIBuildScans(GHRepository repository, RepositoryConfig.Devel
8989
}
9090
long checkId = createDevelocityCheck( repository, sha );
9191
Throwable failure = null;
92+
String query = "";
9293
List<DevelocityCIBuildScan> buildScans = new ArrayList<>();
9394
try {
94-
String query = createBuildScansQuery( checkRuns );
95+
query = createBuildScansQuery( checkRuns );
9596
for ( Build build : develocityBuildsApi.getBuilds( new BuildsQuery.BuildsQueryQueryParam()
9697
.fromInstant( 0L )
9798
.query( query )
@@ -122,7 +123,7 @@ private void extractCIBuildScans(GHRepository repository, RepositoryConfig.Devel
122123
if ( failure != null ) {
123124
Log.errorf( failure, "Failed to extract all build scans from commit %s" + sha );
124125
}
125-
updateDevelocityCheck( repository, config, checkId, buildScans, failure );
126+
updateDevelocityCheck( repository, config, checkId, query, buildScans, failure );
126127
}
127128
catch (IOException | RuntimeException e) {
128129
Log.errorf( e, "Failed to report build scans from commit %s" + sha );
@@ -249,11 +250,13 @@ private long createDevelocityCheck(GHRepository repository, String sha) throws I
249250
}
250251

251252
private void updateDevelocityCheck(GHRepository repository, RepositoryConfig.Develocity.BuildScan config,
252-
long checkId, List<DevelocityCIBuildScan> buildScans, Throwable failure)
253+
long checkId, String query, List<DevelocityCIBuildScan> buildScans, Throwable failure)
253254
throws IOException {
254255
String formattedBuildScanList = "";
256+
String footer = "";
255257
try {
256258
formattedBuildScanList = reportFormatter.summary( buildScans, config );
259+
footer = reportFormatter.footer( query, false );
257260
}
258261
catch (RuntimeException e) {
259262
if ( failure == null ) {
@@ -270,12 +273,18 @@ private void updateDevelocityCheck(GHRepository repository, RepositoryConfig.Dev
270273
if ( failure == null ) {
271274
conclusion = GHCheckRun.Conclusion.NEUTRAL;
272275
title = "Found %s build scan%s".formatted( buildScans.size(), buildScans.size() != 1 ? "s" : "" );
273-
text = formattedBuildScanList;
276+
text = formattedBuildScanList + footer;
274277
}
275278
else {
276279
conclusion = GHCheckRun.Conclusion.FAILURE;
277280
title = "Develocity Build Scans extraction failed with exception";
278-
text = formattedBuildScanList + "\n\n```\n" + ExceptionUtils.getStackTrace( failure ) + "\n```";
281+
try {
282+
footer = reportFormatter.footer( query, true );
283+
}
284+
catch (RuntimeException e) {
285+
failure.addSuppressed( e );
286+
}
287+
text = formattedBuildScanList + "\n\n```\n" + ExceptionUtils.getStackTrace( failure ) + "\n```" + footer;
279288
}
280289

281290
if ( deploymentConfig.isDryRun() ) {

src/main/java/org/hibernate/infra/bot/develocity/DevelocityReportFormatter.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package org.hibernate.infra.bot.develocity;
22

33
import java.net.URI;
4+
import java.time.Clock;
5+
import java.time.temporal.ChronoUnit;
6+
import java.time.temporal.TemporalUnit;
47
import java.util.Collection;
58
import java.util.HashMap;
69
import java.util.LinkedHashMap;
@@ -14,8 +17,10 @@
1417
import jakarta.enterprise.context.ApplicationScoped;
1518
import jakarta.ws.rs.core.UriBuilder;
1619

20+
import org.hibernate.infra.bot.config.DeploymentConfig;
1721
import org.hibernate.infra.bot.config.RepositoryConfig;
1822

23+
import io.quarkus.arc.Arc;
1924
import io.quarkus.qute.CheckedTemplate;
2025
import io.quarkus.qute.TemplateExtension;
2126
import io.quarkus.qute.TemplateInstance;
@@ -29,6 +34,11 @@ public String summary(List<DevelocityCIBuildScan> buildScans, RepositoryConfig.D
2934
.render();
3035
}
3136

37+
public String footer(String query, boolean debug) {
38+
return Templates.footer( query, debug )
39+
.render();
40+
}
41+
3242
public record TagColumn(String name, Map<DevelocityCIBuildScan, Set<String>> content) {
3343
}
3444

@@ -85,6 +95,8 @@ private Collection<TagColumn> extractTagColumns(List<DevelocityCIBuildScan> buil
8595
private static class Templates {
8696
public static native TemplateInstance summary(List<DevelocityCIBuildScan> buildScans,
8797
Collection<TagColumn> tagColumns);
98+
99+
public static native TemplateInstance footer(String query, boolean debug);
88100
}
89101

90102
@TemplateExtension
@@ -143,4 +155,26 @@ static List<String> create(String... content) {
143155
return List.of( content );
144156
}
145157
}
158+
159+
@TemplateExtension(namespace = "develocity")
160+
@SuppressWarnings("unused")
161+
private static class DevelocityTemplateExtensions {
162+
static URI webSearchUri(String query) {
163+
var config = Arc.container().instance( DeploymentConfig.class ).get();
164+
var clock = Arc.container().instance( Clock.class ).get();
165+
return UriBuilder.fromUri( config.develocity().uri() )
166+
.path( "scans" )
167+
.queryParam( "search.query", query )
168+
// Make sure the query still works if new build scans are added
169+
.queryParam( "search.startTimeMin", 1 )
170+
.queryParam( "search.startTimeMax", clock.instant().plus( 365, ChronoUnit.DAYS ).toEpochMilli() )
171+
.queryParam( "search.timeZoneId", "UTC" )
172+
.build();
173+
}
174+
175+
static String formatQuery(String query) {
176+
return query.replace( "(", "(\n" )
177+
.replace( ")", "\n)" );
178+
}
179+
}
146180
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.hibernate.infra.bot.util;
2+
3+
import java.time.Clock;
4+
5+
import io.quarkus.arc.Unremovable;
6+
import jakarta.enterprise.context.ApplicationScoped;
7+
import jakarta.enterprise.inject.Produces;
8+
9+
@ApplicationScoped
10+
public class ClockProducer {
11+
12+
@Produces
13+
@ApplicationScoped
14+
@Unremovable
15+
Clock clock() {
16+
return Clock.systemUTC();
17+
}
18+
19+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
3+
Didn't find your build? Try [this search query]({develocity:webSearchUri(query)})
4+
{#if debug}
5+
6+
Full query sent to Develocity:
7+
8+
```
9+
{develocity:formatQuery(query)}
10+
```
11+
{/if}

src/test/java/org/hibernate/infra/bot/develocity/DevelocityReportFormatterTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
import static org.assertj.core.api.Assertions.assertThat;
1212

1313
import java.net.URI;
14+
import java.time.Clock;
15+
import java.time.Instant;
16+
import java.time.LocalDateTime;
17+
import java.time.ZoneOffset;
1418
import java.util.List;
1519
import java.util.Optional;
1620

@@ -19,8 +23,10 @@
1923
import org.hibernate.infra.bot.config.RepositoryConfig;
2024
import org.hibernate.infra.bot.util.Patterns;
2125

26+
import org.junit.jupiter.api.BeforeEach;
2227
import org.junit.jupiter.api.Test;
2328

29+
import io.quarkus.test.junit.QuarkusMock;
2430
import io.quarkus.test.junit.QuarkusTest;
2531

2632
@QuarkusTest
@@ -29,6 +35,13 @@ class DevelocityReportFormatterTest {
2935
@Inject
3036
DevelocityReportFormatter formatter;
3137

38+
@BeforeEach
39+
void setup() {
40+
Instant now = LocalDateTime.of( 2024, 10, 28, 0, 0 ).toInstant( ZoneOffset.UTC );
41+
var clockMock = Clock.fixed( now, ZoneOffset.UTC );
42+
QuarkusMock.installMockForType( clockMock, Clock.class );
43+
}
44+
3245
@Test
3346
void summary_simple() {
3447
var buildScans = List.of(
@@ -254,4 +267,39 @@ private DevelocityCIBuildScan buildScanStub(String provider, String jobOrWorkflo
254267
URI.create( "https://ge.hibernate.org/s/45fv2rr67ofuy/console-log" ) );
255268
}
256269

270+
@Test
271+
void footer_simple() {
272+
assertThat( formatter.footer(
273+
"(value:\"CI job=hibernate-orm-pipeline/PR-9171\" and value:\"CI build number=1\") or (value:\"CI run=11552691889\")",
274+
false ) )
275+
.isEqualTo(
276+
"""
277+
278+
279+
Didn't find your build? Try [this search query](https://ge.hibernate.org/scans?search.query=%28value%3A%22CI+job%3Dhibernate-orm-pipeline%2FPR-9171%22+and+value%3A%22CI+build+number%3D1%22%29+or+%28value%3A%22CI+run%3D11552691889%22%29&search.startTimeMin=1&search.startTimeMax=1761609600000&search.timeZoneId=UTC)
280+
""" );
281+
}
282+
283+
@Test
284+
void footer_debug() {
285+
assertThat( formatter.footer(
286+
"(value:\"CI job=hibernate-orm-pipeline/PR-9171\" and value:\"CI build number=1\") or (value:\"CI run=11552691889\")",
287+
true ) )
288+
.isEqualTo(
289+
"""
290+
291+
292+
Didn't find your build? Try [this search query](https://ge.hibernate.org/scans?search.query=%28value%3A%22CI+job%3Dhibernate-orm-pipeline%2FPR-9171%22+and+value%3A%22CI+build+number%3D1%22%29+or+%28value%3A%22CI+run%3D11552691889%22%29&search.startTimeMin=1&search.startTimeMax=1761609600000&search.timeZoneId=UTC)
293+
294+
Full query sent to Develocity:
295+
296+
```
297+
(
298+
value:"CI job=hibernate-orm-pipeline/PR-9171" and value:"CI build number=1"
299+
) or (
300+
value:"CI run=11552691889"
301+
)
302+
```
303+
""" );
304+
}
257305
}

0 commit comments

Comments
 (0)