Rails Adds GitHub CI Workflow By Default To New Applications

Continuous Integration/Continuous Deployment, also known as Continuous Delivery or CI/CD, is a software development technique that aims to automate the steps involved in integrating code changes into a shared source code repository, testing those changes, and automatically deploying those changes to target environments without the need for human intervention.

It makes early error detection easier and minimises the amount of code that needs to be debugged by a developer to identify the fault’s source.

It also forms the basis of contemporary DevOps operations, facilitating more fluid and agile collaboration between development and operations teams.

Several well-known CI/CD solutions include AWS CodeDeploy, GitHub CI, GitLab, TeamCity, Bamboo and Jenkins.

GitHub CI/CD

GitHub Actions is a powerful CI/CD tool provided by GitHub that gives developers the ability to automate their processes to build, test, and release software. It provides customizable CI/CD starter workflows that are suited for different languages and frameworks, enabling quick setup for for deployment, testing, and package installation tasks.

Before

Before Rails 7.2, we had to manually integrate GitHub CI workflow to our project.

Integrating GitHub CI/CD with a Rails application is relatively straightforward. Here’s a step-by-step guide to get started:

  • Make a folder named .github/workflows in our Rails project’s root directory.

  • Inside this folder, create a YAML file (for example, ci.yml) to outline our CI/CD workflow.

  • Define the tasks we want to automate, like running tests, building app, and deploying to staging or production.

  • Specify triggers for when the workflow should kick off, such as whenever code is pushed to a particular branch or when a pull request is initiated.

Here’s a basic example of a GitHub CI/CD workflow for a Rails application:

name: CI Test Suite
on:
  push:
    branches: [develop, main]
  pull_request:
    types: [labeled, opened, synchronize, reopened]
  workflow_dispatch:

jobs:
  tests:
    name: Running tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Setup PostgreSQL
        uses: Harmon758/[email protected]
        with:
          postgresql version: 14.9-alpine3.18
          postgresql db: test
          postgresql user: root
          postgresql password: "password"

      - name: Setup Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.0.0

      - name: Install gems
        run: |
          bundle config path vendor/bundle
          bundle install --jobs 4 --retry 3

      - name: Run Rubocop
        run: |
          bundle exec rubocop

      - name: Run tests
        run:
          bundle exec rspec --exclude-pattern "spec/system/**/*_spec.rb"

After

Rails 7.2 now includes Brakeman and RuboCop, and it also ships with a default GitHub CI workflow.

On executing rails new <app_name>, we will notice two new files with default configurations, making it easier for newcomers to have good start with automated scanning, linting, testing and contributing effectively right from the start.

.github/workflows/ci.yml
.github/dependabot.yml

If we don’t want GitHub CI workflow in our Rails application, we can skip it by passing --skip-ci flag while creating the app.

Here is the default .github/workflows/ci.yml

name: CI

on:
  pull_request:
  push:
    branches: [ main ]

jobs:
  scan_ruby:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: .ruby-version
          bundler-cache: true

      - name: Scan for security vulnerabilities in Ruby dependencies
        run: bin/brakeman --no-pager

  scan_js:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: .ruby-version
          bundler-cache: true

      - name: Scan for security vulnerabilities in JavaScript dependencies
        run: bin/importmap audit

  lint:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: .ruby-version
          bundler-cache: true

      - name: Lint code for consistent style
        run: bin/rubocop -f github

  test:
    runs-on: ubuntu-latest

    # services:
    #  redis:
    #    image: redis
    #    ports:
    #      - 6379:6379
    #    options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
    steps:
      - name: Install packages
        run: sudo apt-get update && sudo apt-get install --no-install-recommends -y google-chrome-stable curl libjemalloc2 libsqlite3-0 libvips 

      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: .ruby-version
          bundler-cache: true

      - name: Run tests
        env:
          RAILS_ENV: test
          # REDIS_URL: redis://localhost:6379/0
        run: bin/rails db:setup test test:system

      - name: Keep screenshots from failed system tests
        uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: screenshots
          path: $/tmp/screenshots
          if-no-files-found: ignore

Conclusion

By automating the testing and deployment processes, we can ensure our application is always in a reliable state and ready for release.

GitHub Actions flexibility and integration with our existing repositories make it an ideal choice for streamlining our development workflow.

Need help on your Ruby on Rails or React project?

Join Our Newsletter