
Wasp 应用 CI/CD 实战指南基于 GitHub Actions 的自动化测试与持续部署【免费下载链接】waspThe batteries-included full-stack framework for the AI era. Develop JS/TS web apps (React, Node.js, and Prisma) using declarative code that abstracts away complex full-stack features like auth, background jobs, RPC, email sending, end-to-end type safety, single-command deployment, and more.项目地址: https://gitcode.com/GitHub_Trending/wa/wasp在 Wasp 全栈框架React Node.js Prisma中CI/CD 是推代码即上线的关键一环持续集成CI在每次代码推送后自动验证与测试改动尽早暴露问题持续部署CD则把通过验证的代码自动发布到生产环境。本文以 Wasp 0.18 版本的官方 CI/CD 文档为核心结合本仓库内的真实示例与源码完整讲解如何在 GitHub Actions 中运行端到端测试、单元测试并以 Docker 镜像或静态文件两种方式实现自动化部署读完即可在你的 Wasp 项目里落地一套可运行的流水线。认识 CI 与 CD为什么 Wasp 应用需要流水线持续集成Continuous IntegrationCI每当代码被推送到仓库时通过自动化流程对代码变更进行校验和测试。它帮助我们尽早捕获 bug并确保应用始终处于可用状态。Wasp 应用往往同时包含客户端React SPA、服务端Node.js与数据库Prisma 管理的 PostgreSQL三部分任何一个环节回归都会影响整体功能因此 CI 的价值尤其明显。持续部署Continuous DeploymentCD将代码变更自动部署到生产环境。这种push to deploy的工作方式把开发者从手动部署中解放出来你只需要把改动推送到指定分支流水线就会完成构建、打包、推送与上线。设置 CI/CD 对 Wasp 应用来说是可选项但官方强烈建议在部署应用时一并配置。在 CI 中运行测试Wasp 官方文档将 CI 中的测试分为两类端到端测试模拟真实用户与单元测试隔离验证代码逻辑。两者互补E2E 覆盖用户真实操作路径单测则更轻更快、能在毫秒级反馈问题。端到端E2E测试模拟真实用户操作端到端测试使用真实浏览器模拟用户使用你的应用可以覆盖登录、加购、创建任务等完整场景。有了 E2E你就不必在每次改动后手动回归测试整个应用。在 CI 中运行 Wasp 应用的 E2E 测试需要三步在 CI 环境中安装 Wasp在 CI 环境中启动你的应用连同数据库针对运行中的应用执行 E2E 测试。官方示例以GitHub Actions作为 CI 平台、以Playwright作为 E2E 测试框架。你可以在仓库内直接看到这类测试的真实形态本仓库的多个示例项目都带有e2e-tests目录例如 examples/kitchen-sink/e2e-tests含 19 个测试文件、examples/waspello/e2e-tests、examples/ask-the-documents/e2e-tests 等它们都可以作为你搭建自己 E2E 测试的参照模板——把e2e-tests目录复制到你的项目里按你的应用修改即可这样本地也能直接跑通 E2E。一个典型的 Wasp E2E 测试长这样模拟登录并添加任务的完整用户流程import { expect, test } from playwright/test import { generateRandomUser, logUserIn } from ./utils const user generateRandomUser() test.describe(basic user flow test, () { test(log in and add task, async ({ page }) { await logUserIn({ page, user }) await expect(page).toHaveURL(/) await expect(page.locator(body)).toContainText(No tasks yet.) // Add a task await page.fill(input[namedescription], First task) await page.click(input:has-text(Create task)) await expect(page.locator(body)).toContainText(First task) }) })这个测试先通过generateRandomUser()生成随机用户、用logUserIn完成登录再断言页面 URL 与文案随后通过选择器定位输入框提交任务最后验证任务出现在页面上。utils中的辅助函数封装了注册、登录等重复操作是 E2E 测试保持简洁的关键。仓库里的 examples/kitchen-sink/e2e-tests/playwright.config.ts 展示了与 CI 深度配合的 Playwright 配置其中有几个值得注意的设计export default defineConfig({ testDir: ./tests, /* Fail the build on CI if you accidentally left test.only in the source code. */ forbidOnly: !!process.env.CI, /* Retry on CI only */ retries: process.env.CI ? 2 : 0, /* Opt out of parallel tests on CI. */ workers: process.env.CI ? 1 : undefined, reporter: process.env.CI ? dot : list, ... });forbidOnly: !!process.env.CI在 CI 上如果误留了test.only会直接让构建失败防止只跑一个测试的调试代码被合入retries仅在 CI 环境自动重试 2 次规避偶发的网络抖动导致的失败workers: 1CI 上关闭并行降低资源占用与相互干扰reporterCI 使用紧凑的dot报告本地使用可读性更好的list。要在 GitHub Actions 中运行这些测试需要在仓库中创建.github/workflows/e2e-tests.yml工作流文件。参考官方文档给出的步骤一个完整的工作流大致如下name: E2E Tests on: push: branches: [main] pull_request: jobs: e2e: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkoutv4 - name: Setup Node.js uses: actions/setup-nodev4 with: node-version: 20 - name: Install Wasp run: curl -sSL https://get.wasp.sh/installer.sh | sh -s -- -v 0.18.0 # 替换为你的 Wasp 版本 - name: Install dependencies run: wasp install - name: Start the database run: wasp db start - name: Start the app run: wasp start - name: Run E2E tests run: npx playwright test要点CI 环境需要 Node.js 与 Wasp CLI数据库与应用需要先于测试启动Playwright 的webServer配置项也可以代为管理启动流程见 examples/kitchen-sink/e2e-tests/playwright.config.ts 中的webServer配置最后在应用运行状态下执行 Playwright 测试。单元测试快速验证代码逻辑单元测试在隔离环境中测试代码逻辑的单个片段比 E2E 更简单、更快速但不模拟真实用户交互。两者结合使用单测负责快速回归核心逻辑E2E 负责验证整体用户体验。对于客户端代码可以使用 Wasp 内置的客户端测试支持详见 web/versioned_docs/version-0.18/project/testing.md服务端代码则可以自由选择任意测试框架。在 CI 中运行单元测试的方式与 E2E 类似在 CI 环境中安装 Wasp用wasp test client run运行客户端测试用你自己的测试框架运行服务端测试。关于客户端测试官方文档 web/versioned_docs/version-0.18/project/testing.md 给出了更完整的细节几个关键点直接决定了 CI 脚本怎么写底层技术栈Wasp 基于 Vite客户端测试通过 Vitest 运行并内置了jsdom浏览器环境模拟、testing-library/react渲染与断言辅助、msw服务端 mock等库测试文件识别规则测试文件必须放在src目录内且扩展名匹配 Vitest 的 glob 模式例如yourFile.test.ts、YourComponent.spec.jsx运行命令wasp test client进入 watch 模式开发用wasp test client run只运行一次CI 用。wasp test client之后的所有参数都会透传给 Vitest CLI注意不要同时运行wasp test和wasp start两者都会尝试编译项目到.wasp/out会产生冲突。此外Wasp 还提供了两个 React 测试辅助函数renderInContext把组件包进QueryClientProvider和Router再渲染与mockServer基于 msw 提供mockQuery/mockApi来模拟查询与 API 响应。这些能力意味着客户端单测在 CI 上无需真实后端即可运行速度很快。持续部署CD的两种主流方式Wasp 官方文档介绍了两种用 CI/CD 流水线部署应用的方式用 Docker 打包服务端和客户端将客户端部署为静态文件。方式一用 Docker 打包服务端与客户端把应用打包成 Docker 镜像是目前最主流的部署方式好处是同一份镜像可以轻松部署到不同环境staging、production 等环境差异被隔离在镜像内部。要将应用构建为 Docker 镜像需要在 CD 环境中安装 Docker用wasp build构建应用构建 Docker 镜像并推送到 Docker Registry分别为服务端应用和客户端应用各构建一份对部分托管平台还需要通知它们拉取并部署新版本。什么是 Docker RegistryDocker Registry 是存放 Docker 镜像的地方部署平台可以从这里拉取镜像。最常见的 Registry 是 Docker Hub也可以使用 GitHub Container RegistryGHCR等其他 Registry。构建产物说明在 Wasp 0.18 中wasp build会在项目根目录生成.wasp/build文件夹其中包含服务端与客户端两套构建产物在更新的 Wasp 版本中该目录改名为.wasp/out细节以你所用版本的 CLI 参考为准。服务端的Dockerfile就位于.wasp/build目录内可以直接用来构建服务端镜像。示例部署Coolify GitHub Actions GHCR官方文档以Coolify 部署示例见 self-hosted.md 的 Coolify 章节为例使用 GitHub Actions 构建 Docker 镜像使用 GitHub Container RegistryGHCR存储镜像。整个deploy.yml工作流的六个关键步骤认证 GitHub Container RegistryGHCR使用docker/login-action动作完成 GHCR 登录认证准备 Docker 镜像元数据使用docker/metadata-action动作生成后续构建与部署所需的额外信息如镜像标签构建 Wasp 应用执行wasp build在.wasp/build文件夹中得到服务端和客户端产物打包服务端镜像并推送到 GHCR使用.wasp/build目录中的Dockerfile通过docker/build-push-action动作构建并推送服务端 Docker 镜像打包客户端镜像并推送到 GHCR为客户端编写一个Dockerfile官方方案是用一个简单的 Go 静态服务器来托管客户端应用再次使用docker/build-push-action构建并推送客户端镜像通知 Coolify 部署新版本通过 Coolify 的 Webhook API 触发其拉取新镜像并完成部署。这六步构成了一个完整的Docker 化 镜像仓库 通知部署闭环同样适用于其他支持从 Registry 拉取镜像的 PaaS/自托管平台例如 self-hosted.md 中介绍的 CapRover 也是同一种模式CI 构建并上传镜像平台拉取部署。方式二客户端静态化部署Wasp 的客户端是单页应用SPA构建后会变成纯静态的 HTML、CSS 和 JS 文件可以上传到任何支持静态文件托管的平台。这意味着客户端不必使用 Docker 镜像——托管静态文件通常比托管 Docker 镜像更便宜。要将客户端应用部署为静态文件需要在 CD 环境中用wasp build构建应用构建客户端应用进入.wasp/build/web-app目录执行npm install npm run build构建产物在.wasp/build/web-app/build目录把静态文件上传到你的托管平台。Netlify / Cloudflare 的 GitHub Actions 示例官方在 PaaS 部署文档中给出了 Netlify 和 Cloudflare 两个静态部署的完整 GitHub Actions 工作流示例其骨架一致可作为客户端静态部署流水线的通用模板name: Deploy Client to Netlify on: push: branches: - main # Deploy on every push to the main branch jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkoutv4 - name: Setup Node.js uses: actions/setup-nodev4 with: node-version: 20 - name: Install Wasp run: curl -sSL https://get.wasp.sh/installer.sh | sh -s -- -v 0.18.0 # Change to your Wasp version - name: Wasp Build run: wasp build - name: Install dependencies and build the client run: | cd ./.wasp/build/web-app npm install REACT_APP_API_URL${{ secrets.WASP_SERVER_URL }} npm run build - name: Deploy to Netlify run: | cd ./.wasp/build/web-app npx netlify-cli deploy --prod --dirbuild --auth$NETLIFY_AUTH_TOKEN --site$NETLIFY_SITE_NAME env: NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} NETLIFY_SITE_NAME: netlify-site-name其中三个环境变量需要提前配置到 GitHub Repository Secrets 中NETLIFY_AUTH_TOKENNetlify 的 Personal Access Token在 Netlify 后台生成NETLIFY_SITE_NAME你的 Netlify 项目名称WASP_SERVER_URL服务端的 URL一般要等服务端部署完成后才有后端未就绪时可以跳过但依赖后端的功能会失效。重要提醒Wasp 是 SPA客户端路由由前端处理。部署到 Netlify 时必须确保其将所有 URL 重定向到index.html。Wasp 默认会在.wasp/build/web-app/下生成netlify.toml来配置这一行为如果你用 CI 而非 CLI 部署务必让 Netlify 识别该文件或手动配置重定向规则。Cloudflare Pages 会自动把所有路径重定向到index.html因此无需额外配置。生产环境的环境变量与开发环境的本质区别CI/CD 流水线中一个极易踩坑的点是环境变量。开发时Wasp 支持用.env.client和.env.server文件管理变量但部署时这两个文件会被忽略必须通过其他方式提供详见 web/versioned_docs/version-0.18/deployment/env-vars.md。客户端环境变量在构建过程中被注入到客户端 JS 代码中对任何浏览者都是公开可见的绝不能存放密钥如第三方 API Secret。生产构建时把客户端变量直接传给构建命令即可REACT_APP_API_URLurl_to_wasp_backend npm run build。原理是 WaspVite在构建时把代码中所有import.meta.env.REACT_APP_*替换为实际值。注意在托管平台上为客户端设置环境变量是无效的——构建完成后客户端只是静态文件不会再读取运行时环境。服务端环境变量DATABASE_URL、WASP_WEB_CLIENT_URL、JWT_SECRET等必须通过托管平台提供的机制设置。例如部署到 Fly.io 时用fly secrets set SOME_VARsomevalue在 GitHub Actions 里则使用secrets.XXX引用仓库 Secret。这正是上面 Netlify 示例中REACT_APP_API_URL出现在构建命令里、而NETLIFY_AUTH_TOKEN出现在仓库 Secret 里的原因。上线前的最后一道保险本地验证生产构建在把wasp build产物交给 CI/CD 之前推荐先用 Wasp 0.18 提供的wasp build start命令在本地彩排一遍生产构建。该命令会基于wasp build的输出启动一个本地服务器用与生产一致的优化后代码运行应用并要求你显式指定--server-env/--client-env或对应的--*-env-file环境变量——这会逼着你提前梳理清楚生产环境到底需要哪些变量从而在 CI/CD 阶段减少构建成功但运行失败的返工。完整说明见 local-testing.md 与 CLI 参考。小结一套完整的 Wasp CI/CD 流水线将上述内容串起来一个生产可用的 Wasp CI/CD 流水线包含以下环节CI 测试安装 Wasp → 启动数据库与应用 → 运行 Playwright E2E同时用wasp test client run快速跑客户端单测服务端单测用你熟悉的框架执行构建wasp build生成.wasp/build部署产物客户端 SPA 静态文件 服务端应用及DockerfileCD 部署二选一——Docker 路线构建服务端与客户端镜像并推送到 Registry如 GHCR再通过 Webhook 通知 Coolify/CapRover 等平台拉取部署静态路线客户端走 Netlify/Cloudflare 等静态托管注意 SPA 重定向到index.html服务端仍按 Docker 方式部署环境变量客户端变量注入到构建命令服务端变量配置到托管平台或仓库 Secret。这套流程与仓库内的真实工程完全对应examples/kitchen-sink、examples/waspello、examples/ask-the-documents等示例项目均自带e2e-tests目录与 Playwright 配置可供参考部署相关文档详见 ci-cd.md 同目录的部署文档。【免费下载链接】waspThe batteries-included full-stack framework for the AI era. Develop JS/TS web apps (React, Node.js, and Prisma) using declarative code that abstracts away complex full-stack features like auth, background jobs, RPC, email sending, end-to-end type safety, single-command deployment, and more.项目地址: https://gitcode.com/GitHub_Trending/wa/wasp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考