CI/CDよく使うGHAのプラグインの紹介

CI/CDでリリース作業を自動化するのに、GitHub Actions（GHA）を使用しています。日々の業務でGHAに触れないことはないと言っても過言ではないくらいです。私が重宝しているプラグインの使用方法を具体的に紹介をします。

**読者ターゲット**

- GHAの経験が業務で2週間程度の人
- GHAの経験は2週間以上あるが、下記で紹介するプラグインを使用してこなかった人

※　基準値に2週間を使用しているのは、あくまで参考程度であり、私自身が業務で2週間ほど使用して構文の理解が深まった、yamlの書き方に慣れてきたと感じたためです。

# actions/checkout

## 何ができるプラグインか

このプラグインでは、`$GITHUB_WORKSPACE`においてリポジトリにチェックアウトすることでworkflowからアクセスできるようにします。

## 使用ケース

私がプロジェクトで使用しているケースは、workflowで特定のリポジトリにアクセスしなければならないケースです。
- 特定のリポジトリのソースコードが必要 (read/GET)
- 特定のリポジトリでwrite/PUT作業が必要

ℹ️ `actions/checkout`でチェックアウトできるリポジトリは複数可能で、`jobs`の中で何度も異なるリポジトリにチェックアウトすることができます。

## よく使用するOption

- `repository: <str>`: チェックアウトしたいリポジトリ名
- `ref: <str>`: チェックアウトしたいリポジトリのブランチやタグ名
- `token: <str>` : Token
- `path: <str>`: チェックアウトしたいリポジトリ名（複数リポジトリにチェックアウトする場合便利）
- `fetch-depth: <int>`: fetchするcommit数（defaultは1。0は全てのブランチとタグのhistoryをfetch）
- `submodules: <boolean>`: submoduleがあるリポジトリではrecursiveでクローンする 

optionには、環境変数を渡して使用しています。

## workflow 記載例

```yml
- name: checkout repo
  uses: actions/checkout@v4
  with:
    repository: ${{env.MY_ORG}}/${{env.MY_REPO}}
    ref: ${{env.BRANCH}}
    token: ${{secrets.GITHUB_TOKEN}}
    path: ${{env.MY_REPO}}
    fetch-depth: 0
    submodules: true
```
GHAはデフォルトでRunnerのwork spaceのルートにいます。
上記のように設定しても、workflowが自動的にチェックアウトしたリポジトリに移動するわけではないです。
この場合、`working-directory`という構文を使用することでチェックアウトしたリポジトリのソースコードを使用することができます。

`jobs`ごと、`steps`ごとに`working-directory`を指定することができます。
```yml
# stepsで設定
- name: run CI
  working-directory: ${{env.MY_REPO}}
  run: |
    echo "working directory is ${{env.MY_REPO}}"
    pwd
```

```yml
# jobsで設定
jobs: CI
  runs-on: ubuntu-latest
  defaults:
    run:
      shell: bash
      working-directory: ${{env.MY_REPO}}
```

参考リンク: 
- https://github.com/actions/checkout
- [GitHub公式ドキュメント | working-directory](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#defaultsrunworking-directory)

# actions/upload-artifact
## 何ができるプラグインか
GitHub ActionsのArtifactsに成果物としてZipを格納することができます。

## 使用ケース

自動でデータを取得して、成果物として出力させたいと思った時は、このプラグインが重宝します。
私のプロジェクトでは、APIを使用してさまざまな数値のデータを取得し、csvファイルに集計してArtifactsへアップロードさせているケースが多いです。

## よく使用するOption
- `name: <str>`: デフォルトでは`artifact`というzipファイル名になります
- `path: <str>`: オプションではなく必須項目です。何をアップロードすべきかをプラグインに指示するため、ファイルパスを記載します

この他にも保持期間や圧縮レベル、ファイルが存在しない場合の処置を設定できるオプションがありますが、私のプロジェクトでは上記2点で済んでいます。

## workflow 記載例

```yml
steps:
  - name: generate report
    run: |
      mkdir -p /tmp/report
      echo hello-world > /tmp/report/hello-world.txt
  - name: upload artifact
    uses: actions/upload-artifact@v4
    with:
      name: report-txt
      path: /tmp/report/hello-world.txt
```

パターンがあれば、ワイルドカードを使用することも可能です。また、環境変数を使用することもできます。
```yml
steps:
  - name: upload artifact
    uses: actions/upload-artifact@v4
    with:
      name: report-${{env.MYREPO}}
      path: |
        /tmp/report/hello*.txt
        ${{ github.workspace }}/test/*
```

この他にも特定のファイルを含めない書き方など、様々な記載方法が公式のREADMEに掲載されています。

ℹ️ 気をつけなければいけないのは、`actions/upload-artifact`では`working-directory`が無効になることです。`jobs`レベルで使用していたとしてもです。
私は、いつも絶対パスで記載するようにしています。
上記の例のように`${{ github.workspace }}`やGITHUB_ENVの環境変数などをうまく使用すると読みやすさアップ＆エラー軽減になると思います。

参考リンク:
- https://github.com/actions/upload-artifact

# tibdex/github-app-token
## 何ができるプラグインか

GitHub Appsを使用する際、Workflowの中でTokenを作成する必要があります。このプラグインはそれをするためのものです。

## 使用ケース

「何ができるプラグインか」と重複しますが、プロジェクトで自前のGitHub Appsを作成し、GHAでTokenを作成するのにこのプラグインを使っています。
このプラグインで生成したTokenをactions/checkoutと併用したり、stepsで使用することが可能です。

## よく使用するOption

私のプロジェクトでは、必須の項目しか使用していません。

- `app_id: <str>`: GitHub Appsを登録したらApp IDが参照できるので、secretに格納しておきます。環境変数を使用してApp IDを参照できるようにします
- `private_key: <str>`: GitHub Appsを登録する際にPrivate Keyを生成し、secretに格納しておきます。環境変数を使用してApp IDを参照できるようにします

ハードコードで使用することも可能ですが、リポジトリの開示レベル（Private/Public）に関わらず、リポジトリレベルまたはOrganizationレベルのsecretsに登録し、環境変数として使用することを強く勧めます。Token関連はsecretsに。これは、Best Practiceです👮🏻‍♀️

この他のoptionに、権限付与やリポジトリの指定をすることも可能です。詳しくは、READMEを参照してください。

ℹ️ 私のプロジェクトでは、GitHub AppsはOrganizationレベルで設定していて、Appsがアクセスできるリポジトリやリポジトリレベルの権限もその時に設定しているので、optionで設定する必要がないです。

参考リンク:
- https://github.com/tibdex/github-app-token
- [GitHub公式ドキュメント（Archived）](https://web.archive.org/web/20230115194214/https://docs.github.com/en/issues/planning-and-tracking-with-projects/automating-your-project/automating-projects-using-actions#example-workflow-authenticating-with-a-github-app)

## workflow記載例

```yml
- name: generate token
  id: generate_token
  uses: tibdex/github-app-token@v2
    app_id: ${{ secrets.APP_ID }} 
    private_key: ${{ secrets.PRIVATE_KEY }}

- name: generate report
  run: |
    ./generate-report.sh
  env:
    ACCESS_TOKEN: ${{steps.generate_token.outputs.token}}
```
このプラグインを使用して生成したTokenをstepsで使用する例です。
この他の記載例や使用ケースは上述したGitHub公式ドキュメント（Archived）でも紹介されています。

### 補足

**なぜArchivedのリンクを貼り付けているのか？**

`tibdex/github-app-token`は数年前からお世話になっているのですが、去年（2023年）の6月に公式公認の[`actions/create-github-token`](https://github.com/actions/create-github-app-token)がリリースされました。
最新のドキュメントではこの公式公認のプラグインにドキュメントが書き換えられているため、Archivedのドキュメントのリンクを貼っています。

**将来的に公式公認のプラグインに置き換えなければならないか**

私のチームでも、どうするか話し合いました。
公式公認のプラグインが出たことでユーザーがそちらに流れていく、そして徐々にメンテナンスもされなくなっていく可能性は高いです。
今すぐにということはないですが、来年（2025年）`tibdex/github-app-token`がどのくらいの頻度で更新されているか、最後のリリースはいつかなど確認して決めようということになりました。

ちなみに、公式公認の`actions/create-github-token`に切り替える場合は、これまで`secrets`に登録していたApp IDを`variable`に登録する必要があります。
環境変数をそのまま使用できないので、ご注意ください。

```yml
- name: generate token
  id: generate_token
  uses: actions/create-github-app-token@v1
    app_id: ${{ vars.APP_ID }} # <----- ここが変わる
    private_key: ${{ secrets.PRIVATE_KEY }}
- name: generate report
  run: |
    ./generate-report.sh
  env:
    ACCESS_TOKEN: ${{steps.generate_token.outputs.token}}
```

# 参考

- [actions/checkout](https://github.com/actions/checkout)
- [GitHub公式ドキュメント | working-directory](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#defaultsrunworking-directory)
- [actions/upload-artifact](https://github.com/actions/upload-artifact)
- [tibdex/github-app-token](https://github.com/tibdex/github-app-token)
- [GitHub公式ドキュメント（Archived）| tibdex/github-app-token](https://web.archive.org/web/20230115194214/https://docs.github.com/en/issues/planning-and-tracking-with-projects/automating-your-project/automating-projects-using-actions#example-workflow-authenticating-with-a-github-app)
- [actions/create-github-token](https://github.com/actions/create-github-app-token)