Enable Full CI/CD with Jenkins and VSTS


There is a much easier way to do this now. You can read how here Setting up CI/CD with the TFS Plugin for Jenkins


In a previous post I showed how you could trigger a release from Jenkins using the Release Management REST API.  Since that post, the REST for Release Management as changed so I wanted to write and update.  Instead of just duplicating that post I decided to take it a step further and have the Jenkins build automatically trigger when I commit code to Visual Studio Team Services (VSTS).  This would give us a full CI/CD pipeline with Jenkins and VSTS. In this post I will show you the pieces needed to enable full CI/CD using Jenkins and VSTS.

Before I begin I will state some assumptions:

  1. You have a working Jenkins installation with the following plugins:
    • Credentials
    • Get client
    • Git
    • Post-Build Script
    • PowerShell
  2. You have a VSTS account
  3. Your code will be in VSTS Git repository
  4. The attached PowerShell file is in the root of your repository

We are going to begin and end this post in Jenkins.  Step one is to create an empty Freestyle project in Jenkins to wire up to VSTS.

  1. Log into Jenkins
  2. Click New Item
    Field Name Value
    Item name Jenkins CI-CD
  3. Select Freestyle project
  4. Click OK

You can leave this tab open and perform the next steps in a new tab of your browser.  We just needed a Jenkins build to configure VSTS against. We will return to this tab to complete the build at the end of the post.

To connect Jenkins to VSTS so it can clone the Git repository and authenticate during our REST calls, we are going to need to create a Personal Access Token.

  1. Log into VSTS
  2. Click your name in the upper right-hand corner
  3. Click My security
  4. Click Add
  5. Enter appropriate values
  6. Click Create Token
  7. Copy the token value and store it somewhere safe
Now create a Service Endpoint in VSTS to connect to your Jenkins installation.
  1. Log into VSTS
  2. Navigate to a Team Project
  3. Click the Manage Project gear icon in the upper right-hand corner
  4. Click the Services tab
  5. Click New Service Endpoint
  6. Select Jenkins
    Field Name Value
    Connection Name Jenkins
    Server URL {your full Jenkins URL}
    Username {Jenkins user name}
    Password {Jenkins password}
  7. Click OK
Next we will create the release we are going to want to trigger from Jenkins.
  1. Log into VSTS
  2. Navigate to a Team Project
  3. Click Release
  4. Click the Create Release Definition plus button
  5. Select Empty template
  6. Click OK
  7. Enter a name for your definition
  8. Click the Link to a build definition link
  9. Select Jenkins in the Type dropdown
  10. Select the desired Project from the Source (Job) dropdown
  11. Click Link
  12. Click the ellipses of the Default Environment  
  13. Select Deployment conditions…
  14. Select After release creation for Trigger
  15. Click OK
  16. Save your release

Once your release is saved, you can locate the release definition id from the address bar.


We will use this number to make a REST API call to gain access to the other ids we need to trigger a release.  Using the definition id, access this URL:


You will need to locate the environment id and the artifact id.


Next we are going to connect our Jenkins and VSTS via a Service Hook. This will allow communication so Jenkins can be triggered from a commit to VSTS.

  1. Log into VSTS
  2. Navigate to a Team Project
  3. Click the Manage Project gear icon in the upper right-hand corner
  4. Click Service Hooks
  5. Click the + button
  6. Select Jenkins
  7. Click Next
    Field Name Value
    Trigger on this type of event Code pushed
    Repository {your repository}
    Branch [Any]
    Pushed by a member of group [Any]
  8. Click Next
    Field Name Value
    Perform this action Trigger generic build
    Jenkins base URL {your full Jenkins URL}
    Username {Jenkins username}
    User API token (or password) {Jenkins password}
    Build {Build created above}
  9. Click Finish 
We will now update the Jenkins build.  We will only cover the parts needed to talk to VSTS.  I will leave the build steps to build your project for you to configure.
  1. Return to the Jenkins tab
  2. Field Name Value
    Source Code Management Git
    Repository URL https://{instance}.visualstudio.com/DefaultCollection/{project}/_git/{repository}
  3. Click Add next to Credentials
    Field Name Value
    Kind Username with password
    Scope Global (Jenkins, nodes, items, all child items, etc)
    Username {your vsts username}
    Password {personal access token}
    Description Jenkins Access Token from VSTS
  4. Click Add
  5. Select the new credentials
  6. Click Add post-build action
  7. Select Archive the artifacts
    Field Name Value
    Files to archive **/*
  8. Click Add post-build action
  9. Select Execute a set of scripts
  10. Click Add build step
  11. Select Windows PowerShell
  12. Copy and paste the code below into the Command text box
    $workspace = (get-item env:$EnvWORKSPACE).Value
    $build_number = (get-item env:$EnvBUILD_NUMBER).Value
    invoke-expression ".\TriggerRelease.ps1 -TfsCollectionUri https://{instance}.vsrm.visualstudio.com/DefaultCollection -TeamProject {TeamProject} -ReleaseDefinitionId {ReleaseDefinitionId} -TargetEnvironmentId {TargetEnvironmentId} -BuildNumber $build_number -artifactAlias '{artifactAlias}' -artifactId {artifactId} -personalAccessToken {personalAccessToken}"
  13. Update the Instance, Team Project, Release Definition Id, Target Environment Id, Artifact Alias, Artifact Id, and Personal Access Token
  14. Click Save

Now all you have to do is commit a change to VSTS and Jenkins will build the code and trigger a release. When you do, the Service Hook we created will inform Jenkins, who will start a build.


Jenkins will pull the code from the VSTS Git repository using the Personal Access Token we created and build your project.  Finally Jenkins will use the PowerShell script to call the Release Management REST API to trigger the release.


TriggerReleaseV2.ps1 (3.8KB)

Comments (14) -

  • Anvesh

    3/18/2016 11:28:40 AM | Reply

    I am able to trigger the release but it failed the release .In below log at BuildId it is give value 1 but my jenkins Latest BuildId is 15 using the arguments $build_number it is give value 15 only but in below log how its taking the buildid 1 i not getting it.

    2016-03-18T11:03:52.5225962Z Cleaning artifacts directory: C:\a\3fd575cd8…

    2016-03-18T11:03:52.5345954Z Cleaned artifacts directory: C:\a\3fd575cd8

    2016-03-18T11:03:52.5376211Z Number of linked artifacts to download: 1

    2016-03-18T11:03:52.5389487Z Starting artifacts download...

    2016-03-18T11:03:52.5569646Z Downloading linked artifact: NewHorizonsVSO...

    2016-03-18T11:03:52.5579653Z Downloading artifact of type: Jenkins

    2016-03-18T11:03:52.5591335Z Created artifact folder C:\a\3fd575cd8\NewHorizonsVSO

    2016-03-18T11:03:52.7071226Z Got the Jenkins Artifact Details

    2016-03-18T11:03:52.7080538Z Job Name: NewHorizonsVSO

    2016-03-18T11:03:52.7087889Z BuildId: 1

    • anvesh

      3/18/2016 12:17:38 PM | Reply

      I got the solution in power shell script we are passing json format in that idEmbarassedartifactId should replace with idEmbarassedBuildNumber

      after changing this then my build successfully deployed.

  • Uma

    1/11/2017 7:58:14 AM | Reply

    Can we do the steps mentioned in this article in TFS 2015 on premise?
    I tried but I could not found an option to create personal access token

    • Donovan

      1/11/2017 1:24:48 PM | Reply

      TFS 2015 does not support PAT but 2017 does.

  • Kevin

    3/17/2017 9:36:46 PM | Reply

    Our Jenkins implementation is on premise and not publicly accessible, although it can see out.  Will these steps still work for that type of configuration?

    BTW, love your straightforward writing style and exact steps.

    • Donovan

      3/19/2017 3:54:46 PM | Reply

      I would try with the new TFS Plugin.  I have a post on how to use it.

      • zabor

        6/1/2017 7:10:29 AM | Reply

        Hello Donovan - thanks for great article! I have the same case as Kevin -  Jenkins implementation is on premise and not publicly accessible and I'm looking for a solutions that trigger Jenkins Job from a commit to VSTS.

        Do you have any idea how this can be achieved?


  • Stacy

    10/27/2017 6:45:50 PM | Reply

    Here is something I am trying to figure out, and I'm betting you might be the best guy to talk to.  Is there anything that Jenkins can do that VSTS *cannot* do?  I work at a company that relies heavily on Jenkins and I would love to move off of it entirely and onto cloud based builds (for java and .net), if possible.  Other tech in play:  Sonarqube, Sonatype Nexus, Maven.

    • Donovan

      12/3/2017 2:05:43 PM | Reply

      One example of something Jenkins can do today that VSTS can't is build as code. But YAML based build is also coming to VSTS.  We have great support for Sonarqube and Maven. We also have an extension in our marketplace for Nexus marketplace.visualstudio.com/items

  • Kumar

    11/7/2017 7:01:26 AM | Reply

    Hi Donovan,

    I am new to VSTS and want to know how to setup Release management with multiple servers by using vnext release(TFS2015). It would be great help if you provide any document or link for the same.


  • RaviKumar

    3/1/2018 6:44:31 AM | Reply

    Hi Donovan

    Thank you for your article on TFS.
    I have jenkins server and TFS server. I want to create dashboard on TFS for build status chart
    Could you please help/share the steps please.

    Ravi Kumar

  • Shilpa

    5/23/2019 11:15:02 AM | Reply

    I want to use server side hooks in TFS GIt. We want  to restrict user if the git comment dont have valid Jira tickets . We have already setup Client side Hooks but there are challenges in Server side hooks. Can you please let us know how to implement server side hooks ? Please give an example of service hooks. How to implement it.

  • Ankit Thakkar

    9/18/2019 5:44:29 AM | Reply

    I'm getting below error while setup service hook in Azure DevOps to integrate to Jenkins.
    "Jenkins query failed with exception a connection attempt failed because the connected party did not respond after a period of time OR established connection failed to because the connected host failed to respond." in Build and Integration field.

Pingbacks and trackbacks (1)+

Add comment