I am trying to do a web deploy publish using MS Build for two web applications for internal use and testing. I have set up different solution configurations for each of the environments that i want to publish to. IE DevA, DevB. I have updated all the web.configs to do the correct transformations. As a note, the transforms work when i do a right click publish through Visual Studio so I have ruled those out as the problem. My current bat file that I am running uses this command to do the work:
"C:\Program Files (x86)\MSBuild\12.0\Bin\msbuild" project.csproj
/t:Clean;Rebuild;Publish
/p:DeployOnBuild=true;PublishProfile=DevB1_API;AllowUntrustedCertificate=True;username=username;password=password
When i run this command the publish works just fine. However, the web.config is not being transformed. Am i missing a msbuild parameter to force this to happen? Any Help would be appreciated! thanks.
Apparently, for the transform to be executed, you have to specify a build configuration using:
/p:Configuration=Release
Related
I want to configure our pipeline to allow one build to be used for multiple environments without having to create separate builds. According to the docs, it seems like it is possible, as it says:
You can use this technique to create a default package and deploy it to multiple stages.
I named my stage as my environment (preview), and I created a web.config file for that environment (web.preview.config) file. All my environment configuration files in the same path as Web.Config file.
The logs say transformation was complete:
2018-11-17T00:26:52.0383966Z [command]D:\a_tasks\AzureRmWebAppDeployment_497d490f-eea7-4f2b-ab94-48d9c1acdcb1\3.4.13\ctt\ctt.exe s:D:\a_temp\temp_web_package_06958915987488234\Content\D_C\a\1\s\Microsoft.Xbox.Mvp\Microsoft.Xbox.Mvp.Api\obj\Preview\Package\PackageTmp\bin\Web.config t:D:\a_temp\temp_web_package_06958915987488234\Content\D_C\a\1\s\Microsoft.Xbox.Mvp\Microsoft.Xbox.Mvp.Api\obj\Preview\Package\PackageTmp\bin\Web.Release.config d:D:\a_temp\temp_web_package_06958915987488234\Content\D_C\a\1\s\Microsoft.Xbox.Mvp\Microsoft.Xbox.Mvp.Api\obj\Preview\Package\PackageTmp\bin\Web.config pw i
2018-11-17T00:26:52.4335280Z [command]D:\a_tasks\AzureRmWebAppDeployment_497d490f-eea7-4f2b-ab94-48d9c1acdcb1\3.4.13\ctt\ctt.exe s:D:\a_temp\temp_web_package_06958915987488234\Content\D_C\a\1\s\Microsoft.Xbox.Mvp\Microsoft.Xbox.Mvp.Api\obj\Preview\Package\PackageTmp\bin\Web.config t:D:\a_temp\temp_web_package_06958915987488234\Content\D_C\a\1\s\Microsoft.Xbox.Mvp\Microsoft.Xbox.Mvp.Api\obj\Preview\Package\PackageTmp\bin\Web.Preview.config d:D:\a_temp\temp_web_package_06958915987488234\Content\D_C\a\1\s\Microsoft.Xbox.Mvp\Microsoft.Xbox.Mvp.Api\obj\Preview\Package\PackageTmp\bin\Web.config pw i
2018-11-17T00:26:52.5443873Z XML Transformations applied successfully
I can see that it first transformed to release and then it applied preview as the doc says (release then environment). However, although it says XML Transformations applied successfully, when I check the config variables, they are not changed. The only way I could make the transformation work was to define the buildConfiguration variable when I queue a new build, which blocks me from using the same build for different environments.
When I was researching, I found this from this link:
Web.config is transformed during the build process, if you generate the deployment package from "Build" and then deploy it in "Release", then you cannot transform it before deployment.
But the doc said I can use one default package for multiple stages...Does that still mean I have to create separate build for each environment? Is XML transformation not what I should be looking at for the scenario I wanna solve?
Thank you in advance!
++ Edit:
Release Settings:
Release steps (I think? I have a strong feeling that this is what you are looking for...):
1) Make sure you transform works. Test it
here.
2) Ensure in your VS project that you are including the transform file, Web.Preview.config, and copying to output dir.
3) Disable the config transform during the build, you just need to add argument /p:TransformWebConfigEnabled=False in MSBuild Arguments section of your Build task. You also need to add /p:AutoParameterizationWebConfigConnectionStrings=False if you want to update the connection string during the release. This will use the Web.Preview.config to "transform" the web.config.
4) Double check that in your release for the IIS Web App Deploy task under File Transforms & Variable Substitution Options you have XML transformation checked.
None of the answers I found on the internet worked for me on their own for my build and release pipeline. The web.config I got from the release pipeline was always pointing to the non transformed values.
After a few hours pulling my hair I got it to work though.
Some short info about my setup
I want to be able to deploy on all environments with just one build and one release pipeline.
My setup:
One build pipeline that builds all of our standard branches (test,
release, master).
One release pipeline that has different stages
depending on branch that started the release.
Our test stage releases the test branch on our test server.
Stage/Production comes from the same release branch but have their own transform files.
Solution
I followed some of the guide from Microsoft and set up my web.<environment_name>.config to match the release stage names.
I did not need to remove the <Dependent Upon> rows from my .csproj for each transform. Instead all I did was set the property Build Action of each transform to Content as shown by the image bellow.
I then added these commands to the build pipeline's Build Solution -> MSBuild Arguments:
/p:MarkWebConfigAssistFilesAsExclude=false
/p:TransformWebConfigEnabled=false
/p:AutoParameterizationWebConfigConnectionStrings=False
The build now does not try to transform the .config on it's own and also does not exclude the transform files from the artifact, allowing the release pipeline to do the transformation instead. Also, keeping the <Dependent On> for the transform files lets us have a "cleaner" look inside our code editors.
I just got this working so I could have one build with deployment to multiple environments. This is what I did.
In the code, I set each Web.<Environment>.config property to Build Action = "Content". I also set all mine to Copy to Output Directory = "Copy Always". I also unloaded the project and edit the csproj file, then removed the <DependendUpon>Web.config</DependentUpon> lines. This dumps all your web.configs to the root (no file nesting).
In the build, I set pipeline variable BuildConfiguration = "Release". I don't have a Web.Release.config in my project.
In the release, I named the deployment stage after the environment (in my case, Development, Staging, and Production). In all stages, on the Azure deployment task, I checked the XML transform checkbox.
In Azure, I set the ASPNETCORE_ENVIRONMENT to the naming of the staging environment, in my case, Development, Staging, and Production).
I just got this working as well. My issue was actually at the Visual Studio Solution level. I had the MVC project pointed to a different Configuration than the others. So always double check the configs!
I have a .NET solution with several different projects. Each of them I have now set up via the AWS Toolkit so I can just right click and hit "Redeploy to AWS..." but what I would like to do create a script (PowerShell maybe?) that builds and deploys all of my projects automatically.
I know there is a CLI version of the AWS Toolkit called awsdeploy.exe but it doesn't seem like that will perform the compilation and archiving of a project like the AWS Toolkit plugin does.
How do I mimic this behavior?
So I'm currently tackling this question at work, with partial success. What I have found is that you can do the packaging with msbuild, and then deploy with awsdeploy.
For example, if I have a visual studio solution call bas, with two projects, foo and bar, and I want to deploy bar, then I first package bar with msbuild.
msbuild bar/bar.csproj /t:Package /p:PackageLocation=barPackage.zip
This should create a package call barPackage.zip under the bar directory. If you don't find it, look at the msbuild output as it should let you know where it was created.
Now that we have the package, we can deploy. Awsdeploy needs a configuration file. It's just a file that contains key value pairs of the form "key = value". There is an example file in a directory called Samples\, in the same directory where the awsdeploy.exe is located.
If you are using visual studio there is an option for creating the config file while deploying to aws.
More info: http://docs.aws.amazon.com/AWSToolkitVS/latest/UserGuide/tkv-deployment-tool.html#deployment-tool-configuration-file-format
Let's assume we have a configuration file called deployConfig.txt then we can call awsdeploy like so
awsdeploy /r deployConfig.txt
Note that the /r is for redeploy. This assumes that you already have an environment running.
If you don't want to put credential inside the file, you can also do.
awsdeploy /r /DAWSAccessKey=stuff /DAWSSecretKey=stuff deployCon
In general anything we don't want on the file we can specify on the command like by adding /Dsomething=stuff. As you can see above to specify AWSSecretKey we do /DAWSSecretKey=stuff.
The visual studio generated file does not list the location of the package so what I've been doing is
awsdeploy /r /DAWSAccessKey=stuff /DAWSSecretKey=stuff /DDeploymentPackage=bar/bar.zip deployConfig.txt
This almost works for me. But sadly it doesn't quite do the trick. It deploys the package, and I can see the environment trying to load it but fails at some point. I don't know why it's failing to load it. It loads it fine when I deploy it from visual studio.
This is how we're handling it. All of this runs on our CI server:
Step 1 - build web deploy package with msbuild:
msbuild website.csproj /t:WebPublish /p:WebPublishMethod=Package
/p:DesktopBuildPackageLocation=website.zip /p:Configuration=Release
/p:DeployIisAppPath="Default Web Site"
Step 2 - deploy with awsdeploy:
awsdeploy.exe /DAWSAccessKey=**** /DAWSSecretKey=**** /r config.txt
config.txt:
DeploymentPackage = .\website.zip
AWSProfileName = ******
Region = us-east-1
Template = ElasticBeanstalk
UploadBucket = ***********
Application.Name = ***********
Environment.Name = ***********
I am trying to use SpecsFor MVC for automated acceptance testing and I have noticed that it is not building / publishing project correctly on Visual Studio 2012 and hence IIS Express is not running, ending in a 'Page cannot be displayed' message throughout the automated acceptance test.
To take you through all my tests to get this working, initially, when trying to run the automated tests, I was getting a 'Build Failed' message when running
_host = new SpecsForIntegrationHost(config);
_host.Start();
. After loading the SpecsFor MVC source code, I have noticed that the error was because the MSBuild.exe process was failing and the output message was being written to Console.Output. After checking the output, I have noticed that the error was that the Microsoft.WebApplication.targets was not found. After some research, I found the below:
External VS2013 build error "error MSB4019: The imported project <path> was not found"
The one with most votes spoke about removing the <PropertyGroup> node from the .csproj which after removing it, the MSBuild.exe was not exiting with an error code as it only had warnings which still resulted in the project not being built & published correctly. SpecsFor MVC in this case treated this scenario as successful and proceeded with launching IIS Express but since the project was not built successfully, the acceptance tests resulted in another Page Cannot Be Displayed message as IIS Express was not running correctly.
After some further research, I found v11.0\WebApplications\Microsoft.WebApplication.targets was not found when file actually references v10 which outlined that VS 2012 has a new different MSBuild.exe file located in C:\Program Files (x86)\MSBuild\12.0\Bin.
Now the issue is that within the SpecsFor MVC IISTestRunnerAction.PublishSite() method, the path of the MSBuild.exe is being loaded through
System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() which in my case is outputting C:\Windows\Microsoft.NET\Framework64\v4.0.30319\. Changing this manually to C:\Program Files (x86)\MSBuild\12.0\Bin solved the issue and project was built & published successfully.
My final question is: Is there a way where one can change the value of System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() so that I wouldn't need to update the source of the SpecsFor MVC project?
Thanks in advance for any help!
As of SpecsFor.Mvc 3.2.0-rc01 (still a preview release as of right now), you can configure the path to MSBuild like so:
var config = new SpecsForMvcConfig();
config.UseIISExpress()
.With(Project.Named("SpecsFor.Mvc.Demo"))
.CleanupPublishedFiles()
//Set the full path to MSBuild.exe here!
.UseMSBuildExecutableAt(#"C:\Program Files (x86)\MSBuild\12.0\Bin\msbuild.exe")
.ApplyWebConfigTransformForConfig("Test");
To understand how these ".targets" files are organized in Visual Studio is a challenge. I don't know nothing about this SpecsFor MVC works, but if you put the right ".targets" file in it's path, it should work. By your question, I understand that SpecsFor invokes MSBuild internally.
It's a similar problem when you install a new build machine, and a lot of Visual Studio componentes are missing. Not all of them are deployed with the framework. Some comes with Visual Studio separated installers other with specific componentes.
I didn't find an specific installer that deploys this needed file. I just found the MSBuild 2012 installer (http://www.microsoft.com/en-us/download/details.aspx?id=40760), and I don't know if it deploys the previous version .targets.
And also you can try the ASP.NET MVC installer for your specific version.
Another approach is try to find a parameter in SpecsFor to see which version of MSBuild it is invoking. Probably if it uses the version in Program Files\v12, it should work.
I am currently trialling Visual Studio Online with an On-Premises build server. I have managed to move a number of projects into VSOnline but for some reason have hit a brick wall with one.
The project appears to build correctly but when I get to the end of the build I get the following error:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets (4291): The command "copy *.dll ........\PROJECT NAME\bin\Debug /y" exited with code 1.
I have deleted the project and re-created to be sure there was nothing wrong with my initial setup. As far as I can tell I have followed exactly the same process to create this project as I have 2 others that have both worked perfectly.
When I take the MSBuild command that is actually executed and run that directly on the build server it works fine.
Is there any way to get more information about what is going wrong? Has anyone else come across something similar?
Switch your post build events to AfterBuild.
Always use properties instead of hard-coded names. E.g. use $(Configuration) instead of Debug or Release.
The Post Build events for several of the projects were causing the issue when building on TFS.
I added
IF "$(BuildingInsideVisualStudio)"=="true" ( copy command here )
to the Post Build Events so that they only run when building in Visual STudio and are ignored in TFS Build.
How to pass a parameter to a TeamCity Test Runner?
I've added a build configuration to my teamcity project which copies out a test project from TFS into a local location on the server then it runs the tests with NUnit and display the results.
The problem is that when the tests run from my local pc, they should be using some configurations, when they run from Dev Automated Build and Test Automated Build, they should be using other configurations and all should be in TFS.
For example, BaseUrl and Connection string configurations...
private static readonly string BaseUrl = ConfigurationManager.AppSettings[AppSettingKey.BaseUrl];
Currently, I've added a web.config file to my project which works fine only locally.
So, how to pass these parameters to a TeamCity Build Configuration which is configured on Dev and Test environemnts?
Even if I create separate web.config files (e.g. dev.web.config and staging.web.config), I need a way to tell the Build Configuration to use which configuration file?
Hope the question is clear.
many thanks.
Enlightened, found a solution (should have thought more before submiting a question here)!
I'd just create separate dev.app.config and staging.app.config files then on the "Version Control Settings" page on teamcity I can define rules such as copy this file somewhere.
So I just Copy the file onto the root app.config; that's it!
Rule:
+: SolutionName\Tests\ConfigFiles\Dev\App.config=>SolutionName\Tests\App.config
Consider using the configuration parameter i.e. Build | Release
Use your debug build locally and release on TeamCity. You can do this with an MSBuild parameter (/p:Configuration=Release)
Then use the solution here (How to select different app.config for several build configurations) to use the correct app.config.
I prefer this solution as it keeps the definitions within the solution / projects rather than within the build.
[I'm adding this just for completeness - I had originally followed this approach but then found the other solution]
Rules in Version Control Settings works only for directories so the better approach is to use Build step - command line
Go to Build Step in Settings section
and Add Build Step with following settings
Command Line
Custom script: copy TeamCity.App.config App.config
Execute: Only if all previous steps were successful
Reorder this step and run it before compilation step