Compare commits

...

10 Commits

Author SHA1 Message Date
Daz DeBoer 8b6cdb5f58 CI: add requireable aggregate/no-op checks for branch protection (#984)
Prepares CI so a small, stable set of **required status checks** can be
enabled (which in turn unlocks auto-merge), instead of having to list
every fanned-out matrix job. GitHub required checks match by exact name
— no wildcards — so this reduces the surface to a handful of high-level
checks.

## Changes

- **`ci-integ-test.yml`**: add an aggregate gate job
`integ-test-success` that `needs:` all four top-level jobs (the three
suite jobs each wrap a reusable workflow that fans out into many nested
checks) and fails if any did not succeed. `if: always()` ensures it
reports even when a dependency fails. This collapses dozens of nested
integ-test checks into a single requireable check.

- **`ci-init-script-check.yml`**: remove the workflow-level
`pull_request.paths` filter so the workflow runs on every PR and always
reports a status check (previously it was absent on most PRs, which
would deadlock a required check). Relevant-change detection moves into
the job via `tj-actions/changed-files` (same pinned action already used
by `ci-check-no-dist-update.yml`). On a PR the Java/Gradle/test steps
run only when init-script files changed; otherwise the job is a fast
no-op that still succeeds. Push and `workflow_dispatch` runs execute
fully as before.

## Suggested required-check set (all run on every PR, none can deadlock)

- `CI-check-and-unit-test / check-format-and-unit-test`
- `ci-validate-typings.yml / validate-typings`
- `CI-validate-wrappers / validation`
- `CI-codeql / Analyze (javascript-typescript)`
- `CI-integ-test / integ-test-success`
- `CI-init-script-check / test-init-scripts`

`ci-check-no-dist-update` is intentionally **omitted** — it only runs on
`dist/**` edits and is designed to fail, so it shouldn't be a required
gate.

> Confirm the exact check names from the list GitHub shows after this
branch runs once.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 11:04:23 -06:00
bot-githubaction 5852e0e5d8 [bot] Update dist directory 2026-06-10 16:15:39 +00:00
Simon Marquis 318eed7038 Hide obsolete Job summaries (#902)
- Injects a `<!-- gradle-job-summary: ${jobCorrelator} -->` marker on
each job summary
- Lists 100 last comments: unfortunately there is no API to specifically
filter for comments, and checking the last 100 comments (the limit) is
usually enough and does not require iterating over pages
- Mutate comments having this expected marker

I tried to add some tests, but I'm not familiar enough to setup a
complete test suite with proper mocking of GitHub/Octokit with jest.

I could potentially extract the `prComment` creation to check for the
marker presence, let me know.

Note: it seems like there is currently an issue on mutating comments as
`OUTDATED` through graphql. Although it does not work as expected
(flagging as OUTDATED) the comments are still minimized, which is what
we want.
- https://github.com/orgs/community/discussions/19865

Implements #176

---------

Co-authored-by: Daz DeBoer <daz@gradle.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 10:14:48 -06:00
Björn Kautler a740661292 Improve typings (#938)
This PR adds a missing enum value, and makes strings that are actually
delimited lists those lists, so that you for example in the generated
Kotlin bindings can simply do
```kotlin
additionalArguments = listOf(
    "--info",
    "--stacktrace",
    "--show-version"
)
```
instead of needing to do
```kotlin
additionalArguments = listOf(
    "--info",
    "--stacktrace",
    "--show-version"
).joinToString(" ")
```
or writing it all in one line as one string.

This is also how the typings for older versions are in the typing
catalog.

Theoretically, this is a breaking changes as the typings define the API
surface of the action and from the typings bindings are generated. I'll
leave it up to you how you handle it regarding version increase or when
to merge.
2026-06-10 08:54:56 -06:00
Bot Githubaction 7ae0d0208c Update gradle-actions-caching library to v0.6.0 (#982)
Updates to the latest gradle-actions-caching library.
2026-06-10 08:51:32 -06:00
Daz DeBoer e473973a5b Scope CI-integ-test concurrency groups per-branch
The concurrency groups used fixed names spanning all branches, so a push
to main could cancel a pending PR run (and vice versa), leaving PRs not
fully tested.

Append ${{ github.ref }} to each group so runs only supersede pending
runs on the same branch, while different branches run in parallel. Also
drop the `queue: max` key, which is not a valid GitHub Actions
concurrency option and was ignored.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 07:33:01 -07:00
Daz DeBoer 35a4a3f355 Queue up integ-test runs 2026-06-10 08:24:34 -06:00
bot-githubaction b6eebf33f1 [bot] Update dist directory 2026-06-10 14:15:10 +00:00
Daz DeBoer 9901393644 Remove unnecessary dependency overrides (#981)
Removes all `overrides` from `sources/package.json`. Two commits, each
independently verified:

## 1. Remove redundant security overrides

The `shell-quote`, `fast-xml-parser`, `fast-xml-builder` and `eslint >
brace-expansion` overrides added in #980 are **no-ops**: npm's natural
resolution already lands on the exact same patched versions, so they
upgrade nothing. The vulnerabilities were actually resolved by
regenerating the lockfile, not by the overrides.

## 2. Remove obsolete Octokit/Azure overrides

`@azure/logger`, `@octokit/request`, `@octokit/request-error` and
`@octokit/plugin-paginate-rest` were point-in-time pins added to
force-upgrade then-vulnerable transitive deps (5d947f45, #601). The
parent packages (`@actions/github`, `@actions/artifact`) have since
advanced and now resolve **newer, non-vulnerable** versions naturally —
so the overrides only pinned stale versions:

| Package | Pinned (override) | Natural |
|---|---|---|
| `@octokit/request` | 8.4.1 | 10.0.10 |
| `@octokit/request-error` | 5.1.1 | 7.1.0 |
| `@octokit/plugin-paginate-rest` | 9.2.2 | 14.0.0 |
| `@azure/logger` | 1.1.4 | 1.3.0 |

## Verification

- `npm audit` → **0 vulnerabilities**
- `./build` → passes
- `npm test` → **352/352 passing**

### Note on a flaky test
While testing I saw the `wrapper-validation` test *"fetches wrapper jar
checksums for snapshots"* intermittently fail (1–2 failures, then pass
on retry). It is a **pre-existing flaky network test** — it makes ~175
live calls to Gradle services and sits right at its 60s timeout. Its
code path imports neither Octokit nor Azure (`src/wrapper-validation/`
uses only `@actions/http-client`/`nock`/`cheerio`), so it is unrelated
to these overrides; the `nock`/`@mswjs/interceptors`/`undici` versions
are identical before and after.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 08:14:07 -06:00
Daz DeBoer 20ce680c89 Update RELEASING.md 2026-06-09 19:55:28 -06:00
26 changed files with 1023 additions and 806 deletions
+18 -4
View File
@@ -8,10 +8,6 @@ on:
paths-ignore:
- 'dist/**'
pull_request:
paths:
- '.github/workflows/ci-init-script-check.yml'
- 'sources/src/resources/init-scripts/**'
- 'sources/test/init-scripts/**'
workflow_dispatch:
permissions:
@@ -23,16 +19,34 @@ jobs:
steps:
- name: Checkout sources
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
fetch-depth: 0
# Detect whether anything relevant to the init-script tests changed.
# The workflow always runs (so it always reports a status check, making it safe
# to mark as required), but the heavy steps below are skipped on pull requests
# that don't touch the init-scripts. Pushes and manual runs always execute fully.
- name: Check for relevant changes
id: changes
if: github.event_name == 'pull_request'
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
files: |
.github/workflows/ci-init-script-check.yml
sources/src/resources/init-scripts/**
sources/test/init-scripts/**
- name: Setup Java
if: steps.changes.outputs.any_changed == 'true' || github.event_name != 'pull_request'
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: temurin
java-version: 17
- name: Setup Gradle
if: steps.changes.outputs.any_changed == 'true' || github.event_name != 'pull_request'
# Use a released version to avoid breakages
uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
env:
ALLOWED_GRADLE_WRAPPER_CHECKSUMS: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 # Invalid wrapper jar used for testing
- name: Run integration tests
if: steps.changes.outputs.any_changed == 'true' || github.event_name != 'pull_request'
working-directory: sources/test/init-scripts
run: ./gradlew check
+24 -3
View File
@@ -28,7 +28,7 @@ jobs:
needs: build-distribution
uses: ./.github/workflows/suite-integ-test-caching.yml
concurrency:
group: CI-integ-test-caching
group: CI-integ-test-caching-${{ github.ref }}
cancel-in-progress: false
with:
skip-dist: false
@@ -40,7 +40,7 @@ jobs:
needs: caching-integ-tests
uses: ./.github/workflows/suite-integ-test-other.yml
concurrency:
group: CI-integ-test-other
group: CI-integ-test-other-${{ github.ref }}
cancel-in-progress: false
with:
skip-dist: false
@@ -52,8 +52,29 @@ jobs:
needs: other-integ-tests
uses: ./.github/workflows/suite-integ-test-dependency-submission.yml
concurrency:
group: CI-integ-test-dependency-submission
group: CI-integ-test-dependency-submission-${{ github.ref }}
cancel-in-progress: false
with:
skip-dist: false
secrets: inherit
# Aggregate gate: a single check that succeeds only when all integ-test jobs succeed.
# Require this one check in branch protection instead of every fanned-out matrix job.
integ-test-success:
if: ${{ always() }}
needs:
- build-distribution
- caching-integ-tests
- other-integ-tests
- dependency-submission-integ-tests
runs-on: ubuntu-latest
steps:
- name: Fail if any integ-test job failed or was cancelled
if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
run: |
echo "One or more integ-test jobs did not succeed:"
echo " build-distribution: ${{ needs.build-distribution.result }}"
echo " caching-integ-tests: ${{ needs.caching-integ-tests.result }}"
echo " other-integ-tests: ${{ needs.other-integ-tests.result }}"
echo " dependency-submission-integ-tests: ${{ needs.dependency-submission-integ-tests.result }}"
exit 1
+4 -4
View File
@@ -11,16 +11,16 @@
- Note: The gradle actions follow the GitHub Actions convention of including a .0 patch number for the first release of a minor version, unlike the Gradle convention which omits the trailing .0.
## Release gradle/actions
- Create a tag for the release. The tag should have the format `v5.0.0`
- From CLI: `git tag -s -m "v5.0.0" v5.0.0 && git push --tags`
- Create a tag for the release. The tag should have the format `v6.2.0`
- From CLI: `git tag -s -m "v6.2.0" v6.2.0 && git push --tags`
- Note that we sign the tag and set the commit message for the tag to the newly released version.
- Go to https://github.com/gradle/actions/releases and "Draft new release"
- Use the newly created tag and copy the tag name exactly as the release title.
- Craft release notes content based on issues closed, PRs merged and commits
- Include a Full changelog link in the format https://github.com/gradle/actions/compare/v2.12.0...v3.0.0
- Publish the release.
- Force push the `v5` tag (or current major version) to point to the new release. It is conventional for users to bind to a major release version using this tag.
- From CLI: `git tag -f -s -a -m "v5.0.0" v5 && git push -f --tags`
- Force push the `v6` tag (or current major version) to point to the new release. It is conventional for users to bind to a major release version using this tag.
- From CLI: `git tag -f -s -a -m "v6.2.0" v6 && git push -f --tags`
- Note that we sign the tag and set the commit message for the tag to the newly released version.
- Your HEAD must point at the commit to be tagged.
+9 -3
View File
@@ -8,10 +8,16 @@ inputs:
type: string
dependency-resolution-task:
type: string
type: list
separator: ' '
list-item:
type: string
additional-arguments:
type: string
type: list
separator: ' '
list-item:
type: string
# Cache configuration
cache-provider:
@@ -115,7 +121,7 @@ inputs:
build-scan-terms-of-use-agree:
type: enum
allowed-values:
- 'yes'
- yes
develocity-access-key:
type: string
+140 -125
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+137 -106
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+139 -124
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+192 -160
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+76 -62
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+5
View File
@@ -548,6 +548,11 @@ jobs:
- run: ./gradlew build --scan
```
When a comment is added, any earlier Job Summary comments posted by the same job on that Pull Request are
automatically minimized, so only the most recent result remains expanded. This also applies when
`add-job-summary-as-pr-comment: 'on-failure'` is used: once a later run of the job succeeds, the previous
failure comment is collapsed.
Note that to add a Pull Request comment, the workflow must be configured with the `pull-requests: write` permission.
+6 -2
View File
@@ -69,6 +69,7 @@ inputs:
- disabled
- generate
- generate-and-submit
- generate-submit-and-upload
- generate-and-upload
- download-and-submit
@@ -106,7 +107,7 @@ inputs:
build-scan-terms-of-use-agree:
type: enum
allowed-values:
- 'yes'
- yes
develocity-access-key:
type: string
@@ -153,7 +154,10 @@ inputs:
# Deprecated action inputs
arguments:
type: string
type: list
separator: ' '
list-item:
type: string
# Experimental action inputs
gradle-home-cache-strict-match:
+125 -172
View File
@@ -92,6 +92,19 @@
"node": ">= 20"
}
},
"node_modules/@actions/artifact/node_modules/@octokit/endpoint": {
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz",
"integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0",
"universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@actions/artifact/node_modules/@octokit/graphql": {
"version": "9.0.3",
"license": "MIT",
@@ -129,6 +142,35 @@
"@octokit/core": ">=7"
}
},
"node_modules/@actions/artifact/node_modules/@octokit/request": {
"version": "10.0.10",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.10.tgz",
"integrity": "sha512-KxNC2pTqqhszMNrf12ZRd4PonRgyJdsM4F/jySiddQK+DsRcfBtUvqn8t7UsyZhnRJHvX46OohDt5N3VqIWC2w==",
"license": "MIT",
"dependencies": {
"@octokit/endpoint": "^11.0.3",
"@octokit/request-error": "^7.0.2",
"@octokit/types": "^16.0.0",
"content-type": "^2.0.0",
"json-with-bigint": "^3.5.3",
"universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@actions/artifact/node_modules/@octokit/request-error": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz",
"integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@actions/artifact/node_modules/before-after-hook": {
"version": "4.0.0",
"license": "Apache-2.0"
@@ -227,6 +269,19 @@
"node": ">= 20"
}
},
"node_modules/@actions/github/node_modules/@octokit/endpoint": {
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz",
"integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0",
"universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@actions/github/node_modules/@octokit/graphql": {
"version": "9.0.3",
"license": "MIT",
@@ -239,6 +294,21 @@
"node": ">= 20"
}
},
"node_modules/@actions/github/node_modules/@octokit/plugin-paginate-rest": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz",
"integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0"
},
"engines": {
"node": ">= 20"
},
"peerDependencies": {
"@octokit/core": ">=6"
}
},
"node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "17.0.0",
"license": "MIT",
@@ -252,6 +322,35 @@
"@octokit/core": ">=6"
}
},
"node_modules/@actions/github/node_modules/@octokit/request": {
"version": "10.0.10",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.10.tgz",
"integrity": "sha512-KxNC2pTqqhszMNrf12ZRd4PonRgyJdsM4F/jySiddQK+DsRcfBtUvqn8t7UsyZhnRJHvX46OohDt5N3VqIWC2w==",
"license": "MIT",
"dependencies": {
"@octokit/endpoint": "^11.0.3",
"@octokit/request-error": "^7.0.2",
"@octokit/types": "^16.0.0",
"content-type": "^2.0.0",
"json-with-bigint": "^3.5.3",
"universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@actions/github/node_modules/@octokit/request-error": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz",
"integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^16.0.0"
},
"engines": {
"node": ">= 20"
}
},
"node_modules/@actions/github/node_modules/before-after-hook": {
"version": "4.0.0",
"license": "Apache-2.0"
@@ -520,13 +619,16 @@
}
},
"node_modules/@azure/logger": {
"version": "1.1.4",
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.3.0.tgz",
"integrity": "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==",
"license": "MIT",
"dependencies": {
"@typespec/ts-http-runtime": "^0.3.0",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=18.0.0"
"node": ">=20.0.0"
}
},
"node_modules/@azure/storage-blob": {
@@ -1793,167 +1895,10 @@
],
"license": "MIT"
},
"node_modules/@octokit/auth-token": {
"version": "4.0.0",
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/core": {
"version": "5.2.1",
"license": "MIT",
"peer": true,
"dependencies": {
"@octokit/auth-token": "^4.0.0",
"@octokit/graphql": "^7.1.0",
"@octokit/request": "^8.4.1",
"@octokit/request-error": "^5.1.1",
"@octokit/types": "^13.0.0",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/core/node_modules/@octokit/openapi-types": {
"version": "24.2.0",
"license": "MIT",
"peer": true
},
"node_modules/@octokit/core/node_modules/@octokit/types": {
"version": "13.10.0",
"license": "MIT",
"peer": true,
"dependencies": {
"@octokit/openapi-types": "^24.2.0"
}
},
"node_modules/@octokit/endpoint": {
"version": "9.0.6",
"license": "MIT",
"dependencies": {
"@octokit/types": "^13.1.0",
"universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": {
"version": "24.2.0",
"license": "MIT"
},
"node_modules/@octokit/endpoint/node_modules/@octokit/types": {
"version": "13.10.0",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^24.2.0"
}
},
"node_modules/@octokit/graphql": {
"version": "7.1.1",
"license": "MIT",
"peer": true,
"dependencies": {
"@octokit/request": "^8.4.1",
"@octokit/types": "^13.0.0",
"universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/graphql/node_modules/@octokit/openapi-types": {
"version": "24.2.0",
"license": "MIT",
"peer": true
},
"node_modules/@octokit/graphql/node_modules/@octokit/types": {
"version": "13.10.0",
"license": "MIT",
"peer": true,
"dependencies": {
"@octokit/openapi-types": "^24.2.0"
}
},
"node_modules/@octokit/openapi-types": {
"version": "27.0.0",
"license": "MIT"
},
"node_modules/@octokit/plugin-paginate-rest": {
"version": "9.2.2",
"license": "MIT",
"dependencies": {
"@octokit/types": "^12.6.0"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": "5"
}
},
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
"version": "20.0.0",
"license": "MIT"
},
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
"version": "12.6.0",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^20.0.0"
}
},
"node_modules/@octokit/request": {
"version": "8.4.1",
"license": "MIT",
"dependencies": {
"@octokit/endpoint": "^9.0.6",
"@octokit/request-error": "^5.1.1",
"@octokit/types": "^13.1.0",
"universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/request-error": {
"version": "5.1.1",
"license": "MIT",
"dependencies": {
"@octokit/types": "^13.1.0",
"deprecation": "^2.0.0",
"once": "^1.4.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": {
"version": "24.2.0",
"license": "MIT"
},
"node_modules/@octokit/request-error/node_modules/@octokit/types": {
"version": "13.10.0",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^24.2.0"
}
},
"node_modules/@octokit/request/node_modules/@octokit/openapi-types": {
"version": "24.2.0",
"license": "MIT"
},
"node_modules/@octokit/request/node_modules/@octokit/types": {
"version": "13.10.0",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^24.2.0"
}
},
"node_modules/@octokit/types": {
"version": "16.0.0",
"license": "MIT",
@@ -3210,11 +3155,6 @@
],
"license": "MIT"
},
"node_modules/before-after-hook": {
"version": "2.2.3",
"license": "Apache-2.0",
"peer": true
},
"node_modules/binary": {
"version": "0.3.0",
"license": "MIT",
@@ -3640,6 +3580,19 @@
"version": "0.0.1",
"license": "MIT"
},
"node_modules/content-type": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz",
"integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/convert-source-map": {
"version": "2.0.0",
"dev": true,
@@ -3848,10 +3801,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/deprecation": {
"version": "2.3.1",
"license": "ISC"
},
"node_modules/detect-newline": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
@@ -6246,6 +6195,12 @@
"dev": true,
"license": "ISC"
},
"node_modules/json-with-bigint": {
"version": "3.5.8",
"resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.8.tgz",
"integrity": "sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw==",
"license": "MIT"
},
"node_modules/json5": {
"version": "2.2.3",
"dev": true,
@@ -6803,6 +6758,7 @@
},
"node_modules/once": {
"version": "1.4.0",
"dev": true,
"license": "ISC",
"dependencies": {
"wrappy": "1"
@@ -8385,10 +8341,6 @@
"version": "1.0.6",
"license": "MIT"
},
"node_modules/universal-user-agent": {
"version": "6.0.1",
"license": "ISC"
},
"node_modules/unrs-resolver": {
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz",
@@ -8714,6 +8666,7 @@
},
"node_modules/wrappy": {
"version": "1.0.2",
"dev": true,
"license": "ISC"
},
"node_modules/write-file-atomic": {
-12
View File
@@ -68,17 +68,5 @@
"prettier": "3.8.4",
"ts-jest": "29.4.11",
"typescript": "5.9.3"
},
"overrides": {
"@azure/logger": "1.1.4",
"@octokit/request": "8.4.1",
"@octokit/request-error": "5.1.1",
"@octokit/plugin-paginate-rest": "9.2.2",
"shell-quote": "1.8.4",
"fast-xml-parser": "5.8.0",
"fast-xml-builder": "1.2.0",
"eslint": {
"brace-expansion": "5.0.6"
}
}
}
+4
View File
@@ -206,6 +206,10 @@ export class SummaryConfig {
return this.shouldAddJobSummary(this.getJobSummaryOption(), hasFailure)
}
canAddPRComment(): boolean {
return this.getPRCommentOption() !== JobSummaryOption.Never
}
shouldAddPRComment(hasFailure: boolean): boolean {
return this.shouldAddJobSummary(this.getPRCommentOption(), hasFailure)
}
+82 -2
View File
@@ -2,7 +2,7 @@ import * as core from '@actions/core'
import * as github from '@actions/github'
import {BuildResult} from './build-results'
import {SummaryConfig, getActionId, getGithubToken} from './configuration'
import {DependencyGraphConfig, getActionId, getGithubToken, getJobMatrix, SummaryConfig} from './configuration'
import {Deprecation, getDeprecations, getErrors} from './deprecation-collector'
export async function generateJobSummary(
@@ -33,6 +33,10 @@ export async function generateJobSummary(
core.info('============================')
}
if (config.canAddPRComment()) {
await minimizeObsoletePRComments()
}
if (config.shouldAddPRComment(hasFailure)) {
await addPRComment(summaryTable)
}
@@ -48,7 +52,8 @@ async function addPRComment(jobSummary: string): Promise<void> {
const pull_request_number = context.payload.pull_request.number
core.info(`Adding Job Summary as comment to PR #${pull_request_number}.`)
const prComment = `<h3>Job Summary for Gradle</h3>
const prComment = `${jobMarker(context)}
<h3>Job Summary for Gradle</h3>
<a href="${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}" target="_blank">
<h5>${context.workflow} :: <em>${context.job}</em></h5>
</a>
@@ -57,6 +62,7 @@ ${jobSummary}`
const github_token = getGithubToken()
const octokit = github.getOctokit(github_token)
try {
await octokit.rest.issues.createComment({
...context.repo,
@@ -201,3 +207,77 @@ function truncateString(str: string, maxLength: number): string {
return str
}
}
async function minimizeObsoletePRComments(): Promise<void> {
const context = github.context
if (context.payload.pull_request == null) {
core.info('No pull_request trigger detected: not minimizing obsolete PR comments')
return
}
const prNumber = context.payload.pull_request.number
core.info(`Minimizing obsolete Job Summary comments on PR #${prNumber}.`)
const marker = jobMarker(context)
const octokit = github.getOctokit(getGithubToken())
const {owner, repo} = context.repo
const query = `
query($owner: String!, $repo: String!, $prNumber: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $prNumber) {
comments(last: 100) {
nodes { id body isMinimized url }
}
}
}
}
`
let comments: PullRequestComment[]
try {
const {repository} = await octokit.graphql<CommentsQueryResult>(query, {owner, repo, prNumber})
comments = repository.pullRequest?.comments?.nodes?.filter((c): c is PullRequestComment => c !== null) ?? []
} catch (error) {
return core.warning(`Failed to fetch comments: ${error}`)
}
const mutation = `
mutation($id: ID!) {
minimizeComment(input: {subjectId: $id, classifier: OUTDATED}) {
clientMutationId
}
}
`
const commentsToMinimize = comments
.filter(c => !c.isMinimized && c.body.includes(marker))
.map(async c =>
octokit
.graphql(mutation, {id: c.id})
.then(() => core.info(`Successfully minimized (id:${c.id}, url:${c.url})`))
.catch(e => core.warning(`Failed to minimize (id:${c.id}, url:${c.url}, error:${e?.message || e})`))
)
await Promise.allSettled(commentsToMinimize)
}
export function jobMarker(context: typeof github.context): string {
const jobCorrelator = DependencyGraphConfig.constructJobCorrelator(context.workflow, context.job, getJobMatrix())
return `<!-- gradle-job-summary: ${jobCorrelator} -->`
}
interface PullRequestComment {
id: string
body: string
isMinimized: boolean
url: string
}
interface CommentsQueryResult {
repository: {
pullRequest?: {
comments?: {
nodes?: (PullRequestComment | null)[] | null
} | null
} | null
}
}
+33 -2
View File
@@ -1,8 +1,15 @@
import dedent from 'dedent'
import {describe, expect, it} from '@jest/globals'
import * as github from '@actions/github'
import {afterEach, describe, expect, it} from '@jest/globals'
import {BuildResult} from '../../src/build-results'
import {renderSummaryTable} from '../../src/job-summary'
import {jobMarker, renderSummaryTable} from '../../src/job-summary'
const MATRIX_INPUT_ENV = 'INPUT_WORKFLOW-JOB-CONTEXT'
function fakeContext(workflow: string, job: string): typeof github.context {
return {workflow, job} as unknown as typeof github.context
}
const successfulHelpBuild: BuildResult = {
rootProjectName: 'root',
@@ -177,3 +184,27 @@ describe('renderSummaryTable', () => {
})
})
})
describe('jobMarker', () => {
const original = process.env[MATRIX_INPUT_ENV]
afterEach(() => {
if (original === undefined) {
delete process.env[MATRIX_INPUT_ENV]
} else {
process.env[MATRIX_INPUT_ENV] = original
}
})
it('builds a hidden marker from the workflow and job', () => {
process.env[MATRIX_INPUT_ENV] = 'null'
const marker = jobMarker(fakeContext('CI', 'build'))
expect(marker).toBe('<!-- gradle-job-summary: ci-build -->')
})
it('includes the job matrix in the marker', () => {
process.env[MATRIX_INPUT_ENV] = JSON.stringify({os: 'ubuntu', java: '17'})
const marker = jobMarker(fakeContext('CI', 'build'))
expect(marker).toBe('<!-- gradle-job-summary: ci-build-ubuntu-17 -->')
})
})
+1 -1
View File
@@ -18,7 +18,7 @@ export declare interface CacheOptions {
writeOnly: boolean;
overwriteExisting: boolean;
strictMatch: boolean;
cleanup: string;
cleanup: 'always' | 'on-success' | 'never';
encryptionKey?: string;
includes: string[];
excludes: string[];
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "gradle-actions-caching",
"version": "0.3.0",
"version": "0.6.0",
"type": "module",
"main": "./index.js",
"types": "./index.d.ts",
+1 -1
View File
@@ -5,7 +5,7 @@
"toolPackages": [
{
"packageName": "@microsoft/api-extractor",
"packageVersion": "7.57.6"
"packageVersion": "7.58.8"
}
]
}
+4 -1
View File
@@ -14,4 +14,7 @@ inputs:
outputs:
failed-wrapper:
type: string
type: list
separator: '|'
list-item:
type: string