GitLab CIでLaTeXコンパイルをどこでも出来るようにする

こんにちは、whywriteit レポート班のwhywaitaです。

LaTeX環境はWindowsでは少し難があったり、OSXでもEl Capitanではそのままインストール出来ない事態が発生したり、何かと構築/運用に対してハードルが高めです。
また、LaTeXは実際に書きたい文章量に対して組版の為に記載する必要のあるタグが多く、お世辞にも気軽に書ける言語とは言えません。

これらの状況を鑑みて、コンテナ技術であるDockerを用いて、gitとエディタとブラウザさえあればどこでもレポートが生成出来るような環境を作ってみました。

tl;dr

準備

GitLabの構築などは今回は割愛します。GitLab Omnibusを使ってサクッとインストールしてください。

2,3年前はGitLabの構築/運用にかなり苦しい思いをしましたが、最近は非常に簡単に運用できるようになっています。これを機にGitLabに再チャレンジするのも手かも!

レポートリポジトリを作成

レポート毎にリポジトリを分けても良いですが、自分は面倒だったのでほぼ全てのレポートが入っているリポジトリを作成しています。

そして、そのリポジトリのルートディレクトリに以下の2つのファイルを設置しています。

このような感じです。(pre_report.sh でレポート環境を用意した結果です)

whywaita% tree -L 1 -a .  [~/git/report]
.
├── .git
├── .gitlab-ci.yml
├── media              # レポートディレクトリ
└── pre_report.sh

レポートを書く

masawada/mics_reportを用いれば、LaTeXコンパイルを非常に簡略化してくれます。
masawada/mics_report は素晴らしいソフトウェアなのですが、ここだけ残念なので、kakakaya/mics_reportの利用を推奨します。
mics_reportの使用方法については、当該リポジトリのREADMEを参照してください。

GitLab CIでコンパイルする

リポジトリにこの.gitlab-ci.ymlを置いて、レポート名を調整してください。
pre_report.sh で第1引数に取ったレポート名をディレクトリパスに指定すればそれで動きます。便利ですね。

TeXファイルが書き上がったら、GitLabにpushしてみましょう。ちゃんと書けていれば、GitLabのビルドが走り、pdfファイルがダウンロード出来るようになります。

サンプルとして、 gitlab.com にリポジトリを用意してみました。実際に動いている様子はこちらでご確認ください。

https://gitlab.com/whywaita/sample-report-ci

終わりに

これによって、どこに居てもLaTeXコンパイルが出来る環境が手に入りました。

今回の技術の想定としては、メインマシンではLaTeX環境が入っていて、そこではmics_reportを手元のマシンで使いつつ、どこか外に行った際に、LaTeX環境の入っていないサブマシンでレポート修正したい!みたいな時に使えるのでは無いかと思います。(実際に筆者はそのようにつかっています)

サンプルリポジトリとして gitlab.com のGitLab CIを用いてレポートを作成しましたが、このSaaSはrunnerが共用になっていて、いつまで経ってもビルドが走らないのであまりお勧めしません。皆さんは自分のGitLabを立てて、自分でrunnerを用意しましょう。

では、良きGitLabライフを!

cloudpack杯 第5回 ICTトラブルシューティングコンテストに学生運営として参加してきました! #ictsc

前回から継続して、「ICTトラブルシューティングコンテスト」(以下トラコン)の運営委員として参加していました。本当なら本会が終わってすぐに書きたかったのですが、特に時間が取れず、先ほど自分としての最後の仕事を終えたので、その節目として書き始めてみます。

トラコンについては、前回の参加レポートと、公式サイトにある今回のレポート記事を読んで頂ければ、どのような雰囲気なのかは掴めるかなと思います。

なにをやったのか

マネジメント

前回はツチノコブログに記事を書かせて頂いたり、LTの司会をさせて頂いたりと、対外的に出させて頂いたのですが、今回はマネジメント関連をかなりさせて頂きました。

所謂リーダー的なポジションに就いて、「どうやれば人は上手く回るんだろう」と試行錯誤しながら、色々と始めたり、上手く行かなかったり、上手く行かなかった時にどう舵取りすれば良いのか分からなくなったり、慣れない事をやっているなあと思いながら何とかやり遂げられたかなと感じています。

トラコンの運営は、営利団体ではなく、自分と一緒に運営するメンバーも、自分が養っている訳ではありません。つまり、お願いした仕事を解決する事がその人の人生で生きていく為の絶対的な条件となる訳では無いのです。
こういうとちょっと大げさかもしれませんが、実際には学生のメンバーですので、大学の課題で作業に取りかかれないなどは容易に起こりえますし、(普段からの勉強も勿論重要ですが)テスト期間には特に全体の作業が止まってしまいます。これはメンバーに作業を強要しても仕方が無いことですし、そもそも良い組織作りとしてあまり褒められる事ではありません。
ここの調整がとても難しかったです。世間の会社的なマネジメント手法とは前提が違ったりして、どうやって進めるか頭を悩ませたり、本を読んだり、大人の方に相談したりました。個人的にはOSSや勉強会のコミュニティのマネジメント手法を若干参考にしてみました。

色々始めてみる

運営参加が2回目という事もあって、使っていたソフトウェアに不都合があったり、より良く進めていくために環境を整えてみたりという事もしました。

例えば、運営学生が、準備の段階から表示する技術ブログを開設してみました。
より運営学生を身近に感じて貰えればと思いましたが、如何だったでしょうか?

また、プロジェクト管理ツールとして、GitHub Issuesを使ってみました。今まではRedmineを用いて行っていたのですが、学生の時からGitHubを用いてのプロジェクトマネジメントをやってみるのは良い事では無いか?という話になり、採用してみました。

技術

技術的にはあまり個人的に新しい事を出来なかったかなというのが少し悔やまれる所です。
先ほど公開した問題解説にも書いたのですが、今回新しく触った技術と言えばSeleniumですかね。

問題を実装するだけであれば非常に簡単だったのですが、トラブルを誘導するためにログを生成する必要があり、その為にはブラウザを直接操作しなければいけませんでした。
その為にSelenium入門してみました。意外とさっくり書けたので良かったです(かなり泥臭い実装になってしまったのですが、恐らくSeleniumの仕様だろうなあと思いながら書きました…)。

ちなみに、利用したSeleniumのコードを先ほどgistに公開してみました。宜しければご参考までに。

終わりに

前述しましたが、昨日(03/31)、出題した全ての問題文、及び、運営学生が求めた回答を含めた解説を公開しました。是非次回参加のご参考に。また、今回悔しい思いをした皆様も、技術力向上に役立てて頂ければ幸いです。

この問題解説を公開した事により、私の第5回ICTトラブルシューティングコンテストに関する作業はほぼ終わりました。長い半年間だったと感じています。
次回についてですが、少し身の振り方を考えようかなと考えています。興味のある方は直接お目にかかった時にでも聞いて下さいませ。

cloudpack杯 第5回 ICTトラブルシューティングコンテスト、お疲れ様でした!!!!

GitLab CIでPerlアプリケーションのテスト/デプロイを自動化する

こんにちは、whywriteit インフラ班のwhywaitaです。

今回とある案件でGitLab CIを用いたCIを行ったので、その手順について記録したいと思います。

概要

  • GitLab CI
    • 途中でバージョンアップが何回か入ったのでバージョンは不定ですが、8.4 〜 8.6系
  • Perl 5.20.3
    • Coro導入の関係でこのバージョンです(詳細は後述)

今回はアプリケーションは他の人が書いており、それのCI部分を担当しておりました。自分はPerlを殆ど触った事が無かったので、その辺も込みでハマった所を書いておきます。

実装した動作

  • 実行用のUNIXユーザをサーバ上に用意し、ホームディレクトリにデプロイ
  • 本番用/検証用で別ドメインを用意する、サーバは同じ
  • developブランチにpushがあると本番用に、それ以外のブランチへのpushやMerge Requestがあると検証用にデプロイを行う

.gitlab-ci.yml

一昔前はGitLab CIはあくまでGitLabとの連携が強い単独のアプリケーションだったのですが、最近のバージョンではGitLabの1つの機能としてGitLab CIが導入されています。
ではそのビルドをどのように有効化するかと言えば、gitリポジトリ内に .gitlab-ci.yml という名前でファイルを追加するだけです。簡単ですね。

一部マスクしていますが、実際に利用している .gitlab-ci.yml がこちらです。

image: ****/****:latest // 自家製の準備用パッケージ

before_script:
  - perl --version
  - cpanm --installdeps . --force

stages:
  - sqlite3
  - mysql
  - deploy

dev:
  stage: sqlite3
  script:
    - apt-get install -y sqlite3
    - cpanm install DBD::SQLite
    - sqlite3 misc/db/development.db "***" // 初期処理
    - sqlite3 misc/db/development.db "***"
    - sqlite3 misc/db/development.db "***"
    - perl script/development/set_categories.pl
    - perl script/***_web test

production:
  stage: mysql
  script:
    - DEBIAN_FRONTEND=noninteractive apt-get install -y libmysqld-dev mysql-server
    - service mysql start
    - mysql -uroot -e"***" // 初期処理
    - mysql -uroot -e"***"
    - mysql -uroot -e"***"
    - mysql -uroot -e"***"
    - rm -f config/db.json // デプロイ処理
    - mv ./misc/ci/db.json.mysql ./config/db.json
    - perl script/development/set_categories.pl
    - perl script/***_web test

deploy:stg:
  stage: deploy
  when: on_success
  script:
    - cpanm Cinnamon
    - mv ./misc/ci/general.conf.stg ./config/general.conf
    - echo $CI_BUILD_REF_NAME
    - cinnamon staging deploy:update
    - cinnamon staging carton:install
    - cinnamon staging server:restart

deploy:production:
  stage: deploy
  when: on_success
  only:
    - develop
  script:
    - cpanm Cinnamon
    - cinnamon production deploy:update
    - cinnamon production carton:install
    - cinnamon production server:restart

config/deploy.pl に関しては、naoya_ito氏の以下のエントリを参考にして制作しました。

開発メモ#1 : Cinnamon によるデプロイ – naoyaのはてなダイアリー

# config/deploy.pl
use strict;
use warnings;
use Cinnamon::DSL;

set repository  => 'git@gitlab.example.com:***/***.git';
set user        => 'user';
set password    => 'password';

role production => ['example.com'],  {
    deploy_to   => '/home/user/product',
    branch      => 'develop',
};

role staging    => ['example.com'],  {
    deploy_to   => '/home/user/product-stg',
    branch      => $ENV{CI_BUILD_REF_NAME},
};

task deploy  => {
    setup => sub {
        my ($host, @args) = @_;
        my $repository = get('repository');
        my $deploy_to  = get('deploy_to');
        my $branch   = 'origin/' . get('branch');
        remote {
            run "git clone $repository $deploy_to && git checkout -q $branch";
        } $host;
    },
    update => sub {
        my ($host, @args) = @_;
        my $deploy_to = get('deploy_to');
        my $branch   = 'origin/' . get('branch');
        remote {
            run "cd $deploy_to && git fetch origin && git checkout -q $branch && git submodule update --init";
        } $host;
    },
};

task server => {
    start => sub {
        my ($host, @args) = @_;
        my $deploy_to = get('deploy_to');
        remote {
            run "cd $deploy_to && carton exec -- hypnotoad script/***_web";
        } $host;
    },
    stop => sub {
        my ($host, @args) = @_;
        my $deploy_to = get('deploy_to');
        remote {
            run "cd $deploy_to && carton exec -- hypnotoad script/***_web --stop";
        } $host;
    },
    restart => sub {
        my ($host, @args) = @_;
        my $deploy_to = get('deploy_to');
        remote {
            run "cd $deploy_to && carton exec -- hypnotoad script/***_web";
        } $host;
    },
    status => sub {
        my ($host, @args) = @_;
        my $deploy_to = get('deploy_to');
        remote {
            run "ps axuf | grep ***_web";
        } $host;
    },
};

task carton => {
    install => sub {
        my ($host, @args) = @_;
        my $deploy_to = get('deploy_to');
        remote {
            run "cd $deploy_to && carton install";
        } $host;
    },
};

ハマった/工夫した点

Coroが動かない

デプロイツールとして前記した通りCinnamonを選択したのですが、Cinnamonが依存しているCoroは最新版のPerlでは動かないことを知りました。
moznion氏の以下のエントリを見て頂ければ大体終わりです。これを受けて我々はstandard perl 5.20.3を利用しましたが、各自の環境に合わせた選択を推奨します。

plenv で stableperl を利用するの術 & stableperl の話 – その手の平は尻もつかめるさ

CIでのみTerm::ReadKeyのインストールが失敗する

Dockerコンテナでは実際のシェルではないため、インストールは成功してもPerlモジュールインストールテストで落ちるため、結果的にexit codeが1となり落ちます。
我々は検証環境を用意し、動いている事の確認をした上で cpanm --installdeps . --force する事でCIテストを通しました。
テストの実装は以下にある通りですので、皆様はしっかりと検証した上でご利用ください。

  • https://github.com/jonathanstowe/TermReadKey/tree/master/t

検証環境の作成

Viewを書いていたデザイナーの方がサーバを持っていなかったため、別に検証環境を用意しました。
検証環境といいつつ、あるのはMicroServer1台だけだったので、ディレクトリ分けと内部で使用するポートを切り替えるだけの実装でしたが、綺麗な環境でテスト出来るという事で割と評判は良かったです。

最後に

ビルドの成否やGitLabのpush通知などを全てslackに通知していたのですが、マージ出来るかどうかを機械的に判断し、自動的にデプロイする事でかなり開発は高速化出来たかなと感じています。

結果としてコードを書いていた人達の待ち時間がほぼ0の状態までもっていけた(≒インフラ担当として手でのオペレーションをほぼ行う必要がなくなった)ので、仕事は果たせたかなと。

また、少しCIが楽しくなってきたので、他の第3世代CIと呼ばれるSaaSも試してみました。

リポジトリ

エヴァのMAGIシステムを思い出しました。ちょっと面白かったです。

高専カンファ100 in 東京参加してきた! #kosenconf

こんにちは!whywriteit イベント班のwhywaitaです。

去る2015/12/19,20 に電気通信大学にて開催されていた”高専カンファレンス100 in 東京”に、高専生ではないですが参加&登壇してきました!

(さらに…)

誰かwhywaita Advent Calendar 2015の記事を書いてくださいっ! 5日目

本題

お願いしますっ!

(さらに…)

ICTトラブルシューティングコンテスト DMM.com ラボ ツチノコ杯 に学生運営として参加してきました! #ictsc

ちょっとしたご縁がありまして、第4回 ICTトラブルシューティングコンテストに学生運営として参加させて頂きました!

(さらに…)

つらいつらいダンス競技協会アジア支部の公式サイトがオープン!

こんにちは、whywaitaです。

このたび、「つらいつらいダンス競技協会アジア支部」の公式サイトがオープンしました!

(さらに…)

クロスクラウドファンディングからグッズが届きました!

ども、whywaitaです。

以前とりあげた暮井慧ボイスプロジェクトのリターンが届きましたのでご報告。

(さらに…)