From 6ad340f990694a38a9d5fc6f27f67231a4fef141 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 15 Oct 2026 00:22:34 +0000 Subject: [PATCH 1/2] fix: pick the highest Chromium version in a milestone, not the most recent release Releases within a milestone ship on independent per-channel and per-platform schedules, so the most recently released entry from chromiumdash is not necessarily the newest version (e.g. an Extended release published after a newer Beta or Stable build). Sort releases by version, using release time only as a tiebreak. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01PbwafMAXGvxSbV7VWbwGus --- src/utils/get-chromium-tags.ts | 9 ++- tests/utils/get-chromium-tags.spec.ts | 92 +++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 tests/utils/get-chromium-tags.spec.ts diff --git a/src/utils/get-chromium-tags.ts b/src/utils/get-chromium-tags.ts index 238820e..18ba564 100644 --- a/src/utils/get-chromium-tags.ts +++ b/src/utils/get-chromium-tags.ts @@ -1,3 +1,5 @@ +import { compareChromiumVersions } from './compare-chromium-versions.js'; + type ReleaseType = 'Extended' | 'Stable' | 'Beta' | 'Dev' | 'Canary'; export type ReleaseParams = { @@ -30,5 +32,10 @@ export async function getChromiumReleases({ throw new Error(`Failed to fetch Chromium releases: ${response.status}`); } const releases = (await response.json()) as Release[]; - return releases.sort((a, b) => a.time - b.time).map((r) => r.version); + // Order by version rather than release time: channels (Extended, Stable, + // Beta, ...) and platforms within a milestone ship on their own schedules, + // so the most recently released entry is not necessarily the newest version. + return releases + .sort((a, b) => compareChromiumVersions(a.version, b.version) || a.time - b.time) + .map((r) => r.version); } diff --git a/tests/utils/get-chromium-tags.spec.ts b/tests/utils/get-chromium-tags.spec.ts new file mode 100644 index 0000000..312b11f --- /dev/null +++ b/tests/utils/get-chromium-tags.spec.ts @@ -0,0 +1,92 @@ +import nock from 'nock'; +import { afterEach, describe, expect, it } from 'vitest'; + +import { getChromiumReleases, Release } from '../../src/utils/get-chromium-tags.js'; + +describe('getChromiumReleases', () => { + afterEach(() => { + nock.cleanAll(); + }); + + function mockReleases(releases: Partial[]) { + return nock('https://chromiumdash.appspot.com') + .get('/fetch_releases') + .query(true) + .reply(200, releases); + } + + it('orders releases by version rather than by release time', async () => { + // An Extended release can go out after a Stable or Beta release in the + // same milestone while still carrying an older version. + mockReleases([ + { + channel: 'Extended', + platform: 'Windows', + milestone: 156, + time: 4000, + version: '156.0.8078.13', + }, + { + channel: 'Stable', + platform: 'Windows', + milestone: 156, + time: 3000, + version: '156.0.8078.12', + }, + { + channel: 'Beta', + platform: 'Windows', + milestone: 156, + time: 2000, + version: '156.0.8078.17', + }, + { channel: 'Beta', platform: 'Mac', milestone: 156, time: 1000, version: '156.0.8078.4' }, + ]); + + const releases = await getChromiumReleases({ milestone: 156 }); + + expect(releases).toEqual(['156.0.8078.4', '156.0.8078.12', '156.0.8078.13', '156.0.8078.17']); + expect(releases[releases.length - 1]).toEqual('156.0.8078.17'); + }); + + it('compares version components numerically', async () => { + mockReleases([ + { channel: 'Stable', platform: 'Linux', milestone: 156, time: 2000, version: '156.0.8078.9' }, + { + channel: 'Stable', + platform: 'Linux', + milestone: 156, + time: 1000, + version: '156.0.8078.10', + }, + ]); + + await expect(getChromiumReleases({ milestone: 156 })).resolves.toEqual([ + '156.0.8078.9', + '156.0.8078.10', + ]); + }); + + it('passes the channel and milestone filters to chromiumdash', async () => { + const scope = nock('https://chromiumdash.appspot.com') + .get('/fetch_releases') + .query({ + platform: 'Win32,Windows,Linux,Mac', + num: '10', + channel: 'Canary', + milestone: '157', + }) + .reply(200, []); + + await expect(getChromiumReleases({ channel: 'Canary', milestone: 157 })).resolves.toEqual([]); + expect(scope.isDone()).toBe(true); + }); + + it('throws when chromiumdash responds with an error', async () => { + nock('https://chromiumdash.appspot.com').get('/fetch_releases').query(true).reply(500); + + await expect(getChromiumReleases({ milestone: 156 })).rejects.toThrow( + 'Failed to fetch Chromium releases: 500', + ); + }); +}); From 34c56d6791a0a41777ec3e3d8b9cb4cd5837e3d1 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 15 Oct 2026 01:17:57 +0000 Subject: [PATCH 2/2] refactor: drop release-time tiebreak from Chromium version sort Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01PbwafMAXGvxSbV7VWbwGus --- src/utils/get-chromium-tags.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/get-chromium-tags.ts b/src/utils/get-chromium-tags.ts index 18ba564..0d494cf 100644 --- a/src/utils/get-chromium-tags.ts +++ b/src/utils/get-chromium-tags.ts @@ -36,6 +36,6 @@ export async function getChromiumReleases({ // Beta, ...) and platforms within a milestone ship on their own schedules, // so the most recently released entry is not necessarily the newest version. return releases - .sort((a, b) => compareChromiumVersions(a.version, b.version) || a.time - b.time) + .sort((a, b) => compareChromiumVersions(a.version, b.version)) .map((r) => r.version); }