@fuzdev/fuz_gitops 0.78.1 → 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 (179) hide show
  1. package/README.md +78 -24
  2. package/dist/ModulesDetail.svelte +15 -22
  3. package/dist/ModulesDetail.svelte.d.ts.map +1 -1
  4. package/dist/ModulesNav.svelte +4 -1
  5. package/dist/ModulesPage.svelte +1 -3
  6. package/dist/ModulesPage.svelte.d.ts.map +1 -1
  7. package/dist/PageHeader.svelte +2 -2
  8. package/dist/PageHeader.svelte.d.ts +0 -3
  9. package/dist/PageHeader.svelte.d.ts.map +1 -1
  10. package/dist/PullRequestsDetail.svelte +10 -9
  11. package/dist/PullRequestsDetail.svelte.d.ts.map +1 -1
  12. package/dist/PullRequestsPage.svelte +1 -3
  13. package/dist/PullRequestsPage.svelte.d.ts.map +1 -1
  14. package/dist/ReposTable.svelte +27 -48
  15. package/dist/ReposTable.svelte.d.ts.map +1 -1
  16. package/dist/ReposTree.svelte +5 -19
  17. package/dist/ReposTree.svelte.d.ts.map +1 -1
  18. package/dist/ReposTreeNav.svelte +5 -7
  19. package/dist/ReposTreeNav.svelte.d.ts.map +1 -1
  20. package/dist/TablePage.svelte +1 -3
  21. package/dist/TablePage.svelte.d.ts.map +1 -1
  22. package/dist/TreeItemPage.svelte +1 -3
  23. package/dist/TreeItemPage.svelte.d.ts.map +1 -1
  24. package/dist/TreePage.svelte +1 -3
  25. package/dist/TreePage.svelte.d.ts.map +1 -1
  26. package/dist/ci_reconcile.d.ts +6 -10
  27. package/dist/ci_reconcile.d.ts.map +1 -1
  28. package/dist/ci_reconcile.js +6 -8
  29. package/dist/dependency_graph.d.ts +26 -49
  30. package/dist/dependency_graph.d.ts.map +1 -1
  31. package/dist/dependency_graph.js +37 -80
  32. package/dist/dependency_updater.d.ts +1 -1
  33. package/dist/dependency_updater.d.ts.map +1 -1
  34. package/dist/dependency_updater.js +6 -1
  35. package/dist/fetch_repo_data.d.ts +34 -8
  36. package/dist/fetch_repo_data.d.ts.map +1 -1
  37. package/dist/fetch_repo_data.js +44 -22
  38. package/dist/fs_fetch_value_cache.d.ts +1 -1
  39. package/dist/fs_fetch_value_cache.js +1 -1
  40. package/dist/git_operations.d.ts +6 -49
  41. package/dist/git_operations.d.ts.map +1 -1
  42. package/dist/git_operations.js +13 -126
  43. package/dist/github.d.ts +17 -2
  44. package/dist/github.d.ts.map +1 -1
  45. package/dist/github.js +15 -6
  46. package/dist/github_helpers.d.ts.map +1 -1
  47. package/dist/github_helpers.js +3 -11
  48. package/dist/gitops_analyze.task.d.ts +24 -2
  49. package/dist/gitops_analyze.task.d.ts.map +1 -1
  50. package/dist/gitops_analyze.task.js +43 -30
  51. package/dist/gitops_config.d.ts +34 -79
  52. package/dist/gitops_config.d.ts.map +1 -1
  53. package/dist/gitops_config.js +76 -53
  54. package/dist/gitops_constants.d.ts +6 -4
  55. package/dist/gitops_constants.d.ts.map +1 -1
  56. package/dist/gitops_constants.js +6 -4
  57. package/dist/gitops_plan.task.d.ts +29 -3
  58. package/dist/gitops_plan.task.d.ts.map +1 -1
  59. package/dist/gitops_plan.task.js +80 -58
  60. package/dist/gitops_publish.task.d.ts +62 -2
  61. package/dist/gitops_publish.task.d.ts.map +1 -1
  62. package/dist/gitops_publish.task.js +187 -102
  63. package/dist/gitops_run.task.d.ts +74 -0
  64. package/dist/gitops_run.task.d.ts.map +1 -1
  65. package/dist/gitops_run.task.js +174 -160
  66. package/dist/gitops_sync.task.d.ts +65 -3
  67. package/dist/gitops_sync.task.d.ts.map +1 -1
  68. package/dist/gitops_sync.task.js +154 -30
  69. package/dist/gitops_task_helpers.d.ts +86 -59
  70. package/dist/gitops_task_helpers.d.ts.map +1 -1
  71. package/dist/gitops_task_helpers.js +120 -79
  72. package/dist/gitops_validate.task.d.ts +1 -2
  73. package/dist/gitops_validate.task.d.ts.map +1 -1
  74. package/dist/gitops_validate.task.js +15 -22
  75. package/dist/graph_validation.d.ts +16 -27
  76. package/dist/graph_validation.d.ts.map +1 -1
  77. package/dist/graph_validation.js +23 -64
  78. package/dist/local_repo.d.ts +50 -62
  79. package/dist/local_repo.d.ts.map +1 -1
  80. package/dist/local_repo.js +80 -193
  81. package/dist/log_helpers.d.ts +8 -8
  82. package/dist/log_helpers.d.ts.map +1 -1
  83. package/dist/multi_repo_publisher.d.ts +10 -0
  84. package/dist/multi_repo_publisher.d.ts.map +1 -1
  85. package/dist/multi_repo_publisher.js +115 -51
  86. package/dist/npm_registry.d.ts +23 -19
  87. package/dist/npm_registry.d.ts.map +1 -1
  88. package/dist/npm_registry.js +20 -47
  89. package/dist/operations.d.ts +75 -180
  90. package/dist/operations.d.ts.map +1 -1
  91. package/dist/operations.js +15 -7
  92. package/dist/operations_defaults.d.ts +17 -2
  93. package/dist/operations_defaults.d.ts.map +1 -1
  94. package/dist/operations_defaults.js +104 -121
  95. package/dist/output_helpers.d.ts +36 -0
  96. package/dist/output_helpers.d.ts.map +1 -1
  97. package/dist/output_helpers.js +37 -3
  98. package/dist/preflight_checks.d.ts +20 -27
  99. package/dist/preflight_checks.d.ts.map +1 -1
  100. package/dist/preflight_checks.js +37 -126
  101. package/dist/publish_steps.d.ts +2 -4
  102. package/dist/publish_steps.d.ts.map +1 -1
  103. package/dist/publish_steps.js +2 -6
  104. package/dist/publishing_event.d.ts +2 -8
  105. package/dist/publishing_event.d.ts.map +1 -1
  106. package/dist/publishing_event.js +5 -4
  107. package/dist/publishing_event_handler.d.ts +10 -8
  108. package/dist/publishing_event_handler.d.ts.map +1 -1
  109. package/dist/publishing_event_handler.js +14 -12
  110. package/dist/publishing_plan.d.ts +16 -1
  111. package/dist/publishing_plan.d.ts.map +1 -1
  112. package/dist/publishing_plan.js +328 -250
  113. package/dist/publishing_plan_logging.d.ts +1 -1
  114. package/dist/publishing_plan_logging.d.ts.map +1 -1
  115. package/dist/publishing_plan_logging.js +21 -14
  116. package/dist/repo.svelte.d.ts +7 -0
  117. package/dist/repo.svelte.d.ts.map +1 -1
  118. package/dist/repo.svelte.js +3 -0
  119. package/dist/repo_readiness.d.ts +210 -0
  120. package/dist/repo_readiness.d.ts.map +1 -0
  121. package/dist/repo_readiness.js +516 -0
  122. package/dist/repos_status.d.ts +3340 -0
  123. package/dist/repos_status.d.ts.map +1 -0
  124. package/dist/repos_status.js +555 -0
  125. package/dist/repos_status_load.d.ts +65 -0
  126. package/dist/repos_status_load.d.ts.map +1 -0
  127. package/dist/repos_status_load.js +131 -0
  128. package/package.json +7 -27
  129. package/src/lib/ci_reconcile.ts +7 -11
  130. package/src/lib/dependency_graph.ts +45 -97
  131. package/src/lib/dependency_updater.ts +7 -1
  132. package/src/lib/fetch_repo_data.ts +66 -29
  133. package/src/lib/fs_fetch_value_cache.ts +1 -1
  134. package/src/lib/git_operations.ts +15 -187
  135. package/src/lib/github.ts +20 -8
  136. package/src/lib/github_helpers.ts +5 -12
  137. package/src/lib/gitops_analyze.task.ts +79 -41
  138. package/src/lib/gitops_config.ts +88 -137
  139. package/src/lib/gitops_constants.ts +6 -4
  140. package/src/lib/gitops_plan.task.ts +113 -61
  141. package/src/lib/gitops_publish.task.ts +255 -122
  142. package/src/lib/gitops_run.task.ts +250 -178
  143. package/src/lib/gitops_sync.task.ts +208 -33
  144. package/src/lib/gitops_task_helpers.ts +166 -110
  145. package/src/lib/gitops_validate.task.ts +17 -27
  146. package/src/lib/graph_validation.ts +25 -86
  147. package/src/lib/local_repo.ts +109 -316
  148. package/src/lib/log_helpers.ts +8 -18
  149. package/src/lib/multi_repo_publisher.ts +138 -53
  150. package/src/lib/npm_registry.ts +37 -62
  151. package/src/lib/operations.ts +78 -150
  152. package/src/lib/operations_defaults.ts +108 -154
  153. package/src/lib/output_helpers.ts +55 -3
  154. package/src/lib/preflight_checks.ts +47 -183
  155. package/src/lib/publish_steps.ts +15 -13
  156. package/src/lib/publishing_event.ts +5 -4
  157. package/src/lib/publishing_event_handler.ts +18 -16
  158. package/src/lib/publishing_plan.ts +451 -287
  159. package/src/lib/publishing_plan_logging.ts +32 -23
  160. package/src/lib/repo.svelte.ts +8 -0
  161. package/src/lib/repo_readiness.ts +647 -0
  162. package/src/lib/repos_status.ts +671 -0
  163. package/src/lib/repos_status_load.ts +173 -0
  164. package/dist/config_reconcile.d.ts +0 -46
  165. package/dist/config_reconcile.d.ts.map +0 -1
  166. package/dist/config_reconcile.js +0 -64
  167. package/dist/paths.d.ts +0 -7
  168. package/dist/paths.d.ts.map +0 -1
  169. package/dist/paths.js +0 -6
  170. package/dist/repo_ops.d.ts +0 -59
  171. package/dist/repo_ops.d.ts.map +0 -1
  172. package/dist/repo_ops.js +0 -170
  173. package/dist/resolved_gitops_config.d.ts +0 -9
  174. package/dist/resolved_gitops_config.d.ts.map +0 -1
  175. package/dist/resolved_gitops_config.js +0 -12
  176. package/src/lib/config_reconcile.ts +0 -98
  177. package/src/lib/paths.ts +0 -6
  178. package/src/lib/repo_ops.ts +0 -216
  179. package/src/lib/resolved_gitops_config.ts +0 -27
@@ -2,14 +2,12 @@
2
2
  * Reconciles each repo's declared `ci` flag against whether it actually has
3
3
  * GitHub Actions workflow files on disk.
4
4
  *
5
- * The gitops config derives `ci` from visibility (on for public repos, off for
6
- * private) with per-repo overrides; this check catches drift between that
7
- * declaration and reality —
5
+ * The registry (`repos.toml`) derives `ci` from visibility (on for public repos,
6
+ * off for private) with per-repo overrides; this check catches drift between
7
+ * that declaration and reality —
8
8
  * a repo that claims CI but ships no workflow, or one that disclaims CI yet
9
- * still carries one. Repos that aren't checked out locally can't be judged, so
10
- * the caller marks them uncheckable and they're skipped. Archived repos are
11
- * frozen on their host, so their CI state is intentionally left alone and they're
12
- * skipped too.
9
+ * still carries one. Archived repos are frozen on their host, so their CI state
10
+ * is intentionally left alone and they're skipped.
13
11
  *
14
12
  * @module
15
13
  */
@@ -28,12 +26,10 @@ export interface CiDrift {
28
26
  }
29
27
  export interface CiReconcileInput {
30
28
  repo_url: string;
31
- /** The declared/derived `ci` value from the gitops config. */
29
+ /** The declared/derived `ci` value from the registry. */
32
30
  ci: boolean;
33
31
  /** Whether the repo has at least one workflow file on disk. */
34
32
  has_workflows: boolean;
35
- /** Whether the repo is checked out locally; uncheckable repos are skipped. */
36
- checkable: boolean;
37
33
  /** Whether the repo is archived (frozen) on its host; archived repos are skipped. */
38
34
  archived: boolean;
39
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ci_reconcile.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/ci_reconcile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,2EAA2E;AAC3E,MAAM,MAAM,WAAW;AACtB,yDAAyD;AACvD,YAAY;AACd,uDAAuD;GACrD,UAAU,CAAC;AAEd,MAAM,WAAW,OAAO;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,EAAE,EAAE,OAAO,CAAC;IACZ,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,WAAW,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,EAAE,EAAE,OAAO,CAAC;IACZ,+DAA+D;IAC/D,aAAa,EAAE,OAAO,CAAC;IACvB,8EAA8E;IAC9E,SAAS,EAAE,OAAO,CAAC;IACnB,qFAAqF;IACrF,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,KAAK,CAAC,gBAAgB,CAAC,KAAG,KAAK,CAAC,OAAO,CAY1E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,KAAG,OAIrD,CAAC"}
1
+ {"version":3,"file":"ci_reconcile.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/ci_reconcile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,2EAA2E;AAC3E,MAAM,MAAM,WAAW;AACtB,yDAAyD;AACvD,YAAY;AACd,uDAAuD;GACrD,UAAU,CAAC;AAEd,MAAM,WAAW,OAAO;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,EAAE,EAAE,OAAO,CAAC;IACZ,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,WAAW,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,EAAE,EAAE,OAAO,CAAC;IACZ,+DAA+D;IAC/D,aAAa,EAAE,OAAO,CAAC;IACvB,qFAAqF;IACrF,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,KAAK,CAAC,gBAAgB,CAAC,KAAG,KAAK,CAAC,OAAO,CAY1E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,KAAG,OAIrD,CAAC"}
@@ -2,14 +2,12 @@
2
2
  * Reconciles each repo's declared `ci` flag against whether it actually has
3
3
  * GitHub Actions workflow files on disk.
4
4
  *
5
- * The gitops config derives `ci` from visibility (on for public repos, off for
6
- * private) with per-repo overrides; this check catches drift between that
7
- * declaration and reality —
5
+ * The registry (`repos.toml`) derives `ci` from visibility (on for public repos,
6
+ * off for private) with per-repo overrides; this check catches drift between
7
+ * that declaration and reality —
8
8
  * a repo that claims CI but ships no workflow, or one that disclaims CI yet
9
- * still carries one. Repos that aren't checked out locally can't be judged, so
10
- * the caller marks them uncheckable and they're skipped. Archived repos are
11
- * frozen on their host, so their CI state is intentionally left alone and they're
12
- * skipped too.
9
+ * still carries one. Archived repos are frozen on their host, so their CI state
10
+ * is intentionally left alone and they're skipped.
13
11
  *
14
12
  * @module
15
13
  */
@@ -22,7 +20,7 @@ import { join } from 'node:path';
22
20
  export const reconcile_ci = (repos) => {
23
21
  const drift = [];
24
22
  for (const repo of repos) {
25
- if (!repo.checkable || repo.archived)
23
+ if (repo.archived)
26
24
  continue;
27
25
  const { repo_url, ci, has_workflows } = repo;
28
26
  if (ci && !has_workflows) {
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * Dependency graph data structure and algorithms for multi-repo publishing.
3
3
  *
4
- * Provides `DependencyGraph` class with topological sort (via `@fuzdev/fuz_util/sort.ts`)
5
- * and cycle detection by dependency type.
6
- * For validation workflow and publishing order computation, see `graph_validation.ts`.
4
+ * Provides the `DependencyGraph` class, built from local repos, with topological sort
5
+ * (via `@fuzdev/fuz_util/sort.ts`), cycle detection by dependency type, and
6
+ * wildcard-range analysis.
7
+ * For the publishing order and the analysis workflow, see `graph_validation.ts`.
7
8
  *
8
9
  * @module
9
10
  */
@@ -17,7 +18,6 @@ export type DependencyType = (typeof DEPENDENCY_TYPE)[keyof typeof DEPENDENCY_TY
17
18
  export interface DependencySpec {
18
19
  type: DependencyType;
19
20
  version: string;
20
- resolved?: string;
21
21
  }
22
22
  export interface DependencyGraphJson {
23
23
  nodes: Array<{
@@ -28,7 +28,6 @@ export interface DependencyGraphJson {
28
28
  spec: DependencySpec;
29
29
  }>;
30
30
  dependents: Array<string>;
31
- publishable: boolean;
32
31
  }>;
33
32
  edges: Array<{
34
33
  from: string;
@@ -38,20 +37,32 @@ export interface DependencyGraphJson {
38
37
  export interface DependencyNode {
39
38
  name: string;
40
39
  version: string;
41
- repo?: LocalRepo;
42
40
  dependencies: Map<string, DependencySpec>;
43
41
  dependents: Set<string>;
44
- publishable: boolean;
42
+ }
43
+ /** Cycles and wildcard dependencies found by `DependencyGraph.analyze`. */
44
+ export interface DependencyAnalysis {
45
+ production_cycles: Array<Array<string>>;
46
+ dev_cycles: Array<Array<string>>;
47
+ wildcard_deps: Array<{
48
+ pkg: string;
49
+ dep: string;
50
+ version: string;
51
+ }>;
45
52
  }
46
53
  export declare class DependencyGraph {
47
54
  #private;
48
55
  nodes: Map<string, DependencyNode>;
49
56
  edges: Map<string, Set<string>>;
50
- constructor();
51
- init_from_repos(repos: Array<LocalRepo>): void;
57
+ /**
58
+ * Builds the graph from local repos.
59
+ *
60
+ * Two passes: first creates nodes, then builds edges (dependents).
61
+ * Prioritizes prod/peer deps over dev deps when the same package appears in
62
+ * multiple dependency types (the stronger constraint wins).
63
+ */
64
+ constructor(repos: Array<LocalRepo>);
52
65
  get_node(name: string): DependencyNode | undefined;
53
- get_dependents(name: string): Set<string>;
54
- get_dependencies(name: string): Map<string, DependencySpec>;
55
66
  /**
56
67
  * Computes topological sort order for dependency graph.
57
68
  *
@@ -79,45 +90,11 @@ export declare class DependencyGraph {
79
90
  production_cycles: Array<Array<string>>;
80
91
  dev_cycles: Array<Array<string>>;
81
92
  };
82
- toJSON(): DependencyGraphJson;
83
- }
84
- /**
85
- * Builder for creating and analyzing dependency graphs.
86
- */
87
- export declare class DependencyGraphBuilder {
88
- /**
89
- * Constructs dependency graph from local repos.
90
- *
91
- * Two-pass algorithm: first creates nodes, then builds edges (dependents).
92
- * Prioritizes prod/peer deps over dev deps when same package appears in
93
- * multiple dependency types (stronger constraint wins).
94
- *
95
- * @returns fully initialized dependency graph with all nodes and edges
96
- */
97
- build_from_repos(repos: Array<LocalRepo>): DependencyGraph;
98
93
  /**
99
- * Computes publishing order using topological sort with dev deps excluded.
100
- *
101
- * Excludes dev dependencies to break circular dev dependency cycles while
102
- * preserving production/peer dependency ordering. This allows patterns like
103
- * shared test utilities that depend on each other for development.
104
- *
105
- * @returns package names in safe publishing order (dependencies before dependents)
106
- * @throws {Error} if production/peer cycles detected (cannot be resolved by exclusion)
94
+ * Reports cycles by type and wildcard (`*`) dependency ranges.
95
+ * Tolerates cycles: it reports them rather than throwing.
107
96
  */
108
- compute_publishing_order(graph: DependencyGraph): Array<string>;
109
- analyze(graph: DependencyGraph): {
110
- production_cycles: Array<Array<string>>;
111
- dev_cycles: Array<Array<string>>;
112
- wildcard_deps: Array<{
113
- pkg: string;
114
- dep: string;
115
- version: string;
116
- }>;
117
- missing_peers: Array<{
118
- pkg: string;
119
- dep: string;
120
- }>;
121
- };
97
+ analyze(): DependencyAnalysis;
98
+ toJSON(): DependencyGraphJson;
122
99
  }
123
100
  //# sourceMappingURL=dependency_graph.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dependency_graph.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/dependency_graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dependency_graph.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/dependency_graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,eAAO,MAAM,eAAe;;;;CAIlB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEpF,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IACnC,KAAK,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,cAAc,CAAA;SAAE,CAAC,CAAC;QAC5D,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;KAC1B,CAAC,CAAC;IACH,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACxB;AAED,2EAA2E;AAC3E,MAAM,WAAW,kBAAkB;IAClC,iBAAiB,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACxC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACjC,aAAa,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpE;AAED,qBAAa,eAAe;;IAC3B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAa;IAC/C,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAa;IAE5C;;;;;;OAMG;gBACS,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IA4CnC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIlD;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,WAAW,UAAQ,GAAG,KAAK,CAAC,MAAM,CAAC;IAiBpD;;;;;;;;;;OAUG;IACH,qBAAqB,IAAI;QACxB,iBAAiB,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QACxC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;KACjC;IAMD;;;OAGG;IACH,OAAO,IAAI,kBAAkB;IAyD7B,MAAM,IAAI,mBAAmB;CAoB7B"}
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * Dependency graph data structure and algorithms for multi-repo publishing.
3
3
  *
4
- * Provides `DependencyGraph` class with topological sort (via `@fuzdev/fuz_util/sort.ts`)
5
- * and cycle detection by dependency type.
6
- * For validation workflow and publishing order computation, see `graph_validation.ts`.
4
+ * Provides the `DependencyGraph` class, built from local repos, with topological sort
5
+ * (via `@fuzdev/fuz_util/sort.ts`), cycle detection by dependency type, and
6
+ * wildcard-range analysis.
7
+ * For the publishing order and the analysis workflow, see `graph_validation.ts`.
7
8
  *
8
9
  * @module
9
10
  */
@@ -15,30 +16,28 @@ export const DEPENDENCY_TYPE = {
15
16
  DEV: 'dev'
16
17
  };
17
18
  export class DependencyGraph {
18
- nodes;
19
- edges; // pkg -> dependents
20
- constructor() {
21
- this.nodes = new Map();
22
- this.edges = new Map();
23
- }
24
- init_from_repos(repos) {
25
- // First pass: create nodes
19
+ nodes = new Map();
20
+ edges = new Map(); // pkg -> dependents
21
+ /**
22
+ * Builds the graph from local repos.
23
+ *
24
+ * Two passes: first creates nodes, then builds edges (dependents).
25
+ * Prioritizes prod/peer deps over dev deps when the same package appears in
26
+ * multiple dependency types (the stronger constraint wins).
27
+ */
28
+ constructor(repos) {
29
+ // first pass: create nodes
26
30
  for (const repo of repos) {
27
31
  const { library, package_json } = repo;
28
32
  const node = {
29
33
  name: library.name,
30
34
  version: package_json.version || '0.0.0',
31
- repo,
32
35
  dependencies: new Map(),
33
- dependents: new Set(),
34
- publishable: !package_json.private
36
+ dependents: new Set()
35
37
  };
36
- // Extract dependencies
37
38
  const deps = package_json.dependencies || EMPTY_OBJECT;
38
39
  const dev_deps = package_json.devDependencies || EMPTY_OBJECT;
39
40
  const peer_deps = package_json.peerDependencies || EMPTY_OBJECT;
40
- // Add dependencies, prioritizing prod/peer over dev
41
- // (if a package appears in multiple dep types, use the stronger constraint)
42
41
  for (const [name, version] of Object.entries(deps)) {
43
42
  node.dependencies.set(name, { type: DEPENDENCY_TYPE.PROD, version });
44
43
  }
@@ -46,7 +45,7 @@ export class DependencyGraph {
46
45
  node.dependencies.set(name, { type: DEPENDENCY_TYPE.PEER, version });
47
46
  }
48
47
  for (const [name, version] of Object.entries(dev_deps)) {
49
- // Only add dev deps if not already present as prod/peer
48
+ // only add dev deps if not already present as prod/peer
50
49
  if (!node.dependencies.has(name)) {
51
50
  node.dependencies.set(name, { type: DEPENDENCY_TYPE.DEV, version });
52
51
  }
@@ -54,12 +53,11 @@ export class DependencyGraph {
54
53
  this.nodes.set(library.name, node);
55
54
  this.edges.set(library.name, new Set());
56
55
  }
57
- // Second pass: build edges (dependents)
56
+ // second pass: build edges (dependents) for internal dependencies
58
57
  for (const node of this.nodes.values()) {
59
58
  for (const [dep_name] of node.dependencies) {
60
- if (this.nodes.has(dep_name)) {
61
- // Internal dependency
62
- const dep_node = this.nodes.get(dep_name);
59
+ const dep_node = this.nodes.get(dep_name);
60
+ if (dep_node) {
63
61
  dep_node.dependents.add(node.name);
64
62
  this.edges.get(dep_name).add(node.name);
65
63
  }
@@ -69,13 +67,6 @@ export class DependencyGraph {
69
67
  get_node(name) {
70
68
  return this.nodes.get(name);
71
69
  }
72
- get_dependents(name) {
73
- return this.edges.get(name) || new Set();
74
- }
75
- get_dependencies(name) {
76
- const node = this.nodes.get(name);
77
- return node ? node.dependencies : new Map();
78
- }
79
70
  /**
80
71
  * Computes topological sort order for dependency graph.
81
72
  *
@@ -120,6 +111,22 @@ export class DependencyGraph {
120
111
  const dev_cycles = this.#find_cycles((spec) => spec.type === DEPENDENCY_TYPE.DEV);
121
112
  return { production_cycles, dev_cycles };
122
113
  }
114
+ /**
115
+ * Reports cycles by type and wildcard (`*`) dependency ranges.
116
+ * Tolerates cycles: it reports them rather than throwing.
117
+ */
118
+ analyze() {
119
+ const { production_cycles, dev_cycles } = this.detect_cycles_by_type();
120
+ const wildcard_deps = [];
121
+ for (const node of this.nodes.values()) {
122
+ for (const [dep_name, spec] of node.dependencies) {
123
+ if (spec.version === '*') {
124
+ wildcard_deps.push({ pkg: node.name, dep: dep_name, version: spec.version });
125
+ }
126
+ }
127
+ }
128
+ return { production_cycles, dev_cycles, wildcard_deps };
129
+ }
123
130
  /** DFS cycle detection following only edges that match the filter. */
124
131
  #find_cycles(include) {
125
132
  const cycles = [];
@@ -167,8 +174,7 @@ export class DependencyGraph {
167
174
  name,
168
175
  spec
169
176
  })),
170
- dependents: Array.from(node.dependents),
171
- publishable: node.publishable
177
+ dependents: Array.from(node.dependents)
172
178
  }));
173
179
  const edges = [];
174
180
  for (const [from, tos] of this.edges) {
@@ -179,52 +185,3 @@ export class DependencyGraph {
179
185
  return { nodes, edges };
180
186
  }
181
187
  }
182
- /**
183
- * Builder for creating and analyzing dependency graphs.
184
- */
185
- export class DependencyGraphBuilder {
186
- /**
187
- * Constructs dependency graph from local repos.
188
- *
189
- * Two-pass algorithm: first creates nodes, then builds edges (dependents).
190
- * Prioritizes prod/peer deps over dev deps when same package appears in
191
- * multiple dependency types (stronger constraint wins).
192
- *
193
- * @returns fully initialized dependency graph with all nodes and edges
194
- */
195
- build_from_repos(repos) {
196
- const graph = new DependencyGraph();
197
- graph.init_from_repos(repos);
198
- return graph;
199
- }
200
- /**
201
- * Computes publishing order using topological sort with dev deps excluded.
202
- *
203
- * Excludes dev dependencies to break circular dev dependency cycles while
204
- * preserving production/peer dependency ordering. This allows patterns like
205
- * shared test utilities that depend on each other for development.
206
- *
207
- * @returns package names in safe publishing order (dependencies before dependents)
208
- * @throws {Error} if production/peer cycles detected (cannot be resolved by exclusion)
209
- */
210
- compute_publishing_order(graph) {
211
- return graph.topological_sort(true); // Exclude dev dependencies
212
- }
213
- analyze(graph) {
214
- const { production_cycles, dev_cycles } = graph.detect_cycles_by_type();
215
- const wildcard_deps = [];
216
- const missing_peers = [];
217
- for (const node of graph.nodes.values()) {
218
- for (const [dep_name, spec] of node.dependencies) {
219
- if (spec.version === '*') {
220
- wildcard_deps.push({ pkg: node.name, dep: dep_name, version: spec.version });
221
- }
222
- if (spec.type === DEPENDENCY_TYPE.PEER && !graph.nodes.has(dep_name)) {
223
- // External peer dependency
224
- missing_peers.push({ pkg: node.name, dep: dep_name });
225
- }
226
- }
227
- }
228
- return { production_cycles, dev_cycles, wildcard_deps, missing_peers };
229
- }
230
- }
@@ -19,7 +19,7 @@ export interface UpdatePackageJsonOptions {
19
19
  * 3. Creates auto-changeset if `published_versions` provided (for transitive updates)
20
20
  * 4. Commits both `package.json` and changeset with standard message
21
21
  *
22
- * Uses version strategy to determine prefix (exact, caret, tilde) while preserving
22
+ * Uses version strategy to determine prefix (exact, caret, tilde, gte) while preserving
23
23
  * existing prefixes when possible.
24
24
  *
25
25
  * @throws {Error} if file operations or git operations fail
@@ -1 +1 @@
1
- {"version":3,"file":"dependency_updater.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/dependency_updater.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAMlE,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGnE,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAElE,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACnD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,MAAM,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM,SAAS,EACf,SAAS,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,UAAS,wBAA6B,KACpC,OAAO,CAAC,IAAI,CAkId,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,MAAM,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,GAC5B,OAAO,KAAK,CAAC,SAAS,CAAC,EACvB,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,UAAS,qBAA0B,KACjC,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAA;CAAE,CAuD5E,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC/B,MAAM,SAAS,EACf,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,KAC5B,GAAG,CACL,MAAM,EACN;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,cAAc,GAAG,iBAAiB,GAAG,kBAAkB,CAAA;CAAE,CAkD/F,CAAC"}
1
+ {"version":3,"file":"dependency_updater.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/dependency_updater.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAMlE,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGnE,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAElE,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,kBAAkB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACnD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,MAAM,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM,SAAS,EACf,SAAS,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,UAAS,wBAA6B,KACpC,OAAO,CAAC,IAAI,CAwId,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,MAAM,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,GAC5B,OAAO,KAAK,CAAC,SAAS,CAAC,EACvB,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,UAAS,qBAA0B,KACjC,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAA;CAAE,CAuD5E,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC/B,MAAM,SAAS,EACf,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,KAC5B,GAAG,CACL,MAAM,EACN;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,cAAc,GAAG,iBAAiB,GAAG,kBAAkB,CAAA;CAAE,CAkD/F,CAAC"}
@@ -11,7 +11,7 @@ import { default_git_operations, default_fs_operations } from './operations_defa
11
11
  * 3. Creates auto-changeset if `published_versions` provided (for transitive updates)
12
12
  * 4. Commits both `package.json` and changeset with standard message
13
13
  *
14
- * Uses version strategy to determine prefix (exact, caret, tilde) while preserving
14
+ * Uses version strategy to determine prefix (exact, caret, tilde, gte) while preserving
15
15
  * existing prefixes when possible.
16
16
  *
17
17
  * @throws {Error} if file operations or git operations fail
@@ -73,6 +73,7 @@ export const update_package_json = async (repo, updates, options = {}) => {
73
73
  if (!write_result.ok) {
74
74
  throw new Error(`Failed to write package.json: ${write_result.message}`);
75
75
  }
76
+ const staged = [];
76
77
  // Create changeset if we have published version info
77
78
  if (published_versions && published_versions.size > 0) {
78
79
  // Build dependency updates info for changeset
@@ -107,6 +108,7 @@ export const update_package_json = async (repo, updates, options = {}) => {
107
108
  if (!add_result.ok) {
108
109
  throw new Error(`Failed to stage changeset: ${add_result.message}`);
109
110
  }
111
+ staged.push(changeset_path);
110
112
  }
111
113
  }
112
114
  // Commit the changes (including both package.json and changeset)
@@ -114,8 +116,11 @@ export const update_package_json = async (repo, updates, options = {}) => {
114
116
  if (!add_pkg_result.ok) {
115
117
  throw new Error(`Failed to stage package.json: ${add_pkg_result.message}`);
116
118
  }
119
+ staged.push('package.json');
120
+ // commit only what this staged, so nothing else in the index rides along
117
121
  const commit_result = await git_ops.commit({
118
122
  message: `update dependencies after publishing`,
123
+ files: staged,
119
124
  cwd: repo.repo_dir
120
125
  });
121
126
  if (!commit_result.ok) {
@@ -2,18 +2,44 @@ import type { Logger } from '@fuzdev/fuz_util/log.ts';
2
2
  import type { FetchValueCache } from '@fuzdev/fuz_util/fetch.ts';
3
3
  import type { RepoJson } from './repo.svelte.js';
4
4
  import type { LocalRepo } from './local_repo.js';
5
+ /**
6
+ * Options for `fetch_repo_data`.
7
+ */
8
+ export interface FetchRepoDataOptions {
9
+ /** The repos to fetch GitHub metadata for, in order. */
10
+ local_repos: Array<LocalRepo>;
11
+ /** GitHub API token, sent with each request. */
12
+ token?: string;
13
+ /** Response memoization, from `fuz_util`'s `fetch.ts`. */
14
+ cache?: FetchValueCache;
15
+ log?: Logger;
16
+ /** Milliseconds to wait before each API request. Defaults to `33`. */
17
+ delay?: number;
18
+ /** Sent as the `x-github-api-version` header when set. */
19
+ github_api_version?: string;
20
+ /** The `fetch` the API requests go through. Defaults to `globalThis.fetch`. */
21
+ fetch?: typeof globalThis.fetch;
22
+ }
5
23
  /**
6
24
  * Fetches GitHub metadata (CI status, PRs) for all repos.
7
25
  *
8
- * Fetches sequentially with delay between requests to respect GitHub API rate limits.
9
- * Uses `await_in_loop` intentionally to avoid parallel requests overwhelming the API.
26
+ * Fetches sequentially with a delay before each request to respect GitHub API
27
+ * rate limits. Uses `await_in_loop` intentionally to avoid parallel requests
28
+ * overwhelming the API. CI status is read for the branch each repo's registry
29
+ * entry follows (`main` when it names none), and that branch is written to
30
+ * `RepoJson.branch`.
10
31
  *
11
- * Error handling: Logs fetch failures but continues processing remaining repos.
12
- * Repos with failed fetches will have `null` for `check_runs` or `pull_requests`.
32
+ * A repo whose registry entry declares no CI (`ci: false`) isn't asked for
33
+ * check runs, and one with none on its branch isn't a failure: both leave
34
+ * `check_runs` `null` without logging. A failed fetch is logged as an error
35
+ * and leaves `null` for that repo's `check_runs` or `pull_requests`, and the
36
+ * remaining repos still fetch — except a 401 response or a repo URL without a
37
+ * GitHub owner, which throw.
13
38
  *
14
- * @param delay - milliseconds between API requests (default: 33ms)
15
- * @param cache - optional cache from `fuz_util`'s `fetch.js` for response memoization
16
- * @returns array of `Repo` objects with GitHub metadata attached
39
+ * @param options - the repos, credentials, cache, and pacing
40
+ * @returns a `RepoJson` for each repo, in the order given
41
+ * @throws {Error} on a 401 response (check `SECRET_GITHUB_API_TOKEN`) or a
42
+ * repo whose URL has no GitHub owner
17
43
  */
18
- export declare const fetch_repo_data: (resolved_repos: Array<LocalRepo>, token?: string, cache?: FetchValueCache, log?: Logger, delay?: number, github_api_version?: string) => Promise<Array<RepoJson>>;
44
+ export declare const fetch_repo_data: (options: FetchRepoDataOptions) => Promise<Array<RepoJson>>;
19
45
  //# sourceMappingURL=fetch_repo_data.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch_repo_data.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/fetch_repo_data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,GAC3B,gBAAgB,KAAK,CAAC,SAAS,CAAC,EAChC,QAAQ,MAAM,EACd,QAAQ,eAAe,EACvB,MAAM,MAAM,EACZ,cAAU,EACV,qBAAqB,MAAM,KACzB,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAkCzB,CAAC"}
1
+ {"version":3,"file":"fetch_repo_data.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/fetch_repo_data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAOjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,wDAAwD;IACxD,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC9B,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,+EAA+E;IAC/E,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,eAAe,GAAU,SAAS,oBAAoB,KAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CA+C5F,CAAC"}
@@ -3,44 +3,66 @@ import { fetch_github_check_runs, fetch_github_pull_requests } from './github.js
3
3
  /**
4
4
  * Fetches GitHub metadata (CI status, PRs) for all repos.
5
5
  *
6
- * Fetches sequentially with delay between requests to respect GitHub API rate limits.
7
- * Uses `await_in_loop` intentionally to avoid parallel requests overwhelming the API.
6
+ * Fetches sequentially with a delay before each request to respect GitHub API
7
+ * rate limits. Uses `await_in_loop` intentionally to avoid parallel requests
8
+ * overwhelming the API. CI status is read for the branch each repo's registry
9
+ * entry follows (`main` when it names none), and that branch is written to
10
+ * `RepoJson.branch`.
8
11
  *
9
- * Error handling: Logs fetch failures but continues processing remaining repos.
10
- * Repos with failed fetches will have `null` for `check_runs` or `pull_requests`.
12
+ * A repo whose registry entry declares no CI (`ci: false`) isn't asked for
13
+ * check runs, and one with none on its branch isn't a failure: both leave
14
+ * `check_runs` `null` without logging. A failed fetch is logged as an error
15
+ * and leaves `null` for that repo's `check_runs` or `pull_requests`, and the
16
+ * remaining repos still fetch — except a 401 response or a repo URL without a
17
+ * GitHub owner, which throw.
11
18
  *
12
- * @param delay - milliseconds between API requests (default: 33ms)
13
- * @param cache - optional cache from `fuz_util`'s `fetch.js` for response memoization
14
- * @returns array of `Repo` objects with GitHub metadata attached
19
+ * @param options - the repos, credentials, cache, and pacing
20
+ * @returns a `RepoJson` for each repo, in the order given
21
+ * @throws {Error} on a 401 response (check `SECRET_GITHUB_API_TOKEN`) or a
22
+ * repo whose URL has no GitHub owner
15
23
  */
16
- export const fetch_repo_data = async (resolved_repos, token, cache, log, delay = 33, github_api_version) => {
24
+ export const fetch_repo_data = async (options) => {
25
+ const { local_repos, token, cache, log, delay = 33, github_api_version, fetch } = options;
17
26
  const repos = [];
18
- for (const { library, package_json, repo_config } of resolved_repos) {
27
+ for (const { library, package_json, entry } of local_repos) {
19
28
  const repo_url = library.repo_url;
20
- // CI status
21
- await wait(delay);
22
- const check_runs = await fetch_github_check_runs(library, {
23
- cache,
24
- log,
25
- token,
26
- api_version: github_api_version,
27
- ref: repo_config.branch
28
- });
29
- if (!check_runs)
30
- log?.error('failed to fetch CI status: ' + repo_url);
29
+ const branch = entry.branch ?? 'main';
30
+ // CI status, for repos the registry says run CI
31
+ let check_runs = null;
32
+ if (entry.ci) {
33
+ await wait(delay);
34
+ const fetched = await fetch_github_check_runs(library, {
35
+ cache,
36
+ log,
37
+ token,
38
+ api_version: github_api_version,
39
+ ref: branch,
40
+ fetch
41
+ });
42
+ if (fetched.ok) {
43
+ check_runs = fetched.value;
44
+ if (!check_runs)
45
+ log?.debug(`no check runs on \`${branch}\`: ${repo_url}`);
46
+ }
47
+ else {
48
+ log?.error(`failed to fetch CI status (${fetched.status}): ${repo_url}`);
49
+ }
50
+ }
31
51
  // pull requests
32
52
  await wait(delay);
33
53
  const pull_requests = await fetch_github_pull_requests(library, {
34
54
  cache,
35
55
  log,
36
56
  token,
37
- api_version: github_api_version
57
+ api_version: github_api_version,
58
+ fetch
38
59
  });
39
60
  if (!pull_requests)
40
- log?.error('failed to fetch issues: ' + repo_url);
61
+ log?.error('failed to fetch pull requests: ' + repo_url);
41
62
  repos.push({
42
63
  library_json: library.library_json,
43
64
  package_json,
65
+ branch,
44
66
  check_runs,
45
67
  pull_requests
46
68
  });
@@ -14,7 +14,7 @@ export interface FetchCache {
14
14
  * cache is cleared (delete file) and starts fresh. This handles format changes.
15
15
  *
16
16
  * Uses `structuredClone` to track changes - only writes to disk if data modified.
17
- * Formatted with Prettier before writing for version control friendliness.
17
+ * Formatted with gro's `format_file` before writing for version control friendliness.
18
18
  *
19
19
  * @param name - cache filename (without .json extension)
20
20
  * @param dir - cache directory (defaults to `.gro/build/fetch/`)
@@ -11,7 +11,7 @@ import { existsSync } from 'node:fs';
11
11
  * cache is cleared (delete file) and starts fresh. This handles format changes.
12
12
  *
13
13
  * Uses `structuredClone` to track changes - only writes to disk if data modified.
14
- * Formatted with Prettier before writing for version control friendliness.
14
+ * Formatted with gro's `format_file` before writing for version control friendliness.
15
15
  *
16
16
  * @param name - cache filename (without .json extension)
17
17
  * @param dir - cache directory (defaults to `.gro/build/fetch/`)