Skip to content

Commit 784b6e4

Browse files
biilmannclaude
andauthored
feat(deploy): significantly improve agent experience (AX) with non-interactive deploy support (#7552)
* feat(deploy): significantly improve agent experience with better non-interactive support This change dramatically improves the "agent experience" (AX) for AI agents and automated tools using the deploy command: **Key Improvements:** - Added `--create [name]` flag to create and deploy sites in one command - Added `--team <slug>` flag for explicit team selection when creating sites - Intelligent team handling: auto-use single team, require explicit selection for multiple teams - Comprehensive help text with copy-pasteable commands shown at every interactive prompt - Proper command parsing with optional site names (`--create` vs `--create sitename`) **Agent Flow Example:** Before: Agents got stuck in interactive menus when deploying new projects After: Agents can successfully deploy with: `netlify deploy --create my-site --team my-team --dir . --prod` **Interactive Improvements:** - Show copy-pasteable commands before every prompt - Context-aware help text (includes current flags like --prod, --dir, etc.) - Better team selection messaging when multiple teams available - Cleaner help text when only one team available **Validation & Error Handling:** - Proper TypeScript types for new flags (`create?: string | boolean`) - Validation that --team only works with --create - Clear error messages with actionable examples - Smart fallbacks for single vs multiple team scenarios This maintains full backward compatibility while enabling seamless automated deployments. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * refactor(deploy): eliminate code duplication in command generation Removed duplicate command generation logic in prepareProductionDeploy by reusing the shared generateDeployCommand helper function. This improves maintainability and ensures consistent command generation across all scenarios. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * fix(deploy): remove emojis from help text and fix locked deployment instructions - Removed emojis from all help text messages for cleaner CLI output - Fixed locked deployment instructions to use --prod-if-unlocked flag instead of manual unlock - Added proper warning about only using --prod-if-unlocked when absolutely sure - Updated generateDeployCommand to support prodIfUnlocked flag 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * refactor(deploy): derive flag map programmatically from Commander.js options Refactored generateDeployCommand to derive available flags from the actual Commander.js command definition instead of maintaining a hardcoded flagMap. This approach: - Eliminates manual flag mapping maintenance - Automatically includes new flags as they're added to the command - Uses command.options to introspect actual option definitions - Handles all option types (string, number, boolean) correctly - Maintains special handling for quoted message values The function now dynamically builds commands from the live command definition, making it more maintainable and less prone to drift. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * fix(deploy): preserve all original flags in generated commands Removed unnecessary filtering of hidden and deprecated options from generateDeployCommand. If users included these flags in their original command, they should be preserved in the copyable command for consistency. This ensures the generated command exactly matches what the user originally attempted to run. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * remove(teams): remove unnecessary netlify teams command The teams command is not needed since the deploy command now properly handles team selection with clear error messages that list available teams when multiple teams are present. This simplifies the codebase while maintaining all necessary functionality for both interactive and non-interactive team selection. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * Clean CLAUDE.md file * refactor(deploy): rename --create flag to --create-site for clarity Change the --create flag to --create-site in the deploy command to make the flag name more explicit and descriptive. This improves clarity about what the flag does when creating new sites during deployment. Changes: - Rename --create flag to --create-site in command definition - Update all option references from options.create to options.createSite - Update help text and examples to use new flag name - Update TypeScript types to reflect the change - Maintain existing functionality and validation logic 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * refactor(bin): simplify error handling in run.js Change error handling from explicit .catch() with process.exit(1) back to simple top-level await. This removes the explicit fatal error logging and process exit, allowing errors to bubble up naturally. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * fix(deploy): prevent duplicate --build and --no-build flags in generated commands Fix the generateDeployCommand function to properly handle Commander.js negatable boolean options. Previously, both --build and --no-build flags were being added to generated command suggestions, causing confusing output like "netlify deploy --create-site <NAME> --build --no-build". Changes: - Add special handling for the 'build' option to only show --no-build when build is false - Skip processing the --no-build option separately since it's handled with build logic - Add flag deduplication to prevent any duplicate flags in generated commands - Maintain clean command suggestions without redundant or conflicting flags This ensures users get clean, actionable command suggestions without conflicting flags that would cause command errors. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * refactor(deploy): simplify generateDeployCommand with generic negated flag handling Replace complex special-case logic with clean, generic handling for any --no-* flags. Only include negated flags when explicitly used by the user (value === false). Remove verbose comments and deduplication logic in favor of preventing issues at the source. Changes: - Generic handling for all --no-* flags instead of hardcoding --no-build - Remove special build flag logic and deduplication - Clean up verbose comments for better code readability - Maintain functionality: include --no-build only when user specifies it 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * refactor(deploy): extract site creation logic into focused functions Replace complex nested if/else chains with clean, single-purpose functions. The site creation logic was deeply nested with multiple levels of branching that was hard to follow and maintain. Changes: - Extract ensureSiteExists() as main entry point with clear branching - Add createSiteWithFlags() for --create-site flag handling - Add validateTeamForSiteCreation() for team validation logic - Add promptForSiteAction() for interactive site selection - Use early returns to eliminate nesting levels - Remove verbose comments in favor of self-documenting code Results in cleaner, more testable code with the same functionality. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * fix(deploy): resolve linting issues in refactored site creation functions Fix ESLint errors introduced in the site creation logic refactor: - Use optional chaining for option.long?.startsWith() - Replace any types with proper TypeScript types ($TSFixMe, SiteInfo) - Ensure all code follows project linting standards 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * Tweak deploy command description * Remove + from Create and configure menu option * style: fix prettier formatting issues Apply prettier formatting to files that were not properly formatted. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * test: update help command snapshot for deploy description Update the help command snapshot to reflect the new deploy command description that was changed from 'Create a new deploy from the contents of a folder' to 'Deploy your project to Netlify'. This fixes the failing CI/CD integration tests. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * style: fix prettier formatting for init and gh-auth files Apply prettier formatting to resolve code style warnings. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * docs: sync documentation for deploy command changes Update auto-generated documentation to reflect: - New deploy command description: 'Deploy your project to Netlify' - Added --create-site flag documentation - Added --team flag documentation - Updated examples with new flag usage - Improved command description and help text Generated via: npm run docs 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> --------- Co-authored-by: Claude <[email protected]>
1 parent bd4e641 commit 784b6e4

File tree

8 files changed

+343
-171
lines changed

8 files changed

+343
-171
lines changed

CLAUDE.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Development Commands
6+
7+
### Build and Development
8+
- `npm run build` - Compiles TypeScript using `tsc --project tsconfig.build.json`
9+
- `npm run dev` - Runs TypeScript compiler in watch mode
10+
- `npm run clean` - Removes the `dist/` directory
11+
12+
### Testing
13+
- `npm test` - Runs the full test suite (unit, integration, and e2e tests)
14+
- `npm run test:unit` - Runs unit tests only with `vitest run tests/unit/`
15+
- `npm run test:integration` - Runs integration tests with `vitest run --retry=3 tests/integration/`
16+
- `npm run test:e2e` - Runs end-to-end tests with `vitest run --config vitest.e2e.config.ts`
17+
- **Single test file**: `npm exec vitest -- run tests/unit/lib/account.test.ts`
18+
- **Single test by name**: `npm exec vitest -- run tests/unit/lib/account.test.ts -t 'test name'`
19+
- **Debug tests**: `DEBUG_TESTS=true npm exec vitest -- run [test-file] -t 'test name'`
20+
- `npm run test:init` - Sets up test dependencies for various fixtures (Hugo, Next.js, monorepo)
21+
22+
### Code Quality
23+
- `npm run lint` - Runs ESLint with cache
24+
- `npm run lint:fix` - Runs ESLint and automatically fixes issues
25+
- `npm run format` - Formats code with Prettier
26+
- `npm run format:check` - Checks code formatting without modifying files
27+
- `npm run typecheck` - Runs TypeScript type checking
28+
- `npm run typecheck:watch` - Runs TypeScript type checking in watch mode
29+
30+
### Running the CLI Locally
31+
- `./bin/run.js [command]` - Runs the CLI locally
32+
- `DEBUG=true ./bin/run.js [command]` - Runs with stack traces enabled for debugging
33+
- `npm run start -- [command]` - Alternative way to run CLI locally
34+
35+
## Architecture
36+
37+
### Core Structure
38+
The Netlify CLI is built with **Commander.js** for CLI interface, **@netlify/js-client** for API interactions, and **TypeScript** with modular architecture. The system uses a registry pattern for managing Functions and Edge Functions, with sophisticated local development server capabilities.
39+
40+
### Key Architectural Patterns
41+
42+
#### Command Architecture
43+
- All commands extend `BaseCommand` class (`src/commands/base-command.ts`) which provides:
44+
- Consistent config loading and API client setup
45+
- Site information management and linking
46+
- Authentication and token handling
47+
- Analytics and telemetry integration
48+
- Commands follow a modular structure with separate `index.ts` files for exports
49+
- Each command supports both interactive prompts and non-interactive flag-based operation
50+
51+
#### Registry Pattern for Runtime Management
52+
- **FunctionsRegistry** (`src/lib/functions/registry.ts`): Manages Netlify Functions lifecycle
53+
- Supports multiple runtimes (JavaScript/TypeScript, Go, Rust)
54+
- Handles hot reloading and file watching
55+
- Manages function builds and serving
56+
- **EdgeFunctionsRegistry** (`src/lib/edge-functions/registry.ts`): Manages Edge Functions
57+
- Uses `@netlify/edge-bundler` for Deno-based edge runtime
58+
- Handles Edge Function deployment and local serving
59+
60+
#### Development Server Architecture (`netlify dev`)
61+
The dev server (`src/commands/dev/dev.ts`) orchestrates multiple subsystems:
62+
- **Proxy Server**: Routes requests between static files, functions, and edge functions
63+
- **Functions Server**: Executes Netlify Functions locally with runtime-specific handlers
64+
- **Edge Functions Proxy**: Serves Edge Functions via Deno runtime
65+
- **Framework Detection**: Auto-detects and integrates with various web frameworks
66+
- **Live Tunneling**: Provides public URLs for local development via Netlify's tunnel service
67+
68+
#### Config System
69+
- Uses `@netlify/config` for configuration resolution and normalization
70+
- Supports `netlify.toml` files with environment-specific overrides
71+
- Integrates with Netlify's build plugins system
72+
- Handles environment variable injection from multiple sources (process, .env files, Netlify site settings)
73+
74+
### Key Libraries and Their Roles
75+
76+
#### Core Infrastructure
77+
- `src/lib/api.ts` - Netlify API client wrapper with authentication
78+
- `src/lib/build.ts` - Build system integration and config caching
79+
- `src/lib/settings.ts` - Project and global settings management
80+
- `src/utils/command-helpers.ts` - Shared utilities for CLI commands (logging, error handling, prompts)
81+
82+
#### Function Runtime System
83+
- `src/lib/functions/runtimes/` - Runtime-specific builders and executors
84+
- `js/` - JavaScript/TypeScript function handling with `zip-it-and-ship-it`
85+
- `go/` - Go function compilation and execution
86+
- `rust/` - Rust function compilation via Cargo
87+
- `src/lib/functions/server.ts` - Local function server with request/response handling
88+
89+
#### Development Tools
90+
- `src/utils/dev.ts` - Development server utilities and environment setup
91+
- `src/utils/proxy-server.ts` - HTTP proxy for routing dev server requests
92+
- `src/utils/detect-server-settings.ts` - Framework detection and port management
93+
94+
#### Deployment System
95+
- `src/utils/deploy/` - Site deployment orchestration
96+
- File hashing, diffing, and upload optimization
97+
- Build artifact management and caching
98+
- Progress tracking and status reporting
99+
100+
### Testing Architecture
101+
- **Unit Tests** (`tests/unit/`): Test individual modules and utilities
102+
- **Integration Tests** (`tests/integration/`): Test full command workflows using fixtures
103+
- **E2E Tests**: Test complete user scenarios with real Netlify API interactions
104+
- **Fixtures** (`tests/integration/__fixtures__/`): Sample projects for testing different frameworks and configurations
105+
106+
### Important Implementation Details
107+
108+
#### Environment Variable Handling
109+
Environment variables are loaded from multiple sources with specific precedence:
110+
1. Process environment
111+
2. `.env` files (multiple variants supported)
112+
3. Netlify site settings (shared, project-specific)
113+
4. Addon-provided variables
114+
5. Build-time configuration
115+
116+
#### Function URL Routing
117+
Functions are accessible via standardized URL patterns:
118+
- `/.netlify/functions/[function-name]` - Standard functions
119+
- `/.netlify/builders/[function-name]` - On-demand builders
120+
- Custom paths supported via function configuration
121+
122+
#### Build Plugin Integration
123+
The CLI integrates with Netlify's build plugin system, allowing plugins to:
124+
- Modify build configuration
125+
- Add custom build steps
126+
- Integrate with the development server
127+
- Provide additional CLI commands
128+
129+
### Development Setup Requirements
130+
- Node.js 20.12.2+ required
131+
- Git LFS must be installed for full test suite
132+
- Some integration tests require Netlify Auth Token (`NETLIFY_AUTH_TOKEN`) or login via `./bin/run.js login`
133+
- Live tests can be disabled with `NETLIFY_TEST_DISABLE_LIVE=true`
134+
135+
### Coding Style:
136+
- Never write comments on what the code does, make the code clean and self explanatory instead

docs/commands/deploy.md

Lines changed: 12 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -7,74 +7,18 @@ sidebar:
77
# `deploy`
88

99
<!-- AUTO-GENERATED-CONTENT:START (GENERATE_COMMANDS_DOCS) -->
10-
Create a new deploy from the contents of a folder
11-
Deploys from the build settings found in the netlify.toml file, or settings from the API.
10+
Deploy your project to Netlify
1211

13-
The following environment variables can be used to override configuration file lookups and prompts:
12+
Builds and deploys your project to Netlify. Creates a draft deploy by default.
13+
Use --prod to deploy directly to your live site.
1414

15-
- `NETLIFY_AUTH_TOKEN` - an access token to use when authenticating commands. Keep this value private.
16-
- `NETLIFY_SITE_ID` - override any linked project in the current working directory.
15+
The deploy command will:
16+
- Build your project (unless --no-build is specified)
17+
- Upload static files, functions, and edge functions
18+
- Process redirects and headers from netlify.toml or _redirects/_headers files
19+
- Provide deploy and function logs URLs
1720

18-
Lambda functions in the function folder can be in the following configurations for deployment:
19-
20-
21-
Built Go binaries:
22-
------------------
23-
24-
```
25-
functions/
26-
└── nameOfGoFunction
27-
```
28-
29-
Build binaries of your Go language functions into the functions folder as part of your build process.
30-
31-
32-
Single file Node.js functions:
33-
-----------------------------
34-
35-
Build dependency bundled Node.js lambda functions with tools like webpack or browserify into the function folder as part of your build process.
36-
37-
```
38-
functions/
39-
└── nameOfBundledNodeJSFunction.js
40-
```
41-
42-
Unbundled Node.js functions that have dependencies outside or inside of the functions folder:
43-
---------------------------------------------------------------------------------------------
44-
45-
You can ship unbundled Node.js functions with the CLI, utilizing top level project dependencies, or a nested package.json.
46-
If you use nested dependencies, be sure to populate the nested node_modules as part of your build process before deploying using npm or yarn.
47-
48-
```
49-
project/
50-
├── functions
51-
│ ├── functionName/
52-
│ │ ├── functionName.js (Note the folder and the function name need to match)
53-
│ │ ├── package.json
54-
│ │ └── node_modules/
55-
│ └── unbundledFunction.js
56-
├── package.json
57-
├── netlify.toml
58-
└── node_modules/
59-
```
60-
61-
Any mix of these configurations works as well.
62-
63-
64-
Node.js function entry points
65-
-----------------------------
66-
67-
Function entry points are determined by the file name and name of the folder they are in:
68-
69-
```
70-
functions/
71-
├── aFolderlessFunctionEntrypoint.js
72-
└── functionName/
73-
├── notTheEntryPoint.js
74-
└── functionName.js
75-
```
76-
77-
Support for package.json's main field, and intrinsic index.js entrypoints are coming soon.
21+
For detailed configuration options, see the Netlify documentation.
7822

7923
**Usage**
8024

@@ -86,6 +30,7 @@ netlify deploy
8630

8731
- `alias` (*string*) - Specifies the alias for deployment, the string at the beginning of the deploy subdomain. Useful for creating predictable deployment URLs. Avoid setting an alias string to the same value as a deployed branch. `alias` doesn’t create a branch deploy and can’t be used in conjunction with the branch subdomain feature. Maximum 37 characters.
8832
- `context` (*string*) - Specify a deploy context for environment variables read during the build (”production”, ”deploy-preview”, ”branch-deploy”, ”dev”) or `branch:your-branch` where `your-branch` is the name of a branch (default: dev)
33+
- `create-site` (*string*) - Create a new site and deploy to it. Optionally specify a name, otherwise a random name will be generated. Requires --team flag if you have multiple teams.
8934
- `dir` (*string*) - Specify a folder to deploy
9035
- `filter` (*string*) - For monorepos, specify the name of the application to run the command in
9136
- `functions` (*string*) - Specify a functions folder to deploy
@@ -99,6 +44,7 @@ netlify deploy
9944
- `prod` (*boolean*) - Deploy to production
10045
- `site` (*string*) - A project name or ID to deploy to
10146
- `skip-functions-cache` (*boolean*) - Ignore any functions created as part of a previous `build` or `deploy` commands, forcing them to be bundled again as part of the deployment
47+
- `team` (*string*) - Specify team slug when creating a site. Only works with --create-site flag.
10248
- `timeout` (*string*) - Timeout to wait for deployment to finish
10349
- `trigger` (*boolean*) - Trigger a new build of your project on Netlify without uploading local files
10450

@@ -115,6 +61,7 @@ netlify deploy --message "A message with an $ENV_VAR"
11561
netlify deploy --auth $NETLIFY_AUTH_TOKEN
11662
netlify deploy --trigger
11763
netlify deploy --context deploy-preview
64+
netlify deploy --create-site my-new-site --team my-team # Create site and deploy
11865
```
11966

12067

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Provision a production ready Postgres database with a single command
6363

6464
### [deploy](/commands/deploy)
6565

66-
Create a new deploy from the contents of a folder
66+
Deploy your project to Netlify
6767

6868
### [dev](/commands/dev)
6969

0 commit comments

Comments
 (0)