Skip to content

Commit 366e44a

Browse files
authored
fix(amazonq): always show latest build logs aws#5316
Problem: When users download the pre-build error logs, then run another transformation without clicking the "Start a new transformation" button, if another pre-build error occurs, the **old** logs will show up. This could happen if they close the Q Chat tab and re-run a transformation, or if they close the IDE between job runs. If they do click the "Start a new transformation" button, everything works fine, but we need to handle these other situations. Solution: Use `makeTemporaryToolkitFolder()` which creates a new folder with a random name, so that the logs are downloaded there, meaning we don't have to deal with deleting the old logs that would otherwise be in the same folder as the new logs.
1 parent e4c21dc commit 366e44a

File tree

5 files changed

+26
-50
lines changed

5 files changed

+26
-50
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Bug Fix",
3+
"description": "Amazon Q Code Transformation: always show build logs from last job run"
4+
}

packages/core/src/amazonqGumby/chat/controller/controller.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import {
2424
openHilPomFile,
2525
postTransformationJob,
2626
processTransformFormInput,
27-
resetDebugArtifacts,
2827
startTransformByQ,
2928
stopTransformByQ,
3029
validateCanCompileProject,
@@ -286,7 +285,6 @@ export class GumbyController {
286285
break
287286
case ButtonActions.CONFIRM_START_TRANSFORMATION_FLOW:
288287
this.resetTransformationChatFlow()
289-
await resetDebugArtifacts()
290288
this.messenger.sendCommandMessage({ ...message, command: GumbyCommands.CLEAR_CHAT })
291289
await this.transformInitiated(message)
292290
break
@@ -473,6 +471,7 @@ export class GumbyController {
473471
undefined,
474472
GumbyNamedMessages.JOB_FAILED_IN_PRE_BUILD
475473
)
474+
await openBuildLogFile()
476475
this.messenger.sendViewBuildLog(message.tabID)
477476
}
478477
}

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

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ import DependencyVersions from '../../amazonqGumby/models/dependencies'
7171
import { dependencyNoAvailableVersions } from '../../amazonqGumby/models/constants'
7272
import { HumanInTheLoopManager } from '../service/transformByQ/humanInTheLoopManager'
7373
import { setContext } from '../../shared/vscode/setContext'
74+
import { makeTemporaryToolkitFolder } from '../../shared'
7475

7576
function getFeedbackCommentData() {
7677
const jobId = transformByQState.getJobId()
@@ -527,14 +528,26 @@ export async function pollTransformationStatusUntilPlanReady(jobId: string) {
527528
// Since we don't yet have a good way of knowing what the error was,
528529
// we try to fetch any build failure artifacts that may exist so that we can optionally
529530
// show them to the user if they exist.
530-
const tmpDir = path.join(os.tmpdir(), 'q-transformation-build-logs')
531-
await downloadAndExtractResultArchive(jobId, undefined, tmpDir, 'Logs')
532-
const pathToLog = path.join(tmpDir, 'buildCommandOutput.log')
533-
transformByQState.setPreBuildLogFilePath(pathToLog)
531+
let pathToLog = ''
532+
try {
533+
const tempToolkitFolder = await makeTemporaryToolkitFolder()
534+
const tempBuildLogsDir = path.join(tempToolkitFolder, 'q-transformation-build-logs')
535+
await downloadAndExtractResultArchive(jobId, undefined, tempBuildLogsDir, 'Logs')
536+
pathToLog = path.join(tempBuildLogsDir, 'buildCommandOutput.log')
537+
transformByQState.setPreBuildLogFilePath(pathToLog)
538+
} catch (e) {
539+
transformByQState.setPreBuildLogFilePath('')
540+
getLogger().error(
541+
'CodeTransformation: failed to download any possible build error logs: ' + (e as Error).message
542+
)
543+
throw e
544+
}
534545

535-
if (fs.existsSync(pathToLog)) {
546+
if (fs.existsSync(pathToLog) && !transformByQState.isCancelled()) {
536547
throw new TransformationPreBuildError()
537548
} else {
549+
// not strictly needed to reset path here and above; doing it just to represent unavailable logs
550+
transformByQState.setPreBuildLogFilePath('')
538551
throw new PollJobError()
539552
}
540553
}
@@ -735,14 +748,6 @@ export async function cleanupTransformationJob() {
735748
CodeTransformTelemetryState.instance.resetCodeTransformMetaDataField()
736749
}
737750

738-
export async function resetDebugArtifacts() {
739-
const buildLogPath = transformByQState.getPreBuildLogFilePath()
740-
if (buildLogPath && fs.existsSync(buildLogPath)) {
741-
fs.rmSync(path.dirname(transformByQState.getPreBuildLogFilePath()), { recursive: true, force: true })
742-
}
743-
transformByQState.setPreBuildLogFilePath('')
744-
}
745-
746751
export async function stopTransformByQ(
747752
jobId: string,
748753
cancelSrc: CancelActionPositions = CancelActionPositions.BottomHubPanel

packages/core/src/codewhisperer/service/transformByQ/transformApiHandler.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -881,17 +881,16 @@ export async function downloadAndExtractResultArchive(
881881

882882
const pathToArchive = path.join(pathToArchiveDir, 'ExportResultsArchive.zip')
883883

884-
await downloadResultArchive(jobId, downloadArtifactId, pathToArchive, downloadArtifactType)
885-
886884
let downloadErrorMessage = undefined
887885
try {
888886
// Download and deserialize the zip
887+
await downloadResultArchive(jobId, downloadArtifactId, pathToArchive, downloadArtifactType)
889888
const zip = new AdmZip(pathToArchive)
890889
zip.extractAllTo(pathToArchiveDir)
891890
} catch (e) {
892891
downloadErrorMessage = (e as Error).message
893892
getLogger().error(`CodeTransformation: ExportResultArchive error = ${downloadErrorMessage}`)
894-
throw new Error('Error downloading transformation result artifacts')
893+
throw new Error('Error downloading transformation result artifacts: ' + downloadErrorMessage)
895894
}
896895
}
897896

packages/core/src/test/codewhisperer/commands/transformByQ.test.ts

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import * as fs from 'fs-extra'
99
import * as sinon from 'sinon'
1010
import { makeTemporaryToolkitFolder } from '../../../shared/filesystemUtilities'
1111
import { transformByQState, TransformByQStoppedError } from '../../../codewhisperer/models/model'
12-
import { resetDebugArtifacts, stopTransformByQ } from '../../../codewhisperer/commands/startTransformByQ'
12+
import { stopTransformByQ } from '../../../codewhisperer/commands/startTransformByQ'
1313
import { HttpResponse } from 'aws-sdk'
1414
import * as codeWhisperer from '../../../codewhisperer/client/codewhisperer'
1515
import * as CodeWhispererConstants from '../../../codewhisperer/models/constants'
@@ -297,34 +297,3 @@ describe('transformByQ', function () {
297297
assert.deepStrictEqual(actual, expected)
298298
})
299299
})
300-
301-
describe('resetDebugArtifacts', () => {
302-
it('should remove the directory containing the pre-build log file if it exists', async () => {
303-
const dirPath = await createTestWorkspaceFolder()
304-
const preBuildLogFilePath = path.join(dirPath.uri.fsPath, 'DummyLog.log')
305-
await toFile('', preBuildLogFilePath)
306-
transformByQState.setPreBuildLogFilePath(preBuildLogFilePath)
307-
308-
await resetDebugArtifacts()
309-
310-
assert.strictEqual(fs.existsSync(preBuildLogFilePath), false)
311-
assert.strictEqual(transformByQState.getPreBuildLogFilePath(), '')
312-
})
313-
314-
it('should not remove any directory if the pre-build log file path is not set', async () => {
315-
transformByQState.setPreBuildLogFilePath('')
316-
317-
await resetDebugArtifacts()
318-
319-
assert.strictEqual(transformByQState.getPreBuildLogFilePath(), '')
320-
})
321-
322-
it('should not remove any directory if the pre-build log file does not exist', async () => {
323-
const preBuildLogFilePath = 'non/existent/path/to/pre-build.log'
324-
transformByQState.setPreBuildLogFilePath(preBuildLogFilePath)
325-
326-
await resetDebugArtifacts()
327-
328-
assert.strictEqual(transformByQState.getPreBuildLogFilePath(), '')
329-
})
330-
})

0 commit comments

Comments
 (0)