Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Analyze SonarCloud quality issues for a specific PR
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | 89% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 111% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 135% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 89% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 92% | 0% |
Analyze SonarCloud quality issues for a specific PR. Generates comprehensive report with metrics, top violators, and action plan.
Core principle: Analysis-only = no code changes, pure insight.
$SONARQUBE_TOKEN environment variablebash# Set SonarQube token (add to ~/.bashrc or ~/.zshrc) export SONARQUBE_TOKEN="your_token_here" # Verify token is set echo $SONARQUBE_TOKEN
To get token:
Configure your SonarCloud project details:
bash# Add to project's CLAUDE.md or as environment variables SONAR_ORGANIZATION="your-org-name" SONAR_PROJECT_KEY="your-org_your-project" SONAR_BASE_URL="https://sonarcloud.io/api"
If not set: Ask user to provide organization and project key.
Important: Direct curl with -u "$SONARQUBE_TOKEN:" fails in zsh due to authentication parsing. Use bash script wrapper:
bash# Create temporary bash script to handle authentication cat > /tmp/fetch_sonar.sh << 'SCRIPT' #!/bin/bash curl -s -u "${SONARQUBE_TOKEN}:" \ "https://sonarcloud.io/api/issues/search?componentKeys=${SONAR_PROJECT_KEY}&pullRequest=$1&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true&ps=500" SCRIPT chmod +x /tmp/fetch_sonar.sh /tmp/fetch_sonar.sh $PR_NUMBER > /tmp/sonar_pr_$PR_NUMBER.json
API Parameters:
componentKeys: Your project keypullRequest: PR numberissueStatuses: OPEN,CONFIRMED (exclude resolved)sinceLeakPeriod: Only new issues in this PRps: Page size (max 500)Create Node.js analysis script at /tmp/sonar_analyze.js:
javascriptconst fs = require('fs'); const prNumber = process.argv[2]; const data = JSON.parse(fs.readFileSync(`/tmp/sonar_pr_${prNumber}.json`, 'utf8')); const issues = data.issues || []; // Group by severity const bySeverity = issues.reduce((acc, i) => { acc[i.severity] = (acc[i.severity] || 0) + 1; return acc; }, {}); // Group by type const byType = issues.reduce((acc, i) => { acc[i.type] = (acc[i.type] || 0) + 1; return acc; }, {}); // Group by file const byFile = issues.reduce((acc, i) => { const file = i.component.split(':')[1] || i.component; acc[file] = (acc[file] || 0) + 1; return acc; }, {}); // Group by rule const byRule = issues.reduce((acc, i) => { if (!acc[i.rule]) { acc[i.rule] = { count: 0, severity: i.severity, message: i.message }; } acc[i.rule].count++; return acc; }, {}); // Output structured data console.log(JSON.stringify({ total: data.total, bySeverity, byType, topFiles: Object.entries(byFile) .sort((a, b) => b[1] - a[1]) .slice(0, 10), topRules: Object.entries(byRule) .map(([rule, d]) => ({ rule, ...d })) .sort((a, b) => b.count - a.count) .slice(0, 5) }, null, 2));
Run analysis:
bashnode /tmp/sonar_analyze.js $PR_NUMBER > /tmp/sonar_analysis_$PR_NUMBER.json
Generate formatted report from analysis:
📊 SonarCloud Analysis - PR #XXX
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📈 EXECUTIVE SUMMARY
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Total Issues: {TOTAL}
By Severity:
🔴 Blocker/Critical: {COUNT} ({PERCENTAGE}%)
🟡 Major: {COUNT} ({PERCENTAGE}%)
🔵 Minor/Info: {COUNT} ({PERCENTAGE}%)
By Type:
🐛 Bugs: {COUNT}
🛡️ Vulnerabilities: {COUNT}
🧹 Code Smells: {COUNT}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📂 TOP 10 FILES WITH ISSUES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. src/components/UserProfile.tsx - 8 issues
2. src/services/auth.service.ts - 5 issues
3. src/utils/validation.ts - 4 issues
...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠️ TOP 5 VIOLATED RULES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1. typescript:S1854 (MAJOR) - 12 occurrences
"Dead stores should be removed"
2. typescript:S3776 (CRITICAL) - 8 occurrences
"Cognitive Complexity of functions should not be too high"
3. typescript:S1186 (MINOR) - 6 occurrences
"Functions should not be empty"
...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ ACTION PLAN
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Priority 1 - CRITICAL/BLOCKER ({COUNT} issues):
• Fix immediately before merge
• Focus on: {TOP_FILES}
Priority 2 - MAJOR ({COUNT} issues):
• Address in this PR if possible
• Consider technical debt ticket if extensive
Priority 3 - MINOR/INFO ({COUNT} issues):
• Can be addressed in follow-up PR
• Add to backlog for refactoring sprint
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔗 LINKS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
View in SonarCloud:
https://sonarcloud.io/project/pull_requests_list?id={PROJECT_KEY}&pullRequest={PR_NUMBER}| SonarCloud | Symbol | Priority | Action | |------------|--------|----------|--------| | BLOCKER | 🔴 | P0 | Fix immediately | | CRITICAL | 🔴 | P0 | Fix immediately | | MAJOR | 🟡 | P1 | Fix in this PR | | MINOR | 🔵 | P2 | Consider for follow-up | | INFO | 🔵 | P3 | Optional improvement |
| Type | Symbol | Description | |------|--------|-------------| | BUG | 🐛 | Code that is demonstrably wrong | | VULNERABILITY | 🛡️ | Security issues | | CODE_SMELL | 🧹 | Maintainability issue | | SECURITY_HOTSPOT | 🔒 | Security-sensitive code to review |
Always clean up temporary files after execution:
bashrm -f /tmp/fetch_sonar.sh rm -f /tmp/sonar_pr_$PR_NUMBER.json rm -f /tmp/sonar_analyze.js rm -f /tmp/sonar_analysis_$PR_NUMBER.json
| Error | Cause | Action | |-------|-------|--------| | Token not set | $SONARQUBE_TOKEN missing | Ask user to export token | | 401 Unauthorized | Invalid or expired token | Request new token from SonarCloud | | 404 Not Found | PR doesn't exist in SonarCloud | Verify PR number and project key | | Empty response | No issues found | Report clean PR, congratulate team | | >500 issues | Pagination limit reached | Warn about incomplete data, suggest filtering | | Network error | API unreachable | Check internet connection, retry |
Create .sonarcloud.properties or add to CLAUDE.md:
properties# SonarCloud Configuration SONAR_ORGANIZATION=your-org SONAR_PROJECT_KEY=your-org_your-project SONAR_EXCLUSIONS=**/*.test.ts,**/*.spec.ts,**/migrations/** SONAR_COVERAGE_EXCLUSIONS=**/*.test.ts,src/test/**
SonarCloud API limits:
Tip: Cache results for repeated queries to same PR.
yaml- name: SonarQube Analysis run: | export SONARQUBE_TOKEN=${{ secrets.SONAR_TOKEN }} export SONAR_PROJECT_KEY="${{ secrets.SONAR_PROJECT }}" claude -p "/sonarqube ${{ github.event.pull_request.number }}"
Add to .claude/hooks/pre-merge.sh:
bash#!/bin/bash PR_NUMBER=$(gh pr view --json number -q .number) claude -p "/sonarqube $PR_NUMBER"
Never:
/tmp (cleanup required)Always:
bash# Only show critical/blocker issues /sonarqube 123 --severity BLOCKER,CRITICAL # Only show bugs and vulnerabilities /sonarqube 123 --types BUG,VULNERABILITY # Specific file pattern /sonarqube 123 --files "src/services/**"
bash# Compare issues across PRs /sonarqube 123,124,125 --compare
Cause: Invalid or missing token
Fix:
bash# Regenerate token in SonarCloud # Export new token export SONARQUBE_TOKEN="new_token_here"
Cause: Analysis not yet complete or PR not analyzed
Fix: Wait for SonarCloud analysis to complete (~2-5 minutes after PR creation)
Cause: Wrong project key
Fix: Verify project key in SonarCloud URL:
https://sonarcloud.io/project/overview?id=YOUR_PROJECT_KEYbash# Basic usage /sonarqube 170 # With PR prefix /sonarqube PR #234 # Using PR URL /sonarqube https://github.com/org/repo/pull/170 # Custom severity filter (if implemented) /sonarqube 170 --critical-only
PR Number: $ARGUMENTS
Other measured skills in the registry, with their headline benchmark lift.