Embed React frontend via go:embed and update CI to use make build & make image#14
Conversation
- Add web/embed.go with go:embed directive for web/dist - Add manager/rest/frontend.go to serve embedded SPA with index.html fallback - Register frontend routes in manager's StartRestApp - Add Node.js build stage to Dockerfile - Add build-web target to Makefile - Update .gitignore for web/dist and web/node_modules Co-authored-by: ianchen0119 <42661015+ianchen0119@users.noreply.github.com>
Co-authored-by: ianchen0119 <42661015+ianchen0119@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR implements frontend embedding by building the React application in web/ and embedding it into the Go binary using go:embed, allowing the manager to serve the frontend directly without external dependencies. The decision maker service is unaffected by these changes.
Changes:
- Added
go:embeddirective inweb/embed.goto embed the React build output into the binary - Implemented SPA-aware static file serving in
manager/rest/frontend.gowith fallback toindex.htmlfor client-side routing - Integrated multi-stage Docker build with Node.js frontend build stage and Makefile
build-webtarget
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| web/embed.go | Exports the built frontend assets via go:embed all:dist directive |
| web/dist/.gitkeep | Placeholder file ensuring the dist directory exists for go:embed compilation |
| web/.gitignore | Updated to track .gitkeep while ignoring other dist contents |
| manager/rest/frontend.go | Implements SPA serving logic with static asset handling and client-side routing fallback |
| manager/rest/frontend_test.go | Unit tests for frontend serving with and without index.html |
| manager/app/rest_app.go | Integrates frontend registration into the REST app startup sequence |
| Makefile | Adds build-web target for frontend build and wires it into the main build |
| Dockerfile | Adds Node.js build stage for frontend compilation before Go build |
| distFS, err := fs.Sub(web.DistFS, "dist") | ||
| if err != nil { | ||
| return | ||
| } |
There was a problem hiding this comment.
The error from fs.Sub is silently ignored. This could hide configuration issues or embed problems during startup. Consider logging the error to help with debugging if the frontend fails to load. The codebase uses logger.Logger for similar initialization issues (e.g., in manager/app/rest_app.go and manager/service/strategy_svc.go).
| if !hasIndex { | ||
| return | ||
| } |
There was a problem hiding this comment.
Consider logging when the frontend is not registered (either because fs.Sub failed or index.html is missing). This would help developers understand whether the frontend is being served or not, especially in development environments. For example, log an info message like "Frontend not registered: index.html not found" when hasIndex is false.
Switch build verification to use Makefile targets: - Add Node.js setup for frontend build - Use make build (deps + frontend + Go binary) - Add make image to verify Docker image builds Co-authored-by: ianchen0119 <42661015+ianchen0119@users.noreply.github.com>
The build pipeline had two gaps: the React frontend in
web/was not embedded into the Go binary, and CI was using rawgo buildinstead of the Makefile targets that include the frontend build step.Frontend embedding (manager mode only)
web/embed.go—//go:embed all:distexposes built assets asembed.FSmanager/rest/frontend.go— serves embedded SPA withindex.htmlfallback for client-side routing; no-ops gracefully if frontend wasn't built (checks forindex.htmlpresence)manager/app/rest_app.go— callsRegisterFrontend(engine)after API routes, so/api/v1/*,/health,/swagger/*take precedence over theGET /*wildcardBuild pipeline
Makefile— newbuild-webtarget (npm ci && npm run build);buildnow depends on itDockerfile— addednode:22-alpinestage to build frontend assets before the Go builder stageCI/CD
.github/workflows/ci.yml— replacedgo mod download+go build -v ./...withmake build+make image; addedactions/setup-node@v4for Node.js 22Housekeeping
web/.gitignoreupdated to trackdist/.gitkeepwhile ignoring build outputweb/dist/.gitkeepplaceholder sogo:embedcompiles without a frontend build💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.