TFS Build Website deployment package web.config transformation not working - web-config

So I am trying to use TFS Build for generating deployment packages for my 3 environments (ST, UAT, Prod).
This what I followed to successfully genrate the package locally.
http://social.msdn.microsoft.com/Forums/en-US/tfsbuild/thread/74bb16ab-5fe6-4c00-951b-666afd639864/
So my local machine will generate the package for the acyive configuration and everything is good. Here is my Build definition :
/p:DeployOnBuild=true;DeployTarget=Package
I run my solution file and the web deployment project in the Projects To Build.
It creates the respective folders with ST, UAT and PROD. In each of these there is a _PublishedWebsites folder. This folder have 2 folders.
1) MydeploymentProject - It contains the transformed web.config
2) MyDeploymentProject_Package - Contains the Package folder contents along with the zip file and setparameters files. Here the everything is not transformed. But if I check the TempBuildDir on the TFS server it does contain the transformed config.
When compared the logs local and on server, I found that the on my local After transformation files are updated and package is created whereas on TFS the AfterBuild target is called transformation done and it ends there.
this is my local log
Target "WPPCopyWebApplicaitonPipelineCircularDependencyError" skipped, due to false condition; ($(WPPCopyWebApplicaitonPipelineCircularDependencyError)) was evaluated as (False).
Target "ProcessItemToExcludeFromDeployment" in file "C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets" from project "C:\TAX-IT\Main\Source\TDDB\TDDB_deploy2\TDDB_deploy2.wdproj" (target "PipelineCollectFilesPhase" depends on it):
Done building target "ProcessItemToExcludeFromDeployment" in project "TDDB_deploy2.wdproj".
Target "GetProjectWebProperties" in file "C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets" from project "C:\TAX-IT\Main\Source\TDDB\TDDB_deploy2\TDDB_deploy2.wdproj" (target "PipelineCollectFilesPhase" depends on it):
Using "GetProjectProperties" task from assembly "C:\Program Files\MSBuild\Microsoft\WebDeployment\v10.0\....\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll".
Task "GetProjectProperties"
I am not sure what is wrong.
Also I installed VS2010, web deploy 2.0 and 3.0 and web deployment tools on my Build servers.
Anyone have faced this and resolved.
Please help.
Thanks

MadCoder,
From what I've gathered from your description, you have everything set up correctly. It seems like you are just missing the "Configuration" parameter. When you do run the Build Definition, it uses the configuration specified in your "Configurations to Build" argument. If you want to have multiple configurations built (like you are suggesting), you'll need to have multiple configurations defined. One question I have is: When you look at the logs of the TFS Build Process, do you see multiple configurations built, or do you only see one? If you only see one, then you don't have all of the configurations defined in order to transform the config file. According to your description, you'll need to see something like this in your build definition configuration:
If you don't want to deploy to a webserver, you can stop reading here, and don't have to continue on.
If you choose to use a TFS Build Definition to deploy to a web server, you'll need to have a target web server somewhere and you'll need to install and configure the Web Deploy v2/v3 on that server as well.
When you are using TFS Build Definitions to deploy, the transformation happens upon deployment, not during packaging (prior to deployment). It may package up a transformed config somewhere, but it won't actually transform the config bundled with the website. The only way I've been able to get the deployment to actually work with a transformed config is when I had a website specified in the MSBUILD args. Here is an example of my MSBUILD args:
/p:DeployOnBuild=True /p:DeployTarget=MSDeployPublish /p:MSDeployPublishMethod=RemoteAgent /p:MsDeployServiceUrl=MyWebServer/MsDeployAgentService /p:DeployIisAppPath="MyWebsite as named in IIS" /p:UserName=MyDomain\MyWebDeployUser /p:Password=MyWebDeployPassword
If you don't want MSBUILD to do the actual deployment (I prefer not to because then your deployment process is tied to TFS), you can do the deployment after the build process and use the CTT Project, found on codeplex. This tool performs the exact same transformations as MSBUILD, but it also includes the ability to parameterize settings so you can define classes of environments (for example, 3 QA environments, 2 Staging Environments, etc.) and still use the respective transforms for that class of environment.

Related

.NET Core - how does the 'dotnet publish' command work?

I have a solution with some projects targeting .NET Standard 2.0 and a console application project targeting .NET Core 2.1.
I set "myFolder" as the output folder.
Building from VisualĀ Studio, I get all DLL files in:
"myFolder\netstandard2.0"
"myFolder\netcoreapp2.1"
I get the same using the "dotnet build" command.
Now I need my console application's EXE file.
So I use the "dotnet publish -c Release -r win-x64 MySolution.sln" command.
Now I get this new directory, "myFolder\netcoreapp2.1\win-x64", where I find all DLL files and the console application's EXE file.
Not enough!
I find one directory more, "myFolder\netcoreapp2.1\win-x64\publish", where I find again all DLL files and the console application's EXE file.
Which meaning do they have? I read the command documentation, but I didn't find my answer.
Per the documentation
-o|--output <OUTPUT_DIRECTORY>
Specifies the path for the output directory. If not specified, it defaults to ./bin/[configuration]/[framework]/publish/ for a framework-dependent deployment or ./bin/[configuration]/[framework]/[runtime]/publish/ for a self-contained deployment.
dotnet publish -c Release -r win-x64 --output ./MyTargetFolder MySolution.sln
All you really need to understand to be able to successfully publish and deploy is that you need to dotnet publish and ensure that you have a Release configuration -c Release, as well as any other required options on the command line.
All of your files will be in the 'publish' subfolder, e.g. ./bin/Release/[framework that your solution is targeting]/publish. The files contained here are everything that is needed for a running instance of your application/service. The MySolution.dll is the entry point for your app/service, and will automatically link to all of the other dependencies and configuration stored in the publish folder.
To configure and deploy a running instance, you need to work out how to deploy all of those files to a server, and somehow configure something (e.g. a web server, runtime, service host ...) to call your MySolution.dll.
Note that in your dotnet publish you're specifying -r, which means that your application is targetted to run under 64 bit Windows, as opposed to a Linux distribution or OSĀ X (which makes it less portable, but it has the advantage of isolating your application from changes to an installed runtime on a server that you deploy it to.). That's why you're seeing an extra folder win-x64.
Also you're explicitly building from the solution configuration specified by your solution file MySolution.sln, which is probably the most reliable thing to do as this will ensure that any projects used as dependencies by your solution (which is a typical good practice) will be included in the build/publish.

Building/deploying azure webjob with website copies source files instead of binaries/executable

I've added a webjobs sdk project to my existing website. The website runs as an azure app service. I've always done building and deployment by queueing up a new build in visual studio online and deploying from there to my azure website. Recently I created this webjob project in the same solution, that based on this webjobs-list.json generated and put in the website project should cause the webjob to also be deployed with the website during deployment (or so the documentation says). What is happening though is that when it deploys, and I take a look at what is in app_data\jobs\continuous, is not the binaries and executable that I expect, it's the actual source code/project files that have been copied into there. Obviously that isn't going to run, and it shouldn't have thrown source code out there on my website anyway.
I also had to change my release definition in visual studio online to just look for [my website project name].zip, instead of just *.zip, because otherwise I'd get an error from the release indicating: Error: More than one package matched with specified pattern. Please restrain the search patern.
...this appeared to be because the build process not only creates a zip file for my website, it also creates one for the webjobs project. From what I understand and have read, I am supposed to change my release to just look for the website zip file and ignore the other zip file, and just let that get deployed and it should all work fine, but again, what is copied into my jobs folder on the website isn't the binaries or executable for the webjob, it's the actual source files.
How can I get this to deploy just the binaries and executable with the site instead of the source files?
The only other thing I could find to do is remove the webjobs-list.json file from the web project so they are no longer linked together, which causes the build to no longer populate app_data\jobs\continuous with my web job project source files when deployed, and to create an additional task in my release definition to grab and deploy the other zip file that is created during the build (for the webjob project, and it contains the debug files with those binaries for whatever reason). However everything I read tells me that this is not supposed to have to be done, it should just work without me having to do this.
EDIT:
My web project is an MVC 5 project that I created with VS 2013. The web jobs project uses the 2.0.0.0 version of the webjobs sdk.
The build and release definitions, I followed the steps in this article to create:
https://www.visualstudio.com/en-us/docs/build/apps/cd/deploy-webdeploy-webapps
The only additional thing I did after following this article, is in my release definition, I changed the Package or Folder field to look for [my mvc web project name].zip, instead of *.zip, otherwise I'd get the error message noted above.

Packaging SF service into a single file

I am working through how to automate the build and deploy of my Service Fabric app. Currently I'm working on the package step and while it is creating files within the pkg subfolder it is always creating a folder hierarchy of files, not a true package in a single file. I would swear I've seem a .SFPKG file (or something similarly named) that has everything in one file (a zip maybe?). Is there some way to to create such a file with msbuild?
Here's the command line I'm using currently:
msbuild myservice.sfproj "/p:Configuration=Dev;Platform=AnyCPU" /t:Package /consoleloggerparameters:verbosity=minimal /maxcpucount
I'm concerned about not having a single file because it seems inefficient in sending a new package up to my clusters, and it's harder for me to manage a bunch of files on a build automation server.
I believe you read about the .sfpkg at
https://azure.microsoft.com/documentation/articles/service-fabric-get-started-with-a-local-cluster
Note that internally we do not yet support provisioning a .sfpkg file. This is a feature that will be coming in soon (date TBD). Instead, we upload each file in the application package.
Update (SF 6.1 - April 2018)
Since 6.1 it is possible to create a ZIP file (*.sfpkg) and upload it to an external store. Service Fabric executes a GET operation to download the sfpkg application package. For more infos see https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-package-apps#create-an-sfpkg
NOTE: This only works with external provisioning, the Azure image store still doesn't support sfpkg files.

Custom action after ClickOnce deployment / publishing

How can I run custom script which will upload ClickOnce deployment files to a web-server (in my case Windows Azure Blog Storage) right after publishing? Is it possible to modify MSBuild file in some way so it would run custom script right after ClickOnce published files into a local folder?
Yes, you can hook to build process using various technics:
pre and post build actions ( from visual studio project properties menu). It's actually exec task hooked into your project file
you can override your DependsOn property for concrete target and append execution of your own target (pre-Msbuild 4.0 way)
you can declare your target and hook with AfterTarget\BeforeTarget attributes (Msbuild4.0 way).
As for uploading something to blob - you can use Exec task in your own target to upload or use whatever tool\script you usually use to uploading files to website\Blob storage.
NB: You could clarify your question with following points (if you need more concrete answer) :
what kind of build process you are using - build from VS, CI server with custom msbuild script, CI server that building your sln file etc
what kind of script\tool you want to execute to upload build result.
do you know the name of last executed msbuild target, after which you want to fire your tool.

Packaging with NAnt, how to handle different environments

I'm using NAnt to build an ASP.NET MVC project.
The NAnt script then creates a zip package, containing a deploy script and all the necessary files.
The deploy script backs up the current running website, sets up the newer version of the website and updates the DB.
This works fine for a single environment.
However, we're asked more and more to set up a Staging/Acceptance environment next to the production. These environments, of course, differ in file structure, DB server, config settings etc.
How can I best handle this in the deploy scripts? I don't want to create separate variables for each environment, distinguishable by name only.
Providing defaults and providing the variables in separate files seems more logical.
Does anyone have practical experiences with this?
Store the things that you think are likely to change between environments in config files.
Visual Studio can do the heavy lifting here if you like; you can create settings and specify default values from the Settings tab of a Visual Studio project's properties.
This will create the config file for you and provide strongly-typed access through Properties.Settings.Default.
As for handling multiple environments through your build, I've seen some people recommend maintaining multiple copies of the config files - one for each environment for example - and others recommend using nant to modify the config files during the build or deployment phase. You can use a property passed to nant on the command line (for example) to select which environment you are building (or deploying, depending on how you're doing it).
I don't recommend either of these approaches because:
They both require changes to your build to support new environments.
If you change a setting in a deployed environment and forget to update the build then the next deployment will reset the change (somewhat defeating the point of config settings).
If someone creates a new environment (lets say they want to explore issues arising from upgrading to a new version of SQL Server for example) and doesn't fancy creating all new config files in the build system, they might decide to just use an existing environment's settings. Let's say they choose to deploy using the live settings and forget to change something afterwards. Your new 'test' environment could now be pointing to live kit.
I create a copy of each config file (called web.config.example, for example) and comment out the settings within them (unless they have meaningful defaults). I check these in and have those deployed instead of the real web.config (that is, web.config is NOT deployed automatically. web.config.example is deployed as web.config.example.
The admin of the new environment will have to copy and rename the file to web.config and provide meaningful values). I also put all the calls to the settings behind my own wrapper class - if a mandatory setting is missing I throw an exception.
The build and my environments no longer depend on each other - one build can be deployed to any environment.
If a setting is missing (a new environment or a new setting in an existing environment) then you get a nice clear exception raised to tell the admin what to do.
Existing settings are not altered after an upgrade because only the .example files were updated. It's an admin task to compare the current settings with the latest example and revise if necessary.
To configure the deployment, you could put all the environmental settings (install paths, etc) into nant properties and move them into a separate file (settings.build for example) then use the nant include task to include that file at the top of your deployment file (deploy.build for example). You can then deploy a new version of deploy.build without overwriting your config changes as they are in settings.build. If a new property is introduced into deploy.build nant will fail with a nice message to tell you that you haven't set that property.