- ENG
- Services
- Unser Serviceportfolio
Wir erwecken Ihre digitale Produktvision zum Leben: Vom testbaren Prototypen bis zur fertigen Softwarelösung.
- Kooperationsmodelle
Kooperationsmodelle passend zu Ihren Bedürfnissen: Komplette Nearshoring Teams, deutschsprachige Experten vor Ort mit Nearshoring-Teams oder gemischte Teams mit unseren Partnern.
- Arbeitsweise
Durch enge Zusammenarbeit mit Ihrem Unternehmen schaffen wir maßgeschneiderte Lösungen, die auf Ihre Anforderungen abgestimmt sind und zu nachhaltigen Ergebnissen führen.
- Unser Serviceportfolio
- Über uns
- Wer wir sind
Wir sind ein Full-Service Nearshoring-Anbieter für digitale Softwareprodukte, ein perfekter Partner mit deutschsprachigen Experten vor Ort, Ihre Business-Anforderungen stets im Blick
- Unser Team
Das ProductDock Team ist mit modernen Technologien und Tools vertraut und setzt seit 15 Jahren zusammen mit namhaften Firmen erfolgreiche Projekte um.
- Unsere Standorte
Wir sind ProductDock, ein Full-Service Nearshoring-Anbieter für Softwareprodukte mit Hauptsitz in Berlin und Entwicklungs-Hubs in Lissabon, Novi Sad, Banja Luka und Doboj.
- Wozu Nearshoring
Wir kombinieren Nearshore- und Fachwissen vor Ort, um Sie während Ihrer gesamten digitalen Produktreise optimal zu unterstützen. Lassen Sie uns Ihr Business gemeinsam auf das nächste digitale Level anheben.
- Wer wir sind
- Unser Leistungen
- Karriere
- Arbeiten bei ProductDock
Unser Fokus liegt auf der Förderung von Teamarbeit, Kreativität und Empowerment innerhalb unseres Teams von über 120 talentierten Tech-Experten.
- Offene Stellen
Begeistert es dich, an spannenden Projekten mitzuwirken und zu sehen, wie dein Einsatz zu erfolgreichen Ergebnissen führt? Dann bist du bei uns richtig.
- Info Guide für Kandidaten
Wie suchen wir unsere Crew-Mitglieder aus? Wir sehen dich als Teil unserer Crew und erklären gerne unseren Auswahlprozess.
- Arbeiten bei ProductDock
- Newsroom
- News
Folgen Sie unseren neuesten Updates und Veröffentlichungen, damit Sie stets über die aktuellsten Entwicklungen von ProductDock informiert sind.
- Events
Vertiefen Sie Ihr Wissen, indem Sie sich mit Gleichgesinnten vernetzen und an unseren nächsten Veranstaltungen Erfahrungen mit Experten austauschen.
- News
- Blog
- Kontakt
25. Sep. 2024 •5 minutes read
Automating Mule deployments: From Dev to Prod with GitHub Actions
Danijel Dragičević
MuleSoft Developer
In this blog post, we will explore the automation of deployment of Mule applications to both CloudHub 1.0 and CloudHub 2.0 using GitHub Actions. We’ll walk through how to configure our Mule application for deployment on both versions of CloudHub, streamlining the process from build to deployment.
Throughout this guide, we’ll demonstrate how to deploy to different environments, which will be particularly helpful for teams transitioning between these two services. CloudHub 2.0 offers improved scalability, flexibility, and resource consumption. Also, in the future, it will be the main focus of MuleSoft when it comes to updates and security patches.
Configuring environments on the Anypoint Platform
To begin, set up the required environments on the Anypoint Platform. We can do this either through the platform’s UI’s Access Management section or the Anypoint CLI. While both methods are effective, the CLI allows for automation, faster execution, and greater scalability when managing multiple environments. The instructions for installing the Anypoint CLI are in the following documentation: Anypoint CLI Installation.
Once the Anypoint CLI is installed, authenticate using your platform credentials and create the necessary environments. If we’re on a free account, all environments must be of type “Sandbox,” while “Production” environments require a paid subscription.
# Authenticate:
$ anypoint-cli-v4 conf username <username>
$ anypoint-cli-v4 conf password <password>
$ anypoint-cli-v4 conf organization <organization>
# Create environments:
$ anypoint-cli-v4 account:environment:create dev --type sandbox
$ anypoint-cli-v4 account:environment:create qa --type sandbox
$ anypoint-cli-v4 account:environment:create prod --type sandbox
Preparing the Mule application for deployment
With our environments set up, the next step is to configure the Mule application. In this example, we’re using a basic application with a /ping endpoint, which returns key identifiers such as groupId, artifactId, and version.
The API contract is defined in a RAML file, a widely used specification in the MuleSoft ecosystem. The OpenAPI Specification is also supported and can be utilized if needed.
#%RAML 1.0
title: mule-github-actions-api
version: v1.0.0
/ping:
get:
displayName: Get application info
description: Shows application identifiers, fetched from the pom file
responses:
200:
body:
application/json:
type: !include dataTypes/ping-response-data-type.raml
example: !include examples/ping-response-example.raml
We configure pom.xml and property placeholders to populate these values dynamically during the build process.
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>config/common.yaml</include>
</includes>
</resource>
</resources>
This configuration instructs Maven to substitute values defined in the config/common.yaml with the values from the pom.xml.
Values in the config file can be accessed with the DataWeave using the p(propertyName: String) function:
%dw 2.0
output application/json skipNullOn="everywhere"
---
{
groupId: p('application.groupId'),
artifactId: p('application.artifactId'),
version: p('application.version')
}
For deploying to CloudHub 1.0 and CloudHub 2.0, the mule-maven-plugin is essential. We configure separate profiles in pom.xml to handle deployments to either CloudHub version. These profiles allow us to switch between deployment environments by specifying the relevant profile in the GitHub Action script.
Below is the plugin configuration for CloudHub 1.0 deployments:
<profiles>
<profile>
<id>cloudHubDeployment</id>
<build>
<plugins>
<plugin>
<groupId>org.mule.tools.maven</groupId>
<artifactId>mule-maven-plugin</artifactId>
<version>${mule.maven.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<cloudHubDeployment>
<uri>https://anypoint.mulesoft.com</uri>
<muleVersion>${app.runtime}</muleVersion>
<username>${anypoint.username}</username>
<password>${anypoint.password}</password>
<applicationName>
${project.artifactId}-${anypoint.environment}
</applicationName>
<environment>${anypoint.environment}</environment>
<releaseChannel>EDGE</releaseChannel>
<javaVersion>17</javaVersion>
<workerType>MICRO</workerType>
<region>us-east-2</region>
<workers>1</workers>
<objectStoreV2>true</objectStoreV2>
</cloudHubDeployment>
<classifier>mule-application</classifier>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
And here is the configuration for CloudHub 2.0 deployments:
<profiles>
<profile>
<id>cloudhub2Deployment</id>
<build>
<plugins>
<plugin>
<groupId>org.mule.tools.maven</groupId>
<artifactId>mule-maven-plugin</artifactId>
<version>${mule.maven.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<cloudhub2Deployment>
<uri>https://anypoint.mulesoft.com</uri>
<muleVersion>${app.runtime}</muleVersion>
<username>${anypoint.username}</username>
<password>${anypoint.password}</password>
<applicationName>
${project.artifactId}-${anypoint.environment}
</applicationName>
<environment>${anypoint.environment}</environment>
<releaseChannel>EDGE</releaseChannel>
<javaVersion>17</javaVersion>
<replicas>1</replicas>
<target>Cloudhub-US-East-2</target>
<vCores>0.1</vCores>
<provider>MC</provider>
<deploymentSettings>
<generateDefaultPublicUrl>true</generateDefaultPublicUrl>
</deploymentSettings>
</cloudhub2Deployment>
<classifier>mule-application</classifier>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
The configuration varies slightly between CloudHub 1.0 and 2.0, especially in terms of region, worker types, and other resource allocations. Refer to the MuleSoft Deployment Documentation for further details on each parameter.
Versioning is critical when deploying to CloudHub 2.0, as each deployment creates a new asset in Exchange. To ensure the application is ready for release, use the versions-maven-plugin to remove SNAPSHOT from the version. After deployment to production, increment the version for the next development cycle.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.8.1</version>
</plugin>
Setting up a GitHub repository
Next, we have to create a GitHub repository to store our source code and automate the deployment process. We can use the GitHub CLI to create and manage the repository or use the GitHub web interface for a more visual experience.
Once this tool is installed, we can authenticate and verify our GitHub account using:
# Authenticate:
$ gh auth login
# Verify:
$ gh auth status
github.com
✓ Logged in to github.com account danijeldragicevic (keyring)
- Active account: true
- Git operations protocol: https
- Token: gho_************************************
- Token scopes: 'gist', 'read:org', 'repo', 'workflow'
Ensure that our authentication token includes the repo scope, as we’ll need this token to interact with our repository through GitHub Actions.
To create a new repository for our application, run:
$ gh repo create mule-github-actions-app --public
✓ Created repository danijeldragicevic/mule-github-actions-app on GitHub
https://github.com/danijeldragicevic/mule-github-actions-app
It’s important to note that our repository must be public for free GitHub accounts to use GitHub Actions.
Set up a develop branch and protect it by requiring pull requests for all changes. This approach ensures that code merges into the branch only after review and approval.
$ cd ~/AnypointCodeBuilder/workspace/mule-github-actions-app
$ git init
$ git add .
$ git commit -m "first commit"
$ git remote add origin https://github.com/danijeldragicevic/mule-github-actions-app.git
$ git branch -M develop
$ git push -u origin develop
Create branch protection rule:
curl -X PUT \
-u danijeldragicevic:gToken \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/danijeldragicevic/mule-github-actions-app/branches/develop/protection \
-d '{
"required_pull_request_reviews": {
"required_approving_review_count": 1
},
"restrictions": {
"users": ["danijeldragicevic"]
},
"enforce_admins": true,
"required_status_checks": null
}'
This setup ensures that code can only be merged into this branch with at least one approval from a team member. We can adjust the number of required approvals based on the size of the team. The restrictions also apply to administrators, enforcing that all changes must go through pull requests rather than direct commits.
Finally, we have to create secrets in our GitHub repository for authentication against the Anypoint Platform and GitHub itself. GitHub Actions will use these secrets to securely handle authentication and authorization during the deployment process.
$ gh secret set ANYPOINT_PLATFORM_USERNAME -b"username" --repo danijeldragicevic/mule-github-actions-app
$ gh secret set ANYPOINT_PLATFORM_PASSWORD -b"password" --repo danijeldragicevic/mule-github-actions-app
$ gh secret set G_TOKEN -b"gToken" --repo danijeldragicevic/mule-github-actions-app
Automating deployments with GitHub Actions
With the repository and secrets configured, it’s time to set up GitHub Actions. First, we have to create a .github/workflows/main.yaml file at the root level of our project, which is a default location where GitHub looks for workflow definitions. When changes are pushed to the repository, GitHub checks this directory for .yaml files that define workflows to trigger actions. Our example uses the workflow_dispatch trigger, which allows for manual deployments to specific environments (dev, qa, prod).
on:
workflow_dispatch:
inputs:
environment:
description: 'Environment to deploy to'
type: choice
required: true
options:
- dev
- qa
- prod
Permissions are granted for GitHub Actions to commit to the repository when needed.
permissions:
contents: write
The workflow includes build, deploy, and verify jobs. The build job has an additional step to create a release if deployment is intended for the QA environment: removing SNAPSHOT from the application version and publishing the release.
- name: Create release
if: ${{ github.event.inputs.environment == 'qa' }}
run: |
mvn versions:set -DremoveSnapshot versions:commit
version=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
git add pom.xml
git commit -m "Create release $version"
git push https://x-access-token:$githubToken@github.com/${{ github.repository }}.git develop
git tag $version
git push https://x-access-token:$githubToken@github.com/${{ github.repository }}.git $version
shell: bash
env:
githubToken: ${{ secrets.G_TOKEN }}
Although including a test job is common, Mule applications require a commercial license to access and download the MUnit library. While MUnit tests can be run locally (as the libs are included with Anypoint Studio or Anypoint Code Builder installation for free), this isn’t possible on a bare Linux instance, such as those used in GitHub Actions, without configuring the access to the Mule Soft’s Nexus repository.
The deploy job sets the deployment type and directs the deployment to CloudHub 1.0 or CloudHub 2.0, depending on the selected environment.
- name: Set deployment type
uses: ./.github/actions/deployment-type-config
with:
targetEnvironment: ${{ github.event.inputs.environment }}
- name: Deploy to CH1.0
if: env.deploymentType == 'cloudHubDeployment'
uses: ./.github/actions/deploy-to-ch1-config
with:
username: ${{ secrets.ANYPOINT_PLATFORM_USERNAME }}
password: ${{ secrets.ANYPOINT_PLATFORM_PASSWORD }}
targetEnvironment: ${{ github.event.inputs.environment }}
- name: Deploy to CH2.0
if: env.deploymentType == 'cloudhub2Deployment'
uses: ./.github/actions/deploy-to-ch2-config
with:
username: ${{ secrets.ANYPOINT_PLATFORM_USERNAME }}
password: ${{ secrets.ANYPOINT_PLATFORM_PASSWORD }}
targetEnvironment: ${{ github.event.inputs.environment }}
Our action script that deploys the application has two steps. The first step is to publish the built application to Anypoint Exchange, MuleSoft’s central repository for sharing and discovering reusable assets such as APIs and connectors.
- name: Publish to Exchange
run: |
mvn deploy --settings .maven/settings.xml -DskipMunitTests \
-Danypoint.username="$username" \
-Danypoint.password="$password" \
shell: bash
env:
username: ${{ inputs.username }}
password: ${{ inputs.password }}
Once the application is published to Exchange, the next step is to deploy it to the target environment (in this case, CloudHub 2.0):
- name: Deploy the application
run: |
artifactName=$(ls *.jar | head -1)
mvn deploy --settings .maven/settings.xml -DskipMunitTests -DmuleDeploy -Pcloudhub2Deployment\
-Dmule.artifact=$artifactName \
-Danypoint.username="$username" \
-Danypoint.password="$password" \
-Danypoint.environment="$targetEnvironment"
shell: bash
env:
username: ${{ inputs.username }}
password: ${{ inputs.password }}
targetEnvironment: ${{ inputs.targetEnvironment }}
Verifying deployments and preparing for the next cycle
After deployment, the verify job ensures the service is running and responding by pinging the appropriate instance of the application.
- name: Verify deployment
run: |
if [[ "$targetEnvironment" == "dev" ]]; then
curl -f http://mule-github-actions-app-dev.us-e2.cloudhub.io/api/ping || exit 1
elif [[ "$targetEnvironment" == "qa" ]]; then
curl -f http://mule-github-actions-app-qa.us-e2.cloudhub.io/api/ping || exit 1
elif [[ "$targetEnvironment" == "prod" ]]; then
curl -f https://mule-github-actions-app-prod-qefjd6.5sc6y6-3.usa-e2.cloudhub.io/api/ping || exit 1
else
echo "Skipping deployment verification"
exit 0
fi
shell: bash
env:
targetEnvironment: ${{ github.event.inputs.environment }}
If successful, the application version is incremented, and the branch is prepared for the next development cycle, ensuring that the project is ready for further work.
- name: Set next development cycle
if: ${{ github.event.inputs.environment == 'prod' }}
run: |
mvn versions:set -DnextSnapshot versions:commit
version=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
git checkout develop || git checkout -b develop
git add pom.xml
git commit -m "Increase version to $version for next development cycle"
git push https://x-access-token:$githubToken@github.com/${{ github.repository }}.git develop
shell: bash
env:
githubToken: ${{ secrets.G_TOKEN }}
Conclusion
By integrating GitHub Actions with the Anypoint Platform, we can automate the entire deployment lifecycle of Mule applications — from building and testing to deploying and verifying. This approach reduces manual intervention, improves reliability, and ensures a consistent deployment process across all environments. As we continue to scale our deployments, leveraging tools like GitHub Actions and Anypoint CLI will become even more valuable, saving time and reducing errors.
To see the complete source code and this deployment process in action, visit the GitHub repository. Feel free to explore, fork, or contribute to the project!
Tags:
Danijel Dragičević
MuleSoft DeveloperDanijel is a MuleSoft developer, content creator, and mentor. He has been part of our family since April 2014. Over the past few years, he has focused on developing integrations using Java and MuleSoft’s Anypoint Platform, following the API-led connectivity strategy.