b26d292a64
gates / gates (push) Failing after 1m40s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
28 lines
1.3 KiB
Python
28 lines
1.3 KiB
Python
#!/usr/bin/env python3
|
|
"""R-345: nothing in this repo's build tooling tags or pushes an image as `:latest`.
|
|
Scans hub/Makefile, scripts/build-hub.sh and every Dockerfile/Makefile/*.sh under hub/ and scripts/ (a walk).
|
|
Run: python3 scripts/test_no_latest_push.py"""
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
BAD = re.compile(r"^(?![ \t]*#)[^\n]*?(\bdocker\s+(tag|push)\b[^#\n]*:latest\b|-t\s+\S*:latest\b)", re.M)
|
|
hits, scanned = [], 0
|
|
for top in ("hub", "scripts"):
|
|
for dp, dns, fns in os.walk(os.path.join(ROOT, top)):
|
|
dns[:] = [d for d in dns if d not in (".git", "__pycache__", "node_modules")]
|
|
for f in fns:
|
|
if f in ("Makefile", "Dockerfile") or f.endswith(".sh"):
|
|
p = os.path.join(dp, f)
|
|
scanned += 1
|
|
for m in BAD.finditer(open(p, encoding="utf-8", errors="replace").read()):
|
|
hits.append("%s: %s" % (os.path.relpath(p, ROOT), m.group(0).strip()))
|
|
if scanned < 5:
|
|
print("FAIL: scanned only %d build files — the scope is wrong" % scanned)
|
|
sys.exit(1)
|
|
if hits:
|
|
print("FAIL: a :latest tag/push in build tooling (R-345):\n " + "\n ".join(hits))
|
|
sys.exit(1)
|
|
print("OK: %d build files, no docker tag/push of :latest" % scanned)
|