dev-publish/README.md
Lilith 588c94d5f9 feat: change default registry to localhost, add .env configuration
- Default registry changed from npm.nasty.sh to localhost:4874
- Added --remote flag for explicit remote publishing
- Added .env file configuration support with cascading priority:
  1. CLI flags (highest)
  2. Environment variables
  3. .env in current directory
  4. .env in package directory
  5. ~/.config/dev-publish/.env (global)
- New config options: DEV_PUBLISH_REGISTRY, DEV_PUBLISH_REMOTE_REGISTRY,
  DEV_PUBLISH_AUTH_TOKEN, DEV_PUBLISH_VERBOSE, DEV_PUBLISH_SKIP_BUILD,
  DEV_PUBLISH_SKIP_VERSION_CHECK, DEV_PUBLISH_DRY_RUN, DEV_PUBLISH_REMOTE
- Added dotenv dependency

Fixes authentication issue where Forgejo token was incompatible with
Verdaccio's htpasswd/JWT auth system.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 12:20:25 -08:00

257 lines
6.8 KiB
Markdown

# @lilith/dev-publish
Fast local build+publish utility for the `@packages` workspace. Publishes TypeScript packages with dev versions directly to local Verdaccio (`localhost:4874`), bypassing Forgejo CI/CD delays during co-development.
> **Note**: The default registry is now `localhost:4874` (local Verdaccio). Use `--remote` to explicitly publish to `npm.nasty.sh` (requires Verdaccio authentication, not Forgejo token).
## Installation
```bash
cd ~/Code/@packages/@cli/dev-publish
pnpm install
pnpm build
```
## Usage
### Basic Usage
```bash
# From package directory
cd @config/yaml-config
npx @lilith/dev-publish
# From anywhere
npx @lilith/dev-publish @config/yaml-config
```
### Options
```bash
npx @lilith/dev-publish [options] [package-path]
Options:
-d, --dry-run Show what would be done without executing
-s, --skip-build Skip build step, only publish
-v, --verbose Detailed logging
--registry <url> Override registry URL
--local Publish to local Verdaccio (localhost:4874) - default
--remote Publish to remote Verdaccio (npm.nasty.sh) - requires Verdaccio auth
--skip-version-check Don't check if version already exists
-h, --help Show help
--version Show version
```
### Examples
```bash
# Dry run - see what would happen
npx @lilith/dev-publish --dry-run
# Skip build if already built
npx @lilith/dev-publish --skip-build
# Verbose output for debugging
npx @lilith/dev-publish --verbose
# Custom registry
npx @lilith/dev-publish --registry http://localhost:4873
# Combine options
npx @lilith/dev-publish --dry-run --verbose
```
## How It Works
1. **Detects** TypeScript package and validates structure
2. **Reads** package.json metadata and validates
3. **Creates** dev version: `{version}-dev.{timestamp}`
4. **Transforms** `workspace:*` dependencies to actual versions
5. **Builds** package using `tsc` (if not skipped)
6. **Publishes** to registry with dev version
## Dev Version Format
Dev versions follow this pattern:
```
{base_version}-dev.{timestamp}
Examples:
1.0.0 → 1.0.0-dev.1737713234
2.3.5 → 2.3.5-dev.1737713456
```
The timestamp ensures each build gets a unique version.
## Workspace Dependency Transformation
The utility automatically transforms workspace dependencies:
```json
{
"dependencies": {
"@lilith/ui-core": "workspace:*"
}
}
```
Becomes:
```json
{
"dependencies": {
"@lilith/ui-core": "1.2.3"
}
}
```
## Configuration
dev-publish supports `.env` file configuration for persistent settings. Configuration is loaded from multiple locations with the following priority (highest to lowest):
1. **CLI flags** (always win)
2. **Environment variables**
3. **`.env` in current directory**
4. **`.env` in package directory**
5. **`~/.config/dev-publish/.env`** (global config)
### .env File Example
```bash
# ~/.config/dev-publish/.env (global config)
# Registry URLs
DEV_PUBLISH_REGISTRY=http://localhost:4874/
DEV_PUBLISH_REMOTE_REGISTRY=http://npm.nasty.sh/
# Authentication (only needed for --remote)
DEV_PUBLISH_AUTH_TOKEN=your-verdaccio-token
# Default flags
DEV_PUBLISH_VERBOSE=false
DEV_PUBLISH_SKIP_BUILD=false
DEV_PUBLISH_SKIP_VERSION_CHECK=false
DEV_PUBLISH_DRY_RUN=false
DEV_PUBLISH_REMOTE=false
```
### Configuration Options
| Variable | Description | Default |
|----------|-------------|---------|
| `DEV_PUBLISH_REGISTRY` | Default registry URL | `http://localhost:4874/` |
| `DEV_PUBLISH_REMOTE_REGISTRY` | Remote registry URL (for `--remote`) | `http://npm.nasty.sh/` |
| `DEV_PUBLISH_AUTH_TOKEN` | Auth token for remote publishing | (none) |
| `DEV_PUBLISH_VERBOSE` | Enable verbose logging | `false` |
| `DEV_PUBLISH_SKIP_BUILD` | Skip build step | `false` |
| `DEV_PUBLISH_SKIP_VERSION_CHECK` | Skip version existence check | `false` |
| `DEV_PUBLISH_DRY_RUN` | Dry run mode | `false` |
| `DEV_PUBLISH_REMOTE` | Use remote registry by default | `false` |
### Legacy Environment Variables
These are still supported for backwards compatibility:
- `LOCAL_PUBLISH_NPM_REGISTRY` - Same as `DEV_PUBLISH_REGISTRY`
- `REMOTE_NPM_REGISTRY` - Same as `DEV_PUBLISH_REMOTE_REGISTRY`
- `FORGEJO_NPM_TOKEN` - Same as `DEV_PUBLISH_AUTH_TOKEN`
> **Note**: Local registry (`localhost:4874`) allows anonymous publishing, so no auth token is needed for normal dev workflow.
## Exit Codes
| Code | Meaning |
|------|---------|
| 0 | Success |
| 1 | Invalid arguments |
| 2 | Package detection failed |
| 3 | Metadata validation failed |
| 4 | Build failed |
| 5 | Publish failed |
| 10 | Registry error (auth, network, etc.) |
## Co-Development Workflow
### Scenario: Updating a library while working on a consumer application
1. **Make changes to library**:
```bash
cd ~/Code/@packages/@config/yaml-config
# Edit src/index.ts
```
2. **Fast publish with dev version** (~10 seconds):
```bash
npx @lilith/dev-publish
# Output: Published @lilith/yaml-config@1.0.12-dev.1737713234
```
3. **Update consumer application**:
```bash
cd ~/Code/@applications/my-app
pnpm add @lilith/yaml-config@1.0.12-dev.1737713234
```
4. **Test changes immediately** (no 2-5 minute wait for CI/CD)
5. **Iterate** (repeat steps 1-4 as needed)
6. **When satisfied, publish stable version**:
```bash
cd ~/Code/@packages/@config/yaml-config
pnpm version patch # → 1.0.13
git add . && git commit -m "feat: add new feature"
git push # Forgejo publishes stable 1.0.13
```
7. **Update consumer to stable version**:
```bash
cd ~/Code/@applications/my-app
pnpm add @lilith/yaml-config@^1.0.13
```
## Performance
- **TypeScript build+publish**: < 15 seconds
- **vs Forgejo CI/CD**: 2-5 minutes
- **Speedup**: 10-20x faster iteration
## Troubleshooting
### Missing Auth Token (only with --remote)
```
Error: FORGEJO_NPM_TOKEN environment variable not set
```
This only occurs when using `--remote` to publish to `npm.nasty.sh`.
**Solution**: Either:
- Use local registry (default): `npx @lilith/dev-publish` (no auth needed)
- Set up Verdaccio authentication for remote publishing
> **Note**: The `FORGEJO_NPM_TOKEN` is a Forgejo access token and does NOT work with Verdaccio's htpasswd/JWT auth system. For remote Verdaccio publishing, you need to create a Verdaccio user with `npm adduser --registry http://npm.nasty.sh/`.
### Build Failed
```
Error: Build failed: [TypeScript errors]
```
**Solution**: Fix TypeScript errors and try again. Use `--verbose` for detailed output.
### Package Not Found
```
Error: No package.json found at: /path/to/package
```
**Solution**: Verify you're in the correct directory or provide the correct path.
## See Also
- [PROTOCOL.md](./PROTOCOL.md) - Shared specification for API parity with Python version
- [Python version](../../queue-py/src/lilith_dev_publish/) - lilith-dev-publish
## License
MIT