@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.
Files changed (117) hide show
  1. package/README.md +13 -6
  2. package/dist/changeset_generator.d.ts.map +1 -1
  3. package/dist/changeset_generator.js +2 -16
  4. package/dist/changeset_reader.d.ts +1 -1
  5. package/dist/changeset_reader.d.ts.map +1 -1
  6. package/dist/dependency_graph.js +1 -1
  7. package/dist/git_operations.d.ts +5 -0
  8. package/dist/git_operations.d.ts.map +1 -1
  9. package/dist/git_operations.js +5 -0
  10. package/dist/gitops_analyze.task.d.ts +1 -0
  11. package/dist/gitops_analyze.task.d.ts.map +1 -1
  12. package/dist/gitops_analyze.task.js +12 -17
  13. package/dist/gitops_plan.task.d.ts +1 -0
  14. package/dist/gitops_plan.task.d.ts.map +1 -1
  15. package/dist/gitops_plan.task.js +9 -2
  16. package/dist/gitops_publish.task.d.ts +3 -2
  17. package/dist/gitops_publish.task.d.ts.map +1 -1
  18. package/dist/gitops_publish.task.js +90 -26
  19. package/dist/gitops_run.task.d.ts +2 -1
  20. package/dist/gitops_run.task.d.ts.map +1 -1
  21. package/dist/gitops_run.task.js +40 -7
  22. package/dist/gitops_sync.task.d.ts +1 -0
  23. package/dist/gitops_sync.task.d.ts.map +1 -1
  24. package/dist/gitops_sync.task.js +16 -2
  25. package/dist/gitops_task_helpers.d.ts +16 -2
  26. package/dist/gitops_task_helpers.d.ts.map +1 -1
  27. package/dist/gitops_task_helpers.js +11 -3
  28. package/dist/gitops_validate.task.d.ts +1 -0
  29. package/dist/gitops_validate.task.d.ts.map +1 -1
  30. package/dist/gitops_validate.task.js +20 -20
  31. package/dist/graph_validation.d.ts +16 -1
  32. package/dist/graph_validation.d.ts.map +1 -1
  33. package/dist/graph_validation.js +15 -0
  34. package/dist/local_repo.d.ts +22 -10
  35. package/dist/local_repo.d.ts.map +1 -1
  36. package/dist/local_repo.js +92 -75
  37. package/dist/log_helpers.d.ts +0 -5
  38. package/dist/log_helpers.d.ts.map +1 -1
  39. package/dist/log_helpers.js +8 -19
  40. package/dist/multi_repo_publisher.d.ts +29 -2
  41. package/dist/multi_repo_publisher.d.ts.map +1 -1
  42. package/dist/multi_repo_publisher.js +307 -233
  43. package/dist/operations.d.ts +6 -26
  44. package/dist/operations.d.ts.map +1 -1
  45. package/dist/operations_defaults.d.ts.map +1 -1
  46. package/dist/operations_defaults.js +1 -19
  47. package/dist/output_helpers.d.ts.map +1 -1
  48. package/dist/output_helpers.js +7 -6
  49. package/dist/paths.d.ts +0 -4
  50. package/dist/paths.d.ts.map +1 -1
  51. package/dist/paths.js +0 -4
  52. package/dist/publish_gate.d.ts +44 -0
  53. package/dist/publish_gate.d.ts.map +1 -0
  54. package/dist/publish_gate.js +32 -0
  55. package/dist/publish_steps.d.ts +60 -0
  56. package/dist/publish_steps.d.ts.map +1 -0
  57. package/dist/publish_steps.js +113 -0
  58. package/dist/publishing_event.d.ts +123 -0
  59. package/dist/publishing_event.d.ts.map +1 -0
  60. package/dist/publishing_event.js +140 -0
  61. package/dist/publishing_event_handler.d.ts +42 -0
  62. package/dist/publishing_event_handler.d.ts.map +1 -0
  63. package/dist/publishing_event_handler.js +75 -0
  64. package/dist/publishing_plan.d.ts +1 -2
  65. package/dist/publishing_plan.d.ts.map +1 -1
  66. package/dist/publishing_plan.js +18 -1
  67. package/dist/publishing_plan_helpers.d.ts +1 -1
  68. package/dist/publishing_plan_helpers.d.ts.map +1 -1
  69. package/dist/publishing_plan_helpers.js +2 -15
  70. package/dist/publishing_plan_logging.d.ts.map +1 -1
  71. package/dist/publishing_plan_logging.js +15 -23
  72. package/dist/repo_ops.d.ts +1 -1
  73. package/dist/repo_ops.js +1 -1
  74. package/dist/version_utils.d.ts +17 -3
  75. package/dist/version_utils.d.ts.map +1 -1
  76. package/dist/version_utils.js +22 -0
  77. package/package.json +6 -7
  78. package/src/lib/changeset_generator.ts +10 -19
  79. package/src/lib/changeset_reader.ts +1 -2
  80. package/src/lib/dependency_graph.ts +1 -1
  81. package/src/lib/git_operations.ts +5 -0
  82. package/src/lib/gitops_analyze.task.ts +18 -23
  83. package/src/lib/gitops_plan.task.ts +10 -2
  84. package/src/lib/gitops_publish.task.ts +100 -25
  85. package/src/lib/gitops_run.task.ts +39 -7
  86. package/src/lib/gitops_sync.task.ts +18 -3
  87. package/src/lib/gitops_task_helpers.ts +20 -3
  88. package/src/lib/gitops_validate.task.ts +30 -22
  89. package/src/lib/graph_validation.ts +26 -0
  90. package/src/lib/local_repo.ts +114 -83
  91. package/src/lib/log_helpers.ts +8 -26
  92. package/src/lib/multi_repo_publisher.ts +387 -269
  93. package/src/lib/operations.ts +6 -22
  94. package/src/lib/operations_defaults.ts +1 -19
  95. package/src/lib/output_helpers.ts +7 -6
  96. package/src/lib/paths.ts +0 -5
  97. package/src/lib/publish_gate.ts +53 -0
  98. package/src/lib/publish_steps.ts +149 -0
  99. package/src/lib/publishing_event.ts +151 -0
  100. package/src/lib/publishing_event_handler.ts +98 -0
  101. package/src/lib/publishing_plan.ts +23 -3
  102. package/src/lib/publishing_plan_helpers.ts +5 -18
  103. package/src/lib/publishing_plan_logging.ts +19 -39
  104. package/src/lib/repo_ops.ts +1 -1
  105. package/src/lib/version_utils.ts +30 -9
  106. package/dist/npm_install_helpers.d.ts +0 -23
  107. package/dist/npm_install_helpers.d.ts.map +0 -1
  108. package/dist/npm_install_helpers.js +0 -60
  109. package/dist/semver.d.ts +0 -26
  110. package/dist/semver.d.ts.map +0 -1
  111. package/dist/semver.js +0 -137
  112. package/dist/serialization_types.d.ts +0 -59
  113. package/dist/serialization_types.d.ts.map +0 -1
  114. package/dist/serialization_types.js +0 -42
  115. package/src/lib/npm_install_helpers.ts +0 -85
  116. package/src/lib/semver.ts +0 -170
  117. 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 { BumpType } from './semver.js';
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;AAC/C,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAG1C,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,iBAAiB,CAAC;AAUzD,OAAO,EAAC,mBAAmB,EAAE,KAAK,cAAc,EAAC,MAAM,8BAA8B,CAAC;AAEtF,MAAM,WAAW,aAAa;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,QAAQ,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,aAAa,CAAC,EAAE,QAAQ,CAAC;IACzB,aAAa,CAAC,EAAE,QAAQ,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,cAAc,GAAG,iBAAiB,GAAG,kBAAkB,CAAC;IAC9D,gBAAgB,EAAE,OAAO,CAAC;CAC1B;AAGD,MAAM,WAAW,sBAAsB;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,QAAQ,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,uBAAuB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtC,aAAa,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,SAAS,GAAG,gBAAgB,GAAG,YAAY,GAAG,MAAM,CAAC;IAC7D,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACzC,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,mBAAmB;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;KAAC,CAAC,CAAC;IAC1E,SAAS,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;IAC7C,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC3B,iBAAiB,EAAE,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACjD,UAAU,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACpC,kBAAkB,EAAE,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACnD,aAAa,EAAE,mBAAmB,CAAC;IACnC,gBAAgB,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC9B,gBAAgB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAChC,eAAe,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IACtC,kBAAkB,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC5C,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACxB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtB,YAAY,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,mBAAmB,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACpC,OAAO,KAAK,CAAC,SAAS,CAAC,EACvB,UAAS,mBAAwB,KAC/B,OAAO,CAAC,cAAc,CAmaxB,CAAC"}
1
+ {"version":3,"file":"publishing_plan.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/publishing_plan.ts"],"names":[],"mappings":"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"}
@@ -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 { BumpType } from './semver.js';
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,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAE1C,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;CA2E9C,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,IA8Bb,CAAC"}
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
- const current_version = repo.library.package_json.version || '0.0.0';
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,IAiKF,CAAC"}
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
- // Log each group with diff-style output
124
- if (with_changesets.length > 0) {
125
- log.info(st('cyan', 'Version Changes (from changesets):'));
126
- for (const change of with_changesets) {
127
- const idx = ordered_changes.indexOf(change);
128
- log_version_change_with_diffs(change, idx, ordered_changes.length, dependency_updates, breaking_cascades, log);
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
- if (with_escalation.length > 0) {
133
- log.info(st('yellow', 'Version Changes (bump escalation):'));
134
- for (const change of with_escalation) {
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'));
@@ -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 `gitops.config.ts` (defaults to `./gitops.config.ts`)
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 `gitops.config.ts` (defaults to `./gitops.config.ts`)
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) => {
@@ -1,4 +1,5 @@
1
- import type { BumpType } from './semver.js';
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: "major" | "minor" | "patch") => boolean;
51
- export declare const detect_bump_type: (old_version: string, new_version: string) => "major" | "minor" | "patch";
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,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAE1C,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,GAC9B,aAAa,MAAM,EACnB,WAAW,OAAO,GAAG,OAAO,GAAG,OAAO,KACpC,OAWF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC5B,aAAa,MAAM,EACnB,aAAa,MAAM,KACjB,OAAO,GAAG,OAAO,GAAG,OAOtB,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"}
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"}
@@ -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.71.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.0",
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.0",
46
- "@fuzdev/fuz_util": "^0.63.0",
47
- "@fuzdev/gro": "^0.200.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.2.1",
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 {strip_version_prefix} from './version_utils.js';
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
- ): 'major' | 'minor' | 'patch' => {
73
- const current_version = repo.library.package_json.version || '0.0.0';
74
- const [major] = current_version.split('.').map(Number);
75
- const is_pre_1_0 = major === 0;
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 {BumpType} from './semver.js';
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;