Merge pull request #633 from buster-so/dallin/should-be-able-to-turbo-build-lint-test-unit-without-env-vars

Dallin/should-be-able-to-turbo-build-lint-test-unit-without-env-vars
This commit is contained in:
dal 2025-07-25 18:38:40 -06:00 committed by GitHub
commit 3e821f5609
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 114 additions and 30 deletions

View File

@ -3,12 +3,6 @@ description:
globs:
alwaysApply: true
---
# CLAUDE.md
This file provides guidance to Claude Code when working with code in this monorepo.
**Note**: Many packages and apps have their own CLAUDE.md files with specific implementation details and patterns. Always check for a local CLAUDE.md when working in a specific directory.
## Monorepo Structure
This is a pnpm-based monorepo using Turborepo with the following structure:
@ -54,6 +48,58 @@ When writing code, follow this workflow to ensure code quality:
- Keep business logic separate from infrastructure concerns
- Use proper error handling at each level
## Environment Variables
This project uses a centralized environment variable system:
1. **All environment variables are defined at the root level** in a single `.env` file
2. **Turbo passes these variables** to all packages via the `globalEnv` configuration in `turbo.json`
3. **Individual packages validate** their required environment variables using the shared `@buster/env-utils` package
### Setting Up Environment Variables
1. Copy `.env.example` to `.env` at the project root:
```bash
cp .env.example .env
```
2. Fill in the required values in `.env`
3. All packages will automatically have access to these variables through Turbo
### Adding New Environment Variables
When adding new environment variables:
1. Add the variable to `.env.example` with a descriptive comment
2. Add the variable name to the `globalEnv` array in `turbo.json`
3. Update the package's `validate-env.js` script to include the new variable
4. Update the package's `env.d.ts` file with the TypeScript type definition
### Migrating Packages to Centralized Env
To migrate an existing package to use the centralized environment system:
1. Remove any local `.env` files from the package
2. Add `@buster/env-utils` as a dependency:
```json
"@buster/env-utils": "workspace:*"
```
3. Update the package's `scripts/validate-env.js` to use the shared utilities:
```javascript
import { loadRootEnv, validateEnv } from '@buster/env-utils';
loadRootEnv();
const requiredEnv = {
DATABASE_URL: process.env.DATABASE_URL,
// ... other required variables
};
const { hasErrors } = validateEnv(requiredEnv);
if (hasErrors) process.exit(1);
```
### 3. Ensure Type Safety
```bash
# Build entire monorepo to check types
@ -202,18 +248,23 @@ export async function getWorkspaceSettingsHandler(
## Database Operations
### Query Organization
- **All database queries must be created as helper functions** in `@packages/database/src/queries/`
- **Organize by table** - Each table should have its own subdirectory (e.g., `assets/`, `chats/`, `users/`)
- **Type all queries** - Every query function must have properly typed parameters and return types
- **Export from index** - Each subdirectory should have an `index.ts` that exports all queries for that table
- **Reusable and composable** - Write queries as small, focused functions that can be composed together
### Soft Delete and Upsert Practices
- In our database, we never hard delete, we always use soft deletes with the `deleted_at` field
- For update operations, we should almost always perform an upsert unless otherwise specified
```
**Test Running Guidelines**:
## Test Running Guidelines
- When running tests, use the following Turbo commands:
- `turbo test:unit` for unit tests
- `turbo test:integration` for integration tests
- `turbo test` for running all tests
# important-instruction-reminders
Do what has been asked; nothing more, nothing less.
NEVER create files unless they're absolutely necessary for achieving your goal.
ALWAYS prefer editing an existing file to creating a new one.
NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.
## Pre-Completion Workflow
- Always run `turbo test:unit, lint, and build:dry-run` before making any pull request or finishing a feature, bugfix, etc. to ensure things make it through CI/CD
- You can run all these checks simultaneously with `turbo build:dry-run lint test:unit`

View File

@ -259,10 +259,13 @@ export async function getWorkspaceSettingsHandler(
### Soft Delete and Upsert Practices
- In our database, we never hard delete, we always use soft deletes with the `deleted_at` field
- For update operations, we should almost always perform an upsert unless otherwise specified
```
**Test Running Guidelines**:
## Test Running Guidelines
- When running tests, use the following Turbo commands:
- `turbo test:unit` for unit tests
- `turbo test:integration` for integration tests
- `turbo test` for running all tests
- `turbo test` for running all tests
## Pre-Completion Workflow
- Always run `turbo test:unit, lint, and build:dry-run` before making any pull request or finishing a feature, bugfix, etc. to ensure things make it through CI/CD
- You can run all these checks simultaneously with `turbo build:dry-run lint test:unit`

View File

@ -7,8 +7,9 @@
}
},
"scripts": {
"prebuild": "tsx scripts/validate-env.ts && pnpm run typecheck",
"prebuild": "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || (tsx scripts/validate-env.ts && pnpm run typecheck)",
"build": "tsup",
"build:dry-run": "tsup",
"dev": "bun --watch src/index.ts",
"dev:build": "tsup --watch",
"lint": "biome check --write",

View File

@ -6,8 +6,9 @@
"scripts": {
"dev": "echo 'y' | npx trigger.dev@v4-beta dev",
"deploy": "echo 'y' | npx trigger.dev@v4-beta deploy",
"prebuild": "tsx scripts/validate-env.ts",
"prebuild": "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || tsx scripts/validate-env.ts",
"build": "echo 'No build step required but we run it to make sure env is loaded' && tsc --noEmit",
"build:dry-run": "echo 'No build step required but we run it to make sure env is loaded' && tsc --noEmit",
"lint": "biome check --write",
"test": "vitest run",
"test:watch": "vitest watch",

View File

@ -4,6 +4,7 @@
"scripts": {
"ai:dev": "pnpm --filter @buster/ai dev",
"build": "turbo build",
"build:dry-run": "SKIP_ENV_CHECK=true turbo run build:dry-run",
"check": "biome check ${1:-.}",
"check:fix": "biome check --write ${1:-.}",
"ci:check": "pnpm run check && pnpm run typecheck",

View File

@ -13,8 +13,9 @@
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"prebuild": "tsx scripts/validate-env.ts",
"prebuild": "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || tsx scripts/validate-env.ts",
"build": "tsc",
"build:dry-run": "tsc",
"build:commonjs": "tsc --module commonjs --moduleResolution node",
"build:commonjs:watch": "npm run build:commonjs && tsc --module commonjs --moduleResolution node --watch",
"dev": "tsc --watch",

View File

@ -14,8 +14,9 @@
}
},
"scripts": {
"prebuild": "tsx scripts/validate-env.ts",
"prebuild": "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || tsx scripts/validate-env.ts",
"build": "tsc",
"build:dry-run": "tsc",
"typecheck": "tsc --noEmit",
"dev": "tsc --watch",
"dev:mastra": "mastra dev --dir src",

View File

@ -13,8 +13,9 @@
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"prebuild": "tsx scripts/validate-env.ts",
"prebuild": "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || tsx scripts/validate-env.ts",
"build": "tsc",
"build:dry-run": "tsc",
"build:commonjs": "tsc --module commonjs --moduleResolution node",
"build:commonjs:watch": "npm run build:commonjs && tsc --module commonjs --moduleResolution node --watch",
"lint": "biome check --write",

View File

@ -19,8 +19,9 @@
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"prebuild": "tsx scripts/validate-env.ts",
"prebuild": "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || tsx scripts/validate-env.ts",
"build": "tsc",
"build:dry-run": "tsc",
"build:commonjs": "tsc --module commonjs --moduleResolution node",
"build:commonjs:watch": "npm run build:commonjs && tsc --module commonjs --moduleResolution node --watch",
"db:check": "drizzle-kit check",

View File

@ -11,8 +11,9 @@
}
},
"scripts": {
"prebuild": "tsx scripts/validate-env.ts",
"prebuild": "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || tsx scripts/validate-env.ts",
"build": "tsc",
"build:dry-run": "tsc",
"typecheck": "tsc --noEmit",
"test": "vitest run",
"test:unit": "vitest run --exclude '**/*.int.test.ts' --exclude '**/*.integration.test.ts' --passWithNoTests",

View File

@ -15,8 +15,9 @@
}
},
"scripts": {
"prebuild": "tsx scripts/validate-env.ts",
"prebuild": "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || tsx scripts/validate-env.ts",
"build": "tsc",
"build:dry-run": "tsc",
"typecheck": "tsc --noEmit",
"dev": "tsc --watch",
"lint": "biome check",

View File

@ -15,8 +15,9 @@
}
},
"scripts": {
"prebuild": "tsx scripts/validate-env.ts",
"prebuild": "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || tsx scripts/validate-env.ts",
"build": "tsc",
"build:dry-run": "tsc",
"typecheck": "tsc --noEmit",
"dev": "tsc --watch",
"lint": "biome check --write",

View File

@ -19,8 +19,9 @@
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"prebuild": "tsx scripts/validate-env.ts",
"prebuild": "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || tsx scripts/validate-env.ts",
"build": "tsc",
"build:dry-run": "tsc",
"build:commonjs": "tsc --module commonjs --moduleResolution node",
"build:commonjs:watch": "npm run build:commonjs && tsc --module commonjs --moduleResolution node --watch",
"lint": "biome check --write",

View File

@ -14,8 +14,9 @@
}
},
"scripts": {
"prebuild": "tsx scripts/validate-env.ts",
"prebuild": "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || tsx scripts/validate-env.ts",
"build": "tsc",
"build:dry-run": "tsc",
"typecheck": "tsc --noEmit",
"lint": "biome check --write",
"test": "vitest run",

View File

@ -372,12 +372,15 @@ async function createPackageFiles(config: PackageConfig) {
},
},
scripts: {
prebuild: "tsx scripts/validate-env.ts",
prebuild: "[ \"$SKIP_ENV_CHECK\" = \"true\" ] || tsx scripts/validate-env.ts",
build: "tsc",
"build:dry-run": "tsc",
typecheck: "tsc --noEmit",
dev: "tsc --watch",
lint: "biome check --write",
test: "vitest run",
"test:unit": "vitest run --exclude '**/*.int.test.ts' --exclude '**/*.integration.test.ts' --passWithNoTests",
"test:integration": "vitest run **/*.int.test.ts **/*.integration.test.ts",
"test:watch": "vitest watch",
"test:coverage": "vitest run --coverage",
},

10
scripts/prebuild.sh Normal file
View File

@ -0,0 +1,10 @@
#!/bin/bash
# Skip env validation if SKIP_ENV_CHECK is set
if [ "$SKIP_ENV_CHECK" = "true" ]; then
echo "Skipping environment validation (dry-run build)"
exit 0
fi
# Otherwise run the validation script
tsx scripts/validate-env.ts

View File

@ -7,13 +7,18 @@
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
},
"build:dry-run": {
"dependsOn": ["^build:dry-run"],
"outputs": ["dist/**", ".next/**"],
"env": ["SKIP_ENV_CHECK"]
},
"dev": {
"cache": false,
"persistent": true,
"dependsOn": ["@buster/database#dev"]
},
"lint": {
"dependsOn": ["^build", "^lint"]
"dependsOn": ["^lint"]
},
"typecheck": {
"dependsOn": ["^build"]
@ -22,7 +27,7 @@
"dependsOn": ["^build"]
},
"test:unit": {
"dependsOn": ["^build"]
"dependsOn": ["^test:unit"]
},
"test:integration": {
"dependsOn": ["^build"]