VSO Build vNext - get TFS revision number - tfs

In my build steps I need to provide TFS revision number as a paramter. I know there is a variable $(Build.SourceVersion) but it returns it with a "CS" prefix e.g. "CS1234"
Is there an easy way to remove that "CS" prefix? Any built-in string functions?
Thanks

I'm not aware about any built-in functions to format that string - you'll have to do it in your script somewhere. Note that $(Build.SourceVersion) variable returns empty string if you specify it in the Build Number Format field in your build definition. This thread might give you more details.

There is no build in method. Also changeset number and revision number are not the same thing. You will get COMMIT ID in $(Build.SourceVersion) if you are using GIT repository.
You may use PowerShell to strip that part off. Following line should give you the numeric portion.
[string]$version = ($Env:BUILD_SOURCEVERSION -replace'\D+(\d+)','$1')

Adding to #cilerler's answer, I've used this generic Powershell script as my first VSTS build step:
Param(
[string] $SourceBranchName = $Env:BUILD_SOURCEBRANCHNAME,
[string] $SourceVersion = $Env:BUILD_SOURCEVERSION
)
Write-Host "SourceBranchName = $SourceBranchName"
Write-Host "SourceVersion = $SourceVersion"
if ($SourceBranchName -eq "trunk"){
$MajorMinor = "0.0"
}
else{
$MajorMinor = $SourceBranchName
}
# Remove CS from changeset number
$Revision = ($SourceVersion -replace 'C','')
$BuildNumber = "$MajorMinor.$Revision.0"
Write-Host "Setting Build Number '$BuildNumber'"
Write-Host "##vso[build.updatebuildnumber]$BuildNumber"
Note that it presumes that your branch name is in the format Major.Minor (eg. 1.4) or trunk.
Also, it seems the VSTS documentation is wrong, the Build.SourceVersion variables is of the form C1226.

Related

Increment variable value in TFS build +1

I have a Microsoft Visual Studio Team Foundation Server (Version 15.117.26714.0) with predefined variable $(ProjectBuildNumber).
Is there any way to increment, during build process, value of variable with minor build number by +1?
$(ProjectBuildNumber) = 663
So, that on next build it will be:
$(ProjectBuildNumber) = 664
You can't reference variables in the build number of the Build Definition. But what you can do is override the build number in the build itself. You can either use a magic log command or use my VSTS Variables Task to set the Build.BuildNumber in the build itself. The Variables Task does expand variable references. You could probably just set the value to the current value to get it expanded.
To issue the log command yourself use a batch script, PowerShell or bash to output the following specific string to the console:
##vso[build.updatebuildnumber]build number
Update build number for current build. Example:
##vso[build.updatebuildnumber]my-new-build-number
Minimum agent version: 1.88
source: https://github.com/Microsoft/vsts-tasks/blob/master/docs/authoring/commands.md
An alternative option is to use the $(Rev) option:
Build.BuildNumber = 1.1.$(Rev:.r)
That will automatically increase the variable each time the build runs.
To update a variable in a Build Definition use yet another extension:
These things combined should be able to get what you want.
In the variable section,
set the value of ProjectBuildNumber to $[counter('', 663)].
This will queue build starting with 663 as ProjectBuildNumber and increments by 1 for the subsequent queue of builds.
Unfortunately counter function (Expressions) is not available in TFS 2018. In this old version the best solution for me is to use a PowerShell script as the first Task of the build. You can than have your parameter
$(ProjectBuildNumber)
as an input argument, and place this inline script:
$ProjectBuildNumber=$args[0]
$ProjectBuildNumber++
Write-Host "##vso[task.setvariable variable=ProjectBuildNumber;]$ProjectBuildNumber"
After this Task you can use your incremented ProjectBuildNumber variable in all subsequent Tasks.

How to access build folder number in TFS 2017

I typically tell TFS what folder to use via $(build.sourcesdirectory) which translates into C:\Builds\1\s .
However, I need to repack the deployment zip, so I had to add Content\C_C\Builds\myproj\1\s to my CI.
This isn't very good as the 1 can change due to dev ops work.
Is there a variable or technique I can use to replace the 1 with a variable?
I tried $(Agent.Id) with no luck...
You can use PowerShell to retrieve the number from variable $(build.sourcesdirectory) and pass the value to a new variable.
Dynamically get the number Sample:
$string = "$env:BUILD_SOURCESDIRECTORY"
#$string = "E:\andyli-v\01Agent\_work\6\s" (The length is 29, the number '6' in the string is the 27th character, So get the substring as (26,1) means get one character behind the 26th character)
$parameter = $string.Substring(26, 1)
Write-Host "BUILD_SOURCESDIRECTORY is :" $string
Write-Host "The String length is : "$string.Length
Write-Host "The number is : "$parameter
You can use $parameter directly to get the number if do actions within the same script.
Set a variable :
If you want a variable, you can set it via PS :
Write-Output ("##vso[task.setvariable variable=GetNumber;]$parameter")
You can reference there articles to set the variable:
https://roadtoalm.com/2016/08/11/set-output-variable-in-a-powershell-vsts-build-task/
http://blog.majcica.com/2016/02/19/passing-values-between-tfs-2015-build-steps/

VSTS no longer adds build number to Global List upon build complete?

I am using VSTS build & release feature to build the .net project. After building the project, I want build number to be updated in the Global List so that I can select the same build number to resolve the defects (Integrated in Build) and while executing the test cases through MTM.
This feature was present when we were using in-premise TFS 2013.
Please let me know if there is a way to update the build no. in the Global List using VSTS Rest API.
Thanks in Advance!!
There isn’t the Rest API to update the Global List, you can update the Global List by using VSTS/TFS client API (WorkItemStore.ImportGlobalLists Method) or witadmin commands.
A sample by using PowerShell: Get TfsCollection and TFS Services and Adding to a GlobalList.
function Add-TfsGlobalListItem {
Param(
[parameter(Mandatory=$true)][Microsoft.TeamFoundation.Client.TfsTeamProjectCollection] $TfsCollection,
[parameter(Mandatory=$true)][String] $GlobalListName,
[parameter(Mandatory=$true)][String] $GlobalEntryValue
)
# Get Global List
$store = Get-TfsWorkItemStore $TfsCollection
[xml]$export = $store.ExportGlobalLists();
$globalLists = $export.ChildNodes[0];
$globalList = $globalLists.SelectSingleNode("//GLOBALLIST[#name='$GlobalListName']")
# if no GL then add it
If ($globalList -eq $null)
{
$globalList = $export.CreateElement("GLOBALLIST");
$globalListNameAttribute = $export.CreateAttribute("name");
$globalListNameAttribute.Value = $GlobalListName
$globalList.Attributes.Append($globalListNameAttribute);
$globalLists.AppendChild($globalList);
}
#Create a new node.
$GlobalEntry = $export.CreateElement("LISTITEM");
$GlobalEntryAttribute = $export.CreateAttribute("value");
$GlobalEntryAttribute.Value = $GlobalEntryValue
$GlobalEntry.Attributes.Append($GlobalEntryAttribute);
#Add new entry to list
$globalList.AppendChild($GlobalEntry)
# Import list to server
$store.ImportGlobalLists($globalLists)
On the other hand, you can refer to this article to update related work item of build: Build association with work Items in vNext
Update:
Simple code to connect to VSTS:
param(
[string]$address,
[string]$username,
[string]$password
)
$credentials = New-Object System.Net.NetworkCredential($username, $password)
$tfsCollection = New-Object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection((New-Object System.URI($address)))
$wis = $tfsCollection.GetService([Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore])
Then, you can specify the arguments in PowerShell task (build or release) Arguments textbox -address XXX -username XXX -password XXX. (The username can be empty and use personal access token as password)
On the other hand, you can import the assemblies files that in Microsoft Team Foundation Server Extended Client package.

Is possible to change the value of a variable during execution of a release in TFS 2017

In TFS 2017, when a release definition is created a set of custom variables can be created too.
In the scope of an Agent, Is possible to change the value of one variable?
I tried with an inline powershell script:
$env:MyVariable = "changed value"
also try with :
[Environment]::SetEnvironmentVariable("MyVariable ", "changed value.", "User")
without success.
You could use the Logging command to change the custom variable's value.
In your PowerShell script file(script1.ps1), write:
$NewVersion = "NewValue"
Write-Host ("##vso[task.setvariable variable=customVariable;]$NewVersion")
Then add a Powershell script to run this file.
And you could add another Powershell script file(script2.ps1) to output the custom value. Run this file after script1 to check if the value has been changed successfully.
Here is a similar question: How to change a tfs build variable in script
Did you try Write-Host?
Write-host $env:OutputVar
Can't check myself now, but you can take a look here for detail.

How to get build time stamp from Jenkins build variables?

How can I get build time stamp of the latest build from Jenkins?
I want to insert this value in the Email subject in post build actions.
Build Timestamp Plugin will be the Best Answer to get the TIMESTAMPS in the Build process.
Follow the below Simple steps to get the "BUILD_TIMESTAMP" variable enabled.
STEP 1:
Manage Jenkins -> Plugin Manager -> Installed...
Search for "Build Timestamp Plugin".
Install with or without Restart.
STEP 2:
Manage Jenkins -> Configure System.
Search for 'Build Timestamp' section, then Enable the CHECKBOX.
Select the TIMEZONE, TIME format you want to setup with..Save the Page.
USAGE:
When Configuring the Build with ANT or MAVEN,
Please declare a Global variable as,
E.G. btime=${BUILD_TIMESTAMP}
(use this in your Properties box in ANT or MAVEN Build Section)
use 'btime' in your Code to any String Variables etc..
NOTE: This changed in Jenkins 1.597, Please see here for more info regarding the migration
You should be able to view all the global environment variables that are available during the build by navigating to https://<your-jenkins>/env-vars.html.
Replace https://<your-jenkins>/ with the URL you use to get to Jenkins webpage (for example, it could be http://localhost:8080/env-vars.html).
One of the environment variables is :
BUILD_ID
The current build id, such as "2005-08-22_23-59-59" (YYYY-MM-DD_hh-mm-ss)
If you use jenkins editable email notification, you should be able to use ${ENV, var="BUILD_ID"} in the subject line of your email.
One way this can be done is using shell script in global environment section, here, I am using UNIX timestamp but you can use any shell script syntax compatible time format:
pipeline {
agent any
environment {
def BUILDVERSION = sh(script: "echo `date +%s`", returnStdout: true).trim()
}
stages {
stage("Awesome Stage") {
steps {
echo "Current build version :: $BUILDVERSION"
}
}
}
}
Try use Build Timestamp Plugin and use BUILD_TIMESTAMP variable.
Generate environment variables from script (Unix script) :
echo "BUILD_DATE=$(date +%F-%T)"
I know its late replying to this question, but I have recently found a better solution to this problem without installing any plugin. We can create a formatted version number and can then use the variable created to display the build date/time.
Steps to create: Build Environment --> Create a formatted version number:
Environment Variable Name: BUILD_DATE
Version Number Format String: ${BUILD_DATE_FORMATTED}
thats it. Just use the variable created above in the email subject line as ${ENV, var="BUILD_DATE"} and you will get the date/time of the current build.
You can use the Jenkins object to fetch the start time directly
Jenkins.getInstance().getItemByFullName(<your_job_name>).getBuildByNumber(<your_build_number>).getTime()
also answered it here:
https://stackoverflow.com/a/63074829/1968948
BUILD_ID used to provide this information but they changed it to provide the Build Number since Jenkins 1.597. Refer this for more information.
You can achieve this using the Build Time Stamp plugin as pointed out in the other answers.
However, if you are not allowed or not willing to use a plugin, follow the below method:
def BUILD_TIMESTAMP = null
withCredentials([usernamePassword(credentialsId: 'JenkinsCredentials', passwordVariable: 'JENKINS_PASSWORD', usernameVariable: 'JENKINS_USERNAME')]) {
sh(script: "curl https://${JENKINS_USERNAME}:${JENKINS_PASSWORD}#<JENKINS_URL>/job/<JOB_NAME>/lastBuild/buildTimestamp", returnStdout: true).trim();
}
println BUILD_TIMESTAMP
This might seem a bit of overkill but manages to get the job done.
The credentials for accessing your Jenkins should be added and the id needs to be passed in the withCredentials statement, in place of 'JenkinsCredentials'. Feel free to omit that step if your Jenkins doesn't use authentication.
This answer below shows another method using "regexp feature of the Description Setter Plugin" which solved my problem as I could not install new plugins on Jenkins due to permission issues:
Use build timestamp in setting build description Jenkins
If you want add a timestamp to every request from browser to jenkins server.
You can refer to the jenkins crumb issuer mechanism, and you can hack the /scripts/hudson-behavior.js add modify here. so it will transform a timestamp to server.
/**
* Puts a hidden input field to the form so that the form submission will have the crumb value
*/
appendToForm : function(form) {
// add here. ..... you code
if(this.fieldName==null) return; // noop
var div = document.createElement("div");
div.innerHTML = "<input type=hidden name='"+this.fieldName+"' value='"+this.value+"'>";
form.appendChild(div);
}

Resources