概要

GitHub Actionsの定期実行を利用してGithubのissueを検索し、Slackに通知する仕組みを作った。

JavaScriptの作成

esm.shを使うことでパッケージインストールを省いている。 このスクリプトの結果としてSlackのペイロードを出力するようにしているところがポイント。 GitHub Actions上でJSONを加工するのは苦痛だったのでこのようにした。

import { Octokit } from "https://esm.sh/octokit?dts";

const SECRET_KEY = Deno.env.get('SECRET_KEY');
const octokit = new Octokit({ auth: SECRET_KEY });

const owner_name = Deno.env.get('OWNER_NAME');
const repo_name = Deno.env.get('REPO_NAME');
const query = Deno.env.get('QUERY');

await octokit.rest.search.issuesAndPullRequests({
  q: `repo:${owner_name}/${repo_name} is:issue is:open ${query}`
}).then(response => {
  const items = response.data.items;
  const issues = items.map(item => {
    return {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": `<${item.url}|#${item.number}> ${item.title}`
      }
    };
  });

  const base = {
    "blocks": [
      {
        "type": "context",
        "elements": [
          {
            "type": "plain_text",
            "text": "検索結果 :eyes:",
            "emoji": true
          }
        ]
      },
      {
        "type": "divider"
      },
      ...issues
    ]
  }

  console.log(JSON.stringify(base));
});

Deno.exit(0);

GitHub ActionsからSlack通知する

上記スクリプトを実行するようなワークフローを作る。 複数行の出力を別のステップに受け渡すためにGITHUB_OUTPUTを使っている。 idとともに${{steps.deno.outputs.JSON_OBJECT}}のように指定すると複数行の文字列を取得できる。

name: Deadline Issue Slack
on: 
  schedule:
    - cron: "0 1 * * *"
  workflow_dispatch:

jobs:
  notification:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    env:
      TZ: 'Asia/Tokyo'

    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Setup Deno
      uses: denoland/setup-deno@v1
      with:
        deno-version: v1.x

    - name: Execute Deno
      id: deno
      run: |
          echo "JSON_OBJECT<<EOF" >> $GITHUB_OUTPUT
          deno run --allow-env --allow-net ./.github/assets/main.js >> $GITHUB_OUTPUT
          echo 'EOF' >> $GITHUB_OUTPUT
      env:
        KEY: ${{secrets.SECRET_KEY}}
        OWNER_NAME: xxx
        REPO_NAME: xxx

    - name: Send To Slack
      uses: slackapi/slack-github-[email protected]
      env:
        SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
        SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
      with:
        payload: ${{steps.deno.outputs.JSON_OBJECT}}

結果

いい感じに出力できた。今回はissueを出力してみたがいろいろ応用は効きそう。