今週作業したIssueを元に進捗報告のベースを自動出力してみる

毎週行っている更新Issueの一覧作成が何気に手間かかっていたので、Workflowで自動的に済ませられるようにしてみました。
2021.10.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

毎週末に進捗を週報に掲載しています。gh コマンドにてIssueの更新差分を取得して貼り付けていましたが、予め出力させておいてコピペのみで完了できれば楽になり、やり方次第では他にも応用できるかもと思い、Workflowにて週報用の雛形に近いものを出力するように組んでみました。

GitHub ActionsでGitHub Cliを実行する

ホストランナーに含まれているため、追加インストールの必要はありません。jobの環境変数に GH_TOKEN にて GITHUB_TOKEN を指定するのみです。

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - uses: actions/checkout@v2
      - name: Get current date
        id: date
        run: echo "::set-output name=date::$(date +'%Y-%m-%d')"

      - name: Report issues
        run: |
          echo '## Weekly Issue Status' >  docs/issue_report/${{ steps.date.outputs.date }}.md
          gh issue list --search "is:open sort:created-asc created:>$(date +'%Y-%m-%d' --date '5 day ago')" --json "url,title,state,number" | jq -r '.[] | .result = "- [" + .state + " - #" + (.number|tostring) + " " +  .title + "](" + .url + ")"| .result' >> docs/issue_report/${{ steps.date.outputs.date }}.md
          gh issue list --search "is:closed sort:created-asc closed:>$(date +'%Y-%m-%d' --date '5 day ago')" --json "url,title,state,number" | jq -r '.[] | .result = "- [" + .state + " - #" + (.number|tostring) + " " +  .title + "](" + .url + ")"| .result' >>  docs/issue_report/${{ steps.date.outputs.date }}.md
          echo '## Markdown Format' >> docs/issue_report/${{ steps.date.outputs.date }}.md
          echo '```text' >> docs/issue_report/${{ steps.date.outputs.date }}.md
          gh issue list --search "is:open sort:created-asc created:>$(date +'%Y-%m-%d' --date '5 day ago')" --json "url,title,state,number" | jq -r '.[] | .result = "- [" + .state + " - #" + (.number|tostring) + " " +  .title + "](" + .url + ")"| .result' >> docs/issue_report/${{ steps.date.outputs.date }}.md
          gh issue list --search "is:closed sort:created-asc closed:>$(date +'%Y-%m-%d' --date '5 day ago')" --json "url,title,state,number" | jq -r '.[] | .result = "- [" + .state + " - #" + (.number|tostring) + " " +  .title + "](" + .url + ")"| .result' >>  docs/issue_report/${{ steps.date.outputs.date }}.md
          echo '```' >> docs/issue_report/${{ steps.date.outputs.date }}.md

これで以下のような出力になります。

出力結果をコミットする

出力しただけでは残らないためコミットしておきます。

      - name: "Commit if any changes were made"
        run: |
          git remote add github "https://$COMMITTER_USERNAME:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git"
          git pull github ${GITHUB_REF} --ff-only
          if [[ `git status --porcelain` ]]; then
            git add docs/issue_report/${{ steps.date.outputs.date }}.md
            git config --global user.email $COMMITTER_EMAIL
            git config --global user.name $COMMITTER_NAME
            git commit -m "Update $OUTPUT_FILE_NAME"
            git push github HEAD:${GITHUB_REF}
          fi

リモートにてコミットされるため、ローカルではgit pull --rebase が必須になることだけ注意します。

Workflow全体

部分的にピックアップしての解説だったため、以下に全体を掲載しておきます。

name: Generate issues report

on: [push, workflow_dispatch]

env:
  COMMITTER_EMAIL: xxxxxx@gmail.com
  COMMITTER_NAME: github-actions
  COMMITTER_USERNAME: github-actions

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - uses: actions/checkout@v2
      - name: Get current date
        id: date
        run: echo "::set-output name=date::$(date +'%Y-%m-%d')"

      - name: Report issues
        run: |
          echo '## Weekly Issue Status' >  docs/issue_report/${{ steps.date.outputs.date }}.md
          gh issue list --search "is:open sort:created-asc created:>$(date +'%Y-%m-%d' --date '5 day ago')" --json "url,title,state,number" | jq -r '.[] | .result = "- [" + .state + " - #" + (.number|tostring) + " " +  .title + "](" + .url + ")"| .result' >> docs/issue_report/${{ steps.date.outputs.date }}.md
          gh issue list --search "is:closed sort:created-asc closed:>$(date +'%Y-%m-%d' --date '5 day ago')" --json "url,title,state,number" | jq -r '.[] | .result = "- [" + .state + " - #" + (.number|tostring) + " " +  .title + "](" + .url + ")"| .result' >>  docs/issue_report/${{ steps.date.outputs.date }}.md
          echo '## Markdown Format' >> docs/issue_report/${{ steps.date.outputs.date }}.md
          echo '```text' >> docs/issue_report/${{ steps.date.outputs.date }}.md
          gh issue list --search "is:open sort:created-asc created:>$(date +'%Y-%m-%d' --date '5 day ago')" --json "url,title,state,number" | jq -r '.[] | .result = "- [" + .state + " - #" + (.number|tostring) + " " +  .title + "](" + .url + ")"| .result' >> docs/issue_report/${{ steps.date.outputs.date }}.md
          gh issue list --search "is:closed sort:created-asc closed:>$(date +'%Y-%m-%d' --date '5 day ago')" --json "url,title,state,number" | jq -r '.[] | .result = "- [" + .state + " - #" + (.number|tostring) + " " +  .title + "](" + .url + ")"| .result' >>  docs/issue_report/${{ steps.date.outputs.date }}.md
          echo '```' >> docs/issue_report/${{ steps.date.outputs.date }}.md
      - name: "Commit if any changes were made"
        run: |
          git remote add github "https://$COMMITTER_USERNAME:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY.git"
          git pull github ${GITHUB_REF} --ff-only
          if [[ `git status --porcelain` ]]; then
            git add docs/issue_report/${{ steps.date.outputs.date }}.md
            git config --global user.email $COMMITTER_EMAIL
            git config --global user.name $COMMITTER_NAME
            git commit -m "Update $OUTPUT_FILE_NAME"
            git push github HEAD:${GITHUB_REF}
          fi

あとがき

ActionsにはIssuesを定期的に記録するものもあるのですが、ドキュメントではなくそれ自体をIssueにしていたり、open状態のIssueのみ取扱うもの等、想定しているActionがなかったため自力で試してみました。

他にも色々と応用できる仕組みなので、自動コミットするフローの作成に躊躇していたり、ghをWorkflow上で使う方法がわからなくて諦めていた場合等の参考になれば幸いです。