pcbjam/deploy/site/03-ensure-project.sh
Viktor Vaczi 04ce88f8a4 fix(deploy/site): make the Pages steps work with wrangler login alone
`wrangler login` yields an OAuth token that wrangler uses itself but that
cannot be replayed as a REST bearer token, and it only carries zone:read.
03 and 06 were reaching for the REST API for things wrangler can answer,
so they died on a missing CLOUDFLARE_API_TOKEN even though every Pages
operation they needed was already authorised.

03 now reads `pages project list --json` for existence and the Git
provider, and proves the production branch EMPIRICALLY from
`pages deployment list --environment production` — if a deployment on
that branch is labelled Production, the setting must be right. That is a
stronger check than reading the field, which the REST endpoint would have
given us. 06 resolves the production deployment the same way.

cf_have_token() marks the boundary, and cf_token() now explains why a
login is not sufficient for the DNS/ruleset/HSTS phases of 07.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LAmkjM7okPdScp9XLW1JVr
2026-07-27 14:04:28 +02:00

75 lines
3.5 KiB
Shell
Executable file

#!/usr/bin/env bash
# Idempotently ensure the Cloudflare Pages project exists with the right
# production branch and compatibility settings.
#
# deploy/site/03-ensure-project.sh # dry run
# deploy/site/03-ensure-project.sh --apply
#
# Naming this "ensure" rather than "create" is the contract: running it twice is
# normal and must not look like an error.
set -euo pipefail
. "$(dirname "$0")/lib/common.sh"
. "$(dirname "$0")/lib/cf-api.sh"
require_cmd curl jq npx
parse_common_flags "$@"
dry_banner
section "project $PAGES_PROJECT"
row="$($WRANGLER pages project list --json 2>/dev/null \
| jq -r --arg n "$PAGES_PROJECT" '.[] | select(."Project Name"==$n)')"
if [ -n "$row" ]; then
echo "exists already"
else
dry "create Pages project $PAGES_PROJECT (production branch: $PAGES_PROD_BRANCH)" -- \
$WRANGLER pages project create "$PAGES_PROJECT" \
--production-branch "$PAGES_PROD_BRANCH" \
--compatibility-date 2026-06-01 --compatibility-flags nodejs_compat
[ "$DRY_RUN" = 1 ] && { echo; echo "done: (dry run) would create $PAGES_PROJECT"; exit 0; }
row="$($WRANGLER pages project list --json 2>/dev/null \
| jq -r --arg n "$PAGES_PROJECT" '.[] | select(."Project Name"==$n)')"
[ -n "$row" ] || die "project still not listed after create"
fi
section "asserting settings"
# `wrangler pages project list` reports the Git provider but not the production
# branch, and the REST endpoint that would needs an API token. So prove the branch
# EMPIRICALLY instead, from the deployments: if a deployment on $PAGES_PROD_BRANCH
# is labelled Production, the project's production branch is that branch. That is
# a stronger check than reading the setting.
src="$(printf '%s' "$row" | jq -r '."Git Provider" // "?"')"
dom="$(printf '%s' "$row" | jq -r '."Project Domains" // "?"')"
if [ "$src" != "No" ]; then
die "project appears Git-connected (Git Provider: $src). Cloudflare's own builds
would race the uploads from deploy-site.yml. Disconnect it in the dashboard."
fi
echo " ok Direct Upload (not Git-connected)"
prod="$($WRANGLER pages deployment list --project-name "$PAGES_PROJECT" \
--environment production --json 2>/dev/null || true)"
nprod="$(printf '%s' "$prod" | jq 'length' 2>/dev/null || echo 0)"
if [ "${nprod:-0}" -gt 0 ]; then
br="$(printf '%s' "$prod" | jq -r '.[0].Branch // "?"')"
env="$(printf '%s' "$prod" | jq -r '.[0].Environment // "?"')"
# The most expensive mistake available here: if the project's production branch
# is not what deploy-site.yml passes to --branch, every deploy lands as a
# PREVIEW and the live site silently never updates (see deploy-demo.yml).
if [ "$br" = "$PAGES_PROD_BRANCH" ] && [ "$env" = "Production" ]; then
echo " ok branch '$br' deploys land as $env"
else
die "latest production-environment deployment is branch='$br' env='$env',
but deploys use --branch '$PAGES_PROD_BRANCH'. If those disagree, every deploy
becomes a preview and www.pcbjam.com never updates. Fix it in
Pages -> $PAGES_PROJECT -> Settings -> Builds & deployments."
fi
else
warn "no production deployment yet — the branch check runs after 05-deploy.sh"
fi
sub="$(printf '%s' "$dom" | sed 's/,.*//')"
section "done"
echo "note: the custom domain is NOT set here — there is no 'wrangler pages domain'"
echo " subcommand. 07-dns-cutover.sh attaches www.pcbjam.com via the API,"
echo " which needs a real API token (wrangler's OAuth login is zone:read only)."
echo "done: https://${sub}"