DEV Community

Cover image for GitHub Actions: Run RSpec Test On Every Push For Free
Sulman Baig
Sulman Baig

Posted on • Edited on

GitHub Actions: Run RSpec Test On Every Push For Free

GitHub Actions:

GitHub has a great feature called GitHub 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:

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
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (9)

Collapse
 
walidvb profile image
Walid

Great post, and great explanations!

I'm still struggling to get it fully working, and in particular, to understand how processes are launched, such as psql.
I have a repo containing the frontend(expo) and the backend(rails), and I use rspec to test my frontend code, which is run against a another process serving the frontend(a simple nodejs on another port, and I change Capybara.app_host).

Ideally, I would have be able to:

  1. setup and build my rails app(as described)
  2. setup and build my frontend app
  3. run a the lightweight server to serve my front end
  4. run rspec (with the other server running, to be able to load the html)

Wondering how/if this can be accomplished with github actions though!

Collapse
 
sulmanweb profile image
Sulman Baig

I have never done that. Will be nice though. Github actions is like docker try searching for some node official action and run it after ruby action is complete.

Collapse
 
walidvb profile image
Walid

that's what i'm on, but i guess the process is killed before the ruby action runs..

Thread Thread
 
sulmanweb profile image
Sulman Baig

You can call another action in one action that might help your cause.

Thread Thread
 
walidvb profile image
Walid

will keep you posted and share the solution!

Collapse
 
thadeu profile image
Thadeu Esteves Jr

missing add webpack step :)

Collapse
 
sulmanweb profile image
Sulman Baig

I used rails API only mode and vue app has babel and webpack builtin so no need to add webpack anywhere

Collapse
 
starswan profile image
Stephen Dicks

nice article, a couple of points:

  1. I couldn't get your 'on:' syntax to work
  2. The actions/setup-ruby is now unmaintained, there's a better one at ruby/setup-ruby@v1
Collapse
 
humayunnaseer profile image
HumayunNaseer

i,m facing
no schema has been selected to create in ... error
on the command => run: bin/rails db:create db:schema:load
before this i was creating the schema by pgAdmin how can i do this here?