diff --git a/.github/workflows/deploy-webapp.yml b/.github/workflows/deploy-webapp.yml new file mode 100644 index 0000000..6aae361 --- /dev/null +++ b/.github/workflows/deploy-webapp.yml @@ -0,0 +1,92 @@ +name: Deploy Webapp to Cloudflare Pages + +on: + push: + branches: [ main ] + pull_request: + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + contents: read + deployments: write + pull-requests: write + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Setup OCaml + uses: ocaml/setup-ocaml@v3 + with: + ocaml-compiler: 5.1.0 + + - name: Install OCaml dependencies + run: | + opam install . --deps-only --with-test + + - name: Build webapp + run: | + eval $(opam env) + make build-webapp + + # Only run tests when deploying to production (main branch) + - name: Install Playwright browsers + if: github.ref == 'refs/heads/main' + working-directory: webapp + run: npx playwright install --with-deps + + - name: Run webapp tests + if: github.ref == 'refs/heads/main' + run: | + eval $(opam env) + make test-webapp + + - name: Check for modified files before deployment + run: | + echo "Checking for modified files..." + git status --porcelain || echo "No uncommitted changes" + + - name: Deploy to Cloudflare Pages + id: deploy + uses: cloudflare/wrangler-action@v3 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + command: pages deploy webapp/app/dist --project-name=pyfinalo-webapp --branch=${{ github.head_ref || github.ref_name }} + + - name: Extract deployment URL + id: deployment-url + run: | + # The deployment URL is in the wrangler output + # For PRs, it's the preview URL like https://HASH.pyfinalo-webapp.pages.dev + echo "Deployment successful! Check the wrangler output above for URLs." + + - name: Comment PR with deployment URL + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const issue_number = context.issue.number; + const branch_name = '${{ github.head_ref }}'; + const preview_url = `https://${branch_name}.pyfinalo-webapp.pages.dev`; + + const deployment_info = `## 🚀 Webapp deployed! + + **Preview URL**: ${preview_url} + + The deployment should be available shortly. If the link doesn't work immediately, please wait a moment for Cloudflare to propagate the changes.`; + + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue_number, + body: deployment_info + }); diff --git a/webapp/DEPLOYMENT.md b/webapp/DEPLOYMENT.md new file mode 100644 index 0000000..392be56 --- /dev/null +++ b/webapp/DEPLOYMENT.md @@ -0,0 +1,43 @@ +# Webapp Deployment + +The pyfinalo webapp is automatically deployed to Cloudflare Pages. + +## Automatic Deployments + +- **Production**: Pushes to `main` branch deploy to https://pyfinalo-webapp.pages.dev +- **Preview**: Pull requests create preview deployments at unique URLs + +## Setup Requirements + +The following GitHub secrets must be configured: + +1. `CLOUDFLARE_ACCOUNT_ID`: Your Cloudflare account ID +2. `CLOUDFLARE_API_TOKEN`: API token with Cloudflare Pages edit permissions + +### Creating the API Token + +Consult https://developers.cloudflare.com/pages/how-to/use-direct-upload-with-continuous-integration/ + +## Deployment Process + +1. Code is built using `make build-webapp` +2. For production deployments, tests run with `make test-webapp` +3. Built assets from `webapp/app/dist` are deployed to Cloudflare Pages + +## Manual Deployment + +From the webapp directory: + +```bash +# Deploy to preview +bun run --cwd app deploy + +# Deploy to production +bun run --cwd app deploy-live +``` + +## Project Configuration + +- Project name: `pyfinalo-webapp` +- Build output: `webapp/app/dist` +- Framework: React + Vite