Skip to content

Commit d5599fc

Browse files
committed
fix(build): remove PyYAML dependency from entitlement checks
- parse workflow heredocs directly as text using the standard library - validate unique heredoc markers and report missing terminators - derive indentation from the heredoc terminator for robust extraction - improve malformed entitlement and workflow error messages
1 parent 0160276 commit d5599fc

1 file changed

Lines changed: 34 additions & 21 deletions

File tree

‎scripts/check_entitlements_sync.sh‎

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,45 +41,58 @@ FORBIDDEN = {
4141
}
4242
4343
44-
def entitlements_from_workflow(path, job, marker, terminator):
45-
"""The verbatim copy the signing job writes, lifted out of its heredoc."""
46-
import yaml
47-
d = yaml.safe_load(open(path))
48-
for step in d["jobs"][job]["steps"]:
49-
run = step.get("run") or ""
50-
if marker not in run:
51-
continue
52-
after = run.split(marker, 1)[1]
53-
lines = []
54-
for line in after.split("\n"):
55-
if line.strip() == terminator:
56-
break
57-
lines.append(line[10:] if line.startswith(" " * 10) else line)
58-
return plistlib.loads("\n".join(lines).encode())
59-
return None
44+
def entitlements_from_workflow(path, marker, terminator):
45+
"""The verbatim copy the signing job writes, lifted out of its heredoc.
46+
47+
Read as TEXT, not through a YAML parser. A heredoc body is a textual
48+
construct -- the workflow's own shell finds it exactly this way -- and
49+
reaching for PyYAML to locate it added a dependency the macOS runner's
50+
python3 does not have. This runs on stdlib alone, which is the only thing
51+
a check that gates a build should need.
52+
"""
53+
text = open(path, encoding="utf-8").read()
54+
if text.count(marker) != 1:
55+
return None, f"expected exactly one {marker.strip()} heredoc"
56+
57+
after = text.split(marker, 1)[1]
58+
body = []
59+
for line in after.split("\n"):
60+
if line.strip() == terminator:
61+
# De-indent by whatever the terminator is indented by: a heredoc
62+
# closed with <<- or written at a different depth still works.
63+
pad = len(line) - len(line.lstrip())
64+
return "\n".join(
65+
l[pad:] if l.startswith(" " * pad) else l for l in body
66+
), None
67+
body.append(line)
68+
return None, f"heredoc opened with {marker.strip()} is never closed"
6069
6170
6271
pairs = [
6372
(
6473
"Developer ID",
6574
f"{repo}/resource/entitlements/Normal.entitlements",
6675
f"{repo}/.github/workflows/build.yml",
67-
"sign-macos",
6876
"<<'PLIST'\n",
6977
"PLIST",
7078
),
7179
]
7280
73-
for name, repo_file, workflow, job, marker, terminator in pairs:
81+
for name, repo_file, workflow, marker, terminator in pairs:
7482
try:
7583
committed = plistlib.load(open(repo_file, "rb"))
7684
except Exception as exc: # noqa: BLE001
7785
failures.append(f"{name}: {repo_file} does not parse: {exc}")
7886
continue
7987
80-
applied = entitlements_from_workflow(workflow, job, marker, terminator)
81-
if applied is None:
82-
failures.append(f"{name}: no entitlements heredoc found in {job}")
88+
body, why = entitlements_from_workflow(workflow, marker, terminator)
89+
if body is None:
90+
failures.append(f"{name}: {why} in {workflow}")
91+
continue
92+
try:
93+
applied = plistlib.loads(body.encode())
94+
except Exception as exc: # noqa: BLE001
95+
failures.append(f"{name}: the copy in {workflow} does not parse: {exc}")
8396
continue
8497
8598
if committed != applied:

0 commit comments

Comments
 (0)