Github Actionsが使えるようになったので使ってみる

## 本記事

本記事では、少し前にアナウンスされたGithub ActionsというCIツールのようなものを実際に触ってみて、現時点での使い勝手をまとめてみようと思います。

実際に使えるようになると以下のようなタブが追加されています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/b9557388-21a3-aa0a-bedf-d654015b6f0a.png)


まだベータ版ですが使うには申し込む必要があるので、この[リンク](https://github.com/features/actions)から申し込んでください。

## 初めて使ってみる
### ActionページにいってWorkflowを作ってみる

Actionページに行くと以下のようなページでWorkflowを作り始められます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/3e81ac5f-da8d-6d8a-a4d0-b5e5650f9594.png)


"Create a new workflow"を押して開始してみます。

### Visual Editor
#### 基本的なこと

以下のように設定できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/89db822d-2d1f-f2ed-8d35-a674189c6d89.png)


いくつものWorkflowを定義できるようです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/3e6fccac-972d-81cb-6153-7abb35425a6e.png)


一つ目のActionのEditをおしてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/e5836eff-ae75-a300-cccc-c8e35845adb0.png)

これは**トリガー**です。

> どのようなことが起きればこのWorkflowが走るか

を定義するものです。

`Run`で定義するトリガーは以下のものがあります。

| 項目 |トリガー条件| 
|:----|:---|
|  check_run | Checkが走って`created`, `rerequested`, `requested_action`になったら|
| check_suite | Check runの集合で、ステータスが`completed`, `requested`, `rerequested`になったら |
| commit_comment| コミットコメントが`created`になったらトリガー| 
| create |ブランチやタグが作られたら | 
| delete | ブランチやタグが削除されたら |
| deployment| APIを通してデプロイメントが作られたら |
|deployment_status| デプロイメントステータスが更新されたら |
| fork | リポジトリがフォークされたら |
| gollum| Wikiページがアップデートされたら |
| issue_comment | Issueにコメントが`created`、`edited`か`deleted`されたら |
| issues | Issueが`assigned`, `unassigned`, `labeled`, `unlabeled`, `opened`, `edited`, `milestoned`, `demilestoned`, `closed`, `reopened`されたら |
| label | ラベルが`created`, `edited`, `deleted`したら |
| member | メンバーが招待、削除に追加されたり権限が変わったら |
| milestone | マイルストーンが`created`, `closed`, `opened`, edited`か`deleted`されたら |
|page_build | ページサイトが`built`されたり失敗されたら |
| project_card | Project Cardが`created`、`edited`, `moved`, Issueに`converted`か`deleted`されたら|
| project_column | Project Columnが`created`, `edited`, `moved`か`deleted`されたら |
| project | Projectが`created`, `edited`, `closed`、`reopenend`, `deleted`されたら |
| public | リポジトリがPrivateからPublicに変わったら|
|pull_request_review_comment | Pull requestにreviewコメントがついたら |
| pull_request_review| Pull requestがreviewされたら |
|pull_request| Pull requestが`assigned`, `opened`などしたら(多すぎて省略します) |
| push | tagやコミットがpushされたら |
| repository_vulnerability_alert | vulnerability alertが通知されたら |
| release| リリースが作成されたら | 
|repository_dispatch | 他のユーザーがアプリのイベントをトリガーしたら |
| status| リポジトリステータスがAPIによって変更されたら |
|watch| ユーザーがリポジトリがStarされたら |

2019/07/25
@yui_tang さんに指摘され、`delete`の説明欄の間違いを修正しました！ありがとうございます！

非常にトリガーが豊富ですね。  

詳細はこちらをご覧ください。

https://help.github.com/en/articles/events-that-trigger-workflows#webhook-events


#### トリガーを組み立てる

次はトリガーをもらって、何をするかを定義します。

以下のようにトリガー枠の青い点を点線にドラッグしてつなぎます。

![hoge.gif](https://qiita-image-store.s3.amazonaws.com/0/153320/28a8f797-15b4-5557-0214-5d9d6c9003a8.gif)

ビルドインですでにいくつかActionがあります。
また、GCPを使う人は、かなり簡単にアクションを作ることができるとおもいます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/0aa950f5-910b-9348-dbcb-e30ce7bdbf7e.png)


適当に自前のRun Actionを定義します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/04813755-8ea9-b8f2-3b96-a10ba9a340af.png)

#### 環境変数を定義

また、環境変数を定義することができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/59bd42a3-30cc-7640-cfee-6c4fabd51a7f.png)

あとで解説しますが、再利用可能なActionsにすることができます。

#### Secretも定義

また、Secretも定義できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/1746ff4b-f65c-ea6e-87b8-c71ba3df3ee9.png)


Plain Textで保存するのはセキュリティ的にあれということがあればGoogle KMSなどを合わせて使うと安全でしょう。[参考リンク](http://www.1915keke.com/entry/2018/10/02/032806)


#### Workflowを保存する

あとで解説しますが`./.github/`以下にワークフローの設定ファイルが保存されます。

右上でコミットして保存します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/2b69cffa-7ebc-c576-46d9-8f68c5cfabda.png)

### ファイルで設定もできる

先ほどWorkflowを保存しましたが、同様に`./.github/hogehoge.workflow`と`.workflow`がつく名前で定義することができます。

これによって**宣言的にWorkflow**を定義することができます。

このような感じで保存されています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/12986637-228e-b95f-0b37-e6afb84b3b80.png)


そして、プレビューでVisual Modeでみることができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/6d378c41-6114-a554-9b79-f8aa268391fe.png)


実際は以下のようなファイルになっています。

```
workflow "New workflow" {
  on = "push"
  resolves = ["Hello World"]
}

action "Hello World" {
  uses = "./say_hello.sh"
  env = {
    MY_NAME = "KeisukeYamashita"
  }
  args = "\"Hello world, I'm $MY_NAME!\""
}
```

- `on`: トリガーのイベント
- `resolves`: Actionを解決する

### ログも見れる

Check APIのようにログをみることができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/fd6985b2-3f37-a58d-233a-6bb1534c55f5.png)

## YAMLの設定方法(追記: 2019/08/20)

正式にCI/CDがサポートされたのでYAMLの書き方を紹介します。

### 1. `.github/workflows`以下に設定を書く

workflowは１つに限らず、複数、書くことができます。

### 2. Workflowの設定を書く

まず、ルートレベルにWorkflowの設定を書き込みます。

```yaml
name: WORKFLOW_NAME
on: [push, pull_request]
```

単一のイベントだけならば以下のようにします。

```yaml
name: WORKFLOW_NAME
on: [push, pull_request]
```

そのイベントの中でも、どれかのファイルに絞りたいときは以下のように指定します。

```yaml
paths:       # Push events containing matching files
  - test/*
  - *.xml
```

この`on`はワークフローが実行される条件です。**Pull Request**限らず、書くことができるのがよいところです。またかきますが、以下のようなイベントでワークフローを書くことができます。

| 項目 |トリガー条件| 
|:----|:---|
|  check_run | Checkが走って`created`, `rerequested`, `requested_action`になったら|
| check_suite | Check runの集合で、ステータスが`completed`, `requested`, `rerequested`になったら |
| commit_comment| コミットコメントが`created`になったらトリガー| 
| create |ブランチやタグが作られたら | 
| delete | ブランチやタグが削除されたら |
| deployment| APIを通してデプロイメントが作られたら |
|deployment_status| デプロイメントステータスが更新されたら |
| fork | リポジトリがフォークされたら |
| gollum| Wikiページがアップデートされたら |
| issue_comment | Issueにコメントが`created`、`edited`か`deleted`されたら |
| issues | Issueが`assigned`, `unassigned`, `labeled`, `unlabeled`, `opened`, `edited`, `milestoned`, `demilestoned`, `closed`, `reopened`されたら |
| label | ラベルが`created`, `edited`, `deleted`したら |
| member | メンバーが招待、削除に追加されたり権限が変わったら |
| milestone | マイルストーンが`created`, `closed`, `opened`, edited`か`deleted`されたら |
|page_build | ページサイトが`built`されたり失敗されたら |
| project_card | Project Cardが`created`、`edited`, `moved`, Issueに`converted`か`deleted`されたら|
| project_column | Project Columnが`created`, `edited`, `moved`か`deleted`されたら |
| project | Projectが`created`, `edited`, `closed`、`reopenend`, `deleted`されたら |
| public | リポジトリがPrivateからPublicに変わったら|
|pull_request_review_comment | Pull requestにreviewコメントがついたら |
| pull_request_review| Pull requestがreviewされたら |
|pull_request| Pull requestが`assigned`, `opened`などしたら(多すぎて省略します) |
| push | tagやコミットがpushされたら |
| repository_vulnerability_alert | vulnerability alertが通知されたら |
| release| リリースが作成されたら | 
|repository_dispatch | 他のユーザーがアプリのイベントをトリガーしたら |
| status| リポジトリステータスがAPIによって変更されたら |
|watch| ユーザーがリポジトリがStarされたら |

### 3. Job: トリガーされたときの一連のタスクを定義する

`job.<job_id>` で指定をします。サンプルでは以下のようにあります。

```yaml
jobs:
  my_first_job:
    name: My first job
  my_second_job:
    name: My second job
```

#### 3.0 `uses`: コードを再利用

パブリックリポジトリのワークフローや、公式のジョブを使うことができます。

もっとも使うのは以下の `checkout`　ジョブでしょう。ワークフローの実行環境へコードをcheckoutしてくれます。

```yaml
uses: actions/checkout@master
```

一覧は[Github Actions repository](https://github.com/actions)で見ることができます。

#### 3.1 `runs-on`: マシンの設定

これらがどのマシンで動くかは、以下のように設定ができます。

* ubuntu-latest, ubuntu-18.04, または ubuntu-16.04
* windows-latest, windows-2019, または windows-2016
* macOS-latest または macOS-10.14

#### 3.2 コンテナの設定

以下のようにコンテナを使って実行することができます。

```yaml
jobs:
  my_job:
    container:
      image: node:10.16-jessie
      env:
        NODE_ENV: development
      ports:
      - 80
      volumes:
      - my_docker_volume:/volume_mount
      options: --cpus 1
````

`volume`のマウントをすることができます。

### 4. Secretの設定

SecretはリポジトリのSettings -> Secretから設定ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153320/215cc6c0-1af6-3ab3-189f-2ac1f38753cd.png)

設定をするには以下のようにします。

```yaml
env:
   GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS}}
```

### 5. CronJobを設定

実はGithub ActionsでもCronJobを設定することができます。

```yaml
on:
  schedule:
    # * is a special character in YAML so you have to quote this string
  - cron:  '0 * * * *'
```

このように`on`をCronTabのように設定をすることで使うことができます。

### 6. Eventの情報を取得する

環境変数`GITHUB_EVENT_PATH`で指定されている`/github/workflow/event.json`で指定できて、これがEventのPayloadになっています。

実際に、Payloadに使われるのは[REST API v3](https://developer.github.com/v3/activity/events/types/)で指定できるようなものです。

例えばPull RequestがきたときはPullRequestEventオブジェクトができます。使いたいイベントに合わせてオブジェクトを調べると、色んな事ができると思います。


## 気になる点
### Workflowの差分はどのように見れるのか?

試しにActionの名前を`Hello World`から`End World`に変更し、プルリクを投げてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/9ba52d39-2143-076a-5af3-fd8315d832d3.png)

しかも`resolve`(=トリガーとAction)を繋げ忘れたことをCheckしてくれました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/12a358ca-8508-4abd-2e5d-256749cf847b.png)


**差分自体はPlain Textでみることになりそうです**。


### Visual Editorで複雑なWorkflowは定義できるの

現時点ではできないようです。

新しいActionはPlain Textでしか作成できないみたいです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/153320/1234c486-837a-e16f-e61b-e4d46b9d4a91.png)

### Status Badgeみたいなのはあるの？

探している感じ、ありそうではないです。
しかし、MergeをしてGithub Workflowがはしっている状態だと、このように知ることはできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153320/740bdc34-8396-cb94-bce9-297378a1934e.png)

後に実装されるのではないかと期待をしています。そして、MasterでのWorkflowが無事、終了すると以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153320/0aee3fcc-f578-8322-2bd8-f686c531a304.png)

## まとめ

まだまだドキュメントも豊富ではありませんが、Githubにソースコードを置かないチームはなかなかないので、Githubだけで完結してくれると非常に嬉しいです。

特にCIは種類も豊富で、できることできないことを把握して技術選定するのが面倒なので、GithubActionsがデフォルトスタンダードになってくれるといいなと思います。

## 参考文献
### 公式ドキュメント

[GitHub Actions | GitHub Developer Guide](https://developer.github.com/actions/)

### YAMLの公式のDocument

[Workflow syntax for GitHub Actions](https://help.github.com/en/articles/workflow-syntax-for-github-actions)