LoginSignup
10
6

More than 3 years have passed since last update.

GitHub Actions で TeX のコンパイルと PDF 化をさせようとしたら意外に苦戦した話

Last updated at Posted at 2019-10-22

概要

GitHub Actions を使って「push したら TeX のコンパイルと PDF 化を実行する」を実現しようとしたら,本質とはあまり関係のない部分で結構苦戦したので,その内容をまとめる.

詳細

を参考にリポジトリを準備する.どこで苦戦したかを明らかにするために,最初に 修正前 のソースコードを提示する.すなわち,これから示すソースコードたちをコピペして使ってもエラーを吐くので注意.修正したものは本記事の最後に示す.

リポジトリの準備: 修正前

GitHub のリポジトリに以下の通りファイルを用意.

.
│  main.tex
│
└─.github
    │
    ├─actions
    │  └─latex
    │          Dockerfile
    │          entrypoint.sh
    │
    └─workflows
            main.yml

.github 内のそれぞれのファイルの中身は次の通り.

Dockerfile
FROM ubuntu:latest

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

RUN mktexlsr && mkdir -p /app
WORKDIR /app

ADD entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh
#!/bin/bash
set -eux

# build pdf (change if necessary)
ptex2pdf main.tex

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

# extract release id
rel_id=`echo ${res} | python3 -c 'import json,sys;print(json.load(sys.stdin)["id"])'`

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

on:
  push:
    paths: main.tex

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Set up Git repository
        uses: actions/checkout@v1
      - name: Build docker image
        uses: ユーザー名/リポジトリ名/.github/actions/latex@master
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

困った点その1: permission denied

entrypoint.sh の実行段階で

/usr/bin/docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"/entrypoint.sh\": permission denied": unknown.

というエラーが出た.軽く調べたのち

を参考に,Dockerfileentrypoint.sh に実行権限を与えるように直した.

Dockerfileの最終行付近
ADD entrypoint.sh /entrypoint.sh
RUN ["chmod", "+x", "/entrypoint.sh"]    # この行が追加部分
ENTRYPOINT ["/entrypoint.sh"]

困った点その2: exec user process caused "no such file or directory"

同じく entrypoint.sh の実行段階で

standard_init_linux.go:211: exec user process caused "no such file or directory"

というエラー文が出た.調べたところ

と同一の症状だったため,entrypoint.sh の改行コードが CRLF なのを LF に直したところ,エラーは解消された.

困った点その3: ptex2pdf の実行オプション

jsarticle を使いたかったのだが,entrypoint.sh 内で ptex2pdf をそのまま実行していたため

! Undefined control sequence.
l.1 \documentstyle
                  {jsarticle}
? 
! Emergency stop.
l.1 \documentstyle
                  {jsarticle}

というエラー文が出た.これは適当なオプションを付けることで解消.

entrypoint.shの5行目
#!/bin/bash
set -eux

# build pdf (change if necessary)
ptex2pdf -l -ot -kanji=utf8 main.tex    # この行が変更点

困った点その4: GITHUB_TOKEN

ここまでで,GitHub 上での TeX のコンパイルと PDF 化は実現される.その次には「生成された PDF をリリースする」という動作が発生するのだが,そこで発生したエラーが下記である.

/entrypoint.sh: line 16: GITHUB_TOKEN: unbound variable
+ res=

結論のみ述べると,entrypoint.shGITHUB_TOKEN がきちんと受け渡されていないことが原因であった.そこで,main.yml を次のように修正した.

main.ymlの最終行付近
      - name: Build docker image
        uses: ユーザー名/リポジトリ名/.github/actions/latex@master    # この行以下が修正箇所
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

これでめでたく PDF ファイルのリリースまでが実現される.

リポジトリの準備: 修正後

修正後のソースコードは以下の通りである.

Dockerfile
FROM ubuntu:latest

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

RUN mktexlsr && mkdir -p /app
WORKDIR /app

ADD entrypoint.sh /entrypoint.sh
RUN ["chmod", "+x", "/entrypoint.sh"]
ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh
#!/bin/bash
set -eux

# build pdf (change if necessary)
ptex2pdf -l -ot -kanji=utf8 main.tex

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

# extract release id
rel_id=`echo ${res} | python3 -c 'import json,sys;print(json.load(sys.stdin)["id"])'`

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

on:
  push:
    paths: main.tex

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Set up Git repository
        uses: actions/checkout@v1
      - name: Build docker image
        uses: ユーザー名/リポジトリ名/.github/actions/latex@master
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

これらのファイルを配置し,実際に PDF がリリースされているリポジトリはこちら

参考

10
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
6