Continuous Integration of Applications to CloudHub 2.0 using Github Actions

Continuous Integration of Applications to CloudHub 2.0 using Github Actions

Prerequisites:

  • Github

  • Anypoint Platform (Exchange Contributor, Runtime Access)

Mule API Project Structure:

Before you Deploy Mule Application to Cloudhub 2.0

Update Pom xml file with Distribution Management

<distributionManagement>
  <repository>
    <id>exchange-connected-app-v3</id>
    <name>Exchange Private Repository</name>
    <url>https://maven.anypoint.mulesoft.com/api/v3/organizations/${project.groupId}/maven</url>
    <layout>default</layout>
  </repository>
</distributionManagement>

Update Pom Xml with repositories

<repositories>
        <repository>
            <id>exchange-connected-app-v3</id>
            <name>Anypoint Exchange</name>
            <url>https://maven.anypoint.mulesoft.com/api/v3/maven</url>
            <layout>default</layout>
        </repository>
        <repository>
            <id>mulesoft-releases</id>
            <name>MuleSoft Releases Repository</name>
            <url>https://repository.mulesoft.org/releases/</url>
            <layout>default</layout>
        </repository>
        <repository>
            <id>anypoint-exchange-v3</id>
            <name>Anypoint Exchange V3</name>
            <url>https://maven.anypoint.mulesoft.com/api/v3/maven</url>
            <layout>default</layout>
        </repository>
</repositories>

For groupId please refer How to know my Organization ID (Org ID) on the Anypoint Platform

For the deployment of Mule application to Cloudhub 2.0 , application has to be published to exchange and then the deployment.

To publish the application to Anypoint Exchange create folder .maven and make file settings.xml.

<?xml version="1.0"?>
<settings>

  <pluginGroups>
    <pluginGroup>org.mule.tools</pluginGroup>
  </pluginGroups>

  <servers>
    <server>
        <username>~~~Client~~~</username>
        <password>${CONNECTED_APP_CLIENT_ID}~?~${CONNECTED_APP_CLIENT_SECRET}</password>
        <id>exchange-connected-app-v3</id>
      </server>
  </servers>

  <profiles>
    <profile>    
        <properties>
          <org.id>${ORGANIZATION_ID}</org.id>
        </properties>
        <repositories>
          <repository>
            <id>exchange-connected-app-v3</id>
            <name>Corporate Repository</name>
            <url>https://maven.anypoint.mulesoft.com/api/v3/organizations/${org.id}/maven</url>
          </repository>
          <repository>
            <id>exchange-connected-app-v2</id>
            <name>Corporate Repository</name>
            <url>https://maven.anypoint.mulesoft.com/api/v2/organizations/${org.id}/maven</url>
          </repository>
        </repositories>
        <id>exchange-repos</id>
      </profile>
  </profiles>

    <activeProfiles>
    <activeProfile>exchange-repos</activeProfile>
  </activeProfiles>

</settings>

This repository will serve as an example. The code for your Mule application should be stored here.

When your code is uploaded to GitHub, create a new folder named .github. Inside this folder, create another folder named workflows. This is where the YAML file containing the pipeline's actual code should be created.

In the YAML script below, the Git reference points to the develop branch, and the pipeline starts running only in the develop branch. Similarly, you can create jobs for multiple environments for each branch.

# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events for all branches

 push:
  branches: ["develop","main"]
 pull_request:
  branches: ["develop","main"]


jobs:
 build:
  if: ${{ contains(github.ref, 'dev') ||contains(github.ref, 'release') }}
  runs-on: ubuntu-latest
  steps:
    - run: echo 'MULE CONNECTED APP USER--${{vars.MULE_CONNECT_APP_USER}}'
    - run: echo 'MULE CONNECTED APP PASSWORD--${{vars.MULE_CONNECT_APP_PWD}}'
    - run: echo 'Eventname-- ${{ github.event_name  }}'
    - run: echo 'event-- ${{ github.event  }}'
    - run: echo 'Ref-- ${{ github.ref  }}'
    - run: echo 'RefName-- ${{ github.refname  }}'
    - run: echo 'github head ref-- ${{   github.head_ref }}'
    - name: Checkout this repo
      uses: actions/checkout@v3
    - name: Cache dependencies
      uses: actions/cache@v3
      with:
        path: ~/.m2/repository
        key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
        restore-keys: |
          ${{ runner.os }}-maven-
    - name: Set up JDK 1.8
      uses: actions/setup-java@v3
      with:
        distribution: 'zulu'
        java-version: 8
    - name: Build with Maven
      env:
        USERNAME: ${{ secrets.CONNECTED_APP_CLIENT_ID }}
        PASSWORD: ${{ secrets.CONNECTED_APP_CLIENT_SECRET }}
        KEY: ${{ secrets.decryption_key }}    
      #run: mvn --settings .maven/settings.xml clean install -e -X --file pom.xml
      run: mvn -B  package --file pom.xml --settings .maven/settings.xml -DskipMunitTests

    - name: Stamp artifact file name with commit hash
      run: |
        artifactName1=$(ls target/*.jar | head -1)
        commitHash=$(git rev-parse --short "$GITHUB_SHA")
        artifactName2=$(ls target/*.jar | head -1 | sed "s/.jar/-$commitHash.jar/g")
        mv $artifactName1 $artifactName2
    - name: Upload artifact 
      uses: actions/upload-artifact@v3
      with:
          name: artifacts
          path: target/*.jar

 deploy_to_dev:
    environment:
      name: Dev
    if: ${{ contains(github.ref, 'dev') }}
    needs: build
    runs-on: ubuntu-latest
    steps:  
    - run: echo 'PROVIDER***--${{vars.DEPLOY_PROVIDER}}'
    - run: echo 'REPLICA COUNT***--${{vars.REPLICA_COUNT}}'

    - name: Checkout this repo
      uses: actions/checkout@v3
    - name: Cache dependencies
      uses: actions/cache@v3
      with:
        path: ~/.m2/repository
        key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
        restore-keys: |
          ${{ runner.os }}-maven-
    - uses: actions/download-artifact@v3
      with:
        name: artifacts
    - name: Deploy to dev
      env:
        CONNECTED_APP_CLIENT_ID: ${{ secrets.CONNECTED_APP_CLIENT_ID }}
        CONNECTED_APP_CLIENT_SECRET: ${{ secrets.CONNECTED_APP_CLIENT_SECRET }}
        KEY: ${{ secrets.decryption_key }}
      run: |
        mvn deploy --settings .maven/settings.xml  -DskipMunitTests -Dappname_env='dev' -Denvironment=Sandbox -DMULE_ENV=dev -DDEPLOY_TARGET=Cloudhub-US-East-2 -DMULE_PROVIDER=MC -DDEPLOY_MULE_VERSION=4.6.2  -DDEPLOY_VCORE=1 -DDEPLOY_FORWARD_SSL_SESSION=true -DDEPLOY_LAST_MILE_SECURITY=true -DCONNECTED_APP_CLIENT_ID="$CONNECTED_APP_CLIENT_ID" -DCONNECTED_APP_CLIENT_SECRET="$CONNECTED_APP_CLIENT_SECRET"

Update Connected App Secrets:

For connected app credentials refer Connected App functionality

update connected app secrets in repository settings as below

If you are following any branching strategy, raise a pull request to the develop branch. As per the above script, the Git reference is pointed to the develop branch, so the pipeline will get triggered accordingly.