diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0fe8f5a25..f40d74124 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -81,12 +81,30 @@ jobs: uses: actions/setup-node@v4 with: node-version: 'lts/*' - cache: yarn + # NOTE: `cache: yarn` is intentionally NOT set. This repo is a Yarn + # Berry project (yarn.lock __metadata version 10). setup-node's + # `cache: yarn` resolves the cache folder using the yarn binary on + # PATH *during this step* — which is the runner's default Yarn + # Classic 1.x, because corepack's Berry shim isn't activated until + # the next step. That would cache the wrong (Classic) folder. + # Release runs only on workflow_run after CI success on main (low + # frequency), so the marginal cache benefit doesn't justify the + # misconfiguration risk. (qs-02 / TD-3.) + + - name: Enable corepack (activate Yarn Berry from packageManager) + # Runs AFTER setup-node so corepack uses the pinned Node toolchain. + # `corepack enable` installs the yarn shim that resolves the version + # in package.json's `packageManager` field (yarn@4.15.0), so the + # install below runs under Berry — not the runner's default Yarn + # Classic 1.x, which silently ignores --immutable and mis-reads the + # v10 lockfile. (qs-02 / TD-3.) + run: corepack enable - name: Install Node dependencies # --immutable: error if yarn.lock drifts from package.json. Matches # the PHP SDK's pattern — prevents accidental lockfile mutation in - # CI while still catching out-of-sync lockfiles at PR time. + # CI while still catching out-of-sync lockfiles at PR time. Honored + # correctly now that corepack has activated Yarn Berry above. run: yarn install --immutable - name: Run semantic-release diff --git a/.gitignore b/.gitignore index 021544900..0e1344121 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,9 @@ node_modules/ .yarn/cache .yarn/install-state.gz .pnp.* + +# Parity tooling — nested Berry project under tools/ (qs-02). Its .yarn +# artifacts are NOT covered by the root-anchored patterns above, so ignore +# them explicitly. tools/package.json + tools/yarn.lock ARE committed. +tools/.yarn/cache +tools/.yarn/install-state.gz diff --git a/package.json b/package.json index 35710b6fb..a7fcd8819 100644 --- a/package.json +++ b/package.json @@ -2,14 +2,13 @@ "name": "convert-android-sdk-release-tooling", "private": true, "type": "module", - "description": "Release automation tooling and cross-SDK parity-vector generation for the Convert Android SDK.", + "description": "Release automation tooling for the Convert Android SDK (semantic-release). Cross-SDK parity-vector generation lives in tools/package.json and is intentionally isolated from this release install path.", + "packageManager": "yarn@4.15.0", "scripts": { "release": "semantic-release", - "release:dry-run": "semantic-release --dry-run --no-ci", - "generate:parity-vectors": "node tools/generate-parity-vectors.mjs > packages/core/src/test/resources/hash-parity-vectors.json" + "release:dry-run": "semantic-release --dry-run --no-ci" }, "devDependencies": { - "@convertcom/js-sdk-bucketing": "file:../javascript-sdk/packages/bucketing", "@semantic-release/changelog": "^6.0.0", "@semantic-release/exec": "^7.0.0", "@semantic-release/git": "^10.0.0", diff --git a/tools/PARITY.md b/tools/PARITY.md index 8f3c742a5..c0b5adbf5 100644 --- a/tools/PARITY.md +++ b/tools/PARITY.md @@ -21,8 +21,14 @@ The android-sdk owns the **Kotlin side** of parity: - The vector file at `packages/core/src/test/resources/hash-parity-vectors.json` (committed; regenerated only from the JS SDK reference). - The generation script at `tools/generate-parity-vectors.mjs` - (committed; runs against `@convertcom/js-sdk-bucketing` from the - sibling javascript-sdk checkout). + (committed; runs against the PUBLISHED `@convertcom/js-sdk-bucketing` + npm package, pinned in `tools/package.json`). The script and its + dependency live in an isolated `tools/package.json` — deliberately + separate from the root release `package.json`, so the release pipeline + never installs the parity dependency. Regeneration is run from `tools/` + and needs no sibling javascript-sdk checkout (it resolves bucketing from + npm), making it portable and reproducible against the exact version + other Convert SDKs consume. - The Kotlin parity gate `HashParityTest.kt`. The JS side maintains its own equivalent parity suite. Other SDKs (PHP, @@ -61,7 +67,7 @@ to silently regenerate. precise `description`). Then regenerate locally: ```sh - cd android-sdk + cd android-sdk/tools yarn install yarn generate:parity-vectors ``` diff --git a/tools/generate-parity-vectors.mjs b/tools/generate-parity-vectors.mjs index a95557946..0bcc4db66 100644 --- a/tools/generate-parity-vectors.mjs +++ b/tools/generate-parity-vectors.mjs @@ -18,26 +18,33 @@ * ────────────────────────────────────────────────────────────────────── * How to run * ────────────────────────────────────────────────────────────────────── - * cd android-sdk - * yarn install # once + * This tooling lives in its OWN package (android-sdk/tools), isolated from + * the root release package.json so the release pipeline never installs the + * parity dependency. Run it from tools/: + * + * cd android-sdk/tools + * yarn install # once (pulls bucketing from npm) * yarn generate:parity-vectors # regenerate vectors - * # or equivalently: - * node tools/generate-parity-vectors.mjs \ - * > packages/core/src/test/resources/hash-parity-vectors.json + * # or equivalently, from tools/: + * node generate-parity-vectors.mjs \ + * > ../packages/core/src/test/resources/hash-parity-vectors.json * * ────────────────────────────────────────────────────────────────────── * Dependencies * ────────────────────────────────────────────────────────────────────── * Requires: * - Node 20+ (uses ESM + top-level await-compatible runtime) - * - `@convertcom/js-sdk-bucketing` resolved via the `file:../javascript-sdk/ - * packages/bucketing` devDependency in the android-sdk's package.json. - * That pulls in the PRE-BUILT `lib/index.mjs` which has murmurhash - * bundled in — no internet access needed at runtime. + * - `@convertcom/js-sdk-bucketing` — the PUBLISHED npm package, pinned in + * tools/package.json (`^3.1.2`). No sibling javascript-sdk checkout is + * needed: regeneration is portable and reproducible against the exact + * published version other Convert SDKs consume. The package ships a + * PRE-BUILT `lib/index.mjs` with murmurhash bundled in. * - * If the sibling javascript-sdk checkout moves or the bucketing lib - * hasn't been built (no `lib/index.mjs`), run - * `cd ../javascript-sdk && yarn install && yarn bucketing:build`. + * To regenerate against a newer JS SDK bucketing release, bump the version + * range in tools/package.json, run `yarn install` in tools/, then + * `yarn generate:parity-vectors`. A version bump that changes existing + * vectors is a cross-SDK breaking change — see "When the JS SDK changes + * hash logic" in PARITY.md. * * ────────────────────────────────────────────────────────────────────── * When to regenerate diff --git a/tools/package.json b/tools/package.json new file mode 100644 index 000000000..58734781d --- /dev/null +++ b/tools/package.json @@ -0,0 +1,13 @@ +{ + "name": "convert-android-sdk-parity-tooling", + "private": true, + "type": "module", + "description": "Cross-SDK parity-vector generation for the Convert Android SDK. Regen-only; isolated from release tooling, and pinned to the PUBLISHED @convertcom/js-sdk-bucketing npm package so regeneration is portable (no sibling javascript-sdk checkout needed) and reproducible.", + "packageManager": "yarn@4.15.0", + "scripts": { + "generate:parity-vectors": "node generate-parity-vectors.mjs > ../packages/core/src/test/resources/hash-parity-vectors.json" + }, + "devDependencies": { + "@convertcom/js-sdk-bucketing": "3.1.2" + } +} diff --git a/tools/yarn.lock b/tools/yarn.lock new file mode 100644 index 000000000..5b8f8f943 --- /dev/null +++ b/tools/yarn.lock @@ -0,0 +1,26 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 10 + cacheKey: 10c0 + +"@convertcom/js-sdk-bucketing@npm:3.1.2": + version: 3.1.2 + resolution: "@convertcom/js-sdk-bucketing@npm:3.1.2" + peerDependencies: + "@convertcom/js-sdk-enums": ">=2.3.0" + "@convertcom/js-sdk-logger": ">=2.1.2" + "@convertcom/js-sdk-types": ">=3.9.0" + "@convertcom/js-sdk-utils": ">=2.2.3" + checksum: 10c0/74f99e46613c0029949dea2ad53dbd58e1ebd4ac1c933052e93f8c7b8c641ac3460b041b17eb1599ead996d36c81097bdeba0fe97f012cd8bf2b3c435f5a1acc + languageName: node + linkType: hard + +"convert-android-sdk-parity-tooling@workspace:.": + version: 0.0.0-use.local + resolution: "convert-android-sdk-parity-tooling@workspace:." + dependencies: + "@convertcom/js-sdk-bucketing": "npm:3.1.2" + languageName: unknown + linkType: soft diff --git a/yarn.lock b/yarn.lock index 048470c01..85c7ea94f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,7 +2,7 @@ # Manual changes might be lost - proceed with caution! __metadata: - version: 9 + version: 10 cacheKey: 10c0 "@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.26.2": @@ -30,18 +30,6 @@ __metadata: languageName: node linkType: hard -"@convertcom/js-sdk-bucketing@file:../javascript-sdk/packages/bucketing::locator=convert-android-sdk-release-tooling%40workspace%3A.": - version: 3.1.2 - resolution: "@convertcom/js-sdk-bucketing@file:../javascript-sdk/packages/bucketing#../javascript-sdk/packages/bucketing::hash=e0b32a&locator=convert-android-sdk-release-tooling%40workspace%3A." - peerDependencies: - "@convertcom/js-sdk-enums": ">=2.3.0" - "@convertcom/js-sdk-logger": ">=2.1.2" - "@convertcom/js-sdk-types": ">=3.9.0" - "@convertcom/js-sdk-utils": ">=2.2.3" - checksum: 10c0/4cb42cbd7be9e596671396e5b8c8dbc46562e121bbeba6cbd4c4bffe708bb582553cc2e3cd3741352b9b3f8ce40e19dd562419a993fc14d39a601f008d6fb50f - languageName: node - linkType: hard - "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -1171,7 +1159,6 @@ __metadata: version: 0.0.0-use.local resolution: "convert-android-sdk-release-tooling@workspace:." dependencies: - "@convertcom/js-sdk-bucketing": "file:../javascript-sdk/packages/bucketing" "@semantic-release/changelog": "npm:^6.0.0" "@semantic-release/exec": "npm:^7.0.0" "@semantic-release/git": "npm:^10.0.0"