From 73b61b445944f5b36c2fb1126a4f606b6fcc4ad9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 1 Jul 2025 13:36:02 +0200 Subject: [PATCH 1/8] =?UTF-8?q?=F0=9F=9A=80=20[Feature]:=20Add=20'Remainin?= =?UTF-8?q?g'=20property=20to=20GitHubContext=20types=20and=20update=20for?= =?UTF-8?q?matting=20for=20display?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/formats/GitHubContext.Format.ps1xml | 46 +++++++++++++++++++++++++ src/types/GitHubContext.Types.ps1xml | 27 +++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/types/GitHubContext.Types.ps1xml diff --git a/src/formats/GitHubContext.Format.ps1xml b/src/formats/GitHubContext.Format.ps1xml index 3e3337abe..bd2519306 100644 --- a/src/formats/GitHubContext.Format.ps1xml +++ b/src/formats/GitHubContext.Format.ps1xml @@ -26,6 +26,9 @@ + + + @@ -49,6 +52,49 @@ TokenExpirationDate + + + if ($null -eq $_.Remaining) { + return + } + + if ($_.Remaining -lt 0) { + $text = "Expired" + } else { + $text = $_.Remaining | Format-TimeSpan -Precision 2 + } + + if ($Host.UI.SupportsVirtualTerminal -and + ($env:GITHUB_ACTIONS -ne 'true')) { + switch ($_.AuthType) { + 'UAT' { + $MaxValue = [TimeSpan]::FromHours(8) + } + 'IAT' { + $MaxValue = [TimeSpan]::FromHours(1) + } + } + $Value = $_.Remaining + $ratio = [Math]::Min(($Value / $MaxValue), 1) + + if ($ratio -lt 0) { + $r = 255 + $g = 0 + } elseif ($ratio -le 0.5) { + $r = [Math]::Round(255 * (2 * $ratio)) + $g = 255 + } else { + $r = 255 + $g = [Math]::Round(255 * (2 - 2 * $ratio)) + } + $b = 0 + $color = $PSStyle.Foreground.FromRgb($r, $g, $b) + "$color$Text$($PSStyle.Reset)" + } else { + $Text + } + + diff --git a/src/types/GitHubContext.Types.ps1xml b/src/types/GitHubContext.Types.ps1xml new file mode 100644 index 000000000..372126655 --- /dev/null +++ b/src/types/GitHubContext.Types.ps1xml @@ -0,0 +1,27 @@ + + + + InstallationGitHubContext + + + Remaining + + if ($null -eq $this.TokenExpirationDate) { return } + New-TimeSpan -Start (Get-Date) -End $this.TokenExpirationDate + + + + + + UserGitHubContext + + + Remaining + + if ($null -eq $this.TokenExpirationDate) { return } + New-TimeSpan -Start (Get-Date) -End $this.TokenExpirationDate + + + + + From 7a1d50d67a8615e96d704f91e1920c0fee1a713f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 1 Jul 2025 14:21:46 +0200 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Rename=20'Remaini?= =?UTF-8?q?ng'=20property=20to=20'RemainingTime'=20in=20GitHubContext=20ty?= =?UTF-8?q?pes=20and=20update=20related=20formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/formats/GitHubContext.Format.ps1xml | 23 +++++++++++++---------- src/types/GitHubContext.Types.ps1xml | 4 ++-- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/formats/GitHubContext.Format.ps1xml b/src/formats/GitHubContext.Format.ps1xml index bd2519306..8ec839202 100644 --- a/src/formats/GitHubContext.Format.ps1xml +++ b/src/formats/GitHubContext.Format.ps1xml @@ -54,14 +54,14 @@ - if ($null -eq $_.Remaining) { + if ($null -eq $_.RemainingTime) { return } - if ($_.Remaining -lt 0) { + if ($_.RemainingTime -lt 0) { $text = "Expired" } else { - $text = $_.Remaining | Format-TimeSpan -Precision 2 + $text = $_.RemainingTime | Format-TimeSpan -Precision 2 } if ($Host.UI.SupportsVirtualTerminal -and @@ -74,24 +74,27 @@ $MaxValue = [TimeSpan]::FromHours(1) } } - $Value = $_.Remaining + $Value = $_.RemainingTime $ratio = [Math]::Min(($Value / $MaxValue), 1) - if ($ratio -lt 0) { + if ($ratio -ge 1) { + $r = 0 + $g = 255 + } elseif ($ratio -le 0) { $r = 255 $g = 0 - } elseif ($ratio -le 0.5) { - $r = [Math]::Round(255 * (2 * $ratio)) + } elseif ($ratio -ge 0.5) { + $r = [Math]::Round(255 * (2 - 2 * $ratio)) $g = 255 } else { $r = 255 - $g = [Math]::Round(255 * (2 - 2 * $ratio)) + $g = [Math]::Round(255 * (2 * $ratio)) } $b = 0 $color = $PSStyle.Foreground.FromRgb($r, $g, $b) - "$color$Text$($PSStyle.Reset)" + "$color$text$($PSStyle.Reset)" } else { - $Text + $text } diff --git a/src/types/GitHubContext.Types.ps1xml b/src/types/GitHubContext.Types.ps1xml index 372126655..cf58d6858 100644 --- a/src/types/GitHubContext.Types.ps1xml +++ b/src/types/GitHubContext.Types.ps1xml @@ -4,7 +4,7 @@ InstallationGitHubContext - Remaining + RemainingTime if ($null -eq $this.TokenExpirationDate) { return } New-TimeSpan -Start (Get-Date) -End $this.TokenExpirationDate @@ -16,7 +16,7 @@ UserGitHubContext - Remaining + RemainingTime if ($null -eq $this.TokenExpirationDate) { return } New-TimeSpan -Start (Get-Date) -End $this.TokenExpirationDate From afaaf1b4bcc0a5de3b7a0ac82904dd1c223ac602 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 1 Jul 2025 16:10:26 +0200 Subject: [PATCH 3/8] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Refactor=20GitHub?= =?UTF-8?q?Context=20types=20by=20removing=20InstallationGitHubContext=20a?= =?UTF-8?q?nd=20UserGitHubContext=20definitions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/GitHubContext.Types.ps1xml | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/types/GitHubContext.Types.ps1xml b/src/types/GitHubContext.Types.ps1xml index cf58d6858..b16b585d4 100644 --- a/src/types/GitHubContext.Types.ps1xml +++ b/src/types/GitHubContext.Types.ps1xml @@ -1,19 +1,7 @@ - InstallationGitHubContext - - - RemainingTime - - if ($null -eq $this.TokenExpirationDate) { return } - New-TimeSpan -Start (Get-Date) -End $this.TokenExpirationDate - - - - - - UserGitHubContext + GitHubContext RemainingTime From 3248810a364a4a2df43ed480522b627b194eadc8 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 1 Jul 2025 16:13:33 +0200 Subject: [PATCH 4/8] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20formatti?= =?UTF-8?q?ng=20to=20use=20'Remaining'=20property=20instead=20of=20'Remain?= =?UTF-8?q?ingTime'=20in=20GitHubContext=20display?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/formats/GitHubContext.Format.ps1xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/formats/GitHubContext.Format.ps1xml b/src/formats/GitHubContext.Format.ps1xml index 8ec839202..28a1a0b11 100644 --- a/src/formats/GitHubContext.Format.ps1xml +++ b/src/formats/GitHubContext.Format.ps1xml @@ -54,14 +54,14 @@ - if ($null -eq $_.RemainingTime) { + if ($null -eq $_.Remaining) { return } - if ($_.RemainingTime -lt 0) { + if ($_.Remaining -lt 0) { $text = "Expired" } else { - $text = $_.RemainingTime | Format-TimeSpan -Precision 2 + $text = "$($_.Remaining.Hours)h $($_.Remaining.Minutes)m $($_.Remaining.Seconds)s" } if ($Host.UI.SupportsVirtualTerminal -and @@ -74,8 +74,7 @@ $MaxValue = [TimeSpan]::FromHours(1) } } - $Value = $_.RemainingTime - $ratio = [Math]::Min(($Value / $MaxValue), 1) + $ratio = [Math]::Min(($_.Remaining / $MaxValue), 1) if ($ratio -ge 1) { $r = 0 From f0169a17ced12324631d7a3b343f8ef833b47b91 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 1 Jul 2025 16:32:02 +0200 Subject: [PATCH 5/8] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Refactor=20GitHub?= =?UTF-8?q?Context=20constructors=20to=20initialize=20properties=20from=20?= =?UTF-8?q?PSCustomObject?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/classes/public/Context/GitHubContext.ps1 | 22 ++++++++++- .../GitHubContext/AppGitHubContext.ps1 | 37 +++++++++++------- .../InstallationGitHubContext.ps1 | 39 ++++++++++++------- .../GitHubContext/UserGitHubContext.ps1 | 36 +++++++++++------ .../Auth/Context/Resolve-GitHubContext.ps1 | 10 +++-- .../public/Auth/Context/Get-GitHubContext.ps1 | 6 +-- 6 files changed, 104 insertions(+), 46 deletions(-) diff --git a/src/classes/public/Context/GitHubContext.ps1 b/src/classes/public/Context/GitHubContext.ps1 index 8145217cd..4eaee6d32 100644 --- a/src/classes/public/Context/GitHubContext.ps1 +++ b/src/classes/public/Context/GitHubContext.ps1 @@ -62,9 +62,29 @@ # The default value for the 'per_page' API parameter used in 'GET' functions that support paging. [int] $PerPage - # Simple parameterless constructor GitHubContext() {} + GitHubContext([pscustomobject]$Object) { + $this.ID = $Object.ID + $this.Name = $Object.Name + $this.DisplayName = $Object.DisplayName + $this.Type = $Object.Type + $this.HostName = $Object.HostName + $this.ApiBaseUri = $Object.ApiBaseUri + $this.ApiVersion = $Object.ApiVersion + $this.AuthType = $Object.AuthType + $this.NodeID = $Object.NodeID + $this.DatabaseID = $Object.DatabaseID + $this.UserName = $Object.UserName + $this.Token = $Object.Token + $this.TokenType = $Object.TokenType + $this.Enterprise = $Object.Enterprise + $this.Owner = $Object.Owner + $this.Repository = $Object.Repository + $this.HttpVersion = $Object.HttpVersion + $this.PerPage = $Object.PerPage + } + [string] ToString() { return $this.Name } diff --git a/src/classes/public/Context/GitHubContext/AppGitHubContext.ps1 b/src/classes/public/Context/GitHubContext/AppGitHubContext.ps1 index 68a010afd..e9e795adf 100644 --- a/src/classes/public/Context/GitHubContext/AppGitHubContext.ps1 +++ b/src/classes/public/Context/GitHubContext/AppGitHubContext.ps1 @@ -14,20 +14,31 @@ # The events that the app is subscribing to once installed [string[]] $Events - # Simple parameterless constructor AppGitHubContext() {} - # Creates a context object from a hashtable of key-vaule pairs. - AppGitHubContext([hashtable]$Properties) { - foreach ($Property in $Properties.Keys) { - $this.$Property = $Properties.$Property - } - } - - # Creates a context object from a PSCustomObject. - AppGitHubContext([PSCustomObject]$Object) { - $Object.PSObject.Properties | ForEach-Object { - $this.($_.Name) = $_.Value - } + AppGitHubContext([pscustomobject]$Object) { + $this.ID = $Object.ID + $this.Name = $Object.Name + $this.DisplayName = $Object.DisplayName + $this.Type = $Object.Type + $this.HostName = $Object.HostName + $this.ApiBaseUri = $Object.ApiBaseUri + $this.ApiVersion = $Object.ApiVersion + $this.AuthType = $Object.AuthType + $this.NodeID = $Object.NodeID + $this.DatabaseID = $Object.DatabaseID + $this.UserName = $Object.UserName + $this.Token = $Object.Token + $this.TokenType = $Object.TokenType + $this.Enterprise = $Object.Enterprise + $this.Owner = $Object.Owner + $this.Repository = $Object.Repository + $this.HttpVersion = $Object.HttpVersion + $this.PerPage = $Object.PerPage + $this.ClientID = $Object.ClientID + $this.OwnerName = $Object.OwnerName + $this.OwnerType = $Object.OwnerType + $this.Permissions = $Object.Permissions + $this.Events = $Object.Events } } diff --git a/src/classes/public/Context/GitHubContext/InstallationGitHubContext.ps1 b/src/classes/public/Context/GitHubContext/InstallationGitHubContext.ps1 index b7dc45a15..f6163d1ee 100644 --- a/src/classes/public/Context/GitHubContext/InstallationGitHubContext.ps1 +++ b/src/classes/public/Context/GitHubContext/InstallationGitHubContext.ps1 @@ -21,20 +21,33 @@ # The target login or slug of the installation. [string] $InstallationName - # Simple parameterless constructor InstallationGitHubContext() {} - # Creates a context object from a hashtable of key-vaule pairs. - InstallationGitHubContext([hashtable]$Properties) { - foreach ($Property in $Properties.Keys) { - $this.$Property = $Properties.$Property - } - } - - # Creates a context object from a PSCustomObject. - InstallationGitHubContext([PSCustomObject]$Object) { - $Object.PSObject.Properties | ForEach-Object { - $this.($_.Name) = $_.Value - } + InstallationGitHubContext([pscustomobject]$Object) { + $this.ID = $Object.ID + $this.Name = $Object.Name + $this.DisplayName = $Object.DisplayName + $this.Type = $Object.Type + $this.HostName = $Object.HostName + $this.ApiBaseUri = $Object.ApiBaseUri + $this.ApiVersion = $Object.ApiVersion + $this.AuthType = $Object.AuthType + $this.NodeID = $Object.NodeID + $this.DatabaseID = $Object.DatabaseID + $this.UserName = $Object.UserName + $this.Token = $Object.Token + $this.TokenType = $Object.TokenType + $this.Enterprise = $Object.Enterprise + $this.Owner = $Object.Owner + $this.Repository = $Object.Repository + $this.HttpVersion = $Object.HttpVersion + $this.PerPage = $Object.PerPage + $this.ClientID = $Object.ClientID + $this.TokenExpirationDate = $Object.TokenExpirationDate + $this.InstallationID = $Object.InstallationID + $this.Permissions = $Object.Permissions + $this.Events = $Object.Events + $this.InstallationType = $Object.InstallationType + $this.InstallationName = $Object.InstallationName } } diff --git a/src/classes/public/Context/GitHubContext/UserGitHubContext.ps1 b/src/classes/public/Context/GitHubContext/UserGitHubContext.ps1 index 345aaf867..1c01c66ad 100644 --- a/src/classes/public/Context/GitHubContext/UserGitHubContext.ps1 +++ b/src/classes/public/Context/GitHubContext/UserGitHubContext.ps1 @@ -22,20 +22,32 @@ # 2024-01-01-00:00:00 [datetime] $RefreshTokenExpirationDate - # Simple parameterless constructor UserGitHubContext() {} - # Creates a context object from a hashtable of key-vaule pairs. - UserGitHubContext([hashtable]$Properties) { - foreach ($Property in $Properties.Keys) { - $this.$Property = $Properties.$Property - } - } - - # Creates a context object from a PSCustomObject. UserGitHubContext([PSCustomObject]$Object) { - $Object.PSObject.Properties | ForEach-Object { - $this.($_.Name) = $_.Value - } + $this.ID = $Object.ID + $this.Name = $Object.Name + $this.DisplayName = $Object.DisplayName + $this.Type = $Object.Type + $this.HostName = $Object.HostName + $this.ApiBaseUri = $Object.ApiBaseUri + $this.ApiVersion = $Object.ApiVersion + $this.AuthType = $Object.AuthType + $this.NodeID = $Object.NodeID + $this.DatabaseID = $Object.DatabaseID + $this.UserName = $Object.UserName + $this.Token = $Object.Token + $this.TokenType = $Object.TokenType + $this.Enterprise = $Object.Enterprise + $this.Owner = $Object.Owner + $this.Repository = $Object.Repository + $this.HttpVersion = $Object.HttpVersion + $this.PerPage = $Object.PerPage + $this.AuthClientID = $Object.AuthClientID + $this.DeviceFlowType = $Object.DeviceFlowType + $this.Scope = $Object.Scope + $this.TokenExpirationDate = $Object.TokenExpirationDate + $this.RefreshToken = $Object.RefreshToken + $this.RefreshTokenExpirationDate = $Object.RefreshTokenExpirationDate } } diff --git a/src/functions/private/Auth/Context/Resolve-GitHubContext.ps1 b/src/functions/private/Auth/Context/Resolve-GitHubContext.ps1 index e6fa3048c..463122e2d 100644 --- a/src/functions/private/Auth/Context/Resolve-GitHubContext.ps1 +++ b/src/functions/private/Auth/Context/Resolve-GitHubContext.ps1 @@ -45,10 +45,12 @@ Write-Verbose "Anonymous: [$Anonymous]" if ($Anonymous -or $Context -eq 'Anonymous') { Write-Verbose 'Returning Anonymous context.' - return [GitHubContext]@{ - Name = 'Anonymous' - AuthType = 'Anonymous' - } + return [GitHubContext]::new( + [pscustomobject]@{ + Name = 'Anonymous' + AuthType = 'Anonymous' + } + ) } if ($Context -is [string]) { diff --git a/src/functions/public/Auth/Context/Get-GitHubContext.ps1 b/src/functions/public/Auth/Context/Get-GitHubContext.ps1 index 2e7deec7c..4a9440ab3 100644 --- a/src/functions/public/Auth/Context/Get-GitHubContext.ps1 +++ b/src/functions/public/Auth/Context/Get-GitHubContext.ps1 @@ -73,13 +73,13 @@ Write-Verbose "Converting to: [$($contextObj.Type)GitHubContext]" switch ($contextObj.Type) { 'User' { - [UserGitHubContext]::new($contextObj) + [UserGitHubContext]::new([pscustomobject]$contextObj) } 'App' { - [AppGitHubContext]::new($contextObj) + [AppGitHubContext]::new([pscustomobject]$contextObj) } 'Installation' { - [InstallationGitHubContext]::new($contextObj) + [InstallationGitHubContext]::new([pscustomobject]$contextObj) } default { throw "Unknown context type: [$($contextObj.Type)]" From e3746c22ec2056c50b22ef3361df7603f9e3d41f Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 1 Jul 2025 16:44:58 +0200 Subject: [PATCH 6/8] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Update=20token=20?= =?UTF-8?q?expiration=20date=20properties=20in=20InstallationGitHubContext?= =?UTF-8?q?=20and=20UserGitHubContext=20to=20be=20nullable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Context/GitHubContext/InstallationGitHubContext.ps1 | 4 ++-- .../public/Context/GitHubContext/UserGitHubContext.ps1 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/classes/public/Context/GitHubContext/InstallationGitHubContext.ps1 b/src/classes/public/Context/GitHubContext/InstallationGitHubContext.ps1 index f6163d1ee..c1a6ec77a 100644 --- a/src/classes/public/Context/GitHubContext/InstallationGitHubContext.ps1 +++ b/src/classes/public/Context/GitHubContext/InstallationGitHubContext.ps1 @@ -4,10 +4,10 @@ # The token expiration date. # 2024-01-01-00:00:00 - [datetime] $TokenExpirationDate + [System.Nullable[datetime]] $TokenExpirationDate # The installation ID. - [uint64] $InstallationID + [System.Nullable[uint64]] $InstallationID # The permissions that the app is requesting on the target [pscustomobject] $Permissions diff --git a/src/classes/public/Context/GitHubContext/UserGitHubContext.ps1 b/src/classes/public/Context/GitHubContext/UserGitHubContext.ps1 index 1c01c66ad..fad314e37 100644 --- a/src/classes/public/Context/GitHubContext/UserGitHubContext.ps1 +++ b/src/classes/public/Context/GitHubContext/UserGitHubContext.ps1 @@ -13,14 +13,14 @@ # The token expiration date. # 2024-01-01-00:00:00 - [datetime] $TokenExpirationDate + [System.Nullable[datetime]] $TokenExpirationDate # The refresh token. [securestring] $RefreshToken # The refresh token expiration date. # 2024-01-01-00:00:00 - [datetime] $RefreshTokenExpirationDate + [System.Nullable[datetime]] $RefreshTokenExpirationDate UserGitHubContext() {} From 976c94dd72fec1a5a5136eb9998fe6d7668b8fc9 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 1 Jul 2025 16:59:00 +0200 Subject: [PATCH 7/8] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Rename=20'Remaini?= =?UTF-8?q?ngTime'=20property=20back=20to=20'Remaining'=20in=20GitHubConte?= =?UTF-8?q?xt=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/GitHubContext.Types.ps1xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/GitHubContext.Types.ps1xml b/src/types/GitHubContext.Types.ps1xml index b16b585d4..2e93ecc49 100644 --- a/src/types/GitHubContext.Types.ps1xml +++ b/src/types/GitHubContext.Types.ps1xml @@ -4,7 +4,7 @@ GitHubContext - RemainingTime + Remaining if ($null -eq $this.TokenExpirationDate) { return } New-TimeSpan -Start (Get-Date) -End $this.TokenExpirationDate From 4e71f1b3fd5d29fe3269d7ba7dce5825849b2273 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Tue, 1 Jul 2025 17:10:06 +0200 Subject: [PATCH 8/8] =?UTF-8?q?=F0=9F=A9=B9=20[Patch]:=20Rename=20'GitHubC?= =?UTF-8?q?ontext'=20to=20'UserGitHubContext'=20and=20ensure=20'Remaining'?= =?UTF-8?q?=20property=20is=20defined=20in=20both=20UserGitHubContext=20an?= =?UTF-8?q?d=20InstallationGitHubContext?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/GitHubContext.Types.ps1xml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/types/GitHubContext.Types.ps1xml b/src/types/GitHubContext.Types.ps1xml index 2e93ecc49..2b1c79e3d 100644 --- a/src/types/GitHubContext.Types.ps1xml +++ b/src/types/GitHubContext.Types.ps1xml @@ -1,7 +1,19 @@ - GitHubContext + UserGitHubContext + + + Remaining + + if ($null -eq $this.TokenExpirationDate) { return } + New-TimeSpan -Start (Get-Date) -End $this.TokenExpirationDate + + + + + + InstallationGitHubContext Remaining