このエントリーは、技術同人誌 Advent Calendar 2019 の20日目エントリーです。(またしても1日遅れ…)
CSS組版のビルドの自動化
Vivliostyleを用いたCSS組版のビルドにおいては、通常、以下の様な フローで成果物であるPDFを生成します。
この方法ではWebブラウザーを立ち上げて、印刷メニューから印刷を行うわけですが、入稿間際の修正が頻繁になる時などは、自動化したくなるのが人情というものです。特に共同執筆で締め切り間際のコミットラッシュの時とかそうですね。
Chrome59から導入されたHeadless Chromeを使うと、このようなCSS組版のビルドの工程を自動化することができます。本エントリーは、CSS組版のビルドの工程をGitHub Actionsを使ってビルドする過程について述べるものです。
ヘッドレスChromeによるPDF作成
緑豆はるさめ(@spring_raining)さんの「CSSではじめる同人誌制作」によると、ヘッドレスChromeでPDFを出力するには、以下の様な工程を踏みます。
画面に表示されないChromeは、Chrome DevTool ProtocolというAPIと通じてプログラムを使って操作します。 PDF出力プログラムでは、このAPIを使ってヘッドレスモードのChromeと接続し、PDFの保存を指示します。
何か難しそうですが大丈夫です。vivliostyle-cliという神ライブラリーがあります。このライブラリーを使用すると、ヘッドレスChrome上で印刷メニューを呼び出して、PDFを保存する操作を savepdf
というコマンドで行う事が出来るようになります。
Markdownで書かれた原稿をPandoc でビルドし、ヘッドレスChrome上で動作するVivliostyleでレイアウトして、PDF出力するスクリプト(build.sh
)は次の様になります。(抜粋)
cd src pandoc \ -f markdown+smart+raw_tex+citations+yaml_metadata_block+fenAced_code_blocks+inline_notes \ -c book.css --filter pandoc-crossref \ -M "crossrefYaml=${PWD}/../crossref_config.yaml" \ --toc --toc-depth=2 \ --filter pandoc-citeproc -o ../target/${OUTPUT}.html \ --reference-location=block \ -B cover.html -A imprint.html \ tmp.md --verbose cd ../ RET=$? mkdir -p target/img cp -f src/*.css src/*.otf src/*.ttf target/ cp -rf src/img/* target/img/ npm install node rewrite.js target/${OUTPUT}.html target/${OUTPUT}-rewrite.html savepdf --no-sandbox -s JIS-B5 -o target/${OUTPUT}.pdf target/${OUTPUT}-rewrite.html exit $RET
このスクリプトを呼び出す Dockerfile
を記述します。
FROM (Azure Container Registryのドメイン)/pandoc-viola-savepdf-ja:2.6.1 RUN npm install -g npm@latest RUN mkdir -p /tmp/code ADD . /tmp/code/ RUN rm -rf /tmp/code/target RUN mkdir -p /tmp/code/target WORKDIR /tmp/code CMD bash /tmp/code/build.sh
このDockerfileを使って、Docker上でビルドするスクリプト build-local.sh
は次の通りです。
なお、Azure Container Registry上に格納しているDockerイメージを生成するDockerfileは、以下のGitHubレポジトリーで公開しています。*1
#!/bin/bash set -eux docker build -t tf2 . docker run tf2 # ビルドしたPDFをコンテナーから取り出す ID=$(docker ps -a |grep tf2 |awk '{print $1}') docker cp ${ID}:/tmp/code/target .
GitHub ActionsによるCSS組版のビルド
GitHub Actionsでは、Gitレポジトリーの .github/workflows
ディレクトリー配下にビルドの設定を格納します。
レポジトリーのWebページ上の「Actions」タブを選択し、「Set up a workflow yourself」のボタンを選択すると、設定ファイルの編集画面に遷移します。この画面でyamlファイルを編集し、保存することで、Gitレポジトリーに設定ファイルをコミットすることができます。
GitHub Actionsで、VivlitstyleによるCSS組版のビルドを行うyamlの設定の例は次の通りです。
name: CI on: [push] jobs: build: runs-on: ubuntu-latest steps: - name: Docker Login uses: Azure/docker-login@v1 with: login-server: '(Azure Container Registryのドメイン)' username: '(Azure Container Registryのユーザー名)' password: ${{ secrets.crpassword }} - uses: actions/checkout@v1 - name: Run build run: bash ./build-local.sh - name: Upload uses: actions/upload-artifact@v1.0.0 with: name: sweetmudic-vol10.pdf path: target/sweetmusic-vol10.pdf - name: upload to dropbox run: bash ./deploy.sh env: DROPBOX_TOKEN: ${{ secrets.dropbox_token }}
ここではビルドを行うイメージをAzure Conrainer Registryに格納しているため、Docker Login を使ってDocker Registry にログインしています。
GitHub Actionsで外部リソースへの認証情報などを設定する場合は、レポジトリーの「Settings」→「 Secrets」の項目から、認証トークンなどの情報を保存します。yamlの設定ファイル内からは ${{ secrets.crpassword }}
の形式で呼び出します。
最後の upload to dropbox
の項目についてはこの次で説明します。
GitHub ActionsからDropboxへのアップロード
共同で執筆している場合などに生成したPDFへのアクセスを容易にするために、PDFをDropboxにアップロードし、Slackで通知することを考えます。
まず、DropboxのアクセストークンをCreate a new app on the DBX Platform にアクセスします。
最初のメニューでは「Dropbox API」を選択します。「Choose the type of access you need 」の項目は「App folder」を選択します。
メニューの指示に従って入力し、画面内の「Generated access token」の下の「Generate」をクリックしてトークンを作成します、取得したトークンをGitHubのSecretsに設定します。
先にあげたGitHub Actionsの設定例の中では、upload to dropbox
のステップでDropboxへのアップロードを起こっています。アップロードを行うスクリプト deploy.sh
の記述は次の通りです。
set -eux export TZ="Asia/Tokyo" TIMESTAMP=$(date "+%Y%m%d-%H%M%S") TARGET="sweetmusic-vol10" curl -X POST -f -H "Authorization: Bearer ${DROPBOX_TOKEN}" \ -D - -H "Dropbox-API-Arg: {\"path\": \"/${TARGET}-${TIMESTAMP}.pdf\",\"mode\": \"overwrite\",\"mute\": false}" \ -H "Content-Type: application/octet-stream" \ --data-binary @target/${TARGET}.pdf \ https://content.dropboxapi.com/2/files/upload
ここまでの設定を行った上で、作成した原稿をGitレポジトリーにコミットしてpushすると、GitHub Actionsによるビルドが行われ、Dropboxに作成したPDFがアップロードされます。
Slackへの通知
最後に、DropboxへのURLをSlackに通知します。
IFTTHやZapier 等のサービスでDropboxとSlackを連携することにより、Dropboxへのファイルのアップロードをトリガーにして、SlackにダウンロードのURLの通知を行う事ができます。以下はZapierにより、DropboxとSlackのアカウントの連携を行っている例です。
ここまで設定を行うと、原稿をGitレポジトリーにpushするとビルドが行われ、作成したPDFへのリンクがSlackに通知されます。
まとめ
GitHub ActionsでCSS組版のビルドを自動化する工程について取り上げました。ここでは自動化のプラットフォームとしてGitHub Actionsを用いましたが、WerckerやBitbucket Pipelines など、Dockerイメージをビルドに使用できるプラットフォームでも、同じ考えでビルドの自動化を組み込むことができます。
*1:ビルドすると5.8GBほどあるイメージができます