@@ -141,7 +141,7 @@ public static Command CreateCommand(
141141 if ( ! string . IsNullOrWhiteSpace ( dryRunConfig . DeploymentProjectPath ) )
142142 {
143143 var detectedPlatform = platformDetector . Detect ( dryRunConfig . DeploymentProjectPath ) ;
144- var detectedRuntime = GetRuntimeForPlatform ( detectedPlatform ) ;
144+ var detectedRuntime = GetRuntimeForPlatform ( detectedPlatform , dryRunConfig . DeploymentProjectPath , executor , logger ) ;
145145 logger . LogInformation ( " - Detected Platform: {Platform}" , detectedPlatform ) ;
146146 logger . LogInformation ( " - Runtime: {Runtime}" , detectedRuntime ) ;
147147 }
@@ -301,6 +301,7 @@ await CreateInfrastructureAsync(
301301 planSku ,
302302 webAppName ,
303303 generatedConfigPath ,
304+ deploymentProjectPath ,
304305 platform ,
305306 logger ,
306307 needDeployment ,
@@ -411,6 +412,7 @@ public static async Task CreateInfrastructureAsync(
411412 string ? planSku ,
412413 string webAppName ,
413414 string generatedConfigPath ,
415+ string deploymentProjectPath ,
414416 Models . ProjectPlatform platform ,
415417 ILogger logger ,
416418 bool needDeployment ,
@@ -496,7 +498,7 @@ public static async Task CreateInfrastructureAsync(
496498 var webShow = await executor . ExecuteAsync ( "az" , $ "webapp show -g { resourceGroup } -n { webAppName } --subscription { subscriptionId } ", captureOutput : true , suppressErrorLogging : true ) ;
497499 if ( ! webShow . Success )
498500 {
499- var runtime = GetRuntimeForPlatform ( platform ) ;
501+ var runtime = GetRuntimeForPlatform ( platform , deploymentProjectPath , executor , logger ) ;
500502 logger . LogInformation ( "Creating web app {App} with runtime {Runtime}" , webAppName , runtime ) ;
501503 var createResult = await executor . ExecuteAsync ( "az" , $ "webapp create -g { resourceGroup } -p { planName } -n { webAppName } --runtime \" { runtime } \" --subscription { subscriptionId } ", captureOutput : true , suppressErrorLogging : true ) ;
502504 if ( ! createResult . Success )
@@ -552,7 +554,7 @@ public static async Task CreateInfrastructureAsync(
552554 }
553555 else
554556 {
555- var linuxFxVersion = GetLinuxFxVersionForPlatform ( platform ) ;
557+ var linuxFxVersion = GetLinuxFxVersionForPlatform ( platform , deploymentProjectPath , executor , logger ) ;
556558 logger . LogInformation ( "Web app already exists: {App} (skipping creation)" , webAppName ) ;
557559 logger . LogInformation ( "Configuring web app to use {Platform} runtime ({LinuxFxVersion})..." , platform , linuxFxVersion ) ;
558560 await AzWarnAsync ( executor , logger , $ "webapp config set -g { resourceGroup } -n { webAppName } --linux-fx-version \" { linuxFxVersion } \" --subscription { subscriptionId } ", "Configure runtime" ) ;
@@ -818,8 +820,14 @@ internal static async Task EnsureAppServicePlanExistsAsync(
818820 /// Get the Azure Web App runtime string based on the detected platform
819821 /// (from A365SetupRunner GetRuntimeForPlatform method)
820822 /// </summary>
821- private static string GetRuntimeForPlatform ( Models . ProjectPlatform platform )
823+ private static string GetRuntimeForPlatform ( Models . ProjectPlatform platform , string ? deploymentProjectPath , CommandExecutor executor , ILogger logger )
822824 {
825+ var dotnetVersion = ResolveDotNetRuntimeVersion ( platform , deploymentProjectPath , executor , logger ) ;
826+ if ( ! string . IsNullOrWhiteSpace ( dotnetVersion ) )
827+ {
828+ return $ "DOTNETCORE:{ dotnetVersion } ";
829+ }
830+
823831 return platform switch
824832 {
825833 Models . ProjectPlatform . Python => "PYTHON:3.11" ,
@@ -833,8 +841,14 @@ private static string GetRuntimeForPlatform(Models.ProjectPlatform platform)
833841 /// Get the Azure Web App Linux FX Version string based on the detected platform
834842 /// (from A365SetupRunner GetLinuxFxVersionForPlatform method)
835843 /// </summary>
836- private static string GetLinuxFxVersionForPlatform ( Models . ProjectPlatform platform )
844+ private static string GetLinuxFxVersionForPlatform ( Models . ProjectPlatform platform , string ? deploymentProjectPath , CommandExecutor executor , ILogger logger )
837845 {
846+ var dotnetVersion = ResolveDotNetRuntimeVersion ( platform , deploymentProjectPath , executor , logger ) ;
847+ if ( ! string . IsNullOrWhiteSpace ( dotnetVersion ) )
848+ {
849+ return $ "DOTNETCORE:{ dotnetVersion } ";
850+ }
851+
838852 return platform switch
839853 {
840854 Models . ProjectPlatform . Python => "PYTHON|3.11" ,
@@ -844,6 +858,51 @@ private static string GetLinuxFxVersionForPlatform(Models.ProjectPlatform platfo
844858 } ;
845859 }
846860
861+ private static string ? ResolveDotNetRuntimeVersion (
862+ Models . ProjectPlatform platform ,
863+ string ? deploymentProjectPath ,
864+ CommandExecutor executor ,
865+ ILogger logger )
866+ {
867+ if ( platform != Models . ProjectPlatform . DotNet ||
868+ string . IsNullOrWhiteSpace ( deploymentProjectPath ) )
869+ {
870+ return null ;
871+ }
872+
873+ var csproj = Directory
874+ . GetFiles ( deploymentProjectPath , "*.csproj" , SearchOption . TopDirectoryOnly )
875+ . FirstOrDefault ( ) ;
876+ if ( csproj == null )
877+ {
878+ logger . LogWarning ( "No .csproj file found in deploymentProjectPath: {Path}" , deploymentProjectPath ) ;
879+ return null ;
880+ }
881+
882+ var version = DotNetProjectHelper . DetectTargetRuntimeVersion ( csproj , logger ) ;
883+ if ( string . IsNullOrWhiteSpace ( version ) )
884+ {
885+ logger . LogWarning ( "Unable to detect TargetFramework version from {Project}" , csproj ) ;
886+ return null ;
887+ }
888+
889+ // Validate local SDK
890+ var sdkResult = executor . ExecuteAsync ( "dotnet" , "--version" , captureOutput : true ) . GetAwaiter ( ) . GetResult ( ) ;
891+ var installedVersion = sdkResult . Success ? sdkResult . StandardOutput . Trim ( ) : null ;
892+
893+ if ( ! sdkResult . Success ||
894+ string . IsNullOrWhiteSpace ( installedVersion ) ||
895+ ! installedVersion . StartsWith ( version , StringComparison . Ordinal ) )
896+ {
897+ throw new DotNetSdkVersionMismatchException (
898+ requiredVersion : version ,
899+ installedVersion : installedVersion ,
900+ projectFilePath : csproj ) ;
901+ }
902+
903+ return version ; // e.g. "8.0", "9.0"
904+ }
905+
847906 private static string Short ( string ? text )
848907 => string . IsNullOrWhiteSpace ( text ) ? string . Empty : ( text . Length <= 180 ? text . Trim ( ) : text [ ..177 ] + "..." ) ;
849908
0 commit comments