如何在Azure DevOps中实现Synapse Notebook的SonarQube有效扫描并获取报告?
修复Azure DevOps中Synapse Notebook的SonarCloud扫描脚本
问题分析
你的当前脚本存在以下关键问题,导致无法有效分析Synapse Notebook中的多语言代码:
- 直接分析JSON文件无法提取内嵌的Python/PySpark、SQL、R代码
- 限制仅分析Python语言(
sonar.language=py),忽略了SQL和R代码 - 使用
jq将JSON格式的API结果转成HTML的方式无法生成有效的可视化分析报告 - 路径配置未适配多语言代码的提取需求
解决方案脚本
以下是修正后的完整DevOps脚本,包含代码提取、多语言分析和正确的报告生成流程:
trigger: none # - main # - master pool: vmImage: ubuntu-latest variables: extractedCodeDir: '$(Build.SourcesDirectory)/extracted_code' sonarProjectKey: 'ABCD' sonarOrganization: '****' steps: - checkout: self # 从Synapse Notebook JSON中提取多语言代码 - script: | mkdir -p $(extractedCodeDir)/python $(extractedCodeDir)/sql $(extractedCodeDir)/r for notebook in $(Build.SourcesDirectory)/notebook/*.json; do echo "处理Notebook文件: $notebook" # 提取Python/PySpark代码 jq -r '.cells[] | select(.cell_type == "code") | select(.metadata.language == "python") | .source[]' "$notebook" > "$(extractedCodeDir)/python/$(basename $notebook .json).py" # 提取SQL代码 jq -r '.cells[] | select(.cell_type == "code") | select(.metadata.language == "sql") | .source[]' "$notebook" > "$(extractedCodeDir)/sql/$(basename $notebook .json).sql" # 提取R代码 jq -r '.cells[] | select(.cell_type == "code") | select(.metadata.language == "r") | .source[]' "$notebook" > "$(extractedCodeDir)/r/$(basename $notebook .json).r" done echo "提取完成的代码文件列表:" ls -R $(extractedCodeDir) displayName: '从Synapse Notebooks提取代码' condition: succeeded() # SonarCloud扫描准备 - task: SonarCloudPrepare@3 inputs: SonarQube: 'SonarCloud' organization: '$(sonarOrganization)' scannerMode: 'cli' configMode: 'manual' cliProjectKey: '$(sonarProjectKey)' cliProjectName: 'ABCD' cliSources: '$(extractedCodeDir)' extraProperties: | sonar.sources=$(extractedCodeDir) sonar.python.version=3.x sonar.r.version=4.x # 根据实际使用的R版本调整 sonar.sql.dialect=tsql # 适配Synapse SQL方言,可按需修改 sonar.verbose=true sonar.language=py,sql,r # 启用所有支持的语言分析 displayName: '准备SonarCloud分析' condition: succeeded() # 执行SonarCloud分析 - task: SonarCloudAnalyze@3 inputs: jdkversion: 'JAVA_HOME_17_X64' displayName: '运行SonarCloud分析' condition: succeeded() # 生成并导出HTML报告 - script: | # 从扫描结果中获取分析任务ID REPORT_TASK=$(Build.SourcesDirectory)/.scannerwork/report-task.txt CE_TASK_ID=$(grep "ceTaskId" $REPORT_TASK | cut -d'=' -f2) # 等待SonarCloud云端分析完成 echo "等待SonarCloud分析任务完成..." while true; do STATUS=$(curl -u $SONAR_TOKEN: -s "https://sonarcloud.io/api/ce/task?id=$CE_TASK_ID" | jq -r '.task.status') if [ "$STATUS" == "SUCCESS" ]; then break elif [ "$STATUS" == "FAILED" ]; then echo "SonarCloud分析任务失败!" exit 1 fi sleep 10 done # 下载官方HTML格式分析报告 curl -u $SONAR_TOKEN: -X GET "https://sonarcloud.io/api/issues/export?componentKeys=$(sonarProjectKey)&format=html" -o $(Build.ArtifactStagingDirectory)/sonar-report.html displayName: '导出SonarCloud HTML报告' condition: succeeded() # 验证报告存在性 - script: | if [ -f "$(Build.ArtifactStagingDirectory)/sonar-report.html" ]; then echo "##vso[task.setvariable variable=SONAR_REPORT_EXISTS]true" else echo "未找到Sonar分析报告!" echo "##vso[task.setvariable variable=SONAR_REPORT_EXISTS]false" fi displayName: '检查Sonar报告是否存在' condition: succeeded() # 发布分析报告 - task: PublishBuildArtifacts@1 condition: and(succeeded(), eq(variables['SONAR_REPORT_EXISTS'], 'true')) inputs: pathToPublish: '$(Build.ArtifactStagingDirectory)/sonar-report.html' artifactName: 'SonarCloudHTMLReport' publishLocation: 'Container' displayName: '发布SonarCloud分析报告'
关键修复说明
- 代码提取:使用
jq工具从Synapse Notebook的JSON结构中,按语言类型提取代码单元格内容,分别保存为.py、.sql、.r文件,确保SonarCloud能识别并分析每种语言。 - 多语言支持:移除单一语言限制,配置
sonar.language=py,sql,r,并分别指定Python、R版本和SQL方言,覆盖所有代码类型的分析需求。 - 报告生成:通过SonarCloud官方API获取完成的分析任务,下载官方生成的HTML报告,替代之前无效的JSON转HTML方式。
- 流程优化:增加云端分析等待逻辑,避免因分析未完成导致报告下载失败;使用变量管理目录路径,提升脚本可读性和维护性。
内容的提问来源于stack exchange,提问作者RSK
相关产品推荐
相关产品推荐

