@foss.global/codefeed 5.4.0 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/changelog.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 2026-11-14 - 5.5.0
4
+
5
+ ### Features
6
+
7
+ - record each repository's issues with their comments, labels and milestones in a collaboration unit, split the collaboration measures by kind and count project boards (giteasourceinventory)
8
+ - `discover(signal, { classes: ['collaboration'] })` sets discovery's `collaboration: true`, and `units()` then adds one `{ kind: 'collaboration', owner, name, id }` unit per repository, keyed by its discovered id; a discovery that selects collaboration while a repository has no id rejects with `repository-id-missing` (S8 ruling D12, U3; S8 U1 ruling 1).
9
+ - A collaboration unit is an `IForgeSourceCollaborationInventory` (`@foss.global/interfaces` 3.4): `highestNumber`, the highest number Gitea lists among the repository's issues and pull requests (not measured when it lists neither), every repository label and milestone, and every issue sorted by number with its comments, all verbatim: title, body, `ref`, times, poster and original author, assignees, label, milestone and project ids, `locked`, `pinOrder`, `dueDate`, `timeEstimate`, and the counts of tracked times, dependencies, attachments and reactions. Gitea's `content_version` is not recorded. A list is `notMeasured`, without a read of it, while Gitea's API hides it: the issues when the issue unit is disabled or an external tracker, or when time tracking (for the repository or the instance) or dependencies are switched off, since Gitea then refuses every issue's tracked times or dependencies with 404 and a refused read must never count as none. Any failed read fails the unit, and so do an issue naming a milestone the listing lacks (`issue-milestone-unlisted`), a number listed twice (`duplicate-number`) and a result over `forgeSourceInventoryUnitMaxBytes` (`unit-over-bound`); records are never partial or truncated. Every read is a GET with the administrator's token, without `Sudo`.
10
+ - Gitea 28.2.0's REST API never reports `original_author` or `original_author_id`, so `originalAuthor` is null for every record; content Gitea imported from another service keeps its source authors only in Gitea's database and reads as posted by the importing account, which the Docker Gitea test shows with an import. An imported repository's issues are therefore `notMeasured` whenever its record's `original_url` is set and the listing holds an issue, with the reason "Gitea imported this repository (original_url is set); its API names the importing account as poster and never reports the original author.", and none of its issues is read further; an imported repository without issues keeps a complete empty list, and the rule does not depend on `mirror` (S8 U3 ruling, Q1). `original_url` is never recorded. A forge that fills the original author still has it recorded.
11
+ - Each organization owner records `labelRecords`, its labels sorted by id (null while `labels` is not complete); the composed inventory keeps them, and carries `collaboration` sorted by owner and name, exactly when discovery selects collaboration. A collaboration unit that failed, was not measured or answers for another name is a reason (`collaboration: unit failed: <code>`), and a list that is not measured is a reason by its path (`collaboration.issues: <reason>`).
12
+ - A repository's `collaboration.byKind` splits comments, reactions, attachments and attachment bytes into their issue and pull request kinds and counts open, closed and merged pull requests; each mixed measure is the sum of its kinds (S8 ruling D13, D14). `collaboration.projects` counts the repository's project boards, which Gitea serves while the projects unit is disabled, and is not measured while the unit allows only owner boards; each owner's `projects` counts its own boards, read with the administrator's token for private owners too (S8 U1 ruling 8).
13
+ - Compatibility: repository and owner units each read one more listing (`/projects`); a repository record whose `projects_mode` is not `repo`, `owner` or `all` (`invalid-projects-mode`; `invalid-string` when missing), or whose `has_issues` disagrees with its trackers (`inconsistent-issue-unit`), fails the repository unit, as Gitea 28.2.0 cannot produce either state (S8 U3 ruling, Q3). A collaboration unit whose repository record lacks `original_url` as a string fails with `invalid-string`. Time tracking or dependencies switched off leave every affected repository's issues `notMeasured`, for the owner's per-repository decision (S8 ruling D13). Composing a stored result from a reader before this version names the missing `labelRecords`, `projects` and `byKind` as reasons, so the inventory stays incomplete until those units are measured again.
14
+ - Dependencies: `@foss.global/interfaces` ^3.5.1, which defines the collaboration records (3.4.0) and documents the original-author and `labelRecords` rules above (3.5.1); for the Docker Gitea test, `@foss.global/forgefixtures` ^1.2.0, whose default seed holds the issue cases and records their fields.
15
+
16
+ ### Fixes
17
+
18
+ - measure a repository's issues while only its pull request unit is disabled, and the reverse (giteasourceinventory)
19
+ - Gitea 28.2.0 lists every issue and issue comment while only the pull request unit is disabled (`ListIssues` and `ListRepoIssueComments` filter by the readable unit), but 5.4.0 reported every issue, pull request, comment, review, reaction and attachment measure as `notMeasured` when either unit was off (S8 ruling, G2). Each kind is now measured while its own unit is readable; only the measures of the hidden kind, and the mixed measures that include it, are `notMeasured`.
20
+ - An issue unit configured as an external tracker keeps Gitea's `has_issues` true while its API lists none of the repository's issues; 5.4.0 counted them as a complete zero. They are now `notMeasured` with the reason that the issues unit is an external tracker.
21
+
3
22
  ## 2026-11-13 - 5.4.0
4
23
 
5
24
  ### Fixes
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@foss.global/codefeed',
6
- version: '5.4.0',
6
+ version: '5.5.0',
7
7
  description: 'The @foss.global/codefeed module generates commit/activity feeds from forge providers including Gitea and GitManager.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx1QkFBdUI7SUFDN0IsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHVIQUF1SDtDQUNySSxDQUFBIn0=
@@ -43,13 +43,16 @@ export interface IGiteaSourceInventoryOptions {
43
43
  packageTransferTimeoutMs?: number;
44
44
  }
45
45
  /** A class of source data a run measures only when its discovery selects it. */
46
- export type TGiteaSourceInventoryClass = 'packages';
46
+ export type TGiteaSourceInventoryClass = 'packages' | 'collaboration';
47
47
  export interface IGiteaSourceDiscoveryOptions {
48
48
  /**
49
49
  * Classes beside the instance, owners and repositories to list for
50
50
  * measurement. `packages` lists every package, so `units` measures one unit
51
51
  * per package; without it, discovery carries no `packages` and the package
52
- * class is unread.
52
+ * class is unread. `collaboration` sets discovery's `collaboration: true`,
53
+ * so `units` measures one collaboration unit per repository, and the
54
+ * composed inventory carries the records and every organization's
55
+ * `labelRecords`; without it, collaboration records are unread.
53
56
  */
54
57
  classes?: readonly TGiteaSourceInventoryClass[];
55
58
  }
@@ -90,17 +93,21 @@ export declare class GiteaSourceInventory {
90
93
  get metrics(): IForgeRequestMetrics;
91
94
  /**
92
95
  * Identifies the source and its reader and lists every owner and repository
93
- * with its id, and with `classes: ['packages']` every package from the
94
- * administrator package listing (`packages`, absent otherwise). Rejects
95
- * unless the token belongs to a site administrator, and rejects an unknown
96
- * class with `invalid-options`; a listing that does not finish, or that
97
- * lists a repository id twice, is reported in `incompleteReasons`.
96
+ * with its id, with `classes: ['packages']` every package from the
97
+ * administrator package listing (`packages`, absent otherwise), and with
98
+ * `classes: ['collaboration']` sets `collaboration: true`. Rejects unless
99
+ * the token belongs to a site administrator, and rejects an unknown class
100
+ * with `invalid-options`; a listing that does not finish, or that lists a
101
+ * repository id twice, is reported in `incompleteReasons`.
98
102
  */
99
103
  discover(signalArg?: AbortSignal, optionsArg?: IGiteaSourceDiscoveryOptions): Promise<IDiscovery>;
100
104
  /**
101
105
  * Every unit a run over this discovery measures: the instance, then owners,
102
106
  * then repositories, then the packages discovery lists when it selected
103
- * them.
107
+ * them, then, when it selected collaboration, one collaboration unit per
108
+ * repository, keyed by the repository's id. A discovery that selects
109
+ * collaboration while a repository has no id rejects with
110
+ * `repository-id-missing`; it never falls back to keying by name.
104
111
  */
105
112
  units(discoveryArg: IDiscovery): TUnit[];
106
113
  /**
@@ -114,12 +121,13 @@ export declare class GiteaSourceInventory {
114
121
  lookupRepository(idArg: string, signalArg?: AbortSignal): Promise<TGiteaSourceRepositoryLookup>;
115
122
  /**
116
123
  * Measures one unit. Never rejects: a unit whose primary record cannot be
117
- * read is `failed`, and so is a repository unit carrying an id that its name
118
- * no longer answers with (`repository-identity-changed`). A package unit is
119
- * read whole or fails, never partly: a listing that does not finish, an
120
- * index that is not what its file list promises (`unexpected-manifest-shape`)
121
- * and a result over `forgeSourceInventoryUnitMaxBytes` of UTF-8 JSON
122
- * (`unit-over-bound`) fail it, and its record is never truncated.
124
+ * read is `failed`, and so is a repository or collaboration unit carrying an
125
+ * id that its name no longer answers with (`repository-identity-changed`).
126
+ * Package and collaboration units are read whole or fail, never partly: a
127
+ * listing that does not finish, an index that is not what its file list
128
+ * promises (`unexpected-manifest-shape`) and a result over
129
+ * `forgeSourceInventoryUnitMaxBytes` of UTF-8 JSON (`unit-over-bound`) fail
130
+ * it, and its records are never truncated.
123
131
  */
124
132
  measureUnit(unitArg: TUnit, signalArg?: AbortSignal): Promise<TUnitResult>;
125
133
  /**
@@ -139,7 +147,11 @@ export declare class GiteaSourceInventory {
139
147
  * `packages` and `totals.packageContent` (`composeGiteaPackageContent`) are
140
148
  * present exactly when discovery lists packages, an empty list included; a
141
149
  * package without a record is left out, never truncated, and makes its
142
- * content measures partial.
150
+ * content measures partial. `collaboration` and every organization's
151
+ * `labelRecords` are present exactly when discovery selects collaboration: a
152
+ * repository without a collaboration result for its discovered id is left
153
+ * out and named in the reasons, and a record list that is not measured is a
154
+ * reason by its path, such as `collaboration.issues`.
143
155
  */
144
156
  export declare const composeGiteaSourceInventory: (discoveryArg: IDiscovery, resultsArg: TUnitResult[], generatorsArg: plugins.fossInterfaces.data.IForgeSourceInventoryGenerator[]) => IInventory;
145
157
  export {};