search
LoginSignup
5

More than 1 year has passed since last update.

posted at

updated at

Organization

GitLab CIで知っておくと便利かもしれないtips

本記事は Ateam Finergy Inc. Advent Calendar 2020 19日目の記事です。

はじめに

みなさん、GitLab CIを使っているでしょうか?
エイチームフィナジーではプロジェクト管理にGitLabを使用しており、自動化などのためにGitLab CIを活用しています。
GitLab CIは機能が豊富な反面、書いていない期間が長いと、しばしば書き方を忘れがちになります。

今回はGitLab CIの知っておくと便利な機能について紹介します。

ちなみに、この記事で出てくる例は、Ruby on Railsのプロジェクトを前提としている物が多いですが、ご容赦ください。

service

依存するミドルウェアを立てます。

example

たとえば、DBです。
プロジェクトでDBにMySQLを使っているとして、単体テストをするのにMySQLに接続する必要があります。
そのMySQLを用意するということです。
servicesにはDockerイメージを使用するため、MySQLのDockerを参考に設定します。
https://hub.docker.com/_/mysql

  services:
    - name: mysql:5.6
  variables:
    MYSQL_DATABASE: app_test
    MYSQL_ROOT_PASSWORD: app

これでホスト名がmysqlでMySQLに接続できるようになります。

応用編

実際のプロジェクトでは、しばしばMySQLのホスト名を変えたかったり、MySQLの起動オプションをつけたい場合があります。
その場合alias command を使います

alias

別の名前でコンテナに接続できます。
それによってMySQLを別のホスト名として接続できます。
下記はホスト名をdbにする例です。

  services:
    - name: mysql:5.6
      alias: db
  variables:
    MYSQL_DATABASE: app_test
    MYSQL_ROOT_PASSWORD: app

command

commandを指定できます。
下記はMySQLにinnodb_large_prefixオプションを設定する例です。

  services:
    - name: mysql:5.6
      command:
        - "mysqld"
        - "--innodb_large_prefix=ON"
        - "--innodb_file_format=Barracuda"
        - "--innodb_file_format_max=Barracuda"
  variables:
    MYSQL_DATABASE: app_test
    MYSQL_ROOT_PASSWORD: app

cache

キャッシュはビルド時間の短縮に繋がります。

example

例えば、npm installでインストールしたファイルをキャッシュしておくことによって、ビルド時間が減らせます。

  cache:
    paths:
      - node_modules

応用編

cache:key:files

たとえば、cache:key:filesを設定することによって、特定のファイルが変わったときにキャッシュキーを変更することができます。
下記はyarn.lockファイルをキャッシュキーにしている例です。

  cache:
    key:
      files:
        - yarn.lock
    paths:
      - node_modules

needs

ジョブの依存関係を記述することによって、並列でジョブを実行します。

例えば、stageが別れていると前のstageが終わるまで待っておかないといけないというパターンがあります。
needsを使えば、前のステージを待たずに、複数のステージで同時にジョブを実行できます。
つまり、下記のようになります。

needs未使用

before.gif

needs使用
after.gif

needs未使用のdeploy_jobは、testステージのジョブが終わるのを待っているのに対して、needs使用のものはtestステージが終わるのを待たずにdeploy_jobを実行できます。

example

stages:
  - build
  - test
  - deploy

build_job:
  stage: build
  script:
    - echo build # build script

test_job:
  stage: test
  script:
    - echo test # test script

deploy_job:
  stage: deploy
  script:
    - echo deploy # deploy script
  needs:
    - build_job

extends

設定を使い回せます。

example

たとえばRubyのプロジェクトで、Ruby製のツールを使用するときは、事前にbundle installをする必要があります。
その設定を使い回す例は下記となります。

stages:
  - rubocop
  - rspec

.ruby:
  before_script:
    - apk add build-base mysql-client mysql-dev tzdata
    - bundle config set path vendor/bundle
    - bundle install -j $(nproc)

rubocop:
  stage: rubocop
  extends: .ruby
  script:
    - bundle exec rubocop

rspec:
  stage: test
  extends: .ruby
  script:
    - bundle exec rspec

応用編

ネスト

extendsしようとするものの中で、extendsできます。
先程のbundle installする例に加えて、ruleを追加した例が下記となります。

stages:
  - rspec
  - staging

.ruby:
  before_script:
    - apk add build-base mysql-client mysql-dev tzdata
    - bundle config set path vendor/bundle
    - bundle install -j $(nproc)

rspec:
  stage: test
  extends: .ruby
  script:
    - bundle exec rspec


.deploy:
  extends: .ruby
  rules:
    - if: '$CI_COMMIT_BRANCH == "master"'

staging:
  stage: staging
  extends: .deploy
  script:
    - bundle exec cap staging ecs:deploy

artifacts

成果物を残せます。

example

たとえば、webpackなどでビルドした結果を残すものは下記となります。

build:frontend:
  stage: build
  before_script:
    - apk add yarn
    - cd frontend
    - yarn install
  script:
    - yarn build
  artifacts:
    paths:
      - frontend/public

pages

GitLab Pagesにデプロイします。

example

pages:
  artifacts:
    paths:
      - public

注意点

  • job名はpagesでなければなりません。
  • artifactsでpublicを指定しなければなりません。

dependencies

他のjobで作ったartifactsを使います。

example

たとえば、rspecのカバレッジ結果をSimpleCovを使ってGitLab Pagesに出したいとします。
SimpleCovはrspecを実行するとcoverageというディレクトリにファイルを出力します。
そのcoverageファイルをpagesジョブで使いたい場合は、下記のようになります。


rspec:
  stage: test
  script:
    - bundle exec rspec
  artifacts:
    paths:
      - coverage/

pages:
  stage: pages
  dependencies:
    - rspec
  script:
    - mv coverage public
  artifacts:
    paths:
      - public

リファレンス

今回紹介した機能を全部使ったサンプル

ちなみに、全部使ったサンプルのプロジェクトがこちらとなります。
よければ参考にしてみてください。

.gitlab-ci
# This file is a template, and might need editing before it works on your project.
# Official language image. Look for the different tagged releases at:
# https://hub.docker.com/r/library/ruby/tags/
image: "ruby:2.7.2-alpine"

# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service

stages:
  - build
  - rubocop
  - test
  - pages
  - staging
  - production

build:frontend:
  stage: build
  before_script:
    - apk add yarn
    - cd frontend
    - yarn install
  script:
    - yarn build
  artifacts:
    paths:
      - frontend/public
  cache:
    key:
      files:
        - yarn.lock
    paths:
      - node_modules

build:docker:
  stage: build
  image: docker:19.03.13
  services:
    - docker:19.03.13-dind
  script:
    - apk add aws-cli
    - aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 887840435665.dkr.ecr.ap-northeast-1.amazonaws.com
    - docker build -t rails-ci-sample .
    - docker tag rails-ci-sample:latest 887840435665.dkr.ecr.ap-northeast-1.amazonaws.com/rails-ci-sample:$CI_COMMIT_SHA
    - docker push 887840435665.dkr.ecr.ap-northeast-1.amazonaws.com/rails-ci-sample:$CI_COMMIT_SHA

.ruby:
  cache:
    key:
      files:
        - Gemfile.lock
    paths:
      - vendor/bundle
  before_script:
    - apk add build-base mysql-client mysql-dev tzdata
    - bundle config set path vendor/bundle
    - bundle install -j $(nproc)

rubocop:
  stage: rubocop
  extends: .ruby
  script:
    - bundle exec rubocop
  needs: []

rspec:
  stage: test
  extends: .ruby
  services:
    - name: mysql:latest
      alias: db
  variables:
    MYSQL_DATABASE: app_test
    MYSQL_ROOT_PASSWORD: app
    RAILS_ENV: test
  script:
    - bin/rails db:create
    - bin/rails db:migrate
    - bin/rspec
  artifacts:
    paths:
      - coverage/
  needs: []

pages:
  stage: pages
  needs:
    - rspec
  dependencies:
    - rspec
  script:
    - mv public _public
    - mv coverage public
  artifacts:
    paths:
      - public

.deply:
  extends: .ruby
  needs:
    - build:frontend
    - build:docker

staging:
  stage: staging
  extends: .deply
  script:
    - bundle exec cap staging ecs:deploy
  rules:
    - if: '$CI_COMMIT_BRANCH == "master"'

production:
  stage: production
  extends: .deply
  script:
    - bundle exec cap production ecs:deploy
  rules:
    - if: '$CI_COMMIT_BRANCH == "master"'
      when: manual

おわりに

いかがでしたでしょうか。
今回は、GitLab CIの知っておくと便利な機能について紹介しました。
GitLab CIを設定する際の参考にしていただければ幸いです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
5