React Native Developer Series: Expo, Version Control, GitHub and Initial CI/CD Processes

Written by: madelyn
6 min read

This is Part One of a four-part developer series from Evan Glazer.

Series Abstract

Finishing the application build processes is normally very dilatory to many organizations. Especially in mobile platforms that need to use very specific criteria. In this developer series, building an application in React Native won’t be our primary goal; building processes that give us the ability to Build, utilize CI/CD mechanisms through a pipeline and continuously deploy (CD) to different environment types for testing and publishing to the app stores in React Native will be the main theme. We’re going to start by creating a simple application that will show us a version number using environment variables. We will continue to work through increasing the functionality to inevitably be able to move from a static type of build to a dynamic build process increasing the build numbers automatically for the application version. It will be imperative that we start by outlining the tools and technology we will need to follow the series.

CI/CD Mobile Battle?

Is it worth it!? Too Costly? Where to start?

This is the part where processes can become an additional expense for the business. This is a big issue because companies are spending a lot of money paying a software engineer to release a mobile application to the app store, which sometimes could take a whole day to make happen. But some of the biggest defeats are when ONLY one engineer knows how to build and package the project, or has all the provisioning profiles and certificates set up for production, staging, develop environments on their machine and no one else knows how to properly prepare a release. But at the end of the day, you won’t have to rely on John Doe to do a release as one day he might be on vacation and the business will be stuck not being able to release new products or fixes. Right now, CI/CD for React Native doesn’t have a fully-wrapped solution – it requires a mid-senior level software engineer (in my opinion) to build out the processes needed for an application, which is sometimes considered advanced DevOps.

To-Do Checklist

These are the main technologies we need to become acquainted with in this series:

  • Sign up with Github. We will use this to store our project and utilize branches to help promote the build pipeline.

  • Sign up here with this free tier account with AWS. We will be using a lot of the resources like RDS, Code Pipeline, Code Build.

  • Sign up with Expo Client. We will use Expo Kit to give us over-the-air updates and to handle certain release channel methodology to manage the publishing of app files.

In the next parts of this series, we will implement other technologies like Fastlane, CodeBuild, CodePipeline, S3, Databases, Mac Mini (remote dedicated-server), Jenkins/XCode Studio CI, etc.

Development has begun!

In this part of the series, we’re going to work toward creating a simple application that will be configured with semantic versioning using environment variables, and we will prepare our repository to be able to commit to GitHub. Deployment Process:

  • Version Bump our application

  • Commit and Push to GitHub

  • Provision the application schema

  • Build the schema

  • Export in S3 and database

  • Upload to app stores

  • Add release notes

  • Distribute

Expo setup

Now that you have signed up for Expo, we will go ahead and follow the documentation carefully.

Is the server up?

Using Expo CLI we can run expo start to start our server

Eject to add Expokit

This is a shortcut (in my opinion) to help get the project jump-started and setup with tools to make the deployment process easier and this is by us utilizing the expo eject process. expo eject will require you to log in and give the application bundle identifiers you’re using in your application.

Let's see the app

Time to install the pods in the project, what is that? CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. Go into our projects ios directory: cd ios Now run pod install from your project’s ios directory.

Open your project’s xcworkspace file in Xcode from the ios directory.

Use Xcode to build, install and run the project on your test device or simulator. This will happen by default if you click the big “Play” button in Xcode. Once it’s running, the iOS app should automatically request your JS bundle from the project you’re serving from Expo CLI.

Let's create a static screen with the version from an environment variable

Firstly, our project has been set up at this point by us just launching the project and viewing the generated files. Next off, we want to introduce environment variables, which will help us set certain attributes in our application that need to be secretive and global. react-native-config will help us achieve a build process with loading environment variables in the project during the pre-build actions. It is very important to make sure you follow the setup guide and have the Environment Variables coming through on the debugger, Xcode, and Android Studio output. You can do some testing on this by utilizing NSLog for Objective C and Log.d for Java, and console.log for the expo debugger. We will follow proper semantic versioning with the version core identified as: "." "." ()

<major> ::= <numeric identifier>

We will have two environments: Development and Production

.env – This is mainly to utilize error handling by having a base env file just in case there’s an issue with the schema.

ENV = none

MAJOR = 1

MINOR = 0

BUILD = 0

PATCH = 1
.env.development
ENV=Development
MAJOR=1
MINOR=0
BUILD=0
PATCH=1
.env.production
ENV=Production
MAJOR=1
MINOR=0
BUILD=0
PATCH=1

Now let’s go to our App.js file and build our semantic versioning:

import React from 'react'>;
import { StyleSheet, Text, View } from 'react-native';
import Config from "react-native-config";

const MAJOR = Config.MAJOR;
const MINOR = Config.MINOR;
const BUILD = Config.BUILD;
const PATCH = Config.PATCH;

export default function App() {
  return (
    View style={styles.container}
      Text{MAJOR}.{MINOR}.{BUILD}({PATCH}Text
    View
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

The App container mainly just shows a view with the environment variables we had set. And when we build it, we should see the screen look like this:

Push to Github

Now, let’s connect our project to GitHub. We will need to initialize the project for git.

$ git init

Now, let’s add everything we’ve been working on so far.

$ git add .

Let’s make this our initial base commit to build upon.

$ git commit -m “init base commit”

Now we need to go into GitHub and create our repository and copy the URL given and insert that to the terminal for setting the origin. our terminal and set the origin by pasting the url from the clipboard.

$ git remote add origin {paste url from clipboard}

And now we can push our local work to our controller branch.

$ git push -u origin master

What's next?

We have accomplished quite a bit in part one of this four-part series:

  • [x] Getting Acquainted with the Goals

  • [x] To-Do Checklist

  • [x] Development has begun!

  • [x] Push to Github

In the second part of this developer series, the main focus will be implementing Fastlane with understanding the type of tools and processes made available for iOS and Android.

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.