Skip to content

Commit da4d0e8

Browse files
committed
ci: only run homepage validation for site changes
1 parent c792312 commit da4d0e8

1 file changed

Lines changed: 83 additions & 25 deletions

File tree

.github/workflows/techapi-pr-validation-comment.yml

Lines changed: 83 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,56 @@ jobs:
6464
python-version: "3.12"
6565
cache: pip
6666

67+
- name: Detect TechAPI homepage changes
68+
id: site_changes
69+
shell: bash
70+
run: |
71+
set -euo pipefail
72+
python - <<'PY' >> "$GITHUB_OUTPUT"
73+
from __future__ import annotations
74+
75+
import hashlib
76+
import re
77+
from pathlib import Path
78+
79+
def digest(path: Path) -> str:
80+
return hashlib.sha256(path.read_bytes()).hexdigest()
81+
82+
def rel_site_files(root: Path) -> dict[str, Path]:
83+
site = root / "site"
84+
if not site.exists():
85+
return {}
86+
wanted_files = {"site/package.json", "site/package-lock.json"}
87+
files: dict[str, Path] = {}
88+
for path in sorted(site.rglob("*")):
89+
if not path.is_file():
90+
continue
91+
rel = str(path.relative_to(root)).replace("\\", "/")
92+
if (
93+
rel.startswith("site/src/")
94+
or rel.startswith("site/public/")
95+
or rel in wanted_files
96+
or re.match(r"site/astro\.config\.[cm]?[jt]s$", rel)
97+
):
98+
if rel.startswith("site/public/v1/") or rel == "site/public/openapi.json":
99+
continue
100+
files[rel] = path
101+
return files
102+
103+
head = rel_site_files(Path("TechAPI"))
104+
base = rel_site_files(Path("TechAPI-main"))
105+
added = sorted(set(head) - set(base))
106+
deleted = sorted(set(base) - set(head))
107+
modified = sorted(key for key in set(head) & set(base) if digest(head[key]) != digest(base[key]))
108+
has_changes = bool(added or modified or deleted)
109+
print(f"changed={'true' if has_changes else 'false'}")
110+
print(f"added={len(added)}")
111+
print(f"modified={len(modified)}")
112+
print(f"deleted={len(deleted)}")
113+
PY
114+
67115
- uses: actions/setup-node@v4
116+
if: steps.site_changes.outputs.changed == 'true'
68117
with:
69118
node-version: "22"
70119
cache: npm
@@ -105,6 +154,7 @@ jobs:
105154
echo "integrity_status=${integrity_status:-1}" >> "$GITHUB_OUTPUT"
106155
107156
- name: Build TechAPI homepage
157+
if: steps.site_changes.outputs.changed == 'true'
108158
id: site_build
109159
shell: bash
110160
run: |
@@ -419,11 +469,13 @@ jobs:
419469
run: |
420470
short_sha="${TECHAPI_HEAD_SHA:0:7}"
421471
result="PASS"
422-
if [ "${{ steps.validate.outputs.status }}" != "success" ] || [ "${{ steps.site_build.outputs.status }}" != "0" ]; then
472+
site_changed="${{ steps.site_changes.outputs.changed }}"
473+
site_build_status="${{ steps.site_build.outputs.status }}"
474+
if [ "${{ steps.validate.outputs.status }}" != "success" ] || { [ "${site_changed}" = "true" ] && [ "${site_build_status}" != "0" ]; }; then
423475
result="FAIL"
424476
fi
425477
426-
VALIDATION_STATUS="${{ steps.validate.outputs.status }}" SITE_BUILD_STATUS="${{ steps.site_build.outputs.status }}" python - <<'PY'
478+
VALIDATION_STATUS="${{ steps.validate.outputs.status }}" SITE_CHANGED="${{ steps.site_changes.outputs.changed }}" SITE_BUILD_STATUS="${{ steps.site_build.outputs.status }}" python - <<'PY'
427479
from __future__ import annotations
428480
429481
import os
@@ -434,7 +486,8 @@ jobs:
434486
log = log_path.read_text(encoding="utf-8", errors="replace")
435487
lines = log.splitlines()
436488
failed = os.environ.get("VALIDATION_STATUS") != "success"
437-
site_failed = os.environ.get("SITE_BUILD_STATUS") != "0"
489+
site_changed = os.environ.get("SITE_CHANGED") == "true"
490+
site_failed = site_changed and os.environ.get("SITE_BUILD_STATUS") != "0"
438491
439492
section_counts: dict[str, int] = {}
440493
current_section: str | None = None
@@ -491,28 +544,29 @@ jobs:
491544
out.append("")
492545
out.append("</details>")
493546
494-
site_log_path = Path("site-build.log")
495-
site_log = site_log_path.read_text(encoding="utf-8", errors="replace") if site_log_path.exists() else ""
496-
site_log = re.sub(r"\x1b\[[0-9;]*m", "", site_log)
497-
if site_failed:
498-
out.append("")
499-
out.append("<details><summary>Detailed homepage build log excerpt</summary>")
500-
out.append("")
501-
out.append("```text")
502-
excerpt = site_log[-12000:] if len(site_log) > 12000 else site_log
503-
out.append(excerpt.rstrip())
504-
out.append("```")
505-
out.append("")
506-
out.append("</details>")
507-
elif site_log:
508-
summary = [line for line in site_log.splitlines() if "Complete!" in line or "page(s) built" in line]
509-
if summary:
547+
if site_changed:
548+
site_log_path = Path("site-build.log")
549+
site_log = site_log_path.read_text(encoding="utf-8", errors="replace") if site_log_path.exists() else ""
550+
site_log = re.sub(r"\x1b\[[0-9;]*m", "", site_log)
551+
if site_failed:
510552
out.append("")
511-
out.append("Homepage build:")
553+
out.append("<details><summary>Detailed homepage build log excerpt</summary>")
512554
out.append("")
513555
out.append("```text")
514-
out.extend(summary[-4:])
556+
excerpt = site_log[-12000:] if len(site_log) > 12000 else site_log
557+
out.append(excerpt.rstrip())
515558
out.append("```")
559+
out.append("")
560+
out.append("</details>")
561+
elif site_log:
562+
summary = [line for line in site_log.splitlines() if "Complete!" in line or "page(s) built" in line]
563+
if summary:
564+
out.append("")
565+
out.append("Homepage build:")
566+
out.append("")
567+
out.append("```text")
568+
out.extend(summary[-4:])
569+
out.append("```")
516570
517571
Path("validation-notes.md").write_text("\n".join(out) + "\n", encoding="utf-8")
518572
PY
@@ -531,11 +585,15 @@ jobs:
531585
echo "| --- | --- |"
532586
echo "| \`python -m app.validate\` | $([ "${{ steps.validate.outputs.app_status }}" = "0" ] && echo PASS || echo FAIL) |"
533587
echo "| \`python integrity_check.py TechAPI/data --strict\` | $([ "${{ steps.validate.outputs.integrity_status }}" = "0" ] && echo PASS || echo FAIL) |"
534-
echo "| \`cd TechAPI/site && npm ci && npm run build\` | $([ "${{ steps.site_build.outputs.status }}" = "0" ] && echo PASS || echo FAIL) |"
588+
if [ "${site_changed}" = "true" ]; then
589+
echo "| \`cd TechAPI/site && npm ci && npm run build\` | $([ "${site_build_status}" = "0" ] && echo PASS || echo FAIL) |"
590+
fi
535591
echo
536592
cat change-review.md
537-
echo
538-
cat site-change-review.md
593+
if [ "${site_changed}" = "true" ]; then
594+
echo
595+
cat site-change-review.md
596+
fi
539597
} > change-comment.md
540598
541599
{
@@ -586,5 +644,5 @@ jobs:
586644
run: echo "::warning::TECHENGINEBOT_TOKEN/TECHAPI_TOKEN is not configured; validation ran but no PR comment was posted."
587645

588646
- name: Fail on validation errors
589-
if: steps.validate.outputs.status != 'success' || steps.site_build.outputs.status != '0'
647+
if: steps.validate.outputs.status != 'success' || (steps.site_changes.outputs.changed == 'true' && steps.site_build.outputs.status != '0')
590648
run: exit 1

0 commit comments

Comments
 (0)