Open8

GitHub Actionsのランナーのnodeが16 -> 20アップデートされる予定と最新のOctokit.jsがnode16サポートを切った件の調査

Kesin11Kesin11

Discussionの内容の3行まとめ

  • benwellsさん:node18をスキップしてnode16 -> 20に上げる予定
  • AWareさん:octokit.jsではnode16のサポートが切られたのでGitHub社内でサポートバージョンが統一されていないことは残念
  • razor-xさん:node20がLTSになるのは2023-10-24なので実際にnode20が使えるようになるのは11月ぐらいという認識でよい?(訳注:文中では2022-10-24と書いてあるが、node20のLTSサポート開始は2023-10-24なのでtypoな気がしている)
Kesin11Kesin11

個人的に気になったのはoctokit.jsの件で、たしかにv3.0.0からnode 16以下のサポートが切られている。
代表的なのはactions/github-scriptだが、個人が作成しているactionsの中でもGithubのAPIを叩くactionsであればみんなoctokitを使ってそうなので、それらのoctokitが最新化されたらnode 16が使われているGitHub Actionsのランナーで動かなくなる可能性もある・・・?

という疑問から調査スタート

Kesin11Kesin11

まず本当にoctokit.jsを使っているかの確認。絶対に使ってるだろうと思っていたactions/github-scriptだがoctokit.jsを使っていなかった
https://github.com/actions/github-script/blob/v6.4.1/package.json

じゃあどうやってAPIを叩いているのかと調べてみたところ、 @octokit/core という別のパッケージを使っていることが分かった。
じゃあoctokit.jsの影響は受けないのかと思いきや、octokit/core も最近リリースされたv5.0.0で同様にnode16以下のサポートが切られていたので、結局同じことになる可能性が残った。

ちなみにactions/github-scriptが使っている @octokit/core は現状では"^3.5.1"と少し古いバージョンが使われているため、node16が使われているGitHub Actionsのランナーで直ちに動かなくなるということはない。

まあもし影響が発生していたらとっくに誰かが問題を報告しているはずだけど、未だにそういう話は聞かないので今のところ実際に問題はなさそう。

Kesin11Kesin11

次なる疑念としては、actions/github-scriptなどが @octokit/coreを最新化し、それまでにランナーのnodeが20にまだアップデートできずに16が使われていたらある日突然動かなくなってしまうのでは?ということ。

実際に自分で最新の @octokit/core を使ってAPIを叩くactionsを作ってみれば確認できるので試してみた。
https://github.com/Kesin11/actions-octokit-core-v5-playground

実際の中身であるindex.jsはこんな感じ。リポジトリ詳細のAPIを叩くだけの超シンプルなコード。

const { Octokit } = require("@octokit/core");

async function run() {
 console.log("Node version:", process.version)

 const token = process.env.GITHUB_TOKEN
 if (!token) throw new Error("GITHUB_TOKEN is undefined")

 const octokit = new Octokit({ auth: token })

 console.log("GET /repos/Kesin11/actions-octokit-core-v5-playground")
 const res = await octokit.request("GET /repos/Kesin11/actions-octokit-core-v5-playground")
 console.dir(res.data)
}

run();

これを自分のローカルでnode20, node16で切り替えながら実行してみると、node20では問題なく動くがnode16だと以下のようなエラーになる

GET /repos/Kesin11/actions-octokit-core-v5-playground
/xxxxxxx/actions-octokit-core-v5-playground/node_modules/@octokit/request/dist-node/index.js:57
    throw new Error(
          ^

Error: fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing

fetchが使えないから自分でfetchの実装を持ってきて new Octokt() で渡してくださいという親切なエラーが書かれている。このあたりがnode 16以下のサポートが切られた理由っぽい。

Kesin11Kesin11

ここまでで @octokit/core をアップデートしたらnode16のままではエラーになる確信が得られたが、今度は逆にnode16のまま固定して @octokit/core のバージョンを最新のv5と1つ前のv4に切り替えることで、v5にしない限りはnode16のランナーでも大丈夫であることを念のために確認しておく。

ちょっと工夫を行い、GitHub Actionsの中で @octokit/core のバージョン違いを npm i して再度ビルドし直してから実際に動かしてみるということをやってみた。
https://github.com/Kesin11/actions-octokit-core-v5-playground/blob/main/.github/workflows/test.yaml

結果はこちら
想定通りにnode16で固定されてしまっているGitHub Actionsランナー内では @octokit/core のバージョンをv5まで引き上げると先ほどと同じエラーになってしまう。v4系最新のv4.2.4であれば大丈夫。

Kesin11Kesin11

一見すると将来に燃えそうな感じなのですが、冷静に考え直すと以下の理由でさほど問題にはならなそう

  • actionsが使っている @octokit/core のバージョンが最新のv5にならない限りは問題ない
    • actions/github-scriptでさえpackage.jsonを見るに未だにv3系を使っているので、v5系を急ぐ必要はあまりなさそうに思える
  • 仮にv5系が必要だったとしてもエラーで案内されている https://github.com/octokit/octokit.js/#fetch-missing に従ってワークアラウンド対応をすれば動く可能性がある
  • 冒頭のdiscussionより、ランナー内蔵のnode16を20にアップデートする計画がある。これが実行されればそもそも今回のような懸念は不要

結論

という理由から、node16とOctokit( @octokit/core )のサポートバージョンが噛み合わなくなっている問題は直ちに影響は無いと考えて大丈夫だと自分は思いました。

ただし、GitHubのAPIを叩く機能を有するactionsを自作している方は依存パッケージのバージョンを上げる際に、ローカルでテストするだけではなくて実際のランナー上で動作することを確認するのを忘れないようにした方がよいと思います。

Kesin11Kesin11

これを書いてから数日後に actions/runner@v2.308.0がリリースされ、node20が内蔵されたようです。

Add node20 to runner (#2732)

ということでこのスクラップで検討したことはgithub.comではほとんど問題になることはないはず。
ただしGitHub Enterprise Server(GHES)は事情が異なり、v2.308.0のランナーがGHESで使えるようになるまでにはタイムラグが存在するのでその間は注意が必要。