Header Ads Widget

Responsive Advertisement

Master in CI/CD pipeline using Maven with java

1)      CI/CD pipeline using Maven


Creating a CI/CD pipeline using Java, Maven, Git, Jenkins, Jenkinsfile, SonarQube, Nexus, and Groovy script involves integrating these tools for a seamless build, test, code quality analysis, and deployment process. Here's a step-by-step guide:


1. Set Up the Tools

Ø  Git: Ensure your code is stored in a Git repository (GitHub, GitLab, or Bitbucket).

Ø  Maven: Configure your project with a pom.xml for build and dependency management.

Ø  Jenkins: Install Jenkins and required plugins:

ü  Git Plugin

ü  Maven Integration

ü  Pipeline Plugin

ü  SonarQube Scanner

ü  Nexus Artifact Uploader

Ø  SonarQube: Install and configure SonarQube for static code analysis.

Ø  Nexus: Install Nexus for artifact storage and hosting.

Ø  Groovy: Use Groovy for custom Jenkins pipelines.


2. Jenkins Pipeline Configuration

  1. Connect Jenkins with Git:

Ø  Add your Git repository credentials in Jenkins.

Ø  In the job configuration, link your Git repository.

  1. Install SonarQube Scanner:

Ø  Configure SonarQube in Jenkins under Manage Jenkins > Configure System.

Ø  Add SonarQube server details and authentication tokens.

  1. Configure Nexus:

Ø  Set up a repository in Nexus for storing artifacts.

Ø  Generate a user token for uploading artifacts.

  1. Create a Jenkinsfile: Define your CI/CD pipeline using a Jenkinsfile. Save it in the root directory of your Git repository.

3. Sample Jenkinsfile

This file defines the CI/CD stages: clone, build, test, code analysis, and deploy.

groovy

pipeline {

    agent any

 

    tools {

        maven 'Maven_3.8.6' // Replace with your Maven version

        jdk 'JDK_11'        // Replace with your Java version

    }

 

    environment {

        SONAR_TOKEN = credentials('sonarqube-token') // Store SonarQube token in Jenkins credentials

        NEXUS_URL = 'http://nexus.example.com/repository/releases/' // Replace with your Nexus URL

    }

 

    stages {

        stage('Clone Repository') {

            steps {

                git branch: 'main', url: 'https://github.com/your-repo/project.git'

            }

        }

 

        stage('Build') {

            steps {

                sh 'mvn clean install'

            }

        }

 

        stage('Unit Tests') {

            steps {

                sh 'mvn test'

            }

        }

 

        stage('Code Quality Analysis') {

            steps {

                withSonarQubeEnv('SonarQube') {

                    sh 'mvn sonar:sonar -Dsonar.projectKey=your_project_key -Dsonar.login=$SONAR_TOKEN'

                }

            }

        }

 

        stage('Upload to Nexus') {

            steps {

                script {

                    def artifactPath = "target/your-artifact.jar"

                    nexusArtifactUploader(

                        nexusVersion: 'nexus3',

                        protocol: 'http',

                        nexusUrl: 'nexus.example.com',

                        groupId: 'com.example',

                        artifactId: 'your-artifact',

                        version: '1.0.0',

                        repository: 'releases',

                        file: artifactPath

                    )

                }

            }

        }

    }

 

    post {

        success {

            echo 'Pipeline completed successfully!'

        }

        failure {

            echo 'Pipeline failed. Please check the logs.'

        }

    }

}

 


4. Explanation of Jenkinsfile Stages

  1. Clone Repository:

Ø  Clones the code from the Git repository.

  1. Build:

Ø  Uses Maven to compile and package the application.

  1. Unit Tests:

Ø  Executes tests to validate functionality.

  1. Code Quality Analysis:

Ø  Runs static analysis using SonarQube.

  1. Upload to Nexus:

Ø  Uploads the Maven artifact (e.g., JAR or WAR file) to Nexus.

 


2)      CI/CD pipeline using Maven to extract maven project version name


 

To make the version dynamic in your CI/CD pipeline, you can extract it from your Maven project's pom.xml file or pass it as a parameter in the Jenkins job. Here's how you can do it:


Option 1: Extract Version from pom.xml

  1. Use Maven to read the version from pom.xml:

groovy

stage('Determine Version') {

    steps {

        script {

            def pom = readMavenPom file: 'pom.xml'

            env.APP_VERSION = pom.version

            echo "Project version is: ${env.APP_VERSION}"

        }

    }

}

 

  1. Update the Upload to Nexus stage to use the extracted version:

groovy

stage('Upload to Nexus') {

    steps {

        script {

            def artifactPath = "target/your-artifact.jar"

            nexusArtifactUploader(

                nexusVersion: 'nexus3',

                protocol: 'http',

                nexusUrl: 'nexus.example.com',

                groupId: 'com.example',

                artifactId: 'your-artifact',

                version: env.APP_VERSION,

                repository: 'releases',

                file: artifactPath

            )

        }

    }

}

 


Option 2: Pass Version as a Jenkins Parameter

  1. Add a parameter to the Jenkins job:
    • Go to the job configuration.
    • Check "This project is parameterized."
    • Add a "String Parameter" named VERSION.
  2. Access the parameter in the pipeline:

groovy

pipeline {

    parameters {

        string(name: 'VERSION', defaultValue: '1.0.0', description: 'Application version')

    }

 

    stages {

        stage('Upload to Nexus') {

            steps {

                script {

                    def artifactPath = "target/your-artifact.jar"

                    nexusArtifactUploader(

                        nexusVersion: 'nexus3',

                        protocol: 'http',

                        nexusUrl: 'nexus.example.com',

                        groupId: 'com.example',

                        artifactId: 'your-artifact',

                        version: params.VERSION,

                        repository: 'releases',

                        file: artifactPath

                    )

                }

            }

        }

    }

}

 


Option 3: Generate Version Dynamically

You can generate the version dynamically based on a timestamp or Git commit hash.

groovy

stage('Determine Version') {

    steps {

        script {

            def timestamp = new Date().format("yyyyMMddHHmmss")

            env.APP_VERSION = "1.0.0-${timestamp}"

            echo "Generated version is: ${env.APP_VERSION}"

        }

    }

}

 

Use env.APP_VERSION wherever the version is required.


Final Pipeline with Dynamic Version

Here's a complete example combining Option 1 and Option 2:

groovy

pipeline {

    agent any

 

    parameters {

        string(name: 'VERSION', defaultValue: '', description: 'Specify application version (leave blank to use pom.xml version)')

    }

 

    stages {

        stage('Determine Version') {

            steps {

                script {

                    if (params.VERSION) {

                        env.APP_VERSION = params.VERSION

                    } else {

                        def pom = readMavenPom file: 'pom.xml'

                        env.APP_VERSION = pom.version

                    }

                    echo "Using application version: ${env.APP_VERSION}"

                }

            }

        }

 

        stage('Upload to Nexus') {

            steps {

                script {

                    def artifactPath = "target/your-artifact.jar"

                    nexusArtifactUploader(

                        nexusVersion: 'nexus3',

                        protocol: 'http',

                        nexusUrl: 'nexus.example.com',

                        groupId: 'com.example',

                        artifactId: 'your-artifact',

                        version: env.APP_VERSION,

                        repository: 'releases',

                        file: artifactPath

                    )

                }

            }

        }

    }

}

 

This approach ensures flexibility while maintaining consistency across builds.

 

3)      CI/CD pipeline using Maven to extract version, groupId and artifactId


To make the version, groupId, and artifactId dynamic in your CI/CD pipeline, you can extract these values from the Maven pom.xml file using Jenkins' Pipeline Utility Steps Plugin. Here's how you can achieve this:


Extract Dynamic Values from pom.xml

Use the readMavenPom step to read the pom.xml and extract groupId, artifactId, and version.


Pipeline Example

groovy

pipeline {

    agent any

 

    tools {

        maven 'Maven_3.8.6' // Specify your Maven installation

        jdk 'JDK_11'        // Specify your JDK installation

    }

 

    environment {

        NEXUS_URL = 'http://nexus.example.com/repository/releases/' // Replace with your Nexus URL

    }

 

    stages {

        stage('Extract Metadata') {

            steps {

                script {

                    // Read pom.xml

                    def pom = readMavenPom file: 'pom.xml'

                    // Extract values

                    env.GROUP_ID = pom.groupId

                    env.ARTIFACT_ID = pom.artifactId

                    env.VERSION = pom.version

 

                    echo "Group ID: ${env.GROUP_ID}"

                    echo "Artifact ID: ${env.ARTIFACT_ID}"

                    echo "Version: ${env.VERSION}"

                }

            }

        }

 

        stage('Build') {

            steps {

                sh 'mvn clean install'

            }

        }

 

        stage('Upload to Nexus') {

            steps {

                script {

                    def artifactPath = "target/${env.ARTIFACT_ID}-${env.VERSION}.jar"

                    nexusArtifactUploader(

                        nexusVersion: 'nexus3',

                        protocol: 'http',

                        nexusUrl: 'nexus.example.com',

                        groupId: env.GROUP_ID,

                        artifactId: env.ARTIFACT_ID,

                        version: env.VERSION,

                        repository: 'releases',

                        file: artifactPath

                    )

                }

            }

        }

    }

 

    post {

        success {

            echo 'Pipeline completed successfully!'

        }

        failure {

            echo 'Pipeline failed. Please check the logs.'

        }

    }

}

 


Key Steps Explained

  1. Extract Metadata:
    1. Use readMavenPom to read pom.xml.
    2. Extract the groupId, artifactId, and version dynamically.
  2. Dynamic Artifact Path:
    1. Use ${env.ARTIFACT_ID}-${env.VERSION}.jar to construct the artifact path dynamically based on extracted values.
  3. Nexus Upload:
    1. Pass groupId, artifactId, and version dynamically to nexusArtifactUploader.

Prerequisites

  1. Jenkins Plugins:
    1. Install the Pipeline Utility Steps Plugin for readMavenPom.
    2. Install the Nexus Artifact Uploader Plugin.
  2. Maven Project:
    1. Ensure your pom.xml has valid groupId, artifactId, and version fields.
  3. Jenkins Credentials:
    1. Add Nexus credentials in Jenkins for secure uploads.

 

4)      CI/CD pipeline using Maven with Veracode scan setup


 


Adding Veracode Scan to the CI/CD pipeline further enhances security by performing advanced application security testing. Below is a detailed CI/CD pipeline setup integrating Maven, Git, Jenkins, Jenkinsfile, SonarQube, Security Scan (OWASP Dependency-Check), Veracode Scan, Nexus, and Groovy Script.


Step 1: Prerequisites

  1. Jenkins: Install and configure Jenkins with these plugins:

Ø  Git Plugin

Ø  Maven Integration Plugin

Ø  Pipeline Plugin

Ø  SonarQube Scanner Plugin

Ø  OWASP Dependency-Check Plugin

Ø  Veracode Jenkins Plugin

Ø  Nexus Artifact Uploader Plugin

  1. SonarQube: Set up SonarQube server and generate an API token.
  2. Veracode: Configure Veracode credentials and API keys.
  3. Maven Project:

Ø  Ensure pom.xml is configured with required dependencies.

  1. Nexus: Install and configure Nexus as a repository for artifacts.

Step 2: Design the CI/CD Pipeline

The pipeline includes these stages:

  1. Clone Repository: Fetch code from Git.
  2. Build: Compile the application using Maven.
  3. Unit Tests: Execute tests with Maven.
  4. Static Code Analysis: Analyze code quality using SonarQube.
  5. Security Scans:

Ø  OWASP Dependency-Check

Ø  Veracode Scan

  1. Upload Artifact: Publish the build artifact to Nexus.

Step 3: Jenkinsfile with Veracode Integration

groovy

pipeline {

    agent any

 

    tools {

        maven 'Maven_3.8.6' // Specify Maven version

        jdk 'JDK_11'        // Specify JDK version

    }

 

    environment {

        SONAR_TOKEN = credentials('sonarqube-token') // SonarQube token from Jenkins credentials

        VERACODE_CREDENTIALS = credentials('veracode-api-key') // Veracode credentials (ID and Key)

        NEXUS_URL = 'http://nexus.example.com/repository/releases/' // Nexus URL

    }

 

    stages {

        stage('Clone Repository') {

            steps {

                git branch: 'main', url: 'https://github.com/your-repo/project.git'

            }

        }

 

        stage('Build') {

            steps {

                sh 'mvn clean install'

            }

        }

 

        stage('Unit Tests') {

            steps {

                sh 'mvn test'

            }

        }

 

        stage('Code Quality Analysis') {

            steps {

                withSonarQubeEnv('SonarQube') {

                    sh 'mvn sonar:sonar -Dsonar.projectKey=your_project_key -Dsonar.login=$SONAR_TOKEN'

                }

            }

        }

 

        stage('Security Scan - Dependency Check') {

            steps {

                script {

                    sh 'mvn org.owasp:dependency-check-maven:check'

                }

                archiveArtifacts artifacts: '**/dependency-check-report.html', allowEmptyArchive: true

                echo "Dependency-Check completed. Report archived."

            }

        }

 

        stage('Security Scan - Veracode') {

            steps {

                script {

                    veracodeApplicationAnalysis(

                        credentialsId: 'veracode-api-key', // Veracode credentials in Jenkins

                        appName: 'Your Application',      // Replace with your Veracode app name

                        sandboxName: 'Default',          // Optional: Specify sandbox

                        fileNamePattern: '**/*.jar',     // Artifacts to scan

                        createProfile: false,

                        scanType: 'STATIC',

                        waitForCompletion: true

                    )

                }

                echo "Veracode scan completed."

            }

        }

 

        stage('Upload to Nexus') {

            steps {

                script {

                    def pom = readMavenPom file: 'pom.xml'

                    def artifactPath = "target/${pom.artifactId}-${pom.version}.jar"

                    nexusArtifactUploader(

                        nexusVersion: 'nexus3',

                        protocol: 'http',

                        nexusUrl: 'nexus.example.com',

                        groupId: pom.groupId,

                        artifactId: pom.artifactId,

                        version: pom.version,

                        repository: 'releases',

                        file: artifactPath

                    )

                }

            }

        }

    }

 

    post {

        success {

            echo 'Pipeline completed successfully!'

        }

        failure {

            echo 'Pipeline failed. Check the logs for details.'

        }

    }

}

 


Step 4: Explanation of Stages

  1. Clone Repository:

Ø  Fetch the latest code from Git.

  1. Build:

Ø  Build and package the application using Maven.

  1. Unit Tests:

Ø  Run unit tests using Maven.

  1. Code Quality Analysis:

Ø  Perform static code analysis using SonarQube.

  1. Security Scan - Dependency Check:

Ø  Scan for known vulnerabilities using OWASP Dependency-Check.

  1. Security Scan - Veracode:

Ø  Upload the built artifact (e.g., JAR) to Veracode for a comprehensive security scan.

  1. Upload to Nexus:

Ø  Publish the artifact dynamically to the Nexus repository.


Step 5: Prerequisites for Veracode Integration

  1. Configure Veracode API Key:

Ø  Add Veracode API credentials (ID and Key) to Jenkins:

ü  Go to Manage Jenkins > Credentials > System > Global credentials.

ü  Add Veracode credentials.

  1. Verify Veracode Plugin:

Ø  Install the Veracode Jenkins Plugin.

Ø  Configure the Veracode credentials in Jenkins.

  1. Define Veracode Application:

Ø  Ensure the application exists in Veracode for the scan.


Step 6: Running the Pipeline

  1. Commit the Jenkinsfile to your Git repository.
  2. Create a new Jenkins Pipeline job:

Ø  Link it to your Git repository and branch.

  1. Trigger the pipeline and monitor its execution in Jenkins.

Key Benefits of This Pipeline

Ø  Automation: Fully automates build, test, code quality, and security scans.

Ø  Dynamic Artifact Handling: Automatically fetches groupId, artifactId, and version from pom.xml.

Ø  Comprehensive Security: Leverages OWASP Dependency-Check and Veracode for enhanced security.

Ø  Artifact Management: Stores artifacts in Nexus for easy distribution.

 

5)      CI/CD pipeline using Maven with dependencyManagement  


 

Understanding <dependencyManagement> in Maven

The <dependencyManagement> section in Maven is a powerful feature that allows you to centrally manage dependency versions and scope declarations for a project and its submodules (in a multi-module project). It helps maintain consistency and avoid version conflicts across multiple modules.


Key Points

  1. Centralized Version Control:
    • Versions for dependencies are specified in the <dependencyManagement> section.
    • Child modules can inherit these versions without specifying them explicitly.
  2. Dependency Declaration:
    • Dependencies listed in <dependencyManagement> are not included in the build unless they are explicitly added in a module’s <dependencies> section.
  3. Scope Inheritance:
    • Dependency scope (e.g., compile, test, provided) can also be managed and inherited.
  4. Overrides:
    • It allows overriding transitive dependencies' versions to ensure consistent versions across the project.

Structure of <dependencyManagement>

xml

<dependencyManagement>

    <dependencies>

        <dependency>

            <groupId>com.example</groupId>

            <artifactId>my-library</artifactId>

            <version>1.0.0</version> <!-- Version managed here -->

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-core</artifactId>

            <version>5.3.10</version>

            <scope>compile</scope>

        </dependency>

    </dependencies>

</dependencyManagement>

 


How It Works

  1. Parent pom.xml:
    • Place the <dependencyManagement> section in the parent POM file.

xml

<project>

    <groupId>com.example</groupId>

    <artifactId>parent-project</artifactId>

    <version>1.0.0</version>

    <packaging>pom</packaging>

    <modules>

        <module>module-a</module>

        <module>module-b</module>

    </modules>

 

    <dependencyManagement>

        <dependencies>

            <dependency>

                <groupId>com.google.guava</groupId>

                <artifactId>guava</artifactId>

                <version>30.1.1-jre</version>

            </dependency>

        </dependencies>

    </dependencyManagement>

</project>

 

  1. Child Module POM (module-a):
    • The child module does not need to specify the version for guava. It inherits the version from the parent POM.

xml

<project>

    <parent>

        <groupId>com.example</groupId>

        <artifactId>parent-project</artifactId>

        <version>1.0.0</version>

    </parent>

 

    <dependencies>

        <dependency>

            <groupId>com.google.guava</groupId>

            <artifactId>guava</artifactId> <!-- Version inherited -->

        </dependency>

    </dependencies>

</project>

 


Benefits of <dependencyManagement>

  1. Consistency:
    • Ensures all modules use the same version of a dependency.
  2. Simplified Child POMs:
    • Reduces boilerplate by allowing child modules to omit the version.
  3. Conflict Resolution:
    • Overrides transitive dependency versions to prevent mismatches.
  4. Centralized Updates:
    • Changing a version in the parent POM updates it for all child modules.

Difference Between <dependencyManagement> and <dependencies>

Feature

<dependencyManagement>

<dependencies>

Purpose

Define dependency versions and scope for inheritance.

Include specific dependencies in the build.

Automatic Inclusion

No, child modules must explicitly declare the dependency.

Yes, dependencies are automatically included.

Use in Parent POM

Typically used in parent POMs for centralized version control.

Directly adds dependencies for the current project.

Scope Inheritance

Yes, can define default scopes for dependencies.

No, scope is only applicable to the current project.

 


Example with Transitive Dependency Version Conflict

Problem:

Suppose two dependencies pull different versions of the same transitive dependency, causing a conflict:

xml

<dependencies>

    <dependency>

        <groupId>org.springframework</groupId>

        <artifactId>spring-core</artifactId>

        <version>5.3.10</version>

    </dependency>

    <dependency>

        <groupId>org.springframework</groupId>

        <artifactId>spring-context</artifactId>

        <version>5.3.9</version>

    </dependency>

</dependencies>

 

Solution:

Use <dependencyManagement> to specify a unified version:

xml

<dependencyManagement>

    <dependencies>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-core</artifactId>

            <version>5.3.10</version>

        </dependency>

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-context</artifactId>

            <version>5.3.10</version>

        </dependency>

    </dependencies>

</dependencyManagement>

 


Best Practices

  1. Use <dependencyManagement> in parent POMs for multi-module projects.
  2. Define only versions and scopes; avoid adding unnecessary dependencies.
  3. Regularly update the managed versions to include the latest security patches.
  4. Use dependency management to resolve transitive dependency conflicts.

CI/CD pipeline using Maven
CI/CD pipeline using Maven

For Tools information, visit:

Ø  Auto-Update Batch File with Latest JAR & Start App Automatically

Ø  Connectingto IBM WebSphere MQ in Java

Ø  How to create maven project

Ø  VisualVM monitoring like jconsole

Ø  Stylus studio convert edifact message

Ø  JConsole Monitoring for Java Standalone or Web application project

Ø  Apache Cluster router load balancer

Ø  Generate a Token in Sonatype Nexus & Use It in Maven & Jenkins

Ø  CI/CD Pipeline in Jenkins: Staging & Production Artifact Flow in java app

 



  









Post a Comment

0 Comments