4

チェックインしようとしているファイルが Gated ビルド定義の一部であるため、TFS で Workspace.Checkin コマンドを使用するとエラーが発生します。TFS API を使用してゲート チェックインをオーバーライドする方法を尋ねる人がたくさんいます。しかし、非常に異なる質問は次のとおりです。実際にゲート チェックインをプログラムで実行したい場合はどうすればよいでしょうか。TFS API でこれをトリガーするにはどうすればよいですか?

私がやりたいことは次のとおりです。

  1. 一連の保留中の変更の通常のチェックイン操作を実行します
  2. 起動されたゲートビルドに関する情報を受け取る
  3. そのビルドの完了イベントをサブスクライブするか、完了するまでビルドをポーリングします。
  4. ビルドが成功し、変更がコミットされた場合は続行します (可能であれば結果の変更セットを取得します)
  5. ビルドが成功しなかった場合は停止し、エラーを報告します。

この質問に答えるものは何も見つかりませんでした。おそらく、これをやりたいと思っているのは私だけが狂っているほどのエッジケースです。そうは言っても、これに対する私の必要性は正当です。私が把握できる唯一のことは、ゲート チェックイン プロセスの下位レベルの機能を実行する必要があるということです。1) ビルド定義を調べて、いずれかのファイルのパスがいずれかのパスと一致するかどうかを確認します。ゲートされたビルドのいずれかで。2) 交差が存在する場合、保留中の変更のシェルブセットを作成する 3) シェルブセットを使用して、ゲートされた定義の新しいビルドをキューに入れる 4) ビルド定義を照会し、ビルド ステータスが完了するまで情報を更新する 5) ビルドが成功した場合、保留中の変更の保留を解除してから、オーバーライドを使用してチェックインします。

ただし、これらの手順を実行しても、結果のビルドはゲート ビルドのようには見えないことに注意してください。ポリシー オーバーライド通知が送信されます。ビルドが実際に実行されたことを誰かに知らせる唯一の方法は、ポリシー オーバーライド コメントにそのような情報を含めることです。これを行うより直接的な方法で、他のゲートビルドのように見えるものはありますか?

4

2 に答える 2

8

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
}
于 2014-04-09T16:45:17.710 に答える
4

以前はやったことがありませんが、これは少し役立つはずです:

ワークスペースを使用して変更をチェックインし、このチェックインがゲート ビルドによって保護されている場合、GatedCheckinExceptionがスローされます。この例外には、シェルブセットを作成し、そのシェルブセットで正しいビルドをトリガーするために必要なすべての情報が含まれている必要があります。たとえば、AffectedBuildDefinitionsプロパティには、ゲートされたビルド定義であるビルド定義が含まれている必要があります。

それが役立つことを願っています。

于 2014-03-26T09:35:52.810 に答える