Continuous Integration (CI) and Continuous Delivery (CD) are concepts which can help you to build and deploy with confidence.
It's the idea of automating as much as you can, like running tests or creating new releases.
CI/CD is a relatively broad idea and can get as complex as you can make it.
In this guide, we will create a basic setup for testing (CI) and deployments (CD).
Also, the configuration for Bitbucket Pipelines, Gitlab CI, and Travis CI are provided.
Other CI/CD vendors can be used too; everything is executable through CLI.
Test with Jest
Testing is an essential part of an average CI workflow.
This process gives you the confidence when shipping by running all automated tests on every relevant change.
Without this, you can't be sure if a proposed change breaks the expected behavior of any existing functionality.
Before we can run the tests, we need to install the dependencies. You can use yarn, npm-install or even the faster npm-ci command.
After this, we can run the tests with Jest. Unfortunately, we can't use the original npm-test script shipped with expo-cli.
This script is designed to start a daemon that watches for file changes and reruns the tests.
In CI environments we need Jest to run the tests once and exit with a (un)successful status code.
Also, it's also a good idea to explicitly tell Jest it is running in a CI environment.
Jest will handle snapshots more strictly.
To summarize we will set up the CI to run the following two scripts.
$ npm ci
$ npx jest --ci
before_script:- npm install -g npm@latest
script:- npm ci
- npx jest --ci
Put this into .travis.yml in the root of your repository.
As you might have noticed already, the tests in CI are a bit slower compared to running them locally.
It's slower because your hardware is more powerful than the CI hardware.
Jest can leverage the use of parallel testing with such equipment.
Also, Some vendors limit the hardware resources or offer "premium" services for more power.
Luckily there is a relatively easy way to improve the speed of Jest; using the power of caching.
There is no definitive way of telling how much it improves.
Using the expo-cli tabs project as an example, it can speed up by a factor of 4x - 5x.
Now that we have a proper CI workflow in place, we will focus on the Continuous Deployment (CD) part.
In this process, we will make a new build and push it to Expo.
Combined with Over The Air (OTA) updates, this can create a simple but effective CD infrastructure.
Just like the CI part, we first need to install the dependencies.
After this, we need to authenticate at Expo and "publish" a new build.
Prepare Expo CLI
To interact with the Expo API, we need to install the Expo CLI.
You can use an environment with this library preinstalled, or you can add it to the project as a development dependency.
The latter is the easiest way but might increase the installation time.
For vendors that charge you per minute, it might we worth creating a prebuilt environment.
To install the Expo CLI into your project, you can execute this script.
$ npminstall --save-dev expo-cli
Next, we will configure the publishing step of your application to Expo.
Before we can do this, we need to authenticate as the owner of the app.
This is possible by storing the username or email with the password in the environment.
Every vendor has implemented their storage mechanism for sensitive data like passwords, although they are very similar.
Most vendors make use of environment variables which are "injected" into the environment and scrubbed from the logs to keep it safe.
To perform the authentication, we will add this script to our configuration:
After having the CLI library and authentication in place, we can finally create the build step.
In this step, we will create a new build and send it to Expo.
It finalizes the whole workflow of creating, testing and shipping your application.
To create the builds, we will add this script to our configuration:
-run:name: Installing dependencies
command: npm ci
-run:name: Login into Expo
command: npx expo-cli login -u $EXPO_USERNAME -p $EXPO_PASSWORD
-run:name: Publish to Expo
command: npx expo-cli publish --non-interactive --max-workers 1 --release-channel $EXPO_RELEASE_CHANNEL
Put this into .circleci/config.yml in the root of your repository.
CI and CD are concepts which are far from fully covered in this guide.
The best thing you can do to get familiar with these subjects is to make stuff yourself.
Here are some extra links that might help you further.