1
0

Add an option to disable Java problem matchers (#1133)

* Add problem matcher opt-out

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 38eb7886-7ea3-4e4d-8d5f-e3f975135053

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Bruno Borges
2026-07-16 11:28:10 -04:00
committed by GitHub
parent 6e2e32e729
commit e40a8e0642
9 changed files with 101 additions and 25 deletions
+3 -1
View File
@@ -53,6 +53,8 @@ For more details, see the full release notes on the [releases page](https://git
- `set-default`: Set to `false` to install a JDK without making it the default. When `false`, `JAVA_HOME` and `PATH` are not updated, but `JAVA_HOME_<major>_<arch>` is still set so the JDK remains discoverable. Default value: `true`. See [Installing JDK without setting as default](docs/advanced-usage.md#Installing-JDK-without-setting-as-default) for more details. - `set-default`: Set to `false` to install a JDK without making it the default. When `false`, `JAVA_HOME` and `PATH` are not updated, but `JAVA_HOME_<major>_<arch>` is still set so the JDK remains discoverable. Default value: `true`. See [Installing JDK without setting as default](docs/advanced-usage.md#Installing-JDK-without-setting-as-default) for more details.
- `problem-matcher`: Set to `false` to disable Java problem matcher annotations (compiler diagnostics and uncaught exceptions). Default value: `true`. See [Java problem matcher](docs/advanced-usage.md#java-problem-matcher-compiler-annotations) for details and annotation limits.
- `verify-signature`: Verifies downloaded Java package signatures when supported by the selected distribution. Currently supported for `temurin` and `microsoft`. If set to `true` for unsupported distributions, the action fails. - `verify-signature`: Verifies downloaded Java package signatures when supported by the selected distribution. Currently supported for `temurin` and `microsoft`. If set to `true` for unsupported distributions, the action fails.
- `verify-signature-public-key`: ASCII-armored GPG public key used to verify the downloaded package signature. Overrides the default bundled key for the selected distribution. - `verify-signature-public-key`: ASCII-armored GPG public key used to verify the downloaded package signature. Overrides the default bundled key for the selected distribution.
@@ -208,7 +210,7 @@ steps:
cache: 'maven' cache: 'maven'
cache-dependency-path: 'sub-project/pom.xml' # optional cache-dependency-path: 'sub-project/pom.xml' # optional
- name: Build with Maven - name: Build with Maven
run: mvn -B package --file pom.xml run: mvn package --file pom.xml
``` ```
> [!NOTE] > [!NOTE]
+44
View File
@@ -0,0 +1,44 @@
import {afterEach, beforeEach, describe, expect, it, jest} from '@jest/globals';
const mockGetInput = jest.fn<(...args: any[]) => any>();
const mockInfo = jest.fn<(...args: any[]) => any>();
const mockDebug = jest.fn<(...args: any[]) => any>();
jest.unstable_mockModule('@actions/core', () => ({
getInput: mockGetInput,
info: mockInfo,
debug: mockDebug,
warning: jest.fn(),
setSecret: jest.fn()
}));
const {configureProblemMatcher} = await import('../src/problem-matcher.js');
const {INPUT_PROBLEM_MATCHER} = await import('../src/constants.js');
describe('configureProblemMatcher', () => {
let inputs: Record<string, string>;
beforeEach(() => {
inputs = {};
mockGetInput.mockImplementation((name: string) => inputs[name] ?? '');
});
afterEach(() => {
jest.resetAllMocks();
});
it('registers the Java problem matcher by default', () => {
configureProblemMatcher('/matchers/java.json');
expect(mockInfo).toHaveBeenCalledWith('##[add-matcher]/matchers/java.json');
});
it('does not register the Java problem matcher when disabled', () => {
inputs[INPUT_PROBLEM_MATCHER] = 'false';
configureProblemMatcher('/matchers/java.json');
expect(mockInfo).not.toHaveBeenCalled();
expect(mockDebug).toHaveBeenCalledWith('Java problem matcher is disabled');
});
});
+4
View File
@@ -94,6 +94,10 @@ inputs:
description: 'Whether Maven should print artifact download/transfer progress to the build log. When "false" (default) the action sets "-ntp" (--no-transfer-progress) in MAVEN_ARGS to produce cleaner logs. Set to "true" to keep the progress output. Has no effect on non-Maven builds.' description: 'Whether Maven should print artifact download/transfer progress to the build log. When "false" (default) the action sets "-ntp" (--no-transfer-progress) in MAVEN_ARGS to produce cleaner logs. Set to "true" to keep the progress output. Has no effect on non-Maven builds.'
required: false required: false
default: false default: false
problem-matcher:
description: 'Whether to register the Java problem matcher (compiler errors/warnings and uncaught exceptions). Set to "false" to disable annotations.'
required: false
default: true
outputs: outputs:
distribution: distribution:
description: 'Distribution of Java that has been installed' description: 'Distribution of Java that has been installed'
+1
View File
@@ -95924,6 +95924,7 @@ const INPUT_JDK_FILE = 'jdk-file';
const INPUT_JDK_FILE_DEPRECATED = 'jdkFile'; const INPUT_JDK_FILE_DEPRECATED = 'jdkFile';
const INPUT_CHECK_LATEST = 'check-latest'; const INPUT_CHECK_LATEST = 'check-latest';
const INPUT_SET_DEFAULT = 'set-default'; const INPUT_SET_DEFAULT = 'set-default';
const INPUT_PROBLEM_MATCHER = 'problem-matcher';
const INPUT_VERIFY_SIGNATURE = 'verify-signature'; const INPUT_VERIFY_SIGNATURE = 'verify-signature';
const INPUT_VERIFY_SIGNATURE_PUBLIC_KEY = 'verify-signature-public-key'; const INPUT_VERIFY_SIGNATURE_PUBLIC_KEY = 'verify-signature-public-key';
const INPUT_SERVER_ID = 'server-id'; const INPUT_SERVER_ID = 'server-id';
+16 -1
View File
@@ -73283,6 +73283,7 @@ const INPUT_JDK_FILE = 'jdk-file';
const INPUT_JDK_FILE_DEPRECATED = 'jdkFile'; const INPUT_JDK_FILE_DEPRECATED = 'jdkFile';
const INPUT_CHECK_LATEST = 'check-latest'; const INPUT_CHECK_LATEST = 'check-latest';
const INPUT_SET_DEFAULT = 'set-default'; const INPUT_SET_DEFAULT = 'set-default';
const INPUT_PROBLEM_MATCHER = 'problem-matcher';
const INPUT_VERIFY_SIGNATURE = 'verify-signature'; const INPUT_VERIFY_SIGNATURE = 'verify-signature';
const INPUT_VERIFY_SIGNATURE_PUBLIC_KEY = 'verify-signature-public-key'; const INPUT_VERIFY_SIGNATURE_PUBLIC_KEY = 'verify-signature-public-key';
const INPUT_SERVER_ID = 'server-id'; const INPUT_SERVER_ID = 'server-id';
@@ -133988,6 +133989,19 @@ function configureMavenArgs() {
`Set '${INPUT_SHOW_DOWNLOAD_PROGRESS}: true' to keep the download progress output.`); `Set '${INPUT_SHOW_DOWNLOAD_PROGRESS}: true' to keep the download progress output.`);
} }
;// CONCATENATED MODULE: ./src/problem-matcher.ts
function configureProblemMatcher(matcherPath) {
const problemMatcherEnabled = util_getBooleanInput(INPUT_PROBLEM_MATCHER, true);
if (!problemMatcherEnabled) {
core_debug('Java problem matcher is disabled');
return;
}
info(`##[add-matcher]${matcherPath}`);
}
;// CONCATENATED MODULE: ./src/setup-java.ts ;// CONCATENATED MODULE: ./src/setup-java.ts
@@ -134000,6 +134014,7 @@ function configureMavenArgs() {
async function run() { async function run() {
try { try {
const versions = getMultilineInput(INPUT_JAVA_VERSION); const versions = getMultilineInput(INPUT_JAVA_VERSION);
@@ -134073,7 +134088,7 @@ async function run() {
} }
endGroup(); endGroup();
const matchersPath = external_path_.join(external_path_.dirname((0,external_url_.fileURLToPath)(import.meta.url)), '..', '..', '.github'); const matchersPath = external_path_.join(external_path_.dirname((0,external_url_.fileURLToPath)(import.meta.url)), '..', '..', '.github');
info(`##[add-matcher]${external_path_.join(matchersPath, 'java.json')}`); configureProblemMatcher(external_path_.join(matchersPath, 'java.json'));
await configureAuthentication(); await configureAuthentication();
configureMavenArgs(); configureMavenArgs();
if (cache && isCacheFeatureAvailable()) { if (cache && isCacheFeatureAvailable()) {
+16 -22
View File
@@ -355,9 +355,9 @@ steps:
java-version: '25' java-version: '25'
cache: 'maven' cache: 'maven'
- name: Seed the Maven cache - name: Seed the Maven cache
run: mvn -B dependency:go-offline dependency:resolve-plugins run: mvn dependency:go-offline dependency:resolve-plugins
- name: Build with Maven - name: Build with Maven
run: mvn -B verify --file pom.xml run: mvn verify --file pom.xml
``` ```
Separate seed job — useful for a matrix where different legs run different goals Separate seed job — useful for a matrix where different legs run different goals
@@ -378,7 +378,7 @@ jobs:
java-version: '25' java-version: '25'
cache: 'maven' cache: 'maven'
- name: Seed the Maven cache - name: Seed the Maven cache
run: mvn -B dependency:go-offline dependency:resolve-plugins run: mvn dependency:go-offline dependency:resolve-plugins
build: build:
needs: seed-cache needs: seed-cache
@@ -394,7 +394,7 @@ jobs:
java-version: '25' java-version: '25'
cache: 'maven' cache: 'maven'
- name: Build - name: Build
run: mvn -B ${{ matrix.goal }} --file pom.xml run: mvn ${{ matrix.goal }} --file pom.xml
``` ```
### Caveats ### Caveats
@@ -410,7 +410,7 @@ jobs:
Profile-gated plugins, conditionally-active modules, and artifacts a plugin Profile-gated plugins, conditionally-active modules, and artifacts a plugin
fetches at execution time may still be missed. For the most complete cache, fetches at execution time may still be missed. For the most complete cache,
seed with the fullest goal set your CI actually uses (for example seed with the fullest goal set your CI actually uses (for example
`mvn -B verify` with every profile enabled). `mvn verify` with every profile enabled).
- **Multi-module projects:** run the seed at the reactor root so every module's - **Multi-module projects:** run the seed at the reactor root so every module's
plugins are resolved. plugins are resolved.
@@ -585,7 +585,7 @@ jobs:
java-version: '11' java-version: '11'
- name: Build with Maven - name: Build with Maven
run: mvn -B package --file pom.xml run: mvn package --file pom.xml
- name: Publish to GitHub Packages Apache Maven - name: Publish to GitHub Packages Apache Maven
run: mvn deploy run: mvn deploy
@@ -743,7 +743,7 @@ jobs:
settings-path: ${{ github.workspace }} # location for the settings.xml file settings-path: ${{ github.workspace }} # location for the settings.xml file
- name: Build with Maven - name: Build with Maven
run: mvn -B package --file pom.xml run: mvn package --file pom.xml
- name: Publish to GitHub Packages Apache Maven - name: Publish to GitHub Packages Apache Maven
run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml
@@ -773,26 +773,27 @@ jobs:
show-download-progress: true # keep Maven download/transfer progress in the logs show-download-progress: true # keep Maven download/transfer progress in the logs
- name: Build with Maven - name: Build with Maven
run: mvn -B package --file pom.xml run: mvn package --file pom.xml
``` ```
***NOTES***: ***NOTES***:
- `MAVEN_ARGS` is honored by Maven 3.9.0+ and the Maven Wrapper (`mvnw`). Older Maven versions ignore it, so on those you can pass `--no-transfer-progress` on the command line instead. - `MAVEN_ARGS` is honored by Maven 3.9.0+ and the Maven Wrapper (`mvnw`). Older Maven versions ignore it, so on those you can pass `--no-transfer-progress` on the command line instead.
- This setting only affects Maven. It has no effect on Gradle, sbt, or other build tools. - This setting only affects Maven. It has no effect on Gradle, sbt, or other build tools.
- `-ntp` only controls transfer/progress output; it does not change whether Maven runs in batch mode. Use `-B`/`--batch-mode` (or `<interactiveMode>false</interactiveMode>` in `settings.xml`) if you also want non-interactive runs. - `-ntp` only controls transfer/progress output. The `settings.xml` generated by `setup-java` separately sets `<interactiveMode>false</interactiveMode>`. If you use `overwrite-settings: false`, ensure your existing settings disable interactive mode or pass `-B`/`--batch-mode`.
## Java problem matcher (compiler annotations) ## Java problem matcher (compiler annotations)
`setup-java` registers a [problem matcher](https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md) for Java after installing the JDK. It scans the log output of subsequent steps and turns `javac` diagnostics into GitHub [annotations](https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#setting-a-warning-message) that appear in the run summary and inline on the affected files. It matches two kinds of lines: By default, `setup-java` registers a [problem matcher](https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md) for Java after installing the JDK. It scans the log output of subsequent steps and turns Java diagnostics into GitHub [annotations](https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#setting-a-warning-message) that appear in the run summary and inline on the affected files. It matches three kinds of lines:
- Compiler errors and warnings, e.g. `App.java:12: error: cannot find symbol` (owner `javac`). - Compiler errors and warnings, e.g. `App.java:12: error: cannot find symbol` (owner `javac`).
- Maven compiler errors and warnings, e.g. `[ERROR] /path/App.java:[12,5] cannot find symbol` (owner `maven-javac`).
- Uncaught-exception header lines, e.g. `Exception in thread "main" ...`; because these lines have no file or line captures, they appear as log/run-level annotations rather than inline file annotations (owner `java`). - Uncaught-exception header lines, e.g. `Exception in thread "main" ...`; because these lines have no file or line captures, they appear as log/run-level annotations rather than inline file annotations (owner `java`).
This is enabled by default and requires no configuration. GitHub Actions limits problem matcher annotations to 10 of each severity per step and 50 annotations per job. Additional diagnostics remain available in the build log. Log grouping does not change these limits because every matched diagnostic still counts as an annotation.
### Disabling the problem matcher ### Disabling the problem matcher
There is no action input to turn the matcher off, but you can disable it for the rest of the job with the built-in [`remove-matcher`](https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md#remove-a-problem-matcher) workflow command. Pass the matcher **owner** (not a file name); the Java matcher defines two owners, `javac` and `java`, so remove both to fully suppress it: Set `problem-matcher` to `false` to prevent the matcher from being registered:
```yaml ```yaml
jobs: jobs:
@@ -805,19 +806,13 @@ jobs:
with: with:
distribution: '<distribution>' distribution: '<distribution>'
java-version: '21' java-version: '21'
problem-matcher: false
- name: Disable the Java problem matcher
run: |
echo "::remove-matcher owner=javac::"
echo "::remove-matcher owner=java::"
- name: Build with Maven - name: Build with Maven
run: mvn -B package --file pom.xml run: mvn package --file pom.xml
``` ```
***NOTES***: Disabling the matcher only stops annotations from being created. Compiler output remains in the log, and compilation errors still fail the build step.
- `remove-matcher` only stops annotations from being created; the underlying compiler output is unchanged, so a failing `javac`/build still fails the step.
- The command is scoped to the job, so add the step right after `setup-java` (and before your build) in every job where you want the matcher disabled.
## Publishing using Gradle ## Publishing using Gradle
```yaml ```yaml
@@ -1131,4 +1126,3 @@ Notes and caveats:
- Prefer giving the certificate a stable, descriptive `-alias` so re-runs are idempotent (re-importing the same alias will fail; add `keytool -delete -alias internal-ca ...` first if you re-run within a long-lived runner). - Prefer giving the certificate a stable, descriptive `-alias` so re-runs are idempotent (re-importing the same alias will fail; add `keytool -delete -alias internal-ca ...` first if you re-run within a long-lived runner).
This documents the post-install workflow; there is no dedicated action input for supplying a custom `cacerts` file. This documents the post-install workflow; there is no dedicated action input for supplying a custom `cacerts` file.
+1
View File
@@ -8,6 +8,7 @@ export const INPUT_JDK_FILE = 'jdk-file';
export const INPUT_JDK_FILE_DEPRECATED = 'jdkFile'; export const INPUT_JDK_FILE_DEPRECATED = 'jdkFile';
export const INPUT_CHECK_LATEST = 'check-latest'; export const INPUT_CHECK_LATEST = 'check-latest';
export const INPUT_SET_DEFAULT = 'set-default'; export const INPUT_SET_DEFAULT = 'set-default';
export const INPUT_PROBLEM_MATCHER = 'problem-matcher';
export const INPUT_VERIFY_SIGNATURE = 'verify-signature'; export const INPUT_VERIFY_SIGNATURE = 'verify-signature';
export const INPUT_VERIFY_SIGNATURE_PUBLIC_KEY = 'verify-signature-public-key'; export const INPUT_VERIFY_SIGNATURE_PUBLIC_KEY = 'verify-signature-public-key';
export const INPUT_SERVER_ID = 'server-id'; export const INPUT_SERVER_ID = 'server-id';
+14
View File
@@ -0,0 +1,14 @@
import * as core from '@actions/core';
import {INPUT_PROBLEM_MATCHER} from './constants.js';
import {getBooleanInput} from './util.js';
export function configureProblemMatcher(matcherPath: string): void {
const problemMatcherEnabled = getBooleanInput(INPUT_PROBLEM_MATCHER, true);
if (!problemMatcherEnabled) {
core.debug('Java problem matcher is disabled');
return;
}
core.info(`##[add-matcher]${matcherPath}`);
}
+2 -1
View File
@@ -14,6 +14,7 @@ import {fileURLToPath} from 'url';
import {getJavaDistribution} from './distributions/distribution-factory.js'; import {getJavaDistribution} from './distributions/distribution-factory.js';
import {JavaInstallerOptions} from './distributions/base-models.js'; import {JavaInstallerOptions} from './distributions/base-models.js';
import {configureMavenArgs} from './maven-args.js'; import {configureMavenArgs} from './maven-args.js';
import {configureProblemMatcher} from './problem-matcher.js';
async function run() { async function run() {
try { try {
@@ -120,7 +121,7 @@ async function run() {
'..', '..',
'.github' '.github'
); );
core.info(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); configureProblemMatcher(path.join(matchersPath, 'java.json'));
await auth.configureAuthentication(); await auth.configureAuthentication();
configureMavenArgs(); configureMavenArgs();