GitHub Actions: Run RSpec Test On Every Push For Free
Tags: github, rails, ruby, testing
Published: 2020-07-25 16:45:13

# GitHub Actions:

GitHub has a great feature called [GitHub Actions](https://github.com/features/actions). Recently GitHub has made this feature free for around 2000 minutes with 2 Core and 7GB systems per month.

> GitHub Actions make it easy to automate all your software workflows, now with world-class CI/CD. Build, test, and deploy your code right from GitHub. Make code reviews, branch management, and issue triaging work the way you want.

I use GitHub Actions for two major purposes:
- Auto start unit-testing on every push to validate the code pushed to the repo.
- Second to automatically deploy the code to the server when code is pushed to the master branch. So no need to deploy after doing hectic coding.

In this article, I will explain "How I use GitHub Actions To Run RSpec Unit Testing Suite Once my code is pushed to any branch in GitHub.".

# Init GitHub Actions In Repo:
Create a folder in the root of repo named `.github` and then create a folder named `workflows` inside `.github` folder.
Now create a YAML file inside the `workflows` folder with the name of the task. I create the file name `api-rspec.yml` in the folder to test RSpec for the API.

# Settings through the YAML file:

The final file can be seen in the code below:

```yaml
name: CI RSpec Tests

on: [push, pull_request]
  push:
   paths:
   - 'api/**'
  pull_request:
    paths:
    - 'api/**'

jobs:
  build:
    name: CI
    runs-on: ubuntu-latest
    env:
      api-dir: ./api 
    
    services:
      postgres:
        image: postgres:11.6
        ports: ["5432:5432"]
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
      redis:
        image: redis
        ports: ["6379:6379"]
      elasticsearch:
        image: elasticsearch:6.8.8
        ports: ["9200:9200"]
        options: -e="discovery.type=single-node" --health-cmd="curl http://localhost:9200/_cluster/health" --health-interval=10s --health-timeout=5s --health-retries=10
        
    steps:
      - uses: actions/checkout@v1
      - uses: actions/setup-ruby@v1
        with:
          ruby-version: 2.6.6
      
      - name: Install PostgreSQL
        run: sudo apt-get -yqq install libpq-dev

      - name: Run bundle install
        working-directory: ${{env.api-dir}}
        run: |
          gem install bundler
          bundle install --jobs 4 --retry 3
      - name: Setup Database
        working-directory: ${{env.api-dir}}
        env:
          RAILS_ENV: test
          PGHOST: localhost
          PGUSER: postgres
        run: bin/rails db:create db:schema:load

      - name: Build and test with rspec
        working-directory: ${{env.api-dir}}
        env:
          RAILS_ENV: test
          PGHOST: localhost
          PGUSER: postgres
        run: bundle exec rspec spec
```

# Explaining the Above Code:

**Line 1**, I gave the name to my GitHub Action to be performed.

**Line 3...9**, As my repo is monorepo with API and front in the same repo I said that on every push and pull request in the repo if something changed in a folder called `api` then call this GitHub Action.

**Line 11..16**, Defines the job of building a system to GitHub Actions. and tells GitHub to run the action on the latest ubuntu machine with a directory of rails be `/api`.

**Line 18...29**, My Rails includes services like Redis, Postgres and elastic search. So I tell here to initialize those services in the ubuntu machine we created above. Also, verify that services have started especially elastic search as it takes around 10-15 seconds to start the service.

**Line 31...35**, I used prebuilt GitHub official actions to get the code and install ruby according to the provided version to the ubuntu machine.

**Line 37,38**, I installed the Postgres packages needed by my code to run successfully.

**Line 40...44**, Now I run bundle install in my code so that the gems required by my rails project are included in the system.

**Line 45...51**, Now I attach the ubuntu machine Postgres with my code and do the migrations to set the database according to schema loaded.

**Line 53...59**, Now nothing is left just run the RSpec and It will test all the unit tests included in my code.

---

# Conclusion:

GitHub is providing a free machine that boots up when I push code or create a pull request. Then this machine tests the newly pushed code according to provided test cases and validates that pushed code doesn't break the previous features.

Now, when I push a code site back and relax, and when GitHub's ✅ comes to the pushed code this shows the new code is ready to be deployed without any worries.

Happy Coding!