fix(build): Linux artifact staging — absolute source + don't wipe output
Lint / pssa (push) Failing after 23s
Lint / python (push) Failing after 43s

Two bugs made the Linux smoke "succeed" with an empty artifact:
- artifact_source was always joined as workdir + '/' + src, so an
  absolute source (/opt/ci/output) became /opt/ci/build//opt/ci/output
  and was never found — only a non-fatal WARNING was logged.
- `rm -rf output_dir` ran unconditionally; when the build writes
  directly into the collect dir (the smoke case: output == source),
  it deleted the build output before collection.

Resolve absolute vs workdir-relative; when the source is the output
dir, collect in place without wiping; a missing/empty source is now a
hard failure instead of a silent empty artifact.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Simone
2026-05-17 16:12:50 +02:00
parent ce71c95083
commit ce5e68f357
+33 -10
View File
@@ -180,17 +180,40 @@ def _linux_build(
click.echo("[build run] artifact packaging skipped (--skip-artifact).")
return
t.run(f"rm -rf {_sh_quote(output_dir)} && mkdir -p {_sh_quote(output_dir)}")
# Resolve the artifact source: absolute path as-is, else relative
# to the build workdir. (artifact_source may be absolute, e.g.
# /opt/ci/output; the old `workdir + '/' + src` produced
# /opt/ci/build//opt/ci/output and silently found nothing.)
src = artifact_source or "dist"
cp_cmd = (
f"if [ -d {_sh_quote(workdir + '/' + src)} ]; then "
f"cp -r {_sh_quote(workdir + '/' + src + '/.')} {_sh_quote(output_dir + '/')}; "
f"elif [ -e {_sh_quote(workdir + '/' + src)} ]; then "
f"cp {_sh_quote(workdir + '/' + src)} {_sh_quote(output_dir + '/')}; "
f"else echo '[build run] WARNING: artifact source not found: {src}' >&2; fi"
)
t.run(cp_cmd)
click.echo(f"[build run] artifact staged at {output_dir}")
srcpath = src.rstrip("/") if src.startswith("/") else workdir.rstrip("/") + "/" + src
out = output_dir.rstrip("/")
if srcpath == out or srcpath.startswith(out + "/"):
# The build wrote directly into the collect dir; do NOT wipe it
# (that deleted the build output) and nothing to copy. Fail
# loudly if it is missing or empty rather than collecting an
# empty artifact.
click.echo(
f"[build run] artifact source is the output dir ({out}); collecting in place"
)
t.run(
f"if [ ! -d {_sh_quote(out)} ] || "
f'[ -z "$(ls -A {_sh_quote(out)} 2>/dev/null)" ]; then '
f"echo '[build run] artifact source not found or empty: {out}' >&2; "
f"exit 1; fi"
)
else:
t.run(f"rm -rf {_sh_quote(out)} && mkdir -p {_sh_quote(out)}")
cp_cmd = (
f"if [ -d {_sh_quote(srcpath)} ]; then "
f"cp -r {_sh_quote(srcpath + '/.')} {_sh_quote(out + '/')}; "
f"elif [ -e {_sh_quote(srcpath)} ]; then "
f"cp {_sh_quote(srcpath)} {_sh_quote(out + '/')}; "
f"else echo '[build run] artifact source not found: {srcpath}' >&2; "
f"exit 1; fi"
)
t.run(cp_cmd)
click.echo(f"[build run] artifact staged at {out}")
# ---------------------------------------------------------------- Windows flow