🥱

めんどくさがりなりに set-output から $GITHUB_OUTPUT を使うように置き換える

2022/11/05に公開

2022 年 10 月 11 日に以下の記事が GitHub Changelog に公開されました。

https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/

結果を別ジョブやステップで利用できるようにするため、従来は ::set-output::save-state から始まる文字列を echo していました。セキュリティ向上の観点から 2023 年 6 月 1 日以降これらを無効化するとのアナウンスでした。
ランナーバージョン 2.298.2 以降を利用したアクションの結果ページを見ると、以下のようなアノテーションが発生していることが確認できます。

これを解決するために、$GITHUB_OUTPUT$GITHUB_STATE を使うようワークフローを修正しなければならないのですが、大量のプロジェクトを管理している場合これを修正するのは非常に骨が折れます。

だったら、半自動化して楽に作業しようというのが今回の記事のネタです。めんどくさがりなので。

環境

  • Windows 10 21H2 (Build 19044.2130)
  • PowerShell 7.2.7
  • Python 3.10.4
  • janeklb/gh-search 0.8.3
  • Windows Subsystem for Linux (v2)
    • Ubuntu 20.04.3 LTS

作業方針

やるべきことは「対象となるリポジトリ・ファイルの抽出」と「ワークフローファイルの修正」です。

対象となるリポジトリ・ファイルの抽出についてですが、できれば公式の GitHub CLI を使いたいです。しかしドキュメントを眺める限り「ソースコードを検索する機能」は GitHub CLI にない[1]ので、別のアプローチで収集する必要があります。
GitHub Code Search などを使ってちまちま作業する手段もあるのですが、ここではなるべく楽に作業したいので janeklb/gh-search を使おうと思います。[2]

ワークフローファイルの修正についてですが、これは sed を使って置き換えてしまうのが楽だと思っています。
ただ失敗の可能性を考慮して自動処理前にブランチを切っておくことと、コミット自体は Visual Studio Code などを使って手動で実行します。

作業

作業方針を簡単に決めたので、それに沿って作業をします。

対象となるリポジトリ・ファイルの抽出

とりあえず、janeklb/gh-search をインストールします。

pip install gh-search

janeklb/gh-search を使うにあたって、Personal access token が必要です。
Personal access token の作成ページ から作成します。7 日間限定で repo に権限を振ればよさそうです。
Fine-grained personal access token でもかまいません。

取得した Personal access token は環境変数 GITHUB_TOKEN に設定しておきます。

$env:GITHUB_TOKEN="ghp_XXXXXXXXXXXXXXXXXXXXXXXXXX"

次に対象とするユーザーやオーガニゼーションを決めます。ここでは私のアカウント book000 と個人用オーガニゼーション tomacheese を対象とすることにします。
これらに対して gh-search コマンドを使って検索を実施しましょう。

gh-search user:book000 set-output -o json > book000.json
gh-search user:tomacheese set-output -o json > tomacheese.json

-o json をつけることで JSON として吐き出すことができるので、これをファイルに流し込みます。
結果は JSON 配列になっているので、作業しやすいように加工しましょう。ここでは Notion で見たかったので Python を使って CSV に変換します。

merged.csv を使って Notion に CSV インポートしてゴニョゴニョしてとりあえず見やすくしておきました。

ワークフローファイルの修正

とりあえずワークフローを sed で修正するシェルスクリプトを作ります。

#!/bin/sh
sed -i -E 's/echo "::set-output name=(.+?)::(.+?)"/echo "\1=\2" >> $GITHUB_OUTPUT/g' .github/workflows/*.yml
sed -i -E 's/echo "::save-state name=(.+?)::(.+?)"/echo "\1=\2" >> $GITHUB_STATE/g' .github/workflows/*.yml

これをアクセスしやすい場所(C:\replace-set-output.sh とか…)に一時的に置いておきます。

次に、各リポジトリ下で打つコマンドを作ります。
ci/set-output ブランチをチェックアウトして、WSL の Ubuntu で先ほど作成したシェルスクリプトを実行するコマンドをワンライナーで作ってしまいましょう。

git checkout -q -b ci/set-output upstream/master ; git checkout -q -b ci/set-output upstream/main ; git checkout -q -b ci/set-output origin/master ; git checkout -q -b ci/set-output origin/main ; bash -c "/mnt/c/replace-set-output.sh"

ci/set-output ブランチは upstreamoriginmastermain から作成させます。
git checkout は元ブランチがない場合や作成先ブランチがすでにある場合はブランチを作成しないので、この書き方をすれば upstream/master, upstream/main, origin/master, origin/main の順番で元ブランチがあれば ci/set-output ブランチを作ります。

あとはこれを各リポジトリで実行し、実行結果を Visual Studio Code で確認したうえでコミットを作成・Pull Request を作成すれば楽に作業できます。

GitHub Pull Requests and Issues 拡張機能をいれれば、Visual Studio Code 上で Pull Request も作成できてさらに楽ちん。


ここまで記事を書いて、azu さんがマイグレーションツールを作っていることを Twitter で知りました。npx set-env-to-github_env コマンドを使うことで楽に修正できるのでこっちの方が良さそうです。

https://twitter.com/azu_re/status/1585562486052630528

https://github.com/azu/set-env-to-github_env

脚注
  1. GitHub CLI の search マニュアル によれば、検索できるのは Issue と PR とリポジトリだけなようです。 ↩︎

  2. GitHub CLI に実装されていない以上、どんな悪いことをしてコード検索なんてしているんだろうと思ったら、GitHub の Search code REST API を使っているだけでした。てっきりスクレイピングでもしているのかと…。 ↩︎

GitHubで編集を提案

Discussion