fix(ci): cascade wait-step SHA capture leaked pip stdout (4th defect)
All checks were successful
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 3s
sop-tier-check / tier-check (pull_request) Successful in 11s

Run 5196 (2026-05-11 02:46Z, first-ever successful publish) succeeded
the publish job but failed the cascade job at the wait-for-PyPI-
propagation step:

  ::error::PyPI propagated 0.1.130 but wheel content SHA256 mismatch.
  ::error::Expected: 536b123816f3c7fb54690b80be482b28cabd1874690e9e93d8586af3864c7fba
  ::error::Got:      Collecting molecule-ai-workspace-runtime==0.1.130
  ::error::Fastly may be serving stale content. Refusing to fan out cascade.

The 'Got:' is pip's own stdout, not a SHA. Root cause:

  HASH=$(python -m pip download ... 2>/dev/null && sha256sum ... | awk ...)

The shell pipeline captures BOTH commands' stdout into $HASH. `2>/dev/null`
only silences stderr, not stdout. pip download writes 'Collecting ...' to
stdout by default, so it leaks into HASH ahead of sha256sum's output.

Fix: split into two steps, redirect pip stdout to /dev/null explicitly,
capture only sha256sum's output into HASH.

Impact: cascade-to-8-template-repos failed, but PyPI publish itself
succeeded. Users (workspace-template-* maintainers) can pin manually
via 'docker build --build-arg RUNTIME_VERSION=X.Y.Z' until cascade is
healed. hongming-pc is doing exactly this for the plugins_registry rollout.

4th and likely last workflow defect after #353, #355, #357.

Refs: #351, #353, #355, #357, #348 Q3
This commit is contained in:
claude-ceo-assistant 2026-05-10 19:51:18 -07:00
parent aed164ed6f
commit 84ffa2da6c

View File

@ -207,13 +207,23 @@ jobs:
# Stage (b): download wheel + SHA256 compare against what we built.
# Catches Fastly stale-content serving old bytes under a new version URL.
HASH=$(python -m pip download \
--no-deps \
--no-cache-dir \
--dest /tmp/wheel-probe \
"molecule-ai-workspace-runtime==${RUNTIME_VERSION}" \
2>/dev/null \
&& sha256sum /tmp/wheel-probe/*.whl | awk '{print $1}')
#
# Caught run 5196 (first-ever successful publish, 2026-05-11): the
# previous one-liner `HASH=$(pip download ... && sha256sum ...)`
# captured pip's stdout (`Collecting molecule-ai-workspace-runtime
# ==X.Y.Z`) into HASH, then the SHA comparison failed against the
# leaked `Collecting...` string. `2>/dev/null` silences stderr but
# NOT stdout; pip writes its progress to stdout by default.
# Fix: split into two steps, silence pip's stdout explicitly, capture
# only sha256sum's output into HASH.
python -m pip download \
--no-deps \
--no-cache-dir \
--dest /tmp/wheel-probe \
--quiet \
"molecule-ai-workspace-runtime==${RUNTIME_VERSION}" \
>/dev/null 2>&1
HASH=$(sha256sum /tmp/wheel-probe/*.whl | awk '{print $1}')
if [ "$HASH" != "$EXPECTED_SHA256" ]; then
echo "::error::PyPI propagated $RUNTIME_VERSION but wheel content SHA256 mismatch."
echo "::error::Expected: $EXPECTED_SHA256"