Skip to content

feat(amazonq): enable client-side build #7226

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

Merged
merged 26 commits into from
Jun 24, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Feature",
"description": "/transform: run all builds client-side"
}
9 changes: 3 additions & 6 deletions packages/amazonq/test/e2e/amazonq/transformByQ.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,6 @@ describe('Amazon Q Code Transformation', function () {
waitIntervalInMs: 1000,
})

// TO-DO: add this back when releasing CSB
/*
const customDependencyVersionPrompt = tab.getChatItems().pop()
assert.strictEqual(
customDependencyVersionPrompt?.body?.includes('You can optionally upload a YAML file'),
Expand All @@ -139,19 +137,18 @@ describe('Amazon Q Code Transformation', function () {
tab.clickCustomFormButton({ id: 'gumbyTransformFormContinue' })

// 2 additional chat messages get sent after Continue button clicked; wait for both of them
await tab.waitForEvent(() => tab.getChatItems().length > 13, {
await tab.waitForEvent(() => tab.getChatItems().length > 10, {
waitTimeoutInMs: 5000,
waitIntervalInMs: 1000,
})
*/

const sourceJdkPathPrompt = tab.getChatItems().pop()
assert.strictEqual(sourceJdkPathPrompt?.body?.includes('Enter the path to JDK 8'), true)

tab.addChatMessage({ prompt: '/dummy/path/to/jdk8' })

// 2 additional chat messages get sent after JDK path submitted; wait for both of them
await tab.waitForEvent(() => tab.getChatItems().length > 10, {
await tab.waitForEvent(() => tab.getChatItems().length > 12, {
waitTimeoutInMs: 5000,
waitIntervalInMs: 1000,
})
Expand All @@ -173,7 +170,7 @@ describe('Amazon Q Code Transformation', function () {
text: 'View summary',
})

await tab.waitForEvent(() => tab.getChatItems().length > 11, {
await tab.waitForEvent(() => tab.getChatItems().length > 13, {
waitTimeoutInMs: 5000,
waitIntervalInMs: 1000,
})
Expand Down
Binary file not shown.
40 changes: 8 additions & 32 deletions packages/core/src/amazonqGumby/chat/controller/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,9 @@ import {
} from '../../errors'
import * as CodeWhispererConstants from '../../../codewhisperer/models/constants'
import MessengerUtils, { ButtonActions, GumbyCommands } from './messenger/messengerUtils'
import { CancelActionPositions, JDKToTelemetryValue, telemetryUndefined } from '../../telemetry/codeTransformTelemetry'
import { CancelActionPositions } from '../../telemetry/codeTransformTelemetry'
import { openUrl } from '../../../shared/utilities/vsCodeUtils'
import {
telemetry,
CodeTransformJavaTargetVersionsAllowed,
CodeTransformJavaSourceVersionsAllowed,
} from '../../../shared/telemetry/telemetry'
import { telemetry } from '../../../shared/telemetry/telemetry'
import { CodeTransformTelemetryState } from '../../telemetry/codeTransformTelemetryState'
import DependencyVersions from '../../models/dependencies'
import { getStringHash } from '../../../shared/utilities/textUtilities'
Expand Down Expand Up @@ -308,7 +304,6 @@ export class GumbyController {
}

private async validateLanguageUpgradeProjects(message: any) {
let telemetryJavaVersion = JDKToTelemetryValue(JDKVersion.UNSUPPORTED) as CodeTransformJavaSourceVersionsAllowed
try {
const validProjects = await telemetry.codeTransform_validateProject.run(async () => {
telemetry.record({
Expand All @@ -317,12 +312,6 @@ export class GumbyController {
})

const validProjects = await getValidLanguageUpgradeCandidateProjects()
if (validProjects.length > 0) {
// validProjects[0].JDKVersion will be undefined if javap errors out or no .class files found, so call it UNSUPPORTED
const javaVersion = validProjects[0].JDKVersion ?? JDKVersion.UNSUPPORTED
telemetryJavaVersion = JDKToTelemetryValue(javaVersion) as CodeTransformJavaSourceVersionsAllowed
}
telemetry.record({ codeTransformLocalJavaVersion: telemetryJavaVersion })
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of useless telemetry, so getting rid of some things and will remove them from the commons package shortly

return validProjects
})
return validProjects
Expand Down Expand Up @@ -384,7 +373,7 @@ export class GumbyController {
break
case ButtonActions.CONTINUE_TRANSFORMATION_FORM:
this.messenger.sendMessage(
CodeWhispererConstants.continueWithoutYamlMessage,
CodeWhispererConstants.continueWithoutConfigFileMessage,
message.tabID,
'ai-prompt'
)
Expand Down Expand Up @@ -437,9 +426,7 @@ export class GumbyController {
userChoice: skipTestsSelection,
})
this.messenger.sendSkipTestsSelectionMessage(skipTestsSelection, message.tabID)
this.promptJavaHome('source', message.tabID)
// TO-DO: delete line above and uncomment line below when releasing CSB
// await this.messenger.sendCustomDependencyVersionMessage(message.tabID)
await this.messenger.sendCustomDependencyVersionMessage(message.tabID)
})
}

Expand All @@ -465,16 +452,9 @@ export class GumbyController {
const fromJDKVersion: JDKVersion = message.formSelectedValues['GumbyTransformJdkFromForm']

telemetry.record({
// TODO: remove JavaSource/TargetVersionsAllowed when BI is updated to use source/target
codeTransformJavaSourceVersionsAllowed: JDKToTelemetryValue(
fromJDKVersion
) as CodeTransformJavaSourceVersionsAllowed,
codeTransformJavaTargetVersionsAllowed: JDKToTelemetryValue(
toJDKVersion
) as CodeTransformJavaTargetVersionsAllowed,
source: fromJDKVersion,
target: toJDKVersion,
codeTransformProjectId: pathToProject === undefined ? telemetryUndefined : getStringHash(pathToProject),
codeTransformProjectId: pathToProject === undefined ? undefined : getStringHash(pathToProject),
userChoice: 'Confirm-Java',
})

Expand Down Expand Up @@ -503,7 +483,7 @@ export class GumbyController {
const schema: string = message.formSelectedValues['GumbyTransformSQLSchemaForm']

telemetry.record({
codeTransformProjectId: pathToProject === undefined ? telemetryUndefined : getStringHash(pathToProject),
codeTransformProjectId: pathToProject === undefined ? undefined : getStringHash(pathToProject),
source: transformByQState.getSourceDB(),
target: transformByQState.getTargetDB(),
userChoice: 'Confirm-SQL',
Expand Down Expand Up @@ -563,7 +543,7 @@ export class GumbyController {
canSelectMany: false,
openLabel: 'Select',
filters: {
'YAML file': ['yaml'], // restrict user to only pick a .yaml file
File: ['yaml', 'yml'], // restrict user to only pick a .yaml file
},
})
if (!fileUri || fileUri.length === 0) {
Expand All @@ -576,7 +556,7 @@ export class GumbyController {
this.messenger.sendUnrecoverableErrorResponse('invalid-custom-versions-file', message.tabID)
return
}
this.messenger.sendMessage('Received custom dependency version YAML file.', message.tabID, 'ai-prompt')
this.messenger.sendMessage(CodeWhispererConstants.receivedValidConfigFileMessage, message.tabID, 'ai-prompt')
transformByQState.setCustomDependencyVersionFilePath(fileUri[0].fsPath)
this.promptJavaHome('source', message.tabID)
}
Expand Down Expand Up @@ -660,17 +640,13 @@ export class GumbyController {
const pathToJavaHome = extractPath(data.message)
if (pathToJavaHome) {
transformByQState.setSourceJavaHome(pathToJavaHome)
// TO-DO: delete line below and uncomment the block below when releasing CSB
await this.prepareLanguageUpgradeProject(data.tabID)
// if source and target JDK versions are the same, just re-use the source JAVA_HOME and start the build
/*
if (transformByQState.getTargetJDKVersion() === transformByQState.getSourceJDKVersion()) {
transformByQState.setTargetJavaHome(pathToJavaHome)
await this.prepareLanguageUpgradeProject(data.tabID)
} else {
this.promptJavaHome('target', data.tabID)
}
*/
} else {
this.messenger.sendUnrecoverableErrorResponse('invalid-java-home', data.tabID)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ export class Messenger {
message = CodeWhispererConstants.noPomXmlFoundChatMessage
break
case 'could-not-compile-project':
message = CodeWhispererConstants.cleanInstallErrorChatMessage
message = CodeWhispererConstants.cleanTestCompileErrorChatMessage
break
case 'invalid-java-home':
message = CodeWhispererConstants.noJavaHomeFoundChatMessage
Expand Down Expand Up @@ -704,7 +704,7 @@ ${codeSnippet}
}

public async sendCustomDependencyVersionMessage(tabID: string) {
const message = CodeWhispererConstants.chooseYamlMessage
const message = CodeWhispererConstants.chooseConfigFileMessage
const buttons: ChatItemButton[] = []

buttons.push({
Expand All @@ -731,7 +731,7 @@ ${codeSnippet}
tabID
)
)
const sampleYAML = `name: "custom-dependency-management"
const sampleYAML = `name: "dependency-upgrade"
description: "Custom dependency version management for Java migration from JDK 8/11/17 to JDK 17/21"

dependencyManagement:
Expand All @@ -744,7 +744,7 @@ dependencyManagement:
targetVersion: "3.0.0"
originType: "THIRD_PARTY"
plugins:
- identifier: "com.example.plugin"
- identifier: "com.example:plugin"
targetVersion: "1.2.0"
versionProperty: "plugin.version" # Optional`

Expand Down
6 changes: 0 additions & 6 deletions packages/core/src/amazonqGumby/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ export class NoMavenJavaProjectsFoundError extends ToolkitError {
}
}

export class ZipExceedsSizeLimitError extends ToolkitError {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We often allowlist certain customers for ZIP size limits greater than the default of 2GB, so remove this client-side check (which didn't seem to work well anyway) and let our service fail the transformation with a relevant error message if the ZIP is too large.

constructor() {
super('Zip file exceeds size limit', { code: 'ZipFileExceedsSizeLimit' })
}
}

export class AlternateDependencyVersionsNotFoundError extends Error {
constructor() {
super('No available versions for dependency update')
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/codewhisperer/client/codewhisperer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ export class DefaultCodeWhispererClient {
/**
* @description Use this function to get the status of the code transformation. We should
* be polling this function periodically to get updated results. When this function
* returns COMPLETED we know the transformation is done.
* returns PARTIALLY_COMPLETED or COMPLETED we know the transformation is done.
*/
public async codeModernizerGetCodeTransformation(
request: CodeWhispererUserClient.GetTransformationRequest
Expand All @@ -272,15 +272,15 @@ export class DefaultCodeWhispererClient {
}

/**
* @description After the job has been PAUSED we need to get user intervention. Once that user
* intervention has been handled we can resume the transformation job.
* @description During client-side build, or after the job has been PAUSED we need to get user intervention.
* Once that user action has been handled we can resume the transformation job.
* @params transformationJobId - String id returned from StartCodeTransformationResponse
* @params userActionStatus - String to determine what action the user took, if any.
*/
public async codeModernizerResumeTransformation(
request: CodeWhispererUserClient.ResumeTransformationRequest
): Promise<PromiseResult<CodeWhispererUserClient.ResumeTransformationResponse, AWSError>> {
return (await this.createUserSdkClient()).resumeTransformation(request).promise()
return (await this.createUserSdkClient(8)).resumeTransformation(request).promise()
}

/**
Expand Down
Loading
Loading