Resolving SDK Resolver Failure in .NET MAUI Projects
Syed Aizaz Z.
DevOps Cloud Engineer | AWS Certified | Docker | Kubernetes | Infrastructure as Code | Networking & Security. | IREB? Certified Agile Requirements Engineer | Distributed Software Systems Masters TU Darmstadt
Recently, I encountered an issue while working on a .NET MAUI project where the build process in Azure DevOps pipelines threw an exception. The error message read:
[error]/opt/hostedtoolcache/dotnet/sdk/8.0.401/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.ImportWorkloads.props(14,38): Error MSB4242: SDK Resolver Failure: "The SDK resolver "Microsoft.DotNet.MSBuildWorkloadSdkResolver" failed while attempting to resolve the SDK "Microsoft.NET.SDK.WorkloadAutoImportPropsLocator". Exception: "System.IO.FileNotFoundException: Workload version 8.0.401, which was specified in /home/vsts/work/1/s/src/TheAppName/global.json, was not found."
The problem boiled down to the fact that the workloadVersion value from the global.json file was not being read correctly, causing the SDK to fail to resolve the appropriate workload version, which is critical for the build process.
Here is what the problematic global.json the file looked like this:
{
"sdk": {
"version": "8.0.401",
"rollForward": "disable",
"workloadVersion": "8.0.401",
}
}
Initial Fix: Bash on Linux
In my initial attempt, I wrote a pipeline task to extract the workloadVersion from the global.json using Bash. On a Linux agent, the following steps worked as expected:
- script: |
# Install jq if it's not already available
if ! command -v jq &> /dev/null; then
sudo apt-get update
sudo apt-get install -y jq
fi
# Locate global.json and extract the workloadVersion
globalJsonPath=$(find .. -name "global.json")
workloadVersion=$(jq -r '.sdk.workloadVersion' "$globalJsonPath")
# Pass workloadVersion to the pipeline
echo "##vso[task.setvariable variable=WorkloadVersion]$workloadVersion"
displayName: 'Extract workloadVersion from global.json'
This method worked perfectly on Linux since it used Bash to navigate directories and extract values using jq.
The Issue on Windows
However, when I tried running the same pipeline on a Windows agent, it threw the following error:
领英推荐
'#' is not recognized as an internal or external command, operable program or batch file.
The reason? Bash commands don't work out-of-the-box in Windows environments, as Windows uses cmd.exe by default for command-line operations.
Final Fix: Using Bash@3 Task
- task: Bash@3
displayName: 'Extract workloadVersion from global.json'
inputs:
targetType: 'inline'
script: |
# Install jq if it's not already available
if ! command -v jq &> /dev/null; then
sudo apt-get update
sudo apt-get install -y jq
fi
# Locate global.json and extract the workloadVersion
globalJsonPath=$(find .. -name "global.json")
workloadVersion=$(jq -r '.sdk.workloadVersion' "$globalJsonPath")
# Pass workloadVersion to the pipeline
echo "##vso[task.setvariable variable=WorkloadVersion]$workloadVersion"
Key Takeaways:
Conclusion
If you're facing a similar SDK Resolver failure in your pipelines, especially when dealing with workload versions specified in global.json, ensure that the appropriate shell environment is being used for your build agents. Using tasks like Bash@3 in Azure DevOps can help bridge the gap between Linux and Windows environments, ensuring consistent behavior.
However, despite fixing the issue, I'm still curious why the global.json value wasn't initially read properly. If anyone has insights into the underlying cause of this behavior, I'd love to hear your thoughts!
Feel free to share your experiences or ask questions if you've encountered similar issues!