Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby on CI #ginzarails

2b680c5f22146e764e2998dd4595ec93?s=47 sue445
August 28, 2020

Ruby on CI #ginzarails

銀座Rails#24の発表資料です
https://ginza-rails.connpass.com/event/181807/

2b680c5f22146e764e2998dd4595ec93?s=128

sue445

August 28, 2020
Tweet

Transcript

  1. Ruby on CI 2020/08/28 銀座rails#24 @sue445

  2. 自己紹介 • Go Sueyoshi (a.k.a. sue445) • ピクシブ インフラ部所属 ◦ AWS,

    GCP, CI ◦ アプリケーションコードを一切触らずにパフォーマンスチューニングす るリアルISUCON ◦ その他色々
  3. 自己紹介 • 社内GitLabメンテナ ◦ 運用知見はSoftware Design 2020年1月 号に書いた(ダイマ) ◦ https://gihyo.jp/magazine/SD/archive/

    2020/202001
  4. 自己紹介 • 女児アニメチョットワカル ◦ プリキュアシリーズ全話視聴 ◦ プリティーシリーズ(プリティーリズム・プリパラ・King of Prism・キ ラッとプリ☆チャン)全話視聴

    ◦ アイカツ(無印〜オンパレード)全話視聴
  5. 自己紹介 • 自称YAMLエンジニア ◦ Ansible, docker-compose, CircleCI, GitLab CI, Travis

    CI Wercker, GitHub Actions, Serverless Framework, AWS SAM, Kubernetes • 自称CIマニア ◦ Jenkins(昔), Travis CI, CircleCI, Wercker, GitLab CI, GitHub Actions
  6. 自己紹介 • RubyKaigi 2019 Speaker ◦ Best practices in web

    API client development ◦ https://rubykaigi.org/2019/presentations/sue445.html • RubyKaigi 2020 Speaker ◦ Ruby on CI ◦ https://rubykaigi.org/2020/presentations/sue445.html ◦ しかし中止(◞‸◟)
  7. 9/4(金)が僕の登壇日だった...

  8. 今日話すこと • RubyKaigi2020で話すつもりだった内容 ◦ CFP: https://sue445.fanbox.cc/posts/771529 • CIマニアがCIの話をする ◦ Railsはおろか、Ruby固有の話もそんなにありません

    ◦ 逆に言うと他言語でも使い回せるベストプラクティスです
  9. アジェンダ • なぜCIをするのか • CIの歴史 • 何をCI/CDするのか • いつCIを導入すべきか •

    いつ(どのタイミングで、どの周期で)CIすべきか • 何を使うべきか • スロービルド改善 • CIのキャッシュ戦略 • これからのCI
  10. まとめ • 何をしたいかや規模によって使うもの(SaaS、セルフホスティング含めて) が変わる ◦ 銀の弾丸はない • CIの仕組みやエコシステムにのっかることによっていくらでもリファクタリン グできる •

    手作業を自動化することによって生産性を何倍にもできる • 技術革新によってその時点の最適解がすぐに陳腐化する ◦ 作った当時の最適解が今の最適解とは限らない ◦ 必要に応じて式年遷宮も必要
  11. アジェンダ • なぜCIをするのか • CIの歴史 • 何をCI/CDするのか • いつCIを導入すべきか •

    いつ(どのタイミングで、どの周期で)CIすべきか • 何を使うべきか • スロービルド改善 • CIのキャッシュ戦略 • これからのCI
  12. (sue445は)なぜCIするか? • 教科書的な模範解答はググればいくらでも出てくるのであくまで僕がどう してCIするかの話です • 異論は認める

  13. (sue445は)なぜCIするか? • 働きたくないから ◦ 日本人は勤勉で真面目で働き者 ◦ 僕は真逆

  14. 働かずに5000兆円欲しい!!!

  15. (sue445は)なぜCIするか? • 人は間違えるが機械は間違えない ◦ 自分自身も信用しない ◦ Q. 機械も間違えるのでは? ▪ A.

    機械が間違えてるのではなく、機械を作った人間や機械に支 持を出した(コードを書いた)人間が間違えてる
  16. アジェンダ • なぜCIをするのか • CIの歴史 • 何をCI/CDするのか • いつCIを導入すべきか •

    いつ(どのタイミングで、どの周期で)CIすべきか • 何を使うべきか • スロービルド改善 • CIのキャッシュ戦略 • これからのCI
  17. CIの歴史 • 2005年: 自前で頑張る期 • 2011年: SaaS登場 • 2014年: Dockerの台頭

    • 2019年: MSの本気
  18. 自前で頑張る期 • 2005年: Hudson • 2011年: Jenkins • この時代は自分でCIサーバを立てるのが主流 •

    自分でCIサーバの面倒を見る必要があって大変 ◦ 仕事を減らすために導入したはずなのに仕事が増えるジレンマ ◦ メンテナが属人化する問題(Jenkinsおじさん)
  19. SaaS登場 • 2011年: Travis CI • 2011年: CircleCI 1.0 •

    2011年: Wercker (box (non Docker)) • 2016年: CloudBees (SasS版Jenkins) • CIサービスが用意した環境を利用 ◦ 自分でサーバを管理しなくてよくなった反面、CIサービス毎のハック がつらい ◦ ローカルだと問題ないのにCIがなぜかコケる ◦ CI毎に互換性がないのでポータビリティが微妙
  20. Dockerの台頭 • 2014: Docker Hub • 2014: Wercker (Docker support)

    • 2017: CircleCI 2.0 (Docker support) • CIの実行環境がポータビリティになった ◦ ベースのDockerイメージが一緒ならどこで動かしても同じ環境なの が保証される
  21. MSの本気 • 2019: GitHub Actions ◦ ヘビーなマトリクスビルドも並列数で殴れるようになった(後述)

  22. アジェンダ • なぜCIをするのか • CIの歴史 • 何をCI/CDするのか • いつCIを導入すべきか •

    いつ(どのタイミングで、どの周期で)CIすべきか • 何を使うべきか • スロービルド改善 • CIのキャッシュ戦略 • これからのCI
  23. 何をCI(CD)するか • 普通のRuby製アプリ • gem

  24. 普通のRuby製アプリのCI • test:rspecなど • lint : rubocop, slimlintなどのような静的解析 • deploy

    ◦ アプリ:capisrtanoなど ▪ デプロイを自動にするか手動にするかはアプリによって変わる (本番環境のみCI上から手動デプロイとか) ◦ ドキュメント:YARD, Storybookなど
  25. gemのCI • deployがない以外はアプリと構成は一緒 • RubyのバージョンやRailsのバージョン毎に分けたgemfileによってマトリ クスビルド ◦ マトリクステストのジョブ数を増やしすぎるとジョブの実行時間が長く なるのでほどほどに ◦

    今までの経験上、Rubyのバージョンはサポートしてる下限(最古)と 上限(最新)でいいことが多い ◦ Railsはマイナーバージョン毎に細かい挙動が変わるので全部テスト しないときつい
  26. 余談1: CIのジョブをどこまで細分化すべきか? • testやlintなどのように依存しないジョブを複数ジョブで並列実行するか 単一ジョブで直列実行するかはケースバイケース

  27. ジョブを細分化した方がいい場合 • 基本的には並列実行の方が効率的だしジョブ毎の依存関係がなくなる • 時間のかかるジョブを分割して並列実行することで実行時間を減らせる • 実行環境(dockerイメージ)が変わる場合はジョブ分けないと無理 ◦ 例)通常はRubyのDockerイメージを使いつつnpm系だけnode系 のイメージを使う。デプロイ時にaws-cliやgcloudコマンドだけが

    入ったDockerイメージを使う
  28. ジョブを細分化しない方がいい場合 • 一瞬系のジョブの場合、ジョブの中で実行してるコマンドの実行時間より も、docker pullやリポジトリのcheckoutなどのジョブ初期化の方が時間 がかかることが多いので細分化しすぎると逆効果 • CIサービスのプランによって並列数が制限されている場合は敢えて並列 数を増やさないこともある

  29. 余談2: Ruby以外の活用事例 • 例)packageやバイナリやDockerイメージのビルド、Terraformの実行 • Terraform運用事例書きました ◦ https://inside.pixiv.blog/2020/07/30/172828

  30. 余談3: CIのスケジューラを利用したbotの定期実行 について • GitHub Actionsでは禁止されているので注意 ◦ 「GitHubアクションが使用されるリポジトリに関連するソフトウェアプ ロジェクトの製造、テスト、デプロイ、公開に関連しないその他の行 為。」にあたる

    ◦ https://help.github.com/ja/github/site-policy/github-additi onal-product-terms#a-actions-usage
  31. アジェンダ • なぜCIをするのか • CIの歴史 • 何をCI/CDするのか • いつCIを導入すべきか •

    いつ(どのタイミングで、どの周期で)CIすべきか • 何を使うべきか • スロービルド改善 • CIのキャッシュ戦略 • これからのCI
  32. いつCIを導入すべきか? • 継続的にメンテする必要が出てきた時 ◦ 基本的にはリポジトリ作成時にCIを導入する ◦ 逆にいうと使い捨てのコードにはテストもCIも不要 • 2〜3回手作業をやってルーチン化し始めたら自動化 ◦

    早ければ早い方がいい
  33. アジェンダ • なぜCIをするのか • CIの歴史 • 何をCI/CDするのか • いつCIを導入すべきか •

    いつ(どのタイミングで、どの周期で)CIすべきか • 何を使うべきか • スロービルド改善 • CIのキャッシュ戦略 • これからのCI
  34. いつ(どのタイミングで、どの周期で)CIすべきか? • アプリの場合 • gemの場合

  35. アプリの場合のCI実行周期 • pushやPRの単位 • 定期ビルド(Nightly Build) ◦ 毎コミット実行したくない重めのインテグレーションテスト ◦ 継続的な負荷テスト

    ◦ 開発用のDockerイメージをビルド
  36. gemの場合のCI実行周期 • 基本的にはアプリと同様(push, PRの単位) • 定期ビルドが重要 ◦ 自分のコードに変更がなくても依存してるgemの破壊的変更により masterブランチのビルドはすぐにぶっ壊れる ▪

    例)古いRubyのサポート切れ (required_ruby_version) ◦ 最低週1回は定期ビルドすべき ▪ 他の人のリポジトリにPR投げた時に自分の変更以外でビルドが コケるのがすごい嫌なので、自分のgemは全部weekly buildを してる
  37. FAQ. Gemfile.lockをコミットしてればmasterの ビルドは壊れないのでは? • A. そうね ◦ Gemfile.lockをコミットすることで使うgemのバージョンが固定化さ れるので、何もしないのにビルドが壊れることはなくなるというメリット はある

    • デメリットの方が多いと思ってる ◦ 個人の感想です
  38. Gemfile.lockをコミットするデメリット • gemに対してbundle updateするコスト ◦ CIで複数のgemfileをつかっているとそれらもbundle updateする 必要が出てくる ◦ dependabotがサブディレクトリには対応しているがGemfile以外の

    名前に非対応 ▪ https://dependabot.com/docs/config-file/ ▪ https://help.github.com/en/github/administering-a-re pository/configuration-options-for-dependency-updat es
  39. Gemfile.lockをコミットするデメリット • gemは色んな状況(依存gemのバージョン)で使われるので、 Gemfile.lockをコミットするとそういったケースをCIで検知できなくなる ◦ 本当に依存gemのバージョンを管理したければgemspecを使うべき • version.rb変えた時にGemfile.lockで差分が出るのでrake release直 前にGemfile.lockもコミットする必要がある

    ◦ gitの差分がある状態でrake releaseしようとすると失敗するのだ が、もしかしたらRubyMineが裏でbundle installしてるせいかもし れない
  40. アジェンダ • なぜCIをするのか • CIの歴史 • 何をCI/CDするのか • いつCIを導入すべきか •

    いつ(どのタイミングで、どの周期で)CIすべきか • 何を使うべきか • スロービルド改善 • CIのキャッシュ戦略 • これからのCI
  41. CIは何を使うべきか • 何を使うべきか x 3 ◦ CIサービス ◦ Dockerイメージ ◦

    実行環境 • だいたいみんなGitHub使っていると思うのでGitHub前提 • 自分が使ったことあるやつ中心
  42. gemで使うべきCI • たくさんgem(5個以上くらい)をメンテしてるならGitHub Actions、それ以 外ならTravis CIかCircleCI

  43. gemでTravis CIやGitHub ActionsやCircleCI を選択する理由 • 「各Rubyのバージョン x 各Railsのバージョン」のようなマトリクスビルドが 書きやすい ◦

    https://docs.travis-ci.com/user/build-matrix/ • 最近CircleCIもマトリクスビルドを正式にサポートした ◦ https://circleci.com/blog/circleci-matrix-jobs/
  44. Travis CIのマトリクスビルド • メリット ◦ GitHub Actionsに比べると少ない記述量で書ける ▪ シンプルなgemのCIであればTravis CIで十分なことも多い

    • デメリット ◦ 5並列/ownerなので大量にgemをメンテして一気にPRマージすると ビルドが詰まる ◦ 30個のgemのweekly build 1.5時間
  45. GitHub Actionsのマトリクスビルド • メリット ◦ 20並列/repo ◦ ownerごとの上限はプランによって変わる ▪ https://help.github.com/en/actions/getting-started-wi

    th-github-actions/about-github-actions#usage-limits ◦ 30個のgemのweekly build 15分 • デメリット ◦ Travis CIに比べたら記述が冗長
  46. アプリで使うべきCI • 基本的にはCircleCIかGitHub Actionsでいい ◦ 複雑なworkflowを書けるのでやりたいことはだいたい実現できる • 個人的にはCircleCI推し ◦ GitHub

    ActionsはYAMLのアンカー(&〜)とエイリアス(*〜)が使え なくてリファクタリング時にたまに困る
  47. アプリとかgemとか関係無しにGitHub Actionsを 使った方がいいケース • CI上でGitHub APIを使う場合 ◦ メインでCircleCI使ってても一部分だけGitHub Actionsは選択肢と してアリ

  48. 【注意】CI 上でパーソナルアクセストークンは使って はいけない • 会社orgの場合、個人のパーソナルアクセストークンを使うとその人が退 職してorgからいなくなった時にCIが止まる ◦ ボットユーザの管理が必要 • パーソナルアクセストークンはリポジトリ単位の権限管理ができない

    ◦ (ボットユーザ含めて)orgの誰か1人のトークンが漏れたらその人がア クセス可能なリポジトリ全部漏洩したと一緒 ◦ 漏れたらインシデント
  49. GitHub APIを使う場合なぜGitHub Actionsを 使った方がいいのか? • CI用のパーソナルアクセストークンの発行が不要なため ◦ https://help.github.com/ja/actions/configuring-and-manag ing-workflows/authenticating-with-the-github_token ◦

    secrets.GITHUB_TOKEN で使える • インストールアクセストークン ◦ hubコマンドで試したけど自分自身のプライベートリポジトリとパブリッ クリポジトリは見れるけど、他のプライベートリポジトリは見えなかった • 有効期限60分なので仮に漏れても被害は最小限
  50. 余談1: GitLabの場合 • GitLabではGitLab CIを使うのがデファクト ◦ 機能的にもCircleCIと同等なので遜色ない ◦ リポジトリとCIが統合しているのでメリットも多い ▪

    例)セットアップ不要、ビルドが終わったらMergeRequestを自動 マージ • ピクシブでのGitLab CI事例 ◦ https://speakerdeck.com/sue445/pixiv-tech-salon-numbe r-pixivtechsalon ◦ https://sue445.hatenablog.com/entry/2019/12/18/000108
  51. 余談2: クラウドのCIツール • CodeBuild(AWS)やCloud Build(GCP)など • クラウドにデプロイする前提ならクラウドのCIツールを使うのもあり ◦ VPN内にアクセス可能なアクセスキーなどを外に出さなくてよかった り、踏み台サーバが不要なのでセキュアというメリット

  52. RubyのDockerイメージについて • 最近のCIはDockerイメージを使うのが主流 • Dockerイメージソムリエ(自称)として色んなイメージを使った結果、最終 的にこの3つに落ち着いた ◦ https://hub.docker.com/_/ruby ◦ https://hub.docker.com/r/circleci/ruby

    ◦ https://hub.docker.com/r/rubylang/ruby
  53. 余談: Dockerイメージソムリエが気をつけてること • Docker Hubではたくさんのイメージが公開されているが、頻繁に更新さ れていることが一番大事 ◦ Rubyの場合最低でも最新版が出たらすぐにパッチバージョン単位 (x.y.z)でtagがうたれてリリースされていないと厳しい ◦

    gemのCIを考えるとマイナーバージョン単位(2.7とか)でtagが打たれ ていると嬉しい • 個人が手動でリリースしてるようなDockerイメージを使うのはメンテされ なくなるリスクがあるので使いづらい
  54. https://hub.docker.com/_/ruby • slimやalpineもあるのでイメージサイズを抑えたい時はこっち • 一番利用されている • Docker Official ImagesだがRubyコアチームの公式ではない

  55. https://hub.docker.com/r/circleci/ruby • _/ruby ベース • テストに必要なものが全部入りで便利(そこそこ重い) • nodeタグやbrowserタグもあるので必要に応じて使う ◦ https://circleci.com/docs/2.0/circleci-images/

    ◦ headless chromeのインストールに困ったらコレ • circleciと言いつつ他のCIでも普通に使える • 普通のdockerイメージと違って実行時のユーザがrootユーザじゃなく circleciユーザなのが注意(sudoはある)
  56. https://hub.docker.com/r/rubylang/ruby • Rubyコアチームの公式 • GitHub ActionsでTravis CIのruby-headみたいな開発版のrubyでビ ルドをしたい時にmaster-nightly-bionicタグが便利

  57. 余談: cimg/ruby • 最近CircleCIが新しいDockerイメージを出したらしい ◦ https://hub.docker.com/r/cimg/ruby ◦ circleci/rubyよりイメージが軽量化 ▪ circleci/ruby:2.7.1

    => 476.71 MB ▪ cimg/ruby:2.7.1 => 332.04 MB • 日本語の詳しいブログ ◦ https://budougumi0617.github.io/2020/06/08/circleci_cim g_go_2020/
  58. CIの実行環境は何を使うか • CircleCI ◦ 前述のDockerイメージのどれか • GitHub Actions ◦ GitHub

    ActionsのVM上でビルドを実行 ◦ GitHub ActionsのVM上でコンテナを起動しその中でビルドを実行
  59. GitHub ActionsのVM上でビルドを実行 • 基本的には ruby/setup-ruby でいい ◦ https://github.com/ruby/setup-ruby ◦ ruby

    orgなので安心感がある(eregonさんがメンテナ) • GitHub公式の actions/setup-ruby は最新版への追従が遅いので実 アプリで使うのは厳しい ◦ https://github.com/actions/setup-ruby • 詳しいこと ◦ https://mstshiwasaki.hatenablog.com/entry/2020/02/08/1 30844
  60. GitHub ActionsのVM上でコンテナを起動しその 中でビルドを実行 • 基本的にはVMとコンテナどっちでもいい • 下記のような場合はDockerイメージを使うしかない ◦ Docker Hubにしかない古いRubyのバージョンでCIしたい時

    ◦ gemのマトリクステストなどで開発版のRubyでCIする必要がある場 合 ▪ rubylang/ruby:master-nightly-bionic
  61. アジェンダ • なぜCIをするのか • CIの歴史 • 何をCI/CDするのか • いつCIを導入すべきか •

    いつ(どのタイミングで、どの周期で)CIすべきか • 何を使うべきか • スロービルド改善 • CIのキャッシュ戦略 • これからのCI
  62. スロービルド改善 • 「CIの スロービルドに 立ち向かう」 #一句 • 実際にCIのビルドを1回20分から10分にした事例をベースに、どうCIを チューニングすればいいかを紹介

  63. どこが遅いかを調べる • 「推測するな、計測せよ」って言葉もあるのでまずはどこで時間がかかって るか調べる • CIサービスによってはstep毎の時間が出るので楽

  64. どこが遅いかを調べる • time コマンドを仕込めばコマンド単位で計測はできる • rspec --profile で各example単位でのワーストワンキングを出せる

  65. スロービルド対策の方針 • ジョブ起動時のdockerイメージのpullが重いパターン ◦ 700MB超えるイメージを使うとこの問題に引っかかる ◦ たいていの場合Docker Hubで配布されてるイメージを使ってる場合 が多いので、alpine版やslim版があればそれを使う ▪

    パッケージが足りずに大量のパッケージをapt-get install(yum install)するコストも出てくるのでケースバイケース ◦ CIサービスによっては1ジョブで複数コンテナを起動できることが多い が減らすのも大事。(例:rubocop実行時はDBやredisのコンテナを 起動しないなど)
  66. スロービルド対策の方針 • gemなどのライブラリインストール ◦ CI側で適切にキャッシュしてやる(後述) • パッケージインストールやmake ◦ makeしたバイナリをCIのキャッシュに乗せるのも有り ◦

    インストールそのものが遅い場合はCI専用のDockerイメージを作っ た方が速いのだが、オレオレDockerイメージというメンテすべきもの が増えるので一長一短
  67. スロービルド対策の方針 • テスト ◦ CIマシンで複数コア積んでいることが多いので、全CPU使うような設 定にする ▪ CPUのコア数に応じて自動で並列bundle installするコマンド ▪

    bundle install --job=$(nproc) ◦ 1つのジョブを複数のジョブに分割&並列化する
  68. スロービルド対策の方針 • テスト ◦ DBアクセスが多すぎて遅いのであれば https://hub.docker.com/r/circleci/mysql のramがついてるtag を使ってみるのも一興 ▪ ストレージの代わりにRAMを使うので速い分、メモリを喰ってジョ

    ブによってはOOMになる可能性があるので注意 ▪ ramつけるだけで使えるので試しやすいし戻しやすい
  69. 設定ファイルをシンプルにする • ボトルネックが分かってチューニングしようにもスパゲッティymlが足を 引っ張ることが多いのでリファクタリングもセットで行う • 複数箇所で使うものはymlにインラインで書かずにシェルスクリプトに抽出 する • CircleCIのorbsのように再利用できる仕組みがあれば乗っかる

  70. オチ • ここまでやっても多少は速くなったが劇的に改善しなかったのでCircleCI の並列数を増やしたら速くなった(それはそう)

  71. CIのキャッシュ戦略 • 長いのでブログ参照 • GitLab CIとCircleCIのキャッシュ戦略の違い - くりにっき ◦ https://sue445.hatenablog.com/entry/2019/10/30/084626

  72. アジェンダ • なぜCIをするのか • CIの歴史 • 何をCI/CDするのか • いつCIを導入すべきか •

    いつ(どのタイミングで、どの周期で)CIすべきか • 何を使うべきか • スロービルド改善 • CIのキャッシュ戦略 • これからのCI
  73. これからのCI • 分からん • 今後もどんどん便利なツールが出てくるはずなので定期的に式年遷宮し た方がよさそう • 基本的にはDockerイメージとシェルを実行する場所が変わるだけなので 容易に乗り換えできるはず

  74. 参考: index_shotgunの式年遷宮 • https://github.com/sue445/index_shotgun • Travis CI期 ◦ sqlite3, MySQL,

    PostgreSQLだけ • Travis CI + Wercker併用期 ◦ Travis CIでOracleインストールするだけで30分くらいかかってつら い ◦ この当時Dockerに対応してたのがWerckerのみだったのでOracle のCIするためにWercker利用
  75. 参考: index_shotgunの式年遷宮 • Travis CI + CircleCI 2.0併用期 ◦ Werckerも悪くはなかったが設定がymlで完結しないつらみ

    ▪ ワークフローの設定は画面で設定する必要がある ◦ CiecleCI 2.0が出たあたりで移行
  76. 参考: index_shotgunの式年遷宮 • GitHub Actions ◦ .circleci/config.yml 修正しただけでTravis CIのクソデカビルドが 走るのがつらい

    ◦ Travis CI並列数が全然足りない ▪ Travis CIだと5並列で50ビルド計1時間。ピーク期は70ビルド計 2時間 ◦ GitHub Actions発表直後に移行 ▪ 20並列で70ビルド20分
  77. まとめ • 何をしたいかや規模によって使うもの(SaaS、セルフホスティング含めて) が変わる ◦ 銀の弾丸はない • CIの仕組みやエコシステムにのっかることによっていくらでもリファクタリン グできる •

    手作業を自動化することによって生産性を何倍にもできる • 技術革新によってその時点の最適解がすぐに陳腐化する ◦ 作った当時の最適解が今の最適解とは限らない ◦ 必要に応じて式年遷宮も必要
  78. one more thing

  79. one more thing CI as a CI 「CIをCIする」

  80. 複数リポジトリのCI設定の共通化(CI as a CI) • アプリケーションコードと同様CIの設定も継続的にメンテしていく ◦ みんなリファクタリング大好きだよね? • 複数リポジトリメンテしてるとリポジトリによって設定が違うと大変なので極

    力統一したい • 同一yamlを複数リポジトリでコピペして使い回すのが理想だがgemに よってサポートしてるrubyのバージョンが変わったりするので厳しい ◦ とはいえ8割方一緒なので共通化できる
  81. というわけでCI as a CIした • https://github.com/sue445/ci-config-itamae • RailsのmigrationとAnsibleのplaybookがあわさった感じ • Itamaeを活用したマイグレーションシステム

    • 自分の作業を効率化することに特化してるので汎用化はあまり考えられ ていない
  82. Usage (Generate a migration file) $ ./bin/generate --template=github_actions some_migration Write

    to /path/to/ci-config-itamae/cookbooks/migrate/github_actions/202 00311232827_some_migration.rb
  83. Usage (Edit a migration) file "#{node[:repo]}/.github/workflows/test.yml" do action :edit block

    do |content| next if content.include?("centos:8") content.gsub!(<<-YAML, <<-YAML) - centos:7 YAML - centos:7 - centos:8 YAML end only_if "ls #{node[:repo]}/.github/workflows/test.yml" end
  84. Usage (Apply to a repo) # dry run結果が問題なければ--dry-runを外して実行 $ ./bin/migrate

    --recipe=cookbooks/migrate/github_actions/20200311232827_som e_migration.rb -m "This is commit message" --repo=github.com/sue445/rubicure --dry-run
  85. Usage (Apply to multiple repos) # dry run結果が問題なければ--dry-runを外して実行 $ ./bin/migrate

    --recipe=cookbooks/migrate/github_actions/20200311232827_som e_migration.rb -m "This is commit message" --include=gem --dry-run
  86. 挙動 • ローカルの複数リポジトリに対して下記を実行 ◦ ghq get ◦ git pull ◦

    git checkout -b 【適当なブランチ名】 ◦ Itamaeでmigrationを適用 ◦ 差分があったらコミットしてPR投げる • 30個のリポジトリにPR投げるまで10分 ◦ これ作る前は手作業で半日がかり • PR投げられたらあとはビルドが終わるまで待つだけ