GitHub Actionsをはじめてみよう！

## はじめに
GitHub Actionsはソフトウェア開発において、ビルド、デプロイ等の定型作業を自動化を簡単にできるツールです。GitHubAcrtionsのワークフローを作成しておくことにより、デプロイ等の定型作業を気楽に行えるようになるメリットがあります。
最初はとっつきづらいかもしれませんが、慣れれば簡単かと思うのでぜひマスターしていきましょう。

## どのようなツールか
ざっくりいうと、GitHub側でサーバーを用意してくれて、その環境に対象のリポジトリのコードを用意し、好きなコマンドを実行できるツールです。
これをつかって、テスト、ビルド、デプロイ等の作業を自動化することができます。


## 何が嬉しいのか
GitHubActionsを使うことにより以下の３つの恩恵があるかと思います。
#### 環境差分の解消
一般的な開発現場では、複数の作業者がいることが多いかと思います。コードのビルド、デプロイ等の作業を実施する際に、作業環境によって結果に違いが発生することがありますが、GitHubActionsの実行環境でこれらの作業を行うことにより、環境差分をなくすことができます。

#### 作業手順の簡略化
テスト、ビルド、デプロイの作業は複数のコマンドを決まった手順で実行しなければならないことがありますが、それらのコマンドをワークフローに記載しておくことにより、自動的に実行することができるので、作業者の負担を減らすことができます。

#### 実行漏れを防ぐ
テストの実行等の作業は、テストコードを実装しているプロジェクトでは、コードをプッシュする前に毎回実行するべきですが、ワークフローの実行をプルリクエスト等に紐づけておくことにより毎回必ず実施されことを確認することができます。

## 最初のワークフローを作成してみよう
前置きはこれくらいにして早速作成してみたいと思います。
今回作成するワークフローは下記のようなものにします。

1. GitHub上でプルリクエストを出す
2. テストコードをGitHubActionsで自動的に実行し、マージ前に結果を確認することができる

#### 実装手順 
まずはじめに今回実装したリポジトリを貼っておきます。

https://github.com/mametaro2024/actions_test

1 . リポジトリのルートディレクトリに下記のディレクトリを作成します。
```
.github/workflows
```
2 . 上記ディレクトリ内にworkflowを記載するyamlファイルを作成します。(名称は任意でOK)
```yml:.github/workflows/test.yml

# workflowの名称を定義
name: test

# workflowを起動するトリガーを定義 
on:
  pull_request:

# 実処理を書いていく部分
jobs:
  hello-world:
    # 実行環境を定義
    runs-on: ubuntu-latest
    steps:
      # 実行環境に対象リポジトリのコードをチェックアウト
      - name: Check out code
        uses: actions/checkout@v4

      # goの実行環境を設定
      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.23.x'
      
      # テストコマンドの実行
      - name: test
        run : go test ./...

```

GitHub Actionsで必要な実装はこれだけです。
    細かい点は公式を確認頂くのが良いかと思いますが、解説が必要そうな項目だけ簡単に記載してみます。
- on
workflowが実行されるトリガーとなるイベントを定義します。
今回はpull_requestを使っているのでプルリクエストが発生するとワークフローが実行されます。
もし、手動で実行したい場合は`workflow_dispatch`を使うと手動実行できるようになります。

https://docs.github.com/ja/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows

- runs-on
ワークフローの実行環境を定義します。今回はlinux環境前提でしたので、`ubuntu-latest`
を指定しています。指定可能な値は下記が参考になります。

https://docs.github.com/ja/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners


- uses
他の人が作ったワークフローを再利用することができます。
例えば、`actions/checkout@v4`は対象のリポジトリをGitHubActionsの実行環境にチェックアウトするワークフローです。
これらはGitHubのMarketPlaceで公開されているものが多くあるのでそれらを使うことにより効率的に開発をすることができます。

https://github.com/marketplace?type=actions

その他細かい記載方法等については公式のドキュメントが参考になるかと思います。

https://docs.github.com/ja/actions/writing-workflows/workflow-syntax-for-github-actions

#### テスト対象
またテスト対象となるコードも記載しておきます。
内容としては、httpアクセスに対してhello worldを表示するだけのハンドラーと、それに対するテストコードになります。
- ハンドラー
```golang:hello_handler.go
package main

import (
	"fmt"
	"net/http"
)

type HelloHandler struct{}

func (h *HelloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello world!")
}

```
- テスト
```golang:hello_handler_test.go
package main

import (
	"net/http/httptest"
	"testing"
)

func TestHelloHandler(t *testing.T) {

	req := httptest.NewRequest("GET", "/", nil)
	rec := httptest.NewRecorder()

	handler := HelloHandler{}

	handler.ServeHTTP(rec, req)

	expected := "Hello world!"
	result := rec.Body.String()

	if result != expected {
		t.Errorf("expected result is %v but actually %v", expected, result)
	}

}
```
## 実際にGitHub上で実行してみる
今回はプルリクエストを出すことを契機にワークフローが実行されるシナリオなので、GitHub上でプルリクエストを出してみます。
#### 失敗の場合
上記の`hello_handler.go`の「Hello world!」の部分を「Hello, world!」に変更してわざとテストが失敗する状態でプルリクエストを出します。
![スクリーンショット 2024-12-07 23.57.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499266/c459d5e1-8a1d-718d-8e35-cbfd32529b56.png)
上記のようにプルリクエストの確認画面でマージする前にワークフローが失敗していることを確認できできます。また、Detailsを開くと下記が開きます。

![スクリーンショット 2024-12-07 23.57.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499266/4b263b4e-f604-4b9b-ec08-6ea62f22d989.png)
実際にGitHub Actions側で用意してくれた環境上でコマンドが実行されている様子を確認できます。


#### 成功の場合
上記の変更を元に戻して再びプルリクエストを出します。
![スクリーンショット 2024-12-07 23.55.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499266/d253a439-4592-aefa-eee3-52a0cefac89a.png)
成功の場合はこのように緑色でワークフローが正常に終了していることがわかります。またDetailsは下記です。

![スクリーンショット 2024-12-07 23.56.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499266/c25a7552-fc2d-d6de-ff8a-35a673cb3b2a.png)
こちらも実際にコマンドを実行し、テストが成功していることがわかります。

## まとめ
今回GitHub Actionsで簡単なワークフローを実装してみましたが、一度実装すれば、他の作業者にも恩恵がある内容かと思います。
今回はテストの実行という簡単なコマンドだけでしたが、もっと複雑なワークフローを実装することもできるので、興味を持った方は是非実装してみてください！