Building a CI Pipeline using Github Actions for Sharetribe and RoR

Building a CI Pipeline using Github Actions for Sharetribe and RoR

Continuous Integration (CI) is a crucial part of modern software development workflows. It helps ensure that changes to the codebase are regularly integrated and tested, reducing the risk of introducing bugs and maintaining a high level of code quality. Github Actions is a powerful tool that enables developers to create custom workflows for their CI/CD needs. In this article, we will walk you through building a CI pipeline using Github Actions for Sharetribe , a popular online marketplace platform written in Ruby on Rails . However, the CI pipeline written below can be adapted to any Ruby on Rails project.

Prerequisites

Before we start, make sure you have the following:

  1. A Github repository set up for your Sharetribe project.

  2. Basic knowledge of Github Actions and YAML syntax.

Setting up the CI Pipeline

The first step is to create a .github/workflows directory at the root of your Github repository. Inside this directory, create a YAML file, e.g., ci.yml, and add the following content:

name: Continuous Integration
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

The on section specifies when the CI pipeline should be triggered. In this case, it will be triggered on push events to the specified branches and when pull requests are opened targeting those branches.

Next, we define the jobs that make up our CI pipeline. For Sharetribe, we’ll start with a test job. Add the following to your YAML file:

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:5.7
        env:
          MYSQL_HOST: 127.0.0.1
          MYSQL_DB: sharetribe_local_test
          MYSQL_ALLOW_EMPTY_PASSWORD: yes
          MYSQL_ROOT_PASSWORD: root
        ports:
          - "3306:3306"
        options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
      # How to use Redis
      redis:
        image: redis
        ports:
        - 6379/tcp
    steps:
      # Add steps here

This test job runs on an ubuntu-latest runner and sets up MySQL and Redis services using Docker images. These services are essential for running tests in the Sharetribe environment.

Now, let’s add the steps required to set up the Sharetribe environment and run tests. The following steps will help you get started:

      - uses: actions/checkout@v3

      # Cache Ubuntu packages to speed up builds
      - uses: awalsh128/cache-apt-pkgs-action@latest
        with:
          packages: unixodbc wget nano build-essential libpq-dev shared-mime-info
          version: 1.0

      # Install Sphinx
      - name: Install Sphinx
        run: |
          mkdir -pv /opt/sphinx/log /opt/sphinx/index
          wget http://sphinxsearch.com/files/sphinx-2.2.11-release.tar.gz -O /tmp/sphinxsearch.tar.gz
          cd /opt/sphinx && tar -xf /tmp/sphinxsearch.tar.gz
          rm /tmp/sphinxsearch.tar.gz
          sudo apt-get install sphinxsearch

      # Fix Ownership
      - name: Fix Ownership
        run: |
              mkdir -p \
              app/assets/webpack \
              public/assets \
              public/webpack \
              && sudo chown -R $(whoami) \
              $HOME/work/marketplace/marketplace/app/assets/javascripts \
              $HOME/work/marketplace/marketplace/app/assets/webpack \
              $HOME/work/marketplace/marketplace/client/app/ \
              $HOME/work/marketplace/marketplace/public/assets \
              $HOME/work/marketplace/marketplace/public/webpack \
              $HOME/work/marketplace/marketplace/config/

      # Use Node.js 10.15.3
      - name: Use Node.js 10.15.3
        uses: actions/setup-node@v3
        with:
          node-version: 10.15.3

      # Cache NPM dependencies to speed up builds
      - uses: c-hive/gha-npm-cache@v1
        id: cache
        with:
          directory: client

      # Install JS dependencies
      - name: Install JS dependencies
        run: npm install

      # Setup Ruby environment and cache bundler
      - name: Setup Ruby
        uses: ruby/setup-ruby@v1
        with:
          bundler-cache: true

      # Create and load the database
      - name: Create and load database
        env: 
          MYSQL_ROOT_PASSWORD: root
          DB_PORT: ${{ job.services.mysql.ports[3306] }} # get randomly assigned published port
          REDIS_PORT: ${{ job.services.redis.ports[6379] }}
        run: |
          RAILS_ENV=test bundle exec rake db:create
          RAILS_ENV=test bundle exec rake db:structure:load
          RAILS_ENV=test bundle exec rails db:migrate

      # Configure Sphinx and precompile assets
      - name: Configure Sphinx and precompile assets
        env: 
          MYSQL_ROOT_PASSWORD: root
          DB_PORT: ${{ job.services.mysql.ports[3306] }} # get randomly assigned published port
          REDIS_PORT: ${{ job.services.redis.ports[6379] }}
          RAILS_ENV: test
        run: |
          RAILS_ENV=test bundle exec rake ts:configure
          script/prepare-assets.sh

      # Run tests
      - name: Run tests
        env: 
          MYSQL_ROOT_PASSWORD: root
          DB_PORT: ${{ job.services.mysql.ports[3306] }} # get randomly assigned published port
          REDIS_PORT: ${{ job.services.redis.ports[6379] }}
          stripe_key: ${{ secrets.STRIPE_KEY }}
          stripe_publishable_key: ${{ secrets.STRIPE_PUBLISHABLE_KEY }}
          stripe_private_key_pattern: ${{ secrets.STRIPE_PRIVATE_KEY_PATTERN }}
          stripe_publishable_key_pattern: ${{ secrets.STRIPE_PUBLISHABLE_KEY_PATTERN }}
          stripe_payout_delay: ${{ secrets.STRIPE_PAYOUT_DELAY }}
          stripe_expiration_period: ${{ secrets.STRIPE_EXPIRATION_PERIOD }}
          stripe_charges_mode: ${{ secrets.STRIPE_CHARGES_MODE }}
        run: |
          bundle exec rails db:environment:set RAILS_ENV=test
          bundle exec rspec

      # Coverage analysis
      - uses: joshmfrankel/simplecov-check-action@main
        with:
          minimum_suite_coverage: 70
          minimum_file_coverage: 70
          github_token: ${{ secrets.GITHUB_TOKEN }}

This completes the CI pipeline setup. Let’s go through some of the key steps in the pipeline:

  • We check out the repository using actions/checkout@v3.

  • We cache Ubuntu packages and NPM dependencies to speed up subsequent builds.

  • We install Sphinx, fix file ownership, and set up the required Ruby and Node.js environments.

  • We create and load the database and configure Sphinx before running tests.

  • Finally, we perform coverage analysis to ensure sufficient test coverage.

Configuring Secrets

As you can see, we use environment variables to configure the Sharetribe environment during the CI pipeline. Some of these values, such as the Stripe keys, should be kept secret. Github Actions allows you to store these secrets as encrypted environment variables in the repository settings. To use them, add the necessary secrets in the repository settings and reference them in the env section of the pipeline steps.

Conclusion

Congratulations! You have successfully set up a CI pipeline using Github Actions for Sharetribe/ Ruby on Rails. With this pipeline in place, your codebase will be continuously integrated, tested, and analyzed for code coverage. Remember to regularly review your CI pipeline and update it as your project evolves. Continuous improvement is key to successful software development. Happy coding!

References

comments powered by Disqus

Related Posts

Exploring if Large Language Models possess consciousness

Exploring if Large Language Models possess consciousness

As technology continues to advance, the development of large language models has become a topic of great interest and debate. These models, such as OpenAI’s GPT-4, are capable of generating coherent and contextually relevant text that often mimics human-like language patterns.

Read more
Fine-Tuning Alpaca: Enabling Communication between LLMs on my M1 Macbook Pro

Fine-Tuning Alpaca: Enabling Communication between LLMs on my M1 Macbook Pro

In this blog post, I will share a piece of the work I created for my thesis, which focused on analyzing student-tutor dialogues and developing a text generation system that enabled communication between a student chatbot and a tutor chatbot.

Read more
Comparative Analysis of Text Prediction in Gmail and Outlook

Comparative Analysis of Text Prediction in Gmail and Outlook

The use of communication tools like chat and email to complete daily activities is becoming more and more crucial. Time can be saved and productivity increased with accurate real-time phrase completion.

Read more