@@ -51,13 +51,22 @@ jobs:
5151 repository : GetTechAPI/TechAPI
5252 ref : ${{ env.TECHAPI_HEAD_SHA }}
5353 path : TechAPI
54+ fetch-depth : 0
5455
55- - name : Checkout TechAPI main
56+ - name : Checkout TechAPI PR base
5657 uses : actions/checkout@v4
5758 with :
5859 repository : GetTechAPI/TechAPI
59- ref : main
60- path : TechAPI-main
60+ ref : develop
61+ path : TechAPI-base
62+ fetch-depth : 0
63+
64+ - name : Pin PR base to the merge base
65+ shell : bash
66+ run : |
67+ git -C TechAPI fetch --no-tags origin develop
68+ base_sha="$(git -C TechAPI merge-base origin/develop HEAD)"
69+ git -C TechAPI-base checkout --detach "$base_sha"
6170
6271 - uses : actions/setup-python@v6
6372 with :
@@ -100,7 +109,7 @@ jobs:
100109 return files
101110
102111 head = rel_site_files(Path("TechAPI"))
103- base = rel_site_files(Path("TechAPI-main "))
112+ base = rel_site_files(Path("TechAPI-base "))
104113 added = sorted(set(head) - set(base))
105114 deleted = sorted(set(base) - set(head))
106115 modified = sorted(key for key in set(head) & set(base) if digest(head[key]) != digest(base[key]))
@@ -135,11 +144,26 @@ jobs:
135144
136145 {
137146 echo
138- echo "## integrity_check.py --strict"
139- python integrity_check.py TechAPI/data --strict
140- echo "integrity_status=$?"
147+ echo "## integrity_check.py (PR head compared with PR base)"
148+ python integrity_check.py TechAPI/data --hard-report head-hard.json
149+ echo "head_integrity_scan_status=$?"
150+ python integrity_check.py TechAPI-base/data --hard-report base-hard.json > baseline-integrity.log
151+ echo "base_integrity_scan_status=$?"
141152 } >> validation.log 2>&1
142- integrity_status=$(grep "integrity_status=" validation.log | tail -n 1 | cut -d= -f2)
153+ integrity_status=$(python - <<'PY'
154+ import json
155+ from pathlib import Path
156+
157+ head = set(json.loads(Path("head-hard.json").read_text(encoding="utf-8")))
158+ base = set(json.loads(Path("base-hard.json").read_text(encoding="utf-8")))
159+ introduced = sorted(head - base)
160+ with Path("validation.log").open("a", encoding="utf-8") as log:
161+ log.write(f"\nBaseline hard anomalies: {len(base)}; PR head: {len(head)}; introduced: {len(introduced)}\n")
162+ for anomaly in introduced:
163+ log.write(f"NEW HARD ANOMALY: {anomaly}\n")
164+ print("1" if introduced else "0")
165+ PY
166+ )
143167
144168 sed -i '/_status=/d' validation.log
145169
@@ -173,7 +197,6 @@ jobs:
173197 - name : Build data quality summary
174198 shell : bash
175199 run : |
176- git -C TechAPI fetch --no-tags --depth=1 origin main
177200 python - <<'PY'
178201 from __future__ import annotations
179202
@@ -186,7 +209,7 @@ jobs:
186209 from typing import Any
187210
188211 HEAD = Path("TechAPI/data")
189- BASE = Path("TechAPI-main /data")
212+ BASE = Path("TechAPI-base /data")
190213 CATEGORIES = (
191214 "brand",
192215 "soc",
@@ -227,8 +250,7 @@ jobs:
227250 "diff",
228251 "--name-status",
229252 "--no-renames",
230- "FETCH_HEAD",
231- "HEAD",
253+ "origin/develop...HEAD",
232254 "--",
233255 "data",
234256 ],
@@ -469,7 +491,7 @@ jobs:
469491 site_lines.append("## Changed site")
470492 site_lines.append("")
471493 head_site = rel_site_files(Path("TechAPI"))
472- base_site = rel_site_files(Path("TechAPI-main "))
494+ base_site = rel_site_files(Path("TechAPI-base "))
473495 site_added = sorted(set(head_site) - set(base_site))
474496 site_deleted = sorted(set(base_site) - set(head_site))
475497 site_modified = sorted(
@@ -573,12 +595,13 @@ jobs:
573595 continue
574596 if current_section and line.startswith(" "):
575597 section_counts[current_section] += 1
576- if any(token in line for token in ("DUP ", "slug!=file", " > ") ):
577- hard_lines.append(line)
598+ if line.startswith("NEW HARD ANOMALY: " ):
599+ hard_lines.append(line.removeprefix("NEW HARD ANOMALY: ") )
578600
579601 out: list[str] = []
580602 out.append("## Validation notes")
581603 out.append("")
604+ out.append("- The integrity gate blocks only hard anomalies introduced by this PR relative to its merge base.")
582605 out.append("- Full advisory outlier listings are suppressed on successful runs because they are dataset-wide and mostly stable between PRs.")
583606 out.append("- Failure runs still include a detailed log excerpt for debugging.")
584607 if key_lines:
@@ -596,7 +619,7 @@ jobs:
596619 out.append(f"| {name} | {count} |")
597620 if hard_lines:
598621 out.append("")
599- out.append("Potential blocking lines :")
622+ out.append("New blocking anomalies :")
600623 out.append("")
601624 out.append("```text")
602625 out.extend(hard_lines[:80])
@@ -654,7 +677,7 @@ jobs:
654677 echo "| Check | Result |"
655678 echo "| --- | --- |"
656679 echo "| \`python -m app.validate\` | $([ "${{ steps.validate.outputs.app_status }}" = "0" ] && echo PASS || echo FAIL) |"
657- echo "| \`python integrity_check.py TechAPI/data --strict\` | $([ "${{ steps.validate.outputs.integrity_status }}" = "0" ] && echo PASS || echo FAIL) |"
680+ echo "| New hard integrity anomalies vs PR base | $([ "${{ steps.validate.outputs.integrity_status }}" = "0" ] && echo PASS || echo FAIL) |"
658681 if [ "${site_changed}" = "true" ]; then
659682 echo "| \`cd TechAPI/site && npm ci && npm run build\` | $([ "${site_build_status}" = "0" ] && echo PASS || echo FAIL) |"
660683 fi
0 commit comments