diff --git a/Test/private/MockCall_Project700.ps1 b/Test/private/MockCall_Project700.ps1 index 106d952..e6105f4 100644 --- a/Test/private/MockCall_Project700.ps1 +++ b/Test/private/MockCall_Project700.ps1 @@ -29,10 +29,17 @@ function Get-Mock_Project_700 { # Repository Info $repoContent = Get-MockFileContentJson -fileName $project.repofile -AsHashtable - $project.repository = $repoContent.data.repository - $project.repository.owner = $repoContent.data.repository.owner.login - $project.repository.Remove('parent') - + $project.repo = @{ + id = $repoContent.data.repository.id + owner = $repoContent.data.repository.owner.login + name = $repoContent.data.repository.name + nameWithOwner = $repoContent.data.repository.nameWithOwner + getRepoMockFile = $project.repofile + object = $repoContent.data.repository + } + $project.repo.object.Remove('parent') + $project.repo.object.owner = $repoContent.data.repository.owner.login + # Project info $project.id = $pActual.id $project.owner = $pActual.owner.login @@ -54,13 +61,20 @@ function Get-Mock_Project_700 { $project.items.totalCount = $pActual.items.nodes.count $project.items.doneCount = 6 # too complicated to read from structure - # Create issue in repo - $project.createIssueInRepo = @{ - name = $project.repository.name - owner = $project.repository.owner - id = $project.repository.id - issueUrl = "https://github.com/octodemo/rulasg-dev-1/issues/30" + # issueToCreateAddAndRemove + $id = "I_kwDOPrRnkc7T2Al2" + $itemId ="PVTI_lADOAlIw4c4BCe3VzggVZH8" + $project.issueToCreateAddAndRemove= @{ + id = $id + number = 46 + url = "https://github.com/octodemo/rulasg-dev-1/issues/46" + getIssueOrPullRequestMockFile = "invoke-getissueorpullrequest-46.json" + itemId = $itemId + addIssueToOProjectMockFile = "invoke-additemtoproject-$($project.id)-$id.json" + createIssueMockfile = "invoke-createissue-$($project.repo.id).json" + removeIssueFromProjectMockFile = "invoke-removeitemfromproject-$($project.id)-$itemId.json" } + # Issues to find $project.issueToFind = @{} $project.issueToFind.Ids = ($pActual.items.nodes | Where-Object { $_.content.title -eq "Issue to find" }).Id diff --git a/Test/private/mocks/invoke-additemtoproject-PVT_kwDOAlIw4c4BCe3V-I_kwDOPrRnkc7T2Al2.json b/Test/private/mocks/invoke-additemtoproject-PVT_kwDOAlIw4c4BCe3V-I_kwDOPrRnkc7T2Al2.json new file mode 100644 index 0000000..75d1221 --- /dev/null +++ b/Test/private/mocks/invoke-additemtoproject-PVT_kwDOAlIw4c4BCe3V-I_kwDOPrRnkc7T2Al2.json @@ -0,0 +1,62 @@ +{ + "data": { + "addProjectV2ItemById": { + "item": { + "id": "PVTI_lADOAlIw4c4BCe3VzggVZH8", + "type": "ISSUE", + "fullDatabaseId": "135619711", + "project": { + "id": "PVT_kwDOAlIw4c4BCe3V", + "url": "https://github.com/orgs/octodemo/projects/700" + }, + "content": { + "__typename": "Issue", + "id": "I_kwDOPrRnkc7T2Al2", + "body": "", + "title": "kkk", + "updatedAt": "2025-10-26T16:02:46Z", + "createdAt": "2025-10-26T16:02:46Z", + "number": 46, + "url": "https://github.com/octodemo/rulasg-dev-1/issues/46", + "state": "OPEN", + "repository": { + "name": "rulasg-dev-1", + "owner": { + "login": "octodemo" + } + }, + "comments": { + "totalCount": 0, + "nodes": [] + } + }, + "fieldValues": { + "nodes": [ + { + "__typename": "ProjectV2ItemFieldRepositoryValue", + "repository": { + "url": "https://github.com/octodemo/rulasg-dev-1" + }, + "field": { + "__typename": "ProjectV2Field", + "id": "PVTF_lADOAlIw4c4BCe3Vzg0rg-k", + "name": "Repository", + "dataType": "REPOSITORY" + } + }, + { + "__typename": "ProjectV2ItemFieldTextValue", + "text": "kkk", + "field": { + "__typename": "ProjectV2Field", + "id": "PVTF_lADOAlIw4c4BCe3Vzg0rg-M", + "name": "Title", + "dataType": "TITLE" + } + } + ] + } + } + } + } +} diff --git a/Test/private/mocks/invoke-createissue-R_kgDOPrRnkQ.json b/Test/private/mocks/invoke-createissue-R_kgDOPrRnkQ.json index 5209733..faac8ab 100644 --- a/Test/private/mocks/invoke-createissue-R_kgDOPrRnkQ.json +++ b/Test/private/mocks/invoke-createissue-R_kgDOPrRnkQ.json @@ -2,8 +2,15 @@ "data": { "createIssue": { "issue": { - "id": "I_kwDOPrRnkc7Sj4N0", - "url": "https://github.com/octodemo/rulasg-dev-1/issues/30" + "title": "kkk", + "body": "", + "number": 46, + "url": "https://github.com/octodemo/rulasg-dev-1/issues/46", + "id": "I_kwDOPrRnkc7T2Al2", + "repository": { + "id": "R_kgDOPrRnkQ", + "nameWithOwner": "octodemo/rulasg-dev-1" + } } } } diff --git a/Test/private/mocks/invoke-getissueorpullrequest-46.json b/Test/private/mocks/invoke-getissueorpullrequest-46.json new file mode 100644 index 0000000..bbe8a0c --- /dev/null +++ b/Test/private/mocks/invoke-getissueorpullrequest-46.json @@ -0,0 +1,16 @@ +{ + "data": { + "resource": { + "__typename": "Issue", + "title": "kkk", + "body": "", + "number": 46, + "url": "https://github.com/octodemo/rulasg-dev-1/issues/46", + "id": "I_kwDOPrRnkc7T2Al2", + "repository": { + "id": "R_kgDOPrRnkQ", + "nameWithOwner": "octodemo/rulasg-dev-1" + } + } + } +} diff --git a/Test/private/mocks/invoke-removeissue-any.json b/Test/private/mocks/invoke-removeissue-any.json new file mode 100644 index 0000000..48f395f --- /dev/null +++ b/Test/private/mocks/invoke-removeissue-any.json @@ -0,0 +1,10 @@ +{ + "data": { + "deleteIssue": { + "repository": { + "id": "R_kgDOPrRnkQ", + "url": "https://github.com/octodemo/rulasg-dev-1" + } + } + } +} diff --git a/Test/private/mocks/invoke-removeitemfromproject-PVT_kwDOAlIw4c4BCe3V-PVTI_lADOAlIw4c4BCe3VzggVZH8.json b/Test/private/mocks/invoke-removeitemfromproject-PVT_kwDOAlIw4c4BCe3V-PVTI_lADOAlIw4c4BCe3VzggVZH8.json new file mode 100644 index 0000000..fa4a953 --- /dev/null +++ b/Test/private/mocks/invoke-removeitemfromproject-PVT_kwDOAlIw4c4BCe3V-PVTI_lADOAlIw4c4BCe3VzggVZH8.json @@ -0,0 +1,7 @@ +{ + "data": { + "deleteProjectV2Item": { + "deletedItemId": "PVTI_lADOAlIw4c4BCe3VzggVZH8" + } + } +} diff --git a/Test/public/issues/New-ProjectIssue.test.ps1 b/Test/public/issues/New-ProjectIssue.test.ps1 index 69e86e6..68d6f08 100644 --- a/Test/public/issues/New-ProjectIssue.test.ps1 +++ b/Test/public/issues/New-ProjectIssue.test.ps1 @@ -3,24 +3,62 @@ function Test_NewProjectIssueDirect{ Reset-InvokeCommandMock Mock_DatabaseRoot - $p = Get-Mock_Project_700 ; - $r = $p.createIssueInRepo + $p = Get-Mock_Project_700 + $r = $p.repo + $i = $p.issueToCreateAddAndRemove - $title = "Test Issue from New-ProjectIssueDirect" - $body = "This is a test issue created by New-ProjectIssueDirect test" - $command = "Invoke-CreateIssue -RepositoryId $($r.id) -Title ""$title"" -Body ""$body""" + $issueTitle = "Random value title" + $issueBody = "Random value body" + $mockfilename = $i.createIssueMockfile + + # MockCall_GetProject $p + MockCallJson -Command "Invoke-Repository -Owner $($r.owner) -Name $($r.name)" -FileName $r.getRepoMockFile + MockCallJson -Command "Invoke-CreateIssue -RepositoryId $($r.id) -Title ""$issueTitle"" -Body ""$issueBody""" -FileName $mockfilename - MockCallJson -Command "Invoke-Repository -Owner $($r.owner) -Name $($r.name)" -FileName $p.repoFile - MockCallJson -command $command -FileName "invoke-createissue-$($r.id).json" + $params = @{ + RepoOwner = $r.owner + RepoName = $r.name + Title = $issueTitle + Body = $issueBody + } + $result = New-ProjectIssueDirect @params - $result = New-ProjectIssueDirect -RepoOwner $r.owner -RepoName $r.name -Title "Test Issue from New-ProjectIssueDirect" -Body "This is a test issue created by New-ProjectIssueDirect test" + # Assert + Assert-AreEqual -Expected $i.url -Presented $result - # Invoke-CreateIssue -RepositoryId $result.Id -Title "Test Issue from New-ProjectIssueDirect" -Body "This is a test issue created by New-ProjectIssueDirect test" -ProjectIds @($p.id) +} - # Assert - Assert-AreEqual -Expected $r.issueUrl -Presented $result +function Test_NewProjectIssue{ + Reset-InvokeCommandMock + Mock_DatabaseRoot + + $p = Get-Mock_Project_700 ; $owner = $p.owner ; $projectNumber = $p.number + $r = $p.repo + $i = $p.issueToCreateAddAndRemove + $issueTitle = "Random value title" + $issueBody = "Random value body" + $mockfilenameCreate = "invoke-createissue-$($r.id).json" + $mockfilenameGet = "invoke-getissueorpullrequest-$($i.number).json" + + MockCall_GetProject $p + MockCallJson -Command "Invoke-Repository -Owner $($r.owner) -Name $($r.name)" -FileName $r.getRepoMockFile + MockCallJson -Command "Invoke-CreateIssue -RepositoryId $($r.id) -Title ""$issueTitle"" -Body ""$issueBody""" -FileName $mockfilenameCreate + MockCallJson -Command "Invoke-GetIssueOrPullRequest -Url $($i.url)" -fileName $mockfilenameGet + MockCallJson -Command "Invoke-AddItemToProject -ProjectId $($p.id) -ContentId $($i.id)" -fileName $i.addIssueToOProjectMockFile + + # Create issue + $params = @{ + ProjectOwner = $owner + ProjectNumber = $projectNumber + RepoOwner = $r.owner + RepoName = $r.name + Title = $issueTitle + Body = $issueBody + } + + $result = New-ProjectIssue @params + Assert-AreEqual -Expected $result -Presented $i.itemId } -test \ No newline at end of file diff --git a/Test/public/issues/Remove-ProjectIssue.test.ps1 b/Test/public/issues/Remove-ProjectIssue.test.ps1 new file mode 100644 index 0000000..3200e7a --- /dev/null +++ b/Test/public/issues/Remove-ProjectIssue.test.ps1 @@ -0,0 +1,38 @@ +function Test_RemoveProjectIssue_SUCCESS { + + Reset-InvokeCommandMock + Mock_DatabaseRoot + + $p = Get-Mock_Project_700 ; $owner = $p.owner ; $projectNumber = $p.number + $i = $p.issueToCreateAddAndRemove + + MockCall_GetProject $p + + # Add item to project to remover it later + MockCallJson -Command "Invoke-GetIssueOrPullRequest -Url $($i.url)" -fileName $i.getIssueOrPullRequestMockFile + MockCallJson -Command "Invoke-AddItemToProject -ProjectId $($p.id) -ContentId $($i.id)" -fileName $i.addIssueToOProjectMockFile + $itemId = Add-ProjectItem -owner $owner -projectNumber $projectNumber -Url $i.url + $item = Get-ProjectItem -Id $itemId + Assert-AreEqual -expected $i.id -Presented $item.contentId + + MockCallJson -Command "Invoke-RemoveItemFromProject -ProjectId $($p.id) -ItemId $($i.itemId)" -fileName $i.removeIssueFromProjectMockFile + + # Act + $result = Remove-ProjectItem -Owner $owner -ProjectNumber $projectNumber -ItemId $itemId + + # Assert + Assert-AreEqual -Expected $i.url -Presented $result + Assert-IsFalse -Condition $(Test-ProjectItem -Url $i.url) + + # Remove issue assocaited + $itemId = Add-ProjectItem -owner $owner -projectNumber $projectNumber -Url $i.url + Assert-IsTrue -Condition $(Test-ProjectItem -Url $i.url) + MockCallJson -Command "Invoke-RemoveIssue -IssueId $($i.id)" -FileName "invoke-removeissue-any.json" + + # Act + $result = Remove-ProjectItem -Owner $owner -ProjectNumber $projectNumber -ItemId $itemId -DeleteIssue + + # Assert + Assert-IsTrue -Condition $result + +} \ No newline at end of file diff --git a/Test/public/repository/get-repository.test.ps1 b/Test/public/repository/get-repository.test.ps1 index e351aaa..a40a72b 100644 --- a/Test/public/repository/get-repository.test.ps1 +++ b/Test/public/repository/get-repository.test.ps1 @@ -4,15 +4,17 @@ function Test_GetRepository{ Mock_DatabaseRoot $p = Get-Mock_Project_700 ; - $r = $p.repository + $r = $p.repo + $ro = $p.repo.object + MockCallJson -Command "Invoke-Repository -Owner $($r.owner) -Name $($r.name)" -FileName $p.repoFile $result = Get-Repository -Owner $r.owner -Name $r.name #Assert - foreach ( $key in $r.Keys ){ - Assert-AreEqual -Expected:$r.$key -Presented:$result.$key + foreach ( $key in $ro.Keys ){ + Assert-AreEqual -Expected:$ro.$key -Presented:$result.$key } # Assert repo cache created diff --git a/private/item/getResourceid.ps1 b/private/item/getResourceid.ps1 index c37dd3b..f48908e 100644 --- a/private/item/getResourceid.ps1 +++ b/private/item/getResourceid.ps1 @@ -9,7 +9,7 @@ function Get-ContentIdFromUrlDirect{ [Parameter(Mandatory,Position = 0)][string]$Url ) - $issue = Get-ProjectIssue -Url $url + $issue = Get-ProjectIssueDirect -Url $url $ret = $issue.id diff --git a/public/driver/issue/Invoke-CreateDraftItem.ps1 b/public/driver/issue/Invoke-CreateDraftItem.ps1 index c6cdaca..e216870 100644 --- a/public/driver/issue/Invoke-CreateDraftItem.ps1 +++ b/public/driver/issue/Invoke-CreateDraftItem.ps1 @@ -24,8 +24,8 @@ function Invoke-CreateDraftItem{ $variables = @{ input = @{ projectId = $ProjectId - title = $Title - body = $Body + title = $Title | ConvertTo-InvokeParameterString + body = $Body | ConvertTo-InvokeParameterString } } diff --git a/public/driver/issue/Invoke-CreateIssue.ps1 b/public/driver/issue/Invoke-CreateIssue.ps1 index 8b98947..5fc0e49 100644 --- a/public/driver/issue/Invoke-CreateIssue.ps1 +++ b/public/driver/issue/Invoke-CreateIssue.ps1 @@ -19,8 +19,8 @@ function Invoke-CreateIssue { $variables = @{ input = @{ repositoryId = $RepositoryId - title = $Title - body = $Body + title = $Title | ConvertTo-InvokeParameterString + body = $Body | ConvertTo-InvokeParameterString #projectIds = $ProjectIds # assigneeIds = $AssigneeIds diff --git a/public/driver/issue/Invoke-RemoveIssue.ps1 b/public/driver/issue/Invoke-RemoveIssue.ps1 new file mode 100644 index 0000000..589cd69 --- /dev/null +++ b/public/driver/issue/Invoke-RemoveIssue.ps1 @@ -0,0 +1,17 @@ +function Invoke-RemoveIssue { + param( + [Parameter(Mandatory = $true)][string]$IssueId + ) + + $query = Get-GraphQLString "removeIssue.mutant" + + $variables = @{ + input = @{ + issueId = $IssueId + } + } + + $response = Invoke-GraphQL -Query $query -Variables $variables + + return $response +} Export-ModuleMember -Function Invoke-RemoveIssue \ No newline at end of file diff --git a/public/driver/issue/Invoke-UpdateDraftIssue.ps1 b/public/driver/issue/Invoke-UpdateDraftIssue.ps1 index 9b0c77e..4f42117 100644 --- a/public/driver/issue/Invoke-UpdateDraftIssue.ps1 +++ b/public/driver/issue/Invoke-UpdateDraftIssue.ps1 @@ -29,12 +29,12 @@ function Invoke-UpdateDraftIssue{ # Title can not be empty if(-not [string]::IsNullOrWhiteSpace($Title)){ - $variables.input.title = $Title + $variables.input.title = $Title | ConvertTo-InvokeParameterString } # This will avoid to empty the body if(-not [string]::IsNullOrWhiteSpace($Body)){ - $variables.input.body = $Body + $variables.input.body = $Body | ConvertTo-InvokeParameterString } # Check if variables are is empty diff --git a/public/driver/issue/Invoke-UpdateIssue.ps1 b/public/driver/issue/Invoke-UpdateIssue.ps1 index 86dda09..d2eeaa9 100644 --- a/public/driver/issue/Invoke-UpdateIssue.ps1 +++ b/public/driver/issue/Invoke-UpdateIssue.ps1 @@ -44,12 +44,12 @@ function Invoke-UpdateIssue{ # Title can not be empty if(-not [string]::IsNullOrWhiteSpace($Title)){ - $variables.input.title = $Title - } + $variables.input.title = $Title | ConvertTo-InvokeParameterString + } # This will avoid to empty the body if(-not [string]::IsNullOrWhiteSpace($Body)){ - $variables.input.body = $Body + $variables.input.body = $Body | ConvertTo-InvokeParameterString } # Check if variables are is empty diff --git a/public/driver/issue/Invoke-UpdatePullRequest.ps1 b/public/driver/issue/Invoke-UpdatePullRequest.ps1 index 0f37318..7131271 100644 --- a/public/driver/issue/Invoke-UpdatePullRequest.ps1 +++ b/public/driver/issue/Invoke-UpdatePullRequest.ps1 @@ -29,12 +29,12 @@ function Invoke-UpdatePullRequest{ # Title can not be empty if(-not [string]::IsNullOrWhiteSpace($Title)){ - $variables.input.title = $Title + $variables.input.title = $Title | ConvertTo-InvokeParameterString } # This will avoid to empty the body if(-not [string]::IsNullOrWhiteSpace($Body)){ - $variables.input.body = $Body + $variables.input.body = $Body | ConvertTo-InvokeParameterString } # Check if variables are is empty diff --git a/public/graphql/_issue.tag b/public/graphql/_issue.tag index ae93fcf..ef80c4e 100644 --- a/public/graphql/_issue.tag +++ b/public/graphql/_issue.tag @@ -1 +1 @@ -{ title,body,number,url,id,repository{id,nameWithOwner}} \ No newline at end of file +{ title,body,number,url,id,repository{{repository}}} \ No newline at end of file diff --git a/public/graphql/_repository.tag b/public/graphql/_repository.tag new file mode 100644 index 0000000..76b1d6b --- /dev/null +++ b/public/graphql/_repository.tag @@ -0,0 +1 @@ +{id,url} \ No newline at end of file diff --git a/public/graphql/removeIssue.mutant b/public/graphql/removeIssue.mutant new file mode 100644 index 0000000..b762fc3 --- /dev/null +++ b/public/graphql/removeIssue.mutant @@ -0,0 +1,5 @@ +mutation IssueDelete($input:DeleteIssueInput!){ + deleteIssue(input: $input){ + repository{{repository}} + } +} \ No newline at end of file diff --git a/public/graphql/repository.query b/public/graphql/repository.query index ccf462d..9f81617 100644 --- a/public/graphql/repository.query +++ b/public/graphql/repository.query @@ -1,10 +1,4 @@ -fragment repo on Repository { - id - name - owner { login } - hasIssuesEnabled - description - } +fragment repo on Repository {{repository}} query RepositoryInfo($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { diff --git a/public/issues/Get-ProjectIssue.ps1 b/public/issues/Get-ProjectIssue.ps1 index 8b94228..8019e02 100644 --- a/public/issues/Get-ProjectIssue.ps1 +++ b/public/issues/Get-ProjectIssue.ps1 @@ -1,16 +1,13 @@ -function Get-ProjectIssue { +Set-MyInvokeCommandAlias -Alias GetIssueOrPullRequest -Command 'Invoke-GetIssueOrPullRequest -Url {url}' + +function Get-ProjectIssueDirect { [CmdletBinding()] param ( [Parameter(Position=0)][string]$Url ) # Check the project cache of the default project - $owner,$projectNumber = Get-OwnerAndProjectNumber - $cache = Get-ProjectItemByUrl -Owner $owner -ProjectNumber $projectNumber -Url $Url - if( $cache ) { return $cache } - - # Find project $params = @{ url = $Url } @@ -29,4 +26,50 @@ function Get-ProjectIssue { return $ret -} Export-ModuleMember -Function Get-ProjectIssue \ No newline at end of file +} Export-ModuleMember -Function Get-ProjectIssueDirect + +function Get-ProjectIssue { + [CmdletBinding()] + param ( + [Parameter(Position=0)][string]$Url, + [Parameter()][switch]$Force + ) + + # Check the project cache of the default project + $owner,$projectNumber = Get-OwnerAndProjectNumber + $item = Get-ProjectItemByUrl -Owner $owner -ProjectNumber $projectNumber -Url $Url -Force:$Force + if( $item ) { + $issue = $item | Convert-ItemToIssue + return $issue + } + + # Not in cache. Get Direct + $issue = Get-ProjectIssueDirect -Url $Url + + # TODO: update the cache if issue is an item of the project + # This will required or transform Issue to Item or create a new issue database + + return $issue + +} Export-ModuleMember -Function Get-ProjectIssue + +function Convert-ItemToIssue { + param( + [Parameter(Mandatory,ValueFromPipeline)][object]$Item + ) + + process { + + $issue = @{ + __typename = "Issue" + id = $Item.contentId + title = $Item.Title + body = $Item.Body + number = $Item.number + url = $Item.urlContent + repository = $Item.Repository + } + return $issue + } + +} \ No newline at end of file diff --git a/public/issues/New-ProjectIssue.ps1 b/public/issues/New-ProjectIssue.ps1 index 8ff184c..eea982a 100644 --- a/public/issues/New-ProjectIssue.ps1 +++ b/public/issues/New-ProjectIssue.ps1 @@ -12,6 +12,11 @@ function New-ProjectIssueDirect { $repo = Get-Repository -Owner $RepoOwner -Name $RepoName + if( ! $repo ) { + "Repository $RepoOwner/$RepoName not found" | Write-MyError + return $null + } + $params = @{ repoid = $repo.id title = $Title | ConvertTo-InvokeParameterString diff --git a/public/issues/Remove-IssueDirect.ps1 b/public/issues/Remove-IssueDirect.ps1 new file mode 100644 index 0000000..686527f --- /dev/null +++ b/public/issues/Remove-IssueDirect.ps1 @@ -0,0 +1,28 @@ + +Set-MyInvokeCommandAlias -Alias RemoveIssue -Command 'Invoke-RemoveIssue -IssueId {issueId}' + + +function Remove-IssueDirect { + [CmdletBinding()] + param( + [Parameter(Position = 0)][string]$Url + ) + + $issue = Get-ProjectIssue -Url $Url + + if( ! $issue ){ + throw "Issue with URL $Url not found" + } + + $result = Invoke-MyCommand -Command RemoveIssue -Parameters @{ issueId = $issue.id } + + $repoUrl = $result.data.deleteIssue.repository.url + + # Verify response value + if($issue.repository -ne $repoUrl){ + throw "Issue not removed properly" + } + + return $true + + } \ No newline at end of file diff --git a/public/items/project_item.ps1 b/public/items/project_item.ps1 index c2caa4d..262ced6 100644 --- a/public/items/project_item.ps1 +++ b/public/items/project_item.ps1 @@ -81,12 +81,12 @@ function Get-ProjectItemByUrl{ if(-not $item){ "Item not found for URL [$Url]" | Write-MyError - return $null + return } return $item } -} +} Export-ModuleMember -Function Get-ProjectItemByUrl function Test-ProjectItem { [CmdletBinding()] @@ -402,17 +402,19 @@ function Add-ProjectItemDirect { # Get project id $db = Get-Project -Owner $Owner -ProjectNumber $ProjectNumber - $projectId = $db.ProjectId - if (-not $projectId) { + if ( ! $db) { "Project ID not found for Owner [$Owner] and ProjectNumber [$ProjectNumber]" | Write-MyError return $null + } else { + $projectId = $db.ProjectId } } process { - if(Test-ProjectItem -Url $Url -Owner $Owner -ProjectNumber $ProjectNumber){ - $item = Search-ProjectItem -Filter $Url -FieldName "urlContent" -IncludeDone -Owner $Owner -ProjectNumber $ProjectNumber -PassThru + if(Test-Item $db $Url){ + $item = Get-ItemByUrl $db $url + # return the id as if has been aded return $item.id } @@ -460,7 +462,6 @@ function Remove-ProjectItemDirect { [Parameter()][string]$Owner, [Parameter()][string]$ProjectNumber, [Parameter(Mandatory, ValueFromPipelineByPropertyName,ValueFromPipeline, Position = 0)][Alias("Id")][string]$ItemId, - [Parameter()][switch]$DeleteIssue, [Parameter()][switch]$Force ) @@ -474,18 +475,18 @@ function Remove-ProjectItemDirect { if ($db) { $projectId = $db.ProjectId } - else { - throw "Project not found for Owner [$Owner] and ProjectNumber [$ProjectNumber]" - } } process { + + # With no Project Id we ned to abort + if( ! $projectId ){ return } $item = Get-Item $db $ItemId if (-not $item) { "Item [$ItemId] not found in project [$Owner/$ProjectNumber]" | Write-MyHost - return $null + return } $itemId = $item.id @@ -493,11 +494,6 @@ function Remove-ProjectItemDirect { try{ - if (-not $projectId) { - "Project ID not found for Owner [$Owner] and ProjectNumber [$ProjectNumber]" | Write-MyError - return $null - } - # Remove item from project if ($PSCmdlet.ShouldProcess($ItemId, "RRemove from project $Owner/$ProjectNumber")) { $response = Invoke-MyCommand -Command RemoveItemFromProject -Parameters @{ projectid = $projectId ; itemid = $ItemId } @@ -533,33 +529,70 @@ function Remove-ProjectItemDirect { Remove-Item $db $ItemId Save-ProjectDatabaseSafe -Database $db - if (! $DeleteIssue){ + return $itemUrl + } + +} Export-ModuleMember -Function Remove-ProjectItemDirect + +function Remove-ProjectItem { + [CmdletBinding(SupportsShouldProcess)] + [Alias ("rpi")] + param( + [Parameter()][string]$Owner, + [Parameter()][string]$ProjectNumber, + [Parameter(Mandatory, ValueFromPipelineByPropertyName,ValueFromPipeline, Position = 0)][Alias("Id")][string]$ItemId, + [Parameter()][switch]$DeleteIssue, + [Parameter()][switch]$Force + + ) + + process { + + # Get item to delete issue later + if( ! $DeleteIssue){ + # Remove item from project + $itemUrl = Remove-ProjectItemDirect -Owner $Owner -ProjectNumber $ProjectNumber -ItemId $ItemId -Force:$Force return $itemUrl } + + # Find Item to remove + $item = Get-ProjectItem -ItemId $ItemId - # Remove issue - if($item.type -eq "Issue") { - "Deleting issue associated to item [$ItemId]" | Write-Verbose - $item = Get-ProjectItem -Owner $Owner -ProjectNumber $ProjectNumber -ItemId $ItemId -Force - if ($item -and $item.urlContent) { - try { - Remove-ProjectIssueDirect -Url $item.url - } - catch { - "Issue associated to item [$ItemId] could not be deleted: $_" | Write-MyWarning - } - } - else { - "No issue associated to item [$ItemId]" | Write-MyWarning + if( ! $item){ + "Item [$ItemId] not found, cannot delete issue" | Write-MyWarning + return $false + } + + # Remove issue associated with the item + # If DraftIssue when it´s already delete when removed from project + # If PullRequest. PR can not be deleted + if($item.type -ne "Issue") { + "Item [$ItemId] is not an Issue, skipping issue deletion" | Write-MyHost + return $itemUrl + } + + "Deleting issue associated to item [$ItemId]" | Write-Verbose + if ($item.urlContent) { + try { + $result = Remove-IssueDirect -Url $item.url + } catch { + "Issue associated to item [$ItemId] could not be deleted: $_" | Write-MyWarning + return $false } } else { - "Item [$ItemId] is not an Issue, skipping issue deletion" | Write-MyHost + "No issue associated to item [$ItemId]" | Write-MyWarning } - return $itemUrl + if($result){ + "Issue associated to item [$ItemId] deleted successfully" | Write-Verbose + return $true + } else { + "Issue associated to item [$ItemId] could not be deleted properly" | Write-MyWarning + return $false + } } -} Export-ModuleMember -Function Remove-ProjectItemDirect -Alias "rpi" +} Export-ModuleMember -Function Remove-ProjectItem -Alias "rpi" function Get-ProjectItemDirect { [CmdletBinding()]