Skip to content

Commit

Permalink
Review335 (#347)
Browse files Browse the repository at this point in the history
* Update README.md

* Update README.md

* Fixed Update-VSTeamRelease WARNING: VS402865: An empty body in the POST request is not allowed. #326

* added integration tests for release definition

* fixed unit tests for changed implementation of content type

Co-authored-by: Sebastian Schütze <[email protected]>
  • Loading branch information
DarqueWarrior and SebastianSchuetze authored Jul 28, 2020
1 parent eaabe56 commit 804dad3
Show file tree
Hide file tree
Showing 9 changed files with 387 additions and 13 deletions.
15 changes: 10 additions & 5 deletions Source/Private/common.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ function _callAPI {
# call.
[switch]$UseProjectId,
# This flag makes sure that even if a default project is set that it is
# not used to build the URI for the API call. Not all API require or
# not used to build the URI for the API call. Not all API require or
# allow the project to be used. Setting a default project would cause
# that project name to be used in building the URI that would lead to
# that project name to be used in building the URI that would lead to
# 404 because the URI would not be correct.
[Alias('IgnoreDefaultProject')]
[switch]$NoProject
Expand Down Expand Up @@ -64,6 +64,11 @@ function _callAPI {
$params.Add('UserAgent', (_getUserAgent))
$params.Add('TimeoutSec', (_getDefaultTimeout))

#always use utf8 and json as default content type instead of xml
if ($false -eq $PSBoundParameters.ContainsKey("ContentType")) {
$params.Add('ContentType', 'application/json; charset=utf-8')
}

if (_useWindowsAuthenticationOnPremise) {
$params.Add('UseDefaultCredentials', $true)
$params.Add('Headers', @{ })
Expand All @@ -80,7 +85,7 @@ function _callAPI {
$params['Headers'].Add($key, $AdditionalHeaders[$key])
}
}

# We have to remove any extra parameters not used by Invoke-RestMethod
$extra = 'NoProject', 'UseProjectId', 'Area', 'Resource', 'SubDomain', 'Id', 'Version', 'JSON', 'ProjectName', 'Team', 'Url', 'QueryString', 'AdditionalHeaders'
foreach ($e in $extra) { $params.Remove($e) | Out-Null }
Expand Down Expand Up @@ -136,7 +141,7 @@ function _testAdministrator {
}

# When you mock this in tests be sure to add a Parameter Filter that matches
# the Service that should be used.
# the Service that should be used.
# Mock _getApiVersion { return '1.0-gitUnitTests' } -ParameterFilter { $Service -eq 'Git' }
# Also test in the Assert-MockCalled that the correct version was used in the URL that was
# built for the API call.
Expand Down Expand Up @@ -247,7 +252,7 @@ function _buildRequestURI {

process {
_hasAccount

$sb = New-Object System.Text.StringBuilder

$sb.Append($(_addSubDomain -subDomain $subDomain -instance $(_getInstance))) | Out-Null
Expand Down
2 changes: 1 addition & 1 deletion Source/Public/Add-VSTeamBuildDefinition.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ function Add-VSTeamBuildDefinition {
)

process {
return _callAPI -Method Post -ProjectName $ProjectName -Area build -Resource definitions -Version $(_getApiVersion Build) -infile $InFile -ContentType 'application/json'
return _callAPI -Method Post -ProjectName $ProjectName -Area build -Resource definitions -Version $(_getApiVersion Build) -infile $InFile
}
}
4 changes: 2 additions & 2 deletions Source/Public/Update-VSTeamBuildDefinition.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ function Update-VSTeamBuildDefinition {
# Call the REST API

if ($InFile) {
_callAPI -Method Put -ProjectName $ProjectName -Area build -Resource definitions -Id $Id -Version $(_getApiVersion Build) -InFile $InFile -ContentType 'application/json' | Out-Null
_callAPI -Method Put -ProjectName $ProjectName -Area build -Resource definitions -Id $Id -Version $(_getApiVersion Build) -InFile $InFile | Out-Null
}
else {
_callAPI -Method Put -ProjectName $ProjectName -Area build -Resource definitions -Id $Id -Version $(_getApiVersion Build) -Body $BuildDefinition -ContentType 'application/json' | Out-Null
_callAPI -Method Put -ProjectName $ProjectName -Area build -Resource definitions -Id $Id -Version $(_getApiVersion Build) -Body $BuildDefinition | Out-Null
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Source/Public/Update-VSTeamRelease.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function Update-VSTeamRelease {
if ($Force -or $pscmdlet.ShouldProcess($Id, "Update Release")) {
# Call the REST API
$resp = _callAPI -ProjectName $projectName -SubDomain vsrm -Area release -Resource releases -Id $id `
-Method Put -ContentType 'application/json' -body $body -Version $(_getApiVersion Release)
-Method Put -body $body -Version $(_getApiVersion Release)

Write-Output $resp
}
Expand Down
4 changes: 2 additions & 2 deletions Source/Public/Update-VSTeamReleaseDefinition.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ function Update-VSTeamReleaseDefinition {
if ($Force -or $pscmdlet.ShouldProcess('', "Update Release Definition")) {
# Call the REST API
if ($InFile) {
_callAPI -Method Put -ProjectName $ProjectName -SubDomain vsrm -Area Release -Resource definitions -Version $(_getApiVersion Release) -InFile $InFile -ContentType 'application/json' | Out-Null
_callAPI -Method Put -ProjectName $ProjectName -SubDomain vsrm -Area Release -Resource definitions -Version $(_getApiVersion Release) -InFile $InFile | Out-Null
}
else {
_callAPI -Method Put -ProjectName $ProjectName -SubDomain vsrm -Area Release -Resource definitions -Version $(_getApiVersion Release) -Body $ReleaseDefinition -ContentType 'application/json' | Out-Null
_callAPI -Method Put -ProjectName $ProjectName -SubDomain vsrm -Area Release -Resource definitions -Version $(_getApiVersion Release) -Body $ReleaseDefinition | Out-Null
}
}
}
Expand Down
63 changes: 63 additions & 0 deletions integration/test/010_projects.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Set-StrictMode -Version Latest

$global:skippedOnTFS = ($env:ACCT -like "http://*")
$global:skipVariableGroups = ($env:API_VERSION -eq 'TFS2017')
$global:skipReleaseDefs = ($env:API_VERSION -eq 'TFS2017')

Describe 'VSTeam Integration Tests' -Tag 'integration' {
BeforeAll {
Expand All @@ -17,6 +18,7 @@ Describe 'VSTeam Integration Tests' -Tag 'integration' {

Write-Host "SkippedOnTFS = $($global:skippedOnTFS)"
Write-Host "SkipVariableGroups = $($global:skipVariableGroups)"
Write-Host "SkipReleaseDefs = $($global:skipReleaseDefs)"

$originalLocation = Get-Location

Expand Down Expand Up @@ -158,6 +160,67 @@ Describe 'VSTeam Integration Tests' -Tag 'integration' {
}
}

Context 'ReleaseDefinition full exercise' -Skip:$skipReleaseDefs {
BeforeAll {
# Everytime you run the test a new "$newProjectName" is generated.
# This is fine if you are running all the tests but not if you just
# want to run these. So if the newProjectName can't be found in the
# target system change newProjectName to equal the name of the project
# found with the correct description.
$newProjectName = Get-ProjectName

if ($acct -like "http://*") {
$defaultQueue = Get-VSTeamQueue -ProjectName $newProjectName | Where-Object { $_.poolName -eq "Default" }
}
else {
$defaultQueue = Get-VSTeamQueue -ProjectName $newProjectName | Where-Object { $_.poolName -eq "Hosted" }
}

$srcReleaseDef = Get-Content "$PSScriptRoot\sampleFiles\010_releasedef_1.json" -Raw | ConvertFrom-Json
$srcReleaseDef.name = "$newProjectName-CD1"
$srcReleaseDef.environments[0].deployPhases[0].deploymentInput.queueId = $defaultQueue.Id
$tmpReleaseDef1 = (New-TemporaryFile).FullName
$srcReleaseDef | ConvertTo-Json -Depth 10 | Set-Content -Path $tmpReleaseDef1

Add-VSTeamReleaseDefinition -ProjectName $newProjectName -InFile $tmpReleaseDef1

$srcReleaseDef = Get-Content "$PSScriptRoot\sampleFiles\010_releasedef_2.json" -Raw | ConvertFrom-Json
$srcReleaseDef.name = "$newProjectName-CD2"
$srcReleaseDef.environments[0].deployPhases[0].deploymentInput.queueId = $defaultQueue.Id
$tmpReleaseDef2 = (New-TemporaryFile).FullName
$srcReleaseDef | ConvertTo-Json -Depth 10 | Set-Content -Path $tmpReleaseDef2

Add-VSTeamReleaseDefinition -ProjectName $newProjectName -InFile $tmpReleaseDef2
}

It 'Should have 2 release definition' {
$buildDefs = Get-VSTeamReleaseDefinition -ProjectName $newProjectName
$buildDefs.Count | Should -Be 2
}

It 'Get-VSTeamReleaseDefinition by Id should return intended attribute values for 1st release definition' {
$releaseDefId = (Get-VSTeamReleaseDefinition -ProjectName $newProjectName | Where-Object { $_.Name -eq $($newProjectName + "-CD1") }).Id
$releaseDefId | Should -Not -Be $null
$releaseDef = Get-VSTeamReleaseDefinition -ProjectName $newProjectName -Id $releaseDefId
$releaseDef.Name | Should -Be $($newProjectName + "-CD1")
$releaseDef.environments[0].deployPhases.Count | Should -Be 1
$releaseDef.environments[0].deployPhases[0].Name | Should -Be "Phase 1"
$releaseDef.environments[0].deployPhases[0].workflowTasks.Count | Should -Be 1
$releaseDef.environments[0].deployPhases[0].workflowTasks[0].Name | Should -Be "PowerShell Script"
$releaseDef.environments[0].deployPhases[0].workflowTasks[0].inputs.targetType | Should -Be "inline"
}

It 'Get-VSTeamReleaseDefinition by Id should return 2 phases for 2nd build definition' {
$releaseDefId = (Get-VSTeamReleaseDefinition -ProjectName $newProjectName | Where-Object { $_.Name -eq $($newProjectName + "-CD2") }).Id
((Get-VSTeamReleaseDefinition -ProjectName $newProjectName -Id $releaseDefId).environments[0].deployPhases).Count | Should -Be 2
}

It 'Remove-VSTeamReleaseDefinition should delete build definition' {
Get-VSTeamReleaseDefinition -ProjectName $newProjectName | Remove-VSTeamReleaseDefinition -ProjectName $newProjectName -Force
Get-VSTeamReleaseDefinition -ProjectName $newProjectName | Should -Be $null
}
}

Context 'Pool full exercise' {
It 'Get-VSTeamPool Should return agent pools' {
$actual = Get-VSTeamPool
Expand Down
137 changes: 137 additions & 0 deletions integration/test/sampleFiles/010_releasedef_1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
{
"source": "undefined",
"revision": 1,
"description": null,
"createdBy": null,
"createdOn": "0001-01-01T00:00:00",
"modifiedBy": null,
"modifiedOn": "0001-01-01T00:00:00",
"isDeleted": false,
"variables": {},
"variableGroups": [],
"environments": [
{
"id": 0,
"name": "Environment 1",
"variables": {},
"variableGroups": [],
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 0
}
]
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 0
}
]
},
"deployPhases": [
{
"deploymentInput": {
"parallelExecution": {
"parallelExecutionType": 0
},
"skipArtifactsDownload": false,
"artifactsDownloadInput": {
"downloadInputs": []
},
"queueId": 25,
"demands": [],
"enableAccessToken": false,
"timeoutInMinutes": 0,
"jobCancelTimeoutInMinutes": 1,
"condition": "succeeded()",
"overrideInputs": {}
},
"rank": 1,
"phaseType": 1,
"name": "Phase 1",
"refName": null,
"workflowTasks": [
{
"environment": {},
"taskId": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
"version": "2.*",
"name": "PowerShell Script",
"refName": "",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"definitionType": "task",
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"targetType": "inline",
"filePath": "",
"arguments": "",
"script": "Write-Host \"Hello World\"\n",
"errorActionPreference": "stop",
"failOnStderr": "false",
"ignoreLASTEXITCODE": "false",
"pwsh": "false",
"workingDirectory": ""
}
}
]
}
],
"environmentOptions": {
"emailNotificationType": "OnlyOnFailure",
"emailRecipients": "release.environment.owner;release.creator",
"skipArtifactsDownload": false,
"timeoutInMinutes": 0,
"enableAccessToken": false,
"publishDeploymentStatus": true,
"badgeEnabled": false,
"autoLinkWorkItems": false,
"pullRequestDeploymentEnabled": false
},
"demands": [],
"conditions": [],
"executionPolicy": {
"concurrencyCount": 1,
"queueDepthCount": 0
},
"schedules": [],
"retentionPolicy": {
"daysToKeep": 30,
"releasesToKeep": 3,
"retainBuild": true
},
"processParameters": {},
"properties": {},
"preDeploymentGates": {
"id": 0,
"gatesOptions": null,
"gates": []
},
"postDeploymentGates": {
"id": 0,
"gatesOptions": null,
"gates": []
},
"environmentTriggers": []
}
],
"artifacts": [],
"triggers": [],
"releaseNameFormat": null,
"tags": [],
"properties": {},
"id": 0,
"name": "AzureFunctions_CD - 3",
"path": "\\",
"projectReference": null,
"_links": {}
}
Loading

0 comments on commit 804dad3

Please sign in to comment.