or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

changelog-generation.mdconfiguration.mdgit-operations.mdgithub-integration.mdindex.mdrepository-analysis.mdversion-management.md
tile.json

version-management.mddocs/

Version Management

Semantic version analysis and automated package.json version bumping based on conventional commit types. This module provides intelligent version calculation and package management integration for automated release workflows.

Capabilities

Determine Semver Change

Analyzes conventional commits to determine the appropriate semantic version bump type.

/**
 * Determine semantic version change from conventional commits
 * @param commits - Array of parsed conventional commits
 * @param config - Changelog configuration with type semver mappings
 * @returns Semver bump type or null if no version change needed
 */
function determineSemverChange(
  commits: GitCommit[],
  config: ChangelogConfig
): SemverBumpType | null;

Usage Examples:

import { 
  determineSemverChange, 
  parseCommits, 
  loadChangelogConfig 
} from "changelogen";

const config = await loadChangelogConfig(process.cwd());
const commits = parseCommits(rawCommits, config);

// Analyze commits for version change
const bumpType = determineSemverChange(commits, config);

switch (bumpType) {
  case "major":
    console.log("Breaking changes detected - major version bump required");
    break;
  case "minor":
    console.log("New features detected - minor version bump required");
    break;
  case "patch":
    console.log("Bug fixes detected - patch version bump required");
    break;
  case null:
    console.log("No version bump needed");
    break;
}

Bump Version

Automatically bumps the version in package.json based on conventional commits or explicit options.

/**
 * Bump package version based on commits or explicit options
 * @param commits - Array of parsed conventional commits
 * @param config - Changelog configuration
 * @param opts - Optional version bump options
 * @returns New version string or false if no bump needed
 */
function bumpVersion(
  commits: GitCommit[],
  config: ChangelogConfig,
  opts?: BumpVersionOptions
): Promise<string | false>;

Usage Examples:

import { bumpVersion, parseCommits, loadChangelogConfig } from "changelogen";

const config = await loadChangelogConfig(process.cwd());
const commits = parseCommits(rawCommits, config);

// Automatic version bump based on commits
const newVersion = await bumpVersion(commits, config);
if (newVersion) {
  console.log(`Version bumped to ${newVersion}`);
}

// Explicit version bump
const majorBump = await bumpVersion(commits, config, { type: "major" });

// Prerelease version bump
const prereleaseVersion = await bumpVersion(commits, config, {
  type: "prerelease",
  preid: "beta"
});

// Version with custom suffix
const canaryVersion = await bumpVersion(commits, config, {
  suffix: true  // Uses date + commit hash
});

// Version with specific suffix
const customVersion = await bumpVersion(commits, config, {
  suffix: "rc.1"
});

Version Bump Types

type SemverBumpType =
  | "major"      // 1.0.0 -> 2.0.0
  | "premajor"   // 1.0.0 -> 2.0.0-0
  | "minor"      // 1.0.0 -> 1.1.0
  | "preminor"   // 1.0.0 -> 1.1.0-0
  | "patch"      // 1.0.0 -> 1.0.1
  | "prepatch"   // 1.0.0 -> 1.0.1-0
  | "prerelease"; // 1.0.0-0 -> 1.0.0-1

Version Bump Options

interface BumpVersionOptions {
  /** Explicit version bump type */
  type?: SemverBumpType;
  
  /** Prerelease identifier (e.g., "alpha", "beta", "rc") */
  preid?: string;
  
  /** Add suffix to version (true for auto-generated, string for custom) */
  suffix?: boolean | string;
}

Semantic Version Rules

Commit Type Mapping

Default semver mappings for conventional commit types:

const defaultTypeMappings = {
  feat: "minor",      // New features
  perf: "patch",      // Performance improvements
  fix: "patch",       // Bug fixes
  refactor: "patch",  // Code refactoring
  docs: "patch",      // Documentation changes
  build: "patch",     // Build system changes
  types: "patch",     // Type definition changes
  // chore, examples, test, style, ci: no version bump
};

Breaking Change Detection

Breaking changes trigger major version bumps:

  • Commits with ! after type/scope: feat!: breaking change
  • Commits with BREAKING CHANGE: in commit body
  • Always results in major bump (or minor for 0.x.x versions)

Pre-1.0 Version Handling

Special handling for pre-1.0 versions following semantic versioning conventions:

  • 0.x.y versions: major changes become minor, minor changes become patch
  • 0.0.x versions: all changes become patch
  • Breaking changes in 0.x.y increment minor version instead of major

Examples:

// Normal versioning (1.x.x)
"1.2.3" + major = "2.0.0"
"1.2.3" + minor = "1.3.0"
"1.2.3" + patch = "1.2.4"

// Pre-1.0 versioning (0.x.y)
"0.2.3" + major = "0.3.0"  // Breaking changes increment minor
"0.2.3" + minor = "0.2.4"  // New features increment patch
"0.2.3" + patch = "0.2.4"

// Pre-0.1 versioning (0.0.x)
"0.0.3" + major = "0.0.4"  // All changes increment patch
"0.0.3" + minor = "0.0.4"
"0.0.3" + patch = "0.0.4"

Package.json Integration

Read Package JSON

/**
 * Read package.json from the configured directory
 * @param config - Changelog configuration with cwd
 * @returns Promise resolving to PackageJson object
 */
function readPackageJSON(config: ChangelogConfig): Promise<PackageJson>;

Write Package JSON

/**
 * Write updated package.json to the configured directory
 * @param config - Changelog configuration with cwd
 * @param pkg - Updated PackageJson object
 * @returns Promise resolving when write completes
 */
function writePackageJSON(
  config: ChangelogConfig, 
  pkg: PackageJson
): Promise<void>;

Package Renaming

/**
 * Rename package in package.json (useful for canary releases)
 * @param config - Changelog configuration
 * @param newName - New package name (or suffix starting with -)
 * @returns Promise resolving when rename completes
 */
function renamePackage(
  config: ChangelogConfig, 
  newName: string
): Promise<void>;

Usage Examples:

import { renamePackage, readPackageJSON } from "changelogen";

// Add suffix to existing name
await renamePackage(config, "-canary");  // "mypackage" -> "mypackage-canary"

// Set explicit new name
await renamePackage(config, "mypackage-beta");

// Read current package info
const pkg = await readPackageJSON(config);
console.log(`Current version: ${pkg.version}`);

Version Suffix Generation

Automatic Suffix

When suffix: true is specified, generates timestamp + commit hash suffix:

// Format: YYMMDD-HHMMSS-{shortHash}
// Example: "1.2.3-240919-140954-abc123"

Custom Suffix

When suffix: string is specified, uses the provided string:

await bumpVersion(commits, config, { suffix: "rc.1" });
// Result: "1.2.3-rc.1"

await bumpVersion(commits, config, { suffix: "beta.2" });
// Result: "1.2.3-beta.2"

Integration with Release Workflow

Version management integrates seamlessly with other changelogen features:

import { 
  loadChangelogConfig,
  getGitDiff,
  parseCommits,
  bumpVersion,
  generateMarkDown
} from "changelogen";

// Complete release workflow
const config = await loadChangelogConfig(process.cwd());
const rawCommits = await getGitDiff(config.from, config.to);
const commits = parseCommits(rawCommits, config);

// Bump version
const newVersion = await bumpVersion(commits, config);
if (newVersion) {
  config.newVersion = newVersion;
  
  // Generate changelog with new version
  const markdown = await generateMarkDown(commits, config);
  console.log(`Release ${newVersion}:\n${markdown}`);
}

Error Handling

Version management handles various error conditions:

  • Missing package.json: Throws descriptive error
  • Invalid current version: Falls back to "0.0.0"
  • No version change needed: Returns false
  • File write permissions: Propagates filesystem errors
  • Invalid semver operations: Handled by underlying semver library