@modulify/conventional-release 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/plan.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ import { Mode, Options, Package, Range, Scope, ScopePackage, Slice, SliceMode } from '../types/index';
2
+ import { Runtime } from './runtime';
3
+ export type DiscoveredSlice = {
4
+ id: string;
5
+ kind: Slice['kind'];
6
+ mode: SliceMode;
7
+ partition?: string;
8
+ packages: Package[];
9
+ range: Range;
10
+ };
11
+ export type DiscoveredScope = {
12
+ mode: Mode;
13
+ packages: Package[];
14
+ affected: Package[];
15
+ slices: DiscoveredSlice[];
16
+ };
17
+ export declare function toScope(scope: DiscoveredScope, cwd: string): Scope;
18
+ /** Discovers packages, affected scope, and ordered release slices without side effects. */
19
+ export declare function discover(runtime: Runtime, options: Options): Promise<DiscoveredScope>;
20
+ export declare function toScopePackage(pkg: Package, cwd: string): ScopePackage;
21
+ export declare function toSlice(slice: DiscoveredSlice, cwd: string): Slice;
22
+ export declare function uniquePackages(packages: Package[]): Package[];
23
+ export declare function uniqueStrings(values: string[]): string[];
24
+ export declare function packageIdentity(pkg: Package, cwd: string): string;
@@ -0,0 +1,11 @@
1
+ import { Reporter, Result, RunContext, Scope, Slice, SliceResult } from '../types/index';
2
+ export declare function createRunContext({ cwd, dry, }: {
3
+ cwd: string;
4
+ dry: boolean;
5
+ }): RunContext;
6
+ export declare function reportStart(reporter: Reporter | undefined, context: RunContext): Promise<void>;
7
+ export declare function reportScope(reporter: Reporter | undefined, scope: Scope, context: RunContext): Promise<void>;
8
+ export declare function reportSliceStart(reporter: Reporter | undefined, slice: Slice, context: RunContext): Promise<void>;
9
+ export declare function reportSliceSuccess(reporter: Reporter | undefined, slice: SliceResult, context: RunContext): Promise<void>;
10
+ export declare function reportSuccess(reporter: Reporter | undefined, result: Result, context: RunContext): Promise<void>;
11
+ export declare function reportError(reporter: Reporter | undefined, error: unknown, context: RunContext): Promise<void>;
@@ -0,0 +1,36 @@
1
+ import { Client as HistoryClient } from '@modulify/conventional-git';
2
+ export type Shell = {
3
+ exec(command: string, args?: string[]): Promise<unknown>;
4
+ };
5
+ export type Git = {
6
+ add(files: string[]): Promise<unknown>;
7
+ commit(options: {
8
+ files: string[];
9
+ message: string;
10
+ }): Promise<unknown>;
11
+ tag(options: {
12
+ name: string;
13
+ message: string;
14
+ }): Promise<unknown>;
15
+ };
16
+ export type PackageManagerName = 'yarn' | 'pnpm' | 'npm' | 'bun';
17
+ export interface PackageManager {
18
+ command: PackageManagerName;
19
+ lockfile: string;
20
+ }
21
+ export interface Runtime {
22
+ cwd: string;
23
+ dry: boolean;
24
+ changelogFile: string;
25
+ packageManager: PackageManager;
26
+ history: Pick<HistoryClient, 'traverse' | 'url'>;
27
+ writeChangelog(changes: string): Promise<string>;
28
+ sh: Shell;
29
+ git: Git;
30
+ }
31
+ /** Creates the default runtime used by the public planning and release APIs. */
32
+ export declare function createRuntime({ cwd, dry, changelogFile, }?: {
33
+ cwd?: string;
34
+ dry?: boolean;
35
+ changelogFile?: string;
36
+ }): Runtime;
package/package.json ADDED
@@ -0,0 +1,98 @@
1
+ {
2
+ "name": "@modulify/conventional-release",
3
+ "type": "module",
4
+ "version": "0.1.0",
5
+ "license": "ISC",
6
+ "homepage": "https://github.com/modulify/conventional/tree/main/packages/conventional-release#readme",
7
+ "engines": {
8
+ "node": ">=20.0.0"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.cjs",
15
+ "default": "./dist/index.mjs"
16
+ },
17
+ "./types": {
18
+ "types": "./types/index.d.ts",
19
+ "default": "./types/index.d.ts"
20
+ },
21
+ "./types/*": {
22
+ "types": "./types/*.d.ts",
23
+ "default": "./types/*.d.ts"
24
+ }
25
+ },
26
+ "types": "dist/index.d.ts",
27
+ "bin": "./bin/index.js",
28
+ "peerDependencies": {
29
+ "@types/node": ">=20",
30
+ "@types/semver": "^7.7.1"
31
+ },
32
+ "peerDependenciesMeta": {
33
+ "@types/node": {
34
+ "optional": true
35
+ },
36
+ "@types/semver": {
37
+ "optional": true
38
+ }
39
+ },
40
+ "dependencies": {
41
+ "@modulify/conventional-bump": "^0.1.0",
42
+ "@modulify/conventional-changelog": "^0.1.0",
43
+ "@modulify/conventional-git": "^0.1.0",
44
+ "@modulify/git-toolkit": "^0.0.2",
45
+ "@modulify/pkg": "^1.0.1",
46
+ "chalk": "^5.6.2",
47
+ "figures": "^6.1.0",
48
+ "semver": "^7.7.3",
49
+ "yargs": "^17.7.2"
50
+ },
51
+ "devDependencies": {
52
+ "@types/node": "^22.18.6",
53
+ "@types/semver": "^7.7.1",
54
+ "@types/yargs": "^17.0.35",
55
+ "tslib": "^2.8.1",
56
+ "typescript": "^5.9.3",
57
+ "vite": "^7.3.0",
58
+ "vite-plugin-dts": "^4.5.4",
59
+ "vitest": "^4.0.16"
60
+ },
61
+ "author": {
62
+ "name": "modulify",
63
+ "email": "https://github.com/modulify"
64
+ },
65
+ "contributors": [
66
+ {
67
+ "name": "Zaitsev Kirill",
68
+ "email": "zaytsev.cmath10@gmail.com"
69
+ },
70
+ {
71
+ "name": "conventional-changelog team",
72
+ "url": "https://github.com/conventional-changelog"
73
+ }
74
+ ],
75
+ "keywords": [
76
+ "conventional",
77
+ "git",
78
+ "release"
79
+ ],
80
+ "files": [
81
+ "bin/*.cjs",
82
+ "bin/*.js",
83
+ "bin/*.mjs",
84
+ "dist/*.cjs",
85
+ "dist/*.mjs",
86
+ "dist/*.d.ts",
87
+ "types/*.d.ts",
88
+ "LICENSE.md",
89
+ "README.md"
90
+ ],
91
+ "publishConfig": {
92
+ "access": "public"
93
+ },
94
+ "scripts": {
95
+ "build": "node ./scripts/build-cli.mjs --prepare && vite build && node ./scripts/build-cli.mjs",
96
+ "typecheck": "tsc -b tsconfig.typecheck.json"
97
+ }
98
+ }
@@ -0,0 +1,124 @@
1
+ import type { Manifest } from '@modulify/pkg/types/manifest'
2
+
3
+ export type { Manifest }
4
+
5
+ /** Package node discovered in the release scope. */
6
+ export type Package = {
7
+ /** Package name from `package.json` when available. */
8
+ name?: string
9
+ /** Absolute filesystem path to the package root. */
10
+ path: string
11
+ /** Parsed package manifest. */
12
+ manifest: Manifest
13
+ /** Nested workspace packages discovered under this package. */
14
+ children: Package[]
15
+ }
16
+
17
+ /** Release coordination strategy for the selected repository scope. */
18
+ export type Mode = 'sync' | 'async' | 'hybrid'
19
+ /** Execution mode for a single slice. */
20
+ export type SliceMode = 'sync' | 'async'
21
+ /** Semantic kind of slice in the public scope/result model. */
22
+ export type SliceKind = 'sync' | 'async' | 'partition'
23
+
24
+ /** Git advisory range used to calculate the next version for a step. */
25
+ export interface Range {
26
+ /** Explicit lower tag bound for commit analysis. */
27
+ fromTag?: string
28
+ /** Prefix or pattern used to match release tags. */
29
+ tagPrefix?: string | RegExp
30
+ }
31
+
32
+ /** Workspace selection filters applied during package discovery. */
33
+ export type WorkspaceSelector = {
34
+ /** Workspace names or paths to include. */
35
+ include?: string[]
36
+ /** Workspace names or paths to exclude after inclusion. */
37
+ exclude?: string[]
38
+ }
39
+
40
+ /** Named workspace partition participating in hybrid scope discovery. */
41
+ export type Partition = Range & {
42
+ /** Execution mode for workspaces matched by this partition. */
43
+ mode: SliceMode
44
+ /** Workspace selectors belonging to the partition. */
45
+ workspaces: string[]
46
+ }
47
+
48
+ /** Public package descriptor returned from scopes and results. */
49
+ export type ScopePackage = {
50
+ /** Package name from `package.json` when available. */
51
+ name?: string
52
+ /** The current package version when available. */
53
+ version?: string
54
+ /** Package path relative to the release root. */
55
+ path: string
56
+ }
57
+
58
+ /** Single slice in a computed scope. */
59
+ export interface Slice {
60
+ /** Stable identifier for the slice. */
61
+ id: string
62
+ /** High-level semantic kind of the slice. */
63
+ kind: SliceKind
64
+ /** Execution mode used for the slice. */
65
+ mode: SliceMode
66
+ /** Partition name for hybrid partition slices. */
67
+ partition?: string
68
+ /** Packages participating in the slice. */
69
+ packages: ScopePackage[]
70
+ /** Git advisory range used for version calculation. */
71
+ range: Range
72
+ }
73
+
74
+ /** Deterministic release scope produced before side effects are applied. */
75
+ export interface Scope {
76
+ /** Global release mode used for discovery. */
77
+ mode: Mode
78
+ /** All packages in the resolved release scope. */
79
+ packages: ScopePackage[]
80
+ /** Packages affected by the current working tree state. */
81
+ affected: ScopePackage[]
82
+ /** Ordered release slices to execute. */
83
+ slices: Slice[]
84
+ }
85
+
86
+ /** Result of applying a single release slice. */
87
+ export interface SliceResult extends Slice {
88
+ /** Version used as the starting point for the slice. */
89
+ currentVersion: string
90
+ /** Version produced for the slice. */
91
+ nextVersion: string
92
+ /** Semantic release type reported by the advisor. */
93
+ releaseType: string
94
+ /** Whether the slice produced a version change. */
95
+ changed: boolean
96
+ /** Whether the slice ran in dry-run mode. */
97
+ dry: boolean
98
+ /** Files touched or planned for the slice. */
99
+ files: string[]
100
+ /** Tag created or planned for the slice. */
101
+ tag?: string
102
+ /** Commit message created or planned for the slice. */
103
+ commitMessage?: string
104
+ /** Annotated tag message created or planned for the slice. */
105
+ tagMessage?: string
106
+ }
107
+
108
+ /** Aggregated result of executing all release slices. */
109
+ export interface Result {
110
+ /** Global release mode used for execution. */
111
+ mode: Mode
112
+ /** Whether at least one slice produced a version change. */
113
+ changed: boolean
114
+ /** Whether the release ran in dry-run mode. */
115
+ dry: boolean
116
+ /** All packages in the resolved release scope. */
117
+ packages: ScopePackage[]
118
+ /** Packages affected by the current working tree state. */
119
+ affected: ScopePackage[]
120
+ /** Per-slice execution results. */
121
+ slices: SliceResult[]
122
+ /** Union of files touched across all changed slices. */
123
+ files: string[]
124
+ }
@@ -0,0 +1,23 @@
1
+ export type {
2
+ Mode,
3
+ Partition,
4
+ Package,
5
+ Scope,
6
+ ScopePackage,
7
+ Range,
8
+ Result,
9
+ Slice,
10
+ SliceKind,
11
+ SliceMode,
12
+ SliceResult,
13
+ WorkspaceSelector,
14
+ Manifest,
15
+ } from './domain'
16
+
17
+ export type {
18
+ Options,
19
+ Reporter,
20
+ RunContext,
21
+ RunOptions,
22
+ TagContext,
23
+ } from './release'
@@ -0,0 +1,93 @@
1
+ import type { ReleaseType as SemverReleaseType } from 'semver'
2
+
3
+ import type {
4
+ Partition,
5
+ Mode,
6
+ Result,
7
+ Scope,
8
+ ScopePackage,
9
+ Range,
10
+ Slice,
11
+ SliceKind,
12
+ SliceMode,
13
+ SliceResult,
14
+ WorkspaceSelector,
15
+ } from './domain'
16
+
17
+ /** Context object passed to tag and message formatters. */
18
+ export interface TagContext {
19
+ /** Stable identifier of the current release slice. */
20
+ id: string
21
+ /** Semantic kind of the current slice. */
22
+ kind: SliceKind
23
+ /** Execution mode of the current slice. */
24
+ mode: SliceMode
25
+ /** Partition name for hybrid partition slices. */
26
+ partition?: string
27
+ /** Packages participating in the current slice. */
28
+ packages: ScopePackage[]
29
+ /** Semantic release type produced by the advisor. */
30
+ releaseType: string
31
+ /** Version produced for the current slice. */
32
+ version: string
33
+ }
34
+
35
+ /** Invocation context passed to reporter hooks. */
36
+ export interface RunContext {
37
+ /** Working directory used as the release root. */
38
+ cwd: string
39
+ /** Whether side effects are skipped. */
40
+ dry: boolean
41
+ }
42
+
43
+ /** Lifecycle reporter used during `run(...)` execution. */
44
+ export interface Reporter {
45
+ /** Called before config resolution and scope discovery begin. */
46
+ onStart?(context: RunContext): void | Promise<void>
47
+ /** Called after the public scope has been resolved. */
48
+ onScope?(scope: Scope, context: RunContext): void | Promise<void>
49
+ /** Called before a slice starts execution. */
50
+ onSliceStart?(slice: Slice, context: RunContext): void | Promise<void>
51
+ /** Called after a slice has completed execution. */
52
+ onSliceSuccess?(slice: SliceResult, context: RunContext): void | Promise<void>
53
+ /** Called after the full release has completed successfully. */
54
+ onSuccess?(result: Result, context: RunContext): void | Promise<void>
55
+ /** Called when `run(...)` exits with an error. */
56
+ onError?(error: unknown, context: RunContext): void | Promise<void>
57
+ }
58
+
59
+ /** High-level options accepted by the release planner and executor. */
60
+ export interface Options extends Range {
61
+ /** Global release strategy for the selected repository scope. */
62
+ mode?: Mode
63
+ /** Explicit semantic release type override. */
64
+ releaseAs?: SemverReleaseType
65
+ /** Prerelease channel used when generating prerelease versions. */
66
+ prerelease?: 'alpha' | 'beta' | 'rc'
67
+ /** Whether dependency installation should run after manifest updates, or extra arguments appended after the installation subcommand. */
68
+ install?: boolean | string[]
69
+ /** Workspace discovery filters. */
70
+ workspaces?: WorkspaceSelector
71
+ /** Named hybrid partitions for mixed sync/async discovery. */
72
+ partitions?: Record<string, Partition>
73
+ /** Range style applied to bumped internal dependencies. */
74
+ dependencyPolicy?: 'preserve' | 'caret' | 'exact'
75
+ /** Custom tag name formatter. */
76
+ tagName?: (context: TagContext) => string
77
+ /** Custom annotated tag message formatter. */
78
+ tagMessage?: (context: TagContext & { tag: string; }) => string
79
+ /** Custom commit message formatter. */
80
+ commitMessage?: (context: TagContext & { tag: string; }) => string
81
+ /** Changelog file path relative to the repository root. */
82
+ changelogFile?: string
83
+ }
84
+
85
+ /** High-level options accepted by the public planning and execution APIs. */
86
+ export interface RunOptions extends Options {
87
+ /** Working directory used as the release root. */
88
+ cwd?: string
89
+ /** Whether side effects should be skipped. */
90
+ dry?: boolean
91
+ /** Optional lifecycle reporter for run-time progress and summaries. */
92
+ reporter?: Reporter
93
+ }