Github ActionsでGKEバージョンアップの自動PR

# はじめに
Github Actionsにはcron scheduleがあるので、定期実行ジョブを回せるなと思ったので、標記作ることにしました。

https://help.github.com/ja/articles/workflow-syntax-for-github-actions#undefined

バージョンあげたPRを飛ばしてくれる系は[dependabot](https://dependabot.com/)的なものがあるんですが、k8sバージョンアップはサポートしてなかったりするので、作りました。

誰か知ってたら教えてください。

# 結論
https://github.com/junpayment/cicdversionuplabo/blob/master/.github/workflows/versionup.yml

# 解説

## cronするところ

こんな感じ。特筆するとこはなし。

```yaml
name: versionup

on:
  schedule:
    - cron: '0 */1 * * *'
```

## 最新のGKEバージョンを取りに行くところ

GKEバージョンを`gcloud container get-server-config`で取得しに行きます。
そのため、先にgcloudをインストールします。

CirclCIみたいにセットアップされたコンテナ上でCIできないので、必要なツールは都度インストールする必要があります。めんど〜〜、CI時間伸びる〜〜

```yaml
    - name: Install Gcloud
      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
```

認証情報もsecretsから引っ張っていきます。ここら辺もCircleCIみたいにcontext使えればなおよし。
ここでは、terraformを使うことを想定してるので、`terraform.tfvars`をsedで書き換えます。
最終的に`git diff`で差分無かったらスルーします。

```yaml
    - name: Get latest GKE version string and modify version
      env:
        GOOGLE_APPLICATION_CREDENTIALS_JSON: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS_JSON }}
        GOOGLE_APPLICATION_CREDENTIALS: ./google_application_credentials.json
        GOOGLE_PROJECT_ID: junpayment
      run: |
        echo ${GOOGLE_APPLICATION_CREDENTIALS_JSON} > ${GOOGLE_APPLICATION_CREDENTIALS}
        gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS}
        gcloud config set project ${GOOGLE_PROJECT_ID}
        export JSON=`gcloud container get-server-config --region asia-northeast1 --format json`
        export NEW_MASTER_VERSION=`echo ${JSON} | jq -r '.validMasterVersions | .[0]'`
        export NEW_NODE_VERSION=`echo ${JSON} | jq -r '.validNodeVersions | .[0]'`
        echo ${NEW_MASTER_VERSION} > .new_master_version
        echo ${NEW_NODE_VERSION} > .new_node_version
        sed -i -r "s/^(master_version\s*=\s*)\".*\"/\1\"${NEW_MASTER_VERSION}\"/" terraform.tfvars
        sed -i -r "s/^(node_version\s*=\s*)\".*\"/\1\"${NEW_NODE_VERSION}\"/" terraform.tfvars
        export DIFF=`git diff`
        test ${#DIFF} -gt 0 ; exit 0
```

## PRを作る

PRは`hub`コマンドでやります。
hubの公式githubのreleaseからバイナリを引っ張ります。
今回のvmは`ubuntu-latest`なのでlinux版を引っ張ってきます。

```yaml
    - name: Install hub
      run: |
        wget https://github.com/github/hub/releases/download/v2.12.8/hub-linux-amd64-2.12.8.tgz
        tar -xvf hub-linux-amd64-2.12.8.tgz
        cd hub-linux-amd64-2.12.8
        sudo cp -a bin/hub /usr/local/bin/
```

ブランチ作ってcommitしてpushをします。
イケてないなと思ったのが、ユーザ/パスを指定しなければいけなかったところです。

githubのCIサービスなんだから、CI動かしたユーザ権限で何もせずにgitコマンドを動かさせてくれたら嬉しかったです。


```yaml
    - name: Make a PR
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        GITHUB_USERNAME: ${{ secrets.GITHUB_USERNAME }}
        GITHUB_EMAIL: ${{ secrets.GITHUB_EMAIL }}
      run: |
        export NEW_MASTER_VERSION=`cat .new_master_version`
        export NEW_NODE_VERSION=`cat .new_node_version`

        git fetch
        git branch -r | grep update_${NEW_MASTER_VERSION}_${NEW_NODE_VERSION} && exit 0

        git checkout -b feature/update_${NEW_MASTER_VERSION}_${NEW_NODE_VERSION}
        git add terraform.tfvars

        git config --global user.name ${GITHUB_USERNAME}
        git config --global user.email ${GITHUB_EMAIL}
        git commit --amend --reset-author -m "update_${NEW_MASTER_VERSION}_${NEW_NODE_VERSION}"

        git remote rm origin
        git remote add origin https://${GITHUB_USERNAME}:${GITHUB_TOKEN}@github.com/${GITHUB_USERNAME}/cicdversionuplabo.git
        git push -u origin feature/update_${NEW_MASTER_VERSION}_${NEW_NODE_VERSION}

        hub pull-request -m "update_${NEW_MASTER_VERSION}_${NEW_NODE_VERSION}"
```

以上