Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Start vNext build from Powershell and get artifacts

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?

  1. Get Sources for ChangeSetId
  2. MSBuild application with given configuration
  3. Get build Artifacts using PowerShell
  4. Deploy to environment using Release Management (Powershell as well)
like image 760
Samjongenelen Avatar asked Sep 10 '15 07:09

Samjongenelen


People also ask

How have we improved the experience with powershellget and NuGet?

We have improved the experience with PowerShellGet and private NuGet feeds by focusing on pain points using an Azure Artifacts feed. We addressed pain points by enabling/documenting the following features: What is Azure Artifacts and Why would I use it?

When to use Azure artifacts with powershellget?

A common use scenario for Azure Artifacts with PowerShellGet is for organizations which need a controlled access feed for sharing their private internal packages and vetted external packages within their organization. Package owners may also want to use Azure Artifacts as part of their CI/CD pipeline in Azure DevOps.

What do I need to install to run Azure artifacts?

The other component you will need is the Azure Artifacts credential provider. The credential provider comes pre-installed with Visual studio, so if you have VS 15.9, you don’t need to install anything. Otherwise the steps for installing the credential provider, which are platform dependent are provided here.

How do I set the VSS_NuGet_External_feed_endpoints variable?

Configure an environment variable with your credentials. To do set the VSS_NUGET_EXTERNAL_FEED_ENDPOINTS variable to Note may need to restart the agent service or the computer before the environment variables are available to the agent. For assistance with this step check out the Artifacts Credential Provider GitHub .


2 Answers

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.

like image 63
Yan Sklyarenko Avatar answered Oct 04 '22 20:10

Yan Sklyarenko


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.

  1. Connect to TFS' Build system
  2. List Build Definition items (for myself, Poc)
  3. Search for some string and get Build ID
  4. Kick off a build, using a hard coded ID 7 (because I knew this was going to work, and therefor my work was done)
  5. Get the Artifacts (in which I incorporated the VSO build task 'Publish Artifacts Server')
  6. 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)
like image 39
Samjongenelen Avatar answered Oct 04 '22 20:10

Samjongenelen