Page 1
PHPゆるふわCI入門
A casually guide for PHP Continuous Integration
2019-03-30 PHPerKaigi 2019 Day 1
Nerima Coconeri Hall
#phperkaigi
公開日:
by USAMI Kenta @tadsan
に東京都の練馬区立区民・産業プラザ Coconeriホールで開催された『PHPerKaigi 2019』でレギュラートーク(30分)として発表しました。
PHPゆるふわCI入門
A casually guide for PHP Continuous Integration
2019-03-30 PHPerKaigi 2019 Day 1
Nerima Coconeri Hall
#phperkaigi
お前誰よ
うさみけんた (@tadsan) / Zonu.EXE
お前誰よ
2013年頃から仕事でPHPを書いてます
今回の発表の内容とは
アジェンダ
CI
とは何か
CI
で何ができるか
CI
実行環境の種類
CI
ゆるふわに を始める 実際の事例について
CodeIgniter
の
(Web Framework) 話はしません
CD
(Continuous
delivery/deployment)
の
話もしません
個別の 製品の
CI
設定の話も
しません
CI
とは何か
CI
で何ができるか
CI
実行環境の種類
CI
ゆるふわに を始める 実際の事例について
本題の前に
今回紹介するツールと
GitLab CIの設定をまとめて セットアップできるプロジェ
クトを用意してます
https://gitlab.com/zonuexe/phperkaigi-ci
予め断っておきますが この構成では規模の大 きなプロジェクトでは
パフォーマンス目立ち
ます(断言)
実プロジェクトに 導入する際は各自 の責任で取捨選択
してください
あとすみません Windowsでは
たぶん動きません
とは何か
CI
単にシーアイ
とは
CI
と呼びます
Continuous Integration
(継続的インテグレーション)の略
もともとはXP
(エクストリームプログラミング)
コミュニティで明文化されたもの
…らしい
有名な文章は2000年に書かれた
議論には登るが、実⾏に移されることの少 ない「ベストプラクティス」がソフトウェア 開発にはいっぱいある。その中でも、もっと も基本的かつ重要なもの⼀つが、「完全に ⾃動化されたビルドとテストプロセス」だ。 これは、プロジェクトチームが⾃分のソフト ウェアのビルドやテストを⼀⽇に何度も⾏
うことを可能にするものである。
継続的インテグレーション オブラブ訳
–Martin Fowler, ( )
http://objectclub.jp/community/XP-jp/xp_relate/cont-j
テスト自動化に必要なこと
(引用)
全てのソースコードが格納され、誰でも最新の(そして 過去の)ソースを取り出すことが可能な、ただ一つの出
入口を設定すること
ビルドプロセスを自動化して、誰でも、コマンド一つで
ソースからシステムを作り出すことができること
テスト作業を自動化して、コマンド一つでいつでもテス
トスィートを実行できるようにすること
現行の実行可能モジュールで、もっとも適切であると 自信を持てるようなものを、誰でも入手可能であるよう
にすること
継続的インテグレーション オブラブ訳
–Martin Fowler, ( )
http://objectclub.jp/community/XP-jp/xp_relate/cont-j
テスト自動化に必要なこと
(引用)
Git/GitHub
全てのソースコードが格納され、誰でも最新の(そして 過去の)ソースを取り出すことが可能な、ただ一つの出
Composer
入口を設定すること
ビルドプロセスを自動化して、誰でも、コマンド一つで
テスティング
ソースからシステムを作り出すことができること
フレームワーク
テスト作業を自動化して、コマンド一つでいつでもテス
トスィートを実行できるようにすること
git tag / master
現行の実行可能モジュールで、もっとも適切であると 自信を持てるようなものを、誰でも入手可能であるよう
にすること
継続的インテグレーション オブラブ訳
–Martin Fowler, ( )
http://objectclub.jp/community/XP-jp/xp_relate/cont-j
テスト自動化に必要なこと
(引用)
Git/GitHub
全てのソースコードが格納され、誰でも最新の(そして
CIの前提となる
過去の)ソースを取り出すことが可能な、ただ一つの出
Composer
入口を設定すること
環境は揃ってるので
ビルドプロセスを自動化して、誰でも、コマンド一つで
テスティング
ソースからシステムを作り出すことができること
フレームワーク
基本的に組み合せで
テスト作業を自動化して、コマンド一つでいつでもテス
かなりいける
トスィートを実行できるようにすること
git tag / master
現行の実行可能モジュールで、もっとも適切であると 自信を持てるようなものを、誰でも入手可能であるよう
にすること
継続的インテグレーション オブラブ訳
–Martin Fowler, ( )
http://objectclub.jp/community/XP-jp/xp_relate/cont-j
銀の弾丸はない
コードの規模や構造によって 導入できるツール・できない
ツールがある
大規模なコードになるほど
実行時間が掛かるようになり
工夫が必要になってくる
で何ができるか
CI
継続的にされてると嬉しいこと
いろいろあるだろうが、基本的 にはコードが正常に保たれてる
ことは確認し続けたい
(コード上の異常発生を迅速に知る) そのほか属人化してる項目や 忘れられがちなプロセスを盛
り込めるとよい
コードの異常を検知するには
実行してチェックする
自動テスト
(ユニットテスト, 受け入れテスト)
人間が動作確認
実行せずコードの品質を検査する
「QAツール」と総称される
自動テスト(ユニットテスト)
PHPUnit, phpspecなど
小さな単位でテストすることが 理想だが、コードが古く結合度 が高いプロジェクトではユニッ トテストに表現することが困難
なこともある
自動テスト(受け入れテスト)
Codeception
実際にHTTPリクエストを行っ てテストできるフレームワーク 古くテストが少ないプロジェク トではこちらの方が導入しやす
いかもしれない
QAツール
(Quality Assurance)
大まかに二種類に大別できる
字句解析ベースで主にスタイル
を検査するもの
再帰的な型検査を行うもの
コーディングスタイルベース
コードを字句的に解釈する
PHPMD (PHP Mess Detector) PHP_CodeSniffer & phpcbf PHP Coding Standards Fixer
修正までやってくれるやつ
型検査を含む精密な型検査
字句的な静的解析ツールはオブ ジェクトの未定義メソッド検出 などはできないのに対して、最 近開発が活発なツールはコード パスを詳細に解析して、さまざ
まな情報を出してくれる
型検査を含む精密な型検査
それぞれ開発が活発なツール
PHPStan, Psalm, Phan
ぶっちゃけキャラが被ってるけ ど、それぞれ検出してくれるポ
イントが違ったりする
PHPStan vs Phan
Phanは純粋な静的解析
プロジェクト全体スキャン
PHPStanは実行時情報も利用
し必要なファイルのみ解析
高速に結果を返したい場合は
PHPStanの方が有利
PHPStanの制約
クラスや関数・定数の定義を 予め(または遅延)読み込みでき
るようにする必要がある
PSR-1(定義だけのファイルと 副作用の処理を分離すること)
が重要
PHPStanの制約
ComposerとかPSR-1を考慮し てない時代のPHPプロジェクトに は厳しいが、ハードルを越えれば
高速で頻繁なビルドが可能
PHPStanの効能
今回の本題とは少し離れるが、 EmacsやVimでチェッカーのバッ クエンドとして適切に設定す ると、PhpStormを凌ぐ情報量
がリアルタイムで得られる
Vim+ALE
の実行環境
CI
いろいろ
はいつ実行する
CI
「たくさんやるほうが望ましい」 多くの サービスでGitHubと
CI
連携して、Pull Requestを作成 したブランチにPushするたびに
毎回ビルドを行うのが普通
結果はPRのページに表示される
汎用 の実行環境
CI
テストプログラムを「自動的」かつ 「継続的」に実行する必要がある 汎用の と特定用途の がある
CI CI
現実的には下記のどちらか
各種 SaaS 契約
のどれかと
CI
用のサーバを自前で用意
CI
SaaS (hosted)
CI
サーバ自前管理の必要がない 典型的にはGitHubなどと連携
側が用意したOS環境を利用す
CI
るものと、Dockerイメージを利
用するものがある
SaaSの制約
CI
GitHub Enterpriseやオンプレ
のGitLabは連携できない
各種 のオンプレ版(有償)を利
CI
用することで利用できるが、 サーバの調達・管理は自前で
行う必要がある
オンプレミスの
CI
サーバを自前で調達・管理する
必要がある
無料の製品ではJenkinsの牙城
だった
自前でGitLab CEを 機能を持っ
CI
てるので連携することもできる
GitLabの場合
GitLabには複数ある
SaaS版のGitLab.com オンプレ版のGitLab
それぞれの有料・無料版
どちらも 機能が統合されてる
CI
GitLab.com
無料でプライベートリポジトリ可
無料版でも 機能が利用可能
CI
グループあたり月2000分まで
設定ファイルに書くだけで
Dockerでビルドが実行される
特定用途の
CI
PHP解析
SensioLabsInsight
Scrutinizer
コーディングスタイル
StyleCI
御託はわかった
で、結局いろいろ準備
しなくちゃいけなくて めんどくさいんでしょ?
ゆるふわに始める
CI
もっと気軽に手を
付けられるところから
やっていきましょう
継続して動かせる
サーバがない
さてどうするか
テスト自動化に必要なこと
(引用)
全てのソースコードが格納され、誰でも最新の(そして 過去の)ソースを取り出すことが可能な、ただ一つの出
入口を設定すること
ビルドプロセスを自動化して、誰でも、コマンド一つで
ソースからシステムを作り出すことができること
テスト作業を自動化して、コマンド一つでいつでもテス
トスィートを実行できるようにすること
現行の実行可能モジュールで、もっとも適切であると 自信を持てるようなものを、誰でも入手可能であるよう
にすること
継続的インテグレーション オブラブ訳
–Martin Fowler, ( )
http://objectclub.jp/community/XP-jp/xp_relate/cont-j
複雑な反復作業があれば、
一個のコマンド で
(スクリプト)
まとめてみることから始める
ところで
みなさんSyntaxErrorのPHP スクリプトを本番に反映して 事故ったことはありますか?
私はたくさんあります
!
Syntax Errorになる
ファイルを確実に
捕捉してみましょう
git ls-files '*\.php' |
xargs -I{} php -l {}
xargs
Windowsには が
ない のでPHPで
(たぶん)
https://gist.github.com/zonuexe/a513afd1d6933b3cc5cca0eb866f2834
ファイルが数十個単位ならす ぐに終るが、数千単位になる
と全数の検査はかなり 時間が掛かるので注意
弊社での事例に
ついて
ファイル数
6264
行数
毎回全ファイルを チェックするのは
さすがにつらい
デプロイ時に常にgit tagをつける
デプロイスクリプトで、
デプロイ成功したら日時と作 業者名を含むタグを生成して
originにpushする
最新のリリースタグとの差分をとる
これで最新デプロイと手元の
差分があるファイル抽出できる
デプロイ時に を行う
php -l
差分のあるファイル全部に対し てチェックを実施し、一つでも エラーのファイルがあったらデ
プロイ処理を中断する
中断されるとtagはつかないの で、差分が隠れることはない
MergeRequestと二種類のビルド
PHPUnit
PHPStanおよび独自Linter
それぞれ実行時間は1分ちょっと
PHPStan
PHPStan本運用のためbootstrap 処理の軽いリファクタリングをした
_autoloader_for_static_analysis.php この作業によってPhpactorと
いう別ツールも利用可能に
PHPUnit
直列実行で10分前後かかっていた テストが依存するMySQLを複数起 動し、PHPUnitのプロセスを並列
実行することで1分程度で完了
masterブランチへのテスト
MRのテストを無視してmaster にマージされたときの防波堤 この段階で失敗したテストは
Slackで報告される
時刻に依存したテストのランダ ムフェイルがたまに報告される
実行環境
GitLab CI + Jenkins
以前はPHPStanの警告はGitLab
のMRへのコメントで報告 現在は 実行はAWSまたは
CI
Jenkinsで、それぞれの結果を GitLabのパイプラインに統合
まとめ
どのような を導入するか
CI
プロジェクトの現状・性質による
テストが書ける密結合度か
定義ファイルは分離されてるか (同名の関数や定数が複数定義
されてるとはまる)
発表時に書き
そびれたこと
小姑
CI
コーディングスタイルのような重 箱の隅は人間がコードレビューで
小うるさく責めるより、Botが鉄の
心で指摘した方が角が立たない PHP-CS-Fixerやphpcbfのよう なコマンド一撃で修正されるよう
にすれば手間もかからない
どんな場合も静的解析を導入すべきか
普通の既存プロジェクトをPHPStan やPhanで解析すると異常な量の 型の不整合の警告が出るのが普通 多すぎる警告を目のあたりにする
と、人間は無力感に苛まれる
(学習性無力感)
警告を深刻に受け止めない
そのプロダクトが実際は動いてる のであれば、現状をあまり深刻に
感じる必要はない
警告は記述の不整合や曖昧な点を 教えてくれてるだけなので、「警 告を減らす」ことに価値がある
注目する警告を減らす
Phanであればmasterでのログ 出力とブランチでの出力が減る
(増えない)ことだけに注目する PHPStanであれば、ブランチで変
更したファイル
(と、そのクラス/関数を
だけを対象にしてみる
使ったファイル)
解析に怯えすぎず
ご安全に