Roppongi.rb を支える技術 ~Github Actions 編 その1~

背景

自分は数年前から Roppongi.rb のオーガナイザーをやってます。最近は他のオーガナイザーの方と一緒にイベントの方針を変えてオープンスペーステクノロジーOST)というワークショップの手法の1つを採用してイベントを毎月1回開催しています。流れとしてはイベントの参加者で議論したい内容を出し合って、投票し、投票数が多い議題を順番にワイワイするという感じです。

roppongirb.connpass.com

直近だと「良いテストを書くには?」や「Rails を起動するコンテナイメージを小さくするには?」のような Ruby に関連した様々な内容でワイワイしました。自分は現職では Ruby を使うことはないのですが、Ruby 自体は好きな言語の1つなのでこのような「現場」x「Ruby」なテーマは現場に今どういう問題があってそれを Ruby を使ってどう解決しようとしているのかを知れるのでとても興味深いです。

イベントは Github 上で議論用のリポジトリを作成して下記の流れで行っています。

  1. 各自話したい内容を issue にして作成する
  2. 自分が話したいと思う内容の issue にリアクションをする
  3. 集計して投票数が多いものから順にワイワイする

課題

さきほどの最後のステップの集計に関して2つの問題がイベントを重ねていく中で出てきました。

  1. すべての issue を開いてリアクションの数を確認するので issue の数が増えていくと面倒になる
  2. イベントごとに投票数をリセットするために投票用のコメントを各 issue につけるため、issue の数が増えていくと面倒になる

つまり今後イベントを重ねていくと面倒くささが増していくことがわかりました。

解決

今回はさきほどの課題2つを Github Actions を使って解決しました。Github Actions によって実現したい流れは下記になります。

  1. (👥) event 用の issue を作成する (label に event をもっている)
  2. (🤖) event 用の issue に過去の議論してない issue を自動でコメント
  3. (🤖) 新しい issue が追加されるとそれを event 用の issue に自動でコメント

2, 3, を Github Actions が行います。これにより投票や集計の処理は1つの issue 上で行われるため、上記の問題が完璧ではないもの解消されます。Github Actions を選んだ理由として、今回やりたいことが「issue を開いた時」というイベントをトリガーにするため、これを扱いやすい方法が Github Actions だったからです。

まず完成形の YAML ファイルは下記になります。

name: Open new issue

on:
  issues:
    types:
      - opened

jobs:
  event:
    if: contains(github.event.issue.labels.*.name, 'event')
    runs-on: ubuntu-latest
    steps:
      - uses: k1LoW/github-script-ruby@v2
        with:
          script: |
            github.auto_paginate = true
            repo = "#{context.repo.owner}/#{context.repo.repo}"
            issue = context.payload.issue
            non_event_issues = github.search_issues("repo:#{repo} -label:event is:open", per_page: 100).items
            non_event_issues.each do |non_event_issue|
              comment = "[#{non_event_issue.title}](#{non_event_issue.html_url})"
              github.add_comment(repo, issue.number, comment)
            end
  non-event:
    if: contains(github.event.issue.labels.*.name, 'event') == false
    runs-on: ubuntu-latest
    steps:
      - uses: k1LoW/github-script-ruby@v2
        with:
          script: |
            github.auto_paginate = true
            repo = "#{context.repo.owner}/#{context.repo.repo}"
            issue = context.payload.issue
            comment = "[#{issue.title}](#{issue.html_url})"
            event_issues = github.search_issues("repo:#{repo} label:event is:open", per_page: 100).items
            event_issues.each do |event_issue|
              github.add_comment(repo, event_issue.number, comment)
            end

ロジックは k1LoW/github-script-ruby という Action を使用して実装しました。これは Github Actions が公式の Action として提供している actions/github-script に inspire して作成されたもので actions/github-script が Node.js をワークフローに書くのに対して k1LoW/github-script-rubyRuby を書くことでそれが実行されます。この Action に関しては作者の方が書いた下記の記事が分かりやすいです。

tech.pepabo.com

この Action を選んだ理由として、まずは Ruby で解決できるというのが主な理由です。後は今回実現したいものがシンプルなタスクだったので、できるだけシンプルな解決策を使用したいと思ったからです。

ワークフローには2つの job が定義されておりそれぞれ 2, 3, を行う役割を担っており、 jobs.*.if でそれぞれを出し分けています。各 Ruby のコードは Github API で同リポジトリ内の issue を取得して後は event 用の issue にコメントするというシンプルなものになっています。

最後に

今回は直近困っていることを Github Actions と k1LoW/github-script-ruby を使うことでどのように解決したかについて書きました。

イベントは毎月開催しているので興味がある方はぜひ一緒にワイワイしましょう!