GitHub Actionsを活用して擬似APIサーバーを用意する


はじめに

たぶん割と最近、GitHub Actionsという機能が追加されました。
これは、所定のイベントに対し所定のActions(シェルスクリプトの実行)を発火させる事が出来るというやつです。
例えばdevブランチへのPRがマージされたらビルドしてdev-pagesブランチにプッシュ、なんていういわゆるCI/CD向けの機能です。

この度、現在大きな動きとなっているCOVID-19対策サイトの北海道版に参加し、この機能を用いた開発を行いました。これを例に、タイトルのとおりGitHubを擬似APIサーバーに仕立てる事が可能では?という提案を本記事で行います。

GitHub Actionsによるスケジューリング

Actionsに至った経緯

https://github.com/Kanahiro/covid19hokkaido_scraping
前述の対策サイト開発の際、可視化の元となるJSON形式のデータをこさえるのに作ったスクリプトです。(当時のversionでは)実行すると道のウェブサイトを巡回したり、ブランチに保持している静的なCSVファイルを読み出してjsonファイルを出力する機能を持ちます(現在は外部のCSVファイルを読み込みます)。
当初はひとまず、という事で書いたスクリプトで、main.pyを手動で実行する必要がありました。そんなときJUST道ITのメンバーから「スケジューリングとかできます?」という提案が。この時点では出来るかどうかわからなかったのでとりあえず返事はせず、こっそり実装方法を調べてみたら意外に簡単だったので実装しました(Actionsは神)。

スケジューリング手法

参考サイト:GitHub Actionsをスケジューラとして利用する

Actionsはyamlファイルで定義されます。最初に発火するタイミング"on"を定義します。
通常のCI/CDの用途であれば、特定ブランチへのpushをトリガーにしたりします。
が、以下のとおり記述する事で、15分おきの実行とする事が出来ます。


on:
  schedule:
    - cron:  '*/15 * * * *'

#(cron?なんだそりゃ?となったのは秘密)

これでスケジューリングは出来ました。
じゃあ、15分おきに前述のスクリプトを実行して、別ブランチに生成したjsonデータをpushすれば良いじゃない!
という事で、以下のようなyamlファイルでスケジューリングする事となりました。


name: Python application

on:
  schedule:
    - cron:  '*/15 * * * *'

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Set up Python 3.8
      uses: actions/setup-python@v1
      with:
        python-version: 3.8
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
    - name: Run script
      run: |
        python main.py #メインスクリプトを実行
    - name: deploy
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./data
        publish_branch: gh-pages

他人のyamlファイルを参考に書いたので、フルスクラッチで書けと言われると泣きます。
pipで依存をインストール出来るのとか、すげぇなぁ〜と思いました。
main.pyは実行すると、同じディレクトリにあるdataディレクトリ内にjsonファイル群を出力します。
スクリプトの処理が終了後、dataディレクトリ内のファイルをgh-pagesにpushします(secrets.GITHUB_TOKENにより権限を持ちます)
という事で、gh-pagesには、15分に一度生成されるjsonファイル群が納められるようになりました。

擬似APIサーバーとして

タイトル詐欺な気がしますが、以上で私が提案する擬似APIサーバーは完成しています。
https://raw.githubusercontent.com/Kanahiro/covid19hokkaido_scraping/gh-pages/patients.json
これは前述のスクリプトのリポジトリ上で、Actionsにより15分おきに自動生成されるjsonファイルです。
このファイルは(まだ自分で検証出来ていませんが)CORS制限にかからないようなので、フロントで直接読み出せます。
つまりフロント側で、このファイルを取得して要素を「色付け」すれば実質的にAPIサーバーとして扱えているのではないでしょうか!

という提案でした。
別途APIサーバーを建てるリソースがなかったり、冗長だったり、面倒な場合に有効だと考えています。
あと、よそのサービスを挟まずGitHubですべて完結するのも、見通しが良くなりGoodだと思います。

追記:GitHub Pagesについて

前述の出力したjsonの向け先をgh-pagesブランチにしていましたが、何故だかgithub.io経由でアクセス出来なかったので上記のraw.githubusercontent.comに直接アクセスしていました。が、しかしコメントにて以下のようなやりとりが。

ん…?何か見覚えのあるアカウント名の気が…

さっきのActionsのスクリプト

      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./data
        publish_branch: gh-pages

(この御方(@peaceiris氏) スクリプトで使ってる、gh-pagesにpushするアクションを作った人だ…)
という事で、settingsから、再度gh-pagesに出力するように選択したところ…

無事gh-pagesでホスティング出来ました、どうもすみませんでした(そしてありがとうございます)。
という事で、Actionsの設定後、再度gh-pagesをホスティングするようsettingsを確認をいじる必要がありますので気をつけてください。