2014-05-19 25 views
6

Sul server builds ho impostato TeamCity (8.1.1) in modo che esegua il processo di compilazione se ci sono cambiamenti nel master, in uno dei rami di funzionalità o in uno dei pull richiesta rami utilizzando l'identificatore di filiale:Crea TeamCity su tutti i rami git

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

ho attivato l'opzione di compilazione:

teamcity.git.use.local.mirrors=true 

che clona il repository in una directory al di fuori della directory di compilazione e poi tira da quel repository locale.

Il processo di compilazione richiede l'accesso al repository git e al ramo master, anche per le build di uno dei rami funzione o rami di richieste pull. Tuttavia, TeamCity ha solo il ramo che contiene le modifiche nel repository locale, rendendo così le mie build fallite, ad es. quando la modifica è avvenuta sul ramo issue/mycoolissue, questo è l'unico ramo esistente nel repository git nello spazio di lavoro di TeamCity.

Ho provato a eseguire un locale git fetch per ottenere il ramo master ma poiché il repository locale non ha il ramo master questo non riesce. Mentre potrei aggiungere un puntatore remoto all'origine (un repository privato github) che significherebbe che dovrei gestire anche le credenziali e preferirei che TeamCity si occupasse di tutto questo per me.

La mia domanda è se c'è un modo per dire a TeamCity di trascinare tutti i rami nel repository locale e nel repository funzionante?

+1

Downvoter alcuna ragione per la downvote? Sarei felice di migliorare la mia domanda se non ha senso. – Petrik

risposta

0

Si scopre che (finora) non c'è modo di farlo correttamente in TeamCity, quindi nel frattempo questo problema è stato risolto eseguendo uno script MsBuild aggiuntivo all'inizio del processo di compilazione che verifica se il master il ramo è presente nel repository (locale) corrente e lo ottiene se non lo è.

Lo script si presenta come:

<?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> 

In questo script lo script inline GitHasMasterBranch MsBuild assomiglia:

<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> 

e lo script GitGetMasterBranch MsBuild linea assomiglia:

<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> 

In sostanza, tutto questo ultimo script è memorizzare il curren t nome del ramo, eseguire un GIT fetch per ottenere tutti i rami, eseguire un GIT checkout del ramo principale e quindi eseguire un GIT checkout del ramo originale.

Non è l'approccio più veloce ma funziona per ora.

4

A partire da TeamCity 10.0.4, è possibile farlo con l'aggiunta di un parametro di configurazione teamcity.git.fetchAllHeads=trueSee here

Problemi correlati