Implementing a robust Continuous Integration and Continuous Deployment (CI/CD) pipeline is essential for maintaining code quality and facilitating seamless deployments in Ruby on Rails applications. Drone CI offers a flexible and powerful platform to automate testing and deployment processes. This guide provides a comprehensive Drone CI configuration template tailored for running RSpec tests in a Ruby on Rails project. By integrating RSpec with Drone CI, development teams can ensure that their codebase remains reliable and that new changes do not introduce regressions.
Add RSpec to Your Gemfile: Include the RSpec gem in both development and test groups to facilitate testing.
group :development, :test do
gem 'rspec-rails', '~> 5.0'
end
Install Dependencies: Run the following command to install the RSpec gem along with other dependencies.
bundle install
Initialize RSpec: Generate the necessary RSpec configuration files using the Rails generator.
$ rails generate rspec:install
Ensure that your config/database.yml is properly set up for the test environment. Below is an example configuration using PostgreSQL:
test:
adapter: postgresql
encoding: unicode
database: test_db
pool: 5
username: postgres
password: postgres
host: localhost
Place a .drone.yml file in the root directory of your Ruby on Rails project. This file defines the CI/CD pipeline that Drone CI will execute.
---
kind: pipeline
type: docker
name: default
steps:
- name: restore_cache
image: plugins/cache
settings:
restore: true
cache_key: cache-ruby-{{ .Branch }}
cache_restore_keys:
- cache-ruby-
paths:
- vendor/bundle
- name: setup_ruby
image: ruby:3.2.2
environment:
RAILS_ENV: test
DATABASE_URL: postgresql://postgres:postgres@database:5432/test
REDIS_URL: redis://redis:6379/0
commands:
- apt-get update && apt-get install -y nodejs postgresql-client
- gem install bundler --no-document
- bundle install --jobs=20 --retry=5
- yarn install --frozen-lockfile
- name: setup_database
image: postgres:14
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: test
commands:
- until pg_isready -h "database" -p 5432; do
echo "Waiting for PostgreSQL to be ready...";
sleep 2;
done
- bundle exec rake db:create
- bundle exec rake db:schema:load
- name: run_tests
image: ruby:3.2.2
environment:
RAILS_ENV: test
DATABASE_URL: postgresql://postgres:postgres@database:5432/test
REDIS_URL: redis://redis:6379/0
commands:
- bundle exec rspec
- name: save_cache
image: plugins/cache
settings:
rebuild: true
cache_key: cache-ruby-{{ .Branch }}
paths:
- vendor/bundle
services:
- name: database
image: postgres:14
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: test
- name: redis
image: redis:7
ports:
- 6379
cache:
- paths:
- vendor/bundle
- node_modules
trigger:
event:
- push
- pull_request
branch:
- main
- develop
Pipeline Type: Specifies the use of a Docker-based pipeline named "default".
Steps: Defines a series of tasks that Drone CI will execute sequentially.
restore_cache: Uses the plugins/cache plugin to restore cached dependencies, significantly speeding up the build process by avoiding repeated installations.
setup_ruby: Sets up the Ruby environment by installing necessary system packages like Node.js and PostgreSQL client, installs Bundler, and then installs Ruby and JavaScript dependencies using bundle install and yarn install.
setup_database: Initializes the PostgreSQL database service. It waits until the database is ready to accept connections, then creates the test database and loads the schema.
run_tests: Executes the RSpec test suite to validate the application's functionality.
save_cache: Saves the updated dependencies back to the cache for future builds.
Services: Defines external services required by the application during testing, such as PostgreSQL and Redis.
Cache Configuration: Specifies the directories to cache, including Ruby gems and Node.js modules, to optimize build times.
Trigger Conditions: Configures the pipeline to run on specific Git events, such as pushes and pull requests to the main and develop branches.
For security reasons, sensitive information like database passwords should not be hard-coded into the .drone.yml file. Instead, use Drone's Secrets management feature to store and inject these variables securely. This can be set up through the Drone CI interface and referenced in the pipeline using the secrets. keyword.
Example:
environment:
DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD}@database:5432/test
In this example, ${POSTGRES_PASSWORD} is retrieved from the secrets stored in Drone.
Implementing caching for dependencies can significantly reduce build times. The plugins/cache is utilized to store and restore the vendor/bundle and node_modules directories, which contain Ruby gems and Node.js packages respectively.
To further optimize test execution time, consider running tests in parallel. RSpec supports parallel test execution, which can be enabled by appending the --parallel flag to the rspec command:
bundle exec rspec --parallel
This approach distributes the test suite across multiple CPU cores, reducing overall test duration.
For large codebases, running the entire test suite for every change can be time-consuming. Implement selective testing by targeting specific directories or files that have changed:
commands:
- bundle exec rspec spec/models spec/controllers
This command runs tests only within the spec/models and spec/controllers directories, saving time by avoiding unnecessary test runs.
While this guide focuses on testing, integrating deployment steps into the CI/CD pipeline can automate the release process. Here's how you can add an optional deployment step:
- name: deploy
image: plugins/ssh
settings:
host: your.server.com
username: deploy_user
password:
from_secret: deploy_password
script:
- cd /path/to/app
- git pull
- bundle install
- yarn install
- bundle exec rake db:migrate
- sudo systemctl restart your_app_service
This step connects to your deployment server via SSH, pulls the latest code, installs dependencies, migrates the database, and restarts the application service. Ensure that sensitive information like SSH passwords or keys are managed securely using Drone's Secrets.
Always use Drone's Secrets management to handle sensitive data. Never commit secrets directly into your .drone.yml or version control system.
For complex projects, consider breaking down your pipeline into multiple smaller pipelines or using Drone's pipeline templates feature. This promotes reusability and maintainability.
Integrate monitoring tools and notifications to stay informed about the status of your builds and deployments. Drone CI supports various integrations, including Slack, email, and webhook notifications.
Below is a complete example of a .drone.yml file configured to run RSpec tests in a Ruby on Rails project using Drone CI:
---
kind: pipeline
type: docker
name: default
steps:
- name: restore_cache
image: plugins/cache
settings:
restore: true
cache_key: cache-ruby-{{ .Branch }}
cache_restore_keys:
- cache-ruby-
paths:
- vendor/bundle
- name: setup_ruby
image: ruby:3.2.2
environment:
RAILS_ENV: test
DATABASE_URL: postgresql://postgres:postgres@database:5432/test
REDIS_URL: redis://redis:6379/0
commands:
- apt-get update && apt-get install -y nodejs postgresql-client
- gem install bundler --no-document
- bundle install --jobs=20 --retry=5
- yarn install --frozen-lockfile
- name: setup_database
image: postgres:14
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: test
commands:
- until pg_isready -h "database" -p 5432; do
echo "Waiting for PostgreSQL to be ready...";
sleep 2;
done
- bundle exec rake db:create
- bundle exec rake db:schema:load
- name: run_tests
image: ruby:3.2.2
environment:
RAILS_ENV: test
DATABASE_URL: postgresql://postgres:postgres@database:5432/test
REDIS_URL: redis://redis:6379/0
commands:
- bundle exec rspec --parallel
- name: save_cache
image: plugins/cache
settings:
rebuild: true
cache_key: cache-ruby-{{ .Branch }}
paths:
- vendor/bundle
services:
- name: database
image: postgres:14
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: test
- name: redis
image: redis:7
ports:
- 6379
cache:
- paths:
- vendor/bundle
- node_modules
trigger:
event:
- push
- pull_request
branch:
- main
- develop
Setting up a CI/CD pipeline with Drone CI for a Ruby on Rails application enhances the development workflow by automating testing and deployment processes. By integrating RSpec tests into the Drone CI pipeline, teams can ensure code quality and reliability, facilitating faster and more confident deployments. This comprehensive guide provides a solid foundation for configuring your CI/CD pipeline, with opportunities for further optimization and customization based on your project's specific needs.