diff --git a/GitHubEvents.ps1 b/GitHubEvents.ps1 new file mode 100644 index 00000000..b23ce631 --- /dev/null +++ b/GitHubEvents.ps1 @@ -0,0 +1,125 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +function Get-GitHubEvent +{ +<# + .DESCRIPTION + Lists events for an issue, repository, or a single event + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .PARAMETER OwnerName + Owner of the repository. + If not supplied here, the DefaultOwnerName configuration property value will be used. + + .PARAMETER RepositoryName + Name of the repository. + If not supplied here, the DefaultRepositoryName configuration property value will be used. + + .PARAMETER Uri + Uri for the repository. + The OwnerName and RepositoryName will be extracted from here instead of needing to provide + them individually. + + .PARAMETER EventID + The ID of a specific event to get. If not supplied, will return back all events for this repository. + + .PARAMETER Issue + Issue number to get events for. If not supplied, will return back all events for this repository. + + .PARAMETER AccessToken + If provided, this will be used as the AccessToken for authentication with the + REST Api. Otherwise, will attempt to use the configured value or will run unauthenticated. + + .PARAMETER NoStatus + If this switch is specified, long-running commands will run on the main thread + with no commandline status update. When not specified, those commands run in + the background, enabling the command prompt to provide status information. + If not supplied here, the DefaultNoStatus configuration property value will be used. + + .EXAMPLE + Get-GitHubEvent -OwnerName Powershell -RepositoryName PowerShellForGitHub + + Get the events for the PowerShell\PowerShellForGitHub project. +#> + [CmdletBinding( + SupportsShouldProcess, + DefaultParametersetName='RepositoryElements')] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification="Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently.")] + param( + [Parameter(Mandatory, ParameterSetName='RepositoryElements')] + [Parameter(Mandatory, ParameterSetName='IssueElements')] + [Parameter(Mandatory, ParameterSetName='EventElements')] + [string] $OwnerName, + + [Parameter(Mandatory, ParameterSetName='RepositoryElements')] + [Parameter(Mandatory, ParameterSetName='IssueElements')] + [Parameter(Mandatory, ParameterSetName='EventElements')] + [string] $RepositoryName, + + [Parameter(Mandatory, ParameterSetName='RepositoryUri')] + [Parameter(Mandatory, ParameterSetName='IssueUri')] + [Parameter(Mandatory, ParameterSetName='EventUri')] + [string] $Uri, + + [Parameter(Mandatory, ParameterSetName='EventUri')] + [Parameter(Mandatory, ParameterSetName='EventElements')] + [int] $EventID, + + [Parameter(Mandatory, ParameterSetName='IssueUri')] + [Parameter(Mandatory, ParameterSetName='IssueElements')] + [int] $Issue, + + [string] $AccessToken, + + [switch] $NoStatus + ) + + Write-InvocationLog + + $elements = Resolve-RepositoryElements + $OwnerName = $elements.ownerName + $RepositoryName = $elements.repositoryName + + $telemetryProperties = @{ + 'OwnerName' = (Get-PiiSafeString -PlainText $OwnerName) + 'RepositoryName' = (Get-PiiSafeString -PlainText $RepositoryName) + 'ProvidedIssue' = $PSBoundParameters.ContainsKey('Issue') + 'ProvidedEvent' = $PSBoundParameters.ContainsKey('EventID') + } + + if ($PSBoundParameters.ContainsKey('EventID')) + { + $uriFragment = "repos/$OwnerName/$RepositoryName/issues/events/$EventID" + $description = "Getting event $EventID for $RepositoryName" + } + elseif ($PSBoundParameters.ContainsKey('Issue')) + { + $uriFragment = "repos/$OwnerName/$RepositoryName/issues/$Issue/events" + $description = "Getting events for issue $Issue in $RepositoryName" + } + else + { + $uriFragment = "repos/$OwnerName/$RepositoryName/issues/events" + $description = "Getting events for $RepositoryName" + } + + $acceptHeaders = @( + 'application/vnd.github.starfox-preview+json', + 'application/vnd.github.sailer-v-preview+json', + 'application/vnd.github.symmetra-preview+json', + 'application/vnd.github.machine-man-preview') + + $params = @{ + 'UriFragment' = $uriFragment + 'Description' = $description + 'AccessToken' = $AccessToken + 'AcceptHeader' = $acceptHeaders -join ',' + 'TelemetryEventName' = $MyInvocation.MyCommand.Name + 'TelemetryProperties' = $telemetryProperties + 'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus) + } + + return Invoke-GHRestMethodMultipleResult @params +} diff --git a/PowerShellForGitHub.psd1 b/PowerShellForGitHub.psd1 index fb44f43f..1f9f805b 100644 --- a/PowerShellForGitHub.psd1 +++ b/PowerShellForGitHub.psd1 @@ -24,6 +24,7 @@ 'GitHubBranches.ps1', 'GitHubCore.ps1', 'GitHubComments.ps1', + 'GitHubEvents.ps1', 'GitHubIssues.ps1', 'GitHubLabels.ps1', 'GitHubMiscellaneous.ps1', @@ -51,6 +52,7 @@ 'Get-GitHubComment', 'Get-GitHubConfiguration', 'Get-GitHubEmoji', + 'Get-GitHubEvent', 'Get-GitHubGitIgnore', 'Get-GitHubIssue', 'Get-GitHubIssueTimeline', diff --git a/Tests/GitHubEvents.tests.ps1 b/Tests/GitHubEvents.tests.ps1 new file mode 100644 index 00000000..1d76003e --- /dev/null +++ b/Tests/GitHubEvents.tests.ps1 @@ -0,0 +1,158 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +<# +.Synopsis + Tests for GitHubEvents.ps1 module +#> + +[String] $root = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path) +. (Join-Path -Path $root -ChildPath 'Tests\Config\Settings.ps1') +Import-Module -Name $root -Force + +function Initialize-AppVeyor +{ +<# + .SYNOPSIS + Configures the tests to run with the authentication information stored in AppVeyor + (if that information exists in the environment). + + .DESCRIPTION + Configures the tests to run with the authentication information stored in AppVeyor + (if that information exists in the environment). + + The Git repo for this module can be found here: http://aka.ms/PowerShellForGitHub + + .NOTES + Internal-only helper method. + + The only reason this exists is so that we can leverage CodeAnalysis.SuppressMessageAttribute, + which can only be applied to functions. + + We call this immediately after the declaration so that AppVeyor initialization can heppen + (if applicable). + +#> + [CmdletBinding()] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "", Justification="Needed to configure with the stored, encrypted string value in AppVeyor.")] + param() + + if ($env:AppVeyor) + { + $secureString = $env:avAccessToken | ConvertTo-SecureString -AsPlainText -Force + $cred = New-Object System.Management.Automation.PSCredential "", $secureString + Set-GitHubAuthentication -Credential $cred + + $script:ownerName = $env:avOwnerName + $script:organizationName = $env:avOrganizationName + + $message = @( + 'This run is executed in the AppVeyor environment.', + 'The GitHub Api Token won''t be decrypted in PR runs causing some tests to fail.', + '403 errors possible due to GitHub hourly limit for unauthenticated queries.', + 'Use Set-GitHubAuthentication manually. modify the values in Tests\Config\Settings.ps1,', + 'and run tests on your machine first.') + Write-Warning -Message ($message -join [Environment]::NewLine) + } +} + +Initialize-AppVeyor + +$accessTokenConfigured = Test-GitHubAuthenticationConfigured +if (-not $accessTokenConfigured) +{ + $message = @( + 'GitHub API Token not defined, some of the tests will be skipped.', + '403 errors possible due to GitHub hourly limit for unauthenticated queries.') + Write-Warning -Message ($message -join [Environment]::NewLine) +} + +# Backup the user's configuration before we begin, and ensure we're at a pure state before running +# the tests. We'll restore it at the end. +$configFile = New-TemporaryFile + +try +{ + Backup-GitHubConfiguration -Path $configFile + Reset-GitHubConfiguration + + if ($accessTokenConfigured) + { + Describe 'Getting events from repository' { + $repositoryName = [Guid]::NewGuid() + $null = New-GitHubRepository -RepositoryName $repositoryName + + Context 'For getting events from a new repository' { + $events = @(Get-GitHubEvent -OwnerName $ownerName -RepositoryName $repositoryName) + + It 'Should have no events' { + $events.Count | Should be 0 + } + } + + $issue = New-GithubIssue -OwnerName $ownerName -RepositoryName $repositoryName -Title "New Issue" + Update-GitHubIssue -OwnerName $ownerName -RepositoryName $repositoryName -Issue $issue.number -State closed + + Context 'For getting events from a repository' { + $events = @(Get-GitHubEvent -OwnerName $ownerName -RepositoryName $repositoryName) + + It 'Should have an event from closing an issue' { + $events.Count | Should be 1 + } + } + + $null = Remove-GitHubRepository -OwnerName $ownerName -RepositoryName $repositoryName + } + + Describe 'Getting events from an issue' { + $repositoryName = [Guid]::NewGuid() + $null = New-GitHubRepository -RepositoryName $repositoryName + $issue = New-GithubIssue -OwnerName $ownerName -RepositoryName $repositoryName -Title "New Issue" + + Context 'For getting events from a new issue' { + $events = @(Get-GitHubEvent -OwnerName $ownerName -RepositoryName $repositoryName -Issue $issue.number) + + It 'Should have no events' { + $events.Count | Should be 0 + } + } + + Context 'For getting events from an issue' { + Update-GitHubIssue -OwnerName $ownerName -RepositoryName $repositoryName -Issue $issue.number -State closed + Update-GitHubIssue -OwnerName $ownerName -RepositoryName $repositoryName -Issue $issue.number -State open + $events = @(Get-GitHubEvent -OwnerName $ownerName -RepositoryName $repositoryName) + + It 'Should have two events from closing and opening the issue' { + $events.Count | Should be 2 + } + } + + $null = Remove-GitHubRepository -OwnerName $ownerName -RepositoryName $repositoryName + } + + Describe 'Getting an event directly' { + $repositoryName = [Guid]::NewGuid() + $null = New-GitHubRepository -RepositoryName $repositoryName + $issue = New-GithubIssue -OwnerName $ownerName -RepositoryName $repositoryName -Title "New Issue" + Update-GitHubIssue -OwnerName $ownerName -RepositoryName $repositoryName -Issue $issue.number -State closed + Update-GitHubIssue -OwnerName $ownerName -RepositoryName $repositoryName -Issue $issue.number -State open + $events = @(Get-GitHubEvent -OwnerName $ownerName -RepositoryName $repositoryName) + + Context 'For getting an event directly'{ + $singleEvent = Get-GitHubEvent -OwnerName $ownerName -RepositoryName $repositoryName -EventID $events[0].id + + It 'Should have the correct event type'{ + $singleEvent.event | Should be 'reopened' + } + } + + $null = Remove-GitHubRepository -OwnerName $ownerName -RepositoryName $repositoryName + } + } +} +catch +{ + # Restore the user's configuration to its pre-test state + Restore-GitHubConfiguration -Path $configFile +} + diff --git a/USAGE.md b/USAGE.md index 0495d294..55adcc0b 100644 --- a/USAGE.md +++ b/USAGE.md @@ -42,6 +42,10 @@ * [Adding a new comment to an issue](#adding-a-new-comment-to-an-issue) * [Editing an existing comment](#editing-an-existing-comment) * [Removing a comment](#removing-a-comment) + * [Events](#Events) + * [Get events from a repository](#get-events-from-a-repository) + * [Get events from an issue](#get-events-from-an-issue) + * [Get a single event](#get-a-single-event]) ---------- ## Logging @@ -411,3 +415,22 @@ Set-GitHubComment -OwnerName Powershell -RepositoryName PowerShellForGitHub -Com ```powershell Remove-GitHubComment -OwnerName Powershell -RepositoryName PowerShellForGitHub -CommentID 1 ``` + +---------- + +### Events + +#### Get events from a repository +```powershell +Get-GitHubEvent -OwnerName Powershell -RepositoryName PowerShellForGitHub +``` + +#### Get events from an issue +```powershell +Get-GitHubEvent -OwnerName Powershell -RepositoryName PowerShellForGitHub -Issue 1 +``` + +#### Get a single event +```powershell +Get-GitHubEvent -OwnerName Powershell -RepositoryName PowerShellForGitHub -EventID 1 +```