これは「imtakalab Advent Calendar 2024」の23日目の記事です。
https://adventar.org/calendars/10354

目次

はじめに

どうも MotoShin です。 すごい久しぶりのブログ更新になりますが、所属研究室で Advent Calendar をやるとのことなので久しぶりに記事を書いてみようと思います。 私は社会人博士として会社で働きながら研究室に所属しているのですが、博士課程に進む前に決めていたテーマとして研究室の開発手法のモダン化を掲げていました(実は)。 そこで Docker や Git を使用していくための勉強会を開いたり、研究室用の GitHub Organization を作ったりして環境を整備していました。 そのお陰で Git の利用と GitHub の簡単な利用は確かに増えて、一部では Docker を使った環境構築をしている人も出てきました。 個人的にはかなりの手応えを感じていますが、まだまだ足りない部分も多いので、今回は GitHub を使い倒す方法を紹介していきたいと思います。

GitHub を使い倒す

皆さんはもちろん Git を手足のように使いこなせていると思います。 あんなに勉強会とかしてもらったしね、もちろんね、使いこなせてるよね。 しかし、GitHub を使いこなせているかと言われると 🤔 となる人も多いのではないでしょうか。 GitHub はリモートリポジトリを管理するためだけのサービスだと思っている人が多いのではないでしょうか?

そこで、GitHub でここはできるようになってほしい、というポイントや自分がよく使っている機能などを紹介していきたいと思います。

なお、ここからは下記のリポジトリで実際に作業していきながら話を進めていきたいと思います。
https://github.com/MotoShin/imtakalab-advent-calendar-2024-handson

Pull Request の活用

まず GitHub を使う上で絶対に使ってほしいのが Pull Request (PR) です。 PR は GitHub でのコードレビューを行うための機能です。 UI 上で差分を確認しながらコメントを残したり、コードの変更をリクエストすることができます。 何より変更履歴を振り返る際に PR を出しておくと、差分とともに振り返ることができるので非常に便利です。

まず、greeting.txt というファイルを作成してこのファイルに変更を加えることを考えます。変更前のgreeting.txtの中身は以下の通りです。

Hello, World.

これを下記のように変更したいとしましょう。

Hello, World.
こんにちは、世界。

日本語にした途端、壮大な物語が始まりそうな気がしますね。

この変更を行うために、まずはブランチを切ります。(まさかmainブランチに直接プッシュなんてしませんよね、許されませんよ。)

$ git checkout -b add-japanese-greeting

はい。そんでもって、greeting.txt を編集して こんにちは、世界。 の行を追加します。 その後、コミットしてリモートリポジトリにプッシュします。

$ git add greeting.txt
$ git commit -m "Add Japanese greeting"
$ git push origin add-japanese-greeting

そうすると、GitHub 上で新しいブランチが作られた旨のメッセージが出てきます。 この緑色の Compare & pull request ボタンを押して Pull Request を作成します。

Pull Request のタイトルと本文を書いて、Create pull request ボタンを押せば Pull Request が作成されます。 そうやって作成された PR が下記です。
https://github.com/MotoShin/imtakalab-advent-calendar-2024-handson/pull/1

PR が作成されたら、コードレビューをしてみましょう。 差分確認には下記の画像の赤枠で囲っている Files changed タブをクリックすると差分を確認できます。

そうすると変更差分が UI 上でわかりやすく表示されていることがわかります。 今回の変更は追加のみで規模も小さいですが、変更箇所が多くなってくるとこの差分表示が非常に便利です。

更に、この画面では変更箇所についてコメントを残すことも可能です。緑色の行にマウスカーソルをもっていくと + マークが表示されるので、そのマークをクリックするとコメントを残すことができます。 この機能によって PR レビュー者が PR 作成者に変更意図を質問したり、ミスを指摘できたりします。 また、1人での作業でも変更箇所に何かしらメモ書きを残すことが可能で、変更理由などを振り返りたいときに便利です。

そして、PR レビューをする立場になった場合に絶対にやってほしいのが Approve です。 これは一見するとやり方が難しいですが、PR の変更内容を確認して問題がなかったという証跡にもなるので非常に重要です。 PR レビューの際は絶対に実施するようにしましょう。

やり方は下記の通りです。 差分の画面にて、Review changes ボタン(下記の赤枠のボタン)をクリックします。

すると、コメント入力欄が表示されるので何かメッセージを入力(入力しなくてもいい)して、Approve を選択して Submit review ボタンを押します。

すると、PR 作成画面に遷移して、Approve が表示されていることが確認できます。 Approve は PR 作成者自身ではつけることができないので、複数人で開発しているときのみ使える機能です。

これで PR で実施するべきことは完了したので、PR をマージしてしまいましょう。 PR 作成者自身がマージすることもできますが、他の人がマージすることもできます。 PR 画面下部にて Merge pull request ボタンを押すとマージされます。

Release の活用

次に GitHub の Release 機能を活用してみましょう。 Release はバージョンリリースを行うための機能で、GitHub 上でリリースノートを作成することができます。 自分がよく使う場面としては、論文を書いた当時のコードをシンクするために使っています。 論文に載せた結果を出したプログラムコードを Release として登録しておくことで、論文の結果の再現をしたくなった際に Release 履歴を辿ればすぐに当時のコードまで遡ることができてすぐに再現実験ができます。 実際の業務では Release を行ったアプリケーションコードを deploy することで、deploy したバージョンにバグがあっても前の Release に戻すことで切り戻せるなどの利用方法があります。 また、Release したバージョン同士で差分を見ることもできるので、どのバージョンでどのような変更があったかを確認することもできます。

とりあえず、特定の段階で Release を作っておけばすぐに戻したり差分を見れたり色々できるので便利、ということです。

では、早速 Release を作ってみましょう。 Release を作るにはまず Release 用のタグを作成する必要があります。 tag は git のコマンドで作成することができます。

# v0.0.1という名前のtagの作成
$ git tag v0.0.1
# tag一覧の表示
$ git tag
# tagのpush
$ git push origin v0.0.1

これで GitHub のリモートリポジトリ上に v0.0.1 という名前の tag が作成されました。 UI 上で見てみましょう。 画像の赤枠の部分を押下すると tag 一覧が表示されます。

tag 一覧に v0.0.1 が表示されていることが確認できます。

この v0.0.1 の tag を Release として登録してみましょう。 Release 画面に遷移するために、上記画像 Releases タブをクリックします。 そうすると Create a new release ボタンが表示されるのでクリックします。

ボタン押下後、下記のような画面が出てきます。

この画面では Release のタイトルや本文、Release に含める tag の指定することができます。 下記の操作を画像に書いてある番号順に実施します。

  1. プルダウンにて Release 対象の tag (v0.0.1) を選択
  2. Release のタイトルを入力
  3. General Release Notes ボタンを押下すると Release 内容を本文に自動入力してくれる!
  4. Publish release ボタンを押下すると Release が作成される

こうすると下記のように Release が作成されます。
https://github.com/MotoShin/imtakalab-advent-calendar-2024-handson/releases/tag/v0.0.1

GitHub Actions の活用

GitHub Actions は CI/CD を行うための機能です。 CI/CD とは、Continuous Integration / Continuous Deployment の略で、コードの変更を自動的にビルドやテストを行い、リリースまでを自動化するためのプラクティスです。 まぁ、要は GitHub 上で何かしらのアクションをすれば、連動してなんでもできるすごいやつってことです。

Tip

GitHub Actions は いっぱい使うと課金されるので注意してください。
詳細は GitHub Actions の課金について を参照してください。

今回は、研究室でよくあるケースとして論文執筆の際に役立つユースケースを想定します。 $\LaTeX$ ファイルを Git 管理して、差分のレビューなどを GitHub の PR 上で行いたいと考えたとします。 しかし、$\LaTeX$ ファイルの差分の見たところで pdf 上でどこが変わったのかよくわからん、となりますよね。

そんなときに GitHub Actions ですね! 今回の目的は、PR 作成時に latexdiff で差分を pdf 上で表現して、その pdf を PR に添付することです。

まず、GitHub Actions で実行するためのワークフローファイルを作成します。 .github/workflows ディレクトリを作成し、その中に latexdiff.yml という名前でファイルを作成します。

$ mkdir -p .github/workflows
$ touch .github/workflows/latexdiff.yml

ここから latexdiff.yml の中身を一生懸命調べながら書いていくのですが、今回は僕が検証し切って完成したものを特別に書いておきます。

# PR作成、再オープン、変更時にmainブランチのmain.texとの差分を
# LaTeXdiffでPDF出力してoutput-pdfブランチにpushするworkflow
name: Output LaTeX difference

on:
  pull_request:
    types: [opened, reopened, synchronize]
    paths:
      - '**.tex'

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      # 全てのリポジトリをfetchする (fetch-depth: 0)
      - name: Set up Git repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      # output-pdfブランチに比較するためのLaTeXファイルを準備
      - name: Prepare output-pdf branch
        run: |
          echo "HEAD: ${{ github.head_ref }}"
          echo "BASE: ${{ github.base_ref }}"
          git config user.name github-actions[bot]
          git config user.email 41898282+github-actions[bot]@users.noreply.github.com
          git checkout output-pdf
          git merge origin/${{ github.head_ref }}
          git show origin/${{ github.base_ref }}:main.tex > base.tex          

      # LaTeXdiffで差分を取得し、output-pdfブランチにpush
      - name: Compile LaTeX
        uses: xu-cheng/texlive-action@v2
        with:
          scheme: full
          run: |
            ls base.tex main.tex
            latexdiff base.tex main.tex > diff.tex
            pdflatex diff.tex            

      # 差分PDFファイルをpush
      - name: Push diff PDF file
        run: |
          git status
          git add diff.pdf
          git commit -m "Add diff PDF file."
          git push origin output-pdf          

      # PRに差分PDFファイルのリンクをコメント
      - name: Create PR comment
        env: 
          PR_NUMBER: ${{ github.event.number }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          echo "差分をPDFで確認したい場合は下記を参照してください。<br>https://github.com/MotoShin/imtakalab-advent-calendar-2024-handson/blob/output-pdf/diff.pdf" > /tmp/comment.md
          gh pr comment "${PR_NUMBER}" -F /tmp/comment.md          

コメントにもあるのでよく読んでください、とぶん投げてもいいんですがざっくり説明します。

まずは、最初の部分。 ここは GitHub Actions の名前とトリガー (発生条件) を設定しています。 name: で名前を、on: でトリガーを設定しています。 この場合は、PR が作成されたとき、再オープンされたとき、PR に新たにコミットが追加されたときに実行されるように設定しています。 また、paths: でファイルのパスを指定しています。 ここでは、.tex ファイルが変更されたときに実行されるように設定しています。

name: Output LaTeX difference

on:
  pull_request:
    types: [opened, reopened, synchronize]
    paths:
      - '**.tex'

次に、jobs: でジョブを設定しています。 runs-on: で実行環境を指定しています。 ここでは、ubuntu-latest を指定しています。

jobs:
  build:
    runs-on: ubuntu-latest

Note

補足ですが、今回は main ブランチとは別に output-pdf ブランチを使用しています。 output-pdf ブランチの役割は main ブランチに向けて PR が作成された際に、main ブランチとの差分を latexdiff で取得し、その差分を PDF にして output-pdf ブランチに push することで UI 上で PDF で差分を見るという役割です。

そして、steps: でジョブ内で実行するステップを設定しています。 uses: で使用するアクションを指定しています。 with: でアクションに渡す引数を指定しています。 run: でターミナルで実行するようなコマンドを記載しています。 これらのコマンドは仮想環境上で実行されます。

ざっくりイメージを言うと、uses で指定した公式が準備してくれてるものや、他の人が作ったものを使って、runs-on で指定した環境内で更に仮想環境を起動して、その仮想環境の中で run で指定したコマンドを実行している、という感じです (ものによっては仮想環境を使わないものなどもあります) 。

steps:
  - name: Set up Git repository
    uses: actions/checkout@v4
    with:
      fetch-depth: 0
steps:
  - name: Prepare output-pdf branch
    run: |
      echo "HEAD: ${{ github.head_ref }}"
      echo "BASE: ${{ github.base_ref }}"
      git config user.name github-actions[bot]
      git config user.email 41898282+github-actions[bot]@users.noreply.github.com
      git checkout output-pdf
      git merge origin/${{ github.head_ref }}
      git show origin/${{ github.base_ref }}:main.tex > base.tex      
steps:
  - name: Compile LaTeX
    uses: xu-cheng/texlive-action@v2
    with:
      scheme: full
      run: |
        ls base.tex main.tex
        latexdiff base.tex main.tex > diff.tex
        pdflatex diff.tex        
steps:
  - name: Push diff PDF file
    run: |
      git status
      git add diff.pdf
      git commit -m "Add diff PDF file."
      git push origin output-pdf      
steps:
  - name: Create PR comment
    env: 
      PR_NUMBER: ${{ github.event.number }}
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    run: |
      echo "差分をPDFで確認したい場合は下記を参照してください。<br>https://github.com/MotoShin/imtakalab-advent-calendar-2024-handson/blob/output-pdf/diff.pdf" > /tmp/comment.md
      gh pr comment "${PR_NUMBER}" -F /tmp/comment.md      

ここまで書いてきて疲れてる感があるのでもしわからんことあれば聞いてくれるなどしてくれればと思いますが、uses で指定しているやつとかでググると該当のリポジトリが出てくるので、そこに使い方とか書いてあります。 興味があれば読んでみてください。

動かしてみる

なんと動かすまでに5時間くらい試行錯誤してます。 もう達成感でいっぱいです。

はい、では動かしてみましょう。 まずは main.tex について変更を加えて PR を作成する必要がありますね。 main.tex の中身は適当に生成 AI に数式とか表とか含んだ $\LaTeX$ ファイルを生成させておきました。 ファイル はこんな感じです。 結構真面目な感じですね。

はい、ここにゴリラの説明を加えて PR を作成しました。 PR は下記です。

https://github.com/MotoShin/imtakalab-advent-calendar-2024-handson/pull/4

色々 PR の画面で見慣れないものがあると思います。 PR 本文のことではないですよ。

これとか

これとか

これです。

文字にすると下記のような感じです。

  1. コミットハッシュの番号にチェックマーク
  2. github-actions というユーザーがコメントを残している
  3. All checks have passed の欄ができてる

これらは GitHub Actions が PR 作成時に実行されていることを示しています。 では、GitHub Actions が実行されてることを確認してみましょう。 1 のチェックマークをクリックするか、3 の Show all checks をクリックした後に Details をクリックすると、GitHub Actions の実行ログを確認することができます。

Details をクリックすると下記ページに遷移します。

https://github.com/MotoShin/imtakalab-advent-calendar-2024-handson/actions/runs/12445077589/job/34746028858?pr=4

ここで、GitHub Actions の実行ログを確認することができます。 細かくは自分で見て欲しいですが、例えば Compile LaTeX のジョブのログを見てみると何だが docker で色々してそうなログとかが見られると思います。

そんでもって、PR のコメントですね。 これが今回の成果物です。 コメントのリンクを押下してみましょう。 そうすると、追加されている部分の差分が青で強調された PDF が見られるはずです!

https://github.com/MotoShin/imtakalab-advent-calendar-2024-handson/blob/output-pdf/diff.pdf

これで、PDF 上と PR 上の両方で差分を見ながらレビューできる体制が整いましたね!

(おまけ) GitHub Pages の活用

GitHub Pages は GitHub が提供している静的サイトホスティングサービスです。 このブログも GitHub Pages で運用しています。 もう疲れちゃったので GitHub Pages についての説明は勘弁してください。 ググって調べてくれ!

まぁ、静的なページであれば無料で公開することが可能なのでポートフォリオとか作りたい人は使ってみるといいかと思います!

まとめ

GitHub を使い倒すために GitHub の機能の一部を紹介しました。 今回紹介したものは、自分がよく使っている機能で GitHub を使い倒すにはまだまだ足りていません。 自分もまだまだ勉強不足なので、これからも GitHub を使い倒すために様々な機能を試していきたいと思います。

Git を必死に覚えたのに今度は GitHub かよ、と思うかもしれませんが Git も GitHub もエンジニアの友達です。 仲良くしてみると必ず恩恵を受けることができます。 自分ができることからでいいのでこれらのツールを使っていってみましょう。 特に GitHub Actions は手動で実行している煩わしさなどを解消してくれる非常に便利な機能です、ぜひ使ってみてください!

参考