diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..2a563de --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,58 @@ +name: CI + +on: + pull_request: + push: + branches: + - main + +jobs: + web: + name: Web checks + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run web tests + run: pnpm test:web + + - name: Build web app + run: pnpm build:web + + api: + name: API tests + runs-on: ubuntu-latest + defaults: + run: + working-directory: apps/api + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + cache: pip + cache-dependency-path: apps/api/requirements.txt + + - name: Install API dependencies + run: pip install -r requirements.txt + + - name: Run API tests + run: pytest diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml new file mode 100644 index 0000000..eb8f85f --- /dev/null +++ b/.github/workflows/deploy-pages.yml @@ -0,0 +1,61 @@ +name: Deploy web to GitHub Pages + +on: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build web app for GitHub Pages + run: pnpm build:web + env: + VITE_API_BASE_URL: ${{ vars.VITE_API_BASE_URL }} + + - name: Configure GitHub Pages + uses: actions/configure-pages@v5 + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: apps/web/dist + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/README.md b/README.md index 0924314..503b50b 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,36 @@ pnpm install pnpm dev ``` +## CI/CD and deployment + +This repo now includes GitHub Actions workflows: + +- `.github/workflows/ci.yml`: runs web tests/build plus API tests on pull requests and pushes to `main`. +- `.github/workflows/deploy-pages.yml`: builds `apps/web` and deploys it to GitHub Pages on pushes to `main`. + +### GitHub Pages limitations + +GitHub Pages hosts static assets only, so this setup deploys the React frontend. The backend API (`apps/api`) still needs to run elsewhere (e.g., Hetzner, Fly.io, Render, Railway, etc.). + +For production, set the frontend API endpoint with: + +- `VITE_API_BASE_URL` in your GitHub Action/repository variables or secrets (or hardcode if preferred). + +### Enable Pages in GitHub + +1. Push to `main` so the workflow runs. +2. In GitHub repo settings, open **Pages**. +3. Set **Source** to **GitHub Actions**. +4. After deployment, your site URL will be shown in the workflow output. + +### Using a custom domain (optional) + +If you want your own domain/subdomain: + +1. Create DNS record to GitHub Pages target. +2. Add a `CNAME` file in `apps/web/public` (or configure custom domain in Pages settings). +3. Enable HTTPS in Pages settings. + ## Tests API tests: diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index 875ac68..74a3278 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -1,7 +1,11 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; +const repositoryPath = process.env.GITHUB_REPOSITORY?.split("/")[1]; +const base = process.env.GITHUB_ACTIONS && repositoryPath ? `/${repositoryPath}/` : "/"; + export default defineConfig({ + base, plugins: [react()], server: { port: 5173,