Continuous Integration: This is the process of keeping code iterations as small as possible, and integrating them into the main codebase. By keeping our changes small, we can more quickly identify and fix new issues introduced into the codebase, as well as more quickly release stable updates. In this example, you will briefly touch on this process by automating unit testing via the MUnit plugin.
Continuous Delivery: This process ties back into continuous integration, and is the concept that our codebase should always remain deliverable. The main codebase should never enter a state which can not be deployed. As part of this process, we automate building and testing, typically via automatic deployment into QA and UAT environments. We will cover this by utilizing the mule-maven-plugin
to automate deployment into our Sandbox environment.
Continuous Deployment: This is typically considered the next and final step in building out an automated pipeline; when a company is utilizing continuous deployment, the release management is tied into an automated process. While we will be taking a simplistic approach, we will touch on this today by creating a protected main branch, which requires that our build and test phases in Sandbox have passed before they can be merged into the master branch, and trigger a deployment to the Production environment.
In this codelab, we will build a MuleSoft API, which you will commit to a new GitHub repository. We will then walk through setting up GitHub Actions to act as our CI platform. Your project will:
mule-maven-plugin
to automate this process, parameterizing various secrets through the GitHub secrets vaultIn order to automate mule application testing and deployment, we first have to have an actual application to work with! We will be using the hello-world example in MuleSoft's exchange.
cicid-with-github
Open an Example from Exchange
in the package explorerProvided by MuleSoft
on the left in the exchange windowOpen
in the top righthello-world
Next, we will create a GitHub repository to house our code, and to run our CI/CD workflow. Everything we will be doing with GitHub can be performed with a free account.
New
to create a new repositoryhello-world-mule-lab
git remote add origin
https://github.com/...
commandcicd-with-github/hello-world
git init
git remote add origin ...
we copied earlier.gitignore
file first. In the hello-world directory, create a file called .gitignore
and paste the following:# ------------------------------------------------------------------------------ #
# Java defaults (https://github.com/github/gitignore/blob/master/Java.gitignore) #
# ------------------------------------------------------------------------------ #
*.class
# Package Files #
*.jar
*.war
*.ear
# ------------------------------------------------------------------------------------------- #
# Eclipse-specific (https://github.com/github/gitignore/blob/master/Global/Eclipse.gitignore) #
# ------------------------------------------------------------------------------------------- #
*.pydevproject
.metadata
bin/**
tmp/**
tmp/**/*
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.project
.classpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
# --------------- #
# Studio-specific #
# --------------- #
target/
.mule/**
.mule/**/*
.DS_Store
velocity.log
src/main/resources/config/*
.gitignore
file, run the command git add .
git commit -m "First commit"
git push -u origin master
hello-world
In order to deploy to CloudHub via an external CI platform, we need to setup some secrets to use as environment variables. For complete documentation on settings you can provide the plugin, see https://docs.mulesoft.com/mule-runtime/4.3/mmp-concept
You will need to add each of the environment variables below to your GitHub Repository's secrets. To add a repository secret:
Add the following secrets to your repo:
When your done, your repository secrets should look like this:
------
Mule applications are, at the heart of things, mavenized java applications. In order to automate the build and deployment process, MuleSoft provides the mule-maven-plugin
. Whether you're hosting your applications on CloudHub, AWS, Azure, GCP, on-prem, a raspberry pi in your closet, etc.. you can use the mule-maven-plugin
to automate your deployments via the Anypoint Control Plane. In this workshop, to keep things as simple as possible, we will be deploying our application to a single .1vcore worker in CloudHub. For information about deployment to other platforms, check the documentation: https://docs.mulesoft.com/mule-runtime/4.3/mmp-concept
Back to Anypoint Studio!
mule.maven.plugin.version
and update the version to the latest version on the release page to ensure we have the latest fixes. At the time of writing this, the latest version is 3.4.2
.<properties>
<munit.version>2.1.2</munit.version>
<mule.maven.plugin.version>3.4.2</mule.maven.plugin.version>
</properties>
cloudHubDeployment
entry to the mule-maven-plugin
entry in the plugins
section of the pom.xml file.<plugins>
<plugin>
<groupId>org.mule.tools.maven</groupId>
<artifactId>mule-maven-plugin</artifactId>
<version>${mule.maven.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<classifier>mule-application</classifier>
<cloudHubDeployment>
<muleVersion>4.3.0</muleVersion>
<username>${env.PLATFORM_USERNAME}</username>
<password>${env.PLATFORM_PASSWORD}</password>
<applicationName>hello-world-SOMETHING-UNIQUE</applicationName>
<environment>Sandbox</environment>
<workers>1</workers>
<workerType>MICRO</workerType>
<objectStoreV2>true</objectStoreV2>
<region>us-east-2</region>
<businessGroupId>${env.BUS_GROUP_ID}</businessGroupId>
</cloudHubDeployment>
</configuration>
</plugin>
...
</plugins>
We're specifying how we want the application deployed to CloudHub. For the complete list of available keys, see https://docs.mulesoft.com/mule-runtime/4.3/deploy-to-cloudhub
When authenticating with maven repositories, maven needs credentials (duh!). Typically, reusable credentials are stored in a shared settings.xml
file located in your m2 folder. You can do the same thing with your CI platform; the majority of CI platforms (GitHub only offers these features for paid accounts) allow you to store shared organization credentials / configurations. As we're using a free GitHub repository, we'll go ahead and add a settings.xml file to our project.
/cicd-with-github/hello-world/.maven/settings.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<settings>
<servers>
<server>
<id>MuleRepository</id>
<username>${env.NEXUS_USERNAME}</username>
<password>${env.NEXUS_PASSWORD}</password>
</server>
<server>
<id>anypoint-exchange-v2</id>
<username>${env.PLATFORM_USERNAME}</username>
<password>${env.PLATFORM_PASSWORD}</password>
</server>
</servers>
<pluginGroups>
<pluginGroup>org.mule.tools</pluginGroup>
</pluginGroups>
<profiles>
<profile>
<id>mule-extra-repos</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>mule-public</id>
<url>https://repository.mulesoft.org/nexus/content/repositories/public</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>mule-public</id>
<url>https://repository.mulesoft.org/nexus/content/repositories/public</url>
</pluginRepository>
</pluginRepositories>
</profile>
<profile>
<id>Mule</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>MuleRepository</id>
<name>MuleRepository</name>
<url>https://repository.mulesoft.org/nexus-ee/content/repositories/releases-ee/</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
</settings>
We're in the home stretch now! Now that we've created our repository, setup our secrets, and configured our application for automated deployment, we need to create the workflow. While we can do this just as easily from our local file system, for this lab we're going to use the GitHub web interface to create the workflow.
Replace the default workflow code with the following:
name: Sandbox - Build and Deploy
on:
push:
branches: master
#normally you wouldn't be deploying master branch pushes to Sandbox,
#but we're keeping things simple! 😁
jobs:
buildAndDeploy:
runs-on: ubuntu-latest
steps:
#first, we need to checkout our mule application's code
- name: Checkout repository
uses: actions/checkout@v2
- name: Build and deploy artifact to sandbox
#run the maven deploy lifecycle. The -B indicated a batch process,
#which reduces the amount of logging the deployment does
run: mvn -B deploy -DmuleDeploy -s .maven/settings.xml
#Pass in the secrets we need for deployment as environment variables
env:
NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }}
NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }}
PLATFORM_USERNAME: ${{ secrets.PLATFORM_USERNAME }}
PLATFORM_PASSWORD: ${{ secrets.PLATFORM_PASSWORD }}
SANDBOX_CLIENT_ID: ${{ secrets.SANDBOX_CLIENT_ID }}
SANDBOX_CLIENT_SECRET: ${{ secrets.SANDBOX_CLIENT_SECRET }}
BUS_GROUP_ID: ${{ secrets.BUS_GROUP_ID }}
src/test/munit
) which will be automatically run:Today we created an automated deployment of a Mule Application using GitHub Actions. While our GitHub workflow and GitHub secrets are unique to GitHub, the concepts used are not. Whether your using Jenkins, Azure Pipelines, CircleCI, GitLab, etc, the process is largely the same:
mule-maven-plugin
This was an extremely simplistic example, but Mule Applications are standard mavenized java applications. This means you can make your CI processes as complicated or simple as your use case dictated, eg: multibranch pipelines, secure vaults trigger builds via webhooks, SonarQube for quality gates, etc.
If you had any issues with this lab, please feel free to open an issue: https://github.com/mikeacjones/hello-world-mule-lab/issues/new