diff --git a/scripts/i18n-icu-contract.test.ts b/scripts/i18n-icu-contract.test.ts
index 17f5d4d97..b6baba69d 100644
--- a/scripts/i18n-icu-contract.test.ts
+++ b/scripts/i18n-icu-contract.test.ts
@@ -1,7 +1,7 @@
import assert from 'node:assert/strict'
import { test } from 'node:test'
-import { contractFromMessage, contractsEqual } from './i18n-icu-contract'
+import { contractFromMessage, contractsEqual, sourceContractChanged } from './i18n-icu-contract'
test('same plain text contract is equal', () => {
assert.equal(
@@ -56,3 +56,26 @@ test('select branch changes contract', () => {
false,
)
})
+
+test('invalid previous source message is treated as changed', () => {
+ assert.equal(
+ sourceContractChanged(
+ 'Get support at {support-link}',
+ 'Get support at ',
+ 'previous',
+ 'current',
+ ),
+ true,
+ )
+})
+
+test('invalid current source message is rejected', () => {
+ assert.throws(() =>
+ sourceContractChanged(
+ 'Get support at ',
+ 'Get support at {support-link}',
+ 'previous',
+ 'current',
+ ),
+ )
+})
diff --git a/scripts/i18n-icu-contract.ts b/scripts/i18n-icu-contract.ts
index fa961df98..5f6002615 100644
--- a/scripts/i18n-icu-contract.ts
+++ b/scripts/i18n-icu-contract.ts
@@ -99,6 +99,22 @@ export function contractsEqual(a: Contract, b: Contract) {
return JSON.stringify(a) === JSON.stringify(b)
}
+export function sourceContractChanged(
+ previousText: string,
+ currentText: string,
+ previousLabel: string,
+ currentLabel: string,
+) {
+ const after = contractFromMessage(currentText, currentLabel)
+
+ try {
+ const before = contractFromMessage(previousText, previousLabel)
+ return !contractsEqual(before, after)
+ } catch {
+ return true
+ }
+}
+
async function readJson(file: string): Promise {
return JSON.parse(await readFile(file, 'utf8')) as MessageFile
}
@@ -250,10 +266,14 @@ async function changedSourceIds(baseRef: string, scope?: string) {
const currentText = textOf(currentEntry)
if (previousText === undefined || currentText === undefined) continue
- const before = contractFromMessage(previousText, `${baseRef}:${sourceFile}:${key}`)
- const after = contractFromMessage(currentText, `${sourceFile}:${key}`)
-
- if (!contractsEqual(before, after)) {
+ if (
+ sourceContractChanged(
+ previousText,
+ currentText,
+ `${baseRef}:${sourceFile}:${key}`,
+ `${sourceFile}:${key}`,
+ )
+ ) {
const ids = changed.get(destPath) ?? new Set()
ids.add(key)
changed.set(destPath, ids)