【GitHub Actions】Dockerコンテナを実行してみた

GitHub Actionsのジョブ内でDockerコンテナを起動し、コンテナで簡単なステップを実行してみました。

#簡単なステップの実行
Dockerイメージを指定してワークフローを実行すると、仮想マシン(Linux)上でコンテナが実行されます。

```container.yml
name: Container
on: push

jobs:
  node-docker:
    runs-on: ubuntu-latest
    container: #起動するコンテナイメージを指定
      image: node:13.5.0-alpine3.10 #指定のdockerイメージを使用
    steps: #dockerコンテナ内でステップを実行
      - name: Log node version
        run: |
          node -v #nodeバージョンの確認
          cat /etc/os-release #Linuxバージョンの確認
```

nodeとLinuxのバージョンを確認すると、指定したdockerイメージのバージョンと確かに同じです。
![スクリーンショット 2021-03-27 9.08.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/bc4e67a8-4b6e-ad4e-9fcb-e651256fe445.png)


#ステップ単位でDockerイメージを利用
ステップごとにDockerイメージを指定してコンテナを起動することができます。

例えば、以下の`docker-steps`ジョブでは`node:10.18.0-jessie`のイメージを指定しており、`log node version`のステップではこのコンテナで`node -v`が実行されます。
次の`Step with docker`のステップでは、`docker://node:12.14.1-alpine3.10`がアクションとして実行され、`node:12.14.1-alpine3.10`のイメージからコンテナが起動します。そのため、`with`で指定している`/bin/echo`はこちらのコマンドで実行されます。
最後の`Log node version`ステップも、同様に`uses`で指定したイメージから起動したコンテナで`/usr/local/bin/node`が実行されます。

```yml
name: Container
on: push

jobs:
  docker-steps:
    runs-on: ubuntu-latest
    container:
      image: node:10.18.0-jessie
    steps:
      - name: log node version
        run: node -v
      - name: Step with docker
        uses: docker://node:12.14.1-alpine3.10 #このステップだけで起動するコンテナイメージ
        with:
          entrypoint: '/bin/echo' #コンテナ起動時にechoコマンドを実行
          args: 'Hello World' #echoコマンドの引数
      - name: Log node version
        uses: docker://node:12.14.1-alpine3.10 
        with:
          entrypoint: '/usr/local/bin/node' #コンテナ起動時にnodeコマンドを実行
          args: -v #nodeコマンドの引数(バージョン確認)
```

#自作シェルスクリプトの実行
ローカルで作成したシェルスクリプトのファイル(`script.sh`)をコンテナで実行するステップ(`Run a script`)を作成します。

ステップから与えた引数と`Hello World`を出力する簡単なスクリプトを作成し、`chmod +x script.sh`で予めすべてのユーザに実行権限を与えます。

```script.sh
#!/bin/sh
echo $1
echo "Hello World"
```
ジョブに新しいステップを追加します。
作成したスクリプトを実行するため、ステップの前に`actions/checkout@v2`のアクションを追加します。スクリプトを含むリポジトリがコンテナ内にクローンされます。

```yml
      - uses: actions/checkout@v2 #次ステップでファイル読み込むのでクローンが必要
      - name: Run a script
        uses: docker://node:12.14.1-alpine3.10 
        with:
          entrypoint: './script.sh' #作成したシェルスクリプトを実行
          args: "Some string"

```

#Slackへの通知
Slack-NotifyのDockerイメージを使い、Incoming Webhook経由でSlackに通知を行うステップを作成します。

```yml
      - name: send a slack message
        uses: docker://technosophos/slack-notify
        env:
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} #WEBHOOK URL
          SLACK_MESSAGE: "Hello slack"
```

通知を行うためにはWebhookのURLである`SLACK_WEBHOOK`と通知メッセージである`SLACK_MESSAGE`が必要です。

以下がWebhookURLの作成手順です。

slack apiで`Create an App`をクリックします。
![スクリーンショット 2021-03-31 22.17.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/c4423b84-b88a-babd-168e-0f88795666b0.png)

通知元の名前を記述し、通知先のワークスペースを選択します。
![スクリーンショット 2021-03-31 22.18.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/471e1d0c-2caa-5b8e-1008-48b9554b10e0.png)

Incoming Webhooksをクリックします。
![スクリーンショット 2021-03-31 22.18.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/e399eb94-47c6-33d4-8c9e-7ac36b86c471.png)

トグルをonにして`Add New Webhook to Workspace`をクリックすると、Webhook URLが表示されます。
![スクリーンショット 2021-03-31 22.19.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/212317bf-fa44-1e11-3207-fa78cba3223c.png)

投稿先のチャンネルを選択します。
![スクリーンショット 2021-03-31 22.20.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/b80eb89b-54c3-1283-6742-ba902f967f54.png)

ymlファイルを作成したGitHubリポジトリのSettingsで`SLACK_WEBHOOK`という環境変数を作成します。
Valueに先ほど作成されたWebhook URLをコピーペーストします。
![スクリーンショット 2021-03-31 22.21.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/a0bd29ed-662c-0cfa-c426-d846c3c722fe.png)

リポジトリをプッシュするとワークフローが実行され、チャンネルにメッセージが通知されます。
![スクリーンショット 2021-03-31 22.29.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/35770669-0310-ff6f-7809-d5a98e5aa3e9.png)

#おわりに
今度はCI/CDパイプラインをつくってみようと思います。

#参考資料
https://www.udemy.com/share/102DqFCEEZd11VRno=/

https://docs.github.com/en/actions/reference