@angelmsger/fx 0.18.0 → 0.19.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 +9 -1
- package/README.md +1 -0
- package/dist/adapters/code-host/bitbucket-cli/provider.js +4 -3
- package/dist/adapters/code-host/bitbucket-cli/provider.js.map +1 -1
- package/dist/adapters/code-host/github/provider.js +4 -3
- package/dist/adapters/code-host/github/provider.js.map +1 -1
- package/dist/adapters/code-host/local-git/provider.js +39 -6
- package/dist/adapters/code-host/local-git/provider.js.map +1 -1
- package/dist/adapters/error-tracker/sentry/client.js +18 -8
- package/dist/adapters/error-tracker/sentry/client.js.map +1 -1
- package/dist/adapters/error-tracker/sentry/provider.js +2 -1
- package/dist/adapters/error-tracker/sentry/provider.js.map +1 -1
- package/dist/adapters/error-tracker/sentry/tracker.js +176 -37
- package/dist/adapters/error-tracker/sentry/tracker.js.map +1 -1
- package/dist/application/release/baseline.js +44 -0
- package/dist/application/release/baseline.js.map +1 -0
- package/dist/application/release/errors.js +146 -22
- package/dist/application/release/errors.js.map +1 -1
- package/dist/application/release/facts.js +16 -6
- package/dist/application/release/facts.js.map +1 -1
- package/dist/application/release/index.js +92 -11
- package/dist/application/release/index.js.map +1 -1
- package/dist/application/release/repo.js +118 -20
- package/dist/application/release/repo.js.map +1 -1
- package/dist/application/release/version-declaration.js +54 -0
- package/dist/application/release/version-declaration.js.map +1 -0
- package/dist/application/release/version-history.js +86 -0
- package/dist/application/release/version-history.js.map +1 -0
- package/dist/application/repo/show.js +9 -1
- package/dist/application/repo/show.js.map +1 -1
- package/dist/application/repo/version.js +83 -0
- package/dist/application/repo/version.js.map +1 -0
- package/dist/cli/commands/index.js +2 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/release/check.js +31 -0
- package/dist/cli/commands/release/check.js.map +1 -1
- package/dist/cli/commands/release/overrides.js +19 -0
- package/dist/cli/commands/release/overrides.js.map +1 -0
- package/dist/cli/commands/repo/show.js +12 -4
- package/dist/cli/commands/repo/show.js.map +1 -1
- package/dist/cli/commands/repo/version.js +36 -0
- package/dist/cli/commands/repo/version.js.map +1 -0
- package/dist/cli/notices.js +5 -4
- package/dist/cli/notices.js.map +1 -1
- package/dist/cli/release-coverage.js +47 -0
- package/dist/cli/release-coverage.js.map +1 -0
- package/dist/cli/release-view.js +53 -38
- package/dist/cli/release-view.js.map +1 -1
- package/dist/cli/render/report.js +5 -0
- package/dist/cli/render/report.js.map +1 -1
- package/dist/domain/members/classify.js +5 -2
- package/dist/domain/members/classify.js.map +1 -1
- package/dist/domain/members/ownership-evidence.js +63 -0
- package/dist/domain/members/ownership-evidence.js.map +1 -0
- package/dist/domain/release/errors.js +76 -12
- package/dist/domain/release/errors.js.map +1 -1
- package/dist/domain/release/types.js.map +1 -1
- package/dist/domain/release/version-evidence.js +6 -0
- package/dist/domain/release/version-evidence.js.map +1 -0
- package/dist/domain/release/version.js +44 -5
- package/dist/domain/release/version.js.map +1 -1
- package/dist/domain/release/window.js +67 -3
- package/dist/domain/release/window.js.map +1 -1
- package/dist/domain/report.js +2 -0
- package/dist/domain/report.js.map +1 -1
- package/package.json +1 -1
- package/skills/fx-workspace/SKILL.md +1 -1
- package/skills/fx-workspace/references/commands.md +119 -18
- package/skills/fx-workspace/references/workspace-tasks.md +34 -20
|
@@ -2,24 +2,27 @@
|
|
|
2
2
|
// activity, so first-seen is judged here; see "Unresolved errors" in
|
|
3
3
|
// docs/design/release.md.
|
|
4
4
|
import { releaseFinding } from './types.js';
|
|
5
|
-
import {
|
|
6
|
-
//
|
|
7
|
-
// asked for no more, and says whether it had more.
|
|
5
|
+
import { instantMs, isWithinRange, resolveRange } from './window.js';
|
|
6
|
+
// Maximum page size; the application continues until exhaustion or an explicit partial result.
|
|
8
7
|
export const ISSUE_CEILING = 1000;
|
|
9
8
|
export function errorsFinding(input) {
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
const range = input.range ?? resolveRange({ since: input.since }, input.now);
|
|
10
|
+
const candidates = input.issues.filter((issue) => issue.status !== 'resolved' && issue.status !== 'ignored');
|
|
11
|
+
const dated = candidates.flatMap((issue) => {
|
|
12
|
+
const at = hasLifetimeDate(issue) && issue.firstSeen !== null ? instantMs(issue.firstSeen) : undefined;
|
|
13
|
+
return at === undefined ? [] : [{ issue, at }];
|
|
14
14
|
});
|
|
15
|
-
const fresh = dated.filter((d) => d.
|
|
16
|
-
const undated =
|
|
15
|
+
const fresh = dated.filter((d) => isWithinRange(d.issue.firstSeen, range)).map((d) => d.issue);
|
|
16
|
+
const undated = candidates.length - dated.length;
|
|
17
|
+
const failures = input.page?.failures?.map((failure) => failure.error) ?? [];
|
|
18
|
+
const incomplete = input.capped || undated > 0 || input.page?.coverage === 'incomplete' || failures.length > 0;
|
|
17
19
|
const evidence = {
|
|
18
20
|
env: input.env,
|
|
19
21
|
slug: input.slug,
|
|
20
22
|
since: input.since,
|
|
21
23
|
capped: input.capped,
|
|
22
24
|
undated,
|
|
25
|
+
error_evidence: errorEvidence(input, range),
|
|
23
26
|
issues: fresh.map((i) => ({
|
|
24
27
|
short_id: i.shortId,
|
|
25
28
|
title: i.title,
|
|
@@ -31,14 +34,26 @@ export function errorsFinding(input) {
|
|
|
31
34
|
})),
|
|
32
35
|
};
|
|
33
36
|
const [level, said] = verdict(input, fresh.length, undated);
|
|
34
|
-
const
|
|
37
|
+
const firstFailure = input.page?.pagesRead === 0 ? input.page.failures?.[0] : undefined;
|
|
38
|
+
const suffix = fresh.length > 0 && incomplete ? '; evidence is incomplete' : '';
|
|
39
|
+
const message = firstFailure?.error.message ?? `${said} (${input.label})${suffix}`;
|
|
35
40
|
return releaseFinding('errors', input.repo, level, message, {
|
|
36
41
|
evidence,
|
|
37
|
-
coverage:
|
|
42
|
+
coverage: incomplete ? 'incomplete' : 'checked',
|
|
43
|
+
...(failures.length === 0
|
|
44
|
+
? {}
|
|
45
|
+
: {
|
|
46
|
+
failure: failures[0],
|
|
47
|
+
failures,
|
|
48
|
+
handoff: failures[0]?.handoff,
|
|
49
|
+
fix: failures.find((failure) => failure.next_steps.length > 0)?.next_steps[0],
|
|
50
|
+
}),
|
|
38
51
|
});
|
|
39
52
|
}
|
|
40
53
|
function verdict(input, fresh, undated) {
|
|
41
|
-
const window =
|
|
54
|
+
const window = input.range === undefined
|
|
55
|
+
? `first seen in ${input.env} in the last ${input.since}`
|
|
56
|
+
: `first seen in ${input.env} in [${input.range.start}, ${input.range.end})`;
|
|
42
57
|
if (fresh > 0) {
|
|
43
58
|
const floor = input.capped ? 'at least ' : '';
|
|
44
59
|
return ['fail', `${floor}${fresh} unresolved issue${fresh === 1 ? '' : 's'} ${window}`];
|
|
@@ -52,6 +67,55 @@ function verdict(input, fresh, undated) {
|
|
|
52
67
|
// The tracker stopped at the ceiling: what it did not send is unread, not absent.
|
|
53
68
|
if (input.capped)
|
|
54
69
|
return ['warn', `more unresolved issues than fx asked for; none of them ${window}`];
|
|
70
|
+
if (input.page?.coverage === 'incomplete')
|
|
71
|
+
return ['warn', `unresolved issue evidence in ${input.env} is incomplete`];
|
|
55
72
|
return ['ok', `no unresolved issue ${window}`];
|
|
56
73
|
}
|
|
74
|
+
function errorEvidence(input, range) {
|
|
75
|
+
const page = input.page;
|
|
76
|
+
return {
|
|
77
|
+
range,
|
|
78
|
+
observed_at: input.now.toISOString(),
|
|
79
|
+
activity_scope: 'range',
|
|
80
|
+
status_filter: 'unresolved',
|
|
81
|
+
status_scope: 'current',
|
|
82
|
+
deduplication: 'latest_observation',
|
|
83
|
+
// Each request observes current state at its own time; there is no shared snapshot.
|
|
84
|
+
status_observed_at: null,
|
|
85
|
+
items: input.issues.map((issue) => ({
|
|
86
|
+
id: issue.id,
|
|
87
|
+
short_id: issue.shortId,
|
|
88
|
+
title: issue.title,
|
|
89
|
+
level: issue.level,
|
|
90
|
+
lifetime_first_seen: hasLifetimeDate(issue) ? issue.firstSeen : null,
|
|
91
|
+
first_seen_scope: hasLifetimeDate(issue) ? 'lifetime' : 'unknown',
|
|
92
|
+
list_first_seen: issue.listFirstSeen ?? null,
|
|
93
|
+
list_first_seen_scope: 'unknown',
|
|
94
|
+
window_first_seen: issue.windowFirstSeen ?? null,
|
|
95
|
+
last_seen: issue.lastSeen,
|
|
96
|
+
count: issue.count,
|
|
97
|
+
count_scope: 'unknown',
|
|
98
|
+
url: issue.url,
|
|
99
|
+
culprit: issue.culprit,
|
|
100
|
+
status: issue.status ?? null,
|
|
101
|
+
status_observed_at: issue.statusObservedAt ?? null,
|
|
102
|
+
assignee: issue.assignee ?? null,
|
|
103
|
+
})),
|
|
104
|
+
has_more: input.capped,
|
|
105
|
+
...(page?.next === undefined ? {} : { next: page.next }),
|
|
106
|
+
pages_read: page?.pagesRead ?? 1,
|
|
107
|
+
coverage: input.capped ||
|
|
108
|
+
input.issues.some((issue) => !hasLifetimeDate(issue)) ||
|
|
109
|
+
(page?.failures?.length ?? 0) > 0
|
|
110
|
+
? 'incomplete'
|
|
111
|
+
: (page?.coverage ?? 'checked'),
|
|
112
|
+
failures: page?.failures ?? [],
|
|
113
|
+
truncation_reason: page?.truncationReason ?? null,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function hasLifetimeDate(issue) {
|
|
117
|
+
return (issue.firstSeenScope !== 'unknown' &&
|
|
118
|
+
issue.firstSeen !== null &&
|
|
119
|
+
instantMs(issue.firstSeen) !== undefined);
|
|
120
|
+
}
|
|
57
121
|
//# sourceMappingURL=errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/domain/release/errors.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,qEAAqE;AACrE,0BAA0B;AAK1B,OAAO,EAAE,cAAc,EAAuB,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/domain/release/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/domain/release/types.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,yEAAyE;AACzE,oEAAoE;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/domain/release/types.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,yEAAyE;AACzE,oEAAoE;AAGpE,OAAO,EAAE,OAAO,EAA4D,MAAM,cAAc,CAAC;AAKjG,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAU,CAAC;AA+FjE,MAAM,UAAU,cAAc,CAC5B,KAAY,EACZ,IAAY,EACZ,KAAY,EACZ,OAAe,EACf,QAAsB,EAAE;IAExB,OAAO,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AACrD,CAAC;AAED,uEAAuE;AACvE,qDAAqD;AACrD,MAAM,UAAU,UAAU,CACxB,KAAY,EACZ,IAAY,EACZ,MAAc,EACd,QAAsB,EAAE;IAExB,OAAO,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;AAC3F,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,UAAU,CAAC,KAAY,EAAE,IAAY,EAAE,GAAW;IAChE,OAAO,cAAc,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,GAAG,eAAe,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,CAAC;AAClG,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Pinned declaration and history evidence, independent of release policy. A field
|
|
2
|
+
// change is a first-parent Git event, never a publication or deployment timestamp.
|
|
3
|
+
export function sameVersionSource(a, b) {
|
|
4
|
+
return a.file === b.file && a.field === b.field && a.package_name === b.package_name;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=version-evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-evidence.js","sourceRoot":"","sources":["../../../src/domain/release/version-evidence.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,mFAAmF;AAqDnF,MAAM,UAAU,iBAAiB,CAAC,CAAgB,EAAE,CAAgB;IAClE,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,YAAY,CAAC;AACvF,CAAC"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
// The version a repository declares for itself, from VERSION or a dependency file.
|
|
2
2
|
// It finds the written declaration without running a build that might compute another.
|
|
3
3
|
// VERSION is plain text; structured metadata uses the readers below.
|
|
4
|
+
import path from 'node:path';
|
|
4
5
|
import { parse } from 'smol-toml';
|
|
5
6
|
// A Gradle build often keeps its version beside the build file.
|
|
6
7
|
export const GRADLE_PROPERTIES = 'gradle.properties';
|
|
7
8
|
export const ROOT_VERSION = 'VERSION';
|
|
9
|
+
// Reader order is the automatic declaration discovery order.
|
|
8
10
|
export const VERSION_READERS = {
|
|
9
11
|
[ROOT_VERSION]: (text) => text,
|
|
10
12
|
'package.json': packageVersion,
|
|
@@ -15,12 +17,49 @@ export const VERSION_READERS = {
|
|
|
15
17
|
[GRADLE_PROPERTIES]: propertiesVersion,
|
|
16
18
|
};
|
|
17
19
|
export function declaredVersion(file, text) {
|
|
18
|
-
const
|
|
20
|
+
const name = path.posix.basename(file);
|
|
21
|
+
if (!Object.hasOwn(VERSION_READERS, name))
|
|
22
|
+
return undefined;
|
|
23
|
+
const reader = VERSION_READERS[name];
|
|
19
24
|
if (reader === undefined)
|
|
20
25
|
return undefined;
|
|
21
26
|
const version = reader(text)?.trim();
|
|
22
27
|
return version === undefined || version === '' ? undefined : version;
|
|
23
28
|
}
|
|
29
|
+
// Field names are structural paths, except plain text (text) and Gradle/properties
|
|
30
|
+
// assignments (version). A POM property records the field actually carrying the value.
|
|
31
|
+
export function versionDeclaration(file, text) {
|
|
32
|
+
const name = path.posix.basename(file);
|
|
33
|
+
const value = declaredVersion(file, text);
|
|
34
|
+
if (value === undefined)
|
|
35
|
+
return undefined;
|
|
36
|
+
if (name === 'package.json') {
|
|
37
|
+
const doc = JSON.parse(text);
|
|
38
|
+
return { file, field: '/version', value, package_name: stringAt(doc, ['name']) ?? null };
|
|
39
|
+
}
|
|
40
|
+
if (name === 'pyproject.toml') {
|
|
41
|
+
const doc = parse(text);
|
|
42
|
+
const table = stringAt(doc, ['project', 'version']) === undefined ? ['tool', 'poetry'] : ['project'];
|
|
43
|
+
return {
|
|
44
|
+
file,
|
|
45
|
+
field: `/${[...table, 'version'].join('/')}`,
|
|
46
|
+
value,
|
|
47
|
+
package_name: stringAt(doc, [...table, 'name']) ?? null,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (name === 'pom.xml') {
|
|
51
|
+
const values = pomValues(text);
|
|
52
|
+
const field = values.has('project/version') ? 'project/version' : 'project/parent/version';
|
|
53
|
+
const property = /^\$\{([\w.-]+)\}$/.exec(values.get(field) ?? '')?.[1];
|
|
54
|
+
return {
|
|
55
|
+
file,
|
|
56
|
+
field: `/${property === undefined ? field : `project/properties/${property}`}`,
|
|
57
|
+
value,
|
|
58
|
+
package_name: values.get('project/artifactId') ?? null,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return { file, field: name === ROOT_VERSION ? 'text' : 'version', value, package_name: null };
|
|
62
|
+
}
|
|
24
63
|
function packageVersion(text) {
|
|
25
64
|
try {
|
|
26
65
|
const doc = JSON.parse(text);
|
|
@@ -53,14 +92,14 @@ function stringAt(doc, path) {
|
|
|
53
92
|
return typeof at === 'string' ? at : undefined;
|
|
54
93
|
}
|
|
55
94
|
// The project's own <version>, else the one it inherits from <parent>; a single
|
|
56
|
-
// ${property} is resolved from the project's <properties
|
|
95
|
+
// ${property} is resolved from the project's <properties>. Composite and recursive
|
|
96
|
+
// expressions are unreadable because fx does not run Maven's expression evaluator.
|
|
57
97
|
function pomVersion(text) {
|
|
58
98
|
const values = pomValues(text);
|
|
59
99
|
const version = values.get('project/version') ?? values.get('project/parent/version');
|
|
60
100
|
const property = version === undefined ? undefined : /^\$\{([\w.-]+)\}$/.exec(version)?.[1];
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return values.get(`project/properties/${property}`) ?? version;
|
|
101
|
+
const resolved = property === undefined ? version : values.get(`project/properties/${property}`);
|
|
102
|
+
return resolved === undefined || resolved.includes('${') ? undefined : resolved;
|
|
64
103
|
}
|
|
65
104
|
// The text of every element, keyed by its path from the root.
|
|
66
105
|
function pomValues(text) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/domain/release/version.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,uFAAuF;AACvF,qEAAqE;AAErE,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/domain/release/version.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,uFAAuF;AACvF,qEAAqE;AAErE,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAMlC,gEAAgE;AAChE,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AACrD,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC;AAEtC,6DAA6D;AAC7D,MAAM,CAAC,MAAM,eAAe,GAA4C;IACtE,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI;IAC9B,cAAc,EAAE,cAAc;IAC9B,gBAAgB,EAAE,gBAAgB;IAClC,SAAS,EAAE,UAAU;IACrB,cAAc,EAAE,aAAa;IAC7B,kBAAkB,EAAE,aAAa;IACjC,CAAC,iBAAiB,CAAC,EAAE,iBAAiB;CACvC,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,IAAY;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5D,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;IACrC,OAAO,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AACvE,CAAC;AAED,mFAAmF;AACnF,uFAAuF;AACvF,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,IAAY;IAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;IAC3F,CAAC;IACD,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAY,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,KAAK,GACT,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACzF,OAAO;YACL,IAAI;YACJ,KAAK,EAAE,IAAI,CAAC,GAAG,KAAK,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;YAC5C,KAAK;YACL,YAAY,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,EAAE,MAAM,CAAC,CAAC,IAAI,IAAI;SACxD,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,wBAAwB,CAAC;QAC3F,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxE,OAAO;YACL,IAAI;YACJ,KAAK,EAAE,IAAI,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,sBAAsB,QAAQ,EAAE,EAAE;YAC9E,KAAK;YACL,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,IAAI;SACvD,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;AAChG,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,CAAC;QACH,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,SAAS,CAAC;QAC9D,MAAM,OAAO,GAAI,GAA+B,CAAC,SAAS,CAAC,CAAC;QAC5D,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,kFAAkF;QAClF,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,oFAAoF;AACpF,SAAS,gBAAgB,CAAC,IAAY;IACpC,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;QACxD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AAC/F,CAAC;AAED,SAAS,QAAQ,CAAC,GAAY,EAAE,IAAuB;IACrD,IAAI,EAAE,GAAG,GAAG,CAAC;IACb,KAAK,MAAM,GAAG,IAAI,IAAI;QACpB,EAAE,GAAG,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC,CAAE,EAA8B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChG,OAAO,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC;AAED,gFAAgF;AAChF,mFAAmF;AACnF,mFAAmF;AACnF,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtF,MAAM,QAAQ,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5F,MAAM,QAAQ,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,sBAAsB,QAAQ,EAAE,CAAC,CAAC;IACjG,OAAO,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;AAClF,CAAC;AAED,8DAA8D;AAC9D,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;IACjF,MAAM,GAAG,GAAG,uCAAuC,CAAC;IACpD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC;QACtD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;YAC7B,IAAI,KAAK,KAAK,EAAE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAChE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;QACtC,CAAC;aAAM,IAAI,IAAI,KAAK,SAAS,IAAI,WAAW,KAAK,GAAG,EAAE,CAAC;YACrD,IAAI,OAAO,KAAK,GAAG;gBAAE,IAAI,CAAC,GAAG,EAAE,CAAC;;gBAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,4FAA4F;AAC5F,SAAS,aAAa,CAAC,IAAY;IACjC,KAAK,MAAM,IAAI,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QAClD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACpD,MAAM,OAAO,GAAG,kCAAkC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACnE,IAAI,OAAO,KAAK,SAAS;gBAAE,OAAO,OAAO,CAAC;QAC5C,CAAC;IACH,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,uFAAuF;AACvF,kEAAkE;AAClE,SAAS,eAAe,CAAC,IAAY;IACnC,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,KAAyB,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtD,IAAI,IAAI,CAAC,GAAG,OAAO,CAAC;YACpB,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC;YACpB,IAAI,CAAC,KAAK,KAAK;gBAAE,KAAK,GAAG,SAAS,CAAC;QACrC,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YAClC,KAAK,GAAG,CAAC,CAAC;YACV,IAAI,IAAI,CAAC,CAAC;QACZ,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;YAChE,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC;YAClC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACtE,MAAM,IAAI,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9D,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/D,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;QACf,CAAC;;YAAM,IAAI,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACjE,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC;IAC5C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Relative look-back syntax and reproducible, timezone-qualified half-open ranges.
|
|
2
2
|
import { DevkitError } from '../errors.js';
|
|
3
3
|
const UNIT_MS = {
|
|
4
4
|
h: 60 * 60 * 1000,
|
|
@@ -6,12 +6,13 @@ const UNIT_MS = {
|
|
|
6
6
|
w: 7 * 24 * 60 * 60 * 1000,
|
|
7
7
|
};
|
|
8
8
|
const PATTERN = /^(\d+)([hdw])$/;
|
|
9
|
+
const INSTANT = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(Z|[+-]\d{2}:\d{2})$/;
|
|
9
10
|
export function parseWindow(text) {
|
|
10
11
|
const m = PATTERN.exec(text.trim());
|
|
11
12
|
if (m === null || m[1] === undefined || m[2] === undefined)
|
|
12
13
|
return undefined;
|
|
13
|
-
const
|
|
14
|
-
return
|
|
14
|
+
const ms = Number(m[1]) * (UNIT_MS[m[2]] ?? 0);
|
|
15
|
+
return ms > 0 && Number.isSafeInteger(ms) ? ms : undefined;
|
|
15
16
|
}
|
|
16
17
|
export function isWindow(text) {
|
|
17
18
|
return parseWindow(text) !== undefined;
|
|
@@ -25,4 +26,67 @@ export function windowMs(text) {
|
|
|
25
26
|
nextSteps: ['fx release check --since 14d'],
|
|
26
27
|
});
|
|
27
28
|
}
|
|
29
|
+
// Check calendar components before parsing. Provider timestamps may carry microseconds;
|
|
30
|
+
// comparisons truncate fractional seconds to milliseconds and never round into the next bound.
|
|
31
|
+
export function instantMs(text) {
|
|
32
|
+
const match = INSTANT.exec(text);
|
|
33
|
+
if (match === null)
|
|
34
|
+
return undefined;
|
|
35
|
+
const [year, month, day, hour, minute, second] = match.slice(1, 7).map(Number);
|
|
36
|
+
if (year === undefined || month === undefined || day === undefined)
|
|
37
|
+
return undefined;
|
|
38
|
+
const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
39
|
+
const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1];
|
|
40
|
+
if (days === undefined ||
|
|
41
|
+
day < 1 ||
|
|
42
|
+
day > days ||
|
|
43
|
+
(hour ?? 24) > 23 ||
|
|
44
|
+
(minute ?? 60) > 59 ||
|
|
45
|
+
(second ?? 60) > 59)
|
|
46
|
+
return undefined;
|
|
47
|
+
const zone = match[8] ?? '';
|
|
48
|
+
if (zone !== 'Z' && (Number(zone.slice(1, 3)) > 23 || Number(zone.slice(4)) > 59))
|
|
49
|
+
return undefined;
|
|
50
|
+
const fraction = match[7];
|
|
51
|
+
const millis = fraction === undefined ? '' : `.${fraction.slice(0, 3).padEnd(3, '0')}`;
|
|
52
|
+
const ms = Date.parse(`${text.slice(0, 19)}${millis}${zone}`);
|
|
53
|
+
return Number.isFinite(ms) ? ms : undefined;
|
|
54
|
+
}
|
|
55
|
+
export function resolveRange(input, now) {
|
|
56
|
+
if (input.start !== undefined || input.end !== undefined) {
|
|
57
|
+
if (input.since !== undefined)
|
|
58
|
+
throw badRange('Use either since or start/end, not both');
|
|
59
|
+
if (input.start === undefined || input.end === undefined)
|
|
60
|
+
throw badRange('Both start and end are required');
|
|
61
|
+
return absoluteRange(input.start, input.end);
|
|
62
|
+
}
|
|
63
|
+
const end = now.getTime();
|
|
64
|
+
const start = end - windowMs(input.since ?? '14d');
|
|
65
|
+
if (!Number.isFinite(end) || !Number.isFinite(new Date(start).getTime()))
|
|
66
|
+
throw badRange('The relative window is outside the supported date range');
|
|
67
|
+
return absoluteRange(new Date(start).toISOString(), now.toISOString());
|
|
68
|
+
}
|
|
69
|
+
export function absoluteRange(start, end) {
|
|
70
|
+
const floor = instantMs(start);
|
|
71
|
+
const ceiling = instantMs(end);
|
|
72
|
+
if (floor === undefined || ceiling === undefined)
|
|
73
|
+
throw badRange('Start and end must be ISO timestamps with an explicit timezone');
|
|
74
|
+
if (floor >= ceiling)
|
|
75
|
+
throw badRange('Start must be earlier than end');
|
|
76
|
+
return {
|
|
77
|
+
start: new Date(floor).toISOString(),
|
|
78
|
+
end: new Date(ceiling).toISOString(),
|
|
79
|
+
bounds: '[start,end)',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export function isWithinRange(date, range) {
|
|
83
|
+
const at = date === null ? undefined : instantMs(date);
|
|
84
|
+
return at !== undefined && at >= Date.parse(range.start) && at < Date.parse(range.end);
|
|
85
|
+
}
|
|
86
|
+
function badRange(message) {
|
|
87
|
+
return new DevkitError('usage', 'BAD_TIME_RANGE', message, {
|
|
88
|
+
hint: 'Use a positive relative window or two timezone-qualified ISO timestamps.',
|
|
89
|
+
nextSteps: ['fx release check --help'],
|
|
90
|
+
});
|
|
91
|
+
}
|
|
28
92
|
//# sourceMappingURL=window.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"window.js","sourceRoot":"","sources":["../../../src/domain/release/window.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"window.js","sourceRoot":"","sources":["../../../src/domain/release/window.ts"],"names":[],"mappings":"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"}
|
package/dist/domain/report.js
CHANGED
|
@@ -10,6 +10,8 @@ export function finding(group, id, level, message, extra = {}) {
|
|
|
10
10
|
...(extra.fix === undefined ? {} : { fix: extra.fix }),
|
|
11
11
|
...(extra.handoff === undefined ? {} : { handoff: extra.handoff }),
|
|
12
12
|
...(extra.evidence === undefined ? {} : { evidence: extra.evidence }),
|
|
13
|
+
...(extra.failure === undefined ? {} : { failure: extra.failure }),
|
|
14
|
+
...(extra.failures === undefined ? {} : { failures: extra.failures }),
|
|
13
15
|
...(extra.required === undefined ? {} : { required: extra.required }),
|
|
14
16
|
...(extra.actions === undefined ? {} : { actions: extra.actions }),
|
|
15
17
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/domain/report.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,6EAA6E;
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/domain/report.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: fx-workspace
|
|
3
|
-
version: 0.
|
|
3
|
+
version: 0.19.0
|
|
4
4
|
description: 'Use only when the user explicitly asks for the fx workspace CLI or manifest, or the current task is inside an fx-managed workspace or routed by its fx-derived AGENTS.md. Drive workspace init and sync, repository status and selection, manifest validation and editing, companion tools and login, doctor, agent Skills, repository ownership, environment coordinates and readiness through can/where, and release checks across dependencies, branches, builds and errors. Do not use for generic Sentry, OpenObserve, Jenkins, Kubernetes, logs, errors or builds outside an fx-managed workspace.'
|
|
5
5
|
metadata:
|
|
6
6
|
requires:
|
|
@@ -163,6 +163,38 @@ returns the corresponding explicit queries instead of an unrelated fuzzy area.
|
|
|
163
163
|
|
|
164
164
|
`fx repo show <repo>` — the resolved entry, disk state and URLs, plus `owners`: `[]` when the members document names nobody, `null` when the workspace has no members document at all, else items of `area`, `lead`, `scenario`, `devLead`, `roles`, every person as `{id, name, email}` (name and email `null` when the id is not in the document, `all` included); `contact` is the project's contact. Its `next_steps` use the canonical repository name and explicit workspace to select an unpicked repository and synchronize missing shared checkouts; inspection itself never changes selection or downloads files.
|
|
165
165
|
|
|
166
|
+
`ownership_evidence` is an additional scope-aware projection. It carries `as_of`,
|
|
167
|
+
`basis: current_members_document`, `historical_snapshot: false`, `coverage`,
|
|
168
|
+
`items` and `has_more: false`. Each item retains the repository-linked area/scenario,
|
|
169
|
+
context, named people, responsibility teams and collective assignments. A person's
|
|
170
|
+
status, mentor and leader remain explicit current facts. `--as-of YYYY-MM-DD`
|
|
171
|
+
filters declared relationship intervals, defaulting to today in UTC; it does not
|
|
172
|
+
reconstruct old membership documents. `not_configured` means no members document,
|
|
173
|
+
`not_covered` means no linked scope, and a checked scope can still say
|
|
174
|
+
`no_relationships`. Do not expand collective `all` or infer an assignee from Git
|
|
175
|
+
authors. A team workflow selects an owner from applicable responsibility evidence.
|
|
176
|
+
|
|
177
|
+
`fx repo version <repo>` reads pinned version history for any known repository,
|
|
178
|
+
even one excluded from the release checklist. `version_evidence` carries
|
|
179
|
+
`requested_ref`, `resolved_sha`, `declaration`, `last_change`, `coverage`,
|
|
180
|
+
`commits_read`, `termination`, `next_sha` and structured `failures`.
|
|
181
|
+
`declaration` is `{file, field, package_name, value}`. `last_change` identifies the
|
|
182
|
+
commit, committer time, old/new values, `history_mode: first_parent` and whether
|
|
183
|
+
this is a field change or actual root declaration. A dependency edit is not a
|
|
184
|
+
version-field change. Source path, field and package identity stay fixed during
|
|
185
|
+
the walk; renamed files, shallow/missing parents and exhausted budgets remain
|
|
186
|
+
incomplete. `next_sha` describes a stop point, not an automatic resume mechanism.
|
|
187
|
+
The optional `baseline_evidence` pins both refs and compares their declarations
|
|
188
|
+
and complete commit range. `evidence_complete` covers both requested facets.
|
|
189
|
+
Use the command's help for ref, path, baseline and history-budget options.
|
|
190
|
+
|
|
191
|
+
Automatic declaration discovery skips dependency-only files such as
|
|
192
|
+
`requirements.txt`. A present but unreadable supported source remains incomplete;
|
|
193
|
+
only the documented Gradle fallback selects adjacent `gradle.properties`.
|
|
194
|
+
Maven versions must be literals or one project property resolved to a literal.
|
|
195
|
+
Composite, nested or unresolved expressions retain
|
|
196
|
+
`VERSION_DECLARATION_UNREADABLE`; they are not concrete versions.
|
|
197
|
+
|
|
166
198
|
### Diagnostic reports
|
|
167
199
|
|
|
168
200
|
Login and doctor reject unknown explicit tool/environment selectors before setup
|
|
@@ -174,9 +206,15 @@ same ambiguous setup. Doctor marks its missing verification as incomplete.
|
|
|
174
206
|
`fx doctor` returns `preparation`, diagnostic `coverage` (`complete` or `incomplete`),
|
|
175
207
|
`summary {ok, warn, fail}` and `findings[]`. The preparation verdict owns task completion;
|
|
176
208
|
optional host activation can remain unverified. An incomplete verdict exits 12.
|
|
177
|
-
`fx release check` returns `ok`, `complete`, summary and findings and exits zero when its
|
|
209
|
+
`fx release check` returns `ok`, `complete`, `evidence_complete`, summary and findings and exits zero when its
|
|
178
210
|
checklist was produced. Findings carry group, id, level, coverage, message, fix and
|
|
179
|
-
handoff;
|
|
211
|
+
handoff; caught query errors also carry a structured `failure` with recovery, retained
|
|
212
|
+
in compact JSON. Full results also carry evidence. Incomplete checks are not passes:
|
|
213
|
+
`RELEASE_INCOMPLETE` means no confirmed failure but missing evidence, and a known
|
|
214
|
+
failure can also have incomplete coverage. Human output groups identical unavailable
|
|
215
|
+
causes separately from confirmed problems; `--details` expands all repository checks.
|
|
216
|
+
A missing error-tracker project is incomplete coverage and must be corrected or
|
|
217
|
+
explicitly marked not covered; never substitute an organization-wide query. `repos[]` says what each release would ship,
|
|
180
218
|
in summaries too. For `can`, inspect its capability status.
|
|
181
219
|
|
|
182
220
|
Doctor groups are `repos`, `root`, `tools`, `login`, `agents`, `manifest`, `self`,
|
|
@@ -192,33 +230,59 @@ repair rows; use `--details` to inspect all attempts. Each attempt is
|
|
|
192
230
|
structured recovery errors before post-repair findings are collected.
|
|
193
231
|
`completed` means the repair ran, not that the subsequent check passed.
|
|
194
232
|
|
|
195
|
-
`fx release check
|
|
196
|
-
[--jobs]` covers repositories selected by manifest release policy; `fx release` is its
|
|
233
|
+
`fx release check` covers repositories selected by manifest release policy; `fx release` is its
|
|
197
234
|
compatibility name. It is read-only: it never merges, tags, publishes or deploys.
|
|
235
|
+
Use `--help` for selection, absolute/relative error windows and optional version
|
|
236
|
+
history, historical baseline and version-path overrides. Override keys must name
|
|
237
|
+
selected repositories; use a separate invocation for multiple packages in one repo.
|
|
198
238
|
|
|
199
|
-
Each `repos[]` entry
|
|
200
|
-
unanswered
|
|
239
|
+
Each `repos[]` entry includes `name`, `source`, `target`, `version_file`, `unmerged`,
|
|
240
|
+
`note` and `unanswered`, plus `range`, `version_evidence`, `baseline_evidence` and
|
|
241
|
+
`facet_coverage`. `source`
|
|
201
242
|
and `target` are the branch heads `{branch, sha, date, message, version}`; `version` is
|
|
202
|
-
what the
|
|
203
|
-
|
|
243
|
+
what the selected root `VERSION` or package metadata declares at that commit, null
|
|
244
|
+
when unknown. `target` is null for a repository releasing from one branch, and both are null
|
|
204
245
|
when the code host was not asked or did not answer, which the findings explain.
|
|
205
246
|
`unmerged` is `{commits, authors}`: how many people's commits the source has that the
|
|
206
247
|
target lacks, and how many people wrote them; null when not compared. To read those
|
|
207
248
|
commits, ask the code host's own CLI for the range from `target.sha` to `source.sha`;
|
|
208
249
|
`fx repo show <repo>` gives where the repository lives on the host. `unanswered[]` lists
|
|
209
|
-
each question to the code host that failed as `{field, reason}`, where `
|
|
250
|
+
each question to the code host that failed as `{field, reason, error}`, where `error`
|
|
251
|
+
retains structured recovery and `field` is the
|
|
210
252
|
value left null (`version_file`, `source.commit`, `source.version`, `target.commit`,
|
|
211
253
|
`target.version`, `unmerged`); a null without an entry means the repository declares
|
|
212
254
|
none.
|
|
213
255
|
|
|
256
|
+
`version_evidence` uses the standalone version contract above. `baseline_evidence`
|
|
257
|
+
is `{baseline, head, commits, coverage, failures}`. The default JSON summary replaces
|
|
258
|
+
the commit array with `commits_count` and an omitted count; `--details` or explicit
|
|
259
|
+
`--fields` retains the full array. Failures remain visible. Each snapshot has
|
|
260
|
+
`requested_ref`, `resolved_sha` and `declaration`. Its commits include bots and
|
|
261
|
+
merges since the caller's baseline, independently of `unmerged`. A version-field
|
|
262
|
+
change, tag or source declaration does not establish an artifact build, publication
|
|
263
|
+
or deployment. fx does not infer a next minor version.
|
|
264
|
+
|
|
265
|
+
`facet_coverage` distinguishes `checked`, `incomplete`, `not_requested` and
|
|
266
|
+
`not_applicable` for `declaration`, `version_history`, `baseline` and `errors`.
|
|
267
|
+
Error findings also retain a top-level `failures` array in summary output, with
|
|
268
|
+
structured error codes, retryability and recovery steps. Detailed error candidates
|
|
269
|
+
keep the latest metadata observation per ID; a resolved/ignored detail can follow
|
|
270
|
+
an unresolved list result and is excluded from the fresh-issue verdict.
|
|
271
|
+
|
|
272
|
+
`evidence_complete` additionally covers requested facts and unanswered questions;
|
|
273
|
+
it does not redefine `ok` or check coverage `complete`. The report's `observed_at`
|
|
274
|
+
is one command-start timestamp. Absolute ranges normalize to UTC and use
|
|
275
|
+
`[start,end)`; relative policies share this observation time but can use different
|
|
276
|
+
durations. The top-level `range` is null when per-repository ranges differ.
|
|
277
|
+
|
|
214
278
|
Evidence is grouped by check:
|
|
215
279
|
|
|
216
|
-
| Group | Evidence
|
|
217
|
-
| -------- |
|
|
218
|
-
| `merge` | `source`, `target`, `ahead[]`, `behind[]`, `filtered`, `unknown[]` directions; commits have `sha`, `author {id, name}`, `date`, `message`
|
|
219
|
-
| `deps` | `file`, `offending[] {name, version, section, runtime}`
|
|
220
|
-
| `ci` | `builds[] {side, env, branch, path, number, status, started_at, url, commit, head, current}`; null `path` means no declared job
|
|
221
|
-
| `errors` | `env`, `slug`, `since`, `capped`, `undated`, `issues[]
|
|
280
|
+
| Group | Evidence |
|
|
281
|
+
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
282
|
+
| `merge` | `source`, `target`, `ahead[]`, `behind[]`, `filtered`, `unknown[]` directions; commits have `sha`, `author {id, name}`, `date`, `message` |
|
|
283
|
+
| `deps` | `file`, `offending[] {name, version, section, runtime}` |
|
|
284
|
+
| `ci` | `builds[] {side, env, branch, path, number, status, started_at, url, commit, head, current}`; null `path` means no declared job |
|
|
285
|
+
| `errors` | `query_context`, `env`, `slug`, `since`, `capped`, `undated`, legacy fresh `issues[]`, and complete candidate metadata in `error_evidence` |
|
|
222
286
|
|
|
223
287
|
CI `current` compares the commit the build checked out, `commit`, with the branch head
|
|
224
288
|
`head` when the platform names it. A null `commit` (Jenkins before jenkins-cli 0.12.0)
|
|
@@ -227,13 +291,50 @@ freshness heuristic, not revision verification; use the companion's build detail
|
|
|
227
291
|
when the task requires an exact commit match.
|
|
228
292
|
The full report's merge/dependency/issue evidence is available with `--details`.
|
|
229
293
|
|
|
294
|
+
Every errors finding includes `evidence.query_context`, even when authentication
|
|
295
|
+
or collection fails or the check is not applicable. It is
|
|
296
|
+
`{repository, environment, range, observed_at, source}`; `source` is
|
|
297
|
+
`{platform, provider, coordinate_fingerprint}` or null for an unavailable or
|
|
298
|
+
explicitly uncovered coordinate. The fingerprint preserves the provider's query
|
|
299
|
+
identity before authentication without exposing arbitrary vars.
|
|
300
|
+
|
|
301
|
+
Sentry query fingerprints identify the configured endpoint, organization and
|
|
302
|
+
project selector, so repository aliases for one project retain the same source
|
|
303
|
+
identity. Repository and environment are bound separately in `query_context`.
|
|
304
|
+
Other tracker providers may supply their own query fingerprint; without it, the
|
|
305
|
+
full canonical coordinate fingerprint is retained conservatively.
|
|
306
|
+
|
|
307
|
+
For an audited retry, match the repository, environment, normalized range and
|
|
308
|
+
non-null source identity before superseding an earlier failure; keep both
|
|
309
|
+
observation times. A different server, organization, project or period is another
|
|
310
|
+
query. Each attempt remains separate and is not an atomic remote snapshot.
|
|
311
|
+
|
|
312
|
+
`error_evidence` retains every collected candidate returned by an unresolved
|
|
313
|
+
query and active in the range, including older issues. It carries `items`, `range`, `observed_at`,
|
|
314
|
+
`pages_read`, `has_more`, optional `next`, `coverage`, `failures` and
|
|
315
|
+
`truncation_reason`. Inspect these before treating a query as complete. fx follows
|
|
316
|
+
pagination internally; there is no public cursor-resume flag. Keep the same
|
|
317
|
+
absolute bounds when retrying or investigating a continuation with the companion.
|
|
318
|
+
Lifetime first-seen comes from issue detail; `lifetime_first_seen` and
|
|
319
|
+
`first_seen_scope` never use window/list dates as a fallback. Missing details
|
|
320
|
+
remain unknown. `list_first_seen` has unknown scope and `window_first_seen` stays
|
|
321
|
+
separate. `count_scope: unknown` prevents treating counts as newly occurring
|
|
322
|
+
events. `status_scope: current` describes each item's actual `status_observed_at`,
|
|
323
|
+
not state at the historical window; the aggregate status time is null. Assignee
|
|
324
|
+
is read metadata, not a selected or newly assigned owner. The legacy verdict
|
|
325
|
+
counts lifetime first appearances only; old regressions require separate review.
|
|
326
|
+
|
|
230
327
|
Uncovered explicit repositories yield `REPO_NOT_COVERED`, unmatched tags
|
|
231
328
|
`TAG_NOT_FOUND`, unknown environments `ENV_NOT_FOUND`, and an empty checklist
|
|
232
329
|
`CHECKLIST_EMPTY`. `--since` accepts windows such as `14d`, `48h` or `2w`;
|
|
233
|
-
invalid windows yield `BAD_SINCE`.
|
|
330
|
+
invalid windows yield `BAD_SINCE`. Mixing relative and absolute bounds, missing a
|
|
331
|
+
bound or invalid timezone-qualified timestamps yields `BAD_TIME_RANGE`.
|
|
332
|
+
Missing platform responses/jobs, undated
|
|
234
333
|
issues and builds that cannot be dated against the branch head warn rather
|
|
235
|
-
than prove readiness.
|
|
236
|
-
|
|
334
|
+
than prove readiness. Closing notices distinguish `RELEASE_FAILURES` for confirmed
|
|
335
|
+
failures, `RELEASE_INCOMPLETE` for missing check coverage without confirmed failures,
|
|
336
|
+
and `RELEASE_OK` for complete checks without failures. Inspect `evidence_complete`
|
|
337
|
+
separately for requested repository facts.
|
|
237
338
|
|
|
238
339
|
### Update notices
|
|
239
340
|
|