From 4befabf3f2d7541b2fe29198523cc51ae8531779 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Sat, 27 Jun 2026 15:40:47 -0400 Subject: [PATCH 1/3] =?UTF-8?q?Add=20scheduled=20trunk=20=E2=86=92=20Play?= =?UTF-8?q?=20internal=20build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New build_and_upload_trunk_internal lane builds WordPress & Jetpack from trunk and uploads them to the Play Store internal track, to validate the release-from-trunk model. versionName = planned release (no -rc); versionCode via release-toolkit's ContinuousBuildCodeFormatter, written to version.properties for the build only (not committed). Adds a command script + a scheduled pipeline (manually triggerable via the PIPELINE env). --- .buildkite/commands/build-trunk-internal.sh | 10 ++++ .buildkite/schedules/build-trunk-internal.yml | 22 ++++++++ fastlane/lanes/build.rb | 53 +++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100755 .buildkite/commands/build-trunk-internal.sh create mode 100644 .buildkite/schedules/build-trunk-internal.yml diff --git a/.buildkite/commands/build-trunk-internal.sh b/.buildkite/commands/build-trunk-internal.sh new file mode 100755 index 000000000000..3c149a1da8f8 --- /dev/null +++ b/.buildkite/commands/build-trunk-internal.sh @@ -0,0 +1,10 @@ +#!/bin/bash -eu + +echo "--- :rubygems: Setting up Gems" +install_gems + +echo "--- :closed_lock_with_key: Installing Secrets" +bundle exec fastlane run configure_apply + +echo "--- :hammer_and_wrench: Build WordPress & Jetpack and upload to the Play internal track" +bundle exec fastlane build_and_upload_trunk_internal skip_confirm:true skip_prechecks:true diff --git a/.buildkite/schedules/build-trunk-internal.yml b/.buildkite/schedules/build-trunk-internal.yml new file mode 100644 index 000000000000..6c246bbf2b71 --- /dev/null +++ b/.buildkite/schedules/build-trunk-internal.yml @@ -0,0 +1,22 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/buildkite/pipeline-schema/main/schema.json +--- + +# Builds WordPress & Jetpack from `trunk` and uploads them to the Play Store `internal` testing +# track, to validate the "release from trunk" model. Runs on a schedule (configured in the +# Buildkite UI); also triggerable manually via the `PIPELINE` env var for testing. + +agents: + queue: "android" + +steps: + - label: ":android: Build trunk → Play internal" + command: .buildkite/commands/build-trunk-internal.sh + plugins: [$CI_TOOLKIT] + +# Failure notifications are disabled for now. If re-enabled, they go to #wpmobile. +# notify: +# - slack: +# channels: +# - "#wpmobile" +# message: "Trunk → Play internal build failed." +# if: build.state == "failed" diff --git a/fastlane/lanes/build.rb b/fastlane/lanes/build.rb index ac11e2872ce0..bf1d7ba6bcae 100644 --- a/fastlane/lanes/build.rb +++ b/fastlane/lanes/build.rb @@ -111,6 +111,59 @@ create_gh_release(app: app, version_name: version_name, prerelease: true) if options[:create_release] end + ##################################################################################### + # build_and_upload_trunk_internal + # ----------------------------------------------------------------------------------- + # Builds WordPress & Jetpack from the current commit and uploads them to the Play Store + # `internal` testing track. Intended to run from `trunk` (manually or on a schedule) to + # validate the "release from trunk" model. + # + # The version is computed on the fly and written to `version.properties` for the build + # only — it is NOT committed: + # - versionName: the planned release version (without the `-rc-N` suffix) + # - versionCode: via release-toolkit's `ContinuousBuildCodeFormatter`, + # i.e. `(major * 10 + minor) * 1_000_000 + BUILDKITE_BUILD_NUMBER` + # ----------------------------------------------------------------------------------- + # Usage: + # bundle exec fastlane build_and_upload_trunk_internal [skip_confirm:] [skip_prechecks:] + ##################################################################################### + desc 'Build WordPress & Jetpack from trunk and upload them to the Play Store internal track' + lane :build_and_upload_trunk_internal do |options| + version_name = current_release_version + + unless options[:skip_prechecks] + ensure_git_branch(branch: DEFAULT_BRANCH) unless is_ci + + ensure_git_status_clean unless is_ci + + UI.important("Building #{version_name} for upload to the Play Store internal track") + + UI.user_error!('Aborted by user request') unless options[:skip_confirm] || UI.confirm('Do you want to continue?') + + android_build_preflight + end + + version = VERSION_FORMATTER.parse(version_name) + build_code = Fastlane::Wpmreleasetoolkit::Versioning::ContinuousBuildCodeFormatter.new.build_code( + major: version.major, + minor: version.minor, + build_number: Integer(ENV.fetch('BUILDKITE_BUILD_NUMBER')) + ) + + UI.important("Building trunk internal build: #{version_name} (#{build_code})") + + # Set the version for this build only. We deliberately do not commit this change. + VERSION_FILE.write_version(version_name: version_name, version_code: build_code) + + %i[wordpress jetpack].each do |app| + build_bundle(app: app, version_name: version_name, build_code: build_code, buildType: 'Release') + upload_build_to_play_store(app: app, version_name: version_name, track: 'internal') + # `upload_gutenberg_sourcemaps` builds a file path from the app name, so it needs a String + # (a Symbol can't be passed to `File.join`). + upload_gutenberg_sourcemaps(app: app.to_s, release_version: version_name) + end + end + ##################################################################################### # upload_build_to_play_store # ----------------------------------------------------------------------------------- From b51880a608969bc729ebc54e5d05c083cdbc02a1 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Wed, 1 Jul 2026 17:29:10 -0400 Subject: [PATCH 2/3] Send trunk internal build notifications to #build-and-ship --- .buildkite/schedules/build-trunk-internal.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.buildkite/schedules/build-trunk-internal.yml b/.buildkite/schedules/build-trunk-internal.yml index 6c246bbf2b71..1a03c4452eab 100644 --- a/.buildkite/schedules/build-trunk-internal.yml +++ b/.buildkite/schedules/build-trunk-internal.yml @@ -12,11 +12,5 @@ steps: - label: ":android: Build trunk → Play internal" command: .buildkite/commands/build-trunk-internal.sh plugins: [$CI_TOOLKIT] - -# Failure notifications are disabled for now. If re-enabled, they go to #wpmobile. -# notify: -# - slack: -# channels: -# - "#wpmobile" -# message: "Trunk → Play internal build failed." -# if: build.state == "failed" + notify: + - slack: "#build-and-ship" From bd2100961a0e852487bcf0a09c7f1a5fbb4459cc Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Fri, 10 Jul 2026 23:03:45 -0400 Subject: [PATCH 3/3] Address review feedback: shebang, named lane params, env guard --- .buildkite/commands/build-trunk-internal.sh | 4 +++- fastlane/lanes/build.rb | 14 +++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.buildkite/commands/build-trunk-internal.sh b/.buildkite/commands/build-trunk-internal.sh index 3c149a1da8f8..fd99d379ac70 100755 --- a/.buildkite/commands/build-trunk-internal.sh +++ b/.buildkite/commands/build-trunk-internal.sh @@ -1,4 +1,6 @@ -#!/bin/bash -eu +#!/usr/bin/env bash + +set -eu echo "--- :rubygems: Setting up Gems" install_gems diff --git a/fastlane/lanes/build.rb b/fastlane/lanes/build.rb index bf1d7ba6bcae..f9a01e764a9f 100644 --- a/fastlane/lanes/build.rb +++ b/fastlane/lanes/build.rb @@ -128,29 +128,33 @@ # bundle exec fastlane build_and_upload_trunk_internal [skip_confirm:] [skip_prechecks:] ##################################################################################### desc 'Build WordPress & Jetpack from trunk and upload them to the Play Store internal track' - lane :build_and_upload_trunk_internal do |options| + lane :build_and_upload_trunk_internal do |skip_prechecks: false, skip_confirm: false| version_name = current_release_version - unless options[:skip_prechecks] + unless skip_prechecks ensure_git_branch(branch: DEFAULT_BRANCH) unless is_ci ensure_git_status_clean unless is_ci UI.important("Building #{version_name} for upload to the Play Store internal track") - UI.user_error!('Aborted by user request') unless options[:skip_confirm] || UI.confirm('Do you want to continue?') + UI.user_error!('Aborted by user request') unless skip_confirm || UI.confirm('Do you want to continue?') android_build_preflight end + build_number = ENV.fetch('BUILDKITE_BUILD_NUMBER') do + UI.user_error!('BUILDKITE_BUILD_NUMBER is not set; the versionCode derives from it (Buildkite only).') + end + version = VERSION_FORMATTER.parse(version_name) build_code = Fastlane::Wpmreleasetoolkit::Versioning::ContinuousBuildCodeFormatter.new.build_code( major: version.major, minor: version.minor, - build_number: Integer(ENV.fetch('BUILDKITE_BUILD_NUMBER')) + build_number: Integer(build_number) ) - UI.important("Building trunk internal build: #{version_name} (#{build_code})") + UI.important("Building #{DEFAULT_BRANCH} internal build: #{version_name} (#{build_code})") # Set the version for this build only. We deliberately do not commit this change. VERSION_FILE.write_version(version_name: version_name, version_code: build_code)