@fuzdev/fuz_gitops 0.78.0 → 0.79.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 (196) hide show
  1. package/README.md +91 -17
  2. package/dist/ModulesDetail.svelte +22 -27
  3. package/dist/ModulesDetail.svelte.d.ts.map +1 -1
  4. package/dist/ModulesNav.svelte +8 -5
  5. package/dist/ModulesNav.svelte.d.ts.map +1 -1
  6. package/dist/ModulesPage.svelte +3 -5
  7. package/dist/ModulesPage.svelte.d.ts.map +1 -1
  8. package/dist/PageFooter.svelte +2 -2
  9. package/dist/PageHeader.svelte +6 -6
  10. package/dist/PageHeader.svelte.d.ts +0 -3
  11. package/dist/PageHeader.svelte.d.ts.map +1 -1
  12. package/dist/PullRequestsDetail.svelte +29 -20
  13. package/dist/PullRequestsDetail.svelte.d.ts.map +1 -1
  14. package/dist/PullRequestsPage.svelte +4 -6
  15. package/dist/PullRequestsPage.svelte.d.ts.map +1 -1
  16. package/dist/ReposTable.svelte +43 -55
  17. package/dist/ReposTable.svelte.d.ts.map +1 -1
  18. package/dist/ReposTree.svelte +9 -21
  19. package/dist/ReposTree.svelte.d.ts.map +1 -1
  20. package/dist/ReposTreeNav.svelte +9 -12
  21. package/dist/ReposTreeNav.svelte.d.ts.map +1 -1
  22. package/dist/TablePage.svelte +3 -5
  23. package/dist/TablePage.svelte.d.ts.map +1 -1
  24. package/dist/TreeItemPage.svelte +3 -5
  25. package/dist/TreeItemPage.svelte.d.ts.map +1 -1
  26. package/dist/TreePage.svelte +3 -5
  27. package/dist/TreePage.svelte.d.ts.map +1 -1
  28. package/dist/changeset_generator.d.ts.map +1 -1
  29. package/dist/changeset_generator.js +2 -2
  30. package/dist/changeset_reader.d.ts.map +1 -1
  31. package/dist/changeset_reader.js +3 -3
  32. package/dist/ci_reconcile.d.ts +6 -10
  33. package/dist/ci_reconcile.d.ts.map +1 -1
  34. package/dist/ci_reconcile.js +6 -8
  35. package/dist/dependency_graph.d.ts +26 -49
  36. package/dist/dependency_graph.d.ts.map +1 -1
  37. package/dist/dependency_graph.js +40 -83
  38. package/dist/dependency_updater.d.ts +1 -1
  39. package/dist/dependency_updater.d.ts.map +1 -1
  40. package/dist/dependency_updater.js +14 -9
  41. package/dist/fetch_repo_data.d.ts +34 -8
  42. package/dist/fetch_repo_data.d.ts.map +1 -1
  43. package/dist/fetch_repo_data.js +44 -22
  44. package/dist/fs_fetch_value_cache.d.ts +1 -1
  45. package/dist/fs_fetch_value_cache.d.ts.map +1 -1
  46. package/dist/fs_fetch_value_cache.js +3 -3
  47. package/dist/git_operations.d.ts +6 -49
  48. package/dist/git_operations.d.ts.map +1 -1
  49. package/dist/git_operations.js +13 -126
  50. package/dist/github.d.ts +17 -2
  51. package/dist/github.d.ts.map +1 -1
  52. package/dist/github.js +17 -8
  53. package/dist/github_helpers.d.ts.map +1 -1
  54. package/dist/github_helpers.js +3 -11
  55. package/dist/gitops_analyze.task.d.ts +24 -2
  56. package/dist/gitops_analyze.task.d.ts.map +1 -1
  57. package/dist/gitops_analyze.task.js +47 -34
  58. package/dist/gitops_config.d.ts +34 -79
  59. package/dist/gitops_config.d.ts.map +1 -1
  60. package/dist/gitops_config.js +76 -53
  61. package/dist/gitops_constants.d.ts +6 -4
  62. package/dist/gitops_constants.d.ts.map +1 -1
  63. package/dist/gitops_constants.js +6 -4
  64. package/dist/gitops_plan.task.d.ts +29 -3
  65. package/dist/gitops_plan.task.d.ts.map +1 -1
  66. package/dist/gitops_plan.task.js +83 -61
  67. package/dist/gitops_publish.task.d.ts +62 -2
  68. package/dist/gitops_publish.task.d.ts.map +1 -1
  69. package/dist/gitops_publish.task.js +193 -105
  70. package/dist/gitops_run.task.d.ts +74 -0
  71. package/dist/gitops_run.task.d.ts.map +1 -1
  72. package/dist/gitops_run.task.js +176 -162
  73. package/dist/gitops_sync.task.d.ts +65 -3
  74. package/dist/gitops_sync.task.d.ts.map +1 -1
  75. package/dist/gitops_sync.task.js +163 -37
  76. package/dist/gitops_task_helpers.d.ts +86 -59
  77. package/dist/gitops_task_helpers.d.ts.map +1 -1
  78. package/dist/gitops_task_helpers.js +120 -79
  79. package/dist/gitops_validate.task.d.ts +1 -2
  80. package/dist/gitops_validate.task.d.ts.map +1 -1
  81. package/dist/gitops_validate.task.js +25 -32
  82. package/dist/graph_validation.d.ts +16 -27
  83. package/dist/graph_validation.d.ts.map +1 -1
  84. package/dist/graph_validation.js +24 -65
  85. package/dist/local_repo.d.ts +50 -62
  86. package/dist/local_repo.d.ts.map +1 -1
  87. package/dist/local_repo.js +83 -196
  88. package/dist/log_helpers.d.ts +8 -8
  89. package/dist/log_helpers.d.ts.map +1 -1
  90. package/dist/multi_repo_publisher.d.ts +10 -0
  91. package/dist/multi_repo_publisher.d.ts.map +1 -1
  92. package/dist/multi_repo_publisher.js +125 -61
  93. package/dist/npm_registry.d.ts +23 -19
  94. package/dist/npm_registry.d.ts.map +1 -1
  95. package/dist/npm_registry.js +21 -48
  96. package/dist/operations.d.ts +75 -180
  97. package/dist/operations.d.ts.map +1 -1
  98. package/dist/operations.js +15 -7
  99. package/dist/operations_defaults.d.ts +17 -2
  100. package/dist/operations_defaults.d.ts.map +1 -1
  101. package/dist/operations_defaults.js +111 -128
  102. package/dist/output_helpers.d.ts +36 -0
  103. package/dist/output_helpers.d.ts.map +1 -1
  104. package/dist/output_helpers.js +37 -3
  105. package/dist/preflight_checks.d.ts +20 -27
  106. package/dist/preflight_checks.d.ts.map +1 -1
  107. package/dist/preflight_checks.js +37 -126
  108. package/dist/publish_gate.d.ts.map +1 -1
  109. package/dist/publish_steps.d.ts +2 -4
  110. package/dist/publish_steps.d.ts.map +1 -1
  111. package/dist/publish_steps.js +4 -8
  112. package/dist/publishing_event.d.ts +2 -8
  113. package/dist/publishing_event.d.ts.map +1 -1
  114. package/dist/publishing_event.js +20 -17
  115. package/dist/publishing_event_handler.d.ts +10 -8
  116. package/dist/publishing_event_handler.d.ts.map +1 -1
  117. package/dist/publishing_event_handler.js +19 -17
  118. package/dist/publishing_plan.d.ts +16 -1
  119. package/dist/publishing_plan.d.ts.map +1 -1
  120. package/dist/publishing_plan.js +332 -254
  121. package/dist/publishing_plan_helpers.d.ts.map +1 -1
  122. package/dist/publishing_plan_helpers.js +3 -3
  123. package/dist/publishing_plan_logging.d.ts +1 -1
  124. package/dist/publishing_plan_logging.d.ts.map +1 -1
  125. package/dist/publishing_plan_logging.js +22 -15
  126. package/dist/repo.svelte.d.ts +7 -0
  127. package/dist/repo.svelte.d.ts.map +1 -1
  128. package/dist/repo.svelte.js +3 -0
  129. package/dist/repo_readiness.d.ts +210 -0
  130. package/dist/repo_readiness.d.ts.map +1 -0
  131. package/dist/repo_readiness.js +516 -0
  132. package/dist/repos_status.d.ts +3340 -0
  133. package/dist/repos_status.d.ts.map +1 -0
  134. package/dist/repos_status.js +555 -0
  135. package/dist/repos_status_load.d.ts +65 -0
  136. package/dist/repos_status_load.d.ts.map +1 -0
  137. package/dist/repos_status_load.js +131 -0
  138. package/dist/version_utils.js +1 -1
  139. package/package.json +15 -34
  140. package/src/lib/cargo_toml.ts +3 -3
  141. package/src/lib/changeset_generator.ts +19 -19
  142. package/src/lib/changeset_reader.ts +18 -18
  143. package/src/lib/ci_reconcile.ts +12 -16
  144. package/src/lib/dependency_graph.ts +61 -113
  145. package/src/lib/dependency_updater.ts +36 -30
  146. package/src/lib/fetch_repo_data.ts +71 -34
  147. package/src/lib/fs_fetch_value_cache.ts +15 -11
  148. package/src/lib/git_operations.ts +22 -194
  149. package/src/lib/github.ts +33 -21
  150. package/src/lib/github_helpers.ts +9 -16
  151. package/src/lib/gitops_analyze.task.ts +104 -66
  152. package/src/lib/gitops_config.ts +90 -139
  153. package/src/lib/gitops_constants.ts +6 -4
  154. package/src/lib/gitops_plan.task.ts +128 -76
  155. package/src/lib/gitops_publish.task.ts +280 -144
  156. package/src/lib/gitops_run.task.ts +265 -193
  157. package/src/lib/gitops_sync.task.ts +236 -52
  158. package/src/lib/gitops_task_helpers.ts +170 -114
  159. package/src/lib/gitops_validate.task.ts +44 -54
  160. package/src/lib/graph_validation.ts +28 -89
  161. package/src/lib/local_repo.ts +128 -335
  162. package/src/lib/log_helpers.ts +18 -28
  163. package/src/lib/multi_repo_publisher.ts +192 -110
  164. package/src/lib/npm_registry.ts +42 -67
  165. package/src/lib/operations.ts +99 -160
  166. package/src/lib/operations_defaults.ts +157 -201
  167. package/src/lib/output_helpers.ts +58 -6
  168. package/src/lib/preflight_checks.ts +52 -188
  169. package/src/lib/publish_gate.ts +7 -9
  170. package/src/lib/publish_steps.ts +27 -25
  171. package/src/lib/publishing_event.ts +26 -23
  172. package/src/lib/publishing_event_handler.ts +24 -22
  173. package/src/lib/publishing_plan.ts +474 -310
  174. package/src/lib/publishing_plan_helpers.ts +16 -12
  175. package/src/lib/publishing_plan_logging.ts +53 -44
  176. package/src/lib/repo.svelte.ts +16 -8
  177. package/src/lib/repo_readiness.ts +647 -0
  178. package/src/lib/repos_status.ts +671 -0
  179. package/src/lib/repos_status_load.ts +173 -0
  180. package/src/lib/version_utils.ts +3 -3
  181. package/dist/config_reconcile.d.ts +0 -46
  182. package/dist/config_reconcile.d.ts.map +0 -1
  183. package/dist/config_reconcile.js +0 -60
  184. package/dist/paths.d.ts +0 -7
  185. package/dist/paths.d.ts.map +0 -1
  186. package/dist/paths.js +0 -6
  187. package/dist/repo_ops.d.ts +0 -59
  188. package/dist/repo_ops.d.ts.map +0 -1
  189. package/dist/repo_ops.js +0 -170
  190. package/dist/resolved_gitops_config.d.ts +0 -9
  191. package/dist/resolved_gitops_config.d.ts.map +0 -1
  192. package/dist/resolved_gitops_config.js +0 -12
  193. package/src/lib/config_reconcile.ts +0 -94
  194. package/src/lib/paths.ts +0 -6
  195. package/src/lib/repo_ops.ts +0 -216
  196. package/src/lib/resolved_gitops_config.ts +0 -27
@@ -1,40 +1,49 @@
1
- import type {Task} from '@fuzdev/gro';
2
- import {z} from 'zod';
3
- import {styleText as st} from 'node:util';
1
+ import type { Task } from '@fuzdev/gro';
2
+ import type { Logger } from '@fuzdev/fuz_util/log.ts';
3
+ import { z } from 'zod';
4
+ import { styleText as st } from 'node:util';
4
5
 
5
- import {get_gitops_ready} from './gitops_task_helpers.ts';
6
+ import {
7
+ get_gitops_ready,
8
+ log_readiness_block,
9
+ type ResolveGitopsReposOptions
10
+ } from './gitops_task_helpers.ts';
11
+ import type { LocalRepo } from './local_repo.ts';
12
+ import type { ChangesetOperations } from './operations.ts';
13
+ import { default_changeset_operations } from './operations_defaults.ts';
6
14
  import {
7
15
  generate_publishing_plan,
8
- log_publishing_plan,
9
- type PublishingPlan,
10
- type LogPlanOptions,
16
+ version_change_kind,
17
+ type PublishingPlan
11
18
  } from './publishing_plan.ts';
12
- import {format_and_output, type OutputFormatters} from './output_helpers.ts';
13
- import {GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.ts';
19
+ import { log_publishing_plan, type LogPlanOptions } from './publishing_plan_logging.ts';
20
+ import {
21
+ format_and_output,
22
+ output_is_machine,
23
+ route_human_output,
24
+ type OutputFormatters
25
+ } from './output_helpers.ts';
26
+ import { GITOPS_CONFIG_PATH_DEFAULT } from './gitops_constants.ts';
14
27
 
15
28
  /** @nodocs */
16
29
  export const Args = z.strictObject({
17
30
  config: z
18
31
  .string()
19
- .meta({description: 'path to the gitops config file, absolute or relative to the cwd'})
32
+ .meta({ description: 'path to the gitops config file, absolute or relative to the cwd' })
20
33
  .default(GITOPS_CONFIG_PATH_DEFAULT),
21
- dir: z
34
+ registry: z
22
35
  .string()
23
- .meta({description: 'path containing the repos, defaults to the parent of the config dir'})
36
+ .meta({
37
+ description:
38
+ 'path to the repos.toml registry, when `repos` would not find it walking up from the cwd'
39
+ })
24
40
  .optional(),
25
41
  format: z
26
42
  .enum(['stdout', 'json', 'markdown'])
27
- .meta({description: 'output format'})
43
+ .meta({ description: 'output format' })
28
44
  .default('stdout'),
29
- outfile: z.string().meta({description: 'write output to file instead of logging'}).optional(),
30
- verbose: z.boolean().meta({description: 'show additional details'}).default(false),
31
- sync: z
32
- .boolean()
33
- .meta({
34
- description:
35
- 'sync repos (switch branch, pull, install) before planning instead of reading the working tree as-is',
36
- })
37
- .default(false),
45
+ outfile: z.string().meta({ description: 'write output to file instead of logging' }).optional(),
46
+ verbose: z.boolean().meta({ description: 'show additional details' }).default(false)
38
47
  });
39
48
  export type Args = z.infer<typeof Args>;
40
49
 
@@ -44,7 +53,7 @@ export type Args = z.infer<typeof Args>;
44
53
  *
45
54
  * Usage:
46
55
  * `gro gitops_plan`
47
- * `gro gitops_plan --dir ../repos`
56
+ * `gro gitops_plan --registry ../repos.toml`
48
57
  * `gro gitops_plan --config ./custom.config.ts`
49
58
  *
50
59
  * @nodocs
@@ -52,42 +61,73 @@ export type Args = z.infer<typeof Args>;
52
61
  export const task: Task<Args> = {
53
62
  summary: 'generate a publishing plan based on changesets',
54
63
  Args,
55
- run: async ({args, log}): Promise<void> => {
56
- const {dir, config, format, outfile, verbose, sync} = args;
64
+ run: async ({ args, log }): Promise<void> => {
65
+ await run_gitops_plan(args, log);
66
+ }
67
+ };
68
+
69
+ /**
70
+ * The side effects `run_gitops_plan` reaches through, injectable for tests.
71
+ *
72
+ * @nodocs
73
+ */
74
+ export interface GitopsPlanDeps {
75
+ /** Loads the configured repos as they sit (`get_gitops_ready`). */
76
+ load_repos: (options: ResolveGitopsReposOptions) => Promise<{ local_repos: Array<LocalRepo> }>;
77
+ /** Reads each repo's changesets for the plan. */
78
+ changeset_ops: ChangesetOperations;
79
+ }
57
80
 
58
- log.info(st('cyan', 'Generating multi-repo publishing plan...'));
81
+ const default_gitops_plan_deps: GitopsPlanDeps = {
82
+ load_repos: get_gitops_ready,
83
+ changeset_ops: default_changeset_operations
84
+ };
59
85
 
60
- // Load local repos; read the working tree as-is unless `--sync`
61
- const {local_repos} = await get_gitops_ready({
62
- config,
63
- dir,
64
- download: false, // Don't download if missing
65
- sync,
66
- log,
67
- });
86
+ /**
87
+ * Runs `gro gitops_plan`: loads the repos as they sit, logs the readiness
88
+ * block, generates the plan, and outputs it. Under `--format json` or
89
+ * `markdown` without `--outfile`, the log goes to stderr and stdout carries
90
+ * the document alone (`route_human_output`).
91
+ *
92
+ * @throws {Error} when the plan has errors that would block publishing, after outputting it
93
+ * @nodocs
94
+ */
95
+ export const run_gitops_plan = async (
96
+ args: Args,
97
+ log: Logger,
98
+ deps: Partial<GitopsPlanDeps> = {}
99
+ ): Promise<void> => {
100
+ const { load_repos, changeset_ops } = { ...default_gitops_plan_deps, ...deps };
101
+ const { config, registry, format, outfile, verbose } = args;
102
+ const write_stdout = route_human_output(log, output_is_machine(format, outfile));
68
103
 
69
- if (local_repos.length === 0) {
70
- log.error('No local repos found');
71
- return;
72
- }
104
+ log.info(st('cyan', 'Generating multi-repo publishing plan...'));
73
105
 
74
- log.info(` Found ${local_repos.length} local repos`);
106
+ // Load local repos as they sit, and say which aren't at rest
107
+ const { local_repos } = await load_repos({ config, registry, log });
108
+ log_readiness_block(local_repos, log);
75
109
 
76
- // Generate publishing plan
77
- const plan = await generate_publishing_plan(local_repos, {log, verbose});
110
+ log.info(` Found ${local_repos.length} local repos`);
78
111
 
79
- // Format and output using output_helpers
80
- await format_and_output(plan, create_plan_formatters({verbose}), {format, outfile, log});
112
+ // Generate publishing plan
113
+ const plan = await generate_publishing_plan(local_repos, { log, verbose, ops: changeset_ops });
81
114
 
82
- // Exit with error if there are blocking issues
83
- if (plan.errors.length > 0) {
84
- throw new Error('Publishing plan found errors that would block publishing');
85
- }
86
- },
115
+ // Format and output using output_helpers
116
+ await format_and_output(plan, create_plan_formatters({ verbose }), {
117
+ format,
118
+ outfile,
119
+ log,
120
+ write_stdout
121
+ });
122
+
123
+ // Exit with error if there are blocking issues
124
+ if (plan.errors.length > 0) {
125
+ throw new Error('Publishing plan found errors that would block publishing');
126
+ }
87
127
  };
88
128
 
89
129
  const create_plan_formatters = (
90
- options: LogPlanOptions = {},
130
+ options: LogPlanOptions = {}
91
131
  ): OutputFormatters<PublishingPlan> => ({
92
132
  json: (plan) => {
93
133
  const output = {
@@ -97,12 +137,13 @@ const create_plan_formatters = (
97
137
  breaking_cascades: Object.fromEntries(plan.breaking_cascades),
98
138
  warnings: plan.warnings,
99
139
  info: plan.info,
100
- errors: plan.errors,
140
+ no_changes: plan.no_changes,
141
+ errors: plan.errors
101
142
  };
102
143
  return JSON.stringify(output, null, 2);
103
144
  },
104
145
  markdown: (plan) => format_plan_as_markdown(plan),
105
- stdout: (plan, log) => log_publishing_plan(plan, log, options),
146
+ stdout: (plan, log) => log_publishing_plan(plan, log, options)
106
147
  });
107
148
 
108
149
  const format_plan_as_markdown = (plan: PublishingPlan): Array<string> => {
@@ -114,7 +155,8 @@ const format_plan_as_markdown = (plan: PublishingPlan): Array<string> => {
114
155
  breaking_cascades,
115
156
  warnings,
116
157
  info,
117
- errors,
158
+ no_changes,
159
+ errors
118
160
  } = plan;
119
161
 
120
162
  lines.push('# Publishing Plan');
@@ -140,21 +182,21 @@ const format_plan_as_markdown = (plan: PublishingPlan): Array<string> => {
140
182
 
141
183
  // Version changes
142
184
  if (version_changes.length > 0) {
143
- const with_changesets = version_changes.filter(
144
- (vc) => vc.has_changesets && !vc.needs_bump_escalation,
185
+ const with_changesets = version_changes.filter((vc) => version_change_kind(vc) === 'explicit');
186
+ const with_escalation = version_changes.filter(
187
+ (vc) => version_change_kind(vc) === 'escalation'
145
188
  );
146
- const with_escalation = version_changes.filter((vc) => vc.needs_bump_escalation);
147
- const with_auto_changesets = version_changes.filter((vc) => vc.will_generate_changeset);
189
+ const with_auto_changesets = version_changes.filter((vc) => version_change_kind(vc) === 'auto');
148
190
 
149
191
  if (with_changesets.length > 0) {
150
192
  lines.push('## Version Changes (from changesets)');
151
193
  lines.push('');
152
- lines.push('| Package | From | To | Bump | Major |');
153
- lines.push('|---------|------|----|------|-------|');
194
+ lines.push('| Package | From | To | Bump | Breaking |');
195
+ lines.push('|---------|------|----|------|----------|');
154
196
  for (const change of with_changesets) {
155
- const is_major = change.bump_type === 'major' ? '💥 Yes' : 'No';
197
+ const breaking = change.breaking ? '💥 Yes' : 'No';
156
198
  lines.push(
157
- `| \`${change.package_name}\` | ${change.from} | ${change.to} | ${change.bump_type} | ${is_major} |`,
199
+ `| \`${change.package_name}\` | ${change.from} | ${change.to} | ${change.bump_type} | ${breaking} |`
158
200
  );
159
201
  }
160
202
  lines.push('');
@@ -163,17 +205,17 @@ const format_plan_as_markdown = (plan: PublishingPlan): Array<string> => {
163
205
  if (with_escalation.length > 0) {
164
206
  lines.push('## Version Changes (bump escalation required)');
165
207
  lines.push('');
166
- lines.push('| Package | From | To | Changesets Bump | Required Bump | Major |');
167
- lines.push('|---------|------|-----|-----------------|---------------|-------|');
208
+ lines.push('| Package | From | To | Changesets Bump | Required Bump | Breaking |');
209
+ lines.push('|---------|------|-----|-----------------|---------------|----------|');
168
210
  for (const change of with_escalation) {
169
- const is_major = change.bump_type === 'major' ? '💥 Yes' : 'No';
211
+ const breaking = change.breaking ? '💥 Yes' : 'No';
170
212
  lines.push(
171
- `| \`${change.package_name}\` | ${change.from} | ${change.to} | ${change.existing_bump} | ${change.required_bump} | ${is_major} |`,
213
+ `| \`${change.package_name}\` | ${change.from} | ${change.to} | ${change.existing_bump} | ${change.required_bump} | ${breaking} |`
172
214
  );
173
215
  }
174
216
  lines.push('');
175
217
  lines.push(
176
- '> ⬆️ These packages have changesets, but dependencies require a larger version bump.',
218
+ '> ⬆️ These packages have changesets, but dependencies require a larger version bump.'
177
219
  );
178
220
  lines.push('');
179
221
  }
@@ -181,12 +223,12 @@ const format_plan_as_markdown = (plan: PublishingPlan): Array<string> => {
181
223
  if (with_auto_changesets.length > 0) {
182
224
  lines.push('## Version Changes (auto-generated for dependency updates)');
183
225
  lines.push('');
184
- lines.push('| Package | From | To | Bump | Major |');
185
- lines.push('|---------|------|-----|------|-------|');
226
+ lines.push('| Package | From | To | Bump | Breaking |');
227
+ lines.push('|---------|------|-----|------|----------|');
186
228
  for (const change of with_auto_changesets) {
187
- const is_major = change.bump_type === 'major' ? '💥 Yes' : 'No';
229
+ const breaking = change.breaking ? '💥 Yes' : 'No';
188
230
  lines.push(
189
- `| \`${change.package_name}\` | ${change.from} | ${change.to} | ${change.bump_type} | ${is_major} |`,
231
+ `| \`${change.package_name}\` | ${change.from} | ${change.to} | ${change.bump_type} | ${breaking} |`
190
232
  );
191
233
  }
192
234
  lines.push('');
@@ -234,7 +276,7 @@ const format_plan_as_markdown = (plan: PublishingPlan): Array<string> => {
234
276
  ? 'peer'
235
277
  : 'dev';
236
278
  lines.push(
237
- `- "${update.updated_dependency}": "${update.current_version}" # ${type_label}`,
279
+ `- "${update.updated_dependency}": "${update.current_version}" # ${type_label}`
238
280
  );
239
281
  lines.push(`+ "${update.updated_dependency}": "${update.new_version}" # ${type_label}`);
240
282
  }
@@ -255,25 +297,35 @@ const format_plan_as_markdown = (plan: PublishingPlan): Array<string> => {
255
297
  lines.push('');
256
298
  }
257
299
 
258
- // Info (packages with no changes - normal status)
300
+ // Info (normal status, not warnings)
259
301
  if (info.length > 0) {
260
- lines.push('## ℹ️ No Changes to Publish');
302
+ lines.push('## ℹ️ Info');
303
+ lines.push('');
304
+ for (const line of info) {
305
+ lines.push(`- ${line}`);
306
+ }
307
+ lines.push('');
308
+ }
309
+
310
+ // Packages with nothing to publish (normal status)
311
+ if (no_changes.length > 0) {
312
+ lines.push('## No Changes to Publish');
261
313
  lines.push('');
262
- lines.push('*These packages have no changesets and no dependency updates:*');
314
+ lines.push('*These packages have no changesets and nothing to publish:*');
263
315
  lines.push('');
264
- for (const pkg of info) {
316
+ for (const pkg of no_changes) {
265
317
  lines.push(`- \`${pkg}\``);
266
318
  }
267
319
  lines.push('');
268
320
  }
269
321
 
270
322
  // Summary
271
- const major_bump_count = version_changes.filter((vc) => vc.bump_type === 'major').length;
323
+ const breaking_count = version_changes.filter((vc) => vc.breaking).length;
272
324
  lines.push('## Summary');
273
325
  lines.push('');
274
326
  lines.push(`- **Packages to publish**: ${version_changes.length}`);
275
327
  lines.push(`- **Dependency updates**: ${dependency_updates.length}`);
276
- lines.push(`- **Major version bumps**: ${major_bump_count}`);
328
+ lines.push(`- **Breaking changes**: ${breaking_count}`);
277
329
  lines.push(`- **Warnings**: ${warnings.length}`);
278
330
  lines.push(`- **Errors**: ${errors.length}`);
279
331