We have a Jenkins server, using jenkins-build-per-branch to sync from git whenever a (php or java) project has a valid pom.xml. We use maven versioning strategy to manage our artefacts, and git-flow as a branching strategy / tool. We also use the jenkins option "Build whenever a SNAPSHOT dependency is built" wherever possible.
The problem we have is when building a -SNAPSHOT artefact - all hell breaks loose and everything wants to build at once. (Building a 'develop' -SNAPSHOT causes all downstream 'feature' AND 'develop' branches to start)
Ideally we would like to find some way that we don't cross pollenate between feature and develop builds when jenkins launches downstream jobs.
Has anyone tried this? Would something like the Conditional+BuildStep+Plugin help? https://wiki.jenkins-ci.org/display/JENKINS/Conditional+BuildStep+Plugin
This is an old question but it's still relevant 6 years later. There is a "threshold" field on the Build whenever a SNAPSHOT dependency is built setting that provides some control over which builds will trigger
From the pipeline-maven-plugin README:
Threshold based on the Maven lifecycle phase reached in the Maven
build of the upstream job (package, install, deploy). By default, only
the maven builds who reach the deploy phase will trigger downstream
builds.
For example, in a scripted pipeline's withMaven() you can set a pipelineGraphPublisher with lifecycleThreshold: 'deploy' like:
withMaven(
maven: MAVEN_VERSION,
jdk: JAVA_VERSION,
mavenOpts: MAVEN_OPTS,
globalMavenSettingsConfig: globals.MAVEN_SETTINGS_ID,
options: [
pipelineGraphPublisher(
lifecycleThreshold: 'deploy',
includeSnapshotVersions: true
)
]) {
sh("mvn ${PHASE}")
}
Then any SNAPSHOT build that executes a lifecycle phase below deploy (e.g. package or install) will not trigger a downstream job. Note that deploy is already the default so this example isn't particularly useful, but it shows how to use the setting and you may want to set this to another phase.
That's part one done, but now you need a way to conditionally execute different Maven lifecycle phases for the builds that you do want to trigger downstream builds vs. the ones that you don't want to trigger downstream builds. We do this based on the branch name so that Pull Request and Release branches don't trigger upstream packages:
/**
* Return the correct Maven goal for the current branch
*
* Because the pipelineGraphPublisher's lifecycleThreshold in the withMaven() call above is set to 'deploy', pipelines
* that run the 'install' goal will not trigger downstream jobs; this helps us minimize superfluous Jenkins builds:
*
* https://github.com/jenkinsci/pipeline-maven-plugin/blob/master/README.adoc#trigger-downstream-pipeline-when-a-snapshot-is-built
*/
String getGoalForCurrentBranch() {
if ( env.BRANCH_NAME ==~ /(^PR-(\d+)$)|(^releases\/v.*)/ ) {
echo("Pull Request or release branch detected! Executing Maven 'install' goal rather than 'deploy' goal to avoid triggering downstream Jenkins jobs")
return 'install'
}
return 'deploy'
}
You can then call this getGoalForCurrentBranch() method wherever you're executing mvn to determine which lifecycle phase is executed:
withMaven(
...
sh("mvn ${getGoalForCurrentBranch()}")
)
Most branches will execute mvn deploy and will trigger a downstream Jenkins job, but Pull Request branches will execute mvn install and will not trigger a downstream job.
The caveat to this is that you may have other things that depend on certain lifecycle phases. In the above example, Pull Request branch artifacts won't get deployed to your artifact repository (e.g. Nexus). In our case this is actually the desired behavior but you'll need to determine what's acceptable for you and tweak your threshold accordingly.
In the dependent projects you can disable the "Build whenever a SNAPSHOT dependency is built" hook via
if (branchName.indexOf("mule4auto") >= 0) {
println "for mule4auto do not build when mulestac is build";
// for mule4auto do not build when mulestac is build, wait for
// mule4auto-converter project has run (commited something).
} else {
tempPipelineTriggers += [
snapshotDependencies()
];
}
println "triggers: tempPipelineTriggers=${tempPipelineTriggers}";
Additionally you may need to disable the fingerprint for the specific branches which should not be build (mule4auto in our case):
// see https://github.com/jenkinsci/pipeline-maven-plugin/blob/master/README.adoc
def tempMavenOptions = [];
// disable Archiving (fingerprinting should still work)
tempMavenOptions += artifactsPublisher(disabled: true);
if (branchName.indexOf("mule4auto") >= 0) {
println "Disable fingerprint for mule4auto to prevent jobs building when mulestac4 SNAPSHOT is build";
tempMavenOptions += dependenciesFingerprintPublisher(disabled: true);
tempMavenOptions += pipelineGraphPublisher(disabled: true);
}
// see https://plugins.jenkins.io/pipeline-maven
withMaven(
// Maven installation declared in the Jenkins "Global Tool Configuration"
maven: toolMaven,
jdk: toolJdkToBeUsed,
options: tempMavenOptions
) {
println "JAVA_HOME ${JAVA_HOME}";
println "MAVEN_HOME ${MAVEN_HOME}";
....
})
(both in destination pipeline)
I do not see an option like "Build whenever an upstream dependency is built" in our Jenkin's jobs. It's called "Build whenever a SNAPSHOT dependency is built" here (Jenkins v1.592 with its latest plugins). Is that what you mean?
There's also this last sentence in its inline help: "If this behavior is problematic, uncheck this option." :-)
I don't know whether Conditional BuildStep Plugin would help in this case. We use it but not to achieve such.
Depending on how long your jobs run I'd suggest to:
use the Build whenever ... in conjunction with Advanced Project Options → Quiet period if the jobs don't run long (let's say a few minutes)
deactivate the build-whenever-all-and-everywhere as suggested and use Post-build Actions → Build other projects or Trigger parameterized build on other project to establish a real up-/downstream build flow if your jobs run longer
Related
Wanted to accommodate scheduled build starting 12AM every 3 hrs till 3PM on every weekday(mon-fri). It should be triggered build only if anything is committed into github repository.
Please provide the exact code as few code is working for multi-branch but not for above schedule.
Sorry what do you mean by the scheduled "build"?
Do you want the Multi-Branch to check for more branches on your given interval?
If so you can only do it by "Scan Multibranch Pipeline with defaults Triggers"
Do you want to issue a build on the branch when there is change on it?
Noted that the option in
the mult-branch folder > "Scan Multibranch Pipeline with defaults Now" and get all current branches > status > the jobs > View Configuration
is read only.
So, to alter the option, from https://issues.jenkins-ci.org/browse/JENKINS-33900?focusedCommentId=326181&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-326181
, I think you should use the Jenkinsfile to do theSCM for every job.
So, for all jobs you need to configure for SCM poll,
include a Jenkinsfile on Git for each of them (Don't forget to install the pipeline-model-definition plugin and all its dependent plugins):
pipeline {
triggers {
pollSCM('H 0-15/3 * * H(1-5)')
}
agent any
stages{
stage('Build') {
steps {
echo 'Building.. or whatever'
}
}
}
}
That should do the job, at least it works for me``
Hope it helps
We have a build chain setup using teamcity 2017.2.
It looks like the following
A -> B
A:
generates a version number using gitversion
has a VCS root defined
uses gitversion command line to define a version number
B:
sets its version number to the same as A using a dependency proprty
has a snapshot dependency on A with the following settings
Do not run new build if there is a suitable one
Only use successful builds from suitable ones
On failed dependency: cancel build
On failed to start/canceled dependency: make build failed to start
When I make a commit and run B it will trigger A and then B will run, teamcity will show the pending change of the commit that I just made.
However if B fails for whatever reason (and A succeeds) when I rerun B it will rerun for the same commit but the pending changes will be empty. The same also happens if I just want to rerun a previous successful build of B.
The reason this matters is that I'm using the teamcity api to pull a list of changes for a build and passing that off to my deployment tool.
I've tried enabling "Show changes for snapshot dependencies in B" but that did not seem to have an effect
I have a canary build (BuildA) in TeamCity (10.0.2) that builds master, develop, and all feature/* branches when commits occur.
I'd like to create another build (BuildB) that takes a small set of artifacts from BuildA, and runs FxCop on the files. And I want BuildB to have a Finish Build trigger, so that when BuildA completes for any branch, BuildB will get the artifacts from that branches build and run.
There seem to be some hurdles to setting this up:
When I open the "Edit Artifact Dependency" box, I have to specify a "Build branch", which is a logical branch name, not a wildcard or pattern match. So I don't know how to setup an artifact dependency on all builds coming out of BuildA.
The "Finish Build Trigger" has a branch filter, which looks like I can put "+:*" in to catch all branches, but how does that line up with the "Artifact Dependency" branch name value?
Why dont you just trigger BuildB, which in turn builds BuildA instead.
Then you can get artifacts from that specific build easily.
I have a TeamCity project which includes 4 configurations and the build chain needs to look something like this:
Build which can be triggered manually and executes .bat scripts that compiles a bunch of artifacts for the Deploy and TEST to pick up.
Deploy and TEST – Region 1 has an artifact dependency on the Build config.
Deploy and TEST – Region 2 has an artifact dependency on the Build config.
Since I wanted both Region1 and Region2 to run in parallel as soon as Build is successful, I added a Snapshot dependency to Deploy and TEST – Region 1 and Deploy and TEST – Region 2 on Build config
Now I need to configure the Test Status config just to report the failure/success of the previous config (Deploy and TEST configs).
How can this be achieved? Also, do I need to tweak my set up anywhere for the use case I am trying to achieve?
The setup looks correct. To get the build chain status in Test Status configuration, you need to add snapshot dependencies on Deploy and TEST – Region 1 and Deploy and TEST – Region 2 configurations. If any build from the chain fails, Test Status build will also fail with status: "Snapshot dependencies failed: ... < build configurations names >"
If you add these snapshot dependencies and run Test Status via UI, the whole build chain will be added to the queue. Also you can configure one VCS trigger in Test Status build configuration with option "Trigger on changes in snapshot dependencies". With this options enabled, the whole build chain will be triggered even if changes are detected in dependencies, not in the resulting build.
This article can be helpful.
I have to build: Internet & Common. I would like that when I click on "Run" for the "Internet" build that the "Common" build executes first.
Is it possible ? I saw artifact dependencies, but I don't need any data to be copied, I just want to build "Common" before "Internet" every time a build for "Internet" is requested.
Thanks
If they're using the same VCS root, then configuring a snapshot dependency between the "Internet" build configuration and the "Common" build configuration will enable you to do that; this basically ensures that all the dependencies are built from the same snapshot of the VCS.
If you must have the "Common" build execute regardless of its current state, then uncheck the default 'Do not run new build if there is a suitable one' option. This will ensure "Common" is run every time you hit Run on "Internet".