Skip to content

Commit cdd55de

Browse files
committed
feat(deployment): optimize Netlify deployment and edge function compatibility
1 parent c741b6a commit cdd55de

File tree

80 files changed

+4012
-2690
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+4012
-2690
lines changed

.github/actions/setup-node-deps/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ runs:
2626
- name: Setup pnpm
2727
uses: pnpm/action-setup@v4
2828
with:
29-
version: 10.24.0
29+
version: 10.25.0
3030

3131
- name: Setup Node.js
3232
id: setup-node

.github/actions/setup/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ inputs:
1212
pnpm-version:
1313
description: 'pnpm version to use'
1414
required: false
15-
default: '10.24.0'
15+
default: '10.25.0'
1616
install-args:
1717
description: 'Additional arguments for pnpm install'
1818
required: false

.github/workflows/auto-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050
- name: Setup pnpm
5151
uses: pnpm/action-setup@v4
5252
with:
53-
version: 10.24.0
53+
version: 10.25.0
5454

5555
- name: Setup Node.js
5656
uses: actions/setup-node@v6

.github/workflows/reusable/setup-node-pnpm.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ on:
1212
description: 'pnpm version to use'
1313
required: false
1414
type: string
15-
default: '10.24.0'
15+
default: '10.25.0'
1616
fetch-depth:
1717
description: 'Git fetch depth'
1818
required: false

.github/workflows/security.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ on:
2020
workflow_dispatch:
2121

2222
env:
23-
PNPM_VERSION: 10.24.0
23+
PNPM_VERSION: 10.25.0
2424

2525
concurrency:
2626
group: ${{ github.workflow }}-${{ github.ref }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,4 @@ SEARCH_CACHING_ANALYSIS.md
145145
SEARCH_OPTIMIZATION_ANALYSIS.md
146146
SEARCH_SYSTEM_ARCHITECTURE.md
147147
SEARCH_UNIFICATION_TODO.md
148+
VERIFY_INNGEST_DEPLOYMENT.md

.pnpmfile.cjs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* pnpmfile.cjs - Package Manifest Modification Hook
3+
*
4+
* This file modifies package manifests during installation to optimize dependencies.
5+
* Currently used to limit Sharp platform binaries to Linux x64 only (for Netlify Functions).
6+
*
7+
* @see https://pnpm.io/pnpmfile
8+
*/
9+
10+
function readPackage(pkg, context) {
11+
// Only modify Sharp's optionalDependencies to install Linux x64 binaries only
12+
// This prevents installing ~150MB of unnecessary platform binaries (macOS, ARM, etc.)
13+
// Netlify Functions run on Linux x64, so we only need those binaries
14+
if (pkg.name === 'sharp') {
15+
// Store original count for logging
16+
const originalCount = Object.keys(pkg.optionalDependencies || {}).length;
17+
18+
// Keep only Linux x64 binaries (needed for Netlify Functions)
19+
// Remove all other platform binaries (macOS, ARM, Windows, etc.)
20+
const linuxX64Only = {
21+
// Core Sharp Linux x64 binary
22+
'@img/sharp-linux-x64': pkg.optionalDependencies?.['@img/sharp-linux-x64'],
23+
// libvips Linux x64 binary (required for Sharp to work)
24+
'@img/sharp-libvips-linux-x64': pkg.optionalDependencies?.['@img/sharp-libvips-linux-x64'],
25+
};
26+
27+
// Remove undefined entries (in case version doesn't match)
28+
Object.keys(linuxX64Only).forEach(key => {
29+
if (!linuxX64Only[key]) {
30+
delete linuxX64Only[key];
31+
}
32+
});
33+
34+
// Replace optionalDependencies with Linux x64 only
35+
if (Object.keys(linuxX64Only).length > 0) {
36+
pkg.optionalDependencies = linuxX64Only;
37+
38+
// Log what we're doing (only in development)
39+
if (process.env.NODE_ENV !== 'production') {
40+
console.log(
41+
`[pnpmfile] Modified sharp@${pkg.version}: ` +
42+
`Keeping only Linux x64 binaries (${Object.keys(linuxX64Only).length} packages) ` +
43+
`instead of ${originalCount} platform binaries`
44+
);
45+
}
46+
}
47+
}
48+
49+
return pkg;
50+
}
51+
52+
module.exports = {
53+
hooks: {
54+
readPackage,
55+
},
56+
};

.pnpmrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,11 @@ lifecycle-scripts-allow-list[]=sharp
44
lifecycle-scripts-allow-list[]=esbuild
55
lifecycle-scripts-allow-list[]=msw
66
lifecycle-scripts-allow-list[]=lefthook
7+
8+
# Hoist Next.js and React to root for type compatibility
9+
# This ensures all packages use the same Next.js installation
10+
# Fixes TypeScript type compatibility issues in monorepo
11+
# See PNPM_HOISTING_EXPLANATION.md for details
12+
public-hoist-pattern[]=next
13+
public-hoist-pattern[]=react
14+
public-hoist-pattern[]=react-dom

apps/edge/supabase/functions/public-api/routes/content-generate/generators/skills.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,8 @@ function escapeYamlString(str: string): string {
232232
* @returns A Uint8Array containing the bytes of the ZIP archive with one entry: `{slug}/SKILL.md`
233233
*/
234234
function generateZipBuffer(slug: string, skillMdContent: string): Uint8Array {
235-
// TODO: Replace with proper Deno-compatible ZIP library
236-
// For now, create a minimal ZIP structure manually
237-
// This is a simplified implementation - a proper ZIP library would be better
235+
// Create a minimal ZIP structure manually
236+
// This is a simplified implementation
238237

239238
// Create ZIP file structure manually
240239
// ZIP format: [Local File Header][File Data][Central Directory][End of Central Directory]

apps/web/netlify.toml

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# Netlify Configuration
2+
# Documentation: https://docs.netlify.com/configure-builds/file-based-configuration/
3+
# Next.js Plugin: https://docs.netlify.com/frameworks/next-js/overview/
4+
5+
[build]
6+
# Monorepo configuration
7+
# Base directory: empty (root) - where dependencies are installed and build runs
8+
# This is the default, but explicitly set to override incorrect UI setting
9+
# UI incorrectly had "dir": "apps/web/.next" which prevented builds from starting
10+
base = ""
11+
12+
# Package directory: where site files are located (including this netlify.toml)
13+
# For monorepos, this is the subdirectory containing your site
14+
package = "apps/web"
15+
16+
# Build command - runs in the base directory (root)
17+
# Uses Turbo to build only the web app from the monorepo
18+
command = "turbo run build --filter web"
19+
20+
# Publish directory - Next.js output directory
21+
# Path is relative to base directory (root)
22+
# Next.js plugin handles this automatically, but we specify for clarity
23+
publish = "apps/web/.next"
24+
25+
# Build environment variables
26+
[build.environment]
27+
# Node.js version (matches package.json engines requirement)
28+
NODE_VERSION = "22"
29+
# pnpm version (matches packageManager in package.json)
30+
# Corepack will use this version from package.json automatically
31+
PNPM_VERSION = "10.25.0"
32+
# Enable pnpm (Netlify will use pnpm when it detects pnpm-lock.yaml)
33+
NPM_USE_PNPM = "true"
34+
# pnpm flags for monorepo compatibility
35+
# shamefully-hoist helps with dependency resolution in monorepos
36+
PNPM_FLAGS = "--shamefully-hoist"
37+
# Next.js static generation concurrency limit
38+
# Reduced from default (12) to 4 to prevent database connection pool exhaustion
39+
# This allows more pages to be generated in the same worker, improving cache hit rates
40+
# after pre-fetching in generateStaticParams
41+
NEXT_STATIC_GENERATION_MAX_CONCURRENCY = "4"
42+
# CRITICAL: Disable Turbo remote cache to prevent build hangs
43+
# When TURBO_TOKEN/TURBO_TEAM aren't set, Turbo tries to connect to remote cache
44+
# and hangs indefinitely. This forces local-only cache.
45+
TURBO_REMOTE_CACHE_ENABLED = "false"
46+
# Disable Netlify Edge Functions for Next.js Middleware
47+
# Our middleware/proxy.ts uses Node.js-only dependencies (pino via logger) that don't work in edge runtimes.
48+
# Setting this to true forces middleware to use regular serverless functions instead of edge functions.
49+
# See: https://docs.netlify.com/build/frameworks/framework-setup-guides/nextjs/legacy-runtime/middleware
50+
NEXT_DISABLE_NETLIFY_EDGE = "true"
51+
52+
# Next.js plugin configuration
53+
# Explicitly add the plugin (required for Next.js on Netlify)
54+
# The plugin handles Next.js-specific optimizations, routing, and ISR
55+
[[plugins]]
56+
package = "@netlify/plugin-nextjs"
57+
58+
# Clean ISR blobs plugin - removes blobs after build to prevent 400 upload errors
59+
# The Next.js plugin generates large ISR cache blobs that fail to upload
60+
# Path must be absolute relative to base directory (root) for monorepos
61+
[[plugins]]
62+
package = "/netlify/plugins/clean-blobs"
63+
64+
# Inngest plugin - registers serverless Inngest functions
65+
# Configured to use /api/inngest endpoint (default)
66+
[[plugins]]
67+
package = "netlify-plugin-inngest"
68+
[plugins.inputs]
69+
host = "https://claudepro.directory"
70+
path = "/api/inngest"
71+
72+
# Build cache directories for faster rebuilds
73+
# These directories persist between builds to speed up subsequent deployments
74+
[[cache.directories]]
75+
# Next.js build cache (compiled pages, chunks, etc.)
76+
# This is critical for faster rebuilds
77+
path = "apps/web/.next/cache"
78+
[[cache.directories]]
79+
# Turbo build cache (monorepo build artifacts)
80+
# Speeds up monorepo builds by caching task outputs
81+
path = ".turbo"
82+
[[cache.directories]]
83+
# pnpm store cache (dependency cache)
84+
# Speeds up dependency installation
85+
path = ".pnpm-store"
86+
87+
# Note: We intentionally do NOT cache node_modules
88+
# Caching node_modules can cause issues with dependency resolution
89+
# and is generally not recommended by Netlify
90+
91+
# Redirects and rewrites (handled by Next.js plugin automatically)
92+
# Next.js plugin automatically configures:
93+
# - Static file serving
94+
# - API routes
95+
# - Dynamic routes
96+
# - ISR (Incremental Static Regeneration)
97+
# - Server-side rendering
98+
# - Image optimization
99+
100+
# Edge Functions (if using Netlify Edge Functions)
101+
# Uncomment if you have edge functions to deploy
102+
# [build.edge_functions]
103+
# directory = "apps/edge/functions"
104+
105+
# Functions configuration
106+
# Exclude large dependencies to reduce function size (250MB limit)
107+
[functions]
108+
# Exclude unnecessary Sharp platform binaries
109+
# Netlify Functions run on Linux x64 only, so we only need sharp-libvips-linux-x64
110+
# Excluding all other platform binaries saves ~130MB
111+
# Note: pnpm uses @img+sharp-* format in .pnpm directory
112+
included_files = [
113+
# Exclude .env files (should use Netlify UI for env vars, not bundled files)
114+
# These files are automatically included by Next.js plugin but shouldn't be in function bundle
115+
# Environment variables should be set in Netlify UI with proper scoping (Build vs Functions)
116+
# Use absolute paths relative to base directory (root) for monorepos
117+
"!apps/web/.env",
118+
"!apps/web/.env.local",
119+
"!apps/web/.env.production",
120+
"!apps/web/.env.production.local",
121+
"!.env",
122+
"!.env.local",
123+
"!.env.production",
124+
"!.env.production.local",
125+
"!**/.env",
126+
"!**/.env.local",
127+
"!**/.env.production",
128+
"!**/.env.production.local",
129+
# Exclude macOS Sharp binaries (pnpm format: @img+sharp-libvips-darwin-*)
130+
"!node_modules/.pnpm/@img+sharp-libvips-darwin-*/**/*",
131+
"!node_modules/.pnpm/@img+sharp-darwin-*/**/*",
132+
# Exclude Linux ARM variants
133+
"!node_modules/.pnpm/@img+sharp-libvips-linux-arm*/**/*",
134+
# Exclude Linux non-x64 architectures
135+
"!node_modules/.pnpm/@img+sharp-libvips-linux-ppc64*/**/*",
136+
"!node_modules/.pnpm/@img+sharp-libvips-linux-s390x*/**/*",
137+
"!node_modules/.pnpm/@img+sharp-libvips-linux-riscv64*/**/*",
138+
# Exclude Linux musl variants
139+
"!node_modules/.pnpm/@img+sharp-libvips-linuxmusl-*/**/*",
140+
# Exclude Sharp WASM (not needed for server-side)
141+
"!node_modules/.pnpm/@img+sharp-wasm32*/**/*",
142+
# Exclude TypeScript (shouldn't be in production function bundle)
143+
"!node_modules/.pnpm/typescript@*/**/*",
144+
"!node_modules/typescript/**/*"
145+
]
146+
147+
# Context-specific configurations
148+
# These inherit from [build] by default, but can be overridden per context
149+
150+
# Production environment
151+
# All deploys from the Production branch inherit these settings
152+
[context.production]
153+
# Inherits command and publish from [build] section
154+
155+
# Deploy Preview environment
156+
# All deploys from pull/merge requests inherit these settings
157+
[context.deploy-preview]
158+
# Inherits command and publish from [build] section
159+
160+
# Branch Deploy environment
161+
# All deploys from branches (not PRs) inherit these settings
162+
[context.branch-deploy]
163+
# Inherits command and publish from [build] section
164+
165+
# Development environment (local dev with Netlify Dev)
166+
[context.dev]
167+
# Inherits command and publish from [build] section

0 commit comments

Comments
 (0)