patch

CI のビルド時に patch を適用する際の注意点

More than 1 year has passed since last update.

CI(継続的インテグレーション)のビルド処理の中で patch の適用を実行する際の注意点です。

問題点

CI(継続的インテグレーション)のビルド処理で cache に前回のファイルが残っていると、2回目のビルドで Reversed patch と判断されて元に戻ってしまうことがあります。

例) node_modules/foo/bar/xxx に対して xxx.patch を適用したい場合

# 1回目
$ patch --batch -p0 -i xxx.patch
patching file node_modules/foo/bar/xxx

# 2回目
$ patch --batch -p0 -i xxx.patch
patching file node_modules/foo/bar/xxx
Reversed (or previously applied) patch detected!  Assuming -R. # 元に戻ってしまう

Reserved patch を無視するように

Reversed patch を無視するには、patch コマンドの -N オプションを使います。

$ patch --batch -N -p0 -i xxx.patch
patching file node_modules/foo/bar/xxx
Reversed (or previously applied) patch detected!  Skipping patch.
1 out of 1 hunk ignored -- saving rejects to file node_modules/foo/bar/xxx.rej

これで元に戻ることを防ぐことはできるのですが、終了ステータスが「異常終了 (1)」となるため、CI 上でこれを実行するとビルドが失敗してしまいます。
また、node_modules/foo/bar/xxx.rej ファイルができてしまうのも気になります。

解決策

一度 --dry-run で試してみて、成功したときだけ実行するようなスクリプトにすればこの問題を回避することができました。

patch-xxx.sh
#!/bin/bash

PATCH_CMD="patch --batch --silent -p0 -N -i xxx.patch"

if ${PATCH_CMD} --dry-run; then
  ${PATCH_CMD}
fi