2014-03-25 34 views
3

我在TFS中使用Workspace.Checkin命令獲取錯誤,因爲我試圖檢入的文件是Gated構建定義的一部分。有很多人問如何使用TFS API來覆蓋門控簽到。但是一個非常不同的問題是:如果我真的想要想要以編程方式執行門控檢入?我如何在TFS API中觸發這個?如何以編程方式觸發門控檢入?

我想要做的是:

  1. 執行一組未決的正常入住操作改變
  2. 接收有關推出
  3. 門控構建信息要麼訂閱完成該構建的事件,或輪詢構建,直到它完成。
  4. 如果構建成功並且提交了更改(如果可能,則獲取生成的更改集),繼續執行
  5. 如果構建失敗,請停止並報告錯誤。

我找不到任何答案來回答這個問題;也許是這樣一個邊緣案例,我是唯一足夠瘋狂想要這樣做的人。也就是說,我對此的需求是合理的。我唯一能想到的是,我需要通過門控簽入過程的低級功能: 1)遍歷構建定義以查看任何文件的路徑是否與任何文件的路徑一致任何門控版本的路徑。 2)如果存在交集,則創建待處理更改的擱置集合 3)使用擱置集合排隊新定義的門控定義 4)查詢構建定義並刷新信息,直到構建狀態完成 5)如果構建成功,取消保留待處理的更改,然後使用覆蓋登記。

但是,請注意,即使我執行這些步驟,最終的構建看起來也不會像門控構建。將發送策略重寫通知,讓別人知道構建實際執行的唯一方法是將這些信息包含在策略重寫註釋中。有沒有更直接的方法來做到這一點,使它看起來像任何其他門控構建?

回答

7

斯科爾多的帖子提示我能夠弄清楚如何做到這一點。這裏是代碼:

//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 (waitForGatedBuild) 
     { 
      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 
} 
3

我從來沒有過,但這個應該你有點幫助:

當使用工作區,這個籤你簽入的變化是通過門控構建保護,一個GatedCheckinException被拋出。這個例外應該有所有必要的信息來創建一個shelveset並用這個shelveset觸發正確的構建。例如,AffectedBuildDefinitions屬性應該包含門控構建定義的構建定義。

希望有所幫助。

+0

謝謝,這似乎有我需要的必要信息。我會試試這個! – paulyphonic

相關問題