GitHub Actionsの使い方

Github謹製のCD/CIツールとしてGitHub Actionsを使ってみましたのでメモを残します。

今回テストしたGithubは、
①githubのソースコードを含めたコンテナイメージ化
②コンテナイメージをGCR(Google Container Registry)にアップロード
③GCRよりGKE上のkubenetesにデプロイ
④部分的にチャットワークにメッセージ送信
の4つです。

GCPのcredential.jsonをGithubのSercretに登録する

GCPを触るので、事前に取得した認証ファイルを使うことになりますが、リポジトリ内に認証ファイルを上げずに、githubのsercretに登録します。
jsonファイルの中身をそのまま貼り付けるのではなく、base64エンコード形式で貼る必要があります。

bast64 xxxxx.json #認証ファイル

GithubActionファイルの作成

Actionメニューより、NewWorkFlowを選択します。

以前の情報を見ると、初期の頃はビジュアライズなインターフェースで作成が出来たようですが、今はYAML形式での記載になります。
今回は、Docker imageのテンプレートを選びます。

リポジトリの/.github/workflows/dockerimage.ymlとしてテンプレートが挿入されるので、以下のようにカスタマイズします。

name: Docker Image CI

# CI/CDのトリガーになる動作を指定
# 以下はmasterブランチが変更されたら...
on:
  push:
    branches:
      - master

jobs:
  build:
    # CIで使うベースイメージ?
    runs-on: ubuntu-latest

    steps:
    # ベースイメージにリポジトリをcloneする 
    - uses: actions/checkout@v1

    # チャットワークにgit logの内容を送信する
    - name: Send cahtwork from gitlog
      env:
        ROOM_ID: xxxxxxxx
        API_TOKEN: xxxxxxxxxxxxxxx
        REPO_NAME: 'test repo'
      run: |
        git log --numstat -m -1 --date=iso --pretty='[%ad] %h %an : %s' > gitlog.txt
        curl -s -X POST -H "X-ChatWorkToken: ${API_TOKEN}" -d "body=[info][title]${REPO_NAME}[/title]`cat gitlog.txt`[/info]" "https://api.chatwork.com/v2/rooms/${ROOM_ID}/messages"

    # Docker buildを実行
    - name: Build the Docker image
      run: docker build -f Dockerfile . -t {タグ}  #リポジトリ直下にDockerfileを置いています

    # イメージにタグを付ける
    - name: Tagging Docker
      run: docker tag {タグ} gcr.io/{プロジェクトID}/{タグ}:latest

    # 
    - name: gcloud auth
      uses: actions/gcloud/auth@master
      env:
        GCLOUD_AUTH: ${{ secrets.GCR_KEY }}

    - name: Upload to GCS
      env:
        PROJECT_ID: skyticket-devel-161401
        GCLOUD_AUTH: ${{ secrets.GCR_KEY }}
        GOOGLE_APPLICATION_CREDENTIALS: ./service-account.json
      run: |
        export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)"
        echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
        curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
        sudo apt-get update
        sudo apt-get install google-cloud-sdk
        echo ${GCLOUD_AUTH} | base64 --decode > ${GOOGLE_APPLICATION_CREDENTIALS}
        cat $GOOGLE_APPLICATION_CREDENTIALS | docker login -u _json_key --password-stdin https://gcr.io
        gcloud auth activate-service-account --key-file $GOOGLE_APPLICATION_CREDENTIALS
        gcloud config set project ${PROJECT_ID}
        gcloud docker -- push gcr.io/${PROJECT_ID}/sky_scrayping/sky_scrayping:latest

    # GKEにデプロイ
    - name: Deploy Kubenetes
      env:
        cluster_name: test-cluster
        cluster_ip: xx.xx.xx.xx
      run: |
        kubectl config set-cluster ${cluster_name} --server=http://${cluster_ip}
        kubectl config set-context ${cluster_name}
        gcloud container clusters get-credentials ${cluster_name} --zone=us-west1-a

        # kubenetest のマニフェストはmanifest/dev.ymlに置いており、
        # deployを強制する為にマニフェストの一部を置換しています。
        sed -i -e "s/annotations_reloaded-at/`date  +%s`/g" manifest/dev.yml
        kubectl apply -f manifest/dev.yml

    # チャットワークにデプロイ完了の通知する
    - name: Send cahtwork from Deploy
      env:
        ROOM_ID: xxxxxxxx
        API_TOKEN: xxxxxxxxxxxxxxx
        REPO_NAME: 'test repo'
        BODY: '開発環境のデプロイが完了しました'
      run: |
        curl -s -X POST -H "X-ChatWorkToken: ${API_TOKEN}" -d "body=[info][title]${REPO_NAME}[/title]`echo -e ${BODY}`[/info]" "https://api.chatwork.com/v2/rooms/${ROOM_ID}/messages"

    # Actionが失敗した時はチャットワークにデプロイ失敗の通知する
    - name: error notification
      if: failure()   # これ重要
      env:
        ROOM_ID: xxxxxxxx
        API_TOKEN: xxxxxxxxxxxxxxx
        REPO_NAME: 'test repo'
        BODY: '開発環境のデプロイが失敗しました\n詳細はgithubActionのステータスを参照してください'
      run: |
        curl -s -X POST -H "X-ChatWorkToken: ${API_TOKEN}" -d "body=[info][title]${REPO_NAME}[/title]`echo -e ${BODY}`[/info]" "https://api.chatwork.com/v2/rooms/${ROOM_ID}/messages"

一度定義したenvは他の場所でも参照出来ると思います。