From 220c469ee71eb80cc306baacd88c5dc9205c47d2 Mon Sep 17 00:00:00 2001 From: ryan Date: Sun, 30 Aug 2026 15:00:30 +0800 Subject: [PATCH] fix(build): embed frontend into driver_http dist Copy the static export to backend/plugins/drivers/driver_http/dist so Wavelet's //go:embed all:dist actually ships the OpenFlare UI. Point release builds at backend/go.mod and assert index.html after copy. --- .dockerignore | 1 + .github/workflows/build-release.yml | 17 +++++++++----- Makefile | 5 ++-- ...-compose.yml => docker-compose.wavelet.yml | 0 docker/Dockerfile | 23 +++++++++++++------ docker/Dockerfile.cross | 20 ++++++++++------ scripts/update_go_license.sh | 2 ++ 7 files changed, 46 insertions(+), 22 deletions(-) rename docker-compose.yml => docker-compose.wavelet.yml (100%) diff --git a/.dockerignore b/.dockerignore index 0ccf3745..f5528fd0 100644 --- a/.dockerignore +++ b/.dockerignore @@ -33,3 +33,4 @@ frontend/*.tsbuildinfo frontend/package-lock.json internal/router/dist/ internal/router/root/dist/ +backend/plugins/drivers/driver_http/dist/ diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index e0ec8b00..dacde310 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -12,6 +12,7 @@ on: env: APP_NAME: openflare-server + GO_DIR: backend GO_MAIN: ./main.go GO_BUILD_TAGS: embed_frontend GO_LDFLAGS: -s -w @@ -20,7 +21,7 @@ env: FRONTEND_DIR: frontend FRONTEND_BUILD_COMMAND: pnpm build:embed FRONTEND_OUT_DIR: frontend/out - EMBED_DIST_DIR: backend/OpenFlare/plugins/server/router/root/dist + EMBED_DIST_DIR: backend/plugins/drivers/driver_http/dist EXTRA_FILES: | LICENSE README.md @@ -145,6 +146,7 @@ jobs: rm -rf "$EMBED_DIST_DIR" mkdir -p "$(dirname "$EMBED_DIST_DIR")" cp -R "$FRONTEND_OUT_DIR" "$EMBED_DIST_DIR" + test -f "$EMBED_DIST_DIR/index.html" - name: Upload embedded frontend uses: actions/upload-artifact@v4 @@ -192,7 +194,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version-file: go.mod + go-version-file: ${{ env.GO_DIR }}/go.mod cache: true - name: Build binary @@ -212,6 +214,9 @@ jobs: binary_name="${binary_name}.exe" fi + # Assert the embedded UI is present so a release cannot ship an API-only binary. + test -f "$EMBED_DIST_DIR/index.html" + ldflags="$GO_LDFLAGS -X Wavelet/pkg/buildinfo.Version=$VERSION -X Wavelet/pkg/buildinfo.BuildTime=$BUILD_DATE" build_args=( -trimpath @@ -223,7 +228,7 @@ jobs: build_args=(-tags "$GO_BUILD_TAGS" "${build_args[@]}") fi - ( cd backend && go build "${build_args[@]}" "$GO_MAIN" ) + (cd "$GO_DIR" && go build "${build_args[@]}" "$GO_MAIN") - name: Package artifact id: package @@ -296,7 +301,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version-file: go.mod + go-version-file: ${{ env.GO_DIR }}/go.mod # GeoIP MMDB is not embedded; Docker images COPY mmdb files, bare binaries seed via download on first start. - name: Build Agent @@ -345,7 +350,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version-file: go.mod + go-version-file: ${{ env.GO_DIR }}/go.mod - name: Build Relay env: @@ -393,7 +398,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version-file: go.mod + go-version-file: ${{ env.GO_DIR }}/go.mod - name: Build Flared env: diff --git a/Makefile b/Makefile index 39b37976..4b5b6342 100644 --- a/Makefile +++ b/Makefile @@ -29,8 +29,9 @@ build-embedded: NEXT_PUBLIC_APP_VERSION="$(VERSION)" \ NEXT_PUBLIC_APP_BUILD_DATE="$(BUILD_DATE)" \ pnpm build:embed - rm -rf backend/OpenFlare/plugins/server/router/root/dist - cp -R frontend/out backend/OpenFlare/plugins/server/router/root/dist + rm -rf backend/plugins/drivers/driver_http/dist + cp -R frontend/out backend/plugins/drivers/driver_http/dist + test -f backend/plugins/drivers/driver_http/dist/index.html cd backend && go build \ -tags embed_frontend \ -ldflags "-s -w -X '$(MODULE)/pkg/buildinfo.Version=$(VERSION)' -X '$(MODULE)/pkg/buildinfo.BuildTime=$(BUILD_DATE)'" \ diff --git a/docker-compose.yml b/docker-compose.wavelet.yml similarity index 100% rename from docker-compose.yml rename to docker-compose.wavelet.yml diff --git a/docker/Dockerfile b/docker/Dockerfile index 67ec552d..b1efa829 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -20,12 +20,13 @@ RUN corepack enable && corepack prepare pnpm@10.10.0 --activate WORKDIR /workspace/frontend -COPY frontend/package.json frontend/pnpm-lock.yaml ./ +COPY frontend/package.json frontend/pnpm-lock.yaml frontend/pnpm-workspace.yaml ./ RUN pnpm install --frozen-lockfile COPY frontend/ ./ -RUN pnpm build:embed +# Assert index.html so a silent export failure cannot ship an API-only binary. +RUN pnpm build:embed && test -f out/index.html FROM golang:${GO_VERSION}-alpine AS backend-builder @@ -36,13 +37,21 @@ RUN apk add --no-cache ca-certificates git WORKDIR /workspace -COPY backend/go.mod backend/go.sum ./ -RUN go mod download +# Cache dependency layer +COPY backend/go.mod backend/go.sum ./backend/ +RUN cd backend && go mod download -COPY backend/ ./ -COPY --from=frontend-builder /workspace/frontend/out ./internal/router/root/dist +COPY . . -RUN CGO_ENABLED=0 GOOS=linux go build \ +# Drop any stale bundle carried in the context, then overlay the fresh export so +# `//go:embed all:dist` in driver_http picks up exactly this frontend build. +RUN rm -rf backend/plugins/drivers/driver_http/dist +COPY --from=frontend-builder /workspace/frontend/out backend/plugins/drivers/driver_http/dist + +WORKDIR /workspace/backend + +RUN test -f plugins/drivers/driver_http/dist/index.html && \ + CGO_ENABLED=0 GOOS=linux go build \ -tags embed_frontend \ -trimpath \ -ldflags="-s -w -X Wavelet/pkg/buildinfo.Version=${VERSION} -X Wavelet/pkg/buildinfo.BuildTime=${BUILD_DATE}" \ diff --git a/docker/Dockerfile.cross b/docker/Dockerfile.cross index bf572ecc..76336dff 100644 --- a/docker/Dockerfile.cross +++ b/docker/Dockerfile.cross @@ -43,12 +43,13 @@ RUN corepack enable && corepack prepare pnpm@10.10.0 --activate WORKDIR /workspace/frontend # Cache dependency layer -COPY frontend/package.json frontend/pnpm-lock.yaml ./ +COPY frontend/package.json frontend/pnpm-lock.yaml frontend/pnpm-workspace.yaml ./ RUN pnpm install --frozen-lockfile COPY frontend/ ./ -RUN pnpm build:embed +# Assert index.html so a silent export failure cannot ship API-only binaries. +RUN pnpm build:embed && test -f out/index.html # ── Stage 2: Cross-compile Go backend ────────────────────────────────────── FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS builder @@ -66,13 +67,17 @@ RUN apk add --no-cache ca-certificates git WORKDIR /workspace # Cache dependency layer -COPY backend/go.mod backend/go.sum ./ -RUN go mod download +COPY backend/go.mod backend/go.sum ./backend/ +RUN cd backend && go mod download -COPY backend/ ./ +COPY . . -# Overlay the compiled frontend into the embed path -COPY --from=frontend-builder /workspace/frontend/out ./internal/router/root/dist +# Drop any stale bundle carried in the context, then overlay the fresh export so +# `//go:embed all:dist` in driver_http picks up exactly this frontend build. +RUN rm -rf backend/plugins/drivers/driver_http/dist +COPY --from=frontend-builder /workspace/frontend/out backend/plugins/drivers/driver_http/dist + +WORKDIR /workspace/backend # Build matrix: GOOS × GOARCH # CGO_ENABLED=0 — fully static, no libc dependency, required for cross-compilation. @@ -81,6 +86,7 @@ COPY --from=frontend-builder /workspace/frontend/out ./internal/router/root/dist # -X — stamp version string at link time. # TARGET_OS / TARGET_ARCH — when non-empty, skip non-matching combinations. RUN set -e; \ + test -f plugins/drivers/driver_http/dist/index.html; \ mkdir -p /out; \ FILTER_OS="${TARGET_OS}"; \ FILTER_ARCH="${TARGET_ARCH}"; \ diff --git a/scripts/update_go_license.sh b/scripts/update_go_license.sh index 85be313f..28dfbe42 100755 --- a/scripts/update_go_license.sh +++ b/scripts/update_go_license.sh @@ -58,6 +58,8 @@ find_go_files() { -o -path './frontend/out' \ -o -path './internal/router/dist' \ -o -path './internal/router/root/dist' \ + -o -path './backend/plugins/drivers/driver_http/dist' \ + -o -path './plugins/drivers/driver_http/dist' \ -o -path './vendor' \) -prune \ -o -type f -name '*.go' -print }