Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 drafts, published later by publish_release)
- Create a draft GitHub release with release notes and download links
- Notify #dotcom-studio on Slack
PROMPT
Expand All @@ -300,12 +300,16 @@ lane :publish_release do |version:, skip_confirm: false, github_username: nil|

UI.important <<~PROMPT
Publishing release #{version}. This will:
- 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
PROMPT
next unless skip_confirm || UI.confirm('Continue?')

# Update CDN build visibility from Internal to External
make_cdn_builds_public(version: version)
Comment on lines +310 to +311
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not consistent with what it currently does, which is not about making it public and changing it from internal to external, but about changing it from draft to published…

Of course this might change back depending of if using the Draft state was indeed the right move (i.e. if it still allows this build to be easily downloadable and testable by the team and RM for smoke-testing) or if we're gonna switch back to using internal vs external.


# Publish the draft GitHub release
publish_github_release(
repository: GITHUB_REPO,
Expand Down Expand Up @@ -581,7 +585,8 @@ def distribute_builds(
arch: build[:arch],
build_type: build_type,
install_type: build[:install_type],
visibility: 'external',
visibility: :external,
post_status: release_tag&.match?(/beta/i) ? nil : 'draft',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure the condition is right here?

This means that the first beta post code freeze as well as the intermediate betas that occur in the middle of the release will be uploaded as draft (and then never published). While those should probably be internal instead.

That also means that the final build we do at the end of the release process, the one that drops the beta suffix because it's supposed to be the final version, will not match the /beta/i RegEx, and thus will be uploaded as non-draft. While it's exactly not what we want.

Also, based on the code at the start of this lane, there also exists "Nightly Builds"—for which release_tag is nil, which means means this will publish those as non-draft as well.


I think instead we should:

  • For build_type of both Nightly and Beta, use visibility: :internal but post_status: 'publish', so that they are published but only internally
  • For build_type == 'Production builds, especially the final build done at the end of the release scenario, use visibility: :external but post_status: 'draft'… until we get to the next stage in the Release Scenario to publish it once it has been smoke-tested.

version: version,
build_number: build_number,
release_notes: release_notes,
Expand Down Expand Up @@ -819,6 +824,41 @@ def create_draft_github_release(version:, release_tag:, builds:)
UI.success("Created draft GitHub release #{release_tag} with download links")
end

# Publish CDN builds by changing their post status from draft to publish.
#
# 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')
#
def make_cdn_builds_public(version:)
release_version = "v#{version}"
builds = list_apps_cdn_builds(
site_id: WPCOM_STUDIO_SITE_ID,
version: release_version,
post_status: 'draft'
)
Comment on lines +836 to +841
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a risk—especially in the rare case that issues was found in a final release build and the team decides to make a new commit on the release/ branch then re-upload a new final build—that there would be more than one build with version v#{version} in the CDN for each platform, and that we'd then end up publishing all of them (the bad one as well as the subsequent one with the fix) instead of only the last one?

Tbh I'm not sure this is a case the current setup fully support yet anyway.

  • e.g. what happens to the version bump logic if you finalize_release once, which removes the -betaN suffix from the version, then find an issue and redo another finalize_release, would the logic that removes the -betaN be a no-op on the version already being X.Y.Z? Will it crash?
  • What about the AppsCDN side of things, is the CDN plugin ok with uploading a build with the same metadata (version, platform…) twice? Does it replace the old one with the new one in that case, or keep both entries (which is where your list_apps_cdn_builds call would return duplicates)

Maybe it's only a concern for a future iteration though. But I figured I'd still raise the question, including in case this informs our thoughts about using visibility: :internal and not using list_apps_cdn_builds but storing the post_id values at initial upload time somewhere instead.


if builds.empty?
UI.important("No draft CDN builds found for #{release_version}. They may have already been published.")
return
end

UI.message("Publishing #{builds.size} CDN build(s) for #{release_version}...")

builds.each do |build|
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],
post_status: 'publish'
)
end

UI.success('All CDN builds are now published')
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)
Expand Down