Increment variable value in TFS build +1 - tfs

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.

Related

How to "reduce" Jenkins Pipeline output path

We were building our solution without any "Pipeline" in Jenkins until recently, so I'm currently in the progress to move our build to multibranch pipelines.
The issue that I'm running into is that we have a lot of structure une our solution(lot of subfolder, and sometimes some big names).
Currently, the jenkins pipeline extract everything in a folder that looks like:
D:\ws\ght-build_feature_pipelines-TMQ33LB5OQIQ5VXVMFKFDG2HWCD4MUOGEGUWJUOMZ5D2GI42BIQA
Which is very-long, and now we are reaching the 260 characters limit of MSBuild:
C:\Program Files (x86)\Microsoft Visual
Studio\2017\Professional\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(2991,5):
error MSB3553: Resource file
"obj\Release\xx.aaaaaaaaaa.yyy.bbbbbb.dddddddddddddd.yyyyyyy.vvv.dddddddddd.Resources.resources"
has an invalid name. The item metadata "%(FullPath)" cannot be applied
to the path
"obj\Release\xx.aaaaaaaaaa.yyy.bbbbbb.dddddddddddddd.yyyyyyy.vvv.dddddddddd.Resources.resources".
The specified path, file name, or both are too long. The fully
qualified file name must be less than 260 characters, and the
directory name must be less than 248 characters.
[D:\ws\ght-build_feature_pipelines-TMQ33LB5OQIQ5VXVMFKFDG2HWCD4MUOGEGUWJUOMZ5D2GI42BIQA\Src\bbbbbb\dddddd\dddddddddddddd\yyyyyyy\xx.aaaaaaaaaa.yyy.bbbbbb.dddddddddddddd.yyyyyyy.vvv\xx.aaaaaaaaaa.yyy.bbbbbb.dddddddddddddd.yyyyyyy.vvv.csproj]
We have so much cases where the length is big that it's really a big job to refactor everything, so I'm looking on how to specify to jenkins a smaller path?
What I finally did:
pipeline {
agent {
node{
label 'windows-node'
customWorkspace "D:\\ws\\${env.BRANCH_NAME}"
}
}
options{
skipDefaultCheckout()
}
...
}
And I've a step that does the checkout. It was easier for me to have a "per-job" behavior, without touching jenkins global settings.
Update (for any recent Jenkins instances)
Turns out that with recent Jenkins versions PATH_MAX seems to be ignored.
The only thing it does: Issue a warning in the Jenkins log when smaller than a certain value, which actually does not matter - as the setting itself will anyways be ignored (as seen on Jenkins 2.249.3). See also: JENKINS-2111
As far as I can tell - the new setting was introduced in jenkins-branch-api 2.0.21:
There's a new property introduced: MAX_LENGTH.
This defaults to 32 characters by default.
You can set it the same way like PATH_MAX:
As a java property - to ensure that Jenkins will start using the right setting, e.g.:
-Djenkins.branch.WorkspaceLocatorImpl.MAX_LENGTH=40
or during run-time, using the script console:
jenkins.branch.WorkspaceLocatorImpl.MAX_LENGTH=40
For older Jenkins instances
Actually there's a java property you can set to specify the length of the directory name, e.g.:
-Djenkins.branch.WorkspaceLocatorImpl.PATH_MAX=20
To make it permanent you have to specify this property in the Jenkins java startup configuration file.
You may also read and write this property using the Jenkins script console for temporary changes or to just give it a try as it takes effect immediately, e.g.
println jenkins.branch.WorkspaceLocatorImpl.PATH_MAX
jenkins.branch.WorkspaceLocatorImpl.PATH_MAX = 20
println jenkins.branch.WorkspaceLocatorImpl.PATH_MAX
Setting this value to 0 changes the path generation behavior.
For details please check:
https://issues.jenkins-ci.org/browse/JENKINS-34564
https://issues.jenkins-ci.org/browse/JENKINS-38706

Is there a way to set next Build Number manually on Jenkins

After system restart where Jenkins is stored, one of the jobs is constantly failing it is trying to create bulid with number 1 but there is already 1400 past builds. Is there a way to change it so the build will be created with correct increment so in this case 1401.
Full stactrace from jenkins:
java.lang.IllegalStateException: [Directory]\builds\1 already existed; will
not overwite with [Build.Name] #1
at hudson.model.RunMap.put(RunMap.java:189)
at jenkins.model.lazy.LazyBuildMixIn.newBuild(LazyBuildMixIn.java:178)
at hudson.model.AbstractProject.newBuild(AbstractProject.java:1011)
at hudson.model.AbstractProject.createExecutable(AbstractProject.java:1210)
at hudson.model.AbstractProject.createExecutable(AbstractProject.java:144)
at hudson.model.Executor$1.call(Executor.java:328)
at hudson.model.Executor$1.call(Executor.java:310)
at hudson.model.Queue._withLock(Queue.java:1251)
at hudson.model.Queue.withLock(Queue.java:1189)
at hudson.model.Executor.run(Executor.java:310)
You can use a groovy script in $JENKINS_URL/script as follows:
item = Jenkins.instance.getItemByFullName("jobName")
item.updateNextBuildNumber(1401)
It looks like you can use the "Next Build Number" plugin to accomplish this: https://wiki.jenkins.io/display/JENKINS/Next+Build+Number+Plugin
There is a file you can edit: $JENKINS_HOME/jobs/../nextBuildNumber
$ cat /var/lib/jenkins/jobs/my-project/branches/develop/nextBuildNumber
42
You will need to reload configuration after changing it.

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);
}

How to specify a value for a Jenkins environment variable that contains a space

I am trying to specify a value for a Jenkins environment variable (as created on the Manage Jenkins -> Configure System screen, under the heading "Global properties") which contains a space. I want to use this environment variable in an Execute Shell build step. The option that I need to appear in the command line in the build step is:
--platform="Windows 7"
The syntax I am using on the command line is --platform=${VARIABLE_NAME}
No matter how I attempt to format it, Jenkins seems to reformat it so that it is treated as two values. I have tried:
Windows 7
"Windows 7"
'Windows 7'
Windows\ 7
The corresponding results, when output during the Execute Shell build step have been:
--platform=Windows 7
'--platform="Windows' '7"'
'--platform='\''Windows' '7'\'''
--platform=Windows/ 7
I have also tried changing my command line syntax to --platform='${VARIABLE_NAME}' as well as '--platform=${VARIABLE_NAME}', but in each of those cases the ${VARIABLE_NAME} is not resolved at all and just appears as ${VARIABLE_NAME} on the resulting command.
I am hoping there is a way to make this work. Any suggestions are most appreciated.
You should be able to use spaces without any special characters in the global properties section.
For example, I set a variable "THIS_VAL" to have the value "HAS SPACES".
My test build job was the following:
#!/bin/bash
set +v
echo ${THIS_VAL}
echo "${THIS_VAL}"
echo $THIS_VAL
and the output was
[workspace] $ /bin/bash /tmp/hudson8126983335734936805.sh
HAS SPACES
HAS SPACES
HAS SPACES
Finished: SUCCESS
I think what you need to do is use the following:
--platform="${VARIABLE_NAME}"
NOTE: Use double quotes, not single quotes. Using single quotes makes the stuff inside the quotes literal, meaning that any variables will be printed as is, not parsed into the actual value. Therefore '${VARIABLE_NAME}' will be printed as is, not parsed into "Windows 7".
EDIT:
Based on #BobSilverberg comment below, use the following:
--platform="$VARIABLE_NAME"
Note: no curly brackets.

Resources