CI/CD of Functions and Plugins in Flex Development using GitHub Actions

December 13, 2021
Written by
Reviewed by


If you’re designing your contact center using Twilio Flex, you might have come across questions on how effectively and efficiently you can deploy your Flex plugins and Twilio Functions. Twilio has answered it by providing the twilio-cli for both Flex and Functions.

Usually, developers will make changes, test them locally, and then deploy them to a Twilio account using the CLI command. And during (or prior to) deployment, developers will commit the changes to a code repository. However, with this approach, there is no control over what is published, and developers may commit the code at a later stage than what is live. The approach is error-prone and dependent on your developers to do the right things. Most companies want to enforce rules and best practices for code produced by their developers and want automated checks done before any code goes live. This post explains how we can create a continuous integration and deployment pipeline using GitHub Actions and use that pipeline to deploy Twilio Flex Plugins and Functions.


Directory structure

My sample repository follows a structure like this:

├── .github/workflows
├── Flex
├── Functions

We will use the Flex folder to host all the Flex plugins with each plugin having its own subfolder and the Functions folder will contain all the Twilio Functions and Assets.

Functions folder for Flex plugins

Twilio functions and assets

Use Git Feature Branching and defining branches

Once the code repository is set up, create two branches (you can create as many branches as you wish based on your desired Twilio environments):

  • master (branch for deploying code to PROD instance)
  • develop (branch for deploying code to DEV instance)

As a developer, first check out the entire repository and create a new feature branch from the develop branch for the development work you want to perform.

In this example, I have created a feature branch called feature/change-plugin.

Feature branch for testing Flex plugins

Once you have your feature branch, perform all the development on this branch and commit the changes regularly to the repository. You can test your changes locally using the Twilio CLI commands and once you’re happy with the changes, commit them and create a pull request against the develop branch.

Workflow files

The repository hosts workflow files under the .github/workflows folder, which defines the actions to be performed on the commits or merge requests. The workflow files supplied along with the above repository make use of GitHub Action’s push event on develop and master branches to trigger workflows for each environment.

The repository has two files for each environment with following naming convention:

  • <environment_name>_flex_deploy.yml => all Twilio Flex plugin deployments
  • <environment_name>_function_deploy.yml => all  Twilio Function deployments

Naming in my Flex plugin and asset direction

The steps defined in the workflow files will check for the latest pull request merged to the branch and then extract only those folders which are changed. For example, if a developer only changed one plugin in a release, the workflow will skip build and deployment for the Functions folder and will only execute the build/deploy action on the affected plugin.

To achieve this, the workflow steps make use of Github’s REST API to fetch the latest changed folders.

The following command will fetch all the changed plugin folders on the latest pull request and create a job to deploy each of them separately.

curl -s  -H "Authorization: token ${{secrets.REPO_TOKEN}}"${{github.repository}}/pulls/${{github.event.pull_request.number}}/files | jq -r '.[]  .filename' | cut -d "/" -f 1,2 | sed '/^Flex/!d'  | cut -d "/" -f 2 | jq -R -s -c 'split("\n")[:-1]'

Similarly the following command will return whether there are any changes made into the functions folder in the latest pull request.

curl -s  -H "Authorization: token ${{secrets.REPO_TOKEN}}"${{github.repository}}/pulls/${{github.event.pull_request.number}}/files | jq -r '.[]  .filename' | cut -d "/" -f 1,2 | jq -R -s -c 'split("\n")[:-1]' | jq '. | contains (["Functions/"])'

GitHub Secrets

The process makes use of GitHub Secrets to store your Twilio Account SID and Auth Token. These are required for deploying Functions and Flex plugins for each environment. Additionally, we also need to create an Access Token with repo permissions enabled. This access token will be used to invoke GitHub REST API requests.


This tutorial gave a small intro into how you can utilise the Twilio CLI commands in GitHub Actions to achieve continuous integration and deployment. You may modify the workflow to add more checks (test coverage, document generation, etc.). This can even be extended to automatically release branches once the deployment is successful.

I can’t wait to see what you build! 

Prasanth Pillai is a Senior Solutions Architect on the Twilio Professional Services team. He’s keen on automating and optimising processes to help customers build solutions that scale on Twilio. He can be reached at ppillai[at]