@fuzdev/fuz_gitops 0.71.0 → 0.73.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/README.md +13 -6
- package/dist/changeset_generator.d.ts.map +1 -1
- package/dist/changeset_generator.js +2 -16
- package/dist/changeset_reader.d.ts +1 -1
- package/dist/changeset_reader.d.ts.map +1 -1
- package/dist/dependency_graph.js +1 -1
- package/dist/git_operations.d.ts +5 -0
- package/dist/git_operations.d.ts.map +1 -1
- package/dist/git_operations.js +5 -0
- package/dist/gitops_analyze.task.d.ts +1 -0
- package/dist/gitops_analyze.task.d.ts.map +1 -1
- package/dist/gitops_analyze.task.js +12 -17
- package/dist/gitops_plan.task.d.ts +1 -0
- package/dist/gitops_plan.task.d.ts.map +1 -1
- package/dist/gitops_plan.task.js +9 -2
- package/dist/gitops_publish.task.d.ts +3 -2
- package/dist/gitops_publish.task.d.ts.map +1 -1
- package/dist/gitops_publish.task.js +90 -26
- package/dist/gitops_run.task.d.ts +2 -1
- package/dist/gitops_run.task.d.ts.map +1 -1
- package/dist/gitops_run.task.js +40 -7
- package/dist/gitops_sync.task.d.ts +1 -0
- package/dist/gitops_sync.task.d.ts.map +1 -1
- package/dist/gitops_sync.task.js +16 -2
- package/dist/gitops_task_helpers.d.ts +16 -2
- package/dist/gitops_task_helpers.d.ts.map +1 -1
- package/dist/gitops_task_helpers.js +11 -3
- package/dist/gitops_validate.task.d.ts +1 -0
- package/dist/gitops_validate.task.d.ts.map +1 -1
- package/dist/gitops_validate.task.js +20 -20
- package/dist/graph_validation.d.ts +16 -1
- package/dist/graph_validation.d.ts.map +1 -1
- package/dist/graph_validation.js +15 -0
- package/dist/local_repo.d.ts +22 -10
- package/dist/local_repo.d.ts.map +1 -1
- package/dist/local_repo.js +92 -75
- package/dist/log_helpers.d.ts +0 -5
- package/dist/log_helpers.d.ts.map +1 -1
- package/dist/log_helpers.js +8 -19
- package/dist/multi_repo_publisher.d.ts +29 -2
- package/dist/multi_repo_publisher.d.ts.map +1 -1
- package/dist/multi_repo_publisher.js +307 -233
- package/dist/operations.d.ts +6 -26
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations_defaults.d.ts.map +1 -1
- package/dist/operations_defaults.js +1 -19
- package/dist/output_helpers.d.ts.map +1 -1
- package/dist/output_helpers.js +7 -6
- package/dist/paths.d.ts +0 -4
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +0 -4
- package/dist/publish_gate.d.ts +44 -0
- package/dist/publish_gate.d.ts.map +1 -0
- package/dist/publish_gate.js +32 -0
- package/dist/publish_steps.d.ts +60 -0
- package/dist/publish_steps.d.ts.map +1 -0
- package/dist/publish_steps.js +113 -0
- package/dist/publishing_event.d.ts +123 -0
- package/dist/publishing_event.d.ts.map +1 -0
- package/dist/publishing_event.js +140 -0
- package/dist/publishing_event_handler.d.ts +42 -0
- package/dist/publishing_event_handler.d.ts.map +1 -0
- package/dist/publishing_event_handler.js +75 -0
- package/dist/publishing_plan.d.ts +1 -2
- package/dist/publishing_plan.d.ts.map +1 -1
- package/dist/publishing_plan.js +18 -1
- package/dist/publishing_plan_helpers.d.ts +1 -1
- package/dist/publishing_plan_helpers.d.ts.map +1 -1
- package/dist/publishing_plan_helpers.js +2 -15
- package/dist/publishing_plan_logging.d.ts.map +1 -1
- package/dist/publishing_plan_logging.js +15 -23
- package/dist/repo_ops.d.ts +1 -1
- package/dist/repo_ops.js +1 -1
- package/dist/version_utils.d.ts +17 -3
- package/dist/version_utils.d.ts.map +1 -1
- package/dist/version_utils.js +22 -0
- package/package.json +6 -7
- package/src/lib/changeset_generator.ts +10 -19
- package/src/lib/changeset_reader.ts +1 -2
- package/src/lib/dependency_graph.ts +1 -1
- package/src/lib/git_operations.ts +5 -0
- package/src/lib/gitops_analyze.task.ts +18 -23
- package/src/lib/gitops_plan.task.ts +10 -2
- package/src/lib/gitops_publish.task.ts +100 -25
- package/src/lib/gitops_run.task.ts +39 -7
- package/src/lib/gitops_sync.task.ts +18 -3
- package/src/lib/gitops_task_helpers.ts +20 -3
- package/src/lib/gitops_validate.task.ts +30 -22
- package/src/lib/graph_validation.ts +26 -0
- package/src/lib/local_repo.ts +114 -83
- package/src/lib/log_helpers.ts +8 -26
- package/src/lib/multi_repo_publisher.ts +387 -269
- package/src/lib/operations.ts +6 -22
- package/src/lib/operations_defaults.ts +1 -19
- package/src/lib/output_helpers.ts +7 -6
- package/src/lib/paths.ts +0 -5
- package/src/lib/publish_gate.ts +53 -0
- package/src/lib/publish_steps.ts +149 -0
- package/src/lib/publishing_event.ts +151 -0
- package/src/lib/publishing_event_handler.ts +98 -0
- package/src/lib/publishing_plan.ts +23 -3
- package/src/lib/publishing_plan_helpers.ts +5 -18
- package/src/lib/publishing_plan_logging.ts +19 -39
- package/src/lib/repo_ops.ts +1 -1
- package/src/lib/version_utils.ts +30 -9
- package/dist/npm_install_helpers.d.ts +0 -23
- package/dist/npm_install_helpers.d.ts.map +0 -1
- package/dist/npm_install_helpers.js +0 -60
- package/dist/semver.d.ts +0 -26
- package/dist/semver.d.ts.map +0 -1
- package/dist/semver.js +0 -137
- package/dist/serialization_types.d.ts +0 -59
- package/dist/serialization_types.d.ts.map +0 -1
- package/dist/serialization_types.js +0 -42
- package/src/lib/npm_install_helpers.ts +0 -85
- package/src/lib/semver.ts +0 -170
- package/src/lib/serialization_types.ts +0 -92
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured events for multi-repo publishing.
|
|
3
|
+
*
|
|
4
|
+
* Publishing emits a stream of tagged events alongside its human-readable logging,
|
|
5
|
+
* so machine consumers (CI, dashboards) can follow a run step by step. Every run
|
|
6
|
+
* opens with a `run_started` event carrying `wetrun`: when `false`, the run is a dry
|
|
7
|
+
* run and every `package_completed` is a prediction (its `commit` is `'simulated'`)
|
|
8
|
+
* rather than an applied change. A run's `run_finished` summary is derived from the
|
|
9
|
+
* same event list via `summarize_events`, so the stream and the summary never drift.
|
|
10
|
+
*
|
|
11
|
+
* Events are consumed through a `PublishingEventHandler` sink (see
|
|
12
|
+
* `publishing_event_handler.ts`).
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
/**
|
|
18
|
+
* Coarse triage classification for a failed package. Lets consumers branch on
|
|
19
|
+
* failure kind without parsing the message.
|
|
20
|
+
*/
|
|
21
|
+
export const PublishingErrorCode = z.enum([
|
|
22
|
+
'publish',
|
|
23
|
+
'network',
|
|
24
|
+
'auth',
|
|
25
|
+
'dependency',
|
|
26
|
+
'build',
|
|
27
|
+
// the real published version diverged from the frozen plan's prediction — an
|
|
28
|
+
// invariant violation, distinct from an ordinary publish failure (see fail-loud
|
|
29
|
+
// drift detection in `multi_repo_publisher.ts`)
|
|
30
|
+
'drift',
|
|
31
|
+
'other',
|
|
32
|
+
]);
|
|
33
|
+
/** Tallied outcome of a publishing run, derived from its events via `summarize_events`. */
|
|
34
|
+
export const PublishingRunSummary = z.strictObject({
|
|
35
|
+
total: z.number().meta({ description: 'packages in the publishing order (the candidate set)' }),
|
|
36
|
+
published: z.number().meta({ description: 'packages published (or, in a dry run, predicted)' }),
|
|
37
|
+
failed: z.number(),
|
|
38
|
+
skipped: z.number(),
|
|
39
|
+
duration: z.number().meta({ description: 'wall-clock duration in milliseconds' }),
|
|
40
|
+
});
|
|
41
|
+
/**
|
|
42
|
+
* A single structured event emitted during a publishing run. Tagged on `event` so the
|
|
43
|
+
* union serializes as one self-describing JSON object per event (JSON-lines on the wire).
|
|
44
|
+
*/
|
|
45
|
+
export const PublishingEvent = z.discriminatedUnion('event', [
|
|
46
|
+
z.strictObject({
|
|
47
|
+
event: z.literal('run_started'),
|
|
48
|
+
wetrun: z.boolean().meta({ description: 'false means every package_completed is a prediction' }),
|
|
49
|
+
total: z.number(),
|
|
50
|
+
}),
|
|
51
|
+
z.strictObject({
|
|
52
|
+
event: z.literal('package_skipped'),
|
|
53
|
+
name: z.string(),
|
|
54
|
+
reason: z.string(),
|
|
55
|
+
}),
|
|
56
|
+
z.strictObject({
|
|
57
|
+
event: z.literal('package_completed'),
|
|
58
|
+
name: z.string(),
|
|
59
|
+
old_version: z.string(),
|
|
60
|
+
new_version: z.string(),
|
|
61
|
+
// mirrors `BumpType` from `version_utils.ts`; inline so the event schema is self-contained
|
|
62
|
+
bump_type: z.enum(['major', 'minor', 'patch']),
|
|
63
|
+
breaking: z.boolean(),
|
|
64
|
+
commit: z.string().meta({ description: "'simulated' in a dry run, otherwise the commit hash" }),
|
|
65
|
+
tag: z.string(),
|
|
66
|
+
}),
|
|
67
|
+
z.strictObject({
|
|
68
|
+
event: z.literal('npm_waited'),
|
|
69
|
+
name: z.string(),
|
|
70
|
+
version: z.string().meta({ description: 'the version waited on after publishing' }),
|
|
71
|
+
}),
|
|
72
|
+
z.strictObject({
|
|
73
|
+
event: z.literal('package_failed'),
|
|
74
|
+
name: z.string(),
|
|
75
|
+
error: z.string(),
|
|
76
|
+
code: PublishingErrorCode,
|
|
77
|
+
}),
|
|
78
|
+
z.strictObject({
|
|
79
|
+
event: z.literal('dependency_updated'),
|
|
80
|
+
dependent: z.string(),
|
|
81
|
+
dependency: z.string(),
|
|
82
|
+
version: z.string(),
|
|
83
|
+
// 'prod'/'peer' updates run inline in the publish pass; 'dev' updates run in the later
|
|
84
|
+
// dev-dependency pass. Lets a consumer reconstruct which side-effect phase this is.
|
|
85
|
+
dep_type: z.enum(['prod', 'peer', 'dev']),
|
|
86
|
+
// true when the update creates an auto-changeset (a publishable dependent republishes);
|
|
87
|
+
// false for dev-dep updates and update-only leaves (private dependents never publish).
|
|
88
|
+
creates_changeset: z.boolean(),
|
|
89
|
+
}),
|
|
90
|
+
z.strictObject({
|
|
91
|
+
event: z.literal('deploy_started'),
|
|
92
|
+
name: z.string(),
|
|
93
|
+
}),
|
|
94
|
+
z.strictObject({
|
|
95
|
+
event: z.literal('deploy_completed'),
|
|
96
|
+
name: z.string(),
|
|
97
|
+
}),
|
|
98
|
+
z.strictObject({
|
|
99
|
+
event: z.literal('deploy_failed'),
|
|
100
|
+
name: z.string(),
|
|
101
|
+
error: z.string(),
|
|
102
|
+
}),
|
|
103
|
+
z.strictObject({
|
|
104
|
+
event: z.literal('run_finished'),
|
|
105
|
+
summary: PublishingRunSummary,
|
|
106
|
+
}),
|
|
107
|
+
]);
|
|
108
|
+
/**
|
|
109
|
+
* Derives a run summary from the captured event list — the single canonical path from
|
|
110
|
+
* events to summary, so the `run_finished` summary always agrees with the stream.
|
|
111
|
+
* Call before emitting `run_finished` (which is not itself counted).
|
|
112
|
+
*
|
|
113
|
+
* @param events - the events captured so far this run
|
|
114
|
+
* @param duration - wall-clock duration in milliseconds
|
|
115
|
+
*/
|
|
116
|
+
export const summarize_events = (events, duration) => {
|
|
117
|
+
let total = 0;
|
|
118
|
+
let published = 0;
|
|
119
|
+
let failed = 0;
|
|
120
|
+
let skipped = 0;
|
|
121
|
+
for (const event of events) {
|
|
122
|
+
switch (event.event) {
|
|
123
|
+
case 'run_started':
|
|
124
|
+
total = event.total;
|
|
125
|
+
break;
|
|
126
|
+
case 'package_completed':
|
|
127
|
+
published++;
|
|
128
|
+
break;
|
|
129
|
+
case 'package_failed':
|
|
130
|
+
failed++;
|
|
131
|
+
break;
|
|
132
|
+
case 'package_skipped':
|
|
133
|
+
skipped++;
|
|
134
|
+
break;
|
|
135
|
+
default:
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return { total, published, failed, skipped, duration };
|
|
140
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composable sinks for the publishing event stream.
|
|
3
|
+
*
|
|
4
|
+
* A `PublishingEventHandler` is anything that can receive a `PublishingEvent`. Handlers
|
|
5
|
+
* compose: `multi_handler` fans out, `masking_handler` redacts secrets then forwards.
|
|
6
|
+
* Emission is best-effort and synchronous — an observability sink must never fail or
|
|
7
|
+
* slow a run. The default sink is `null_handler` (drops everything).
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import type { PublishingEvent } from './publishing_event.js';
|
|
12
|
+
/** A sink for publishing events. */
|
|
13
|
+
export interface PublishingEventHandler {
|
|
14
|
+
emit: (event: PublishingEvent) => void;
|
|
15
|
+
}
|
|
16
|
+
/** A `capture_handler` also exposes the events it has collected. */
|
|
17
|
+
export interface CapturingEventHandler extends PublishingEventHandler {
|
|
18
|
+
readonly events: Array<PublishingEvent>;
|
|
19
|
+
}
|
|
20
|
+
/** Drops every event. The default when no handler is supplied. */
|
|
21
|
+
export declare const null_handler: () => PublishingEventHandler;
|
|
22
|
+
/** Collects events in memory. Used to build the run report and in tests. */
|
|
23
|
+
export declare const capture_handler: () => CapturingEventHandler;
|
|
24
|
+
/**
|
|
25
|
+
* Writes each event as one JSON object per line (JSON-lines) to `process.stdout`.
|
|
26
|
+
* Write failures are swallowed — the stream is observability, not control flow.
|
|
27
|
+
*/
|
|
28
|
+
export declare const stdout_handler: () => PublishingEventHandler;
|
|
29
|
+
/** Fans an event out to every handler in order. */
|
|
30
|
+
export declare const multi_handler: (handlers: Array<PublishingEventHandler>) => PublishingEventHandler;
|
|
31
|
+
/**
|
|
32
|
+
* Wraps a handler, masking secrets in each event's string fields before forwarding.
|
|
33
|
+
*
|
|
34
|
+
* @param inner - the handler to forward masked events to
|
|
35
|
+
* @param mask - the masking function, defaults to `mask_secrets`
|
|
36
|
+
*/
|
|
37
|
+
export declare const masking_handler: (inner: PublishingEventHandler, mask?: (event: PublishingEvent) => PublishingEvent) => PublishingEventHandler;
|
|
38
|
+
/** Redacts known secret shapes from a string. */
|
|
39
|
+
export declare const redact_secrets: (text: string) => string;
|
|
40
|
+
/** Returns a copy of the event with secrets redacted from its string-valued fields. */
|
|
41
|
+
export declare const mask_secrets: (event: PublishingEvent) => PublishingEvent;
|
|
42
|
+
//# sourceMappingURL=publishing_event_handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publishing_event_handler.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/publishing_event_handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AAE3D,oCAAoC;AACpC,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;CACvC;AAED,oEAAoE;AACpE,MAAM,WAAW,qBAAsB,SAAQ,sBAAsB;IACpE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;CACxC;AAED,kEAAkE;AAClE,eAAO,MAAM,YAAY,QAAO,sBAE9B,CAAC;AAEH,4EAA4E;AAC5E,eAAO,MAAM,eAAe,QAAO,qBAQlC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,sBAQhC,CAAC;AAEH,mDAAmD;AACnD,eAAO,MAAM,aAAa,GAAI,UAAU,KAAK,CAAC,sBAAsB,CAAC,KAAG,sBAMtE,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAC3B,OAAO,sBAAsB,EAC7B,OAAM,CAAC,KAAK,EAAE,eAAe,KAAK,eAA8B,KAC9D,sBAID,CAAC;AAWH,iDAAiD;AACjD,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,MACgD,CAAC;AAE/F,uFAAuF;AACvF,eAAO,MAAM,YAAY,GAAI,OAAO,eAAe,KAAG,eAMrD,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composable sinks for the publishing event stream.
|
|
3
|
+
*
|
|
4
|
+
* A `PublishingEventHandler` is anything that can receive a `PublishingEvent`. Handlers
|
|
5
|
+
* compose: `multi_handler` fans out, `masking_handler` redacts secrets then forwards.
|
|
6
|
+
* Emission is best-effort and synchronous — an observability sink must never fail or
|
|
7
|
+
* slow a run. The default sink is `null_handler` (drops everything).
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
/** Drops every event. The default when no handler is supplied. */
|
|
12
|
+
export const null_handler = () => ({
|
|
13
|
+
emit: () => { },
|
|
14
|
+
});
|
|
15
|
+
/** Collects events in memory. Used to build the run report and in tests. */
|
|
16
|
+
export const capture_handler = () => {
|
|
17
|
+
const events = [];
|
|
18
|
+
return {
|
|
19
|
+
events,
|
|
20
|
+
emit: (event) => {
|
|
21
|
+
events.push(event);
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Writes each event as one JSON object per line (JSON-lines) to `process.stdout`.
|
|
27
|
+
* Write failures are swallowed — the stream is observability, not control flow.
|
|
28
|
+
*/
|
|
29
|
+
export const stdout_handler = () => ({
|
|
30
|
+
emit: (event) => {
|
|
31
|
+
try {
|
|
32
|
+
process.stdout.write(JSON.stringify(event) + '\n');
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// best-effort: a logging sink must never fail a run
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
/** Fans an event out to every handler in order. */
|
|
40
|
+
export const multi_handler = (handlers) => ({
|
|
41
|
+
emit: (event) => {
|
|
42
|
+
for (const handler of handlers) {
|
|
43
|
+
handler.emit(event);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* Wraps a handler, masking secrets in each event's string fields before forwarding.
|
|
49
|
+
*
|
|
50
|
+
* @param inner - the handler to forward masked events to
|
|
51
|
+
* @param mask - the masking function, defaults to `mask_secrets`
|
|
52
|
+
*/
|
|
53
|
+
export const masking_handler = (inner, mask = mask_secrets) => ({
|
|
54
|
+
emit: (event) => {
|
|
55
|
+
inner.emit(mask(event));
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
// Minimal redaction rules: npm auth tokens (bare or registry-scoped), `SECRET_*`
|
|
59
|
+
// env-style assignments, and `npm_`-prefixed tokens. Deliberately lean — error
|
|
60
|
+
// strings can carry npm/git output; a fuller secret catalog is deferred.
|
|
61
|
+
const SECRET_RULES = [
|
|
62
|
+
[/((?:\/\/[^\s:]+:)?_authToken\s*=\s*)\S+/gi, '$1[redacted]'],
|
|
63
|
+
[/(SECRET_[A-Z0-9_]+\s*[=:]\s*)\S+/g, '$1[redacted]'],
|
|
64
|
+
[/(npm_[A-Za-z0-9]{4})[A-Za-z0-9]{12,}/g, '$1[redacted]'],
|
|
65
|
+
];
|
|
66
|
+
/** Redacts known secret shapes from a string. */
|
|
67
|
+
export const redact_secrets = (text) => SECRET_RULES.reduce((acc, [pattern, replacement]) => acc.replace(pattern, replacement), text);
|
|
68
|
+
/** Returns a copy of the event with secrets redacted from its string-valued fields. */
|
|
69
|
+
export const mask_secrets = (event) => {
|
|
70
|
+
const masked = {};
|
|
71
|
+
for (const [key, value] of Object.entries(event)) {
|
|
72
|
+
masked[key] = typeof value === 'string' ? redact_secrets(value) : value;
|
|
73
|
+
}
|
|
74
|
+
return masked;
|
|
75
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Logger } from '@fuzdev/fuz_util/log.js';
|
|
2
2
|
import type { LocalRepo } from './local_repo.js';
|
|
3
|
-
import type
|
|
3
|
+
import { type BumpType } from './version_utils.js';
|
|
4
4
|
import type { ChangesetOperations } from './operations.js';
|
|
5
5
|
export { log_publishing_plan, type LogPlanOptions } from './publishing_plan_logging.js';
|
|
6
6
|
export interface VersionChange {
|
|
@@ -21,7 +21,6 @@ export interface DependencyUpdate {
|
|
|
21
21
|
current_version: string;
|
|
22
22
|
new_version: string;
|
|
23
23
|
type: 'dependencies' | 'devDependencies' | 'peerDependencies';
|
|
24
|
-
causes_republish: boolean;
|
|
25
24
|
}
|
|
26
25
|
export interface VerboseChangesetDetail {
|
|
27
26
|
package_name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publishing_plan.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/publishing_plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAGpD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"publishing_plan.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/publishing_plan.ts"],"names":[],"mappings":"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"}
|
package/dist/publishing_plan.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { styleText as st } from 'node:util';
|
|
2
2
|
import { validate_dependency_graph } from './graph_validation.js';
|
|
3
|
-
import { is_breaking_change, compare_bump_types, calculate_next_version } from './version_utils.js';
|
|
3
|
+
import { is_breaking_change, compare_bump_types, calculate_next_version, } from './version_utils.js';
|
|
4
4
|
import { default_changeset_operations } from './operations_defaults.js';
|
|
5
5
|
import { GITOPS_MAX_ITERATIONS_DEFAULT } from './gitops_constants.js';
|
|
6
6
|
import { calculate_dependency_updates, get_required_bump_for_dependencies, } from './publishing_plan_helpers.js';
|
|
@@ -70,6 +70,17 @@ export const generate_publishing_plan = async (repos, options = {}) => {
|
|
|
70
70
|
const repo = repos.find((r) => r.library.name === pkg_name);
|
|
71
71
|
if (!repo)
|
|
72
72
|
continue;
|
|
73
|
+
// Private packages never publish — exclude them from version changes entirely (no
|
|
74
|
+
// publish step, npm-wait, bump escalation, or auto-changeset). They keep their slot in
|
|
75
|
+
// the topological order. Flag a private package that carries a changeset, since that
|
|
76
|
+
// changeset can't be published.
|
|
77
|
+
if (repo.library.package_json.private) {
|
|
78
|
+
const private_has_changesets = await ops.has_changesets({ repo });
|
|
79
|
+
if (private_has_changesets.ok && private_has_changesets.value) {
|
|
80
|
+
warnings.push(`${pkg_name} is private — its changeset(s) will not be published`);
|
|
81
|
+
}
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
73
84
|
// Check for changesets
|
|
74
85
|
const has_result = await ops.has_changesets({ repo });
|
|
75
86
|
if (!has_result.ok) {
|
|
@@ -140,6 +151,10 @@ export const generate_publishing_plan = async (repos, options = {}) => {
|
|
|
140
151
|
// Process packages to check for bump escalation and auto-generated changesets
|
|
141
152
|
for (const repo of repos) {
|
|
142
153
|
const pkg_name = repo.library.name;
|
|
154
|
+
// Private packages are excluded from version changes (they never publish), so they
|
|
155
|
+
// never escalate or auto-generate a changeset.
|
|
156
|
+
if (repo.library.package_json.private)
|
|
157
|
+
continue;
|
|
143
158
|
// Get required bump from dependencies
|
|
144
159
|
const required_bump = get_required_bump_for_dependencies(repo, dependency_updates, breaking_packages);
|
|
145
160
|
// Find triggering dependency for verbose output
|
|
@@ -248,6 +263,8 @@ export const generate_publishing_plan = async (repos, options = {}) => {
|
|
|
248
263
|
const { dependency_updates: pending_updates } = calculate_dependency_updates(repos, predicted_versions, breaking_packages);
|
|
249
264
|
for (const repo of repos) {
|
|
250
265
|
const pkg_name = repo.library.name;
|
|
266
|
+
if (repo.library.package_json.private)
|
|
267
|
+
continue; // private packages never publish
|
|
251
268
|
const required_bump = get_required_bump_for_dependencies(repo, pending_updates, breaking_packages);
|
|
252
269
|
// Check if this package would need processing
|
|
253
270
|
const existing_entry = version_changes.find((vc) => vc.package_name === pkg_name);
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @module
|
|
7
7
|
*/
|
|
8
8
|
import type { LocalRepo } from './local_repo.js';
|
|
9
|
-
import type
|
|
9
|
+
import { type BumpType } from './version_utils.js';
|
|
10
10
|
import type { DependencyUpdate } from './publishing_plan.js';
|
|
11
11
|
/**
|
|
12
12
|
* Calculates all dependency updates between packages based on predicted versions.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publishing_plan_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/publishing_plan_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"publishing_plan_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/publishing_plan_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAoD,KAAK,QAAQ,EAAC,MAAM,oBAAoB,CAAC;AACpG,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAE3D;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,GACxC,OAAO,KAAK,CAAC,SAAS,CAAC,EACvB,oBAAoB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACvC,mBAAmB,GAAG,CAAC,MAAM,CAAC,KAC5B;IACF,kBAAkB,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC5C,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;CAwE9C,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kCAAkC,GAC9C,MAAM,SAAS,EACf,oBAAoB,KAAK,CAAC,gBAAgB,CAAC,EAC3C,mBAAmB,GAAG,CAAC,MAAM,CAAC,KAC5B,QAAQ,GAAG,IAqBb,CAAC"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module
|
|
7
7
|
*/
|
|
8
|
-
import { needs_update } from './version_utils.js';
|
|
8
|
+
import { needs_update, required_bump_for_dependency_update } from './version_utils.js';
|
|
9
9
|
/**
|
|
10
10
|
* Calculates all dependency updates between packages based on predicted versions.
|
|
11
11
|
*
|
|
@@ -29,7 +29,6 @@ export const calculate_dependency_updates = (repos, predicted_versions, breaking
|
|
|
29
29
|
current_version,
|
|
30
30
|
new_version,
|
|
31
31
|
type: 'dependencies',
|
|
32
|
-
causes_republish: true,
|
|
33
32
|
});
|
|
34
33
|
if (breaking_packages.has(dep_name)) {
|
|
35
34
|
const cascades = breaking_cascades.get(dep_name) || [];
|
|
@@ -52,7 +51,6 @@ export const calculate_dependency_updates = (repos, predicted_versions, breaking
|
|
|
52
51
|
current_version,
|
|
53
52
|
new_version,
|
|
54
53
|
type: 'peerDependencies',
|
|
55
|
-
causes_republish: true,
|
|
56
54
|
});
|
|
57
55
|
if (breaking_packages.has(dep_name)) {
|
|
58
56
|
const cascades = breaking_cascades.get(dep_name) || [];
|
|
@@ -75,7 +73,6 @@ export const calculate_dependency_updates = (repos, predicted_versions, breaking
|
|
|
75
73
|
current_version,
|
|
76
74
|
new_version,
|
|
77
75
|
type: 'devDependencies',
|
|
78
|
-
causes_republish: false,
|
|
79
76
|
});
|
|
80
77
|
}
|
|
81
78
|
}
|
|
@@ -100,15 +97,5 @@ export const get_required_bump_for_dependencies = (repo, dependency_updates, bre
|
|
|
100
97
|
}
|
|
101
98
|
// Check if any of these dependencies have breaking changes
|
|
102
99
|
const has_breaking_deps = relevant_updates.some((update) => breaking_packages.has(update.updated_dependency));
|
|
103
|
-
|
|
104
|
-
const [major] = current_version.split('.').map(Number);
|
|
105
|
-
const is_pre_1_0 = major === 0;
|
|
106
|
-
if (has_breaking_deps) {
|
|
107
|
-
// Breaking changes propagate
|
|
108
|
-
// Pre-1.0: use minor for breaking changes
|
|
109
|
-
// 1.0+: use major for breaking changes
|
|
110
|
-
return is_pre_1_0 ? 'minor' : 'major';
|
|
111
|
-
}
|
|
112
|
-
// For non-breaking dependency updates, use patch
|
|
113
|
-
return 'patch';
|
|
100
|
+
return required_bump_for_dependency_update(repo.library.package_json.version || '0.0.0', has_breaking_deps);
|
|
114
101
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publishing_plan_logging.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/publishing_plan_logging.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAGpD,OAAO,KAAK,EACX,cAAc,EAQd,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,cAAc;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AA2GD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM,cAAc,EACpB,KAAK,MAAM,EACX,UAAS,cAAmB,KAC1B,
|
|
1
|
+
{"version":3,"file":"publishing_plan_logging.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/publishing_plan_logging.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAGpD,OAAO,KAAK,EACX,cAAc,EAQd,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,cAAc;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AA2GD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM,cAAc,EACpB,KAAK,MAAM,EACX,UAAS,cAAmB,KAC1B,IA6IF,CAAC"}
|
|
@@ -120,31 +120,23 @@ export const log_publishing_plan = (plan, log, options = {}) => {
|
|
|
120
120
|
const with_changesets = ordered_changes.filter((vc) => vc.has_changesets && !vc.needs_bump_escalation);
|
|
121
121
|
const with_escalation = ordered_changes.filter((vc) => vc.needs_bump_escalation);
|
|
122
122
|
const with_auto_changesets = ordered_changes.filter((vc) => vc.will_generate_changeset);
|
|
123
|
-
//
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
123
|
+
// A single running counter across all groups so positions read 1..N with no
|
|
124
|
+
// gaps. (Numbering per-group index would make the first group skip the numbers
|
|
125
|
+
// that land in a later group, e.g. jump from `[9/12]` to `[11/12]`.)
|
|
126
|
+
const total = with_changesets.length + with_escalation.length + with_auto_changesets.length;
|
|
127
|
+
let position = 0;
|
|
128
|
+
const log_change_group = (title, color, changes) => {
|
|
129
|
+
if (changes.length === 0)
|
|
130
|
+
return;
|
|
131
|
+
log.info(st(color, title));
|
|
132
|
+
for (const change of changes) {
|
|
133
|
+
log_version_change_with_diffs(change, position++, total, dependency_updates, breaking_cascades, log);
|
|
129
134
|
}
|
|
130
135
|
log.info('');
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const idx = ordered_changes.indexOf(change);
|
|
136
|
-
log_version_change_with_diffs(change, idx, ordered_changes.length, dependency_updates, breaking_cascades, log);
|
|
137
|
-
}
|
|
138
|
-
log.info('');
|
|
139
|
-
}
|
|
140
|
-
if (with_auto_changesets.length > 0) {
|
|
141
|
-
log.info(st('cyan', 'Version Changes (auto-generated):'));
|
|
142
|
-
for (const change of with_auto_changesets) {
|
|
143
|
-
const idx = ordered_changes.indexOf(change);
|
|
144
|
-
log_version_change_with_diffs(change, idx, ordered_changes.length, dependency_updates, breaking_cascades, log);
|
|
145
|
-
}
|
|
146
|
-
log.info('');
|
|
147
|
-
}
|
|
136
|
+
};
|
|
137
|
+
log_change_group('Version Changes (from changesets):', 'cyan', with_changesets);
|
|
138
|
+
log_change_group('Version Changes (bump escalation):', 'yellow', with_escalation);
|
|
139
|
+
log_change_group('Version Changes (auto-generated):', 'cyan', with_auto_changesets);
|
|
148
140
|
}
|
|
149
141
|
else {
|
|
150
142
|
log.info(st('dim', 'No packages to publish'));
|
package/dist/repo_ops.d.ts
CHANGED
|
@@ -35,7 +35,7 @@ export interface RepoPath {
|
|
|
35
35
|
* Get repo paths from gitops config without full git sync.
|
|
36
36
|
* Lighter weight than `get_gitops_ready()` - just resolves paths.
|
|
37
37
|
*
|
|
38
|
-
* @param config_path - path to
|
|
38
|
+
* @param config_path - path to the gitops config file (defaults to `gitops.config.ts`)
|
|
39
39
|
* @returns array of repo info with name, path, and url
|
|
40
40
|
*/
|
|
41
41
|
export declare const get_repo_paths: (config_path?: string) => Promise<Array<RepoPath>>;
|
package/dist/repo_ops.js
CHANGED
|
@@ -59,7 +59,7 @@ export const DEFAULT_EXCLUDE_EXTENSIONS = [
|
|
|
59
59
|
* Get repo paths from gitops config without full git sync.
|
|
60
60
|
* Lighter weight than `get_gitops_ready()` - just resolves paths.
|
|
61
61
|
*
|
|
62
|
-
* @param config_path - path to
|
|
62
|
+
* @param config_path - path to the gitops config file (defaults to `gitops.config.ts`)
|
|
63
63
|
* @returns array of repo info with name, path, and url
|
|
64
64
|
*/
|
|
65
65
|
export const get_repo_paths = async (config_path) => {
|
package/dist/version_utils.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
/** A semver bump kind: `major`, `minor`, or `patch`. */
|
|
2
|
+
export type BumpType = 'major' | 'minor' | 'patch';
|
|
2
3
|
export declare const is_wildcard: (version: string) => boolean;
|
|
3
4
|
/**
|
|
4
5
|
* Strips version prefix (^, ~, >=, <=, etc) from a version string.
|
|
@@ -47,8 +48,21 @@ export declare const get_update_prefix: (current_version: string, default_strate
|
|
|
47
48
|
* Pre-1.0: minor bumps are breaking
|
|
48
49
|
* 1.0+: major bumps are breaking
|
|
49
50
|
*/
|
|
50
|
-
export declare const is_breaking_change: (old_version: string, bump_type:
|
|
51
|
-
|
|
51
|
+
export declare const is_breaking_change: (old_version: string, bump_type: BumpType) => boolean;
|
|
52
|
+
/**
|
|
53
|
+
* The bump a package must take when one of its prod/peer dependencies updates.
|
|
54
|
+
* Pre-1.0: `minor` for a breaking dependency, otherwise `patch`.
|
|
55
|
+
* 1.0+: `major` for a breaking dependency, otherwise `patch`.
|
|
56
|
+
*
|
|
57
|
+
* Single source of truth for the dependency-driven bump rule, shared by the plan
|
|
58
|
+
* (`get_required_bump_for_dependencies`) and the auto-changeset generator
|
|
59
|
+
* (`calculate_required_bump`) so the two never drift.
|
|
60
|
+
*
|
|
61
|
+
* @param current_version - the package's current version, used to detect the pre-1.0 regime
|
|
62
|
+
* @param has_breaking_deps - whether any updated dependency is a breaking change
|
|
63
|
+
*/
|
|
64
|
+
export declare const required_bump_for_dependency_update: (current_version: string, has_breaking_deps: boolean) => BumpType;
|
|
65
|
+
export declare const detect_bump_type: (old_version: string, new_version: string) => BumpType;
|
|
52
66
|
/**
|
|
53
67
|
* Compares bump types. Returns positive if a > b, negative if a < b, 0 if equal.
|
|
54
68
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version_utils.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/version_utils.ts"],"names":[],"mappings":"AAEA,
|
|
1
|
+
{"version":3,"file":"version_utils.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/version_utils.ts"],"names":[],"mappings":"AAEA,wDAAwD;AACxD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAEnD,eAAO,MAAM,WAAW,GAAI,SAAS,MAAM,KAAG,OAE7C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS,MAAM,KAAG,MAEtD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,KAAG,MAGpD,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gCAAgC,GAAI,SAAS,MAAM,KAAG,MAWlE,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,EAAE,aAAa,MAAM,KAAG,OASnE,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iBAAiB,GAC7B,iBAAiB,MAAM,EACvB,mBAAkB,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,IAAU,KAC3C,MAcF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,aAAa,MAAM,EAAE,WAAW,QAAQ,KAAG,OAW7E,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mCAAmC,GAC/C,iBAAiB,MAAM,EACvB,mBAAmB,OAAO,KACxB,QASF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,aAAa,MAAM,EAAE,aAAa,MAAM,KAAG,QAO3E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,GAAG,QAAQ,EAAE,GAAG,QAAQ,KAAG,MAO7D,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,iBAAiB,MAAM,EAAE,WAAW,QAAQ,KAAG,MAkBrF,CAAC"}
|
package/dist/version_utils.js
CHANGED
|
@@ -96,6 +96,28 @@ export const is_breaking_change = (old_version, bump_type) => {
|
|
|
96
96
|
return bump_type === 'major';
|
|
97
97
|
}
|
|
98
98
|
};
|
|
99
|
+
/**
|
|
100
|
+
* The bump a package must take when one of its prod/peer dependencies updates.
|
|
101
|
+
* Pre-1.0: `minor` for a breaking dependency, otherwise `patch`.
|
|
102
|
+
* 1.0+: `major` for a breaking dependency, otherwise `patch`.
|
|
103
|
+
*
|
|
104
|
+
* Single source of truth for the dependency-driven bump rule, shared by the plan
|
|
105
|
+
* (`get_required_bump_for_dependencies`) and the auto-changeset generator
|
|
106
|
+
* (`calculate_required_bump`) so the two never drift.
|
|
107
|
+
*
|
|
108
|
+
* @param current_version - the package's current version, used to detect the pre-1.0 regime
|
|
109
|
+
* @param has_breaking_deps - whether any updated dependency is a breaking change
|
|
110
|
+
*/
|
|
111
|
+
export const required_bump_for_dependency_update = (current_version, has_breaking_deps) => {
|
|
112
|
+
const [major] = current_version.split('.').map(Number);
|
|
113
|
+
const is_pre_1_0 = major === 0;
|
|
114
|
+
if (has_breaking_deps) {
|
|
115
|
+
// Breaking changes propagate: pre-1.0 uses minor, 1.0+ uses major
|
|
116
|
+
return is_pre_1_0 ? 'minor' : 'major';
|
|
117
|
+
}
|
|
118
|
+
// Non-breaking dependency updates only need a patch
|
|
119
|
+
return 'patch';
|
|
120
|
+
};
|
|
99
121
|
export const detect_bump_type = (old_version, new_version) => {
|
|
100
122
|
const old_parts = old_version.split('.').map(Number);
|
|
101
123
|
const new_parts = new_version.split('.').map(Number);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fuzdev/fuz_gitops",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.73.0",
|
|
4
4
|
"description": "a tool for managing many repos",
|
|
5
5
|
"glyph": "🪄",
|
|
6
6
|
"logo": "logo.svg",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"@fuzdev/fuz_css": ">=0.61.0",
|
|
33
33
|
"@fuzdev/fuz_ui": ">=0.198.0",
|
|
34
|
-
"@fuzdev/fuz_util": ">=0.63.
|
|
34
|
+
"@fuzdev/fuz_util": ">=0.63.1",
|
|
35
35
|
"@fuzdev/gro": ">=0.200.0",
|
|
36
36
|
"@sveltejs/kit": "^2",
|
|
37
37
|
"svelte": "^5",
|
|
@@ -42,10 +42,9 @@
|
|
|
42
42
|
"@fuzdev/blake3_wasm": "^0.1.1",
|
|
43
43
|
"@fuzdev/fuz_code": "^0.45.1",
|
|
44
44
|
"@fuzdev/fuz_css": "^0.61.1",
|
|
45
|
-
"@fuzdev/fuz_ui": "^0.198.
|
|
46
|
-
"@fuzdev/fuz_util": "^0.63.
|
|
47
|
-
"@fuzdev/gro": "^0.
|
|
48
|
-
"@jridgewell/trace-mapping": "^0.3.31",
|
|
45
|
+
"@fuzdev/fuz_ui": "^0.198.1",
|
|
46
|
+
"@fuzdev/fuz_util": "^0.63.2",
|
|
47
|
+
"@fuzdev/gro": "^0.202.0",
|
|
49
48
|
"@ryanatkn/eslint-config": "^0.12.1",
|
|
50
49
|
"@sveltejs/acorn-typescript": "^1.0.9",
|
|
51
50
|
"@sveltejs/adapter-static": "^3.0.10",
|
|
@@ -63,7 +62,7 @@
|
|
|
63
62
|
"prettier-plugin-svelte": "^3.5.1",
|
|
64
63
|
"svelte": "^5.56.0",
|
|
65
64
|
"svelte-check": "^4.4.6",
|
|
66
|
-
"svelte-docinfo": "^0.
|
|
65
|
+
"svelte-docinfo": "^0.4.0",
|
|
67
66
|
"svelte2tsx": "^0.7.52",
|
|
68
67
|
"tslib": "^2.8.1",
|
|
69
68
|
"typescript": "^5.9.3",
|
|
@@ -11,7 +11,11 @@ import {join} from 'node:path';
|
|
|
11
11
|
import type {Logger} from '@fuzdev/fuz_util/log.js';
|
|
12
12
|
import type {LocalRepo} from './local_repo.js';
|
|
13
13
|
import type {PublishedVersion} from './multi_repo_publisher.js';
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
strip_version_prefix,
|
|
16
|
+
required_bump_for_dependency_update,
|
|
17
|
+
type BumpType,
|
|
18
|
+
} from './version_utils.js';
|
|
15
19
|
import type {FsOperations} from './operations.js';
|
|
16
20
|
import {default_fs_operations} from './operations_defaults.js';
|
|
17
21
|
|
|
@@ -69,24 +73,11 @@ export const create_changeset_for_dependency_updates = async (
|
|
|
69
73
|
const calculate_required_bump = (
|
|
70
74
|
repo: LocalRepo,
|
|
71
75
|
updates: Array<DependencyVersionChange>,
|
|
72
|
-
):
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
// Check if any dependency had breaking changes
|
|
78
|
-
const has_breaking = updates.some((u) => u.breaking);
|
|
79
|
-
|
|
80
|
-
if (has_breaking) {
|
|
81
|
-
// Breaking changes propagate
|
|
82
|
-
// Pre-1.0: use minor for breaking changes
|
|
83
|
-
// 1.0+: use major for breaking changes
|
|
84
|
-
return is_pre_1_0 ? 'minor' : 'major';
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// For non-breaking dependency updates, always use patch
|
|
88
|
-
return 'patch';
|
|
89
|
-
};
|
|
76
|
+
): BumpType =>
|
|
77
|
+
required_bump_for_dependency_update(
|
|
78
|
+
repo.library.package_json.version || '0.0.0',
|
|
79
|
+
updates.some((u) => u.breaking),
|
|
80
|
+
);
|
|
90
81
|
|
|
91
82
|
/**
|
|
92
83
|
* Generates markdown changeset content for dependency updates.
|
|
@@ -13,8 +13,7 @@ import {readdir, readFile} from 'node:fs/promises';
|
|
|
13
13
|
import {join} from 'node:path';
|
|
14
14
|
|
|
15
15
|
import type {LocalRepo} from './local_repo.js';
|
|
16
|
-
import type
|
|
17
|
-
import {compare_bump_types, calculate_next_version} from './version_utils.js';
|
|
16
|
+
import {compare_bump_types, calculate_next_version, type BumpType} from './version_utils.js';
|
|
18
17
|
|
|
19
18
|
export interface ChangesetInfo {
|
|
20
19
|
filename: string;
|