Any way to run commands/script after VS2015 Publish wizard has copied files to output? - deployment

I have a very simple Windows service project I want to deploy to a server using Visual Studio 2015. I can successfully deploy using the Publish wizard (right-click on project -> Publish and deploy to \\myserver\c$\somepath\), but I need to 1) stop the service before publishing (so that the executable can be replaced), and 2) restart the service after the files have been copied.
I know how to start/stop services from the command line, and this answer provides a way to do it directly in a build action. However, I can't seem to find a way to execute any action after VS has copied the files to the output directory on the server.
For example, I have tried adding the following to my .csproj file without luck:
<Target Name="Mytarget" AfterTargets="AfterPublish">
<Warning Text="After AfterPublish" />
</Target>
Mytarget executes before VS actually copies the files to the server, so evidently, I can't hook onto AfterPublish. I've also tried PipelinePreDeployCopyAllFilesToOneFolder, CopyAllFilesToSingleFolderForPackage, and MSDeployPublish without luck (these don't seem to execute at all).
My end goal is to allow more-or-less one-click updating of the service, without having to log on to remote desktop and run a script manually after each update.
Is there any way I can have VS automatically execute an action after publishing a Windows service project to a server?

Related

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.

How to avoid mixed output files with MSBuild?

I have a C# big project in Visual Studio 2013 that is formed by:
3 Web projects
2 Windows Services project
14 Dlls projects
2 Test projects
1 Database Project (.sqlproj)
As you can guess the final files are:
3 Web Projects
2 Windows Services
Database
I build it with msbuild.exe invoked from PowerShell.
$msbuild="C:\windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe"
$option0 = 'FOO.sln /t:Clean,Rebuild /p:Configuration=Debug /p:Outdir=$outputdir'
iex "$msbuild $option0" | tee C:\TFS\Oscar\Build\oscar.txt
The project builds and in the output folder I have a nice directory called _PublishedWebsites that contains the three websites, one in each directory. From here it wouldn't be complicated to deploy to servers using PowerShell.
In outputdir I have my FooDB.dacpac so I can easily use sqlpackage to deploy it to SQL Server.
My problem is with Windows Services. Instead of being in a folder they are in output folder, mixed with all DLLs, sqlproj files, test files.
Is there any way of having them in a folder similar to "_PublishedWebsites"?
I can copy all files to each windows service folder on deploy and will work... but feels wrong...
YES! You can actually use MSDeploy which is the underlying technology for WebDeploy to create a similar deployment package for a Windows service or scheduled task.
The basic steps are
extend MSBuild to zip up the files into a package
add pre/post sync commands
create a deploy cmd to execute the package
https://dotnetcatch.com/2016/03/18/deploy-non-web-apps-with-msdeploy/
We've been using the nuget package PublishedApplications in in our Windows Service projects (which are actually just Console Apps using TopShelf ).
As a result, we get a nicely packaged app in the output folder {OutDir}/_PublishedApplications/{appName} (next to {OutDir}/PublishedWebSites) for those services.
I'm still looking for a way to get a similar behavior for *.sqlproj projects ...

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.

Error when attempting to deploy a WAR to Glassfish 3 using an Ant Build Script

I am investigating how to use both Glassfish and Ant buildfiles. I've written a build script (for the first time) which will create a WAR file of my basic Hello World app.
I am then trying to deploy this WAR to Glassfish as part of the build script. I found details of the glassfish-deploy task and have managed to get this included in the build script after including the ant-task jar file in the class path.
However, when I run the script I get the message:
[glassfish-deploy] Install Directory of application server not known. Specify either the installDir attribute or the asinstall.dir property
I've tried to find out what is meant by this, but can find no reference to either the installDir attribute or the asinstall.dir property. I have managed to deploy the created WAR file through Glassfish's admin webpage but I cannot seem to get this Ant script to do it successfully.
Any pointers or guidance would be most helpful.
OKay after a lightbulb moment I managed to resolve this by editing the task in my build script so it is now <glassfish-deploy file="${name}.war" installDir="C:\\glassfish3\\glassfish" force="true"/>
As it appears that the ant script does not know where Glassfish is installed. This resolves the issue and the script runs (and workds) However the next stage is to figure out how to do this without having to hardcode the location into into the build script. Especially if I want to write a script that can deploy the WAR file to a remote server.

TFS 2010: run powershell script stored in source control

We've started using TFS2010 over at the company I work at. We create e-commerce web applications (shopping sites). I'm creating a custom template to deploy web projects after a build using a build template.
I've looked at the web deploy tool, but MSDN seems to indicate that it can only do initial deployments, and I need to be able to do incremental deployments with the same script.
I'm thinking of using the invokeActivity activity in the template to use powershell to do the job by specifying an FTP script which automatically copies the output of a build to a designated FTP site and then runs the SQL (upgrade) scripts, if needed by using SSH or s powershell remoting interactive session. (possibly specified in a separate SQL script)
There is some unknown for me which I can't get clear through the use of google:
When queuing a build, will I be able to let the user specify a script present in source control ( e.g. $(source)\scripts\ftpscript.ps1 ) as the script which is to be used? Will powershell be able to access/use that file? or should I copy it to the build directory and specify when I run it? (I don't know how to set up the template to get files from source control, so a pointer to some helpful info how to do that would be very much appreciated)
If the previous just doesn't work at all, could I create a folder \scripts\ in my website project, commit that to source control and then use BuildDetail.DropLocationRoot & "\scripts\" as the location for the script and fore a copy of the script files by enabling the force copy option?
To run a PowerShell script I think you can use the InvokeProcess activity which would trigger something like this:
%windir%\system32\windowspowershell\v1.0\powershell.exe "$(SolutionRoot)\test.ps1
And yes, you can reach a script file present in source control using the "SourcesDirectory" keyword.