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.
Downvoter alcuna ragione per la downvote? Sarei felice di migliorare la mia domanda se non ha senso. – Petrik