2009-05-11 3 views
1

Nous utilisons l'intégration continue dans le cadre de notre automatisation de la construction. Pour chaque enregistrement, le serveur de construction tfs construit le projet et le déploie sur nos serveurs Web en cas de succès. Lorsque la construction échoue, elle crée automatiquement un nouveau bug avec les détails de l'échec de construction.TFS: Comment puis-je fermer automatiquement les éléments de travail correspondants sur une build réussie?

En raison de CI et de l'activité sur le serveur, 10 ou 20 éléments de travail peuvent échouer avant que la génération ne recommence à fonctionner.

Donc, j'ai deux options. Je voudrais avoir le processus de construction voir si un élément de travail ouvert existe déjà pour un échec de construction et juste ajouter des détails à cela; OU, j'aimerais que le serveur de construction ferme automatiquement tous les éléments d'échec de construction lorsqu'il recommence à fonctionner.

Des idées?

Répondre

2

Vous pouvez créer une tâche MSBuild pour effectuer l'une de ces options. Voici un morceau de code similaire que j'utilise pour commencer mais comme je ne connais pas les détails de votre travail ou processus, vous devrez le changer.

Ce code prend tous les éléments de travail associés à une génération et met à jour leur état.

Si vous sélectionnez votre première option, vous pouvez simplement modifier la méthode UpdateWorkItemStatus et mettre à jour toutes les WI existantes. Pour la deuxième méthode, vous devrez faire un peu plus de travail car vous devez rechercher la version précédente plutôt que de la prendre comme entrée.

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"/> 
Questions connexes