PHPゆるふわCI入門

公開日:

東京都練馬区立区民・産業プラザ Coconeriホールで開催された『PHPerKaigi 2019』でレギュラートーク(30分)として発表しました。

Download PDF

スライドテキスト

Page 1

PHPゆるふわCI入門

A casually guide for PHP Continuous Integration

2019-03-30 PHPerKaigi 2019 Day 1
Nerima Coconeri Hall

#phperkaigi

Page 2

お前誰よ
うさみけんた (@tadsan) / Zonu.EXE

  • GitHub/Packagistでは id: zonuexe
    • ピクシブ株式会社サービスプラットフォーム事業部
  • Emacs Lisper, PHPer
  • Emacs PHP Modeのメンテナ引き継ぎました
    • 好きなリスプはEmacs Lispです
    • Qiitaに記事を書いたり変なコメントしてるよ

Page 3

お前誰よ
2013年頃から仕事でPHPを書いてます

  • その前はRubyをちょっとやってました
  • 普段はPHP勉強会@東京などでふざけた話をします
  • 今回は実用的な話をします
  • 去年は前夜祭トークでふざけた話をしました

今回の発表の内容とは

  • あんまり関連ないです 無関係ではないけど

Page 4

Page 5

Page 6

Page 7

アジェンダ

Page 8

CI
とは何か

CI
で何ができるか

CI
実行環境の種類

CI
ゆるふわに を始める 実際の事例について

Page 9

CodeIgniter

(Web Framework) 話はしません

Page 10

CD
(Continuous

delivery/deployment)

話もしません

Page 11

個別の 製品の

CI
設定の話も

しません

Page 12

CI
とは何か

CI
で何ができるか

CI
実行環境の種類

CI
ゆるふわに を始める 実際の事例について

Page 13

本題の前に

Page 14

今回紹介するツールと
GitLab CIの設定をまとめて セットアップできるプロジェ
クトを用意してます

https://gitlab.com/zonuexe/phperkaigi-ci

Page 15

予め断っておきますが この構成では規模の大 きなプロジェクトでは

パフォーマンス目立ち
ます(断言)

Page 16

実プロジェクトに 導入する際は各自 の責任で取捨選択
してください

Page 17

あとすみません Windowsでは

たぶん動きません

Page 18

とは何か

CI

Page 19

単にシーアイ

とは

CI

と呼びます

Continuous Integration

(継続的インテグレーション)の略
もともとはXP

(エクストリームプログラミング)

コミュニティで明文化されたもの

…らしい
有名な文章は2000年に書かれた

Page 20

議論には登るが、実⾏に移されることの少 ない「ベストプラクティス」がソフトウェア 開発にはいっぱいある。その中でも、もっと も基本的かつ重要なもの⼀つが、「完全に ⾃動化されたビルドとテストプロセス」だ。 これは、プロジェクトチームが⾃分のソフト ウェアのビルドやテストを⼀⽇に何度も⾏
うことを可能にするものである。

継続的インテグレーション オブラブ訳

–Martin Fowler, ( )

http://objectclub.jp/community/XP-jp/xp_relate/cont-j

Page 21

Page 22

テスト自動化に必要なこと

(引用)

全てのソースコードが格納され、誰でも最新の(そして 過去の)ソースを取り出すことが可能な、ただ一つの出
入口を設定すること
ビルドプロセスを自動化して、誰でも、コマンド一つで
ソースからシステムを作り出すことができること
テスト作業を自動化して、コマンド一つでいつでもテス
トスィートを実行できるようにすること
現行の実行可能モジュールで、もっとも適切であると 自信を持てるようなものを、誰でも入手可能であるよう
にすること

継続的インテグレーション オブラブ訳

–Martin Fowler, ( )
http://objectclub.jp/community/XP-jp/xp_relate/cont-j

Page 23

テスト自動化に必要なこと

(引用)

Git/GitHub

全てのソースコードが格納され、誰でも最新の(そして 過去の)ソースを取り出すことが可能な、ただ一つの出

Composer

入口を設定すること
ビルドプロセスを自動化して、誰でも、コマンド一つで
テスティング

ソースからシステムを作り出すことができること
フレームワーク

テスト作業を自動化して、コマンド一つでいつでもテス
トスィートを実行できるようにすること

git tag / master

現行の実行可能モジュールで、もっとも適切であると 自信を持てるようなものを、誰でも入手可能であるよう
にすること

継続的インテグレーション オブラブ訳

–Martin Fowler, ( )
http://objectclub.jp/community/XP-jp/xp_relate/cont-j

Page 24

テスト自動化に必要なこと

(引用)

Git/GitHub

全てのソースコードが格納され、誰でも最新の(そして
CIの前提となる

過去の)ソースを取り出すことが可能な、ただ一つの出

Composer

入口を設定すること

環境は揃ってるので

ビルドプロセスを自動化して、誰でも、コマンド一つで
テスティング

ソースからシステムを作り出すことができること
フレームワーク

基本的に組み合せで

テスト作業を自動化して、コマンド一つでいつでもテス
かなりいける

トスィートを実行できるようにすること

git tag / master

現行の実行可能モジュールで、もっとも適切であると 自信を持てるようなものを、誰でも入手可能であるよう
にすること

継続的インテグレーション オブラブ訳

–Martin Fowler, ( )
http://objectclub.jp/community/XP-jp/xp_relate/cont-j

Page 25

銀の弾丸はない

コードの規模や構造によって 導入できるツール・できない
ツールがある
大規模なコードになるほど

実行時間が掛かるようになり
工夫が必要になってくる

Page 26

で何ができるか

CI

Page 27

継続的にされてると嬉しいこと

いろいろあるだろうが、基本的 にはコードが正常に保たれてる
ことは確認し続けたい

(コード上の異常発生を迅速に知る) そのほか属人化してる項目や 忘れられがちなプロセスを盛
り込めるとよい

Page 28

コードの異常を検知するには

実行してチェックする
自動テスト

(ユニットテスト, 受け入れテスト)

人間が動作確認
実行せずコードの品質を検査する
「QAツール」と総称される

Page 29

自動テスト(ユニットテスト)

PHPUnit, phpspecなど
小さな単位でテストすることが 理想だが、コードが古く結合度 が高いプロジェクトではユニッ トテストに表現することが困難
なこともある

Page 30

自動テスト(受け入れテスト)

Codeception
実際にHTTPリクエストを行っ てテストできるフレームワーク 古くテストが少ないプロジェク トではこちらの方が導入しやす
いかもしれない

Page 31

QAツール

(Quality Assurance)

大まかに二種類に大別できる
字句解析ベースで主にスタイル
を検査するもの
再帰的な型検査を行うもの

Page 32

コーディングスタイルベース

コードを字句的に解釈する

PHPMD (PHP Mess Detector) PHP_CodeSniffer & phpcbf PHP Coding Standards Fixer
修正までやってくれるやつ

Page 33

型検査を含む精密な型検査

字句的な静的解析ツールはオブ ジェクトの未定義メソッド検出 などはできないのに対して、最 近開発が活発なツールはコード パスを詳細に解析して、さまざ
まな情報を出してくれる

Page 34

型検査を含む精密な型検査

それぞれ開発が活発なツール

PHPStan, Psalm, Phan
ぶっちゃけキャラが被ってるけ ど、それぞれ検出してくれるポ
イントが違ったりする

Page 35

Page 36

PHPStan vs Phan

Phanは純粋な静的解析
プロジェクト全体スキャン
PHPStanは実行時情報も利用
し必要なファイルのみ解析
高速に結果を返したい場合は
PHPStanの方が有利

Page 37

PHPStanの制約

クラスや関数・定数の定義を 予め(または遅延)読み込みでき
るようにする必要がある
PSR-1(定義だけのファイルと 副作用の処理を分離すること)
が重要

Page 38

PHPStanの制約

ComposerとかPSR-1を考慮し てない時代のPHPプロジェクトに は厳しいが、ハードルを越えれば
高速で頻繁なビルドが可能

Page 39

PHPStanの効能

今回の本題とは少し離れるが、 EmacsやVimでチェッカーのバッ クエンドとして適切に設定す ると、PhpStormを凌ぐ情報量
がリアルタイムで得られる

Page 40

Page 41

Vim+ALE

Page 42

の実行環境

CI
いろいろ

Page 43

はいつ実行する

CI

「たくさんやるほうが望ましい」 多くの サービスでGitHubと

CI

連携して、Pull Requestを作成 したブランチにPushするたびに
毎回ビルドを行うのが普通
結果はPRのページに表示される

Page 44

汎用 の実行環境

CI

テストプログラムを「自動的」かつ 「継続的」に実行する必要がある 汎用の と特定用途の がある

CI CI
現実的には下記のどちらか
各種 SaaS 契約

のどれかと

CI
用のサーバを自前で用意

CI

Page 45

SaaS (hosted)

CI

サーバ自前管理の必要がない 典型的にはGitHubなどと連携
側が用意したOS環境を利用す

CI
るものと、Dockerイメージを利
用するものがある

Page 46

Page 47

SaaSの制約

CI

GitHub Enterpriseやオンプレ
のGitLabは連携できない
各種 のオンプレ版(有償)を利

CI

用することで利用できるが、 サーバの調達・管理は自前で

行う必要がある

Page 48

オンプレミスの

CI

サーバを自前で調達・管理する
必要がある
無料の製品ではJenkinsの牙城
だった

自前でGitLab CEを 機能を持っ

CI

てるので連携することもできる

Page 49

GitLabの場合

GitLabには複数ある
SaaS版のGitLab.com オンプレ版のGitLab
それぞれの有料・無料版
どちらも 機能が統合されてる

CI

Page 50

GitLab.com

無料でプライベートリポジトリ可
無料版でも 機能が利用可能

CI

グループあたり月2000分まで
設定ファイルに書くだけで
Dockerでビルドが実行される

Page 51

特定用途の

CI

PHP解析

SensioLabsInsight
Scrutinizer
コーディングスタイル

StyleCI

Page 52

御託はわかった

Page 53

で、結局いろいろ準備

しなくちゃいけなくて めんどくさいんでしょ?

Page 54

ゆるふわに始める

CI

Page 55

もっと気軽に手を

付けられるところから

やっていきましょう

Page 56

継続して動かせる
サーバがない

さてどうするか

Page 57

テスト自動化に必要なこと

(引用)

全てのソースコードが格納され、誰でも最新の(そして 過去の)ソースを取り出すことが可能な、ただ一つの出
入口を設定すること
ビルドプロセスを自動化して、誰でも、コマンド一つで
ソースからシステムを作り出すことができること
テスト作業を自動化して、コマンド一つでいつでもテス
トスィートを実行できるようにすること
現行の実行可能モジュールで、もっとも適切であると 自信を持てるようなものを、誰でも入手可能であるよう
にすること

継続的インテグレーション オブラブ訳

–Martin Fowler, ( )
http://objectclub.jp/community/XP-jp/xp_relate/cont-j

Page 58

複雑な反復作業があれば、

一個のコマンド で

(スクリプト)

まとめてみることから始める

Page 59

ところで

Page 60

みなさんSyntaxErrorのPHP スクリプトを本番に反映して 事故ったことはありますか?

Page 61

私はたくさんあります

!

Page 62

Syntax Errorになる

ファイルを確実に

捕捉してみましょう

Page 63

git ls-files '*\.php' |

xargs -I{} php -l {}

Page 64

xargs

Windowsには が

ない のでPHPで
(たぶん)

https://gist.github.com/zonuexe/a513afd1d6933b3cc5cca0eb866f2834

Page 65

ファイルが数十個単位ならす ぐに終るが、数千単位になる

と全数の検査はかなり 時間が掛かるので注意

Page 66

弊社での事例に
ついて

Page 67

Page 68

ファイル数

6264

行数

Page 69

毎回全ファイルを チェックするのは

さすがにつらい

Page 70

デプロイ時に常にgit tagをつける

デプロイスクリプトで、

デプロイ成功したら日時と作 業者名を含むタグを生成して
originにpushする

Page 71

最新のリリースタグとの差分をとる

これで最新デプロイと手元の

差分があるファイル抽出できる

Page 72

デプロイ時に を行う

php -l

差分のあるファイル全部に対し てチェックを実施し、一つでも エラーのファイルがあったらデ
プロイ処理を中断する
中断されるとtagはつかないの で、差分が隠れることはない

Page 73

MergeRequestと二種類のビルド

PHPUnit
PHPStanおよび独自Linter
それぞれ実行時間は1分ちょっと

Page 74

PHPStan

PHPStan本運用のためbootstrap 処理の軽いリファクタリングをした

_autoloader_for_static_analysis.php この作業によってPhpactorと
いう別ツールも利用可能に

Page 75

PHPUnit

直列実行で10分前後かかっていた テストが依存するMySQLを複数起 動し、PHPUnitのプロセスを並列
実行することで1分程度で完了

Page 76

masterブランチへのテスト

MRのテストを無視してmaster にマージされたときの防波堤 この段階で失敗したテストは
Slackで報告される
時刻に依存したテストのランダ ムフェイルがたまに報告される

Page 77

実行環境

GitLab CI + Jenkins
以前はPHPStanの警告はGitLab
のMRへのコメントで報告 現在は 実行はAWSまたは

CI

Jenkinsで、それぞれの結果を GitLabのパイプラインに統合

Page 78

まとめ

Page 79

どのような を導入するか

CI

プロジェクトの現状・性質による
テストが書ける密結合度か
定義ファイルは分離されてるか (同名の関数や定数が複数定義
されてるとはまる)

Page 80

発表時に書き

そびれたこと

Page 81

小姑

CI

コーディングスタイルのような重 箱の隅は人間がコードレビューで

小うるさく責めるより、Botが鉄の
心で指摘した方が角が立たない PHP-CS-Fixerやphpcbfのよう なコマンド一撃で修正されるよう
にすれば手間もかからない

Page 82

どんな場合も静的解析を導入すべきか

普通の既存プロジェクトをPHPStan やPhanで解析すると異常な量の 型の不整合の警告が出るのが普通 多すぎる警告を目のあたりにする
と、人間は無力感に苛まれる

(学習性無力感)

Page 83

警告を深刻に受け止めない

そのプロダクトが実際は動いてる のであれば、現状をあまり深刻に
感じる必要はない
警告は記述の不整合や曖昧な点を 教えてくれてるだけなので、「警 告を減らす」ことに価値がある

Page 84

注目する警告を減らす

Phanであればmasterでのログ 出力とブランチでの出力が減る

(増えない)ことだけに注目する PHPStanであれば、ブランチで変
更したファイル

(と、そのクラス/関数を
だけを対象にしてみる

使ったファイル)

Page 85

解析に怯えすぎず

ご安全に