15年続くWebサービスへのCI/CDとテストコードの導入

24003578771c047a2bcac2a52a8d0781?s=47 Yuto Kubo
December 01, 2019

 15年続くWebサービスへのCI/CDとテストコードの導入

PHP Conference Japan 2019

24003578771c047a2bcac2a52a8d0781?s=128

Yuto Kubo

December 01, 2019
Tweet

Transcript

  1. 15年続くWebサービスへの CI/CDとテストコードの導入 久保 雄登 /9bo9bo 株式会社ウエディングパーク

  2. • 久保 雄登(9bo9bo) – 株式会社ウエディングパーク – メディア開発本部 チーフエンジニア • 業務

    – クライアント向け管理画面の運用・開発 – データ活用基盤の開発 • その他 – カレーライスを作る – 社内Hack(お困りごと解決) – ミュージカル観劇(家族の影響) – 群馬県(出身は埼玉) 自己紹介 2
  3. Wedding Park について 3

  4. • 式場探しの決め手が見つかるクチコミサイト • 2004年にオープン。今年で15周年 Wedding Park 4

  5. • 結婚に関連するサービスを展開 姉妹サービス 5

  6. ところで、 6

  7. • Q. どんな印象を持たれますか? – 独自フレームワーク? – PHP5を使い続けている? – 闇が広がる? 15周年を迎えるWebサービスって……

    7
  8. 安心してください 8

  9. • 2016年〜システムリプレイスを実施 – PHP7 + Laravel を基盤としたシステムに入替 – 2019年にPHP5系システムは全廃 •

    だけど、つらい部分もある… – 複雑化した仕様、依存関係の多いシステム、 etc – 今日はこのあたりをお話しします 現行システムはすべてPHP7で稼働 9
  10. • Wedding Parkを支えるシステムのこれまで • CIの導入に至った経緯 • CIの導入 • レガシーシステムにテストを入れる •

    現在のCI/CDの設定 • まとめ 今日お話しすること 10
  11. • Wedding Parkを支えるシステムのこれまで • CIの導入に至った経緯 • CIの導入 • レガシーシステムにテストを入れる •

    現在のCI/CDの設定 • まとめ 今日お話しすること 11
  12. Wedding Parkを支える システムのこれまで 12

  13. システムのリプレイスは積極的 • アプリケーションの歴史 〜2012年:PHP5 + Ethna 〜2017年:PHP5 + ZendFramework 1

    2017年〜:PHP7 + Laravel 5 [現行] • DBの歴史 – 2012年に整理したテーブルを継続して利用 Wedding Parkを支えるシステム 13
  14. • 増え続ける機能 • 陳腐化していく仕様書マスター • 開発時は「今までの仕様」に「この機能を追加」 – 今までの仕様の記録がない…… – 把握していない仕様があって障害発生

    • サービスが成長すれば、DBも成長する – 約700テーブル – 今は使っていないテーブルやカラムが混在 長寿命システムの悩み 14
  15. • 歴史を感じるモノリシックな構成 システム構成 ユーザ 社内 管理 法人 管理 バッチ ……

    15
  16. • Modelやシステムのコアに関する処理は git subtree で共有 – 実装箇所の一元管理、開発作業の効率化が目的 開発を効率的に行うアーキテクチャ ユーザ 社内

    管理 法人 管理 バッチ git subtree 16
  17. • Wedding Parkを支えるシステムのこれまで • CIの導入に至った経緯 • CIの導入 • レガシーシステムにテストを入れる •

    現在のCI/CDの設定 • まとめ 今日お話しすること 17
  18. CIの導入に至った経緯 18

  19. • Modelやシステムのコアに関する処理は git subtree で共有 – 実装箇所の一元管理、開発作業の効率化が目的 再掲: 開発を効率的に行うアーキテクチャ ユーザ

    社内 管理 法人 管理 バッチ git subtree 19
  20. 事件は起きた! 20

  21. • 十分にテストされないままリリース あるプロジェクトでコアに関する処理を 変更 ユーザ 法人 管理 バッチ git subtree

    社内 管理 21
  22. • 十分にテストされないままリリース – バグの含まれる処理がシステム全体に配布される あるプロジェクトでコアに関する処理を 変更 git subtree ユーザ 社内

    管理 法人 管理 バッチ 22
  23. そのまま障害へ! 23

  24. • コアプログラムに関するテストコードは実装 してあった – テストも失敗していた • テストの実行は開発者に委ねられていた • リリース前に自動的に検証される仕組みは なかった

    障害のふりかえり 24
  25. CI入れたい…! 25

  26. • Wedding Parkを支えるシステムのこれまで • CIの導入に至った経緯 • CIの導入 • レガシーシステムにテストを入れる •

    現在のCI/CDの設定 • まとめ 今日お話しすること 26
  27. • 開発時の自動テストやコード解析は一切行っ ていなかった – 頼りになるのはIDE(PhpStorm)の解析のみ • 一度も呼び出されないprivate関数がちらほら • コードレビュー時に気がつかなければ そのままリリースされてしまう

    27 CIが一切ない開発環境
  28. • CI: Continuous Integration – いつでも正しく動くようにする仕組み • 例: Unitテスト、E2Eテスト、コード解析 •

    CD: Continuous Delivery – いつでもリリースできるようにする仕組み • 例: 自動デプロイ CI / CD 28
  29. • 当初はデプロイサーバのJenkinsで実行 – デプロイサーバとアプリケーションサーバの環境 を揃えておく必要があった – 異なるPHPバージョンを共存させられないため、 一部のアプリのみの導入にとどまっていた • GitLab

    CIの検討 – Dockerコンテナ上で動作するため、複数のPHP バージョンを用意できる – すべてのアプリでテストが実施可能 29 CIの導入
  30. • git push をトリガーに各種テストを行う CIの流れ 開発者 git push GitLab CI

    テスト Merge Request / Merge 次の開発へ 30 GitLab
  31. • デプロイの仕組みは既に導入済み – 今回はGitLab CIに移行せずそのまま CDの流れ Capistrano デプロイサーバ 対象サーバ git

    clone deploy 31
  32. • Wedding Parkを支えるシステムのこれまで • CIの導入に至った経緯 • CIの導入 • レガシーシステムにテストを入れる •

    現在のCI/CDの設定 • まとめ 今日お話しすること 32
  33. レガシーシステムで テストを書く悩み 33

  34. DBマイグレーションがない! 34

  35. • Unitテストは既に実装されつつあった • DBを使ったFeatureテストは未実装 – DBのスキーマは日々変わる – マイグレーションがないためDBの状態を管理でき ない –

    テストのたびにDBからdumpする必要がある DBマイグレーションがない 35 マイグレーションの検討
  36. • Laravel Migration Exporter for Sequel Pro – 既存のDBからLaravel用のマイグレーションファイ ルを作成してくれるツール

    – Sequel Pro のプラグインとして動作 マイグレーションファイルを作成する 試してみたところ… 36
  37. テーブル数が多すぎて フリーズ! 37

  38. • mysqldump で定期的にスキーマ情報を dump – Git Repository に push •

    テストの際に、git clone して DB へ import ならば、昔ながらの方法で 38
  39. .gitlab-ci.yml の例 GitLab CI で mysqldump と git push dump:

    variables: GIT_STRATEGY: clone script: - git config user.name $GITLAB_USER_NAME && git config user.email $GITLAB_USER_EMAIL - git remote set-url origin https://gitlab-ci-token:$API_TOKEN@${CI_REPOSITORY_URL##*@} - git checkout $CI_COMMIT_REF_NAME # DB のダンプ - mysqldump -hDB -uUSER -p$PASS --single-transaction --skip-dump-date --no-data -- databases yourDB > yourDB.sql # 差分があるときはコミット - git add -u - |- if [ `git status -s | wc -l` -gt 0 ]; then git commit -m "updated at `date +%Y/%m/%d-%H:%M`" git push --push-option=ci.skip origin $CI_COMMIT_REF_NAME fi 39
  40. ひととおりのテストが 書けるように! 40

  41. • Wedding Parkを支えるシステムのこれまで • CIの導入に至った経緯 • CIの導入 • レガシーシステムにテストを入れる •

    現在のCI/CDの設定 • まとめ 今日お話しすること 41
  42. • ビルドテスト – Sass, JavaScript • PHPUnit • 静的解析 –

    PHPStan(Larastan) – ESLint • コード整形 – PHP-CS-Fixer – prettier • 脆弱性診断 現在のCIの設定 42
  43. • ビルドテスト – Sass, JavaScript • PHPUnit • 静的解析 –

    PHPStan(Larastan) – ESLint • コード整形 – PHP-CS-Fixer – prettier • 脆弱性診断 現在のCIの設定 今回はこちらを詳しく説明 43
  44. • ビルドテスト – Sass, JavaScript • PHPUnit • 静的解析 –

    PHPStan(Larastan) – ESLint • コード整形 – PHP-CS-Fixer – prettier • 脆弱性診断 現在のCIの設定 44
  45. • 社内のコーディング規約はPSRに準拠 • PHP-CS-Fixer でコード整形を実施 PHP Coding Standards Fixer での整形

    45
  46. • コード整形の実行は開発者に委ねられている – よく忘れる – コードレビューでの指摘はお互い気をつかう • コード整形の自動化 – php-cs-fixer-commit

    を使うと、GitLab CI 上で コード整形 & git push してくれる コード整形を自動化したい composer require --dev enomotodev/php-cs-fixer-commit 46
  47. • ビルドテスト – Sass, JavaScript • PHPUnit • 静的解析 –

    PHPStan(Larastan) – ESLint • コード整形 – PHP-CS-Fixer – prettier • 脆弱性診断 現在のCIの設定 47
  48. • 定期的に利用しているパッケージに脆弱性が 含まれていないか確認する – npm audit – SensioLabs Security Checker

    • 継続的なcomposerアップデート – gitlabci-composer-update-mr 脆弱性診断 48
  49. • 定期的に利用しているパッケージに脆弱性が 含まれていないか確認する – npm audit – SensioLabs Security Checker

    • 継続的なcomposerアップデート – gitlabci-composer-update-mr 脆弱性診断 49
  50. • composer.lock の内容に脆弱性が報告されて いるパッケージがない存在しないか確認 – composer版はAPIとの通信が必要 – Symfony CLI を使うとオフラインで実行可能

    SensioLabs Security Checker curl -sS https://get.symfony.com/cli/installer | bash $HOME/.symfony/bin/symfony security:check 50
  51. • composer パッケージの更新は放置されがち – 差分の確認が大変 – composer update して git

    commit するのが面倒 • gitlabci-composer-update-mr – composer update して更新があった場合は マージリクエストを作成してくれる 継続的な composer アップデート composer global require enomotodev/gitlabci-composer-update-mr $COMPOSER_HOME/vendor/bin/gitlabci-composer-update-mr master 51
  52. 最終的なワークフロー composer install npm install npm run build phpunit larastan

    eslint + Prettier php-cs-fixer deploy npm audit symfony security:check Preparation Test Deploy Security Check ※ 定期実行 52 composer update
  53. • Wedding Parkを支えるシステムのこれまで • CIの導入に至った経緯 • CIの導入 • レガシーシステムにテストを入れる •

    現在のCI/CDの設定 • まとめ 今日お話しすること 53
  54. CIを入れて良かったこと 54

  55. • デプロイ不可能なコードの混入を防げるように – 開発の段階で未然に気がつける • レビュー時の指摘事項の軽減 – 「空白入れて」「PHPDoc直して」などのピリッとする 指摘を減らせた –

    本質的なレビューが行えるようになった • 後回ししがちなパッケージアップデートが前向き になった CIを入れて良かったこと 55
  56. CIを入れても変わらなかった こと 56

  57. • コードカバレッジは一向に増えない – 一部の開発者だけに普及 – まだまだ温かみのある手動テストが主流 • 開発フローはいつもと同じ – 良い意味で、CIの存在を意識せずに開発を行える

    – 各種チェックで指摘されなければこれまでと同じ 開発 – CIは心の支え CIを入れても変わらなかったこと 57
  58. 最後に 58

  59. 15年続くサービスの開発は 困難なことが多いけれど、 歴史があるぶん出来ることも 多くて楽しい 59

  60. • 15年続くWebサービスのCI環境を整備 – 不完全なコードの混入を防げるように – コード自動整形・静的解析でコードレビューの負 荷軽減 • テストを書くための基盤を構築 –

    DBマイグレーションのない環境でのテストの実施 まとめ 60