fix: refuse to publish a build that logged a vite error
verify-and-publish / gate (push) Successful in 14m30s
verify-and-publish / publish (push) Has been skipped

The build output went to /dev/null and only the exit code was checked,
which `astro build` returns as 0 even when vite cannot resolve an asset.
Run by hand -- the gate is not in the loop then -- this script would have
force-pushed that build over the live site.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Marcos Paulo
2026-09-06 09:15:42 +00:00
parent be271f65c1
commit 25ef5af63e
+14 -2
View File
@@ -65,7 +65,19 @@ fi
previous=$(git rev-parse origin/pages) previous=$(git rev-parse origin/pages)
echo "publish-pages: building $head" echo "publish-pages: building $head"
pnpm run build >/dev/null # `astro build` exits 0 even when vite fails to resolve an asset, so the exit
# code alone is not enough to know the build is whole. The gate greps for this
# too; repeat it here because this script is also run by hand.
build_log=$(mktemp)
trap 'rm -f "$build_log"' EXIT
pnpm run build >"$build_log" 2>&1 || {
cat "$build_log" >&2
fail 'astro build failed'
}
if grep -q '\[ERROR\]' "$build_log"; then
cat "$build_log" >&2
fail 'astro build logged an error and still exited 0; refusing to publish'
fi
# A build can succeed and still emit a stub -- that is exactly how this site # A build can succeed and still emit a stub -- that is exactly how this site
# would go down. Check the routes exist before overwriting anything live. # would go down. Check the routes exist before overwriting anything live.
@@ -80,7 +92,7 @@ done
# expected". mktemp -d gives a private directory to put that path in. # expected". mktemp -d gives a private directory to put that path in.
index_dir=$(mktemp -d) index_dir=$(mktemp -d)
index="$index_dir/index" index="$index_dir/index"
trap 'rm -rf "$index_dir"' EXIT trap 'rm -rf "$index_dir"; rm -f "$build_log"' EXIT
# `--force` because the repository .gitignore lists `dist`; here `dist` *is* the # `--force` because the repository .gitignore lists `dist`; here `dist` *is* the
# work tree, so those rules would otherwise exclude everything we mean to ship. # work tree, so those rules would otherwise exclude everything we mean to ship.
GIT_INDEX_FILE="$index" git --work-tree=dist add --all --force . GIT_INDEX_FILE="$index" git --work-tree=dist add --all --force .