In this guide I am going to show you how to setup CI/CD with GitHub Actions for Rails. I assume you are running Linux and have Rails 6 installed together with PostgreSQL and Git. If you need help, I wrote a guide on how to install Rails with PostgreSQL on Ubuntu 20.04. In this tutorial we will create a basic Rails application. We will upload the application to GitHub, integrate GitHub Actions, and setup a CI/CD workflow that deploys to Heroku. Let’s begin!
Setting Up PostgreSQL
Create a PostgreSQL user for the Rails app we’ll create in the next step. To do this, switch into the postgres
user and fire up psql
:
$ sudo -u postgres -i
$ psql
Then create a new user (or “role”, as PostgreSQL calls it):
$ create role social_network with createdb login password 'password1';
To go back you type \q
to exit psql and exit
to return to your main terminal.
Creating a New Rails App
Navigate to a directory on your computer where you want to store the project (I like to use ~/dev
) and execute the following commands:
$ rails new social_network -d postgresql
$ cd social_network
Open up the config/database.yml
file in a text editor and under default
find the line that says pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
and add the following lines:
host: localhost
username: social_network
password: <%= ENV['SOCIAL_NETWORK_DATABASE_PASSWORD'] %>
We are going to need an environment variable to store the database password. The password should match the password used in the previous step. Execute the following commands:
$ echo 'export SOCIAL_NETWORK_DATABASE_PASSWORD="password1"' >> ~/.bashrc
$ source ~/.bashrc
Finally, we’ll create our database and launch our application.
$ rails db:create
$ rails server
You can now visit http://localhost:3000 and if everything has gone right you will be greeted by the following website:

Add Project to GitHub
Next up, let’s create a new repository on GitHub. You can create a new repository here once you’re logged into GitHub.

Then we want to link the GitHub repository to our local project. In the social_network
folder execute the following command:
$ git remote add origin git@github.com:your_username/social-network.git
Or if you prefer to use HTTPS instead of SSH, run the following command:
$ git remote add origin https://github.com/your_username/social-network.git
Verify that we’ve set the remote origin correctly:
$ git remote -v
origin git@github.com:your_username/social-network.git (fetch)
origin git@github.com:your_username/social-network.git (push)
Because we’ve let GitHub create a README.md and .gitignore file for us, let’s remove the the ones generated by Rails, and pull the new files (including a LICENCE file) from GitHub into our local project folder:
$ rm .gitignore README.md
$ git pull origin main
From github.com:your_username/social-network
* branch main -> FETCH_HEAD
Now to push all our local files onto GitHub, execute the following commands. Note here that we have to rename our master branch to main, GitHub no longer uses the name master in order to rid itself from references to slavery.
$ git add -A
$ git commit -m "Initial commit"
$ git branch -m master main
$ git push --set-upstream origin main
If everything went well, we’ve successfully uploaded our newly created Rails application to GitHub.
Continuous Integration with GitHub Actions
To set up GitHub Actions for our project we’ll need a workflow file. A workflow is an automated procedure that you can add to a repository. Workflows are made up of one or more jobs and can be scheduled or triggered by an event. The workflow can be used to build, test, package, release, or deploy a project on GitHub. You can read more about GitHub Actions here. In this tutorial we’re going to use a workflow to test the project and, if all tests pass, deploy the project to Heroku.
Let’s start by creating a functional workflow file. This file will be able to automatically run the, currently non-existent, tests. In your project folder create a new directory .github/workflows/
. Within the newly created workflows directory create a new workflow file social-network.yml
:
name: Social Network
on: [push]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres
ports: ['5432:5432']
env:
POSTGRES_USER: social_network
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Check out repository code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v1
with:
node-version: '14.x'
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7
bundler-cache: true
- name: Install dependencies
run: |
bundle install --jobs 4 --retry 3
yarn
- name: Set up database
run: bundle exec rails db:prepare
env:
SOCIAL_NETWORK_DATABASE_PASSWORD: postgres
- name: Run tests
run: bundle exec rails test
env:
RAILS_ENV: test
SOCIAL_NETWORK_DATABASE_PASSWORD: postgres
To understand the workflow file I recommend you take a moment to read the “Understanding the workflow file” section in the GitHub Actions documentation here. Now, commit and push the file to GitHub:
$ git add -A
$ git commit -m "Add automated tests workflow"
$ git push
Head over to GitHub and select the Actions tab in the social-network repository and click on “Add automated tests workflow”, you will see the following output:

We’ve successfully set up continuous integration! In the next section we will focus on automatic deployment to Heroku.
Continuous Deployment with GitHub Actions
Create a new Heroku account if you haven’t already got on here. Then, create a new app within Heroku here. Choose an app name and select your region, I like to prefix the app name with my last name:

In order to deploy to Heroku we will need to setup a GitHub Secret with the Heroku API key. The API key can be found here. Create a new GitHub secret:
- On GitHub, navigate to the main page of the repository.
- Under the repository name, click Settings.
- In the left sidebar, click Secrets.
- Click New repository secret.
- Type
HEROKU_API_KEY
in the Name input box. - Paste the Heroku API key in the Value input box.
We can now use this secret in the workflow file. Update the workflow file to deploy to Heroku once all tests pass:
name: Social Network
on: [push]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres
ports: ['5432:5432']
env:
POSTGRES_USER: social_network
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Check out repository code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v1
with:
node-version: '14.x'
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7
bundler-cache: true
- name: Install dependencies
run: |
bundle install --jobs 4 --retry 3
yarn
- name: Set up database
run: bundle exec rails db:prepare
env:
SOCIAL_NETWORK_DATABASE_PASSWORD: postgres
- name: Run tests
run: bundle exec rails test
env:
RAILS_ENV: test
SOCIAL_NETWORK_DATABASE_PASSWORD: postgres
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: akhileshns/heroku-deploy@v3.6.8
with:
heroku_api_key: ${{secrets.HEROKU_API_KEY}}
heroku_app_name: 'Your Heroku app name'
heroku_email: 'Your email'
In order to execute commands on Heroku once the project is deployed, we need a Procfile
. We will need to execute commands that set up the database and start the application. Go ahead and create the file in the project root directory with the following contents:
release: bundle exec rails db:prepare
web: bundle exec puma -C config/puma.rb
Commit the changes:
$ git add -A
$ git commit -m "Add automated deployment to workflow"
We are almost ready to push to GitHub. But first, add a root route so that the project knows what to display whenever a users surfs to the website. Add a function named index
to app/controllers/application_controller.rb
:
class ApplicationController < ActionController::Base
def index
render html: 'Hello, world!'
end
end
Then, add a root route to config/routes.rb
:
Rails.application.routes.draw do
root 'application#index'
end
Commit the changes once more and push to GitHub:
$ git add -A
$ git commit -m "Add root route"
$ git push
Head over to GitHub Actions and confirm that all tests pass:

And that’s it! The project is now successfully deployed to Heroku.
