MSBuild & SQL Server Database Project: bind the deploy and publish desination to the build configuration - visual-studio-2012

Visual Studio 2012. SQL Server Database Project.
Four build configurations were created in solution: Debug, DevDb, TestDb, LocalDb.
Three publish profiles were created in project: DevDb.publish.xml, TestDb.publish.xml, LocalDb.publish.xml
Pushing F5 button (!) I want to:
deploy project with connection string from project properties if
build configuration is Debug.
publish project with connection string
from the corresponding publish profiles if build configuration is
DevDb, TestDb or LocalDb.
To do this I edit project (.sqlproj) xml, trying to catch a call of the Deploy target and replace the standart Deploy target with a custom behavior:
<Target Name="Deploy">
<!-- The first statment is for Debug configuration -->
<MSBuild Condition=" '$(Configuration)' == 'Debug' "
Targets="Deploy"
Projects="$(MSBuildProjectFile)"
Properties="Configuration=$(Configuration);"
/>
<!-- The second statement is for DevDb, TestDb, LocalDb configurations -->
<MSBuild Condition=" '$(Configuration)' != 'Debug' "
Targets="SqlPublish"
Projects="$(MSBuildProjectFile)"
Properties="SqlPublishProfilePath=$(Configuration).publish.xml;
Configuration=$(Configuration);"
/>
</Target>
The second statement works fine and I get deployment to the right destination.
The problem is with the first statement - it produces a circular dependency.
error MSB4006: There is a circular dependency in the target dependency graph involving target "Deploy".
My question is: how to intersect (catch and replace) the standart target and if it's required to invoke the standart target again?
Or am I trying to reinvent the wheel and there is another way to do what I want?
(What I want is described above under words "Pushing F5 button" :)

I think I've got the solution.
So if we put such a PropertyGroup with Condition and a custom Target to the end of database project xml file:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
----------- Skip -----------
<PropertyGroup Condition=" '$(Configuration)' != 'Debug' and Exists('$(Configuration).publish.xml')">
<DeployDependsOn>
PublishDatabase
</DeployDependsOn>
</PropertyGroup>
<Target Name="PublishDatabase"> <!-- Custom Target -->
<Message
Text="Deploy is replaced with SqlPublish for configuration = $(Configuration)"
Importance="high" />
<MSBuild
Targets="SqlPublish"
Projects="$(MSBuildProjectFile)"
Properties="SqlPublishProfilePath=$(Configuration).publish.xml;
Configuration=$(Configuration);" />
</Target>
</Project>
we will get the following behaviour:
If the solution build configuration is differ from Debug and the publish profile *.publish.xml exists, then the Deploy target and
operation will be replaced with SqlPublish target and this publish
operation will get the required configuration such as connection
string from the corresponding publish profile.
If the solution build configuration is Debug, then we preserve the standart Visual Studio behaviour when it take th connection string from the project properties.

Related

Visual Studio Online - DevOps

Current client we are setting up CI/CD using VSO => Azure devops and I need some help with the configuration of the releases in the environments. Here's the situation and issue.
I've got the builds all set up and working properly.
I've got 2 Environments set up in the release configuration. Artifact is set up for the drops. Dev environment is set up as well as QA.
In VS2015 I've got the web.config transforms and configurations set up for Debug, Dev, QA, and Release. Dev/QA/Release each have a transformation that is to be applied for their respective enviornment.
Build triggers upon checkin and the release deployment triggers correctly upon successful build.
Dev environment and QA environment both trigger correctly in the release and are released accordingly.
In the task configuration for each I've got the XML Transformation selected as well as the correct deployment slot. The issue is that the only web.config transformation that is being applied is the release transformation not the correct transformation for the respective environment.
I have 4 transformation configs in the environment set up.
web.config
web.Debug.config
web.Dev.config
web.QA.config
web.Release.config
in VSO I have 2 environments set up in the Release Package
Dev & QA
In each of the environment I have the XML Transformation check which the tooltip states that it will apply the web.Release.config and each respective environment config.
The later is not happening.
logs:
the logs state:
Unable to apply transformation for the given package. Verify the following.

1. Whether the Transformation is already applied for the MSBuild generated package during build. If yes, remove the tag for each config in the csproj file and rebuild.

2. Ensure that the config file and transformation files are present in the same folder inside the package.
Both of those states have been confirmed. I've got the transform configs set to copy if newer.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.8\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.8\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.Default.props" Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.Default.props')" />
<Import Project="..\packages\Microsoft.Net.Compilers.2.4.0\build\Microsoft.Net.Compilers.props" Condition="Exists('..\packages\Microsoft.Net.Compilers.2.4.0\build\Microsoft.Net.Compilers.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{88941EE6-99FC-4DE5-8FE3-9F532FD855F2}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TripManager</RootNamespace>
<AssemblyName>TripManager</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
<UseIISExpress>true</UseIISExpress>
<IISExpressSSLPort>44385</IISExpressSSLPort>
<IISExpressAnonymousAuthentication>disabled</IISExpressAnonymousAuthentication>
<IISExpressWindowsAuthentication>enabled</IISExpressWindowsAuthentication>
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
<TargetFrameworkProfile />
<Use64BitIISExpress />
<TypeScriptToolsVersion>1.8</TypeScriptToolsVersion>
<ApplicationInsightsResourceId>/subscriptions/ee4492d7-5913-4e7b-85c0-3915e8c6c5c2/resourcegroups/rg-TripTracker-dev-SC/providers/microsoft.insights/components/TripManager</ApplicationInsightsResourceId>
<WebProject_DirectoryAccessLevelKey>1</WebProject_DirectoryAccessLevelKey>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Dev|AnyCPU'">
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'QA|AnyCPU'">
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
</Project>
The problem is that config transform files are not included in the build result.
Ensure that the config file and transformation files are present in
the same folder inside the package.
Marina Liu's answer could work, but there is a much simpler way to achieve this:
The transform file should not be Dependent upon web.config. Just create a new file in the same directory as the web.config file.
Set the Build Action of the transform file to Content.
Or just change the entry in the .csproj file from this:
<None Include="Web.QA.config">
<DependentUpon>Web.config</DependentUpon>
</None>
To this:
<Content Include="Web.QA.config" />
This makes sure the files are included in the package after build.
No matter whether the transformation is applied for the MSBuild generated package or not, add the config files to the zipped package (as option 2 in release log suggests: Ensure that the config file and transformation files are present in the same folder inside the package) should work.
So you can add the config files in your build definition before the artifacts published. Detail steps as below:
After Visual Studio Build task (and before Publish Build Artifacts) and the following tasks to extract the zip file and add config files in the extract folder, then zip the files again:
1. Extract files task
Archive file patterns: $(Build.ArtifactStagingDirectory)\*.zip
Destination folder: specify the folder for the extract files, such as $(Build.ArtifactStagingDirectory)\test
2. Copy Files task
Source Folder: $(Build.SourcesDirectory)
Contents: **\*.config
Target Folder: Folder for the extract files, such as $(Build.ArtifactStagingDirectory)\test
3. Delete Files task
Source Folder: $(Build.ArtifactStagingDirectory)
Contents: *.zip (delete the zip file which generated by Visual Studio Build task)
4. Archive Files task
Root folder (or file) to archive: Folder for the extract files, such as $(Build.ArtifactStagingDirectory)\test
Archive type: zip
Archive file to create: such as $(Build.ArtifactStagingDirectory)\package.zip
5. Delete Files task
Source Folder: $(Build.ArtifactStagingDirectory)
Contents: delete the extract folder,such as test
Then the package will be deployed to Azure App Service successful in release.

TypeScript Unit-Testing on VSTS with Continuous Integration in a C# Web Application

I have a web application with continuous integration via visual studio team services and I want to add unit tests for my typescript code.
First try
At first I tried to create a Blank Node.js Console Application in my solution. I wrote some tests (with 'mocha',etc...) which worked fine locally. But as I commited the solution I noticed the build server not being able to...well...build:
Error : web.config not found in project, to create a project to deploy to Microsoft Azure you must create an Azure Node.js project.
This message suggested that msbuild wanted to create a deployable package of my NodeJS Project even though I only used it for testing purposes. The first thing that came to mind was to add a minimal web.config even though I did not want to publish the NodeJS project:
Error MSB4062: The "TypeScript.Tasks.FormatLocalizedString" task could not be loaded from the assembly C:\xxx\Microsoft.TypeScript.MSBuild.2.3.3\build\\..\tools\net45\TypeScript.Tasks.dll. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
I don't really see any way out of this...
Second try
Then I tried to use a UnitTest Project instead of the NodeJS Project. Surely this will work, or so I thought. With this approach I ran into the problem that VS Test did not recognize my Unit Tests (which worked fine on my NodeJS project) as there was no option to mark my files with the appropriate "Test Framework" attribute which was present on the file properties in the NodeJS Project. Instead there were the default file options for "Custom Tool", etc:
No Problem! I'll just adjust the .csproj file directly!
<TypeScriptCompile Include="main.test.ts">
<SubType>Code</SubType>
<TestFramework>Mocha</TestFramework>
<Publish>False</Publish>
</TypeScriptCompile>
But, alas, no dice...The Tests still could not be found by VS Test
Question
What is the best practices approach here? Is there something I'm not thinking of? Was the 'First try' correct and I just did not find the correct option to disable the publishing of my NodeJS App?
PS
I now think my first approach was the correct one. Just to be clear: A lot of things already worked:
Installed Node Tools for Visual Studio on the Build Server
Compiling typescript via VSTS
Running Tests in VS Test locally
List item
Running npm install on build (in VSTS)
Now all I need is for the build to go through :/
I now notice that I did not write the full error message for the last error in the first approach:
##[error]C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\TypeScript\Microsoft.TypeScript.targets(60,5): Error MSB4062: The "TypeScript.Tasks.FormatLocalizedString" task could not be loaded from the assembly C:\Agent-PaketBuildIntern1\_work\54\s\packages\Microsoft.TypeScript.MSBuild.2.3.3\build\\..\tools\net45\TypeScript.Tasks.dll. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
So we see here that it uses the .targets file under C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\TypeScript\ and not the one under ......\packages\Microsoft.TypeScript.MSBuild.2.3.3\tools
Could this be the problem? How do I go about correcting that?
.njsproj file:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<VisualStudioVersion>14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<Name>MyProjectName</Name>
<RootNamespace>MyProjectName</RootNamespace>
<SccProjectName>SAK</SccProjectName>
<SccProvider>SAK</SccProvider>
<SccAuxPath>SAK</SccAuxPath>
<SccLocalPath>SAK</SccLocalPath>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>5697a590-d15f-401b-b8d8-138bbd5d3330</ProjectGuid>
<ProjectHome>.</ProjectHome>
<StartupFile>
</StartupFile>
<StartWebBrowser>False</StartWebBrowser>
<SearchPath>
</SearchPath>
<WorkingDirectory>.</WorkingDirectory>
<OutputPath>.</OutputPath>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<ProjectTypeGuids>{3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}</ProjectTypeGuids>
<TypeScriptSourceMap>true</TypeScriptSourceMap>
<TypeScriptModuleKind>CommonJS</TypeScriptModuleKind>
<EnableTypeScript>true</EnableTypeScript>
<StartWebBrowser>false</StartWebBrowser>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Content Include="tsconfig.json">
<SubType>Code</SubType>
</Content>
<Content Include="package.json" />
<Content Include="README.md" />
<Content Include="Web.config" />
<TypeScriptCompile Include="Scripts\typings\node\node.d.ts" />
<TypeScriptCompile Include="bootstrap.test.ts">
<SubType>Code</SubType>
<TestFramework>Mocha</TestFramework>
<Publish>False</Publish>
</TypeScriptCompile>
<TypeScriptCompile Include="util\templates.ts">
<SubType>Code</SubType>
</TypeScriptCompile>
</ItemGroup>
<ItemGroup>
<Folder Include="util\" />
<Folder Include="Scripts\" />
<Folder Include="Scripts\typings\" />
<Folder Include="Scripts\typings\node\" />
</ItemGroup>
<PropertyGroup>
<PreBuildEvent>cd $(ProjectDir)
call npm install
</PreBuildEvent>
</PropertyGroup>
<Import Project="..\..\..\packages\Microsoft.TypeScript.MSBuild.2.3.3\build\Microsoft.TypeScript.MSBuild.targets" Condition="Exists('..\..\..\packages\Microsoft.TypeScript.MSBuild.2.3.3\build\Microsoft.TypeScript.MSBuild.targets')" />
<Import Project="$(VSToolsPath)\Node.js Tools\Microsoft.NodejsTools.targets" />
</Project>
Refer to these steps (vs2015):
Create a new Node.js Console Application
Update package.json dependencies and scripts like this
:
{
"name": "nodejs-console-app-demo",
"version": "0.0.0",
"description": "NodejsConsoleAppDemo",
"main": "app.js",
"author": {
"name": "XXX",
"email": ""
},
"dependencies": {
"#types/mocha": "^2.2.41",
"assert": "^1.4.1",
"mocha": "^3.4.2",
"typescript": "^2.4.1"
},
"scripts": {
"tsc": "tsc"
}
}
Right click the project/folder >Add> New Item> Select TypeScript Mocha UnitTest file
Add your test code
Add a folder to your project (e.g. ntvs)
Copy 1.1 folder in C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\Node.js Tools for Visual Studio to that ntvs folder
Right click your project > Add > New Item> Select Json template> add a new json file to project > Rename it to tsconfig.json
:
{
"compilerOptions": {
"noImplicitAny": false,
"noEmitOnError": true,
"removeComments": false,
"sourceMap": true,
"target": "ES6",
"module": "commonjs",
"moduleResolution": "node",
"watch": false
},
"exclude": [
"node_modules"
],
"include": [
"src/**/*",
"test/**/*"
]
}
Right click your project > Unload project
Right click your project > Edit [projectname].njsproj
Change <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> to <VisualStudioVersion>14.0</VisualStudioVersion>
Save all changes and add files to source control (by default .dll files will be ignored, so make sure all files in ntvs folder have been added to source control, you can right click ntvs folder > add files to source control)
Create a build definition
Npm install task (Command: install; Working folder: [package.json file path, such as $(Build.SourcesDirectory)\NodejsConsoleAppDemo]
Npm install task (Command: custom; Working folder: [tsconfig.json file path, such as $(Build.SourcesDirectory)\NodejsConsoleAppDemo]; Command and arguments: run tsc)
Visual Studio Test task (Test assemblies: [project file path, such as NodejsConsoleAppDemo\NodejsConsoleAppDemo.njsproj; Search folder: $(System.DefaultWorkingDirectory); Test platform version: Visual Studio 2015; Path to custom test adapters: [ntvs folder path, such as NodejsConsoleAppDemo/ntvs]]
Queue build with Hosted agent
There is an article that can help you: nodejstools.
If you are using VS 2017, you can refer to this thread: Running node.js tests locally in vstest.console.exe gives … Error: An exception occurred while invoking executor 'executor://nodejstestexecutor/v1.
After several attempts to make this work I decided to solve the problem at hand by putting the Mocha tests inside the Web Application Project and running them via npm (in the build steps). Inside the CI build definition I published the result of these tests via mocha-junit-reporter (https://www.npmjs.com/package/mocha-junit-reporter - see this answer for details).
This works for my requirements, although I would have liked to have the unit tests in a seperate project.

How to share parameters configuration between VS publish profile and MSDeploy SetParameters.xml?

I have a web application in Visual Studio 2012. I publish this website to IIS using publish profiles (.pubxml).
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<ExcludeApp_Data>False</ExcludeApp_Data>
<MSDeployServiceURL>server</MSDeployServiceURL>
<DeployIisAppPath>site</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>False</SkipExtraFilesOnServer>
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
<EnableMSDeployBackup>True</EnableMSDeployBackup>
<UserName>domain\username</UserName>
</PropertyGroup>
<ItemGroup>
<MSDeployParameterValue Include="MyParam">
<ParameterValue>MyValue</ParameterValue>
</MSDeployParameterValue>
...
</ItemGroup>
</Project>
Beside I setup a CI to build a package with msbuild and then use it to publish to the different environnement using msdeploy. Both in 2 separates steps, so I can reuse the same package multiple times.
To do this I need to use a SetParameters.xml with a different syntax than the publish profil used by VS.
<?xml version="1.0" encoding="utf-8"?>
<parameters>
<setParameter name="IIS Web Application Name" value="site" />
<setParameter name="MyParam" value="MyValue" />
...
</parameters>
Is there a way to share the parameters configuration in a single file so I can maintain only one file ?
I see this answers from 2014 but I can't managed to make it works.
I've researched this and can't find a way to override the SetParameters file when publish via VisualStudio. It doesn't look like the MSBuild tasks support this.
The best alternative I can offer is to use the commandline instead of right click publish. You can create the MSDeploy package by calling the Package target:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild /t:Package /p:PublishProfile=<profile-name>
And then deploy using MSDeploy.exe:
"C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -source:package=WebApplication7.zip -dest:manifest=WebApplication7.DestManifest.xml -setParamFile:SetParameters.custom.xml
The following blog posts has more details:
https://dotnetcatch.com/2016/02/25/the-anatomy-of-a-webdeploy-package/

How to setup building steps for CruiseControl.net from repository of the building project?

I'd like to store ccnet.config file (or other cc.net configuration file for this project) in the repository (git) of my project and make CC.NET use it when I force building from dashboard. How can I do it?
Thank you!
Your "ccnet.config" should remain fairly static.
If you need different "logic" for your solution/project building, then I suggest:
1. Write your ccnet.config code to pull source code from repository. (aka, Task #1)
2. In your repository, include a MasterBuild.proj (msbuild definition).
3. Have cc.net call msbuild.exe on MasterBuild.proj (aka, Task #2).
4. Have the majority of your logic inside the MasterBuild.proj file. That is what you check in/out of source control.
If you think of CC.NET as a "super fancy msbuild.exe executor", you're world will make more sense IMHO.
Here is a very basic msbuild (definition) file.
You can call it
MySolutionMasterBuild.proj (or similar)
Put this in the same directory as your .sln file (in source control).
Use CC.NET to download the code.
Then wire up msbuild.exe to call the below file.
Then have any extra logic inside the .proj file.
You can do some of the other CC.NET stuff, like post build emailing and merging any results xml, but the majority of the logic (my preference anyways)..........would be in the file below.
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="AllTargetsWrapped">
<PropertyGroup>
<!-- Always declare some kind of "base directory" and then work off of that in the majority of cases -->
<WorkingCheckout>.</WorkingCheckout>
<ArtifactDestinationFolder>$(WorkingCheckout)\ZZZArtifacts</ArtifactDestinationFolder>
</PropertyGroup>
<Target Name="AllTargetsWrapped">
<CallTarget Targets="CleanArtifactFolder" />
<CallTarget Targets="BuildItUp" />
<CallTarget Targets="CopyFilesToArtifactFolder" />
</Target>
<Target Name="BuildItUp" >
<MSBuild Projects="$(WorkingCheckout)\MySolution.sln" Targets="Build" Properties="Configuration=$(Configuration)">
<Output TaskParameter="TargetOutputs" ItemName="TargetOutputsItemName"/>
</MSBuild>
<Message Text="BuildItUp completed" />
</Target>
<Target Name="CleanArtifactFolder">
<RemoveDir Directories="$(ArtifactDestinationFolder)" Condition="Exists($(ArtifactDestinationFolder))"/>
<MakeDir Directories="$(ArtifactDestinationFolder)" Condition="!Exists($(ArtifactDestinationFolder))"/>
<Message Text="Cleaning done" />
</Target>
<Target Name="CopyFilesToArtifactFolder">
<ItemGroup>
<MyExcludeFiles Include="$(WorkingCheckout)\**\*.doesnotexist" />
</ItemGroup>
<ItemGroup>
<MyIncludeFiles Include="$(WorkingCheckout)\bin\$(Configuration)\**\*.*" Exclude="#(MyExcludeFiles)"/>
</ItemGroup>
<Copy
SourceFiles="#(MyIncludeFiles)"
DestinationFiles="#(MyIncludeFiles->'$(ArtifactDestinationFolder)\%(Filename)%(Extension)')"
/>
</Target>
</Project>
Take a look at the scenario's at
http://www.cruisecontrolnet.org/projects/ccnet/wiki/Build_Server_Scenarios
Step 1 Setting up Source Control
Step 2 Build on Check-in
Step 3 Add unit tests
Step 4 Add Coverage
Step 5 Add source code analysis
There are build scripts foreseen in each step where you can base yourself on.

Include files in MSBuild that are not part of project

I'm trying to create an automated build for my web application project.
We use a standard CMS project and have tweaked some parts of it. Only the tweaked files are part of our project, but I want to include the full CMS in the deployment package.
So I've created a custom .targets file to define a task to include the CMS files during the build:
<Target Name="GetCMSFiles">
<ItemGroup>
<!-- Include the CMS files into the package -->
<_CMSFiles Include="..\packages\CMSFiles\**\*" />
<FilesForPackagingFromProject Include="%(_CMSFiles.Identity)">
<DestinationRelativePath>
%(RecursiveDir)%(Filename)%(Extension)
</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<!-- VS2010 -->
<CopyAllFilesToSingleFolderForPackageDependsOn>
GetCMSFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<!-- VS2012 -->
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
GetCMSFiles;
$(CopyAllFilesToSingleFolderForMsdeployDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
This works fine, but the problem is that the files from our project do not get copied to the deployment folder. So in other words, it does not overwrite the files that already exist after I copied them with the GetCMSFiles task.
The way I see it there are two options:
Force the CopyAllFilesToSingleFolder to overwrite any existing files in the deployment folder.
Have a condition in the GetCMSFiles task to only include files that don't already exist in the project.
But I'm not sure whether this is possible and how to achieve this. Any ideas?

Resources