diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..73b9dff --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +ps_modules/ +*.vsix \ No newline at end of file diff --git a/BuildReleaseRetentionTask/BuildReleaseRetentionTask.ps1 b/BuildReleaseRetentionTask/BuildReleaseRetentionTask.ps1 index f0c0a8b..b11d535 100644 --- a/BuildReleaseRetentionTask/BuildReleaseRetentionTask.ps1 +++ b/BuildReleaseRetentionTask/BuildReleaseRetentionTask.ps1 @@ -1,8 +1,7 @@ +[CmdletBinding()] Param( - $mode, - $usedefaultcreds - ) - +) + function Set-BuildRetention { param @@ -10,42 +9,26 @@ function Set-BuildRetention $tfsuri, $teamproject, $buildID, - $releaseid, $keepForever, $usedefaultcreds ) + $boolKeepForever = [System.Convert]::ToBoolean($keepForever) + $webclient = Get-WebClient -usedefaultcreds $usedefaultcreds - write-verbose "Setting BuildID $buildID with Retention set to $keepForever" + write-verbose "Setting BuildID $buildID with retention set to $boolKeepForever" - $uri = "$($tfsUri)/$($teamproject)/_apis/build/builds/$($buildID)?api-version=2.0" - $data = @{keepForever = $keepForever} | ConvertTo-Json - $response = $webclient.UploadString($uri,"PATCH", $data) -} - -function Set-ReleaseRetention -{ - param - ( - $tfsuri, - $teamproject, - $buildID, - $releaseid, - $keepForever, - $usedefaultcreds - ) - write-verbose "Setting ReleaseID $releaseid with Retention set to $keepForever" - $body = @{ - "keepForever"= 'true' - } - $Uri = "$($tfsUri)$($teamproject)/_apis/release/releases/$($releaseid)?api-version=2.2-preview.1" - $buildresponse = Invoke-RestMethod -Method Patch -UseDefaultCredentials -ContentType application/json -Uri $Uri -Body (ConvertTo-Json $body) - - write-verbose "Respones Value = $buildresponse" + try { + $uri = "$($tfsUri)/$($teamproject)/_apis/build/builds/$($buildID)?api-version=2.0" + $data = @{keepForever = $boolKeepForever} | ConvertTo-Json + $response = $webclient.UploadString($uri,"PATCH", $data) + } catch + { + Write-Error "Cannot update the build, probably a rights issues see https://github.com/rfennell/AzurePipelines/wiki/BuildTasks-Task (foot of page) to see notes on granting rights" + } } - function Get-BuildsForRelease { param @@ -61,7 +44,11 @@ function Get-BuildsForRelease write-verbose "Getting Builds for Release releaseID" # at present Jun 2016 this API is in preview and in different places in VSTS hence this fix up - $rmtfsUri = $tfsUri -replace ".visualstudio.com", ".vsrm.visualstudio.com/defaultcollection" + $rmtfsUri = $tfsUri -replace ".visualstudio.com", ".vsrm.visualstudio.com/defaultcollection" + + # at september 2018 this API is also available at vsrm.dev.azure.com + $rmtfsUri = $rmtfsUri -replace "dev.azure.com", "vsrm.dev.azure.com" + $uri = "$($rmtfsUri)/$($teamproject)/_apis/release/releases/$($releaseId)?api-version=3.0-preview" $response = $webclient.DownloadString($uri) @@ -69,7 +56,8 @@ function Get-BuildsForRelease $return = @() $data.artifacts.Where({$_.type -eq "Build"}).ForEach( { - $return += $_.definitionReference.version.id + $return += @{ 'id' = $_.definitionReference.version.id; + 'name' = $_.alias } }) $return @@ -92,9 +80,8 @@ function Get-WebClient $webclient.UseDefaultCredentials = $true } else { Write-Verbose "Using SystemVssConnection personal access token" - $vssEndPoint = Get-ServiceEndPoint -Name "SystemVssConnection" -Context $distributedTaskContext - $personalAccessToken = $vssEndpoint.Authorization.Parameters.AccessToken - $webclient.Headers.Add("Authorization" ,"Bearer $personalAccessToken") + $vstsEndpoint = Get-VstsEndpoint -Name SystemVssConnection -Require + $webclient.Headers.Add("Authorization" ,"Bearer $($vstsEndpoint.auth.parameters.AccessToken)") } $webclient.Encoding = [System.Text.Encoding]::UTF8 @@ -107,28 +94,60 @@ function Get-WebClient # Output execution parameters. $VerbosePreference ='Continue' # equiv to -verbose +$mode = Get-VstsInput -Name "mode" +$usedefaultcreds = Get-VstsInput -Name "usedefaultcreds" +$artifacts = Get-VstsInput -Name "artifacts" +$keepForever = Get-VstsInput -Name "keepForever" + # Get the build and release details -$collectionUrl = $env:SYSTEM_TEAMFOUNDATIONSERVERURI +$collectionUrl = $env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI $teamproject = $env:SYSTEM_TEAMPROJECT $releaseid = $env:RELEASE_RELEASEID $buildid = $env:BUILD_BUILDID -Write-Verbose "collectionUrl = [$env:SYSTEM_TEAMFOUNDATIONSERVERURI]" +Write-Verbose "collectionUrl = [$env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI]" Write-Verbose "teamproject = [$env:SYSTEM_TEAMPROJECT]" Write-Verbose "releaseid = [$env:RELEASE_RELEASEID]" Write-Verbose "buildid = [$env:BUILD_BUILDID]" Write-Verbose "usedefaultcreds =[$usedefaultcreds]" +Write-Verbose "artifacts = [$artifacts]" +Write-Verbose "mode = [$mode]" +Write-Verbose "keepForever = [$keepForever]" if ($mode -eq "AllArtifacts") { + Write-Verbose ("Updating all artifacts") $builds = Get-BuildsForRelease -tfsUri $collectionUrl -teamproject $teamproject -releaseid $releaseid -usedefaultcreds $usedefaultcreds - foreach($id in $builds) + foreach($build in $builds) { - Set-BuildRetention -tfsUri $collectionUrl -teamproject $teamproject -buildid $id -releaseid $releaseid -keepForever $true -usedefaultcreds $usedefaultcreds - Set-ReleaseRetention -tfsUri $collectionUrl -teamproject $teamproject -buildid $id -releaseid $releaseid -keepForever $true -usedefaultcreds $usedefaultcreds + Write-Verbose ("Updating artifact $build.name") + Set-BuildRetention -tfsUri $collectionUrl -teamproject $teamproject -buildid $build.id -keepForever $keepForever -usedefaultcreds $usedefaultcreds } +} elseif ($mode -eq "Prime") +{ + Write-Verbose ("Updating only primary artifact") + Set-BuildRetention -tfsUri $collectionUrl -teamproject $teamproject -buildid $buildid -keepForever $keepForever -usedefaultcreds $usedefaultcreds } else { - Set-BuildRetention -tfsUri $collectionUrl -teamproject $teamproject -buildid $buildid -releaseid $releaseid -keepForever $true -usedefaultcreds $usedefaultcreds - Set-ReleaseRetention -tfsUri $collectionUrl -teamproject $teamproject -buildid $id -releaseid $releaseid -keepForever $true -usedefaultcreds $usedefaultcreds + Write-Verbose ("Updating only named artifacts") + if ([string]::IsNullOrEmpty($artifacts) -eq $true) { + Write-Error ("The artifacts list to update is empty") + } else { + $artifactsArray = $artifacts -split "," | foreach {$_.Trim()} + if ($artifactsArray -gt 0) { + $builds = Get-BuildsForRelease -tfsUri $collectionUrl -teamproject $teamproject -releaseid $releaseid -usedefaultcreds $usedefaultcreds + Write-Verbose "$($builds.Count) builds found for release" + foreach($build in $builds) + { + if ($artifactsArray -contains $build.name) { + Write-Verbose ("Updating artifact $($build.name)") + Set-BuildRetention -tfsUri $collectionUrl -teamproject $teamproject -buildid $build.id -keepForever $keepForever -usedefaultcreds $usedefaultcreds + } else { + Write-Verbose ("Skipping artifact $($build.name) as not in named list") + } + } + } else { + Write-Error ("The artifacts list cannot be split") + } + } } \ No newline at end of file diff --git a/BuildReleaseRetentionTask/icon.ico b/BuildReleaseRetentionTask/icon.png similarity index 100% rename from BuildReleaseRetentionTask/icon.ico rename to BuildReleaseRetentionTask/icon.png diff --git a/BuildReleaseRetentionTask/task.json b/BuildReleaseRetentionTask/task.json index 2186b49..ebe64ce 100644 --- a/BuildReleaseRetentionTask/task.json +++ b/BuildReleaseRetentionTask/task.json @@ -1,17 +1,17 @@ { "id": "7b42ca94-dc22-43dd-8b65-fcbf854b6b78", "name": "RetentionTask", - "friendlyName": "Set Retention forever on a Build Release", - "description": "Set Retention forever on a Build Release", + "friendlyName": "Set Retention forever on a Build and Release", + "description": "Set Retention forever on a Build and Release", "category": "Utility", "visibility": [ - "Release" - ], + "Release" + ], "author": "Haribabu, Bavanari", "version": { "Major": 2, - "Minor": 0, - "Patch": 0 + "Minor": 2, + "Patch": 2 }, "minimumAgentVersion": "1.82.0", "groups": [ @@ -20,9 +20,9 @@ "displayName": "Advanced", "isExpanded": false } - ], - "inputs": [ - { + ], + "inputs": [ + { "name": "mode", "type": "pickList", "label": "Build selection mode", @@ -30,23 +30,41 @@ "required": true, "options": { "AllArtifacts": "All build artifacts", + "NamedArtifacts": "Named artifacts", "Prime": "Only primary build artifact" }, "helpMarkDown": "Select the builds to update." - }, - { + }, + { + "name": "artifacts", + "type": "string", + "label": "Artifacts", + "defaultValue": "", + "required": false, + "helpMarkDown": "A comma separated list of artifacts", + "visibleRule": "mode = NamedArtifacts" + }, + { "name": "usedefaultcreds", "type": "boolean", "label": "Use default credentials", "defaultValue": "False", "required": false, "helpMarkDown": "If true will use the credentials of the running agent as opposed to access token provided by build service.", - "groupName":"advanced" + "groupName": "advanced" + }, + { + "name": "keepForever", + "type": "boolean", + "label": "Set Build Retension", + "defaultValue": "True", + "required": false, + "helpMarkDown": "If true will set the build retension on the build" } - ], - "instanceNameFormat": "Update Build Release Retention", + ], + "instanceNameFormat": "Update Build Retension", "execution": { - "PowerShell": { + "PowerShell3": { "target": "$(currentDirectory)\\BuildReleaseRetentionTask.ps1", "argumentFormat": "", "workingDirectory": "$(currentDirectory)" diff --git a/ReadMe b/ReadMe deleted file mode 100644 index 3f79340..0000000 --- a/ReadMe +++ /dev/null @@ -1 +0,0 @@ -# BuildAndReleaseKeepForever diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..41b151a --- /dev/null +++ b/build.ps1 @@ -0,0 +1,14 @@ +if (Test-Path .\BuildReleaseRetentionTask\ps_modules\VstsTaskSdk) +{ + Remove-Item -Recurse -Force .\BuildReleaseRetentionTask\ps_modules\VstsTaskSdk +} +New-Item .\sdk_download -ItemType Directory +Save-Module -Name VstsTaskSdk -Path .\sdk_download + +New-Item .\BuildReleaseRetentionTask\ps_modules\VstsTaskSdk -ItemType Directory +$VstsTaskModule = Get-ChildItem VstsTaskSdk.psd1 -Recurse +Copy-Item -Recurse "$($VstsTaskModule.Directory)\*" .\BuildReleaseRetentionTask\ps_modules\VstsTaskSdk + +Remove-Item -Recurse -Force .\sdk_download + +tfx extension create --manifest-globs .\vss-extension.json \ No newline at end of file diff --git a/readme.md b/readme.md index 77f3f7e..594bf94 100644 --- a/readme.md +++ b/readme.md @@ -6,7 +6,12 @@ When a release has successfully deployed to PRODUCTION environment, we wanted to ### Releases - 1.0.x - Initial release - 2.0.x - Updated code to work with VSTS also +- 2.2.x - Packaged PowerShell task SDK with task +### Building the Extension +- Ensure that your machine has internet access. +- Ensure that you have the TFX command line client installed (run `npm install -g tfx-cli` to install). +- Run the build.ps1 script to download the latest version of the PowerShell task SDK and package everything. ## Included Tasks ### Build Release Retension Task diff --git a/vss-extension.json b/vss-extension.json index a314b3a..83e0a78 100644 --- a/vss-extension.json +++ b/vss-extension.json @@ -1,7 +1,7 @@ { "manifestVersion": 1, "id": "BuildReleaseSetRetention-Tasks", - "version": "2.0.0", + "version": "2.2.2", "name": "Set Retention forever on a Build Release", "publisher": "HariBabuBavanari", "description": "A set of tasks that update TFS 2015 Builds and Releases Retention.", @@ -32,7 +32,7 @@ "path": "readme.md" }, "license": { - "path": "license.md" + "path": "LICENSE" } }, "screenshots": [