Skip to content

Commit 7eab4f1

Browse files
Add a vendor-drift CI gate and refresh targets for the MEOS-API artefacts
A Makefile regenerates the vendored MEOS-API artefacts under vendor/meos-api/: vendor-meos-api from the MEOS-API and MobilityDB headers, vendor-meos-api-from-prs from the enrichment and OpenAPI PR branches, and vendor-meos-api-movfeat from the OGC API – Moving Features projection generator on MEOS-API PR #13. A GitHub Actions workflow re-runs the refresh on push to master, on a daily schedule, and on demand, failing when the vendored copy drifts from upstream so the change surfaces as a refresh.
1 parent 6622659 commit 7eab4f1

3 files changed

Lines changed: 155 additions & 3 deletions

File tree

.github/workflows/vendor-drift.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: Vendor drift (MEOS-API)
2+
3+
# Re-runs the `make vendor-meos-api` target against the live MEOS-API master
4+
# and fails if the vendored artefacts under `vendor/meos-api/` are out of date.
5+
#
6+
# Surfaces upstream changes as actionable PR diffs instead of letting them
7+
# silently rot. The CI failure message tells the maintainer to run
8+
#
9+
# make vendor-meos-api
10+
#
11+
# locally and submit a refresh PR.
12+
#
13+
# Step 3 of `docs/MEOS_API_INGESTION_PLAN.md`.
14+
15+
on:
16+
pull_request:
17+
paths:
18+
- 'vendor/meos-api/**'
19+
- 'Makefile'
20+
- '.github/workflows/vendor-drift.yml'
21+
push:
22+
branches: [master]
23+
schedule:
24+
# Daily 06:00 UTC — pings the maintainer if MEOS-API master moves and the
25+
# vendored copy goes stale, even without a MobilityAPI PR open.
26+
- cron: '0 6 * * *'
27+
workflow_dispatch:
28+
29+
jobs:
30+
vendor-drift:
31+
name: Refresh & diff vendored artefacts
32+
runs-on: ubuntu-latest
33+
steps:
34+
- uses: actions/checkout@v4
35+
36+
# libclang (the Python wheel) bundles the .so but not the system C
37+
# headers MEOS depends on (json-c, gsl, proj, postgres). Without them,
38+
# `size_t` degrades to `int`, `json_object *` degrades to `int *`, etc.,
39+
# which would show up as false drift on every CI run. Install the same
40+
# dev headers a local MobilityDB build expects so libclang resolves
41+
# everything correctly.
42+
- name: Install dev headers for libclang sysroot (matches local parse)
43+
run: |
44+
sudo apt-get update -qq
45+
sudo apt-get install -y --no-install-recommends \
46+
clang libclang-dev \
47+
libjson-c-dev libgsl-dev libproj-dev libgeos-dev \
48+
postgresql-server-dev-16
49+
50+
- name: Refresh vendored MEOS-API artefacts from master
51+
run: make vendor-meos-api
52+
53+
- name: Detect drift
54+
id: drift
55+
run: |
56+
if git diff --exit-code -- vendor/meos-api/; then
57+
echo "drift=false" >> "$GITHUB_OUTPUT"
58+
echo "::notice::vendor/meos-api/ is up to date with MEOS-API master."
59+
else
60+
echo "drift=true" >> "$GITHUB_OUTPUT"
61+
echo "::error::vendor/meos-api/ is stale. Run \`make vendor-meos-api\` locally and open a refresh PR."
62+
git diff --stat -- vendor/meos-api/
63+
exit 1
64+
fi

Makefile

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# MobilityAPI build & vendoring targets
2+
3+
MEOS_API_REPO ?= https://github.com/MobilityDB/MEOS-API
4+
MEOS_API_REF ?= master
5+
MEOS_API_PR5 ?= refs/pull/5/head # MEOS-API PR #5 (OpenAPI projection)
6+
MEOS_API_PR4 ?= refs/pull/4/head # MEOS-API PR #4 (enrichment)
7+
MEOS_API_PR13 ?= refs/pull/13/head # MEOS-API PR #13 (OGC MovFeat projection)
8+
MOBILITYDB_REPO ?= https://github.com/MobilityDB/MobilityDB
9+
MOBILITYDB_REF ?= master
10+
VENDOR_DIR := vendor/meos-api
11+
12+
.PHONY: vendor-meos-api vendor-meos-api-from-prs vendor-meos-api-movfeat
13+
14+
# Regenerate vendored MEOS-API artefacts from MEOS-API + MobilityDB headers.
15+
#
16+
# `output/*.json` is .gitignore'd in MEOS-API (generated by `python3 run.py
17+
# <path-to-meos-include>`), so we have to:
18+
# 1. clone MEOS-API at the requested ref,
19+
# 2. clone MobilityDB at the requested ref so MEOS-API's parser can read its
20+
# headers (`meos/include/`),
21+
# 3. install libclang,
22+
# 4. run `python3 run.py <MobilityDB-headers-path>` to produce output/*.json,
23+
# 5. copy the JSON artefacts into $(VENDOR_DIR).
24+
vendor-meos-api:
25+
@echo "[vendor] regenerating meos-api artefacts from"
26+
@echo " MEOS-API: $(MEOS_API_REPO)@$(MEOS_API_REF)"
27+
@echo " MobilityDB: $(MOBILITYDB_REPO)@$(MOBILITYDB_REF) (headers source)"
28+
@mkdir -p $(VENDOR_DIR)
29+
@tmpdir=$$(mktemp -d) && \
30+
git clone --depth 1 --branch $(MEOS_API_REF) $(MEOS_API_REPO) $$tmpdir/meos-api && \
31+
git clone --depth 1 --branch $(MOBILITYDB_REF) $(MOBILITYDB_REPO) $$tmpdir/mobilitydb && \
32+
cd $$tmpdir/meos-api && \
33+
pip install --quiet --user -r requirements.txt && \
34+
python3 run.py $$tmpdir/mobilitydb/meos/include && \
35+
if [ -f report.py ]; then python3 report.py $$tmpdir/mobilitydb/meos/include || true; fi && \
36+
if [ -f object_model_parity.py ]; then python3 object_model_parity.py || true; fi && \
37+
cp -v output/meos-idl.json $(CURDIR)/$(VENDOR_DIR)/ && \
38+
( [ -f output/meos-coverage.json ] && cp -v output/meos-coverage.json $(CURDIR)/$(VENDOR_DIR)/ || true ) && \
39+
( [ -f output/meos-object-model-parity.json ] && cp -v output/meos-object-model-parity.json $(CURDIR)/$(VENDOR_DIR)/ || true ) && \
40+
cd $(CURDIR) && rm -rf $$tmpdir
41+
@echo "[vendor] done — $(VENDOR_DIR) refreshed"
42+
43+
# Fetch the enriched catalog + OpenAPI projection from the open PR branches
44+
# (PR #4 ships parser/enrich.py, PR #5 ships generate_openapi.py).
45+
vendor-meos-api-from-prs:
46+
@echo "[vendor] fetching from open PR branches (#4 enrichment + #5 OpenAPI)"
47+
@mkdir -p $(VENDOR_DIR)
48+
@tmpdir=$$(mktemp -d) && \
49+
git clone $(MEOS_API_REPO) $$tmpdir/meos-api && \
50+
git clone --depth 1 --branch $(MOBILITYDB_REF) $(MOBILITYDB_REPO) $$tmpdir/mobilitydb && \
51+
cd $$tmpdir/meos-api && \
52+
git fetch origin $(MEOS_API_PR4):pr4 $(MEOS_API_PR5):pr5 && \
53+
git checkout pr5 && \
54+
git merge --no-edit pr4 || true && \
55+
pip install --quiet --user -r requirements.txt && \
56+
python3 run.py $$tmpdir/mobilitydb/meos/include && \
57+
python3 generate_openapi.py && \
58+
cp -v output/meos-idl.json $(CURDIR)/$(VENDOR_DIR)/ && \
59+
( [ -f output/meos-coverage.json ] && cp -v output/meos-coverage.json $(CURDIR)/$(VENDOR_DIR)/ || true ) && \
60+
( [ -f output/meos-object-model-parity.json ] && cp -v output/meos-object-model-parity.json $(CURDIR)/$(VENDOR_DIR)/ || true ) && \
61+
( [ -f output/meos-openapi.json ] && cp -v output/meos-openapi.json $(CURDIR)/$(VENDOR_DIR)/ || true ) && \
62+
cd $(CURDIR) && rm -rf $$tmpdir
63+
@echo "[vendor] done — $(VENDOR_DIR) refreshed from PRs #4 + #5"
64+
65+
# Fetch the OGC API – Moving Features OpenAPI projection from MEOS-API PR #13
66+
# (`generate_movfeat_openapi.py` + `generator/movfeat.py`). This is the contract
67+
# the OGC endpoints dispatch against; it is generated, not committed, so it is
68+
# produced on the merged PR #4 (enrichment) + #5 (OpenAPI) + #13 (MovFeat) tree.
69+
vendor-meos-api-movfeat:
70+
@echo "[vendor] generating meos-movfeat-openapi.json from MEOS-API PR #13"
71+
@mkdir -p $(VENDOR_DIR)
72+
@tmpdir=$$(mktemp -d) && \
73+
git clone $(MEOS_API_REPO) $$tmpdir/meos-api && \
74+
git clone --depth 1 --branch $(MOBILITYDB_REF) $(MOBILITYDB_REPO) $$tmpdir/mobilitydb && \
75+
cd $$tmpdir/meos-api && \
76+
git fetch origin $(MEOS_API_PR4):pr4 $(MEOS_API_PR5):pr5 $(MEOS_API_PR13):pr13 && \
77+
git checkout pr13 && \
78+
git merge --no-edit pr5 pr4 || true && \
79+
pip install --quiet --user -r requirements.txt && \
80+
python3 run.py $$tmpdir/mobilitydb/meos/include && \
81+
python3 generate_openapi.py && \
82+
python3 generate_movfeat_openapi.py && \
83+
( [ -f output/meos-movfeat-openapi.json ] && cp -v output/meos-movfeat-openapi.json $(CURDIR)/$(VENDOR_DIR)/ || \
84+
{ echo "::error::generate_movfeat_openapi.py produced no output/meos-movfeat-openapi.json"; exit 1; } ) && \
85+
cd $(CURDIR) && rm -rf $$tmpdir
86+
@echo "[vendor] done — $(VENDOR_DIR)/meos-movfeat-openapi.json refreshed from PR #13"

vendor/meos-api/PROVENANCE.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@
3535
},
3636
"meos-movfeat-openapi.json": {
3737
"source_repo": "MobilityDB/MEOS-API",
38-
"source_branch": "MISSING — natural follow-up named in PR #5's body",
39-
"describes": "OGC API – Moving Features OpenAPI projection. The immediate dependency for MobilityAPI per `docs/MEOS_API_INGESTION_PLAN.md`.",
40-
"status": "MISSING_UPSTREAM"
38+
"source_branch": "feat/movfeat-openapi-generator (PR #13)",
39+
"source_path": "output/meos-movfeat-openapi.json (generated by generate_movfeat_openapi.py + generator/movfeat.py; not committed)",
40+
"regenerate": "make vendor-meos-api-movfeat",
41+
"describes": "OGC API – Moving Features OpenAPI projection. The contract the OGC endpoints dispatch against, per `docs/MEOS_API_INGESTION_PLAN.md`.",
42+
"status": "FROM_OPEN_PR13"
4143
}
4244
}
4345
}

0 commit comments

Comments
 (0)