GitHub Actions Job Summariesを使うならactions/github-scriptが便利

2022/05/13に公開

GitHub Actions Job Summaries

先日 GitHub からアナウンスがあり、GitHub Actions から簡単に Job Summary を扱えるようになりました。

https://github.blog/2022-05-09-supercharging-github-actions-with-job-summaries/

公式のドキュメントでは、頑張って YAML からマニュアルで環境変数を通じて操作する方法が紹介されていますが、これだと書くのが少々辛いです。

- name: Generate list using Markdown
  run: |
    echo "This is the lead in sentence for the list" >> $GITHUB_STEP_SUMMARY
    echo "" >> $GITHUB_STEP_SUMMARY # this is a blank line
    echo "- Lets add a bullet point" >> $GITHUB_STEP_SUMMARY
    echo "- Lets add a second bullet point" >> $GITHUB_STEP_SUMMARY
    echo "- How about a third one?" >> $GITHUB_STEP_SUMMARY

ただ、ブログでもアナウンスされている通り、@actions/core npm パッケージもアップデートされ、新たに追加された core.summary クラスから簡単に Job Summary を扱えるようになっています。

import * as core from '@actions/core' 
  await core.summary
  .addHeading('Test Results')
  .addCodeBlock(generateTestResults(), "js")
  .addTable([
    [{data: 'File', header: true}, {data: 'Result', header: true}],
    ['foo.js', 'Pass ✅'],
    ['bar.js', 'Fail ❌'],
    ['test.js', 'Pass ✅']
  ])
  .addLink('View staging deployment!', 'https://github.com')
  .write()

上記のサンプルコードから分かるように、Markdown のヘルパー関数が色々と用意されています。

actions/github-script

GitHub Actions で @actions/core を簡単に実行するには、actions/github-script が便利です。

actions/github-script を使うと、その名の通りスクリプト的にワークフローから JS を実行できるようになり、余計なセットアップを一切考慮せずに、プログラムから各種 GitHub API を簡単に操作できるようになります。

よくある例では、PR への自動コメント追加などが挙げられます。
下記の例では、Pull Request 時に Terraform plan を実行し、その結果を github.rest.issues.createComment() を使ってコメントに投稿しています (sample code)。

      - name: Terraform Plan
        id: plan
        if: github.event_name == 'pull_request'
        run: terraform plan -no-color -input=false
        continue-on-error: true

      - uses: actions/github-script@v6
        if: github.event_name == 'pull_request'
        env:
          PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outcome }}\`
            #### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\`
            #### Terraform Validation 🤖\`${{ steps.validate.outcome }}\`
            #### Terraform Plan 📖\`${{ steps.plan.outcome }}\`
            <details><summary>Show Plan</summary>
            \`\`\`terraform\n
            ${process.env.PLAN}
            \`\`\`
            </details>
            *Pushed by: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`;
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: output
            })

全く同じ要領で、core.summary を使って Job Summary に同じ内容を投稿することができます。

      - name: Terraform Plan
        id: plan
        if: github.event_name == 'pull_request'
        run: terraform plan -no-color -input=false
        continue-on-error: true

      - uses: actions/github-script@v6
        if: github.event_name == 'pull_request'
        env:
          PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const output = `\n#### Terraform Format and Style 🖌 \`${{ steps.fmt.outcome }}\`\n
            #### Terraform Initialization ⚙️ \`${{ steps.init.outcome }}\`\n
            #### Terraform Validation 🤖 \`${{ steps.validate.outcome }}\`\n
            #### Terraform Plan 📖 \`${{ steps.plan.outcome }}\`\n
            <details><summary>Show Plan</summary>
            \`\`\`terraform\n
            ${process.env.PLAN}
            \`\`\`
            </details>
            *Pushed by: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`;
            await core.summary
              .addHeading('Terraform plan report')
              .addRaw(output)
              .write()

PR コメントを残す方法も便利ですが、
修正コミットの毎に bot のコメントが増えるといった側面もあり、場合によってはコメントの自動削除をしたくなったり、多少運用上の工夫が必要なケースもあると思います。

Job Summary を使う場合にはそういった問題はなくなりそうです。

Discussion