nektos/act GHAローカル実行

久々にactを使うので過去に作成した自分用メモを現代向けに修正しつつまとめました。

## 導入
Homebrewなどでインストール
```bash
% brew install act

% act --version
act version 0.2.76
```

## 実行
- `.github/workflows`があるリポジトリで実行
- MシリーズMacの場合`--container-architecture linux/amd64`をつけないとワーニングになる 
```bash

# Jobリスト取得
% act -l
Stage  Job ID  Job name  Workflow name  Workflow file  Events
0      test    test      Run test-all   test-all.yaml  push

# Job実行
% act

# Jobを指定して実行
% act -j job1

# -P <platform>=<docker-image>で代替のイメージを指定
% act -P self-hosted=catthehacker/ubuntu:act-latest
```

## 色々な設定
- 環境変数
    - .envファイルに設定することで取り込まれる
- シークレット
    - トークンが必要なワークフロー(OIDCなど)を利用する場合、アクセストークンを設定する必要がある
    - `-s GITHUB_TOKEN=(アクセストークン)`フラグで指定
- 実行時にデフォルトで指定したいフラグ
    - .actrcに記述

### 設定例
.actrc:
```
-P self-hosted=node:16-buster-slim
--env-file .act.env
--secret-file .act.secrets
--container-architecture linux/amd64
```
※ `--env-file`・`--secret-file`で利用するenvとsecretを設定できる

.act.env:
```
MYSQL_PASSWORD=password
```

.act.secrets:
```
# tokenを入れたりする
GITHUB_TOKEN="$(gh auth token)"
```

## 制限
ランナーイメージ

actではホストランナーとして利用できるイメージは[限られている。](https://github.com/nektos/act/blob/master/IMAGES.md)
コンテナでジョブを実行することで本番ランナーとの環境差異は減らせるが、動作しないアプリケーションもある。

## サービスコンテナ
actは[サービスコンテナ](https://docs.github.com/ja/actions/use-cases-and-examples/using-containerized-services/about-service-containers)の利用が出来ない。
DB環境などを使いたい場合はdocker内で実行するなどの工夫が必要。

```
  docker:
    runs-on: [ self-hosted ]
    steps:
      - name: checkout
        uses: actions/checkout@v3
      - name: docker run
        run: |
          docker run --name mysql-server -e MYSQL_ROOT_PASSWORD=${MYSQL_PASSWORD} -d mysql:5.6
          docker run --name python --link mysql -d python:3.6
```

## その他の情報
### トリガーとなるイベント
GHAのワークフロー内では、`github.event` コンテキストを使用して、トリガーイベントに関連する情報へアクセスすることができる。

参考：https://docs.github.com/ja/rest/using-the-rest-api/github-event-types?apiVersion=2022-11-28

例：
- github.event.before: プッシュ前のコミットSHA
- github.event.size: プッシュ内のコミット数

ワークフロー内で`github.event.*`などのイベント固有の情報を利用している場合は、actではトリガーとするイベントデータのシミュレーションが行える。

```json
  {
     "before": "abc123",
     "after": "def456"
   }
```

```
# ちなみにトリガー未指定の場合はPUSHトリガーが実行される
act -e event.json
```


## 【おまけ】GitHub Actions用語・機能についてざっくりまとめ
- ワークフロー
    - GitHub Actionsの自動化プロセス
    - ​​リポジトリ内の .github/workflows配下のYAMLで定義
    - 複数定義・別のワークフローで再利用可能
- イベント
    - ワークフロー実行のトリガー
    - PUSH、PR、forkなど
    - on:で定義
- ジョブ
    - 1つのランナーで実行される複数のステップのまとまり
    - jobs.<job_id>:で定義
    - 指定しない限り複数のJobは並列実行される
- ランナー
    - ジョブが実行されるサーバー
    - jobs.<job_id>.runs-on:で定義
    - ランナーに付与したラベルで条件を指定する
    - 利用できるランナーの中から条件に完全に一致するものが選ばれる
    - 種類
        - GitHubが提供するサーバー
            - Ubuntu Linux・Microsoft Windows・macOSが用意されていて利用できる
        - セルフホステッドランナー
            - 自分で用意したマシン
- セルフホステッドランナー
    - 自分で用意したマシンをランナーとして利用できる。GitHub提供サーバーよりも細かい調整が行える
    - セルフホストランナーアプリケーションをインストールする
    - 要件に合えば色々なマシンを利用できる
    - 管理レベル
        - リポジトリ・Organization・Enterprise単位で管理する
- ステップ
    - ジョブで実行されるタスク
    - jobs.<job_id>.steps:配下に定義
    - アクション、コマンド実行などを実行する
    - ステップ毎に1つのシェルで実行される
        - なのでシェル変数などは共有されない
    - 後続のステップに値を渡す場合は環境変数の定義などが必要
- アクション
    - ステップで実行する再利用可能なコード単位
    - 事前定義されたアクション、サードパーティ製アクション、パブリックdockerイメージで定義されたアクション、独自のアクションなどを利用できる
    - jobs.<job_id>.steps[*].uses:でアクションを指定する
- コンテナ
    - jobs.<job_id>.container:で実行するコンテナイメージを指定
    - 指定しない限りランナーのホストで直接実行される
- サービスコンテナ
    - データベースなどのサービスをホストするコンテナ
    - jobs.<job_id>.services:で指定