ci: build frontend bundle before Go compile in release.yml + Dockerfile

Phase 8 cut all panel HTML routes over to web/dist/ and embedded the
Vite bundle into the Go binary via //go:embed all:dist. web/dist/ is
.gitignored, so on a fresh CI checkout it doesn't exist — every Go
build since Phase 8 has been failing with "pattern dist: no matching
files found" or producing a binary that 404s on first asset request.

release.yml: add a setup-node@v4 + npm ci + npm run build trio before
the existing go build step in both the Linux matrix job (7 arches)
and the Windows job. npm cache is keyed on frontend/package-lock.json.

Dockerfile: add a node:22-alpine frontend stage that runs npm ci +
npm run build and emits to /src/web/dist (via vite.config.js's outDir).
The golang builder stage then COPY --from=frontend /src/web/dist into
./web/dist before the go build, so embed.FS sees the bundle.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
MHSanaei 2026-05-09 16:49:42 +02:00
parent 6bdf4bb4a0
commit d3dcd1d8bd
No known key found for this signature in database
GPG key ID: 7E4060F2FBE5AB7A
2 changed files with 52 additions and 0 deletions

View file

@ -83,6 +83,23 @@ jobs:
go-version-file: go.mod
check-latest: true
# Frontend dist must be built BEFORE go build — Go's //go:embed
# all:dist directive in web/web.go requires web/dist/ to exist
# at compile time. web/dist/ is .gitignored, so on a fresh CI
# checkout it doesn't exist until vite emits it.
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Build frontend bundle
run: |
npm ci
npm run build
working-directory: frontend
- name: Build 3X-UI
run: |
export CGO_ENABLED=1
@ -209,6 +226,23 @@ jobs:
go-version-file: go.mod
check-latest: true
# Frontend dist must be built BEFORE go build — see comment on the
# Linux job above. This step is identical except npm runs on the
# Windows runner here.
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Build frontend bundle
shell: pwsh
run: |
npm ci
npm run build
working-directory: frontend
- name: Install MSYS2
uses: msys2/setup-msys2@v2
with:

View file

@ -1,3 +1,20 @@
# ========================================================
# Stage: Frontend (Vite)
# ========================================================
# web/dist/ is .gitignored and embedded into the Go binary via
# //go:embed all:dist in web/web.go, so the SPA bundle MUST be built
# before the Go compile step. We build it in its own stage so the
# Go builder image doesn't need Node installed.
FROM node:22-alpine AS frontend
WORKDIR /src/frontend
COPY frontend/package.json frontend/package-lock.json ./
RUN npm ci
COPY frontend/ ./
RUN npm run build
# Vite outDir is set to ../web/dist (see frontend/vite.config.js), so
# the bundle lands at /src/web/dist — that's what we copy into the
# next stage.
# ========================================================
# Stage: Builder
# ========================================================
@ -12,6 +29,7 @@ RUN apk --no-cache --update add \
unzip
COPY . .
COPY --from=frontend /src/web/dist ./web/dist
ENV CGO_ENABLED=1
ENV CGO_CFLAGS="-D_LARGEFILE64_SOURCE"