Tech Racho エンジニアの「?」を「!」に。
  • 開発

Gitのpush時にCIのビルドを回避する方法

はじめまして。10月に入社しました、エンジニアのsugitaです。

こういう記事を書くときにテーマ設定で時間をかけてしまう性格なので、技術的なことなら何でも書いていいと言われて逆に迷ってしまいましたが、今回はCIを使って開発しているときの小ネタを紹介します。

TL;DR

CIサービスのビルドを無駄に回さないようにする方法を紹介します。

  1. コミットメッセージに[ci skip]を含める
  2. commit.templateの設定
  3. .git/info/excludeの設定

背景

私はコードを書くとき、細かい単位でコミットしてremoteへのpushも頻繁にするほうなのですが、今のプロジェクトでは、GitHubレポジトリへのpushをフックとしてCIのビルドが動く設定になっています。そのため、pushするたびにビルドが動いてしまいます。

本当はpull requestのレビュー前だけ動いて、自動テストとコードのスタイルチェックが通っていることを確認できればそれでよいので、pushのたびにビルドが動いてしまうのを回避したいと考えました。今回は、プロジェクト全体に影響しないよう、CI側の設定を変えることなく、個人的な設定で回避する方法をご紹介します。

方法

1. コミットメッセージにキーワードを仕込む

各種CIサービスには、ビルドをスキップするためのキーワードが設定されています。詳細は下の記事によくまとまっていました。

CIサービスの自動ビルドをスキップする方法まとめ – Qiita

Travis CI/Circle CI/AppVeyerであれば、
[ci skip]をコミットメッセージのどこか(行頭でなくても可)に書くとpush時にCI起動をスキップできる。
同記事より

今のプロジェクトではCircleCIを使っているため、上記の通り、コミットメッセージに[ci skip]と書くと、無事ビルドをスキップさせることができました。

2. コミットメッセージのテンプレートを作る

上記のやり方でひとまず目的は達成されたわけですが、毎回[ci skip]と手で打ち込むのは面倒ですし、エンジニアの仕事は手作業を自動化することです。というわけで、コミットメッセージにデフォルトでキーワードが含まれるように設定します。

まずはコミットメッセージのテンプレートとなる.gitmessage.txtを用意します。(ファイル名は任意に設定できます)

  • .gitmessage.txt
# 空行
# 空行
[ci skip]

わかりにくいので1行目と2行目にコメントを入れましたが、実際はコメントもなく全くの空行です。
一応解説しておくと、1行目はタイトル行でコミットごとに任意の内容を書きたいので空行、2行目はGitのコミットメッセージの慣習として空行、3行目に毎回固定で入れたい[ci skip]とだけ書いています。

続いてこのテンプレートファイルをGitに教えるために変数の設定をします。次のコマンドをGit管理ディレクトリ直下で実行しましょう。

$ git config  commit.template .gitmessage.txt

これで設定は完了です。試しにコミットを作ってみます。

無事、テンプレートが適用された状態でコミットメッセージ編集画面が開きました。これで毎回[ci skip]と手で打ち込む必要がなくなり、CIを動かしたいときだけ3行目を消せば良くなりましたね。

3. テンプレートファイルのignore設定

前項まででほとんど目的を達成できましたが、まだ問題が残っています。.gitmessage.txtを追加したので、GitにはUntracked filesとして認識されてしまいます。

$ git status
On branch feature/hoge
Your branch is up to date with 'origin/feature/hoge'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    .gitmessage.txt

nothing added to commit but untracked files present (use "git add" to track)

.gitmessage.txt.gitignoreに追加してGit管理下から除外したいところですが、多くのプロジェクトでは.gitignore自体がGitの管理下に置かれているため、個人的な設定は混入させたくありません。今回は「プロジェクト全体に影響しないように個人的な設定で対処する」ことがテーマですので、別の方法を採ります。

Gitのignore対象を個人的に設定する方法は2通りあります。

グローバルな設定

1つ目は、グローバルなignore設定ファイルを作成する方法です。

$ git config --global core.excludesfile ~/.gitignore_global

この方法だと、同じマシンで管理しているすべてのGitレポジトリに.gitignore_globalの設定が反映されます。テキストエディタの一時ファイル(.swpなど)やOS固有のファイル(.DS_Storeなど)のignore設定はこちらに書くといいでしょう。今回は、プロジェクト固有かつ個人的なignore設定をしたいので、こちらの方法は適しません。もうひとつの方法を使います。

レポジトリ固有の設定

2つ目は.git/info/exludeにignore設定を記載する方法です。この方法だと、ignore設定がGitの管理下に置かれず、かつレポジトリ固有の設定となります。今回の場合だと次のような内容になります。

  • .git/info/exclude
.gitmessage.txt

まとめ

今回ご紹介した3つの設定はどれも調べればすぐ出てきますし、すでにご存知の方も多かったと思います。ただ、組み合わせることで日々の開発でほんの少し不便に感じていることを解消できる事例として、ご参考にしていただけたなら幸いです。


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。