Hi I have the following target.
<Target
Name="TestCopy"
AfterTargets="BeforeBuild"
>
<Message
Text="Copying base Sitecore config files #(GenerateDuringBuild)
%(GenerateDuringBuild.RootDir)%(GenerateDuringBuild.Directory)UpdatedConfiguration\%(GenerateDuringBuild.Filename)\%(GenerateDuringBuild.Filename)%(GenerateDuringBuild.Extension)
%(GenerateDuringBuild.RootDir)%(GenerateDuringBuild.Directory)UpdatedConfiguration\%(GenerateDuringBuild.Filename)\%(GenerateDuringBuild.Filename)%(GenerateDuringBuild.Extension).test
"
/>
<Copy
SourceFiles="%(GenerateDuringBuild.RootDir)%(GenerateDuringBuild.Directory)UpdatedConfiguration\%(GenerateDuringBuild.Filename)\%(GenerateDuringBuild.Filename)%(GenerateDuringBuild.Extension)"
DestinationFiles="%(GenerateDuringBuild.RootDir)%(GenerateDuringBuild.Directory)UpdatedConfiguration\%(GenerateDuringBuild.Filename)\%(GenerateDuringBuild.Filename)%(GenerateDuringBuild.Extension).test"
Condition="!Exists('%(GenerateDuringBuild.FullPath)')"
/>
</Target>
The Message outputs the correct paths but does not do the copy.
The file does not exist.
Wrong variable name. GenerateDuringBuild is for another task. Lesson Learned. Do not copy and paste.
Related
I believe this is more of an msbuild-related question.
Have a .net core app and I need to conditionally publish a file and based on the build config selected in Visual Studio 2019, the file should be renamed before publishing to the target.
So Im looking at modifying the csproj file (which is nothing but an msbuild file itself)
I dont see a condition option on the copy task
https://learn.microsoft.com/en-us/visualstudio/msbuild/copy-task?view=vs-2019
The goal Im after, is if I have 3 different files
tester-notes.dev.json
tester-notes.debug.json
tester-notes.prod.json
If prod is selected as a build config, I want the file published to be tester-notes.prod.json, but renamed to tester-notes.json
Assuming you have three files(build action = None) in Solution Explorer when developing:
You can use something similar to this script to rename and copy to publish folder if you're using FileSystem publish mode:
<ItemGroup Condition="$(Configuration)=='Dev'">
<FileToRename Include="$(ProjectDir)\tester-notes.dev.json" />
</ItemGroup>
<ItemGroup Condition="$(Configuration)=='Debug'">
<FileToRename Include="$(ProjectDir)\tester-notes.debug.json" />
</ItemGroup>
<ItemGroup Condition="$(Configuration)=='Prof'">
<FileToRename Include="$(ProjectDir)\tester-notes.prof.json" />
</ItemGroup>
<Target Name="DoSthAfterPublish1" AfterTargets="Publish" Condition="$(Configuration)=='Dev'">
<Copy SourceFiles="#(FileToRename)" DestinationFiles="#(FileToRename->Replace('.dev.json','.json'))"/>
<Move SourceFiles="$(ProjectDir)\tester-notes.json" DestinationFolder="$(PublishDir)" OverwriteReadOnlyFiles="true"/>
</Target>
<Target Name="DoSthAfterPublish2" AfterTargets="Publish" Condition="$(Configuration)=='Debug'">
<Copy SourceFiles="#(FileToRename)" DestinationFiles="#(FileToRename->Replace('.debug.json','.json'))"/>
<Move SourceFiles="$(ProjectDir)\tester-notes.json" DestinationFolder="$(PublishDir)" OverwriteReadOnlyFiles="true"/>
</Target>
<Target Name="DoSthAfterPublish3" AfterTargets="Publish" Condition="$(Configuration)=='Prof'">
<Copy SourceFiles="#(FileToRename)" DestinationFiles="#(FileToRename->Replace('.prof.json','.json'))"/>
<Move SourceFiles="$(ProjectDir)\tester-notes.json" DestinationFolder="$(PublishDir)" OverwriteReadOnlyFiles="true"/>
</Target>
And if you can reset tester-notes.debug.json to tester-notes.Debug.json,, then we may combine the three targets into one by using DestinationFiles="#(FileToRename->Replace('.$(Configuration).json','.json'))". Hope it makes some help :)
In addition:
According to the Intellisense we can find the Copy task supports Condition:
If I use msbuild to build my project, all the folders not included in my solution are not deployed. Is there a way of deploying the umbraco and umbraco_client folders using msbuild?
I have tried using Targets like:
https://gist.github.com/aaronpowell/6695293
How can we include the files created by ajaxmin in the msdeploy package created by MSBuild
https://blog.samstephens.co.nz/2010/10/18/msbuild-including-extra-files-multiple-builds/
But hey are not being copied to the output folder. Am I missing anything?
You can use a msbuild target(run after the build ends) in which it calls the msbuild copy task to copy necessary files or folders to output folder. Use AfterTargets="build" to let the target run after the build.
A target script which works in my machine looks like this:
<Target Name="Copyumbraco" AfterTargets="build">
<ItemGroup>
<UmbracoFiles Include="$(ProjectDir)**\umbraco\**\*" />
<Umbraco_ClientFiles Include="$(ProjectDir)**\umbraco_client\**\*" />
</ItemGroup>
<Copy SourceFiles="#(UmbracoFiles)" DestinationFolder="$(OutputPath)\%(RecursiveDir)"/>
<Copy SourceFiles="#(Umbraco_ClientFiles)" DestinationFolder="$(OutputPath)\%(RecursiveDir)"/>
</Target>
Using $(ProjectDir) property to define the path, so Msbuild can find those two folders if they are in project folder as you mentioned in comment.
The \%(RecursiveDir) set the msbuild copy task to copy the files to destination path with original folder structure. If what you want to just copy all files to Output folder, you don't need to set it, then the script should be:
<Target Name="Copyumbraco" AfterTargets="build">
<ItemGroup>
<UmbracoFiles Include="$(ProjectDir)**\umbraco\**\*" />
<Umbraco_ClientFiles Include="$(ProjectDir)**\umbraco_client\**\*" />
</ItemGroup>
<Copy SourceFiles="#(UmbracoFiles)" DestinationFolder="$(OutputPath)"/>
<Copy SourceFiles="#(Umbraco_ClientFiles)" DestinationFolder="$(OutputPath)"/>
</Target>
Add the target script into the your project's project file(xx.csproj), make sure you place the script in the format below, then it can work when you use msbuild to build the project.
<Project Sdk="Microsoft.NET.Sdk.Web">
...
<Target Name="Copyumbraco" AfterTargets="build">
...
</Target>
</Project>
In addition:
For normal projects like console app, class library, the $(OutputPath) represents the output path. But for web site project, we can use $(WebProjectOutputDir) , hint from Mario!
In my project I have a json file I use for configuration that I have git set to ignore. When the repository is first cloned, the configuration file that is part of the project and that is copied to the output directory doesn't exist. I've gotten this to work using tasks in the 'BeforeBuild' target in the project that will copy the sample file to the actual config file if it doesn't exist.
<Target Name="BeforeBuild">
<ItemGroup>
<MySourceFiles Include="Configuration.sample.json" />
</ItemGroup>
<ItemGroup>
<MyDestinationFiles Include="Configuration.json" />
</ItemGroup>
<Message Importance="high" Condition="!Exists('#(MyDestinationFiles)')"
Text="Copying #(MySourceFiles) to #(MyDestinationFiles)" />
<Copy Condition="!Exists('#(MyDestinationFiles)')"
SourceFiles="#(MySourceFiles)"
DestinationFiles="#(MyDestinationFiles)" />
</Target>
So if I build the project, then delete the configuration file and do a build, nothing happens because no changes have been made that would change the outputs I think. Is there a way to change the project file so that a build will be flagged as necessary? It shouldn't come up very often and I can always do a 'Clean' or 'Rebuild' manually, but it's nagging at me since I'm just starting to learn MSBuild files.
From the documentation on a Target's Outputs attribute:
The files that form outputs into this target. Multiple files are
separated by semicolons. The timestamps of the files will be compared
with the timestamps of files in Inputs to determine whether the Target
is up to date
So if you add the paths to the outputfiles created by your Beforebuild target to it's Outputs attribute, at the start of every build msbuild will check if those files exist and if not it will start a build because now the project is considered to not be up-to-date anymore. In practice use:
<Target Name="BeforeBuild" Outputs="#(MyDestinationFiles)">
Can I turn off generating these folders on build? They contain some .dll, .pdb and other files I don't need. I'm just using Typescript compilation.
Yes, it is possible. I relied on the following nice overview on how to hijack a build process:
http://sedodream.com/2013/06/01/HijackingTheVisualStudioBuildProcess.aspx
Three main tricks:
1) project_name.csproj is the one you need to modify, it is XML MSBUILD file.
2) You cannot remove dependency from WebApplication.targets, you need to "deactivate" them as below.
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v11.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
3) You have to implement general contract for clean/build/rebuild targets.
Mine looks like:
<Target Name="Build">
<Exec Command="call node_modules\.bin\tsc.cmd src/main.ts --out js/game.min.js > $(Temp)\tscout.txt" IgnoreExitCode="true" WorkingDirectory="$(SolutionDir)" />
<Exec Command="type $(Temp)\tscout.txt" />
</Target>
<Target Name="Rebuild" DependsOnTargets="Clean;Build">
</Target>
<Target Name="Clean">
<RemoveDir Directories="js">
</RemoveDir>
</Target>
You could create a New WebSite instead of New Project. That one should not create any binary output.
I have a custom MSBuild task that takes in a set of JavaScript files, minifies them, and outputs them, with the extension .min.js. When I do a normal build through Visual Studio, it works perfectly and the .min.js files are output to the same directory as the original files. When I try to deploy using the Publish feature in Visual Studio, only the original .js files make it to the publish directory.... How can I get the output of my task to be counted as "content" so that it will end up in the published folder?
EDIT:
I was able to figure it out by adding the Output tag inside my task and then creating an ItemGroup around that:
<Target Name="AfterBuild">
<ItemGroup>
<JavaScriptFiles Include="Scripts\*.js" Exclude="Scripts\*.min.js" />
</ItemGroup>
<JsCompress Files="#(JavaScriptFiles)" OutputPath="Scripts">
<Output TaskParameter="CompressedFiles" ItemName="CompressedFiles" />
</JsCompress>
<ItemGroup>
<Content Include="#(CompressedFiles)" />
</ItemGroup>
</Target>
Build and Publish are separate targets. Add a target to your project, abstract your minification to its own target, then make the AfterBuild and Publish target depend on the minification target. Something like this:
<Target Name="AfterBuild" DependsOnTargets="Build;Minify">
</Target>
<Target Name="Publish" DependsOnTargets="Build;Minify">
</Target>
<Target Name="Minify" DependsOnTargets="Build">
<ItemGroup>
<JavaScriptFiles Include="Scripts\*.js" Exclude="Scripts\*.min.js" />
</ItemGroup>
<JsCompress Files="#(JavaScriptFiles)" OutputPath="Scripts">
<Output TaskParameter="CompressedFiles" ItemName="CompressedFiles" />
</JsCompress>
<ItemGroup>
<Content Include="#(CompressedFiles)" />
</ItemGroup>
</Target>
This snippet, of course, means you have to have a build target, which may or not be the case. For that reason you may need to modify this. Hope this helps!
Change the file properties. Check the Build Action and Copy to Output Directory properties for those files.