VS2012 MSBuild: Publish a Web Application Project with Existing Publish Profile - visual-studio-2012

In the Visual Studio 2012 Build menu, there's a Publish command. In this you can establish profiles which are saved as .pubxml files in the Properties folder of the Project. I have one such profile that's a simple file copy operation - it just compiles the site and dumps it to a folder.
How can I use msbuild at the command line to publish a compiled web application to a folder?
What I've tried
I've tried the example from this question:
After Publish event in Visual Studio
And the changes and examples given here:
http://www.digitallycreated.net/Blog/59/locally-publishing-a-vs2010-asp.net-web-application-using-msbuild
The latter seems to get closest, but it causes every library Project the .csproj I'm attempting to publish from to throw an error:
Project "MainProj.csproj" (1) is building "ReferencedProj.csproj" (2) on node 1 (default targets).
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(609,5): error : The OutputPath property is not set for project 'ReferencedProj.csproj'. Please check to make sure that you have specified a valid combination of Configuration and Platform for this project. Configuration='Staging' Platform='AnyCPU'. You may be seeing this message because you are trying to build a project without a solution file, and have specified a non-default Configuration or Platform that doesn't exist for this project. [ReferencedProj.csproj]
Done Building Project "ReferencedProj.csproj" (default targets) -- FAILED.
This approach is very similar to what's suggested in this answer:
https://stackoverflow.com/a/7077178/176877
The crucial difference may be that I'm in Visual Studio 2012, rather than VS2008 or 2010.

Old question, but in case this helps anyone, this simple, stripped back approach worked fine for me:
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
...
<BuildDependsOn>
$(BuildDependsOn);
PublishOtherProject;
</BuildDependsOn>
</PropertyGroup>
<Target Name="PublishOtherProject">
<MSBuild Projects="pathtomyproject.csproj" Properties="DeployOnBuild=true;PublishProfile=nameOfPublishProfile" />
</Target>
The key line being:
<MSBuild Projects="pathtomyproject.csproj" Properties="DeployOnBuild=true;PublishProfile=nameOfPublishProfile" />

Related

how to publish wepback bundles on VSTS for MVC app on azure

I am having trouble figuring out how to use VSTS to deploy an arbitrary directory from my build to an azure web app.
The arbitrary directory is produced during the build step and contains the webpack bundled javascript for my app. Here are the details:
I have an MVC 5 app and I just started using webpack to bundle the output of my typescript files. webpack creates a set of bundles and writes them to $(project_dir)/Scripts/bundles.
All my typescript source are in various other directories under /Scripts as well (App, Api, Lib etc). But from a VS project point of view, bundles is empty, but added to the project.
Everything works great locally. I can do a debug build and webpack-dev-server serves up the bundles. I can do a release build and webpack happily creates the bundles on disk in /Scripts/bundles. And my code happily consumes the bundles.
I have edited the project file to include:
<Content Include="Scripts\Bundles\**" />
and if I do a publish from within visual studio it all works great. But VSTS doesn't seem to recognize this part of the project
We use VSTS to do our building and releasing to azure. I can't for the life of me figure out how to get VSTS to publish this /Scripts/bundles directory.
In my project properties, I created a pre-build step that runs webpack. I know that the files are in the Scripts/bundles directory at the end of the build because the closest I have come to getting this working is to have the VSTS build a second artifact that is the zip file of that bundles directory and the files are in there.
I could solve my problem if I knew one of the following (I think):
how to get an arbitrary directory to show up in the main artifact like the normal build output - I can then use my standard release definition to push it to azure
how to publish a second artifact in a release definition?
If you can solve #2, the issue is that in building the artifact for /Scripts/bundle, it put the contents of the bundle directory in the root of the zip file, rather than having bundle as the root of the zip file. So when I unzip the file, It will have to first create /Scripts/bundle and then unzip.
I must have been entering the wrong search terms when I was first trying to figure out how to do this. Once I hit on the right search terms I found a bunch of articles that talk about how to get "extra files" into the deployment package for Azure.
Here is a good article. I basically followed it and things just worked. I added these lines to my csproj file:
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
WebpackBundles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
<CopyAllFilesToSingleFolderForMsdeployDependsOn>
WebpackBundles;
$(CopyAllFilesToSingleFolderForMsdeployDependsOn);
</CopyAllFilesToSingleFolderForMsdeployDependsOn>
</PropertyGroup>
<Target Name="WebpackBundles">
<ItemGroup>
<_CustomWebPackFiles Include="Scripts\bundles\*" />
<_CustomWebPackFiles Include="Scripts\bundles\**\*" />
<FilesForPackagingFromProject Include="%(_CustomWebPackFiles.Identity)">
<DestinationRelativePath>Scripts\bundles\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
The PropertyGroup was already there. I just inserted the WebpackBundles; call into those two elements and then defined the WebpackBundles target.
And I ended up removing the
<Content Include="Scripts\Bundles\**" />
line and replaced it with the new Target that the article suggests. I am running webpack as a pre-build step only on the release build. I am using webpack-dev-server for the debug build locally. The only change I had to make to our VSTS build was to add two npm steps:
npm install
npm install webpack -g
this allowed the pre-build step to find the webpack executable and run it.
there was no change to the VSTS release definition because the webpack bundles got put into the deployment zip file in the right location.

.Net Core Website publish Microsoft.WebSite.Publishing.targets

I am on .Net Core 2.0.
I create a new solution containing a webapp and a website. The website project contains an index.html and web.config file.
I have no issue publishing the web application, but the website causes me some trouble.
I added a publish profile configured for FileSystem publish method.
When I run dotnet publish on the default .publishproj generated, I get the following error message
error MSB4019: The imported project
"C:\ProgramFiles\dotnet\sdk\2.0.0\Microsoft\
VisualStudio\v10.5\Web\Microsoft.Web
Site.Publishing.targets" was not found. Confirm that the path in the
<Import> declaration is correct, and that the file exists on disk.
Ok, so I change the website.publishproj value to where the targets file is located.
<!--<Import
Project="$(_WebPublishTargetsPath)\Web\Microsoft.WebSite.Publishing.targets"
/>-->
<Import Project="C:\Program Files
(x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\
Microsoft.WebSite.Publishing.targets" />
Then I get
error MSB3030: Could not copy the file
"C:\Users\Administrator\AppData\Local\Temp\WebSitePublish\WebSite2-
1026028577\obj\Debug\website.exe" because it was not found.
[C:\Users\Administrator\Documents\visual studio
2017\WebSites\WebSite2\website.publishproj]
I can publish the website using visual studio without any issue. What am I missing?
It looks like you are trying to use the dotnet CLI tooling to publish "classic" website projects which is not supported. Use msbuild from the developer command prompt instead.

Typescript in VS2012: (automatically) generating .js from .ts

I've added file1.ts and I can see there's a dependent to it - namely file1.js.
I notice that any changes I made to file1.ts - file1.js doesn't get automatically re-generated.
The only workaround I have at the moment is by calling tsc.exe - as part of pre-build event.
My question is - are there any better workaround or maybe a setting somewhere I might've missed ?
Install the Web Essentials 2012 extension in Visual Studio 2012.
It will re-generate the .js file on every save of the .ts file.
http://visualstudiogallery.msdn.microsoft.com/07d54d12-7133-4e15-becb-6f451ea3bea6
You have to add a BeforeBuild target to your ASP.NET application's CSPROJ:
<Target Name="BeforeBuild">
<Exec Command=""$(PROGRAMFILES)\Microsoft SDKs\TypeScript\0.8.0.0\tsc" #(TypeScriptCompile ->'"%(fullpath)"', ' ')" />
</Target>
tip: edit your csproj file with notepad.
Support for typescript has been removed from Web Essentials 2012 v3
you now need to download typescript support directly from microsoft:
http://www.microsoft.com/en-us/download/details.aspx?id=34790
In Visual Studio you need to invoke the build process for your files to be generated. The playground does not use the same build system, and it triggers the compilation once the source changes, so this is why you are seeing the difference in behavior.
plug
You can use Install-Package TypeScript.Compile to add a afterbuild target that compiles all TypeScript files included in your project.

Missing Second-Level Binary References with MSBuild Web Deployment

I am trying to do a Jenkins-based automated build/deployment of a web application (.NET 4.0). The web application project has several project references, which in turn have binary references third party DLLs.
The problem:
The second-level references (references of project references) are not pulled into the bin folder in the obj\<CONFIGURATION>\Package\PackageTmp\bin folder, used for building deployment packages.
When I build in the visual studio, the second level references are pulled into the regular build output directory.
When building with MSBuild, second level dependencies are not pulled into the regular output directory, nor into the PackageTmp\bin directory.
This is confirmed by MS as a Won't-Fix issue here.
Related questions here, here and here either do not match my problem, or offer solutions that don't work. I've reviewed all answers, not just the accepted ones.
My build command looks like this (using MSBuild 4.0):
MSBuild MySolution.sln /p:Configuration=Integration /p:platform="Any
CPU" /t:Clean,Build /p:DeployOnBuild=true /p:DeployTarget=Package
/p:AutoParameterizationWebConfigConnectionStrings=false
I've tried to manually edit Reference elements in project files, adding <Private>True</Private>, with no success.
I am trying to work around this known issue, so that my second-level dependencies are automatically and correctly pulled into the web publishing temp directory.
My current attempt combines the general approach here (customizing the web publishing pipeline by adding a MyProject.wpp.targets file next to the web project file), combined with some MSBuild code for finding DLLs here. So far this has either produced no results or broken the project file. I am new to custom MSBuild code and find it pretty arcane.
My Question: I am looking for a more complete example that works in my specific case. I think the goal is to intervene in the web publishing pipeline that gathers files for copying to the package temp directory, and adding the second-level dependencies to it.
My custom MyWebProj.wpp.targets looks like this:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<BRPathFiles Include="$(SolutionDir)..\Common\**\*.dll;$(SolutionDir)**\*.dll" />
<ConfigPathFiles Include="$(SolutionDir)..\Common\**\*.config;$(SolutionDir)**\*.config" />
</ItemGroup>
<Target Name="CopySecondLevelDependencies" BeforeTargets="CopyAllFilesToSingleFolderForPackage">
<RemoveDuplicates Inputs="#(BRPathFiles->'%(RootDir)%(Directory)')">
<Output TaskParameter="Filtered" ItemName="BRPaths" />
</RemoveDuplicates>
<RemoveDuplicates Inputs="#(ConfigPathFiles->'%(RootDir)%(Directory)')">
<Output TaskParameter="Filtered" ItemName="ConfigPaths" />
</RemoveDuplicates>
<CreateItem Include="%(BRPaths.Identity);%(ConfigPaths.Identity);">
<Output ItemName="FileList" TaskParameter="Include"/>
</CreateItem>
<CreateItem Value="#(BRSearchPath);$(ConfigSearchPath)">
<Output TaskParameter="Value" PropertyName="SecondLevelFiles" />
</CreateItem>
</Target>
<ItemGroup>
<FilesForPackagingFromProject
Include="%(SecondLevelFiles->'$(OutDir)%(FileName)%(Extension)')">
<DestinationRelativePath>$(_PackageTempDir)\bin\%(FileName)%(Extension) </DestinationRelativePath>
<FromTarget>CopySecondLevelDependencies</FromTarget>
<Category>Run</Category>
</FilesForPackagingFromProject>
</ItemGroup>
</Project>
Assuming you have collected all libraries needed at runtime in a folder outside your solution/project, have you tried just using post-build events to copy all these libraries to your main project target directory (bin) and then include that directory in your deployment package using Sayeds method: http://sedodream.com/2010/05/01/WebDeploymentToolMSDeployBuildPackageIncludingExtraFilesOrExcludingSpecificFiles.aspx (also available in this post: How do you include additional files using VS2010 web deployment packages?)?
I have (among others) the following line in my main project's post-build events:
xcopy "$(ProjectDir)..\..\Libraries\*.dll" "$(TargetDir)" /Y /S
In addition to this, I have added the following lines to my .csproj file:
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
PostBuildLibraries;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<Target Name="PostBuildLibraries">
<ItemGroup>
<_PostBuildLibraries Include="$(TargetDir)**\*" />
<FilesForPackagingFromProject Include="%(_PostBuildLibraries.Identity)">
<DestinationRelativePath>$(OutDir)%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
Be sure to add these lines after the import of the "Microsoft.WebApplication.targets". Check out the links above for more details.
This makes all the desired libraries available after each build (copied to the project's target directory) and each time I create a deployment package (copied to the obj\<CONFIGURATION>\Package\PackageTmp\bin).
Also, since I'm building my main project, not my solution, I'm using the $(ProjectDir) macro instead of the $(SolutionDir).

CruiseControl.Net Failed Build - No explanation

I am just beginning to set up a Continuous Integration Server using CruiseControl.Net. To keep things simple to begin with, I used the Visual Studio Task to carry out the build, pointing it at the project solution file. However, when the build process occurs, CC.Net successfully gets the latest source version from Subversion, and appears to run the devenv command. The build process then fails, but there is no explanation about why. Here is the output:
BUILD FAILED
Project: MyProject
Date of build: 2009-09-09 16:31:13
Running time: 00:00:49
Integration Request: Dashboard triggered a build (ForceBuild)
Modifications since last build (0)
Tests run: 0, Failures: 0, Not run: 0,
Time: 0 seconds No Tests Run This
project doesn't have any tests
There is nothing else displayed on the page. My XML Logs don't show any build results either.
This is my configuration file:
<!--<ccnetconfig><configurationVersion>1.4</configurationVersion></ccnetconfig>-->
<cruisecontrol>
<project name="MyProject">
<workingDirectory>C:\Users\Builder\Desktop\builder-pc\MyProject</workingDirectory>
<sourcecontrol type="svn">
<trunkUrl>svn://builder-pc/MyProject/trunk</trunkUrl>
<workingDirectory>C:\Users\Builder\Desktop\builder-pc\MyProject</workingDirectory>
<executable>C:\Program Files\Subversion\bin\svn.exe</executable>
<autoGetSource>True</autoGetSource>
<tagOnSuccess>True</tagOnSuccess>
</sourcecontrol>
<tasks>
<devenv>
<solutionfile>C:\Users\Builder\Desktop\builder-pc\MyProject\trunk\MyProject.sln</solutionfile>
<configuration>release</configuration>
<buildtype>Rebuild</buildtype>
<executable>C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe</executable>
<buildTimeoutSeconds>600</buildTimeoutSeconds>
</devenv>
</tasks>
</project>
</cruisecontrol>
I have deliberately removed things like the SVN username and password.
Building the solution using the VS Command Prompt works, albeit with warnings. This is using the same swtiches that CC.Net would be using.
Can anyone help? Is it failing because there are no unit tests to run, or because of the warnings? Or is it best to switch to MSBuild or NAnt instead of using the Visual Studio Task?
If there is no useful information in the build log, try looking at the server log for information about the failure.
I think the reason you aren't seeing any output in the xml log files is because you don't have an appropriate <publishers> section in your <project>.
Try:
<publishers>
<xmllogger />
</publishers>
Try running the build with MSBuild instead of devenv.exe. If the log gets merged into the xml but is not displayed properly in the web dashboard, make sure that appropriate xsl transforms are enabled. Also, as Scrappydog mentioned, add the xmllogger publisher (although it should be added by default if you don't have any publishers defined at all, you can check this in the 'Project Configuration' page on the dashboard.
You should use devnev.com (note the file extension is .com, not .exe) in the same path (i.e. C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE), instead of devnev.exe.
The <executable> block is optional, and from the CruiseControl.NET documentation, it will use the latest version of devnev.com, not devnev.exe.

Resources