-
Notifications
You must be signed in to change notification settings - Fork 605
feat(amazonq): enable client-side build / run JAR #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
base: master
Are you sure you want to change the base?
Changes from all commits
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": "Feature", | ||
"description": "/transform: run all builds client-side" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,12 +30,6 @@ export class NoMavenJavaProjectsFoundError extends ToolkitError { | |
} | ||
} | ||
|
||
export class ZipExceedsSizeLimitError extends ToolkitError { | ||
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 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') | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
|
||
import * as vscode from 'vscode' | ||
import * as fs from 'fs' // eslint-disable-line no-restricted-imports | ||
import os from 'os' | ||
import path from 'path' | ||
import { getLogger } from '../../shared/logger/logger' | ||
import * as CodeWhispererConstants from '../models/constants' | ||
|
@@ -16,7 +17,6 @@ import { | |
jobPlanProgress, | ||
FolderInfo, | ||
ZipManifest, | ||
TransformByQStatus, | ||
TransformationType, | ||
TransformationCandidateProject, | ||
RegionProfile, | ||
|
@@ -43,7 +43,6 @@ import { | |
validateOpenProjects, | ||
} from '../service/transformByQ/transformProjectValidationHandler' | ||
import { | ||
getVersionData, | ||
prepareProjectDependencies, | ||
runMavenDependencyUpdateCommands, | ||
} from '../service/transformByQ/transformMavenHandler' | ||
|
@@ -82,7 +81,7 @@ import { AuthUtil } from '../util/authUtil' | |
|
||
export function getFeedbackCommentData() { | ||
const jobId = transformByQState.getJobId() | ||
const s = `Q CodeTransform jobId: ${jobId ? jobId : 'none'}` | ||
const s = `Q CodeTransformation jobId: ${jobId ? jobId : 'none'}` | ||
return s | ||
} | ||
|
||
|
@@ -110,10 +109,10 @@ export async function processSQLConversionTransformFormInput(pathToProject: stri | |
|
||
export async function compileProject() { | ||
try { | ||
const dependenciesFolder: FolderInfo = getDependenciesFolderInfo() | ||
const dependenciesFolder: FolderInfo = await getDependenciesFolderInfo() | ||
transformByQState.setDependencyFolderInfo(dependenciesFolder) | ||
const modulePath = transformByQState.getProjectPath() | ||
await prepareProjectDependencies(dependenciesFolder, modulePath) | ||
const projectPath = transformByQState.getProjectPath() | ||
await prepareProjectDependencies(dependenciesFolder.path, projectPath) | ||
} catch (err) { | ||
// open build-logs.txt file to show user error logs | ||
await writeAndShowBuildLogs(true) | ||
|
@@ -175,18 +174,15 @@ export async function humanInTheLoopRetryLogic(jobId: string, profile: RegionPro | |
if (status === 'PAUSED') { | ||
const hilStatusFailure = await initiateHumanInTheLoopPrompt(jobId) | ||
if (hilStatusFailure) { | ||
// We rejected the changes and resumed the job and should | ||
// try to resume normal polling asynchronously | ||
// resume polling | ||
void humanInTheLoopRetryLogic(jobId, profile) | ||
} | ||
} else { | ||
await finalizeTransformByQ(status) | ||
} | ||
} catch (error) { | ||
status = 'FAILED' | ||
// TODO if we encounter error in HIL, do we stop job? | ||
await finalizeTransformByQ(status) | ||
// bubble up error to callee function | ||
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.
Our HIL (Human-in-the-Loop) feature I believe is effectively obsolete once this PR is merged; will discuss to confirm and then hopefully will be able to delete all of the dead HIL-related code here. |
||
throw error | ||
} | ||
} | ||
|
@@ -225,11 +221,9 @@ export async function preTransformationUploadCode() { | |
|
||
const payloadFilePath = zipCodeResult.tempFilePath | ||
const zipSize = zipCodeResult.fileSize | ||
const dependenciesCopied = zipCodeResult.dependenciesCopied | ||
|
||
telemetry.record({ | ||
codeTransformTotalByteSize: zipSize, | ||
codeTransformDependenciesCopied: dependenciesCopied, | ||
}) | ||
|
||
transformByQState.setPayloadFilePath(payloadFilePath) | ||
|
@@ -408,7 +402,7 @@ export async function finishHumanInTheLoop(selectedDependency?: string) { | |
|
||
// 7) We need to take that output of maven and use CreateUploadUrl | ||
const uploadFolderInfo = humanInTheLoopManager.getUploadFolderInfo() | ||
await prepareProjectDependencies(uploadFolderInfo, uploadFolderInfo.path) | ||
await prepareProjectDependencies(uploadFolderInfo.path, uploadFolderInfo.path) | ||
// zipCode side effects deletes the uploadFolderInfo right away | ||
const uploadResult = await zipCode({ | ||
dependenciesFolder: uploadFolderInfo, | ||
|
@@ -449,13 +443,11 @@ export async function finishHumanInTheLoop(selectedDependency?: string) { | |
await terminateHILEarly(jobId) | ||
void humanInTheLoopRetryLogic(jobId, profile) | ||
} finally { | ||
// Always delete the dependency directories | ||
telemetry.codeTransform_humanInTheLoop.emit({ | ||
codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId(), | ||
codeTransformJobId: jobId, | ||
codeTransformMetadata: CodeTransformTelemetryState.instance.getCodeTransformMetaDataString(), | ||
result: hilResult, | ||
// TODO: make a generic reason field for telemetry logging so we don't log sensitive PII data | ||
reason: hilResult === MetadataResult.Fail ? 'Runtime error occurred' : undefined, | ||
}) | ||
await HumanInTheLoopManager.instance.cleanUpArtifacts() | ||
|
@@ -504,7 +496,7 @@ export async function startTransformationJob( | |
throw new JobStartError() | ||
} | ||
|
||
await sleep(2000) // sleep before polling job to prevent ThrottlingException | ||
await sleep(5000) // sleep before polling job status to prevent ThrottlingException | ||
throwIfCancelled() | ||
|
||
return jobId | ||
|
@@ -523,9 +515,7 @@ export async function pollTransformationStatusUntilPlanReady(jobId: string, prof | |
transformByQState.setJobFailureErrorChatMessage(CodeWhispererConstants.failedToCompleteJobChatMessage) | ||
} | ||
|
||
// Since we don't yet have a good way of knowing what the error was, | ||
// we try to fetch any build failure artifacts that may exist so that we can optionally | ||
// show them to the user if they exist. | ||
// try to download pre-build error logs if available | ||
let pathToLog = '' | ||
try { | ||
const tempToolkitFolder = await makeTemporaryToolkitFolder() | ||
|
@@ -689,23 +679,16 @@ export async function postTransformationJob() { | |
const durationInMs = calculateTotalLatency(CodeTransformTelemetryState.instance.getStartTime()) | ||
const resultStatusMessage = transformByQState.getStatus() | ||
|
||
if (transformByQState.getTransformationType() !== TransformationType.SQL_CONVERSION) { | ||
// the below is only applicable when user is doing a Java 8/11 language upgrade | ||
const versionInfo = await getVersionData() | ||
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. This was executing a shell command at the end of every transformation just to emit telemetry on the user's Maven version, which nobody even looked at. |
||
const mavenVersionInfoMessage = `${versionInfo[0]} (${transformByQState.getMavenName()})` | ||
const javaVersionInfoMessage = `${versionInfo[1]} (${transformByQState.getMavenName()})` | ||
|
||
telemetry.codeTransform_totalRunTime.emit({ | ||
buildSystemVersion: mavenVersionInfoMessage, | ||
codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId(), | ||
codeTransformJobId: transformByQState.getJobId(), | ||
codeTransformResultStatusMessage: resultStatusMessage, | ||
codeTransformRunTimeLatency: durationInMs, | ||
codeTransformLocalJavaVersion: javaVersionInfoMessage, | ||
result: resultStatusMessage === TransformByQStatus.Succeeded ? MetadataResult.Pass : MetadataResult.Fail, | ||
reason: `${resultStatusMessage}-${chatMessage}`, | ||
}) | ||
} | ||
telemetry.codeTransform_totalRunTime.emit({ | ||
codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId(), | ||
codeTransformJobId: transformByQState.getJobId(), | ||
codeTransformResultStatusMessage: resultStatusMessage, | ||
codeTransformRunTimeLatency: durationInMs, | ||
result: | ||
transformByQState.isSucceeded() || transformByQState.isPartiallySucceeded() | ||
? MetadataResult.Pass | ||
: MetadataResult.Fail, | ||
}) | ||
|
||
if (transformByQState.isSucceeded()) { | ||
void vscode.window.showInformationMessage(CodeWhispererConstants.jobCompletedNotification, { | ||
|
@@ -728,9 +711,14 @@ export async function postTransformationJob() { | |
}) | ||
} | ||
|
||
if (transformByQState.getPayloadFilePath() !== '') { | ||
if (transformByQState.getPayloadFilePath()) { | ||
// delete original upload ZIP at very end of transformation | ||
fs.rmSync(transformByQState.getPayloadFilePath(), { recursive: true, force: true }) | ||
fs.rmSync(transformByQState.getPayloadFilePath(), { force: true }) | ||
} | ||
// delete temporary build logs file | ||
const logFilePath = path.join(os.tmpdir(), 'build-logs.txt') | ||
if (fs.existsSync(logFilePath)) { | ||
fs.rmSync(logFilePath, { force: true }) | ||
} | ||
|
||
// attempt download for user | ||
|
@@ -746,14 +734,11 @@ export async function transformationJobErrorHandler(error: any) { | |
transformByQState.setToFailed() | ||
transformByQState.setPolledJobStatus('FAILED') | ||
// jobFailureErrorNotification should always be defined here | ||
let displayedErrorMessage = | ||
const displayedErrorMessage = | ||
transformByQState.getJobFailureErrorNotification() ?? CodeWhispererConstants.failedToCompleteJobNotification | ||
if (transformByQState.getJobFailureMetadata() !== '') { | ||
displayedErrorMessage += ` ${transformByQState.getJobFailureMetadata()}` | ||
transformByQState.setJobFailureErrorChatMessage( | ||
`${transformByQState.getJobFailureErrorChatMessage()} ${transformByQState.getJobFailureMetadata()}` | ||
) | ||
} | ||
transformByQState.setJobFailureErrorChatMessage( | ||
transformByQState.getJobFailureErrorChatMessage() ?? CodeWhispererConstants.failedToCompleteJobChatMessage | ||
) | ||
void vscode.window | ||
.showErrorMessage(displayedErrorMessage, CodeWhispererConstants.amazonQFeedbackText) | ||
.then((choice) => { | ||
|
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.
Lots of useless telemetry, so getting rid of some things and will remove them from the commons package shortly