Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
cb06d67
chore(JsonSchemaComparison): sync COUNTRY_CONTRACT_VERSIONS from tiger
gabrielseco Sep 21, 2026
9abe9e5
chore(ci): schedule weekly COUNTRY_CONTRACT_VERSIONS sync
gabrielseco Sep 21, 2026
f3786b0
chore(scripts): show country names in the contract-versions gap report
gabrielseco Sep 21, 2026
229fc48
chore(scripts): trim comment verbosity to match repo convention
gabrielseco Sep 21, 2026
9ad180a
chore: genericize tiger references to 'BE repo', drop obsolete prompt…
gabrielseco Sep 21, 2026
7d02c9e
chore: remove remaining tiger mentions from comments/docstrings
gabrielseco Sep 21, 2026
2f21877
chore(scripts): commit the contract-version gap report as JSON
gabrielseco Sep 21, 2026
433a433
Merge remote-tracking branch 'origin/main' into chore/sync-country-co…
gabrielseco Oct 1, 2026
a0a69d5
chore: merge main and adapt contract-versions sync to pnpm and the pi…
gabrielseco Oct 30, 2026
0a96704
fix(scripts): skip the countries the API rejects when syncing contrac…
gabrielseco Oct 30, 2026
114cee2
fix(scripts): only rewrite the version files when the versions actual…
gabrielseco Oct 30, 2026
165309f
Merge remote-tracking branch 'origin/main' into chore/sync-country-co…
gabrielseco Oct 30, 2026
cb82b87
feat(scripts): update the version matrix when syncing contract versions
gabrielseco Oct 30, 2026
4a36c03
fix(ci): open the weekly sync PR with an app token so CI runs on it
gabrielseco Oct 30, 2026
b90a20f
chore(scripts): drop the generated gap-report JSON, the version matri…
gabrielseco Oct 30, 2026
5ce6a64
fix(scripts): read France and Italy platform versions from their back…
gabrielseco Oct 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions .github/workflows/sync-country-contract-versions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Sync Country Contract Versions

on:
schedule:
# Weekly, Monday ~06:20 UTC (off the round hour on purpose).
- cron: '23 6 * * 1'
workflow_dispatch:

permissions:
contents: read

jobs:
sync:
name: Sync COUNTRY_CONTRACT_VERSIONS from the BE repo
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout remote-flows
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false

- name: Enable Corepack
run: corepack enable

- name: Use Node.js
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: '24.15.0'
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts

- name: Check for BE repo GitLab token
id: check-token
env:
BE_REPO_TOKEN: ${{ secrets.BE_REPO_GITLAB_READ_TOKEN }}
run: |
if [ -z "$BE_REPO_TOKEN" ]; then
echo "::warning::BE_REPO_GITLAB_READ_TOKEN is not configured. Skipping sync. See scripts/sync-country-contract-versions.ts for what this needs."
echo "has_token=false" >> "$GITHUB_OUTPUT"
else
echo "has_token=true" >> "$GITHUB_OUTPUT"
fi

# Only the BE repo's contract_details schemas are needed here.
- name: Sparse-checkout BE repo contract_details schemas
if: steps.check-token.outputs.has_token == 'true'
env:
BE_REPO_TOKEN: ${{ secrets.BE_REPO_GITLAB_READ_TOKEN }}
run: |
git clone --depth 1 --filter=blob:none --sparse \
"https://oauth2:${BE_REPO_TOKEN}@gitlab.com/remote-com/employ-starbase/tiger.git" \
be-repo-schemas
git -C be-repo-schemas sparse-checkout set apps/tiger/priv/json_schemas/contract_details

- name: Run sync script
if: steps.check-token.outputs.has_token == 'true'
run: |
pnpm run sync:contract-versions \
--be-repo-path=./be-repo-schemas \
--write \
--report-file=/tmp/gap-report.md

- name: Mint a GitHub App token for the pull request
id: app-token
if: steps.check-token.outputs.has_token == 'true'
uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0
with:
client-id: ${{ secrets.SCHEMA_CANARY_APP_CLIENT_ID }}
private-key: ${{ secrets.SCHEMA_CANARY_APP_PRIVATE_KEY }}
permission-contents: write
permission-pull-requests: write

- name: Create pull request
if: steps.check-token.outputs.has_token == 'true'
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with:
token: ${{ steps.app-token.outputs.token }}
commit-message: 'chore(JsonSchemaComparison): sync COUNTRY_CONTRACT_VERSIONS from the BE repo'
branch: chore/sync-country-contract-versions-auto
delete-branch: true
title: 'chore(JsonSchemaComparison): sync COUNTRY_CONTRACT_VERSIONS from the BE repo'
body-path: /tmp/gap-report.md
add-paths: |
src/components/JsonSchemaComparison/schemaVersions.ts
docs/schema-changes/eor/contract-details/countries/README.md
20 changes: 10 additions & 10 deletions docs/schema-changes/eor/contract-details/countries/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ Click a country name to open its migration guide. Countries without a link are o

| Country | Code | Contract Details | Remote platform | Up to date | Last Updated |
| -------------------------------- | ---- | ---------------- | --------------- | ---------- | ------------ |
| [Albania](./ALB.md) | ALB | v4 | v4 | Yes | October 2026 |
| [Argentina](./ARG.md) | ARG | v5 | v5 | Yes | October 2026 |
| [Armenia](./ARM.md) | ARM | v3 | v3 | Yes | October 2026 |
| [Australia](./AUS.md) | AUS | v6 | v6 | Yes | October 2026 |
| [Austria](./AUT.md) | AUT | v8 | v8 | Yes | October 2026 |
| [Albania](./ALB.md) | ALB | v4 | v5 | No | October 2026 |
| [Argentina](./ARG.md) | ARG | v5 | v6 | No | October 2026 |
| [Armenia](./ARM.md) | ARM | v3 | v4 | No | October 2026 |
| [Australia](./AUS.md) | AUS | v6 | v7 | No | October 2026 |
| [Austria](./AUT.md) | AUT | v8 | v9 | No | October 2026 |
| [Bangladesh](./BGD.md) | BGD | v8 | v8 | Yes | October 2026 |
| [Belgium](./BEL.md) | BEL | v8 | v8 | Yes | October 2026 |
| Bolivia | BOL | v1 | v5 | No | - |
Expand All @@ -53,7 +53,7 @@ Click a country name to open its migration guide. Countries without a link are o
| [Cyprus](./CYP.md) | CYP | v7 | v7 | Yes | October 2026 |
| [Czech Republic](./CZE.md) | CZE | v7 | v7 | Yes | October 2026 |
| [Denmark](./DNK.md) | DNK | v6 | v6 | Yes | October 2026 |
| [Dominican Republic](./DOM.md) | DOM | v6 | v6 | Yes | October 2026 |
| [Dominican Republic](./DOM.md) | DOM | v6 | v7 | No | October 2026 |
| Ecuador | ECU | v1 | v7 | No | - |
| [Egypt](./EGY.md) | EGY | v6 | v6 | Yes | October 2026 |
| [El Salvador](./SLV.md) | SLV | v4 | v4 | Yes | October 2026 |
Expand Down Expand Up @@ -83,12 +83,12 @@ Click a country name to open its migration guide. Countries without a link are o
| [Luxembourg](./LUX.md) | LUX | v5 | v5 | Yes | October 2026 |
| [Malaysia](./MYS.md) | MYS | v5 | v5 | Yes | October 2026 |
| [Malta](./MLT.md) | MLT | v5 | v5 | Yes | October 2026 |
| [Mauritius](./MUS.md) | MUS | v6 | v5 | Yes | October 2026 |
| [Mauritius](./MUS.md) | MUS | v6 | v6 | Yes | October 2026 |
| [Mexico](./MEX.md) | MEX | v9 | v9 | Yes | October 2026 |
| Moldova | MDA | v1 | v6 | No | - |
| [Morocco](./MAR.md) | MAR | v8 | v8 | Yes | October 2026 |
| [Netherlands](./NLD.md) | NLD | v7 | v7 | Yes | October 2026 |
| [New Zealand](./NZL.md) | NZL | v8 | v8 | Yes | October 2026 |
| [New Zealand](./NZL.md) | NZL | v8 | v9 | No | October 2026 |
| [Nicaragua](./NIC.md) | NIC | v4 | v4 | Yes | October 2026 |
| [Nigeria](./NGA.md) | NGA | v5 | v5 | Yes | October 2026 |
| North Macedonia | MKD | v1 | v6 | No | - |
Expand All @@ -108,7 +108,7 @@ Click a country name to open its migration guide. Countries without a link are o
| Slovakia | SVK | v1 | v6 | No | - |
| [Slovenia](./SVN.md) | SVN | v6 | v6 | Yes | October 2026 |
| [South Africa](./ZAF.md) | ZAF | v5 | v5 | Yes | October 2026 |
| [South Korea](./KOR.md) | KOR | v7 | v6 | Yes | October 2026 |
| [South Korea](./KOR.md) | KOR | v7 | v7 | Yes | October 2026 |
| [Spain](./ESP.md) | ESP | v8 | v8 | Yes | October 2026 |
| Sri Lanka | LKA | v1 | v8 | No | - |
| [Sweden](./SWE.md) | SWE | v5 | v5 | Yes | October 2026 |
Expand All @@ -119,7 +119,7 @@ Click a country name to open its migration guide. Countries without a link are o
| Turkey | TUR | v1 | v7 | No | - |
| [Uganda](./UGA.md) | UGA | v5 | v5 | Yes | October 2026 |
| Ukraine | UKR | v1 | v7 | No | - |
| [United Arab Emirates](./ARE.md) | ARE | v6 | v6 | Yes | October 2026 |
| [United Arab Emirates](./ARE.md) | ARE | v6 | v7 | No | October 2026 |
| [United Kingdom](./GBR.md) | GBR | v7 | v7 | Yes | October 2026 |
| [United States](./USA.md) | USA | v9 | v9 | Yes | October 2026 |
| [Uruguay](./URY.md) | URY | v6 | v6 | Yes | October 2026 |
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"schema-snapshot": "tsx scripts/schema-snapshot.ts",
"dump:schema": "tsx scripts/dump-schema.ts",
"seed:onboarding": "tsx scripts/seed-onboarding.ts",
"sync:contract-versions": "tsx scripts/sync-country-contract-versions.ts",
"size": "tsx scripts/analyze-bundle-size.ts",
"size:check": "tsx scripts/check-size-limits.ts",
"size:badge": "tsx scripts/update-size-badge.ts",
Expand Down
91 changes: 91 additions & 0 deletions scripts/contract-versions-matrix.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { updateVersionMatrix } from './contract-versions-matrix';

const header = [
'| Country | Code | Contract Details | Remote platform | Up to date | Last Updated |',
'| ------- | ---- | ---------------- | --------------- | ---------- | ------------ |',
];

function matrix(...rows: string[]) {
return [...header, ...rows, ''].join('\n');
}

describe('updateVersionMatrix', () => {
it('raises the platform version and flips Up to date to No when the pin is behind', () => {
const readme = matrix(
'| Albania | ALB | v4 | v4 | Yes | October 2026 |',
);

const { content, unreadableRows } = updateVersionMatrix(readme, { ALB: 5 });

expect(content).toBe(
matrix(
'| Albania | ALB | v4 | v5 | No | October 2026 |',
),
);
expect(unreadableRows).toEqual([]);
});

it('marks a country Yes when the pin is at or above the platform version', () => {
const readme = matrix(
'| Albania | ALB | v5 | v4 | No | - |',
);

const { content } = updateVersionMatrix(readme, { ALB: 5 });

expect(content).toBe(
matrix(
'| Albania | ALB | v5 | v5 | Yes | - |',
),
);
});

it('reads the platform version for FRA and ITA from their backend codes', () => {
const readme = matrix(
'| Italy | ITA | v2 | v2 | Yes | - |',
);

const { content } = updateVersionMatrix(readme, { ITA: 5, ITA_APL: 3 });

expect(content).toBe(
matrix(
'| Italy | ITA | v2 | v3 | No | - |',
),
);
});

it('updates the platform version for France but keeps its documented Up to date', () => {
const readme = matrix(
'| France | FRA | v1 | v2 | Yes | - |',
);

const { content } = updateVersionMatrix(readme, { FRA: 6, FRA_SAS: 3 });

expect(content).toBe(
matrix(
'| France | FRA | v1 | v3 | Yes | - |',
),
);
});

it('leaves countries without a backend version and non-table lines alone', () => {
const readme = `Intro line\n${matrix(
'| Albania | ALB | v4 | v4 | Yes | - |',
)}`;

const { content } = updateVersionMatrix(readme, { ZZZ: 3 });

expect(content).toBe(readme);
});

it('reports a row whose Contract Details cell is not a plain version', () => {
const row =
'| Albania | ALB | v4 (beta) | v4 | Yes | - |';

const { content, unreadableRows } = updateVersionMatrix(matrix(row), {
ALB: 5,
});

expect(content).toBe(matrix(row));
expect(unreadableRows).toEqual([row]);
});
});
52 changes: 52 additions & 0 deletions scripts/contract-versions-matrix.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
export const BACKEND_CODE_BY_SDK_CODE: Record<string, string> = {
FRA: 'FRA_SAS',
ITA: 'ITA_APL',
};

const UP_TO_DATE_UNTOUCHED = new Set(['FRA']);

const CODE_CELL = 2;
const CONTRACT_DETAILS_CELL = 3;
const PLATFORM_CELL = 4;
const UP_TO_DATE_CELL = 5;

function withCellValue(cell: string, value: string): string {
return ` ${value.padEnd(cell.length - 2)} `;
}

/**
* Updates the "Remote platform" and "Up to date" columns of the README's
* Version Matrix from the latest version counts. Rows it can't read are
* returned in `unreadableRows` and left untouched.
*/
export function updateVersionMatrix(
readme: string,
latestCounts: Record<string, number>,
): { content: string; unreadableRows: string[] } {
const unreadableRows: string[] = [];
const content = readme.split('\n').map((line) => {
const cells = line.split('|');
if (cells.length !== 8 || !line.startsWith('| ')) {
return line;
}
const code = cells[CODE_CELL].trim();
const latest = latestCounts[BACKEND_CODE_BY_SDK_CODE[code] ?? code];
if (latest === undefined) {
return line;
}
const pinnedMatch = /^v(\d+)$/.exec(cells[CONTRACT_DETAILS_CELL].trim());
if (!pinnedMatch) {
unreadableRows.push(line);
return line;
}
cells[PLATFORM_CELL] = withCellValue(cells[PLATFORM_CELL], `v${latest}`);
if (!UP_TO_DATE_UNTOUCHED.has(code)) {
cells[UP_TO_DATE_CELL] = withCellValue(
cells[UP_TO_DATE_CELL],
Number(pinnedMatch[1]) >= latest ? 'Yes' : 'No',
);
}
return cells.join('|');
});
return { content: content.join('\n'), unreadableRows };
}
Loading
Loading