How To Build a CI/CD Pipeline for Ruby on Rails
🎧 Spotlights
Hey there,
This week, I've been working with Ruby on Rails. I wanted to share a deployment approach: Continuous Integration and Continuous Delivery (CI/CD).
CI/CD automates the software development lifecycle. It allows the team to build, test, and deploy your Ruby on Rails applications with every code change. By leveraging GitHub Actions, you can set up workflows to catch issues early and push updates live faster.
I've included examples of implementing CI/CD for your Ruby on Rails projects, from running tests on every push to automating deployments.
Once you set up these pipelines, you'll save valuable time and enjoy the benefits throughout your project.
Do you want to make your software development process faster and easier?
Imagine being able to build, test, and deploy your Ruby on Rails applications every time you change your code. With CI/CD, you can save a lot of time and focus more on creating incredible software, which means you can release updates faster and more.
Getting started with CI/CD has always been challenging! GitHub Actions is free and super simple to use.
What Is Continuous Integration And Delivery?
First, let’s explain what CI/CD is.
CI/CD is a way to deliver new features more often by automating the software development process.
Continuous Integration (CI) means that code is built and tested whenever new code is added to your project. This helps catch mistakes early.
Continuous Delivery (CD) automates the deployment part. When you make a change, and it gets merged into the main code, this step puts those changes into the live version of your application.
Continuous Integration With GitHub Actions
If you’re using GitHub, starting with Continuous Integration is super easy!
You can use GitHub Actions to automate your build, test, and deployment process. You can create workflows that build and test your code whenever you push changes or deploy it when you make a new version.
Write a workflow that runs when something happens in your repository, like pushing code to the main branch or creating a new tag.
Here’s an example of a GitHub Actions workflow to build and test a Ruby on Rails project:
name: Ruby on Rails CI
on:
push:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:alpine
env:
POSTGRES_DB: myapp_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
ports:
- 5432:5432
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.0
- name: Install dependencies
run: bundle install
- name: Run tests
run: bundle exec rspec
Here’s what’s happening in this workflow:
This workflow runs every time you push code to the main branch.
This lets your tests run against a test database.
The `bundle install` command installs all the necessary gems for your application.
- Running tests: The tests are executed using RSpec to ensure your application works as it should.
You can add this to your GitHub repository today and start getting instant feedback whenever you commit code.
You'll get notified if something goes wrong during the build or a test fails!
Continuous Delivery With GitHub Actions
While Continuous Integration is a great start, the real magic happens when you automate your deployment process.
Imagine this:
You make a change to your code.
That change triggers the deployment pipeline.
A few minutes later, your updates are live for everyone to see!
It’s usually a bit more complex because we must consider configuration and database changes, but you get the idea!
If you’re running your application on a server or in the cloud, you can deploy it using a GitHub Action.
Here’s an example of a deployment pipeline I use to publish my Ruby on Rails application:
name: Ruby on Rails CI
on:
push:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:alpine
env:
POSTGRES_DB: myapp_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
ports:
- 5432:5432
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.0
- name: Install dependencies
run: bundle install
- name: Run tests
run: bundle exec rspec
Here’s what’s different in this workflow:
This step makes sure your assets are ready for production.
The SSH command pulls the latest code, installs dependencies, runs database migrations, and restarts the server.
If you are enjoying the learning journal, please ❤️
You can use GitHub secrets to keep secret information safe in your workflows. You can define these secrets on GitHub and use them in your actions without exposing them in your code.
Think about how much time you spend on deployments. You might be surprised at how much time you could save by automating them!
The best part is that once you set up your build and deployment pipelines, you can continue to enjoy them throughout your project.
If someone will benefit from this content, please share.
💻 👓
Form-Specific Validations
Avoid: Including validations specific to a particular form or context directly in your Active Record models.
Why: Form-specific validations can lead to tightly coupled code and make it difficult to reuse models across different forms or contexts. Instead, use form objects to encapsulate these validations.
Example of What to Avoid:
class User < ApplicationRecord
validates :password, presence: true, if: :new_record?
end
Suggested Approach Using Form Objects:
class UserForm
include ActiveModel::Model
attr_accessor :name, :email, :password
validates :email, presence: true, uniqueness: true
validates :name, presence: true
validates :password, presence: true, if: :new_record?
def save
return false unless valid?
User.create(name: name, email: email, password: password)
end
end
Github Repo: Alt Rails
🧪 Next Actions
Moving back to do some Go
Keep expanding on Ruby on Rails patterns to improve maintenance
Might delve a bit in Typescript