イマドキの cron は GitHub Actions / CircleCI でやりたい

2020/09/13 追記
「GitHub Actions の規約違反では?」というコメントがありましたが、追記時点の規約では特別禁止されていません。
https://docs.github.com/ja/github/site-policy/github-additional-product-terms#a-actions-usage
唯一グレーラインに相当する可能性のある『サーバーレスコンピューティング』も日本語訳に残っているだけものであり、英語の原文からは既に削除されている項目のため、問題ない利用方法となります。

昔は cron といえば Heroku と Heroku Scheduler だったけれど、Heroku Scheduler が遅延するようになってから、自分用の定刻バッチを楽に動かせる手段がなくてしばらく困っていたり。

しっかりとしたプロジェクトを作成する場合なんかは Firebase Functions が cron 対応しているので、それを使うことが多く、現に Contributter あたりはそれで実現しているものの、ユーザー数=1のものの場合、 Firebase のプロジェクトを作ってまでやることではない気持ちが強い。

というわけで最近は GitHub Actions あるいは CircleCI のスケジューラーで cron を管理するようにした。

コピペで使えるコードはそれぞれの例の部分に記載。

ユースケース

自分の場合は結構朝に必要な情報を受け取りきってしまいたいので、その日の情報を個人の Slack に流すようにしている。

一例を上げると

  • 払い込みなど鬼通知してくれないと忘れる ToDo は普段のタスクリストと分けて GitHub Actions で毎日 9時 に通知
  • 毎朝 10時になると市場があいていて、よる 18時 には閉まっているので FOLIO のレポートを通知
  • 毎朝 10時に前日の Stripe での売上高のレポートを通知

といった具合。

他にも深夜に KPI レポートが飛んできたりして、朝見たりしてる。

これらそれぞれに対してプロジェクトを作ったりするのもイヤではあるのと、あと権限とかを考えると安易に一つのレポジトリに Bot のコードを集約させたくもないモチベーションもあり、別のレポジトリで管理しながらもプロジェクト作成などを必要としない CI 基盤で cron 実行をしている。

GitHub Actions の例

払い込み ToDo 通知 Bot の設定をほぼそのままコピペ。

GitHub Actions は secrets の設定も楽かつ、 GitHub Projects など GitHub API のリソースと紐づくようなものを利用する場合はトークンが引き回せたりする点も悪くない。

個人の private repo でも無償かつ作成数に制限もない。また、かなり長い間運用しているものの、遅延したこともないので安心して使うことができる。

詳細は ドキュメント 参照。

なお、デフォルトでは UTC であり、日本では +9 した時間で動く点について注意すること。

name: todo

on:
  schedule:
    - cron: 0 0 * * *

env:
  SLACK_TOKEN: {{ $secrets.SLACK_TOKEN }}

jobs:
  cleanup:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [12.x]

    steps:
      - uses: actions/checkout@v1
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        if: steps.cache.outputs.cache-hit != 'true'
        with:
          node-version: ${{ matrix.node-version }}
      - name: Install
        run: |
          yarn
      - name: execute
        run: |
          yarn start

CircleCI

CircleCI は前から CircleCI だったところで惰性で使っている。

CircleCI のほうが artifacts の取り扱いなどが優秀だったり workflows のデータ共有がやりやすかったりする点で優位性があることも多いけれど、cron 程度なら GitHub Actions で事足りるので新規の Bot では使ってない。

前は private repo でも無料なのが助かる意味で使っていた。

こちらもデフォルトでは UTC であり、日本では +9 した時間で動く点について注意すること。

# .circleci/config.yml
version: 2
jobs:
  cron:
    docker:
      - image: &docker_image circleci/node:latest
    working_directory: &workspace_directory ~/app
    steps:
      - checkout
      - run: yarn
      - run: yarn start

workflows:
  version: 2
  main:
    jobs:
      - cron
  schedule:
    triggers:
      - schedule:
          cron: "0 1 * * *"
          filters:
            branches:
              only:
                - master
    jobs:
      - cron

プロジェクトにあった環境とバージョンに image を変更して、 yarnyarn start の部分を変えてくれると OK。

node:latest の部分を適当に合うバージョンに変えると、 Node プロジェクトならだいたいそのまま動く。

おわりに

日常のための工夫であり、 SLA をしっかり見た上でつかっているわけではないので、Production で使う際はその辺りしっかり見た上で注意して利用すること。