public async Task Execute(RunningDeployment context) { var variables = context.Variables; var servicePrincipal = ServicePrincipalAccount.CreateFromKnownVariables(variables); string?webAppName = variables.Get(SpecialVariables.Action.Azure.WebAppName); if (webAppName == null) { throw new Exception("Web App Name must be specified"); } string?resourceGroupName = variables.Get(SpecialVariables.Action.Azure.ResourceGroupName); if (resourceGroupName == null) { throw new Exception("resource group name must be specified"); } string?slotName = variables.Get(SpecialVariables.Action.Azure.WebAppSlot); var packageFileInfo = new FileInfo(variables.Get(TentacleVariables.CurrentDeployment.PackageFilePath) !); switch (packageFileInfo.Extension) { case ".zip": Archive = new ZipPackageProvider(); break; case ".nupkg": Archive = new NugetPackageProvider(); break; case ".war": Archive = new WarPackageProvider(Log, variables, context); break; default: throw new Exception("Unsupported archive type"); } var azureClient = servicePrincipal.CreateAzureClient(); var webApp = await azureClient.WebApps.GetByResourceGroupAsync(resourceGroupName, webAppName); var targetSite = AzureWebAppHelper.GetAzureTargetSite(webAppName, slotName, resourceGroupName); // Lets process our archive while the slot is spun up. we will await it later before we try to upload to it. var slotCreateTask = new Task(() => { }); if (targetSite.HasSlot) { slotCreateTask = FindOrCreateSlot(webApp, targetSite); } string[]? substitutionFeatures = { KnownVariables.Features.ConfigurationTransforms, KnownVariables.Features.StructuredConfigurationVariables, KnownVariables.Features.SubstituteInFiles }; /* * Calamari default behaviors * https://github.com/OctopusDeploy/Calamari/tree/master/source/Calamari.Common/Features/Behaviours */ var uploadPath = string.Empty; if (substitutionFeatures.Any(featureName => context.Variables.IsFeatureEnabled(featureName))) { uploadPath = (await Archive.PackageArchive(context.StagingDirectory, context.CurrentDirectory)) .FullName; } else { uploadPath = (await Archive.ConvertToAzureSupportedFile(packageFileInfo)).FullName; } if (uploadPath == null) { throw new Exception("Package File Path must be specified"); } // need to ensure slot is created as slot creds may be used if (targetSite.HasSlot) { await slotCreateTask; } var publishingProfile = await PublishingProfile.GetPublishingProfile(targetSite, servicePrincipal); string?credential = await Auth.GetBasicAuthCreds(servicePrincipal, targetSite); string token = await Auth.GetAuthTokenAsync(servicePrincipal); var webAppClient = new WebSiteManagementClient(new Uri(servicePrincipal.ResourceManagementEndpointBaseUri), new TokenCredentials(token)) { SubscriptionId = servicePrincipal.SubscriptionNumber }; var httpClient = webAppClient.HttpClient; httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credential); Log.Info($"Uploading package to {targetSite.SiteAndSlot}"); await UploadZipAsync(publishingProfile, httpClient, uploadPath, targetSite.ScmSiteAndSlot); }