@@ -46,27 +46,28 @@ def _bake_file(library: str) -> Path:
4646 return REPO_ROOT / "utils" / "build" / "docker" / library / "docker-bake.hcl"
4747
4848
49+ def _run (cmd : list [str ]) -> subprocess .CompletedProcess :
50+ """Run `cmd`, printing stderr (and stdout, if any) before raising on failure."""
51+ result = subprocess .run (cmd , cwd = REPO_ROOT , check = False , capture_output = True , text = True )
52+ if result .returncode != 0 :
53+ print (f"Error: command failed: { ' ' .join (cmd )} " )
54+ if result .stdout :
55+ print (result .stdout )
56+ if result .stderr :
57+ print (result .stderr )
58+ result .check_returncode ()
59+ return result
60+
61+
4962def _bake_config (bake_file : Path , target : str ) -> dict :
5063 """Resolved bake config (context, dockerfile, args, tags) for a single target."""
51- result = subprocess .run (
52- ["docker" , "buildx" , "bake" , "--print" , "--progress" , "quiet" , "-f" , str (bake_file ), target ],
53- cwd = REPO_ROOT ,
54- check = True ,
55- capture_output = True ,
56- text = True ,
57- )
64+ result = _run (["docker" , "buildx" , "bake" , "--print" , "--progress" , "quiet" , "-f" , str (bake_file ), target ])
5865 return json .loads (result .stdout )["target" ][target ]
5966
6067
6168def _tracked_files (path : str ) -> list [Path ]:
6269 """Every git-tracked file under `path` (a file or a directory), sorted."""
63- result = subprocess .run (
64- ["git" , "ls-files" , path ],
65- cwd = REPO_ROOT ,
66- check = True ,
67- capture_output = True ,
68- text = True ,
69- )
70+ result = _run (["git" , "ls-files" , path ])
7071 return sorted (REPO_ROOT / line for line in result .stdout .splitlines () if line )
7172
7273
@@ -94,18 +95,25 @@ def compute_hash(bake_config: dict, dependencies: list[str]) -> str:
9495
9596
9697def image_exists (tag : str ) -> bool :
98+ """Whether `tag` exists on the registry. `docker manifest inspect` exits non-zero both
99+ when the tag genuinely doesn't exist and on unrelated failures (auth, network); print
100+ the error either way so a real failure isn't silently mistaken for a missing tag.
101+ """
97102 result = subprocess .run (
98103 ["docker" , "manifest" , "inspect" , tag ],
99104 cwd = REPO_ROOT ,
100105 check = False ,
101106 capture_output = True ,
107+ text = True ,
102108 )
109+ if result .returncode != 0 and result .stderr :
110+ print (result .stderr .strip ())
103111 return result .returncode == 0
104112
105113
106114def build_and_push (bake_file : Path , target : str , tag : str ) -> None :
107115 print (f"Building and pushing { tag } " )
108- subprocess . run (
116+ _run (
109117 [
110118 "docker" ,
111119 "buildx" ,
@@ -117,9 +125,7 @@ def build_and_push(bake_file: Path, target: str, tag: str) -> None:
117125 "-f" ,
118126 str (bake_file ),
119127 target ,
120- ],
121- cwd = REPO_ROOT ,
122- check = True ,
128+ ]
123129 )
124130
125131
0 commit comments