Skip to content

Commit bdbd8e8

Browse files
authored
telemetry(amazonq): code fix events #6420
## Problem Need to understand: - How many users are using fix feature from /review (not auto-review) - How many fixes were generated/applied for each scanJob - How many code fix requests were unable to generate a fix ## Solution - Add flag `autoDetected` to be able to filter out auto-review findings - Add flag `includesFix` to be able to see fix requests that generated no fixes - Add `codewhispererCodeScanJobId` to associate a fix action with a specific scan that produced the finding
1 parent 2ff5518 commit bdbd8e8

File tree

6 files changed

+77
-26
lines changed

6 files changed

+77
-26
lines changed

package-lock.json

Lines changed: 40 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"mergeReports": "ts-node ./scripts/mergeReports.ts"
4141
},
4242
"devDependencies": {
43-
"@aws-toolkits/telemetry": "^1.0.293",
43+
"@aws-toolkits/telemetry": "^1.0.295",
4444
"@playwright/browser-chromium": "^1.43.1",
4545
"@stylistic/eslint-plugin": "^2.11.0",
4646
"@types/he": "^1.2.3",

packages/amazonq/test/unit/codewhisperer/service/securityScanHandler.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,31 @@ describe('securityScanHandler', function () {
131131
assert.equal(aggregatedCodeScanIssueList.length, 2)
132132
assert.equal(aggregatedCodeScanIssueList[0].issues.length, 3)
133133
})
134+
135+
it('should set autoDetected based on scope', async function () {
136+
mockClient.listCodeScanFindings.resolves(
137+
buildMockListCodeScanFindingsResponse(JSON.stringify([buildRawCodeScanIssue()]))
138+
)
139+
for (const [scope, expectedValue] of [
140+
[CodeAnalysisScope.FILE_AUTO, true],
141+
[CodeAnalysisScope.FILE_ON_DEMAND, false],
142+
[CodeAnalysisScope.PROJECT, false],
143+
] as [CodeAnalysisScope, boolean][]) {
144+
const aggregatedCodeScanIssueList = await listScanResults(
145+
mockClient,
146+
'jobId',
147+
'codeScanFindingsSchema',
148+
['projectPath'],
149+
scope,
150+
undefined
151+
)
152+
assert.ok(
153+
aggregatedCodeScanIssueList.every((item) =>
154+
item.issues.every((issue) => issue.autoDetected === expectedValue)
155+
)
156+
)
157+
}
158+
})
134159
})
135160

136161
describe('mapToAggregatedList', () => {

packages/core/src/codewhisperer/commands/basicCommands.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,8 @@ export const applySecurityFix = Commands.declare(
447447
result: 'Succeeded',
448448
credentialStartUrl: AuthUtil.instance.startUrl,
449449
codeFixAction: 'applyFix',
450+
autoDetected: targetIssue.autoDetected,
451+
codewhispererCodeScanJobId: targetIssue.scanJobId,
450452
}
451453
let languageId = undefined
452454
try {
@@ -711,6 +713,7 @@ export const generateFix = Commands.declare(
711713
} else {
712714
hasSuggestedFix = suggestedFix !== undefined
713715
}
716+
telemetry.record({ includesFix: hasSuggestedFix })
714717
const updatedIssue: CodeScanIssue = {
715718
...targetIssue,
716719
fixJobId: jobId,
@@ -755,6 +758,8 @@ export const generateFix = Commands.declare(
755758
findingId: targetIssue.findingId,
756759
ruleId: targetIssue.ruleId,
757760
variant: refresh ? 'refresh' : undefined,
761+
autoDetected: targetIssue.autoDetected,
762+
codewhispererCodeScanJobId: targetIssue.scanJobId,
758763
})
759764
}
760765
})

packages/core/src/codewhisperer/models/model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@ export interface CodeScanIssue {
487487
scanJobId: string
488488
language: string
489489
fixJobId?: string
490+
autoDetected?: boolean
490491
}
491492

492493
export interface AggregatedCodeScanIssue {

packages/core/src/codewhisperer/service/securityScanHandler.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export async function listScanResults(
8383
if (existsSync(filePath) && statSync(filePath).isFile()) {
8484
const aggregatedCodeScanIssue: AggregatedCodeScanIssue = {
8585
filePath: filePath,
86-
issues: issues.map((issue) => mapRawToCodeScanIssue(issue, editor, jobId)),
86+
issues: issues.map((issue) => mapRawToCodeScanIssue(issue, editor, jobId, scope)),
8787
}
8888
aggregatedCodeScanIssueList.push(aggregatedCodeScanIssue)
8989
}
@@ -92,7 +92,7 @@ export async function listScanResults(
9292
if (existsSync(maybeAbsolutePath) && statSync(maybeAbsolutePath).isFile()) {
9393
const aggregatedCodeScanIssue: AggregatedCodeScanIssue = {
9494
filePath: maybeAbsolutePath,
95-
issues: issues.map((issue) => mapRawToCodeScanIssue(issue, editor, jobId)),
95+
issues: issues.map((issue) => mapRawToCodeScanIssue(issue, editor, jobId, scope)),
9696
}
9797
aggregatedCodeScanIssueList.push(aggregatedCodeScanIssue)
9898
}
@@ -103,7 +103,8 @@ export async function listScanResults(
103103
function mapRawToCodeScanIssue(
104104
issue: RawCodeScanIssue,
105105
editor: vscode.TextEditor | undefined,
106-
jobId: string
106+
jobId: string,
107+
scope: CodeWhispererConstants.CodeAnalysisScope
107108
): CodeScanIssue {
108109
const isIssueTitleIgnored = CodeWhispererSettings.instance.getIgnoredSecurityIssues().includes(issue.title)
109110
const isSingleIssueIgnored =
@@ -130,6 +131,7 @@ function mapRawToCodeScanIssue(
130131
visible: !isIssueTitleIgnored && !isSingleIssueIgnored,
131132
scanJobId: jobId,
132133
language,
134+
autoDetected: scope === CodeWhispererConstants.CodeAnalysisScope.FILE_AUTO,
133135
}
134136
}
135137

0 commit comments

Comments
 (0)