GitHubActionsで効率化した結果を視覚化したい実装編

## はじめに

https://qiita.com/yusuke-sasaki/items/8b3fe9ad0cf759355d98

前回上記投稿で調べた内容を利用して実際にアクションで結果を表示してくれるものを試作してみました。

## 作ったもの

結果はせっかくなので[ジョブサマリー](https://github.blog/2022-05-09-supercharging-github-actions-with-job-summaries/)に表示するようにしてみました。  
アクションを実行すると、以下のようなかたちで集計され、稼働時間をまとめて表示してくれます。

入力画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1062357/18c2a181-0b3d-3ff3-b2d5-655475cac7e7.png)

出力画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1062357/077ef899-8a28-2dfc-f932-00e5cc3f80c0.png)

### ymlファイル

```yml
name: workflow totalization

on:
  workflow_dispatch:
    inputs:
      method:
        description: '直近1ヶ月を取得するか、手動で取得期間を入力するか選択してください'
        required: true
        default: '1month'
        type: choice
        options:
        - 1month
        - manual
      daystart:
        description: '[manual選択時]実績状況の取得開始日をyyyy-MM-ddで入力してください。（例：2022-10-26）'
        type: string
      dayend:
        description: '[manual選択時]実績状況の取得終了日をyyyy-MM-ddで入力してください。（例：2022-10-28）'
        type: string

permissions:
  contents: read

jobs:
  workflowtotalization:
    runs-on: ubuntu-latest
    steps:
      - if: ${{ github.event.inputs.method == '1month' }}
        env:
          TZ: 'Asia/Tokyo' # タイムゾーン指定
        run: |
          echo "CREATED='>$(date --date='1 months ago' +'%Y-%m-%d')'" >> $GITHUB_ENV
          :
      - if: ${{ github.event.inputs.method == 'manual' }}
        run: |
          echo "CREATED='${{ github.event.inputs.daystart }}..${{ github.event.inputs.dayend }}'" >> $GITHUB_ENV
          :
      - uses: actions/github-script@v6
        with:
          script: |
            const result = await github.rest.actions.listWorkflowRunsForRepo({
              owner: context.repo.owner,
              repo: context.repo.repo,
              created: ${{ env.CREATED }}
            })
            
            let workflows = {};
            for(let workflow of result.data.workflow_runs){
              const run = await github.rest.actions.listJobsForWorkflowRun({
                owner: context.repo.owner,
                repo: context.repo.repo,
                run_id: workflow.id,
              });              
              var diff = (new Date(run.data.jobs[0].completed_at).getTime()) - (new Date(run.data.jobs[0].started_at).getTime());
              if(diff > 0){
                if(workflow.name in workflows){
                  workflows[workflow.name] += diff / 1000
                } else {
                  workflows[workflow.name] = diff / 1000
                }
              }
            }
            
            let output = "";
            for(let key in workflows){
              output +=  key + " : " + workflows[key] + "s<br>";
            }
            
            await core.summary
              .addHeading('Workflows report')
              .addRaw(output)
              .write()
```

前回調べたGithubAPIを利用して情報を取得し、取得した情報をワークフローごとに集計して表示するだけのシンプルなものですが、スクリプトの書き方に慣れていなかったりとなかなかに苦戦しました・・・

備忘録も兼ねてちょっとだけ解説します.

入力部は`workflow-dispatch`を活用してるだけなので割愛です。

主な処理はGithubactionsでスクリプトを動かす`github-script`に記述している部分なのですが、
まず最初の[listWorkflowRunsForRepo](https://docs.github.com/ja/rest/actions/workflow-runs#list-workflow-runs-for-a-repository)でリポジトリ内の実行したワークフロー一覧を取得します。

```javascript
const result = await github.rest.actions.listWorkflowRunsForRepo({
    owner: context.repo.owner,
    repo: context.repo.repo,
    created: ${{ env.CREATED }}
})
```

そして取得した実行ワークフローに対して、[listJobsForWorkflowRun](https://docs.github.com/ja/rest/actions/workflow-jobs#list-jobs-for-a-workflow-run)で取得したJobの稼働時間を計算してワークフローごとに集計していきます。
（※ワークフロー1つにつきJobを1つで作成している自身の作成方針ではこれで取得できますが、複数のJobで構成されるアクションを運用している場合は他のAPIを組み合わせる必要があるかもしれません。）

```javascript
const run = await github.rest.actions.listJobsForWorkflowRun({
    owner: context.repo.owner,
    repo: context.repo.repo,
    run_id: workflow.id,
});   
```
上記2つのAPIを利用することでGithub Actionsの稼働実績を集計することができました。
しかし、`listWorkflowRunsForRepo`が最大100件分しか取得できていなかったり、出力結果が寂しかったりと改善したい点はまだまだあります。

またいい感じに改善し、実際に利用できるレベルになれば記事にしたいと思います。

# 参考

https://docs.github.com/ja/rest/actions/workflow-jobs

https://octokit.github.io/rest.js/v18