We are using Azure Pipelines in Azure Devops to build our project and are attempting to analyze the project with the SonarCloudAnalyze@1 task.
The task works as expected for my .NET/C# project, but not my Angular/TypeScript project. I believe this is due to the fact that the Analyzer detects Javascript, and requires NodeJS for the analysis.
The error I’m receiving when running my pipeline which targets my Angular/TypeScript project is as follows:
The version of node.js (10) you have used to run this analysis is deprecated and we stopped accepting it.
Please update to at least node.js 14. You can find more information here: https://docs.sonarcloud.io/appendices/scanner-environment/
Our Angular project has a requirement of NodeJS 10 due to the version of Angular (7) we still run. I understand, according to the documentation, that the SonarScanner should be able to use a different version for the analysis.
Running NodeJS Tool Installer task (NodeTool@1) with versionSpec 16.x
I have attempted to configure it to use a different version first by running the task NodeTool@1 with versionSpec: ‘16.x’ prior to the SonarCloudAnalyze@1 task. This downloads the appropriate node version and puts it in the agent’s tools directory. Further, the task says it is prepending the path to the environement PATH variable. I have confirmed it is doing so by executing a task with a simple echo statement.
- task: NodeTool@0
displayName: "Install Node 16.x"
inputs:
versionSpec: "16.x"
- task: CmdLine@2
inputs:
script: "echo %PATH%"
This outputs the PATH variable with the correct path to version 16.15.1 prepended to the front.
I then run the SonarCloudAnalyze@1 where it fails stating that it is still trying to use node version 10.
At this point, I notice that node version 10 is installed on the agent machine. However, my expectation is that SonarScanner should be using the node version referenced by the PATH environment variable.
Running SonarCloudPrepare@1 after NodeTool@0 with versionSpec 16.x
I decided that maybe the preparation stage needed to also be run with version 16 tool set on the PATH. So, I run the preparation task after the node tool installer task. Then, when I get ready to build, I run the node tool installer task again to switch back to version 10.x which is required by my project. Finally, when I get ready to analyze, I once again run the node tool installer task to switch back to version 16.
It still fails with the same error stating that the analyzer is trying to use node version 10.
Setting the path to the node version explicitly in sonar-project.properties
I tried setting the sonar-project.properties to explicitly point at the nodejs executable to use. I did this as follows:
sonar.nodejs.executable=../../_tool/node/16.15.1/x64/node.exe
While this does appear to work, it has the disadvantage of self-hosted agents needing to be configured in a specific way so that we can make assumptions about where the executable would be located.
I tried to embed some variables in the file, but they did not seem to get expanded. For example:
sonar.nodejs.executable=$(Agent.ToolsDirectory)/node/16.15.1/x64/node.exe
But the scanner was unable to find the location (probably due to it not getting expanded).
ERROR: Provided Node.js executable file does not exist. Property 'sonar.nodejs.executable' was set to '$(Agent.ToolsDirectory)/node/16.15.1/x64/node.exe'
Another disadvantage of using a hardcoded path to the executable like this would be that we would manually need to update the version of Node being used with the analyzer over time instead of just allowing the tool installer task to always use the latest.
Here is my complete Azure Pipeline YAML, with potentially sensitive information asterisked out.
trigger:
- master
pool:
name: "Default"
steps:
- task: NodeTool@0
displayName: "Configure Node 16.x"
inputs:
versionSpec: "16.x"
- task: SonarCloudPrepare@1
displayName: "Prepare SonarCloud Analysis"
inputs:
SonarCloud: "SonarCloud"
organization: "***"
projectKey: "***"
projectName: "***"
scannerMode: "CLI"
configMode: "file"
configFile: "web/sonar-project.properties"
- task: NodeTool@0
displayName: "Configure Node 10.x"
inputs:
versionSpec: "10.x"
- task: Npm@1
displayName: "Install NPM Dependencies"
inputs:
command: "install"
workingDir: "web/"
- task: Npm@1
displayName: "Build Angular"
inputs:
command: "custom"
workingDir: "web/"
customCommand: "run build -- --c=production"
- task: NodeTool@0
displayName: "Configure Node 16.x"
inputs:
versionSpec: "16.x"
- task: SonarCloudAnalyze@1
displayName: "SonarCloud Analysis"
- task: SonarCloudPublish@1
inputs:
pollingTimeoutSec: "300"
I’m looking for a solution that doesn’t involve hardcoded paths to the Node installation. Does anyone have an idea why the analyzer doesn’t seem to be honoring the PATH variable’s path to the node installation?