From be999e38debbcc6714c19cd9e47728c43b751b6e Mon Sep 17 00:00:00 2001 From: Carolina Canelas Date: Mon, 3 Aug 2026 15:11:02 -0300 Subject: [PATCH 1/2] chore: add sonar CLI pre-commit hook via Husky Wire a secrets-only pre-commit gate (sonar hook git-pre-commit) through scripts/sonar-verify-staged.sh/.ps1, invoked by Husky on pre-commit. Never calls `sonar analyze --staged` directly, since that also triggers Vortex Agentic Analysis and returns 403 for orgs without that entitlement (VTEX included). Full code-quality scanning stays enforced by CI. Co-Authored-By: Claude Sonnet 5 --- .husky/pre-commit | 4 ++++ package.json | 4 +++- scripts/sonar-verify-staged.ps1 | 26 ++++++++++++++++++++++++++ scripts/sonar-verify-staged.sh | 22 ++++++++++++++++++++++ yarn.lock | 5 +++++ 5 files changed, 60 insertions(+), 1 deletion(-) create mode 100755 .husky/pre-commit create mode 100644 scripts/sonar-verify-staged.ps1 create mode 100755 scripts/sonar-verify-staged.sh diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 000000000..cd16b6306 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +bash scripts/sonar-verify-staged.sh diff --git a/package.json b/package.json index 1cd7c2ae4..14c30a96a 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "prepublishOnly": "bash ./scripts/publishLock.sh", "ci:build": "yarn build && yarn gen", "ci:test": "yarn test --ci --coverage", - "ci:prettier-check": "prettier --check --config ./.prettierrc \"src/**/*.ts\" \"src/**/*.js\"" + "ci:prettier-check": "prettier --check --config ./.prettierrc \"src/**/*.ts\" \"src/**/*.js\"", + "prepare": "husky" }, "jest": { "transform": { @@ -118,6 +119,7 @@ "@types/semver": "^5.5.0", "@types/uuid": "^3.4.6", "get-port": "^5.1.1", + "husky": "^9.1.7", "jest": "^25.1.0", "npm-run-all": "^4.1.3", "rimraf": "^2.5.2", diff --git a/scripts/sonar-verify-staged.ps1 b/scripts/sonar-verify-staged.ps1 new file mode 100644 index 000000000..d03b7e2f4 --- /dev/null +++ b/scripts/sonar-verify-staged.ps1 @@ -0,0 +1,26 @@ +# Sonar pre-commit gate for staged files (Windows-safe path resolution). +# +# Runs a secrets-only scan (`sonar hook git-pre-commit`). The golden-path command +# `sonar analyze --staged` also triggers Agentic Analysis, which currently returns +# 403 for the VTEX org (feature not enabled yet), so it is kept commented out below. +# Code quality is still enforced by the full Sonar scan in CI. +$ErrorActionPreference = "Stop" + +$sonarInPath = Get-Command sonar -ErrorAction SilentlyContinue +if ($sonarInPath) { + $sonarExe = $sonarInPath.Source +} else { + $sonarExe = Join-Path $env:LOCALAPPDATA "sonarqube-cli\bin\sonar.exe" + if (-not (Test-Path $sonarExe)) { + Write-Host "Sonar CLI not found. Install with:" -ForegroundColor Red + Write-Host " Windows: irm https://raw.githubusercontent.com/SonarSource/sonarqube-cli/refs/heads/master/user-scripts/install.ps1 | iex" -ForegroundColor Red + Write-Host " macOS/Linux: curl -o- https://raw.githubusercontent.com/SonarSource/sonarqube-cli/refs/heads/master/user-scripts/install.sh | bash" -ForegroundColor Red + Write-Host " Docs: https://darkkitchen.vtex.com/docs/default/domain/engineering/engineering-golden-path/qa-static-analysis/" -ForegroundColor Red + exit 1 + } +} + +# Golden path (re-enable when Agentic Analysis is available for the org): +# & $sonarExe analyze --staged --project vtex_goldenpath +& $sonarExe hook git-pre-commit +exit $LASTEXITCODE diff --git a/scripts/sonar-verify-staged.sh b/scripts/sonar-verify-staged.sh new file mode 100755 index 000000000..374b57227 --- /dev/null +++ b/scripts/sonar-verify-staged.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# Sonar pre-commit gate for staged files (macOS/Linux). +# +# Runs a secrets-only scan (`sonar hook git-pre-commit`). The golden-path command +# `sonar analyze --staged` also triggers Agentic Analysis, which currently returns +# 403 for the VTEX org (feature not enabled yet), so it is kept commented out below. +# Code quality is still enforced by the full Sonar scan in CI. +set -euo pipefail + +if command -v sonar >/dev/null 2>&1; then + SONAR_CMD="$(command -v sonar)" +elif [[ -x "${HOME}/.local/share/sonarqube-cli/bin/sonar" ]]; then + SONAR_CMD="${HOME}/.local/share/sonarqube-cli/bin/sonar" +else + echo "Sonar CLI not found. Install with:" >&2 + echo " curl -o- https://raw.githubusercontent.com/SonarSource/sonarqube-cli/refs/heads/master/user-scripts/install.sh | bash" >&2 + exit 1 +fi + +# Golden path (re-enable when Agentic Analysis is available for the org): +# exec "$SONAR_CMD" analyze --staged --project vtex_goldenpath +exec "$SONAR_CMD" hook git-pre-commit diff --git a/yarn.lock b/yarn.lock index 6330ccc57..20e08c0e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2993,6 +2993,11 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" +husky@^9.1.7: + version "9.1.7" + resolved "https://registry.yarnpkg.com/husky/-/husky-9.1.7.tgz#d46a38035d101b46a70456a850ff4201344c0b2d" + integrity sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA== + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" From 247f8d60a423323ef6df8d72bd01a90d4974dff6 Mon Sep 17 00:00:00 2001 From: Carolina Canelas Date: Mon, 3 Aug 2026 15:11:57 -0300 Subject: [PATCH 2/2] chore: add sonarqube MCP config for Claude Code and Cursor Add root .mcp.json with the sonarqube MCP server and point .cursor/mcp.json at it via symlink so Claude Code and Cursor share one config. Narrow the blanket .cursor/ gitignore rule so this one shared file can be tracked while local Cursor state stays ignored. Co-Authored-By: Claude Sonnet 5 --- .cursor/mcp.json | 1 + .gitignore | 3 ++- .mcp.json | 8 ++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 120000 .cursor/mcp.json create mode 100644 .mcp.json diff --git a/.cursor/mcp.json b/.cursor/mcp.json new file mode 120000 index 000000000..c67157dc4 --- /dev/null +++ b/.cursor/mcp.json @@ -0,0 +1 @@ +../.mcp.json \ No newline at end of file diff --git a/.gitignore b/.gitignore index e894e2478..3bacb02d5 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,5 @@ package-lock.json yarn-error.log # AI IDE -.cursor/ +.cursor/* +!.cursor/mcp.json diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 000000000..d5f36500d --- /dev/null +++ b/.mcp.json @@ -0,0 +1,8 @@ +{ + "mcpServers": { + "sonarqube": { + "type": "http", + "url": "http://sonarqube.vtex.systems/mcp" + } + } +}