Image for post Using mirthSync to implement CI/CD for Mirth Connect

Using mirthSync to implement CI/CD for Mirth Connect

  • Mirth Connect
  • CI/CD
  • mirthSync

March 1, 2019

Whats on this page:

We’ve shown in previous posts that mirthSync can be used to move code between different Mirth Connect systems and can also be used in conjunction with Git for tracking code/config changes. In this post we’ll dive into implementing a simple CI/CD pipeline by wiring together Github Actions, mirthSync, and multiple Mirth Connect deployments. This will show how changes can be implemented, tracked, and automatically deployed to a staging environment from a development environment.

Set up a Git repository

The first step in implementing CI/CD for Mirth is to create a repository for tracking changes to your mirth code and configuration. We’ll be using Github with Github actions for this example but the same basic approach can be used for any combination of source control and CI/CD systems.

You can check out the end-result of the process described in this post at our Github mirthsync-ci repository.

First we’ll create our new repository for tracking changes on Github. Go ahead and initialize the repository with a README and .gitignore file.

MirthSync Step 1

Fetch and commit our Mirth code

Now that we have a minimal repository on Github we’ll need to populate it with our Mirth code and some supplementary files to assist with our CI/CD workflow.

Note: The following steps are performed on a Linux environment but the same concepts apply to Windows environments as well (though you may need to adjust some files and steps accordingly).

Let’s open a terminal and get a local checkout of our newly created Git repository. You can get the repository url from Github.

MirthSync Step 2

git clone git@github.com:SagaHealthcareIT/mirthsync-ci.git
  Cloning into 'mirthsync-ci'...
  remote: Enumerating objects: 223, done.
  remote: Counting objects: 100% (223/223), done.
  remote: Compressing objects: 100% (124/124), done.
  remote: Total 223 (delta 86), reused 143 (delta 55), pack-reused 0
  Receiving objects: 100% (223/223), 45.43 KiB | 802.00 KiB/s, done.
  Resolving deltas: 100% (86/86), done.

Ok — we have our local checkout of the repository — let’s move onto populating the repository with a minimal set of files and directories for working with Mirthsync. Once you’re finished you should end up with a directory structure that looks something like the tree below.

The src directory is the ’target’ for our mirthSync actions. It contains Mirth code and configuration split out into an intuitive structure of XML and code files that can be opened with a normal text editor and stored within a source control repository.

Other noteworthy files are the Makefile, mirthsync.yml file, and .envrc. The Makefile isn’t strictly necessary but is used as a convenient way to script out various actions that are useful while working with Mirth and mirthSync. The mirthsync.yml file contains the Github actions configuration and steps. The .envrc.dist file is a template that can be copied to an actual .envrc file for use with ‘direnv’ (an open source tool for associating environment variables with directories). Like the Makefile - the direnv configuration is not necessary and is there for convenience.

└── mirthsync-ci
  ├── .envrc.dist
  ├── .github
  │   └── workflows
  │   └── mirthsync.yml
  ├── .gitignore
  ├── Makefile
  ├── README.md
  └── src
  ├── Alerts
  │   ├── test alerts 2.xml
  │   └── test alert.xml
  ├── Channels
  │   ├── %2Fthis%5C is %2Fa %5C group%2F%5Cwith weird%5Ccharacters%2F
  │   │   ├── Http Hello3 3083.xml
  │   │   └── index.xml
  │   ├── Http 3080.xml
  │   └── This is a group
  │   ├── Http Hello2 3081.xml
  │   ├── Http Hello3 3082.xml
  │   └── index.xml
  ├── CodeTemplates
  │   ├── Library 1
  │   │   ├── index.xml
  │   │   ├── Template 1.xml
  │   │   └── Template 3 Library 1.xml
  │   └── Library 2
  │   ├── index.xml
  │   └── Template 2.xml
  ├── ConfigurationMap.xml
  ├── GlobalScripts
  │   └── globalScripts.xml
  └── Resources.xml

  29 directories, 47 files

To create the src directory you’ll need mirthSync available on your command line. In my case — I place the mirthsync.sh script on my path. You can also invoke mirthSync directly by running ‘java -jar’ on the mirthsync uberjar.

mirthsync.sh -s https://localhost:8443/api -u admin -p admin -i -t src pull
/usr/bin/java
found java executable in PATH
version 11.0.13
Authenticating to server at https://localhost:8443/api as admin
Downloading from https://localhost:8443/api/server/configurationMap to src/
        File: src//ConfigurationMap.xml
.........
Downloading from https://localhost:8443/api/alerts to src/Alerts
        File: src/Alerts/test alert.xml
        File: src/Alerts/test alerts 2.xml
Finished!

The preceding command and output is used to ‘pull’ Mirth code and configuration from my local development environment into the ‘src’ directory. Descriptions for the various command line switches can be seen with a ‘mirthsync.sh –help’ command. Now that you have a src directory go ahead and commit the code and push it to Github.

Configure Github Actions

Now that we have our Mirth code in source control - let’s add a Github actions workflow. To get a jumpstart on creating this file you can copy the contents of mirthsync.yml from the sample Github repository.

This YML file specifies that it is meant for the ‘main’ branch in Git. It won’t run on code pushes to other branches. The goal is to allow commits to a ‘dev’ branch. When a developer is satisfied with their changes they can merge the changes to ‘main’. This will kick off the workflow. The next steps in the workflow download mirthSync to the build container and then push the code changes in the ‘src’ folder to our staging server.

At the bottom of the YML file you can see the command used to push to the remote staging Mirth server.

STAGE_URL=${{ secrets.STAGE_URL }} STAGE_USER=${{ secrets.STAGE_USER }} STAGE_PASS=${{ secrets.STAGE_PASS }} make push-remote

This command references several ‘secrets’ that are necessary to log into the remote Mirth server and push the changes. Also - in our example we’re running our push via the Makefile. This isn’t necessary since mirthSync doesn’t require Make but it’s convenient since we run push/pull commands frequently during development. To see the actual command run - look inside the makefile for the ‘push-remote’ target. It looks like this….

mirthsync.sh -s ${STAGE_URL} -u ${STAGE_USER} -p ${STAGE_PASS} -t src --include-configuration-map -f push

The preceding command says use the url, username, password specified in the environment and push the contents of src to the remote server. The configuration map is included in this push via the ‘–include-configuration-map’ parameter since the config map is not pushed by default. Also, the ‘-f’ option is present to override any channel version differences on the remote server.

In the case of our Github Actions workflow - we specify these environment variables in the repository ‘Secrets’ configuration to prevent disclosure of sensitive info in our setup and workflow output. For local development we rely on ‘direnv’ and our local .envrc file to configure appropriate environment variables for the local command line.

At this time, go ahead and configure your Secrets using the Github UI repository. In the sample repository the secrets looks like this.

MirthSync Step 3

With our secrets configured, we can go ahead and commit and push our github actions mirthsync.yml file. If everything is configured correctly you should see your workflow kick off and deploy the repository code to your remote ‘staging’ Mirth environment. Here’s a view of a recent workflow run in our sample repository…

MirthSync Step 4

Closing Thoughts

At this point it would be good to show a full development workflow using mirthSync from dev changes/testing to a pull-request/review cycle and eventually deployment to production but this post is already getting a little on the long side. I’ll be sure to post a link to the next post that deals with mirthSync and CI/CD here.

READING DONE