Nagare (流れ) is a comprehensive release management library for JavaScript/TypeScript projects that automates version bumping, changelog generation, and GitHub releases using conventional commits and semantic versioning.
Basic programmatic usage
Basic programmatic usage
import { ReleaseManager } from "jsr:@rick/nagare"; const config = { project: { name: "My App", repository: "https://github.com/user/my-app" }, versionFile: { path: "./version.ts", template: "typescript" } }; const releaseManager = new ReleaseManager(config); const result = await releaseManager.release(); if (result.success) { console.log(`Released version ${result.version}`); }
Architecture Overview
Nagare follows a layered architecture with clear separation of concerns:
┌─────────────────────────────────────────┐ │ CLI Interface │ ← User entry point ├─────────────────────────────────────────┤ │ Manager Layer │ ← Orchestration │ ReleaseManager │ RollbackManager │ ├─────────────────────────────────────────┤ │ Integration Layer │ ← External systems │ GitOperations │ GitHubIntegration │ ... │ ├─────────────────────────────────────────┤ │ Processing Layer │ ← Data transformation │ TemplateProcessor │ ChangelogGen │ ... │ ├─────────────────────────────────────────┤ │ Infrastructure Layer │ ← Foundation │ Logger │ Config │ Types │ └─────────────────────────────────────────┘
Intelligent File Handlers (v1.1.0+)
Nagare includes built-in handlers that automatically detect and update common file types:
Simple file updates with built-in handlers
Simple file updates with built-in handlers
updateFiles: [ { path: "./deno.json" }, // Automatically handled { path: "./package.json" }, // Automatically handled { path: "./README.md" }, // Updates badges and version references { path: "./jsr.json" } // Automatically handled ]
Conventional Commits
Nagare analyzes commit messages to determine version bumps:
feat:→ Minor version bump (1.0.0 → 1.1.0)fix:→ Patch version bump (1.0.0 → 1.0.1)feat!:orBREAKING CHANGE:→ Major version bump (1.0.0 → 2.0.0)- Other types → Patch version bump
Extensible Version Files (v1.8.0+)
Add custom exports to generated version files without writing full templates:
Additional exports configuration
Additional exports configuration
versionFile: { path: "./version.ts", template: "typescript", // Add custom exports additionalExports: [ { name: "API_CONFIG", type: "const", value: { baseUrl: "https://api.example.com", timeout: 5000 }, description: "API configuration", asConst: true }, { name: "Utils", type: "class", content: ` static formatVersion(): string { return \`v\${VERSION}\`; }` } ], // Or add raw content extend: { prepend: "// Auto-generated file\\n\\n", append: "\\n// End of generated content" } }
Advanced Usage
Custom file handler
Custom file handler
import { FileHandlerManager } from "jsr:@rick/nagare"; const fileHandler = new FileHandlerManager(); fileHandler.registerHandler({ id: "custom-config", name: "Custom Config Handler", detector: (filepath) => filepath.endsWith(".custom"), patterns: { version: /version:\s*"([^"]+)"/ } });
Custom version template
Custom version template
versionFile: { path: "./version.ts", template: "custom", customTemplate: ` export const VERSION = "{{version}}"; export const BUILD_DATE = "{{buildDate}}"; export const FEATURES = {{metadata.features | jsonStringify}}; ` }
Custom updateFn for complex replacements
Custom updateFn for complex replacements
// For files with special formatting like markdown tables updateFiles: [{ path: "./mod.ts", patterns: { version: /(\| Version \| )([^\s]+)( \|)/, }, updateFn: (content: string, data: TemplateData) => { // Preserve table structure while updating only the version return content.replace( /(\| Version \| )([^\s]+)( \|)/, `$1${data.version}$3` ); }, }]
Migration from Other Tools
From semantic-release
- Nagare uses similar conventional commit analysis
- Configuration is TypeScript-based instead of JSON
- Built-in file update patterns instead of plugins
From standard-version
- Similar changelog generation following Keep a Changelog
- More flexible file update system
- Better TypeScript and Deno support
ChangelogGenerator - CHANGELOG.md management with PR awareness
- config: NagareConfig
-
createChangelogHeader(): string
Create changelog header
-
generatePRChangelogEntry(releaseNotes: PRReleaseNotes): Promise<string>
Generate PR-aware changelog entry using Vento template
-
generatePRGroupedReleaseNotes(): PRReleaseNotesversion: string,date: string,prResult: PRDetectionResult
Generate PR-grouped release notes
-
generatePRReleaseNotes(): Promise<PRReleaseNotes>version: string,commits: ConventionalCommit[]
Generate release notes with PR detection
-
generateTraditionalChangelogEntry(releaseNotes: ReleaseNotes): string
Generate traditional changelog entry (backward compatible)
-
generateTraditionalReleaseNotes(): PRReleaseNotesversion: string,date: string,commits: ConventionalCommit[]
Generate traditional release notes (backward compatibility)
-
getBuiltInPRTemplate(): string
Get built-in PR changelog template
- git: GitOperations
-
insertNewEntry(): stringexistingContent: string,newEntry: string
Insert new entry into existing changelog
- logger: Logger
- prDetector: PRDetector
- templateProcessor: TemplateProcessor
-
updateChangelog(releaseNotes: ReleaseNotes | PRReleaseNotes): Promise<void>
Update CHANGELOG.md with new release notes
DocGenerator - Documentation generation using deno doc
- config: NagareConfig
-
generateDocs(): Promise<void>
Generate documentation using deno doc
-
runCommand(cmd: string[]): Promise<string>
Run command helper
Factory class for creating common Nagare errors with consistent formatting
-
configNotFound(searchedPaths: string[]): NagareError
Create a configuration not found error
-
fileHandlerNotFound(filePath: string): NagareError
Create a file handler not found error
-
gitNotInitialized(): NagareError
Create a git not initialized error
-
githubCliNotFound(): NagareError
Create a GitHub CLI not found error
-
invalidJson(): NagareErrorfilePath: string,parseError: string
Create an invalid JSON error
-
uncommittedChanges(): NagareError
Create an uncommitted changes error
-
versionNotFound(): NagareErrorfilePath: string,searchedPatterns?: string[]
Create a version not found error
Manages built-in and custom file handlers, providing automatic detection and updating of version strings in project files.
-
getAllHandlerIds(): string[]
Get all registered handler IDs
-
getHandler(filePath: string): FileHandler | undefined
Get handler for a specific file path
-
handlers: Map<string, FileHandler>
Map of registered handlers by ID
-
hasHandler(filePath: string): boolean
Check if a handler exists for a file
-
logger: Logger
Logger instance
-
previewChanges(): Promise<FileChangePreview>filePath: string,key: string,newValue: string
Preview what would change in a file
-
registerHandler(handler: FileHandler): void
Register a custom handler
-
updateFile(): Promise<FileUpdateResult>filePath: string,key: string,newValue: string,customUpdateFn?: () => stringcontent: string,data: TemplateData
Update a file using the appropriate handler
GitHubIntegration - GitHub release management
- config: NagareConfig
-
createRelease(releaseNotes: ReleaseNotes): Promise<string | undefined>
Create GitHub release
-
formatReleaseBody(notes: ReleaseNotes): string
Format release body for GitHub
-
runCommand(cmd: string[]): Promise<string>
Run command helper
Provides a comprehensive interface for git operations needed during the release process. Handles commit parsing, tag management, and repository state validation.
-
commitAndTag(version: string): Promise<void>
Create commit and tag for release
- config: NagareConfig
-
deleteLocalTag(tag: string): Promise<void>
Delete a local tag
-
deleteRemoteTag(tag: string): Promise<void>
Delete a remote tag
-
extractPRNumber(message: string): number | null
Extract PR number from a merge commit message Supports various GitHub merge formats
-
getCommitsInPR(mergeCommit: string): Promise<ConventionalCommit[]>
Get commits that were part of a PR Returns commits between merge base and the second parent of merge commit
-
getCommitsSinceLastRelease(): Promise<ConventionalCommit[]>
Get commits since last release
-
getCurrentBranch(): Promise<string>
Get current branch name.
-
getCurrentCommitHash(): Promise<string>
Get current commit hash (short format).
-
getGitUser(): Promise<{ name: string; email: string; }>
Get git user configuration.
-
getLastCommitMessage(): Promise<string>
Get the last commit message
-
getLastReleaseTag(): Promise<string>
Get the last release tag.
-
getLocalTags(): Promise<string[]>
Get list of local tags
-
getMergeCommits(since: string): Promise<Array<{ sha: string; message: string; date: string; }>>
Get merge commits since a specific tag or commit Used for PR detection in changelog generation
-
hasUncommittedChanges(): Promise<boolean>
Check for uncommitted changes in the working directory.
-
isGitRepository(): Promise<boolean>
Check if current directory is a git repository.
- logger: Logger
-
parseConventionalCommit(gitLogLine: string): ConventionalCommit | null
Parse a git log line into a conventional commit
-
pushToRemote(): Promise<void>
Push changes and tags to remote
-
remoteTagExists(tag: string): Promise<boolean>
Check if a remote tag exists
-
resetToCommit(): Promise<void>commitish: string,hard?: boolean
Reset to a previous commit (for rollback)
-
runCommand(cmd: string[]): Promise<string>
Run a git command and return the output
Enhanced error class for Nagare with actionable suggestions
- context: Record<string, unknown>
- docsUrl: string
- suggestions: string[]
-
toJSON(): Record<string, unknown>
Create a JSON representation for logging
-
toString(): string
Format error for CLI output with colors and structure
Provides factory methods for creating common, safe regex patterns for version matching in various file formats.
-
jsonVersion(indentAware?: boolean): RegExp
Build a safe JSON version pattern
-
tsConst(): RegExpname: string,exported?: boolean
Build a TypeScript const pattern
-
versionBadge(badgeService?: "shields.io" | "img.shields.io" | "any"): RegExp
Build a generic version badge pattern
-
yamlVersion(quoted?: "single" | "double" | "both" | "none"): RegExp
Build a safe YAML version pattern
The ReleaseManager orchestrates all aspects of the release process including:
-
attemptAutoFix(): Promise<{ success: boolean; jsrUrl?: string; error?: string; }>logs: string,_version: string,monitor: GitHubActionsMonitor,progress: StdProgressIndicator | null
Attempt to auto-fix CI/CD errors
-
attemptPreflightAutoFix(result: PreflightResult): Promise<PreflightResult>
Tries to automatically fix issues identified by pre-flight checks. Currently supports auto-formatting for format check failures.
- backupManager: BackupManager
-
buildSafeReplacement(): stringpattern: RegExp,newValue: string
Analyzes the regex pattern to determine the appropriate replacement format. Handles common patterns for JSON, YAML, Markdown, and other formats.
- changelogGenerator: ChangelogGenerator
- config: NagareConfig
-
createProgressIndicator(): StdProgressIndicator | null
Create progress indicator instance
-
directJsrVerification(): Promise<verifier: JsrVerifier,packageInfo: { scope: string; name: string; version: string; },_progress: StdProgressIndicator | null>{ success: boolean; jsrUrl?: string; error?: string; attempts?: number; }
Direct JSR verification without CI/CD monitoring
- docGenerator: DocGenerator
- fileHandlerManager: FileHandlerManager
-
formatChangedFiles(): Promise<void>
Runs Deno formatter on all files to ensure consistent formatting before committing. This prevents CI failures due to formatting issues.
-
generateReleaseNotes(): ReleaseNotesversion: string,commits: ConventionalCommit[]
Categorizes commits according to conventional commit types and generates release notes following Keep a Changelog format. Handles breaking changes, commit hash inclusion, and description truncation.
-
getConfig(): NagareConfig
Get the current configuration
-
getFilesToBackup(): string[]_newVersion: string,_releaseNotes: ReleaseNotes
Identifies all files that will be modified during the release process so they can be backed up before any changes are made.
-
getPreflightChecks(): PreflightCheck[]
Defines the validation checks to run before creating a release. These checks ensure code quality and prevent failed releases.
-
getTemplateValue(): string | undefineddata: TemplateData,keyPath: string
Navigates nested objects using dot notation to retrieve values. Converts non-string values to strings for replacement.
- git: GitOperations
- github: GitHubIntegration
- logger: Logger
-
mergeWithDefaults(config: NagareConfig): NagareConfig
Merge user config with defaults
-
performPreflightChecks(): Promise<PreflightResult>
Runs all configured pre-flight checks to validate the codebase before creating a release. This prevents common CI/CD failures.
-
previewFileUpdates(templateData: TemplateData): Promise<void>
Shows what changes would be made to each file without actually modifying them. Useful for verifying patterns work correctly before committing to changes.
-
previewRelease(releaseNotes: ReleaseNotes | PRReleaseNotes): void
Displays a summary of the release notes showing counts for each category. Helps users understand what changes are included before confirming release. Now supports PR-aware release notes with PR grouping information.
-
release(bumpType?: BumpType): Promise<ReleaseResult>
Coordinates the entire release workflow:
-
shouldVerifyJsrPublish(): boolean
Check if JSR publish verification should be performed
- stateTracker: ReleaseStateTracker
- templateProcessor: TemplateProcessor
-
updateCustomFile(): Promise<void>filePattern: FileUpdatePattern,templateData: TemplateData
Updates files using the following priority:
-
updateFiles(): Promise<string[]>version: string,releaseNotes: ReleaseNotes | PRReleaseNotes
Updates all files configured in the release configuration:
-
updateVersionFile(templateData: TemplateData): Promise<void>
Generates and writes the version file using either custom templates or built-in templates. Supports TypeScript, JSON, YAML, and custom formats.
-
validateConfig(config: NagareConfig): { valid: boolean; errors: string[]; }
Validates required fields and configuration consistency. Useful for checking configuration before creating a ReleaseManager.
-
validateEnvironment(): Promise<void>
Performs comprehensive validation including:
-
validateFileUpdatePatterns(): { valid: boolean; warnings: string[]; errors: string[]; suggestions: string[]; }
Validate file update patterns to detect dangerous configurations
-
validateFileUpdatePatternsEnhanced(): { valid: boolean; warnings: string[]; errors: string[]; suggestions: string[]; }
Enhanced validation that checks for:
-
verifyJsrPublication(): Promise<version: string,progress: StdProgressIndicator | null>{ success: boolean; jsrUrl?: string; error?: string; attempts?: number; }
Verify JSR publication with monitoring and auto-fix
- versionUtils: VersionUtils
RollbackManager - Handles release rollbacks
- config: NagareConfig
-
getConfig(): NagareConfig
Get the current configuration
- git: GitOperations
- logger: Logger
-
rollback(targetVersion?: string): Promise<RollbackResult>
Rollback a release
Template processing and file generation using Vento.
-
config: NagareConfig
Nagare configuration
-
generateAdditionalExports(): stringexports: AdditionalExport[],format: TemplateFormat
Generate code for additional exports
-
generateVersionFile(data: TemplateData): Promise<string>
Generate version file content using built-in templates
-
logger: Logger
Logger instance
-
prepareTemplateData(data: TemplateData): Record<string, unknown>
Prepare template data with additional computed values
-
processTemplate(): Promise<string>template: string,data: TemplateData
Process a template string with data using Vento
-
setupSecurityContext(): void
Setup security context for template execution
-
setupVentoFilters(): void
Setup custom Vento filters for release management
-
validateTemplate(template: string): Promise<{ valid: boolean; error?: string; }>
Test template compilation (useful for validation)
-
validateTemplateSecure(template: string): { valid: boolean; error?: string; }
Validate template for security issues
-
vento: ReturnType<vento>
Vento template environment instance
VersionUtils - Semantic versioning operations
-
calculateNewVersion(): stringcurrentVersion: string,commits: ConventionalCommit[],bumpType?: BumpType
Calculate new version based on commits and bump type
- config: NagareConfig
-
getCurrentVersion(): Promise<string>
Get current version from git tags first, then fall back to version file
- git: GitOperations
-
parseVersion(version: string): { major: number; minor: number; patch: number; prerelease: string | null; }
Parse semantic version into components
Bump types for version increments
Log levels
Template formats supported by Nagare's built-in templates. All built-in templates now use Vento syntax for robust processing.
Define additional constants, classes, functions, or types to be included in generated version files. Supports various export types with TypeScript compatibility.
-
asConst: boolean
Whether to add "as const" assertion (for TypeScript const exports)
-
async: boolean
Whether this export is async (for functions)
-
content: string
For complex types like classes and functions, provide the body content. The export declaration will be automatically generated based on the type.
-
description: string
Optional JSDoc comment description
-
isDefault: boolean
Whether this export is default
-
name: string
Export name (must be a valid JavaScript identifier)
-
type: "const"
| "let"
| "var"
| "class"
| "function"
| "interface"
| "type"
| "enum"Export type
-
value: unknown
For simple value exports, provide the JavaScript value. Objects and arrays will be JSON stringified automatically.
Commit type to changelog section mapping
Conventional commit structure
-
body: string
Commit body
-
breakingChange: boolean
Breaking change indicator
-
date: string
Commit date
-
description: string
Commit description
-
hash: string
Git commit hash
-
raw: string
Raw commit message
-
scope: string
Commit scope
-
type: string
Commit type
Preview of changes that would be made to a file
-
error: string
Error message if preview failed
-
matches: Array<{ line: number; original: string; updated: string; }>
List of matches found
File handler definition for intelligent file updates
-
detector: (filePath: string) => boolean
Function to detect if this handler applies to a file
-
id: string
Unique identifier for this handler
-
name: string
Human-readable name
-
patterns: Record<string, RegExp>
Built-in patterns for common fields
-
replacer: () => stringcontent: string,key: string,oldValue: string,newValue: string
Optional custom replacement logic if patterns aren't sufficient
-
validate: (content: string) => { valid: boolean; error?: string; }
Optional post-update validation
-
validators: Record<string, (content: string) => boolean>
Optional validators to ensure patterns work correctly
Defines how additional files are updated during the release process. Can use either regex patterns for find/replace or a custom update function.
-
path: string
File path relative to project root
-
patterns: { [key: string]: RegExp; }
Patterns to find and replace Required if updateFn is not provided
-
updateFn: () => stringcontent: string,data: TemplateData
Optional custom update function If provided, overrides patterns
Result of a file update operation
-
content: string
Updated file content if successful
-
error: string
Error message if failed
-
success: boolean
Whether the update succeeded
-
warnings: string[]
Warning messages
GitHub integration configuration
-
createRelease: boolean
Create GitHub release
-
owner: string
Repository owner
-
releaseTemplate: string
Release template format
-
repo: string
Repository name
-
tokenEnvVar: string
GitHub token (from environment)
Main configuration interface for Nagare
-
commitTypes: CommitTypeMapping
Custom commit type mappings
-
docs: DocsConfig
Documentation generation
-
github: GitHubConfig
GitHub integration settings
-
hooks: { preRelease?: Array<() => Promise<void>>; postRelease?: Array<() => Promise<void>>; }
Hooks allow running custom functions at specific points in the release process. Useful for tasks like formatting, validation, or custom notifications.
-
locale: string
Set the language for all CLI output, error messages, and prompts. If not specified, auto-detects from NAGARE_LOCALE or system locale.
-
options: ReleaseOptions
Advanced options
-
project: { name: string; description?: string; repository: string; homepage?: string; license?: string; author?: string; }
Project metadata
-
release: ReleaseConfig
Advanced release workflow settings including JSR verification, auto-fix capabilities, and progress visualization.
-
releaseNotes: ReleaseNotesConfig
Release notes configuration
-
security: SecurityConfig
Security settings for template processing and file operations. Controls sandboxing levels and validation strictness.
-
templates: TemplateConfig
Template configuration
-
updateFiles: FileUpdatePattern[]
Files to update during release
-
versionFile: VersionFile
Version file configuration
Release notes structure
-
added: string[]
Added features
-
changed: string[]
Changed/improved items
-
date: string
Release date
-
deprecated: string[]
Deprecated features
-
fixed: string[]
Fixed bugs
-
removed: string[]
Removed features
-
security: string[]
Security updates
-
version: string
Release version
Detailed result information from release operations including success status, version changes, generated artifacts, and error details.
-
commitCount: number
Number of commits included in release (if successful)
-
error: string
Error message if failed
-
githubReleaseUrl: string
GitHub release URL if created
-
previousVersion: string
Previous version number (if successful)
-
releaseNotes: ReleaseNotes
Release notes generated for this version (if successful)
-
success: boolean
Whether the release was successful
-
templateInfo: { compiled: boolean; compileError?: string; format: TemplateFormat; customTemplate?: boolean; }
Information about template compilation and processing. Useful for debugging template issues.
-
updatedFiles: string[]
Files that were updated during release (if successful)
-
version: string
New version number (if successful)
Comprehensive data object passed to Vento templates during processing. Contains version information, build metadata, release notes, and custom data. Enhanced with computed properties for easier template access.
-
buildDate: string
Build date in ISO format
- buildDateFormatted: string
-
currentYear: number
Helper properties automatically computed during template processing. Provides convenient access to formatted dates, short hashes, etc.
-
environment: string
Build environment (e.g., "production", "development")
-
gitCommit: string
Git commit hash (full or short)
-
metadata: Record<string, unknown>
Merged metadata from releaseNotes.metadata and template dataProviders. Available as individual properties in templates for easier access.
-
project: NagareConfig["project"]
Project information from configuration
-
releaseNotes: ReleaseNotes
Release notes following Keep a Changelog format
- shortCommit: string
-
version: string
Version information (e.g., "1.2.3")
-
versionComponents: { major: number; minor: number; patch: number; prerelease: string | null; }
Automatically parsed from version string during template processing. Includes major, minor, patch numbers and prerelease identifier.
Defines how version files are generated using either built-in templates (TypeScript, JSON, YAML) or custom Vento templates.
-
additionalExports: AdditionalExport[]
Define additional constants, classes, functions, or types to be included in the generated version file. This allows extending the built-in templates with project-specific exports without writing a full custom template.
-
customTemplate: string
When using TemplateFormat.CUSTOM, provide a Vento template string. Template has access to all TemplateData properties and custom filters.
-
extend: { prepend?: string; append?: string; }
Advanced option to prepend or append raw content to the generated file. Useful for adding imports, comments, or complex code that doesn't fit the additionalExports structure.
-
path: string
Path to the version file relative to project root
-
patterns: { [key: string]: RegExp | undefined; version?: RegExp; buildDate?: RegExp; gitCommit?: RegExp; }
Legacy patterns for extracting/updating version info
-
template: TemplateFormat
Template format (typescript, json, yaml, custom)
Type for error code values
Contains pre-configured handlers for:
Default configuration - UPDATED with safer patterns
Standard error codes for common Nagare errors
- CONFIG_INVALID: string
- CONFIG_MISSING_REQUIRED: string
- CONFIG_NOT_FOUND: string
- DEPENDENCY_NOT_FOUND: string
- FILE_HANDLER_NOT_FOUND: string
- FILE_JSON_INVALID: string
- FILE_NOT_FOUND: string
- FILE_PATTERN_NO_MATCH: string
- FILE_UPDATE_FAILED: string
- GITHUB_AUTH_FAILED: string
- GITHUB_CLI_NOT_FOUND: string
- GITHUB_RELEASE_FAILED: string
- GIT_NOT_INITIALIZED: string
- GIT_NO_COMMITS: string
- GIT_REMOTE_ERROR: string
- GIT_TAG_EXISTS: string
- GIT_UNCOMMITTED_CHANGES: string
- GIT_USER_NOT_CONFIGURED: string
- OPERATION_CANCELLED: string
- PERMISSION_DENIED: string
- RELEASE_FAILED: string
- SECURITY_EMPTY_GIT_REF: string
- SECURITY_GIT_TAG_TOO_LONG: string
- SECURITY_INVALID_CLI_ARG_TYPE: string
- SECURITY_INVALID_COMMIT_HASH: string
- SECURITY_INVALID_FILE_PATH: string
- SECURITY_INVALID_GIT_REF: string
- SECURITY_INVALID_GIT_REF_CHARS: string
- SECURITY_INVALID_GIT_REF_PATTERN: string
- SECURITY_INVALID_SEMVER_FORMAT: string
- SECURITY_INVALID_VERSION: string
- SECURITY_NULL_BYTE_INJECTION: string
- SECURITY_PATH_ESCAPE: string
- SECURITY_PATH_TRAVERSAL: string
- SECURITY_SHELL_INJECTION: string
- TEMPLATE_INVALID: string
- TEMPLATE_PROCESSING_FAILED: string
- TEMPLATE_SECURITY_VIOLATION: string
- UNKNOWN_ERROR: string
- VERSION_BUMP_INVALID: string
- VERSION_FILE_NOT_FOUND: string
- VERSION_INVALID_FORMAT: string
- VERSION_NOT_FOUND: string