diff --git a/.buildkite/release-pipelines/download-translations.yml b/.buildkite/release-pipelines/download-translations.yml deleted file mode 100644 index ba3cbc31e2..0000000000 --- a/.buildkite/release-pipelines/download-translations.yml +++ /dev/null @@ -1,26 +0,0 @@ -# yaml-language-server: $schema=https://raw.githubusercontent.com/buildkite/pipeline-schema/main/schema.json ---- - -env: - IMAGE_ID: $IMAGE_ID - -steps: - - label: ":earth_asia: Download Translations" - plugins: [$CI_TOOLKIT_PLUGIN, $NVM_PLUGIN] - command: | - echo "--- :robot_face: Use bot for Git operations" - source use-bot-for-git - - .buildkite/commands/checkout-release-branch.sh "${RELEASE_VERSION}" - - echo "--- :ruby: Setup Ruby Tools" - install_gems - - echo "--- :earth_asia: Download Translations" - bundle exec fastlane download_translations github_username:"${GITHUB_USERNAME}" skip_confirm:true - agents: - queue: mac - retry: - manual: - reason: If release jobs fail, you should always re-trigger the task from Releases V2 rather than retrying the individual job from Buildkite - allowed: false diff --git a/.buildkite/release-pipelines/new-beta-release.yml b/.buildkite/release-pipelines/new-beta-release.yml index e2043880ca..e295cddb49 100644 --- a/.buildkite/release-pipelines/new-beta-release.yml +++ b/.buildkite/release-pipelines/new-beta-release.yml @@ -17,7 +17,7 @@ steps: install_gems echo "--- :package: Create New Beta" - bundle exec fastlane new_beta_release version:"${RELEASE_VERSION}" skip_confirm:true + bundle exec fastlane new_beta_release version:"${RELEASE_VERSION}" github_username:"${GITHUB_USERNAME}" skip_confirm:true agents: queue: mac retry: diff --git a/docs/localization.md b/docs/localization.md index bf46ce4425..acb872c622 100644 --- a/docs/localization.md +++ b/docs/localization.md @@ -25,12 +25,13 @@ No manual steps are needed for string extraction or import. ### Export and Add (automated) -During **pre-release**, the `download_translations` Fastlane lane downloads translations -from GlotPress in Jed 1.x JSON format (which `@wordpress/i18n` understands) and creates -a PR to merge them into the release branch. It's ok if some translations are missing — -they will be left as English in the app. +During each **beta release**, the `new_beta_release` Fastlane lane downloads translations +from GlotPress in Jed 1.x JSON format (which `@wordpress/i18n` understands) and commits +them directly to the release branch before bumping the version. It's ok if some translations +are missing — they will be left as English in the app. The lane discovers locales from the existing `studio-*.jed.json` files in `tools/common/translations/` and downloads each one from GlotPress. -No manual steps are needed for translation export. +No manual steps are needed for translation export. The standalone `fetch_glotpress_translations` +lane can be used to manually download translations if needed. diff --git a/docs/release-process.md b/docs/release-process.md index 841326306a..9d6c3e9b50 100644 --- a/docs/release-process.md +++ b/docs/release-process.md @@ -14,21 +14,21 @@ Builds are signed, notarized (macOS), and uploaded to the Apps CDN automatically - Extracts translatable strings and commits them to the release branch (a wpcom cron imports them to GlotPress via a backmerge PR) - Generates draft release notes from merged PRs and commits them to the release branch - Creates a backmerge PR from the release branch into `trunk` -- Bumps version to `-beta1` and triggers a build (the build tags and uploads to CDN) ### 2. Beta Releases **ReleasesV2 milestone**: Beta Release | **Fastlane lane**: `new_beta_release` +- Downloads latest translations from GlotPress and commits them to the release branch - Increments the beta number (e.g. beta1 → beta2) - Triggers a build (the build tags the new version and uploads to CDN) +- Creates a backmerge PR from the release branch into `trunk` - Repeat as needed for additional betas ### 3. Pre-Release **ReleasesV2 milestone**: Pre-Release -- **Download translations**: Button triggers `download_translations` lane, which fetches translations from GlotPress and commits them to the release branch - **Release notes**: Review and refine the draft release notes in `RELEASE-NOTES.txt` on the `release/` branch (a draft is auto-generated during code freeze) - **Smoke tests**: Verify betas on macOS and Windows @@ -36,6 +36,7 @@ Builds are signed, notarized (macOS), and uploaded to the Apps CDN automatically **ReleasesV2 milestone**: Release | **Fastlane lane**: `finalize_release` +- Downloads latest translations from GlotPress (to capture any added during the beta period) - Removes beta suffix (sets version to ``) - Triggers the final release build, which uploads to the Apps CDN, creates a **draft** GitHub release with notes and download links, and notifies Slack diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 71690823c4..62763f418e 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -166,14 +166,18 @@ end # Release Management Lanes ######################################################################## -# Create a new release branch from trunk and the first beta. +# Create a new release branch from trunk, extract translatable strings, and generate draft release notes. # -# - Extracts translatable strings and commits them to the release branch (for GlotPress import) # - Creates a `release/` branch from trunk -# - Delegates to {new_beta_release} to bump to beta1, commit, push, tag, and trigger a build +# - Extracts translatable strings and commits them to the release branch (for GlotPress import) +# - Generates draft release notes from merged PRs and commits them to the release branch +# - Creates a backmerge PR from the release branch to trunk (so wpcom cron can import strings to GlotPress) +# +# The first beta is triggered separately via {new_beta_release}. # # @param version [String] The version to freeze (e.g., '1.7.4') # @param skip_confirm [Boolean] Skip interactive confirmation prompts (default: false) +# @param github_username [String, nil] GitHub username to assign as reviewer on the backmerge PR # lane :code_freeze do |version:, skip_confirm: false, github_username: nil| branch_name = "release/#{version}" @@ -184,9 +188,6 @@ lane :code_freeze do |version:, skip_confirm: false, github_username: nil| - Extract translatable strings and commit to `#{branch_name}` - Generate draft release notes from merged PRs - Create a backmerge PR from `#{branch_name}` to `#{MAIN_BRANCH}` - - Trigger the first beta build for all platforms (macOS, Windows), which will then: - - Upload build artifacts to the Apps CDN - - Notify #dotcom-studio on Slack PROMPT next unless skip_confirm || UI.confirm('Continue?') @@ -211,30 +212,29 @@ lane :code_freeze do |version:, skip_confirm: false, github_username: nil| push_to_git_remote(set_upstream: true) - # Create the first beta (bumps version, commits, pushes, tags, triggers build) - new_beta_release(version: version, skip_confirm: skip_confirm) - - # Create backmerge PR from the release branch to MAIN_BRANCH so that the pot strings bundle is uploaded to GlotPress once it hits trunk - # Important: this must come after new_beta_release because the backmerge action switches branches. + # Create backmerge PR so that the .pot strings file reaches trunk for GlotPress import create_backmerge_pr(source_branch: branch_name, github_username: github_username) - UI.success("Code freeze complete! Created #{branch_name} with first beta") + UI.success("Code freeze complete! Created #{branch_name}") end # Create a new beta release on the current release branch. # +# - Downloads latest translations from GlotPress and commits them # - Determines the next beta number automatically from package.json -# - Bumps the version, commits, tags, and triggers a release build +# - Bumps the version, commits, pushes, and triggers a release build +# - Creates a backmerge PR from the release branch to trunk # # @param version [String] The base release version (e.g., '1.7.4') # @param skip_confirm [Boolean] Skip interactive confirmation prompts (default: false) +# @param github_username [String, nil] GitHub username to assign as reviewer on the backmerge PR # -lane :new_beta_release do |version:, skip_confirm: false| +lane :new_beta_release do |version:, skip_confirm: false, github_username: nil| current_version = read_package_json_version current_beta = current_version[/beta(\d+)$/, 1].to_i # Guard against version mismatch (e.g. package.json has 1.7.4-beta3 but version param is 1.8.0) - # Skip the check when current_beta is 0, meaning this is the first beta (called from code_freeze before any bump). + # Skip the check when current_beta is 0, meaning this is the first beta (before any bump). if current_beta.positive? base_version = current_version.sub(/-beta\d+$/, '') UI.user_error!("Version mismatch: package.json has #{current_version} but expected #{version}-betaN") unless base_version == version @@ -244,23 +244,38 @@ lane :new_beta_release do |version:, skip_confirm: false| UI.important <<~PROMPT Creating new beta release #{new_version}. This will: + - Download latest translations from GlotPress - Bump version to #{new_version} - Trigger a release build for all platforms (macOS, Windows), which will then: - Upload build artifacts to the Apps CDN - Tag v#{new_version} - Notify #dotcom-studio on Slack + - Create a backmerge PR from the release branch to `#{MAIN_BRANCH}` PROMPT next unless skip_confirm || UI.confirm('Continue?') + # Download latest translations so they're included in the beta build + fetch_glotpress_translations + git_add(path: [TRANSLATIONS_DIR]) + git_commit( + path: [TRANSLATIONS_DIR], + message: '[skip ci] Update translations', + allow_nothing_to_commit: true + ) + bump_version_commit_and_push(version: new_version) trigger_release_build(version: new_version) UI.success("New beta release created: v#{new_version}") + + # Create backmerge PR so that translations and version bump get merged back to trunk + create_backmerge_pr(source_branch: "release/#{version}", github_username: github_username) end # Finalize the release by removing the beta suffix and triggering the final build. # +# - Downloads latest translations from GlotPress (to capture any translations added during the beta period) # - Bumps version to the final release number (removes beta suffix) # - Triggers a release build in Buildkite # - The build creates a draft GitHub release (with notes and download links) after uploading to CDN @@ -272,6 +287,7 @@ end lane :finalize_release do |version:, skip_confirm: false| UI.important <<~PROMPT Finalizing release #{version}. This will: + - Download latest translations from GlotPress - 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 @@ -280,6 +296,15 @@ lane :finalize_release do |version:, skip_confirm: false| PROMPT next unless skip_confirm || UI.confirm('Continue?') + # Download latest translations to capture any added during the beta period + fetch_glotpress_translations + git_add(path: [TRANSLATIONS_DIR]) + git_commit( + path: [TRANSLATIONS_DIR], + message: '[skip ci] Update translations', + allow_nothing_to_commit: true + ) + bump_version_commit_and_push(version: version) trigger_release_build(version: version) @@ -387,70 +412,6 @@ lane :fetch_glotpress_translations do UI.success("Downloaded translations for #{locales.length} locales") end -# Download the latest translations and create a PR to merge them into the release branch. -# -# @param skip_confirm [Boolean] Skip interactive confirmation prompts (default: false) -# -lane :download_translations do |skip_confirm: false, github_username: nil| - current_branch = Fastlane::Helper::GitHelper.current_git_branch - - UI.important <<~PROMPT - Downloading translations. This will: - - Download latest translations from GlotPress - - Create a PR to merge them into `#{current_branch}` - PROMPT - next unless skip_confirm || UI.confirm('Continue?') - - fetch_glotpress_translations - - translations_branch = 'update/latest-translations' - Fastlane::Helper::GitHelper.delete_local_branch_if_exists!(translations_branch) - Fastlane::Helper::GitHelper.create_branch(translations_branch) - - git_add(path: ['.']) - result = git_commit( - path: ['.'], - message: 'Update translations', - allow_nothing_to_commit: true - ) - - if result.nil? - Fastlane::Helper::GitHelper.checkout_and_pull(current_branch) - Fastlane::Helper::GitHelper.delete_local_branch_if_exists!(translations_branch) - UI.important('No translation changes detected.') - - if is_ci? - buildkite_annotate( - context: 'download-translations', - style: 'info', - message: 'No translation changes detected. No PR was created.' - ) - end - next - end - - Fastlane::Helper::GitHelper.delete_remote_branch_if_exists!(translations_branch) - push_to_git_remote(set_upstream: true, tags: false) - - pr_url = create_pull_request( - repo: GITHUB_REPO, - title: 'Update translations', - body: 'Merges the latest translations from GlotPress.', - labels: 'Releases', - base: current_branch, - head: translations_branch, - reviewers: Array(github_username) - ) - - if is_ci? && pr_url - buildkite_annotate( - context: 'download-translations', - style: 'info', - message: "Translations Pull Request: #{pr_url}" - ) - end -end - ######################################################################## # Build and Distribution Helper Methods ########################################################################