This is the ultimate guide for your next Ruby on Rails project setup on Github with CircleCI for continuous integration in 2020.
So let's start with some basic knowledge.
Note: A full 1:1 "Ruby on Rails set up on Github with CircleCI" article was originally posted on our website. You can also find more tutorials already there.
What is Github?
Github is one of the top 100 websites on the Internet, with ~310M monthly visits. It holds the biggest OpenSource codebase in the world.
One can safely say that it's a proven tool in a programmers' toolbox.
Fun fact is that Ruby, with Ruby on Rails, is a big part of the Github's tech stack.
Among all the other features, Github is a remote repository hosting for the git version control system. When developers create their code, they make constant changes, additions, improvements and deletions to the codebase.
The version control system stores these code revisions in a central repository, which allows programmers to easily collaborate, as they can download the new version of the software, add their changes and upload them.
Why use Github for Ruby on Rails app?
The biggest advantage of using Github for Ruby on Rails project, as well as any other remote repository hosting provider, is that you can create constant backups of your code
Git provides a full history of changes and an ability to roll back to the older version of the code in case of introducing changes that causes errors.
With Github, it is available at any point in time, online. You are not limited to the single machine on which code was written.
Another advantage is that with its massive Open Source codebase there is a big chance that anybody that is going to collaborate with your code is going to know how to use Github, so statistically, a learning curve is the smallest possible.
Github provides an intuitive UI that allows developers to easily collaborate, with its Pull Requests, Code Review and Forks.
It even introduces its own git branching strategy, called GitHub flow.
Continuous integration for Ruby on Rails
Continuous Integration (CI) is a development practice that requires collaborators to upload their code to the shared repository continuously, ideally several times a day.
Every time they do, the code is verified by an automated build, the test suite runs and dedicated static code analysis tools check it for security vulnerabilities, errors, and all kinds of inaccuracies.
It is good for both developers and software to automatically check the code quality and CI a great place to do it.
There are multiple open-source static code analysis tools available for both Ruby and Ruby on Rails.
Most of them can be set up on the CI server to audit the code of Ruby on Rails project every time it's pushed or nightly.
Why use CircleCI for Ruby on Rails app?
CircleCI is a Continous Integration and Delivery cloud provider.
It integrates with Github, so using both of them together is as simple as creating your accounts and setting up the Ruby on Rails project.
No custom servers maintenance, just going through some web forms and you are all set.
No credit card information required, a perfect combination to start small with your project and pay for what you use as you grow.
CircleCI provides an intuitive, well-organized UI with all the information required to establish the problem that occurs when the new code was integrated into the Github hosted codebase.
It is crucial to set up the Continuous Integration system for any project, let alone Ruby on Rails, from the first day of the development.
This is a great way to avoid a lot of technical debt, protect yourself from common mistakes and enforce certain standards that make working with Ruby on Rails codebase pleasing and its maintenance much, much easier.
Create Github account and Ruby on Rails project
Follow the instructions below to create your Github account and set up the Ruby on Rails project.
1.Sign up on the official Github website.
2.Verify your email.
3.You will be redirected to the new Github repository creation page.
4.Provide the repository name and click the "Create repository" button.
5.On the new repository page, get your remote repository HTTPS or SSH link.
6.If you are using Hix on Rails, that's all you are going to need for now, just paste the address into the CLI when asked for it.
7.Navigate to the Ruby on Rails project root directory in the command line and enter git remote add origin YOUR_REPOSITORY_URL
Create CircleCI account linked to Github
Follow the instructions below to create your CircleCI account linked to your Github account, and to set up the Ruby on Rails project continuous integration.
1.Click "Sign up with Github" on the official CircleCI website.
2.On the authorization page, click "Authorize circleci".
3.You will be redirected to the CircleCI dashboard. From the left-side sidebar, select "Add Projects".
4.In the projects tab, click "Set up project" next to the newly created Github project.
Ruby on Rails project on CircleCI
If you are using Hix on Rails, that's it, all you need to do is click "Start building" after pushing the code with your first database migration, as the database creation is a part of the Ruby on Rails application build process and it will fail if no tables are present.
Otherwise, if you sadly did not automate that part of your life yet, follow steps below for Ruby on Rails project configuration on the CircleCI.
In your project root, create the required CircleCI configuration file.
cd path/to/your/project/root
mkdir .circleci
touch .circleci/config.yml
~~~{% endraw %}
Open the CircleCI configuration file with a text editor of your choice and paste the basic code required, depending on your database choice.
##Ruby on Rails with PostgreSQL on CircleCI
PostgreSQL is the most popular choice for Ruby on Rails applications.
For the CircleCI to work you are going to need a specific setup in the {% raw %}`config/database.yml`{% endraw %} file. Notice that the [dotenv-rails](https://github.com/bkeepers/dotenv) gem is used.
{% raw %}`config/database.yml`{% endraw %}{% raw %}
~~~yaml
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV['DB_POOL'] %>
username: <%= ENV['DB_USERNAME'] %>
password: <%= ENV['DB_PASSWORD'] %>
host: <%= ENV['DB_HOST'] %>
port: 5432
development:
<<: *default
database: hix_postgresql_development
test:
<<: *default
database: hix_postgresql_test
production:
<<: *default
database: hix_postgresql_production
~~~{% endraw %}
If you decided to go with it, here's the basic CircleCI configuration for the Ruby on Rails project build with the PostgreSQL database.{% raw %}
~~~yaml
version: 2.1
executors:
default:
working_directory: ~/hix_postgresql
docker:
- image: circleci/ruby:2.6.5
environment:
BUNDLE_JOBS: 3
BUNDLE_PATH: vendor/bundle
BUNDLE_RETRY: 3
BUNDLER_VERSION: 2.0.1
RAILS_ENV: test
DB_HOST: 127.0.0.1
PG_HOST: 127.0.0.1
PGUSER: hixonrails
- image: circleci/postgres:12.0
environment:
POSTGRES_DB: hix_postgresql_test
POSTGRES_USER: hixonrails
commands:
configure_bundler:
description: Configure bundler
steps:
- run:
name: Configure bundler
command: |
echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV
source $BASH_ENV
gem install bundler
jobs:
build:
executor: default
steps:
- checkout
- restore_cache:
keys:
- hix_postgresql-`{{ .Branch }}`-`{{ checksum "Gemfile.lock" }}`
- hix_postgresql-
- configure_bundler
- run:
name: Install bundle
command: bundle install
- run:
name: Wait for DB
command: dockerize -wait tcp://127.0.0.1:5432 -timeout 1m
- run:
name: Setup DB
command: bundle exec rails db:create db:schema:load --trace
- save_cache:
key: hix_postgresql-`{{ .Branch }}`-`{{ checksum "Gemfile.lock" }}`
paths:
- vendor/bundle
- persist_to_workspace:
root: ~/
paths:
- ./hix_postgresql
workflows:
version: 2
integration:
jobs:
- build
~~~
There are multiple adjustments necessary for this code to work with a particular project.
1. In the Docker Ruby image, line 7, adjust your Ruby version. At the time of writing this article the last stable version is used, 2.6.5
2. In the Docker PostgreSQL image, line 17, adjust your PostgreSQL version. At the time of writing this article the last stable version is used, 12.0.
3. In lines 16 and 20, you can adjust the PostgreSQL user name, however, it's not mandatory.
4. Replace all occurrences of the "hix_postgresql" with your Ruby on Rails project name.
For the workflow to pass on the CircleCI, you need to have {% raw %}`db/schema.rb`{% endraw %} file checked into the repository, which means that you need to create at least one database migration.
##Ruby on Rails with MySQL on CircleCI
MySQL is the second most popular choice for Ruby on Rails applications, just behind the PostgreSQL.
For the CircleCI to work you are going to need a specific setup in the {% raw %}`config/database.yml`{% endraw %} file. Notice that the [dotenv-rails](https://github.com/bkeepers/dotenv) gem is used.
{% raw %}`config/database.yml`{% endraw %}{% raw %}
~~~yaml
default: &default
adapter: mysql2
encoding: utf8
pool: <%= ENV['DB_POOL'] %>
username: <%= ENV['DB_USERNAME'] %>
password: <%= ENV['DB_PASSWORD'] %>
host: <%= ENV['DB_HOST'] %>
port: 3306
development:
<<: *default
database: hix_mysql_development
test:
<<: *default
database: hix_mysql_test
production:
<<: *default
database: hix_mysql_production
~~~{% endraw %}
If you decided to go with it, here's the basic CircleCI configuration for the Ruby on Rails project build with the PostgreSQL database.
~~~yaml
version: 2.1
executors:
default:
working_directory: ~/hix_mysql
docker:
- image: circleci/ruby:2.6.5
environment:
BUNDLE_JOBS: 3
BUNDLE_PATH: vendor/bundle
BUNDLE_RETRY: 3
BUNDLER_VERSION: 2.0.1
RAILS_ENV: test
DB_HOST: 127.0.0.1
DB_USERNAME: root
DB_PASSWORD: ''
- image: circleci/mysql:8.0.18
command: [--default-authentication-plugin=mysql_native_password]
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'true'
MYSQL_ROOT_HOST: '%'
commands:
configure_bundler:
description: Configure bundler
steps:
- run:
name: Configure bundler
command: |
echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV
source $BASH_ENV
gem install bundler
jobs:
build:
executor: default
steps:
- checkout
- restore_cache:
keys:
- hix_mysql-`{{ .Branch }}`-`{{ checksum "Gemfile.lock" }}`
- hix_mysql-
- configure_bundler
- run:
name: Install bundle
command: bundle install
- run:
name: Wait for DB
command: dockerize -wait tcp://127.0.0.1:3306 -timeout 1m
- run:
name: Setup DB
command: bundle exec rails db:create db:schema:load --trace
- save_cache:
key: hix_mysql-`{{ .Branch }}`-`{{ checksum "Gemfile.lock" }}`
paths:
- vendor/bundle
- persist_to_workspace:
root: ~/
paths:
- ./hix_mysql
workflows:
version: 2
integration:
jobs:
- build
~~~
There are multiple adjustments necessary for this code to work with a particular project.
1. In the Docker Ruby image, line 7, adjust your Ruby version. At the time of writing this article the last stable version is used, 2.6.5
2. In the Docker MySQL image, line 17, adjust your MySQL version. At the time of writing this article the last stable version is used, 8.0.18.
3. Replace all occurrences of the "hix_mysql" with your Ruby on Rails project name.
For the workflow to pass on the CircleCI, you need to have `db/schema.rb` file checked into the repository, which means that you need to create at least one database migration.
##Ruby on Rails with RSpec on CircleCI
[RSpec](https://rspec.info/) is the most popular Ruby testing framework, hence the tool of our choice.
In the continuous integration flow, running the test suite is one of the most common jobs, to ensure that new features do not break other well-tested parts of a Ruby on Rails application.
On top of that, RSpec can be easily configured with [SimpleCov, the ruby gem for generating test coverage reports](https://github.com/colszowka/simplecov). Generating those reports gives developers a nice overview on how the Ruby on Rails application is maintained.
This is the perfect job for the CircleCI, so if you have decided to go with it, edit the previously created configuration file, adding the RSpec job and running it in the defined workflow.
~~~yaml
jobs:
build:
executor: default
steps:
- checkout
- restore_cache:
keys:
- hix-`{{ .Branch }}`-`{{ checksum "Gemfile.lock" }}`
- hix-
- configure_bundler
- run:
name: Install bundle
command: bundle install
- run:
name: Wait for DB
command: dockerize -wait tcp://127.0.0.1:3306 -timeout 1m
- run:
name: Setup DB
command: bundle exec rails db:create db:schema:load --trace
- run:
name: RSpec
command: |
bundle exec rspec --profile 10 \
--format progress
- store_artifacts:
path: coverage
- save_cache:
key: hix-`{{ .Branch }}`-`{{ checksum "Gemfile.lock" }}`
paths:
- vendor/bundle
- persist_to_workspace:
root: ~/
paths:
- ./hix
workflows:
version: 2
integration:
jobs:
- build
~~~
For the RSpec to work it needs the Ruby on Rails project to be built and the database to be set up.
You can skip the part that stores the artifacts if you did not bother with the SimpleCov setup.
The profiling flag is another thing that's nice to have in the CI workflow - it tells you which tests are the slowest to run.
[Hix on Rails](https://hixonrails.com) comes additionally configured to use [Coveralls](https://coveralls.io/), which gives a nice test coverage percentage badge for your Ruby on Rails project's README.md.
##Ruby on Rails with RuboCop on CircleCI
[RuboCop](https://github.com/rubocop-hq/rubocop) is the most popular Ruby code linting tool available, with almost 400 rules checked in the default configuration.
Next to the default gem, there are plugins that check the Ruby on Rails, RSpec and Ruby code performance rules, which combined gives as the total of almost 500 rules checked, every time new code is contributed to the codebase.
If you decided to use the RuboCop in your Ruby on Rails project here's the CircleCI configuration required.{% raw %}
~~~yaml
rubocop:
executor: default
steps:
- attach_workspace:
at: ~/
- configure_bundler
- run:
name: Rubocop
command: bundle exec rubocop
workflows:
version: 2
integration:
jobs:
- build
- rubocop:
requires:
- build
~~~{% endraw %}
For the complete RuboCop setup for Ruby on Rails applications using RSpec, please read the [Ruby on Rails project RuboCop setup with RSpec](https://hixonrails.com/ruby-on-rails-tutorials/ruby-on-rails-project-rubocop-setup-with-rspec/).
##Ruby on Rails with Brakeman on CircleCI
[Brakeman](https://brakemanscanner.org/) is the most popular ruby gem for Ruby on Rails applications security vulnerabilities audit.
It provides a simple command-line tool that among the total 29 warnings, checks your Ruby on Rails application code for possible [SQL Injection](https://rails-sqli.org/) or [Cross-Site Scripting](https://excess-xss.com/) attacks.
The CircleCI continuous integration suite is the perfect place to check your code for security, so if you decided to use Brakeman in your Ruby on Rails application, here's the required CircleCI configuration.
~~~yaml
brakeman:
executor: default
steps:
- attach_workspace:
at: ~/
- configure_bundler
- run:
name: Brakeman
command: bundle exec brakeman
workflows:
version: 2
integration:
jobs:
- build
- brakeman:
requires:
- build
~~~
Remember, that using any security audit tool does not guarantee that your Ruby on Rails application is 100% safe. Please read the [Open Web Application Security Project Top 10 Project](https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project) and on top of other things, audit your website regularly with tools like Mozilla Observatory.
##Ruby on Rails with Fasterer on CircleCI
[Fast Ruby](https://github.com/JuanitoFatas/fast-ruby) is the open-source project with a multitude of various benchmarks between different Ruby methods able to achieve the same goal.
[Fasterer](https://github.com/DamirSvrtan/fasterer) is a ruby gem, a static code analysis command-line tool that's able to check your code for potentially faster solutions, based on the Fast Ruby benchmarks.
If you decide to use the Fasterer, your continuous integration flow on CircleCI is a perfect place to do so.{% raw %}
~~~yaml
fasterer:
executor: default
steps:
- attach_workspace:
at: ~/
- configure_bundler
- run:
name: Fasterer
command: bundle exec fasterer
workflows:
version: 2
integration:
jobs:
- build
- fasterer:
requires:
- build
~~~{% endraw %}
One option that is recommended to be turned off for Ruby on Rails project using Fasterer is the {% raw %}`each.with_index`{% endraw %} versus the while {% raw %}`loop`{% endraw %}, all the rest of a default configuration is good to go.
##Ruby on Rails with Rails Best Practices on CircleCI
[Rails Best Practices](https://rails-bestpractices.com/) is an old but gold blog about Ruby on Rails applications development. It explains with a great detail common Ruby on Rails (and other) patterns, like "Law of Demeter" and "Tell, don't ask".
Next to the great read, there's another static code analysis tool, called… [Rails Best Practices](https://github.com/flyerhzm/rails_best_practices). It makes sure to report any Ruby on Rails application code that does not apply to the guides written on the blog.
If you decide to use it, your continuous integration suite on CircleCI is the perfect place to do so.
~~~yaml
rails_best_practices:
executor: default
steps:
- attach_workspace:
at: ~/
- configure_bundler
- run:
name: Rails Best Practices
command: bundle exec rails_best_practices
workflows:
version: 2
integration:
jobs:
- build
- rails_best_practices:
requires:
- build
~~~
I strongly recommend against giving up on the tool only because the blog's last update was in 2014. All of the rules, as well as all the code quality checks, are still applicable in the latest Ruby on Rails version.
##Conclusion
Ruby on Rails is a very popular choice for web application development and it comes with many benefits, one of which is the well-established community knowledge on how to do things correctly.
A lot of this knowledge was forged into static code analysis tools that let developers find their mistakes easily.
CircleCI is trivial to use yet very powerful Continous Integration provider that lets you build, test and audit your Ruby on Rails application code with minimal setup, for free.
If you care about the Ruby on Rails application code quality and easy maintenance, that's the perfect combination for you.
Hope you like the tutorial! If you wish to learn more, follow us on dev.to or visit [our blog](https://hixonrails.com/ruby-on-rails-tutorials/). Thanks!
Top comments (0)