Streamlining Rails Development with GitHub CI/CD

railsFebruary 20, 2024Dotby Alkesh Ghorpade

Introduction

In the world of software development, efficiency and automation are essential. Continuous Integration and Continuous Deployment (CI/CD) pipelines have become indispensable tools for modern development workflows. GitHub CI/CD, integrated within the popular code repository platform GitHub, provides a seamless solution for automating the testing and deployment processes. In this blog post, we'll explore how GitHub CI/CD can be leveraged in Rails development to streamline workflows and enhance productivity.

Understanding GitHub CI/CD:

GitHub CI/CD is a feature offered by GitHub that allows developers to automate the process of testing and deploying their applications directly from their GitHub repositories. It enables developers to define workflows using YAML configuration files, which specify the steps to be executed whenever there's a new commit or pull request.

What is Continuous Integration (CI)?

Continuous Integration (CI) transforms software development by enabling developers to push code changes frequently to a shared repository (like GitHub). This triggers automated testing, catching errors early and saving time. Team members can then collaborate by reviewing and suggesting adjustments to the code. If all tests pass, the changes seamlessly merge into the main project, streamlining development.

Development teams can iterate and build software faster by continuously pushing, testing, and integrating code. CI servers like GitHub monitor for new changes, keeping everyone in sync.

What is Continuous Delivery?

Continuous Delivery employs a manual approval gate before deploying your code changes to production.

What is Continuous Deployment?

In Continuous Delivery (CD), code changes that pass automated tests are automatically prepared for deployment but typically require manual approval before going live. This can lead to delays compared to Continuous Deployment (CI/CD), which automates the entire process, deploying changes directly to production upon successful testing.

Stages of the CI/CD pipeline

  • Build Stage

    The build stage in a CI/CD pipeline for Rails applications plays a crucial role in preparing the code for testing and deployment. Here's what it typically involves:

    1. Setting up the environment:

      • Download and install Ruby and necessary dependencies:

        This usually involves tools like rbenv or rvm to manage Ruby versions and install gems required by your application.

      • Build assets:

        If your application uses assets like images or stylesheets, this stage might include compiling them with tools like webpack or sprockets.

      • Configure the database:

        This could involve setting up connection details, running migrations, and seeding data for testing.

    2. Install dependencies:

      • Bundle installation:

        This stage typically uses tools like Bundler to download and install all the gems specified in your Gemfile or Gemfile.lock. This ensures you have the correct versions of all necessary dependencies.

    3. Code analysis:

      • Static code analysis:

        Tools like RuboCop can be used to check for stylistic inconsistencies, potential code smells, and possible security vulnerabilities.

    4. Build artifacts:

      Depending on your deployment strategy, this stage might involve packaging your application into a deployable format. For example, you could create a Docker image or a compressed archive containing your code and assets.

  • Test Stage

    In a Rails CI/CD pipeline, the test stage is where you verify the functionality and integrity of your application after it's been built in the previous stage. This stage plays a vital role in ensuring the quality and stability of your code before deployment. Here's what it typically involves:

    1. Test types:

      • Unit tests:

        These tests focus on individual units of code (methods, classes) to verify they function as expected. Tools like RSpec, MiniTest, or Shoulda are commonly used.

      • Integration tests:

        These tests verify how different components of your application interact with each other. Tools like Capybara and Webdrivers are often used to simulate user interactions.

      • Feature tests:

        These tests cover broader functionalities of your application, mimicking real-world user scenarios. Capybara and Webdrivers are also standard tools for this type.

      • End-to-end tests:

        These tests simulate user journeys through your entire application, ensuring everything works seamlessly from start to finish. Again, Capybara and Webdrivers are popular choices.

    2. Test execution:

      • The test stage usually runs all the test types mentioned above, possibly in a specific order depending on their complexity and dependencies.

      • Each test suite is typically executed in a parallel fashion to optimize overall testing speed.

      • Test results are collected and reported, highlighting any failures or errors encountered.

    The test stage is crucial for catching bugs and ensuring your Rails application functions as intended before deployment. A well-designed test suite with different test types, high coverage, and efficient execution helps build confidence and deliver a high-quality product.

  • Deploy Stage

    In a Rails CI/CD pipeline, the deploy stage is where your application is made available to users after successfully passing the build and test stages or integrated into your production environment. This stage involves carefully transferring your code and assets to the target deployment location. Here's how it typically unfolds:

    1. Deployment strategy:

      • Manual deployment:

        This involves manual steps to transfer the application files (e.g., through SSH, web UI). While less complex, it's prone to errors and slower than automated approaches.

      • Platform-specific deployment:

        Services like Heroku, AWS Elastic Beanstalk, or Google App Engine offer built-in deployment mechanisms for Rails applications, simplifying the process.

      • Containerized deployment:

        Packaging your application as a Docker image allows consistent and portable deployment across different environments.

    2. Deployment steps:

      • Transferring files:

        Based on your chosen strategy, this might involve pushing code to a remote repository, uploading artifacts to a platform, or building and pushing Docker images.

      • Environment setup:

        Configure database connections, application settings, and environment variables on the target server if necessary.

      • Running migrations:

        Apply any database migrations needed to update the schema for the deployed version.

      • Pre-deployment checks:

        Conduct final checks for errors or inconsistencies before making the application publicly available.

      • Rolling deployment:

        Depending on your strategy, you might deploy in stages (e.g., canary deployments) to minimize downtime and roll back quickly if issues arise.

    Overall, the deployment stage in a Rails CI/CD pipeline automates and simplifies the process of delivering your application to users while ensuring a smooth and controlled rollout.

What are GitHub Actions?

GitHub Actions is a CI/CD platform that streamlines software development by automating code builds, tests, and deployment pipelines. Its reusable "actions" simplify complex workflows, enabling you to create automatic tests for every pull request developers submit. Significantly, GitHub Actions can trigger these workflows based on various events within your repository, like new issues, pull requests, or scheduled times. This automation empowers you to deploy approved pull requests directly to production seamlessly.

Create a Workflow with GitHub Actions

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

  1. Create a .github/workflows directory at the root of your Rails project.

  2. Create a YAML file (e.g., ci.yml) within this directory to define your CI/CD workflow.

  3. Define the jobs and steps within the YAML file. For example, you might have steps for running tests, building the application, and deploying to staging or production environments.

  4. Specify triggers for when the workflow should be executed, such as on every push to a specific branch or when a pull request is opened.

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

    name: Rails CI/CD
    
    on:
     push:
       branches: [ main ]
    
    jobs:
      build:
        runs-on: ubuntu-latest
    
        steps:
          - name: Checkout code
            uses: actions/checkout@v2
    
          - name: Set up Ruby
            uses: ruby/setup-ruby@v1
            with:
              ruby-version: 3.0.0
    
          - name: Install dependencies
            run: bundle install
    
          - name: Run tests
            run: bundle exec rspec
    
     # Additional steps for deployment can be added here

    The example above provides a Rails application's basic CI/CD setup. However, workflows can be customized to fit the specific needs of your project. You can add steps for deploying to different environments, running additional tests (such as integration or end-to-end tests), or even performing code quality checks.

Benefits of GitHub CI/CD

GitHub CI/CD (Continuous Integration/Continuous Deployment) offers numerous benefits for software development teams.

  • Increased speed and efficiency:

    1. Faster deployments:

      Automate building, testing, and deploying code changes, leading to quicker releases and shorter feedback loops.

    2. Reduced manual work:

      Free up developers' time by automating repetitive tasks, allowing them to focus on higher-level work.

  • Improved software quality:

    1. Early detection of bugs:

      Run tests automatically after every change, catching issues early and preventing them from reaching production.

    2. Consistent quality:

      Ensure all code changes go through the same build and test process, leading to more consistent quality across the codebase.

  • Enhanced collaboration:

    1. Real-time visibility:

      Everyone involved can see the progress of deployments and tests, fostering better communication and collaboration.

    2. Easy code sharing:

      Integrate with pull requests, allowing developers to see the impact of their changes before they're merged.

In Rails 8

As Rails 8 added Brakeman and RuboCop, the team decided to add a default GitHub CI workflow file for new applications.

On executing rails new <app_name>, you will see two new files with defaults.

  1. .github/workflows/ci.yml
  2. .github/dependabot.yml

Newcomers will be especially well-served by this automated scanning, linting, and testing approach, making it easier for them to jump in and contribute effectively.

To know more about this feature, please refer to this PR.

Closing Remark

Could your team use some help with topics like this and others covered by ShakaCode's blog and open source? We specialize in optimizing Rails applications, especially those with advanced JavaScript frontends, like React. We can also help you optimize your CI processes with lower costs and faster, more reliable tests. Scraping web data and lowering infrastructure costs are two other areas of specialization. Feel free to reach out to ShakaCode's CEO, Justin Gordon, at justin@shakacode.com or schedule an appointment to discuss how ShakaCode can help your project!
Are you looking for a software development partner who can
develop modern, high-performance web apps and sites?
See what we've doneArrow right