-
Notifications
You must be signed in to change notification settings - Fork 275
fix(amazonq): show build logs when pre-build fails #5173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2b4f9b5
8bc7c93
7d78d13
7babde9
525ea67
c7bd28a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { | ||
| "type" : "bugfix", | ||
| "description" : "Amazon Q Code Transformation: show build logs when server-side build fails" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -431,6 +431,11 @@ fun buildTransformStoppedChatContent() = CodeTransformChatMessageContent( | |
| type = CodeTransformChatMessageType.FinalizedAnswer, | ||
| ) | ||
|
|
||
| fun buildTransformFailedChatContent(failureReason: String) = CodeTransformChatMessageContent( | ||
| message = message("codemodernizer.chat.message.transform_failed", failureReason), | ||
| type = CodeTransformChatMessageType.FinalizedAnswer, | ||
| ) | ||
|
|
||
| fun buildUserSQLConversionSelectionSummaryChatContent(moduleName: String, schema: String) = CodeTransformChatMessageContent( | ||
| type = CodeTransformChatMessageType.Prompt, | ||
| message = getUserSQLConversionSelectionFormattedMarkdown(moduleName, schema) | ||
|
|
@@ -537,7 +542,7 @@ fun buildTransformResumingChatContent() = CodeTransformChatMessageContent( | |
| type = CodeTransformChatMessageType.PendingAnswer, | ||
| ) | ||
|
|
||
| fun buildTransformResultChatContent(result: CodeModernizerJobCompletedResult, totalPatchFiles: Int): CodeTransformChatMessageContent { | ||
| fun buildTransformResultChatContent(result: CodeModernizerJobCompletedResult, totalPatchFiles: Int? = null): CodeTransformChatMessageContent { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the transformation fails, no patch files, so this can be optional as it's only used for full or partial successes. |
||
| val resultMessage = when (result) { | ||
| is CodeModernizerJobCompletedResult.JobAbortedZipTooLarge -> { | ||
| "${message( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -61,6 +61,7 @@ import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildSt | |
| import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildTransformAwaitUserInputChatContent | ||
| import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildTransformBeginChatContent | ||
| import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildTransformDependencyErrorChatContent | ||
| import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildTransformFailedChatContent | ||
| import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildTransformFindingLocalAlternativeDependencyChatContent | ||
| import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildTransformInProgressChatContent | ||
| import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildTransformResultChatContent | ||
|
|
@@ -183,7 +184,7 @@ class CodeTransformChatController( | |
| private suspend fun getUserObjective(tabId: String) { | ||
| codeTransformChatHelper.addNewMessage(buildChooseTransformationObjectiveChatContent()) | ||
| codeTransformChatHelper.sendChatInputEnabledMessage(tabId, true) | ||
| codeTransformChatHelper.sendUpdatePlaceholderMessage(tabId, message("codemodernizer.chat.message.choose_objective")) | ||
| codeTransformChatHelper.sendUpdatePlaceholderMessage(tabId, message("codemodernizer.chat.message.choose_objective_placeholder")) | ||
| } | ||
|
|
||
| private suspend fun validateAndReplyOnError(transformationType: CodeTransformType): ValidationResult? { | ||
|
|
@@ -665,9 +666,21 @@ class CodeTransformChatController( | |
| codeTransformChatHelper.addNewMessage(buildStartNewTransformFollowup()) | ||
| } | ||
|
|
||
| private suspend fun handleCodeTransformJobFailed(failureReason: String) { | ||
| codeTransformChatHelper.updateLastPendingMessage(buildTransformFailedChatContent(failureReason)) | ||
| codeTransformChatHelper.addNewMessage(buildStartNewTransformFollowup()) | ||
| } | ||
|
|
||
| private suspend fun handleCodeTransformJobFailedPreBuild(result: CodeModernizerJobCompletedResult.JobFailedInitialBuild) = | ||
| codeTransformChatHelper.addNewMessage( | ||
| buildTransformResultChatContent(result) | ||
| ) | ||
|
|
||
| private suspend fun handleCodeTransformResult(result: CodeModernizerJobCompletedResult) { | ||
| when (result) { | ||
| is CodeModernizerJobCompletedResult.Stopped, CodeModernizerJobCompletedResult.JobAbortedBeforeStarting -> handleCodeTransformStoppedByUser() | ||
| is CodeModernizerJobCompletedResult.JobFailed -> handleCodeTransformJobFailed(result.failureReason) | ||
| is CodeModernizerJobCompletedResult.JobFailedInitialBuild -> handleCodeTransformJobFailedPreBuild(result) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These make sure that 1) when the job fails, the last chat item is updated to say so and 2) when the server-side build fails, a new chat item is sent to say so + include a button to download the build logs (this button functionality was previously implemented in |
||
| else -> { | ||
| if (result is CodeModernizerJobCompletedResult.ZipUploadFailed && result.failureReason is UploadFailureReason.CREDENTIALS_EXPIRED) { | ||
| return | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,17 +5,15 @@ package software.aws.toolkits.jetbrains.services.codemodernizer.panels | |
|
|
||
| import com.intellij.icons.AllIcons | ||
| import com.intellij.openapi.project.Project | ||
| import com.intellij.serviceContainer.AlreadyDisposedException | ||
| import com.intellij.ui.JBColor | ||
| import com.intellij.ui.border.CustomLineBorder | ||
| import com.intellij.ui.components.ActionLink | ||
| import com.intellij.ui.components.JBLabel | ||
| import com.intellij.util.ui.JBInsets | ||
| import com.intellij.util.ui.JBUI | ||
| import icons.AwsIcons | ||
| import software.aws.toolkits.core.utils.getLogger | ||
| import software.aws.toolkits.core.utils.warn | ||
| import software.aws.toolkits.jetbrains.services.codemodernizer.CodeModernizerManager | ||
| import software.aws.toolkits.jetbrains.services.codemodernizer.model.JobId | ||
| import software.aws.toolkits.jetbrains.services.codewhisperer.layout.CodeWhispererLayoutConfig | ||
| import software.aws.toolkits.jetbrains.services.codewhisperer.layout.CodeWhispererLayoutConfig.addHorizontalGlue | ||
| import software.aws.toolkits.jetbrains.ui.feedback.CodeTransformFeedbackDialog | ||
|
|
@@ -42,11 +40,13 @@ class CodeModernizerBanner(val project: Project) : JPanel(BorderLayout()) { | |
| border = BorderFactory.createEmptyBorder(0, 5, 0, 0) | ||
| } | ||
|
|
||
| private val infoLabelJobId = JBLabel().apply { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry just for my own understanding, this is for the ux of displaying the job id in transformation hub right |
||
| foreground = JBColor.GRAY | ||
| border = BorderFactory.createEmptyBorder(0, 5, 0, 0) | ||
| } | ||
|
|
||
| private val infoPanel = JPanel(GridBagLayout()) | ||
|
|
||
| val showDiffAction = ActionLink(message("codemodernizer.toolwindow.banner.action.diff")) { | ||
| CodeModernizerManager.getInstance(project).showDiff() | ||
| } | ||
| val showPlanAction = ActionLink(message("codemodernizer.toolwindow.banner.action.plan")) { | ||
| CodeModernizerManager.getInstance(project).showTransformationPlan() | ||
| } | ||
|
|
@@ -84,6 +84,7 @@ class CodeModernizerBanner(val project: Project) : JPanel(BorderLayout()) { | |
| ) | ||
| } | ||
| add(infoLabelRunningTime, CodeWhispererLayoutConfig.kebabMenuConstraints) | ||
| add(infoLabelJobId, CodeWhispererLayoutConfig.kebabMenuConstraints) | ||
| } | ||
| infoPanel.revalidate() | ||
| infoPanel.repaint() | ||
|
|
@@ -114,28 +115,23 @@ class CodeModernizerBanner(val project: Project) : JPanel(BorderLayout()) { | |
| } | ||
|
|
||
| fun updateRunningTime(runTime: Duration?) { | ||
| try { | ||
| if (runTime == null) { | ||
| infoLabelRunningTime.text = "" | ||
| } else { | ||
| val timeTaken = runTime.toKotlinDuration().inWholeSeconds.seconds.toString() | ||
| infoLabelRunningTime.text = message( | ||
| "codemodernizer.toolwindow.transformation.progress.running_time", | ||
| timeTaken | ||
| ) | ||
| } | ||
| } catch (exception: AlreadyDisposedException) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We already catch this exception in the caller. |
||
| LOG.warn { "Disposed when about to create the loading panel" } | ||
| return | ||
| infoLabelRunningTime.text = if (runTime != null) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again here just curious, what running time is it referring to?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The "42s" in the image above |
||
| message("codemodernizer.toolwindow.transformation.progress.running_time", runTime.toKotlinDuration().inWholeSeconds.seconds.toString()) | ||
| } else { | ||
| "" | ||
| } | ||
| } | ||
|
|
||
| fun updateJobId(jobId: JobId?) { | ||
| infoLabelJobId.text = if (jobId != null) { | ||
| message("codemodernizer.toolwindow.transformation.progress.job_id", jobId.id) | ||
| } else { | ||
| "" | ||
| } | ||
| } | ||
|
|
||
| fun clearActions() { | ||
| currentlyShownOptions.clear() | ||
| buildContent() | ||
| } | ||
|
|
||
| companion object { | ||
| private val LOG = getLogger<CodeModernizerBanner>() | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -88,6 +88,16 @@ class CodeModernizerBottomWindowPanelManager(private val project: Project) : JPa | |
| } | ||
| } | ||
|
|
||
| private fun updateJobId() { | ||
| try { | ||
| val jobId = CodeModernizerSessionState.getInstance(project).currentJobId | ||
| banner.updateJobId(jobId) | ||
| } catch (e: AlreadyDisposedException) { | ||
| LOG.warn { "Disposed when about to update the jobId" } | ||
| return | ||
| } | ||
| } | ||
|
|
||
| fun setJobStartingUI() = setUI { | ||
| add(BorderLayout.CENTER, fullSizeLoadingPanel) | ||
| banner.clearActions() | ||
|
|
@@ -123,6 +133,7 @@ class CodeModernizerBottomWindowPanelManager(private val project: Project) : JPa | |
| fun setJobRunningUI() = setUI { | ||
| add(BorderLayout.CENTER, buildProgressSplitterPanelManager) | ||
| banner.updateContent(message("codemodernizer.toolwindow.banner.job_is_running"), AllIcons.General.BalloonInformation) | ||
| updateJobId() | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make job ID more visible in Transformation Hub by putting it at the top next to the job run time. |
||
| buildProgressSplitterPanelManager.apply { | ||
| reset() | ||
| statusTreePanel.setDefaultUI() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| // Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| package software.aws.toolkits.jetbrains.services.codemodernizer | ||
|
|
||
| import org.junit.Assert.assertEquals | ||
| import org.junit.Assert.assertNotNull | ||
| import org.junit.Assert.assertNull | ||
| import org.junit.Assert.fail | ||
| import org.junit.Test | ||
| import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildTransformResultChatContent | ||
| import software.aws.toolkits.jetbrains.services.codemodernizer.messages.CodeTransformButtonId | ||
| import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeModernizerJobCompletedResult | ||
| import software.aws.toolkits.jetbrains.services.codemodernizer.model.JobId | ||
| import software.aws.toolkits.resources.message | ||
|
|
||
| class CodeTransformChatTest { | ||
|
|
||
| @Test | ||
| fun `test that transform result chat item includes view build log button and message when pre-build fails`() { | ||
| val result = CodeModernizerJobCompletedResult.JobFailedInitialBuild(JobId("dummy-job-id-123"), "Build failed in Java 8 sandbox", true) | ||
| val chatItem = buildTransformResultChatContent(result) | ||
| assertEquals(chatItem.message, message("codemodernizer.chat.message.result.fail_initial_build")) | ||
| assertNotNull(chatItem.buttons) | ||
| assertEquals(chatItem.buttons?.size ?: fail("buttons is null"), 1) | ||
| assertEquals(chatItem.buttons?.get(0)?.id ?: fail("buttons is null"), CodeTransformButtonId.ViewBuildLog.id) | ||
| } | ||
|
|
||
| @Test | ||
| fun `test that transform result chat item includes view summary button and view diff button with correct label when job fully succeeded with 5 patch files`() { | ||
| val result = CodeModernizerJobCompletedResult.JobCompletedSuccessfully(JobId("dummy-job-id-123")) | ||
| val chatItem = buildTransformResultChatContent(result, 5) | ||
| assertEquals(chatItem.message, message("codemodernizer.chat.message.result.success.multiple_diffs")) | ||
| assertNotNull(chatItem.buttons) | ||
| assertEquals(chatItem.buttons?.size ?: fail("buttons is null"), 2) | ||
| assertEquals(chatItem.buttons?.get(0)?.id ?: fail("buttons is null"), CodeTransformButtonId.ViewDiff.id) | ||
| assertEquals(chatItem.buttons?.get(0)?.text ?: fail("buttons is null"), "View diff 1/5") | ||
| assertEquals(chatItem.buttons?.get(1)?.id ?: fail("buttons is null"), CodeTransformButtonId.ViewSummary.id) | ||
| } | ||
|
|
||
| @Test | ||
| fun `test that transform result chat item includes view summary button and view diff button with correct label when job partially succeeded with 1 patch file`() { | ||
| val result = CodeModernizerJobCompletedResult.JobPartiallySucceeded(JobId("dummy-job-id-123")) | ||
| val chatItem = buildTransformResultChatContent(result, 1) | ||
| assertEquals(chatItem.message, message("codemodernizer.chat.message.result.partially_success")) | ||
| assertNotNull(chatItem.buttons) | ||
| assertEquals(chatItem.buttons?.size ?: fail("buttons is null"), 2) | ||
| assertEquals(chatItem.buttons?.get(0)?.id ?: fail("buttons is null"), CodeTransformButtonId.ViewDiff.id) | ||
| assertEquals(chatItem.buttons?.get(0)?.text ?: fail("buttons is null"), "View diff") | ||
| assertEquals(chatItem.buttons?.get(1)?.id ?: fail("buttons is null"), CodeTransformButtonId.ViewSummary.id) | ||
| } | ||
|
|
||
| @Test | ||
| fun `test that transform result chat item does not include any buttons when job failed with known reason`() { | ||
| val result = CodeModernizerJobCompletedResult.JobFailed(JobId("dummy-job-id-123"), message("codemodernizer.file.invalid_pom_version")) | ||
| val chatItem = buildTransformResultChatContent(result) | ||
| assertEquals(chatItem.message, message("codemodernizer.chat.message.result.fail_with_known_reason", result.failureReason)) | ||
| assertNull(chatItem.buttons) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were not using
sessionContext.targetJavaVersion