@sun-asterisk/sunlint
Version:
☀️ SunLint - Multi-language static analysis tool for code quality and security | Sun* Engineering Standards
371 lines (291 loc) • 9.94 kB
Markdown
# API-Compatible Summary Report Format
## Overview
SunLint v1.4.0+ generates summary reports in a format that's **directly compatible** with dashboard APIs, eliminating the need for manual transformation in CI/CD pipelines.
## Output Format
When using `--output-summary=<file>`, SunLint generates a JSON file with the following structure:
```json
{
"repository_url": "https://github.com/sun-asterisk/engineer-excellence",
"repository_name": "engineer-excellence",
"project_path": "coding-quality/extensions/sunlint",
"branch": "main",
"commit_hash": "abc123def456",
"commit_message": "Merge pull request #123\n\nFix: Update quality scoring",
"author_email": "user@example.com",
"author_name": "John Doe",
"pr_number": 123,
"score": 92.6,
"total_violations": 39,
"error_count": 0,
"warning_count": 39,
"info_count": 0,
"lines_of_code": 4954,
"files_analyzed": 22,
"sunlint_version": "1.3.9",
"analysis_duration_ms": 1464,
"violations": [
{
"rule_code": "C065",
"count": 39,
"severity": "warning"
}
],
"metadata": {
"generated_at": "2025-10-09T06:59:57.680Z",
"tool": "SunLint",
"version": "1.3.9",
"analysis_duration_ms": 1464
},
"quality": {
"score": 92.6,
"grade": "A",
"metrics": {
"errors": 0,
"warnings": 39,
"rulesChecked": 1,
"linesOfCode": 4954,
"violationsPerKLOC": 7.9
}
}
}
```
## Field Descriptions
### Repository Information
| Field | Type | Description | Source |
|-------|------|-------------|--------|
| `repository_url` | string | Full HTTPS URL to repository | Git remote or `GITHUB_REPOSITORY` env var |
| `repository_name` | string | Repository name (without owner) | Extracted from URL or repo name |
| `project_path` | string\|null | Relative path from repo root (for mono-repo) | Calculated from git root |
| `branch` | string | Current branch name | Git or `GITHUB_REF_NAME` |
| `commit_hash` | string | Full commit SHA | Git or `GITHUB_SHA` |
| `commit_message` | string | Commit message (may include newlines) | Git log or GitHub event |
| `author_email` | string | Commit author email | Git log or GitHub event |
| `author_name` | string | Commit author name | Git log or GitHub event |
| `pr_number` | number\|null | Pull request number (if applicable) | Extracted from commit message or branch name |
### Quality Metrics
| Field | Type | Description |
|-------|------|-------------|
| `score` | number | Quality score (0-100) |
| `total_violations` | number | Total number of violations found |
| `error_count` | number | Number of error-level violations |
| `warning_count` | number | Number of warning-level violations |
| `info_count` | number | Number of info-level violations (reserved) |
| `lines_of_code` | number | Total lines of code analyzed |
| `files_analyzed` | number | Number of files analyzed |
| `sunlint_version` | string | Version of SunLint used |
| `analysis_duration_ms` | number | Time taken for analysis in milliseconds |
### Violations Array
Each violation object contains:
| Field | Type | Description |
|-------|------|-------------|
| `rule_code` | string | Rule identifier (e.g., "C065") |
| `count` | number | Number of times this rule was violated |
| `severity` | string | Severity level ("error" or "warning") |
## Auto-Detection Features
### 1. Mono-Repo Support
**Automatic `project_path` Detection:**
- If running from repo root → `project_path: null`
- If running from subdirectory → `project_path: "relative/path/from/root"`
**Example Mono-Repo Structure:**
```
my-monorepo/
├── project-a/
│ └── src/
├── project-b/
│ └── src/
└── shared/
```
Running from `my-monorepo/project-a/`:
```json
{
"project_path": "project-a",
"repository_name": "my-monorepo"
}
```
### 2. PR Number Extraction
SunLint automatically extracts PR numbers from:
**Commit Messages:**
- `"Merge pull request #123"` → `pr_number: 123`
- `"Fix #456: Update scoring"` → `pr_number: 456`
- `"Closes #789"` → `pr_number: 789`
**Branch Names:**
- `"pr-123"` → `pr_number: 123`
- `"pull/456"` → `pr_number: 456`
- `"PR-789-feature"` → `pr_number: 789`
### 3. Environment Variable Priority
CI/CD environment variables take precedence over git commands:
```javascript
// Priority order:
1. GITHUB_REPOSITORY → repository_url
2. GITHUB_REF_NAME → branch
3. GITHUB_SHA → commit_hash
4. GITHUB_EVENT_PATH (JSON) → commit details
5. Git commands → fallback for all fields
```
## Usage in CI/CD
### Before v1.4.0 (Manual Transformation Required)
```yaml
- name: Generate Report
run: sunlint --all --output-summary=report.json
- name: Transform for API
run: |
jq -n \
--arg repo_url "${{ github.repository }}" \
--arg commit "${{ github.sha }}" \
--argjson report "$(cat report.json)" \
'{
repository_url: $repo_url,
commit_hash: $commit,
score: $report.quality.score,
total_violations: $report.violations.total,
# ... manual mapping for 15+ fields
}' > api-payload.json
```
### v1.4.0+ (Direct Use - No Transformation!)
```yaml
- name: Generate Report
run: sunlint --all --output-summary=report.json
- name: Upload to Dashboard
run: |
curl -X POST https://dashboard.example.com/api/reports \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${{ secrets.API_TOKEN }}" \
-d @report.json
```
**That's it!** No `jq` transformation needed. 🎉
## GitHub Actions Integration
### Full Example
```yaml
name: Code Quality Check
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Full history for git info
- name: Run SunLint
run: |
npx @sun-asterisk/sunlint \
--input=src \
--all \
--output-summary=quality-report.json
# Environment variables are automatically available
# No need to set them manually!
- name: Upload to Dashboard
run: |
curl -X POST ${{ secrets.DASHBOARD_URL }}/api/reports \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${{ secrets.DASHBOARD_TOKEN }}" \
-d @quality-report.json
```
### Available GitHub Actions Environment Variables
These are **automatically** available and used by SunLint:
```yaml
# Automatically set by GitHub Actions:
GITHUB_REPOSITORY: "owner/repo"
GITHUB_REF_NAME: "main"
GITHUB_SHA: "abc123..."
GITHUB_EVENT_PATH: "/github/workflow/event.json"
# From event.json:
- head_commit.message
- head_commit.author.email
- head_commit.author.name
- pull_request.number (for PR events)
```
## Local Development
When running locally (not in CI/CD), SunLint uses git commands:
```bash
# Local run - auto-detects from git
sunlint --input=src --all --output-summary=local-report.json
# Result uses local git information:
{
"repository_url": "https://github.com/owner/repo", # from git remote
"branch": "feature/my-branch", # from git branch
"commit_hash": "def456...", # from git log
"commit_message": "WIP: My feature", # from git log
"author_email": "me@example.com", # from git config
"author_name": "My Name", # from git config
"pr_number": null # no PR locally
}
```
## Compatibility
### Dashboard API Requirements
The output format is compatible with APIs expecting:
✅ Flat structure (no nested objects for main fields)
✅ Repository metadata (URL, name, path, branch, commit)
✅ Commit details (message, author email, author name)
✅ PR tracking (PR number)
✅ Quality metrics (score, violations, LOC)
✅ Violations summary (grouped by rule)
### Backwards Compatibility
Additional nested objects are included for backwards compatibility:
```json
{
// API-compatible flat fields
"score": 92.6,
"total_violations": 39,
// Legacy nested structure (for backwards compatibility)
"metadata": { ... },
"quality": { ... }
}
```
## Troubleshooting
### Missing Git Information
**Problem**: Some fields are `null` in the output
**Solution**: Ensure you're running from a git repository with commits
```bash
# Check git status
git status
# Verify remote is configured
git remote -v
# Ensure commits exist
git log -1
```
### Incorrect project_path
**Problem**: `project_path` is not null when it should be
**Solution**: Run SunLint from the repository root:
```bash
cd /path/to/repo-root
sunlint --input=. --all --output-summary=report.json
```
### PR Number Not Detected
**Problem**: `pr_number` is `null` in PR builds
**Solution**:
1. For GitHub Actions PR events, use `pull_request` trigger
2. Ensure commit message includes PR reference (e.g., "#123")
3. Use PR branch naming convention (e.g., "pr-123" or "pull/123")
```yaml
on:
pull_request: # This sets pull_request.number in event.json
branches: [ main ]
```
## Migration Guide
### From Manual Transformation to Direct API Upload
**Before:**
```yaml
- run: sunlint --all --output-summary=sunlint-report.json
- run: |
# 30+ lines of jq transformation
jq -n --arg repo ... > api-payload.json
- run: curl -X POST ... -d @api-payload.json
```
**After:**
```yaml
- run: sunlint --all --output-summary=sunlint-report.json
- run: curl -X POST ... -d @sunlint-report.json
```
**Benefits:**
- ✅ **Simpler**: 3 lines instead of 30+
- ✅ **Faster**: No jq processing overhead
- ✅ **More reliable**: No transformation errors
- ✅ **Maintainable**: SunLint handles format updates
## See Also
- [Quality Scoring Guide](QUALITY_SCORING_GUIDE.md)
- [CI/CD Integration Guide](CI-CD-GUIDE.md)
- [Configuration Guide](CONFIGURATION.md)