Skip to content

Commit df29661

Browse files
authored
Merge pull request #426 from raafaelima/add/named-params-create-milestone
Add named params and yard docs to `create_milestone` method at `GithubHelper`
2 parents 80ac4b6 + 7f99d51 commit df29661

File tree

3 files changed

+178
-26
lines changed

3 files changed

+178
-26
lines changed

lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_new_milestone_action.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,27 @@ def self.run(params)
1111

1212
github_helper = Fastlane::Helper::GithubHelper.new(github_token: params[:github_token])
1313
last_stone = github_helper.get_last_milestone(repository)
14+
1415
UI.message("Last detected milestone: #{last_stone[:title]} due on #{last_stone[:due_on]}.")
16+
1517
milestone_duedate = last_stone[:due_on]
1618
milestone_duration = params[:milestone_duration]
1719
newmilestone_duedate = (milestone_duedate.to_datetime.next_day(milestone_duration).to_time).utc
1820
newmilestone_number = Fastlane::Helper::Ios::VersionHelper.calc_next_release_version(last_stone[:title])
1921
number_of_days_from_code_freeze_to_release = params[:number_of_days_from_code_freeze_to_release]
22+
# Because of the app stores review process, we submit the binary 3 days before the intended release date.
23+
# Using 3 days is mostly for historical reasons, for a long time, we've been submitting apps on Friday and releasing them on Monday.
24+
days_until_submission = params[:need_appstore_submission] ? (number_of_days_from_code_freeze_to_release - 3) : milestone_duration
25+
2026
UI.message("Next milestone: #{newmilestone_number} due on #{newmilestone_duedate}.")
21-
github_helper.create_milestone(repository, newmilestone_number, newmilestone_duedate, milestone_duration, number_of_days_from_code_freeze_to_release, params[:need_appstore_submission])
27+
28+
github_helper.create_milestone(
29+
repository: repository,
30+
title: newmilestone_number,
31+
due_date: newmilestone_duedate,
32+
days_until_submission: days_until_submission,
33+
days_until_release: number_of_days_from_code_freeze_to_release
34+
)
2235
end
2336

2437
def self.description

lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,23 @@ def get_last_milestone(repository)
7171
last_stone
7272
end
7373

74-
def create_milestone(repository, newmilestone_number, newmilestone_duedate, newmilestone_duration, number_of_days_from_code_freeze_to_release, need_submission)
75-
# If there is a review process, we want to submit the binary 3 days before its release
76-
#
77-
# Using 3 days is mostly for historical reasons where we release the apps on Monday and submit them on Friday.
78-
days_until_submission = need_submission ? (number_of_days_from_code_freeze_to_release - 3) : newmilestone_duration
79-
submission_date = newmilestone_duedate.to_datetime.next_day(days_until_submission)
80-
release_date = newmilestone_duedate.to_datetime.next_day(number_of_days_from_code_freeze_to_release)
74+
# Creates a new milestone
75+
#
76+
# @param [String] repository The repository name, including the organization (e.g. `wordpress-mobile/wordpress-ios`)
77+
# @param [String] title The name of the milestone we want to create (e.g.: `16.9`)
78+
# @param [Time] due_date Milestone due date—which will also correspond to the code freeze date
79+
# @param [Integer] days_until_submission Number of days from code freeze to submission to the App Store / Play Store
80+
# @param [Integer] days_until_release Number of days from code freeze to release
81+
#
82+
def create_milestone(repository:, title:, due_date:, days_until_submission:, days_until_release:)
83+
UI.user_error!('days_until_release must be greater than zero.') unless days_until_release.positive?
84+
UI.user_error!('days_until_submission must be greater than zero.') unless days_until_submission.positive?
85+
UI.user_error!('days_until_release must be greater or equal to days_until_submission.') unless days_until_release >= days_until_submission
86+
87+
submission_date = due_date.to_datetime.next_day(days_until_submission)
88+
release_date = due_date.to_datetime.next_day(days_until_release)
8189
comment = <<~MILESTONE_DESCRIPTION
82-
Code freeze: #{newmilestone_duedate.to_datetime.strftime('%B %d, %Y')}
90+
Code freeze: #{due_date.to_datetime.strftime('%B %d, %Y')}
8391
App Store submission: #{submission_date.strftime('%B %d, %Y')}
8492
Release: #{release_date.strftime('%B %d, %Y')}
8593
MILESTONE_DESCRIPTION
@@ -96,9 +104,9 @@ def create_milestone(repository, newmilestone_number, newmilestone_duedate, newm
96104
#
97105
# This is a bug in the GitHub API, not in our date computation logic.
98106
# To solve this, we trick it by forcing the time component of the ISO date we send to be `12:00:00Z`.
99-
options[:due_on] = newmilestone_duedate.strftime('%Y-%m-%dT12:00:00Z')
107+
options[:due_on] = due_date.strftime('%Y-%m-%dT12:00:00Z')
100108
options[:description] = comment
101-
client.create_milestone(repository, newmilestone_number, options)
109+
client.create_milestone(repository, title, options)
102110
end
103111

104112
# Creates a Release on GitHub as a Draft

spec/github_helper_spec.rb

Lines changed: 146 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -217,31 +217,162 @@ def get_milestone(milestone_name:)
217217
allow(Octokit::Client).to receive(:new).and_return(client)
218218
end
219219

220-
it 'has the correct dates to code freeze without submission' do
221-
comment = "Code freeze: October 22, 2022\nApp Store submission: November 15, 2022\nRelease: October 25, 2022\n"
222-
options = { due_on: '2022-10-22T12:00:00Z', description: comment }
220+
it 'computes the correct dates for standard period' do
221+
due_date = '2022-12-02T08:00:00Z'.to_time.utc
222+
options = {
223+
due_on: '2022-12-02T12:00:00Z',
224+
description: "Code freeze: December 02, 2022\nApp Store submission: December 06, 2022\nRelease: December 09, 2022\n"
225+
}
223226

224227
expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options)
225-
create_milestone(need_submission: false, milestone_duration: 24, days_code_freeze: 3)
228+
create_milestone(due_date: due_date, days_until_submission: 4, days_until_release: 7)
226229
end
227230

228-
it 'has the correct dates to code freeze with submission' do
229-
comment = "Code freeze: October 22, 2022\nApp Store submission: October 22, 2022\nRelease: October 25, 2022\n"
230-
options = { due_on: '2022-10-22T12:00:00Z', description: comment }
231+
it 'computes the correct dates when submission and release dates are in the same day' do
232+
due_date = '2022-12-02T08:00:00Z'.to_time.utc
233+
options = {
234+
due_on: '2022-12-02T12:00:00Z',
235+
description: "Code freeze: December 02, 2022\nApp Store submission: December 03, 2022\nRelease: December 03, 2022\n"
236+
}
231237

232238
expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options)
233-
create_milestone(need_submission: true, milestone_duration: 19, days_code_freeze: 3)
239+
create_milestone(due_date: due_date, days_until_submission: 1, days_until_release: 1)
240+
end
241+
242+
it 'computes the correct dates when the due date is on the verge of a DST day change' do
243+
# Europe DST starts on the last Sunday of March, and ends on the last Sunday of October
244+
Time.use_zone('Europe/London') do
245+
# March 27th, 2022 is the exact day that London switches to the DST (+1h)
246+
# If the due date is too close to the next day, a day change will happen
247+
# So, 2022-03-27 23:00:00Z will be exactly 2022-03-28 00:00:00 +0100 at the DST change
248+
due_date = Time.zone.parse('2022-03-27 23:00:00Z')
249+
options = {
250+
due_on: '2022-03-28T12:00:00Z',
251+
description: "Code freeze: March 28, 2022\nApp Store submission: March 30, 2022\nRelease: March 31, 2022\n"
252+
}
253+
254+
expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options)
255+
create_milestone(due_date: due_date, days_until_submission: 2, days_until_release: 3)
256+
end
257+
end
258+
259+
it 'computes the correct dates when the due date is on DST but has no day change' do
260+
# Europe DST starts on the last Sunday of March, and ends on the last Sunday of October
261+
Time.use_zone('Europe/London') do
262+
# March 27th, 2022 is the exact day that London switches to the DST (+1h)
263+
# If the due date is not close enough at the day change, nothing will occur.
264+
# So, 2022-03-27 22:00:00Z will be exactly 2022-03-27 23:00:00 +0100 at the DST change.
265+
due_date = Time.zone.parse('2022-03-27 22:00:00Z')
266+
options = {
267+
due_on: '2022-03-27T12:00:00Z',
268+
description: "Code freeze: March 27, 2022\nApp Store submission: March 29, 2022\nRelease: March 30, 2022\n"
269+
}
270+
271+
expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options)
272+
create_milestone(due_date: due_date, days_until_submission: 2, days_until_release: 3)
273+
end
274+
end
275+
276+
it 'computes the correct dates when the due date is one day before a DST change' do
277+
# Europe DST starts on the last Sunday of March, and ends on the last Sunday of October
278+
Time.use_zone('Europe/London') do
279+
# As London changes to DST on March 27th, the date shouldn't be changed
280+
# So, 2022-03-26 23:00:00Z will be exactly 2022-03-26 23:00:00 +0000 at this Timezone.
281+
due_date = Time.zone.parse('2022-03-26 23:00:00Z')
282+
options = {
283+
due_on: '2022-03-26T12:00:00Z',
284+
description: "Code freeze: March 26, 2022\nApp Store submission: March 28, 2022\nRelease: March 29, 2022\n"
285+
}
286+
287+
expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options)
288+
create_milestone(due_date: due_date, days_until_submission: 2, days_until_release: 3)
289+
end
290+
end
291+
292+
it 'computes the correct dates when the offset is between DST endings' do
293+
# Europe DST starts on the last Sunday of March, and ends on the last Sunday of October
294+
Time.use_zone('Europe/London') do
295+
due_date = Time.zone.parse('2022-10-30 23:00:00Z')
296+
options = {
297+
due_on: '2022-10-30T12:00:00Z',
298+
description: "Code freeze: October 30, 2022\nApp Store submission: March 19, 2023\nRelease: March 25, 2023\n"
299+
}
300+
301+
expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options)
302+
create_milestone(due_date: due_date, days_until_submission: 140, days_until_release: 146)
303+
end
304+
end
305+
306+
it 'computes the correct dates when the release and submission dates are at the last day of a DST change' do
307+
# Europe DST starts on the last Sunday of March, and ends on the last Sunday of October
308+
Time.use_zone('Europe/London') do
309+
due_date = Time.zone.parse('2022-03-27 23:00:00Z')
310+
options = {
311+
due_on: '2022-03-28T12:00:00Z',
312+
description: "Code freeze: March 28, 2022\nApp Store submission: October 30, 2022\nRelease: October 31, 2022\n"
313+
}
314+
315+
expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options)
316+
create_milestone(due_date: due_date, days_until_submission: 216, days_until_release: 217)
317+
end
234318
end
235319

236-
def create_milestone(need_submission:, milestone_duration:, days_code_freeze:)
320+
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
321+
# USA DST starts on the second Sunday in March. and ends on the first Sunday in November
322+
# Europe DST starts on the last Sunday of March, and ends on the last Sunday in October
323+
Time.use_zone('Europe/London') do
324+
due_date = Time.zone.parse('2022-03-05 23:00:00Z')
325+
options = {
326+
due_on: '2022-03-05T12:00:00Z',
327+
description: "Code freeze: March 05, 2022\nApp Store submission: May 04, 2022\nRelease: May 05, 2022\n"
328+
}
329+
330+
expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options)
331+
create_milestone(due_date: due_date, days_until_submission: 60, days_until_release: 61)
332+
end
333+
end
334+
335+
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
336+
# USA DST starts on the second Sunday in March. and ends on the first Sunday in November
337+
# Europe DST starts on the last Sunday of March, and ends on the last Sunday in October
338+
Time.use_zone('America/Los_Angeles') do
339+
due_date = Time.zone.parse('2022-03-05 23:00:00Z')
340+
options = {
341+
due_on: '2022-03-05T12:00:00Z',
342+
description: "Code freeze: March 05, 2022\nApp Store submission: May 04, 2022\nRelease: May 05, 2022\n"
343+
}
344+
345+
expect(client).to receive(:create_milestone).with(test_repo, test_milestone_number, options)
346+
create_milestone(due_date: due_date, days_until_submission: 60, days_until_release: 61)
347+
end
348+
end
349+
350+
it 'raises an error if days_until_submission is less than or equal zero' do
351+
due_date = '2022-10-20T08:00:00Z'.to_time.utc
352+
expect { create_milestone(due_date: due_date, days_until_submission: 0, days_until_release: 5) }
353+
.to raise_error(FastlaneCore::Interface::FastlaneError, 'days_until_submission must be greater than zero.')
354+
end
355+
356+
it 'raises an error if days_until_release is less than or equal zero' do
357+
due_date = '2022-10-20T08:00:00Z'.to_time.utc
358+
expect { create_milestone(due_date: due_date, days_until_submission: 12, days_until_release: -8) }
359+
.to raise_error(FastlaneCore::Interface::FastlaneError, 'days_until_release must be greater than zero.')
360+
end
361+
362+
it 'raises an error if days_until_submission is greater than days_until_release' do
363+
due_date = '2022-10-20T08:00:00Z'.to_time.utc
364+
expect { create_milestone(due_date: due_date, days_until_submission: 14, days_until_release: 3) }
365+
.to raise_error(FastlaneCore::Interface::FastlaneError, 'days_until_release must be greater or equal to days_until_submission.')
366+
end
367+
368+
def create_milestone(due_date:, days_until_submission:, days_until_release:)
237369
helper = described_class.new(github_token: 'Fake-GitHubToken-123')
238370
helper.create_milestone(
239-
test_repo,
240-
test_milestone_number,
241-
test_milestone_duedate.to_time.utc,
242-
milestone_duration,
243-
days_code_freeze,
244-
need_submission
371+
repository: test_repo,
372+
title: test_milestone_number,
373+
due_date: due_date,
374+
days_until_submission: days_until_submission,
375+
days_until_release: days_until_release
245376
)
246377
end
247378
end

0 commit comments

Comments
 (0)