Skip to content

Commit 1c7a674

Browse files
bokelleyclaude
andauthored
ci: run the row storage interop test against the JavaScript SDK (#1481)
Adds a Postgres 16 lane that builds adcp-client at main and runs the JS and Python interop test in both directions with ADCP_REQUIRE_JS_INTEROP=1, so a missing build or environment fails instead of skipping. Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
1 parent 5c23598 commit 1c7a674

3 files changed

Lines changed: 82 additions & 2 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,83 @@ jobs:
295295
;;
296296
esac
297297
298+
reporting-js-interop:
299+
needs: changes
300+
if: needs.changes.outputs.run_postgres == 'true'
301+
name: Row storage interop with the JavaScript SDK (Postgres 16)
302+
runs-on: ubuntu-latest
303+
# npm ci and the full adcp-client build dominate; the interop test itself takes seconds.
304+
timeout-minutes: 30
305+
permissions:
306+
contents: read
307+
# PURPOSE: the shared row-storage layout is only shared if the shipped JavaScript SDK reads
308+
# what Python writes and the reverse, against one database and one bucket. This lane builds
309+
# adcp-client at its main branch (deliberately not pinned to a commit) and runs
310+
# test_one_database_and_one_bucket_in_both_directions with ADCP_REQUIRE_JS_INTEROP=1, so a
311+
# missing build or environment fails instead of skipping. If JavaScript main changes its
312+
# stored format before Python mirrors it, this job correctly fails: that is the gate.
313+
services:
314+
postgres:
315+
image: mirror.gcr.io/library/postgres:16
316+
env:
317+
POSTGRES_HOST_AUTH_METHOD: trust
318+
POSTGRES_DB: adcp_interop_test
319+
ports:
320+
- 5432:5432
321+
options: >-
322+
--health-cmd pg_isready
323+
--health-interval 5s
324+
--health-timeout 5s
325+
--health-retries 10
326+
steps:
327+
- uses: actions/checkout@v6
328+
- uses: actions/setup-python@v6
329+
with:
330+
python-version: "3.12"
331+
- name: Set up uv
332+
uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
333+
with:
334+
version: "0.12.8"
335+
enable-cache: true
336+
cache-dependency-glob: pyproject.toml
337+
cache-suffix: "3.12"
338+
prune-cache: true
339+
- name: Check out the JavaScript SDK (main)
340+
uses: actions/checkout@v6
341+
with:
342+
repository: adcontextprotocol/adcp-client
343+
ref: main
344+
path: adcp-client-js
345+
persist-credentials: false
346+
- name: Set up Node 22.12.0
347+
uses: actions/setup-node@v6
348+
with:
349+
node-version: "22.12.0"
350+
cache: npm
351+
cache-dependency-path: adcp-client-js/package-lock.json
352+
- name: Build the JavaScript SDK
353+
working-directory: adcp-client-js
354+
run: |
355+
npm ci
356+
npm run build
357+
test -f dist/lib/reporting/ledger/index.js
358+
- name: Install test dependencies
359+
run: uv pip install --system -e ".[dev,pg]"
360+
- name: Run the interop test in both directions
361+
env:
362+
ADCP_PG_TEST_URL: postgresql://postgres@localhost:5432/adcp_interop_test
363+
ADCP_JS_SDK_DIR: ${{ github.workspace }}/adcp-client-js
364+
ADCP_REQUIRE_JS_INTEROP: "1"
365+
run: |
366+
python -m pytest -n0 -p no:cacheprovider -v -ra \
367+
tests/conformance/reporting/test_reporting_row_storage_interop_pg.py
368+
298369
pg-conformance-required-gate:
299370
name: Postgres conformance tests (Postgres 16)
300371
runs-on: ubuntu-latest
301372
timeout-minutes: 5
302373
permissions: {}
303-
needs: [changes, pg-conformance, pg-reporting-status, pg-reporting-materializer, pg-reporting-receipts, pg-reporting-receipt-compatibility, pg-reporting-feed, pg-reporting-feed-compatibility, pg-reporting-feed-installed, pg-reporting-production, pg-reporting-production-compatibility, pg-reporting-production-installed, reporting-installed-artifact-matrix]
374+
needs: [changes, pg-conformance, pg-reporting-status, pg-reporting-materializer, pg-reporting-receipts, pg-reporting-receipt-compatibility, pg-reporting-feed, pg-reporting-feed-compatibility, pg-reporting-feed-installed, pg-reporting-production, pg-reporting-production-compatibility, pg-reporting-production-installed, reporting-js-interop, reporting-installed-artifact-matrix]
304375
# Failed lanes must still fail the gate; superseded runs should release
305376
# their concurrency slot instead of keeping an uncancelable job queued.
306377
if: ${{ !cancelled() }}

‎scripts/ci/ci_scope.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"pg-reporting-production": "run_postgres",
3838
"pg-reporting-production-installed": "run_postgres",
3939
"pg-reporting-production-compatibility": "run_postgres",
40+
"reporting-js-interop": "run_postgres",
4041
"downstream-imports": "run_packaging",
4142
"reporting-installed-artifact-matrix": "run_packaging",
4243
"storyboard": "run_storyboards",

‎tests/conformance/reporting/test_reporting_row_storage_interop_pg.py‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
from ._generation_support import isolated_reporting_pool
3535

3636
JS_SDK = os.environ.get("ADCP_JS_SDK_DIR")
37+
#: Set by the CI interop lane: a missing build or environment is a failure, never a skip.
38+
REQUIRED = os.environ.get("ADCP_REQUIRE_JS_INTEROP") == "1"
3739
DRIVER = Path(__file__).resolve().parents[2] / "interop" / "reporting_row_storage_js_driver.cjs"
3840

3941

@@ -60,10 +62,16 @@ async def setup(pool: Any, root: Path) -> tuple[PgReportingLedgerStore, Reportin
6062

6163

6264
@pytest.mark.skipif(
63-
not JS_SDK or not shutil.which("node"),
65+
not REQUIRED and (not JS_SDK or not shutil.which("node")),
6466
reason="set ADCP_JS_SDK_DIR to a built adcp-client checkout and install Node",
6567
)
6668
async def test_one_database_and_one_bucket_in_both_directions(tmp_path: Path) -> None:
69+
if REQUIRED:
70+
assert JS_SDK, "ADCP_REQUIRE_JS_INTEROP is set but ADCP_JS_SDK_DIR is not"
71+
assert shutil.which("node"), "ADCP_REQUIRE_JS_INTEROP is set but node is not installed"
72+
assert (
73+
Path(JS_SDK) / "dist/lib/reporting/ledger/index.js"
74+
).is_file(), "ADCP_REQUIRE_JS_INTEROP is set but the JavaScript SDK is not built"
6775
root = tmp_path / "bucket"
6876
async with isolated_reporting_pool() as pool:
6977
_, storage = await setup(pool, root)

0 commit comments

Comments
 (0)