Automating your React Native Workflow with Github Actions

Covenant Ifeoluwa
5 min readMay 31, 2024

--

If you’re building an app with React Native and you leverage on Github then you most definitely have to try automating your repititive tasks with Github Actions. This can significantly enhance your productivity and quality of your code, enabling you to be consistent with your best practices and workflow. Automating repititive tasks can also help to save time overall.

In this article, I will take you on a journey to explore some of the incredible superpowers you can use in the world of Github Actions for your existing or new React Native Projects. I will showcase how to set up reusable workflows and highlighting specific actions for various essential tasks.

Reusability with Composite Actions
One of the key advantages of Github Actions is the ability to create reusable workflows through composite actions. These actions encapsulate common steps such as Node Setup, Dependency Installations, and Caching. This will allow you to streamline their workflows. Defining composite action in a project directory allows the you to effortlessly include it on other workflows without the need for redundant code. In our scenario, to establish a composite action for project setup, we will create a new directory within our project named .github/actions. Inside this directory, a new file named setup-node-pnpm-install/action.yml will outline the steps executed when invoking this action and must define the type as composite.

Here is a what it looks like:

name: "Setup  Node + PNPM + Install Dependencies"
description: "Setup Node + PNPM + Install Dependencies"
runs:
using: "composite"
steps:
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v3
with:
node-version: 18
cache: "pnpm"

- name: 📦 Install Project Dependencies
run: pnpm install --frozen-lockfile
shell: bash

Now, we can use this action in other workflows by calling it using the uses keyword and specifying the path to the action file. Note that you don’t need to include the action.yml; only the folder name is required.

- name: 📦 Setup Node + PNPM + install deps
uses: ./.github/actions/setup-node-pnpm-install

Now that we have the setup ready, let’s begin listing the workflows.

  1. Type Checking
    I assume that you are using TypeScript in your project. If not, you should consider giving it a try. Believe me, it’s worth it.
name: Type Check (tsc)

on:
push:
branches: [main, master]
pull_request:
branches: [main, master]

jobs:
type-check:
name: Type Check (tsc)
runs-on: ubuntu-latest
steps:
- name: 📦 Checkout project repo
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: 📦 Setup Node + PNPM + install deps
uses: ./.github/actions/setup-node-pnpm-install

- name: 📦 Install Reviewdog
if: github.event_name == 'pull_request'
uses: reviewdog/action-setup@v1

- name: 🏃‍♂️ Run TypeScript PR # Reviewdog tsc errorformat: %f:%l:%c - error TS%n: %m
# we only need to add the reviewdog step if it's a pull request
if: github.event_name == 'pull_request'
run: |
pnpm type-check | reviewdog -name="tsc" -efm="%f(%l,%c): error TS%n: %m" -reporter="github-pr-review" -filter-mode="nofilter" -fail-on-error -tee
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name:
🏃‍♂️ Run TypeScript Commit
# If it's not a Pull Request then we just need to run the type-check
if: github.event_name != 'pull_request'
run: pnpm type-check

2. Linting with ESLint
This workflow will run the linting on every push to the main/master branch and on every pull request to main/master. If it’s a pull request, it will add the check to the PR as well as annotate the code with waring and errors with reviewdog.

name: Lint TS (eslint, prettier)

on:
push:
branches: [main, master]
pull_request:
branches: [main, master]

jobs:
lint:
name: Lint TS (eslint, prettier)
runs-on: ubuntu-latest

steps:
- name: 📦 Checkout project repo
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: 📦 Setup Node + PNPM + install deps
uses: ./.github/actions/setup-node-pnpm-install

- name: 🏃‍♂️ Run ESLint PR
if: github.event_name == 'pull_request'
uses: reviewdog/action-eslint@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
reporter: github-pr-review
eslint_flags: ". --ext .js,.jsx,.ts,.tsx"

- name: 🏃‍♂️ Run ESLint PR
if: github.event_name != 'pull_request'
run: pnpm run lint

3. Unit Tests
This workflow runs the unit tests on every push to the main/master branch and on every pull request to main/master. If it’s a pull request, it will post a comment with the coverage details. as well as annotate the test results directly in Github.

⚠️ To ensure proper functionality, you need to make sure that your Jest configuration is set up to generate coverage files in the specified format. You can refer to the jest.config.js file for more information.

name: Tests (jest)

on:
push:
branches: [main, master]
pull_request:
branches: [main, master]

jobs:
test:
name: Tests (jest)
runs-on: ubuntu-latest

steps:
- name: 📦 Checkout project repo
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: 📦 Setup Node + PNPM + install deps
uses: ./.github/actions/setup-node-pnpm-install

- name: 🏃‍♂️ Run Tests
run: pnpm run test:ci

- name: Jest Coverage Comment
uses: MishaKav/jest-coverage-comment@main
if: (success() || failure()) && github.event_name == 'pull_request'
with:
coverage-summary-path: ./coverage/coverage-summary.json
summary-title: "💯 Test Coverage"
badge-title: Coverage
create-new-comment: false
junitxml-title: 😎 Tests Results
junitxml-path: ./coverage/jest-junit.xml
coverage-title: 👀 Tests Details
coverage-path: ./coverage/coverage.txt
report-only-changed-files: true

Here is an example of the comment that will be posted on the pull request.

In conclusion, The versatility of GitHub Actions allows for customization and optimization of development processes, ultimately leading to more efficient and reliable project deliveries. Experimenting with different actions and workflows can further enhance the app-building process, paving the way for a more seamless development experience.

--

--