我在 TFS 中使用 Workspace.Checkin 命令时遇到错误,因为我尝试 checkin 的文件是 Gated 构建定义的一部分。有很多人询问如何使用 TFS API 覆盖门控 checkin 。但一个非常不同的问题是:如果我真的希望 以编程方式执行门控 checkin ,该怎么办?如何在 TFS API 中触发它?

我想做的是:

  • 执行一组未决更改的正常 checkin 操作
  • 接收有关已启动的门控构建的信息
  • 订阅该构建的完成事件,或轮询构建直到完成。
  • 如果构建成功并提交更改,则继续(如果可能,获取结果更改集)
  • 构建不成功则停止,并报错。

  • 我找不到任何东西来回答这个问题;也许这是一种极端情况,以至于我是唯一一个疯狂到想要这样做的人。也就是说,我对此的需求是合理的。我唯一能想到的是,我需要通过门控登记流程的低级功能:
    1) 遍历构建定义以查看任何文件的路径是否与任何门控构建中的任何路径一致。
    2)如果存在交集,则创建待定更改的搁置集
    3) 使用搁置集对门控定义的新构建进行排队
    4)查询构建定义并刷新信息,直到构建状态完成
    5) 如果构建成功,则取消搁置挂起的更改,然后使用覆盖检入。

    但是,请注意,即使我执行了这些步骤,生成的构建也根本不会像门控构建。将发送策略覆盖通知,让某人知道实际执行了构建的唯一方法是将此类信息包含在策略覆盖注释中。有没有更直接的方法来做到这一点,让它看起来像任何其他门控构建?

    最佳答案

    在 Scordo 的帖子的提示下,我能够弄清楚如何做到这一点。这是代码:

    //Initialize connection to server
    TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(ServerAddress));
    try
    {
        tpc.EnsureAuthenticated();
    }
    catch (Exception e)
    {
        System.Environment.Exit(-1);
    }
    VersionControlServer vcServer = tpc.GetService<VersionControlServer>();
    IBuildServer buildServer = tpc.GetService<IBuildServer>();
    
    //.
    //.
    //Program logic goes here...
    //.
    //.
    
    //Get the workspace and the respective changes
    Workspace workspace = vcServer.TryGetWorkspace(LocalProjectPath);
    PendingChange[] changes = workspace.GetPendingChanges();
    
    //Perform the check-in
    bool checkedIn = false;
    
    //Either wait for the gated check-in or continue asynchronously...
    bool waitForGatedCheckin = true;
    
    //Attempt a normal check-in
    try
    {
        //First, see what policy failures exist, and override them if necessary
        CheckinEvaluationResult result = workspace.EvaluateCheckin(CheckinEvaluationOptions.All,
        changes, changes, "Test", null, null);
    
        //Perform the check-in, with overrides if necessary, including Work Item policies
        //or include additional code to comply with those policies
        PolicyOverrideInfo override = null;
        if (result.PolicyFailures != null)
        {
            override = new PolicyOverrideInfo("override reason", result.PolicyFailures);
        }
        workspace.CheckIn(changes, comment, null, null, override);
        checkedIn = true;
    }
    catch (GatedCheckinException gatedException)
    {
        //This exception tells us that a gated check-in is required.
        //First, we get the list of build definitions affected by the check-in
        ICollection<KeyValuePair<string, Uri>> buildDefs = gatedException.AffectedBuildDefinitions;
    
        if (buildDefs.Count == 1)
        {
            //If only one affected build definition exists, then we have everything we need to proceed
            IEnumerator<KeyValuePair<string, Uri>> buildEnum = buildDefs.GetEnumerator();
            buildEnum.MoveNext();
            KeyValuePair<string, Uri> buildDef = buildEnum.Current;
            String gatedBuildDefName = buildDef.Key;
            Uri gatedBuildDefUri = buildDef.Value;
            string shelvesetSpecName = gatedException.ShelvesetName;
            string[] shelvesetTokens = shelvesetSpecName.Split(new char[] { ';' });
    
            //Create a build request for the gated check-in build
            IBuildRequest buildRequest = buildServer.CreateBuildRequest(gatedBuildDefUri);
            buildRequest.ShelvesetName = shelvesetTokens[0]; //Specify the name of the existing shelveset
            buildRequest.Reason = BuildReason.CheckInShelveset; //Check-in the shelveset if successful
            buildRequest.GatedCheckInTicket = gatedException.CheckInTicket; //Associate the check-in
    
            //Queue the build request
            IQueuedBuild queuedBuild = buildServer.QueueBuild(buildRequest);
    
            //Wait for the build to complete, or continue asynchronously
            if (waitForGatedCheckin)
            {
                while (!queuedBuild.Build.BuildFinished)
                {
                    //Get the latest status of the build, and pause to yield CPU
                    queuedBuild.Refresh(QueryOptions.Process);
                    System.Threading.Thread.Sleep(1000)
                }
                if (queuedBuild.Build.Status == BuildStatus.Succeeded)
                {
                    checkedIn = true;
                }
            }
        }
        else
        {
            //Determine a method for specifying the appropriate build definition
            //if multiple build definitions are affected
        }
    }
    catch (CheckinException checkinException)
    {
        //Handle other checkin exceptions such as those occurring with locked files,
        //permissions issues, etc.
    }
    
    if (checkedIn)
    {
        //Additional logic here, if the check-in was successful
    }
    

    关于tfs - 如何以编程方式触发门控登记?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22644561/

    10-13 05:53