copy artifacts build step using a dynamic project name alternatives - jenkins

I have a job that when it finishes (Post build Actions) Triggers a parameterized build (Job A)
The build that is getting triggered sets a string parameter called foo for the value of JOB_NAME
"Job A" has a build step to 'copy artifacts from another project' were I set the project name to the variable i'm passing (%foo%)
I can confirm that %foo% is getting the correct value however when the build step executes it fails to substitute the variable
This is the error message I'm getting
Unable to find project for artifact copy: %foo%
I'm looking for alternatives to solve my problem which is
How to pass dynamically project name for copy artifacts from another project

Did you check the help for Copy artifacts build step? If you click on the question mark next to the Project name field, you will see this text:
Name of source project for copying of artifact(s). May contain references to build parameters like $PARAM (note that when a parameter is used, the source project must be accessible to all authenticated users; this prevents use of parameters to access artifacts of private jobs)
So, you should try $foo instead of %foo%.

Had a similar problem.
The "Question mark text" on Project name that #sti quoted was changed meanwhile and only displays info for maven modules.
The error message i got:
Unable to find project for artifact copy: XYZ
This may be due to incorrect project name or permission settings; see help for project name in job configuration.
gives you a hint about missing permissions, but it might be hard to catch or understand (what kind of project-permission?).
So what was missing for me:
Go into your "source"-Job/Project where you want to copy artifacts FROM, and check that
Permission to Copy Artifact
is correctly set to the job you want to copy INTO. (Or set to a wildcard like *).

For those using jenkins-job-builder, you can set the required permissions like so:
- job:
name: project-to-copy-from
properties:
- copyartifact:
projects: "*"
Then you can use copyartifact like so:
- job:
name: project-to-copy-to
builders:
- copyartifact:
project: project-to-copy-from
which-build: last-successful
http://docs.openstack.org/infra/jenkins-job-builder/properties.html#properties.copyartifact

Related

In Jenkins, how do I get the substring of a build parameter to be part of the build name?

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.

Is there a jenkins plugin to add a why-I-built-this remark, that will appear with 'started by [user]'?

When I run a manual build, I'd often like to mark it with documentation to show why I ran it. Is this feature available with a plugin?
thank you!
I would approach this by adding a build parameter as a string, as above, then use the Description Setter Plugin to set it from that parameter. We use something like this for the regex:
^\++ : BUILD DESCRIPTION : GERRIT_CHANGE_OWNER_EMAIL=([^#\s]*)\S*, BUILD_USER_EMAIL=([^#\s]*)\S*, GERRIT_BRANCH=(\S*), GIT_COMMIT=(\S{8}).*$
and this for the description:
\1\2, \4, \3
As a result we get:
jspain, 0ee3198b, master
or when it fails, we get:
Failed due to timeout.
wayvad, fc7bdf2a, master
this "Failed..." text comes from the Build Timeout Plugin
I am not aware of a plugin that can do this, and after a brief search I could not find one to do what you describe.
You can mimic this behavior by adding a string parameter in the job that takes a default value of automatically started when it's normally run, but that you can change to my reasons for this build when starting it manually.
You could then use a batch (or groovy or ) build step to print the contents of that parameter into the build log. If you do some sort of SCM checkout I'm not sure how close you can get it to print to the line that contains the username that started the job, however you can click on the view parameters button in the job build and see what was in the field quickly without having to parse the logs.
The downside of this is that parameter would have to be added to each job.

How to copy artifacts in a "diamond-join" Jenkins build pipeline?

Is there any documentation/examples on the Copy Artifacts Plugin, namely the "Specified by a build parameter" option?
I'm trying to do a "join-diamond" pipeline such as in this SO question and can't figure out what to put in the Parameter Name option of the "Copy artifacts from another project" build step to get my artifacts copied properly.
All my jobs have a PL_BUILD_NUMBER parameter and I'd like to use it to select which build to copy the artifacts from.
This mailing list post says the parameter must be an XML. So I tried this :
BUILD_SELECTOR=<SpecificBuildSelector><buildNumber>$PL_BUILD_NUMBER</buildNumber></SpecificBuildSelector>
but it did not work. I get this exception in the log:
java.lang.NullPointerException
at java.io.StringReader.<init>(Unknown Source)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1035)
at hudson.plugins.copyartifact.BuildSelectorParameter.getSelectorFromXml(BuildSelectorParameter.java:80)
at hudson.plugins.copyartifact.ParameterizedBuildSelector.getBuild(ParameterizedBuildSelector.java:52)
at hudson.plugins.copyartifact.CopyArtifact.perform(CopyArtifact.java:280)
at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:772)
at hudson.model.Build$BuildExecution.build(Build.java:199)
at hudson.model.Build$BuildExecution.doRun(Build.java:160)
at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:535)
at hudson.model.Run.execute(Run.java:1740)
at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
at hudson.model.ResourceController.execute(ResourceController.java:88)
at hudson.model.Executor.run(Executor.java:233)
What should I put?
There's also the "This build is parametrized --> Build selector for Copy Artifact" that I don't know if I should use it...
Thanks!
You are mixing Specified by a build parameter and Specific build. It's not clear which one you are asking about.
For Specified by a build parameter, you need to configure in two places:
Under "This build is parameterized", select "Build selector for Copy Artifact"
The Name of this parameter is what we will give to Copy Artifact build step later.
From the UI perspective, user will be prompted with a build selector interface (which allows all types of selections: last build, specific build, latest promoted, etc, etc).
On the "Copy Artifact" build step, under "Which build", select "Specified by a build parameter".
It will display another field called "Parameter Name" (with default being BUILD_SELECTOR).
That is the Name of the "Build selector for Copy Artifact" parameter that we created earlier.
Since default is BUILD_SELECTOR, if you called your parameter BUILD_SELECTOR as well, you don't need to change anything.
The value of BUILD_SELECTOR parameter will change greatly based on what you select at parameter screen just before build. You can see its possible values by printing the value of the parameter as a test (echo %BUILD_SELECTOR% on Windows, echo $BUILD_SELECTOR on *nix) and then manually running the build and trying different selectors.
Specifically, the value of:
<SpecificBuildSelector><buildNumber>123</buildNumber></SpecificBuildSelector>
will be used when the user selects Specific build on the parameter screen, and enters value 123
If you need to set this parameter value from outside the job (for example from a script or Parameterized Trigger plugin) you would need to follow this particular structure, depending on the type of the selection you want.
Edit: After re-reading your question and your actual requirement (which is not what the question title is)
In your case, you don't need "Build selector for Copy Artifact" parameter. You just need:
Copy Artifacts build step
Enter Project name to copy from
Under Which build, select Specific build
Under Build number, type $PL_BUILD_NUMBER (which you say you already have in the job)

How to store last value of parameter in parameterized job as a default value for next build in Jenkins?

I have been using Jenkins for a few weeks and I have one small problem. I can't find any plugin or solution for storing the last value of a parameter in a parametrized job as a default value for the next build.
For example:
My parameter takes build version (1.0.0.01) in the first build. In the next build it will be changed to 1.0.0.02, but I want to have a 1.0.0.01 in the default value field as a hint.
Does anybody have a solution or advice?
The Persistent Parameter Plugin is exactly what you are looking for!
You just need to download it from the official Jenkins repository and install it, no need for any additional setup.
Then on your job, you just need to add a "Persistent Parameter" in order to have default values used and saved between builds.
You can add a System groovy build step to your job (or maybe a post build Groovy step) using the Jenkins API to directly modify the project setting the default parameter value.
Here is some code that may be useful to get you started:
import hudson.model.*
paramsDef = build.getParent().getProperty(ParametersDefinitionProperty.class)
if (paramsDef) {
paramsDef.parameterDefinitions.each{ param ->
if (param.name == 'FOO') {
println("Changing parameter ${param.name} default value was '${param.defaultValue}' to '${param.defaultValue} BAR'")
param.defaultValue = "${param.defaultValue} BAR"
}
}
}
Have a look at the class ParameterDefinition in the Jenkins model.
You probably need to modify the default param value based on the current build executing. Some code to get that would look like this:
def thisBuildParamValue = build.buildVariableResolver.resolve('FOO')
The Extended Choice Parameter plugin provides this capability by using default parameter values from a properties file. A default parameter can be selected from a specified property key and this key can be programmatically modified in your current build. I would then use a groovy script in the current build to set the value of the default property key for the next build.
As an example you would have an Extended Choice Parameter whose default value is defined by a properties file version.properties with keys as follows:
versions=1.0.0.02, 1.0.0.01, 1.0.0.00
default.version=1.0.0.02
The parameter definition would include:
Property File=version.properties
Property Key=versions
Default Property File=version.properties
Default Property Key=default.versions
The GUI for your parameter in the next build would show a selection list with 1.0.0.02 selected by default. This feature is also very useful for pipeline builds where you would want the parameters of a downstream build stage to be set by an earlier build.
The only drawback to this approach might be that the parameter UI will be a drop-down selection. You may opt to have a single value in the versions property key so not to confuse your users.
Similar to thiagolr's answer, but for those of you using pipelines! It appears the persistent-parameter-plugin doesn't work for those using pipeline 2.0. But there is a patched version at https://github.com/ashu16815/persistent-parameter-plugin which seems to work for me.
Clone it locally:
git clone https://github.com/ashu16815/persistent-parameter-plugin.git
Build it:
mvn clean install
Install it in Jenkins:
1) Navigate to Jenkins > Manage Jenkins > Manage Plugins
2) Click Advanced tab
3) Scroll down to Upload Plugin
4) Click Choose file and select the persistent-parameter.hpi in the target directory of the maven build above
Now it should persist.

TFS Build Template Nested Arguments

Is it possible to nest TFS build template arguments in one another?
Example (Set via build definition ui):
$(ToolsRoot) = E:\BuildTools
$(MSPECTools) = $(ToolsRoot)\MSpec\
Alternatively, is it possible to use environmental variables.
I have tried both, and neither seemed to work.
I need to find a way of setting the build root dynamically, as it differs on our various build servers.
I suppose you have implemented a topology like the this:
So, you need to control the root for each Agent.If you open the TFS Admin Console > Build configuration in Build Machine #1 you 'll see the Build Controller & Agents A.1 & A.2.If you open TFS Admin Console > Build configuration in Build Machine #2 you 'll see Agents A.3, A.4, A.5 & A.6.
For any given build Agent, if you click on "Properties" you 'll see the "Working Directory" entry, which typically is set to something like $(SystemDrive)\Builds\$(BuildAgentId)\. On runtime this is transformed into something like C:\Builds\55.
For any given build, in the build definition area "Workspaces" this "Working Directory" equals the entry $(SourceDir).
Suppose you have set in Agent A.1 a working directory "C:\A.1\Build" & in Agent A.2 "C:\A.2\Build". In order to get what you need, you have to set in the build definition a mapping to $(SourceDir)\Template

Resources