JavaScriptを有効にしてください

GitHub Appsで公開リポジトリが作成されたら検知する

 ·  ☕ 4 分で読めます

最近、下記の資料を参考に GitHub Organization の運用を見直しました。

その中で、公開リポジトリ作成を禁止したかったのですが、現在 Team プランを利用しているため、GitHub の機能では実現できませんでした。1

公開リポジトリが作成された際に通知してくれる GitHub Apps はあったのですが、要求される権限が大きかったことや簡単に実現できそうだったので、新規に GitHub Apps を作成することにしました。

GitHub Apps

GitHub Apps は Personal Access Token(PAT) 等を用いずに、GitHub API にアクセスしてリポジトリの操作等を行うことができる機能です。

作成した GitHub Apps は Organization 単位でインストールでき、対象とするリポジトリも選択することができます。

PAT を利用しないため、個人ユーザに紐付かず、運用管理が楽なことや、GitHub API にアクセスする際には都度 short lived な token を発行してアクセスするためセキュリティ面でも安全です。

また event も subscribe することができるので、event を契機に何らかのアクションを実行することもできます。

作成自体は簡単で、GitHub の画面から作成することができます。

よくあるユースケースとして GitHub Action でデフォルトの権限では実現できない際に GitHub Apps を利用します。

Probot

今回、公開リポジトリが作成された際に event を受け取り、通知を行う必要があるため、別途 event を受け取るエンドポイントが必要になります。

flow.png

1から作成するのは、short-lived な token の発行処理などを自前で書かないといけないため、今回 Probot という GitHub Apps の framework を利用しました。2

既に node がインストールされている環境では下記のコマンドでプロジェクトを作成することができます。

1
npx create-probot-app my-first-app

テンプレートが用意されているので、利用したいものを選択します。今回は basic-js を選択します。

1
2
3
4
5
❯ basic-js
  basic-ts (use this one for TypeScript support)
  checks-js
  git-data-js
  deploy-js

雛形作成完了後に app.yaml という名前のファイルが作成されています。

app.yaml を編集することで、作成する GitHub Apps の権限を編集することができます。

今回は subscribe する event として、publicrepository 。permission としては metadata:read のみコメントを外します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
default_events:
  ...
  - public
  ...
  - repository
...
default_permissions:
  ...
  metadata: read
  ...

編集後、npm start を実行することで、localhost:3000 から GitHub Apps の作成とインストールをすることができます。

probot-setup-wizard

インストール後、.env に ID や SECRET 情報が記載されています。

1
2
3
4
5
6
WEBHOOK_PROXY_URL=https://smee.io/XXXXXXXXX
APP_ID=XXXXXX
PRIVATE_KEY="XXXXXXXXXXXXXX"
WEBHOOK_SECRET=XXXXXXXXXXXX
GITHUB_CLIENT_ID=XXXXXXXXXX
GITHUB_CLIENT_SECRET=XXXXXXXXXXXXXXXX

smee.io という ngrok のようなサービスと連携するため、再度 npm start をすると local 上で GitHub からの event を受け取れる状態になります。

コード

index.js に処理を記載します。リポジトリが作成されたまたは公開されたイベントを受け取る処理は下記のようになります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
 * This is the main entrypoint to your Probot app
 * @param {import('probot').Probot} app
 */
module.exports = (app) => {
  const { IncomingWebhook } = require("@slack/webhook");
  const url = process.env.SLACK_WEBHOOK_URL;
  const webhook = new IncomingWebhook(url);

  // リポジトリ作成のイベントを受け取る
  app.on("repository.created", async (context) => {
    if (!context.payload.repository.private) {
      app.log("created new repository");
      await webhook.send({
        text: `>>> new public repository was created\n *repo name* : ${context.payload.repository.full_name} \n *url* : ${context.payload.repository.html_url}`,
      });
    }
  });

  // リポジトリが公開されたときのイベントを受け取る
  app.on("repository.publicized", async (context) => {
    app.log("New repo was publicized");
    await webhook.send({
      text: `>>> new repository was publicized \n *repo name* : ${context.payload.repository.full_name} \n *url* : ${context.payload.repository.html_url}`,
    });
  });
};

app.on にそれぞれの event に対応する処理を記載します。

1
2
3
  app.on("イベントタイプ", async (context) => {
    ...
  });

イベントの種類は下記のドキュメントを参照するか

GitHub 上でリポジトリを作成するなどの、実際にその event が発生する操作をすると、GitHub Apps の設定画面で発行された event を確認することができます。

settings

実際の payload を確認することができるので、デバッグする際にも有用です。

Vercel でホスティング

GitHub からの webhook を受け取るために、どこかにホスティングをする必要があります。

SheepMedical では既に Vercel を利用していることもあり、Vercel の Serverless Functions を利用することにしました。

Serveless Functions で実行する都合上 api/github/webhooks/index.js に下記のコードを追加します。

1
2
3
4
5
6
7
8
9
const { createNodeMiddleware, createProbot } = require("probot");

const app = require("../../../app");
const probot = createProbot();

module.exports = createNodeMiddleware(app, {
  probot,
  webhooksPath: "/api/github/webhooks",
});

あわせて、root ディレクトリの index.jsapp.js にリネームします。

.env に記載されていた必要な環境変数を設定して Vercel にデプロイします。

env

最後に Github Apps の設定で webhook を Vercel で発行された url に変更します。

webhook

実際に公開リポジトリを作成すると下記のようなメッセージが設定したチャンネルに通知されます。

message

まとめ

GitHub Apps 自体は既に GitHub Action で利用していたのですが、event を受け取っての処理も probot のおかげか簡単に書くことができるなという印象を持ちました。
GitHub Apps を利用することで、セキュアに GitHub 周りの諸々を簡単に自動化できるので、今後も活用していきたいと思います。

最後に

SheepMedical では各種 SaaS を利用したデリバリー改善、サービスの安定性向上、DevSecOps のライフサイクル改善、自動化等に興味がある方を絶賛募集しています。(時期によっては募集を停止していることがあります。)


  1. 公開リポジトリの禁止は Enterprise プランのみ提供 ↩︎

  2. event を受け取り、slack に通知するだけなので、実際のところはリポジトリの操作は不要で、token を発行する必要もありません。 ↩︎

共有

Shinichi Morimoto
著者
Shinichi Morimoto
Software Developer