Azure-webjobs-sdk: Publishing webjobs alongside an asp.net core site

Created on 31 Oct 2017  路  9Comments  路  Source: Azure/azure-webjobs-sdk

I have a classic asp.net site with various webjobs that use Microsoft.Web.WebJobs.Publish to help package everything up during the build which makes deploying with kudu really easy. Is there a replacement for this that works with .net core? I'd like to start migrating this project but I'm unsure how to handle the webjobs side of it.

improvement

Most helpful comment

@vijayrkn we should discuss this at some point - should the existing webjobs tooling continue to work for .net core based webjobs projects.

All 9 comments

@vijayrkn we should discuss this at some point - should the existing webjobs tooling continue to work for .net core based webjobs projects.

we have tooling support for publishing .NETcore webjobs. it does not use the package Microsoft.Web.WebJobs.Publish but uses the inbuilt websdk. e.g: https://github.com/vijayrkn/ASPNetPublishSamples/blob/master/Publish.cmd#L174

@vijayrkn Is there a way to package multiple projects into a single zip file? I can create a folder for kudu containing the site and webjobs but I'd like to build & package the project on AppVeyor which requires everything to be in the same web deploy file.

@xt0rted - Currently websdk only supports packaging individual projects to its own web deploy packages. You should be able to publish all the artifacts to a single folder and use msdeploy.exe to package everything together.

Are there any plans to add support for .NET Core to Microsoft.Web.WebJobs.Publish? In the meantime, has anything changed in the last few months or is the current recommended practice still overriding and customizing the deployment scripts?

It's my understanding that webjob publishing is now handled by Microsoft.NET.Sdk.Publish. This is part of the Microsoft.NET.Sdk.Web meta package so the only extra changes needed are to modify your webjob projects with <Project Sdk="Microsoft.NET.Sdk;Microsoft.NET.Sdk.Publish"> and then the settings specific to each task like so:

<PropertyGroup>
  <IsWebJobProject>true</IsWebJobProject>
  <WebJobName>MyJob1</WebJobName>
  <WebJobType>Continuous</WebJobType> <!-- Continuous or Triggered -->
</PropertyGroup>

Once those changes are made you'll be able to call msbuild and output the results to a folder of your choosing.

Since originally asking about this I've moved my build script over to Cake. I'm now packing my site and tasks up up like so:

Task("Package")
    .IsDependentOn("PackagePrep")
    .IsDependentOn("Compile")
    .Does(() =>
    {
        var msBuildsettings = new DotNetCoreMSBuildSettings
        {
            MaxCpuCount = -1,
            NoLogo = true,
        };

        msBuildsettings.WithProperty("PublishUrl", MakeAbsolute(paths.ArtifactsDeploy).FullPath)
                       .WithProperty("DeployOnBuild", "true")
                       .WithProperty("Configuration", configuration) // release
                       .WithProperty("WebPublishMethod", "FileSystem")
                       .WithProperty("DeployTarget", "WebPublish")
                       .WithProperty("AutoParameterizationWebConfigConnectionStrings", "false")
                       .WithProperty("SolutionDir", ".");

        DotNetCoreMSBuild(paths.HomepageProject, msBuildsettings);

        foreach (var project in paths.TaskProjects)
        {
            DotNetCoreMSBuild(project.FullPath, msBuildsettings);
        }

        Zip(paths.ArtifactsDeploy, $"{paths.Artifacts}/wwwroot.zip");
    });

If you want to do this with the command line then calling dotnet msbuild with the above parameters should also work.

dotnet msbuild "src\MyJob1\MyJob1.csproj" /p:PublishUrl="%ARTIFACTS%" /p:DeployOnBuild=true /p:Configuration=Release /p:WebPublishMethod=FileSystem /p:DeployTarget=WebPublish /p:AutoParameterizationWebConfigConnectionStrings=false /p:SolutionDir="."

@vijayrkn has an example of doing this more like how the Microsoft.Web.Webjobs.Publish package did, but it's still verbose enough that I find my way easier. You can find that at WebApplication1.csproj#L16-L26

Thanks for following up with how you're doing it now, I appreciate it. I'm not sure what the .csproj file adds if you still have to turn around and modify the deployment files to run msbuild? I was able to update the deployment files directly following the steps here: https://hajekj.net/2017/02/20/deploying-asp-net-core-along-with-a-webjob-to-app-service/

The first method requires calling dotnet msbuild with publish parameters for each project being published. In my example above the website is published to /artifacts and MyJob1 published to /artifacts/app_data/Jobs/Continuous/MyJob1. This differs from the example in that blog post because I'm letting the tooling work out the paths based on the project settings instead of providing them in the dotnet publish call.

The second method works exactly like Microsoft.Web.Webjobs.Publish. It still calls msbuild once per project like above but it's hidden away as a chained build task on the website. So with this you call dotnet msbuild with publish parameters once for the website and that's it. The result is the same though, your site and webjobs are put into the /artifacts folder ready to be deployed.

This is purely an implementation detail but I don't like having to add each webjob to my website project. I had the same complaint with the old tooling and the webjob-publish-settings.json & webjobs-list.json files. With my Cake script I can do ./src/MyProject.Tasks.*/*.csproj and loop over each project calling the publish task. As long as my webjob projects follow that naming scheme any new ones will automatically be published with no additional changes.

My Cake script was part of a larger piece of work to simplify my build process while also letting me build & package the site from anywhere. I'm also not a fan of writing batch files or powershell scripts. Now I let AppVeyor handle PR and production builds instead of kudu which lightens the load on my app service vm and shortens my build times by at least half (running on an S2 instance). AppVeyor then triggers a Zip Push deploy and the rest of the process, warmup, deployment slots, etc., stays the same.

Thanks for the explanation, appreciated. 馃憤

Was this page helpful?
0 / 5 - 0 ratings