mcpField
N
nuget-trusted-publishing

nuget-trusted-publishing

github.com/dotnetクラウド・DevOps5.8k3.5k 回インストール1 日前に更新
リポジトリ

nuget-trusted-publishing について

GitHub Actions から OIDC を使い、長期 API キーに代わる NuGet Trusted Publishing を設定するスキルです。リポジトリの確認、パッケージのローカル検証、nuget.org のポリシー設定、ワークフローの作成や移行を案内します。

主な機能

  1. 01パッケージ種別とプロジェクト設定の確認
  2. 02dotnet pack によるパッケージ検証
  3. 03nuget.org ポリシー設定の案内
  4. 04GitHub Actions ワークフローの作成・移行
  5. 05OIDC 公開時の問題の診断

活用シーン

  1. 01NuGet パッケージの Trusted Publishing 設定
  2. 02API キーを使うワークフローからの移行
  3. 03新しい NuGet 公開ワークフローの作成
  4. 04dotnet ツールや MCP サーバーの公開

MCP 対応

このスキルは MCP サーバーの NuGet パッケージ公開を扱いますが、MCP サーバーやクライアント自体については説明していません。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dotnet/skills --skill nuget-trusted-publishing

インストール後、Claude Code で/nuget-trusted-publishingを入力して読み込まれたか確認します。

同梱ファイルreferences/package-types.mdreferences/publish-workflow.md

詳細

NuGet のトラステッド パブリッシングの設定

GitHub Actions リポジトリでNuGet のトラステッド パブリッシングを設定します。長期間有効な API キーを OIDC ベースの短期間有効なトークンに置き換えるため、ローテーションや漏えいを心配するシークレットは不要です。

前提条件

  • GitHub Actions — このスキルでは GitHub Actions の設定のみを扱います
  • nuget.org アカウント — トラステッド パブリッシング ポリシーを作成する権限が必要です

このスキルを使用するタイミング

次の場合にこのスキルを使用します。

  • NuGet パッケージのトラステッド パブリッシングを設定する
  • secrets.NUGET_API_KEY から OIDC ベースのパブリッシングに移行する
  • キーレスまたは安全な NuGet パブリッシングについて質問された
  • NuGet の公開ワークフローを新規作成する
  • 「NuGet API キーを削除する」または「NuGet/login を使う」よう依頼された
  • dotnet ツール、MCP サーバー、またはテンプレート パッケージのパブリッシングを設定する
  • NuGet/login@v1 または id-token: write について質問された

安全ルール

⚠️ 中断ルール:インフラストラクチャまたは認証の問題に対して修正を 1 回試みた後も、いずれかのフェーズが失敗する場合は、作業を中断してユーザーに確認してください。環境の問題に対して試行を繰り返さないでください。

⚠️ 確認なしに削除または上書きしないでください:API キーのシークレットの削除、タグやリリースの削除、ワークフローのステップの削除、パッケージ ID の変更は行わないでください。NuGet パッケージ ID は恒久的で、誤りを取り消すことはできません。

プロセス

新規リポジトリ向けの簡易手順:ユーザーの構成がシンプル(パッケージ化可能なプロジェクトが 1 つで、既存の公開ワークフローがない)な場合、複数ターンにわたる評価を必須にしないでください。フェーズをまとめ、すぐにワークフローを作成し、nuget.org のポリシーに関するガイダンス、ローカルでのパッケージ化の推奨、ファイル名の一致に関する警告を一度の応答に含めてください。以下の段階的なプロセス全体は、複雑なケースや移行シナリオ向けです。

フェーズ 1:評価

変更を加える前にリポジトリを調査し、結果を報告します。

  1. パッケージ化可能なプロジェクトを見つけて分類する — .csproj ファイルと Directory.Build.props を確認します(パッケージのメタデータはリポジトリ全体に設定されていることがよくあります)。次の順に分類します(先に一致したものが優先されます)。

    • <PackageType>Template</PackageType> → テンプレート
    • <PackageType>McpServer</PackageType> → MCP サーバー(dotnet ツールでもあります)
    • <PackAsTool>true</PackAsTool> → dotnet ツール
    • クラス ライブラリ(IsPackable=true または OutputType の指定なし)→ ライブラリ
    • <OutputType>Exe</OutputType> と <IsPackable>true</IsPackable> → アプリケーション パッケージ(ツールではありませんが、公開は可能です)
    • <OutputType>Exe</OutputType> があり、PackAsTool または IsPackable がない → 既定ではパッケージ化できません(公開する予定があるかユーザーに確認してください)
  2. 各プロジェクトの種類に応じて構成を検証する:

    種類必須項目
    すべてPackageId、Version(.csproj または Directory.Build.props 内)
    dotnet ツールPackAsTool(必須)。ToolCommandName(任意ですが推奨。既定値はアセンブリ名)
    MCP サーバーPackageType=McpServer、パッケージに .mcp/server.json を含める
    テンプレートPackageType=Template、コンテンツ ディレクトリ内に .template.config/template.json を配置
  3. 既存の公開ワークフローを探す — .github/workflows/ 内で dotnet nuget push、nuget push、または dotnet pack を探します。

  4. バージョンの一貫性を確認する — MCP サーバーの場合、.csproj の <Version> が server.json 内の両方のバージョン フィールド(ルートの version と packages[].version)に一致することを確認します。不一致があれば指摘します。

  5. 調査結果をユーザーに報告する:分類、欠落しているプロパティ、バージョンの不一致、既存のワークフローを報告します。複数プロジェクトを含むリポジトリでは、ワークフローを 1 つにするか、パッケージごとに分ける必要があるかを伝えます。不足部分の修正を提案し、プロジェクト ファイルを変更する前に ask_user を使用します。

❌ 種類ごとの詳細と必須プロパティについては、references/package-types.md を参照してください。

フェーズ 2:ローカルでの検証

nuget.org に手を加える前に、ローカルでパッケージを作成して検証してください。公開時のエラーは、取り消せないバージョン番号の消費につながります。

⚠️ この手順については、実行を延期する場合でも必ず伝えてください。 ユーザーには、「初回公開の前に、dotnet pack -c Release -o ./artifacts を実行して、.nupkg が正しく作成されることを確認してください。」と伝えます。

  1. dotnet pack -c Release -o ./artifacts — .nupkg が作成されることを確認します
  2. ツール/MCP サーバーの場合:./artifacts からインストールし、--help を実行してからアンインストールします
  3. ライブラリの場合:.nupkg の内容を確認します(zip ファイルです)
フェーズ 3:nuget.org のポリシー

このフェーズでは、ユーザーが nuget.org 上で操作する必要があります。正確な値を案内してください。

  1. リポジトリ所有者、リポジトリ名、公開に使用するワークフローファイル名を特定します。

    ❌ ポリシーには正確なワークフローファイル名(例:publish.yml または publish.yaml)が必要です。パスの接頭辞を付けず、ファイル名だけを指定してください。一致判定では大文字と小文字は区別されません。ワークフローの name: フィールドは使わないでください。

  2. 信頼された公開ポリシーを作成するようユーザーに案内します。

    nuget.org/account/trustedpublishing に移動 → Add policy

    • Repository Owner:{owner}
    • Repository:{repo}
    • Workflow File:{filename}.yml
    • Environment:release(ワークフローで environment: を使う場合のみ。それ以外は空欄のままにします)

    ポリシーの所有者は、個人アカウントまたは組織からユーザーが選択します。組織が所有するポリシーは、その組織が所有するすべてのパッケージに適用されます。

    プライベートリポジトリの場合、ポリシーは 7 日間「一時的に有効」になり、最初の公開が成功すると恒久的になります。

  3. GitHub Environment を作成するようユーザーに案内します(推奨ですが任意です。シークレットのスコープ設定と承認ゲートを利用できます)。

    リポジトリの Settings → Environments → New environment → release

    環境シークレットを追加します:Name = NUGET_USER、Value = nuget.org のユーザー名(メールアドレスではありません)

    任意で、承認ゲートとして Required reviewers を追加できます。

⚠️ ポリシーを作成したことをユーザーが確認するまでは、古い API キー/シークレットの削除を求めたり、ワークフローでの実行/公開を試みたりしないでください。確認前にワークフローファイルの草案を作成したり、提示したりすることは問題ありません。

フェーズ 4:ワークフローの設定

公開ワークフローを作成または変更します。ワークフローは必ず作成するか、回答内に提示してください。 nuget.org のポリシーがまだ確認できていなくても草案を作成したり提示したりできますが、確認が取れるまでは、実際に実行/公開したり古いシークレットを削除したりするよう案内しないでください。

新規作成: references/publish-workflow.md のテンプレートから publish.yml を作成します。使用する .NET のバージョン、プロジェクトのパス、環境名を調整してください。出力では id-token: write と NuGet/login@v1 に明示的に言及してください。

移行(API キーを使っている既存のワークフロー):既存のワークフローを直接変更します。

  1. 公開ジョブに OIDC の権限と環境を追加します。

    jobs:
      publish:
        environment: release
        permissions:
          id-token: write     # Required — without this, NuGet/login fails with 403
          contents: read      # Explicit — setting permissions overrides defaults
    
  2. プッシュの前に NuGet のログイン手順を追加します。

    - name: NuGet login (OIDC)
      id: login
      uses: NuGet/login@v1
      with:
        user: ${{ secrets.NUGET_USER }}  # nuget.org profile name, NOT email
    
  3. プッシュ手順で API キーを置き換えます。

    --api-key ${{ steps.login.outputs.NUGET_API_KEY }} --skip-duplicate
    
  4. 確認:ユーザーに公開を実行してもらい、パッケージが nuget.org に表示されることを確認します。

❌ 信頼された公開が確認されるまでは、古い API キーのシークレットを削除しないでください。削除すると元に戻せません。確認を待ってください。

トラブルシューティング

問題原因対処方法
NuGet/login 403id-token: write が設定されていないジョブの権限に追加します
"no matching policy"ワークフローのファイル名が一致しないnuget.org で正確なファイル名を確認します
プッシュが未承認パッケージがポリシーアカウントの所有物ではないnuget.org でポリシーの所有者を確認します
トークンの期限切れプッシュの1時間以上前にログインステップを実行しているNuGet/login をプッシュの直前に移動します
ポリシーが「一時的に有効」プライベートリポジトリで、初回の公開が保留中7日以内に公開します
プッシュ時の already_exists同じバージョンを再実行している--skip-duplicate を追加します
GitHub Release 422タグに対するリリースが重複している競合するリリースを削除します(先に確認してください)
再実行で誤った YAML が使用されるgh run rerun は元のコミットの YAML を再実行する障害要因を削除して再実行します — タグの付け直しは絶対に行わないでください

⚠️ 1回の修正を試しても障害が解消しない場合は、作業を中止してユーザーに確認してください。

参考資料

コメント