GitHub Actionsでdeprecation warningが発生しているworkflowを簡単に調べる

#GitHub Actions

GitHub Actions で deprecated な syntax などを使用している場合、このように workflow の summary に警告が表示される。長らく非推奨扱いだったものがいよいよ使えなくなるよ、というアナウンスが最近立て続けにあったので、管理している全リポジトリから対応が必要なものを調べ上げる方法を確認した。

Workflow Summary に Annotations として表示されている警告は以下のエンドポイントから取得できる。

/repos/{owner}/{repo}/check-runs/{check_run_id}/annotations
https://docs.github.com/en/rest/checks/runs#list-check-run-annotations

gh api https://api.github.com/repos/horimislime/github-actions-playground/check-runs/13515468815/annotations [ { "path": ".github", "blob_href": "https://github.com/horimislime/github-actions-playground/blob/8bf0786a13faa4c53133b448a0dc75847c7e58d9/.github", "start_line": 1, "start_column": null, "end_line": 1, "end_column": null, "annotation_level": "warning", "title": "", "message": "Node.js 12 actions are deprecated. Please update the following actions to use Node.js 16: actions/checkout@v2. For more information see: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/.", "raw_details": "" } ]

Actions では commit SHA ごとに Check Suite というものを実行できる。ざっくり言うと lint などで使う仕組みで、Pull Request の Status Check より詳細な機能を提供してくれる上位互換的なもの、という位置付けらしい(例えば変更を加えたファイルに行単位で警告メッセージを表示するなど)。警告はこれの実行単位である Check Run に含まれる。
Check Suite は GitHub Apps などで実装できるようになっている。非推奨な Node バージョンを使っているといった警告は、GitHub が内部的に同じ仕組みに乗っかって出してくれているようだ。

自分が所属している Organization の全リポジトリで警告を調べてみる。これをやるにはまずリポジトリ情報を API で取得しその中の Workflow 一覧を取ってきて、さらに実行履歴を…と地味に長い過程を経るので、Octokit で簡単なスクリプトを用意した。

List all warning messages on GitHub Actions workflows - Gist

// npm i @octokit/rest const { Octokit } = require('@octokit/rest'); const octokit = new Octokit({ auth: process.env.GH_TOKEN, }); (async () => { const orgName = process.env.ORG_NAME; // List all repositories excluding archived status const { data: repos } = await octokit.rest.repos.listForOrg({ org: orgName, per_page: 100, sort: 'pushed', direction: 'desc', }); const activeRepos = repos.filter((repo) => !repo.archived); for (const repo of activeRepos) { const { data: workflows } = await octokit.rest.actions.listRepoWorkflows({ owner: orgName, repo: repo.name, }); if (workflows.total_count === 0) { continue; } // List workflows in use const activeWorkflows = workflows.workflows.filter( (workflow) => workflow.state === 'active', ); console.log(`----- ${repo.name} -----`); for (const workflow of activeWorkflows) { // Get latest successful workflow run const { data: workflowRuns } = await octokit.rest.actions.listWorkflowRuns({ owner: orgName, repo: repo.name, workflow_id: workflow.id, per_page: 1, status: 'success', }); if (workflowRuns.total_count === 0) { continue; } // List Check Suites for the workflow run const { data: checkSuites } = await octokit.rest.checks.listForSuite({ owner: orgName, repo: repo.name, check_suite_id: workflowRuns.workflow_runs[0].check_suite_id, }); // Check if any warning messages exist in the Check Suites const warningMessages = []; for (const checkRun of checkSuites.check_runs) { const { data: annotations } = await octokit.rest.checks.listAnnotations( { owner: orgName, repo: repo.name, check_run_id: checkRun.id, }, ); warningMessages.push( ...Array.from( new Set(annotations.map((annotation) => annotation.message)), ), ); } if (warningMessages.length > 0) { console.log(` ${workflow.html_url} has following warnings: ${warningMessages.join('\n')}`); } } } })();

以下のように実行して終わり。

GH_TOKEN=$(gh auth token) ORG_NAME='my-org' node main.js
----- api-server -----

https://github.com/my-org/api-server/blob/develop/.github/workflows/deploy.yml has following warnings:
Node.js 12 actions are deprecated. Please update the following actions to use Node.js 16: actions/checkout@v2. For more information see: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/.

https://github.com/my-org/api-server/blob/develop/.github/workflows/release.yml has following warnings:
"service_account_key" has been deprecated. Please switch to using google-github-actions/auth which supports both Workload Identity Federation and Service Account Key JSON authentication. For more details, see https://github.com/google-github-actions/setup-gcloud#authorization
Tweet