簡體   English   中英

讓 TeamCity 下拉所有 git 分支

[英]Make TeamCity pull down all git branches

在構建服務器上,我設置了 TeamCity (8.1.1),以便它在使用分支說明符的主分支、功能分支之一或拉取請求分支之一發生更改時執行構建過程:

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

我打開了構建代理選項:

teamcity.git.use.local.mirrors=true

它將存儲庫克隆到構建目錄之外的目錄中,然后從該本地存儲庫中提取。

構建過程需要訪問 git 存儲庫和 master 分支,即使是構建功能分支或拉取請求分支之一。 然而,TeamCity 只有包含本地存儲庫中更改的分支,從而使我的構建失敗,例如,當更改在 issue/mycoolissue 分支上時,這是 TeamCity 工作空間中 git 存儲庫中存在的唯一分支。

我曾嘗試執行本地git fetch來獲取 master 分支,但由於本地存儲庫沒有 master 分支,因此失敗。 雖然我可以添加一個指向源的遠程(一個 github 私有存儲庫),但這意味着我還必須處理憑據,我寧願讓 TeamCity 為我處理所有這些。

我的問題是是否有辦法告訴 TeamCity 將所有分支都拉到本地存儲庫和工作存儲庫中?

從 TeamCity 10.0.4 開始,您可以通過添加配置參數teamcity.git.fetchAllHeads=true來做到這一點, 請參見此處

事實證明(到目前為止)在 TeamCity 中沒有辦法很好地做到這一點,因此與此同時,通過在構建過程開始時運行一個額外的 MsBuild 腳本來驗證主分支是否存在於當前(本地)存儲庫,如果不是,則獲取它。

該腳本如下所示:

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

在此腳本中, GitHasMasterBranch MsBuild 內聯腳本如下所示:

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

GitGetMasterBranch MsBuild 內聯腳本如下所示:

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

基本上所有的這最后一個腳本確實是存儲當前分支的名稱,執行GIT fetch來獲得所有分支,執行GIT checkout的主分支,然后執行GIT checkout原分公司。

這不是最快的方法,但目前有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM