Skip to content

Fix: Prevent runtime downgrade when using --publish-settings-only on Flex Consumption#4761

Merged
liliankasem merged 9 commits intomainfrom
copilot/fix-publish-settings-downgrade
Jan 23, 2026
Merged

Fix: Prevent runtime downgrade when using --publish-settings-only on Flex Consumption#4761
liliankasem merged 9 commits intomainfrom
copilot/fix-publish-settings-downgrade

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 6, 2026

Issue describing the changes in this PR

When using --publish-settings-only with Flex Consumption apps, the runtime stack is silently downgraded (e.g., .NET 9 isolated → .NET 8 isolated). The flag should only sync app settings without modifying runtime configuration.

Root cause: Runtime update logic was coupled within PublishAppSettings, causing runtime updates to occur even during settings-only operations. Additionally, the system was defaulting to .NET 8.0 instead of detecting the actual target framework from the project file.

Changes:

  • Decoupled runtime update logic from PublishAppSettings - it now purely handles app settings
  • Changed runtime version detection from hardcoded default to project-based detection (_requiredNetFrameworkVersion now defaults to null)
  • Centralized runtime updates in ValidateFunctionAppPublish to occur BEFORE code deployment for Flex apps
  • Enhanced UpdateRuntimeConfigForFlex with intelligent version comparison and user prompts
  • Added skipRuntimeUpdate parameter to ValidateFunctionAppPublish to skip runtime updates during settings-only operations
  • Runtime updates now only occur when:
    • A valid target framework is detected from the project file
    • The detected version differs from Azure's current configuration
    • User confirms the update (or force flags are used)
  • Improved code quality based on PR feedback:
    • Changed console output to use ColoredConsole for consistency
    • Reduced nesting in conditional logic using else if

Impact:

  • Settings-only operations (--publish-settings-only) preserve existing runtime configuration
  • Regular publish operations detect the correct runtime version from the project and update Azure accordingly
  • Users are prompted when local and Azure runtime versions differ (unless using force flags)
  • Prevents deployment of incompatible code (e.g., .NET 9 code to .NET 8 runtime)
  • Applies to both Flex and non-Flex apps
  • Clear separation of concerns between app settings publishing and runtime configuration updates

Pull request checklist

  • My changes do not require documentation changes
  • My changes do not need to be backported to a previous version
  • My changes should not be added to the release notes for the next release
  • I have added all required tests (Unit tests, E2E tests)

Additional information

Architectural Improvements:

  1. Project-based Runtime Detection: The system now detects the target framework from the project file (e.g., net9.0) and uses that for Azure runtime configuration, eliminating the hardcoded default that caused downgrades.

  2. Centralized Runtime Updates: For Flex apps, runtime configuration is validated and updated in ValidateFunctionAppPublish before code deployment, ensuring runtime compatibility before deploying code.

  3. Smart Version Management: UpdateRuntimeConfigForFlex now:

    • Compares local project version with Azure configuration
    • Only updates when versions differ
    • Returns early if no version is detected (preserving Azure configuration)
    • Prompts users for confirmation on version mismatches
  4. Clean Separation: PublishAppSettings is now purely focused on app settings publishing, with runtime configuration keys removed from the settings dictionary but handled separately in the appropriate workflow stage.

Testing:

Added unit tests in PublishFunctionAppActionTests.cs covering:

  • Skipping runtime update when no runtime version is detected from the project
  • Skipping runtime update when local and Azure versions match
  • Updating runtime when versions differ with force flag enabled

The tests use Moq to verify the UpdateRuntimeConfigForFlex behavior without requiring e2e infrastructure.

Original prompt

This section details on the original issue you should resolve

<issue_title>[Flex Consumption] publish-settings-only downgrades runtime stack from .NET 9 isolated to .NET 8</issue_title>
<issue_description>### Version

  • Plan: Flex Consumption
  • Runtime: .NET 9 isolated
  • Core Tools version: 4.5.0
  • OS: GitHub Codespaces - Ubuntu 24.04.02 LTS (Noble Numbat)
  • Azure CLI version: 2.80.0

Description

When using Azure Functions Core Tools with the --publish-settings-only flag against a Function App on the Flex Consumption plan, the runtime stack is silently downgraded from .NET 9 isolated to .NET 8 isolated.
This behavior is unexpected and inconsistent with other tooling (e.g., VS Code extension, Azure CLI).

EXPECTED BEHAVIOR

  • --publish-settings-only should only sync App Settings
  • Runtime stack should remain unchanged (Dotnet-isolated - 9.0)

WORKAROUND
Developers can safely use either Azure CLI or the VS Code extension to update App Settings.
Both approaches leave the runtime stack untouched.

Steps to reproduce

STEPS TO REPRODUCE

  1. Create a new resource group
    az group create --name rgFuncRepro --location eastus2

  2. Create a new storage account (globally unique name)
    az storage account create
    --name reprostoragetr
    --resource-group rgFuncRepro
    --location eastus2
    --sku Standard_LRS

  3. Create a Function App on Flex Consumption
    az functionapp create
    --name reprofunc01
    --resource-group rgFuncRepro
    --storage-account reprostoragetr
    --flexconsumption-location eastus2
    --runtime dotnet-isolated
    --runtime-version 9
    --os-type Linux

  4. Confirm runtime stack in portal → Properties
    Expected: Dotnet-isolated - 9.0

  5. Run Core Tools publish-settings-only
    func azure functionapp publish reprofunc01 --publish-settings-only

  6. Observe CLI output
    "Updating function app runtime setting with 'dotnet-isolated 8.0'"

  7. Check portal → Properties again
    Actual: Runtime stack downgraded to Dotnet-isolated - 8.0

  8. Cleanup
    az group delete --name rgFuncRepro --yes --no-wait</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Fix runtime stack downgrade with publish-settings-only flag Fix: Prevent runtime downgrade when using --publish-settings-only on Flex Consumption Jan 6, 2026
Copilot AI requested a review from liliankasem January 6, 2026 23:53
@liliankasem
Copy link
Copy Markdown
Member

@copilot can you identify why PublishAppSettings updates the runtime to begin with? Can we decouple that logic from the updating the runtime?

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 7, 2026

@copilot can you identify why PublishAppSettings updates the runtime to begin with? Can we decouple that logic from the updating the runtime?

Good catch! I've decoupled the runtime update logic from PublishAppSettings.

Why it was coupled: For Flex apps, FUNCTIONS_WORKER_RUNTIME and FUNCTIONS_WORKER_RUNTIME_VERSION from local.settings.json aren't regular app settings—they control the Flex runtime configuration via a separate API call. The original code handled this by extracting and processing them within PublishAppSettings.

What changed (commit 419ded8):

  1. New method UpdateFlexRuntimeFromLocalSettings: Extracts runtime settings and calls UpdateRuntimeConfigForFlex
  2. PublishAppSettings: Now only publishes app settings (removes runtime keys but doesn't process them)
  3. PublishLocalAppSettings: Conditionally calls UpdateFlexRuntimeFromLocalSettings based on PublishLocalSettingsOnly

This gives clearer separation—PublishAppSettings is purely about settings, and callers explicitly decide when to update runtime.

@liliankasem
Copy link
Copy Markdown
Member

@copilot I have refactored the work here, please updare the PR description to reflect the latest changes

@liliankasem liliankasem marked this pull request as ready for review January 8, 2026 01:24
@liliankasem liliankasem requested a review from a team as a code owner January 8, 2026 01:24
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 8, 2026

@copilot I have refactored the work here, please updare the PR description to reflect the latest changes

Updated the PR description to reflect the latest refactoring changes.

@liliankasem
Copy link
Copy Markdown
Member

@copilot please address any feedback provided in this pull request

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 14, 2026

@copilot please address any feedback provided in this pull request

Addressed all feedback in commit 03b13b5:

  1. Changed Console.WriteLine to ColoredConsole.WriteLine (line 180)
  2. Reduced nesting with else if (line 362)
  3. Added unit tests for PublishFunctionAppAction

@liliankasem
Copy link
Copy Markdown
Member

@copilot rebase main

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jan 22, 2026

@copilot rebase main

Rebase completed successfully. The branch has been rebased onto the latest main (commit cfef95a). All 8 commits are now on top of main which includes 4 new commits:

The rebase had no conflicts. However, I cannot force-push the rebased branch due to authentication constraints. You'll need to manually force-push with: git push --force-with-lease origin copilot/fix-publish-settings-downgrade

Copilot AI and others added 3 commits January 22, 2026 12:21
… apps

Co-authored-by: liliankasem <2198905+liliankasem@users.noreply.github.com>
- Extract runtime update logic into separate UpdateFlexRuntimeFromLocalSettings method
- PublishAppSettings now only handles app settings publishing
- PublishLocalAppSettings conditionally calls runtime update based on PublishLocalSettingsOnly flag
- Clearer separation of concerns between settings and runtime updates

Co-authored-by: liliankasem <2198905+liliankasem@users.noreply.github.com>
Copilot AI and others added 5 commits January 22, 2026 12:21
- Extract Flex runtime settings from localAppSettings BEFORE calling PublishAppSettings
- Fixes issue where runtime keys were removed before they could be read
- Simplifies logic by handling extraction inline instead of separate method

Co-authored-by: liliankasem <2198905+liliankasem@users.noreply.github.com>
Co-authored-by: liliankasem <2198905+liliankasem@users.noreply.github.com>
- Changed Console.WriteLine to ColoredConsole.WriteLine for target framework detection
- Reduced nesting in ValidateFunctionAppPublish by using else if
- Added unit tests for UpdateRuntimeConfigForFlex method covering:
  * Skipping update when no runtime version is detected
  * Skipping update when versions match
  * Updating runtime when versions differ with force flag

Co-authored-by: liliankasem <2198905+liliankasem@users.noreply.github.com>
@liliankasem liliankasem force-pushed the copilot/fix-publish-settings-downgrade branch from 063203c to db378ae Compare January 22, 2026 20:21
@liliankasem liliankasem merged commit 7b88c29 into main Jan 23, 2026
38 checks passed
@liliankasem liliankasem deleted the copilot/fix-publish-settings-downgrade branch January 23, 2026 01:26
liliankasem pushed a commit that referenced this pull request Feb 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Flex Consumption] publish-settings-only downgrades runtime stack from .NET 9 isolated to .NET 8

3 participants