2026年8月31日月曜日

【GitHub Actions】シークレットを別のリポジトリに migrate するツールを作った

みなさん、GitHub Actions のシークレットの管理ってどうしてますか?
設定された内容をどこか別の管理場所で保存している場合もあると思いますが、設定するだけで何もしてない場合も多いのではないでしょうか。

登録されたシークレットの中身は基本的に閲覧することはできません。シークレットの操作は gh secret コマンドから行なうことも可能ですが、当然これらも delete / list / set サブコマンドしかなく、get はできません。
GitHub Actions に詳しい人なら、中身を確認する方法はわかるのではないかと思いますが、面倒ではあります。

ただ、シークレットの中身を閲覧できなくても、困ることはほとんどないでしょう。

https://github.com/srz-zumix/gh-secret-kit
今回「シークレットを別のリポジトリに migrate するツール」の紹介をするわけですが、なぜこれが必要になったのか、から説明します。

なぜこれが必要か

きっかけはとあるリポジトリのホスト移動が必要になったことです。
このようなケースは GitHub の公式ツールでサポートされており、 gh-gei を使うことで migrate することができます。
About migrations between GitHub products with GitHub Enterprise Importer - GitHub Docs

しかしながら、サポートされている移行対象のデータは限定的です。
プルリクエストなどは移行できますが、Rulesets や Teams など結構よく使う機能も移行対象外になっています。
当然、シークレットも移行できません。

Rulesets や Teams などは設定を閲覧することができますし、API で取得・設定することも可能なため、それらを移行するのは(手動でも自動でも)難しくはないでしょう。AI に依頼すれば直接やったり、スクリプトを書いたりしてくれる気がします。
しかし、シークレットは簡単には閲覧することができず、リポジトリや Organization に設定されたシークレットを1つ1つ手動で再設定するのは、とても面倒です。
Organization の移動が大量にある場合は考えたくないですね。

でも、シークレットの中身を知る方法がないわけではありません。GitHub Actions のジョブの中では中身を使っているわけですから。
シークレットの移行が自動でできる可能性は 0 ではない。ということで作成をしました。

使い方

使い方はドキュメントにまとめてあるので、そちらを参照してください。
また、Skills も用意してあります。
gh-secret-kit をインストールしたのち、gh secret-kit skills install することでインストールできます。

仕組み
さて、仕組みですが基本は単純です。
移行元で実行されたジョブの中から移行先にシークレットを設定します。
ジョブからはシークレットの内容を知ることができるわけですから、これは実現可能ですよね。

しかし、対象のシークレットはワークフローに静的に記載されている必要があります。
なので、シークレットをリストアップしてワークフローを生成し、その生成したワークフローを push してそれを実行します。

ワークフローを実行する方法はいくつかありますが、デフォルトブランチにワークフローが必要なものと、トピックブランチにあれば良いものので大きく分けられます。
今回 GitHub のリポジトリ移行という目的があるので、デフォルトブランチを書き換えるのは避けたいです。CLI からワークフローを実行するのであれば workflow_dispatch が都合が良いのですが、これはデフォルトブランチにワークフローが必要なため、今回は pull_request イベントの labeled アクティビティで発火させるようにしています。
なぜ labeled なのかというと、任意のタイミングでコミットに紐づかずに再実行可能にしたかったからです。
(ちなみに、デフォルトブランチを変更することなく、workflow_dispatch を実行する方法はあるのですが、実装当時に知らなかったのでこのやり方になっています)

これで CLI からシークレット移行ワークフローを実行させることができるようになります。

ここで問題になるのがアクセス権限です。
移行元のアクセス権限は問題ないと思いますが、移行元に「移行先のシークレット設定が可能なシークレット」が存在しているとは考えにくいです。
このために設定するという手段もあると思います。gh-secret-kit では、どのシークレットを使うか指定できるようになっているので、そのケースにも対応はしています。
しかし、そのシークレットも移行対象となり移行先で消す必要が出てきます。(まぁ、そのための除外オプションもあるのですが)

そうではなく、移行担当者は移行元・移行先どちらの admin 権限を持っているはずなので、担当者の環境でジョブを実行し、担当者の gh auth token を使えば、移行に必要な権限を確実に得ることができるわけです。

GitHub Actions は Self-hoted runner として、好きな環境でランナーを起動することが可能です。ScaleSet API を使って CLI 実行者のローカルマシンでランナーを立ち上げ、専用のランナーラベルを指定してワークフローを実行します。
これにより、既存のランナーを使うことなく移行が可能になるため、開発に影響を与えずに移行が可能になりました。

さいごに
gh-secret-kit は Organization / Repository / Environments のシークレットを移行することが可能ですが、Agents / Codespaces / Dependabot のシークレットには対応していません。
Agents と Codespaces は対応できなくもないかも?しれないですが、Dependabot は無理なような気がしています。もしアイディアあれば教えてください。

あと、このブログを書いてて実はもっと簡単な手順で対応も可能な気がしてきたので、試してみようかなと思います。

これを使う機会はそうそうない気がしますが、誰かの役に立てば幸いです。




0 件のコメント:

コメントを投稿