Continuous Deployment for ZAT App

A simple continuous deployment (CICD) pipeline for your private Zendesk applications.

Image for post
Image for post
Photo by panumas nikhomkhai from Pexels

Zendesk allows creating of custom applications using Zendesk’s App Framework (ZAF) that can be used to enhance the base capabilities of the Zendesk environment. See their app scaffold here. Two different ways to deploy their application are provided: Upload a zip of the application manually or run a sequence of update commands on the developer’s machine.

However, what if we want to have our app automatically deployed whenever we push (or merge) to a specific branch? A third option is presented here: A Github Actions based automatic deployment!

Pre-requisites

Step 1: Creating the Github Actions File

Below, is the first portion of the file. There are a few points worth noting here:

  1. The name attribute defines the name that appears on GitHub whenever our action runs.
  2. The on attribute specifies the condition used to trigger our action. In this case: A push to my-branch.
  3. jobs are the different sequences of steps that compose this workflow. In this tutorial, we will have a single job with multiple steps.
  4. runs-on defines the OS that the workflow will be run on. Github supports Linux, MacOS and Windows.
  5. -uses defines the image that will be used by a given step. actions/checkout@v1 is a Github provided image for checking out our repository inside the Github Action VM.

If the repository containing this code were to be pushed to Github, a workflow would be started that would checkout our repository and then terminate.

name: CIon:
push:
branches:
- my-branch
jobs:
build_and_deploy_my_app:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
...

Step 2: Install Required Packages

...
- name: Use Node.js 12.x
uses: actions/setup-node@v1
with:
node-version: 12.x
- name: Set up Ruby 2.6
uses: actions/setup-ruby@v1
with:
ruby-version: 2.6.x
- name: Install ZAT Toolchain
run: |
gem install zendesk_apps_tools
...

Step 3: Prepare Our App for ENV Injection (Optional)

{
"zat_latest": "3.2.3",
"zat_update_check": "2019-09-01",
"subdomain": ZENDESK_SUBDOMAIN,
"username": ZENDESK_USERNAME,
"password": ZENDESK_TOKEN,
"app_id": ZENDESK_APPID
}

In order for our template file to be updated with the correct value for each of its placeholders (ZENDESK_APPID, etc) and generate the desired .zat file (more on the purpose of the .zat file can be found here), we need to add a step in our Webpack bundler that replaces each placeholder with the correct values that should be available as environment variables.

To accomplish the replacement, we update the CopyWebpackPlugin as shown below:

new CopyWebpackPlugin([
{ from: 'src/manifest.json', to: '../', flatten: true },
{ from: 'src/images/*', to: '.', flatten: true },
{
from: 'src/zat.template',
to: '../.zat',
toType: 'file',
transform: content => {
return content.toString()
.replace(
/ZENDESK_SUBDOMAIN/,
JSON.stringify(process.env.ZENDESK_SUBDOMAIN),
).replace(
/ZENDESK_USERNAME/,
JSON.stringify(process.env.ZENDESK_USERNAME),
).replace(
/ZENDESK_TOKEN/,
JSON.stringify(process.env.ZENDESK_TOKEN)
).replace(
/ZENDESK_APPID/,
process.env.ZENDESK_APPID);
},
},
]),

Step 4: Build the Application and Deploy

Below, we perform the build step and then deploy it to Zendesk. The build step is accomplished by simply running yarn install followed by yarn build . Output files from this step will be placed inside the /dist folder.

Finally, we deploy our application by running the zat update command from within the /dist folder.

...      - name: Build app
working-directory: ./
env:
ZENDESK_SUBDOMAIN: ${{ secrets.ZENDESK_USERNAME }}
ZENDESK_USERNAME: ${{ secrets.ZENDESK_USERNAME }}
ZENDESK_TOKEN: ${{ secrets.ZENDESK_TOKEN }}
ZENDESK_APPID: ${{ secrets.ZENDESK_APPID }}
run: |
yarn install
yarn build
- name: Deploy app
working-directory: ./dist
run: |
zat update

Conclusion

  1. The build is slow due to the installation of required packages. The zendesk_app_tools gem is particularly slow to install (approximately 7 minutes). A better way may be to create a custom action or builder image that has these packages preinstalled.
  2. Include a testing step or create a separate workflow for testing.

Written by

A curious minded engineer.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store