Skip to content

Commit 258c0e9

Browse files
Add benchmark metrics to iOS CI pipeline (#4286)
Measured and reported VM translation time and native compilation time in the PR comment. Updated `scripts/build-ios-app.sh` to capture VM translation time. Updated `scripts/run-ios-ui-tests.sh` to capture compilation time and pass metrics. Updated `RenderScreenshotReport.java` to display benchmark results. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
1 parent 7fffa41 commit 258c0e9

File tree

4 files changed

+102
-15
lines changed

4 files changed

+102
-15
lines changed

scripts/build-ios-app.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,22 @@ xcodebuild -version
6262

6363
bia_log "Building iOS Xcode project using Codename One port"
6464
cd $APP_DIR
65+
VM_START=$(date +%s)
6566
./mvnw package \
6667
-DskipTests \
6768
-Dcodename1.platform=ios \
6869
-Dcodename1.buildTarget=ios-source \
6970
-Dopen=false \
7071
-U -e
72+
VM_END=$(date +%s)
73+
VM_TIME=$((VM_END - VM_START))
7174
cd ../..
7275

76+
ARTIFACTS_DIR="${ARTIFACTS_DIR:-$REPO_ROOT/artifacts}"
77+
mkdir -p "$ARTIFACTS_DIR"
78+
echo "$VM_TIME" > "$ARTIFACTS_DIR/vm_time.txt"
79+
bia_log "VM translation time: ${VM_TIME}s (saved to $ARTIFACTS_DIR/vm_time.txt)"
80+
7381
IOS_TARGET_DIR="$APP_DIR/ios/target"
7482
if [ ! -d "$IOS_TARGET_DIR" ]; then
7583
bia_log "iOS target directory not found at $IOS_TARGET_DIR" >&2

scripts/common/java/RenderScreenshotReport.java

Lines changed: 75 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public static void main(String[] args) throws Exception {
3232

3333
CoverageSummary coverage = loadCoverage(arguments.coverageSummary, arguments.coverageHtmlUrl);
3434

35-
SummaryAndComment output = buildSummaryAndComment(data, title, marker, successMessage, coverage);
35+
SummaryAndComment output = buildSummaryAndComment(data, title, marker, successMessage, coverage, arguments.vmTime, arguments.compilationTime);
3636
writeLines(arguments.summaryOut, output.summaryLines);
3737
writeLines(arguments.commentOut, output.commentLines);
3838
}
@@ -51,7 +51,7 @@ private static void writeLines(Path path, List<String> lines) throws IOException
5151
Files.writeString(path, sb.toString(), StandardCharsets.UTF_8);
5252
}
5353

54-
private static SummaryAndComment buildSummaryAndComment(Map<String, Object> data, String title, String marker, String successMessage, CoverageSummary coverage) {
54+
private static SummaryAndComment buildSummaryAndComment(Map<String, Object> data, String title, String marker, String successMessage, CoverageSummary coverage, Long vmTime, Long compilationTime) {
5555
List<String> summaryLines = new ArrayList<>();
5656
List<String> commentLines = new ArrayList<>();
5757
Object resultsObj = data.get("results");
@@ -148,22 +148,34 @@ private static SummaryAndComment buildSummaryAndComment(Map<String, Object> data
148148

149149
appendCoverageComment(commentLines, coverage);
150150

151-
if (commentLines.isEmpty()) {
151+
// If no visual regressions or errors were found (commentEntries is empty),
152+
// we should display the success message.
153+
// However, we also need to include benchmark results.
154+
if (commentEntries.isEmpty()) {
152155
commentLines.add(successMessage != null ? successMessage : DEFAULT_SUCCESS_MESSAGE);
153156
commentLines.add("");
154-
comparisonOverviewAdded = appendComparisonOverview(commentLines, comparisonSummary);
155-
appendCoverageComment(commentLines, coverage);
156-
} else if (commentLines.size() == 1 && commentLines.get(0).isEmpty()) {
157-
commentLines.add(successMessage != null ? successMessage : DEFAULT_SUCCESS_MESSAGE);
158-
commentLines.add("");
159-
comparisonOverviewAdded = appendComparisonOverview(commentLines, comparisonSummary);
157+
if (!comparisonOverviewAdded) {
158+
comparisonOverviewAdded = appendComparisonOverview(commentLines, comparisonSummary);
159+
}
160160
appendCoverageComment(commentLines, coverage);
161161
}
162162

163-
if (commentLines.isEmpty()) {
164-
commentLines.add(successMessage != null ? successMessage : DEFAULT_SUCCESS_MESSAGE);
165-
commentLines.add("");
166-
appendComparisonOverview(commentLines, comparisonSummary);
163+
// Add benchmark results at the end
164+
appendBenchmarkResults(commentLines, vmTime, compilationTime);
165+
166+
if (commentLines.isEmpty() || (commentLines.size() == 1 && commentLines.get(0).isEmpty())) {
167+
// This fallback block might be redundant now, but kept for safety.
168+
// If for some reason we still have empty lines (e.g. no benchmarks and no visual changes and logic skipped above),
169+
// ensure we output something.
170+
if (commentEntries.isEmpty()) {
171+
if (commentLines.isEmpty() || !commentLines.contains(successMessage != null ? successMessage : DEFAULT_SUCCESS_MESSAGE)) {
172+
commentLines.add(0, successMessage != null ? successMessage : DEFAULT_SUCCESS_MESSAGE);
173+
commentLines.add(1, "");
174+
}
175+
}
176+
if (!comparisonOverviewAdded) {
177+
comparisonOverviewAdded = appendComparisonOverview(commentLines, comparisonSummary);
178+
}
167179
}
168180

169181
if (marker != null && !marker.isEmpty()) {
@@ -219,6 +231,24 @@ private static void appendCoverageSummary(List<String> summaryLines, CoverageSum
219231
}
220232
}
221233

234+
private static void appendBenchmarkResults(List<String> commentLines, Long vmTime, Long compilationTime) {
235+
if (vmTime == null && compilationTime == null) {
236+
return;
237+
}
238+
if (!commentLines.isEmpty() && !commentLines.get(commentLines.size() - 1).isEmpty()) {
239+
commentLines.add("");
240+
}
241+
commentLines.add("### Benchmark Results");
242+
commentLines.add("");
243+
if (vmTime != null) {
244+
commentLines.add(String.format("- **VM Translation Time:** %d seconds", vmTime));
245+
}
246+
if (compilationTime != null) {
247+
commentLines.add(String.format("- **Compilation Time:** %d seconds", compilationTime));
248+
}
249+
commentLines.add("");
250+
}
251+
222252
private static void appendCoverageComment(List<String> commentLines, CoverageSummary coverage) {
223253
if (coverage == null) {
224254
return;
@@ -418,8 +448,10 @@ private static class Arguments {
418448
final String successMessage;
419449
final Path coverageSummary;
420450
final String coverageHtmlUrl;
451+
final Long vmTime;
452+
final Long compilationTime;
421453

422-
private Arguments(Path compareJson, Path commentOut, Path summaryOut, String marker, String title, String successMessage, Path coverageSummary, String coverageHtmlUrl) {
454+
private Arguments(Path compareJson, Path commentOut, Path summaryOut, String marker, String title, String successMessage, Path coverageSummary, String coverageHtmlUrl, Long vmTime, Long compilationTime) {
423455
this.compareJson = compareJson;
424456
this.commentOut = commentOut;
425457
this.summaryOut = summaryOut;
@@ -428,6 +460,8 @@ private Arguments(Path compareJson, Path commentOut, Path summaryOut, String mar
428460
this.successMessage = successMessage;
429461
this.coverageSummary = coverageSummary;
430462
this.coverageHtmlUrl = coverageHtmlUrl;
463+
this.vmTime = vmTime;
464+
this.compilationTime = compilationTime;
431465
}
432466

433467
static Arguments parse(String[] args) {
@@ -439,6 +473,8 @@ static Arguments parse(String[] args) {
439473
String successMessage = null;
440474
Path coverageSummary = null;
441475
String coverageHtmlUrl = null;
476+
Long vmTime = null;
477+
Long compilationTime = null;
442478
for (int i = 0; i < args.length; i++) {
443479
String arg = args[i];
444480
switch (arg) {
@@ -498,6 +534,30 @@ static Arguments parse(String[] args) {
498534
}
499535
coverageHtmlUrl = args[i];
500536
}
537+
case "--vm-time" -> {
538+
if (++i >= args.length) {
539+
System.err.println("Missing value for --vm-time");
540+
return null;
541+
}
542+
try {
543+
vmTime = Long.parseLong(args[i]);
544+
} catch (NumberFormatException e) {
545+
System.err.println("Invalid value for --vm-time: " + args[i]);
546+
return null;
547+
}
548+
}
549+
case "--compilation-time" -> {
550+
if (++i >= args.length) {
551+
System.err.println("Missing value for --compilation-time");
552+
return null;
553+
}
554+
try {
555+
compilationTime = Long.parseLong(args[i]);
556+
} catch (NumberFormatException e) {
557+
System.err.println("Invalid value for --compilation-time: " + args[i]);
558+
return null;
559+
}
560+
}
501561
default -> {
502562
System.err.println("Unknown argument: " + arg);
503563
return null;
@@ -508,7 +568,7 @@ static Arguments parse(String[] args) {
508568
System.err.println("--compare-json, --comment-out, and --summary-out are required");
509569
return null;
510570
}
511-
return new Arguments(compare, comment, summary, marker, title, successMessage, coverageSummary, coverageHtmlUrl);
571+
return new Arguments(compare, comment, summary, marker, title, successMessage, coverageSummary, coverageHtmlUrl, vmTime, compilationTime);
512572
}
513573
}
514574

scripts/lib/cn1ss.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,12 @@ cn1ss_process_and_report() {
354354
if [ -n "${CN1SS_COVERAGE_HTML_URL:-}" ]; then
355355
render_args+=(--coverage-html-url "$CN1SS_COVERAGE_HTML_URL")
356356
fi
357+
if [ -n "${CN1SS_VM_TIME:-}" ]; then
358+
render_args+=(--vm-time "$CN1SS_VM_TIME")
359+
fi
360+
if [ -n "${CN1SS_COMPILATION_TIME:-}" ]; then
361+
render_args+=(--compilation-time "$CN1SS_COMPILATION_TIME")
362+
fi
357363

358364
if ! cn1ss_java_run "$CN1SS_RENDER_CLASS" "${render_args[@]}"; then
359365
cn1ss_log "FATAL: Failed to render screenshot summary/comment"

scripts/run-ios-ui-tests.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ rm -rf "$DERIVED_DATA_DIR"
346346
BUILD_LOG="$ARTIFACTS_DIR/xcodebuild-build.log"
347347

348348
ri_log "Building simulator app with xcodebuild"
349+
COMPILE_START=$(date +%s)
349350
if ! xcodebuild \
350351
-workspace "$WORKSPACE_PATH" \
351352
-scheme "$SCHEME" \
@@ -358,6 +359,9 @@ if ! xcodebuild \
358359
ri_log "STAGE:XCODE_BUILD_FAILED -> See $BUILD_LOG"
359360
exit 10
360361
fi
362+
COMPILE_END=$(date +%s)
363+
COMPILATION_TIME=$((COMPILE_END - COMPILE_START))
364+
ri_log "Compilation time: ${COMPILATION_TIME}s"
361365

362366
BUILD_SETTINGS="$(xcodebuild -workspace "$WORKSPACE_PATH" -scheme "$SCHEME" -sdk iphonesimulator -configuration Debug -showBuildSettings 2>/dev/null || true)"
363367
TARGET_BUILD_DIR="$(printf '%s\n' "$BUILD_SETTINGS" | awk -F' = ' '/ TARGET_BUILD_DIR /{print $2; exit}')"
@@ -612,6 +616,15 @@ export CN1SS_COMMENT_MARKER="<!-- CN1SS_IOS_COMMENT -->"
612616
export CN1SS_COMMENT_LOG_PREFIX="[run-ios-device-tests]"
613617
export CN1SS_PREVIEW_SUBDIR="ios"
614618

619+
# Load VM translation time if available
620+
CN1SS_VM_TIME=0
621+
if [ -f "$ARTIFACTS_DIR/vm_time.txt" ]; then
622+
CN1SS_VM_TIME=$(cat "$ARTIFACTS_DIR/vm_time.txt")
623+
ri_log "Loaded VM translation time: ${CN1SS_VM_TIME}s"
624+
fi
625+
export CN1SS_VM_TIME
626+
export CN1SS_COMPILATION_TIME="$COMPILATION_TIME"
627+
615628
cn1ss_process_and_report \
616629
"iOS screenshot updates" \
617630
"$COMPARE_JSON" \

0 commit comments

Comments
 (0)