fix(ci): eliminate bare bash lookup in contracts

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
Martin Vogel
2026-08-08 23:03:20 +02:00
parent df2088a7ab
commit bc4da94696
3 changed files with 37 additions and 4 deletions
@@ -7,7 +7,7 @@ set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
python3 - "$ROOT" <<'PY'
python3 - "$ROOT" "$BASH" <<'PY'
from __future__ import annotations
import json
@@ -26,6 +26,7 @@ import zipfile
root = pathlib.Path(sys.argv[1])
bash_executable = pathlib.Path(sys.argv[2])
failures: list[str] = []
@@ -382,7 +383,7 @@ def package_fixture(
archive_name = f"codebase-memory-mcp{'-ui' if variant == 'ui' else ''}-{host_goos}-fixture{archive_suffix}"
packaged = subprocess.run(
[
"bash",
str(bash_executable),
str(root / "scripts/package-release.sh"),
host_goos,
"fixture",
@@ -6,7 +6,7 @@ set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
python3 - "$ROOT" <<'PY'
python3 - "$ROOT" "$BASH" <<'PY'
from __future__ import annotations
import csv
@@ -25,6 +25,7 @@ from typing import Dict, List, Optional, Tuple
root = pathlib.Path(sys.argv[1])
bash_executable = pathlib.Path(sys.argv[2])
extractor = root / "scripts/ci/extract-release-archives.sh"
unix_targets = (
"linux-amd64",
@@ -307,7 +308,13 @@ def invoke(
args: Optional[List[str]] = None,
) -> subprocess.CompletedProcess:
return subprocess.run(
["bash", str(extractor), str(archive_dir), str(output_dir), *(args or count_args)],
[
str(bash_executable),
str(extractor),
str(archive_dir),
str(output_dir),
*(args or count_args),
],
cwd=root,
text=True,
stdout=subprocess.PIPE,
+25
View File
@@ -318,6 +318,31 @@ for local, pattern, why in LOCAL_REQUIRED:
if path.exists() and not re.search(pattern, path.read_text()):
failures.append(f"{local}: missing required `{pattern}` — {why}")
# Native Windows process lookup searches system locations before PATH. A bare
# `bash` argv launched by embedded Python can therefore select the WSL alias
# instead of the MSYS2 Bash that is already running this contract. Every
# shell-hosted Python block must receive the current `$BASH` as an explicit
# argument and launch that resolved path. Enforce this textually on every
# maintained shell surface so the rule is deterministic on non-Windows hosts
# too, rather than relying on a runner to happen to have the WSL alias.
BARE_BASH_ARGV = re.compile(r"""[\[(]\s*["']bash["']\s*,""")
shell_surfaces = list(root.glob("*.sh"))
for directory in ("tests", "scripts", "test-infrastructure", "pkg"):
base = root / directory
if not base.exists():
continue
shell_surfaces.extend(base.rglob("*.sh"))
for path in sorted(shell_surfaces):
text = path.read_text(encoding="utf-8")
for match in BARE_BASH_ARGV.finditer(text):
number = text.count("\n", 0, match.start()) + 1
relative = path.relative_to(root).as_posix()
failures.append(
f"{relative}:{number}: embedded Python must launch the current "
"$BASH by explicit argv path; bare `bash` is WSL-alias-sensitive "
"under native Windows process lookup"
)
if failures:
print("VENUE PARITY CONTRACT VIOLATED — one harness, every venue:")
for failure in failures: