i have a console application in vs2010 (C#) and in the project, i have a Folder added by me (right click on project.. add->folder) and i want that when i compile the application (debug or release), then the folder will be created (if not exists) in the debug or release directory.
Is that possible?
The console application is a daemon that access to a database and send emails with templates allocated in that folder.
I hope you can help me. Thanks!
There's no "automatic" way to get VS to create folders (other than the specified output folder) during a build, but there's two pretty easys ways to accomplish it.
Use a post-build event, which you set up in the Build Events tab of your project's properties. This is basically a batch file that you run after the build completes, something like this:
IF NOT EXIST $(OutDir)MySubFolder MKDIR $(OutDir)MySubFolder
XCOPY /D $(ProjectDir)MySubFolder\*.tmpl $(OutDir)MySubFolder
Use MSBuild's AfterBuild event. This is my preferred method, mostly because it integrates better with our automated build process, but it's a little more involved:
Right-click on your project node and Unload it
Right-click on the unloaded project node and Edit the file
Near the bottom is a commented-out pair of XML nodes. Uncomment the AfterBuild target and replace it with something like this:
<Target Name="AfterBuild">
<MakeDir Directory="$(OutDir)MySubFolder" Condition="!Exists('$(OutDir)MySubFolder')" />
<CreateItem Include="$(ProjectDir)MySubFolder\*.tmpl">
<Output TaskParameter="Include" ItemName="Templates" />
</CreateItem>
<Copy SourceFiles="#Templates" DestinationFolder="$(OutDir)MySubFolder" ContinueOnError="True" />
</Target>
Save the changes, close the .csproj file, then right-click and Reload the project.
I solve it, like this:
in the csproj:
<Target Name="AfterBuild">
<MakeDir Directories="$(OutDir)EmailTemplates" Condition="!Exists('$(OutDir)EmailTemplates')" />
<ItemGroup>
<Templates Include="$(ProjectDir)EmailTemplates\*.*" />
</ItemGroup>
<Copy SourceFiles="#(Templates)" DestinationFolder="$(OutDir)EmailTemplates" />
</Target>
Thank you for your help!
Related
We are trying to deploy an AngularJs website to azure that is build with gulp. So we develop in a source application and gulp copies the files to the dist project. The dist project is a Azure cloud source Web Role. The "compiled" files are inside of the project folder, though for some reason they are not copied.
We turned on the option Properties -> Package/Publich Web -> All files in this project folder
After deploying I only see the packes.config, web.config and bin folder. Is there anything we need to do to get the rest of the files deployed?
Yep, gulp generated files are not actually part of the project (included in the xx.csproj file) which is why "All files..." does not work. We accomplish this by adding some custom targets for build to the project file - our gulp files are in a folder called "dist".
Unload Project >> Edit... then include something like:
<Target Name="CustomCollectFiles">
<ItemGroup>
<_DistFiles Include="dist\**\*" />
<FilesForPackagingFromProject Include="%(_DistFiles.Identity)">
<DestinationRelativePath>dist\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<_SrcFiles Include="src\**\*" />
<FilesForPackagingFromProject Include="%(_SrcFiles.Identity)">
<DestinationRelativePath>src\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
<PropertyGroup>
<TypeScriptModuleKind>AMD</TypeScriptModuleKind>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
.
.
.
<Target Name="AfterBuild" DependsOnTargets="CustomCollectFiles">
<Copy SourceFiles="#(_DistFiles)" DestinationFolder="dist" />
</Target>
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.
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?
Can slowcheetah transform an external config file in an azure web role? e.g. I have logging info in log4net.config. But the transformed version does not get created when packaged.
I did not manage to get slowCheetah working in my Azure solution.
One alternative you can use is to create complete config files for each environment - e.g. :
log4net.debug.config
log4net.release.config
and copy the contents of these into the log4net.config at buildtime depending on the build configuration chosen.
This is done by adding a build target to your csproj file like so:
<Target Name="BeforeBuild">
<Delete Files="$(ProjectDir)log4net.config" />
<Copy SourceFiles="$(ProjectDir)log4net.$(Configuration).config"
DestinationFiles="$(ProjectDir)log4net.config" />
</Target>
(you may have to modify the paths in the script depending on where in the solution your config files are)
You can find more information on MSBuild and manipulating your .csproj file here and here
We have CC.NET setup on our ASP.NET app. When we build the project, the ASP.NET app is pre-compiled and copied to a network share, from which a server runs the application.
The server is a bit different from development box'es, and the next server in our staging environment differs even more. The difference is specific config files and so on - so I want to exclude some files - or delete them before the pre-compiled app is copied to a network share.
My config file looks like this:
<project name="Assembly.Web.project">
<triggers>
<intervalTrigger seconds="3600" />
</triggers>
<sourcecontrol type="svn">
<trunkUrl>svn://svn-server/MyApp/Web/Trunk</trunkUrl>
<workingDirectory>C:\build-server\Assembly\Web\TEST-HL</workingDirectory>
<executable>C:\Program Files (x86)\SVN 1.5 bin\svn.exe</executable>
<username>uid</username>
<password>pwd</password>
</sourcecontrol>
<tasks>
<msbuild>
<executable>C:\Windows\Microsoft.NET\Framework64\v3.5\MSBuild.exe</executable>
<workingDirectory>C:\build-server\Assembly\Web\TEST-HL</workingDirectory>
<projectFile>C:\build-server\Assembly\Web\TEST-HL\Web\Web.sln</projectFile>
<buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag</buildArgs>
<targets>Build</targets>
<timeout>900</timeout>
<logger>C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</msbuild>
</tasks>
<publishers>
<buildpublisher>
<sourceDir>C:\build-server\Assembly\Web\PrecompiledWeb</sourceDir>
<publishDir>\\test-web01\Web</publishDir>
<useLabelSubDirectory>false</useLabelSubDirectory>
<alwaysPublish>false</alwaysPublish>
</buildpublisher>
</publishers>
</project>
As you can see, I use a buildPublisher to copy the pre-compiled files to the network share. What I want to do here, is either 1) delete certain files before they are copied or 2) replace those files after they have been copied.
I DO NOT want to have some app running watching specific files for change, and then after that replace the files with other ones. I want something to be either done by CC.NET, or triggered by CC.NET.
Can you launch a .bat file with CC.NET?
I use a NAnt task for all publishing, deploying, cleaning and so on.
Take a look at MSDEPLOY or Web Deployment Projects. There is a question that will provide more detail here
You have to use NAnt for those kind of stuff.
Here is the Task Reference of Nant..
Of course CruiseControl.NET can run a batch file, simply use the exec task. However, an easier answer might just be to have MSBuild do the task for you. It should be simple to add a few steps in the postcompile target.