Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed
- Hide version upgrade toast for askgithub deployment (`EXPERIMENT_ASK_GH_ENABLED`). [#931](https://github.com/sourcebot-dev/sourcebot/pull/931)
- Optimized web package and Docker builds: restructured Docker layers to separate dependency installation from source copying for better cache reuse, consolidated yarn installs, added BuildKit cache mount for Next.js compilation cache, enabled `experimental.optimizePackageImports` for barrel-export packages, and made Sentry build-time features conditional. [#944](https://github.com/sourcebot-dev/sourcebot/pull/944)

### Fixed
- Fixed text inside angle brackets (e.g., `<id>`) being hidden in chat prompt display due to HTML parsing. [#929](https://github.com/sourcebot-dev/sourcebot/pull/929) [#932](https://github.com/sourcebot-dev/sourcebot/pull/932)
Expand Down
70 changes: 56 additions & 14 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,33 @@ RUN CGO_ENABLED=0 GOOS=linux go build -o /cmd/ ./cmd/...
FROM node-alpine AS shared-libs-builder
WORKDIR /app

# Step 1: Copy only package manifests for dependency installation.
# This layer is cached as long as no package.json or lock file changes.
COPY package.json yarn.lock* .yarnrc.yml ./
COPY .yarn ./.yarn
COPY ./packages/db/package.json ./packages/db/package.json
COPY ./packages/db/prisma ./packages/db/prisma
COPY ./packages/schemas/package.json ./packages/schemas/package.json
COPY ./packages/shared/package.json ./packages/shared/package.json
COPY ./packages/queryLanguage/package.json ./packages/queryLanguage/package.json
# All workspace package.json files are needed for Yarn resolution
COPY ./packages/web/package.json ./packages/web/package.json
COPY ./packages/backend/package.json ./packages/backend/package.json
COPY ./packages/mcp/package.json ./packages/mcp/package.json

RUN yarn install --mode=skip-build

# Step 2: Copy source files and build explicitly in topological order.
COPY ./packages/db ./packages/db
COPY ./schemas ./schemas
COPY ./packages/schemas ./packages/schemas
COPY ./packages/shared ./packages/shared
COPY ./packages/queryLanguage ./packages/queryLanguage
COPY ./packages/shared ./packages/shared

RUN yarn workspace @sourcebot/db install
RUN yarn workspace @sourcebot/schemas install
RUN yarn workspace @sourcebot/shared install
RUN yarn workspace @sourcebot/query-language install
RUN yarn workspace @sourcebot/db build && \
yarn workspace @sourcebot/schemas build && \
yarn workspace @sourcebot/query-language build && \
yarn workspace @sourcebot/shared build
# ------------------------------------

# ------ Build Web ------
Expand Down Expand Up @@ -79,20 +95,33 @@ ENV SENTRY_SMUAT=$SENTRY_SMUAT
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Step 1: Install dependencies (cached unless package.json/lock changes).
COPY package.json yarn.lock* .yarnrc.yml ./
COPY .yarn ./.yarn
COPY ./packages/web ./packages/web
COPY --from=shared-libs-builder /app/node_modules ./node_modules
COPY ./packages/web/package.json ./packages/web/package.json
COPY ./packages/db/package.json ./packages/db/package.json
COPY ./packages/db/prisma ./packages/db/prisma
COPY ./packages/schemas/package.json ./packages/schemas/package.json
COPY ./packages/shared/package.json ./packages/shared/package.json
COPY ./packages/queryLanguage/package.json ./packages/queryLanguage/package.json
COPY ./packages/backend/package.json ./packages/backend/package.json
COPY ./packages/mcp/package.json ./packages/mcp/package.json

RUN yarn install --mode=skip-build && \
yarn workspace @sourcebot/db prisma:generate

# Step 2: Copy pre-built shared libraries.
COPY --from=shared-libs-builder /app/packages/db ./packages/db
COPY --from=shared-libs-builder /app/packages/schemas ./packages/schemas
COPY --from=shared-libs-builder /app/packages/shared ./packages/shared
COPY --from=shared-libs-builder /app/packages/queryLanguage ./packages/queryLanguage

# Fixes arm64 timeouts
RUN yarn workspace @sourcebot/web install
# Step 3: Copy web source and build.
COPY ./packages/web ./packages/web

ENV NEXT_TELEMETRY_DISABLED=1
RUN yarn workspace @sourcebot/web build
RUN --mount=type=cache,target=/app/packages/web/.next/cache \
yarn workspace @sourcebot/web build
ENV SKIP_ENV_VALIDATION=0
# ------------------------------

Expand All @@ -117,16 +146,29 @@ ENV SENTRY_RELEASE=$SENTRY_RELEASE

WORKDIR /app

# Step 1: Install dependencies (cached unless package.json/lock changes).
COPY package.json yarn.lock* .yarnrc.yml ./
COPY .yarn ./.yarn
COPY ./schemas ./schemas
COPY ./packages/backend ./packages/backend
COPY --from=shared-libs-builder /app/node_modules ./node_modules
COPY ./packages/backend/package.json ./packages/backend/package.json
COPY ./packages/db/package.json ./packages/db/package.json
COPY ./packages/db/prisma ./packages/db/prisma
COPY ./packages/schemas/package.json ./packages/schemas/package.json
COPY ./packages/shared/package.json ./packages/shared/package.json
COPY ./packages/queryLanguage/package.json ./packages/queryLanguage/package.json
COPY ./packages/web/package.json ./packages/web/package.json
COPY ./packages/mcp/package.json ./packages/mcp/package.json

RUN yarn install --mode=skip-build && \
yarn workspace @sourcebot/db prisma:generate

# Step 2: Copy pre-built shared libraries and backend source.
COPY --from=shared-libs-builder /app/packages/db ./packages/db
COPY --from=shared-libs-builder /app/packages/schemas ./packages/schemas
COPY --from=shared-libs-builder /app/packages/shared ./packages/shared
COPY --from=shared-libs-builder /app/packages/queryLanguage ./packages/queryLanguage
RUN yarn workspace @sourcebot/backend install
COPY ./schemas ./schemas
COPY ./packages/backend ./packages/backend

RUN yarn workspace @sourcebot/backend build

# Upload source maps to Sentry if we have the necessary build-time args.
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"packages/*"
],
"scripts": {
"build": "cross-env SKIP_ENV_VALIDATION=1 yarn workspaces foreach --all --topological run build",
"build": "cross-env SKIP_ENV_VALIDATION=1 yarn workspaces foreach --all --topological --parallel run build",
"test": "yarn workspaces foreach --all --topological run test",
"dev": "concurrently --kill-others --names \"zoekt,worker,web,mcp,schemas\" 'yarn dev:zoekt' 'yarn dev:backend' 'yarn dev:web' 'yarn watch:mcp' 'yarn watch:schemas'",
"with-env": "cross-env PATH=\"$PWD/bin:$PATH\" dotenv -e .env.development -c --",
Expand All @@ -18,7 +18,8 @@
"dev:prisma:studio": "yarn with-env yarn workspace @sourcebot/db prisma:studio",
"dev:prisma:migrate:reset": "yarn with-env yarn workspace @sourcebot/db prisma:migrate:reset",
"dev:prisma:db:push": "yarn with-env yarn workspace @sourcebot/db prisma:db:push",
"build:deps": "yarn workspaces foreach --recursive --topological --from '{@sourcebot/schemas,@sourcebot/db,@sourcebot/shared,@sourcebot/query-language}' run build",
"build:web": "cross-env SKIP_ENV_VALIDATION=1 yarn workspaces foreach --recursive --topological --parallel --from @sourcebot/web run build",
"build:deps": "yarn workspaces foreach --recursive --topological --parallel --from '{@sourcebot/schemas,@sourcebot/db,@sourcebot/shared,@sourcebot/query-language}' run build",
"tool:decrypt-jwe": "yarn with-env yarn workspace @sourcebot/web tool:decrypt-jwe"
},
"devDependencies": {
Expand Down
35 changes: 28 additions & 7 deletions packages/web/next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { withSentryConfig } from "@sentry/nextjs";

const hasSentryConfig = !!(process.env.SENTRY_ORG && process.env.SENTRY_SMUAT);

/** @type {import('next').NextConfig} */
const nextConfig = {
Expand Down Expand Up @@ -40,16 +41,36 @@ const nextConfig = {

turbopack: {},

// @see: https://github.com/vercel/next.js/issues/58019#issuecomment-1910531929
...(process.env.NODE_ENV === 'development' ? {
experimental: {
experimental: {
optimizePackageImports: [
"lucide-react",
"@radix-ui/react-icons",
"react-icons",
"recharts",
"date-fns",
"@ai-sdk/react",
"@ai-sdk/openai",
"@ai-sdk/anthropic",
"@ai-sdk/google",
"@ai-sdk/amazon-bedrock",
"@ai-sdk/azure",
"@ai-sdk/deepseek",
"@ai-sdk/google-vertex",
"@ai-sdk/mistral",
"@ai-sdk/xai",
"@ai-sdk/openai-compatible",
"@codemirror/language-data",
"posthog-js",
],
// @see: https://github.com/vercel/next.js/issues/58019#issuecomment-1910531929
...(process.env.NODE_ENV === 'development' ? {
serverActions: {
allowedOrigins: [
'localhost:3000'
]
}
}
} : {}),
} : {}),
},
};

export default withSentryConfig(nextConfig, {
Expand All @@ -68,11 +89,11 @@ export default withSentryConfig(nextConfig, {
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/

// Upload a larger set of source maps for prettier stack traces (increases build time)
widenClientFileUpload: true,
widenClientFileUpload: hasSentryConfig,

// Automatically annotate React components to show their full name in breadcrumbs and session replay
reactComponentAnnotation: {
enabled: true,
enabled: hasSentryConfig,
},

// Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.
Expand Down