Claude
Skills
Sign in
โ† Back

sonarqube

Included with Lifetime
$97 forever

Analyze SonarCloud quality issues for a specific PR

General

What this skill does


# SonarQube Analysis

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.

## Process

1. **Verify Token**: Check `$SONARQUBE_TOKEN` environment variable
2. **Fetch Issues**: Call SonarCloud API for PR issues
3. **Parse Data**: Group by severity, type, file, rule
4. **Generate Report**: Structured output with action plan
5. **Cleanup**: Remove temporary files

## Prerequisites

### Environment Variable

```bash
# Set SonarQube token (add to ~/.bashrc or ~/.zshrc)
export SONARQUBE_TOKEN="your_token_here"

# Verify token is set
echo $SONARQUBE_TOKEN
```

**To get token:**
1. Go to SonarCloud โ†’ My Account โ†’ Security
2. Generate new token
3. Copy and export as environment variable

### Project Configuration

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.

## Fetch Issues

**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 key
- `pullRequest`: PR number
- `issueStatuses`: OPEN,CONFIRMED (exclude resolved)
- `sinceLeakPeriod`: Only new issues in this PR
- `ps`: Page size (max 500)

## Analysis Script

Create Node.js analysis script at `/tmp/sonar_analyze.js`:

```javascript
const 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:**
```bash
node /tmp/sonar_analyze.js $PR_NUMBER > /tmp/sonar_analysis_$PR_NUMBER.json
```

## Report Format

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}
```

## Severity Mapping

| 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 |

## Issue Types

| Type | Symbol | Description |
|------|--------|-------------|
| BUG | ๐Ÿ› | Code that is demonstrably wrong |
| VULNERABILITY | ๐Ÿ›ก๏ธ | Security issues |
| CODE_SMELL | ๐Ÿงน | Maintainability issue |
| SECURITY_HOTSPOT | ๐Ÿ”’ | Security-sensitive code to review |

## Cleanup

Always clean up temporary files after execution:

```bash
rm -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 Handling

| 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 |

## Configuration Options

### Project-Level Configuration

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/**
```

### API Rate Limits

SonarCloud API limits:
- Free tier: 10,000 requests/day
- Paid tier: Unlimited

**Tip:** Cache results for repeated queries to same PR.

## Integration Examples

### GitHub Actions

```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 }}"
```

### Pre-merge Hook

Add to `.claude/hooks/pre-merge.sh`:

```bash
#!/bin/bash
PR_NUMBER=$(gh pr view --json number -q .number)
claude -p "/sonarqube $PR_NUMBER"
```

## Red Flags - NEVER Do

**Never:**
- โŒ Modify code or auto-fix issues (analysis-only command)
- โŒ Skip token verification (security risk)
- โŒ Leave temp files in `/tmp` (cleanup required)
- โŒ Commit SonarQube token to repository (use env vars)
- โŒ Run without checking token expiration

**Always:**
- โœ… Generate structured, actionable report
- โœ… Clean up after execution
- โœ… Handle API errors gracefully
- โœ… Verify token is valid before API calls
- โœ… Parse and present data clearly

## Advanced Usage

### Custom Filters

```bash
# Only show critical/blocker issues
/sonarqube 123 --severity BLOCKER,CRITICAL

# Only show bugs and vulnerabilities
/sonarqube 123 --types BUG,VULNERABILITY

# Sp

Related in General