Overview
Problem to configure SonarCloud with Monorepo (PNPM) on Bitbucket on Cloud
Status:
- Our monorepo is setup at the Sonar cloud. Each sub-project can be seen on dashboard
- We use PNPM with native orchestration with – filter
- Then we have a single pipeline file to handle all projects
- Javascript stack
- Our company have a team plan / no enterprise plan Sonar Cloud
**Question: How to run the quality gate on monorepo ?
**
On non-monorepo, we used to use pipe to call the scanner and the quality gate and it works well.
Pipeline step - Sonar oldWay
# need to provide an organisation and project keys
- step: &sonarOldWay
name: Analyze on SonarCloud
size: x2
caches:
- pnpm
- sonar
script:
- echo "Running SonarQube scan with SONAR_SCANNER_OPTS=${SONAR_SCANNER_OPTS}"
- pipe: sonarsource/sonarcloud-scan:4.1.0
variables:
SONAR_SCANNER_OPTS: ${SONAR_SCANNER_OPTS}
SONAR_TOKEN: ${SONAR_TOKEN}
EXTRA_ARGS: -Dsonar.sources=\"src\" -Dsonar.tests=\"tests/unit\" -Dsonar.exclusions=\"**/tests/*.js,**/src/assets/images/*,**/src/assets/fonts/*\,**/src/main.ts" -Dsonar.language=\"js\" -Dsonar.javascript.lcov.reportPaths=\"./coverage/lcov.info\" -Dsonar.testExecutionReportPaths=\"./test-report.xml\"
- pipe: sonarsource/sonarcloud-quality-gate:0.2.0
variables:
SONAR_TOKEN: ${SONAR_TOKEN}
This way above, with a monorepo, seems not working as it takes to provides an organization key and a project key and moreover, we do not want to run the scan and the quality gate on projects and libraries that are not touched/changed. Consequenlty SonarCloud pipe does not seen suitable for monorepo ? Moreover I did not find how to analyze in one shot all the monorepo as a workaround….
Consequenly and however, we got success in runner the scanner ‘manually’ based on the affected artefacts by using a javascript scripts and the npm artefact sonar/scan.
#!/usr/bin/env node
import fs from "fs";
import path from "path";
import { createRequire } from 'module';
import { getProjectInfo } from "./utils-app.js"
const require = createRequire(import.meta.url);
const { scan } = require('@sonar/scan');
const projectName = process.argv[2];
if (!projectName) {
console.error("Error - Please provide an application name.");
process.exit(1);
}
const project = getProjectInfo(projectName);
if (!project) {
console.error("Error - The project %s is not recognized.", projectName);
process.exit(1);
}
if (!process.env.SONAR_TOKEN) {
console.error("Error: SONAR_TOKEN must be set in the environment.");
process.exit(1);
}
console.log("Analyzing project %s at path %s...", projectName , project.path);
const sonarConfig = {
token: process.env.SONAR_TOKEN,
options: {
"sonar.projectKey": project.sonarKey,
"sonar.organization": "ubeker",
"sonar.sources": "src",
"sonar.tests": "tests/unit",
"sonar.exclusions": "**/tests/*.js,**/src/assets/images/*,**/src/assets/fonts/*,**/src/main.ts,./dist/**,**/node_modules/**,**/.pnpm/**",
"sonar.language": "js",
"sonar.typescript.lcov.reportPaths": "coverage/lcov.info",
"sonar.testExecutionReportPaths": "test-report.xml",
},
};
scan(sonarConfig, (err) => {
if (err) {
console.error(`Sonar scan failed for project ${projectName}:\n${err.stack}`);
process.exit(1);
} else {
console.log("Analyze successful for %s.", projectName);
}
});
New pipeline step:
- step: &sonarCloudAnalyze
name: Sonar affectedd artefacts
size: 2x
artifacts:
download: true
caches:
- pnpm
- sonar
script:
- export PATH=./node_modules/.bin:$PATH
- export PNPM_STORE_PATH="$HOME/.pnpm-store"
- echo "Installing Pnpm at global scope..."
- npm install -g pnpm@latest-10
- pnpm config set store-dir "$PNPM_STORE_PATH"
- pnpm install
- if [ "$BITBUCKET_BRANCH" = "main" ]; then BASE="...[HEAD~1]"; else BASE="...[origin/main]"; fi
- echo "Using base commit $BASE"
- >-
pnpm --filter "$BASE"
--changed-files-ignore-pattern "**/*.stories.ts"
--changed-files-ignore-pattern "**/*.md"
--changed-files-ignore-pattern "./bitbucket-pipelines.yml"
run sonar
and in each package.json of projects and libraries we have a sonar script:
"scripts": {
"sonar": "node ../../scripts/app/sonar-analyze-app.js ubeker-spa",
},
This works wery well. But when it is time to run the gate, it seems we cannot use the pipe sonarsource/sonarcloud-quality-gate:0.2.0 as it expect some input file sonarcloud-scan.log which is not generated by the manual way obviously (but by the pipe sonarsource/sonarcloud-scan:4.1.0).
We did not find any npm artefact for the quality gate that allows us to use it and then we are stuck at this stage.
So is there a way, a config, to make the quality gate working on monorepo ? on affected artefact ?