GitHub Actionsを使ってみた

## はじめに
タイトルは本当は「GitHub ActionsでGoogleTestを使ったテストモジュールを実行させ、それが失敗した場合該当ブランチのmasterへのマージをプロテクトする」だったのですが長すぎたのでコンパクトにしました。ようやく環境がCIっぽくなってきたなと思います。人はミスをする生き物なので、CIのように機械的にミスを検出する仕組みはいいものだと考えています。

## やったこと
* GitHub Actionsの限定パブリックベータへの参加をリクエストした
* デフォルトワークフローが動作していることを確認した
* GitHub ActionsでCMakeによるコードのビルドを行った
* GitHub ActionsでGoogleTestモジュールを実行した
* GitHubのSettingで失敗ブランチのmasterへのマージをプロテクトした
* 紆余曲折

### パブリックベータへの参加
1. [Sign up for the Beta](https://github.com/features/actions)
2. Actionsタブが作られていることを確認
<img width="318" alt="スクリーンショット 2019-09-22 10.35.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37831/325c6ec3-f4c6-2fc0-dc16-61cb13cb78a8.png">

### デフォルトワークフロー
1. Set up ActionsからSimple workflowを作成
<img width="337" alt="スクリーンショット 2019-09-22 10.36.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37831/cdda13e6-3346-948e-dada-6ae4c647a9fc.png">

2. blank.ymlというものが作られる
<img width="458" alt="スクリーンショット 2019-09-22 10.36.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37831/157a2d6a-1275-7e6b-9bdf-246f0ac189ab.png">

3. pushして動作を確認
<img width="438" alt="スクリーンショット 2019-09-22 10.38.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37831/955245d8-3257-6725-71d3-f619611acdc4.png">
Actionsタブから該当push単位でワークフローの実行ログを確認することができる。

### CMakeによるコードのビルド
1. blank.ymlの編集テスト

```blank.yml
name: CI

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v1
    - name: label change test1
      run: | 
        pwd
        ls
    - name: label change test2
      run: |
        echo Add other actions to build,
        echo test, and deploy your project.
```
実行結果
<img width="393" alt="スクリーンショット 2019-09-22 10.50.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37831/e18585d5-cec0-3f02-9a28-f79c5ed0e684.png">

3. CMakeを使ってビルド

```blank.yml
（略）
    - name: build
      run: |
        cd C++/helloworld/
        mkdir build/
        cd build/
        cmake ..
        make
（略）
```

実行結果
<img width="540" alt="スクリーンショット 2019-09-22 11.52.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37831/f9198b4d-c698-5ce7-7674-acaec2e48998.png">
特に問題なくビルドできていそう

### GoogleTestモジュールの実行
```blank.yml
（略）
    - name: build
      run: |
        cd C++/helloworld/
        ./build.sh
    - name: test
      run: |
         C++/helloworld/build/test_calc
```

```build.sh
#!/bin/bash

set -eu

pushd third_party/
GOOGLETEST_VERSION=release-1.8.1
wget --quiet https://github.com/google/googletest/archive/${GOOGLETEST_VERSION}.tar.gz
tar -xf ${GOOGLETEST_VERSION}.tar.gz
rm ${GOOGLETEST_VERSION}.tar.gz
mkdir googletest-${GOOGLETEST_VERSION}/build/
cd googletest-${GOOGLETEST_VERSION}/build/
cmake ..
make
#make install
popd

rm -rf build/
mkdir build/
cd build/
cmake ..
make
```

```CMakeLists.txt
add_executable(test_calc
  test/test_main.cpp
  test/test_calc.cpp
  src/calc.cpp)
target_link_libraries(test_calc
  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest-release-1.8.1/build/googlemock/gtest/libgtest.a
  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest-release-1.8.1/build/googlemock/gtest/libgtest_main.a
  pthread)
target_include_directories(test_calc PUBLIC
  include
  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest-release-1.8.1/googletest/include)
```
紆余曲折あってGoogleTestをsubmoduleではなくwgetで取ってきてます。また、googletestの`make install`でGitHub Actions環境内でパーミッションエラーが出たため、ビルドパスをリンクパスにしています。

<img width="772" alt="スクリーンショット 2019-09-22 12.04.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37831/2d466511-608c-eac7-3acf-485401b4aa84.png">
感動の瞬間

### 失敗ブランチのmasterへのマージをプロテクト
1. GitHubリポジトリののSettings-Branchesからプロテクト設定を行う
<img width="744" alt="protect_branch.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37831/06664849-3ca7-d6dd-414d-8bf77aee2115.png">
Include administratorsしておかないと、本人が管理者のためプロテクトの確認を行えませんでした。

2. 失敗するテストを作成し実行、プロテクトを確認

```test_calc.cpp
#include <gtest/gtest.h>

#include "calc.h"

class TestCalc : public ::testing::Test {
};

TEST_F(TestCalc, add) {
    EXPECT_EQ(3,  add(1, 2));
    EXPECT_EQ(-2, add(1, -3));
    // NG
    EXPECT_EQ(0, add(1, 1));
}
```

<img width="670" alt="スクリーンショット 2019-09-22 12.09.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37831/6092e2a4-a81b-21af-7162-33cd9a429923.png">
実行ログから失敗を確認することができる。

<img width="777" alt="checkfailed.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37831/ca3b8e88-c427-d167-a723-1debb8fd590c.png">
プロテクトの確認。マージボタンが押せなくなっていることを確認できる。

### 紆余曲折
1. GitHub Actionsでgit submoduleが使えなかった
これ[Add submodule support](https://github.com/actions/zeit-now/issues/8)が行われれば使えるのかしら。
2. GitHub Actionsでdocker buildするとcacheが効かないので遅い
ローカルと同一環境でビルドしてほしい思いでGitHub Actionsでも独自のDockerfileによるDockerビルドを試み成功させましたが、毎回apt installしていることに気がつく。pushのたびにこれだと遅すぎて使えない・・。

## 所感
コードやスクショ込みの記事書く予定で材料集めつつ作業を進めていましたが足りないもの多数。記事を書きながら集めるという効率の悪いことをしました。記事も縦に長くなって可読性下がるし、概要だけのほうがいいのかしら・・。