From 6a84686e30684d7e5d1b2cd998384507b0c78e0f Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Wed, 7 Jan 2026 11:30:04 +0100 Subject: [PATCH 01/13] Redirect WireMock log to separate file --- .buildkite/pipeline.yml | 2 ++ API-Mocks/scripts/start.sh | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 492d203930e4..76ee6479759f 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -147,6 +147,7 @@ steps: artifact_paths: - "build/results/*" - "build/results/crashes/*" + - "build/logs/wiremock.txt" notify: - github_commit_status: context: "UI Tests (iPhone)" @@ -158,6 +159,7 @@ steps: artifact_paths: - "build/results/*" - "build/results/crashes/*" + - "build/logs/wiremock.txt" notify: - github_commit_status: context: "UI Tests (iPad)" diff --git a/API-Mocks/scripts/start.sh b/API-Mocks/scripts/start.sh index c6002ee3b4d2..c04b47c462a6 100755 --- a/API-Mocks/scripts/start.sh +++ b/API-Mocks/scripts/start.sh @@ -4,8 +4,9 @@ set -eu SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" VENDOR_DIR="$(pwd)/vendor/wiremock" +BUILD_ARTIFACTS_DIR="$(pwd)/build/logs" -WIREMOCK_VERSION="2.35.0" +WIREMOCK_VERSION="2.35.2" WIREMOCK_JAR="${VENDOR_DIR}/wiremock-jre8-standalone-${WIREMOCK_VERSION}.jar" if [ ! -f "$WIREMOCK_JAR" ]; then @@ -18,6 +19,12 @@ fi PORT="${1:-8282}" # Start WireMock server. See http://wiremock.org/docs/running-standalone/ +# Redirect output to a log file on CI to reduce log noise +OUTPUT_REDIRECT="/dev/stdout" +if [ -n "${BUILDKITE:-}" ]; then + OUTPUT_REDIRECT="${BUILD_ARTIFACTS_DIR}/wiremock.txt" + mkdir -p "$(dirname "$OUTPUT_REDIRECT")" +fi java -jar "${WIREMOCK_JAR}" --root-dir "${SCRIPT_DIR}/../WordPressMocks/src/main/assets/mocks" \ --port "$PORT" \ - --global-response-templating + --global-response-templating > "$OUTPUT_REDIRECT" 2>&1 From c9f6e287bac9b9cb8b1189a539693bf2cc588767 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Mon, 5 Jan 2026 14:51:25 +0100 Subject: [PATCH 02/13] Add Claude Build Analysis to any failing build job --- .buildkite/claude-analysis.yml | 31 +++++++++++++++++++ .../commands/comment-claude-analysis.sh | 15 +++++++++ .buildkite/pipeline.yml | 13 ++++++++ .buildkite/shared-pipeline-vars | 1 + 4 files changed, 60 insertions(+) create mode 100644 .buildkite/claude-analysis.yml create mode 100755 .buildkite/commands/comment-claude-analysis.sh diff --git a/.buildkite/claude-analysis.yml b/.buildkite/claude-analysis.yml new file mode 100644 index 000000000000..1d0dbf39256d --- /dev/null +++ b/.buildkite/claude-analysis.yml @@ -0,0 +1,31 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/buildkite/pipeline-schema/main/schema.json +--- + +# This pipeline is dynamically uploaded at the end of the build after a wait step + +agents: + queue: default + +steps: + - label: ":claude: Claude Build Analysis" + key: claude-analysis + if: build.state == "failing" + soft_fail: true + command: "exit 1" + plugins: + - $CLAUDE_PLUGIN: + api_key: "$ANTHROPIC_API_KEY" + buildkite_api_token: "$BUILDKITE_TOKEN_FOR_CLAUDE" + analysis_level: "build" + trigger: "always" + custom_prompt: "Do not mention successful points, focus on failures and recovery to keep the analysis succint. Only add the `Best Practices` section if the changes in this PR are directly relevant to it. Only add a `Root Cause` section when you're sure about the issues' causes." + model: "claude-sonnet-4-5" + + - label: ":claude: 💬 Comment Claude Analysis" + command: .buildkite/commands/comment-claude-analysis.sh + depends_on: claude-analysis + allow_dependency_failure: true + if: build.pull_request.id != null + plugins: + - $CI_TOOLKIT_PLUGIN + diff --git a/.buildkite/commands/comment-claude-analysis.sh b/.buildkite/commands/comment-claude-analysis.sh new file mode 100755 index 000000000000..9c23ae99e0c9 --- /dev/null +++ b/.buildkite/commands/comment-claude-analysis.sh @@ -0,0 +1,15 @@ +#!/bin/bash -eu + +# The claude-analysis step only runs when there are build failures, +# so if it ran (and soft_failed), it means there were failures that Claude analyzed. +CLAUDE_OUTCOME=$(buildkite-agent step get outcome --step claude-analysis 2>/dev/null || echo "not_run") + +if [[ "${CLAUDE_OUTCOME}" == "soft_failed" ]]; then + comment_on_pr --id claude-build-analysis "## 🤖 Build Failure Analysis + +This build has failures. Claude has analyzed them - check the build annotations for details." +else + # Remove the comment if the build is now passing (claude-analysis did not run) + comment_on_pr --id claude-build-analysis --if-exist delete +fi + diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 76ee6479759f..37550935983b 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -201,3 +201,16 @@ steps: - label: ":sleuth_or_spy: Lint Localized Strings Format" command: .buildkite/commands/lint-localized-strings-format.sh plugins: [$CI_TOOLKIT_PLUGIN] + + ################# + # Claude Build Analysis - dynamically uploaded so Build result conditions evaluate at runtime after the wait + ################# + - wait: ~ + continue_on_failure: true + + - label: ":claude: 🕵️ Check for Build Failures and Run Claude Analysis" + command: | + source .buildkite/shared-pipeline-vars + buildkite-agent pipeline upload .buildkite/claude-analysis.yml + agents: + queue: upload diff --git a/.buildkite/shared-pipeline-vars b/.buildkite/shared-pipeline-vars index 300d5deea846..75bc5b5a170a 100755 --- a/.buildkite/shared-pipeline-vars +++ b/.buildkite/shared-pipeline-vars @@ -9,3 +9,4 @@ CI_TOOLKIT_PLUGIN_VERSION="5.3.1" export IMAGE_ID="xcode-$XCODE_VERSION" export CI_TOOLKIT_PLUGIN="automattic/a8c-ci-toolkit#$CI_TOOLKIT_PLUGIN_VERSION" +export CLAUDE_PLUGIN="claude-summarize#v1.1.0" From 5e61c836a1f128c0d42a8f75b398f2607717ebb6 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Mon, 5 Jan 2026 20:36:55 +0100 Subject: [PATCH 03/13] Add `allow_dependency_failure` to final wait step --- .buildkite/pipeline.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 37550935983b..362a5dd3291a 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -207,6 +207,7 @@ steps: ################# - wait: ~ continue_on_failure: true + allow_dependency_failure: true - label: ":claude: 🕵️ Check for Build Failures and Run Claude Analysis" command: | From 7a213510d2495256bb53cf3a7779c3017e4844d7 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Mon, 5 Jan 2026 21:09:27 +0100 Subject: [PATCH 04/13] Test wait step dependency to not depend on optional job --- .buildkite/pipeline.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 362a5dd3291a..b82ac3603f71 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -37,6 +37,7 @@ steps: depends_on: ~ - label: ":eyeglasses: Reader one-off TestFlight Upload" + key: testflight_upload_reader depends_on: [build_asc_reader, testflight_triggered_reader] command: | if .buildkite/commands/should-skip-job.sh --job-type build; then @@ -208,6 +209,9 @@ steps: - wait: ~ continue_on_failure: true allow_dependency_failure: true + depends_on: + - step: testflight_upload_reader + allow_failure: true - label: ":claude: 🕵️ Check for Build Failures and Run Claude Analysis" command: | From 8fe005abf5cecf1d0d070199878933188b452f5e Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 6 Jan 2026 11:49:52 +0100 Subject: [PATCH 05/13] Remove wait step to favor an explicit dependency in the Claude step --- .buildkite/pipeline.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index b82ac3603f71..74e27df70fb4 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -54,6 +54,7 @@ steps: # Create Prototype Builds for WP and JP ################# - group: "🛠 Prototype Builds" + key: prototype_builds_group steps: - label: "🛠 WordPress Prototype Build" command: ".buildkite/commands/prototype-build-wordpress.sh" @@ -96,6 +97,7 @@ steps: # Run Unit Tests ################# - group: "🔬 Unit Tests" + key: unit_tests_group steps: - label: "🔬 :wordpress: Unit Tests" command: ".buildkite/commands/run-unit-tests.sh" @@ -140,6 +142,7 @@ steps: # UI Tests ################# - group: "🔬 UI Tests" + key: ui_tests_group steps: - label: "🔬 :jetpack: UI Tests (iPhone)" command: .buildkite/commands/run-ui-tests.sh 'iPhone 17' @@ -169,6 +172,7 @@ steps: # Linters ################# - group: "Linters" + key: linters_group steps: - label: "☢️ Danger - PR Check" command: danger @@ -206,16 +210,18 @@ steps: ################# # Claude Build Analysis - dynamically uploaded so Build result conditions evaluate at runtime after the wait ################# - - wait: ~ - continue_on_failure: true - allow_dependency_failure: true - depends_on: - - step: testflight_upload_reader - allow_failure: true - - label: ":claude: 🕵️ Check for Build Failures and Run Claude Analysis" command: | source .buildkite/shared-pipeline-vars buildkite-agent pipeline upload .buildkite/claude-analysis.yml + # Add specific group dependencies. Using a `wait` step wouldn't work as it would never start given the prompt block + depends_on: + - build_asc_reader + - linters_group + - prototype_builds_group + - unit_tests_group + - ui_tests_group + allow_dependency_failure: true agents: queue: upload + From cc6e1197627eae2e7aa82b853be3e70cf03dc830 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 6 Jan 2026 19:36:39 +0100 Subject: [PATCH 06/13] Add Claude debug as build artifact --- .buildkite/claude-analysis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.buildkite/claude-analysis.yml b/.buildkite/claude-analysis.yml index 1d0dbf39256d..0dd8a8f3655b 100644 --- a/.buildkite/claude-analysis.yml +++ b/.buildkite/claude-analysis.yml @@ -12,6 +12,9 @@ steps: if: build.state == "failing" soft_fail: true command: "exit 1" + artifact_paths: + - "/tmp/claude_debug_${BUILDKITE_BUILD_ID}.txt" + - "/tmp/claude_response_${BUILDKITE_BUILD_ID}.json" plugins: - $CLAUDE_PLUGIN: api_key: "$ANTHROPIC_API_KEY" From 2f8c9a503beb90d138950fd1092d79a8452d6a05 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Wed, 7 Jan 2026 17:48:20 +0100 Subject: [PATCH 07/13] Update Claude analysis to make it clear the trigger is only on failures --- .buildkite/claude-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/claude-analysis.yml b/.buildkite/claude-analysis.yml index 0dd8a8f3655b..27f3ab852402 100644 --- a/.buildkite/claude-analysis.yml +++ b/.buildkite/claude-analysis.yml @@ -20,7 +20,7 @@ steps: api_key: "$ANTHROPIC_API_KEY" buildkite_api_token: "$BUILDKITE_TOKEN_FOR_CLAUDE" analysis_level: "build" - trigger: "always" + trigger: "on-failure" custom_prompt: "Do not mention successful points, focus on failures and recovery to keep the analysis succint. Only add the `Best Practices` section if the changes in this PR are directly relevant to it. Only add a `Root Cause` section when you're sure about the issues' causes." model: "claude-sonnet-4-5" From 9b8c843270258355f82e6e1ac04cd1e76368da6c Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Wed, 7 Jan 2026 17:48:43 +0100 Subject: [PATCH 08/13] Use forked Claude Summarize Plugin version --- .buildkite/shared-pipeline-vars | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/shared-pipeline-vars b/.buildkite/shared-pipeline-vars index 75bc5b5a170a..ac2cb0ac30cc 100755 --- a/.buildkite/shared-pipeline-vars +++ b/.buildkite/shared-pipeline-vars @@ -9,4 +9,4 @@ CI_TOOLKIT_PLUGIN_VERSION="5.3.1" export IMAGE_ID="xcode-$XCODE_VERSION" export CI_TOOLKIT_PLUGIN="automattic/a8c-ci-toolkit#$CI_TOOLKIT_PLUGIN_VERSION" -export CLAUDE_PLUGIN="claude-summarize#v1.1.0" +export CLAUDE_PLUGIN="iangmaia/claude-summarize#iangmaia/add-build-log-mode" From 5c6f962e438477ad36567a583f26cd74650cd772 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Wed, 7 Jan 2026 19:08:53 +0100 Subject: [PATCH 09/13] Add buildkite logs as artifact --- .buildkite/claude-analysis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.buildkite/claude-analysis.yml b/.buildkite/claude-analysis.yml index 27f3ab852402..e5854f8aa3a8 100644 --- a/.buildkite/claude-analysis.yml +++ b/.buildkite/claude-analysis.yml @@ -15,6 +15,7 @@ steps: artifact_paths: - "/tmp/claude_debug_${BUILDKITE_BUILD_ID}.txt" - "/tmp/claude_response_${BUILDKITE_BUILD_ID}.json" + - "/tmp/buildkite_logs_${BUILDKITE_BUILD_ID}.txt" plugins: - $CLAUDE_PLUGIN: api_key: "$ANTHROPIC_API_KEY" From e349939ef796460a291340f80a7080dc01dd44c9 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Wed, 7 Jan 2026 20:04:24 +0100 Subject: [PATCH 10/13] Comment out Keystone Unit Tests and increase max log lines --- .buildkite/claude-analysis.yml | 2 ++ .buildkite/pipeline.yml | 22 +++++++++------------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/.buildkite/claude-analysis.yml b/.buildkite/claude-analysis.yml index e5854f8aa3a8..91d3d8db894f 100644 --- a/.buildkite/claude-analysis.yml +++ b/.buildkite/claude-analysis.yml @@ -21,7 +21,9 @@ steps: api_key: "$ANTHROPIC_API_KEY" buildkite_api_token: "$BUILDKITE_TOKEN_FOR_CLAUDE" analysis_level: "build" + build_log_mode: "failed" trigger: "on-failure" + max_log_lines: 1500 custom_prompt: "Do not mention successful points, focus on failures and recovery to keep the analysis succint. Only add the `Best Practices` section if the changes in this PR are directly relevant to it. Only add a `Root Cause` section when you're sure about the issues' causes." model: "claude-sonnet-4-5" diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 74e27df70fb4..d6d97b2db681 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -116,19 +116,15 @@ steps: notify: - github_commit_status: context: "Reader Unit Tests" - - label: "🔬 Keystone Unit Tests" - command: .buildkite/commands/run-unit-tests-for-scheme.sh Keystone - # Disabled till https://github.com/wordpress-mobile/WordPress-iOS/pull/24537 is completed - # - # The boolean value has to be a string explicitly. - # See validation error against schema. - if: "false" - plugins: [$CI_TOOLKIT_PLUGIN] - artifact_paths: - - "build/results/*" - notify: - - github_commit_status: - context: "Unit Tests Keystone" + # Disabled till https://github.com/wordpress-mobile/WordPress-iOS/pull/24537 is completed + # - label: "🔬 Keystone Unit Tests" + # command: .buildkite/commands/run-unit-tests-for-scheme.sh Keystone + # plugins: [$CI_TOOLKIT_PLUGIN] + # artifact_paths: + # - "build/results/*" + # notify: + # - github_commit_status: + # context: "Unit Tests Keystone" - label: "🔬 WordPressData Unit Tests" command: .buildkite/commands/run-unit-tests-for-scheme.sh WordPressData plugins: [$CI_TOOLKIT_PLUGIN] From d3aa906c3702f46b759d54b71bc5d512b09cdd87 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Thu, 8 Jan 2026 12:37:09 +0100 Subject: [PATCH 11/13] [TO REVERT] Test compilation error --- .../Classes/Utility/Networking/RequestAuthenticator.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WordPress/Classes/Utility/Networking/RequestAuthenticator.swift b/WordPress/Classes/Utility/Networking/RequestAuthenticator.swift index 2bf93dc32667..c73803fa4943 100644 --- a/WordPress/Classes/Utility/Networking/RequestAuthenticator.swift +++ b/WordPress/Classes/Utility/Networking/RequestAuthenticator.swift @@ -9,6 +9,9 @@ import WordPressData /// Unfortunately the effort required for this makes it unfeasible for me to focus on it /// right now, as it involves also moving at least CookieJar, AuthenticationService and AtomicAuthenticationService over there as well. - @diegoreymendez /// + +test compilation error + class RequestAuthenticator: NSObject { enum DotComAuthenticationType { From 0b0f017f787e17344c967aaa499c99233f4e7c8e Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Thu, 8 Jan 2026 12:59:34 +0100 Subject: [PATCH 12/13] Revert "[TO REVERT] Test compilation error" This reverts commit d3aa906c3702f46b759d54b71bc5d512b09cdd87. --- .../Classes/Utility/Networking/RequestAuthenticator.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/WordPress/Classes/Utility/Networking/RequestAuthenticator.swift b/WordPress/Classes/Utility/Networking/RequestAuthenticator.swift index c73803fa4943..2bf93dc32667 100644 --- a/WordPress/Classes/Utility/Networking/RequestAuthenticator.swift +++ b/WordPress/Classes/Utility/Networking/RequestAuthenticator.swift @@ -9,9 +9,6 @@ import WordPressData /// Unfortunately the effort required for this makes it unfeasible for me to focus on it /// right now, as it involves also moving at least CookieJar, AuthenticationService and AtomicAuthenticationService over there as well. - @diegoreymendez /// - -test compilation error - class RequestAuthenticator: NSObject { enum DotComAuthenticationType { From d6cc669528c5543be6955c0193564384def8459c Mon Sep 17 00:00:00 2001 From: "Ian G. Maia" Date: Fri, 9 Jan 2026 19:39:59 +0100 Subject: [PATCH 13/13] Apply suggestions from code review Co-authored-by: Gio Lodi --- .buildkite/claude-analysis.yml | 2 +- .buildkite/pipeline.yml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.buildkite/claude-analysis.yml b/.buildkite/claude-analysis.yml index 91d3d8db894f..7bde6d19b87b 100644 --- a/.buildkite/claude-analysis.yml +++ b/.buildkite/claude-analysis.yml @@ -24,7 +24,7 @@ steps: build_log_mode: "failed" trigger: "on-failure" max_log_lines: 1500 - custom_prompt: "Do not mention successful points, focus on failures and recovery to keep the analysis succint. Only add the `Best Practices` section if the changes in this PR are directly relevant to it. Only add a `Root Cause` section when you're sure about the issues' causes." + custom_prompt: "Do not mention successful points, focus on failures and recovery to keep the analysis succinct. Only add the `Best Practices` section if the changes in this PR are directly relevant to it. Only add a `Root Cause` section when you're sure about the issues' causes." model: "claude-sonnet-4-5" - label: ":claude: 💬 Comment Claude Analysis" diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index d6d97b2db681..109db5f1e597 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -220,4 +220,3 @@ steps: allow_dependency_failure: true agents: queue: upload -