fix(preview): surface deploy errors, pin CLIs, remove unsafe fork guidance
Nobody has claimed this yet.
- Dominant language
- Shell
- Stars
- 0
- Forks
- 1
- Avg merge
- 32m
- Merged PRs (30d)
- 3
Description
Three problems in the two preview actions, from the 2026-07 maintenance audit.
1. A failed Cloudflare deploy produces no diagnostic output
preview-cloudflare/action.yml:93-98 runs DEPLOY_OUTPUT=$(wrangler pages deploy … 2>&1) under bash -eo pipefail: the assignment aborts the step on failure, and 2>&1 sent wrangler's stderr into the variable, so nothing is printed — the log ends at the 🔍 Deploying preview… line at :90. Every reporting path is therefore unreachable: the ::group::Deployment Output dump at :102-104 and the error branch at :106-109. The exit-code capture at :100 is dead both ways — on failure the step is already gone, on success DEPLOY_EXIT_CODE can only read 0.
Fix: wrangler … 2>&1 | tee "$RUNNER_TEMP/wrangler.log"; EXIT=${PIPESTATUS[0]}, plus ::error:: on failure — neither preview action has any ::error:: annotation today.
The companion half, the fatal URL grep, is already fixed: v0.11.1 (#131) made deploy-url a constructed alias at preview-cloudflare/action.yml:124, and the surviving deployment-url extraction at :131-134 ends || true.
preview-netlify/action.yml:72-78 has the same abort-before-dump problem (dump at :80-82) but does not redirect stderr, so netlify's human-readable error still reaches the log and only the captured --json error payload is discarded.
Separate Netlify defect: preview-netlify/action.yml:85 pipes the captured output into python3 -c "…json.load…", which exits non-zero on non-JSON stdout; under set -e the assignment aborts the step, so the "Raw output was:" guard at :88-93 cannot fire in the case it was written for. It only fires on valid JSON that lacks deploy_url/url.
2. netlify-cli@latest / wrangler@latest installed at run time and handed deploy credentials
preview-netlify/action.yml:59 and preview-cloudflare/action.yml:71. The repo SHA-pins every third-party Action against tag hijacking (CHANGELOG.md:328-331, the [0.8.0] Security entry), then fetches two unpinned npm packages with very large dependency trees on every PR and invokes them with the deploy tokens. .github/dependabot.yml declares only conda (:21), github-actions (:77) and docker (:113) — no npm ecosystem, so nothing would keep a pin current either.
Fix: pin exact versions and add npm to Dependabot, or pre-install both CLIs into the images.
Related: preview-netlify/action.yml:75 puts --auth="…" on the command line, landing in the generated step script on disk (PLAN item 8). The same step interpolates four more ${{ }} values — :66, :67, :73, :74 — and has no env: block at all (:61-65). v0.11.1 moved the Cloudflare equivalents into env: at preview-cloudflare/action.yml:77-85; move all five Netlify values in one edit, not just the token.
3. Both READMEs recommend pull_request_target for fork PRs
preview-netlify/README.md:173 and preview-cloudflare/README.md:182 — 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: the fork branch of the trust check tests github.event_name = 'pull_request' (preview-netlify/action.yml:39, preview-cloudflare/action.yml:51), so under pull_request_target it never fires and every fork PR is marked trusted; the deploy step then gates on the same condition (preview-netlify/action.yml:63, preview-cloudflare/action.yml:75) and is skipped outright, producing no preview at all.
Fix: delete the parenthetical; replace with an explicit warning that fork previews are unsupported and pull_request_target must not be used with these actions.
Checklist
-
tee+PIPESTATUSrewrite of the wrangler capture -
Make the Cloudflare URL grep non-fatal— done in v0.11.1 (#131): constructed alias URL plus a|| true-guardeddeployment-urlextraction - Same treatment for the netlify capture so the
--jsonpayload survives, and make the json-parse pipeline atpreview-netlify/action.yml:85non-fatal so the raw-output guard can actually fire -
::error::annotations on deploy failure in both actions - Pin
netlify-cliandwranglerto exact versions; add npm todependabot.yml - Move the Netlify auth token — and the other four interpolated inputs — into
env: - Delete the
pull_request_targetrecommendation from both READMEs; replace with a warning
Sequencing
Land the README pull_request_target deletion first: a two-line doc change with no code risk, and preview-*/README.md matches the harness IGNORED regex at .github/workflows/test-actions.yml:112, so it skips the harness rather than queueing behind the shell rewrite. The harness has no preview jobs, so the shell changes get no automated coverage — they need manual verification on a real PR against both providers.
Closes PLAN item 8.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the README sections at preview-netlify/README.md:173 and preview-cloudflare/README.md:182, then inspect the capture and credential-handling steps in both action.yml files. Review .github/dependabot.yml and the harness guidance in .github/workflows/test-actions.yml:112. Done means the unsafe guidance is replaced, both actions report deploy failures safely, credentials and CLI versions are handled as specified, and both providers receive manual verification because the harness has no preview jobs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions, node.js, python, shell
- Domain
- ci-cd, devops, documentation, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 52/100