TFS 构建分支的服务器构建?

发布于 2024-08-13 04:50:24 字数 542 浏览 2 评论 0原文

我们有一个 TFS 2008 项目,有两个分支(“Main”和“NewFeature”)。 每个都是源代码的完整、独立的“副本”(变体)。

通过更改工作区映射,我们可以将任一变体映射到本地 PC,并且可以毫无问题地使用这两个分支。

但是,如果我设置映射以将构建服务器切换到 NewFeature 分支(就构建服务器而言,它应该简单地交换 NewFeature 源代码,而不需要更改任何其他内容),我会收到错误:

There is no working folder mapping for $/Main/Product.sln

即在构建时从 NewFeature 分支来看,尽管源代码中没有对该分支的任何引用,但仍在 Main 分支中查找某些内容。它似乎正在缓存一些对 Main 的引用?!

我已经完成了完全干净的构建(从服务器中删除了构建文件夹,并使用 /p:ForceGet=true 运行构建,以确保映射刷新到服务器,并且服务器上没有可能缓存该映射的文件工作区绑定),但这没有帮助。

有什么建议吗?

We have a TFS 2008 project with two branches ("Main" and "NewFeature").
Each is a complete, independent "copy" (variant) of the source code.

By changing the workspace mappings, we can map either variant onto our local PCs and have been working with both branches with no problems.

However, if I set up the mappings to switch our build server on to the NewFeature branch (which should simply swap in the NewFeature source code without changing anything else as far as the build server is concerned) I get errors:

There is no working folder mapping for $/Main/Product.sln

i.e. when it is building from the NewFeature branch, something is still looking in the Main branch, even though there are no references anywhere in the source code to this branch. It appears to be caching some reference to Main?!

I have done a completely clean build (deleted the build folder from the server and run the build with /p:ForceGet=true to make sure the mapping is flushed through to the server, and there are no files on the server that might cache the workspace bindings), but this doesn't help.

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

清秋悲枫 2024-08-20 04:50:24

验证:

  • $(SolutionToBuild) 在引用 Product.sln 时使用相对路径
  • $/NewFeature/.../TFSBuild.proj 和 $/NewFeature/Product.sln 之间的相对路径与 Main 分支中的相对路径相同。

/ 编辑/

注意,但是,$/Main 和 $/Branches/Feature 位于树层次结构中的同一级别并不重要。构建服务器上的本地路径也不重要。*重要的是每个分支下面的内容。如果内容内部一致,那么所有现有的构建脚本都应该无需修改即可工作。

有关我如何将所有内容结合在一起的具体示例,请参阅我过去的答案,例如:

我的方法不是唯一的方法,但我可以证明这一点它比我多年来遇到的所有其他变体都要好:)

*坦率地说,尝试对 Team Build 进行微观管理可能会比建议的 MSBuild 脚本重组更痛苦。为了可靠性,您必须放置 tfsbuildservice.exe.config 自定义 在版本控制下的某个地方...如果您拥有 > 1 个构建服务器(或者将来可能),那么您必须考虑更改部署策略...您最终会需要一个元 SCM 流程来管理您的 SCM 流程!

Verify that:

  • $(SolutionToBuild) uses a relative path when referencing Product.sln
  • the relative path between $/NewFeature/.../TFSBuild.proj and $/NewFeature/Product.sln is the same as it is in the Main branch.

/ EDIT /

Note, however, it's not important that $/Main and $/Branches/Feature live at the same level in the tree hierarchy. Nor should the local path on the build server matter.* All that matters is what's underneath each branch. If the contents is internally consistent then all of your existing build scripts should work without modification.

For concrete examples of how I like to tie everything together, see my past answers, e.g.:

My way is not the only way, but I can attest that it works better than all the other variations I've encountered over the years :)

*Frankly, trying to micromanage Team Build can become a lot more painful than the proposed restructuring to your MSBuild scripts. For reliability you have to place your tfsbuildservice.exe.config customizations under version control somewhere...if you own >1 build server (or might in the future) then you have to consider a change deployment strategy...you end up needing a meta-SCM process to manage your SCM process!

稀香 2024-08-20 04:50:24

从 TFS 2010 中的分支运行构建时我也遇到了这个问题。TFS 报告“$/Main/Product.sln 没有工作文件夹映射”解决方案是编辑构建定义,如下所示(我正在使用“默认模板”构建流程模板 - 我尚未使用自定义模板尝试过此操作):

  1. 转到构建定义的“流程”部分/选项卡。
  2. 展开1。必需并查找要构建的项目。确保此条目指向您正在构建的分支内的解决方案文件。
  3. 展开2。基本并查找自动化测试。将其指向正在构建的分支中的正确测试设置文件。

I also had this problem when running a build from a branch in TFS 2010. TFS was reporting that "There is no working folder mapping for $/Main/Product.sln" The solution turned out to be to edit the build definition as follows (I am using the "Default Template" build process template—I have not tried this with a custom template):

  1. Go to the Process section/tab of the build definition.
  2. Expand 1. Required and look for Projects to Build. Make sure this entry is pointing to the solution file inside the branch you are building.
  3. Expand 2. Basic and look for Automated Tests. Point this to the correct test settings file in the branch being built.
装迷糊 2024-08-20 04:50:24

好的,结果出来了 - 我找到了解决方法。

由于我们的遗留构建流程(构建、复制、混淆、构建自定义安装程序、复制到放置文件夹),我无法轻松地将分支放置在主分支旁边。它需要替换它。

因此,如果我有 Main 和 NewFeature,我希望取消映射 Main 并在其位置映射 NewFeature(即在构建服务器上使用“c:\Main”,然后只需更改出现在那里的源代码)

解决方案 #1 (最简单、最明显、最合乎逻辑的解决方案)是使用这些映射:

  • $/NewFeature -> c:\Main

预期结果:NewFeature 代码结构只是替换 Main,并且构建服务器不知道它位于不同的分支上。

实际结果:失败并出现“即使您没有使用 $/Main,但您还没有映射它”错误。

解决方案#2就是这样做:

  • $/Main -> c:\IgnoreThisFolder
  • $/NewFeature -> c:\Main

这有效(它抑制警告,从而允许使用 MSBuild 继续构建,而不知道它正在分支中构建)。然而,它很丑陋,并且构建不必要地获取所有主分支源代码。

解决方案#3(未经测试,尝试成本太高,除非我知道它会比#2更好)是:

  • 将所有源代码(从$/Main,$/Branches/Feature)移至$/Branches/Main 和 $/Branches/Feature 以获得一致的层次结构深度,并重写 MSBuild 脚本以使用这些新路径。
  • 希望我可以仅映射我需要的分支并编辑 TFSBuild.proj 以将其重定向到在该分支中构建。

    (编辑:是的,这很好用。我们现在重新组织了整个代码结构,以便所有内容(所有分支)都位于单个团队项目的共同根下,并且分支/构建不再是问题- 现在可以轻松完成我们需要的任何操作,技巧是将根文件夹插入到层次结构中,以便您可以在您喜欢的任何级别进行分支,以便我们可以传递分支。作为 MSBuild 的参数进行构建,因此现在可以轻松构建任何我们不想处理的分支,并且构建服务器仍然满意。)

总结
所有这些解决方案(使用技术术语)都很糟糕。您必须重新映射工作区(在本例中,这并不简单:需要 9 个映射条目,因此这是一件容易出错且乏味的事情),编辑 TFSBuild.proj,删除所有源代码,然后使用 / 运行构建p:ForceGet=true 在分支之间切换构建。所以切换分支大约需要一个小时。令人难以置信 - 最多需要几分钟!

我意识到我们的项目远未达到理想的设置,但我不敢相信在 TFS 中进行分支会如此困难(这在 SourceSafe、Accurev 和 Perforce 中是小菜一碟,那么为什么在 TFS 中如此痛苦呢?)。

其他人如何组织他们的 TFS 分支?如何在分支之间切换开发人员?如何在分支之间切换服务器构建?真的有必要这么痛苦吗?

OK, the results are in - I've found a workaround.

Due to our legacy build processes (build, copy, obfuscate, build custom installers, copy to drop folder), I can't easily place the branch alongside the main branch. It needs to replace it.

So, if I have Main and NewFeature, I wish to unmap Main and map NewFeature in its place (i.e. use "c:\Main" on the build server, and simply change the source code that appears there)

Solution #1 (the most simple, obvious and logical solution) is to use these mappings:

  • $/NewFeature -> c:\Main

Expected result: NewFeature code structure simply replaces Main, and the build server doesn't know it's on a different branch.

Actual Result: Failure with a "you haven't mapped $/Main even though you're not using it" error.

Solution #2 is to do this:

  • $/Main -> c:\IgnoreThisFolder
  • $/NewFeature -> c:\Main

This works (it suppresses the warning and thus allows the build to proceed with MSBuild unaware that it is building in a branch). However, it's ugly and the build gets all the Main branch source code unnecessarily.

Solution #3 (untested, too expensive to try unless I know it'll work much better than #2) is:

  • Move all the source code (from $/Main, $/Branches/Feature) to $/Branches/Main and $/Branches/Feature to get a consistent hierarchy depth, and rewrite the MSBuild script to work with these new paths.
  • Hope that I can then map in only the branch I need and edit TFSBuild.proj to redirect it to build in that branch.

    (Edit: Yes, this works well. We have now reorganised our entire code structure so that everything (all branches) is under a common root in a single Team Project, and branching/building is no longer a problem - it's easy to do whatever we need now. The trick is to insert a root folder into the hierarchy so that you can branch at any level you like. I've added a small tweak to the build script so that we can pass the branch to build as a parameter to MSBuild, so it's easy to build any variant now. Any branches we don't want to work on can just be cloaked and the build server remains happy.)

Summary
All these solutions (to use the technical term) suck. You have to remap the workspace (in this case, it's not simple: 9 mapping entries are required so it's an error prone and tedious thing to do), edit the TFSBuild.proj, delete all the source code, and run a build with /p:ForceGet=true to switch the build between branches. So it takes about an hour to switch branches. Unbelievable - it should take a few minutes at most!

I realise our project is far from ideally set up, but I can't believe it should be this difficult to branch in TFS (It was a piece of cake in SourceSafe, Accurev, and Perforce, so why so painful in TFS?).

How does everyone else organise their TFS branches? How do you switch developers between branches? How do you switch server builds between branches? Does it really have to be this painful?

沙与沫 2024-08-20 04:50:24

当您编辑构建定义时,有两个地方需要更改。

  1. 源设置 - 指向新项目位置
  2. 流程 - (有时需要一段时间才能加载,因此请耐心等待)在“必需”下,将“要构建的项目”位置更改为新解决方案。

希望这有帮助。

When you Edit the build definition there are two places that need to be changed.

  1. Source Settings - Point to your new project location
  2. Process - (This sometimes takes a while to load so be patient) Under Required, change the "items to build" location to the new solution.

Hope this helps.

默嘫て 2024-08-20 04:50:24

新更新

正如其他答案中所报告的那样,我找到了一种对于短期功能分支来说可行的解决方法,但它确实效果不佳。我又回到了这个问题,完整的解决方案非常简单:

在 TFSBuild.proj 中,路径基于 $(BuildProjectFolderPath)。此路径解析为服务器端(源代码控制路径),例如 $/Main - 而不是本地路径 (D:\ServerBuildFolder\Main)。

不幸的是,由于历史原因,我们的源代码被分成几个团队项目,这意味着一个“分支”被分成源代码管理中的几个分支文件夹(即 $/Main/Code 和 $/Libraries/Code)。您无法创建包含 $/Main 和 $/Libraries 的分支)。因此,我们必须使用工作空间映射将这些不同的片段从源代码管理重新组装回一个连贯的层次结构。

这意味着 Richard 是正确的 - 从 TFSBuild.proj 文件到 .sln 文件的相对路径不正确,因为 MSBuild/TFS 假设 .sln 位于同一团队项目和源代码控制层次结构中(因此正在寻找$/Main/Libraries.sln 而不是 $/Libraries/Libraries.sln)。

解决方案很简单:我将 $(BuildProjectFolderPath) 替换为文件的本地路径(例如 D:\ServerBuildFolder\Main),以便在“本地空间”中解析相对引用(在应用映射之后),并且MSBuild 现在正在顺利运行。

这个故事的寓意是:
1) 如果您希望在这些代码库之间进行任何类型的引用,请不要使用多个团队项目。不要误以为新的团队项目将在应用程序/库之间提供某种轻松的逻辑区别。事实证明,额外的项目只是一场管理噩梦——大量额外的问题却带来绝对的零效益。 (这都是在引擎盖下的一大堆共享,因此所有工作项和源代码管理文件夹在所有项目中仍然可见(!),但它增加了一些砖墙,使项目间链接非常成问题)

2)始终在团队项目源代码管理中创建一个根级文件夹,然后将其他所有内容放在该文件夹下。例如,对于项目“$/Main”,创建“$/Main/Root”,然后将源层次结构中的所有内容放入 Root 中。

通过遵循这些规则,您将来将能够对单个“根”文件夹进行分支,然后只需要一个分支和一个额外的工作区映射。这将帮助您避免过早秃顶。

(在我的辩护中,我一开始就会这样做 - 我正在使用旧设置。为了捍卫旧设置,这在纸面上听起来不错,但不是 Microsoft 支持的方法!)

New update:

As reported in the other answer, I found a workaround that was ok for a short-lived feature branch, but it really didn't work very well. I've since come back to the problem, and the full solution is ridiculously simple:

In the TFSBuild.proj, the path was based on $(BuildProjectFolderPath). This path resolves to a server-side (source control path) like $/Main - not a local path (D:\ServerBuildFolder\Main).

Unfortunately, for historical reasons our source code is split across several team projects, which means the one "branch" is fragmented into several branched folders in Source Control (i.e. $/Main/Code and $/Libraries/Code. You can't create a branch that contains $/Main and $/Libraries). We thus have to reassemble these disparate fragments from Source Control back into a coherent hierarchy using workspace mappings.

This means that Richard was spot on - the relative path from the TFSBuild.proj file to the .sln file was incorrect, because MSBuild/TFS is assuming that the .sln lies within the same Team Project and source control hierarchy (so was looking for $/Main/Libraries.sln instead of $/Libraries/Libraries.sln).

The solution is simple: I replaced $(BuildProjectFolderPath) with a local path (e.g. D:\ServerBuildFolder\Main) for the files, so that the relative reference was resolved in "local space" (after the mappings had been applied), and MSBuild is now running sweetly.

The moral of the story:
1) NEVER use more than one Team Project if there is any chance that you will ever wish to have any kind of reference between those code-bases. Don't be fooled into thinking that a new Team Project will offer some kind of painless logical distinction between applications/libraries. Extra projects have proven to just be an administration nightmare - loads of extra problems for absolutely zero benefit. (It's all one big shared pile under the bonnet, so all the work items and source control folders are still visible in all the projects (!), but it adds a few brick walls that make inter-project links very problematic)

2) Always create a single root-level folder in your Team Project source control, and then put everything else underneath that folder. e.g. For the project "$/Main", create "$/Main/Root" and then put everything from your source hierarchy inside Root.

By following these rules, you will be able to branch the single 'Root' folder in future, and will then only need a single branch and a single extra workspace mapping. This will help you avoid premature baldness.

(In my defence, I would have done it this way to begin with - I'm working with a legacy setup. In defence of the legacy setup, it sounds good on paper but just isn't a Microsoft-supported approach!)

孤单情人 2024-08-20 04:50:24

我收到这个错误,我所能理解的就是定义被破坏了或者其他什么。我只是重新设计了流程(重新添加了我试图构建的解决方案)并重新映射了工作区,它再次开始工作。 HTH。

I got this error and all I can fathom is that the definition became corrupt or something. I just redid the process stuff (re-added the solution I was trying to build) and remapped the workspaces and it started working again. HTH.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文