Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 53 additions & 1 deletion src/Cli/func/Actions/AzureActions/PublishFunctionAppAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -650,11 +650,13 @@ private async Task PublishFunctionApp(Site functionApp, GitIgnoreParser ignorePa
else if (functionApp.IsLinux && functionApp.IsDynamic)
{
// Consumption Linux
WarnIfNoZipIsUnsupported(functionApp);
shouldSyncTriggers = await HandleLinuxConsumptionPublish(functionApp, zipStreamFactory);
}
else if (functionApp.IsFlex)
{
// Flex
WarnIfNoZipIsUnsupported(functionApp);
shouldSyncTriggers = await HandleFlexConsumptionPublish(functionApp, zipStreamFactory);
}
else if (functionApp.IsLinux && functionApp.IsElasticPremium)
Expand Down Expand Up @@ -684,6 +686,7 @@ private async Task PublishFunctionApp(Site functionApp, GitIgnoreParser ignorePa
shouldSyncTriggers = false;

// "--no-zip"
await EnsureNoRunFromPackageSetting(functionApp);
await PublishZipDeploy(functionApp, zipStreamFactory);
}

Expand Down Expand Up @@ -718,6 +721,18 @@ private async Task PublishFunctionApp(Site functionApp, GitIgnoreParser ignorePa
}
}

private void WarnIfNoZipIsUnsupported(Site functionApp)
{
if (RunFromPackageDeploy)
{
return;
}

var plan = functionApp.IsFlex ? "Flex Consumption" : "Linux Consumption";
ColoredConsole.WriteLine(WarningColor(
$"The --nozip flag is not supported for {plan} Function Apps. This deployment will use Run-From-Package."));
}

private async Task SyncTriggers(Site functionApp)
{
await RetryHelper.Retry(
Expand Down Expand Up @@ -1011,6 +1026,42 @@ private async Task PublishRunFromPackageLocal(Site functionApp, Func<Task<Stream
ColoredConsole.WriteLine("Deployment completed successfully.");
}

private async Task EnsureNoRunFromPackageSetting(Site functionApp)
{
if (!RemoveRunFromPackageSetting(functionApp, out _))
{
return;
}

ColoredConsole.WriteLine(WarningColor(
$"Removing {Constants.WebsiteRunFromPackage} app setting before --nozip deployment."));
var result = await AzureHelper.UpdateFunctionAppAppSettings(functionApp, AccessToken, ManagementURL);
if (!result.IsSuccessful)
{
throw new CliException($"Error when removing app settings: {result.ErrorResult}.");
}

await WaitForAppSettingUpdateSCM(
functionApp,
shouldHaveSettings: functionApp.AzureAppSettings,
shouldNotHaveSettings: new Dictionary<string, string> { { Constants.WebsiteRunFromPackage, null } },
timeOutSeconds: 300);
}

internal static bool RemoveRunFromPackageSetting(Site functionApp, out IDictionary<string, string> removedSettings)
{
removedSettings = new Dictionary<string, string>();

if (functionApp.AzureAppSettings.TryGetValue(Constants.WebsiteRunFromPackage, out string value))
{
removedSettings[Constants.WebsiteRunFromPackage] = value;
functionApp.AzureAppSettings.Remove(Constants.WebsiteRunFromPackage);
return true;
}

return false;
}

private async Task WaitForAppSettingUpdateSCM(
Site functionApp,
IDictionary<string, string> shouldHaveSettings = null,
Expand Down Expand Up @@ -1063,7 +1114,8 @@ private async Task WaitForAppSettingUpdateSCM(
{
foreach (KeyValuePair<string, string> keyValuePair in shouldNotHaveSettings)
{
if (scmSettingsDict.ContainsKey(keyValuePair.Key) && scmSettingsDict[keyValuePair.Key] == keyValuePair.Value)
if (scmSettingsDict.ContainsKey(keyValuePair.Key) &&
(keyValuePair.Value == null || scmSettingsDict[keyValuePair.Key] == keyValuePair.Value))
{
scmUpdated = false;
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using Azure.Functions.Cli.Actions.AzureActions;
using Azure.Functions.Cli.Arm.Models;
using Azure.Functions.Cli.Common;
using Azure.Functions.Cli.Helpers;
using Azure.Functions.Cli.StacksApi;
using Moq;
Expand Down Expand Up @@ -202,6 +203,53 @@ public async Task UpdateFrameworkVersions_NonDotnetLinuxApp_NoDotnetVersion_Does
Times.Never);
}

[Theory]
[InlineData("1")]
[InlineData("0")]
[InlineData("")]
public void RemoveRunFromPackageSetting_RemovesExistingSettingRegardlessOfValue(string value)
{
// Arrange
var site = new Site("test-site")
{
AzureAppSettings = new Dictionary<string, string>
{
{ Constants.WebsiteRunFromPackage, value },
{ "OTHER_SETTING", "present" }
}
};

// Act
var removed = PublishFunctionAppAction.RemoveRunFromPackageSetting(site, out var removedSettings);

// Assert
Assert.True(removed);
Assert.False(site.AzureAppSettings.ContainsKey(Constants.WebsiteRunFromPackage));
Assert.Equal("present", site.AzureAppSettings["OTHER_SETTING"]);
Assert.Equal(value, removedSettings[Constants.WebsiteRunFromPackage]);
}

[Fact]
public void RemoveRunFromPackageSetting_WhenAbsent_DoesNotMutateSettings()
{
// Arrange
var site = new Site("test-site")
{
AzureAppSettings = new Dictionary<string, string>
{
{ "OTHER_SETTING", "present" }
}
};

// Act
var removed = PublishFunctionAppAction.RemoveRunFromPackageSetting(site, out var removedSettings);

// Assert
Assert.False(removed);
Assert.Equal("present", site.AzureAppSettings["OTHER_SETTING"]);
Assert.Empty(removedSettings);
}

private static FlexFunctionsStacks CreateMockFlexStacks()
{
return new FlexFunctionsStacks
Expand Down
Loading