2014-05-19 8 views
6

Sur le serveur de builds j'ai configuré TeamCity (8.1.1) afin qu'il exécute le processus de construction s'il y a des changements dans le maître, l'une des branches ou l'un des pull branches de demande en utilisant le prescripteur de branche:Faire équipe tirer toutes les branches git

+:refs/heads/* 
+:refs/pull/(*/merge) 

Je me suis tourné sur l'option d'agent de construction:

teamcity.git.use.local.mirrors=true 

qui clone le dépôt dans un répertoire en dehors du répertoire de construction et tire ensuite à partir de ce référentiel local.

Le processus de construction doit avoir accès au référentiel git et à la branche maître, même pour les constructions d'une des branches de fonctionnalité ou les branches de requête de traction. Toutefois, TeamCity n'a que la branche qui contient les modifications dans le référentiel local, ce qui fait échouer mes builds, par ex. lorsque la modification était sur la branche issue/mycoolissue, alors c'est la seule branche qui existe dans le dépôt git dans l'espace de travail TeamCity.

J'ai essayé d'exécuter un git fetch local pour obtenir la branche principale, mais comme le référentiel local n'a pas la branche principale, cela échoue. Bien que je puisse ajouter une télécommande pointant vers l'origine (un dépôt privé github), cela signifierait que je devrais aussi gérer les informations d'identification et je préférerais que TeamCity s'occupe de tout ça pour moi.

Ma question est de savoir s'il existe un moyen de dire à TeamCity de simplement tirer toutes les branches dans le référentiel local et dans le dépôt de travail?

+1

Downvoter quelque raison que pour la downvote? Je serais heureux d'améliorer ma question si cela n'a aucun sens. – Petrik

Répondre

0

Il s'avère que (jusqu'à présent) il n'y a aucun moyen de le faire correctement dans TeamCity. En attendant ce problème a été résolu en exécutant un script MsBuild supplémentaire au début du processus de construction qui vérifie si le maître La branche est présente dans le dépôt courant (local) et l'obtient si elle ne l'est pas.

Le script ressemble à:

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" 
     DefaultTargets="Run" 
     xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <PropertyGroup> 
     <DirWorkspace>$(MSBuildProjectDirectory)</DirWorkspace> 
     <DirRepository Condition=" '$(DirRepository)' == '' ">$(DirWorkspace)</DirRepository> 
     <DirGit Condition=" '$(DirGit)' == '' ">c:\Program Files (x86)\Git\bin</DirGit>  
    </PropertyGroup> 

    <Import Project="$(DirWorkspace)\GitHasMasterBranch.msbuild" 
      Condition="Exists('$(DirWorkspace)\GitHasMasterBranch.msbuild')"/> 
    <Import Project="$(DirWorkspace)\GitGetMasterBranch.msbuild" 
      Condition="Exists('$(DirWorkspace)\GitGetMasterBranch.msbuild')"/> 

    <Target Name="Run" DependsOnTargets="_DisplayInfo;_FetchOriginMasterIfNotExists"> 
     <!-- Do nothing here --> 
    </Target> 

    <!-- Display info --> 
    <Target Name="_DisplayInfo"> 
     <Message Text="Preparing workspace ..." /> 
    </Target> 

    <PropertyGroup> 
     <ExeGit>$(DirGit)\git.exe</ExeGit> 
    </PropertyGroup> 
    <Target Name="_FetchOriginMasterIfNotExists" DependsOnTargets="_DisplayInfo"> 
     <GitHasMasterBranch LocalPath="$(DirRepository)"> 
      <Output TaskParameter="HasMaster" PropertyName="HasMaster" /> 
     </GitHasMasterBranch> 

     <Message Text="Not fetching master branch because it already exists" Condition="($(HasMaster))" /> 
     <Message Text="Fetching master branch because it does not exist" Condition="(!$(HasMaster))" /> 
     <GitGetMasterBranch LocalPath="$(DirRepository)" Condition="(!$(HasMaster))"/> 
    </Target> 
</Project> 

Dans ce script le script en ligne GitHasMasterBranch MsBuild ressemble:

<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' 
     ToolsVersion="4.0"> 
    <UsingTask TaskName="GitHasMasterBranch" 
       TaskFactory="CodeTaskFactory" 
       AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll"> 
     <ParameterGroup> 
      <LocalPath ParameterType="System.String" Required="true" /> 
      <HasMaster ParameterType="System.Boolean" Output="true" /> 
     </ParameterGroup> 
     <Task> 
      <Code Type="Method" Language="cs"> 
       <![CDATA[ 
        public override bool Execute() 
        { 
         var info = new System.Diagnostics.ProcessStartInfo 
           { 
            FileName = "git", 
            Arguments = "branch", 
            WorkingDirectory = LocalPath, 
            UseShellExecute = false, 
            RedirectStandardOutput = true, 
            RedirectStandardError = true, 
           }; 

         var text = new System.Text.StringBuilder(); 
         var process = new System.Diagnostics.Process(); 
         process.StartInfo = info; 
         process.OutputDataReceived += 
          (s, e) => 
          { 
           text.Append(e.Data); 
          }; 
         process.ErrorDataReceived += 
          (s, e) => 
          { 
           if (!string.IsNullOrWhiteSpace(e.Data)) 
           { 
            Log.LogError(e.Data); 
           } 
          }; 
         process.Start(); 

         process.BeginOutputReadLine(); 
         process.BeginErrorReadLine(); 
         process.WaitForExit(); 

         HasMaster = text.ToString().Contains("* master"); 

         // Log.HasLoggedErrors is true if the task logged any errors -- even if they were logged 
         // from a task's constructor or property setter. As long as this task is written to always log an error 
         // when it fails, we can reliably return HasLoggedErrors. 
         return !Log.HasLoggedErrors; 
        } 
       ]]> 
      </Code> 
     </Task> 
    </UsingTask> 
</Project> 

Et le script en ligne MsBuild GitGetMasterBranch ressemble:

<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' 
     ToolsVersion="4.0"> 
    <UsingTask TaskName="GitGetMasterBranch" 
       TaskFactory="CodeTaskFactory" 
       AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll"> 
     <ParameterGroup> 
      <LocalPath ParameterType="System.String" Required="true" /> 
     </ParameterGroup> 
     <Task> 
      <Code Type="Method" Language="cs"> 
       <![CDATA[ 
        public override bool Execute() 
        { 
         // Get the name of the current branch 
         var info = new System.Diagnostics.ProcessStartInfo 
           { 
            FileName = "git", 
            Arguments = "symbolic-ref --short -q HEAD", 
            WorkingDirectory = LocalPath, 
            UseShellExecute = false, 
            RedirectStandardOutput = true, 
            RedirectStandardError = true, 
           }; 

         var text = new System.Text.StringBuilder(); 
         var process = new System.Diagnostics.Process(); 
         process.StartInfo = info; 
         process.OutputDataReceived += 
          (s, e) => 
          { 
           text.Append(e.Data); 
          }; 
         process.Start(); 

         process.BeginOutputReadLine(); 
         process.BeginErrorReadLine(); 
         process.WaitForExit(); 

         var currentBranch = text.ToString().Trim(); 

         // git fetch 
         info = new System.Diagnostics.ProcessStartInfo 
           { 
            FileName = "git", 
            Arguments = "fetch origin", 
            WorkingDirectory = LocalPath, 
            UseShellExecute = false, 
            RedirectStandardOutput = true, 
            RedirectStandardError = true, 
           }; 

         process = new System.Diagnostics.Process(); 
         process.StartInfo = info; 
         process.OutputDataReceived += 
          (s, e) => 
          { 
           if (!string.IsNullOrWhiteSpace(e.Data)) 
           { 
            Log.LogMessage(MessageImportance.High, e.Data); 
           } 
          }; 
         process.Start(); 

         process.BeginOutputReadLine(); 
         process.BeginErrorReadLine(); 
         process.WaitForExit(); 

         // git checkout master 
         info = new System.Diagnostics.ProcessStartInfo 
           { 
            FileName = "git", 
            Arguments = "checkout master", 
            WorkingDirectory = LocalPath, 
            UseShellExecute = false, 
            RedirectStandardOutput = true, 
            RedirectStandardError = true, 
           }; 

         process = new System.Diagnostics.Process(); 
         process.StartInfo = info; 
         process.OutputDataReceived += 
          (s, e) => 
          { 
           if (!string.IsNullOrWhiteSpace(e.Data)) 
           { 
            Log.LogMessage(MessageImportance.High, e.Data); 
           } 
          }; 
         process.Start(); 

         process.BeginOutputReadLine(); 
         process.BeginErrorReadLine(); 
         process.WaitForExit(); 

         // git pull 
         info = new System.Diagnostics.ProcessStartInfo 
           { 
            FileName = "git", 
            Arguments = "pull", 
            WorkingDirectory = LocalPath, 
            UseShellExecute = false, 
            RedirectStandardOutput = true, 
            RedirectStandardError = true, 
           }; 

         process = new System.Diagnostics.Process(); 
         process.StartInfo = info; 
         process.OutputDataReceived += 
          (s, e) => 
          { 
           if (!string.IsNullOrWhiteSpace(e.Data)) 
           { 
            Log.LogMessage(MessageImportance.High, e.Data); 
           } 
          }; 
         process.Start(); 

         process.BeginOutputReadLine(); 
         process.BeginErrorReadLine(); 
         process.WaitForExit(); 

         // git checkout <CURRENT_BRANCH> 
         info = new System.Diagnostics.ProcessStartInfo 
           { 
            FileName = "git", 
            Arguments = string.Format("checkout {0}", currentBranch), 
            WorkingDirectory = LocalPath, 
            UseShellExecute = false, 
            RedirectStandardOutput = true, 
            RedirectStandardError = true, 
           }; 

         process = new System.Diagnostics.Process(); 
         process.StartInfo = info; 
         process.OutputDataReceived += 
          (s, e) => 
          { 
           if (!string.IsNullOrWhiteSpace(e.Data)) 
           { 
            Log.LogMessage(MessageImportance.High, e.Data); 
           } 
          }; 
         process.Start(); 

         process.BeginOutputReadLine(); 
         process.BeginErrorReadLine(); 
         process.WaitForExit(); 

         // Log.HasLoggedErrors is true if the task logged any errors -- even if they were logged 
         // from a task's constructor or property setter. As long as this task is written to always log an error 
         // when it fails, we can reliably return HasLoggedErrors. 
         return !Log.HasLoggedErrors; 
        } 
       ]]> 
      </Code> 
     </Task> 
    </UsingTask> 
</Project> 

Essentiellement tout ce dernier script est de stocker le curren t nom de la branche, exécutez un GIT fetch pour obtenir toutes les branches, exécutez un GIT checkout dans la branche principale, puis exécutez un GIT checkout de la branche d'origine.

Ce n'est pas l'approche la plus rapide, mais cela fonctionne pour l'instant.

4

A partir de TeamCity 10.0.4, vous pouvez le faire en ajoutant un paramètre de configuration teamcity.git.fetchAllHeads=trueSee here

Questions connexes