2009-05-11 10 views
1

私たちは、ビルドの自動化の一環として継続的な統合を使用しています。すべてのチェックイン時に、tfs build serverはプロジェクトをビルドし、成功するとWebサーバーにデプロイします。TFS:ビルドが成功したら、自動的に一致するワークアイテムを自動的に閉じることができますか?

ビルドに失敗すると、ビルドの失敗の詳細を含む新しいバグが自動的に作成されます。

CIとサーバー上のアクティビティにより、ビルドが再び成功する前に、10または20の失敗作業項目が発生する可能性があります。

私は2つの選択肢があります。ビルドプロセスにビルドの失敗のためのオープンな作業項目がすでに存在するかどうかを確認し、その詳細を追加するか、または、ビルドサーバーがビルド失敗アイテムのすべてを自動的に閉じるようにしたい場合は、それが再び動作を開始します。

アイデア?

答えて

2

これらのオプションのいずれかを実行するMSBuildタスクを作成できます。ここでは、私があなたの作業項目やプロセスの詳細を知らないので、それを変更しなければならないので、私があなたを始められるように使用する同様のコードがあります。

このコードは、ビルドに関連付けられたすべての作業項目を取り込み、そのステータスを更新します。

最初のオプションを選択した場合、UpdateWorkItemStatusメソッドを変更して既存のWIを更新することができます。 2番目の方法では、入力として受け取るのではなく、以前のビルドをルックアップする必要があるため、もう少し作業を行う必要があります。

using System; 
using System.Collections.Generic; 
using System.Text; 
using Microsoft.Build.Utilities; 
using Microsoft.TeamFoundation.Client; 
using Microsoft.TeamFoundation.WorkItemTracking.Client; 
using Microsoft.Build.Framework; 
using Microsoft.TeamFoundation.Build; 
using Microsoft.TeamFoundation.Build.Client; 

namespace Nowcom.TeamBuild.Tasks 
{ 
    public class UpdateWorkItemState: Task 
    { 
     private IBuildDetail _Build; 

     private void test() 
     { 
      TeamFoundationServerUrl = "Teamserver"; 
      BuildUri = "vstfs:///Build/Build/1741"; 
      Execute(); 
     } 

     public override bool Execute() 
     { 
      bool result = true; 

      try 
      { 
       TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer(TeamFoundationServerUrl, new UICredentialsProvider()); 
       tfs.EnsureAuthenticated(); 

       WorkItemStore store = (WorkItemStore)tfs.GetService(typeof(WorkItemStore)); 
       IBuildServer buildServer = (IBuildServer)tfs.GetService(typeof(IBuildServer)); 
       _Build = buildServer.GetAllBuildDetails(new Uri(BuildUri)); 
       //add build step 
       IBuildStep buildStep = InformationNodeConverters.AddBuildStep(_Build, "UpdateWorkItemStatus", "Updating Work Item Status"); 


       try 
       { 
        Log.LogMessageFromText(string.Format("Build Number: {0}", _Build.BuildNumber), MessageImportance.Normal); 

        List<IWorkItemSummary> assocWorkItems = InformationNodeConverters.GetAssociatedWorkItems(_Build); 

         // update work item status 
         UpdateWorkItemStatus(store, assocWorkItems, "Open", "Resolved"); 

        SaveWorkItems(store, assocWorkItems); 
       } 
       catch (Exception) 
       { 
        UpdateBuildStep(buildStep, false); 
        throw; 
       } 

       UpdateBuildStep(buildStep, result); 
      } 
      catch (Exception e) 
      { 
       result = false; 

       BuildErrorEventArgs eventArgs; 
       eventArgs = new BuildErrorEventArgs("", "", BuildEngine.ProjectFileOfTaskNode, BuildEngine.LineNumberOfTaskNode, BuildEngine.ColumnNumberOfTaskNode, 0, 0, string.Format("UpdateWorkItemState failed: {0}", e.Message), "", ""); 

       BuildEngine.LogErrorEvent(eventArgs); 

       throw; 
      } 

      return result; 
     } 

     private static void SaveWorkItems(WorkItemStore store, List<IWorkItemSummary> assocWorkItems) 
     { 
      foreach (IWorkItemSummary w in assocWorkItems) 
      { 
       WorkItem wi = store.GetWorkItem(w.WorkItemId); 

       if (wi.IsDirty) 
       { 
        wi.Save(); 
       } 
      } 
     } 

     // check in this routine if the workitem is a bug created by your CI process. Check by title or assigned to or description depending on your process. 
     private void UpdateWorkItemStatus(WorkItemStore store, List<IWorkItemSummary> assocWorkItems, string oldState, string newState) 
     { 
      foreach (IWorkItemSummary w in assocWorkItems) 
      { 
       Log.LogMessageFromText(string.Format("Updating Workitem Id {0}", w.WorkItemId), MessageImportance.Normal); 
       WorkItem wi = store.GetWorkItem(w.WorkItemId); 
       if (wi.Fields.Contains("Microsoft.VSTS.Build.IntegrationBuild") && wi.State != "Resolved") 
       { 
        wi.Fields["Microsoft.VSTS.Build.IntegrationBuild"].Value =_Build.BuildNumber; 
       } 
       if (wi.State == oldState) 
       { 
        wi.State = newState; 
        foreach (Field field in wi.Fields) 
        { 
         if (!field.IsValid) 
         { 
          break; 
         } 
        } 
       } 

       if (wi.IsDirty) 
       { 
        wi.Save(); 
       } 
      } 
     } 

     private void UpdateBuildStep(IBuildStep step, bool result) 
     { 
      step.Status = result ? BuildStepStatus.Succeeded : BuildStepStatus.Failed; 
      step.FinishTime = DateTime.Now; 
      step.Save(); 
     } 

     [Required] 
     public string BuildUri { get; set; } 

     [Required] 
     public string TeamFoundationServerUrl {get; set;} 
    } 
} 



< UpdateWorkItemState 
TeamFoundationServerUrl="$(TeamFoundationServerUrl)" 
BuildUri="$(BuildUri)" 
ContinueOnError="false"/> 
関連する問題