From 53b391fa2d87de6310c721a52cdae2dc1ad76385 Mon Sep 17 00:00:00 2001 From: Nicolas Dubois Date: Thu, 23 Oct 2025 16:52:10 +0200 Subject: [PATCH 1/6] fix: add support for JDK >17 --- src/releases.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/releases.ts b/src/releases.ts index fde6639..ff8ca06 100644 --- a/src/releases.ts +++ b/src/releases.ts @@ -44,6 +44,10 @@ export class Releases { // Versions after v1.24.0 require JDK 17+ return (await this.getReleaseDataByName('v1.24.0'))!; } + if (javaVersion < 21) { + // Versions after v1.28.0 require JDK 21+ + return (await this.getReleaseDataByName('v1.28.0'))!; + } if (!this.octokit) { return this.callReleasesApi('/latest'); } @@ -56,4 +60,4 @@ export class Releases { const allReleaseData = await this.getAllReleaseData(); return allReleaseData.find(r => r.name === releaseName); } -} \ No newline at end of file +} From e33bac9916ac0040a4f28130cdb24bef037040e3 Mon Sep 17 00:00:00 2001 From: Nicolas Dubois Date: Thu, 23 Oct 2025 16:56:10 +0200 Subject: [PATCH 2/6] ci: add Java 21 to the test matrix --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a9940ca..70ceea0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,7 +21,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - java-version: [8, 11, 17] + java-version: [8, 11, 17, 21] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 From d5277d7fe20b0f0ddc5fe4ba552caf5e69eec468 Mon Sep 17 00:00:00 2001 From: Jacob Emmel <5431471+j-emmel@users.noreply.github.com> Date: Tue, 24 Feb 2026 20:42:33 -0700 Subject: [PATCH 3/6] Rebuild dist/index.js --- dist/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dist/index.js b/dist/index.js index bd36513..982ae02 100644 --- a/dist/index.js +++ b/dist/index.js @@ -32734,6 +32734,10 @@ class Releases { // Versions after v1.24.0 require JDK 17+ return (await this.getReleaseDataByName('v1.24.0')); } + if (javaVersion < 21) { + // Versions after v1.28.0 require JDK 21+ + return (await this.getReleaseDataByName('v1.28.0')); + } if (!this.octokit) { return this.callReleasesApi('/latest'); } From 570f27ff5f4bbc7d32cae9f80de1eba201e94d8b Mon Sep 17 00:00:00 2001 From: Jacob Emmel <5431471+j-emmel@users.noreply.github.com> Date: Sat, 21 Feb 2026 20:59:04 -0700 Subject: [PATCH 4/6] Get 100 latest formatter releases By default, Github's API returns 30 results per page for 'list' requests; this cuts off old Google Java Format releases, including any that run on Java 8. 100 is the maxmimum. There are 42 releases at time of writing, so this happens to let them all through. --- __tests__/releases.test.ts | 15 ++++++++------- dist/index.js | 4 ++-- src/releases.ts | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/__tests__/releases.test.ts b/__tests__/releases.test.ts index a35b6f3..9c29ec6 100644 --- a/__tests__/releases.test.ts +++ b/__tests__/releases.test.ts @@ -105,6 +105,7 @@ function mockOctokitReturnRelease(releaseData: ReleaseData) { } const URL_BASE = "https://api.github.com/repos/google/google-java-format/releases"; +const URL_TAIL = "?per_page=100"; describe('get all release data', () => { test('get all release data with API', async () => { @@ -113,7 +114,7 @@ describe('get all release data', () => { const results = await releases.getAllReleaseData(); expect(results).toEqual(allReleases); // IMPORTANT: should not have a trailing slash - expectLastCurlCallForUrl(URL_BASE); + expectLastCurlCallForUrl(URL_BASE + URL_TAIL); }); test('get all release data with API and call to API fails', async () => { @@ -124,7 +125,7 @@ describe('get all release data', () => { .rejects .toThrow(error) // IMPORTANT: should not have a trailing slash - expectLastCurlCallForUrl(URL_BASE); + expectLastCurlCallForUrl(URL_BASE + URL_TAIL); }); test('get all release data with octokit', async () => { @@ -148,14 +149,14 @@ describe('get latest release data', () => { const result = await releases.getLatestReleaseData(javaVersion); expect(result).toEqual(expectedRelease); // IMPORTANT: should not have a trailing slash - expectLastCurlCallForUrl(URL_BASE); + expectLastCurlCallForUrl(URL_BASE + URL_TAIL); }); test('when java version is 21, then return release latest', async () => { mockApiReturnRelease(dummyReleaseData); const result = await releases.getLatestReleaseData(21); expect(result).toEqual(dummyReleaseData); - expectLastCurlCallForUrl(URL_BASE + "/latest"); + expectLastCurlCallForUrl(URL_BASE + "/latest" + URL_TAIL); }); }); @@ -166,7 +167,7 @@ describe('get latest release data', () => { expect(() => releases.getLatestReleaseData(21)) .rejects .toThrow(error); - expectLastCurlCallForUrl(URL_BASE + "/latest"); + expectLastCurlCallForUrl(URL_BASE + "/latest" + URL_TAIL); }); describe('get latest release data with octokit', () => { @@ -195,7 +196,7 @@ describe('get release by name', () => { const result = await releases.getReleaseDataByName('dummy-release-data'); expect(result).toEqual(dummyReleaseData); // IMPORTANT: should not have a trailing slash - expectLastCurlCallForUrl(URL_BASE); + expectLastCurlCallForUrl(URL_BASE + URL_TAIL); }); test('get release by name (non-existing)', async () => { @@ -204,6 +205,6 @@ describe('get release by name', () => { const result = await releases.getReleaseDataByName('non-existing-data'); expect(result).toBeUndefined(); // IMPORTANT: should not have a trailing slash - expectLastCurlCallForUrl(URL_BASE); + expectLastCurlCallForUrl(URL_BASE + URL_TAIL); }); }); \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 982ae02..bf94612 100644 --- a/dist/index.js +++ b/dist/index.js @@ -32713,7 +32713,7 @@ class Releases { this.octokit = octokit; } async callReleasesApi(pathParameter) { - const url = `${Releases.apiReleases}${pathParameter || ''}`; + const url = `${Releases.apiReleases}${pathParameter || ''}?per_page=100`; const response = await this.execute('curl', ['-sL', url], { ignoreReturnCode: false }); return JSON.parse(response.stdOut); } @@ -32721,7 +32721,7 @@ class Releases { if (!this.octokit) { return this.callReleasesApi(); } - const params = { owner: const_1.repositoryOwner, repo: const_1.repositoryName }; + const params = { owner: const_1.repositoryOwner, repo: const_1.repositoryName, per_page: 100 }; const response = await this.octokit.rest.repos.listReleases(params); return response.data; } diff --git a/src/releases.ts b/src/releases.ts index ff8ca06..1502756 100644 --- a/src/releases.ts +++ b/src/releases.ts @@ -21,7 +21,7 @@ export class Releases { private async callReleasesApi(pathParameter: string | number): Promise; private async callReleasesApi(pathParameter?: number): Promise; private async callReleasesApi(pathParameter?: string | number): Promise { - const url = `${Releases.apiReleases}${pathParameter || ''}`; + const url = `${Releases.apiReleases}${pathParameter || ''}?per_page=100`; const response = await this.execute('curl', ['-sL', url], { ignoreReturnCode: false }); return JSON.parse(response.stdOut); } @@ -30,7 +30,7 @@ export class Releases { if (!this.octokit) { return this.callReleasesApi(); } - const params = { owner: GJF_REPO_OWNER, repo: GJF_REPO_NAME }; + const params = { owner: GJF_REPO_OWNER, repo: GJF_REPO_NAME, per_page: 100 }; const response = await this.octokit.rest.repos.listReleases(params); return response.data; } From 0635e8f58954103eaa5f686e94ade14117d4f856 Mon Sep 17 00:00:00 2001 From: Jacob Emmel <5431471+j-emmel@users.noreply.github.com> Date: Sat, 21 Feb 2026 20:54:31 -0700 Subject: [PATCH 5/6] Add test for Java 17 default formatter version --- __tests__/releases.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/__tests__/releases.test.ts b/__tests__/releases.test.ts index 9c29ec6..37bbbe7 100644 --- a/__tests__/releases.test.ts +++ b/__tests__/releases.test.ts @@ -46,7 +46,8 @@ const dummyReleaseData: ReleaseData = { const dummyReleaseData_1_7 = { ...dummyReleaseData, name: '1.7' }; const dummyReleaseData_v1_24_0 = { ...dummyReleaseData, name: 'v1.24.0' }; -const allReleases = [dummyReleaseData, dummyReleaseData_1_7, dummyReleaseData_v1_24_0]; +const dummyReleaseData_v1_28_0 = { ...dummyReleaseData, name: 'v1.28.0' }; +const allReleases = [dummyReleaseData, dummyReleaseData_1_7, dummyReleaseData_v1_24_0, dummyReleaseData_v1_28_0]; const executor = jest.fn(); type ListReleases = Octokit['rest']['repos']['listReleases']; @@ -139,7 +140,7 @@ describe('get all release data', () => { }); describe('get latest release data', () => { - const casesJavaVersions: [number, ReleaseData][] = [[8, dummyReleaseData_1_7], [11, dummyReleaseData_v1_24_0]]; + const casesJavaVersions: [number, ReleaseData][] = [[8, dummyReleaseData_1_7], [11, dummyReleaseData_v1_24_0], [17, dummyReleaseData_v1_28_0]]; describe('get latest release data with API', () => { const releases = new Releases(executor); From 53636dd239d3fcad0225b10b3df2cf5727341a1b Mon Sep 17 00:00:00 2001 From: Jacob Emmel <5431471+j-emmel@users.noreply.github.com> Date: Sat, 21 Feb 2026 21:09:55 -0700 Subject: [PATCH 6/6] Paginate Octokit listReleases --- __tests__/releases.test.ts | 11 +++++------ dist/index.js | 4 ++-- src/releases.ts | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/__tests__/releases.test.ts b/__tests__/releases.test.ts index 37bbbe7..494320e 100644 --- a/__tests__/releases.test.ts +++ b/__tests__/releases.test.ts @@ -50,11 +50,14 @@ const dummyReleaseData_v1_28_0 = { ...dummyReleaseData, name: 'v1.28.0' }; const allReleases = [dummyReleaseData, dummyReleaseData_1_7, dummyReleaseData_v1_24_0, dummyReleaseData_v1_28_0]; const executor = jest.fn(); +type Paginate = Octokit['paginate']; type ListReleases = Octokit['rest']['repos']['listReleases']; type GetLatestRelease = Octokit['rest']['repos']['getLatestRelease']; +const mockPaginate = jest.fn(); const mockListReleases = jest.fn(); const mockGetLatestRelease = jest.fn(); const octokit = { + paginate: mockPaginate, rest: { repos: { listReleases: mockListReleases, @@ -88,12 +91,7 @@ function mockApiReturnRelease(releaseData: ReleaseData) { } function mockOctokitReturnReleases() { - mockListReleases.mockReturnValueOnce(Promise.resolve({ - headers: undefined as any, - status: 200, - url: '', - data: allReleases - })); + mockPaginate.mockReturnValueOnce(Promise.resolve(allReleases)); } function mockOctokitReturnRelease(releaseData: ReleaseData) { @@ -134,6 +132,7 @@ describe('get all release data', () => { const releases = new Releases(executor, octokit); const results = await releases.getAllReleaseData(); expect(results).toEqual(allReleases); + expect(mockPaginate).toHaveBeenCalledWith(octokit.rest.repos.listReleases, expect.anything()); expect(mockGetLatestRelease).not.toBeCalled(); expect(executor).not.toBeCalled(); }); diff --git a/dist/index.js b/dist/index.js index bf94612..b3c7a23 100644 --- a/dist/index.js +++ b/dist/index.js @@ -32722,8 +32722,8 @@ class Releases { return this.callReleasesApi(); } const params = { owner: const_1.repositoryOwner, repo: const_1.repositoryName, per_page: 100 }; - const response = await this.octokit.rest.repos.listReleases(params); - return response.data; + const allReleases = await this.octokit.paginate(this.octokit.rest.repos.listReleases, params); + return allReleases; } async getLatestReleaseData(javaVersion) { if (javaVersion < 11) { diff --git a/src/releases.ts b/src/releases.ts index 1502756..c674786 100644 --- a/src/releases.ts +++ b/src/releases.ts @@ -31,8 +31,8 @@ export class Releases { return this.callReleasesApi(); } const params = { owner: GJF_REPO_OWNER, repo: GJF_REPO_NAME, per_page: 100 }; - const response = await this.octokit.rest.repos.listReleases(params); - return response.data; + const allReleases = await this.octokit.paginate(this.octokit.rest.repos.listReleases, params); + return allReleases; } async getLatestReleaseData(javaVersion: number): Promise {