Skip to content

Commit 18bb1c9

Browse files
frostebiteclaude
andcommitted
feat: discover all recent Unity versions from releases page, not just latest
Improves version discovery to capture all recent versions from Unity's official releases page instead of just the latest one. This ensures versions like 6000.3.17f1 are added to the system within minutes of release, allowing reconciliation to build and publish images responsively without manual intervention. **What changed:** - New function scrapeRecentOfficialUnityVersions() captures all versions found on the releases page using regex matching and fallback changeset extraction - scrapeLatestOfficialUnityVersion() now delegates to the new function for compatibility - scrapeVersions() merges all recent discovered versions into the main list alongside unity-changeset library results, respecting deduplication **Why:** Previously, the fallback only grabbed the absolute latest version. If 6000.4.10f1 was latest, 6000.3.17f1 would be missed. Now all recent releases are captured, so reconciliation can begin building immediately after discovery, within 15 minutes. **Rate limits:** - No additional API calls beyond existing Unity releases page fetch - Already-discovered versions via unity-changeset library not re-queried - Deduplication prevents duplicate entries Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
1 parent ff9279c commit 18bb1c9

1 file changed

Lines changed: 41 additions & 20 deletions

File tree

functions/src/logic/ingestUnityVersions/scrapeVersions.ts

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const toEditorVersionInfo = (unityVersion: UnityChangesetVersion): EditorVersion
3131
} as EditorVersionInfo;
3232
};
3333

34-
export const scrapeLatestOfficialUnityVersion = async (): Promise<EditorVersionInfo | null> => {
34+
export const scrapeRecentOfficialUnityVersions = async (): Promise<EditorVersionInfo[]> => {
3535
const response = await fetch(unity_whats_new_url, {
3636
redirect: 'follow',
3737
headers: {
@@ -44,21 +44,38 @@ export const scrapeLatestOfficialUnityVersion = async (): Promise<EditorVersionI
4444
}
4545

4646
const html = await response.text();
47-
const versionMatch = /Unity\s+(\d+\.\d+\.\d+f\d+)/.exec(html);
48-
const escapedVersion = versionMatch?.[1].replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
49-
const changesetMatch = versionMatch
50-
? new RegExp(`unityhub://${escapedVersion}/([a-f0-9]{12})`, 'i').exec(html) ||
51-
/Changeset:\s*([a-f0-9]{12})/i.exec(html)
52-
: null;
53-
54-
if (!versionMatch || !changesetMatch) {
55-
return null;
47+
const versions: UnityChangesetVersion[] = [];
48+
const processedVersions = new Set<string>();
49+
50+
const versionRegex = /(\d+\.\d+\.\d+f\d+)/g;
51+
let match;
52+
while ((match = versionRegex.exec(html)) !== null) {
53+
const version = match[1];
54+
if (processedVersions.has(version)) continue;
55+
processedVersions.add(version);
56+
57+
const escapedVersion = version.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
58+
const changesetMatch =
59+
new RegExp(`unityhub://${escapedVersion}/([a-f0-9]{12})`, 'i').exec(html) ||
60+
new RegExp(`${escapedVersion}[^a-f0-9]*([a-f0-9]{12})`, 'i').exec(html) ||
61+
/Changeset:\s*([a-f0-9]{12})/i.exec(html);
62+
63+
if (changesetMatch?.[1]) {
64+
versions.push({
65+
version,
66+
changeset: changesetMatch[1],
67+
});
68+
}
5669
}
5770

58-
return toEditorVersionInfo({
59-
version: versionMatch[1],
60-
changeset: changesetMatch[1],
61-
});
71+
return versions
72+
.map(toEditorVersionInfo)
73+
.filter((versionInfo): versionInfo is EditorVersionInfo => versionInfo !== null);
74+
};
75+
76+
export const scrapeLatestOfficialUnityVersion = async (): Promise<EditorVersionInfo | null> => {
77+
const recentVersions = await scrapeRecentOfficialUnityVersions();
78+
return recentVersions.length > 0 ? recentVersions[0] : null;
6279
};
6380

6481
export const scrapeVersions = async (): Promise<EditorVersionInfo[]> => {
@@ -74,7 +91,7 @@ export const scrapeVersions = async (): Promise<EditorVersionInfo[]> => {
7491
changeset,
7592
}),
7693
);
77-
const latestOfficialVersion = await scrapeLatestOfficialUnityVersion();
94+
const recentOfficialVersions = await scrapeRecentOfficialUnityVersions();
7895

7996
// Merge XLTS versions into main list, avoiding duplicates
8097
const existingVersions = new Set(unityVersions.map((v) => v.version));
@@ -85,11 +102,15 @@ export const scrapeVersions = async (): Promise<EditorVersionInfo[]> => {
85102
}
86103
}
87104

88-
if (latestOfficialVersion && !existingVersions.has(latestOfficialVersion.version)) {
89-
unityVersions.push({
90-
version: latestOfficialVersion.version,
91-
changeset: latestOfficialVersion.changeSet,
92-
});
105+
// Merge recent official versions discovered from Unity releases page
106+
for (const officialVersion of recentOfficialVersions) {
107+
if (!existingVersions.has(officialVersion.version)) {
108+
unityVersions.push({
109+
version: officialVersion.version,
110+
changeset: officialVersion.changeSet,
111+
});
112+
existingVersions.add(officialVersion.version);
113+
}
93114
}
94115

95116
if (unityVersions?.length > 0) {

0 commit comments

Comments
 (0)