Three related problems in the two preview actions: deploy failures are undebuggable, the deploy CLIs are unpinned, and both READMEs recommend an unsafe pattern. Found in the 2026-07 maintenance audit.
1. A failed Cloudflare deploy produces literally zero log output
At preview-cloudflare/action.yml:81, DEPLOY_OUTPUT=$(wrangler pages deploy … 2>&1) runs under bash -eo pipefail. The assignment aborts the step on failure, and because 2>&1 redirected wrangler's stderr into the variable, nothing was ever printed. That makes all of the following unreachable: the ::group::Deployment Output dump at :90, the exit-code check at :94, and the friendly error at :95.
The grep … | head -1 at :101 likewise aborts under pipefail when no URL matches, so the constructed-URL fallback at :104-107 is dead too.
Fix: wrangler … 2>&1 | tee "$RUNNER_TEMP/wrangler.log"; EXIT=${PIPESTATUS[0]}, read the URL with || true, and emit ::error::.
preview-netlify/action.yml:72 has the same abort-before-dump problem but does not redirect stderr, so it is much less damaging — the captured --json error payload is still discarded.
2. netlify-cli@latest / wrangler@latest are installed at run time and handed deploy credentials
preview-netlify/action.yml:59 and preview-cloudflare/action.yml:62. The repo SHA-pins every third-party Action specifically against tag hijacking (CHANGELOG.md:86) and then fetches two unpinned npm packages with very large dependency trees on every PR, immediately invoking them with the deploy tokens.
Fix: pin exact versions and add the npm ecosystem to Dependabot, or pre-install both CLIs into the images.
Related: preview-netlify/action.yml:75 puts --auth="…" on the command line, which lands in the generated step script on disk. The Cloudflare action correctly uses env:. Already tracked as PLAN item 8.
3. Both READMEs recommend pull_request_target for fork PRs
preview-netlify/README.md:173 and preview-cloudflare/README.md:181 — and this advice sits under a heading titled "Security".
Following it means building and executing fork-authored notebooks in a context holding NETLIFY_AUTH_TOKEN / CLOUDFLARE_API_TOKEN and a write-scoped GITHUB_TOKEN — the classic pwn-request pattern. It does not even work, because the deploy step gates on github.event_name == 'pull_request' at preview-netlify/action.yml:63.
Fix: delete the parenthetical and replace it with an explicit warning that fork previews are unsupported and pull_request_target must not be used with these actions.
Checklist
Closes PLAN item 8, and sets up the stable-alias work in #14.
Three related problems in the two preview actions: deploy failures are undebuggable, the deploy CLIs are unpinned, and both READMEs recommend an unsafe pattern. Found in the 2026-07 maintenance audit.
1. A failed Cloudflare deploy produces literally zero log output
At
preview-cloudflare/action.yml:81,DEPLOY_OUTPUT=$(wrangler pages deploy … 2>&1)runs underbash -eo pipefail. The assignment aborts the step on failure, and because2>&1redirected wrangler's stderr into the variable, nothing was ever printed. That makes all of the following unreachable: the::group::Deployment Outputdump at:90, the exit-code check at:94, and the friendly error at:95.The
grep … | head -1at:101likewise aborts underpipefailwhen no URL matches, so the constructed-URL fallback at:104-107is dead too.Fix:
wrangler … 2>&1 | tee "$RUNNER_TEMP/wrangler.log"; EXIT=${PIPESTATUS[0]}, read the URL with|| true, and emit::error::.preview-netlify/action.yml:72has the same abort-before-dump problem but does not redirect stderr, so it is much less damaging — the captured--jsonerror payload is still discarded.2.
netlify-cli@latest/wrangler@latestare installed at run time and handed deploy credentialspreview-netlify/action.yml:59andpreview-cloudflare/action.yml:62. The repo SHA-pins every third-party Action specifically against tag hijacking (CHANGELOG.md:86) and then fetches two unpinned npm packages with very large dependency trees on every PR, immediately invoking them with the deploy tokens.Fix: pin exact versions and add the npm ecosystem to Dependabot, or pre-install both CLIs into the images.
Related:
preview-netlify/action.yml:75puts--auth="…"on the command line, which lands in the generated step script on disk. The Cloudflare action correctly usesenv:. Already tracked as PLAN item 8.3. Both READMEs recommend
pull_request_targetfor fork PRspreview-netlify/README.md:173andpreview-cloudflare/README.md:181— and this advice sits under a heading titled "Security".Following it means building and executing fork-authored notebooks in a context holding
NETLIFY_AUTH_TOKEN/CLOUDFLARE_API_TOKENand a write-scopedGITHUB_TOKEN— the classic pwn-request pattern. It does not even work, because the deploy step gates ongithub.event_name == 'pull_request'atpreview-netlify/action.yml:63.Fix: delete the parenthetical and replace it with an explicit warning that fork previews are unsupported and
pull_request_targetmust not be used with these actions.Checklist
tee+PIPESTATUSrewrite of the wrangler capture; make the URL grep non-fatal--jsonpayload survives::error::annotations on deploy failure in both actionsnetlify-cliandwranglerto exact versions; add npm todependabot.ymlenv:pull_request_targetrecommendation from both READMEs; replace with a warningCloses PLAN item 8, and sets up the stable-alias work in #14.