GitHub ActionsでZenn記事の予約投稿を実現する
「Zenn で記事の予約投稿が出来ると便利だなー」と思って調べてたら GitHub Actions を使って実現できたので紹介します。
仕組み
予約投稿の仕組みは記事追加のプルリクエストの日時指定のマージです。
その実現のためにMerge Schedule
という GitHub Action を利用します。
動きとしては以下の通りです。
- ブランチを切り、公開したい記事を追加。プルリクエストを作成
- GitHub Actions が起動し、Merge Schedule が登録
- 日時指定でプルリクエストがマージされて master が更新
- Zenn で記事が公開
詳細
GitHub Actions の登録
Zenn の記事管理リポジトリに移動して GitHub Actions のディレクトリを作ります。
$ mkdir -p .github/workflows
次に workflows に以下merge-schedule.yml
を作成します。
name: Merge Schedule
on:
pull_request:
types:
- opened
- edited
- synchronize
schedule:
- cron: 0 * * * *
jobs:
merge_schedule:
runs-on: ubuntu-latest
steps:
- uses: gr2m/merge-schedule-action@1ef6893192811edbec08113370a9d973922e84c7
with:
time_zone: "Asia/Tokyo"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
そして変更をコミット & プッシュします。
これでスケジュール投稿の準備が整いました。
プルリクエストの作成
ローカルでプルリクエスト作成用のブランチを切ります。
$ git checkout -b introduce-xvim2
このブランチ上で記事を作成します。記事ファイルの公開指定はpublished: true
としてください。
作成が完了したらコミットしてプルリクエストを作成します。
$ git add introduce-xvim2.md
$ git commmit -m "feat: introduce-xvim2"
$ git push --set-upstream origin introduce-xvim2
そして、プルリクエスト 作成の際の Descriptions に以下のように ISO 形式で公開したい日時を入力してください。これがマージ実行日時(記事公開日時)となります。
/schedule 2020-11-21T20:00
この状態でプルリクエストをオープンし、起動されている GitHub Actions をみてみます。ワークフローが起動していますね。
詳細をみると先ほど指定した公開日時でスケジュールされているのがわかります。
あとは、その指定時間がくるとプルリクエストがマージされ記事が投稿されます。
便利!
注意点
merge-schedule の GitHub Actions がどのように動いているのかを確認したら、以下のようになっていました。
https://github.com/gr2m/merge-schedule-action/blob/master/lib/handle_schedule.js
注目するのは以下処理です。
const duePullRequests = pullRequests.filter(
(pullRequest) => new Date(pullRequest.scheduledDate) < localeDate()
);
どうやら、cron での GitHub Actions 実行時点で、description 記載の実行日時を経過しているプルリクエストを抽出してマージ実行対象とするようです。
なので、厳密に Descriptions に記載した日時にマージされるのではなく、cron での CI 実行時間により左右されます。
もし分単位の公開指定をしたい場合は、GitHub Actions の cron の指定を変える必要があります。
サンプルの例だとcron: 0 * * * *
で、1 時間に 1 回しか実行されません。
例え/schedule 2020-11-21T20:45
と、20 時 45 分に実行を指定しても、それは2020-11-21T21:00
前後に実行されます。
もし、ほぼ 45 分に実行して欲しい場合は merge-schedule.yml
の cron の指定を45 * * * *
とするか、0/15 * * * *
, * * * * *
実行などに変更する必要があります。
ただ、このような指定とするとその分 GitHub Actions が実行されるので、 予約投稿日時によっては GitHub Actions の実行時間の無料枠を超過する可能性がある ことに注意してください。
現実的な設定は、予約投稿するであろう 11-12 時、 18-22 時に cron の起動を限定して
0 3,4,9-12 * * *
とかにするのが良いと思います(cron は UTC 日時なので、-9 時間で設定)。
おわりに
以上「GitHub Action で Zenn の予約投稿を実現する」でした。
こういう応用が効くのも Zenn の良さですね。
自分のライフサイクル的に朝に記事を書きあげることが多いので、予約投稿はとても欲しかった機能でした。来月からスタートするアドベントカレンダーでも使っていきたいです。
Discussion
公式で投稿時刻を設定できる機能がリリースされたようです。
簡単に設定できるので、今はこちらを利用されるのがよさそうです。