koluku's blog

コードは毎日の欠片

GitHub Actionsでactions/github-scriptからJSONのレスポンスを取得する

※Zennからの移植記事です

GitHub ActionsでGitHubに関する操作をしたい場合にREST APIを叩くよりも楽に書けるactions/github-scriptがある。APIの叩き方はOktokit.jsとほぼ同じJavaScriptで書くことができる。 (ただ最近はGitHubホストランナーのUbuntuなどには ghがプリインストールされているので、こちらを用いたほうが読みやすいなと思ってる)

下記はdevelopブランチにpushが発生した場合にPRを作成する例。

name: create pull request on push

on:
  push:
    branches:
      - develop

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: create pull request
        uses: actions/github-script@v4
        with:
          script: |
            github.pulls.create({
              owner: context.repo.owner,
              repo: context.repo.repo,
              base: 'main',
              head: 'develop',
            });
      - name: ...

GitHub ActionsでGitHubを操作したいというシチュエーションは大抵の場合はIssueやPRにまつわるものなのでactions/github-scriptで済むことも少なくないが、稀にAPIを叩いた結果を元に別の実行を行いたいことがある。その場合にactions/github-scriptはレスポンスをJSONで返してくれる。

レスポンスを使うには結果をその場でファイルに保存して次にファイル読み出しで再利用するか、

      - name: compare develop <-> master
        uses: actions/github-script@v4
        with:
          script: |
            const fs = require('fs')
            const data = await github.repos.compareCommits({
              owner: context.repo.owner,
              repo: context.repo.repo,
              base: 'master',
              head: 'develop',
            })
            fs.writeFileSync('/tmp/compare.json', JSON.stringify(data))

APIを叩くstepにidを貼って return で結果を保存してechoで呼び出すかがある。 (ただし、この方法は返ってくる結果が大きいとワークフローのページを開くとブラウザのタブをクラッシュしてしまうので非推奨)

jobs:
  diff:
    runs-on: ubuntu-latest
    steps:
      - name: compare develop <-> master
        uses: actions/github-script@v4
        with:
          script: |
            return github.repos.compareCommits({
              owner: context.repo.owner,
              repo: context.repo.repo,
              base: 'master',
              head: 'develop',
            })
        id: compare_commits
      - name: set flag has_masterdata
        run: |
          echo ${{ toJSON(steps.compare_commits.outputs.result) }} | jq ...

レスポンスを利用する場合の注意点として、REST APIを叩いた場合に返ってくるレスポンス構造はdataキーに包まれて渡されるので、既存のJSONを元にしたスクリプトを実行する際には注意が必要。

{
    "data": {
        ...
        # REST APIを叩いた場合に返ってくるレスポンス情報
    },
    "headers": {
        ...
    },
    "status": 200,
    "url": ...
}