composer-patchesで管理していないパッチをCIで検知する
チーフリライアビリティエンジニア 黒澤はじめに
Drupalを用いたWebサイトの構築では、コアモジュールやコントリビュートモジュールに対して、リリース版に含まれないパッチを適用したり、独自の修正を加えたりすることがあります。これらのパッチは適切に管理されていないと、モジュールの再インストールやアップデート時に消失してしまうリスクがあります。差分が適用されていないファイルで上書きされるためです。
この問題を防ぐために、composer-patchesが使われています。composer-patchesにパッチを登録すると、composer installやcomposer update時に自動的にパッチが適用され、適用漏れや消失を防ぐことができます。
私の参画しているプロジェクトでは、composer-patchesで管理していないパッチの存在が判明していたため、CIを使って管理漏れを検知する取り組みを行いました。
実施内容
GitHubのプルリクエストで次のような検証を行い、composer-patchesで管理していないパッチがあればマージをブロックするようにしました。
- コアモジュールとコントリビュートモジュールの全削除
- vender/ディレクトリの全削除
- composer installを再実行
- 自動的にcomposer-patchesが適用
- Gitで差分の有無を確認
- 差分がなければCI成功
- 差分があればCI失敗
Bashのスクリプトで書くと次のようになります。
# コアモジュールとコントリビュートモジュールの全削除
rm -rf web/core/
rm -rf web/modules/contrib/
# vendor/ディレクトリの全削除
rm -rf vendor/
# composer install再実行
composer install --prefer-dist
# Gitの差分検出
git add -N .
if git diff --quiet web; then
echo "差分はありませんでした。"
else
echo "差分があります。"
git diff --name-only web
exit 1
fi
実施結果
この取り組みによって、composer-patchesで管理していないパッチを洗い出し、管理下に置くことができました。具体的には、次のような差分が検出されました。
- 管理漏れによる差分
- 管理下に置いた差分箇所の再変更による差分
- GitLabマージリクエストの更新による差分
- バイナリーファイルの変更による差分
- モジュール管理方法の揺れによる差分
それぞれ、簡単に紹介します。
管理漏れによる差分
単純にcomposer-patchesへのパッチ登録が漏れていたことによる差分です。モジュールごとにパッチファイルに作成し、composer-patchesに登録することで解消しました。
管理下に置いた差分箇所の再変更による差分
一度composer-patchesに登録した箇所を再度修正した際に、パッチの更新が漏れていたケースもありました。こうした問題の再発をチェックできるようになったのは、CIを利用した成果の1つです。
GitLabマージリクエストの取り込み
composer-patchesでは、ローカルファイルだけではなくURLもパッチとして登録できます。Drupalの多くのモジュールはGitLabで開発されており、パッチとしてマージリクエストを指定することも増えています。
{
"extra": {
"patches": {
"drupal/●●●": {
"説明": "https://git.drupalcode.org/project/●●●/-/merge_requests/番号.patch"
}
}
}
}
ただし、マージリクエストの内容は時間とともに変化するため、CIで繰り返し適用する中で差分が検出されることがあります。今回の取り組みでは、マージリクエストの変化を取り込んだものもありましたが、一部はマージリクエストの内容をファイルに保存して、composer-patchesに登録しなおしました。
バイナリーファイルの変更による差分
composer-patchesはバイナリーファイルを含んだパッチをサポートしていません。画像などのバイナリーファイルを変更している場合は、別途管理する必要があります。
今回の取り組みでcomposer.jsonのscriptsにバイナリーファイルのコピー処理を登録し、post-install-cmdやpost-update-cmdから呼び出すようにしました。これによりcomposer installやcomposer update時にコピー処理が自動実行されます。
{
"scripts": {
"copy-binary-files": "cp patches/path/to/file web/modules/contrib/path/to/file",
"post-install-cmd": [
"@copy-binary-files"
],
"post-update-cmd": [
"@copy-binary-files"
]
}
}
モジュール管理方法の揺れによる差分
今回の取り組みを始めて最初に気がついたことは、実は、composerで管理していないモジュールが複数存在することでした。Drupalはcomposerを使わずに開発することも可能でしたので、一時的にモジュール管理の認識が揃っていなかった模様です。
プロジェクト内での認識はすでにcomposerの利用で統一されていましたので、実務的な対応のみを行いました。具体的には、必要なモジュールはcomposerを使って再インストールし、不要なモジュールは削除しました。
まとめ
Drupal開発を複数人で行う場合、モジュールや差分の管理方法についても認識合わせが大切です。
ドキュメントの整備やオンボーディングも大切ですが、CIも組み合わせることで、思いもしなかったような差分や認識のズレが見えてきます。
この記事が、Drupal開発のヒントになれば幸いです。