diff --git a/.buildkite/release-pipelines/publish-release.yml b/.buildkite/release-pipelines/publish-release.yml new file mode 100644 index 000000000000..ddc73f278fa4 --- /dev/null +++ b/.buildkite/release-pipelines/publish-release.yml @@ -0,0 +1,31 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/buildkite/pipeline-schema/main/schema.json +--- + +agents: + queue: mac + +env: + IMAGE_ID: $IMAGE_ID + +steps: + - label: Publish Release + plugins: [$CI_TOOLKIT_PLUGIN] + command: | + echo '--- :git: Configure Git for release management' + .buildkite/commands/configure-git-for-release-management.sh + + echo '--- :git: Checkout release branch' + .buildkite/commands/checkout-release-branch.sh $RELEASE_VERSION + + echo '--- :ruby: Setup Ruby tools' + install_gems + + echo '--- :closed_lock_with_key: Access secrets' + bundle exec fastlane run configure_apply + + echo '--- :package: Publish Release' + bundle exec fastlane publish_release skip_confirm:true + retry: + manual: + # If those jobs fail, one should always prefer re-triggering a new build from ReleaseV2 rather than retrying the individual job from Buildkite + allowed: false diff --git a/Gemfile b/Gemfile index 3ff95462ebef..3556736476d7 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source 'https://rubygems.org' gem 'cocoapods', '~> 1.14' -gem 'danger-dangermattic', '~> 1.0' +gem 'danger-dangermattic', '~> 1.1' gem 'dotenv' # 2.221.0 includes a fix for an ASC-interfacing bug # @@ -15,7 +15,7 @@ gem 'fastlane-plugin-sentry' # This comment avoids typing to switch to a development version for testing. # # gem 'fastlane-plugin-wpmreleasetoolkit', git: 'https://github.com/wordpress-mobile/release-toolkit', ref: '' -gem 'fastlane-plugin-wpmreleasetoolkit', '~> 11.0' +gem 'fastlane-plugin-wpmreleasetoolkit', '~> 12.0' gem 'rake' gem 'rubocop', '~> 1.60' gem 'rubocop-rake', '~> 0.6' diff --git a/Gemfile.lock b/Gemfile.lock index 443ed025f6f4..3c946df805c6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,16 +5,17 @@ GEM base64 nkf rexml - activesupport (7.1.3.4) + activesupport (7.2.1) base64 bigdecimal - concurrent-ruby (~> 1.0, >= 1.0.2) + concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) - mutex_m - tzinfo (~> 2.0) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) algoliasearch (1.27.5) @@ -24,17 +25,17 @@ GEM ast (2.4.2) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.962.0) - aws-sdk-core (3.201.3) + aws-partitions (1.975.0) + aws-sdk-core (3.205.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) - aws-sigv4 (~> 1.8) + aws-sigv4 (~> 1.9) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.88.0) - aws-sdk-core (~> 3, >= 3.201.0) + aws-sdk-kms (1.91.0) + aws-sdk-core (~> 3, >= 3.205.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.157.0) - aws-sdk-core (~> 3, >= 3.201.0) + aws-sdk-s3 (1.162.0) + aws-sdk-core (~> 3, >= 3.205.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) aws-sigv4 (1.9.1) @@ -91,7 +92,7 @@ GEM colored2 (3.1.2) commander (4.6.0) highline (~> 2.0.0) - concurrent-ruby (1.3.3) + concurrent-ruby (1.3.4) connection_pool (2.4.1) cork (0.3.0) colored2 (~> 3.1) @@ -204,7 +205,7 @@ GEM fastlane-plugin-appcenter (2.1.2) fastlane-plugin-sentry (1.24.0) os (~> 1.1, >= 1.1.4) - fastlane-plugin-wpmreleasetoolkit (11.1.0) + fastlane-plugin-wpmreleasetoolkit (12.1.0) activesupport (>= 6.1.7.1) buildkit (~> 1.5) chroma (= 0.2.0) @@ -213,7 +214,7 @@ GEM git (~> 1.3) google-cloud-storage (~> 1.31) java-properties (~> 0.3.0) - nokogiri (~> 1.11, < 1.17) + nokogiri (~> 1.11) octokit (~> 6.1) parallel (~> 1.14) plist (~> 3.1) @@ -265,29 +266,29 @@ GEM os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) highline (2.0.3) - http-cookie (1.0.6) + http-cookie (1.0.7) domain_name (~> 0.5) httpclient (2.8.3) - i18n (1.14.5) + i18n (1.14.6) concurrent-ruby (~> 1.0) java-properties (0.3.0) jmespath (1.6.2) json (2.7.2) - jwt (2.8.2) + jwt (2.9.0) base64 kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) language_server-protocol (3.17.0.3) + logger (1.6.1) mini_magick (4.13.2) mini_mime (1.1.5) mini_portile2 (2.8.7) - minitest (5.24.1) + minitest (5.25.1) molinillo (0.8.0) multi_json (1.15.0) multipart-post (2.4.1) - mutex_m (0.2.0) nanaimo (0.3.0) nap (1.1.0) naturally (2.2.1) @@ -303,7 +304,7 @@ GEM options (2.3.2) optparse (0.5.0) os (1.1.4) - parallel (1.25.1) + parallel (1.26.3) parser (3.3.4.1) ast (~> 2.4.1) racc @@ -325,8 +326,7 @@ GEM trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) retriable (3.1.2) - rexml (3.3.6) - strscan + rexml (3.3.7) rmagick (5.3.0) pkg-config (~> 1.4) rouge (2.0.7) @@ -352,6 +352,7 @@ GEM sawyer (0.9.2) addressable (>= 2.3.5) faraday (>= 0.17.3, < 3) + securerandom (0.3.1) security (0.1.5) signet (0.19.0) addressable (~> 2.8) @@ -361,7 +362,6 @@ GEM simctl (1.6.10) CFPropertyList naturally - strscan (3.1.0) terminal-notifier (2.0.0) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) @@ -375,7 +375,7 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) uber (0.1.0) - unicode-display_width (2.5.0) + unicode-display_width (2.6.0) word_wrap (1.0.0) xcodeproj (1.25.0) CFPropertyList (>= 2.3.3, < 4.0) @@ -394,12 +394,12 @@ PLATFORMS DEPENDENCIES cocoapods (~> 1.14) - danger-dangermattic (~> 1.0) + danger-dangermattic (~> 1.1) dotenv fastlane (~> 2.221) fastlane-plugin-appcenter (~> 2.1) fastlane-plugin-sentry - fastlane-plugin-wpmreleasetoolkit (~> 11.0) + fastlane-plugin-wpmreleasetoolkit (~> 12.0) rake rmagick (~> 5.3.0) rubocop (~> 1.60) diff --git a/fastlane/lanes/build.rb b/fastlane/lanes/build.rb index f11ae30f87a2..e79816f0d97b 100644 --- a/fastlane/lanes/build.rb +++ b/fastlane/lanes/build.rb @@ -209,7 +209,7 @@ release_version = release_version_current version = options[:beta_release] ? build_code : release_version - release_url = create_release( + release_url = create_github_release( repository: GITHUB_REPO, version: version, release_notes_file_path: WORDPRESS_RELEASE_NOTES_PATH, diff --git a/fastlane/lanes/release.rb b/fastlane/lanes/release.rb index 2c47359caf33..6a0456ac870c 100644 --- a/fastlane/lanes/release.rb +++ b/fastlane/lanes/release.rb @@ -13,7 +13,6 @@ # desc 'Executes the initial steps needed during code freeze' lane :code_freeze do |options| - # Verify that there's nothing in progress in the working copy ensure_git_status_clean # Check out the up-to-date default branch, the designated starting point for the code freeze @@ -367,7 +366,7 @@ UI.user_error!("Terminating as requested. Don't forget to run the remainder of this automation manually.") end - trigger_release_build(branch_to_build: "release/#{hotfix_version}") + trigger_release_build(branch_to_build: release_branch_name(version: hotfix_version)) create_backmerge_pr @@ -435,6 +434,49 @@ end end + # This lane publishes a release on GitHub and creates a PR to backmerge the current release branch into the next release/ branch + # + # @param [Boolean] skip_confirm (default: false) If set, will skip the confirmation prompt before running the rest of the lane + # + # @example Running the lane + # bundle exec fastlane publish_release skip_confirm:true + # + lane :publish_release do |skip_confirm: false| + ensure_git_status_clean + ensure_git_branch_is_release_branch! + + version_number = release_version_current + + current_branch = release_branch_name(version: version_number) + next_release_branch = release_branch_name(version: release_version_next) + + UI.important <<~PROMPT + Publish the #{version_number} release. This will: + - Publish the existing draft `#{version_number}` release on GitHub + - Which will also have GitHub create the associated git tag, pointing to the tip of the branch + - If the release branch for the next version `#{next_release_branch}` already exists, backmerge `#{current_branch}` into it + - If needed, backmerge `#{current_branch}` back into `#{DEFAULT_BRANCH}` + - Delete the `#{current_branch}` branch + PROMPT + unless skip_confirm || UI.confirm('Do you want to continue?') + UI.user_error!("Terminating as requested. Don't forget to run the remainder of this automation manually.") + end + + UI.important "Publishing release #{version_number} on GitHub" + + publish_github_release( + repository: GITHUB_REPO, + name: version_number + ) + + create_backmerge_pr + + # At this point, an intermediate branch has been created by creating a backmerge PR to a hotfix or the next version release branch. + # This allows us to safely delete the `release/*` branch. + # Note that if a hotfix or new release branches haven't been created, the backmerge PR won't be created as well. + delete_remote_git_branch!(current_branch) + end + # Triggers a beta build on CI # # @option [String] branch The name of the branch we want the CI to build, e.g. `release/19.3`. Defaults to `release/` @@ -577,7 +619,7 @@ def create_backmerge_pr pr_url = create_release_backmerge_pull_request( repository: GITHUB_REPO, - source_branch: "release/#{version}", + source_branch: release_branch_name(version: version), labels: ['Releases'], milestone_title: release_version_next ) @@ -614,6 +656,14 @@ def ensure_branch_does_not_exist!(branch_name) UI.user_error!(error_message) end +# Delete a branch remotely, after having removed any GitHub branch protection +# +def delete_remote_git_branch!(branch_name) + remove_branch_protection(repository: GITHUB_REPO, branch: branch_name) + + Git.open(Dir.pwd).push('origin', branch_name, delete: true) +end + def report_milestone_error(error_title:) error_message = <<-MESSAGE #{error_title}