diff --git a/src/Azure.Functions.Cli/Azure.Functions.Cli.csproj b/src/Azure.Functions.Cli/Azure.Functions.Cli.csproj index fa248cb17..55b27d1cd 100644 --- a/src/Azure.Functions.Cli/Azure.Functions.Cli.csproj +++ b/src/Azure.Functions.Cli/Azure.Functions.Cli.csproj @@ -97,6 +97,9 @@ $(AssemblyName).Dockerfile.python3.10 + + $(AssemblyName).Dockerfile.python3.11 + $(AssemblyName).Dockerfile.typescript diff --git a/src/Azure.Functions.Cli/Common/Constants.cs b/src/Azure.Functions.Cli/Common/Constants.cs index 0b8f6429d..cb366b1c9 100644 --- a/src/Azure.Functions.Cli/Common/Constants.cs +++ b/src/Azure.Functions.Cli/Common/Constants.cs @@ -165,6 +165,7 @@ public static class DockerImages public const string LinuxPython38ImageAmd64 = "mcr.microsoft.com/azure-functions/python:3.0.15066-python3.8-buildenv"; public const string LinuxPython39ImageAmd64 = "mcr.microsoft.com/azure-functions/python:3.0.15066-python3.9-buildenv"; public const string LinuxPython310ImageAmd64 = "mcr.microsoft.com/azure-functions/python:4-python3.10-buildenv"; + public const string LinuxPython311ImageAmd64 = "mcr.microsoft.com/azure-functions/python:4-python3.11-buildenv"; } public static class StaticResourcesNames diff --git a/src/Azure.Functions.Cli/Helpers/PythonHelpers.cs b/src/Azure.Functions.Cli/Helpers/PythonHelpers.cs index 58f59e211..0d69ef660 100644 --- a/src/Azure.Functions.Cli/Helpers/PythonHelpers.cs +++ b/src/Azure.Functions.Cli/Helpers/PythonHelpers.cs @@ -165,7 +165,7 @@ public static void AssertPythonVersion(WorkerLanguageVersionInfo pythonVersion, { if (pythonVersion?.Version == null) { - var message = "Could not find a Python version. Python 3.6.x, 3.7.x, 3.8.x, 3.9.x, or 3.10.x is recommended, and used in Azure Functions."; + var message = "Could not find a Python version. Python 3.6.x, 3.7.x, 3.8.x, 3.9.x, 3.10.x or 3.11.x is recommended, and used in Azure Functions."; if (errorIfNoVersion) throw new CliException(message); ColoredConsole.WriteLine(WarningColor(message)); return; @@ -173,23 +173,23 @@ public static void AssertPythonVersion(WorkerLanguageVersionInfo pythonVersion, ColoredConsole.WriteLine(AdditionalInfoColor($"Found Python version {pythonVersion.Version} ({pythonVersion.ExecutablePath}).")); - // Python 3.[6|7|8|9|10] (supported) + // Python 3.[6|7|8|9|10|11] (supported) if (IsVersionSupported(pythonVersion)) { return; } - // Python 3.x (but not 3.[6|7|8|9|10]), not recommended, may fail. E.g.: 3.4, 3.5. + // Python 3.x (but not 3.[6|7|8|9|10|11]), not recommended, may fail. E.g.: 3.4, 3.5. if (pythonVersion.Major == 3) { if (errorIfNotSupported) - throw new CliException($"Python 3.6.x to 3.10.x is required for this operation. " + - $"Please install Python 3.6, 3.7, 3.8, 3.9, or 3.10 and use a virtual environment to switch to Python 3.6, 3.7, 3.8, 3.9, or 3.10."); - ColoredConsole.WriteLine(WarningColor("Python 3.6.x, 3.7.x, 3.8.x, 3.9.x, or 3.10.x is recommended, and used in Azure Functions.")); + throw new CliException($"Python 3.6.x to 3.11.x is required for this operation. " + + $"Please install Python 3.6, 3.7, 3.8, 3.9, 3.10 or 3.11 and use a virtual environment to switch to Python 3.6, 3.7, 3.8, 3.9, 3.10 or 3.11."); + ColoredConsole.WriteLine(WarningColor("Python 3.6.x, 3.7.x, 3.8.x, 3.9.x, 3.10.x or 3.11.x is recommended, and used in Azure Functions.")); } // No Python 3 - var error = "Python 3.x (recommended version 3.[6|7|8|9|10]) is required."; + var error = "Python 3.x (recommended version 3.[6|7|8|9|10|11]) is required."; if (errorIfNoVersion) throw new CliException(error); ColoredConsole.WriteLine(WarningColor(error)); } @@ -222,6 +222,7 @@ public static async Task GetEnvironmentPythonVersion( var python38GetVersionTask = GetVersion("python3.8"); var python39GetVersionTask = GetVersion("python3.9"); var python310GetVersionTask = GetVersion("python3.10"); + var python311GetVersionTask = GetVersion("python3.11"); var versions = new List { @@ -233,6 +234,7 @@ public static async Task GetEnvironmentPythonVersion( await python38GetVersionTask, await python39GetVersionTask, await python310GetVersionTask, + await python311GetVersionTask, }; // Highest preference -- Go through the list, if we find the first python 3.6 or python 3.7 worker, we prioritize that. @@ -553,6 +555,8 @@ public static Task GetDockerInitFileContent(WorkerLanguageVersionInfo in return StaticResources.DockerfilePython39; case 10: return StaticResources.DockerfilePython310; + case 11: + return StaticResources.DockerfilePython311; } } return StaticResources.DockerfilePython37; @@ -574,6 +578,8 @@ private static string GetBuildNativeDepsEnvironmentImage(WorkerLanguageVersionIn return Constants.DockerImages.LinuxPython39ImageAmd64; case 10: return Constants.DockerImages.LinuxPython310ImageAmd64; + case 11: + return Constants.DockerImages.LinuxPython311ImageAmd64; } } return Constants.DockerImages.LinuxPython36ImageAmd64; @@ -585,6 +591,7 @@ private static bool IsVersionSupported(WorkerLanguageVersionInfo info) { switch (info?.Minor) { + case 11: case 10: case 9: case 8: diff --git a/src/Azure.Functions.Cli/StaticResources/Dockerfile.python3.11 b/src/Azure.Functions.Cli/StaticResources/Dockerfile.python3.11 new file mode 100644 index 000000000..c8231eab5 --- /dev/null +++ b/src/Azure.Functions.Cli/StaticResources/Dockerfile.python3.11 @@ -0,0 +1,11 @@ +# To enable ssh & remote debugging on app service change the base image to the one below +# FROM mcr.microsoft.com/azure-functions/python:4-python3.11-appservice +FROM mcr.microsoft.com/azure-functions/python:4-python3.11 + +ENV AzureWebJobsScriptRoot=/home/site/wwwroot \ + AzureFunctionsJobHost__Logging__Console__IsEnabled=true + +COPY requirements.txt / +RUN pip install -r /requirements.txt + +COPY . /home/site/wwwroot diff --git a/src/Azure.Functions.Cli/StaticResources/StaticResources.cs b/src/Azure.Functions.Cli/StaticResources/StaticResources.cs index 90ca993a5..a68b0336f 100644 --- a/src/Azure.Functions.Cli/StaticResources/StaticResources.cs +++ b/src/Azure.Functions.Cli/StaticResources/StaticResources.cs @@ -50,6 +50,8 @@ public static async Task GetValue(string name) public static Task DockerfilePython310 => GetValue("Dockerfile.python3.10"); + public static Task DockerfilePython311 => GetValue("Dockerfile.python3.11"); + public static Task DockerfilePowershell7 => GetValue("Dockerfile.powershell7"); public static Task DockerfilePowershell72 => GetValue("Dockerfile.powershell7.2"); diff --git a/test/Azure.Functions.Cli.Tests/PythonHelperTests.cs b/test/Azure.Functions.Cli.Tests/PythonHelperTests.cs index 13446dce5..28936f255 100644 --- a/test/Azure.Functions.Cli.Tests/PythonHelperTests.cs +++ b/test/Azure.Functions.Cli.Tests/PythonHelperTests.cs @@ -71,6 +71,7 @@ public void ShouldHaveMatchingLinuxFxVersion(string linuxFxVersion, int major, i [InlineData("3.8.0", false)] [InlineData("3.9.0", false)] [InlineData("3.10.0", false)] + [InlineData("3.11.0", false)] public void AssertPythonVersion(string pythonVersion, bool expectException) { WorkerLanguageVersionInfo worker = new WorkerLanguageVersionInfo(WorkerRuntime.python, pythonVersion, "python"); @@ -92,11 +93,11 @@ public SkipIfPythonNonExistFact() string[] pythons; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - pythons = new string[] { "python.exe", "python3.exe", "python36.exe", "python37.exe", "python38.exe", "python39.exe", "python310.exe", "py.exe" }; + pythons = new string[] { "python.exe", "python3.exe", "python36.exe", "python37.exe", "python38.exe", "python39.exe", "python310.exe", "python311.exe", "py.exe" }; } else { - pythons = new string[] { "python", "python3", "python36", "python37", "python38", "python39", "python310" }; + pythons = new string[] { "python", "python3", "python36", "python37", "python38", "python39", "python310", "python311" }; } string pythonExe = pythons.FirstOrDefault(p => CheckIfPythonExist(p));