The complete guide to setup a CI/CD for Rails 6+ on Gitlab Continuous Integration/Deployment for Rails on Gitlab What will we achieve ? The GITLAB-CI Let's do it Conclusion

2025-06-10

在 Gitlab 上为 Rails 6+ 设置 CI/CD 的完整指南

Gitlab 上 Rails 的持续集成/部署

我们将取得什么成果?

GITLAB-CI

我们开始做吧

结论

Gitlab 上 Rails 的持续集成/部署

Gitlab 管道

在这篇博文中,我们将介绍设置 Gitlab 所需的步骤,以便
在一切顺利的情况下运行 Rails 构建、测试和部署。
我将特别关注rails system test如何使它们正常工作。

我们将使用 Heroku 来部署我们的暂存应用程序。

我们将取得什么成果?

构建阶段

该构建将包含:

  • 安装依赖项
  • 数据库设置
  • 资产预编译(资产和 webpacker)

测试阶段

集成测试

在此阶段,我们将运行所有集成测试,这些测试基本上依次
运行:
bundle exec rails test

系统测试

这是我们持续集成中最令人兴奋、最重要的部分。
系统测试在测试需要大量使用
JavaScript(React 或 Vue 应用)的复杂 UI 以及与外部服务(例如)交互时非常有用Google
Map Places

系统测试将模拟普通用户,像普通用户一样在我们的应用程序上点击并填写输入。
此阶段执行的主要命令是bundle exec rails test:system

在这种情况下,交互事实是使用容器嵌入运行真实浏览器来获取和测试我们的前端。Selenium
Chrome browser

部署阶段

这是一个简单的步骤,我们将把我们的应用程序部署到暂存环境。


GITLAB-CI

Gitlab 为所有人提供了一个方案(我们应该感谢他们
所做的一切工作),该方案定义了如何测试/部署代码
以及执行这些任务所需的所有服务。
所有说明都存储.gitlab-ci在我们仓库的根目录中。

这为我们提供了一种集中简单的方法来管理我们的源代码和
持续的集成FREE

它是如何工作的

CI 遵循以下简单步骤:

  1. 启动services您在.gitlab-ci
  2. 将您的 repo 复制到主容器中。
  3. 运行其中所需的所有脚本

使用缓存加速 CI

Gitlab 允许我们缓存文件夹和文件,并在后续任务中使用它们。
无需重新编译所有依赖项,甚至无需下载它们。
就我们的情况而言,缓存所有依赖gemsnode_modules可以节省几分钟时间。

使用工件来调试我们的测试

当系统测试失败时,测试将保存screenshots在一个temp文件夹中。

artifacts使我们能够保存这些文件并将它们与工作联系起来。

当我们想要调试失败的系统测试时,这将对我们有很大帮助。


我们开始做吧

1. 构建

准备构建容器

构建将在容器中执行,因此我们应该有一个包含
所有所需依赖项的容器。

对于现代 Rails 应用程序,我们应该包括:

  • 红宝石
  • 节点 + 纱线
  • 一些系统库

这是dockerfile

FROM ruby:2.4.3

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qqy && apt-get install  -qqyy yarn nodejs postgresql postgresql-contrib libpq-dev cmake

RUN rm -rf /var/lib/apt/lists/*
Enter fullscreen mode Exit fullscreen mode

简单呀!

构建容器

docker build .
Sending build context to Docker daemon  2.048kB
Step 1/6 : FROM ruby:2.6.5
2.6.5: Pulling from library/ruby
16ea0e8c8879: Pull complete
50024b0106d5: Pull complete
ff95660c6937: Pull complete
9c7d0e5c0bc2: Pull complete
29c4fb388fdf: Pull complete
069ad1aadbe0: Pull complete
e7188792d9dd: Pull complete
bae7e74440d1: Pull complete
Digest: sha256:2285f291f222e1b53d22449cc52bad2112f519bcce60248ea1c4d5e8f14c7c04
Status: Downloaded newer image for ruby:2.6.5
 ---> 2ff4e698f315
Step 2/6 : RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
 ---> Running in abb67e50af3e
Warning: apt-key output should not be parsed (stdout is not a terminal)
OK
Removing intermediate container abb67e50af3e
 ---> 461e2dd2134d
Step 3/6 : RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
 ---> Running in 414f508a391c

## Installing the NodeSource Node.js 8.x LTS Carbon repo...

.....
Processing triggers for libc-bin (2.28-10) ...
Removing intermediate container af1183021a8d
 ---> 603cab5f6952
Step 6/6 : RUN rm -rf /var/lib/apt/lists/*
 ---> Running in 53c5950a25c1
Removing intermediate container 53c5950a25c1
 ---> 42b50699301e
Successfully built 42b50699301e

Enter fullscreen mode Exit fullscreen mode

标记

docker tag 42b50699301e registry.gitlab.com/[ORG]/[REPO]/[CONTAINER]:v1
Enter fullscreen mode Exit fullscreen mode

现在,我们应该发布这个容器以使 GitlabCI 能够使用它。

Gitlab再次免费为我们提供容器注册中心!

因此我们只需要将这个容器推送到项目注册表中。

首先,你应该登录 gitlab registry

docker login registry.gitlab.com
# use your gitlab credential
Enter fullscreen mode Exit fullscreen mode

并推

docker push registry.gitlab.com/[ORG]/[REPO]/[CONTAINER]:v1 # v1 is my version tag
Enter fullscreen mode Exit fullscreen mode

如果您的ADSL网络连接上传速度较慢,您可以去
小睡一会儿 ;)

一旦推送完成,我们就可以进入下一步。

构建脚本

这是 gitlab-ci 文件中的主要构建部分

image: "registry.gitlab.com/[ORG]/[REPO]/[CONTAINER]:v1"

variables:
  LC_ALL: C.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8
  RAILS_ENV: "test"
  POSTGRES_DB: test_db
  POSTGRES_USER: runner
  POSTGRES_PASSWORD: ""

# cache gems and node_modules for next usage
.default-cache: &default-cache
  cache:
    untracked: true
    key: my-project-key-5.2
    paths:
      - node_modules/
      - vendor/
      - public/

build:
  <<: *default-cache
  services:
    - postgres:latest
  stage: build
  script:
  - ruby -v
  - node -v
  - yarn --version
  - which ruby
  - gem install bundler  --no-ri --no-rdoc
  - bundle install  --jobs $(nproc) "${FLAGS[@]}" --path=vendor
  - yarn install
  - cp config/database.gitlab config/database.yml
  - RAILS_ENV=test bundle exec rake db:create db:schema:load
  - RAILS_ENV=test bundle exec rails assets:precompile
Enter fullscreen mode Exit fullscreen mode

因此我们使用之前创建的图像来托管构建。

我们应该在项目中添加 aconfig/database.gitlab来替换原始
数据库配置,并使用自定义主机和凭据连接到
由 GitlabCI 启动的 postgres 容器。

  services:
    - postgres:latest
Enter fullscreen mode Exit fullscreen mode

Gitlab 在读取此行时将启动数据库容器(postgress)并
使用之前定义的变量来设置数据库

  POSTGRES_DB: test_db
  POSTGRES_USER: runner
  POSTGRES_PASSWORD: ""
Enter fullscreen mode Exit fullscreen mode

它将config/database.gitlab告诉我们的 rails 应用程序如何连接数据库
,因此在应用程序启动之前,它将database.yml被自定义的数据库取代

test:
  adapter: postgresql
  encoding: unicode
  pool: 5
  timeout: 5000
  host: postgres
  username: runner
  password: ""
  database: test_db
Enter fullscreen mode Exit fullscreen mode

2.集成测试脚本

无需对此进行更多解释

integration_test:
  <<: *default-cache
  stage: test
  services:
    - postgres:latest
    - redis:alpine
  script:
    - gem install bundler  --no-ri --no-rdoc
    - bundle install  --jobs $(nproc) "${FLAGS[@]}" --path=vendor
    - cp config/database.gitlab config/database.yml
    - bundle install --jobs $(nproc) "${FLAGS[@]}" --path=vendor
    - RAILS_ENV=test bundle exec rake db:create db:schema:load
    - RAILS_ENV=test bundle exec rails assets:precompile
    - bundle exec rake test

Enter fullscreen mode Exit fullscreen mode

3. 系统测试脚本

实现系统测试的基础设施非常有趣。


要运行测试,我们应该启动一个浏览器(在容器中)并从 rails 服务器(从另一个容器)获取页面。

系统测试和容器

system_test:
  <<: *default-cache
  stage: test
  services:
    - postgres:latest
    - redis:alpine
    - selenium/standalone-chrome:latest
  script:
    - gem install bundler  --no-ri --no-rdoc
    - bundle install  --jobs $(nproc) "${FLAGS[@]}" --path=vendor
    - cp config/database.gitlab config/database.yml
    - export selenium_remote_url="http://selenium__standalone-chrome:4444/wd/hub/"
    - bundle install  --jobs $(nproc) "${FLAGS[@]}" --path=vendor
    - RAILS_ENV=test bundle exec rake db:create db:schema:load
    - RAILS_ENV=test bundle exec rails assets:precompile
    - bundle exec rake test:system
  artifacts:
    when: on_failure
    paths:
      - tmp/screenshots/
Enter fullscreen mode Exit fullscreen mode

我们应该告诉 capybara 使用正确的IP而不是localhost,因为这里我们的浏览器
和服务器在两个不同的容器中。

environment/test.rb,添加以下行

  net = Socket.ip_address_list.detect{|addr| addr.ipv4_private? }
  ip = net.nil? ? 'localhost' : net.ip_address
  config.domain = ip
  config.action_mailer.default_url_options = { :host => config.domain }

  Capybara.server_port = 8200
  Capybara.server_host = ip
Enter fullscreen mode Exit fullscreen mode

我们应该告诉系统测试在哪里找到chrome driver控制浏览器、更新application_system_test_case.rb

require "test_helper"
require "socket"


def prepare_options
  driver_options = {
    desired_capabilities: {
      chromeOptions: {
        args: %w[headless disable-gpu disable-dev-shm-usage] # preserve memory & cpu consumption
      }
    }
  }

  driver_options[:url] = ENV['selenium_remote_url'] if ENV['selenium_remote_url']

  driver_options
end

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  driven_by :selenium, using: :chrome, screen_size: [1400, 1400],
            options: prepare_options
end

Enter fullscreen mode Exit fullscreen mode

将会rails system test截取屏幕截图并保存到tmp/screenshots

系统测试和截图{:class="img-responsive"}

如您所见,屏幕截图已存储并附加到工作中,太棒了!

4. 暂存部署

build如果阶段成功,这将部署我们的代码tests

deploy_staging:
  stage: deploy
  variables:
    HEROKU_APP_NAME: YOUR_HEROKU_APP_NAME
  dependencies:
    - integration_test
    - system_test
  only:
    - master
  script:
    - gem install dpl
    - dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_API_KEY
Enter fullscreen mode Exit fullscreen mode

存储HEROKU_API_KEY在项目设置中的安全位置

Gitlab CI 变量

有关此内容的更多信息,请参阅Gitlab 变量文档


结论

Gitlab是一个令人惊叹的项目,它提供了一个非常好的平台,所有东西都
很好地集成在一起,编码体验得到了增强。

最后,让我们希望迁移能够 为项目Google compute engine提供更好的稳健性和更少的问题。

长住 Gitlab !!

干杯!

这是完整的Gitlab CI文件

鏂囩珷鏉ユ簮锛�https://dev.to/zimski/the-complete-guide-to-setup-a-cicd-for-rails-5-on-gitlab-2f2d
PREV
Portal - 一款现代文件传输实用程序🌌✨Portal
NEXT
CSS 之美 Pure CSS Gaze