Continuous Integration for Rails 6 with Semaphore, Travis and Coveralls Part 1

Ali Erbay
5 min readAug 28, 2020


I practiced Continous Integration from the very start when I dipped my toes into web development. I would have a really hard time thinking not using CI in any project especially where I collaborate with other fellow developers. Setting up a CI tool for projects become second nature for me. In this article, I will try to talk about CI and explain how to set it up with Semaphore and Travis for a Rails project using RSpec as a test environment.

Continuous Integration (CI) is a development practice that requires developers to integrate code into a shared repository several times a day and each integration is verified by an automated build and automated tests allowing teams to detect problems early.

By integrating regularly, you can detect errors quickly, and locate them more easily. As each change introduced is small more often than not, finding the specific code change that introduced a bug can be done swiftly.

A developer in a development team completes writing a new feature or service then the developer will commit the changes and create a Pull Request to the main branch. This is a common workflow for many developers and this happens frequently in project development. Merging and then checking the build for bugs is very heavy labor work each time when a feature is added to the master repository. Rather than doing this manual labor, CI tools can monitor the version control system, and when a PR is made it would automatically run test suites and see if anything is failing. If something is failed, the CI system will notify developers. In this way, problems and bugs can be detected earlier. Each Integration is verified by an automated build to detect integration errors as quickly as possible. This approach leads to significantly reduced integration problems and allows the team to build robust software more rapidly.

Semaphore Classic

I have used Semaphore Classic more than any other CI tool.

The very first step will be logging in Semaphore with your GitHub account. Then click on create a new project;

After that select your main repo branch, master or development branch whatever you named it

Then Semaphore will start to analyze your repo and its structure;

You don’t need to have Jobs, you can just set Setup as above. This is the bare minimum setup that you will need.

Of course, Language selection should be Ruby and you should select the correct version of your project’s Ruby version. Make sure that .ruby-version file on your repo has the correct version in it, in my case .ruby-version file should include ruby-2.5.1 .

The default database for Rails applications is SQLite. If you are using another you should change it from the dropdown menu.

If you have db/schema.rb pushed up to your Github repo, bundle exec rails db:create command is enough but to be sure you can do bundle exec rails db:setup --all db:migrate instead.

There is one more thing I need to mention. Be sure that your Gemfile.lockis on .gitignorefile before you commit and push your repo on Github. If the bundler gem you are using has 2.x.x version, Semaphore Classic will fail on setting up the build. Because they are using 1.x.x version of it. So it is better to let Semaphore create its on Gemfile.lock so that build will not fail.

Semaphore 2.0

In November 2018, Semaphore has launched Semaphore 2.0. Semaphore 2.0 is a superset of Semaphore Classic but Semaphore 2.0 has the ability to connect different pipelines, configuration YML files, caching, CLI tools. It doesn’t make assumptions about what you might want to do so it’s more customizable and a little bit harder to set up.

They are saying Semaphore Classic is not going anywhere soon so both of them are still an option.

I don’t want to showcase all of the new stuff added here but I will show you how to simply do the exact setup for a Rails project mentioned above.

The start is very much the same (follow same instructions mentioned above for Gemfile.lock and .ruby-version), Login to your Semaphore 2.0 account with your GitHub profile -> Add new project -> Select your repo from the list.

We will start from scratch, so select Single job and then click Customize;

You can create complicated pipelines in Semaphore 2.0 but this set up is just one block to serve our purpose.

I mentioned before that Semaphore 2.0 does not value convention over configuration as Semaphore Classic does.

The GitHub repository used in a Semaphore project is not automatically cloned for reasons of efficiency socheckout command line will be needed for making available the entire GitHub repository of the running Semaphore project to the VM used for executing a job of the pipeline.

The sem-service is a utility on Linux based virtual machines for starting, stopping, and getting the status of background services. Started services will listen on and their default port. The IP address includes all available network interfaces. It seems that Semaphore 2.0 does not support SQLite, so I had to use sem-service start postgres command line to set up the database. The default version is 10.6 if you don’t specify the version.

Instead of a dropdown menu, you now need to write a command to specify the language, sem-version ruby 2.5.1

The rest of the command lines are similar to Semaphore Classic, but Semaphore 2.0 creates a .semaphore/semaphore.yml file in your project root and keeps the build code inside. When you set up build code on the Semaphore web app it automatically pushes the updated semaphore.yml file to Github repo. Below you can see the example,

In my opinion, one of the best features of Semaphore 2.0 is that you don’t need to visit their website to adjust your build, you can edit in your code editor and push it to Github then with the new build commands, Semaphore 2.0 will trigger and do the job for you.

I really suggest you go and check the official documentation of Semaphore 2.0, there are tons of information there which are not included in this article.

On next part of the series, we will take a look at Travis CI and check how to implement Coveralls with Semaphore and Travis!



Ali Erbay

Full Stack Developer BDD/TDD || Ruby on Rails || React || React Native || NodeJS || Express