I am working on Multibranch pipelines in Jenkins.We use SVN as repository and maven for build. I have placed the jenkins file in each branch.
In jenkins file,
After initial checkout, I wrote a function to iterate over the workspace and add the folder names to the list that needs to be build ahead.
In Build stage, I used the list size to iterate using for loop, navigate to the directory and run maven command inside the folder where the POM file is located.
Issue i am trying to solve is, when there is changes in one of the projects under branch, it runs build for all projects due to above configuration. I am looking for some guidance to run build only for changes using pipelines.
Code Snippet -
for ( int i = 0; i < size; i++) {
dir(dirsl[i]) {
try {
withMaven(jdk: 'Java7', maven: 'localmaven') {
bat "mvn clean package"
}
}
catch (e) {
println e
}
}
Also not sure if this is the right way to build using Maven.
Related
I need to run SonarQube for Go code using Jenkins. Unfortunately, there is little information regarding this task.
I have found that the "sonar-project.properties" file should be created, for example:
sonar.projectKey=com.company.projectkey1
sonar.projectName=My Project Name
sonar.sources=.
sonar.exclusions=**/*_test.go,**/vendor/**
sonar.tests=.
sonar.test.inclusions=**/*_test.go
sonar.test.exclusions=**/vendor/**
But how to configure a Jenkins pipeline correctly? I found the following example, but I'm not sure if this is what I need
node {
stage('SCM') {
git '<my_path>.git'
}
stage('SonarQube analysis') {
def scannerHome = tool 'SonarScanner 4.0';
withSonarQubeEnv('My SonarQube Server') {
sh "${scannerHome}/bin/sonar-scanner"
}
}
}
Yes, that is correct.
In your Jenkins pipeline you just need to run sonnar-scanner - that is no different from other languages (see https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-jenkins/). Go language plugin comes with SonarQube so no need to install anything. Scanner will then pickup project configuration from sonar-project.properties in your project root and perform the analysis.
Your sonar-project.properties file seems like a copied example from SonarQube for Go page - you might want to do some adjustments depending on project layout (e.g. add sonar.inclusions=**/.*go). SonarQube should detect files are in Go automatically but you can also add sonar.language=go to that file to force it.
You don't mention if you run SonarQube locally or in cluster mode - but there should be little or no difference (probably adding server url and login to sonar-project.properties in case of cluster installation).
Note that go needs to be installed on scanner machines.
I'm trying to work out how to get Gradle to delete published artifacts from the local maven repository. I figured it should be as easy as setting up a delete task, but this doesn't seem to work...
task cleanMavenLocal(type: Delete) {
delete '~/.m2/repository/example'
}
If it's even possible from Gradle, any ideas how?
You can't do this with Gradle's Delete task since files passed to delete are interpreted relative to the current project directory (see Documentation).
However, Gradle build files are executable code. An ad-hoc task should do the trick.
task cleanMavenLocal {
doLast {
new File('~/.m2/repository/example').deleteDir()
}
}
I decided to port all my Jenkins job over to Jenkins-pipeline. I did a simple test with the following Jenkinsfiles in to the UI:
pipeline {
agent any
stages {
stage('Clone Repo') {
steps {
git changelog: false, credentialsId: 'xxxxxxxxxx ', url: 'https://github.com/xxxxx/xxx.git'
}
}
}
}
This works fine. I created a repo in github and checked in this Jenkinsfile. I changes Jenkins to Pipeline script from SCM and it is finding the Jenkinsfile but falling over with the error message below. I know I've missed something basic, but reading all the documentations; I couldn't work it out. Any help is appreciated.
Here's the Jenkins job. There's a jenkinsfile the ndh_poc.
In the Script Path field, specify the location (and name) of your Jenkinsfile. This location is the one that Jenkins checks out/clones the repository containing your Jenkinsfile, which should match that of the repository’s file structure.
In your case if your jenkinsfile name is Jenkinsfile and is present within the directory ndh_poc at the root of your repository then the Script Path should be ndh_poc/Jenkinsfile
I have a maven Jenkins job, that is part of a multijob. Τhis used to run always on windows nodes, but currently we have created some linux nodes, too, that we want to utilize.
The thing is that inside the job,at build step you have to choose:
This maven version applies when building the job. For example the maven version that applied here,, is linked to the path were maven is installed for windows. So this path, is applicable only for windows nodes, therefore, the job cannot be run by a linux node. Is there a workaround for this?
thanks!
You can achieve it using Jenkins pipeline. Just set two maven config in Jenkins > global tool configuration. One for windows maven and other for linux.
node {
def mvnHome
stage('Build') {
// Run the maven build
if (isUnix()) {
mvnHome = tool 'Maven-linux'
sh "'${mvnHome}/bin/mvn' clean package "
} else {
mvnHome = tool 'Maven-windows'
bat(/"${mvnHome}\bin\mvn" clean package /)
}
}
Another way to do it is to use Jenkins Conditional build step plugin.
Create freestyle job
In Build Step select conditional step single or multiple.
In the Run? you can select execute shell
In Builder select invoke-top-level-maven-target and select maven-linux in maven version. Then you can configure maven goals and other steps
In Build Step on again select conditional step single or multiple.
In the Run? you can select execute windows batch command
In Builder select invoke-top-level-maven-target and select maven-window in maven version. Then you can configure maven goals and other steps
Configure your linux slaves:
Manage jenkins > manage nodes > %node > configure > Node properties
Then specify mvn and java located on your slave and fill in Tool ocations
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