目次

  1. はじめに
  2. 概要
  3. できること
  4. 仕組み
  5. おわりに

SLPアドベントカレンダー2020

はじめに

この記事は,SLP KBIT Advent Calendar 2020 - Adventar の5日目(12月5日)の記事です.
公開が遅くなり,ごめんなさい.

今までの日を見ますと,皆様かなり本格的な内容を紹介していますね.
本日紹介する内容は,技術的にはそこまで大したものではありません.
ただ,ちょろっと試しに作って使ってみて,便利だったので紹介する感じです.

本日は,GitHub ActionsとDockerfileを用いたLaTeXの論文執筆テンプレートを紹介します.
カンのいい人なら,「Dockerfile要らなくね?直接Docker pullすれば良くない?」と気づくでしょう.
しかし,論文執筆時は,カスタムすることも多いでしょうから,敢えてこのようにしています.

概要

リポジトリは i13302/latex-actions です.

12月にもなると,卒論や修論,はたまた学会の全国大会論文の締切が現実味を帯びてきますよね.
理系の学生は,LaTeXで論文を執筆し,Git管理する人が多いかと思います(偏見!).
一般的に論文は以下の流れで執筆することが多いと思います.

  1. 章ごとに執筆
  2. 結合して1枚の論文に
  3. 指導教員等に提出
  4. 真っ赤になって返却

その過程で,以下の課題を感じる人が多いかと思います.

  1. 現在の最新版はビルドできるのか.
  2. 第2著者が書いた部分はビルドできるのか.
  3. 論文PDF(生成物)が欲しいとき,プロジェクトをCloneしてビルドするのが面倒.

そこで,LaTeXのビルドと生成したPDFの提出を,GitHub Actions(以下,Actions)を使って自動化します.
これで,課題は以下の様に解決できます.

  1. ActionsがPassしているので安全!
  2. GitがマージしてActionsがPassしているので安全!
  3. Actionsで勝手にビルドして提出!
GitHub Actions

さあ,皆さんも論文執筆を頑張りましょう!

できること

さて,このシステム?では何ができるのでしょうか.
以下のように実際に執筆する流れで説明します.

執筆

執筆ブランチ(Chap/**)で章ごとに執筆します.
論文によっては,章ごとに違う人が執筆することもあるかもしれません.
執筆のcommitに一区切りが付くとpushします.
pushするとActionsが作動し,ビルドします.
これにより執筆ブランチ毎のビルドの可否が担保されます.

GitHub Branch Chaps

結合

結合ブランチ(develop)にて各章を結合する.
Actionsが1つの論文の固まりとして,ビルドします.
論文としてPDFが生成できることが担保されます.

GItHub Branch develop

提出

提出ブランチ(master)にて提出用のPDFを生成する.
Actionsがビルドした結果をReleaseとして公開してくれます.
指導教員に提出するときは,GitHubのRelease画面からPDFをダウンロードして,メールなりSlackなりで提出するだけです.

GitHub Releases

修正

執筆ブランチに戻って,修正しましょう.

仕組み

さて,仕組み...というか,どのように動作しているかを述べます.

まず,ディレクトリはこのような構成になっています.

├── .github
│   ├── docker
│   │   ├── Dockerfile
│   │   ├── action.yml
│   │   └── entrypoint.sh
│   ├── scripts
│   │   └── paper_release.sh
│   └── workflows
│       ├── push.yml
│       └── release.yml
├── .gitignore
├── README.md
└── paper.tex

それではまず,.githubディレクトリを見てみてください.
3つのサブディレクトリ(dockerscriptsworkflows)があります.

Actionsはイベントが起こったときに,このディレクトリ内を探索します.

ここで,このプロジェクトはいくつのイベントで作成されているか考えると,以下の2つですね.

  1. 執筆ブランチと結合ブランチへのpush時のビルド(push.yml)
  2. 提出ブランチでのpush時のビルドとリリース作成(release.yml)

では,それぞれ見てみましょう.

執筆ブランチと結合ブランチへのpush時のビルド

では,1つ目について見ましょう.
push.ymlを見てください.

6行目から以下のように記述されています.
まあ,なんとなくわかるのですが,単にどのブランチにどうされたときにイベントが走るのか記述されています.
ここでは,Chap/**ブランチとdevelopブランチに,pushされたときに,走るようです.

push.yml

on:
	push:
		branches:
			- Chap/** 
			- develop

それでは,次に12行目を見てみましょう.

runs-onでは,どのような環境で動作するか決めています.
ここでは,ubuntuの最新版にしていますが,macOSやWindows Serverも選べるようです.
(GitHub Actionsのワークフロー構文 - GitHub Docs )

push.yml

jobs:
	# This workflow contains a single job called "build"
	push:
	# The type of runner that the job will run on
	runs-on: ubuntu-latest

最後に,20行目を見てみてください.

stepsでは処理する順序や内容を決めています.
1stepは,name(説明)とuses(動作)で構成されています.
まず,actions/checkout@v2は,まあ正直おまじないです.
プロジェクトのソースコードをチェックアウトして使用することができます.
ブランチの指定やcommit,pushをすることもできます.

push.yml

	steps:
		# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
		- name: Set up Git Repository
		uses: actions/checkout@v2
		- name: Build Step
		uses: ./.github/docker

次の,./.github/dockerは指定パスにある,action.ymlファイルを実行します.
即ち,.github/docker/action.ymlですね.

actions.ymlの中身

ここでは,runsの中身が実行されます.
Dockerを使うときには,using: 'docker'を指定し,Docker イメージを指定します.
コマンドライン引数は,argsで渡すことができます.

ここでは,LaTeXをビルドするイメージをDockerfileentrypoint.shで書いています.

また,Docker以外にも,JavaScriptや複合実行ができるようです.
(GitHub Actionsのメタデータ構文 - GitHub Docs )

action.yml

runs:
	using: 'docker'
	image: 'Dockerfile'
	args: 
		- "paper.tex"

あとは,普通にDockerfileがDocker ビルドされて,イメージを起動します.

Dockerfileを敢えて使っている理由は,単にローカルのビルド環境と合わせやすいからです.
また,目的とする卒論や学会などに合わせてカスタムしたbstファイルやstyを梱包するときは,Dockerファイルをカスタムします.
まあ,詳しくは省略します.気が向いたらそのうち追記するかも...

提出ブランチでのpush時のビルドとリリース作成

では,今度は2つ目のイベントについて考えてみましょう.
release.ymlを見てください.

7行目をみると,今度は,masterブランチにpushしたときに動作するようです.
また,25行目にて,なにやらシェルスクリプトを実行しているようです.
環境変数として,GitHub Tokenを与えていますね.

release.yml

		- name: Release
		env:
			GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
		run: chmod +x ./.github/scripts/paper_release.sh && ./.github/scripts/paper_release.sh

実行しているシェルスクリプトpaper_release.shの中身は,PDFファイルを添付して,Releaseを発行するようになっています.
GitHub Tokenはリリースを発行するために,使っているのですね.

paper_release.sh

# create release
res=`curl -H "Authorization: token $GITHUB_TOKEN" -X POST https://api.github.com/repos/$GITHUB_REPOSITORY/releases \
-d "
{
	\"tag_name\": \"v$TODAY\",
	\"target_commitish\": \"$GITHUB_SHA\",
	\"name\": \"v$TODAY\",
	\"draft\": false,
	\"prerelease\": false
}"`

# extract release id
rel_id=`echo ${res} | jq '.id'`

# upload built pdf
curl -H "Authorization: token $GITHUB_TOKEN" -X POST https://uploads.github.com/repos/$GITHUB_REPOSITORY/releases/${rel_id}/assets?name=\"${TODAY}_$PDFFILE``\"\
	--header 'Content-Type: application/pdf'\
	--upload-file $PDFFILE

このように,masterブランチにpushされたとき,シェルスクリプトが動作し,PDFを添付したReleaseが発行される仕組みとなっています.

おわりに

さて,今回は,SLP KBIT Advent Calendar 2020 - Adventar の5日目として,論文執筆を目的としたGitHub Actionsを提案しました.

論文執筆には,3つの課題があると考えました.

  1. 現在の最新版はビルドできるのか.
  2. 第2著者が書いた部分はビルドできるのか.
  3. 論文PDF(生成物)が欲しいとき,プロジェクトをCloneしてビルドするのが面倒.

その課題には,以下の2つのイベントがあると考えました.

  1. 執筆ブランチと結合ブランチへのpush時のビルド(push.yml)
  2. 提出ブランチでのpush時のビルドとリリース作成(release.yml)

今回は,2つのイベントに応じたActionsを作成し,以下のように課題を解決しました.

  1. ActionsがPassしているので安全!
  2. GitがマージしてActionsがPassしているので安全!
  3. Actionsで勝手にビルドして提出!

このシステムは,DICOMO2020と学内論文の2件の論文執筆に使われました.

以上で数日遅れのアドカレ5日目をおわります.
おまたせして申し訳ございません.
引き続き,SLPのアドカレをよろしくおねがいします.


なにか,コメントがありましたら,Issueでお願いします.