Github Actionsを自作して組織内限定で使用してみる

## はじめに

株式会社インティメート・マージャーでエンジニアをしています、 @april418 です。

弊社ではコード管理に Github を使用しており、それに伴い最も親和性の高い CI/CD ツールとして Github Actions を併せて利用しています。

Github Actions では Github 公式がリリースしているアクション以外に第三者が作成したサードパーティアクションも利用可能です。
これにより多くの機能を自身で作成せずとも利用できます。

通常大体のものは探せば見つかるのですが、探しても欲しいアクションが存在しない！と言うこともあったりします。
そういった場合は自身でアクションを作成することもできます。

とはいえ自作したアクションを一般公開するのはちょっと…という方もご安心を！
組織内やアカウント内限定でのみ使用可能にする設定があります！

社内のいくつかのリポジトリで共通して使う CI/CD 機能などをアクション化しておくと便利そうですね。

というわけで実際に設定してみましょう！

## カスタムアクションの作成

公式のドキュメントがありますので、こちらを参照しながら進めました。

https://docs.github.com/ja/actions/creating-actions

### アクションの種類を選ぶ

ドキュメントによるとカスタムアクションには以下の３つの種類が存在するようです。
- Docker コンテナー
- JavaScript
- 複合アクション

https://docs.github.com/ja/actions/creating-actions/about-custom-actions#types-of-actions

それぞれできることが異なっているので、実現したい機能に合わせて選ぶのが良さそうです。
今回は一番お手軽そうだった JavaScript アクションを選択しました。

### JavaScript アクションの作成

こちらも公式ドキュメントがありますのでそちらを参考にします。

https://docs.github.com/ja/actions/creating-actions/creating-a-javascript-action

`actions/toolkit` というリポジトリに JavaScript アクションを作成する際に使用するライブラリがまとまっているようです。

さらに見ていくとサンプルリポジトリがあるようなので、そちらのコードを確認してみます。

https://github.com/actions/hello-world-javascript-action

このリポジトリでは `src/main.js` が処理の主体になります。

```js:src/main.js
const core = require('@actions/core')
const github = require('@actions/github')

/**
 * The main function for the action.
 * @returns {Promise<void>} Resolves when the action is complete.
 */
async function run() {
  try {
    // The `who-to-greet` input is defined in action metadata file
    const whoToGreet = core.getInput('who-to-greet', { required: true })
    core.info(`Hello, ${whoToGreet}!`)

    // Get the current time and set as an output
    const time = new Date().toTimeString()
    core.setOutput('time', time)

    // Output the payload for debugging
    core.info(
      `The event payload: ${JSON.stringify(github.context.payload, null, 2)}`
    )
  } catch (error) {
    // Fail the workflow step if an error occurs
    core.setFailed(error.message)
  }
}

module.exports = {
  run
}
```

この `hello-world-javascript-action` では、入力 `who-to-greet` を受け取ってログに `"Hello, ${whoToGreet}!"` を出力、その後現在日時を出力として返す、といった内容になっています。

このコードから入出力に使われている `actions/core` ライブラリの使い方が概ね理解できるかと思います。

また、Github Actions を動作させるためには `action.yml` 設定ファイルが必要です。

リポジトリ直下にある `action.yml` ファイルの中身を確認してみましょう。

```yml:action.yml
name: Hello, World!
description: Greet someone and record the time
author: GitHub Actions
# Define your inputs here.
inputs:
  who-to-greet:
    description: Who to greet
    required: true
    default: World

# Define your outputs here.
outputs:
  time:
    description: The time we greeted you

runs:
  using: node20
  main: dist/index.js
```

ここでは Action 自体や入出力項目の説明、そして実行に使用する Node.js のバージョンやファイルのパスが記載されています。

このサンプルではソースコードは JavaScript で記載されていますが、 TypeScript などで記載し Vite などのビルドツールで JavaScript にトランスパイルしてそれを実行させることも可能です。

皆さんの用途に合わせてアクションを作成してみてください。

:::note info
弊社の場合はCDNのキャッシュをパージするカスタムアクションを作成し、フロントエンドリソースの本番環境ビルド・デプロイと併せて実行しています
:::

## Githubの設定

### カスタムアクションリポジトリの設定

カスタムアクションのリポジトリを作成したら、 `Settings` タブを開き、左側のメニューから `Actions > General` を開いてください。

ページの一番下に `Access` という項目があり、デフォルトでは `Not accessible` に設定されています。
これを `Accessible from repositories in the 'YOUR ORGANIZATION NAME' organization` に設定してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166554/d41fc85f-75f8-c222-c0d7-c9a132578167.png)

詳細については以下のリンクに記載がありますので、そちらを確認してみてください。

https://docs.github.com/ja/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#allowing-access-to-components-in-a-private-repository

### Workflow の作成

あとはカスタムアクションを実行したいリポジトリに Workflow を作成します。

```yml:.github/workflows/example.yml
name: Example Workflow

on:
  workflow_dispatch:

jobs:
  custom-action:
    name: Custom Action
    runs-on: ubuntu-latest

    steps:
      - name: Run custom action
        uses: カスタムアクションのリポジトリ名
```

これで組織内の他リポジトリからカスタムアクションを呼び出すことができます！

実行タイミングなど Workflow の内容は用途に合わせて適宜変更してください。

## まとめ

Github Actions は非常に便利なツールですので、サードパーティアクションの利用だけでなく、カスタムアクションも作成してどんどん使い倒していきたいですね！

## 最後に

ここまで読んでいただきありがとうございました！

次回以降の弊社アドベントカレンダーもお楽しみに！

https://qiita.com/advent-calendar/2024/intimatemerger

もし弊社にご興味がありましたら、併せてこちらもご確認ください！

https://recruit.intimatemerger.com/