GitHub Actionsを使用してバージョンを指定してパッチを当てたバイナリをビルドするというフローを自動化する

リポジトリはこちらです。

github.com

何をやっているかというと過去にも実施したWazuh agentにパッチを1行当ててビルドするだけです。

k1low.hatenablog.com

ただ、GitHub Actionsの利用方法としてはなかなか面白い使い方かなと思ったのでエントリにしました。

実現しているのは

欲しい「パッチ済みWazuh agentのバージョン」をタグとして git push すると、それをトリガーにGitHub Actionsのワークフローが起動して

  1. 指定のバージョンの wazuh/wazuh のソースをgit clone
  2. パッチを適用
  3. ディストリビューションごとにビルド
  4. ビルドしたバイナリをtarでまとめてReleasesにアップロード

を並列に実行するというものです。

以下YAML全文

name: build

on:
  push:
    tags:
      - v*

jobs:
  debug-build:
    name: Build agent with patch
    strategy:
      matrix:
        platform: [ubuntu-xenial, ubuntu-bionic, centos-6, centos-7]
    runs-on: ubuntu-latest
    steps:
      - name: Install packages
        run: |
          sudo apt-get -qq update
          sudo apt-get install -qq git tar
          curl -sL https://github.com/tcnksm/ghr/releases/download/v0.13.0/ghr_v0.13.0_linux_amd64.tar.gz -o ghr.tar.gz
          sudo sh -c "tar xf ghr.tar.gz -O ghr_v0.13.0_linux_amd64/ghr > /usr/local/bin/ghr"
          sudo chmod +x /usr/local/bin/ghr
      - name: Check out source code
        uses: actions/checkout@v2

      - name: Make directory
        run: |
          mkdir dist
          mkdir pkg
      - name: Build agent with patch
        run: |
          docker build . -f Dockerfile.${{ matrix.platform }} -t wazuh-debug
          docker run --rm -v $(pwd)/dist:/dist --env WAZUH_VERSION=${GITHUB_REF##*/} wazuh-debug
      - name: Release
        run: |
          tar cfz pkg/wazuh-debug-${GITHUB_REF##*/}-${{ matrix.platform }}.tar.gz dist/
          ghr -replace ${GITHUB_REF##*/} pkg/
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

指定のバージョンでビルドする

前提として

  • wazuh/wazuh がバージョンでタグを切っている

というのがあるのですが、それを利用して各DockerfileのCMDに設定している build.sh 内で

git clone https://github.com/wazuh/wazuh.git -b ${WAZUH_VERSION} --depth 1

を実行し、必要なソースコードをgit cloneしてきています。

${WAZUH_VERSION} はどう取得してきているかというと、環境変数 GITHUB_REF${GITHUB_REF##*/} で文字列置換して取得しています。

GITHUB_REFGitHub Actionsにおいてブランチやタグのrefなのですが、on.push.tags: でタグpushのみでジョブが実行されるようにしているので必然的に「タグ=Wazuh agentのバージョン」を取得できる仕組みになっています。

並列実行する

これは strategy.matrix: を利用しています。

よく strategy.matrix: は言語のバージョンや実行環境の種類などが例にあげられますが、別にそれらに限らず並列実行するのに使えるので便利です。

今回はディストリビューション名を与えて、それを使用してDockerfileのファイル名やリリースするアーカイブ名に使っています。

作成したバイナリは ghr でアップロードしています。

ディストリビューションごとにバイナリファイル名をうまく分けて、かつ -replace オプションを使うことで

  • 並列で
  • 何度でも同じタグのReleaseに

アップロードできるので便利です。


以上です。

今年はさらにGitHub Actionsを使い倒すことになりそうです。