Skip to content

ci: replace Fleek deployment with Cloudflare Pages direct upload - #189

Merged
levalleux-ludo merged 5 commits into
mainfrom
ci/cloudflare-pages-direct-upload
Sep 8, 2026
Merged

ci: replace Fleek deployment with Cloudflare Pages direct upload#189
levalleux-ludo merged 5 commits into
mainfrom
ci/cloudflare-pages-direct-upload

Conversation

@levalleux-ludo

Copy link
Copy Markdown
Member

Replicates interface#1181 for this repo.

Why

The committed workflows still deploy to Fleek, while the live sites are the Cloudflare Pages projects boson-widgets-testing, boson-widgets-staging and boson-widgets, fed by Cloudflare's Git integration off main, deploy/staging and deploy/production. Build settings and env vars for those live in the Cloudflare dashboard: undiffable and invisible to code review. The last release deploy (v0.0.50, Feb 2026) failed outright.

What changes

Build in GitHub Actions and upload with wrangler (Direct Upload). Because every REACT_APP_* is inlined at build time by CRA, Cloudflare no longer needs to build anything — so its dashboard build settings and env vars become irrelevant, not merely duplicated.

Where configuration lives

Unlike interface#1181, which moved ~30 values into GitHub variables, the non-secret values here stay committed in deploy_reusable.yaml — the IPFS gateway, the ipfs:// templates, the dispute periods and the per-environment dApp/DR-Center URLs. They were already in ci_reusable.yaml, where they are diffable and reviewed alongside the code that reads them; moving them into a dashboard-like store would be a regression against the very thing that PR was fixing.

Only secrets move into the testing / staging / production GitHub Environments. That drops the _STAGING / _PRODUCTION name suffixes: GitHub resolves the environment's value and falls back to the repository-level one.

This repo stays on npm. No pnpm migration — that is not part of the deployment change.

Deploy triggers

Env Trigger Lands at
preview every PR (non-fork) pr-<n>.boson-widgets-testing.pages.dev, posted as a sticky comment
testing push to main boson-widgets-testing.pages.dev, gated on the CI checks
staging release published boson-widgets-staging.pages.dev, builds that tag
production manual dispatch with a tag widgets.bosonprotocol.io, builds that tag

published rather than created: created does not fire when a release is published from a draft, which is one way the old workflow could silently skip a deploy.

Incidental fixes

  • Preflight check for the values a deployment cannot work without. src/config.ts throws at module load for ~10 REACT_APP_* variables, and CRA only compiles that file rather than executing it — so a missing value currently builds green, uploads green and serves a blank page. This is the single most valuable step in the PR, and it matters more here than in interface, whose config.ts throws on only three.
  • Non-mutating gates. npm run prettier and npm run lint are --write/--fix, so as CI steps they gated nothing and left the build compiling something other than the committed code. Added prettier:check, lint:check and tsc, run first. All three pass clean on the current tree.
  • There was no testing deploy in CI at all, and PRs built with REACT_APP_ENV_NAME=staging but deployed nothing.
  • Node pinning: CI said 24, volta said 22.14.0, docs/local-development.md said 16.X. Collapsed onto .nvmrc (24, the version CI has actually been shipping with).
  • Dropped @fleek-platform/cli, which took its AWS SDK tree with it (−3270 lockfile lines).

Verification done locally

  • npm ci from the regenerated lockfile; prettier:check, lint:check, tsc — all clean.
  • actionlint — clean across all workflows.
  • npm run build with the workflow's exact testing values: 22M bundle, no file near Cloudflare's 25 MiB limit, no source maps, and no process.env.REACT_APP_* literals survive — confirming the values reach @bosonprotocol/react-kit too, not just src/.
  • Served build/ headless: #/dev, #/redeem and #/finance all render with no config.ts throw. #/redeem shows the app's own Missing 'configId' query param message, i.e. the bundle is live, not blank.

⚠️ Required before merge — this cannot deploy until the setup is done

Repository secrets — add CLOUDFLARE_API_TOKEN (scope: Cloudflare Pages → Edit) and CLOUDFLARE_ACCOUNT_ID. Keep REACT_APP_INFURA_IPFS_PROJECT_ID / _SECRET and both REACT_APP_META_TX_* repository variables as they are.

Three GitHub Environments — none exist today. Each needs a CF_PROJECT variable and three secrets:

testing staging production
var CF_PROJECT boson-widgets-testing boson-widgets-staging boson-widgets
REACT_APP_INFURA_KEY ⚠️ no value exists yet from ..._STAGING from ..._PRODUCTION
REACT_APP_MAGIC_API_KEY ⚠️ no value exists yet from ..._STAGING from ..._PRODUCTION
REACT_APP_WALLET_CONNECT_PROJECT_ID ⚠️ no value exists yet from ..._STAGING from ..._PRODUCTION

The repo has no _TESTING secrets — CI has never built a testing bundle. Take those three from the boson-widgets-testing Cloudflare project's current environment variables, or reuse the staging values if they are shared.

Check each project's production branch with wrangler pages project list. A --branch that does not equal the project's production branch lands as a Preview deployment and the live URL keeps serving the old build. boson-widgets-staging and boson-widgets were Git-connected to deploy/staging / deploy/production, so their production branch is very likely not main — either change it in the dashboard or change cf_branch in deploy-staging.yaml / deploy-production.yaml. Please confirm this before merging.

Then, in this order: merge → confirm a testing deploy → only then disconnect Cloudflare's Git integration on all three projects, so there is never a window without a working deploy path. Once staging and production have each deployed once through the new flow, delete the deploy/staging and deploy/production branches and the now-unused FLEEK_API_KEY, FLEEK_TOKEN, FLEEK_PROJECT_ID and _STAGING/_PRODUCTION-suffixed secrets.

Branch protection on main should require the Format, lint, types and build job of CI - Widgets. Required checks match by name, so renaming the workflow or job detaches the rule silently.

Known trade-off

PR previews use the testing Environment to avoid duplicating secrets, so preview deployments appear in that environment's history alongside real testing deploys. A separate preview Environment would separate them at the cost of a second copy of the values.

🤖 Generated with Claude Code

The committed workflows still deployed to Fleek, while the live sites are the
Cloudflare Pages projects boson-widgets-testing, boson-widgets-staging and
boson-widgets, fed by Cloudflare's Git integration off main, deploy/staging and
deploy/production. Build settings and env vars for those lived in the Cloudflare
dashboard: undiffable and invisible to code review. The last release deploy
(v0.0.50) failed outright.

Build in GitHub Actions and upload with wrangler (Direct Upload). Because every
REACT_APP_* is inlined at build time by CRA, Cloudflare no longer needs to build
anything, so its dashboard build settings and env vars become irrelevant rather
than merely duplicated.

Non-secret configuration stays committed in deploy_reusable.yaml, where it is
diffable and reviewed alongside the code that reads it. Only secrets move into
the testing/staging/production GitHub Environments, which drops the
_STAGING/_PRODUCTION name suffixes: GitHub resolves the environment's value and
falls back to the repository-level one.

Deploy triggers:

  preview     every PR, published at pr-<n>.boson-widgets-testing.pages.dev
  testing     push to main, gated on the CI checks
  staging     release published, builds that tag
  production  manual dispatch with a tag

Incidental fixes:

- Preflight check for the values a deployment cannot work without. src/config.ts
  throws at module load for ~10 REACT_APP_* variables, and CRA only compiles that
  file rather than executing it, so a missing value currently builds green,
  uploads green and serves a blank page.
- Non-mutating gates. npm run prettier and npm run lint are --write/--fix, so as
  CI steps they gated nothing and left the build compiling something other than
  the committed code. Added prettier:check, lint:check and tsc, and run them
  first. All three pass clean on the current tree.
- There was no testing deploy in CI at all, and PRs built with
  REACT_APP_ENV_NAME=staging but deployed nothing.
- Node pinning: CI said 24, volta said 22.14.0, docs said 16.X. Collapsed onto
  .nvmrc (24, the version CI has actually been shipping with).
- Dropped @fleek-platform/cli, which took its AWS SDK tree with it.

Verified locally: npm ci from the regenerated lockfile, prettier:check,
lint:check and tsc all clean; actionlint clean across all workflows; a build with
the workflow's exact testing values produces a 22M bundle with no file near
Cloudflare's 25 MiB limit and no source maps, every REACT_APP_* substituted (no
process.env.REACT_APP_* literals survive); served headless, #/dev, #/redeem and
#/finance all render with no config.ts throw.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 8, 2026 09:15
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It changes production deployment workflows and depends on external GitHub Environment/Cloudflare configuration that can’t be validated from the diff alone.

Pull request overview

This PR migrates the repo’s GitHub Actions deployment path from Fleek to Cloudflare Pages “Direct Upload” via wrangler, making builds fully GitHub-driven and reducing reliance on Cloudflare dashboard build configuration.

Changes:

  • Adds reusable build+deploy workflow plus environment-specific deploy workflows for preview/testing/staging/production Cloudflare Pages uploads.
  • Replaces the previous CI workflow structure with a single CI workflow that runs non-mutating format/lint/type checks (and only builds for fork PRs), and is callable to gate testing deploys.
  • Aligns Node usage via .nvmrc, adds tsc, lint:check, prettier:check scripts, and removes Fleek tooling/config.
File summaries
File Description
README.md Documents new Cloudflare Pages environments, triggers, and configuration ownership.
package.json Adds non-mutating check scripts (prettier:check, lint:check) and tsc; removes Volta config and Fleek CLI.
package-lock.json Regenerates lockfile reflecting removed Fleek dependency tree and related dependency graph changes.
docs/local-development.md Updates local dev prerequisites and adds a “Checks” section matching CI commands.
.nvmrc Introduces a single source of truth for Node version selection.
.github/workflows/deploy-testing.yaml Deploys to testing on main pushes, gated by CI via workflow_call.
.github/workflows/deploy-staging.yaml Deploys tagged releases to staging on release published.
.github/workflows/deploy-production.yaml Adds manual production deploy-by-tag with tag existence verification.
.github/workflows/deploy-preview.yaml Adds PR preview deployments (non-forks) and posts a sticky PR comment with URLs.
.github/workflows/deploy_reusable.yaml Implements the shared build + required-config preflight + Cloudflare Pages upload + smoke check.
.github/workflows/ci.yaml Replaces legacy CI with a single “CI - Widgets” workflow usable by PRs and as a callable gate.
.github/workflows/ci_reusable.yaml Removes the old Fleek-oriented reusable workflow.
.github/actions/setup-node-npm/action.yml Adds a composite action to standardize Node setup from .nvmrc with npm caching.
.fleek.json Removes Fleek site config.
.fleek_staging.json Removes Fleek staging config.
.fleek_production.json Removes Fleek production config.
Review details
  • Files reviewed: 15/16 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/deploy_reusable.yaml Outdated
@levalleux-ludo

Copy link
Copy Markdown
Member Author

First run: green, end to end ✅

The testing Environment has since been created (CF_PROJECT=boson-widgets-testing plus the three secrets), so the preview path ran for real:

npx wrangler pages deploy build --project-name=boson-widgets-testing --branch=pr-189 \
  --commit-hash=dbea255bbedc770226ed6fe9e2c8251dd0ccb572 --commit-message=v0.0.50-4-g3341fca
✨ Success! Uploaded 104 files (3.35 sec)
✨ Deployment alias URL: https://pr-189.boson-widgets-testing.pages.dev

CI - Widgets green in 1m25s, Deploy PR preview green in 3m05s.

Behavioural check against the deployed preview. Loaded #/dev, #/redeem and #/finance in headless Chromium: all three render, no config.ts throw. #/redeem shows the app's own Missing 'configId' query param, i.e. the bundle is live rather than blank.

The same check run against the current boson-widgets-testing.pages.dev — the one Cloudflare's Git integration builds — returns an identical result, including the same 87 console errors on #/dev (Uniswap token-list and subgraph fetches). Those are pre-existing and unrelated to this PR; the subgraph API returns access-control-allow-origin: * for the preview origin, so previews are not a special case.

Remaining setup

  • testing Environment — done, verified by the run above
  • staging Environment — CF_PROJECT=boson-widgets-staging + REACT_APP_INFURA_KEY, REACT_APP_MAGIC_API_KEY, REACT_APP_WALLET_CONNECT_PROJECT_ID (values from the existing ..._STAGING repo secrets)
  • production Environment — CF_PROJECT=boson-widgets + the same three (values from ..._PRODUCTION)
  • Confirm the production branch of boson-widgets-staging and boson-widgets. They were Git-connected to deploy/staging / deploy/production, so cf_branch: main in deploy-staging.yaml / deploy-production.yaml is likely wrong and those deploys would land as Preview while the live URLs keep serving the old build. boson-widgets-testing was already on main, which is why the preview above worked.

Disconnect Cloudflare's Git integration only after a push-to-main testing deploy has succeeded, so there is never a window without a working deploy path.

The comment claimed the list mirrors the non-optional entries of the
EnvVariables array in src/config.ts, but six of its sixteen entries are not
that:

- REACT_APP_META_TX_API_KEY_MAP and _IDS_MAP are `optional: true` in
  src/config.ts; they are required here because their absence silently disables
  gasless transactions rather than throwing.
- REACT_APP_MAGIC_API_KEY and REACT_APP_INFURA_KEY appear nowhere in src/ - they
  are read by @bosonprotocol/react-kit and inlined by CRA's DefinePlugin.
- CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID are not app config at all.

Anyone syncing the list against src/config.ts on the strength of that sentence
would have deleted the six. Spell out the four categories and state the rule
that actually holds: a new non-optional EnvVariables entry belongs here, but the
converse does not follow.

Comment-only; no behaviour change.

Addresses PR #189 review comment r3956316507.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…on 0.43.0-alpha.0

feat: replace IPFS project ID and secret with JWT in Commit and Redeem components
refactor: update config to include ipfsJwt and ipfsGatewayToken
@levalleux-ludo
levalleux-ludo merged commit 53b8b58 into main Sep 8, 2026
3 checks passed
@levalleux-ludo
levalleux-ludo deleted the ci/cloudflare-pages-direct-upload branch September 8, 2026 18:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants