GithubActionsを試してみる

8/8にβ版が一般公開されたので、情報整理のためにまとめてみました。

## 料金

現在公開されている**β版は無料**で使えます。
パブリックリポジトリは**無料**、プライベートリポジトリは以下の通りみたいです

<img width="800" alt="0626f4b787a219489921bc4eee69a418.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341731/c7b73908-88fe-0fe0-1847-c81aaa866a66.png">

セルフホストってなんでしょう…。環境一つもらえるってことなんですかね？


## 利用制限
無料で下記が使えます。

- リポジトリごとに20のワークフローが使える
- Github APIを1時間に1000回実行することができる
- ワークフロー内のジョブは最大6時間まで動かせる
- リポジトリごとに20のジョブを同時に実行することができる

CircleCIではジョブの同時実行が1つ（オープンソースプロジェクトは4）なので
とても太っ腹と思います。

## 利用方法

β版では利用登録をする必要があります。
[Github Actions](https://github.com/features/actions)

筆者は8月中旬に申請して9月に使えるようになりました（白目）
使えるようになると、メールが来て、GithubのリポジトリにActionsが増えているはず…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341731/699db74e-0176-4e4b-c8b6-4a3efa9be7ca.png)


## 利用できる仮想環境

CI上で利用できる環境は、Windows, MacOS, Linux全ての環境を1台無料で使用することができます。
Circle CIはMacOSとWindows環境は無料枠では制限があるので嬉しいですね。
（今後どうなるかはわかりませんが）

というのも、**マトリックスビルド**という複数の環境 × 複数のアプリでのビルドを売りにしているみたいです。


## 定義ファイルの書き方
**YAML**で記述し、Github Actionsを使うリポジトリの`.github/workflows`に配置します。

#### name
ワークフローに名前をつけることができます。

```yaml
name: TEST_WORKFLOW_NAME
```

#### on

**必須項目**

Githubのイベントをトリガーします。
例えば`push`したとき、`pull-request`を作成したとき、ですね。
詳細は以下にイベント一覧が載っています。
[Events that trigger workflows | Github Help](https://help.github.com/en/articles/events-that-trigger-workflows)

```yaml
# pushしたとき
on: [push]


### 複数指定も可能
on: [push, pull_request]

### ファイルやブランチ、タグの指定もできます
on: push
  branches:    # ブランチの指定（例ではmasterだけ）
  - master
  tags:        # タグ指定
  - v1.0.1
  paths:       # ファイル指定。正規表現も使える
  - 'src/*'
  - '*.java'

### ワークフローにはスケジューリングもできる
on: push
  schedule:
  - cron:  '*/15 * * * *' # *を含む場合にはシングルクォートで囲む
```

#### jobs

**必須項目**
`job.<job.id>`で各ジョブを指定します。

```yaml
jobs:
  api_test:
    name: API Test Job         # 名前もつけられます。
  ui_test:
    name: UI Test Job
  ui_build:
    name: UI Build Job
    needs: ui_test              # 起動するために必要なジョブを指定
  deploy:
    name: Deploy Step
    needs: [api_test, ui_build] # 複数指定可
```

```UML
## こんなワークフローになります。
api_test --->-------------> deploy
ui_test ----> ui_build ---┘
```

##### jobs.\<job_id\>.runs-on

**必須項目**
ジョブがどの仮想環境で動くかを指定できます。

```yaml
jobs:
  api_test:
    name: API Test Step 
  runs-on: ubuntu-latest
```

[Virtual environments for GitHub Actions | Guthub Helps](https://help.github.com/en/articles/virtual-environments-for-github-actions#about-virtual-environments)

##### jobs.\<job_id\>.container
コンテナが指定できます。

```yaml
jobs:
  ui_test:
    name: UI Test Step
    container:
      image: node:latest
      volumes:
      - node_volume:/node_volume  # volumeマウントができる       
```

##### jobs.\<job_id\>.steps
タスクのステップを指定します。
name句, run句を指定して実際の処理を書いていきます。

```yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - name: Print Hello-World  # ステップの名前を指定する
      env:                     # 環境変数を指定できます
        PRINT: Hello-World
      run: |
        echo $PRINT
```

また**uses**を使うと、Github Actionsで定義されたステップを使うことができます。
例えば、`actions/checkout`はGithubリポジトリのチェックアウトができます。
(Circle CIのorbのようなイメージ)

```yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@master
```

使えるusesは以下から見ることができます。
[GitHub Actions (リポジトリ)](https://github.com/actions)


しかし、useで使えるactionsはJSかDockerコンテナで作られているため、仮想環境はLinuxを使う必要があります。
[jobs.\<job_id\>.steps.uses](https://help.github.com/en/articles/workflow-syntax-for-github-actions#jobsjob_idstepsuses)

##### jobs.\<job_id\>.services

ジョブの中で使えるコンテナを追加できます。
例えばテストで接続するDB環境やプロキシサーバのコンテナを立てられます。

下記例では、nginxとMySQLを立ててます

```yaml
jobs:
  api_test:
    name: API Test Step 
  services:
    nginx:
      image: nginx
      ports:
      - 8080:80
      env:
        NGINX_PORT: 80
    test_db:
      image: mysql
      ports:
      - 3306:3306
      volumes: data:/db_volume
      env:
        MYSQL_DATABASE: test_app
        MYSQL_USER: hogehoge
```

# 試しに実行

```yaml:build.yml
name: GithubActoinsTest
on: [push]

jobs:
  first_job:
    name: Initial Job
    runs-on: ubuntu-latest
    steps:
      - name: Github First Step
        uses: actions/checkout@master
      - run: echo All Done!
      - run: echo Test Artifact > test.txt
      - uses: actions/upload-artifact@master
        with:
          name: my-artifact
          path: test.txt
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341731/9275a0e9-f836-c567-0821-c5901351e8ac.png)

### Artifact
Actionsの[upload-artifact](https://github.com/actions/upload-artifact)を使うと、アップロードも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341731/07f2aa25-d4bd-d6af-ac06-1a453528ed05.png)



# 気になること

- ワークフロー間のデータ受け渡し
    - Actionsの[upload-artifact](https://github.com/actions/upload-artifact), [download-artifact](https://github.com/actions/download-artifact)を組み合わせることになりそう？
- データのキャッシュ
- 構文チェック

# 終わりに

Circle CI一強だったCIもGithubでできるようになるのは、他のサービスを跨がなくてもいいのはいいことですね。
ドキュメントがまだまだ少ないので、これから増えるといいなと思います。
11/13には一般公開なので、それまでに期待しましょう。


# 参考
[Workflow syntax for GitHub Actions | Github Help](https://help.github.com/en/articles/workflow-syntax-for-github-actions)