MuleSoft CI CD with Maven

CI/CD (Continuous Integration / Continuous Delivery) automates the process of building, testing, and deploying MuleSoft applications. Every code commit triggers an automated pipeline that runs tests, packages the application, and deploys it to the target environment without manual intervention. Maven is the standard build tool for MuleSoft projects and integrates with all major CI/CD platforms.

Why CI/CD for MuleSoft

Manual deployments are slow, error-prone, and inconsistent. A developer who runs ten deployments will make slightly different configuration choices each time. CI/CD ensures every deployment follows exactly the same steps, with the same quality gates, every time.

Manual vs CI/CD Deployment Comparison

Manual Deployment:
  Developer finishes code → manually runs tests → packages JAR →
  logs into Runtime Manager → uploads JAR → sets properties →
  (sometimes forgets a property) → deployment fails in production
  Time: 30–60 minutes per deployment
  Error rate: high

CI/CD Pipeline:
  Developer pushes code to Git →
  Pipeline triggers automatically →
  [Build → Test → Package → Deploy to Dev → Deploy to Staging → Deploy to Prod]
  Time: 10–15 minutes, zero manual steps
  Error rate: near zero (properties managed in pipeline secrets)

MuleSoft Maven Plugin

The Mule Maven Plugin provides Maven goals for deploying to CloudHub, Runtime Fabric, and on-premises runtimes. Add it to your project's pom.xml to enable deployment from the command line and from CI/CD pipelines.

Mule Maven Plugin Configuration in pom.xml

<plugin>
  <groupId>org.mule.tools.maven</groupId>
  <artifactId>mule-maven-plugin</artifactId>
  <version>3.8.3</version>
  <extensions>true</extensions>
  <configuration>
    <classifier>mule-application</classifier>

    <!-- CloudHub deployment configuration -->
    <cloudHubDeployment>
      <uri>https://anypoint.mulesoft.com</uri>
      <muleVersion>4.6.0</muleVersion>
      <username>${anypoint.username}</username>
      <password>${anypoint.password}</password>
      <applicationName>orders-api-${deploy.env}</applicationName>
      <environment>${deploy.env}</environment>
      <region>us-east-1</region>
      <workers>1</workers>
      <workerType>MICRO</workerType>
      <properties>
        <db.host>${db.host}</db.host>
        <db.password>${db.password}</db.password>
        <env>${deploy.env}</env>
      </properties>
    </cloudHubDeployment>
  </configuration>
</plugin>

Maven Build Lifecycle for MuleSoft

Standard Maven Commands

mvn clean
  → Deletes the target/ folder (compiled artifacts)

mvn compile
  → Compiles the Mule XML and Java code

mvn test
  → Runs all MUnit test cases
  → Generates test report in target/surefire-reports/
  → Generates coverage report in target/site/munit/coverage/

mvn package
  → Packages the application as a JAR file
  → Output: target/orders-api-1.0.0-mule-application.jar

mvn deploy -DmuleDeploy
  → Packages and deploys to the configured target
  → Uses the cloudHubDeployment config in pom.xml

CI/CD Pipeline with GitHub Actions

GitHub Actions is a popular CI/CD platform. The workflow file lives in .github/workflows/deploy.yml in your repository.

Complete GitHub Actions Pipeline

# .github/workflows/deploy.yml
name: MuleSoft CI/CD Pipeline

on:
  push:
    branches: [main, develop]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Java 11
        uses: actions/setup-java@v3
        with:
          java-version: '11'

      - name: Cache Maven dependencies
        uses: actions/cache@v3
        with:
          path: ~/.m2
          key: maven-${{ hashFiles('pom.xml') }}

      - name: Run MUnit Tests
        run: mvn clean test
        env:
          ANYPOINT_USERNAME: ${{ secrets.ANYPOINT_USERNAME }}
          ANYPOINT_PASSWORD: ${{ secrets.ANYPOINT_PASSWORD }}

      - name: Check Test Coverage
        run: mvn verify -Dmunit.coverage.runCoverage=true
                        -Dmunit.coverage.failBuild=true
                        -Dmunit.coverage.flowCoverageThreshold=80

  deploy-to-dev:
    needs: build-and-test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/develop'
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with: { java-version: '11' }

      - name: Deploy to Development
        run: |
          mvn deploy -DmuleDeploy \
            -Ddeploy.env=Development \
            -Danypoint.username=${{ secrets.ANYPOINT_USERNAME }} \
            -Danypoint.password=${{ secrets.ANYPOINT_PASSWORD }} \
            -Ddb.host=${{ secrets.DEV_DB_HOST }} \
            -Ddb.password=${{ secrets.DEV_DB_PASSWORD }}

  deploy-to-production:
    needs: build-and-test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    environment: production   # requires manual approval in GitHub
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with: { java-version: '11' }

      - name: Deploy to Production
        run: |
          mvn deploy -DmuleDeploy \
            -Ddeploy.env=Production \
            -Danypoint.username=${{ secrets.ANYPOINT_USERNAME }} \
            -Danypoint.password=${{ secrets.ANYPOINT_PASSWORD }} \
            -Ddb.host=${{ secrets.PROD_DB_HOST }} \
            -Ddb.password=${{ secrets.PROD_DB_PASSWORD }}

CI/CD with Jenkins

Jenkins is common in enterprises. The pipeline is defined in a Jenkinsfile at the root of your repository.

// Jenkinsfile
pipeline {
  agent any
  environment {
    ANYPOINT_CREDS = credentials('anypoint-platform-credentials')
  }
  stages {
    stage('Build') {
      steps {
        sh 'mvn clean compile'
      }
    }
    stage('Test') {
      steps {
        sh 'mvn test'
        junit 'target/surefire-reports/*.xml'
      }
    }
    stage('Package') {
      steps {
        sh 'mvn package -DskipTests'
      }
    }
    stage('Deploy to Staging') {
      steps {
        sh """
          mvn deploy -DmuleDeploy \
            -Ddeploy.env=Staging \
            -Danypoint.username=${ANYPOINT_CREDS_USR} \
            -Danypoint.password=${ANYPOINT_CREDS_PSW}
        """
      }
    }
    stage('Deploy to Production') {
      when { branch 'main' }
      input { message 'Deploy to Production?' }
      steps {
        sh """
          mvn deploy -DmuleDeploy \
            -Ddeploy.env=Production \
            -Danypoint.username=${ANYPOINT_CREDS_USR} \
            -Danypoint.password=${ANYPOINT_CREDS_PSW}
        """
      }
    }
  }
}

Versioning Strategy

Use semantic versioning in your pom.xml. Automate version bumping in the pipeline so every build produces a uniquely versioned artifact stored in Anypoint Exchange.

pom.xml version management:
  Feature branch builds: 1.2.0-SNAPSHOT
  Release tag (v1.2.0):  1.2.0
  
Maven command to set release version:
  mvn versions:set -DnewVersion=1.2.0

Maven command to bump to next snapshot:
  mvn versions:set -DnewVersion=1.3.0-SNAPSHOT

Leave a Comment

Your email address will not be published. Required fields are marked *