Lancer l’exécution d’une build TFS depuis une autre build

La problématique est dans le titre : comment peut-on lancer l’exécution d’une build à partir d’une autre ? D’autre part, j’aimerai également que la build maitre, attende la fin de l’exécution de la build enfant, et en fonction de son statut qu’elle s’arrête ou continue.

La première chose à faire est de développer une activité Workflow Foundation qui va permettre de lancer l’exécution d’une build :

  • Créer un nouveau projet de type Activity Library
  • Ajouter les références suivantes : Microsoft.TeamFoundation.Client, Microsoft.TeamFoundation.Build.Client
  • Ajouter une Code Activity. Voici le code de notre activité :

 

[BuildActivity(HostEnvironmentOption.All)]
public sealed class QueueDemoDefinitionBuildActivity : CodeActivity
{
    private const string TfsCollectionUri = "http://localhost:8080/tfs/defaultcollection";
    private const string BuildDefinitionName = "DemoDefinition";
    private const string TeamProjectName = "Demo";
 
    public OutArgument<IQueuedBuild> Build { get; set; }
 
    protected override void Execute(CodeActivityContext context)
    {
        var collection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(TfsCollectionUri));
        collection.EnsureAuthenticated();
 
        IBuildServer buildServer = (IBuildServer)collection.GetService(typeof(IBuildServer));
 
 
        var buildDefinition = buildServer.GetBuildDefinition(TeamProjectName, BuildDefinitionName);
 
 
        var buildRequest = buildDefinition.CreateBuildRequest();
 
        var queuedBuild = buildServer.QueueBuild(buildRequest);
        
        Build.Set(context, queuedBuild);
    }
}

 

Le principe est simple :

  • On récupère le service de build depuis la collection de projets.
  • On récupère ensuite la définition de la build.
  • Et enfin on met en file la build via la méthode QueueBuild.

Dans notre activité, on remarque le paramètre de sortie Build de type IQueuedBuild que l’on “set” à la fin de l’activité. Nous verrons par la suite à quoi il va servir.

Il ne reste plus qu’à compiler, à déployer notre assembly dans le source control et enfin d’indiquer au contrôleur de Build où se trouvent notre custom assembly.

Pour illustrer cet exemple, j’ai créé un nouveau template de build xaml dans lequel je fais simplement appel à ma nouvelle activité comme ceci :


image

Pour récupérer le paramètre de sortie de cette activité, il nous faut déclarer une variable au niveau de la séquence :


image

Ensuite dans les propriétés de l’activité QueueDemoDefinitionBuildActivity on récupére le paramètre de sortie dans notre variable :


image

Comme je le disais au début de mon post, je veux que ma build maitre attende le résultat de la build enfant.

Nous avons donc besoin d’une boucle While. Sa condition de sortie est que le statut de la build est soit annulé soit terminé :


image

Dans le Body de cette boucle nous allons ajouter une activité de type Delay, de manière à attendre quelques secondes (ou minutes) avant de revérifier le statut. Nous avons également besoin d’appeler la méthode Refresh sur notre objet IQueuedBuild. En effet les propriétés de notre variable ne se mette pas automatiquement à jour. Un appel à la méthode Refresh est donc nécessaire.

Les 2 activités dont nous avons besoin sont présentes dans la toolbox à cette endroit :


image

Dans l’activité While, on ajoute une activité de type séquence, puis on ajoute les activités Delay et InvokeMethod comme ceci :


image

On paramètre l’activité Delay :


image

Pour l’activité InvokeMethod, il faut indiquer l’objet sur lequel la méthode doit être appelée, en l’occurrence QueuedBuild et le nom de la méthode, Refresh. La méthode Refresh prend en paramètre d’entrée une valeur de l’énumération QueryOptions. Dans les propriétés de l’activité InvoMethod, il est possible de renseigner les paramètres d’entrée et de sortie :


image

Une fois que l’on sort de la boucle, cela signifie que la build est terminée. Mais la propriété Status de l’objet QueuedBuild ne nous dis pas si la build est dans l’état Fail ou Success. Pour celà il faut accéder à la propriété suivante : QueuedBuild.Build.Status. Mais encore une fois il faut appeler la méthode Refresh sur la propriété Build :


image

Et maintenant, on met à jour le statut de la build maitre en fonction du résultat de la build enfant à l’aide d’une activité SetBuildProperties,


image

que l’on paramètre de cette manière :


image

Une fois notre workflow de build terminé, on crée une définition de build basée sur ce template :


image

Avant de lancer l’exécution de la build, il faut vérifier que le service de build à la possibilité d’exécuter plusieurs build simultanément. Si ce n’est pas le cas, lorsque la build maitre va lancer l’exécution de la build enfant, la build enfant va attendre que la première soit terminée pour s’exécuter. Et la première va attendre que la build enfant soit terminée aussi… Donc pour vérifier ça, ouvrir la console d’administration de TFS sur le serveur de Build et vérifier la concurrence des builds au niveau des propriétés du contrôleur :


image

On peut maintenant tester et lancer la Master Build. Si on regarde le log d’exécution, on peut voir notre boucle d’attente pendant que l’autre build s’exécute :


image

Depuis la liste des builds en cours d’exécution on aperçoit nos 2 builds :


image

Et enfin au niveau des résultats, si la build enfant échoue alors la master échoue également :


image

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s