PHP Manual
/
セキュリティ

GitHub Actions - 2021年に向けての最適なCI

07. 02. 2021

Obsah článku

Webアプリケーションの開発を始めてしばらく経つと、多くのことが日常的に繰り返されるようになっていることに気づくでしょう。技術的なプロジェクト管理、ファイルのバージョン管理、自動コードレビュー、さまざまなデータ処理、あるいはサーバーへのデプロイやセキュリティ関連など、非常に多くのことが行われています。

企業でコンサルティングをしていると、予防が非常に軽視されているという問題にぶつかることが非常に多いのです。その理由は、開発者があることを非常に困難なことだと認識し、それが自分たちの仕事を増やすことになると考えるからであることが多いのです。しかし、実際には、通常、すべてのセットアップを一度設定するだけで、あとは長期的な利益を享受するだけなのです。

CI(Continuous Integration)とは

CI/CDは、プロジェクトで繰り返される、似たような基盤の定型作業を自動化することができるツールである。CIは、自動テストの実行、コードレビュー、自動デプロイ(アプリケーションをWebサーバーにデプロイすること)、プロジェクト管理、あるいはセキュリティ監査などによく使われます。

CIは、あらかじめ定義されたコマンドをTerminalに対して実行したり、特定のプログラムを実行したりする仮想的なオペレーティングシステムだと考えてください。CIの出力は、成功か失敗かのどちらかで、プロジェクトに直接表示されるだけでなく、管理者にも送られ、対応することができる。特定のイベント(例えば、リポジトリへのコミット、マージ要求/プル要求の受信、タグ/バージョン/リリース、cronのタイムループの実行など)の後にCIジョブを実行するのが良い方法です。

CIの具体的な仕組み

CIの基本は設定ファイルであり、そこで動作やイベントへの対応を定義する。GitHubの場合、ヘルパーディレクトリ .github/workflows を作成し、その中に .yml という拡張子を持つ任意のファイルを作成するだけでよいのです。GitHub はコミットごとにこれを解析し、必要に応じて実行します。

特定のタスクを持つ新しい設定ファイルを定義したい場合を考えてみましょう。これはGitHubや仮想マシン上の別の環境から直接実行されるタスクなので、以下のように環境に関する基本的なことを定義しておく必要があります。

  • タスクの名前(例えば、テストの名前)。
  • トリガーイベント(どのイベントに基づいてタスクを起動するか、例えば、リポジトリにプッシュするたび、あるいはプルリクエストを受け取るたび)
  • タスク自体の定義(多数のタスクが並列に実行されることもありうる)

仕事の場合は、さらに定義します。

  • 職種名
  • 実行環境(通常はオペレーティングシステムの名前)
  • コンテナ製作の手順

上記のコンテナは、すでに プロジェクトの完全なドッカー化 のための最初の準備です。CIの基本的な使い方は比較的簡単で、Dockerを全く理解していなくても、Terminalのコマンドさえ知っていれば大丈夫です。

タスクの具体的な手順の一部として、先ほどインストールしたオペレーティングシステムのインストールを構築するための個々のコマンドを実行する必要があります。つまり、PHPの場合、PHP言語だけをインストールし(バージョンも指定)、プロジェクトのリポジトリをランナーにクローンし、プロジェクトの依存関係(多くの場合Composer)をインストールし、テスト自体を実行することが重要でしょう。

なぜGitHub Actions(CI)を使うのか?

IT業界では、マイクロソフトは低品質なものを作る悪の企業だという迷信があります。しかし、GitHub Actionsの場合、それは全く当てはまりません。なぜなら、彼らは客観的に見て、世界最高のCIプラットフォームを持っているからです。

GitHub CIの基本的な利点は、記法がシンプルでエレガントなことです。予備知識がなくても、わずか数行で独自のテスト環境を構築し、自動的に管理することができます。同時に、特定のタスクの処理速度が速いことも大きなメリットだと考えています。例えば、codestyle(コードの書式設定)とPhpStan(データ型、ロジック、一般的な正しさのチェック)に関するテストは、通常のプロジェクトではGitHub Actionsで50秒以内に評価できますが、例えばGitLabでは同じテストをほぼ8分かけて評価しています。Travisのような他のソリューションは比較的高価で、ほとんどの開発者は、とにかくその特殊な機能の利点を理解していません。

準備した行動

GitHubには、すぐに使える既成のアクションやパッケージのデータベースが豊富にあります。これらは通常、オペレーティングシステム、プログラミング言語、またはコミュニティからのライブラリです。

マーケットプレイス](https://github.com/marketplace?type=actions)でアクションのデータベースを見つけることができます。例えば、私のお気に入りのアクションはSend SMS in case of failure via Twillioです。

完成品例

非常に多くの例私は自分のリポジトリで公開していますでは、私がどのような特定の設定を使用しているかを透過的に見ることができます。

例えば、2021年2月のプロジェクトでは、この構成をコードスタイルのチェックに使いました。

name: Coding Style
on:
push:
branches:
- master
pull_request:
types: [ assigned, opened, synchronize, reopened ]
schedule:
- cron: '1 * * * *'
jobs:
nette_cc:
name: Nette Code Checker
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: shivammathur/setup-php@v2
with:
php-version: 7.4
coverage: none
- run: composer create-project nette/code-checker temp/code-checker ^3 --no-progress
- run: php temp/code-checker/code-checker --strict-types --no-progress
nette_cs:
name: Nette Coding Standard
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: shivammathur/setup-php@v2
with:
php-version: 8.0
coverage: none
- run: composer create-project nette/coding-standard temp/coding-standard ^3 --no-progress --ignore-platform-reqs
- run: php temp/coding-standard/ecs check src

この設定ファイルは、最新の Ubuntu (runs-on: ubuntu-latest) をインストールし、プロジェクトのリポジトリをクローンし (uses: actions/checkout@v2)、 PHP (uses: shivammathur/setup-php@v2) バージョン 7.4 をインストールし (php-version: 7.4) Code-checker パッケージをインストールして PHP で仕事を走らせます。

経験の浅いユーザーのために、もう少しだけ注意点を説明します。

  • CIは、実行するたびに完全なオペレーティングシステムを持つ仮想マシンを起動し、それを使って、例えば、あなたのサーバーと同じようにターミナルでコマンドを呼び出すことができます
  • テスト結果を確認するために、Linux自身が定義しているいわゆるリターンコードが使用される。具体的には、プログラムが「0`」(ゼロ)を返したときが成功、それ以外の数値は失敗を意味する。例えば、シェルスクリプトは同じように動作します。
  • カスタムテストやより複雑なロジックを書きたい場合、例えばPHPを使い、それをCLIジョブ(php file.php コマンド)として実行すると、実行され、その権限でできること(ファイルの操作、インターネット上での通信、画面への出力、...)がすべてできるようになるのです。
  • CIが実行されると、すべての出力が画面に記録され、ウェブブラウザで直接見ることができる
  • ターミナルではユーザーと対話的に操作を行うことができますが、CIではこれをサポートせず、あるときは開始し、あるときは終了するタスクとして設計する必要があります。
  • CIコンテナの実行には1時間のタイムアウトが定義されており、その時間内にすべてが処理されない場合(たとえばプログラムが停止した場合)、システム全体が強制終了され、エラーが報告されます
  • GitHubはcronでCIジョブを自動実行できますが、適切なタイミングで実行されず、遅延して実行されてしまうことが非常に多いです。
  • また、すべてのCIロジックをDockerコンテナでラップし、すべてのマシンまたはサーバー上でローカルに実行することもできます(例)。
  • 秘密の情報(データベースパスワードなど)にアクセスする必要がある場合、GitHubで直接秘密変数を定義するオプションがあり、CIでは実行時にそれらを利用できるようになっている
  • ウェブサーバーへのデプロイは、常にSSH経由で行うのがベストです
  • CIジョブの総実行時間は制限されており、通常は1ヶ月あたり2,000分(これで十分な場合が非常に多く、私は1ジョブが最大1分なので使い切ったことはありません)、また有料で時間を増やすことも可能です。
  • 自分のサーバーでCIランナーをホストして、分単位の制限を回避することもできますが、MicrosoftはGitHub ActionsがホスティングされているAzureに多額の投資をしており、非常に強力なサーバーで動作しているため、サーバーはそれほど速くならない可能性が高くなります。
  • CI用に特定のパッケージ(PhpStanや様々なセキュリティ機能)をインストールすると便利なことが多いので、それらを require-dev ファイルの composer.json セクションに置いて、特定のプロジェクトで必須の依存関係としてインストールされないようにします。

GitHubアプリとボット

他のリポジトリホストとは異なり、GitHubはいわゆるGitHub Appsと自動化ボットをサポートしています。これは、あなたのプロジェクトで(CIなしでも)自動操作を実行できる既製のボットの大規模なデータベースで、彼らが何かに遭遇したとき、例えば、問題をファイルしたり、修正したプルリクエストを送信したりします。

個人的にも使っていて、おすすめです。

  • Dependabot - Composer で自動依存性チェックを行う。例えば、使用しているパッケージの新バージョンが出て互換性がある場合、自動的にプルリクエストを送信する。
  • Codecov - 自動テストでコードカバレッジをチェックし、コードのどの部分がまだカバーされていないかをグラフ化します。
  • Snyk](https://github.com/marketplace/snyk) - セキュリティの脆弱性を自動的にチェックする。
  • Imgbot](https://github.com/apps/imgbot) - 画像データサイズの自動最適化。

その他、多くのアプリケーションはマーケットプレイスで見ることができます。

その他の便利な機能

私はGitHubの自動化タスクを使うのが非常に好きになりました。

私はすべてのリポジトリで自動チェックを設定しており、私がコミットを送信すると(あるいはコミュニティの他の誰かが)、コードの品質(codestyleとPhpStan)、セキュリティなどが侵害されていないかどうか、リアルタイムでフィードバックを得ることができます。

1時間ごとに自動で実行されるテストがあるのですが。例えば、セキュリティ上の脆弱性やCVEがあった場合、具体的に何が起こったのか、具体的なプロジェクトのレベルでも遅くとも1時間以内には知ることができるのです。

長い間、さまざまな構成をテストしてきた結果、私は以下のようなComposerへの依存関係を理想的な最小セットアップと考えるに至りました。

  • phpstan/phpstan` - コードの正しさと論理性をチェックする。
  • tracy/tracy - 高レベルのエラー報告とロギング
  • phpstan/phpstan-nette - Nette における Phpstan の拡張機能と特化した機能
  • spaze/phpstan-disallowed-calls - Michal Spacek による、コード中の危険なもの (忘れられた変数ダンプからシェルコマンドとしてユーザ文字列を実行する機能まで) の (誤った) 使用を処理する素晴らしいライブラリです。
  • roave/security-advisories - 安全でないバージョンのパッケージのインストールをチェックします (特定のパッケージにセキュリティ脆弱性が見つかったり、CVE がリリースされた場合、このパッケージは破損したバージョンのインストールを防止します)

基本的なセキュリティの設定は、少なくとも8時間ごとに自動実行され、エラーがメールに送られるように設定するのが理想的です。なぜなら、プロジェクトのインストールに失敗したり、新しい脆弱性が発見されたりするたびに、できるだけ早くそれを知って、すぐに対応したいからです。

すべて自動で動くので、セキュリティチェックなどの複雑な処理をしたとしても、余計な手間はかからず、初期設定さえしっかりしていれば、いつでも安心して利用できることを忘れないでください。

なぜなら、予防と自動化には大きな可能性があるからです

Jan Barášek   Více o autorovi

Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.

Rád vám pomůžu:

Související články

1.
9.
Status:
All systems normal.
2024