bridge + ci-hygiene: Docker-needing CI jobs (option A)
- bridge: BRIDGE_NO_DAEMON names image-build jobs whose name lacks docker
(default eternitas:ci/build); never posted, like the docker-named ones.
- ci-hygiene: flag docker build/buildx/run/compose, docker-compose and
docker/build-push-action in workflow steps ("needs docker") with the fix:
job services: + a no-Docker smoke test; the image builds at deploy.
- test_guards_report: owner column (14ed23a broke it).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -45,9 +45,11 @@ MODE = os.environ.get("CI_HYGIENE_MODE", "warn")
|
||||
INCLUDE = re.compile(r"(^|/)\.(github|gitea)/workflows/[^/]+\.ya?ml$|(^|/)(Dockerfile[^/]*|[^/]+\.Dockerfile)$")
|
||||
NEVER = re.compile(r"(^|/)(node_modules|vendor|third_party)/")
|
||||
PREFILTER = (r"pip3? install|pip install|uv sync|npm (install|i )|yarn install|pnpm install"
|
||||
r"|^\s*-\s*['\"]?[0-9]+:[0-9]+|:latest|lock[^ ]*\*")
|
||||
r"|^\s*-\s*['\"]?[0-9]+:[0-9]+|:latest|lock[^ ]*\*"
|
||||
r"|docker[ -]compose|docker (build|buildx|run)|docker/build-push-action")
|
||||
|
||||
TOOLING = {"pip", "setuptools", "wheel"}
|
||||
NO_DOCKER_FIX = "use job services: + a no-Docker smoke test; the image builds at deploy"
|
||||
DOCKER_FILE = re.compile(r"(^|/)(Dockerfile[^/]*|[^/]+\.Dockerfile)$")
|
||||
LATEST = re.compile(r"(?:^\s*FROM\s+(?:--platform=\S+\s+)?|--from=|image:\s*['\"]?|docker://)([\w./-]+):latest\b", re.I)
|
||||
LOCKNAME = re.compile(r"(uv\.lock|poetry\.lock|package-lock\.json|pnpm-lock\.yaml|yarn\.lock|requirements[^ ]*\.(txt|lock))", re.I)
|
||||
@@ -121,8 +123,19 @@ def scan_line(path: str, text: str) -> list[tuple[str, str]]:
|
||||
globbed = [t for t in text.split() if "*" in t and LOCKNAME.search(t)]
|
||||
if globbed:
|
||||
hits.append(("optional lock", f"COPY {globbed[0]} (must fail if the lock is missing)"))
|
||||
# Windy Git jobs get NO Docker daemon (I-5), so a docker build/compose/run
|
||||
# step in CI can never pass here (orchestrator 09-23, option A). The real
|
||||
# image build is the deploy step on the target host.
|
||||
if "/workflows/" in path and re.search(r"uses:\s*['\"]?docker/build-push-action", text):
|
||||
hits.append(("needs docker", "docker/build-push-action in CI (no Docker daemon on Windy Git; " + NO_DOCKER_FIX + ")"))
|
||||
for toks in _commands(text):
|
||||
low = [t.lower() for t in toks]
|
||||
if "/workflows/" in path and (
|
||||
low[:2] in (["docker", "build"], ["docker", "buildx"], ["docker", "run"], ["docker", "compose"])
|
||||
or low[:1] == ["docker-compose"]
|
||||
):
|
||||
hits.append(("needs docker", f"{' '.join(low[:2])} in CI (no Docker daemon on Windy Git; " + NO_DOCKER_FIX + ")"))
|
||||
continue
|
||||
# pip install / python -m pip install / uv pip install
|
||||
for i in range(len(low) - 1):
|
||||
if os.path.basename(low[i]) in ("pip", "pip3") and low[i + 1] == "install":
|
||||
|
||||
Reference in New Issue
Block a user