事實證明(到目前爲止)在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>
基本上所有這最後的腳本確實是存儲curren t分支名稱,執行GIT fetch
以獲取所有分支,執行主分支的GIT checkout
,然後執行原始分支的GIT checkout
。
這不是最快的方法,但它現在工作。
Downvoter任何理由downvote這樣做呢?如果沒有意義,我會很樂意改進我的問題。 – Petrik