使TeamCity下拉所有git分支 [英] Make TeamCity pull down all git branches

查看:77
本文介绍了使TeamCity下拉所有git分支的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在构建服务器上,我已经设置了TeamCity(8.1.1),以便如果使用分支指定符的主机,功能分支之一或拉取请求分支之一发生更改,它就会执行构建过程:

On the builds server I have set up TeamCity (8.1.1) so that it executes the build process if there are changes in either the master, one of the feature branches or one of the pull request branches using the branch specifier:

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

我打开了构建代理选项:

I have turned on the build agent option:

teamcity.git.use.local.mirrors=true

将存储库克隆到构建目录之外的目录中,然后从该本地存储库中提取.

which clones the repository in a directory outside the build directory and then pulls from that local repository.

即使对于功能分支或拉取请求分支之一的构建,构建过程也需要访问git存储库和master分支.但是TeamCity仅具有包含本地存储库中的更改的分支,从而使我的构建失败,例如如果更改是在issue/mycoolissue分支上进行的,那么这是TeamCity工作空间中git存储库中唯一的分支.

The build process needs access to the git repository and the master branch, even for builds of one of the feature branches or pull request branches. However TeamCity only has the branch that contains the changes in the local repository thereby making my builds fail, e.g. when the change was on the issue/mycoolissue branch then that is the only branch that exists in the git repository in the TeamCity working space.

我尝试执行本地 git fetch 来获取master分支,但是由于本地存储库没有master分支,因此失败.虽然我可以添加指向源的远程指向(github私有存储库),但这意味着我也必须处理凭据,而我宁愿让TeamCity为我处理所有这些工作.

I have tried performing a local git fetch to get the master branch but because the local repository does not have the master branch this fails. While I could add a remote pointing to the origin (a github private repository) that would mean that I'd have to handle credentials as well and I'd rather have TeamCity take care of all of that for me.

我的问题是,是否有一种方法可以告诉TeamCity将所有分支都拉到本地存储库和工作存储库中?

My question is whether there is a way to tell TeamCity to just pull all the branches into both the local repository and the working repository?

推荐答案

事实证明(到目前为止)在TeamCity中无法很好地做到这一点,因此与此同时,通过运行其他MsBuild解决了此问题脚本在构建过程开始时进行验证,以验证master分支是否存在于当前(本地)存储库中,如果没有,则进行获取.

It turns out that (so far) there is no way to do this nicely in TeamCity so in the mean time this problem has been solved by running an additional MsBuild script at the start of the build process that verifies whether the master branch is present in the current (local) repository and getting it if it is not.

脚本如下:

<?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内联脚本如下:

In this script the GitHasMasterBranch MsBuild inline script looks like:

<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内联脚本如下:

And the GitGetMasterBranch MsBuild inline script looks like:

<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提取以获取所有分支,对master分支执行 GIT签出,然后执行原始分支的 GIT结帐.

Essentially all this last script does is to store the current branch name, perform a GIT fetch to get all the branches, perform a GIT checkout of the master branch and then perform a GIT checkout of the original branch.

这不是最快的方法,但目前可以使用.

It's not the fastest approach but it works for now.

这篇关于使TeamCity下拉所有git分支的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆