Skip to content

Commit c91a9ad

Browse files
Merge branch 'main' into e2e-test
2 parents 9aebccf + a4f5c07 commit c91a9ad

File tree

17 files changed

+101
-39
lines changed

17 files changed

+101
-39
lines changed

.changes/3.61.json

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"date" : "2025-03-27",
3+
"version" : "3.61",
4+
"entries" : [ {
5+
"type" : "feature",
6+
"description" : "Amazon Q: Moved \"Include suggestions with code references\" setting to General"
7+
}, {
8+
"type" : "feature",
9+
"description" : "Add support for 2025.1"
10+
}, {
11+
"type" : "bugfix",
12+
"description" : "Amazon Q: Attempt to reduce thread pool contention locking IDE caused by `@workspace` making a large number of requests"
13+
}, {
14+
"type" : "deprecation",
15+
"description" : "An upcoming release will remove support for JetBrains Gateway version 2024.3 and for IDEs based on the 2024.1 platform"
16+
} ]
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type" : "bugfix",
3+
"description" : "/transform: prompt user to re-authenticate if credentials expire during transformation"
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type" : "bugfix",
3+
"description" : "Gracefully handle additional fields in Amazon Q /dev code generation result without throwing errors"
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type" : "bugfix",
3+
"description" : "/review: set programmingLanguage to Plaintext if language is unknown"
4+
}

.changes/next-release/bugfix-e06391bd-f5ae-4c2a-a102-580d30f3be8d.json

-4
This file was deleted.

.changes/next-release/deprecation-90102050-86a4-4c19-9ecc-70c6e033b949.json

-4
This file was deleted.

.changes/next-release/feature-45f6e6a7-fc5b-4b14-89e2-0d9a2b138c65.json

-4
This file was deleted.

.changes/next-release/feature-c88b1af5-2318-4ca3-903c-a289e5494b1d.json

-4
This file was deleted.

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# _3.61_ (2025-03-27)
2+
- **(Feature)** Amazon Q: Moved "Include suggestions with code references" setting to General
3+
- **(Feature)** Add support for 2025.1
4+
- **(Bug Fix)** Amazon Q: Attempt to reduce thread pool contention locking IDE caused by `@workspace` making a large number of requests
5+
- **(Deprecation)** An upcoming release will remove support for JetBrains Gateway version 2024.3 and for IDEs based on the 2024.1 platform
6+
17
# _3.60_ (2025-03-20)
28
- **(Feature)** AmazonQ /test now displays a concise test plan summary to users.
39
- **(Bug Fix)** Fix inline completion failure due to context length exceeding the threshold

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# SPDX-License-Identifier: Apache-2.0
33

44
# Toolkit Version
5-
toolkitVersion=3.61-SNAPSHOT
5+
toolkitVersion=3.62-SNAPSHOT
66

77
# Publish Settings
88
publishToken=

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevService.kt

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
package software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util
55

6+
import com.fasterxml.jackson.databind.DeserializationFeature
67
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
78
import com.fasterxml.jackson.module.kotlin.readValue
89
import com.intellij.openapi.project.Project
@@ -37,6 +38,9 @@ import software.aws.toolkits.telemetry.Result
3738
private val logger = getLogger<FeatureDevClient>()
3839

3940
class FeatureDevService(val proxyClient: FeatureDevClient, val project: Project) {
41+
private val objectMapper = jacksonObjectMapper()
42+
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
43+
4044
fun createConversation(): String {
4145
val startTime = System.currentTimeMillis()
4246
var failureReason: String? = null
@@ -238,7 +242,7 @@ class FeatureDevService(val proxyClient: FeatureDevClient, val project: Project)
238242
val parsedResult: ExportTaskAssistResultArchiveStreamResult
239243
try {
240244
val result = exportResponse.reduce { acc, next -> acc + next } // To map the result it is needed to combine the full byte array
241-
parsedResult = jacksonObjectMapper().readValue(result)
245+
parsedResult = objectMapper.readValue(result)
242246
} catch (e: Exception) {
243247
logger.error(e) { "Failed to parse downloaded code results" }
244248
throw ExportParseException(operation = FeatureDevOperation.ExportTaskAssistArchiveResult.toString(), desc = null, e.cause)

plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevServiceTest.kt

+17
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,23 @@ class FeatureDevServiceTest : FeatureDevTestBase() {
351351
}.isExactlyInstanceOf(ExportParseException::class.java)
352352
}
353353

354+
@Test
355+
fun `test exportTaskAssistArchiveResult ignore extra fields in the response`() {
356+
runTest {
357+
val codeGenerationJson = "{" +
358+
"\"code_generation_result\":{\"new_file_contents\":{\"test.ts\":\"contents\"},\"deleted_files\":[],\"references\":[],\"extra_filed\":[]}" +
359+
"}"
360+
361+
whenever(featureDevClient.exportTaskAssistResultArchive(testConversationId)).thenReturn(mutableListOf(codeGenerationJson.toByteArray()))
362+
363+
val actual = featureDevService.exportTaskAssistArchiveResult(testConversationId)
364+
assertThat(actual).isInstanceOf(CodeGenerationStreamResult::class.java)
365+
assertThat(actual.new_file_contents).isEqualTo(mapOf(Pair("test.ts", "contents")))
366+
assertThat(actual.deleted_files).isEqualTo(emptyList<String>())
367+
assertThat(actual.references).isEqualTo(emptyList<CodeReferenceGenerated>())
368+
}
369+
}
370+
354371
@Test
355372
fun `test exportTaskAssistArchiveResult returns correct parsed result`() =
356373
runTest {

plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/panels/managers/CodeModernizerBottomWindowPanelManager.kt

+14-11
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import com.intellij.openapi.actionSystem.ActionGroup
88
import com.intellij.openapi.actionSystem.ActionManager
99
import com.intellij.openapi.actionSystem.ActionToolbar
1010
import com.intellij.openapi.application.invokeLater
11+
import com.intellij.openapi.application.runInEdt
1112
import com.intellij.openapi.components.service
1213
import com.intellij.openapi.project.Project
1314
import com.intellij.openapi.projectRoots.JavaSdkVersion
@@ -38,7 +39,7 @@ import javax.swing.BorderFactory
3839
import javax.swing.JPanel
3940

4041
class CodeModernizerBottomWindowPanelManager(private val project: Project) : JPanel(BorderLayout()) {
41-
private var lastShownProgressPanel: Component? = null
42+
private var progressPanel: Component? = null
4243
val toolbar = createToolbar().apply {
4344
targetComponent = this@CodeModernizerBottomWindowPanelManager
4445
component.border = BorderFactory.createCompoundBorder(
@@ -62,14 +63,16 @@ class CodeModernizerBottomWindowPanelManager(private val project: Project) : JPa
6263
}
6364

6465
private fun setUI(function: () -> Unit) {
65-
lastShownProgressPanel = this.components.firstOrNull { it == fullSizeLoadingPanel || it == buildProgressSplitterPanelManager } ?: lastShownProgressPanel
66-
removeAll()
67-
add(BorderLayout.WEST, toolbar.component)
68-
add(BorderLayout.NORTH, banner)
69-
function.invoke()
70-
updateRunTime()
71-
revalidate()
72-
repaint()
66+
runInEdt {
67+
progressPanel = this.components.firstOrNull { it == fullSizeLoadingPanel || it == buildProgressSplitterPanelManager } ?: progressPanel
68+
removeAll()
69+
add(BorderLayout.WEST, toolbar.component)
70+
add(BorderLayout.NORTH, banner)
71+
function.invoke()
72+
updateRunTime()
73+
revalidate()
74+
repaint()
75+
}
7376
}
7477

7578
private fun updateRunTime(now: Instant? = null) {
@@ -173,8 +176,8 @@ class CodeModernizerBottomWindowPanelManager(private val project: Project) : JPa
173176
}
174177

175178
fun showUnalteredJobUI() = setUI {
176-
if (lastShownProgressPanel != null) {
177-
add(BorderLayout.CENTER, lastShownProgressPanel)
179+
if (progressPanel != null) {
180+
add(BorderLayout.CENTER, progressPanel)
178181
} else {
179182
add(BorderLayout.CENTER, fullSizeLoadingPanel)
180183
fullSizeLoadingPanel.progressIndicatorLabel.text = "No jobs active"

plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/utils/CodeTransformApiUtils.kt

+15-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package software.aws.toolkits.jetbrains.services.codemodernizer.utils
55

66
import com.fasterxml.jackson.module.kotlin.readValue
7+
import com.intellij.notification.NotificationAction
78
import com.intellij.openapi.project.Project
89
import com.intellij.serviceContainer.AlreadyDisposedException
910
import kotlinx.coroutines.delay
@@ -23,12 +24,14 @@ import software.aws.toolkits.core.utils.WaiterUnrecoverableException
2324
import software.aws.toolkits.core.utils.Waiters.waitUntil
2425
import software.aws.toolkits.jetbrains.services.codemodernizer.CodeTransformTelemetryManager
2526
import software.aws.toolkits.jetbrains.services.codemodernizer.client.GumbyClient
27+
import software.aws.toolkits.jetbrains.services.codemodernizer.commands.CodeTransformMessageListener
2628
import software.aws.toolkits.jetbrains.services.codemodernizer.constants.BILLING_RATE
2729
import software.aws.toolkits.jetbrains.services.codemodernizer.constants.JOB_STATISTICS_TABLE_KEY
2830
import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeModernizerArtifact.Companion.MAPPER
2931
import software.aws.toolkits.jetbrains.services.codemodernizer.model.CodeTransformType
3032
import software.aws.toolkits.jetbrains.services.codemodernizer.model.JobId
3133
import software.aws.toolkits.jetbrains.services.codemodernizer.model.PlanTable
34+
import software.aws.toolkits.jetbrains.utils.notifyStickyWarn
3235
import software.aws.toolkits.resources.message
3336
import java.time.Duration
3437
import java.util.Locale
@@ -64,8 +67,7 @@ suspend fun JobId.pollTransformationStatusAndPlan(
6467
val maxRefreshes = 10
6568
var numRefreshes = 0
6669

67-
// We refresh token at the start of polling, but for some long jobs that runs for 30 minutes plus, tokens may need to be
68-
// refreshed again when AccessDeniedException or InvalidGrantException are caught.
70+
// refresh token at start of polling since local build just prior can take a long time
6971
refreshToken(project)
7072

7173
try {
@@ -113,8 +115,17 @@ suspend fun JobId.pollTransformationStatusAndPlan(
113115
refreshToken(project)
114116
return@waitUntil state
115117
} catch (e: InvalidGrantException) {
116-
if (numRefreshes++ > maxRefreshes) throw e
117-
refreshToken(project)
118+
CodeTransformMessageListener.instance.onCheckAuth()
119+
notifyStickyWarn(
120+
message("codemodernizer.notification.warn.expired_credentials.title"),
121+
message("codemodernizer.notification.warn.expired_credentials.content"),
122+
project,
123+
listOf(
124+
NotificationAction.createSimpleExpiring(message("codemodernizer.notification.warn.action.reauthenticate")) {
125+
CodeTransformMessageListener.instance.onReauthStarted()
126+
}
127+
)
128+
)
118129
return@waitUntil state
119130
} finally {
120131
delay(sleepDurationMillis)

plugins/amazonq/codetransform/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codemodernizer/CodeWhispererCodeModernizerUtilsTest.kt

+8-5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import io.mockk.every
66
import io.mockk.just
77
import io.mockk.mockkStatic
88
import io.mockk.runs
9+
import io.mockk.verify
910
import kotlinx.coroutines.runBlocking
1011
import org.assertj.core.api.Assertions.assertThat
1112
import org.junit.Before
@@ -26,7 +27,9 @@ import software.aws.toolkits.jetbrains.services.codemodernizer.utils.parseBuildF
2627
import software.aws.toolkits.jetbrains.services.codemodernizer.utils.pollTransformationStatusAndPlan
2728
import software.aws.toolkits.jetbrains.services.codemodernizer.utils.refreshToken
2829
import software.aws.toolkits.jetbrains.services.codemodernizer.utils.validateSctMetadata
30+
import software.aws.toolkits.jetbrains.utils.notifyStickyWarn
2931
import software.aws.toolkits.jetbrains.utils.rules.addFileToModule
32+
import software.aws.toolkits.resources.message
3033
import java.util.concurrent.atomic.AtomicBoolean
3134
import kotlin.io.path.createTempFile
3235

@@ -114,18 +117,18 @@ class CodeWhispererCodeModernizerUtilsTest : CodeWhispererCodeModernizerTestBase
114117
}
115118

116119
@Test
117-
fun `refresh on invalid grant`() {
120+
fun `show re-auth notification on invalid grant exception`() {
118121
val mockInvalidGrantException = Mockito.mock(InvalidGrantException::class.java)
119122

120-
mockkStatic(::refreshToken)
121-
every { refreshToken(any()) } just runs
123+
mockkStatic(::notifyStickyWarn)
124+
every { notifyStickyWarn(any(), any(), any(), any(), any()) } just runs
122125

123126
Mockito.doThrow(
124127
mockInvalidGrantException
125128
).doReturn(
126129
exampleGetCodeMigrationResponse,
127130
exampleGetCodeMigrationResponse.replace(TransformationStatus.STARTED),
128-
exampleGetCodeMigrationResponse.replace(TransformationStatus.COMPLETED), // Should stop before this point
131+
exampleGetCodeMigrationResponse.replace(TransformationStatus.COMPLETED),
129132
).whenever(clientAdaptorSpy).getCodeModernizationJob(any())
130133

131134
Mockito.doReturn(exampleGetCodeMigrationPlanResponse)
@@ -152,7 +155,7 @@ class CodeWhispererCodeModernizerUtilsTest : CodeWhispererCodeModernizerTestBase
152155
TransformationStatus.STARTED,
153156
)
154157
assertThat(expected).isEqualTo(mutableList)
155-
io.mockk.verify { refreshToken(any()) }
158+
verify { notifyStickyWarn(message("codemodernizer.notification.warn.expired_credentials.title"), any(), any(), any(), any()) }
156159
}
157160

158161
@Test

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt

+5-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,11 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) {
264264
return clientAdaptor.createCodeScan(
265265
StartCodeAnalysisRequest.builder()
266266
.clientToken(clientToken.toString())
267-
.programmingLanguage { it.languageName(language) }
267+
.programmingLanguage {
268+
it.languageName(
269+
if (language == CodewhispererLanguage.Unknown.toString()) CodewhispererLanguage.Plaintext.toString() else language
270+
)
271+
}
268272
.artifacts(artifactsMap)
269273
.scope(scope.value)
270274
.codeScanName(codeScanName)

plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties

+1
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,7 @@ codemodernizer.notification.warn.download_failed_invalid_artifact=Amazon Q was u
779779
codemodernizer.notification.warn.download_failed_other.content=Amazon Q ran into an issue while trying to download your {0}. Please try again. {1}
780780
codemodernizer.notification.warn.download_failed_ssl.content=Please make sure all your certificates for your proxy client have been set up correctly for your IDE.
781781
codemodernizer.notification.warn.download_failed_wildcard.content=Check your IDE proxy settings and remove any wildcard (*) references, and then try viewing the diff again.
782+
codemodernizer.notification.warn.expired_credentials.content=Unable to check transformation status as your credentials expired. Try signing out of Amazon Q and signing back in again if 'Reauthenticate' below does not work.
782783
codemodernizer.notification.warn.expired_credentials.title=Your connection to Q has expired
783784
codemodernizer.notification.warn.invalid_project.description.reason.missing_content_roots=None of your open modules are supported for code transformation with Amazon Q. Amazon Q can upgrade Java 8, Java 11, Java 17, and Java 21 projects built on Maven, with content roots configured.
784785
codemodernizer.notification.warn.invalid_project.description.reason.not_logged_in=Amazon Q cannot start the transformation as you are not logged in with Identity Center or Builder ID. Also ensure that you are not using IntelliJ version 232.8660.185 and that you are not developing on a remote host (uncommon).

0 commit comments

Comments
 (0)