A web job can be deployed with
web deploy in Visual Studio to Azure very easily. Getting a web job packaged with VS Web Application is equally simple and straight forward.
To package WebJobTest console application to the deployment package created with WebJobApp web application can be done using VS publish.
Web job getting packaged to deployment package.
A TFS Build can be defined to build the package. More information on setting up a TFS build to create web deploy package refer the post “
How to Deploy to Azure Websites with TFS build 2013 and VS Release Management 2013”.
Web deployment package created with TFS Build.
But the web deployment package created with TFS build does not contain the app_data folder and the jobs in it.
Instead it is getting created as a separate package in build drop.
Investigations done in WWW pointed to below useful suggestions but none worked with TFS build as explained in them.
h
https://github.com/davidebbo-test/WebAppWithWebJobsVS/commit/15e7579075312d620fe42a8746503ba82adf5305
http://chriskirby.net/deploy-your-webjob-projects-with-your-azure-website-using-continuous-delivery/
This issue is discussed in this forum post with Visual Studio Online.
https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/c3f4479b-3502-4fdf-97f9-ababe97ea8fa/webjobs-continuous-deployment-from-vs-online-build?forum=windowsazurewebsitespreview
However when tried building with msbuild locally with deploy arguments successfully packaged the web jobs into the Web Application deployment package.
With that knowledge, as a workaround (It really works :)), set the TFS Build to build to output as configured. This will build the solution with TFS Build outputs in to the local folder of the build agent, which would allow the jobs to be packaged into the web deployment package.
The next problem is getting the built package to the output folder. For that the
https://tfsbuildextensions.codeplex.com/SourceControl/latest#Scripts/GatherItemsForDrop.ps1can be modified and used. Modified script is below.
##-----------------------------------------------------------------------
## <copyright file="GatherItemsForDrop.ps1">(c) http://TfsBuildExtensions.codeplex.com/. This source is subject to the Microsoft Permissive License. See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx. All other rights reserved.</copyright>
##-----------------------------------------------------------------------
# Copy the binaries to the bin directory
# so that the build server can drop them
# to the staging location specified on the Build Defaults tab
#
# See
# http://msdn.microsoft.com/en-us/library/bb778394(v=vs.120).aspx
# http://msdn.microsoft.com/en-us/library/dd647547(v=vs.120).aspx#scripts
# Enable -Verbose option
[CmdletBinding()]
# Disable parameter
# Convenience option so you can debug this script or disable it in
# your build definition without having to remove it from
# the 'Post-build script path' build process parameter.
param([switch]$Disable)
if ($PSBoundParameters.ContainsKey('Disable'))
{
Write-Verbose "Script disabled; no actions will be taken on the files."
}
# This script copies the basic file types for managed code projects.
# You can change this list to meet your needs.
# $FileTypes = $("*.exe","*.dll","*.exe.config","*.pdb")
$FileTypes = $("*.xyz") # make it copy no files from bin (if required a file enable again with proper filename/extension)
# Specify the sub-folders to include
$SourceSubFolders = $("*bin*","*obj*")
# Specify Azure Package File Types
$AzurePackageFileTypes = $("*.deploy.cmd","*.deploy-readme.txt","*.SetParameters.xml","*.SourceManifest.xml", "*.zip")
# Specify Azure Package Containers
$AzureWebPackageContainers = $("*_PublishedWebsites*")
# Specify Azure Web Project Names
$AzureWebProjects = $("WebJobApp")
# If this script is not running on a build server, remind user to
# set environment variables so that this script can be debugged
if(-not $Env:TF_BUILD -and -not ($Env:TF_BUILD_SOURCESDIRECTORY -and $Env:TF_BUILD_BINARIESDIRECTORY))
{
Write-Error "You must set the following environment variables"
Write-Error "to test this script interactively."
Write-Host '$Env:TF_BUILD_SOURCESDIRECTORY - For example, enter something like:'
Write-Host '$Env:TF_BUILD_SOURCESDIRECTORY = "C:\code\FabrikamTFVC\HelloWorld"'
Write-Host '$Env:TF_BUILD_BINARIESDIRECTORY - For example, enter something like:'
Write-Host '$Env:TF_BUILD_BINARIESDIRECTORY = "C:\code\bin"'
exit 1
}
# Make sure path to source code directory is available
if (-not $Env:TF_BUILD_SOURCESDIRECTORY)
{
Write-Error ("TF_BUILD_SOURCESDIRECTORY environment variable is missing.")
exit 1
}
elseif (-not (Test-Path $Env:TF_BUILD_SOURCESDIRECTORY))
{
Write-Error "TF_BUILD_SOURCESDIRECTORY does not exist: $Env:TF_BUILD_SOURCESDIRECTORY"
exit 1
}
Write-Verbose "TF_BUILD_SOURCESDIRECTORY: $Env:TF_BUILD_SOURCESDIRECTORY"
# Make sure path to binary output directory is available
if (-not $Env:TF_BUILD_BINARIESDIRECTORY)
{
Write-Error ("TF_BUILD_BINARIESDIRECTORY environment variable is missing.")
exit 1
}
if ([IO.File]::Exists($Env:TF_BUILD_BINARIESDIRECTORY))
{
Write-Error "Cannot create output directory."
Write-Error "File with name $Env:TF_BUILD_BINARIESDIRECTORY already exists."
exit 1
}
Write-Verbose "TF_BUILD_BINARIESDIRECTORY: $Env:TF_BUILD_BINARIESDIRECTORY"
# Tell user what script is about to do
Write-Verbose "Will look for and then gather "
Write-Verbose "$FileTypes files from"
Write-Verbose "$Env:TF_BUILD_SOURCESDIRECTORY and copy them to "
Write-Verbose $Env:TF_BUILD_BINARIESDIRECTORY
# Find the files
$files = gci $Env:TF_BUILD_SOURCESDIRECTORY -recurse -include $SourceSubFolders |
?{ $_.PSIsContainer } |
foreach { gci -Path $_.FullName -Recurse -include $FileTypes }
if($files)
{
Write-Verbose "Found $files.count files:"
foreach ($file in $files) {
Write-Verbose $file.FullName
}
}
else
{
Write-Warning "Found no files."
}
# If binary output directory exists, make sure it is empty
# If it does not exist, create one
# (this happens when 'Clean workspace' build process parameter is set to True)
if ([IO.Directory]::Exists($Env:TF_BUILD_BINARIESDIRECTORY))
{
$DeletePath = $Env:TF_BUILD_BINARIESDIRECTORY + "\*"
Write-Verbose "$Env:TF_BUILD_BINARIESDIRECTORY exists."
if(-not $Disable)
{
Write-Verbose "Ready to delete $DeletePath"
Remove-Item $DeletePath -recurse
Write-Verbose "Files deleted."
}
}
else
{
Write-Verbose "$Env:TF_BUILD_BINARIESDIRECTORY does not exist."
if(-not $Disable)
{
Write-Verbose "Ready to create it."
[IO.Directory]::CreateDirectory($Env:TF_BUILD_BINARIESDIRECTORY) | Out-Null
Write-Verbose "Directory created."
}
}
# Copy the binaries
Write-Verbose "Ready to copy files."
if(-not $Disable)
{
foreach ($file in $files)
{
Copy $file $Env:TF_BUILD_BINARIESDIRECTORY
}
Write-Verbose "Files copied."
}
#Copy Publish Web Site outputs
foreach ($AzureWebProject in $AzureWebProjects)
{
$AzureWebProjectOutputDirectory = [io.path]::combine($Env:TF_BUILD_BINARIESDIRECTORY, $AzureWebProject)
[IO.Directory]::CreateDirectory($AzureWebProjectOutputDirectory) | Out-Null
$AzureWebProjectSourceDirectory = [io.path]::combine($Env:TF_BUILD_SOURCESDIRECTORY, $AzureWebProject)
# Find the files
$PackageFiles = gci $AzureWebProjectSourceDirectory -recurse -include $AzureWebPackageContainers |
?{ $_.PSIsContainer } |
foreach { gci -Path $_.FullName -Recurse -include $AzurePackageFileTypes }
if($PackageFiles)
{
Write-Verbose "Found $PackageFiles.count files:"
foreach ($PackageFile in $PackageFiles) {
Write-Verbose $PackageFile.FullName
}
}
else
{
Write-Warning "Found no files."
}
# Copy the binaries
Write-Verbose "Ready to copy files."
if(-not $Disable)
{
foreach ($PackageFile in $PackageFiles)
{
Copy $PackageFile $AzureWebProjectOutputDirectory
}
Write-Verbose "Files copied."
}
}
Check the above script to TFS and use it in the build definition.
WebJobApp package created in build drop.
Now the TFS Build successfully packaged the jobs to the WebJobApp deployment package.
A release management template as explained in “
How to Deploy to Azure Websites with TFS build 2013 and VS Release Management 2013” can be created to deploy the WebJobApp to Azure including the web job.
A new website created in Azure.
Release template created.
Creation of above tool is explained in “
How to Deploy to Azure Websites with TFS build 2013 and VS Release Management 2013”
Set deploy parameters from publish profile of the Azure web application.
A release triggered with the template using the TFS build.
Deployment succeeded.
Job deployed with Web Application.
Web Application and the job deployed.