0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RedmineプラグインをGitHub Actionsでテストする(Docker編)

Last updated at Posted at 2020-01-18

以前に書いたRedmineプラグインをGitHub Actionsでテストするでの、以下の問題点を解消するために、Dockerイメージを使用した形に改良したまとめです。

  • パッケージやRedmine自体のインストールも都度行われるため、時間がかかる。
  • actions/setup-rubyで、Ruby v2.3.xはインストールできない。

改良後の結果

Redmine Auto Assign Group Pluginのテストを行うワークフローでの結果です。

テストにかかる時間

Redmine Auto Assign Group Pluginのテストに、GitHub ActionとしてRedmine plugin test actionを使用しています。改良前のv1と改良後のv2での比較は以下の通りで、大きく改善できました。

対象 実行時間(m:ss) v1-v2
v1(改良前) 6:28 ------
v2(改良後) 2:33 3:55

※記事を書いている時点で最新の成功ビルド5件ずつの時間から、最大最小を除いた3件の平均で算出。
※Redmine-Rubyの組み合わせ10環境、テストは49 runs, 244 assertionsでMiniTestを使用。ただし、v1ではRuby v2.3.xは使用できないため、v2.3.xは除いた場合。

Ruby v2.3.xでのテスト

dockerhubのruby:2.3-slimベースのイメージを作成することで、テストできるようになりました。

改良内容

Redmine plugin test actionのv1は、Github Actionsのubuntu-latestに対して環境を作っていくものでした。これだとテストまでの準備に時間がかかるため、あらかじめRedmineをインストールしたテストを実行するイメージをDockerHubに作成しておき、その上でプラグインのテストを実行する動きにしました。

流れをまとめると以下のとおりです。
プラグインのGitHubアクションワークフロー → DockerHubからイメージ取得 → プラグインのテスト実行

プラグインのGitHubアクションワークフロー

Redmine Auto Assign Group Pluginでの変更は、このコミットのような感じです。
環境構築のための定義はバッサリなくなり、RedmineとRubyのバージョン、プラグイン名の指定のみとなりました。これに伴って、GitHubアクションとしてパラメータが変更になったため、v2に変更しています。

DockerHubからイメージ取得

ベースのなる環境は、DockerHubのrubyのslimイメージを元にして、RedmineとChrome、ChromeDriverをインストールしたイメージを作っています。行っている事自体は、v1と同じです。DBはPostgreSQL, MySQL, sqlite31DockerfileのリポジトリはここDockerHubはここです。

RedmineとRubyのバージョン組み合わせの作成

以下の記事がとても参考になりました。
dockerhubのautomated buildで任意のdocker buildコマンドを利用し、単一のDockerfileから設定を動的に変えて複数イメージをビルドする

DockerHubのビルド設定で行ったタグ名を元に、フックでRedmineとRubyのバージョンを取得して、ビルドを行っています。フックは以下のようなものです。

#!/bin/bash
set -eux

LIST=(${DOCKER_TAG/_/ })
RUBY_VERSION=${LIST[1]/ruby/}
REDMINE_VERSION=${LIST[0]//trunk/master}

LIST=(${REDMINE_VERSION//[.-]/ })
if [ ${#LIST[*]} -eq 2 ]; then
  LATEST_VER=LATEST_${REDMINE_VERSION/./_}
  if [ ${LATEST_VER} != "" ]; then
    eval REDMINE_VERSION=\$$LATEST_VER
  fi
fi

docker build --build-arg REDMINE_VERSION=${REDMINE_VERSION} --build-arg RUBY_VERSION=${RUBY_VERSION} -f $DOCKERFILE_PATH -t $IMAGE_NAME .

DOCKER_TAG に、DockerHubのタグ名が入ってきます。 4.1_ruby2.6 などのような規則にしておき解析することで、バージョンを決定して以下のようにDockerfileへARGで渡しています。

ARG RUBY_VERSION
FROM ruby:${RUBY_VERSION}-slim
ARG REDMINE_VERSION

DockerHubのビルド設定は、 Builds - Configure Automated BuildsBUILD RULES に以下のような感じで追加しています。Sourceはすべてmasterにしていますが、 Docker Tag を変えて複数登録することで、組み合わせでイメージをビルドできます。
build_rules.png

GitHubアクションからのイメージ使用

実際にテストを行うGitHubアクションである、Redmine plugin test actionは、Dockerコンテナのアクションとして作成するつもりでした。プラグイン側のアクションから受け取ったパラメータでDockerHubのイメージを指定できるかと思ったのですが、ARGの受け渡しができず、うまくいきませんでした。
このため、v1と同じくシェルスクリプトをキックして、DockerHubのイメージをベースにしたDockerfileをビルド、起動する形にしています。シェルスクリプトはこれです。

GitHubのブランチ名の取得は環境変数から取得しますが、プルリクの場合とブランチへのコミットの場合で分けて取得する必要がありました。

if [ "${GITHUB_HEAD_REF}" = "" ]; then
  PLUGIN_BRANCH=$(echo ${GITHUB_REF#refs/heads/})
else
  PLUGIN_BRANCH=${GITHUB_HEAD_REF}
fi

あとはDockerfileにブランチ名やアクションのパラメータを渡してビルド、実行します。

docker build -t redmine-plugin-test \
             --build-arg REDMINE_VERSION=${REDMINE_VERSION} \
             --build-arg RUBY_VERSION=${RUBY_VERSION} .
docker run -e "GITHUB_REPOSITORY=${GITHUB_REPOSITORY}" \
           -e "PLUGIN_NAME=${PLUGIN_NAME}" \
           -e "PLUGIN_BRANCH=${PLUGIN_BRANCH}" \
           -e "DATABASE=${DATABASE}" \
           -t redmine-plugin-test

プラグインのテスト実行

テスト自体はDockerfileのENTRYPOINTで実行するシェルスクリプトに書いています。
インストール→テスト→アンインストール のrakeを実行する内容になっています。

まとめ

Redmine Auto Assign Group Pluginでの結果は、以下のような感じです。
build_rules.png

Redmine plugin test actionのv1に比べて、だいぶ実行時間を短縮できました。プラグイン側のワークフローもシンプルになったので、使いやすくなったのではと思います。

  1. 2020/04/04編集:v2.0.1でPostgreSQL、MySQL(MariaDB)にも対応しました。

0
0
1

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?