RYDE PASSのブランチ戦略とCI/CD(GitLabフローと自動デプロイ)
はじめに
RYDE株式会社CTOの芝原です。
本記事では、RYDE PASSにおけるブランチ戦略とCI/CDの取り組みについて解説します
私たちは RYDE PASS という多くのお客様にご利用いただくサービスを、小規模な開発チームで運用・開発しています。公共交通を取り扱うというサービスの性質上、安定した運用は欠かせませんが、同時にベンチャー企業ならではのスピード感も求められます。
この両立を実現するためには、自動化が不可欠です。限られたリソースの中で開発を円滑に進めるため、私たちはリリースフローをはじめとするさまざまなプロセスの自動化に取り組んでいます。
本記事では、私たちの開発フローがどのように設計され、どのように運用されているのかを具体的にご紹介します。
全体像
はじめに全体像です。
私たちはGitLabフローをベースにしたブランチ戦略を採用し、各種テスト、ステージングおよび本番環境へのリリースPR作成やデプロイなどを自動化しています。
次章からは、なぜGitLabフローを採用したのか、そして各ステップで具体的にどのような自動化を行っているのかについて詳しく解説していきます。
ブランチ戦略
RYDEでは、GitLab Flowを採用しています。
GitLabフローを選んだ理由
RYDE PASSは公共交通を取り扱う性質上、不具合の発生を極力抑えることを最優先としています。そのため、デプロイ頻度を高めることよりも、安定性を重視した運用を行っています。具体的には、デプロイを原則毎週月曜日に固定し、ステージング環境で1週間の動作確認を行った上で、翌週に本番環境へデプロイするという運用を採用しています。
この運用に最も適したブランチ戦略が、GitLabフローでした。
GitLabフローの概要
GitLabフローは、複数環境(ステージングや本番)を持つプロジェクトに適した、シンプルなブランチ戦略です。
RYDEでは以下の3つの主要ブランチを運用しています:
-
main
ブランチ: 機能開発や修正をマージ -
staging
ブランチ: ステージング環境用 -
production
ブランチ: 本番環境用
他のフローとの比較
過去には他のフローも検討しましたが、それぞれ以下の理由で採用を見送りました。
-
Git-flow
厳格な運用となるのは利点なのですが、その分ブランチ運用が複雑で、現在の小規模なチームでは冗長と判断しました。 -
GitHubフロー
シンプルに運用できる利点はあるものの、main
ブランチの即時デプロイを前提としており、前述したRYDEの安定性重視の運用方針に合いませんでした。
一方で、GitLabフローは、
- 複数環境(ステージングや本番)を持つプロジェクトに適していること
-
シンプルさと安定性を両立している点
が魅力でした。
ちなみに、各フローの比較についてはこの記事も参考になりそうです。
各ステップの内容
次に、最初に全体像でお見せした①から⑥までの各ステップで実施している内容を解説します。
RYDEでは、安定した品質と効率的なデプロイを実現するために、上述のブランチ戦略を基盤としたCI/CDパイプラインをGithub Actions上で運用しています。
① 作業ブランチを作成
開発者は新機能や修正を行うために、main
ブランチから作業ブランチを作成します。
② PR作成(CI)
作業が完了したら、開発者はmain
ブランチへの Pull Request(PR)を作成します。このPRに対して以下のプロセスを実施します。
-
CIの実行
- Lint(Rubocop、ESLint、Prettierなど)
- テスト(RSpec、Jest、Maestroなど)
- テストカバレッジの測定(Codecov)など
- 2名以上のコードレビューと承認
- 承認後、mainブランチへマージ
③ ステージング環境へのリリースPRを自動作成・更新
main
ブランチに変更が加わると、自動的にstaging
ブランチへのリリースPRが作成または更新されます。
このリリースPRの作成にはgit-pr-releaseを使用しています。以下の画像のようにリリース内容として含まれるPRがリストアップされ、変更内容が簡潔に把握できるようになっております。
コード例
name: git-pr-release-staging
on:
push:
branches:
- main
jobs:
git-pr-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2
- run: gem install --no-document git-pr-release
- run: git-pr-release
env:
GIT_PR_RELEASE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GIT_PR_RELEASE_BRANCH_PRODUCTION: staging
GIT_PR_RELEASE_BRANCH_STAGING: main
GIT_PR_RELEASE_LABELS: staging-release
GIT_PR_RELEASE_TEMPLATE: .github/GIT_PR_RELEASE_TEMPLATE.erb
TZ: Asia/Tokyo
④ ステージング環境に自動デプロイ
③で作成されたステージング環境へのリリースPRをマージすると、GitHub Actionsを通じてステージング環境に自動デプロイが行われます。
RYDE PASSはECS Fargateで稼働しており、デプロイツールにはecspressoを採用しています。
Makefile
でデプロイコマンドをラップし、各種コマンドへのパラメーター指定などが楽になるような運用を実現しています。
自動デプロイは以下の流れです。
- docker build
- docker push(ECR)
- ecspresso deploy
コード例
name: deploy-staging
on:
push:
branches:
- staging
workflow_dispatch:
env:
ENVIRONMENT: staging
AWS_ROLE_ARN: arn:aws:iam::xxx:role/GithubActions
ECR_REGISTRY: xxx.dkr.ecr.ap-northeast-1.amazonaws.com
ECR_REPOSITORY: xxx
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment:
name: staging
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v3
- uses: docker/setup-buildx-action@v2
- uses: aws-actions/configure-aws-credentials@v1
with:
aws-region: ap-northeast-1
role-to-assume: ${{ env.AWS_ROLE_ARN }}
- uses: docker/login-action@v2
with:
registry: ${{ env.ECR_REGISTRY }}
- uses: docker/metadata-action@v4
id: meta
with:
images: |
${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}
tags: |
type=sha,prefix=
type=raw,value=latest
- uses: docker/build-push-action@v4
with:
push: true
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
- uses: kayac/ecspresso@v2
with:
version: v2.0.4
- run: make -j deploy ENV=${{ env.ENVIRONMENT }} SKIP_DOCKER_BUILD_AND_PUSH=1
⑤ 本番環境へのリリースPRを自動作成・更新
③ ステージング環境へのリリースPRを自動作成・更新
と同じ内容で、production
ブランチに対してリリースPRを作成します。
⑥ 本番環境に自動デプロイ
④ ステージング環境に自動デプロイ
と同じ内容で、本番環境に自動デプロイします。
最後に
最後までお読みいただきありがとうございます!
簡単ではありますが、RYDE PASSでのGitLabフローを用いたCI/CDの説明でした。
エンジニア採用募集中!
RYDE PASSが取り組む移動交通の領域には、前例のない分野を自分たちで切り開く楽しさと、実生活で使える身近なサービスを創造していく喜びがあります。
私たちと一緒に「移動の未来」を創りませんか?技術が好きな方、挑戦を楽しめる方をお待ちしています!
Discussion