Skip to content

Commit 75f6e15

Browse files
committed
fix(docs): pin the generator's sort locale to en-US
localeCompare with no locale argument uses the runtime default, which varies with LANG and the ICU build. Against the real 254 catalog names, tr-TR reorders 141 positions, et-EE 45, cs-CZ 2 and lt-LT diverges at index 40 — so a contributor on any of those regenerates a different integrations.json and fails CI with no obvious cause. Pins en-US at all four sort sites. The committed artifacts are unchanged: regenerating before and after leaves the tree byte-identical. Adds a guard test asserting the committed catalog matches an explicit en-US ordering, plus one that fails if an unpinned localeCompare returns.
1 parent 292e59f commit 75f6e15

2 files changed

Lines changed: 28 additions & 4 deletions

File tree

scripts/generate-docs.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,3 +697,27 @@ describe('mapper param shapes', () => {
697697
expect(ids).not.toContain('ghostString')
698698
})
699699
})
700+
701+
describe('the generated catalog ordering is locale-independent', () => {
702+
/**
703+
* `localeCompare` with no locale argument uses the runtime default, which varies with `LANG`
704+
* and the ICU build. Against the real catalog names, `tr-TR` (dotted/dotless I), `lt-LT`,
705+
* `cs-CZ` (the `ch` digraph) and `et-EE` each reorder the array, so a contributor on one of
706+
* those locales would regenerate a different `integrations.json` and fail CI with no obvious
707+
* cause. The generator pins `en-US`; this asserts the committed artifact matches that order.
708+
*/
709+
it('sorts integrations.json the way an explicit en-US comparator would', () => {
710+
const catalogPath = path.join(__dirname, '../packages/deployment-config/src/integrations.json')
711+
const names = (
712+
JSON.parse(fs.readFileSync(catalogPath, 'utf-8')).integrations as Array<{ name: string }>
713+
).map(({ name }) => name)
714+
715+
expect(names).toEqual([...names].sort((a, b) => a.localeCompare(b, 'en-US')))
716+
})
717+
718+
it('leaves no unpinned localeCompare in the generator', () => {
719+
const source = fs.readFileSync(path.join(__dirname, 'generate-docs.ts'), 'utf-8')
720+
721+
expect(source).not.toMatch(/localeCompare\(\s*[A-Za-z_$][\w$.]*\s*\)/)
722+
})
723+
})

scripts/generate-docs.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ function writeIconMapping(iconMapping: Record<string, IconRef>): void {
652652

653653
// Generate mapping with direct references (no dynamic access for tree shaking)
654654
const mappingEntries = Object.entries(withAliases)
655-
.sort(([a], [b]) => a.localeCompare(b))
655+
.sort(([a], [b]) => a.localeCompare(b, 'en-US'))
656656
.map(([blockType, iconRef]) => ` ${formatIconMapKey(blockType)}: ${iconRef.name},`)
657657
.join('\n')
658658

@@ -1433,7 +1433,7 @@ function writeIntegrationsIconMapping(iconMapping: Record<string, IconRef>): voi
14331433

14341434
const imports = renderIconImports(Object.values(iconMapping))
14351435
const mappingEntries = Object.entries(iconMapping)
1436-
.sort(([a], [b]) => a.localeCompare(b))
1436+
.sort(([a], [b]) => a.localeCompare(b, 'en-US'))
14371437
.map(([blockType, iconRef]) => ` ${formatIconMapKey(blockType)}: ${iconRef.name},`)
14381438
.join('\n')
14391439

@@ -1608,7 +1608,7 @@ async function writeIntegrationsJson(iconMapping: Record<string, IconRef>): Prom
16081608
}
16091609
}
16101610

1611-
integrations.sort((a, b) => a.name.localeCompare(b.name))
1611+
integrations.sort((a, b) => a.name.localeCompare(b.name, 'en-US'))
16121612

16131613
const jsonPath = path.join(INTEGRATIONS_CATALOG_PATH, 'integrations.json')
16141614
// `JSON.stringify` always expands every array across multiple lines, but Biome's
@@ -4322,7 +4322,7 @@ function groupTriggersByProvider(
43224322
}
43234323
groups.set(
43244324
provider,
4325-
[...byName.values()].sort((a, b) => a.name.localeCompare(b.name))
4325+
[...byName.values()].sort((a, b) => a.name.localeCompare(b.name, 'en-US'))
43264326
)
43274327
}
43284328
return groups

0 commit comments

Comments
 (0)