Build Artifacts with Azure DevOps and deploy to Anypoint Platform CloudHub

  • July 24, 2020

Use an HTTP listener component to create a basic Mule application; the response is a simple text message.

Set the path to “/test” and the response payload to “Azure DevOps POC test application.”

Azure DevOps POC test application

Azure DevOps POC test application

Create an Azure repository and sync application code

An Azure repository holds the source code managed by version control. A single project can have multiple repositories and each repository can have multiple branches depending on your requirements.

  • Create an Azure DevOps account
  • Create a new empty repository for the project
  • Using Git bash commands:
    • Clone the repository on your local drive
    • Add the Mule application — created above
    • Push the code

Here’s a sample project “tjagani” under which is a repository named “azure-devops-poc” that consists of a Mule project named “azure-devops-poc”:

Azure DevOps account

Azure build pipeline [YAML method]

  • Edit the Mule project’s pom.xml file to add the following snippet to repositories and distributionManagement tags — a screenshot follows the code

<repository>
    <id>tjagani</id>
    <url>https://pkgs.dev.azure.com/tjagani/_packaging/tjagani/maven/v1</url>
    <releases>
        <enabled>true</enabled>
    </releases>
    <snapshots>
        <enabled>true</enabled>
    </snapshots>
</repository>
<plugin>
    <groupId>org.mule.tools.maven</groupId>
    <artifactId>mule-maven-plugin</artifactId>
    <version>3.1.6</version>
    <extensions>true</extensions>
    <configuration>
        <cloudHubDeployment>
            <uri>https://anypoint.mulesoft.com/</uri>
            <muleVersion>4.3.0</muleVersion>
            <username>Anypoimt Platform Username</username>
            <password>Anypoimt Platform Password</password>
            <businessGroup>${businessGroup}</businessGroup>
            <workers>${workers}</workers>
            <workerType>${workerType}</workerType>
            <region>us-west-1</region>
            <environment>${environment}</environment>
            <applicationName>${applicationName}</applicationName>
            <properties>
                <anypoint.platform.client_id>${anypoint.platform.client_id}</anypoint.platform.client_id>
                <anypoint.platform.client_secret>${anypoint.platform.client_secret}</anypoint.platform.client_secret>
                <anypoint.platform.config.analytics.agent.enabled>true</anypoint.platform.config.analytics.agent.enabled>
            </properties>
        </cloudHubDeployment>
    </configuration>
</plugin>

Azure build pipeline

  • Go to the Pipelines menu and create a new pipeline with following configurations:
    • Click Create New Pipeline
    • Select the Azure Repos Git option
    • Select the repository created
    • Select Maven
    • Click Save and Run

Variable groups

To reuse the variables across all the pipelines:

  • Create variable groups
  • Reference the variables inside the pipeline

Variable groups

Variable groups

To use the variable group in the pipeline, include the following variables:

- group: PipelineCachingVariables

Once this is included, you can access the variables with $(variableName)

Create Azure artifacts

You can create Azure artifacts in the Maven task by using the option goals ‘deploy’ as shown below.

Create Azure artifacts

Triggers

You can use triggers to run a pipeline automatically to perform continuous integration (CI). Use the following configuration in the YAML file to trigger the pipeline whenever the source code located under a certain location and under a certain branch changes.

branches:
  include:
    - dev
paths:
  include:
    - 'demo-domain/*'

Tag sources

You can tag the sources once the build pipeline is completed by following these steps:

  • Go to the specific build pipeline and click the Edit option
  • Click the three dots and select the Triggers option
  • Click the YAML tab and select Get sources

Tag sources

Now, you can tag the sources on certain conditions (Never, On success and always) and configure the tag format as per standards.

Tag sources

Once the build is complete, you’ll see the tags created under the repository.

Tags created under the repository

Pipeline caching

To reduce the time for the build pipeline to execute, we can implement pipeline caching.

NOTE: Pipeline caching can be implemented only on build pipelines and not on release pipelines.

To implement caching:

  • Create the following pipeline variables before building the pipeline:

Pipeline caching

Here’s the cache task configuration:

- task: Cache@2
  inputs:
    key: 'maven | "$(Agent.OS)" | demo-domain/pom.xml'
    path: '$(MAVEN_CACHE_FOLDER)'
    cacheHitVar: 'CacheRestored'
    restoreKeys: |
      maven | "$(Agent.OS)"
      maven
  displayName: Cache Maven local repo
  • Configure the POM location in the cache task based on the location of POM

You need to include the following option in the Maven task to make use of the pipeline caching strategy:

mavenOptions: '-Xmx3072m $(MAVEN_OPTS)'

Reference YAML code

variables:

- name: MAVEN_CACHE_FOLDER
  value: $(Pipeline.Workspace)/.m2/repository
- name: MAVEN_OPTS
  value: -Dmaven.repo.local=$(MAVEN_CACHE_FOLDER)
trigger:
  branches:
    include:
    - master
  paths:
    include:
    - azure-devops-poc/*

stages:

- stage: __default
  jobs:
  - job: Job
    pool:
      vmImage: ubuntu-latest
    steps:
    - task: MavenAuthenticate@0
      inputs:
        artifactsFeeds: xxxx
    - task: Cache@2
      inputs:
        key: maven | "$(Agent.OS)" | azure-devops-poc/pom.xml
        path: $(MAVEN_CACHE_FOLDER)
        cacheHitVar: CacheRestored
        restoreKeys: >
          maven | "$(Agent.OS)"

          maven
      displayName: Cache Maven local repo
    - task: Maven@3
      inputs:
        mavenPomFile: azure-devops-poc/pom.xml
        goals: deploy
        publishJUnitResults: true
        testResultsFiles: '**/surefire-reports/TEST-*.xml'
        javaHomeOption: JDKVersion
        mavenVersionOption: Default
        mavenOptions: -Xmx3072m $(MAVEN_OPTS)
        mavenAuthenticateFeed: false
        effectivePomSkip: false
        sonarQubeRunAnalysis: false
    - task: CopyFiles@2
      inputs:
        Contents: '**/target/*.jar'
        TargetFolder: $(Build.ArtifactStagingDirectory)
        CleanTargetFolder: true
        flattenFolders: true
    - task: PublishBuildArtifacts@1
      inputs:
        PathtoPublish: $(Build.ArtifactStagingDirectory)
        ArtifactName: DemoApplication
        publishLocation: Container

Run the pipeline job once the above steps are completed. The artifacts should be built and published to Azure Artifacts.

Release pipeline

Once the build pipeline is complete, you can trigger the release pipeline as per requirements.

Here’s a sample release pipeline that gets triggered whenever the build pipeline is completed. The release pipeline can have multiple stages.

Release pipeline

Necessary artifacts must be added in the artifacts section of the release pipeline to trigger it. The following image shows the artifact configured.

Necessary artifacts

You can also configure the predeployment conditions of stages as per requirement. The following image shows these have been triggered using the “After release” option.

Pre-deployment conditions

As this article is about deploying the application to CloudHub, we’ll configure the two necessary tasks:

  • Downloading credentials file
  • Using Bash script tasks, which deploy the JAR to the CloudHub required environment with the Anypoint CLI command

The following snippet is required for credentials file creation. Do not provide an extension to the file.

{
 "Sandbox": {
  "username": "anypoint_username",
  "password": "anypoint_password",
  "organization": "xxxx",
  "environment": "Sandbox",
  "host": ""
 },
 "QA": {
 "username": "anypoint_username",
  "password": "anypoint_password",
  "organization": "xxxx",
  "environment": "QA",
  "host": ""
 }
}

Upload the credentials file to the library section.

Upload the credentials file

Configure the Download Secure File task of a Stage, as shown below.

Download Secure File

Next, configure the second task for deploying to CloudHub, as shown below. Also refer to the following commands for deploying to CloudHub with Anypoint CLI (only for a new application).

NOTE: This command will throw an error if an application with the same name is already deployed. For redeploying the application, use Modify instead of Deploy in the following command.

npm install -g anypoint-cli@latest
mkdir ~/.anypoint
cp $AGENT_TEMPDIRECTORY/credentials ~/.anypoint/

export ANYPOINT_PROFILE="$(environment)"

anypoint-cli runtime-mgr cloudhub-application deploy --runtime "$(runtime)" --workers "$(workers)" --workerSize "$(worker_size)" --property "anypoint.platform.platform_base_uri:https://anypoint.mulesoft.com/"   --property "anypoint.platform.client_id:8aacf1bc75bb4b7f846f0f449b49ec88" --property "anypoint.platform.client_secret:61E03EE97ddB43469E078De2D56aca69" $(application_name) $(jar_file_path)

Below is the command for redeploying the application:

npm install -g anypoint-cli@latest
mkdir ~/.anypoint
cp $AGENT_TEMPDIRECTORY/credentials ~/.anypoint/

export ANYPOINT_PROFILE="$(environment)"

anypoint-cli runtime-mgr cloudhub-application modify --runtime "$(runtime)" --workers "$(workers)" --workerSize "$(worker_size)" --property "anypoint.platform.platform_base_uri:https://anypoint.mulesoft.com/"   --property "anypoint.platform.client_id:8aacf1bc75bb4b7f846f0f449b49ec88" --property "anypoint.platform.client_secret:61E03EE97ddB43469E078De2D56aca69" $(application_name) $(jar_file_path)

Deploy to CloudHub

Finally, execute the created release pipeline. It should deploy the application to the Sandbox and QA environment.

Execute the created release pipeline

Deploy the application

— By Twinkle Jagani