I have a Jenkins server built on a Windows PC, when it builds my project it adds the word Pipeline with a space character separator to the project in the workspace. The value ${ITEM_FULL_NAME} is safe from an OS point of view but I have a problem with a process (Xilinx Memory Interface Generator) that runs in the pipeline that cannot cope with spaces in the path (it is bad that that process cannot cope with space characters in directories but I am stuck with it). Is there a way to ensure the generated ${ITEM_FULL_NAME} variable does not contain space characters?
I have tried to work around the issue by creating a Power Shell script to rename the directory using the underscore character but as feared I cannot do this as a process is running on the folder.
I have looked at the Whitespace plugin but I think this is for inputs into the pipeline not for what Jenkins generates.
I also looked at Restrict Project Naming but again think this is for project input and not what is generated by Jenkins.
Any suggests gratefully received; I am new to Jenkins so if you have a solution it might need spelling out, thank you.
You can use trim to remove the white spaces:
ITEM_FULL_NAME= ITEM_FULL_NAME.trim()
Another way :
If the variable is a parameter variable then you can use below:
parameters { string(defaultValue: "", description: '', name: 'ITEM_FULL_NAME', trim: true) }
Related
I've got a parameterized freestyle Jenkins job, and I'd like to include part of one of the parameters in the build name. The parameter that I'm interested in is called FILE_PATH. Due to the file directory structure of the project used by this job, the file path always starts with the same string, which is 9 characters long. So if FILE_PATH="somepath/what/I/want", I would like the name of my build to be what/I/want.
Some things I've tried putting in the "Set Build Name" field provided by the Build Name Setter plugin:
${FILE_PATH:9}
This gave me the following error:
Failed to evaluate name macro:org.jenkinsci.plugins.tokenmacro.MacroEvaluationException: Unrecognized macro 'FILE_PATH' in '${FILE_PATH:9}'
${"FILE_PATH":9}
FILE_PATH was just treated as a string:
New run name is '${"FILE_PATH":9}'
${$FILE_PATH:9}
This just led to the raw expression being included with FILE_PATH being expanded:
New run name is '${somepath/what/I/want:9}'
${ENV,var="FILE_PATH":9}
This didn't get processed at all:
New run name is '${ENV,var="FILE_PATH":9}'
I've got the Build Name Setter and the Token Macro plugins installed. I'd like to do this in the Build Name plugin, if possible, although I can install any other plugins I need to get this to work.
${ENV:9,var="FILE_PATH"} should do what you are looking for.
An alternative is to also eliminate the beginning of the string, as far as you know what exactly the string is:
${ENV#somepath/,var="FILE_PATH"}
In case you ever need to strip something from the end of the string instead, use % in place of #.
I'm assuming you are using a Jenkinsfile pipeline script?
If so, you can just use the groovy substring method.
variable.substring(9)
Not sure if you can do something similar using parameterized builds.
Can I change the way Jankins names the workspace for concurrent jobs? Currently it uses the #2, #3 when running concurrent builds. I would like to change the "#" to another character. Is this possible. It is causing problems further down in my jobs.
Workspace created for concurrent job #2:
in workspace /devsrc/jenkins/workspace/CKPT_vw5.2_ubuntu#2
Further down in build script:
The environment variable II_SYSTEM contains characters that are not
allowed. The path should only contain alphabetic, digit, period,
underscore and hyphen characters.
+ [ ! -f /devsrc/jenkins/workspace/CKPT_vw5.2_ubuntu#2/ingres/files/config.dat ]
+ exit 1
I didn't test this before posting, but I've used these types of parameters in the past with no problems. See features controlled by system properties. In there, there's one to change the # to something else:
"hudson.slaves.WorkspaceList" (default value: #)
When concurrent builds is enabled, a unique workspace directory name is required for each concurrent build. To create this name, this token is placed between project name and a unique ID, e.g. "my-project#123".
In Ubuntu, I would edit /etc/default/jenkins and add this to the "JAVA_ARGS" property and say use "A" instead of "#". And of course you'll need to restart Jenkins.
-Dhudson.slaves.WorkspaceList=A
We are using Jenkins Pipeline Multibranch Plugin with Blue Ocean.
Through my reading, I believe it is quite common to tie your project's build number to the Jenkins run, as this allows traceability from an installed application through to the CI system, then to the change in source control, and then onto the issue that prompted the change.
The problem is that for each branch, the run number begins at 0. For a project with multiple branches, it seems impossible to guarantee a unique build number.
You can get the Git branch name from $GIT_BRANCH and add this to $BUILD_NUMBER to make an ID that's unique across branches (as long as your company doesn't do something like get themselves taken over by a large corporation that migrates you to another Jenkins server and resets all the build numbers: to protect against that, you might want to use $BUILD_URL).
Only snag is $GIT_BRANCH contains the / character, plus any characters you used when naming the branch, and these may or may not be permitted in all the places where you want an ID. ($BUILD_URL is also going to contain characters like : and /) If this is an issue, one workaround would be to delete unwanted characters with tr:
export MY_ID=$(echo $GIT_BRANCH-$BUILD_NUMBER | tr -dc [A-Za-z0-9-])
(-dc means delete the complement of these characters, so A-Z, a-z, 0-9 and - are the characters you want to keep.)
Maybe instead of a unique (global numeric) build number you might want to try a unique (global) build display name?
According to "pipeline syntax: global variables reference" currentBuild.displayName is a writable property. So you could e.g. add additional information to the build number (in order to make it globally unique) and use that string in subsequent artifact/application build steps (to incorporate that in the application's version output for your desired traceability), e.g. something like:
currentBuild.displayName = "${env.BRANCH_NAME}-${currentBuild.id}"
Using the build's schedule or start time formatted (currentBuild.timeInMillis) as a readable date, or using the SCM revision might be also useful, e.g. resulting in "20180119-091439-rev149923".
See also:
https://groups.google.com/forum/#!msg/jenkinsci-users/CDuWAYLz2zI/NLxwOku4AwAJ
https://support.cloudbees.com/hc/en-us/articles/220860347-How-to-set-build-name-in-Pipeline-job
One way is to have a Job that is being called from all branches and using it's build number. That job can be just a normal pipeline job with a dummy Jenkinsfile like echo "hello". Then just call it like this
def job = build job: 'build number generator', quietPeriod: 0, parameters: [
string(value: "${BRANCH_NAME}-${BUILD_NUMBER}", name: 'UID')
]
def BNUMBER = job.getNumber().toString()
currentBuild.displayName = "build #"+BNUMBER
echo BNUMBER
Not sure if that UID parameter is needed but it forces all calls into "build number generator" job to be unique so Jenkins wouldn't optimize builds that happen at same time to use same "build number generator" job.
You can use an external service to manage a unique build number for your project. It helps to get unique build numbers across branches and across CI servers too.
https://www.nextbuildnumber.net/
I'm working on automating our software's build / deploy process. One major piece of this is executing msbuild to compile multiple Delphi projects.
Following numerous resources such as this one, I can do it successfully from the RAD Studio Command Line (which is simply calling rsvars.bat to set some environment variables). However, when trying to automate both this batch file and the msbuild command from Delphi, I cannot figure out how to proceed.
The key of the issue is that the batch file and the actual msbuild command are two entirely separate commands - although they need to be run together under the same environment. I found this question somewhat related, but I don't see a clear answer for my scenario.
How can I execute msbuild from Delphi while first preparing it with the environment variables as found in rsvars.bat?
As this answer showed, you can run cmd.exe itself with command-line parameters to execute commands.
Per the cmd.exe documentation:
Syntax
cmd [/c|/k] [/s] [/q] [/d] [/a|/u] [/t:{<B><F>|<F>}] [/e:{on|off}] [/f:{on|off}] [/v:{on|off}] [<String>]
Parameters
/c
Carries out the command specified by String and then stops.
...
<String>
Specifies the command you want to carry out.
...
Remarks
Using multiple commands
To use multiple commands for <String>, separate them by the command separator && and enclose them in quotation marks. For example:
"<Command>&&<Command>&&<Command>"
Processing quotation marks
If you specify /c or /k, cmd processes the remainder of String, and quotation marks are preserved only if all of the following conditions are met:
You do not use /s.
You use exactly one set of quotation marks.
You do not use any special characters within the quotation marks (for example: & < > ( ) # ^ | ).
You use one or more white-space characters within the quotation marks.
The String within quotation marks is the name of an executable file.
If the previous conditions are not met, String is processed by examining the first character to verify whether it is an opening quotation mark. If the first character is an opening quotation mark, it is stripped along with the closing quotation mark. Any text following the closing quotation marks is preserved.
So try using CreateProcess() or ShellExecute/Ex() to run an instance of cmd.exe with these parameters:
cmd.exe /C ""<path>\rsvars.bat" && msbuild "<path>\project" <msbuild parameters> ..."
Alternatively, you can have your app load rsvars.bat and parse out the values it defines (or just define the values in your own code), and then execute msbuild using CreateProcess(), passing the desired environment variables to its lpEnvironment parameter. This way, you do not need to actually execute rsvars.bat at all.
Another way which works is to put both commands together into another new batch file. This also allows you to build multiple projects using the same environment. For example DoBuild.bat with the following contents:
call "C:\Program Files (x86)\Embarcadero\Studio\17.0\bin\rsvars.bat"
msbuild "<path>\MyProject.dproj"
msbuild "<path>\MyOtherProject.dproj"
msbuild "<path>\YetAnotherProject.dproj"
Then, just execute your batch file:
Cmd.exe /K "<path>\DoBuild.bat"
I'm writing the Custom Activities of build process template. I got the below issue when build the activity.
>XamlBuildTask : error XC1043: Extension 'Microsoft.Activities.Build.BeforeInitializeComponentExtension' threw an exception of type 'System.IO.PathTooLongException' : '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.'.
Do you have any ideas? Please help!
I find one tip here. Hope it might be helpful to you.
Currently there are a two workarounds:
Reduce the namespace in workflow x:Class property. This makes the
generated file have a shorter name.
Use the subst or mklink command to
create mapping so that the path the solution is located in becomes a
lot smaller. In team build, the workspace mapping needs to be modified
equally.
This still happens in 2015 TFS
This is the best answer I got changing build agent properties
Properties to save path space
The build agent properties dialog defines the "Working directory” for the build agent, defaulting to
“$(SystemDrive)\Builds\$(BuildAgentId)\$(BuildDefinitionPath)”. Based
on the above link, I’m going to go with
“$(SystemDrive)\B\$(BuildDefinitionId)” – that should take the
'”uilds” off the base directory, the TFS project name (19 characters),
a backslash, and the build name (7 characters) out, and replace them
with just a 32-bit number (which should be at most 10 digits, but
since it starts from 1, it’s much more likely to be 3-4 digits),
saving me 23 characters minimum
I may not have been able to shorten $(SourceDir), but it’s just “$(BuildDir)\Sources”, right? I can just configure the build to pull
the code to “$(BuildDir)\S” instead of “$(SourceDir)”, and I
should save another 6 characters, getting me to 29 characters saved,
which should be enough