2009-05-11 2 views
1

Wir verwenden kontinuierliche Integration als Teil unserer Build-Automatisierung. Bei jedem Einchecken erstellt der tfs build server das Projekt und wird bei Erfolg auf unseren Webservern bereitgestellt.TFS: Wie kann ich beim erfolgreichen Build automatisch übereinstimmende Arbeitselemente schließen?

Wenn der Build fehlschlägt, wird automatisch ein neuer Bug mit den Details des Buildfehlers erstellt.

Aufgrund von CI und der Aktivität auf dem Server kann dies zu 10 oder 20 fehlerhaften Arbeitsaufgaben führen, bevor der Build erneut erfolgreich ausgeführt werden kann.

Also, ich habe zwei Möglichkeiten. Ich möchte den Buildprozess entweder sehen lassen, ob ein offenes Arbeitselement für einen Buildfehler bereits existiert, und nur Details hinzufügen; ODER, ich möchte, dass der Erstellungsserver alle Erstellungsfehlerelemente automatisch schließt, wenn er wieder funktioniert.

Irgendwelche Ideen?

Antwort

2

Sie können eine MSBuild-Aufgabe erstellen, um eine dieser Optionen auszuführen. Hier ist ein ähnlicher Code, den ich benutze, um Sie zu starten, aber da ich die Details Ihrer Arbeitsaufgabe oder Ihres Prozesses nicht kenne, müssen Sie sie ändern.

Dieser Code übernimmt alle mit einem Build verbundenen Arbeitselemente und aktualisiert deren Status.

Wenn Sie Ihre erste Option auswählen, können Sie nur die UpdateWorkItemStatus-Methode ändern und vorhandene WIs aktualisieren. Für die zweite Methode müssen Sie etwas mehr Arbeit erledigen, da Sie den vorherigen Build nachschlagen müssen, anstatt ihn als Eingabe zu verwenden.

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"/> 
Verwandte Themen