Ruby on Rails 的 CI:GitHub Actions Ruby on Rails 的 CI:GitHub Actions 与 CircleCI

2025-06-04

Ruby on Rails 的 CI:GitHub Actions

Ruby on Rails 的 CI:GitHub Actions 与 CircleCI

Ruby on Rails 的 CI:GitHub Actions 与 CircleCI

这是由三部分组成的系列文章的一部分,我将引导您使用 GitHub Actions、CircleCI 设置您的 CI 套件,然后比较如果您要为 Rails 应用程序设置持续集成,您可能需要使用哪个套件。

第 1 部分:GitHub Actions

1. 设置操作名称

name: Run Tests & Linters
Enter fullscreen mode Exit fullscreen mode

2. 设置触发操作运行的事件

name: Run Tests & Linters

on:
  pull_request:
    branches:
      - '*'
  push:
    branches:
      - master
Enter fullscreen mode Exit fullscreen mode

这意味着,只要在任何分支上更新 pull_request 并且推送到 master 时,此操作就会运行。

3. 创建您的作业,并选择要运行操作的对象

jobs:
  build:
    runs-on: ubuntu-latest
Enter fullscreen mode Exit fullscreen mode

这告诉我们的操作我们想要在 Ubuntu 上运行该操作,并使用 GitHub 提供的最新版本,即 Ubuntu 18.04。

4. 定义服务

对于典型的 Rails 应用,您可能使用 Redis 来缓存像 Sidekiq 这样的工具,并且可能还拥有一个数据库。在操作中定义服务允许我们使用额外的容器来运行这些类型的工具。

services:
  postgres: # The name of the service
    image: postgres:11 # A docker image
    env: # Environment variables you want to use inside the service
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: postgres
    ports: ['5432:5432'] # The port that you can access the service on
    options: >- # Options for the service, in this case we want to make sure that the Postgres container passes a health check
      --health-cmd pg_isready
      --health-interval 10s
      --health-timeout 5s
      --health-retries 5
  redis: # The name of the service
    image: redis # A docker image
    ports: ['6379:6379'] # The ports that you can access the service on
    options: --entrypoint redis-server # Options for the service
Enter fullscreen mode Exit fullscreen mode

5. 设置依赖项并检出分支

对我来说,这有点棘手。如果你搜索“在 Rails 中使用 GitHub Actions”,你可能会看到类似这样的内容:

- uses: actions/checkout@v1
- name: Setup Ruby
  uses: actions/setup-ruby@v1
  with:
    ruby-version: 2.6.x
- uses: borales/actions-yarn@v2.0.0
  with:
    cmd: install
Enter fullscreen mode Exit fullscreen mode

这个特殊的例子来自我的朋友Chris Oliver,他负责Go Rails(看看吧!!)。

这个解决方案本来很棒,但除了:

  • GitHub 上提供的最新 Ruby 版本是 Ruby 2.6.3
  • GitHub 上提供的最新 Node 版本是 Node 12.13.1

CodeFund,我们使用的是 Ruby 2.6.5(即将升级到 2.7)和 Node 13.0.1。针对这个问题,已经提出了一些解决方案,比如使用ruby​​ build从源代码安装所需的 Ruby 版本,或者使用nvm之类的工具。这些方法可能对你有用,但速度可能很慢,而且对于我以后遇到的问题也不起作用。因此,我编写了自己的 Docker 镜像,其中已经内置了我需要的一切。Ruby 2.6.5、Node 13.0.1、Postgres 所需的附加软件包、用于系统测试的 Chrome、Bundler 2.0.2 以及我的通用环境变量。

我不会在这里解释所有的细节,我知道我可以稍微缩小尺寸,但这是该图像的第一次迭代:

FROM ruby:2.6.5

LABEL "name"="Locomotive"
LABEL "version"="0.0.1"

ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
ENV BUNDLE_PATH='/bundle/vendor'
ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US.UTF-8
ENV LC_ALL=C.UTF-8
ENV PG_HOST='postgres'
ENV PG_PASSWORD='postgres'
ENV PG_USERNAME='postgres'
ENV RACK_ENV='test'
ENV RAILS_ENV='test'
ENV REDIS_CACHE_URL='redis://redis:6379/0'
ENV REDIS_QUEUE_URL='redis://redis:6379/0'

RUN  curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
     echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
     curl -sL https://deb.nodesource.com/setup_13.x | bash - && \
     wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
     echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" | tee /etc/apt/sources.list.d/google-chrome.list && \
     apt-get update && \
     apt-get install -y google-chrome-stable && \
     echo "CHROME_BIN=/usr/bin/google-chrome" | tee -a /etc/environment && \
     wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - && \
     echo 'deb http://dl.google.com/linux/chrome/deb/ stable main' | tee /etc/apt/sources.list.d/google-chrome.list && \
     apt-get -yqq install libpq-dev && \
     apt-get install -qq -y google-chrome-stable yarn nodejs postgresql postgresql-contrib

RUN gem install bundler:2.0.2
Enter fullscreen mode Exit fullscreen mode

6. 使用Docker容器

container:
      image: andrewmcodes/locomotive:v0.0.1 # my image name
      env: # additional environment variables I want to have access to
        DEFAULT_HOST: app.codefund.io
Enter fullscreen mode Exit fullscreen mode

注意:如果您未设置容器,则所有步骤将直接在指定的主机上运行,​​如果您还记得的话,该主机是 Ubuntu 18.04。

截至目前,我们的行动如下:

name: Run Tests & Linters

on:
  pull_request:
    branches:
      - '*'
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:11
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: postgres
        ports: ['5432:5432']
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
      redis:
        image: redis
        ports: ['6379:6379']
        options: --entrypoint redis-server
    container:
      image: andrewmcodes/locomotive:v0.0.1
      env:
        DEFAULT_HOST: app.codefund.io
Enter fullscreen mode Exit fullscreen mode

7.添加步骤

现在是时候在容器内运行命令了。我们先来检查一下代码。

steps:
  - uses: actions/checkout@v2
Enter fullscreen mode Exit fullscreen mode

8.缓存

值得庆幸的是,GitHub 提供了一些示例,可以帮助你开始使用你选择的缓存依赖项工具。我建议你查看这些示例以及文档。

GitHub Actions 缓存示例
缓存文档

注意:单个缓存的最大大小为 400MB,单个仓库最多可拥有 2GB 的缓存。达到 2GB 的限制后,较旧的缓存将根据上次访问的时间进行清除。过去一周内未访问的缓存也将被清除。

 - name: Get Yarn Cache
   id: yarn-cache
   run: echo "::set-output name=dir::$(yarn cache dir)"

 - name: Node Modules Cache
   id: node-modules-cache
   uses: actions/cache@v1
   with:
     path: ${{ steps.yarn-cache.outputs.dir }}
     key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
     restore-keys: |
       ${{ runner.os }}-yarn-

 - name: Gems Cache
   id: gem-cache
   uses: actions/cache@v1
   with:
     path: vendor/bundle
     key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
     restore-keys: |
       ${{ runner.os }}-gem-

 - name: Assets Cache
   id: assets-cache
   uses: actions/cache@v1
   with:
     path: public/packs-test
     key: ${{ runner.os }}-assets-${{ steps.extract_branch.outputs.branch }}
     restore-keys: |
       ${{ runner.os }}-assets-
Enter fullscreen mode Exit fullscreen mode

9. 捆绑、Yarn 和预编译资产

接下来,如果我们的依赖项没有从缓存中恢复,我们将运行 Bundler 和 Yarn 来安装它们,并预编译我们的资产。

 - name: Bundle Install
   run: bundle check || bundle install --path vendor/bundle --jobs 4 --retry 3

 - name: Yarn Install
   run: yarn check || bin/rails yarn:install

 - name: Compile Assets
   run: |
      if [[ ! -d public/packs-test ]]; then
        bin/rails webpacker:compile
      else
        echo "No need to compile assets."
      fi
Enter fullscreen mode Exit fullscreen mode

注意:您可能可以跳过资产编译,这取决于您。

10.更新一些文件

为了使其正常工作,我必须对项目中的某些文件进行一些更新。

  1. config/database.yml更新测试主机为:host: <%= ENV.fetch("PG_HOST", "localhost") %>
  2. 更新test/application_system_test_case.rb
     require "test_helper"

     class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
       driven_by :selenium, using: :headless_chrome, screen_size: [1400,1400] do |driver_options|
        driver_options.add_argument("--disable-dev-shm-usage")
        driver_options.add_argument("--no-sandbox")
      end
    end
Enter fullscreen mode Exit fullscreen mode

11.设置数据库

在运行测试和检查之前我们需要注意的最后一件事是设置数据库。

- name: Setup DB
      run: bin/rails db:drop db:create db:structure:load --trace
Enter fullscreen mode Exit fullscreen mode

12. 运行测试和 Linters

现在我们终于可以运行测试和检查了。

- name: Run Rails Tests
  run: |
    bin/rails test
    bin/rails test:system

- name: Zeitwerk Check
  run: bundle exec rails zeitwerk:check

- name: StandardRB Check
  run: bundle exec standardrb --format progress

- name: ERB Lint
  run: bundle exec erblint app/views_redesigned/**/*.html.erb

- name: Prettier-Standard Check
  run: yarn run --ignore-engines prettier-standard --check 'app/**/*.js'
Enter fullscreen mode Exit fullscreen mode

至此,您的操作就完成了!

这是我完成的操作文件:

name: Run Tests & Linters

on:
  pull_request:
    branches:
      - '*'
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:11
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: postgres
        ports: ['5432:5432']
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
      redis:
        image: redis
        ports: ['6379:6379']
        options: --entrypoint redis-server
    container:
      image: andrewmcodes/locomotive:v0.0.1
      env:
        DEFAULT_HOST: app.codefund.io
    steps:
    - uses: actions/checkout@v1

    - name: Get Yarn Cache
      id: yarn-cache
      run: echo "::set-output name=dir::$(yarn cache dir)"

    - name: Cache Node Modules
      id: node-modules-cache
      uses: actions/cache@v1
      with:
        path: ${{ steps.yarn-cache.outputs.dir }}
        key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
        restore-keys: |
          ${{ runner.os }}-yarn-

    - name: Cache Gems
      id: gem-cache
      uses: actions/cache@v1
      with:
        path: vendor/bundle
        key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
        restore-keys: |
          ${{ runner.os }}-gem-

    - name: Cache Assets
      id: assets-cache
      uses: actions/cache@v1
      with:
        path: public/packs-test
        key: ${{ runner.os }}-assets-${{ steps.extract_branch.outputs.branch }}
        restore-keys: |
          ${{ runner.os }}-assets-

    - name: Bundle Install
      run: bundle install --path vendor/bundle --jobs 4 --retry 3

    - name: Yarn Install
      run: bin/rails yarn:install

    - name: Compile Assets
      shell: bash
      run: |
        if [[ ! -d public/packs-test ]]; then
          bundle exec rails webpacker:compile
        else
          echo "No need to compile assets."
        fi

    - name: Setup DB
      run: bin/rails db:drop db:create db:structure:load --trace

    - name: Run Rails Tests
      run: |
        bin/rails test
        bin/rails test:system

    - name: Zeitwerk Check
      run: bundle exec rails zeitwerk:check

    - name: StandardRB Check
      run: bundle exec standardrb --format progress

    - name: ERB Lint
      run: bundle exec erblint app/views_redesigned/**/*.html.erb

    - name: Prettier-Standard Check
      run: yarn run --ignore-engines prettier-standard --check 'app/**/*.js'
Enter fullscreen mode Exit fullscreen mode

如你所见,为你的 CI 设置 GitHub Actions 可能相当复杂,需要大量的初始设置。如果你正在考虑在你的 Rails 应用上尝试使用它们,希望这篇文章能对你有所帮助。本周晚些时候,请回来查看第二部分:设置 CircleCI!

文章来源:https://dev.to/codefund/ci-for-ruby-on-rails-github-actions-3mn1
PREV
19个编程误区
NEXT
如何制作计算器(可操作且动画化)