I am trying to setup Jenkins. I am using the docker image BlueOcean. I am trying to create a Jenkins pipeline using a Job-DSL. When I create the pipeline myself, and run it, it works. But when I run the pipeline created by the Job-DSL, it fails because of maven.
I looked on internet, but I couldn't find a solution proper to my case.
He is the Jenkinsfile
pipeline {
agent {
docker {
image 'maven:3-alpine'
args '-v /root/.m2:/root/.m2'
}
}
stages {
stage('Build') {
steps {
sh 'mvn -B -DskipTests clean package'
}
}
}
and this is the job-DSL
job('PROJ-unit-tests') {
scm {
git('git://github.com/Jouda-Hidri/Transistics.git') { node ->
node / gitConfigName('DSL User')
node / gitConfigEmail('hxxxa#gmail.com')
}
}
triggers {
scm('*/15 * * * *')
}
steps {
maven('-e clean test')
}
}
Related
I've linked up to the 'github webhook' now.
Now all we have to do is build and deploy to 'ec2'.
Is it a place to create and test files to be uploaded to ec2 in the build phase? If yes, I wonder what the code would look like.
And I wonder how to utilize dir in build .
I'm curious about the code how to write it in the deployment stage
Below is the code I have written so far
pipeline {
agent any
environment {
SLACK_CHANNEL = '#'
}
stages {
stage('Start') {
steps {
slackSend (channel: SLACK_CHANNEL, color: '#FFFFOO', message: "STARTED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
}
}
stage('Checkout') {
steps {
git branch: 'feature/signin.up',
credentialsId: 'github_access_token',
url: 'https://github.com/###/westudy.git'
}
}
stage('Build') {
steps {
{
}
}
}
stage('Deploy') {
steps {
}
}
I have a Jenkins pipeline which is running fine but it depends upon JDK and maven installed tools. There were few instances in the past that these JDK and maven tool's name was changed(e.g. Maven 3.6.2 -> Maven 3.6.3 and it results in my pipeline failure.
stage ("build") {
withMaven(jdk: 'Java SE 8u221', maven: 'Maven 3.6.3', tempBinDir: '') {
sh 'mvn clean package jib:dockerBuild verify'
}
}
I want my pipeline to be independent of what tools are installed. So I rewrite my Jenkins pipeline like below to provide docker image of maven(since JDK is bundled with it)
pipeline {
agent {
docker {
image 'maven:3-alpine'
args '-v /root/.m2:/root/.m2'
}
}
stages {
stage('Checkout') {
steps {
git branch: "master", url: "repo url", credentialsId: 'id'
}
}
stage ("build") {
steps {
sh 'mvn clean package jib:dockerBuild verify'
}
}
}
}
But now I am getting an error Failed to execute goal com.google.cloud.tools:jib-maven-plugin:2.3.0:dockerBuild (default-cli) : Build to Docker daemon failed, perhaps you should make sure Docker is installed and you have correct privileges to run it
It seems that docker daemon is not visible after I provided a maven docker image.
I did solve this by adding docker agent inside of my maven docker image
pipeline {
agent any
stages {
stage('build Dockerfile') {
steps {
sh '''echo "FROM maven:3-alpine
RUN apk add --update docker openrc
RUN rc-update add docker boot" >/var/lib/jenkins/workspace/Dockerfile'''
}
}
stage('run Dockerfile') {
agent{
dockerfile {
filename '/var/lib/jenkins/workspace/Dockerfile'
args '--user root -v $HOME/.m2:/root/.m2 -v /var/run/docker.sock:/var/run/docker.sock'
}
}
steps {
sh 'docker version'
sh 'mvn -version'
sh 'java -version'
}
}
}
}
When working with jenkins 2 (declarative) pipelines and maven I always have a problem with how to organize things within the pipeline to make it resusable and flexible.
On the one side I would like to seperate the pipepline into logical stages like:
pipeline
{
stages
{
stage('Clean') {}
stage('Build') {}
stage('Test') {}
stage('Sanity check') {}
stage('Documentation') {}
stage('Deploy - Test') {}
stage('Selenium tests') {}
stage('Deploy - Production') {}
stage('Deliver') {}
}
}
On the other hand I have maven which runs with
mvn clean deploy site
Simply I could split up maven to
mvn clean
mvn deploy
mvn site
But the 'deploy' includes all lifecycle phases from
validate
compile
test
package
verify
install
deploy
So I saw a lot of pipline examples which do things like
sh 'mvn clean compile'
and
sh 'mvn test'
which results in repeating the validate and compile step a second time and waste "time/resources" in this way.
This could be resolved with doing a
sh 'mvn surefire:test'
instead of running the whole lifecycle again.
So my question is - which is the best way to get a good balance between the jenkins pipline stages and the maven lifecycle?
For me I see two ways:
Split up the maven lifecycles to as much pipeline stages as possible - which will result in better jenkins user feedback (see which stage fails etc.)
Let maven do everything and use the jenkins pipeline only to work with the results of maven (i.e. analyzing unit test results etc.)
Or did I missunderstand something in the CI/CD practice?
Two month later I think I have a well balanced Jenkins pipeline script that is not complete, but works stable on windows and linux. It avoids pitfalls of other examples I have seen.
Jenkinsfile
pipeline
{
agent any
tools
{
maven 'Maven3'
jdk 'JDK8'
}
options
{
buildDiscarder(logRotator(numToKeepStr: '4'))
skipStagesAfterUnstable()
disableConcurrentBuilds()
}
triggers
{
// MINUTE HOUR DOM MONTH DOW
pollSCM('H 6-18/4 * * 1-5')
}
stages
{
stage('Clean')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode clean'
}
else
{
bat 'mvn --batch-mode clean'
}
}
}
}
stage('Build')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode compile'
}
else
{
bat 'mvn --batch-mode compile'
}
}
}
}
stage('UnitTests')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode resources:testResources compiler:testCompile surefire:test'
}
else
{
bat 'mvn --batch-mode resources:testResources compiler:testCompile surefire:test'
}
}
}
post
{
always
{
junit testResults: 'target/surefire-reports/*.xml'
}
}
}
stage('Sanity check')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode checkstyle:checkstyle pmd:pmd pmd:cpd com.github.spotbugs:spotbugs-maven-plugin:spotbugs'
}
else
{
bat 'mvn --batch-mode checkstyle:checkstyle pmd:pmd pmd:cpd com.github.spotbugs:spotbugs-maven-plugin:spotbugs'
}
}
}
}
stage('Packaging')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode jar:jar'
}
else
{
bat 'mvn --batch-mode jar:jar'
}
}
}
}
stage('install local')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode jar:jar source:jar install:install'
}
else
{
bat 'mvn --batch-mode jar:jar source:jar install:install' // maven-jar-plugin falseCreation default is false, so no doubled jar construction here, but required for maven-install-plugin internal data
}
}
}
}
stage('Documentation')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode site'
}
else
{
bat 'mvn --batch-mode site'
}
}
}
post
{
always
{
publishHTML(target: [reportName: 'Site', reportDir: 'target/site', reportFiles: 'index.html', keepAll: false])
}
}
}
stage('Deploy test')
{
steps
{
script
{
if (isUnix())
{
// todo
}
else
{
bat returnStatus: true, script: 'sc stop Tomcat8'
sleep(time:30, unit:"SECONDS")
bat returnStatus: true, script: 'C:\\scripts\\clean.bat'
bat returnStatus: true, script: 'robocopy "target" "C:\\Program Files\\Apache Software Foundation\\Tomcat 9.0\\webapps" Test.war'
bat 'sc start Tomcat8'
sleep(time:30, unit:"SECONDS")
}
}
}
}
stage('Integration tests')
{
steps
{
script
{
if (isUnix())
{
sh 'mvn --batch-mode failsafe:integration-test failsafe:verify'
}
else
{
bat 'mvn --batch-mode failsafe:integration-test failsafe:verify'
}
}
}
}
}
}
Hopefully this is interesting for other developers outside there.
I will update this here when I significantly improve it over time.
For those who also wish to see a maven pom along with a Jenkinsfile please have a look at my small example project at github: TemplateEngine
I think there is no right answer, but the following example worked for us.
stage('Build and Unit Test') {
mvn clean deploy -> with unit tests, without integration tests, deploy local
deploy local:
You can define in a maven profile the distributionManagement like:
<distributionManagement>
<repository>
<id>localFile</id>
<url>file:target/repository/</url>
</repository>
<snapshotRepository>
<id>localFile</id>
<url>file:target/repository/</url>
</snapshotRepository>
</distributionManagement>
}
stage('Pre Integration Tests') {
The binaries are now in target/repository.
From there you can use the binaries as you like.
Copy them to a server, deploy them on an application server, etc.
}
stage('Integration Tests') {
maven failsafe:integration-test failsafe:verify
Already all tests are compiled, just execute them and verify the result.
}
stage('Deploy to Binary Repository (Nexus, Artifactory, etc)') {
Now if everything is ok, finally upload the Binaries.
For that we use wagon-maven-plugin
So from target/repository the files are uploaded to the Binary Repository.
}
So to wrap this up:
Fail fast. If a unit test has errors -> fail the build.
Only build once. Use the same binaries for test, deployment/integration test,
upload to repository, etc.
With that the stages are logical units,
which gives you enough feedback where to look for errors.
I am new to Jenkins and I have created the Maven+TestNG project in eclipse I which I have executed the sample test case to print hello world from POM.xml,which is running fine. I have pushed the project in GIT as well Now I need to execute this from Jenkins using Pipeline script for CI/CD.
I have created below Pipleline script in Jenkins pipeline tab but I am getting error which executing the script. Can you please guide me or provide me the tutorial link where I can get Jenkins pipeline example.
The script is as follow:
node {
def mvnHome
stage('Preparation') { // for display purposes
// Get some code from a GitHub repository
git 'https://github.com/jitsolution19/RestAssured_Framework.git'
// Get the Maven tool.
// ** NOTE: This 'M3' Maven tool must be configured
// ** in the global configuration.
mvnHome = tool 'Maven'
}
stage('Build') {
// Run the maven build
if (isUnix()) {
sh "'${mvnHome}/bin/mvn' -Dmaven.test.failure.ignore clean package"
} else {
bat(/"${mvnHome}\bin\mvn" -Dmaven.test.failure.ignore clean package/)
}
}
stage('Test') {
//Perform test
echo 'Execute the script'
if (isUnix()) {
sh "'${mvnHome}/bin/mvn' -Dmaven.test.failure.ignore test"
} else {
bat(/"${mvnHome}\bin\mvn" -Dmaven.test.failure.ignore test/)
}
}
stage('Results') {
junit '**/target/surefire-reports/TEST-*.xml'
archive 'target/*.jar'
}
}
I'm using Jenkins in a multi-modular Maven project and I have three stages in my pipeline: build, test and deploy. I want to be able to run all unit tests during test stage and, when there are test failures, deploy stage should be skipped.
For now, I managed to find a workaround (which works as I want it to), but I had to explicitly approve usage of some methods, which are marked by Jenkins as vurnelabilities.
I am wondering if there is any clearer way to achieve my goals?
import hudson.tasks.test.AbstractTestResultAction
pipeline {
agent {
docker {
image 'maven:3-jdk-8-alpine'
args '--name maven3 -v /root/.m2:/root/.m2'
}
}
stages {
stage('Build') {
steps {
sh 'mvn clean install -DskipTests'
}
}
stage('Test') {
steps {
sh 'mvn test --fail-never'
}
post {
always {
junit '**/target/surefire-reports/*.xml'
}
}
}
stage('Deploy') {
steps {
script {
def AbstractTestResultAction testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class)
if (testResultAction == null) {
error("Could not read test results")
}
def numberOfFailedTests = testResultAction.failCount
testResultAction = null
if (numberOfFailedTests == null || numberOfFailedTests != 0) {
error("Did not deploy. Number of failed tests: " + numberOfFailedTests)
}
sh 'mvn deploy -DskipTests'
}
}
}
}
}
In your test stage you execute: mvn test --fail-never
Now even if you have test failures maven will return with an exit code 0.
Jenkins is checking the exit code. if it is 0 it will continue with the next command.
so get rid of --fail-never