diff --git a/.github/workflows/build-deploy.yml b/.github/workflows/build-deploy.yml index ebd76e27..a01d5f7c 100644 --- a/.github/workflows/build-deploy.yml +++ b/.github/workflows/build-deploy.yml @@ -9,7 +9,6 @@ on: permissions: contents: read - pages: write id-token: write pull-requests: write deployments: write @@ -252,32 +251,6 @@ jobs: path: build/app/outputs/flutter-apk/app-debug.apk if-no-files-found: error - deploy-web: - needs: [build-web, test-e2e-web] - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/main' - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - steps: - - name: Download build artifact - uses: actions/download-artifact@v4 - with: - name: web-build - path: build/web - - - name: Setup Pages - uses: actions/configure-pages@v4 - - - name: Upload to GitHub Pages - uses: actions/upload-pages-artifact@v3 - with: - path: build/web - - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 - deploy-web-preview: needs: [changes, build-web, test-e2e-web] runs-on: ubuntu-latest diff --git a/AGENTS.md b/AGENTS.md index 00928270..978d70e9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -248,7 +248,7 @@ cd scripts && npm install && node validate-festivals.js The project uses GitHub Actions for: 1. **Build**: Analyze code, run tests, build web -2. **Deploy**: Deploy to GitHub Pages (main branch only) +2. **Deploy**: Deploy to Cloudflare Pages (main branch and PRs) 3. **Worker**: Deploy Cloudflare Worker when changed ## Do Not Modify diff --git a/README.md b/README.md index 9135f164..a8ff9ad5 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,15 @@ API documentation and JSON schemas are available in the [docs/api](docs/api/) di - [Beer List Schema](docs/api/beer-list-schema.json) - JSON Schema for beverage data - [Festival Registry Schema](docs/api/festival-registry-schema.json) - JSON Schema for festival configuration +## Architecture & Documentation + +Technical documentation is available in the [docs](docs/) directory: + +- [URL Routing](docs/URL_ROUTING.md) - Path-based routing implementation and configuration +- [Cloudflare Pages Setup](docs/CLOUDFLARE_PAGES_SETUP.md) - Deployment configuration +- [CI/CD](docs/CICD.md) - Complete CI/CD workflow documentation +- [Testing](docs/TESTING_FLUTTER_WEB.md) - Testing Flutter web applications + ## Deployment The app is deployed to multiple environments: @@ -150,10 +159,6 @@ The app is deployed to multiple environments: - Deployed automatically on push to `main` - Uses Cloudflare Pages project `cambeerfestival-staging`, branch `main` - Workflow: `.github/workflows/build-deploy.yml` (deploy-web-preview job) -- **Development** (GitHub Pages): [richardthe3rd.github.io/cambridge-beer-festival-app](https://richardthe3rd.github.io/cambridge-beer-festival-app/) - - Alternative development environment - - Deployed automatically on push to `main` - - Workflow: `.github/workflows/build-deploy.yml` (deploy-web job) - **PR Previews** (Cloudflare Pages): Unique URL per pull request - Each PR gets its own preview environment (e.g., `.cambeerfestival-staging.pages.dev`) - Preview URL posted as comment on the PR @@ -161,7 +166,7 @@ The app is deployed to multiple environments: ### Deployment Strategy -1. **Development changes**: Push to `main` → Staging (Cloudflare) + GitHub Pages updated +1. **Development changes**: Push to `main` → Staging (Cloudflare Pages) 2. **PR reviews**: Open PR → Unique Cloudflare Pages preview created 3. **Production releases**: Create tag (e.g., `v2025.12.0`) → Production deployment to cambeerfestival.app diff --git a/cloudflare-worker/README.md b/cloudflare-worker/README.md index e21f5c41..b0376f1c 100644 --- a/cloudflare-worker/README.md +++ b/cloudflare-worker/README.md @@ -1,6 +1,6 @@ # Cloudflare Worker - CORS Proxy -This Cloudflare Worker proxies requests to `data.cambridgebeerfestival.com` and adds CORS headers, allowing the Flutter web app hosted on GitHub Pages to access the API data. +This Cloudflare Worker proxies requests to `data.cambridgebeerfestival.com` and adds CORS headers, allowing the Flutter web app to access the API data. ## How It Works diff --git a/docs/CICD.md b/docs/CICD.md index 4da8f8c1..1f14dade 100644 --- a/docs/CICD.md +++ b/docs/CICD.md @@ -34,7 +34,7 @@ on: workflow_dispatch: ``` -- **Push to `main`**: Full build, test, deploy to GitHub Pages + Cloudflare Pages staging +- **Push to `main`**: Full build, test, deploy to Cloudflare Pages staging - **Pull Requests**: Build, test, deploy preview to Cloudflare Pages - **Push to `copilot/**`**: CI builds for Copilot branches - **Manual**: Via workflow_dispatch in GitHub Actions UI @@ -108,22 +108,7 @@ Builds Android APK and App Bundle. - Gradle dependency caching reduces build time by 2-5 minutes on cache hits - Gradle build cache enabled (see gradle.properties) -#### E. `deploy-web` - -Deploys to **GitHub Pages** (development environment). - -**Runs when**: Push to `main` branch - -**Environment**: `github-pages` -**URL**: `https://richardthe3rd.github.io/cambridge-beer-festival-app/` - -**Steps:** -1. Download `web-build` artifact -2. Setup GitHub Pages -3. Upload to Pages -4. Deploy - -#### F. `deploy-web-preview` +#### E. `deploy-web-preview` Deploys to **Cloudflare Pages** (staging and PR previews). @@ -382,8 +367,7 @@ See [GITHUB_SECRETS.md](GITHUB_SECRETS.md) for setup instructions. 4. **Merge to `main`** - Triggers deployment to: - - GitHub Pages (development) - - Cloudflare Pages staging (`main.cambeerfestival.pages.dev`) + - Cloudflare Pages staging (`staging.cambeerfestival.app`) - If worker/festivals.json changed: - Deploys updated worker diff --git a/docs/CLOUDFLARE_PAGES_SETUP.md b/docs/CLOUDFLARE_PAGES_SETUP.md index 1cc970d2..fdf3613a 100644 --- a/docs/CLOUDFLARE_PAGES_SETUP.md +++ b/docs/CLOUDFLARE_PAGES_SETUP.md @@ -30,7 +30,6 @@ The app uses **two separate Cloudflare Pages projects** for clean separation bet | Version tag | `cambeerfestival` | `release` | `cambeerfestival.app` | Production | | Push to `main` | `cambeerfestival-staging` | `main` | `staging.cambeerfestival.app` | Staging | | Pull Request | `cambeerfestival-staging` | `` | `.cambeerfestival-staging.pages.dev` | PR previews | -| Push to `main` | GitHub Pages | N/A | `richardthe3rd.github.io/...` | Development | ## Prerequisites @@ -319,18 +318,6 @@ This workflow handles all non-production deployments and includes multiple jobs: - Share preview URLs with team members for review - No conflicts with staging environment -#### C. Development Deployment (GitHub Pages) - -**Trigger**: Push to `main` branch - -**Job**: `deploy-web` - -**Automatic process**: - -1. Push or merge to `main` -2. Deploys to `richardthe3rd.github.io/cambridge-beer-festival-app/` -3. Serves as alternative development/testing environment - ## Verification After deployment, verify: @@ -399,9 +386,7 @@ If you see CORS errors in browser console: 1. Make changes to code 2. Commit and push to `main` branch -3. GitHub Actions automatically deploys to both: - - GitHub Pages (staging) - - Cloudflare Pages (production) +3. GitHub Actions automatically deploys to Cloudflare Pages staging ### Updating Festivals Data diff --git a/docs/PLAY_STORE_METADATA.md b/docs/PLAY_STORE_METADATA.md index 402ef93c..af37b962 100644 --- a/docs/PLAY_STORE_METADATA.md +++ b/docs/PLAY_STORE_METADATA.md @@ -140,7 +140,7 @@ adb pull /sdcard/screenshot.png You **must** provide a privacy policy URL. Host it on: - Your website -- GitHub Pages +- Cloudflare Pages - Google Docs (make it public) **Privacy Policy Template** (copy and customize): @@ -209,8 +209,8 @@ For questions about this privacy policy, contact: **Where to host:** - Create `docs/privacy-policy.md` in your repo -- Enable GitHub Pages on the repo -- Use URL: `https://yourusername.github.io/cambridge-beer-festival-app/privacy-policy.html` +- Deploy to Cloudflare Pages +- Use URL: `https://cambeerfestival.app/privacy-policy.html` or `https://staging.cambeerfestival.app/privacy-policy.html` ## 🎯 Content Rating diff --git a/docs/URL_ROUTING.md b/docs/URL_ROUTING.md new file mode 100644 index 00000000..cebd86e4 --- /dev/null +++ b/docs/URL_ROUTING.md @@ -0,0 +1,69 @@ +# URL Routing Strategy + +This document explains how URL routing works in the Cambridge Beer Festival app. + +## Overview + +The app uses **path-based routing** (e.g., `/favorites`, `/drink/123`) instead of **hash-based routing** (e.g., `/#/favorites`, `/#/drink/123`). + +## Implementation + +### Flutter Side + +The app uses [go_router](https://pub.dev/packages/go_router) version 14.6.2 (or later) for routing. Starting from go_router 7.0.0, path-based URL strategy is the default on web platforms, so no additional configuration is needed in the Flutter code. + +### Web Server Configuration + +For path-based routing to work correctly on deployed web apps, the web server must be configured to serve `index.html` for all routes (SPA fallback). This is because when a user navigates directly to a route like `/favorites`, the web server needs to serve the main `index.html` file, which then loads the Flutter app that handles the routing internally. + +#### Cloudflare Pages (Production & Staging) + +**File**: `web/_redirects` + +``` +/* /index.html 200 +``` + +This tells Cloudflare Pages to serve `index.html` for all routes with a 200 status code. Cloudflare Pages natively supports the `_redirects` file format. + +#### Local Development with http-server + +For local testing, the project uses `http-server` with the `--proxy` flag to handle SPA routing: + +```bash +npx http-server build/web -p 8080 -c-1 -a 127.0.0.1 --proxy http://127.0.0.1:8080? +``` + +The `--proxy` flag tells http-server to fall back to serving `index.html` for routes that don't exist as physical files, enabling proper SPA behavior during local development and E2E testing. + +## Routes + +The app supports the following routes: + +- `/` - Home screen (drinks list) +- `/favorites` - Favorites screen +- `/about` - About screen +- `/festival-info` - Festival information screen +- `/drink/:id` - Drink detail screen (parameterized) +- `/brewery/:id` - Brewery screen (parameterized) +- `/style/:name` - Style screen (parameterized, URL-encoded) + +## Testing + +E2E tests in `test-e2e/routing.spec.ts` verify: +- Path-based URLs work correctly +- Deep linking to specific routes works +- Browser back/forward buttons work +- Page refresh preserves the current route + +## Benefits of Path-Based Routing + +1. **Better SEO**: Search engines can properly index individual pages +2. **Clean URLs**: URLs look cleaner and more professional +3. **Shareable Links**: Users can share direct links to specific content +4. **Standard Web Behavior**: Works like traditional websites +5. **Better Analytics**: Analytics tools can track page views more accurately + +## Migration Notes + +If you were previously using the app with hash-based routing, existing bookmarks with hash URLs (e.g., `/#/favorites`) will continue to work because go_router handles the migration automatically. \ No newline at end of file diff --git a/web/_redirects b/web/_redirects new file mode 100644 index 00000000..f8243379 --- /dev/null +++ b/web/_redirects @@ -0,0 +1 @@ +/* /index.html 200 \ No newline at end of file