Chr*_*ian 20 tfs build-process tfs2010
我目前正在设置Team Foundation Server 2010,我在执行构建时发现了一个非常奇怪的行为:
情况解释:我们有2个分支机构
所有开发人员仅将代码签入到Development分支中.每天一次,构建管理器将一些更改集合并到Main分支.在开发阶段,每次检查都会持续构建.在主分支上,每天一次(在夜晚)触发构建.
现在假设变更集1-100在下午5点被合并到Main brach中,将变更集101作为合并操作.一些开发人员在5点钟之后检查变更集102-106进入开发分支.现在在晚上11点,每日构建将自动触发并在Main分支上运行.Main分支的最后一个变更集是变更集101.但是,构建详细信息显示变更集106:

我可以想象这种行为是有意的,因为如果你检查主分支上的变更集106,你实际上将获得变更集101的内容.但如果此构建摘要显示正确的数字,它将更具可读性.
问题1:有没有办法操纵SourceGetVersion信息的输出?也许通过构建过程模板?
TFS行为奇怪的第二种情况甚至更糟:当排队新的构建时,可以选择输入"获取版本"参数,如下图所示:

如果我现在点击"队列",则触发构建,并且AGAIN构建细节输出变更集106,尽管我专门设置它以获得变更集76.
问题2:这是一个错误吗?是否有修补程序或其他东西来解决这个问题?或者是否有必须设置的选项标志?
我希望有人知道更多.我真的不相信这是一个错误,因为它是一个至关重要的功能,其他人之前必须遇到它.
谢谢你的帮助!!基督教
编辑1
团队项目的文件夹结构是:
$项目名
构建只会拉动Main分支及其下方的所有内容.
编辑2
以下是构建定义中"工作区"选项卡的图片:

Chr*_*ian 22
最后我发现了发生了什么:
基本上可以在我的图片1中看到的变更集始终是整个团队项目集合的最新变更集.它是"IBuildDetails"类型的对象"BuildDetails"上的属性"SourceGetVersion".
我认为这是一个可以解决的错误:如果您将BuildDetails.SourceGetVersion(这是一个字符串)更改为其他值,那么构建摘要将显示更新的字符串.此外,它然后正确保存到收集数据库.
我为了添加正确的变更集号而做的是我创建了一个自定义构建活动,它将应该构建的分支作为输入参数.它输出正确的变更集.活动通过连接到TFS并下载历史记录来找出正确的变更集.然后它查看历史记录中的所有项目并输出最大的变更集编号.以下是该活动的代码:
using System.Activities;
using System.Collections;
using System.Net;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.Build.Client;
namespace SourceGetVersionActivity
{
[BuildActivity(HostEnvironmentOption.All)]
public sealed class SourceGetVersionActivity : CodeActivity<string>
{
// Define an activity input argument of type string
public InArgument<string> Branch { get; set; }
// If your activity returns a value, derive from CodeActivity<TResult>
// and return the value from the Execute method.
protected override string Execute(CodeActivityContext context)
{
// Obtain the runtime value of the Text input argument
string branch = context.GetValue(this.Branch);
ICredentials account = new NetworkCredential("Useranme", "password", "domain");
// connect / authenticate with tfs
TeamFoundationServer tfs = new TeamFoundationServer("http://tfs:8080/tfs/CollectionName", account);
tfs.Authenticate();
// get the version control service
VersionControlServer versionControl = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
IEnumerable changesets = versionControl.QueryHistory(branch, VersionSpec.Latest, 0, RecursionType.Full,
null, null, null, int.MaxValue, false, false, false, false);
int maxVersion = 0;
foreach (Changeset c in changesets)
{
if (c.ChangesetId > maxVersion)
{
maxVersion = c.ChangesetId;
}
}
return string.Concat('C', maxVersion.ToString());
}
}
}
Run Code Online (Sandbox Code Playgroud)
我尽快调用此活动(在GetBuild活动之后).
基本上在BuildProcessTemplate中我添加了一个Argument(字符串)"Branch",它需要填充一个指向正在构建的顶层文件夹的字符串.自定义活动将其作为输入并输出一个字符串,该字符串是正确的变更集ID.然后,BuildDetail.SourceGetVersion属性将被正确的变更集ID覆盖.
我觉得很奇怪,没有其他人似乎遇到过这个问题.我在互联网上找不到任何有同样问题的人.无论如何,我希望这个答案能帮助将来的其他人.
编辑 - 直接在Workflow Foundation中编写上述代码:
要使用更紧凑的代码获取正确的变更集并避免自定义活动,还可以直接使用Workflow Foundation.下面是"代码"(完全按照上面的C#代码完成):

(1)GetTeamProjectCollection活动获取当前集合.我将它保存在TeamProjectCollection变量中(参见图片底部).重要提示:需要在此序列中定义变量,如果在外部作用域中定义,则会发生错误:"无法序列化类型'Microsoft.TeamFoundation.Client.TfsTeamProjectCollection'.验证类型是否为公共类型且是否具有默认构造函数或实例描述符."
(2)Foreach"changeset"在"TeamProjectCollection.GetService(Of VersionControlServer).QueryHistory(Branch,VersionSpec.Latest,0,RecursionType.Full,Nothing,Nothing,Nothing,Integer.MaxValue,False,False,False).Cast( Of Changeset)()"Foreach循环的TypeArgument是"Microsoft.TeamFoundation.VersionControl.Client.Changeset".此表达式从集合中获取版本控制对象,将其称为"QueryHistory"方法,该方法返回包含所有更改集的IEnumerable.
(3)因此,我们迭代所有变更集并查看ChangesetId.然后将最大ChangesetId保存到变量"maxId".
(4)最后,BuildDetails.SourceGetVersion ="C"+ maxId.ToString()."C"表示该版本是变更集.
我希望有人发现这段"代码"很有用!
基督教
| 归档时间: |
|
| 查看次数: |
3859 次 |
| 最近记录: |