From 921742d8ec8c951dbcea9c65bdb50f2316db976e Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 3 Mar 2026 13:31:37 +0100 Subject: [PATCH 1/3] Upload CDN builds as internal first, then publish as external in publish_release Co-Authored-By: Claude Opus 4.6 --- fastlane/Fastfile | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 71690823c4..382a890288 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -274,7 +274,7 @@ lane :finalize_release do |version:, skip_confirm: false| Finalizing release #{version}. This will: - Bump version to #{version} (remove beta suffix) - Trigger a release build for all platforms (macOS, Windows), which will then: - - Upload build artifacts to the Apps CDN + - Upload build artifacts to the Apps CDN (as Internal, visible only to Automatticians) - Create a draft GitHub release with release notes and download links - Notify #dotcom-studio on Slack PROMPT @@ -300,12 +300,16 @@ lane :publish_release do |version:, skip_confirm: false, github_username: nil| UI.important <<~PROMPT Publishing release #{version}. This will: + - Make CDN builds public (change visibility from Internal to External) - Publish the draft GitHub release for v#{version} - Create a backmerge PR from `#{release_branch}` into `#{MAIN_BRANCH}` - Delete the `#{release_branch}` branch after creating the backmerge PR PROMPT next unless skip_confirm || UI.confirm('Continue?') + # Update CDN build visibility from Internal to External + make_cdn_builds_public(version: version) + # Publish the draft GitHub release publish_github_release( repository: GITHUB_REPO, @@ -581,7 +585,7 @@ def distribute_builds( arch: build[:arch], build_type: build_type, install_type: build[:install_type], - visibility: 'external', + visibility: :internal, version: version, build_number: build_number, release_notes: release_notes, @@ -819,6 +823,37 @@ def create_draft_github_release(version:, release_tag:, builds:) UI.success("Created draft GitHub release #{release_tag} with download links") end +# Make CDN builds public by updating their visibility from Internal to External. +# +# Queries the Apps CDN API to find internal builds matching the version, +# then calls {update_apps_cdn_build_metadata} for each to set visibility to External. +# +# @param version [String] The version to publish (e.g., '1.7.5') +# +def make_cdn_builds_public(version:) + release_version = "v#{version}" + builds = list_apps_cdn_builds( + site_id: WPCOM_STUDIO_SITE_ID, + version: release_version, + visibility: :internal + ) + + UI.user_error!("No internal CDN builds found for #{release_version}. Cannot publish without updating CDN visibility.") if builds.empty? + + UI.message("Updating CDN build visibility to External for #{builds.size} builds...") + + builds.each do |build| + UI.message(" Updating #{build[:title]} (post #{build[:post_id]})...") + update_apps_cdn_build_metadata( + site_id: WPCOM_STUDIO_SITE_ID, + post_id: build[:post_id], + visibility: :external + ) + end + + UI.success('All CDN builds are now public (External visibility)') +end + # Trigger a release build in Buildkite for the given version. # # Uses `buildkite_add_trigger_step` on CI (to create a separate build with proper Git mirroring) From c9467e992a6d23beb5a5dbf04cb552dfa953bf05 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Tue, 3 Mar 2026 14:26:10 +0100 Subject: [PATCH 2/3] Make make_cdn_builds_public idempotent for safe retries If publish_release is rerun after a partial failure, the builds may already be external. Warn and continue instead of erroring out. Co-Authored-By: Claude Opus 4.6 --- fastlane/Fastfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 382a890288..c801495d6c 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -838,7 +838,10 @@ def make_cdn_builds_public(version:) visibility: :internal ) - UI.user_error!("No internal CDN builds found for #{release_version}. Cannot publish without updating CDN visibility.") if builds.empty? + if builds.empty? + UI.important("No internal CDN builds found for #{release_version}. They may have already been made public.") + return + end UI.message("Updating CDN build visibility to External for #{builds.size} builds...") From de78155dc96f4ea947532d11511027fb762402f4 Mon Sep 17 00:00:00 2001 From: Ian Maia Date: Wed, 4 Mar 2026 14:08:32 +0100 Subject: [PATCH 3/3] Switch CDN uploads to draft/publish flow instead of internal/external visibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upload release builds as external+draft, then publish them in publish_release. The CDN plugin hides internal-visibility posts from all API queries, making the previous internal→external approach unworkable. Co-Authored-By: Claude Opus 4.6 --- fastlane/Fastfile | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index c801495d6c..e318318bb3 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -274,7 +274,7 @@ lane :finalize_release do |version:, skip_confirm: false| Finalizing release #{version}. This will: - Bump version to #{version} (remove beta suffix) - Trigger a release build for all platforms (macOS, Windows), which will then: - - Upload build artifacts to the Apps CDN (as Internal, visible only to Automatticians) + - Upload build artifacts to the Apps CDN (as drafts, published later by publish_release) - Create a draft GitHub release with release notes and download links - Notify #dotcom-studio on Slack PROMPT @@ -300,7 +300,7 @@ lane :publish_release do |version:, skip_confirm: false, github_username: nil| UI.important <<~PROMPT Publishing release #{version}. This will: - - Make CDN builds public (change visibility from Internal to External) + - Publish CDN builds (change post status from draft to publish) - Publish the draft GitHub release for v#{version} - Create a backmerge PR from `#{release_branch}` into `#{MAIN_BRANCH}` - Delete the `#{release_branch}` branch after creating the backmerge PR @@ -585,7 +585,8 @@ def distribute_builds( arch: build[:arch], build_type: build_type, install_type: build[:install_type], - visibility: :internal, + visibility: :external, + post_status: release_tag&.match?(/beta/i) ? nil : 'draft', version: version, build_number: build_number, release_notes: release_notes, @@ -823,10 +824,11 @@ def create_draft_github_release(version:, release_tag:, builds:) UI.success("Created draft GitHub release #{release_tag} with download links") end -# Make CDN builds public by updating their visibility from Internal to External. +# Publish CDN builds by changing their post status from draft to publish. # -# Queries the Apps CDN API to find internal builds matching the version, -# then calls {update_apps_cdn_build_metadata} for each to set visibility to External. +# Queries the Apps CDN API to find draft builds matching the version, +# then calls {update_apps_cdn_build_metadata} for each to set status to publish. +# This is idempotent: if no drafts are found (already published), it logs a warning and returns. # # @param version [String] The version to publish (e.g., '1.7.5') # @@ -835,26 +837,26 @@ def make_cdn_builds_public(version:) builds = list_apps_cdn_builds( site_id: WPCOM_STUDIO_SITE_ID, version: release_version, - visibility: :internal + post_status: 'draft' ) if builds.empty? - UI.important("No internal CDN builds found for #{release_version}. They may have already been made public.") + UI.important("No draft CDN builds found for #{release_version}. They may have already been published.") return end - UI.message("Updating CDN build visibility to External for #{builds.size} builds...") + UI.message("Publishing #{builds.size} CDN build(s) for #{release_version}...") builds.each do |build| - UI.message(" Updating #{build[:title]} (post #{build[:post_id]})...") + UI.message(" Publishing #{build[:title]} (post #{build[:post_id]})...") update_apps_cdn_build_metadata( site_id: WPCOM_STUDIO_SITE_ID, post_id: build[:post_id], - visibility: :external + post_status: 'publish' ) end - UI.success('All CDN builds are now public (External visibility)') + UI.success('All CDN builds are now published') end # Trigger a release build in Buildkite for the given version.