Add support for assignee APIs (#54)

Adds support for the [Issues Assignees](https://developer.github.com/v3/issues/assignees/) API's
This commit is contained in:
Pepe Rivera 2018-11-30 14:47:14 -08:00 коммит произвёл Howard Wolosky
Родитель 6cf344fb38
Коммит 680696a833
5 изменённых файлов: 561 добавлений и 5 удалений

386
GitHubAssignees.ps1 Normal file
Просмотреть файл

@ -0,0 +1,386 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
function Get-GitHubAssignee
{
<#
.DESCRIPTION
Lists the available assignees for issues in a repository.
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 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-GitHubAsigneeList -OwnerName Powershell -RepositoryName PowerShellForGitHub
Lists the available assignees for issues from the PowerShell\PowerShellForGitHub project.
#>
[CmdletBinding(
SupportsShouldProcess,
DefaultParametersetName='Elements')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification="Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently.")]
param(
[Parameter(ParameterSetName='Elements')]
[string] $OwnerName,
[Parameter(ParameterSetName='Elements')]
[string] $RepositoryName,
[Parameter(
Mandatory,
ParameterSetName='Uri')]
[string] $Uri,
[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)
}
$params = @{
'UriFragment' = "repos/$OwnerName/$RepositoryName/assignees"
'Description' = "Getting assignee list for $RepositoryName"
'AccessToken' = $AccessToken
'TelemetryEventName' = $MyInvocation.MyCommand.Name
'TelemetryProperties' = $telemetryProperties
'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus)
}
return Invoke-GHRestMethodMultipleResult @params
}
function Test-GitHubAssignee
{
<#
.DESCRIPTION
Checks if a user has permission to be assigned to an issue in this repository. Returns a boolean.
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 Assignee
Username for the assignee
.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.
.OUTPUTS
[bool] If the assignee can be assigned to issues in the repository.
.EXAMPLE
Test-GitHubAssignee -OwnerName Powershell -RepositoryName PowerShellForGitHub -Assignee "LoginID123"
Checks if a user has permission to be assigned to an issue from the PowerShell\PowerShellForGitHub project.
#>
[CmdletBinding(
SupportsShouldProcess,
DefaultParametersetName='Elements')]
[OutputType([bool])]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification="Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently.")]
param(
[Parameter(ParameterSetName='Elements')]
[string] $OwnerName,
[Parameter(ParameterSetName='Elements')]
[string] $RepositoryName,
[Parameter(
Mandatory,
ParameterSetName='Uri')]
[string] $Uri,
[string] $Assignee,
[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)
'Asignee' = (Get-PiiSafeString -PlainText $Assignee)
}
$params = @{
'UriFragment' = "repos/$OwnerName/$RepositoryName/assignees/$Assignee"
'Method' = 'Get'
'Description' = "Checking permission for $Assignee for $RepositoryName"
'AccessToken' = $AccessToken
'TelemetryEventName' = $MyInvocation.MyCommand.Name
'TelemetryProperties' = $telemetryProperties
'ExtendedResult'= $true
'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus)
}
try
{
$response = Invoke-GHRestMethod @params
return $response.StatusCode -eq 204
}
catch
{
return $false
}
}
function New-GithubAssignee
{
<#
.DESCRIPTION
Adds a list of assignees to a Github Issue for the given repository.
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 Issue
Issue number to add the assignees to.
.PARAMETER Assignee
Usernames of users to assign this issue to. NOTE: Only users with push access can add assignees to an issue.
Assignees are silently ignored otherwise.
.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
New-GithubAssignee -OwnerName Powershell -RepositoryName PowerShellForGitHub -Assignee $assignee
Lists the available assignees for issues from the PowerShell\PowerShellForGitHub project.
#>
[CmdletBinding(
SupportsShouldProcess,
DefaultParametersetName='Elements')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification="Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently.")]
param(
[Parameter(ParameterSetName='Elements')]
[string] $OwnerName,
[Parameter(ParameterSetName='Elements')]
[string] $RepositoryName,
[Parameter(
Mandatory,
ParameterSetName='Uri')]
[string] $Uri,
[Parameter(Mandatory)]
[int] $Issue,
[Parameter(Mandatory)]
[ValidateCount(1, 10)]
[string[]] $Assignee,
[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)
'AssigneeCount' = $Assignee.Count
'Issue' = (Get-PiiSafeString -PlainText $Issue)
}
$hashBody = @{
'assignees' = $Assignee
}
$params = @{
'UriFragment' = "repos/$OwnerName/$RepositoryName/issues/$Issue/assignees"
'Body' = (ConvertTo-Json -InputObject $hashBody)
'Method' = 'Post'
'Description' = "Add assignees to issue $Issue for $RepositoryName"
'AccessToken' = $AccessToken
'AcceptHeader' = 'application/vnd.github.symmetra-preview+json'
'TelemetryEventName' = $MyInvocation.MyCommand.Name
'TelemetryProperties' = $telemetryProperties
'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus)
}
return Invoke-GHRestMethod @params
}
function Remove-GithubAssignee
{
<#
.DESCRIPTION
Removes an assignee from a Github issue.
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 Issue
Issue number to remove the assignees from.
.PARAMETER Assignee
Usernames of assignees to remove from an issue. NOTE: Only users with push access can remove assignees from an issue. Assignees are silently ignored otherwise.
.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
Remove-GithubAssignee -OwnerName Powershell -RepositoryName PowerShellForGitHub -Assignee $assignees
Lists the available assignees for issues from the PowerShell\PowerShellForGitHub project.
#>
[CmdletBinding(
SupportsShouldProcess,
DefaultParametersetName='Elements')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSShouldProcess", "", Justification="Methods called within here make use of PSShouldProcess, and the switch is passed on to them inherently.")]
param(
[Parameter(ParameterSetName='Elements')]
[string] $OwnerName,
[Parameter(ParameterSetName='Elements')]
[string] $RepositoryName,
[Parameter(
Mandatory,
ParameterSetName='Uri')]
[string] $Uri,
[Parameter(Mandatory)]
[int] $Issue,
[Parameter(Mandatory)]
[string[]] $Assignee,
[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)
'AssigneeCount' = $Assignee.Count
'Issue' = (Get-PiiSafeString -PlainText $Issue)
}
$hashBody = @{
'assignees' = $Assignee
}
$params = @{
'UriFragment' = "repos/$OwnerName/$RepositoryName/issues/$Issue/assignees"
'Body' = (ConvertTo-Json -InputObject $hashBody)
'Method' = 'Delete'
'Description' = "Removing assignees from issue $Issue for $RepositoryName"
'AccessToken' = $AccessToken
'AcceptHeader' = 'application/vnd.github.symmetra-preview+json'
'TelemetryEventName' = $MyInvocation.MyCommand.Name
'TelemetryProperties' = $telemetryProperties
'NoStatus' = (Resolve-ParameterWithDefaultConfigurationValue -Name NoStatus -ConfigValueName DefaultNoStatus)
}
return Invoke-GHRestMethod @params
}

Просмотреть файл

@ -7,6 +7,8 @@ $script:gitHubApiOrgsUrl = "https://api.github.com/orgs"
$script:defaultAcceptHeader = 'application/vnd.github.v3+json'
Set-Variable -Scope Script -Option ReadOnly -Name ValidBodyContainingRequestMethods -Value ('post', 'patch', 'put', 'delete')
function Invoke-GHRestMethod
{
<#
@ -165,7 +167,7 @@ function Invoke-GHRestMethod
$headers['Authorization'] = "token $AccessToken"
}
if ($Method -in ('post', 'patch', 'put'))
if ($Method -in $ValidBodyContainingRequestMethods)
{
$headers.Add("Content-Type", "application/json; charset=UTF-8")
}
@ -188,7 +190,7 @@ function Invoke-GHRestMethod
$params.Add("UseBasicParsing", $true)
$params.Add("TimeoutSec", (Get-GitHubConfiguration -Name WebRequestTimeoutSec))
if ($Method -in ('post', 'put', 'patch') -and (-not [String]::IsNullOrEmpty($Body)))
if ($Method -in $ValidBodyContainingRequestMethods -and (-not [String]::IsNullOrEmpty($Body)))
{
$bodyAsBytes = [System.Text.Encoding]::UTF8.GetBytes($Body)
$params.Add("Body", $bodyAsBytes)
@ -210,7 +212,7 @@ function Invoke-GHRestMethod
if ($PSCmdlet.ShouldProcess($jobName, "Start-Job"))
{
[scriptblock]$scriptBlock = {
param($Url, $method, $Headers, $Body, $TimeoutSec, $ScriptRootPath)
param($Url, $Method, $Headers, $Body, $ValidBodyContainingRequestMethods, $TimeoutSec, $ScriptRootPath)
# We need to "dot invoke" Helpers.ps1 and GitHubConfiguration.ps1 within
# the context of this script block since we're running in a different
@ -227,7 +229,7 @@ function Invoke-GHRestMethod
$params.Add("UseBasicParsing", $true)
$params.Add("TimeoutSec", $TimeoutSec)
if ($Method -in ('post', 'put', 'patch') -and (-not [String]::IsNullOrEmpty($Body)))
if ($Method -in $ValidBodyContainingRequestMethods -and (-not [String]::IsNullOrEmpty($Body)))
{
$bodyAsBytes = [System.Text.Encoding]::UTF8.GetBytes($Body)
$params.Add("Body", $bodyAsBytes)
@ -265,7 +267,7 @@ function Invoke-GHRestMethod
}
}
$null = Start-Job -Name $jobName -ScriptBlock $scriptBlock -Arg @($url, $Method, $headers, $Body, (Get-GitHubConfiguration -Name WebRequestTimeoutSec), $PSScriptRoot)
$null = Start-Job -Name $jobName -ScriptBlock $scriptBlock -Arg @($url, $Method, $headers, $Body, $ValidBodyContainingRequestMethods, (Get-GitHubConfiguration -Name WebRequestTimeoutSec), $PSScriptRoot)
if ($PSCmdlet.ShouldProcess($jobName, "Wait-JobWithAnimation"))
{

Просмотреть файл

@ -20,6 +20,7 @@
'Helpers.ps1',
'GitHubConfiguration.ps1',
'GitHubAnalytics.ps1',
'GitHubAssignees.ps1',
'GitHubBranches.ps1',
'GitHubCore.ps1',
'GitHubIssues.ps1',
@ -43,6 +44,7 @@
'Backup-GitHubConfiguration',
'Clear-GitHubAuthentication',
'ConvertFrom-Markdown',
'Get-GitHubAssignee',
'Get-GitHubCloneTraffic',
'Get-GitHubCodeOfConduct',
'Get-GitHubConfiguration',
@ -76,10 +78,12 @@
'Invoke-GHRestMethodMultipleResult',
'Lock-GitHubIssue',
'Move-GitHubRepositoryOwnership',
'New-GithubAssignee',
'New-GitHubIssue',
'New-GitHubLabel',
'New-GitHubRepository',
'New-GitHubRepositoryFork',
'Remove-GithubAssignee',
'Remove-GitHubLabel',
'Remove-GitHubRepository',
'Reset-GitHubConfiguration',
@ -89,6 +93,7 @@
'Set-GitHubLabel',
'Set-GitHubRepositoryTopic',
'Split-GitHubUri',
'Test-GitHubAssignee',
'Test-GitHubAuthenticationConfigured',
'Unlock-GitHubIssue',
'Update-GitHubCurrentUser',

Просмотреть файл

@ -0,0 +1,134 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
<#
.Synopsis
Tests for GitHubAssignees.ps1 module
#>
[String] $root = Split-Path -Parent (Split-Path -Parent $Script: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 happen
(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 "<username is ignored>", $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
$script:accessTokenConfigured = Test-GitHubAuthenticationConfigured
if (-not $script: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
Set-GitHubConfiguration -DisableTelemetry # We don't want UT's to impact telemetry
$repo = New-GitHubRepository -RepositoryName ([Guid]::NewGuid().Guid) -AutoInit
$issue = New-GitHubIssue -Uri $repo.svn_url -Title "Test issue"
Describe 'Getting a valid assignee' {
Context 'For getting a valid assignee' {
$assigneeList = @(Get-GitHubAssignee -Uri $repo.svn_url)
It 'Should have returned the one assignee' {
$assigneeList.Count | Should be 1
}
$assigneeUserName = $assigneeList[0].login
It 'Should have returned an assignee with a login'{
$assigneeUserName | Should not be $null
}
$hasPermission = Test-GitHubAssignee -Uri $repo.svn_url -Assignee $assigneeUserName
It 'Should have returned an assignee with permission to be assigned to an issue'{
$hasPermission | Should be $true
}
}
}
Describe 'Adding and removing an assignee to an issue'{
Context 'For adding an assignee to an issue'{
$assigneeList = @(Get-GitHubAssignee -Uri $repo.svn_url)
$assigneeUserName = $assigneeList[0].login
$assignees = @($assigneeUserName)
New-GithubAssignee -Uri $repo.svn_url -Issue $issue.number -Assignee $assignees
$issue = Get-GitHubIssue -Uri $repo.svn_url -Issue $issue.number
It 'Should have assigned the user to the issue' {
$issue.assignee.login | Should be $assigneeUserName
}
Remove-GithubAssignee -Uri $repo.svn_url -Issue $issue.number -Assignee $assignees
$issue = Get-GitHubIssue -Uri $repo.svn_url -Issue $issue.number
It 'Should have removed the user from issue' {
$issue.assignees.Count | Should be 0
}
}
}
Remove-GitHubRepository -Uri $repo.svn_url
}
finally
{
# Restore the user's configuration to its pre-test state
Restore-GitHubConfiguration -Path $configFile
}

Просмотреть файл

@ -30,6 +30,11 @@
* [Get the popular content for a repository](#get-the-popular-content-for-a-repository)
* [Get the number of views for a repository](#get-the-number-of-views-for-a-repository)
* [Get the number of clones for a repository](#get-the-number-of-clones-for-a-repository)
* [Assignees](#assignees)
* [Get assignees](#get-assignees)
* [Check assignee permission](#check-assignee-permission)
* [Add assignee to an issue](#add-assignee-to-an-issue)
* [Remove assignee from an issue](#remove-assignee-from-an-issue)
----------
@ -342,3 +347,27 @@ Get-GitHubViewTraffic -OwnerName PowerShell -RepositoryName PowerShellForGitHub
```powershell
Get-GitHubCloneTraffic -OwnerName PowerShell -RepositoryName PowerShellForGitHub -Per 'day'
```
----------
### Assignees
#### Get assignees
```powershell
Get-GitHubAsignee -OwnerName Powershell -RepositoryName PowerShellForGitHub
```
#### Check assignee permission
```powershell
$HasPermission = Test-GitHubAssignee -OwnerName Powershell -RepositoryName PowerShellForGitHub -Assignee "LoginID123"
```
#### Add assignee to an issue
```powershell
New-GithubAssignee -OwnerName Powershell -RepositoryName PowerShellForGitHub -Assignees $assignees -Issue 1
```
#### Remove assignee from an issue
```powershell
Remove-GithubAssignee -OwnerName Powershell -RepositoryName PowerShellForGitHub -Assignees $assignees -Issue 1
```