Git-aware functionality for reading repository metadata, parsing commits, handling various repository structures including monorepos, and integrating with different hosting platforms.
type HostType = 'github' | 'gitlab' | 'bitbucket' | 'sourcehut' | '';
interface HostedGitInfo {
url: string;
type: HostType;
host: string;
owner?: string;
project?: string;
}
interface HostOptions {
issue: string;
commit: string;
referenceActions: string[];
issuePrefixes: string[];
}
interface Context {
version?: string;
previousTag?: string;
currentTag?: string;
host?: string;
owner?: string;
repository?: string;
repoUrl?: string;
[key: string]: any;
}
interface Commit {
hash?: string;
date?: string;
message?: string;
subject?: string;
body?: string;
type?: string;
scope?: string;
notes?: Array<{ title: string; text: string }>;
references?: Array<{ issue: string; action: string }>;
gitTags?: string;
committerDate?: string;
}
interface Params {
commits: GetCommitsParams;
options: Options;
context?: Context;
repository?: Partial<HostedGitInfo> | null;
package?: Package;
}
type Logger = (source: string, messages: string | string[]) => void;
interface GetCommitsParams {
from?: string;
to?: string;
path?: string;
format?: string;
merges?: boolean;
reverse?: boolean;
}
interface Options {
reset?: boolean;
append?: boolean;
releaseCount?: number;
outputUnreleased?: boolean;
transformCommit?: CommitTransformFunction;
warn?: Logger;
debug?: Logger;
formatDate?(date: string | Date): string;
}
interface Package {
name?: string;
version?: string;
description?: string;
repository?: {
type?: string;
url?: string;
};
[key: string]: any;
}
type CommitTransformFunction = (
commit: Commit,
params: Params
) => Partial<Commit> | null | Promise<Partial<Commit> | null>;Parse git repository URLs and extract hosting platform information.
/**
* Parse various git URL formats and extract repository information
* @param input - Git URL in various formats (HTTPS, SSH, shorthand)
* @returns Parsed repository information or null if invalid
*/
function parseHostedGitUrl(input: string): HostedGitInfo | null;
interface HostedGitInfo {
/** Full repository URL */
url: string;
/** Hosting platform type */
type: HostType;
/** Host base URL */
host: string;
/** Repository owner/organization */
owner?: string;
/** Repository/project name */
project?: string;
}
type HostType = 'github' | 'gitlab' | 'bitbucket' | 'sourcehut' | '';URL Parsing Examples:
import { parseHostedGitUrl } from "conventional-changelog";
// HTTPS URLs
parseHostedGitUrl('https://github.com/user/repo.git');
// Result: { url: 'https://github.com/user/repo', type: 'github', host: 'https://github.com', owner: 'user', project: 'repo' }
// SSH URLs
parseHostedGitUrl('git@github.com:user/repo.git');
// Result: { url: 'https://github.com/user/repo', type: 'github', host: 'https://github.com', owner: 'user', project: 'repo' }
// Shorthand format
parseHostedGitUrl('user/repo');
// Result: { url: 'https://github.com/user/repo', type: 'github', host: 'https://github.com', owner: 'user', project: 'repo' }
// GitLab
parseHostedGitUrl('https://gitlab.com/group/project.git');
// Result: { url: 'https://gitlab.com/group/project', type: 'gitlab', host: 'https://gitlab.com', owner: 'group', project: 'project' }
// Bitbucket
parseHostedGitUrl('https://bitbucket.org/user/repo.git');
// Result: { url: 'https://bitbucket.org/user/repo', type: 'bitbucket', host: 'https://bitbucket.org', owner: 'user', project: 'repo' }Configure changelog generation with repository information.
// Using ConventionalChangelog methods
class ConventionalChangelog {
/**
* Read repository information from git configuration
*/
readRepository(): this;
/**
* Set repository information manually
* @param infoOrGitUrl - Repository info object or git URL string
*/
repository(infoOrGitUrl: string | Partial<HostedGitInfo>): this;
}Repository Configuration Examples:
import { ConventionalChangelog } from "conventional-changelog";
// Automatically read from git configuration
const changelog = new ConventionalChangelog()
.readRepository(); // Reads from 'git config remote.origin.url'
// Set repository URL manually
changelog.repository('https://github.com/my-org/my-repo.git');
// Set repository info object manually
changelog.repository({
type: 'github',
host: 'https://github.com',
owner: 'my-org',
project: 'my-repo',
url: 'https://github.com/my-org/my-repo'
});Platform-specific configurations for different git hosting services.
interface HostOptions {
/** URL pattern for issues */
issue: string;
/** URL pattern for commits */
commit: string;
/** Keywords that reference/close issues in commit messages */
referenceActions: string[];
/** Prefixes for issue references */
issuePrefixes: string[];
}
/**
* Get host-specific options based on repository and context
* @param repository - Repository information
* @param context - Writer context
* @returns Host options or null if unsupported
*/
function getHostOptions(
repository: Partial<HostedGitInfo> | null | undefined,
context: Context | null | undefined
): HostOptions | null;Host Platform Configurations:
// GitHub configuration
const github: HostOptions = {
issue: 'issues',
commit: 'commit',
referenceActions: [
'close', 'closes', 'closed',
'fix', 'fixes', 'fixed',
'resolve', 'resolves', 'resolved'
],
issuePrefixes: ['#', 'gh-']
};
// GitLab configuration
const gitlab: HostOptions = {
issue: 'issues',
commit: 'commit',
referenceActions: [
'close', 'closes', 'closed',
'fix', 'fixes', 'fixed',
'resolve', 'resolves', 'resolved'
],
issuePrefixes: ['#']
};
// Bitbucket configuration
const bitbucket: HostOptions = {
issue: 'issues',
commit: 'commits',
referenceActions: [
'close', 'closes', 'closed',
'fix', 'fixes', 'fixed',
'resolve', 'resolves', 'resolved'
],
issuePrefixes: ['#']
};Utilities for working with git tags and version formatting.
/**
* Guess the next tag format based on previous tag pattern
* @param previousTag - The previous git tag
* @param version - The new version string
* @returns Formatted tag string
*/
function guessNextTag(previousTag: string, version?: string): string;
/**
* Check if a version is unreleased (matches the latest tag)
* @param semverTags - Array of semver tags in descending order
* @param version - Version to check
* @returns True if version is unreleased
*/
function isUnreleasedVersion(semverTags: string[], version: string | undefined): boolean;
// Regular expressions for parsing version tags
const versionTagRegex: RegExp; // /tag:\s*(.*)[,)]/i
const defaultVersionRegex: RegExp; // /tag:\s*[v=]?(.*)[,)]/iTag Handling Examples:
import { guessNextTag, isUnreleasedVersion } from "conventional-changelog";
// Tag format guessing
guessNextTag('v1.0.0', '1.1.0'); // Returns 'v1.1.0'
guessNextTag('1.0.0', '1.1.0'); // Returns '1.1.0'
guessNextTag('release-1.0.0', '1.1.0'); // Returns '1.1.0'
// Unreleased version checking
const tags = ['v1.2.0', 'v1.1.0', 'v1.0.0'];
isUnreleasedVersion(tags, '1.2.0'); // Returns true
isUnreleasedVersion(tags, '1.3.0'); // Returns falseAdvanced commit transformation and filtering for git integration.
/**
* Default commit transformation function
* @param commit - Raw commit data
* @param params - Generation parameters
* @returns Transformed commit data
*/
function defaultCommitTransform(commit: Commit, params: Params): Partial<Commit>;
/**
* Bind logger to specific namespace
* @param namespace - Logging namespace
* @param log - Logger function
* @returns Namespaced logger
*/
function bindLogNamespace(namespace: string, log: Logger): (messages: string | string[]) => void;Commit Processing Examples:
// Custom commit transformation with git tag parsing
const customTransform = (commit, params) => {
const transformed = defaultCommitTransform(commit, params);
// Additional custom processing
if (commit.gitTags) {
// Extract version from git tags
const versionMatch = commit.gitTags.match(/tag:\s*v?([^,)]+)/);
if (versionMatch) {
transformed.version = versionMatch[1];
}
}
return transformed;
};
changelog.options({ transformCommit: customTransform });Advanced patterns for working with monorepo structures.
// Lerna-style monorepo configuration
const lernaPackage = '@my-org/my-package';
changelog.tags({
prefix: `${lernaPackage}@` // Tags like '@my-org/my-package@1.0.0'
});
// Scope commits to specific package directory
changelog.commits({
path: `packages/${packageName}/`
});
// Package-specific configuration
changelog.readPackage(`packages/${packageName}/package.json`);Integration with writer context for URL generation and linking.
// Context integration with repository information
changelog.context({
host: 'https://github.com',
owner: 'my-org',
repository: 'my-repo',
repoUrl: 'https://github.com/my-org/my-repo',
issue: 'issues', // From host options
commit: 'commit', // From host options
linkCompare: true // Enable comparison links
});// Handle repositories without origin remote
try {
changelog.readRepository();
} catch (error) {
console.warn('No remote origin found, using manual repository config');
changelog.repository('https://github.com/fallback/repo.git');
}
// Handle unsupported hosts
changelog.options({
warn: (source, message) => {
if (message.includes('Host is not supported')) {
console.warn('Using generic host configuration');
}
}
});
// Handle parsing failures
const repoInfo = parseHostedGitUrl(urlInput);
if (!repoInfo) {
console.error('Unable to parse repository URL:', urlInput);
// Fallback to manual configuration
}