CircleCI で LaTeX 原稿の CI を実現する

$latex \LaTeX$ を使って論文等の原稿を書いている際に, 複数人で同時に編集したり, ファイルをコミットし忘れたりした結果, 原稿がきちんとコンパイルできなくなることがあります. この記事では CircleCI を用いて Git でバージョン管理している $latex \LaTeX$ 原稿の継続的インテグレーションを実現する方法を紹介します.

2017/12/8 追記: この記事では CircleCI 1.0 を利用しています.CircleCI 2.0 を使って CI を行う「論文執筆を支える継続的インテグレーション: Git から Amazon S3 まで」という記事を書きましたので,興味のある方はそちらもご覧下さい.

目標

今回は CircleCI で $latex \LaTeX$ の原稿がコンパイルできることをチェックし, artifacts として生成された PDF ファイルを確認できるようにすることを目標にします.

TeX Live のバージョン等をローカルの作業環境と揃えることは難しいため, 最終的な原稿のコンパイルは CI ではなくローカルで行うこととします.

CircleCI

CI サービスとして CircleCI を利用したのは, GitHub のプライベートリポジトリを使用する場合でも無料で利用できるためです. また, 今回は Docker を利用して TeX を導入するため, Docker を利用できることも CircleCI を利用した理由の一つです.

CircleCI で利用されるテスト環境は Ubuntu 12.04 または Ubuntu 14.04 です. Ubuntu 14.04 で標準で導入できる TeX Live は 2013 となっており少し古いことに注意が必要です.

今回は Docker を用いてより新しい Ubuntu 16.10 のイメージを使うことにより TeX Live 2016 (texlive in yakkety) を利用します. TeX Live 2013 で十分な場合は, あえて Docker を利用する必要はありません.

Docker イメージ

TeX Live 2016 を用いて原稿をコンパイルするため, Ubuntu 16.10 の Docker イメージをベースに, 新たなイメージを作成します. 以下の Dockerfile では, TeX Live 関係の必要なパッケージのインストールを行なっています. 原稿のソースファイルは /app 以下に配置し, latexmk で原稿をコンパイルすることを想定しています. コンパイル方法等は適宜変更してください.

FROM ubuntu:yakkety

RUN apt-get update \
      && apt-get install -y --no-install-recommends \
          latexmk \
          lmodern \
          texlive \
          texlive-lang-japanese \
      && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /app
WORKDIR /app

CMD latexmk

circle.yml

circle.yml に CircleCI の設定を記述します. まずは, dependencies で原稿をコンパイルするための Docker イメージをビルドします. 次に, test で Docker イメージを実行し, 原稿をコンパイルします.

machine:
  services:
    - docker
dependencies:
  override:
    - docker info
    - docker build -t tex .
test:
  override:
    - docker run -v $(pwd):/app --name tex tex latexmk
  post:
    - docker cp tex:/app/paper.pdf $CIRCLE_ARTIFACTS/

最後に $CIRCLE_ARTIFACTS に生成された PDF ファイルをコピーします. これにより CircleCI の artifacts から生成された PDF ファイルをチェックできます.

まとめ

GitHub の ymyzk/circleci-tex-sample で今回の記事で紹介した Dockerfilecircle.yml の設定例を公開しています. 複数人で作業している場合は, 生成された PDF ファイルへのリンクを Slack 等に通知するようなスクリプトも整備しておくと, より便利に利用できるかもしれません.