MSBuild:部署未包含在项目中的文件

8
我有一个Web项目的预构建事件,使用nodejs来压缩和合并javascript文件,这会创建一个名为BuiltScripts的文件夹,它在scripts文件夹内是一个副本,唯一的区别是文件被压缩了。当我进行部署时,我想发布scripts文件夹,包括其中的BuiltScripts文件夹。为实现这一目标,我已将BuiltScripts文件夹添加到了项目中。但这不是一个理想的解决方案,因为:
  1. 我必须检出BuiltScripts文件夹才能构建,因为其下的文件在源代码控制下是只读的。这在签入时会带来麻烦,因为我不得不检出很多文件。
  2. 当我向项目中添加新文件时,我必须确保记住将其添加到BuiltScripts文件夹中,否则构建版本的文件不会被部署。
  3. 在构建服务器上,BuiltScripts文件夹中的文件也是只读的,所以我的构建将失败。
  4. 同名的两个副本文件会影响文件搜索和基于文本的搜索。
我想让构建服务器在预构建步骤中构建并压缩javascript文件,但我不想将BuiltScripts文件夹添加到项目中。然而,当构建服务器在结束时打包项目时,我希望它能将BuiltScripts文件夹与构建过程的输出一起复制。我该如何实现这一点?

你在使用什么进行部署/发布 - 这是标准的msbuild目标还是你自己做了一些定制? - Alexey Shcherbak
@AlexeyShcherbak MSBuild,TFS,没有自定义内容。 - Aran Mulholland
@AlexeyShcherbak 为什么你说它已经过时了? - Aran Mulholland
我只是不明白为什么要在这里发布与Sayed博客文章非常相似的答案。我提供了他非常详细的帖子链接,我认为你的问题已经在那里得到了回答。这就是为什么我认为我的自己的“尚未发布”的答案是不必要的原因。 - Alexey Shcherbak
@AlexeyShcherbak 好的,我看错了,以为你在说他的帖子已经过时了。 - Aran Mulholland
显示剩余2条评论
3个回答

8

不要使用项目属性的预构建事件(我认为这是您的意思),而是在.csproj/.vbproj文件中重写BeforeBuild目标。

<Project ...>
  ...
  <Target Name="BeforeBuild">
    <!-- Create the 'BuildScripts' directory. -->
    <!-- The $(IntermediateOutputPath) reference the 'obj' folder, which I like to -->
    <!-- use for these kinds of things. -->
    <MakeDir Directories="$(IntermediateOutputPath)BuiltScripts">
      <Output PropertyName="BuildScriptsPath" TaskParameter="DirectoriesCreated" />
    </MakeDir>
    <!-- Execute the javascript minifier. -->
    <Exec Command="..." />
    <!-- Create an item group for the minified scripts so we manipulate the target path. -->
    <CreateItem Include="$(BuildScriptsPath)\*.js">
      <Output ItemName="BuiltScripts" TaskParameter="Include" />
      <Output ItemName="FileWrites" TaskParameter="Include" />
    </CreateItem>
    <!-- Add the minified scripts to the Content item group, -->
    <!-- which the deployment MSBuild inspects for files to deploy. -->
    <CreateItem Include="@(BuiltScripts)"
      AdditionalMetadata="TargetPath=scripts\%(Filename)%(Extension)">
      <Output ItemName="ContentWithTargetPath" TaskParameter="Include" />
    </CreateItem>
  </Target>
  ...
</Project>

如果文件没有部署到正确的目录,您可能需要调整CreateItem任务输出的Content项组的形状。请注意,我使用了项目变换来生成目标路径scripts\YourScript.js
另外,请注意第一个CreateItem任务将输出内容放入名为“FileWrites”的项组中。我发现Clean目标检查该项组以确定要删除哪些文件。
将该XML代码放入项目文件中的<Import>元素之后,就可以直接使用了而不需要提交至源代码控制系统,即使是构建服务器也会很高兴。

你可以添加一步,删除之前 BuiltScripts 文件夹的内容吗? - Aran Mulholland
我运行了我的示例代码,看起来 IncrementalClean 目标将自动删除这些文件,因为它们包含在 FileWrites 项目组中,当您删除 .js 文件并且不希望它再被部署时,这非常有用。 - Matt

0

我有类似的需求,但只涉及将现有文件添加到部署包中,而不是作为构建的一部分生成它们。我发现这个页面上的技术很有用。


0

你可不可以使用一个 post-build 事件来运行一个脚本,实现你想要的功能?我用了一个这样的事件来将我的输出文件移动到与项目完全无关的位置。无论是普通的批处理、VBScript/JScript 还是 PowerShell,你都可以做任何你想做的事情。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接