diff --git a/.changes/next-release/feature-be7581c5-2c7a-4a80-b68d-4e0a8ff1a0b9.json b/.changes/next-release/feature-be7581c5-2c7a-4a80-b68d-4e0a8ff1a0b9.json new file mode 100644 index 00000000000..a1b8f86b2b0 --- /dev/null +++ b/.changes/next-release/feature-be7581c5-2c7a-4a80-b68d-4e0a8ff1a0b9.json @@ -0,0 +1,4 @@ +{ + "type" : "feature", + "description" : "/transform: ask user for permission to rerun job and view logs at end of partially successful transformation" +} \ No newline at end of file diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeTransformChatApp.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeTransformChatApp.kt index 1c32f2f07c5..ae8f33c3202 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeTransformChatApp.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeTransformChatApp.kt @@ -43,6 +43,7 @@ private enum class CodeTransformMessageTypes(val type: String) { CodeTransformCancel("codetransform-cancel"), CodeTransformConfirmSkipTests("codetransform-confirm-skip-tests"), CodeTransformConfirmOneOrMultipleDiffs("codetransform-confirm-one-or-multiple-diffs"), + CodeTransformConfirmPermissionsSelection("codetransform-confirm-permissions"), CodeTransformNew("codetransform-new"), CodeTransformOpenTransformHub("codetransform-open-transform-hub"), CodeTransformOpenMvnBuild("codetransform-open-mvn-build"), @@ -77,6 +78,7 @@ class CodeTransformChatApp : AmazonQApp { CodeTransformMessageTypes.ChatPrompt.type to IncomingCodeTransformMessage.ChatPrompt::class, CodeTransformMessageTypes.CodeTransformConfirmSkipTests.type to IncomingCodeTransformMessage.CodeTransformConfirmSkipTests::class, CodeTransformMessageTypes.CodeTransformConfirmOneOrMultipleDiffs.type to IncomingCodeTransformMessage.CodeTransformConfirmOneOrMultipleDiffs::class, + CodeTransformMessageTypes.CodeTransformConfirmPermissionsSelection.type to IncomingCodeTransformMessage.CodeTransformConfirmPermissions::class, CodeTransformMessageTypes.CodeTransformNew.type to IncomingCodeTransformMessage.CodeTransformNew::class, CodeTransformMessageTypes.CodeTransformOpenTransformHub.type to IncomingCodeTransformMessage.CodeTransformOpenTransformHub::class, CodeTransformMessageTypes.CodeTransformOpenMvnBuild.type to IncomingCodeTransformMessage.CodeTransformOpenMvnBuild::class, @@ -176,6 +178,7 @@ class CodeTransformChatApp : AmazonQApp { is IncomingCodeTransformMessage.ChatPrompt -> inboundAppMessagesHandler.processChatPromptMessage(message) is IncomingCodeTransformMessage.CodeTransformConfirmSkipTests -> inboundAppMessagesHandler.processCodeTransformConfirmSkipTests(message) is IncomingCodeTransformMessage.CodeTransformConfirmOneOrMultipleDiffs -> inboundAppMessagesHandler.processCodeTransformOneOrMultipleDiffs(message) + is IncomingCodeTransformMessage.CodeTransformConfirmPermissions -> inboundAppMessagesHandler.processCodeTransformConfirmPermissions(message) is IncomingCodeTransformMessage.CodeTransformNew -> inboundAppMessagesHandler.processCodeTransformNewAction(message) is IncomingCodeTransformMessage.CodeTransformOpenTransformHub -> inboundAppMessagesHandler.processCodeTransformOpenTransformHub(message) is IncomingCodeTransformMessage.CodeTransformOpenMvnBuild -> inboundAppMessagesHandler.processCodeTransformOpenMvnBuild(message) diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/InboundAppMessagesHandler.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/InboundAppMessagesHandler.kt index 1312328243e..53f48eccae7 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/InboundAppMessagesHandler.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/InboundAppMessagesHandler.kt @@ -25,6 +25,8 @@ interface InboundAppMessagesHandler { suspend fun processCodeTransformOneOrMultipleDiffs(message: IncomingCodeTransformMessage.CodeTransformConfirmOneOrMultipleDiffs) + suspend fun processCodeTransformConfirmPermissions(message: IncomingCodeTransformMessage.CodeTransformConfirmPermissions) + suspend fun processCodeTransformOpenTransformHub(message: IncomingCodeTransformMessage.CodeTransformOpenTransformHub) suspend fun processCodeTransformOpenMvnBuild(message: IncomingCodeTransformMessage.CodeTransformOpenMvnBuild) diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/constants/CodeTransformChatItems.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/constants/CodeTransformChatItems.kt index 4584ca1e985..fdeed3a0b59 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/constants/CodeTransformChatItems.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/constants/CodeTransformChatItems.kt @@ -79,6 +79,13 @@ private val confirmOneOrMultipleDiffsSelectionButton = Button( id = CodeTransformButtonId.ConfirmOneOrMultipleDiffs.id, ) +private val confirmUserSelectionPermissionsButton = Button( + keepCardAfterClick = false, + waitMandatoryFormItems = true, + text = message("codemodernizer.chat.message.button.confirm"), + id = CodeTransformButtonId.ConfirmPermissions.id, +) + private val openMvnBuildButton = Button( id = CodeTransformButtonId.OpenMvnBuild.id, text = message("codemodernizer.chat.message.button.view_build"), @@ -204,14 +211,14 @@ private val selectSkipTestsFlagFormItem = FormItem( title = message("codemodernizer.chat.form.user_selection.item.choose_skip_tests_option"), mandatory = true, options = listOf( - FormItemOption( - label = message("codemodernizer.chat.message.skip_tests_form.skip"), - value = message("codemodernizer.chat.message.skip_tests_form.skip"), - ), FormItemOption( label = message("codemodernizer.chat.message.skip_tests_form.run_tests"), value = message("codemodernizer.chat.message.skip_tests_form.run_tests"), ), + FormItemOption( + label = message("codemodernizer.chat.message.skip_tests_form.skip"), + value = message("codemodernizer.chat.message.skip_tests_form.skip"), + ) ) ) @@ -231,6 +238,50 @@ private val selectOneOrMultipleDiffsFlagFormItem = FormItem( ) ) +private val selectCanRerunJobFormItem = FormItem( + id = CodeTransformFormItemId.SelectCanRerunJob.id, + title = "To improve our service, do we have permission to re-run your job? You will *not* be charged.", + type = "radiogroup", + mandatory = true, + options = listOf( + FormItemOption( + label = "Yes", + value = "Yes", + ), + FormItemOption( + label = "No", + value = "No", + ) + ) +) + +private val selectCanViewLogsFormItem = FormItem( + id = CodeTransformFormItemId.SelectCanViewLogs.id, + title = "Do we also have permission to view the logs?", + type = "radiogroup", + mandatory = true, + options = listOf( + FormItemOption( + label = "Yes", + value = "Yes", + ), + FormItemOption( + label = "No", + value = "No", + ) + ) +) + +private fun getUserPermissionsSelectionMarkdown(canRerunJob: String, canViewLogs: String) = """ + ### Response received + ------------- + + | | | + | :------------------- | -------: | + | **Can re-run job** | $canRerunJob | + | **Can view logs** | $canViewLogs | +""".trimIndent() + private fun getUserLanguageUpgradeSelectionFormattedMarkdown(moduleName: String, targetJdkVersion: String): String = """ ### ${message("codemodernizer.chat.prompt.title.details")} ------------- @@ -323,11 +374,13 @@ fun buildUserInputSkipTestsFlagChatContent(): CodeTransformChatMessageContent = formItems = listOf(selectSkipTestsFlagFormItem), type = CodeTransformChatMessageType.FinalizedAnswer, ) + fun buildUserInputOneOrMultipleDiffsChatIntroContent(version: String): CodeTransformChatMessageContent = CodeTransformChatMessageContent( message = message("codemodernizer.chat.message.one_or_multiple_diffs", version.substring(4)), // extract "17" / "21" from "JDK_17" / "JDK_21" type = CodeTransformChatMessageType.FinalizedAnswer, ) + fun buildUserInputOneOrMultipleDiffsFlagChatContent(): CodeTransformChatMessageContent = CodeTransformChatMessageContent( message = message("codemodernizer.chat.form.user_selection.title"), @@ -339,6 +392,20 @@ fun buildUserInputOneOrMultipleDiffsFlagChatContent(): CodeTransformChatMessageC type = CodeTransformChatMessageType.FinalizedAnswer, ) +fun buildUserInputPermissionsFeedbackChatContent(): CodeTransformChatMessageContent = + CodeTransformChatMessageContent( + message = message("codemodernizer.chat.form.user_permissions.title"), + buttons = listOf( + confirmUserSelectionPermissionsButton, + cancelUserSelectionButton, + ), + formItems = listOf( + selectCanRerunJobFormItem, + selectCanViewLogsFormItem, + ), + type = CodeTransformChatMessageType.FinalizedAnswer, + ) + fun buildUserSkipTestsFlagSelectionChatContent(skipTestsSelection: String) = CodeTransformChatMessageContent( type = CodeTransformChatMessageType.FinalizedAnswer, message = message("codemodernizer.chat.message.skip_tests_form.response", skipTestsSelection.lowercase()) @@ -451,6 +518,11 @@ fun buildUserLanguageUpgradeSelectionSummaryChatContent(moduleName: String, targ message = getUserLanguageUpgradeSelectionFormattedMarkdown(moduleName, targetJdkVersion) ) +fun buildUserPermissionsSelectionChatContent(canRerunJob: String, canViewLogs: String) = CodeTransformChatMessageContent( + type = CodeTransformChatMessageType.Prompt, + message = getUserPermissionsSelectionMarkdown(canRerunJob, canViewLogs), +) + fun buildCompileLocalInProgressChatContent() = CodeTransformChatMessageContent( type = CodeTransformChatMessageType.PendingAnswer, message = message("codemodernizer.chat.message.local_build_begin"), diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/controller/CodeTransformChatController.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/controller/CodeTransformChatController.kt index b292aaf6aaa..267c0f993d3 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/controller/CodeTransformChatController.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/controller/CodeTransformChatController.kt @@ -15,6 +15,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import software.amazon.awssdk.services.codewhispererstreaming.model.TransformationDownloadArtifactType +import software.amazon.awssdk.services.toolkittelemetry.model.Sentiment import software.aws.toolkits.core.utils.debug import software.aws.toolkits.core.utils.error import software.aws.toolkits.core.utils.getLogger @@ -74,11 +75,13 @@ import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildUs import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildUserInputLanguageUpgradeChatContent import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildUserInputOneOrMultipleDiffsChatIntroContent import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildUserInputOneOrMultipleDiffsFlagChatContent +import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildUserInputPermissionsFeedbackChatContent import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildUserInputSQLConversionMetadataChatContent import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildUserInputSkipTestsFlagChatContent import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildUserInputSkipTestsFlagChatIntroContent import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildUserLanguageUpgradeSelectionSummaryChatContent import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildUserOneOrMultipleDiffsSelectionChatContent +import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildUserPermissionsSelectionChatContent import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildUserSQLConversionSelectionSummaryChatContent import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildUserSkipTestsFlagSelectionChatContent import software.aws.toolkits.jetbrains.services.codemodernizer.constants.buildUserStopTransformChatContent @@ -115,6 +118,7 @@ import software.aws.toolkits.jetbrains.services.codemodernizer.utils.validateSct import software.aws.toolkits.jetbrains.services.codewhisperer.telemetry.QFeatureEvent import software.aws.toolkits.jetbrains.services.codewhisperer.telemetry.broadcastQEvent import software.aws.toolkits.jetbrains.services.cwc.messages.ChatMessageType +import software.aws.toolkits.jetbrains.services.telemetry.TelemetryService import software.aws.toolkits.resources.message import software.aws.toolkits.telemetry.CodeTransformPreValidationError @@ -429,6 +433,20 @@ class CodeTransformChatController( } } + override suspend fun processCodeTransformConfirmPermissions(message: IncomingCodeTransformMessage.CodeTransformConfirmPermissions) { + val canRerunJob = message.canRerunJob + val canViewLogs = message.canViewLogs + codeTransformChatHelper.addNewMessage(buildUserPermissionsSelectionChatContent(canRerunJob, canViewLogs)) + if (canRerunJob == "Yes" || canViewLogs == "Yes") { + val sessionState = CodeModernizerSessionState.getInstance(context.project) + val jobId: String = sessionState.currentJobId?.id ?: "None" + TelemetryService.getInstance().sendFeedback( + Sentiment.POSITIVE, + "Permission to re-run job: $canRerunJob\nPermission to view logs: $canViewLogs\njobId: $jobId", + ) + } + } + private fun getSourceJdk(moduleConfigurationFile: VirtualFile): JavaSdkVersion { // this should never throw the RuntimeException since invalid JDK case is already handled in previous validation step val moduleJdkVersion = ModuleUtil.findModuleForFile(moduleConfigurationFile, context.project)?.tryGetJdk(context.project) @@ -719,7 +737,10 @@ class CodeTransformChatController( when (downloadResult) { is DownloadArtifactResult.Success -> { if (downloadResult.artifact !is CodeModernizerArtifact) return artifactHandler.notifyUnableToApplyPatch("") - codeTransformChatHelper.updateLastPendingMessage( + if (result is CodeModernizerJobCompletedResult.JobPartiallySucceeded) { + codeTransformChatHelper.addNewMessage(buildUserInputPermissionsFeedbackChatContent()) + } + codeTransformChatHelper.addNewMessage( buildTransformResultChatContent(result, downloadResult.artifact.patches.size) ) } diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/messages/CodeTransformMessage.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/messages/CodeTransformMessage.kt index 9a32e82aff5..56b35b6d778 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/messages/CodeTransformMessage.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/messages/CodeTransformMessage.kt @@ -22,6 +22,7 @@ enum class CodeTransformButtonId(val id: String) { CancelTransformation("codetransform-input-cancel"), ConfirmSkipTests("codetransform-input-confirm-skip-tests"), ConfirmOneOrMultipleDiffs("codetransform-input-confirm-one-or-multiple-diffs"), + ConfirmPermissions("codetransform-input-confirm-permissions"), StopTransformation("stop_transform"), OpenTransformationHub("open_transformation_hub"), OpenMvnBuild("open_mvn_build"), @@ -39,6 +40,8 @@ enum class CodeTransformFormItemId(val id: String) { SelectTargetVersion("targetVersion"), SelectSkipTestsFlag("skipTestsSelection"), SelectOneOrMultipleDiffsFlag("oneOrMultipleDiffsSelection"), + SelectCanRerunJob("rerunJobSelection"), + SelectCanViewLogs("viewLogsSelection"), DependencyVersion("dependencyVersion"), } @@ -113,6 +116,12 @@ sealed interface IncomingCodeTransformMessage : CodeTransformBaseMessage { val oneOrMultipleDiffsSelection: String, ) : IncomingCodeTransformMessage + data class CodeTransformConfirmPermissions( + @JsonProperty("tabID") val tabId: String, + val canRerunJob: String, + val canViewLogs: String, + ) : IncomingCodeTransformMessage + data class CodeTransformOpenMvnBuild( @JsonProperty("tabID") val tabId: String, ) : IncomingCodeTransformMessage diff --git a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/apps/codeTransformChatConnector.ts b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/apps/codeTransformChatConnector.ts index 86ac9a3fe6f..1b03cb7bc34 100644 --- a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/apps/codeTransformChatConnector.ts +++ b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/apps/codeTransformChatConnector.ts @@ -294,6 +294,14 @@ export class CodeTransformChatConnector { tabType: 'codetransform', oneOrMultipleDiffsSelection: action.formItemValues?.oneOrMultipleDiffsSelection }) + } else if (action.id === FormButtonIds.CodeTransformInputPermissions) { + this.sendMessageToExtension({ + command: 'codetransform-confirm-permissions', + tabID, + tabType: 'codetransform', + canRerunJob: action.formItemValues?.rerunJobSelection, + canViewLogs: action.formItemValues?.viewLogsSelection, + }) } else if (action.id === FormButtonIds.OpenTransformationHub) { this.sendMessageToExtension({ command: 'codetransform-open-transform-hub', diff --git a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/commands.ts b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/commands.ts index 5df19981b3f..27ef735c98c 100644 --- a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/commands.ts +++ b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/commands.ts @@ -38,6 +38,7 @@ type MessageCommand = | 'codetransform-stop' | 'codetransform-confirm-skip-tests' | 'codetransform-confirm-one-or-multiple-diffs' + | 'codetransform-confirm-permissions' | 'codetransform-new' | 'codetransform-open-transform-hub' | 'codetransform-open-mvn-build' diff --git a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/forms/constants.ts b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/forms/constants.ts index e400e2a5541..7bb1cad90eb 100644 --- a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/forms/constants.ts +++ b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/forms/constants.ts @@ -10,6 +10,7 @@ export const enum FormButtonIds { CodeTransformInputCancel = 'codetransform-input-cancel', CodeTransformInputSkipTests = 'codetransform-input-confirm-skip-tests', CodeTransformInputOneOrMultipleDiffs = 'codetransform-input-confirm-one-or-multiple-diffs', + CodeTransformInputPermissions = 'codetransform-input-confirm-permissions', OpenMvnBuild = 'open_mvn_build', StopTransform = 'stop_transform', OpenTransformationHub = 'open_transformation_hub', diff --git a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index 2ce5422fc3e..72b5498eafc 100644 --- a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -614,6 +614,7 @@ code.aws.value_prop_text=Amazon CodeCatalyst: Launch developer environments in t code.aws.workspaces=Amazon CodeCatalyst code.aws.workspaces.short=Dev Environments codemodernizer.builderrordialog.description.title=Error occurred when building your project +codemodernizer.chat.form.user_permissions.title=Amazon Q Permissions Form codemodernizer.chat.form.user_selection.item.choose_module=Choose a module to transform codemodernizer.chat.form.user_selection.item.choose_one_or_multiple_diffs_option=Choose how to receive proposed changes codemodernizer.chat.form.user_selection.item.choose_skip_tests_option=Choose to skip unit tests @@ -686,7 +687,7 @@ codemodernizer.chat.message.skip_tests_form.skip=Skip unit tests codemodernizer.chat.message.sql_metadata_success=I found the following source database, target database, and host based on the schema conversion metadata you provided: codemodernizer.chat.message.sql_module_schema_prompt=To continue, choose the module and schema for this transformation. codemodernizer.chat.message.transform_begin=I'm starting to transform your code. It can take 10 to 30 minutes to upgrade your code, depending on the size of your module. To monitor progress, go to the Transformation Hub. -codemodernizer.chat.message.transform_cancelled_by_user=I cancelled your transformation. If you want to start another transformation, choose **Start a new transformation**. +codemodernizer.chat.message.transform_cancelled_by_user=If you want to start another transformation, choose **Start a new transformation**. codemodernizer.chat.message.transform_failed=I could not complete the transformation. {0} codemodernizer.chat.message.transform_in_progress=If I run into any issues, I might pause the transformation to get input from you on how to proceed. codemodernizer.chat.message.transform_stopped_by_user=I stopped your transformation. If you want to start another transformation, choose **Start a new transformation**. @@ -788,7 +789,7 @@ codemodernizer.notification.warn.maven_failed.title=Amazon Q Code Transform unab codemodernizer.notification.warn.on_resume.unknown_status_response.content=We received data from Amazon Q in a format that the plugin cannot handle. You may need to update the plugin and then try again. codemodernizer.notification.warn.on_resume.unknown_status_response.title=Unable to resume job codemodernizer.notification.warn.submit_feedback=Submit feedback -codemodernizer.notification.warn.unable_to_start_job=Amazon Q could not begin the transformation. Try starting the transformation again. {0} +codemodernizer.notification.warn.unable_to_start_job=Amazon Q could not begin the transformation. Try starting the transformation again. {0}. For more information, see the [Amazon Q documentation](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/transform-java.html#quotas-java-transformation-ide). codemodernizer.notification.warn.unknown_start_failure=Amazon Q could not begin the transformation. Try starting the transformation again. codemodernizer.notification.warn.unknown_status_response=Amazon Q could not complete the transformation. Try starting the transformation again. codemodernizer.notification.warn.upload_failed=Amazon Q could not upload your module. Try starting the transformation again. {0}