Include build output as attachment - cruisecontrol.net

We have a CruiseControl.NET Server 1.5.0.4401 running. One project uses an external compiler, which is included via exec-task. This compiler is configured to write its output into a textfile that is located in the artifact directory. The filename is keil_Revision-x.txt (x is the revision number) whereas the configuration for this file looks like %ccnetartifactdirectory%\keil_%ccnetlabel%.txt.
We want this output file to be attached to the e-mail report CC is sending for each build. The configuration of the email-publisher is (a bit shortened) the following:
<email from="buildmaster#xxx.yy" mailhost="zzz" mailport="25" includeDetails="TRUE" useSSL="FALSE">
<users>
<!-- Here are some users -->
</users>
<groups>
<!-- Here are some groups -->
</groups>
<converters>
<!-- LDAP converter-->
</converters>
<modifierNotificationTypes>
<!-- Several notification types -->
</modifierNotificationTypes>
<subjectSettings>
<!-- Here are some subject settings -->
</subjectSettings>
<attachments>
<file>${CCNetArtifactDirectory}\keil_${CCNetLabel}.txt</file>
</attachments>
</email>
The only problem is, that the files are not attached. The debug output on the cruise control console doesn't contain any error message. The artifact directory contains all files, only they are not attached. Where is the failure?

Are Integration Properties like CCNetLabel available inside CCNET configuration? I venture to doubt that. Up to CCNET 1.4.4 SP1 they weren't. So please check the attachment node in Your project configuration to see if CCNetLabel has been resolved properly.
You need to define preprocessor constants that can replace the integration properties like this:
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<cb:define project.artifact.dir="C:\foodir" />
<project name="foo">
<artifactDirectory>$(project.artifact.dir)</artifactDirectory>
...
<publishers>
...
<email
from="buildmaster#xxx.yy"
mailhost="zzz"
mailport="25"
includeDetails="TRUE"
useSSL="FALSE">
....
<attachments>
<file>$(project.artifact.dir)\keil.txt</file>
</attachments>
</email>
</publishers>
</project>
</cruisecontrol>
You need to instruct your compiler to write the results to a file whose name is predictable by CCNET configuration. Since configuration has no access to the label it must not be part of the filename. If you want to keep the result files from being overwritten by each build, add an executable task that triggers a simple batch file whose purpose is to copy %ccnetartifactdirectory%\keil.txt to %ccnetartifactdirectory%\keil_%ccnetlabel%.txt.
Otherwise the answer to this question might help here as well.

Related

Xamarin.iOS versioning during build

I've been trying to get an automatic versioning system going for builds (mainly due to external crash analytics picking up each build as the same until I change the version manually). The format is simple, I take the CFBundleShortVersionString from the Info.plist, and append the current date and time (in yyyyMMddmmss format) as subversion.
The task I've put together for this:
<Project>
<Target Name="BeforeBuild">
<XmlPeek XmlInputPath="$(ProjectDir)Info.plist" Query="//dict/key[. = 'CFBundleShortVersionString']/following-sibling::string[1]">
<Output TaskParameter="Result" ItemName="VersionNumber" />
</XmlPeek>
<PropertyGroup>
<BuildNumber>$([System.DateTime]::Now.ToString(yyyyMMddmmss))</BuildNumber>
</PropertyGroup>
<XmlPoke XmlInputPath="$(ProjectDir)Info.plist" Query="//dict/key[. = 'CFBundleVersion']/following-sibling::string[1]" Value="$(VersionNumber).$(BuildNumber)" />
</Target>
</Project>
However it fails with the following error:
Target BeforeBuild:
[...]/[...].csproj(1069,5): error MSB3733: Input file "[...]/Info.plist" cannot be opened. For security reasons DTD is prohibited in this XML document. To enable DTD processing set the DtdProcessing property on XmlReaderSettings to Parse and pass the settings into XmlReader.Create method.
Done building target "BeforeBuild" in project "[...].csproj" -- FAILED.
What am I doing wrong? There's not much info about this error, at least not much that I could find and would help fixing it.

msbuild, how to set environment variables?

I am trying to set environment variables using project file (ex. .vcxproj)
I looked at property functions but it didn't seem to have such function.
I know there is a way to retrieve environment variable but couldn't find how to set it.
I feel like there should be way to set environment variables in project file.
The coded task can be put right at the project file since MSBuild v4.0. Like this:
<UsingTask
TaskName="SetEnvironmentVariableTask"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v$(MSBuildToolsVersion).dll">
<ParameterGroup>
<Name ParameterType="System.String" Required="true" />
<Value ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Using Namespace="System" />
<Code Type="Fragment" Language="cs">
<![CDATA[
Environment.SetEnvironmentVariable(Name, Value);
]]>
</Code>
</Task>
</UsingTask>
Note that in MSBuild 14+, the AssemblyFile reference should be just:
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll"
The SetEnvironmentVariableTask can be then used from the target:
<Target Name="SampleTarget" BeforeTargets="Build">
<SetEnvironmentVariableTask Name="TEST_ENV_VAR" Value="$(MSBuildProjectName)" />
</Target>
That's much handier than authoring a separate .DLL for small MSBuild task(s).
In the more recent versions of MS Build (since 2016), you can simply do this:
<Target Name="MyEnvironmentVariables">
<Exec Command="A command that needs environment variables" EnvironmentVariables="HANDY_ENV_VAR_1=500;HANDY_ENV_VAR_2=A Useful Value" />
</Target>
Make sure to separate the variables with a semicolon. You don't need a trailing semicolon though.
If you are only using the variable in the context of MSBuild...
...then you can use the standard MSBuild variables (aka properties) instead of trying to set an environment variable. You can set properties when running msbuild using the /property switch (aka /p switch) (more here), as shown in the example below, which sets the PublishProfile property to the value Debug and the VisualStudioVersion property to the value 15.0
msbuild Project.csproj /p:PublishProfile=Debug /p:VisualStudioVersion=15.0
Find a list of the standard MSBuild's variables/properties at this question
You could also define arbitrary properties in the csproj file itself, using the <PropertyGroup> element. More on that here
If you do need to set a true environment variable...
...well, it's not an out-of-box thing. You can write a custom task and then leverage it in the project file. Here's a link to an MSDN thread that outlines how to do this:
How to set envrionment variables in MSBuild file? This example creates a new C# class SetEnvVar which inherits from the Task class (Microsoft.Build.Utilities.Task), in the MSBuildTasks namespace.
//...
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace MSBuildTasks
{
public class SetEnvVar : Task
{
//...
public override bool Execute()
{
Environment.SetEnvironmentVariable(_variable, _value);
return true;
}
... and then the task is invoked by this part of the csproj file:
<UsingTask
TaskName="MSBuildTasks.SetEnvVar"
AssemblyFile="$(RootDir)Tools\Bin\MSBuildTasks.dll"/>
You might consider writing the environment variables to a text file (.cmd) as a sequence of SET XXX=$(XXX) lines. Then execute the .cmd in the command window.
e.g. Define an ItemGroup with all the SET commands, then use Task 'WriteLinesToFile' to write each item to a line in the .cmd text file.
<ItemGroup>
<BuildEnvItem Include="REM This file is auto generated. Do not edit" />
<BuildEnvItem Include="SET TEST_ENV_VAR=$(TEST_ENV_VAR)" />
<!-- add more as needed -->
<ItemGroup>
<Target Name="DefineBuildEnvironmentVariables">
<WriteLinesToFile File="Build_env.cmd" Lines="#(BuildEnvItem)" Overwrite="true" Encoding="Unicode"/>
</Target>
This is may be useful in the situation where there is an existing .cmd that is using msbuild. The initial .cmd uses msbuild to generate the Build_env.cmd, and then calls Build_env.cmd before proceeding.

CruiseControl.NET Visual Studio Test Cases not showing up on dashboard

I'm using CruiseControl.NET to run visual studio test cases after my project builds. In the raw xml log I can see it running the test cases and saying which passed and which failed, however on the CruiseControl dashboard all it says is:
9 Projects built with no warnings at all :-)
Juchuu !!!
Here's what my project block looks like:
<project name="projectname" queue="queuename" queuePriority="2">
<workingDirectory>C:\Build</workingDirectory>
<category>categoryname</category>
<webURL>http://myurl/ViewProjectReport.aspx</webURL>
<triggers>
<intervalTrigger seconds="60" />
</triggers>
<modificationDelaySeconds>60</modificationDelaySeconds>
&sc;
<tasks>
<msbuild>
<executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable>
<workingDirectory>C:\mypath</workingDirectory>
<projectFile>project.sln</projectFile>
<buildArgs>/v:quiet /noconlog /p:Configuration=Debug</buildArgs>
<targets>Build</targets>
<timeout>900</timeout>
<logger>C:\Program Files\CruiseControl.NET\server\Rodemeyer.MsBuildToCCnet.dll</logger>
</msbuild>
<exec>
<executable>C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\mstest.exe</executable>
<baseDirectory>C:\Build\Test\TestCases\</baseDirectory>
<buildArgs>/testcontainer:testproject\bin\debug\testproject.dll /runconfig:localtestrun.Testrunconfig</buildArgs>
<buildTimeoutSeconds>900</buildTimeoutSeconds>
</exec>
</tasks>
<publishers>
<xmllogger logDir="C:\Program Files\CruiseControl.NET\Logs\Navtrak\H4CommandProcess\" />
</publishers>
</project>
How do I get the passed/failed test cases to show up on the cruisecontrol dashboard page for that specific build?
Thanks,
Justin
See this article for some tips on how to get MSTest results to appear in CruiseControl.Net:
http://confluence.public.thoughtworks.org/display/CCNET/Using+CruiseControl.NET+with+MSTest
Essentially what you need to do is:
Get MSTest to save its test results to an xml (.trx) file (your raw build output might show test results in a test format, however CruiseControl.net needs the results in xml format)
Get CruiseControl.Net to merge this xml file into your cruise control build log.
Add an extra build report that uses an XSLT to show transform the xml test results into pretty html.
The above article goes into more detail on how to do this, as well as a couple of extra considerations (such as deleting old test results).
Also, I've noticed that you are using Visual Studio 2009 - something that the above article does not emphasis is that when you are setting up your dashboard to shown MSTest results, you need to make sure you use the VS2009 specific xslt in the CruiseControl.Net directroy, as the standard one won't display any results on the dashboard.

CruiseControl.NET: How to access modifications in MSBuild task?

I'd like to do some action based on modified files. I have such project configuration
<project name="MyProject">
<sourcecontrol type="vsts" autoGetSource="true">
...
</sourcecontrol>
<tasks>
<msbuild>
...
</msbuild>
</tasks>
Is there any way how to put or access the modifications comes from source control in that configured MSBuild task? I cannot see any integration property for this, but I can see modifications in CCNET build log
<cruisecontrol project="MyProject">
<request source="ScheduledTrunk" buildCondition="ForceBuild">...</request>
<modifications>
<modification type="merge">
<filename>MyFile.cs</filename>
<project>$/MyProject/Trunk/Source/</project>
<date>2010-02-23 02:27:40</date>
<user>domain\user</user>
<comment>Some comment</comment>
<changeNumber>79367</changeNumber>
<version>79367</version>
</modification>
</modifications>
<integrationProperties>
...
</integrationProperties>
<build date="..." buildtime="..." buildcondition="...">
<msbuild
startTime="02/23/2010 11:55:52"
elapsedTime="00:00:51" success="true"
>
...
</msbuild>
</cruisecontrol>
Thanks for suggestion!
BTW do you know why the common CCNet documentation pages are down for several days already? And what is the primary discussion forum for CCNET?
You are looking for the Mofification Writer Task. This tasks writes modification details to an XML file, which can easily be evaluated from an MSBuild task.

cruisecontrol.net email

On CruiseControl.net there is a link called “NUnit Details”. When you click on this it gives a lot of details including a summary section that looks similar to this…
Summary
Assemblies tested: 2
Tests executed: 56
Passes: 54
Fails: 2
Ignored: 2
I would like the summary emailed to me on every build. Any tips would be great.
The format of the e-mail is configured in the ccnet.exe.config or ccservice.exe.config (in C:\Program Files\CruiseControl.NET\server) if you are running ccnet a service.
I believe the file that you want to include is tests.xml as that includes a detailed listing of the nunit test results. Modify the xslFiles section of the configuration file to include this stylesheet. It will look something like this.
<!-- Specifies the stylesheets that are used to transform the build results when using the EmailPublisher -->
<xslFiles>
<file name="xsl\header.xsl"/>
<file name="xsl\compile.xsl"/>
...
<!-- add tests.xsl here... -->
<file name="xsl\tests.xsl"/>
</xslFiles>

Resources