LoginSignup
13
15

More than 3 years have passed since last update.

GitHub Actionsを開発して公開するまで(Docker編)

Last updated at Posted at 2020-05-17

はじめに

Github Actions便利ですよね.毎月2000分までタダで使えるので,個人プロジェクトはほぼこれでまかなえてしまいます.Docker,もしくはJavaScriptで開発できるので,バックエンドの方もフロントの方も触りやすそうです.

すでに公式日本語ドキュメントがあるので,最新情報はこちらを確認してください.
個人的に手順全体の概要があったほうがわかりやすいと思い,この記事を書いています.
action.ymlの役割とAction自体を検証するCIの作成方法は役立つと思います.
その他の詳細部分も書きましたが,個別のAction実装作業には役立たないので読まなくても大丈夫だと思います.

この記事の前提

  • Dockerを利用して開発する前提です.JavaScriptでの開発は扱いません.
  • Dockerにある程度詳しいことを前提としています.

開発に至った背景

  • CI上でElasticSearchを起動したかったが,公式のActionがまだ利用したいバージョンに対応していなかった
  • 利用しているプラグインをインストールした状態でテストしたかったが,こちらも公式が未対応だった
  • なので,上記2点を改善したアクションを自分で開発することにした.

手順の概要

  1. 新しいrepositoryを作る
  2. action.ymlを作る(これから作るActionがどんな引数を受け取るのか定義する)
  3. Dockerfileを作る
  4. コンテナ起動時に実行されるスクリプトを作る
  5. 今回開発したAction自体をテストするCIワークフローを定義する
  6. マーケットプレイスに公開する

詳細

新しい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

マーケットプレイスに公開する

  • 動作確認もできたら,あとは公開するだけです.
  • ここまでの手順を踏んでいれば,以下のような表示がされているはずです. publish-github-action-to-markeplace-button.png
  • このボタンを押して,指示に従い公開しましょう.
  • ここは公式docをみたほうがいいですね

参考と補足

最後に

すでにたくさんActionsが公開されているのですが,まだまだかゆいところに手が届かない感じのものも多いです.
OSS開発するにはまだまだブルーオーシャンです.皆で開発&公開してよりよい開発効率を目指しましょう!

13
15
2

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
13
15