GitHub Actionsでローカルで動くgitコマンドが動かない?
最早欠かせないCI/CDを支えるGitHub Actions
皆さん開発するときにまず実施することって何ですか?
そう、CI/CDですよね。
CI/CDを軽視する者は必ず最後に泣かされるというのはもはや常識と言ってもいいのではないでしょうか。
かくいう私も泣きたくないので、主にGitHub ActionsでCI/CDを構築しています。(弊社ではGitHubを使用しているため)
今日はそんなGitHub Actions構築時、以前ハマった内容についての記事です。
なぜかGitHub Actionsで動かないgitコマンド
問題
今日は早速本題です。下記のコードが正しく動かない時がある理由を考えましょう。
steps: - uses: actions/checkout@v4 - name: Revert and Commit and Push if: env.BRANCH_IS_EXISTING == 'true' env: GH_TOKEN: ${{ secrets.GH_API_KEY_FOR_CREATE_ISSUE }} run: | git config user.name github-actions git config user.email ******@****** git checkout "[ブランチ名]" git revert -n $(git merge-base main "[ブランチ名]")..HEAD git reset HEAD [ワークスペースに変更を加える処理] git add . git commit -m "リセットしてからの変更" git push
[ブランチ名]
のブランチはmainから分岐したブランチとします。
このGitHub Actionsは、エラーが起きる可能性を内包しています。
前提知識
念のため、gitコマンド部分の解説を足しておきます。
git merge-base main "ブランチ名"
これで分岐元のコミットIDを入手出来ます。
revertのコマンドについては、
git revert -n コミットID..HEAD
..
でコミットIDのところから HEAD つまり今いるところまでを取り消していて、
-n
は No Commit つまりこのままコミットはしないというオプションですので、
これでコミットせずに先ほどの分岐元のコミットIDのところまで戻すことが出来ます。
このままだとコミットはされませんが変更がステージされた状態にはなってしまうので、
git reset HEAD
でステージされた変更を取り下げると、完全に分岐元の状態に戻ります。
なので、この Revert and Commit and Push は、ブランチに加えられた変更を一回リセットしてからもう一度 [ワークスペースに変更を加える処理]
を行って、あたかも分岐元のところから処理を行ってコミットするかのように振る舞うGitHub Actions…のようにみえます。
そして特に問題はなさそうですが…実際に動かすと
Error: Process completed with exit code 1.
と、特定の条件でたいした情報もなくエラーが出ます。
ローカルでは問題無く動くのですが…
解答
では、答えです。
罠は
- uses: actions/checkout@v4
のほうにあります。
このcheckoutのアクションは多くの場合に使っている超・汎用的なアクションかと思いますが、
デフォルトの挙動についてご存じでしょうか?
公式リポジトリ actions/checkout: Action for checking out a repo を参照すると
Only a single commit is fetched by default, for the ref/SHA that triggered the workflow.
という記述があります。
ここが全てです。つまり、単一のcommitしかfetchしてこないのがデフォルトの挙動なので、ブランチにすでにコミットが発生してしまっていた場合、今のままでは「分岐元」に戻るための履歴がとれないんですね。
全てのブランチの全てのコミット履歴を拾うためには後続の
Set
fetch-depth: 0
to fetch all history for all branches and tags.
という文章の通り、この設定を盛り込む必要があります!
というわけで、正解は
- uses: actions/checkout@v4 with: fetch-depth: 0
とすれば良い、ということでした。
まとめ
今回はGitHub Actionsでかなりのユースケースで使われるであろう actions/checkout の罠についての内容となりました。
ローカルでgitコマンドを使う場合は履歴を全取得している場合がほとんどかと思うので、今回扱った内容はなかなか原因把握が難しいエラーだと思います。
かくいう私もあまり何も考えず使っていたので、こんな仕様になっていたとは…と再認識するきっかけになりました。やはり使う前に公式ドキュメントは一読するのが基本ですね。
今年もCI/CDをしっかり仕込んで、頑張って品質向上に努めていきましょう。