GitHub Actions を触ってみた。

# GitHub Actions を触ってみた。

## 前置き
* GitHub Actionsとは
GitHubが提供しているCI／CDツール
JenkinsやCircleCIと同じ立ち位置。
[GitHub Enterprise ではまだベータ版](https://github.blog/2020-09-23-github-enterprise-server-2-22/) 
GitHubを使っているなら一番親和性は高い。

* 雑感
発展途上？コレが欲しかった、というのがちょこちょこある。
スニペットの豊富さがやばい。

## 基本的な使い方
workflow と呼ばれるyamlファイルにCI/CDの命令を記述していきます。
docker使ってれば大体わかるはず。
具体的には以下のディレクトリ構造でファイルを配置
`[repository]/.github/workflows/xxx.yml`  
  
すでに様々な言語や環境でのCI/CDのworkflowが準備されているので目的に似通ったモノがあればそれを使えばいい。
*Simple workflow* を選んで自分でゼロから作ることも出来る。
おおよその環境、言語は前述のworkflowで準備されているので、選びつつ微修正がベストだと思う。
  
GitHub のプロジェクトメニューのココを選ぶと
![スクリーンショット 2020-12-08 16.19.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316880/daf0c792-7b49-d836-a31d-769eb1345c75.png)
  
いろいろ出てくる。
![スクリーンショット 2020-12-08 16.25.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316880/40c41624-7cfd-7d8a-c0f4-b8bf8eb761e6.png)

## 実際に書いてみる  
  いわゆるLAMP環境のLaravelで作ったプロジェクトをテスト

```yaml
on: push

jobs:
  test:
    name: phpunit test
    runs-on: ubuntu-latest

    services:
      mysql:
        image: mysql:5.7
        ports:
          - 3306:3306
        options: --health-cmd "mysqladmin ping -h localhost" --health-interval 20s --health-timeout 10s --health-retries 10
        env:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: laravel

    env:
      DB_CONNECTION: mysql
      DB_HOST: 127.0.0.1
      DB_PORT: 3306
      DB_DATABASE: laravel
      DB_USERNAME: secret
      DB_PASSWORD: secret

    steps:
      - uses: actions/checkout@v2
      - name: copy .env
        run: cp .env.ci .env
      - name: cache vendor
        id: cache
        uses: actions/cache@v1
        with:
          path: ./vendor
          key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
          restore-keys: |
            ${{ runner.os }}-composer-
      - name: composer install
        if: steps.cache.outputs.cache-hit != 'true'
        run: composer install -n --prefer-dist
      - name: composer dump autoload
        run: composer dump-autoload
      - name: directory permissions
        run: chmod -R 2777 storage bootstrap/cache
      - name: generate key
        run: php artisan key:generate
      - name: migrate
        run: php artisan migrate
      - name: unit test
        run: php artisan test
```
#### かいつまんで説明  

- - - 
```yaml
on
```
workflow の実行されるタイミングの定義  
今回はpushの場合全てだが以下のように細かく指定することも可能

```yaml
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]
```
- - - 
```yaml
jobs
```
ここが実行されるジョブ本体
今回はubuntu仮想環境を作ってそこで走らせる方法を取っているが他にもありそう。
やってることは下記

1. ubuntu-latestの仮想環境を指定
2. mysqlを構築しつつ、envファイルに環境を定義
3. リポジトリをcheckout
4. Laravel環境の構築
    1. .envファイルをCI環境用からコピー
    2. vendor配下をキャッシュ（毎度作るのは時間がかかるので）
    3. composer install (キャッシュがない時のみ実行)
    4. composer dumpautoload の実行
    5. Laravel固有のキャッシュディレクトリのパーミッション設定
    6. Laravelお約束のkey generate
    7. migration でDB構築
5. artisanコマンドでテストを実行

## 動かしてみる
push時に動くはずだけどGitHubのプロジェクトメニューからActionを選ぶと作成した
workflow を選んで実行させてみることが可能です。

表示されている各タイトル名はyamlで指定したname となる
各工程をパスしたかどうかが視認できる。
![スクリーンショット 2020-12-08 18.21.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316880/11039f0d-21f1-e9a6-291c-4112e8436073.png)


動作がおかしい場合もログがしっかり出るので視認しやすい。
![スクリーンショット 2020-12-08 18.32.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316880/5862b59e-a832-0b24-1ce1-2bd307464edf.png)


ここでちょこちょこと動作を確認して終了です。

## 触ってみた感想
すごい簡単。
予め準備されてるスニペットのパターンが優秀すぎる。
とはいえ今回はデプロイまでは作れてないので、今後の展望としてデプロイまで入れたい。
デプロイは以下がプラスで必要となる。

- SSHの秘密鍵の管理
GitHubのプロジェクトページのSettings - Secrets - Add a new secret
ここで秘密鍵とKNOWN_HOSTS を管理

- workflowでrsync
これに関してはすでにありそう
https://github.com/marketplace?type=actions&query=rsync

## 最後に
ここまでの内容は主にAWS EC2 の環境を想定して作ってたのですが
GitHubActions のworkflowで使える仮想環境とは実際に環境が違ったりしてしまうので
環境に依存するテストとかはクリアにならない。

GitHubActions の拡張を待つよりも
AWSならECS、ECRを使った方が環境を合わせるのが楽だろうと思う。
AWS CodePipelineからの移行なんかも準備してあるみたいだし。

さらに言うと、GCPとか使った方がCI/CDはもっと楽そうな気配もあるので
いろいろな環境でさらに試してみようと思います。