はじめに
Github Actions便利ですよね.毎月2000分までタダで使えるので,個人プロジェクトはほぼこれでまかなえてしまいます.Docker,もしくはJavaScriptで開発できるので,バックエンドの方もフロントの方も触りやすそうです.
すでに公式日本語ドキュメントがあるので,最新情報はこちらを確認してください.
個人的に手順全体の概要があったほうがわかりやすいと思い,この記事を書いています.
action.yml
の役割とAction自体を検証するCIの作成方法は役立つと思います.
その他の詳細部分も書きましたが,個別のAction実装作業には役立たないので読まなくても大丈夫だと思います.
この記事の前提
- Dockerを利用して開発する前提です.JavaScriptでの開発は扱いません.
- Dockerにある程度詳しいことを前提としています.
開発に至った背景
- CI上でElasticSearchを起動したかったが,公式のActionがまだ利用したいバージョンに対応していなかった
- 利用しているプラグインをインストールした状態でテストしたかったが,こちらも公式が未対応だった
- なので,上記2点を改善したアクションを自分で開発することにした.
手順の概要
- 新しいrepositoryを作る
-
action.yml
を作る(これから作るActionがどんな引数を受け取るのか定義する) -
Dockerfile
を作る - コンテナ起動時に実行されるスクリプトを作る
- 今回開発したAction自体をテストするCIワークフローを定義する
- マーケットプレイスに公開する
詳細
新しいrepositoryを作る
- 新しいrepositoryを作ります(対象読者には説明不要と思われるので省略)
- READMEを追加せよと公式にはありますが,なくても動きます.もちろん公開するわけなので,あったほうがベター.英語だとよりベターでしょう.
- 下記は一例です
README.md
# elasticsearch-github-actions
setup elasticsearch in your github actions' workflow
## Usage
steps:
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- uses: miyataka/elasticsearch-github-actions@1
with:
stack-version: '7.6.2'
plugins: 'analysis-kuromoji analysis-icu'
action.yml
を作る(これから作るActionがどんな引数を受け取るのか定義する)
- 今回開発したものを引用します
action.yml
name: 'Run Elasticsearch with Plugins' # actionの名前,マケプレで表示される.
description: 'Elasticsearch with Plugins' # actionの説明,マケプレで表示される.
author: 'miyataka' # 自分のGitHub IDなど
branding: # マケプレのアイコンを設定する
icon: 'database'
color: 'red'
inputs: # Actionを実際にCIで使うときに,渡してほしいパラメータを定義する
stack-version:
description: 'The version of Elasticsearch'
required: true
plugins:
description: 'Elasticsearch plugin strings'
required: false
default: ''
runs:
using: 'docker'
image: 'Dockerfile'
env:
STACK_VERSION: ${{ inputs.stack-version }} # inputでもらったパラメータを環境変数に設定してコンテナにわたす
PLUGINS: ${{ inputs.plugins }}
Dockerfile
を作る
- やっていることはシンプルです.
entrypoint.sh
をイメージに追加しているだけ. - 今回諸事情でdocker in dockerをやるので,ベースイメージは内部で
docker
コマンドを使えるdocker:stable
です
FROM docker:stable
RUN apk add --update bash
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
コンテナ起動時に実行されるスクリプトを作る
- さきほど登場したentrypoint.shを実装します
- hello worldでもなんでもいいのですが,説明の都合上今回開発したものを引用します
#!/bin/bash
set -euxo pipefail
# 必須にした引数が存在するかチェック
if [[ -z $STACK_VERSION ]]; then
echo -e "\033[31;1mERROR:\033[0m Required environment variable [STACK_VERSION] not set\033[0m"
exit 1
fi
docker network create elastic
PLUGINS_STR=`echo ${PLUGINS} | sed -e 's/\n/ /g'` # 引数に含まれている改行文字を置換
MAJOR_VERSION=`echo ${STACK_VERSION} | cut -c 1` # メジャーバージョンを取得
PLUGIN_INSTALL_CMD=""
# pluginsを複数インストールするケースがあるのでfor文でコマンドを組み立てる
if [ "x${PLUGINS_STR}" != "x" ]; then
ARRAY=(${PLUGINS_STR})
for i in "${ARRAY[@]}"
do
PLUGIN_INSTALL_CMD+="elasticsearch-plugin install --batch ${i} && "
done
fi
# single node only
if [ "x${MAJOR_VERSION}" == 'x6' ]; then # メジャーバージョンによって起動オプションを分岐する.
docker run \
--rm \
--env "node.name=es1" \
--env "cluster.name=docker-elasticsearch" \
--env "cluster.routing.allocation.disk.threshold_enabled=false" \
--env "bootstrap.memory_lock=true" \
--env "ES_JAVA_OPTS=-Xms1g -Xmx1g" \
--env "xpack.security.enabled=false" \
--env "xpack.license.self_generated.type=basic" \
--ulimit nofile=65536:65536 \
--ulimit memlock=-1:-1 \
--publish "9200:9200" \
--detach \
--network=elastic \
--name="es1" \
--entrypoint="" \
docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} \
/bin/sh -vc "${PLUGIN_INSTALL_CMD} /usr/local/bin/docker-entrypoint.sh"
elif [ "x${MAJOR_VERSION}" == 'x7' ]; then
docker run \
--rm \
--env "node.name=es1" \
--env "cluster.name=docker-elasticsearch" \
--env "cluster.initial_master_nodes=es1" \
--env "discovery.seed_hosts=es1" \
--env "cluster.routing.allocation.disk.threshold_enabled=false" \
--env "bootstrap.memory_lock=true" \
--env "ES_JAVA_OPTS=-Xms1g -Xmx1g" \
--env "xpack.security.enabled=false" \
--env "xpack.license.self_generated.type=basic" \
--ulimit nofile=65536:65536 \
--ulimit memlock=-1:-1 \
--publish "9200:9200" \
--detach \
--network=elastic \
--name="es1" \
--entrypoint="" \
docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION} \
/bin/sh -vc "${PLUGIN_INSTALL_CMD} /usr/local/bin/docker-entrypoint.sh"
fi
# 上記で起動したコンテナに対して,curlで死活確認するコンテナを立ち上げる
docker run \
--network elastic \
--rm \
appropriate/curl \
--max-time 120 \
--retry 120 \
--retry-delay 1 \
--retry-connrefused \
--show-error \
--silent \
http://es1:9200
sleep 10
echo "Elasticsearch up and running"
今回開発したAction自体をテストするCIワークフローを定義する
- すでにActionを使った事がある場合にはご存知でしょうが,
.github/workflows/*.yml
を配置するとCIを実行してくれますね. - 今回開発したAction自体も思ったとおりに動くか検証するためのCIを作りました
name: Elasticsearch GitHub Action
on: [push]
jobs:
run-action:
name: Start Elasticsearch
runs-on: ubuntu-latest
strategy:
matrix:
elasticsearch: ["6.4.3", "7.6.2"]
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Configure sysctl limits
run: |
sudo swapoff -a
sudo sysctl -w vm.swappiness=1
sudo sysctl -w fs.file-max=262144
sudo sysctl -w vm.max_map_count=262144
- name: Start Elasticsearch # 重要なのはこの部分
uses: ./
with:
stack-version: ${{ matrix.elasticsearch }}
plugins: |
analysis-kuromoji
analysis-icu
- name: Elasticsearch is reachable
run: |
curl --verbose --show-error http://localhost:9200
マーケットプレイスに公開する
- 動作確認もできたら,あとは公開するだけです.
- ここまでの手順を踏んでいれば,以下のような表示がされているはずです.
参考と補足
- 引用したrepositoryはこちらです
- 複数バージョンに対応するためのPRを公式に対して出しています.マージされるといいなぁ.
最後に
すでにたくさんActionsが公開されているのですが,まだまだかゆいところに手が届かない感じのものも多いです.
OSS開発するにはまだまだブルーオーシャンです.皆で開発&公開してよりよい開発効率を目指しましょう!