Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
518 changes: 402 additions & 116 deletions docs/regression-testing.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
// -------- Hotspot Transition Mapping --------

/** Map SQ resolution to SC-compatible resolution. SC only accepts SAFE or FIXED. */
function toScResolution(resolution) {
if (resolution === 'ACKNOWLEDGED') return 'SAFE';
if (resolution === 'FIXED') return 'FIXED';
if (resolution === 'SAFE') return 'SAFE';
return null;
}

/**
* Map a hotspot changelog diff entry to a SonarCloud action { status, resolution }.
*/
Expand All @@ -11,8 +19,8 @@ export function mapHotspotChangelogDiffToAction(diffs) {

if (!newStatus) return null;
if (newStatus === 'TO_REVIEW') return { status: 'TO_REVIEW', resolution: null };
if (newStatus === 'REVIEWED') return { status: 'REVIEWED', resolution: newResolution || 'SAFE' };
if (['SAFE', 'ACKNOWLEDGED', 'FIXED'].includes(newStatus)) return { status: 'REVIEWED', resolution: newStatus };
if (newStatus === 'REVIEWED') return { status: 'REVIEWED', resolution: toScResolution(newResolution) || 'SAFE' };
if (['SAFE', 'ACKNOWLEDGED', 'FIXED'].includes(newStatus)) return { status: 'REVIEWED', resolution: toScResolution(newStatus) };
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Map SonarQube hotspot status/resolution to SonarCloud resolution.
*/
export function mapHotspotResolution(sqHotspot) {
if (sqHotspot.resolution === 'ACKNOWLEDGED') return 'ACKNOWLEDGED';
if (sqHotspot.resolution === 'ACKNOWLEDGED') return 'SAFE';
if (sqHotspot.resolution === 'FIXED') return 'FIXED';
if (sqHotspot.resolution === 'SAFE' || sqHotspot.status === 'REVIEWED') return 'SAFE';
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { applyFallbackHotspotAction } from './apply-fallback-hotspot-action.js';
* Falls back to a single transition when no changelog is available.
*/
export async function syncHotspotStatus(scHotspot, sqHotspot, client) {
if (scHotspot.status === sqHotspot.status && (scHotspot.resolution || null) === (sqHotspot.resolution || null)) {
if (scHotspot.status === sqHotspot.status && (scHotspot.resolution ?? null) === (sqHotspot.resolution ?? null)) {
return false;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
// -------- Map Hotspot Resolution --------

/** Map SQ resolution to SC-compatible resolution. SC only accepts SAFE or FIXED. */
function toScResolution(resolution) {
if (resolution === 'ACKNOWLEDGED') return 'SAFE';
if (resolution === 'FIXED') return 'FIXED';
if (resolution === 'SAFE') return 'SAFE';
return null;
}

// -------- Main Logic --------

/**
Expand All @@ -15,12 +25,12 @@ export function mapHotspotChangelogDiffToAction(diffs) {
// Reviewed with explicit resolution
if (newStatus === 'REVIEWED') {
const newResolution = diffs.find(d => d.key === 'resolution')?.newValue;
return { status: 'REVIEWED', resolution: newResolution || 'SAFE' };
return { status: 'REVIEWED', resolution: toScResolution(newResolution) || 'SAFE' };
}

// In newer SQ versions, status can be SAFE/ACKNOWLEDGED/FIXED directly
if (['SAFE', 'ACKNOWLEDGED', 'FIXED'].includes(newStatus)) {
return { status: 'REVIEWED', resolution: newStatus };
return { status: 'REVIEWED', resolution: toScResolution(newStatus) };
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

// Map SonarQube hotspot status/resolution to SonarCloud resolution.
export function mapHotspotResolution(sqHotspot) {
if (sqHotspot.resolution === 'ACKNOWLEDGED') return 'ACKNOWLEDGED';
if (sqHotspot.resolution === 'ACKNOWLEDGED') return 'SAFE';
if (sqHotspot.resolution === 'FIXED') return 'FIXED';
if (sqHotspot.resolution === 'SAFE' || sqHotspot.status === 'REVIEWED') return 'SAFE';
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { applyFallbackAction } from './apply-fallback-action.js';
// Sync hotspot status by replaying the full changelog transition sequence.
export async function syncHotspotStatus(scHotspot, sqHotspot, client) {
// Skip if statuses and resolutions already match
if (scHotspot.status === sqHotspot.status && (scHotspot.resolution || null) === (sqHotspot.resolution || null)) {
if (scHotspot.status === sqHotspot.status && (scHotspot.resolution ?? null) === (sqHotspot.resolution ?? null)) {
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function getFallbackAction(scHotspot, sqHotspot) {
}

function mapHotspotResolution(sqHotspot) {
if (sqHotspot.resolution === 'ACKNOWLEDGED') return 'ACKNOWLEDGED';
if (sqHotspot.resolution === 'ACKNOWLEDGED') return 'SAFE';
if (sqHotspot.resolution === 'FIXED') return 'FIXED';
if (sqHotspot.resolution === 'SAFE' || sqHotspot.status === 'REVIEWED') return 'SAFE';
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
// -------- Map Hotspot Changelog Diff to Action --------

/** Map SQ resolution to SC-compatible resolution. SC only accepts SAFE or FIXED. */
function toScResolution(resolution) {
if (resolution === 'ACKNOWLEDGED') return 'SAFE';
if (resolution === 'FIXED') return 'FIXED';
if (resolution === 'SAFE') return 'SAFE';
return null;
}

/** Map a changelog diff entry to a SC action { status, resolution }. Returns null if none. */
export function mapHotspotChangelogDiffToAction(diffs) {
const statusDiff = diffs.find(d => d.key === 'status');
Expand All @@ -9,8 +17,8 @@ export function mapHotspotChangelogDiffToAction(diffs) {

if (!newStatus) return null;
if (newStatus === 'TO_REVIEW') return { status: 'TO_REVIEW', resolution: null };
if (newStatus === 'REVIEWED') return { status: 'REVIEWED', resolution: newResolution || 'SAFE' };
if (['SAFE', 'ACKNOWLEDGED', 'FIXED'].includes(newStatus)) return { status: 'REVIEWED', resolution: newStatus };
if (newStatus === 'REVIEWED') return { status: 'REVIEWED', resolution: toScResolution(newResolution) || 'SAFE' };
if (['SAFE', 'ACKNOWLEDGED', 'FIXED'].includes(newStatus)) return { status: 'REVIEWED', resolution: toScResolution(newStatus) };
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { applyFallbackAction } from './hotspot-fallback-action.js';

/** Sync hotspot status by replaying changelog or falling back to single transition. */
export async function syncHotspotStatus(scHotspot, sqHotspot, client) {
if (scHotspot.status === sqHotspot.status && (scHotspot.resolution || null) === (sqHotspot.resolution || null)) return false;
if (scHotspot.status === sqHotspot.status && (scHotspot.resolution ?? null) === (sqHotspot.resolution ?? null)) return false;

const changelog = sqHotspot.changelog;
if (changelog && changelog.length > 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
// -------- Map Hotspot Changelog Diff to SonarCloud Action --------

/** Map SQ resolution to SC-compatible resolution. SC only accepts SAFE or FIXED. */
function toScResolution(resolution) {
if (resolution === 'ACKNOWLEDGED') return 'SAFE';
if (resolution === 'FIXED') return 'FIXED';
if (resolution === 'SAFE') return 'SAFE';
return null;
}

export function mapHotspotChangelogDiffToAction(diffs) {
const statusDiff = diffs.find(d => d.key === 'status');
const resolutionDiff = diffs.find(d => d.key === 'resolution');
Expand All @@ -8,7 +16,7 @@ export function mapHotspotChangelogDiffToAction(diffs) {

if (!newStatus) return null;
if (newStatus === 'TO_REVIEW') return { status: 'TO_REVIEW', resolution: null };
if (newStatus === 'REVIEWED') return { status: 'REVIEWED', resolution: newResolution || 'SAFE' };
if (['SAFE', 'ACKNOWLEDGED', 'FIXED'].includes(newStatus)) return { status: 'REVIEWED', resolution: newStatus };
if (newStatus === 'REVIEWED') return { status: 'REVIEWED', resolution: toScResolution(newResolution) || 'SAFE' };
if (['SAFE', 'ACKNOWLEDGED', 'FIXED'].includes(newStatus)) return { status: 'REVIEWED', resolution: toScResolution(newStatus) };
return null;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// -------- Map SQ Hotspot Status/Resolution to SC Resolution --------

export function mapHotspotResolution(sqHotspot) {
if (sqHotspot.resolution === 'ACKNOWLEDGED') return 'ACKNOWLEDGED';
if (sqHotspot.resolution === 'ACKNOWLEDGED') return 'SAFE';
if (sqHotspot.resolution === 'FIXED') return 'FIXED';
if (sqHotspot.resolution === 'SAFE' || sqHotspot.status === 'REVIEWED') return 'SAFE';
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function getFallbackAction(scHotspot, sqHotspot) {
}

export async function syncHotspotStatus(scHotspot, sqHotspot, client) {
if (scHotspot.status === sqHotspot.status && (scHotspot.resolution || null) === (sqHotspot.resolution || null)) return false;
if (scHotspot.status === sqHotspot.status && (scHotspot.resolution ?? null) === (sqHotspot.resolution ?? null)) return false;

const changelog = sqHotspot.changelog;
if (changelog?.length > 0) {
Expand Down