Cake是为您的应用程序创建交付管道的绝佳工具。 我爱他,因为他允许我用C#编写此管道,我对此非常了解。 Cake,PSake和其他类似框架的一个重要功能是它们创建了一个可以在本地开发人员的计算机和CI服务器上运行的脚本。 在这里,我将解释如何组织与TeamCity的 Cake脚本交互。
要求条件
我假设您已经具备Cake和TeamCity的基本知识。 否则,您可以通过阅读以下资源开始:
对于蛋糕:
对于TeamCity:
现在让我们谈谈Cake和TeamCity的交互。
记录中
Cake管道通常包含多个任务。 对于TeamCity日志中的每个此类任务,都有一个单独的部分会很好。 我想在日志中为每个Cake任务获得一个可折叠部分:

Cake API具有TeamCity.WriteStartBuildBlock和TeamCity.WriteEndBuildBlock方法。 尽管可以在每个任务中使用它们,但是可以将其自动化。 Cake具有在每个任务之前和之后调用的TaskSetup和TaskTeardown方法 。 他们可以打开和关闭TeamCity日志块:
TaskSetup(setupContext => { if(TeamCity.IsRunningOnTeamCity) { TeamCity.WriteStartBuildBlock(setupContext.Task.Name); } }); TaskTeardown(teardownContext => { if(TeamCity.IsRunningOnTeamCity) { TeamCity.WriteEndBuildBlock(teardownContext.Task.Name); } });
在这里, TeamCity.IsRunningOnTeamCity属性用于确定是否弹出TeamCity的代码。
现在,在我们的杂志中,每个任务都有可折叠的块。 但是,可以添加另一项改进。
通常,Cake中的任务有短名称: Build , Test , Clean 。 因此,它们更容易从命令行运行。 但是在TeamCity中,我希望有更详细的Cake任务描述。 这是可以做到的。 要给任务一个描述,请使用Description方法:
Task("Clean") .Description("Create and clean folders with results") .Does(() => { ... });
现在,这些描述可用于在日志中形成块:
TaskSetup(setupContext => { if(TeamCity.IsRunningOnTeamCity) { TeamCity.WriteStartBuildBlock(setupContext.Task.Description ?? setupContext.Task.Name); } }); TaskTeardown(teardownContext => { if(TeamCity.IsRunningOnTeamCity) { TeamCity.WriteEndProgress(teardownContext.Task.Description ?? teardownContext.Task.Name); } });
这提高了其可读性。
取得的进展
如果Cake脚本花费的时间很长,那么了解当前正在运行的任务会很有用。

可以使用TeamCity.WriteStartProgress和TeamCity.WriteEndProgress方法来实现。 他们的呼叫可以插入到相同的TaskSetup和TaskTeardown中 :
TaskSetup(setupContext => { if(TeamCity.IsRunningOnTeamCity) { TeamCity.WriteStartBuildBlock(setupContext.Task.Description ?? setupContext.Task.Name); TeamCity.WriteStartProgress(setupContext.Task.Description ?? setupContext.Task.Name); } }); TaskTeardown(teardownContext => { if(TeamCity.IsRunningOnTeamCity) { TeamCity.WriteEndProgress(teardownContext.Task.Description ?? teardownContext.Task.Name); TeamCity.WriteEndBuildBlock(teardownContext.Task.Description ?? teardownContext.Task.Name); } });
测试结果
如果您在Cake任务中运行测试,那么TeamCity可以向您显示其结果。

可以使用TeamCity.ImportData方法来完成。 它有两个参数:数据类型的字符串描述和包含此数据的文件的路径。 例如,如果您使用MSTest,请按照以下方法告诉TeamCity测试结果:
Task("Run-Tests") .Description("Run tests") .IsDependentOn("Clean") .IsDependentOn("Build") .Does(() => { var testDllsPattern = string.Format("./**/bin/{0}/*.*Tests.dll", configuration); var testDlls = GetFiles(testDllsPattern); var testResultsFile = System.IO.Path.Combine(temporaryFolder, "testResults.trx"); MSTest(testDlls, new MSTestSettings() { ResultsFile = testResultsFile }); if(TeamCity.IsRunningOnTeamCity) { TeamCity.ImportData("mstest", testResultsFile); } });
TeamCity支持多种类型的测试。 除了mstest之外,您还可以使用nunit , vstest和其他一些 。
测试覆盖率分析代码
TeamCity能够显示通过测试分析代码覆盖率的结果。

TeamCity当前支持与DotCover集成。 让我向您展示如何在Cake脚本中使用DotCover。 首先,需要安装DotCover:
#tool "nuget:?package=JetBrains.dotCover.CommandLineTools"
之后,可以在任务中使用它:
Task("Analyse-Test-Coverage") .Description("Analyse code coverage by tests") .IsDependentOn("Clean") .IsDependentOn("Build") .Does(() => { var coverageResultFile = System.IO.Path.Combine(temporaryFolder, "coverageResult.dcvr"); var testDllsPattern = string.Format("./**/bin/{0}/*.*Tests.dll", configuration); var testDlls = GetFiles(testDllsPattern); var testResultsFile = System.IO.Path.Combine(temporaryFolder, "testResults.trx"); DotCoverCover(tool => { tool.MSTest(testDlls, new MSTestSettings() { ResultsFile = testResultsFile }); }, new FilePath(coverageResultFile), new DotCoverCoverSettings() .WithFilter("+:Application") .WithFilter("-:Application.*Tests") ); if(TeamCity.IsRunningOnTeamCity) { TeamCity.ImportData("mstest", testResultsFile); TeamCity.ImportDotCoverCoverage(coverageResultFile); } });
如您所见,测试也在这里运行。 因此,我们可以立即将测试结果以及其代码覆盖率的分析结果告知TeamCity。 TeamCity.ImportDotCoverCoverage方法就是这样做的。
神器出版
在TeamCity中,您可以发布在Cake脚本操作期间创建的一些工件。 NuGet软件包很适合此角色:

为此,请将您要发布的所有工件都放在一个文件夹中。 然后,您可以使用TeamCity.PublishArtifacts方法进行发布:
Task("Publish-Artifacts-On-TeamCity") .Description("Publish artifacts on TeamCity") .IsDependentOn("Create-NuGet-Package") .WithCriteria(TeamCity.IsRunningOnTeamCity) .Does(() => { TeamCity.PublishArtifacts(artifactsFolder); });
结论
如果您希望Cake脚本在TeamCity上运行,希望这些简单的代码示例可以节省您的时间和精力。 脚本的完整版本及其处理的应用程序可以在GitHub上找到 。 祝你好运