From 66ccfcfef36bfb5810f93f8717095414b38147c3 Mon Sep 17 00:00:00 2001 From: Rafael Lima Date: Sun, 6 Nov 2022 16:22:52 +0000 Subject: [PATCH 01/10] GithubHelperSpec: Add Yard Docs and Named Parameters to create_milestone method To become this method cleaner and more legible to call, we're adding named parameters to it, following the name of the current ones, and also adding yard docs to help guide the new people who use it --- .../wpmreleasetoolkit/helper/github_helper.rb | 13 ++++++++++++- spec/github_helper_spec.rb | 12 ++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb b/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb index 74dab2f35..49d6f3b12 100644 --- a/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb +++ b/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb @@ -71,7 +71,18 @@ def get_last_milestone(repository) last_stone end - def create_milestone(repository, newmilestone_number, newmilestone_duedate, newmilestone_duration, number_of_days_from_code_freeze_to_release, need_submission) + # Creates a new milestone + # + # @param [String] repository The repository name, including the organization (e.g. `wordpress-mobile/wordpress-ios`) + # @param [String] newmilestone_number The name of the milestone we want to create (e.g.: `16.9`) + # @param [Time] newmilestone_duedate milestone due date (e.g. `2022-10-22T12:00:00Z`) + # @param [Integer] newmilestone_duration Milestone duration in number of days + # @param [Integer] number_of_days_from_code_freeze_to_release Number of days from code freeze to release + # @param [Boolean] need_submission The app needs to be submitted? + # if `true`, will subtract 3 days from the `:number_of_days_from_code_freeze_to_release`. + # if `false`, will use the days of `:newmilestone_duration` + # + def create_milestone(repository:, newmilestone_number:, newmilestone_duedate:, newmilestone_duration:, number_of_days_from_code_freeze_to_release:, need_submission:) # If there is a review process, we want to submit the binary 3 days before its release # # Using 3 days is mostly for historical reasons where we release the apps on Monday and submit them on Friday. diff --git a/spec/github_helper_spec.rb b/spec/github_helper_spec.rb index d6051da3c..3b8a593cd 100644 --- a/spec/github_helper_spec.rb +++ b/spec/github_helper_spec.rb @@ -236,12 +236,12 @@ def get_milestone(milestone_name:) def create_milestone(need_submission:, milestone_duration:, days_code_freeze:) helper = described_class.new(github_token: 'Fake-GitHubToken-123') helper.create_milestone( - test_repo, - test_milestone_number, - test_milestone_duedate.to_time.utc, - milestone_duration, - days_code_freeze, - need_submission + repository: test_repo, + newmilestone_number: test_milestone_number, + newmilestone_duedate: test_milestone_duedate.to_time.utc, + newmilestone_duration: milestone_duration, + number_of_days_from_code_freeze_to_release: days_code_freeze, + need_submission: need_submission ) end end From b658f874bc83c7038d84bc81e10fd9e834654c7d Mon Sep 17 00:00:00 2001 From: Rafael Lima Date: Sun, 6 Nov 2022 16:24:41 +0000 Subject: [PATCH 02/10] CreateNewMilestoneAction: Adds named parameters to create_milestone GithubHelper's method --- .../actions/common/create_new_milestone_action.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_new_milestone_action.rb b/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_new_milestone_action.rb index 9f3e1ea32..3f1dab480 100644 --- a/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_new_milestone_action.rb +++ b/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_new_milestone_action.rb @@ -18,7 +18,14 @@ def self.run(params) newmilestone_number = Fastlane::Helper::Ios::VersionHelper.calc_next_release_version(last_stone[:title]) number_of_days_from_code_freeze_to_release = params[:number_of_days_from_code_freeze_to_release] UI.message("Next milestone: #{newmilestone_number} due on #{newmilestone_duedate}.") - github_helper.create_milestone(repository, newmilestone_number, newmilestone_duedate, milestone_duration, number_of_days_from_code_freeze_to_release, params[:need_appstore_submission]) + github_helper.create_milestone( + repository: repository, + newmilestone_number: newmilestone_number, + newmilestone_duedate: newmilestone_duedate, + newmilestone_duration: milestone_duration, + number_of_days_from_code_freeze_to_release: number_of_days_from_code_freeze_to_release, + need_submission: params[:need_appstore_submission] + ) end def self.description From 10528dea883ef28294fdd9e39b0d3fe9f6e994de Mon Sep 17 00:00:00 2001 From: Rafael Lima Date: Sun, 6 Nov 2022 16:40:35 +0000 Subject: [PATCH 03/10] GithubHelper#create_milestone: Rephrase yard docs --- lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb b/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb index 49d6f3b12..9cfaff65f 100644 --- a/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb +++ b/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb @@ -76,7 +76,7 @@ def get_last_milestone(repository) # @param [String] repository The repository name, including the organization (e.g. `wordpress-mobile/wordpress-ios`) # @param [String] newmilestone_number The name of the milestone we want to create (e.g.: `16.9`) # @param [Time] newmilestone_duedate milestone due date (e.g. `2022-10-22T12:00:00Z`) - # @param [Integer] newmilestone_duration Milestone duration in number of days + # @param [Integer] newmilestone_duration Number of days that a milestone extents # @param [Integer] number_of_days_from_code_freeze_to_release Number of days from code freeze to release # @param [Boolean] need_submission The app needs to be submitted? # if `true`, will subtract 3 days from the `:number_of_days_from_code_freeze_to_release`. From 255d1082855f9d70090ee4ce7eb4d4587f95996f Mon Sep 17 00:00:00 2001 From: Rafael Lima Date: Mon, 7 Nov 2022 15:01:16 +0000 Subject: [PATCH 04/10] GithubHelper#create_milestone: Rename parameters to be more descriptive --- .../common/create_new_milestone_action.rb | 16 ++++++---- .../wpmreleasetoolkit/helper/github_helper.rb | 29 +++++++------------ spec/github_helper_spec.rb | 10 +++---- 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_new_milestone_action.rb b/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_new_milestone_action.rb index 3f1dab480..d7810ddbf 100644 --- a/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_new_milestone_action.rb +++ b/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_new_milestone_action.rb @@ -11,20 +11,26 @@ def self.run(params) github_helper = Fastlane::Helper::GithubHelper.new(github_token: params[:github_token]) last_stone = github_helper.get_last_milestone(repository) + UI.message("Last detected milestone: #{last_stone[:title]} due on #{last_stone[:due_on]}.") + milestone_duedate = last_stone[:due_on] milestone_duration = params[:milestone_duration] newmilestone_duedate = (milestone_duedate.to_datetime.next_day(milestone_duration).to_time).utc newmilestone_number = Fastlane::Helper::Ios::VersionHelper.calc_next_release_version(last_stone[:title]) number_of_days_from_code_freeze_to_release = params[:number_of_days_from_code_freeze_to_release] + # If there is a review process, we want to submit the binary 3 days before its release + # Using 3 days is mostly for historical reasons where we release the apps on Monday and submit them on Friday. + days_until_submission = params[:need_appstore_submission] ? (number_of_days_from_code_freeze_to_release - 3) : milestone_duration + UI.message("Next milestone: #{newmilestone_number} due on #{newmilestone_duedate}.") + github_helper.create_milestone( repository: repository, - newmilestone_number: newmilestone_number, - newmilestone_duedate: newmilestone_duedate, - newmilestone_duration: milestone_duration, - number_of_days_from_code_freeze_to_release: number_of_days_from_code_freeze_to_release, - need_submission: params[:need_appstore_submission] + title: newmilestone_number, + due_date: newmilestone_duedate, + days_until_submission: days_until_submission, + days_until_release: number_of_days_from_code_freeze_to_release ) end diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb b/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb index 9cfaff65f..3520dba76 100644 --- a/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb +++ b/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb @@ -74,23 +74,16 @@ def get_last_milestone(repository) # Creates a new milestone # # @param [String] repository The repository name, including the organization (e.g. `wordpress-mobile/wordpress-ios`) - # @param [String] newmilestone_number The name of the milestone we want to create (e.g.: `16.9`) - # @param [Time] newmilestone_duedate milestone due date (e.g. `2022-10-22T12:00:00Z`) - # @param [Integer] newmilestone_duration Number of days that a milestone extents - # @param [Integer] number_of_days_from_code_freeze_to_release Number of days from code freeze to release - # @param [Boolean] need_submission The app needs to be submitted? - # if `true`, will subtract 3 days from the `:number_of_days_from_code_freeze_to_release`. - # if `false`, will use the days of `:newmilestone_duration` - # - def create_milestone(repository:, newmilestone_number:, newmilestone_duedate:, newmilestone_duration:, number_of_days_from_code_freeze_to_release:, need_submission:) - # If there is a review process, we want to submit the binary 3 days before its release - # - # Using 3 days is mostly for historical reasons where we release the apps on Monday and submit them on Friday. - days_until_submission = need_submission ? (number_of_days_from_code_freeze_to_release - 3) : newmilestone_duration - submission_date = newmilestone_duedate.to_datetime.next_day(days_until_submission) - release_date = newmilestone_duedate.to_datetime.next_day(number_of_days_from_code_freeze_to_release) + # @param [String] title The name of the milestone we want to create (e.g.: `16.9`) + # @param [Time] due_date milestone due date (e.g. `2022-10-22T12:00:00Z`) + # @param [Integer] days_until_submission Number of days until submission + # @param [Integer] days_until_release Number of days from code freeze to release + # + def create_milestone(repository:, title:, due_date:, days_until_submission:, days_until_release:) + submission_date = due_date.to_datetime.next_day(days_until_submission) + release_date = due_date.to_datetime.next_day(days_until_release) comment = <<~MILESTONE_DESCRIPTION - Code freeze: #{newmilestone_duedate.to_datetime.strftime('%B %d, %Y')} + Code freeze: #{due_date.to_datetime.strftime('%B %d, %Y')} App Store submission: #{submission_date.strftime('%B %d, %Y')} Release: #{release_date.strftime('%B %d, %Y')} MILESTONE_DESCRIPTION @@ -107,9 +100,9 @@ def create_milestone(repository:, newmilestone_number:, newmilestone_duedate:, n # # This is a bug in the GitHub API, not in our date computation logic. # To solve this, we trick it by forcing the time component of the ISO date we send to be `12:00:00Z`. - options[:due_on] = newmilestone_duedate.strftime('%Y-%m-%dT12:00:00Z') + options[:due_on] = due_date.strftime('%Y-%m-%dT12:00:00Z') options[:description] = comment - client.create_milestone(repository, newmilestone_number, options) + client.create_milestone(repository, title, options) end # Creates a Release on GitHub as a Draft diff --git a/spec/github_helper_spec.rb b/spec/github_helper_spec.rb index 3b8a593cd..84f4efee9 100644 --- a/spec/github_helper_spec.rb +++ b/spec/github_helper_spec.rb @@ -234,14 +234,14 @@ def get_milestone(milestone_name:) end def create_milestone(need_submission:, milestone_duration:, days_code_freeze:) + days_until_submission = need_submission ? (days_code_freeze - 3) : milestone_duration helper = described_class.new(github_token: 'Fake-GitHubToken-123') helper.create_milestone( repository: test_repo, - newmilestone_number: test_milestone_number, - newmilestone_duedate: test_milestone_duedate.to_time.utc, - newmilestone_duration: milestone_duration, - number_of_days_from_code_freeze_to_release: days_code_freeze, - need_submission: need_submission + title: test_milestone_number, + due_date: test_milestone_duedate.to_time.utc, + days_until_submission: days_until_submission, + days_until_release: days_code_freeze ) end end From 99a95ac5236d78c8b5d1564f081f6bba9d7a6b3d Mon Sep 17 00:00:00 2001 From: Rafael Lima Date: Tue, 8 Nov 2022 20:50:44 +0000 Subject: [PATCH 05/10] CreateNewMilestoneAction: Rephrase comment about release times to be descriptive --- .../actions/common/create_new_milestone_action.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_new_milestone_action.rb b/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_new_milestone_action.rb index d7810ddbf..0265ba278 100644 --- a/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_new_milestone_action.rb +++ b/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_new_milestone_action.rb @@ -19,8 +19,8 @@ def self.run(params) newmilestone_duedate = (milestone_duedate.to_datetime.next_day(milestone_duration).to_time).utc newmilestone_number = Fastlane::Helper::Ios::VersionHelper.calc_next_release_version(last_stone[:title]) number_of_days_from_code_freeze_to_release = params[:number_of_days_from_code_freeze_to_release] - # If there is a review process, we want to submit the binary 3 days before its release - # Using 3 days is mostly for historical reasons where we release the apps on Monday and submit them on Friday. + # Because of the app stores review process, we submit the binary 3 days before the intended release date. + # Using 3 days is mostly for historical reasons, for a long time, we've been submitting apps on Friday and releasing them on Monday. days_until_submission = params[:need_appstore_submission] ? (number_of_days_from_code_freeze_to_release - 3) : milestone_duration UI.message("Next milestone: #{newmilestone_number} due on #{newmilestone_duedate}.") From 39b23c8970f9ca9ca44af079b6689a193fb741cc Mon Sep 17 00:00:00 2001 From: Rafael Lima Date: Tue, 8 Nov 2022 20:50:50 +0000 Subject: [PATCH 06/10] GithubHelper#create_milestone: Add unit tests and validation to date order --- .../wpmreleasetoolkit/helper/github_helper.rb | 8 ++- spec/github_helper_spec.rb | 70 +++++++++++++++---- 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb b/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb index 3520dba76..7fbb084bc 100644 --- a/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb +++ b/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb @@ -75,11 +75,15 @@ def get_last_milestone(repository) # # @param [String] repository The repository name, including the organization (e.g. `wordpress-mobile/wordpress-ios`) # @param [String] title The name of the milestone we want to create (e.g.: `16.9`) - # @param [Time] due_date milestone due date (e.g. `2022-10-22T12:00:00Z`) - # @param [Integer] days_until_submission Number of days until submission + # @param [Time] due_date Milestone due date—which will also correspond to the code freeze date + # @param [Integer] days_until_submission Number of days from code freeze to submission to the App Store / Play Store # @param [Integer] days_until_release Number of days from code freeze to release # def create_milestone(repository:, title:, due_date:, days_until_submission:, days_until_release:) + UI.user_error!('days_until_release must be greater than zero.') if days_until_release <= 0 + UI.user_error!('days_until_submission must be greater than zero.') if days_until_submission <= 0 + UI.user_error!('days_until_release must be greather than days_until_submission') if days_until_submission >= days_until_release + submission_date = due_date.to_datetime.next_day(days_until_submission) release_date = due_date.to_datetime.next_day(days_until_release) comment = <<~MILESTONE_DESCRIPTION diff --git a/spec/github_helper_spec.rb b/spec/github_helper_spec.rb index 84f4efee9..12a5ed625 100644 --- a/spec/github_helper_spec.rb +++ b/spec/github_helper_spec.rb @@ -217,31 +217,77 @@ def get_milestone(milestone_name:) allow(Octokit::Client).to receive(:new).and_return(client) end - it 'has the correct dates to code freeze without submission' do - comment = "Code freeze: October 22, 2022\nApp Store submission: November 15, 2022\nRelease: October 25, 2022\n" - options = { due_on: '2022-10-22T12:00:00Z', description: comment } + it 'computes the correct dates for standard period' do + due_date = '2022-10-20T08:00:00Z'.to_time.utc + options = { + due_on: '2022-10-20T12:00:00Z', + description: "Code freeze: October 20, 2022\nApp Store submission: October 24, 2022\nRelease: October 27, 2022\n" + } expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options) - create_milestone(need_submission: false, milestone_duration: 24, days_code_freeze: 3) + create_milestone(due_date: due_date, days_until_submission: 4, days_until_release: 7) end - it 'has the correct dates to code freeze with submission' do - comment = "Code freeze: October 22, 2022\nApp Store submission: October 22, 2022\nRelease: October 25, 2022\n" - options = { due_on: '2022-10-22T12:00:00Z', description: comment } + it 'computes the correct dates when the due date is on the verge of a DST day change' do + # The PST to PDT (DST) change is made on the second Sunday in March and finishes on the first Sunday in November + Time.zone = 'Pacific Time (US & Canada)' + due_date = '2022-06-18T23:00:00Z'.to_time + options = { + due_on: '2022-06-19T12:00:00Z', + description: "Code freeze: June 19, 2022\nApp Store submission: June 21, 2022\nRelease: June 22, 2022\n" + } expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options) - create_milestone(need_submission: true, milestone_duration: 19, days_code_freeze: 3) + create_milestone(due_date: due_date, days_until_submission: 2, days_until_release: 3) end - def create_milestone(need_submission:, milestone_duration:, days_code_freeze:) - days_until_submission = need_submission ? (days_code_freeze - 3) : milestone_duration + it 'computes the correct dates when the due date is on DST but has no day change' do + # The PST to PDT (DST) change is made on the second Sunday in March and finishes on the first Sunday in November + Time.zone = 'Pacific Time (US & Canada)' + due_date = '2022-06-18T22:00:00Z'.to_time + options = { + due_on: '2022-06-18T12:00:00Z', + description: "Code freeze: June 18, 2022\nApp Store submission: June 20, 2022\nRelease: June 21, 2022\n" + } + + expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options) + create_milestone(due_date: due_date, days_until_submission: 2, days_until_release: 3) + end + + context 'with input validation' do + it 'raises an error if days_until_submission is less than or equal zero' do + due_date = '2022-10-20T08:00:00Z'.to_time.utc + expect { create_milestone(due_date: due_date, days_until_submission: 0, days_until_release: 5) } + .to raise_error(FastlaneCore::Interface::FastlaneError, 'days_until_submission must be greater than zero.') + end + + it 'raises an error if days_until_release is less than or equal zero' do + due_date = '2022-10-20T08:00:00Z'.to_time.utc + expect { create_milestone(due_date: due_date, days_until_submission: 12, days_until_release: -8) } + .to raise_error(FastlaneCore::Interface::FastlaneError, 'days_until_release must be greater than zero.') + end + + it 'raises an error if submission date is after the release date' do + due_date = '2022-10-20T08:00:00Z'.to_time.utc + expect { create_milestone(due_date: due_date, days_until_submission: 14, days_until_release: 3) } + .to raise_error(FastlaneCore::Interface::FastlaneError, 'days_until_release must be greather than days_until_submission') + end + + it 'raises an error if submission date is equal to release date' do + due_date = '2022-10-20T08:00:00Z'.to_time.utc + expect { create_milestone(due_date: due_date, days_until_submission: 1, days_until_release: 1) } + .to raise_error(FastlaneCore::Interface::FastlaneError, 'days_until_release must be greather than days_until_submission') + end + end + + def create_milestone(due_date:, days_until_submission:, days_until_release:) helper = described_class.new(github_token: 'Fake-GitHubToken-123') helper.create_milestone( repository: test_repo, title: test_milestone_number, - due_date: test_milestone_duedate.to_time.utc, + due_date: due_date, days_until_submission: days_until_submission, - days_until_release: days_code_freeze + days_until_release: days_until_release ) end end From b218ccccd6dfbd427ba9f7ae100f34e8b0d338e1 Mon Sep 17 00:00:00 2001 From: Rafael Lima Date: Mon, 14 Nov 2022 08:09:46 +0000 Subject: [PATCH 07/10] GithubHelper: Fix Timezone changes unit tests --- .../wpmreleasetoolkit/helper/github_helper.rb | 6 +- spec/github_helper_spec.rb | 87 ++++++++++--------- 2 files changed, 49 insertions(+), 44 deletions(-) diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb b/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb index 7fbb084bc..c853ee01f 100644 --- a/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb +++ b/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb @@ -80,9 +80,9 @@ def get_last_milestone(repository) # @param [Integer] days_until_release Number of days from code freeze to release # def create_milestone(repository:, title:, due_date:, days_until_submission:, days_until_release:) - UI.user_error!('days_until_release must be greater than zero.') if days_until_release <= 0 - UI.user_error!('days_until_submission must be greater than zero.') if days_until_submission <= 0 - UI.user_error!('days_until_release must be greather than days_until_submission') if days_until_submission >= days_until_release + UI.user_error!('days_until_release must be greater than zero.') unless days_until_release > 0 + UI.user_error!('days_until_submission must be greater than zero.') unless days_until_submission > 0 + UI.user_error!('days_until_release must be greater or equal to days_until_submission.') unless days_until_release >= days_until_submission submission_date = due_date.to_datetime.next_day(days_until_submission) release_date = due_date.to_datetime.next_day(days_until_release) diff --git a/spec/github_helper_spec.rb b/spec/github_helper_spec.rb index 12a5ed625..a944adb86 100644 --- a/spec/github_helper_spec.rb +++ b/spec/github_helper_spec.rb @@ -218,66 +218,71 @@ def get_milestone(milestone_name:) end it 'computes the correct dates for standard period' do - due_date = '2022-10-20T08:00:00Z'.to_time.utc + due_date = '2022-12-02T08:00:00Z'.to_time.utc options = { - due_on: '2022-10-20T12:00:00Z', - description: "Code freeze: October 20, 2022\nApp Store submission: October 24, 2022\nRelease: October 27, 2022\n" + due_on: '2022-12-02T12:00:00Z', + description: "Code freeze: December 02, 2022\nApp Store submission: December 06, 2022\nRelease: December 09, 2022\n" } expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options) create_milestone(due_date: due_date, days_until_submission: 4, days_until_release: 7) end - it 'computes the correct dates when the due date is on the verge of a DST day change' do - # The PST to PDT (DST) change is made on the second Sunday in March and finishes on the first Sunday in November - Time.zone = 'Pacific Time (US & Canada)' - due_date = '2022-06-18T23:00:00Z'.to_time + it 'computes the correct dates when submission and release dates are in the same day' do + due_date = '2022-12-02T08:00:00Z'.to_time.utc options = { - due_on: '2022-06-19T12:00:00Z', - description: "Code freeze: June 19, 2022\nApp Store submission: June 21, 2022\nRelease: June 22, 2022\n" + due_on: '2022-12-02T12:00:00Z', + description: "Code freeze: December 02, 2022\nApp Store submission: December 03, 2022\nRelease: December 03, 2022\n" } expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options) - create_milestone(due_date: due_date, days_until_submission: 2, days_until_release: 3) + create_milestone(due_date: due_date, days_until_submission: 1, days_until_release: 1) end - it 'computes the correct dates when the due date is on DST but has no day change' do - # The PST to PDT (DST) change is made on the second Sunday in March and finishes on the first Sunday in November - Time.zone = 'Pacific Time (US & Canada)' - due_date = '2022-06-18T22:00:00Z'.to_time - options = { - due_on: '2022-06-18T12:00:00Z', - description: "Code freeze: June 18, 2022\nApp Store submission: June 20, 2022\nRelease: June 21, 2022\n" - } - - expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options) - create_milestone(due_date: due_date, days_until_submission: 2, days_until_release: 3) + it 'computes the correct dates when the due date is on the verge of a DST day change' do + # DST starts on the last Sunday of March and ends on the last Sunday of October + Time.use_zone('Europe/London') do + due_date = Time.zone.parse('2022-03-27 23:00:00Z') + options = { + due_on: '2022-03-28T12:00:00Z', + description: "Code freeze: March 28, 2022\nApp Store submission: March 30, 2022\nRelease: March 31, 2022\n" + } + + expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options) + create_milestone(due_date: due_date, days_until_submission: 2, days_until_release: 3) + end end - context 'with input validation' do - it 'raises an error if days_until_submission is less than or equal zero' do - due_date = '2022-10-20T08:00:00Z'.to_time.utc - expect { create_milestone(due_date: due_date, days_until_submission: 0, days_until_release: 5) } - .to raise_error(FastlaneCore::Interface::FastlaneError, 'days_until_submission must be greater than zero.') + it 'computes the correct dates when the due date is on DST but has no day change' do + # DST starts on the last Sunday of March and ends on the last Sunday of October + Time.use_zone('Europe/London') do + due_date = Time.zone.parse('2022-03-26 23:00:00Z') + options = { + due_on: '2022-03-26T12:00:00Z', + description: "Code freeze: March 26, 2022\nApp Store submission: March 28, 2022\nRelease: March 29, 2022\n" + } + + expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options) + create_milestone(due_date: due_date, days_until_submission: 2, days_until_release: 3) end + end - it 'raises an error if days_until_release is less than or equal zero' do - due_date = '2022-10-20T08:00:00Z'.to_time.utc - expect { create_milestone(due_date: due_date, days_until_submission: 12, days_until_release: -8) } - .to raise_error(FastlaneCore::Interface::FastlaneError, 'days_until_release must be greater than zero.') - end + it 'raises an error if days_until_submission is less than or equal zero' do + due_date = '2022-10-20T08:00:00Z'.to_time.utc + expect { create_milestone(due_date: due_date, days_until_submission: 0, days_until_release: 5) } + .to raise_error(FastlaneCore::Interface::FastlaneError, 'days_until_submission must be greater than zero.') + end - it 'raises an error if submission date is after the release date' do - due_date = '2022-10-20T08:00:00Z'.to_time.utc - expect { create_milestone(due_date: due_date, days_until_submission: 14, days_until_release: 3) } - .to raise_error(FastlaneCore::Interface::FastlaneError, 'days_until_release must be greather than days_until_submission') - end + it 'raises an error if days_until_release is less than or equal zero' do + due_date = '2022-10-20T08:00:00Z'.to_time.utc + expect { create_milestone(due_date: due_date, days_until_submission: 12, days_until_release: -8) } + .to raise_error(FastlaneCore::Interface::FastlaneError, 'days_until_release must be greater than zero.') + end - it 'raises an error if submission date is equal to release date' do - due_date = '2022-10-20T08:00:00Z'.to_time.utc - expect { create_milestone(due_date: due_date, days_until_submission: 1, days_until_release: 1) } - .to raise_error(FastlaneCore::Interface::FastlaneError, 'days_until_release must be greather than days_until_submission') - end + it 'raises an error if days_until_submission is greater than days_until_release' do + due_date = '2022-10-20T08:00:00Z'.to_time.utc + expect { create_milestone(due_date: due_date, days_until_submission: 14, days_until_release: 3) } + .to raise_error(FastlaneCore::Interface::FastlaneError, 'days_until_release must be greater or equal to days_until_submission.') end def create_milestone(due_date:, days_until_submission:, days_until_release:) From de90d4db64228073b33068f6b893afeb946bb6c0 Mon Sep 17 00:00:00 2001 From: Rafael Lima Date: Mon, 14 Nov 2022 20:09:55 +0000 Subject: [PATCH 08/10] GithubHelper: Adds more unit tests to validate the Timezone changes --- spec/github_helper_spec.rb | 62 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/spec/github_helper_spec.rb b/spec/github_helper_spec.rb index a944adb86..6b4e822a4 100644 --- a/spec/github_helper_spec.rb +++ b/spec/github_helper_spec.rb @@ -240,7 +240,7 @@ def get_milestone(milestone_name:) end it 'computes the correct dates when the due date is on the verge of a DST day change' do - # DST starts on the last Sunday of March and ends on the last Sunday of October + # Europe DST starts on the last Sunday of March, and ends on the last Sunday of October Time.use_zone('Europe/London') do due_date = Time.zone.parse('2022-03-27 23:00:00Z') options = { @@ -254,7 +254,7 @@ def get_milestone(milestone_name:) end it 'computes the correct dates when the due date is on DST but has no day change' do - # DST starts on the last Sunday of March and ends on the last Sunday of October + # Europe DST starts on the last Sunday of March, and ends on the last Sunday of October Time.use_zone('Europe/London') do due_date = Time.zone.parse('2022-03-26 23:00:00Z') options = { @@ -267,6 +267,64 @@ def get_milestone(milestone_name:) end end + it 'computes the correct dates when the offset is between DST endings' do + # Europe DST starts on the last Sunday of March, and ends on the last Sunday of October + Time.use_zone('Europe/London') do + due_date = Time.zone.parse('2022-10-30 23:00:00Z') + options = { + due_on: '2022-10-30T12:00:00Z', + description: "Code freeze: October 30, 2022\nApp Store submission: March 19, 2023\nRelease: March 25, 2023\n" + } + + expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options) + create_milestone(due_date: due_date, days_until_submission: 140, days_until_release: 146) + end + end + + it 'computes the correct dates when the release and submission dates are at the last day of a DST change' do + # Europe DST starts on the last Sunday of March, and ends on the last Sunday of October + Time.use_zone('Europe/London') do + due_date = Time.zone.parse('2022-03-27 23:00:00Z') + options = { + due_on: '2022-03-28T12:00:00Z', + description: "Code freeze: March 28, 2022\nApp Store submission: October 30, 2022\nRelease: October 31, 2022\n" + } + + expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options) + create_milestone(due_date: due_date, days_until_submission: 216, days_until_release: 217) + end + end + + it 'computes the correct dates when the due date is before Europe and USA DST changes and ends inside a DST period on Europe' do + # USA DST starts on the second Sunday in March. and ends on the first Sunday in November + # Europe DST starts on the last Sunday of March, and ends on the last Sunday in October + Time.use_zone('Europe/London') do + due_date = Time.zone.parse('2022-03-05 23:00:00Z') + options = { + due_on: '2022-03-05T12:00:00Z', + description: "Code freeze: March 05, 2022\nApp Store submission: May 04, 2022\nRelease: May 05, 2022\n" + } + + expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options) + create_milestone(due_date: due_date, days_until_submission: 60, days_until_release: 61) + end + end + + it 'computes the correct dates when the due date is before Europe and USA DST changes and ends inside a DST period on USA' do + # USA DST starts on the second Sunday in March. and ends on the first Sunday in November + # Europe DST starts on the last Sunday of March, and ends on the last Sunday in October + Time.use_zone('America/Los_Angeles') do + due_date = Time.zone.parse('2022-03-05 23:00:00Z') + options = { + due_on: '2022-03-05T12:00:00Z', + description: "Code freeze: March 05, 2022\nApp Store submission: May 04, 2022\nRelease: May 05, 2022\n" + } + + expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options) + create_milestone(due_date: due_date, days_until_submission: 60, days_until_release: 61) + end + end + it 'raises an error if days_until_submission is less than or equal zero' do due_date = '2022-10-20T08:00:00Z'.to_time.utc expect { create_milestone(due_date: due_date, days_until_submission: 0, days_until_release: 5) } From d87c03ccf738ab4fd7d0818c9d8d5c5b508cd687 Mon Sep 17 00:00:00 2001 From: Rafael Lima Date: Wed, 16 Nov 2022 19:20:33 +0000 Subject: [PATCH 09/10] GithubHelper: Fix Rubocop Issues --- lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb b/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb index c853ee01f..b02000720 100644 --- a/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb +++ b/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb @@ -80,8 +80,8 @@ def get_last_milestone(repository) # @param [Integer] days_until_release Number of days from code freeze to release # def create_milestone(repository:, title:, due_date:, days_until_submission:, days_until_release:) - UI.user_error!('days_until_release must be greater than zero.') unless days_until_release > 0 - UI.user_error!('days_until_submission must be greater than zero.') unless days_until_submission > 0 + UI.user_error!('days_until_release must be greater than zero.') unless days_until_release.positive? + UI.user_error!('days_until_submission must be greater than zero.') unless days_until_submission.positive? UI.user_error!('days_until_release must be greater or equal to days_until_submission.') unless days_until_release >= days_until_submission submission_date = due_date.to_datetime.next_day(days_until_submission) From 7f99d518fab8b4dce5a31ce224eb88cc28a20661 Mon Sep 17 00:00:00 2001 From: Rafael Lima Date: Wed, 16 Nov 2022 21:12:38 +0000 Subject: [PATCH 10/10] GithubHelperSpec: Adds comments to DST cases to be more clear and new spec to cover an addional case --- spec/github_helper_spec.rb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/spec/github_helper_spec.rb b/spec/github_helper_spec.rb index 6b4e822a4..684b7fda0 100644 --- a/spec/github_helper_spec.rb +++ b/spec/github_helper_spec.rb @@ -242,6 +242,9 @@ def get_milestone(milestone_name:) it 'computes the correct dates when the due date is on the verge of a DST day change' do # Europe DST starts on the last Sunday of March, and ends on the last Sunday of October Time.use_zone('Europe/London') do + # March 27th, 2022 is the exact day that London switches to the DST (+1h) + # If the due date is too close to the next day, a day change will happen + # So, 2022-03-27 23:00:00Z will be exactly 2022-03-28 00:00:00 +0100 at the DST change due_date = Time.zone.parse('2022-03-27 23:00:00Z') options = { due_on: '2022-03-28T12:00:00Z', @@ -256,6 +259,25 @@ def get_milestone(milestone_name:) it 'computes the correct dates when the due date is on DST but has no day change' do # Europe DST starts on the last Sunday of March, and ends on the last Sunday of October Time.use_zone('Europe/London') do + # March 27th, 2022 is the exact day that London switches to the DST (+1h) + # If the due date is not close enough at the day change, nothing will occur. + # So, 2022-03-27 22:00:00Z will be exactly 2022-03-27 23:00:00 +0100 at the DST change. + due_date = Time.zone.parse('2022-03-27 22:00:00Z') + options = { + due_on: '2022-03-27T12:00:00Z', + description: "Code freeze: March 27, 2022\nApp Store submission: March 29, 2022\nRelease: March 30, 2022\n" + } + + expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options) + create_milestone(due_date: due_date, days_until_submission: 2, days_until_release: 3) + end + end + + it 'computes the correct dates when the due date is one day before a DST change' do + # Europe DST starts on the last Sunday of March, and ends on the last Sunday of October + Time.use_zone('Europe/London') do + # As London changes to DST on March 27th, the date shouldn't be changed + # So, 2022-03-26 23:00:00Z will be exactly 2022-03-26 23:00:00 +0000 at this Timezone. due_date = Time.zone.parse('2022-03-26 23:00:00Z') options = { due_on: '2022-03-26T12:00:00Z',