diff --git a/.azure-pipelines/publish-to-maven.yml b/.azure-pipelines/publish-to-maven.yml
new file mode 100644
index 000000000..a1ef0a204
--- /dev/null
+++ b/.azure-pipelines/publish-to-maven.yml
@@ -0,0 +1,104 @@
+name: $(Date:yyyyMMdd).$(Rev:r)
+resources:
+ repositories:
+ - repository: MicroBuildTemplate
+ type: git
+ name: 1ESPipelineTemplates/MicroBuildTemplate
+ ref: refs/tags/release
+trigger: none
+extends:
+ template: azure-pipelines/1ES.Official.Publish.yml@MicroBuildTemplate
+ parameters:
+ pool:
+ os: linux
+ name: 1ES_JavaTooling_Pool
+ image: 1ES_JavaTooling_Ubuntu-2004
+ sdl:
+ sourceAnalysisPool:
+ name: 1ES_JavaTooling_Pool
+ image: 1ES_JavaTooling_Windows_2022
+ os: windows
+ stages:
+ - stage: PublishToMaven
+ jobs:
+ - job: PublishToMaven
+ displayName: Maven Release job
+ templateContext:
+ type: releaseJob
+ isProduction: true
+ steps:
+ - task: DownloadBuildArtifacts@1
+ displayName: 'Download Jar Artifacts'
+ inputs:
+ buildType: specific
+ project: 'a4d27ce2-a42d-4b71-8eef-78cee9a9728e'
+ pipeline: 16486
+ downloadType: specific
+ extractTars: false
+ itemPattern: 'm2/**'
+ - script: |
+ echo "import public key"
+ echo $GPG_PUBLIC_B64 | base64 -d | gpg --import
+
+ echo "import secret key"
+ echo $GPG_SECRET_B64 | base64 -d | gpg --batch --passphrase $GPGPASS --import
+ displayName: 'import GPG keys'
+ env:
+ GPG_PUBLIC_B64: $(GPG_PUBLIC_B64)
+ GPG_SECRET_B64: $(GPG_SECRET_B64)
+ GPGPASS: $(GPGPASS)
+ - task: NodeTool@0
+ displayName: 'Use Node 20.x'
+ inputs:
+ versionSpec: 20.x
+ - script: |
+ cd $(System.ArtifactsDirectory)/m2
+ pluginJarFile=$(basename -- java-debug-parent/*.pom)
+
+ # remove .* from end
+ noExt=${pluginJarFile%.*}
+
+ # remove *- from start
+ export releaseVersion=${noExt##*-}
+ echo $releaseVersion
+
+ export artifactFolder=$(pwd .)
+ wget https://raw.githubusercontent.com/microsoft/java-debug/master/scripts/publishMaven.js
+
+ export GPG_TTY=$(tty)
+ node publishMaven.js -task gpg
+ displayName: 'sign artifacts'
+ env:
+ GPG_PUBLIC_B64: $(GPG_PUBLIC_B64)
+ GPG_SECRET_B64: $(GPG_SECRET_B64)
+ GPGPASS: $(GPGPASS)
+ NEXUS_OSSRHPASS: $(NEXUS_OSSRHPASS)
+ NEXUS_OSSRHUSER: $(NEXUS_OSSRHUSER)
+ NEXUS_STAGINGPROFILEID: $(NEXUS_STAGINGPROFILEID)
+ - template: MicroBuild.Publish.yml@MicroBuildTemplate
+ parameters:
+ intent: 'PackageDistribution'
+ contentType: 'Maven'
+ contentSource: 'Folder'
+ folderLocation: '$(System.ArtifactsDirectory)/m2/java-debug-parent'
+ waitForReleaseCompletion: true
+ owners: 'jinbwan@microsoft.com'
+ approvers: 'roml@microsoft.com'
+ - template: MicroBuild.Publish.yml@MicroBuildTemplate
+ parameters:
+ intent: 'PackageDistribution'
+ contentType: 'Maven'
+ contentSource: 'Folder'
+ folderLocation: '$(System.ArtifactsDirectory)/m2/com.microsoft.java.debug.core'
+ waitForReleaseCompletion: true
+ owners: 'jinbwan@microsoft.com'
+ approvers: 'roml@microsoft.com'
+ - template: MicroBuild.Publish.yml@MicroBuildTemplate
+ parameters:
+ intent: 'PackageDistribution'
+ contentType: 'Maven'
+ contentSource: 'Folder'
+ folderLocation: '$(System.ArtifactsDirectory)/m2/com.microsoft.java.debug.plugin'
+ waitForReleaseCompletion: true
+ owners: 'jinbwan@microsoft.com'
+ approvers: 'roml@microsoft.com'
\ No newline at end of file
diff --git a/.azure-pipelines/signjars-nightly.yml b/.azure-pipelines/signjars-nightly.yml
new file mode 100644
index 000000000..8b1e8d12a
--- /dev/null
+++ b/.azure-pipelines/signjars-nightly.yml
@@ -0,0 +1,138 @@
+name: $(Date:yyyyMMdd).$(Rev:r)
+variables:
+ - name: Codeql.Enabled
+ value: true
+schedules:
+ - cron: 0 5 * * 1,2,3,4,5
+ branches:
+ include:
+ - refs/heads/main
+resources:
+ repositories:
+ - repository: self
+ type: git
+ ref: refs/heads/main
+ - repository: 1esPipelines
+ type: git
+ name: 1ESPipelineTemplates/1ESPipelineTemplates
+ ref: refs/tags/release
+trigger: none
+extends:
+ template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines
+ parameters:
+ pool:
+ os: linux
+ name: 1ES_JavaTooling_Pool
+ image: 1ES_JavaTooling_Ubuntu-2004
+ sdl:
+ sourceAnalysisPool:
+ name: 1ES_JavaTooling_Pool
+ image: 1ES_JavaTooling_Windows_2022
+ os: windows
+ customBuildTags:
+ - MigrationTooling-mseng-VSJava-13474-Tool
+ stages:
+ - stage: Build
+ jobs:
+ - job: Job_1
+ displayName: Sign-Jars-Nightly
+ templateContext:
+ outputs:
+ - output: pipelineArtifact
+ artifactName: plugin
+ targetPath: $(Build.ArtifactStagingDirectory)
+ displayName: "Publish Artifact: plugin"
+ steps:
+ - checkout: self
+ fetchTags: true
+ - task: UseDotNet@2
+ displayName: 'Use .NET Core 3.1.x'
+ inputs:
+ packageType: 'sdk'
+ version: '3.1.x'
+ - task: UseDotNet@2
+ displayName: 'Use .NET Core 8.0.x'
+ inputs:
+ packageType: 'sdk'
+ version: '8.0.x'
+ - task: MicroBuildSigningPlugin@4
+ displayName: 'Install Signing Plugin'
+ inputs:
+ signType: real
+ azureSubscription: 'MicroBuild Signing Task (MSEng)'
+ useEsrpCli: true
+ ConnectedPMEServiceName: 0e38ce24-f885-4c86-b997-5887b97a1899
+ feedSource: 'https://mseng.pkgs.visualstudio.com/DefaultCollection/_packaging/MicroBuildToolset/nuget/v3/index.json'
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)'
+ - task: JavaToolInstaller@0
+ displayName: Use Java 21
+ inputs:
+ versionSpec: "21"
+ jdkArchitectureOption: x64
+ jdkSourceOption: PreInstalled
+ - task: CmdLine@2
+ displayName: Parse the release version from pom.xml
+ inputs:
+ script: |-
+ #!/bin/bash
+
+ sudo apt-get install xmlstarlet
+ xmlstarlet --version
+ RELEASE_VERSION=$(xmlstarlet sel -t -v "/_:project/_:version" pom.xml)
+ echo $RELEASE_VERSION
+ echo "##vso[task.setvariable variable=RELEASE_VERSION]$RELEASE_VERSION"
+ - task: CmdLine@2
+ displayName: Build core.jar
+ inputs:
+ script: |
+ ./mvnw clean install -f com.microsoft.java.debug.core/pom.xml -Dmaven.repo.local=./.repository
+
+ mkdir -p jars
+ mv .repository/com/microsoft/java/com.microsoft.java.debug.core/$RELEASE_VERSION/com.microsoft.java.debug.core*.jar jars/
+ - task: CmdLine@2
+ displayName: Sign core jars
+ inputs:
+ script: |
+ files=$(find . -type f -name "com.microsoft.java.debug.core*.jar")
+ for file in $files; do
+ fileName=$(basename "$file")
+ dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$fileName" /certs:100010171
+ done
+ workingDirectory: 'jars'
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ - task: CmdLine@2
+ displayName: install signed core.jar
+ inputs:
+ script: cp jars/com.microsoft.java.debug.core*.jar .repository/com/microsoft/java/com.microsoft.java.debug.core/$RELEASE_VERSION/
+ - task: CmdLine@2
+ displayName: Build plugin.jar
+ inputs:
+ script: |-
+ ./mvnw clean install -N -f pom.xml -Dmaven.repo.local=./.repository
+ ./mvnw clean install -f com.microsoft.java.debug.target/pom.xml -Dmaven.repo.local=./.repository
+ ./mvnw clean install -f com.microsoft.java.debug.plugin/pom.xml -Dmaven.repo.local=./.repository
+
+ mkdir -p jars
+ mv .repository/com/microsoft/java/com.microsoft.java.debug.plugin/$RELEASE_VERSION/com.microsoft.java.debug.plugin*.jar jars/
+ - task: CmdLine@2
+ displayName: Sign plugin jars
+ inputs:
+ script: |
+ files=$(find . -type f -name "com.microsoft.java.debug.plugin*.jar")
+ for file in $files; do
+ fileName=$(basename "$file")
+ dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$fileName" /certs:100010171
+ done
+ workingDirectory: 'jars'
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ - task: CopyFiles@2
+ displayName: "Copy plugin.jar to: $(Build.ArtifactStagingDirectory)"
+ inputs:
+ Contents: |+
+ jars/com.microsoft.java.debug.plugin*.jar
+
+ TargetFolder: $(Build.ArtifactStagingDirectory)
diff --git a/.azure-pipelines/signjars-rc.yml b/.azure-pipelines/signjars-rc.yml
new file mode 100644
index 000000000..e87444603
--- /dev/null
+++ b/.azure-pipelines/signjars-rc.yml
@@ -0,0 +1,169 @@
+name: $(Date:yyyyMMdd).$(Rev:r)
+variables:
+ - name: Codeql.Enabled
+ value: true
+resources:
+ repositories:
+ - repository: self
+ type: git
+ ref: refs/heads/main
+ - repository: 1esPipelines
+ type: git
+ name: 1ESPipelineTemplates/1ESPipelineTemplates
+ ref: refs/tags/release
+trigger: none
+extends:
+ template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines
+ parameters:
+ pool:
+ os: linux
+ name: 1ES_JavaTooling_Pool
+ image: 1ES_JavaTooling_Ubuntu-2004
+ sdl:
+ sourceAnalysisPool:
+ name: 1ES_JavaTooling_Pool
+ image: 1ES_JavaTooling_Windows_2022
+ os: windows
+ customBuildTags:
+ - MigrationTooling-mseng-VSJava-9151-Tool
+ stages:
+ - stage: Build
+ jobs:
+ - job: Job_1
+ displayName: Sign-Jars-RC
+ templateContext:
+ outputs:
+ - output: pipelineArtifact
+ artifactName: m2
+ targetPath: $(Build.ArtifactStagingDirectory)/m2
+ displayName: "Publish Artifact: m2"
+ steps:
+ - checkout: self
+ fetchTags: true
+ - task: UseDotNet@2
+ displayName: 'Use .NET Core 3.1.x'
+ inputs:
+ packageType: 'sdk'
+ version: '3.1.x'
+ - task: UseDotNet@2
+ displayName: 'Use .NET Core 8.0.x'
+ inputs:
+ packageType: 'sdk'
+ version: '8.0.x'
+ - task: MicroBuildSigningPlugin@4
+ displayName: 'Install Signing Plugin'
+ inputs:
+ signType: real
+ azureSubscription: 'MicroBuild Signing Task (MSEng)'
+ useEsrpCli: true
+ ConnectedPMEServiceName: 0e38ce24-f885-4c86-b997-5887b97a1899
+ feedSource: 'https://mseng.pkgs.visualstudio.com/DefaultCollection/_packaging/MicroBuildToolset/nuget/v3/index.json'
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)'
+ - task: JavaToolInstaller@0
+ displayName: Use Java 21
+ inputs:
+ versionSpec: "21"
+ jdkArchitectureOption: x64
+ jdkSourceOption: PreInstalled
+ - task: CmdLine@2
+ displayName: Parse the release version from pom.xml
+ inputs:
+ script: |-
+ #!/bin/bash
+
+ sudo apt-get install xmlstarlet
+ xmlstarlet --version
+ RELEASE_VERSION=$(xmlstarlet sel -t -v "/_:project/_:version" pom.xml)
+ echo $RELEASE_VERSION
+ echo "##vso[task.setvariable variable=RELEASE_VERSION]$RELEASE_VERSION"
+ - task: CmdLine@2
+ displayName: Build core.jar
+ inputs:
+ script: |
+ ./mvnw -N clean install -Dmaven.repo.local=./.repository
+
+ ./mvnw clean install -f com.microsoft.java.debug.core/pom.xml -Dmaven.repo.local=./.repository
+
+ mkdir -p jars
+ mv .repository/com/microsoft/java/com.microsoft.java.debug.core/$RELEASE_VERSION/com.microsoft.java.debug.core*.jar jars/
+ - task: CmdLine@2
+ displayName: Sign core jars
+ inputs:
+ script: |
+ files=$(find . -type f -name "com.microsoft.java.debug.core*.jar")
+ for file in $files; do
+ fileName=$(basename "$file")
+ dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$fileName" /certs:100010171
+ done
+ workingDirectory: 'jars'
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ - task: CmdLine@2
+ displayName: install signed core.jar
+ inputs:
+ script: cp jars/com.microsoft.java.debug.core*.jar .repository/com/microsoft/java/com.microsoft.java.debug.core/$RELEASE_VERSION/
+ - task: CmdLine@2
+ displayName: Build plugin.jar
+ inputs:
+ script: |-
+ ./mvnw clean install -f com.microsoft.java.debug.target/pom.xml -Dmaven.repo.local=./.repository
+ ./mvnw clean install -f com.microsoft.java.debug.plugin/pom.xml -Dmaven.repo.local=./.repository
+
+ mkdir -p jars
+ mv .repository/com/microsoft/java/com.microsoft.java.debug.plugin/$RELEASE_VERSION/com.microsoft.java.debug.plugin*.jar jars/
+ - task: CmdLine@2
+ displayName: Sign plugin jars
+ inputs:
+ script: |
+ files=$(find . -type f -name "com.microsoft.java.debug.plugin*.jar")
+ for file in $files; do
+ fileName=$(basename "$file")
+ dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$fileName" /certs:100010171
+ done
+ workingDirectory: 'jars'
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ - task: CmdLine@2
+ displayName: install signed plugin.jar
+ inputs:
+ script: cp jars/com.microsoft.java.debug.plugin*.jar .repository/com/microsoft/java/com.microsoft.java.debug.plugin/$RELEASE_VERSION/
+ - task: CmdLine@2
+ displayName: build m2 artifacts
+ inputs:
+ script: |
+ ./mvnw source:jar -f com.microsoft.java.debug.core/pom.xml -Dmaven.repo.local=./.repository
+ ./mvnw javadoc:jar -f com.microsoft.java.debug.core/pom.xml -Ddoclint=none -Dmaven.repo.local=./.repository
+
+ ./mvnw source:jar -f com.microsoft.java.debug.plugin/pom.xml -Dmaven.repo.local=./.repository
+ ./mvnw javadoc:jar -f com.microsoft.java.debug.plugin/pom.xml -Ddoclint=none -Dmaven.repo.local=./.repository
+
+ mkdir -p m2/java-debug-parent
+ cp pom.xml m2/java-debug-parent/java-debug-parent-$RELEASE_VERSION.pom
+
+ mkdir -p m2/com.microsoft.java.debug.core
+ cp com.microsoft.java.debug.core/target/com.microsoft.java.debug.core*.jar m2/com.microsoft.java.debug.core
+ cp com.microsoft.java.debug.core/pom.xml m2/com.microsoft.java.debug.core/com.microsoft.java.debug.core-$RELEASE_VERSION.pom
+
+ mkdir -p m2/com.microsoft.java.debug.plugin
+ cp com.microsoft.java.debug.plugin/target/com.microsoft.java.debug.plugin*.jar m2/com.microsoft.java.debug.plugin
+ cp com.microsoft.java.debug.plugin/pom.xml m2/com.microsoft.java.debug.plugin/com.microsoft.java.debug.plugin-$RELEASE_VERSION.pom
+ - task: CmdLine@2
+ displayName: Sign m2 jars
+ inputs:
+ script: |
+ files=$(find . -type f -name "*.jar")
+ for file in $files; do
+ # fileName=$(basename "$file")
+ dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$file" /certs:100010171
+ done
+ workingDirectory: 'm2'
+ env:
+ SYSTEM_ACCESSTOKEN: $(System.AccessToken)
+ - task: CopyFiles@2
+ displayName: "Copy m2 to: $(Build.ArtifactStagingDirectory)"
+ inputs:
+ Contents: |+
+ m2/**
+ TargetFolder: $(Build.ArtifactStagingDirectory)
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index b11684f52..9d7579633 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @testforstephen @jdneo
\ No newline at end of file
+* @testforstephen @jdneo @chagong @wenytang-ms
diff --git a/.github/llms.md b/.github/llms.md
new file mode 100644
index 000000000..55d69b238
--- /dev/null
+++ b/.github/llms.md
@@ -0,0 +1,38 @@
+# Extension Pack for Java
+Extension Pack for Java is a collection of popular extensions that can help write, test and debug Java applications in Visual Studio Code. By installing Extension Pack for Java, the following extensions are installed:
+
+- [📦 Language Support for Java™ by Red Hat ](https://marketplace.visualstudio.com/items?itemName=redhat.java)
+ - Code Navigation
+ - Auto Completion
+ - Refactoring
+ - Code Snippets
+- [📦 Debugger for Java](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-debug)
+ - Debugging
+- [📦 Test Runner for Java](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-test)
+ - Run & Debug JUnit/TestNG Test Cases
+- [📦 Maven for Java](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-maven)
+ - Project Scaffolding
+ - Custom Goals
+- [📦 Gradle for Java](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-gradle)
+ - View Gradle tasks and project dependencies
+ - Gradle file authoring
+ - Import Gradle projects via [Gradle Build Server](https://github.com/microsoft/build-server-for-gradle)
+- [📦 Project Manager for Java](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-dependency)
+ - Manage Java projects, referenced libraries, resource files, packages, classes, and class members
+- [📦 Visual Studio IntelliCode](https://marketplace.visualstudio.com/items?itemName=VisualStudioExptTeam.vscodeintellicode)
+ - AI-assisted development
+ - Completion list ranked by AI
+
+## Label
+When labeling an issue, follow the rules below per label category:
+### General Rules
+- Analyze if the issue is related with the scope of using extensions for Java development. If not, STOP labelling IMMEDIATELY.
+- Assign label per category.
+- If a category is not applicable or you're unsure, you may skip it.
+- Do not assign multiple labels within the same category, unless explicitly allowed as an exception.
+
+### Issue Type Labels
+- [bug]: Primary label for real bug issues
+- [enhancement]: Primary label for enhancement issues
+- [documentation]: Primary label for documentation issues
+- [question]: Primary label for question issues
\ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 41c85cb62..553d95a9a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -12,80 +12,83 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v5
- - name: Set up JDK 17
- uses: actions/setup-java@v1
- with:
- java-version: '17'
+ - name: Set up JDK 21
+ uses: actions/setup-java@v5
+ with:
+ java-version: '21'
+ distribution: 'temurin'
- - name: Cache local Maven repository
- uses: actions/cache@v2
- with:
- path: ~/.m2/repository
- key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
- restore-keys: |
- ${{ runner.os }}-maven-
+ - name: Cache local Maven repository
+ uses: actions/cache@v4
+ with:
+ path: ~/.m2/repository
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: |
+ ${{ runner.os }}-maven-
- - name: Verify
- run: ./mvnw clean verify
+ - name: Verify
+ run: ./mvnw clean verify -U
- - name: Checkstyle
- run: ./mvnw checkstyle:check
+ - name: Checkstyle
+ run: ./mvnw checkstyle:check
windows:
name: Windows
runs-on: windows-latest
timeout-minutes: 30
steps:
- - name: Set git to use LF
- run: |
- git config --global core.autocrlf false
- git config --global core.eol lf
+ - name: Set git to use LF
+ run: |
+ git config --global core.autocrlf false
+ git config --global core.eol lf
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v5
- - name: Set up JDK 17
- uses: actions/setup-java@v1
- with:
- java-version: '17'
+ - name: Set up JDK 21
+ uses: actions/setup-java@v5
+ with:
+ java-version: '21'
+ distribution: 'temurin'
- - name: Cache local Maven repository
- uses: actions/cache@v2
- with:
- path: $HOME/.m2/repository
- key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
- restore-keys: |
- ${{ runner.os }}-maven-
+ - name: Cache local Maven repository
+ uses: actions/cache@v4
+ with:
+ path: $HOME/.m2/repository
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: |
+ ${{ runner.os }}-maven-
- - name: Verify
- run: ./mvnw.cmd clean verify
+ - name: Verify
+ run: ./mvnw.cmd clean verify
- - name: Checkstyle
- run: ./mvnw.cmd checkstyle:check
+ - name: Checkstyle
+ run: ./mvnw.cmd checkstyle:check
darwin:
name: macOS
runs-on: macos-latest
timeout-minutes: 30
steps:
- - uses: actions/checkout@v2
-
- - name: Set up JDK 17
- uses: actions/setup-java@v1
- with:
- java-version: '17'
-
- - name: Cache local Maven repository
- uses: actions/cache@v2
- with:
- path: ~/.m2/repository
- key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
- restore-keys: |
- ${{ runner.os }}-maven-
-
- - name: Verify
- run: ./mvnw clean verify
-
- - name: Checkstyle
- run: ./mvnw checkstyle:check
+ - uses: actions/checkout@v5
+
+ - name: Set up JDK 21
+ uses: actions/setup-java@v5
+ with:
+ java-version: '21'
+ distribution: 'temurin'
+
+ - name: Cache local Maven repository
+ uses: actions/cache@v4
+ with:
+ path: ~/.m2/repository
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: |
+ ${{ runner.os }}-maven-
+
+ - name: Verify
+ run: ./mvnw clean verify -U
+
+ - name: Checkstyle
+ run: ./mvnw checkstyle:check
diff --git a/.github/workflows/triage-agent.yml b/.github/workflows/triage-agent.yml
new file mode 100644
index 000000000..f1df6e117
--- /dev/null
+++ b/.github/workflows/triage-agent.yml
@@ -0,0 +1,125 @@
+name: AI Triage
+on:
+ issues:
+ types: [opened]
+ workflow_dispatch:
+ inputs:
+ issue_number:
+ description: 'Issue number to triage (manual run). e.g. 123'
+ required: true
+
+run-name: >-
+ AI Triage for Issue #${{ github.event.issue.number || github.event.inputs.issue_number }}
+
+permissions:
+ issues: write
+ contents: read
+
+jobs:
+ label_and_comment:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+
+ - name: Get issue data
+ id: get_issue
+ uses: actions/github-script@v6
+ with:
+ script: |
+ const eventName = context.eventName;
+ let issue;
+ if (eventName === 'workflow_dispatch') {
+ const inputs = context.payload.inputs || {};
+ const issueNumber = inputs.issue_number || inputs.issueNumber;
+ if (!issueNumber) core.setFailed('Input issue_number is required for manual run.');
+ const { data } = await github.rest.issues.get({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: parseInt(issueNumber, 10),
+ });
+ issue = data;
+ } else if (context.payload.issue) {
+ issue = context.payload.issue;
+ } else {
+ core.setFailed('No issue information found in the event payload.');
+ }
+ core.setOutput('id', String(issue.number));
+ core.setOutput('user', String((issue.user && issue.user.login) || ''));
+ core.setOutput('title', String(issue.title || ''));
+ core.setOutput('body', String(issue.body || ''));
+ const labelNames = (issue.labels || []).map(label => label.name);
+ core.setOutput('labels', JSON.stringify(labelNames));
+
+ - name: Call Azure Function
+ id: call_azure_function
+ env:
+ PAYLOAD: >-
+ {
+ "authToken": "${{ secrets.GITHUB_TOKEN }}",
+ "repoId": "microsoft/java-debug",
+ "issueData": {
+ "id": ${{ steps.get_issue.outputs.id }},
+ "user": ${{ toJson(steps.get_issue.outputs.user) }},
+ "title": ${{ toJson(steps.get_issue.outputs.title) }},
+ "body": ${{ toJson(steps.get_issue.outputs.body) }},
+ "labels": ${{ steps.get_issue.outputs.labels }}
+ },
+ "mode": "DirectUpdate"
+ }
+
+ run: |
+ # Make the HTTP request with improved error handling and timeouts
+ echo "Making request to triage agent..."
+
+ # Add timeout handling and better error detection
+ set +e # Don't exit on curl failure
+ response=$(timeout ${{ vars.TRIAGE_AGENT_TIMEOUT }} curl \
+ --max-time 0 \
+ --connect-timeout 30 \
+ --fail-with-body \
+ --silent \
+ --show-error \
+ --write-out "HTTPSTATUS:%{http_code}" \
+ --header "Content-Type: application/json" \
+ --request POST \
+ --data "$PAYLOAD" \
+ ${{ secrets.TRIAGE_FUNCTION_LINK }} 2>&1)
+
+ curl_exit_code=$?
+ set -e # Re-enable exit on error
+
+ echo "Curl exit code: $curl_exit_code"
+
+ # Check if curl command timed out or failed
+ if [ $curl_exit_code -eq 124 ]; then
+ echo "❌ Request timed out after 650 seconds"
+ exit 1
+ elif [ $curl_exit_code -ne 0 ]; then
+ echo "❌ Curl command failed with exit code: $curl_exit_code"
+ echo "Response: $response"
+ exit 1
+ fi
+
+ # Extract HTTP status code and response body
+ http_code=$(echo "$response" | grep -o "HTTPSTATUS:[0-9]*" | cut -d: -f2)
+ response_body=$(echo "$response" | sed 's/HTTPSTATUS:[0-9]*$//')
+
+ echo "HTTP Status Code: $http_code"
+
+ # Validate HTTP status code
+ if [ -z "$http_code" ]; then
+ echo "❌ Failed to extract HTTP status code from response"
+ echo "Raw response: $response"
+ exit 1
+ fi
+
+ # Check if the request was successful
+ if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then
+ echo "✅ Azure Function call succeeded"
+ else
+ echo "❌ Azure Function call failed with status code: $http_code"
+ echo "Response: $response_body"
+ exit 1
+ fi
\ No newline at end of file
diff --git a/.github/workflows/triage-all-open-issues.yml b/.github/workflows/triage-all-open-issues.yml
new file mode 100644
index 000000000..092f4ef70
--- /dev/null
+++ b/.github/workflows/triage-all-open-issues.yml
@@ -0,0 +1,145 @@
+name: AI Triage - Process All Open Issues
+on:
+ workflow_dispatch:
+ inputs:
+ dry_run:
+ description: 'Dry run mode - only list issues without processing'
+ required: false
+ default: false
+ type: boolean
+ max_issues:
+ description: 'Maximum number of issues to process (0 = all)'
+ required: false
+ default: '0'
+ type: string
+
+permissions:
+ issues: write
+ contents: read
+ actions: write
+
+jobs:
+ get_open_issues:
+ runs-on: ubuntu-latest
+ outputs:
+ issue_numbers: ${{ steps.get_issues.outputs.issue_numbers }}
+ total_count: ${{ steps.get_issues.outputs.total_count }}
+
+ steps:
+ - name: Get all open issues
+ id: get_issues
+ uses: actions/github-script@v6
+ with:
+ script: |
+ // Use Search API to filter issues at API level
+ const { data } = await github.rest.search.issuesAndPullRequests({
+ q: `repo:${context.repo.owner}/${context.repo.repo} is:issue is:open -label:ai-triaged -label:invalid`,
+ sort: 'created',
+ order: 'asc',
+ per_page: 100
+ });
+
+ const actualIssues = data.items;
+
+ let issuesToProcess = actualIssues;
+ const maxIssues = parseInt('${{ inputs.max_issues }}' || '0');
+
+ if (maxIssues > 0 && actualIssues.length > maxIssues) {
+ issuesToProcess = actualIssues.slice(0, maxIssues);
+ console.log(`Limiting to first ${maxIssues} issues out of ${actualIssues.length} total`);
+ }
+
+ const issueNumbers = issuesToProcess.map(issue => issue.number);
+ const totalCount = issuesToProcess.length;
+
+ console.log(`Found ${actualIssues.length} open issues, processing ${totalCount}:`);
+ issuesToProcess.forEach(issue => {
+ console.log(` #${issue.number}: ${issue.title}`);
+ });
+
+ core.setOutput('issue_numbers', JSON.stringify(issueNumbers));
+ core.setOutput('total_count', totalCount);
+
+ process_issues:
+ runs-on: ubuntu-latest
+ needs: get_open_issues
+ if: needs.get_open_issues.outputs.total_count > 0
+
+ strategy:
+ # Process issues one by one (max-parallel: 1)
+ max-parallel: 1
+ matrix:
+ issue_number: ${{ fromJSON(needs.get_open_issues.outputs.issue_numbers) }}
+
+ steps:
+ - name: Log current issue being processed
+ run: |
+ echo "🔄 Processing issue #${{ matrix.issue_number }}"
+ echo "Total issues to process: ${{ needs.get_open_issues.outputs.total_count }}"
+
+ - name: Check if dry run mode
+ if: inputs.dry_run == true
+ run: |
+ echo "🔍 DRY RUN MODE: Would process issue #${{ matrix.issue_number }}"
+ echo "Skipping actual triage processing"
+
+ - name: Trigger triage workflow for issue
+ if: inputs.dry_run != true
+ uses: actions/github-script@v6
+ with:
+ script: |
+ const issueNumber = '${{ matrix.issue_number }}';
+
+ try {
+ console.log(`Triggering triage workflow for issue #${issueNumber}`);
+
+ const response = await github.rest.actions.createWorkflowDispatch({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ workflow_id: 'triage-agent.yml',
+ ref: 'main',
+ inputs: {
+ issue_number: issueNumber
+ }
+ });
+
+ console.log(`✅ Successfully triggered triage workflow for issue #${issueNumber}`);
+
+ } catch (error) {
+ console.error(`❌ Failed to trigger triage workflow for issue #${issueNumber}:`, error);
+ core.setFailed(`Failed to process issue #${issueNumber}: ${error.message}`);
+ }
+
+ - name: Wait for workflow completion
+ if: inputs.dry_run != true
+ run: |
+ echo "⏳ Waiting for triage workflow to complete for issue #${{ matrix.issue_number }}..."
+ echo "Timeout: ${{ vars.TRIAGE_AGENT_TIMEOUT }} seconds"
+ sleep ${{ vars.TRIAGE_AGENT_TIMEOUT }} # Wait for triage workflow completion
+
+ summary:
+ runs-on: ubuntu-latest
+ needs: [get_open_issues, process_issues]
+ if: always()
+
+ steps:
+ - name: Print summary
+ run: |
+ echo "## Triage Processing Summary"
+ echo "Total open issues found: ${{ needs.get_open_issues.outputs.total_count }}"
+
+ if [ "${{ inputs.dry_run }}" == "true" ]; then
+ echo "Mode: DRY RUN (no actual processing performed)"
+ else
+ echo "Mode: FULL PROCESSING"
+ fi
+
+ if [ "${{ needs.process_issues.result }}" == "success" ]; then
+ echo "✅ All issues processed successfully"
+ elif [ "${{ needs.process_issues.result }}" == "failure" ]; then
+ echo "❌ Some issues failed to process"
+ elif [ "${{ needs.process_issues.result }}" == "skipped" ]; then
+ echo "⏭️ Processing was skipped (no open issues found)"
+ else
+ echo "⚠️ Processing completed with status: ${{ needs.process_issues.result }}"
+ fi
diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
deleted file mode 100644
index 41c70a7e0..000000000
Binary files a/.mvn/wrapper/maven-wrapper.jar and /dev/null differ
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
index 56bb0164e..44f3cf2c1 100644
--- a/.mvn/wrapper/maven-wrapper.properties
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -1 +1,2 @@
-distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip
\ No newline at end of file
+distributionType=only-script
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip
diff --git a/com.microsoft.java.debug.core/.classpath b/com.microsoft.java.debug.core/.classpath
index 9ba41a249..b6fe6b96c 100644
--- a/com.microsoft.java.debug.core/.classpath
+++ b/com.microsoft.java.debug.core/.classpath
@@ -13,7 +13,7 @@
-
+
diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml
index 9faa391fb..8bfdb7292 100644
--- a/com.microsoft.java.debug.core/pom.xml
+++ b/com.microsoft.java.debug.core/pom.xml
@@ -5,7 +5,7 @@
com.microsoft.java
java-debug-parent
- 0.46.0
+ 0.53.2
com.microsoft.java.debug.core
jar
@@ -42,7 +42,7 @@
org.apache.commons
commons-lang3
- 3.6
+ 3.18.0
com.google.code.gson
@@ -62,7 +62,7 @@
commons-io
commons-io
- 2.11.0
+ 2.14.0
diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/Breakpoint.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/Breakpoint.java
index dfdbad4bb..d8316c2e3 100644
--- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/Breakpoint.java
+++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/Breakpoint.java
@@ -42,24 +42,28 @@ public class Breakpoint implements IBreakpoint {
private String condition = null;
private String logMessage = null;
private HashMap