しばやん雑記

Azure Serverless とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure Pipelines での .NET Core アプリケーションのビルド時に NU1101 エラーが出るのを回避する

少し前から Azure Pipelines の Windows ワーカーを使っている場合に、以下のような NuGet パッケージの復元時にエラーが出ることが増えてきました。

参照している NuGet パッケージが多いと大量に出るので結構邪魔ですし、マルチステージでビルドしている場合など、後半でエラーになれば最初からやり直しになるためストレスが溜まります。

f:id:shiba-yan:20210122023000p:plain

NuGet.org 上にしかないパッケージを何故か Visual Studio のオフラインのキャッシュから取ろうとして、エラーになっているという状態です。挙動としては謎ですが、最初に考えられるのは NuGet.org からパッケージのダウンロードが出来なかったという可能性です。

NuGet パッケージの復元時に出るエラーは NuGet の CDN が調子悪いことが原因なことが多いので、エラーの度に NuGet のステータスページを確認していますが、特に障害は報告されていない時にも発生します。

この問題は Visual Studio がインストールされることで、ローカルキャッシュも構築されることに原因があると考えられるので、Windows のワーカー以外では恐らく発生しないでしょう。

Visual Studio がインストールされている場合は、dotnet nuget list source の結果は 2 つ出てきます。

f:id:shiba-yan:20210122040114p:plain

それに比べて Ubuntu 上で確認してみると、公式の NuGet.org しか出てこないです。

f:id:shiba-yan:20210122040216p:plain

この差がエラーの原因と思われるので、Windows でもローカルのキャッシュを削除してしまいます。

対応方法は非常にシンプルでソリューションがあるディレクトリで dotnet new nugetconfig を実行して、新しく nuget.config を作成するだけで完了です。デフォルトの設定では以下のように元のソースをクリアしてから NuGet.org を追加するようになっています。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <!--To inherit the global NuGet package sources remove the <clear/> line below -->
    <clear />
    <add key="nuget" value="https://api.nuget.org/v3/index.json" />
  </packageSources>
</configuration>

<clear /> を忘れるとマージされてしまって意味が無いので注意が必要です。

他にも設定項目は用意されているので、興味がある方は以下のドキュメントを参照してください。

この修正を含めて Azure Pipelines でビルドを行うと、Visual Studio が持つキャッシュが使われなくなるため、よく分からない原因の復元エラーが出なくなりました。

常に NuGet.org からオンデマンドで取る割に早いので正常な時は気にもしませんが、CDN 周りで障害が発生した時には何も出来なくなってしまうので、そういった際に備えて Azure Pipelines 側でキャッシュを有効にしておくのもありだと思います。

キャッシュしたからといって常にビルドパフォーマンスが改善するという話ではなく、むしろオーバーヘッドの方が大きいのですが、障害時にも CI を回し続けられるというのはメリットとなるでしょう。

NuGet パッケージの復元に関しては Windows ワーカーの挙動に謎な部分が多いので、これからは常にリポジトリのルートには nuget.config を明示的に作成しておくことになりそうです。