TFS和本地构建差异

TFS和本地构建差异,tfs,Tfs,在我们的解决方案中,我们有一个“.nuget”文件夹。此文件夹不包含NuGet.exe。相反,我们始终确保在生成时使用NuGet.targets中的以下属性下载最新的NuGet.exe: <DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe> true 这在开发人员的机器上非常有效。始终下载最新版本的NuGet.exe 不幸的是,TFS Build Serv

在我们的解决方案中,我们有一个“.nuget”文件夹。此文件夹不包含NuGet.exe。相反,我们始终确保在生成时使用NuGet.targets中的以下属性下载最新的NuGet.exe:

<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe>
true
这在开发人员的机器上非常有效。始终下载最新版本的NuGet.exe

不幸的是,TFS Build Server上出现了一个问题——出于安全原因(我无法控制),它无法访问Internet,因此无法根据需要下载NuGet.exe。相反,它有一个我们必须使用的NuGet.exe的本地副本(服务器本地)

接下来的问题是,我如何告诉Visual Studio生成系统始终从Internet检索NuGet.exe,并告诉TFS生成系统使用NuGet.exe的本地副本?我确信这与构建变量或类似的东西有关


如果您有任何建议,我们将不胜感激。

要执行此操作,您需要将Nuget.exe签入.Nuget文件夹。然后,本地工作区和生成服务器都可以访问并使用相同的版本

Visual Studio将在您需要更新NuGet时通知您

注意:在生成服务器上没有internet访问不是安全限制。这是黑暗时代的一项严厉政策,需要重新思考。理想情况下,您不希望将任何二进制资产签入SCM,而是在构建时下载它们


这是最佳实践,而您的IT政策正迫使您出现功能障碍。

答案,至少是我的答案,原来很简单

“.nuget”文件夹包含“nuget.targets”,如果需要,可以下载nuget.exe。有一个DownloadNuGet任务,其中包含一段C#代码,用于下载NuGet.exe。如前所述,我们的TFS服务器无法访问Internet,因此此代码段总是引发异常

我的解决方案是向异常处理程序添加一些代码,以便将NuGet.exe从服务器的已知位置复制到需要的“.nugget”文件夹

使用此修改的DownloadNuGet,NuGet.exe将在开发人员的计算机上下载,并将从TFS服务器上的已知位置提取

以下是更新的DownloadNuGet任务,其中包含大量日志记录:

<UsingTask TaskName="DownloadNuGet" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
  <ParameterGroup>
    <OutputFilename ParameterType="System.String" Required="true" />
  </ParameterGroup>
  <Task>
    <Reference Include="System.Core" />
    <Using Namespace="System" />
    <Using Namespace="System.IO" />
    <Using Namespace="System.Diagnostics" />
    <Using Namespace="System.Net" />
    <Using Namespace="Microsoft.Build.Framework" />
    <Using Namespace="Microsoft.Build.Utilities" />
    <Code Type="Fragment" Language="cs">
     <![CDATA[
        try {
           OutputFilename = Path.GetFullPath(OutputFilename);

           Log.LogMessage("***** Downloading latest version of NuGet.exe to: \"" + OutputFilename + '"');
           WebClient webClient = new WebClient();
           webClient.DownloadFile("https://nuget.org/nuget.exe", OutputFilename);
           Log.LogMessage("***** Latest version of NuGet.exe was successfully downloaded: " + OutputFilename);

           return true;
        } catch (Exception ex) {
           // This exception handling code is what's new.
           Log.LogMessage("***** Exception while downloading latest versioln of NuGet.exe: " + ex.GetType() + " ==> " + ex.Message);
           Log.LogMessage("***** Attempting to find NuGet.exe in C:\\NuGet folder.");

           FileInfo nuGetExeFile = new FileInfo(@"C:\NuGet\NuGet.exe");
           nuGetExeFile.CopyTo(OutputFilename, true);

           String formattedFileLength = String.Format("{0:N0}", nuGetExeFile.Length);
           Log.LogMessage("***** NuGet.exe has been copied to \"" + OutputFilename + "\", File size: " + formattedFileLength);

           return true;
        }
     ]]>
    </Code>
  </Task>
</UsingTask



为什么希望本地和团队生成运行不同版本的NuGet?我们不希望本地和团队生成使用不同版本的NuGet.exe。我们希望两种环境始终使用最新版本。对于开发人员来说,这很简单:只需将DownloadNuGetExe属性设置为true,正如我在原始帖子中所示。但是,团队构建更为困难,因为计算机无法访问Internet,因此无法下载最新版本的NuGet.exe。相反,TFS管理员将最新版本的NuGet.exe放在一个众所周知的位置。正如我在原始帖子中所说,我们在“.NuGet”文件夹中没有NuGet.exe。我们不想把它放在那里,也不想登记,因为:1。每个项目都将冗余地签入一个公共文件(NuGet.exe)并。。。2.最终,一些项目会签入更新版本的NuGet.exe,可能会导致存储库中出现多个版本的NuGet.exe。不幸的是,这是解决您问题的推荐和官方解决方案。我对这些答案感到有点惊讶。对我来说,官方的解决方案不是签入与NuGet相关的任何东西(除了“.NuGet\NuGet.config”文件之外),因此VS不会尝试检查“包”文件夹中。也就是说,从VS 2013和TFS 2013开始。NuGet团队希望从MSBuild进程中获得与NuGet相关的工作,hecne NuGet.targets已被弃用。David Ebbo通过指向NuGet官方网站的链接解释了这一切。正确-但是,您声明在生成服务器上没有internet访问,这否定了开箱即用的解决方案n、 另一个现成的解决方案是使用2013年以前的方法。每当更新NuGet.targets文件时,下面的解决方法都会中断。请记住,每当visual studio更新工具时,此方法都会中断。不要依赖此方法。