Repository navigation
Remove unsupported runtimes from SKU built-in profiles - #5507
Conversation
Remove python from supportedRuntimes and workers in windows-consumption and windows-dedicated profiles. Python is only supported on Linux for Azure Functions. Remove go worker entries from profiles where go is not in supportedRuntimes (linux-premium, windows-consumption, windows-dedicated, linux-consumption). Go is only supported on the Flex Consumption plan. Fixes #5293 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3bb763e6-d45c-4b66-b044-67858ad44d49
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3bb763e6-d45c-4b66-b044-67858ad44d49
There was a problem hiding this comment.
Pull request overview
Removes unsupported runtime entries from built-in hosting profiles so the v5 CLI’s profile-based validation aligns more closely with Azure production support constraints (notably Python on Windows, and Go outside Flex Consumption).
Changes:
- Update built-in profiles to remove
pythonfrom Windows profiles’supportedRuntimesandworkers. - Remove
gofrom theworkersconstraints on non-Flex profiles. - Document the change in v5 release notes.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Func/Profiles/BuiltInProfiles.json | Removes Python from Windows profile runtime/worker lists and removes Go worker constraints from non-Flex profiles. |
| src/Func/release_notes.md | Adds a release note entry describing the built-in profile updates. |
Suppressed comments (1)
src/Func/Profiles/BuiltInProfiles.json:96
- Same as
windows-consumption: removingpythonfrom theworkersmap makes the worker version range unconstrained. A Python project on this profile can still trigger an automatic install of the python worker workload and only then fail thesupportedRuntimescheck, which is a surprising side effect for an unsupported runtime. Consider blocking auto-install earlier when the active profile does not support the detected runtime.
"workers": {
"node": {
"version": "[3.13.0]"
}
},
9219594 to
6b34559
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
test/Func.Tests/Commands/StartInitializationTests.cs:537
- This assertion is order-dependent (it requires the supported runtime list to stay in exactly this sequence). Since profile runtime ordering is not semantically important, the test will become brittle if the list order changes in JSON/fixtures.
ex.Message.Should().Contain("node, java, powershell, dotnet-isolated, custom");
ValidateSupportedRuntime now checks both project.StackName and
worker.WorkerRuntime (or workerId for pre-install) against the profile's
supportedRuntimes. A match on either is sufficient. This handles stacks
where the names differ:
- Go: StackName='go', WorkerRuntime='native'
- DotNet: StackName='dotnet', WorkerRuntime='dotnet-isolated'
Built-in profiles now use 'dotnet' (matching StackName) instead of
'dotnet-isolated' in supportedRuntimes.
The check runs in two places:
1. Before auto-install: uses StackName + workerId to prevent unnecessary
downloads for unsupported runtimes
2. After resolution: uses StackName + WorkerRuntime for the definitive
check once the worker is resolved
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3bb763e6-d45c-4b66-b044-67858ad44d49
ad8a281 to
3d157bf
Compare
…ry constructor - Revert supportedRuntimes back to 'dotnet-isolated' in all profiles to avoid breaking SetupRunner.DotNetProfileRuntime which is hardcoded to compare against this value. - Rename ValidateSupportedRuntime parameter from 'workerRuntimeName' to 'runtimeIdentifier' to clarify it accepts either a workload id or a worker runtime name depending on the call site. - Add inline comment at pre-install call site explaining workerId.Value is the workload identifier, not the worker runtime name. - Convert TestFunctionsProject to use primary constructor. - Update test assertion to match reverted profile data. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3bb763e6-d45c-4b66-b044-67858ad44d49
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (3)
src/Func/Commands/Start/Initialization/Steps/ResolveFunctionsWorkerInitializationStep.cs:233
- This error no longer includes what was actually detected (stackName and/or runtimeIdentifier). When debugging mismatches (especially where stack name differs from worker runtime), it’s useful to include both identifiers in the message, e.g. include stackName and runtimeIdentifier alongside stackDisplayName so users can see exactly what value failed validation.
string message = $"Profile '{profile.Name}' does not support the '{stackDisplayName}' stack. "
+ $"Supported runtimes: {string.Join(", ", supportedRuntimes)}.";
throw new GracefulException(message, isUserError: true);
src/Func/Commands/Start/Initialization/Steps/ResolveFunctionsWorkerInitializationStep.cs:212
- The example "Go stack = \"go\" but worker runtime = \"native\"" should be verified against the actual worker runtime identifiers used by this CLI/host. If the Go worker runtime is not literally "native" in this codebase, this comment will mislead future maintainers; consider updating the example to a known-accurate mapping (or rephrasing to avoid hard-coding a potentially changing identifier).
/// <summary>
/// Checks whether the profile supports the runtime by matching against both the stack name
/// and the runtime identifier (workload id or worker runtime name). Some stacks differ between
/// the two (e.g. Go stack = "go" but worker runtime = "native"; DotNet stack = "dotnet" but
/// worker runtime = "dotnet-isolated"). A match on either is sufficient.
/// </summary>
src/Func/Commands/Start/Initialization/Steps/ResolveFunctionsWorkerInitializationStep.cs:226
- This performs up to 2 ordinal-ignore-case comparisons per element of supportedRuntimes. Since you’re checking membership for exactly two values (stackName and runtimeIdentifier), consider materializing supportedRuntimes into a case-insensitive set (or using an existing case-insensitive lookup if available) and calling Contains for each value. This is simpler to read and avoids repeated comparisons on the startup path.
if (supportedRuntimes.Any(runtime =>
string.Equals(runtime, stackName, StringComparison.OrdinalIgnoreCase)
|| string.Equals(runtime, runtimeIdentifier, StringComparison.OrdinalIgnoreCase)))
|
Copilot resolve the merge conflicts in this pull request |
…-profiles # Conflicts: # src/Func/Commands/Start/Initialization/Steps/ResolveFunctionsWorkerInitializationStep.cs Co-authored-by: satvu <35204912+satvu@users.noreply.github.com>
Resolved. Merged |
Use the worker reference's expected runtime identity during pre-install profile validation so Go's native runtime alias is honored consistently. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3bb763e6-d45c-4b66-b044-67858ad44d49
There was a problem hiding this comment.
🟡 Changes recommended
Auto-installed Go workers may retain the incorrect go runtime identity, and test coverage gaps remain.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (2)
src/Func/Profiles/BuiltInProfiles.json:80
- The bundled-profile test only checks the profile names and status, so these worker/runtime removals can regress without a failing test. Add assertions for both Windows profiles' supported runtimes/workers and for the absence of Go workers from the non-Flex profiles.
"supportedRuntimes": [
"node",
"java",
"powershell",
"dotnet-isolated",
"custom"
test/Func.Tests/Commands/StartInitializationTests.cs:597
- This assertion covers the host
IWorkloadInstaller, not theIFunctionsWorkerInstallerthat performs worker auto-install.CreateRunnersupplies a default worker-installer substitute, so the test can still pass ifInstallAsyncis called; wire in a named worker-installer substitute and assert that it receives no install call.
await workloadInstaller.DidNotReceive().InstallFromCatalogAsync(
Arg.Any<string>(),
Arg.Any<NuGetVersion?>(),
Arg.Any<string?>(),
Arg.Any<bool?>(),
Arg.Any<bool>(),
Arg.Any<bool>(),
Arg.Any<IProgress<WorkloadInstallProgress>?>(),
Arg.Any<CancellationToken>());
- Files reviewed: 6/6 changed files
- Comments generated: 1
- Review effort level: Lite
Apply the project worker reference runtime to newly installed workers so first-run Go projects start with FUNCTIONS_WORKER_RUNTIME=native. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3bb763e6-d45c-4b66-b044-67858ad44d49
There was a problem hiding this comment.
🔵 Needs a closer look
Unresolved review findings require additional profile and startup test coverage corrections.
Review details
Suppressed comments (3)
Previously missed (2) — in code that hasn't changed since the last review.
src/Func/Profiles/BuiltInProfiles.json:80
- The bundled profile edits are not asserted by a test that loads the real registry:
BuiltInProfileSourceTestschecks only profile names/status, while the new start tests constructsupportedRuntimesmanually. Add assertions for the actual Windows and Linux definitions (including the removed Python/Go workers) so these production profile values cannot regress unnoticed.
"supportedRuntimes": [
"node",
"java",
"powershell",
"dotnet-isolated",
"custom"
test/Func.Tests/Commands/StartInitializationTests.cs:577
- This test does not enter the worker auto-install path:
CreateRunnerdefaults its worker resolver to return a resolved worker, and theDidNotReceiveassertion targets the hostIWorkloadInstaller, which is already bypassed by the installed host result. Configure the worker resolver to returnNotInstalled, inject a worker-installer substitute, and assert that itsInstallAsyncwas not called.
test/Func.Tests/Commands/StartInitializationTests.cs:481
- Using
["native"]makes both the pre-install runtime and the post-install adjusted runtime match this test profile, so it never exercises the stack-name fallback that the real Flex profile needs (gostack vsnativeworker runtime). Use the actual supported valuegohere so a regression in thestackNamecomparison is caught.
CreateResolvedProfile(workerRanges, ["native"]),
- Files reviewed: 6/6 changed files
- Comments generated: 0 new
- Review effort level: Lite
There was a problem hiding this comment.
🔵 Needs a closer look
A moderate validation gap and two requested test-coverage improvements remain.
Review details
Suppressed comments (3)
src/Func/Commands/Start/Initialization/Steps/ResolveFunctionsWorkerInitializationStep.cs:53
- This check only runs for
NotInstalledandMissingCompatibleVersionfailures. If an unsupported project resolves toInvalidInstallation(for example, an installed worker is missingworker.config.json, which the resolver reports as a non-installable failure), execution skips this validation and reports the worker error instead of enforcing the profile'ssupportedRuntimes. Run the project/reference check beforeResolveWorkerAsync(while retaining the post-resolution check for the actual worker runtime).
ValidateSupportedRuntime(context, project.StackName, project.WorkerReference.WorkerRuntime, project.StackDisplayName);
src/Func/Profiles/BuiltInProfiles.json:80
- The new start tests exercise hand-built
ResolvedProfileinstances, whileBuiltInProfileSourceTestsonly checks profile names and status. Please add a regression assertion for the bundled profiles'workersandsupportedRuntimesentries; otherwise the removed Windows Python/Go support could be reintroduced inBuiltInProfiles.jsonwithout any test failing.
"node",
"java",
"powershell",
"dotnet-isolated",
"custom"
test/Func.Tests/Commands/StartInitializationTests.cs:577
- This test does not exercise the new pre-install guard:
CreateRunnerdefaults toCreateWorkerResolverFactory(), whose resolver returns a resolved worker, so theTryGetInstallableWorkerbranch andworkerInstaller.InstallAsyncare never reached. Configure the resolver to return aNotInstalledresult and assert the injected worker installer receives noInstallAsynccall; otherwise a regression that validates only after auto-install would still pass.
var runner = CreateRunner(projectResolver, new ProfileResolution.Resolved(profile, []), hostWorkloadResolver, workloadInstaller: workloadInstaller);
- Files reviewed: 6/6 changed files
- Comments generated: 0 new
- Review effort level: Lite
Cover missing and invalid worker rejection, bundled runtime support, and both Go stack/runtime matches. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3bb763e6-d45c-4b66-b044-67858ad44d49
|
Addressed the suppressed findings from the latest Copilot review in c046ede:
Validation: 47 targeted tests passed; strict Release build completed with zero warnings/errors. |
Summary
Fixes #5293
Aligns built-in profiles with Azure runtime support and enforces
supportedRuntimesduringfunc start. Unsupported stacks are rejected before worker resolution or auto-install, with a second check against the resolved worker runtime.Changes
Built-in profiles
supportedRuntimesworkerswindows-consumptionpythonpython,gowindows-dedicatedpythonpython,golinux-premiumgolinux-consumptiongoThe profiles continue to use
dotnet-isolated, matching the .NET worker runtime identity consumed byfunc setupand the Functions host.Runtime validation
.NETuses stackdotnetand runtimedotnet-isolated; Go uses stack/workloadgoand runtimenative.FunctionsWorkerReferenceand normalizes newly installed workers to that identity, preserving the worker ID, config path, and version. First-run Go workers therefore resolve asnative, notgo.Tests and release notes
IFunctionsWorkerInstaller..NETruntime matching and bothgoandnativeprofile values during Go auto-install. The fake installer returnsgo; the final worker must benativewith its metadata preserved.src/Func/release_notes.mdwith the user-facing behavior change.Supporting documentation
Python is Linux-only. The Azure Functions supported languages documentation marks Python as supported on Linux and unsupported on Windows. The Azure Functions scale and hosting documentation also states:
Go is Flex Consumption-only. The Go developer reference states:
Validation
Automated
dotnet test test\Func.Tests\Func.Tests.csproj --no-restore --filter "FullyQualifiedName~StartInitializationTests|FullyQualifiedName~FunctionsWorkerReferenceTests|FullyQualifiedName~BuiltInProfileSourceTests" -v minimal— 47 passed.CI=true:dotnet build -c Release --no-restore -v q— succeeded with 0 warnings and 0 errors.Manual — real workload packages
Built a Windows x64 CLI and real workload
.nupkgs, published packages to a local NuGet v3 feed (http://localhost:5555/v3/index.json), and used an isolated CLI/workload home underartifacts\manual-go-test. Created a Go Functions project withfunc init --stack go. Runs used an interactive terminal so worker auto-install was enabled.func start <app> --profile flex --output plain --no-azurite1.0.0-local.20260916232418; reportedResolved worker nativeandresolve_worker complete: native.c046eded, remove Go worker, then runfunc start <app> --profile linux-premium --output plain --no-azuriteProfile 'linux-premium' does not support the 'Go' stack, listed supported runtimes, and exited with code 1. The workload list afterward still contained only the host and Go stack: no worker was installed.Manual-test scope: The Flex run verified real-package auto-install and runtime normalization, not a complete host startup or function invocation. It stopped afterward at extension-bundle resolution because no compatible bundle workload was installed. Go was also unavailable on the test machine. The Linux Premium rejection occurred before those downstream dependencies were needed.