问题
In order to automate our deployments, I would like to rebuild an application, based on a given ChangeSetId. Once this build has completed, I want to get the artifacts of the build (the .exe), so we can deploy them. For the sake of the question I am focussing on the 'Get artifacts from build' part.
For DevOps purposes, I'd like to use PowerShell, since it should be able to access the TFS API libraries and because MS recommends using it.
Environment
I've set up Builds in our On Premise TFS 2015 server (which are working neatly) - and added a VSO task 'Publish artifacts' after this build. So far so good. The published artifacts is are to be stored on the Server, which basically means I have to download the artifacts connected to build - every existing build will have its artifacts linked - which is better then an UNC drop in my book.
No comes my challenge; how do I programmaticaly access these artifacts, step 3?
- Get Sources for ChangeSetId
- MSBuild application with given configuration
- Get build Artifacts using PowerShell
- Deploy to environment using Release Management (Powershell as well)
回答1:
TFS 2015 comes with the new REST API, and it includes the method to get the artifacts of the specific build. I would approach your challenge in the following way:
- Add a "PowerShell script" build step after your "Publish artifacts" step
- In that PowerShell script:
- Get the ID of the current build. TFS exposes a number of predefined variables, and build ID is there. All those variables end up as environment variable, and this post can help you read the appropriate one from your PowerShell script
- Next, make a web request to get build artifacts. As you can see from the API description, you'll have to provide just the build ID
- Then, parse the JSON response - the
downloadUrl
property contains the link to download all the artifacts of the build zipped as a single archive - Finally, extract the archive and pick up those artifacts you need. Perhaps, you'd like to deploy it to your testing environment in this step as well
Hope this helps.
回答2:
Okay so, like Yan Sklyarenko said, TFS 2015 (and 2013, after some update), has an excellent REST API.
I've created a very, very rough basic PowerShell script that does what i want. I cannot emphasize enough how much this code needs refactoring - i really just needed this to work as a proof of concept, and we will develop multiple scripts for different needs, but for the people that came here for a code example, you'll find it here.
- Connect to TFS' Build system
- List Build Definition items (for myself, Poc)
- Search for some string and get Build ID
- Kick off a build, using a hard coded ID 7 (because I knew this was going to work, and therefor my work was done)
- Get the Artifacts (in which I incorporated the VSO build task 'Publish Artifacts Server')
- Extract said received Artifacts, because TFS zips them.
From there on out i will incorporate these scripts and outputs into MS Release Management services - and be ready to migrate to VSO Release vNext when it ships for on-premise TFS 2015!
$projectId ='{ProjectIdGuid}'
$buildNr = '3945'
$username = 'username'
$password = 'password'
$zipDestination = 'C:\temp\unzip\temp.zip'
$workingFolder = ('C:\temp\unzip\' + [System.DateTime]::Now.ToString("yyyyMMddhhmmss")) #temp because of file already exist warnings... after completion we should delete the working directory content
$tfsURL = 'http://myTFS:8080/tfs/MyCollection/'+ $projectId
$cred = New-Object System.Management.Automation.PSCredential($username, (ConvertTo-SecureString -String $password -AsPlainText -Force))
#write list of build definitions (to be used later)
$allbuildDefs = (Invoke-RestMethod -Uri ($tfsURL + '/_apis/build/definitions?api-version=2.0') -Method GET -Credential $cred).value | Where-Object {$_.name -like '*buildName*'} | Out-Default | select name
Write-Host($allbuildDefs)
$buildDefs = ConvertFrom-Json($allbuildDefs)
$buildId = ($buildDefs.value).id;
#Get build Definition for what you want to build
$buildDefinitionURI = $tfsURL + '/_apis/build/requests?api-version=1.0'
#kick off build
$body = '{ "definition": { "id": '+ 7 + '}, reason: "Manual", priority: "Normal"}'
$BuildReqBodyJson = $body | ConvertTo-Json
$buildOutput = Invoke-RestMethod -Method Post -Uri $buildDefinitionURI -Credential $cred -ContentType 'application/json' -Body $body
#get buildNr
#build URI for buildNr
$BuildURI = $tfsURL + '/_apis/build/builds/' + $buildNr + '/artifacts'
#get artifact downloadPath
$downloadURL = (Invoke-RestMethod -Uri $BuildURI -Credential $cred).Value.Resource.downloadUrl
#download ZIP
Invoke-WebRequest -uri $downloadURL -Credential $cred -OutFile $zipDestination
#unzip
Add-Type -assembly 'system.io.compression.filesystem'
[io.compression.zipfile]::ExtractToDirectory($zipDestination, $workingFolder)
来源:https://stackoverflow.com/questions/32496022/start-vnext-build-from-powershell-and-get-artifacts