@copado/agentia-cli 0.116.0-alpha.0 → 0.118.0-alpha.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/README.md +369 -358
- package/dist/commands/cicd/work/commit.d.ts +0 -5
- package/dist/commands/cicd/work/commit.js +18 -33
- package/dist/commands/cicd/work/commit.js.map +1 -1
- package/dist/commands/cicd/work/publish.d.ts +12 -0
- package/dist/commands/cicd/work/publish.js +20 -0
- package/dist/commands/cicd/work/publish.js.map +1 -0
- package/dist/commands/cicd/work/push.d.ts +4 -0
- package/dist/commands/cicd/work/push.js +11 -82
- package/dist/commands/cicd/work/push.js.map +1 -1
- package/dist/commands/cicd/work/set.d.ts +2 -2
- package/dist/commands/cicd/work/set.js +6 -2
- package/dist/commands/cicd/work/set.js.map +1 -1
- package/dist/commands/cicd/work/status.js +14 -13
- package/dist/commands/cicd/work/status.js.map +1 -1
- package/dist/commands/cicd/work/submit.d.ts +2 -0
- package/dist/commands/cicd/work/submit.js +11 -3
- package/dist/commands/cicd/work/submit.js.map +1 -1
- package/dist/commands/cicd/work/test/apex.d.ts +11 -0
- package/dist/commands/cicd/work/test/apex.js +57 -0
- package/dist/commands/cicd/work/test/apex.js.map +1 -0
- package/dist/commands/cicd/work/test.js +12 -4
- package/dist/commands/cicd/work/test.js.map +1 -1
- package/dist/lib/cicd-gateway.d.ts +4 -0
- package/dist/lib/cicd-gateway.js +49 -3
- package/dist/lib/cicd-gateway.js.map +1 -1
- package/dist/lib/defaults-store.d.ts +1 -1
- package/dist/lib/defaults-store.js +1 -1
- package/dist/lib/git-worktree.d.ts +6 -0
- package/dist/lib/git-worktree.js +35 -1
- package/dist/lib/git-worktree.js.map +1 -1
- package/dist/lib/local-quality-gates.d.ts +4 -0
- package/dist/lib/local-quality-gates.js +1 -1
- package/dist/lib/local-quality-gates.js.map +1 -1
- package/dist/lib/mcp/tools.d.ts +12 -2
- package/dist/lib/mcp/tools.js +10 -8
- package/dist/lib/mcp/tools.js.map +1 -1
- package/dist/lib/mcp/work-tools.d.ts +18 -6
- package/dist/lib/mcp/work-tools.js +75 -50
- package/dist/lib/mcp/work-tools.js.map +1 -1
- package/dist/lib/nested-metadata-changes.d.ts +4 -4
- package/dist/lib/setup-templates.d.ts +3 -3
- package/dist/lib/setup-templates.js +33 -28
- package/dist/lib/setup-templates.js.map +1 -1
- package/dist/lib/setup-wizard.js +1 -1
- package/dist/lib/setup-wizard.js.map +1 -1
- package/dist/lib/stock-quality-gates.d.ts +12 -0
- package/dist/lib/stock-quality-gates.js +67 -0
- package/dist/lib/stock-quality-gates.js.map +1 -0
- package/dist/lib/work-apex-test.d.ts +56 -0
- package/dist/lib/work-apex-test.js +265 -0
- package/dist/lib/work-apex-test.js.map +1 -0
- package/dist/lib/work-branch-metadata.d.ts +2 -0
- package/dist/lib/work-branch-metadata.js +9 -0
- package/dist/lib/work-branch-metadata.js.map +1 -1
- package/dist/lib/work-local-commit.d.ts +1 -1
- package/dist/lib/work-local-commit.js +1 -1
- package/dist/lib/work-publish-command.d.ts +26 -0
- package/dist/lib/work-publish-command.js +88 -0
- package/dist/lib/work-publish-command.js.map +1 -0
- package/dist/lib/work-push.d.ts +3 -3
- package/dist/lib/work-push.js +12 -12
- package/dist/lib/work-push.js.map +1 -1
- package/dist/lib/work-set-selection.d.ts +3 -1
- package/dist/lib/work-set-selection.js +19 -1
- package/dist/lib/work-set-selection.js.map +1 -1
- package/dist/lib/work-types.d.ts +12 -1
- package/dist/lib/work-types.js.map +1 -1
- package/oclif.manifest.json +292 -212
- package/package.json +4 -1
- package/templates/AGENTS.md +2 -2
- package/templates/skills/agentia-cicd/SKILL.md +4 -3
- package/templates/skills/agentia-cicd/references/work.md +25 -23
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
import { getMcpRequestSignal } from './mcp/request-context.js';
|
|
4
|
+
const execFileAsync = promisify(execFile);
|
|
5
|
+
export const DEFAULT_APEX_TEST_WAIT_MINUTES = 60;
|
|
6
|
+
const APEX_TEST_MAX_BUFFER_BYTES = 32 * 1024 * 1024;
|
|
7
|
+
const APEX_TEST_TIMEOUT_BUFFER_MS = 60_000;
|
|
8
|
+
const APEX_CLASS_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_]*(\.[A-Za-z][A-Za-z0-9_]*)?$/;
|
|
9
|
+
const ORG_ID_PATTERN = /\b00D[A-Za-z0-9]{12,15}\b/g;
|
|
10
|
+
const USER_ID_PATTERN = /\b005[A-Za-z0-9]{12,15}\b/g;
|
|
11
|
+
const FAILED_OUTCOMES = new Set(['compilefail', 'fail']);
|
|
12
|
+
export class WorkApexTestError extends Error {
|
|
13
|
+
result;
|
|
14
|
+
constructor(result) {
|
|
15
|
+
const failing = result.summary.failing ?? result.tests.filter((test) => isFailedOutcome(test.outcome)).length;
|
|
16
|
+
super(`Apex tests failed (${failing} failing).`);
|
|
17
|
+
this.name = 'WorkApexTestError';
|
|
18
|
+
this.result = result;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
let sfApexTestExecFn = defaultSfApexTestExec;
|
|
22
|
+
export function buildSfApexTestArgs(classNames, waitMinutes) {
|
|
23
|
+
return ['apex', 'run', 'test', '--class-names', ...classNames, '-c', '--json', '--wait', String(waitMinutes)];
|
|
24
|
+
}
|
|
25
|
+
export function parseApexTestClassNames(value) {
|
|
26
|
+
const names = value
|
|
27
|
+
.split(/[,\s]+/)
|
|
28
|
+
.map((name) => name.trim())
|
|
29
|
+
.filter((name) => name.length > 0);
|
|
30
|
+
if (names.length === 0) {
|
|
31
|
+
throw new Error('Requires `--apex-test-classes`.');
|
|
32
|
+
}
|
|
33
|
+
const unique = [];
|
|
34
|
+
const seen = new Set();
|
|
35
|
+
for (const name of names) {
|
|
36
|
+
if (!APEX_CLASS_NAME_PATTERN.test(name)) {
|
|
37
|
+
throw new Error(`Invalid Apex test class name '${name}'. Use identifiers such as MyTest or Namespace.MyTest.`);
|
|
38
|
+
}
|
|
39
|
+
if (seen.has(name)) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
seen.add(name);
|
|
43
|
+
unique.push(name);
|
|
44
|
+
}
|
|
45
|
+
return unique;
|
|
46
|
+
}
|
|
47
|
+
export function validateApexTestWaitMinutes(waitMinutes) {
|
|
48
|
+
if (!Number.isInteger(waitMinutes) || waitMinutes < 1) {
|
|
49
|
+
throw new Error('`--wait` must be a positive integer number of minutes.');
|
|
50
|
+
}
|
|
51
|
+
return waitMinutes;
|
|
52
|
+
}
|
|
53
|
+
export function formatWorkApexTestHuman(result) {
|
|
54
|
+
const failedTests = result.tests.filter((test) => isFailedOutcome(test.outcome));
|
|
55
|
+
const lines = [
|
|
56
|
+
`Apex tests: ${result.summary.outcome ?? (failedTests.length === 0 ? 'Passed' : 'Failed')}`,
|
|
57
|
+
...summaryLines(result.summary),
|
|
58
|
+
];
|
|
59
|
+
if (failedTests.length === 0) {
|
|
60
|
+
return lines.join('\n');
|
|
61
|
+
}
|
|
62
|
+
return [
|
|
63
|
+
...lines,
|
|
64
|
+
'',
|
|
65
|
+
'Failed tests:',
|
|
66
|
+
...failedTests.flatMap((test) => [
|
|
67
|
+
'',
|
|
68
|
+
testLabel(test),
|
|
69
|
+
...(test.outcome === undefined ? [] : [` Outcome: ${test.outcome}`]),
|
|
70
|
+
...(test.message === undefined ? [] : [` Message: ${test.message}`]),
|
|
71
|
+
...(test.stackTrace === undefined ? [] : [` StackTrace: ${test.stackTrace}`]),
|
|
72
|
+
]),
|
|
73
|
+
].join('\n');
|
|
74
|
+
}
|
|
75
|
+
export async function runWorkApexTests({ classNames, waitMinutes: requestedWaitMinutes, }) {
|
|
76
|
+
const waitMinutes = validateApexTestWaitMinutes(requestedWaitMinutes);
|
|
77
|
+
const args = buildSfApexTestArgs(classNames, waitMinutes);
|
|
78
|
+
let stdout;
|
|
79
|
+
try {
|
|
80
|
+
const executed = await sfApexTestExecFn(args, {
|
|
81
|
+
maxBuffer: APEX_TEST_MAX_BUFFER_BYTES,
|
|
82
|
+
signal: getMcpRequestSignal(),
|
|
83
|
+
timeout: waitMinutes * 60 * 1000 + APEX_TEST_TIMEOUT_BUFFER_MS,
|
|
84
|
+
});
|
|
85
|
+
stdout = executed.stdout;
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
throw new Error(sanitizeApexTestError(error));
|
|
89
|
+
}
|
|
90
|
+
const parsed = extractJsonObject(stdout);
|
|
91
|
+
if (parsed.result === undefined) {
|
|
92
|
+
throw new Error(sanitizeApexTestError(parsed.message ?? parsed.name ?? 'Salesforce CLI Apex test run failed.'));
|
|
93
|
+
}
|
|
94
|
+
const result = parseSfApexTestJson(stdout, classNames, waitMinutes);
|
|
95
|
+
if (isTestRunFailed(result)) {
|
|
96
|
+
throw new WorkApexTestError(result);
|
|
97
|
+
}
|
|
98
|
+
if (typeof parsed.status === 'number' && parsed.status !== 0) {
|
|
99
|
+
throw new Error(sanitizeApexTestError(parsed.message ?? parsed.name ?? 'Salesforce CLI Apex test run failed.'));
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
export function parseSfApexTestJson(raw, classNames, waitMinutes) {
|
|
104
|
+
const parsed = extractJsonObject(raw);
|
|
105
|
+
if (parsed.result === undefined) {
|
|
106
|
+
throw new Error(sanitizeApexTestError(parsed.message ?? parsed.name ?? 'Salesforce CLI Apex test run failed.'));
|
|
107
|
+
}
|
|
108
|
+
const tests = (parsed.result.tests ?? []).flatMap((item) => {
|
|
109
|
+
const mapped = mapTestMethod(item);
|
|
110
|
+
return mapped === undefined ? [] : [mapped];
|
|
111
|
+
});
|
|
112
|
+
const summary = mapSummary(parsed.result.summary ?? {});
|
|
113
|
+
return {
|
|
114
|
+
classNames,
|
|
115
|
+
summary,
|
|
116
|
+
tests,
|
|
117
|
+
waitMinutes,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export function setSfApexTestExecForTests(fn) {
|
|
121
|
+
sfApexTestExecFn = fn;
|
|
122
|
+
}
|
|
123
|
+
export function resetSfApexTestExecForTests() {
|
|
124
|
+
sfApexTestExecFn = defaultSfApexTestExec;
|
|
125
|
+
}
|
|
126
|
+
async function defaultSfApexTestExec(args, options) {
|
|
127
|
+
try {
|
|
128
|
+
const { stderr, stdout } = await execFileAsync('sf', args, {
|
|
129
|
+
encoding: 'utf8',
|
|
130
|
+
maxBuffer: options.maxBuffer,
|
|
131
|
+
signal: options.signal,
|
|
132
|
+
timeout: options.timeout,
|
|
133
|
+
});
|
|
134
|
+
return { stderr: stderr.toString(), stdout: stdout.toString() };
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
if (isExecFileError(error) && typeof error.stdout === 'string' && error.stdout.trim().length > 0) {
|
|
138
|
+
return {
|
|
139
|
+
stderr: typeof error.stderr === 'string' ? error.stderr : '',
|
|
140
|
+
stdout: error.stdout,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function extractJsonObject(raw) {
|
|
147
|
+
const start = raw.indexOf('{');
|
|
148
|
+
if (start === -1) {
|
|
149
|
+
throw new Error('Salesforce CLI returned non-JSON output.');
|
|
150
|
+
}
|
|
151
|
+
return JSON.parse(raw.slice(start));
|
|
152
|
+
}
|
|
153
|
+
function mapSummary(summary) {
|
|
154
|
+
return {
|
|
155
|
+
...(optionalString(summary.commandTime) === undefined ? {} : { commandTime: optionalString(summary.commandTime) }),
|
|
156
|
+
...(optionalString(summary.failRate) === undefined ? {} : { failRate: optionalString(summary.failRate) }),
|
|
157
|
+
...(optionalNumber(summary.failing) === undefined ? {} : { failing: optionalNumber(summary.failing) }),
|
|
158
|
+
...(optionalString(summary.orgWideCoverage) === undefined
|
|
159
|
+
? {}
|
|
160
|
+
: { orgWideCoverage: optionalString(summary.orgWideCoverage) }),
|
|
161
|
+
...(optionalString(summary.outcome) === undefined ? {} : { outcome: optionalString(summary.outcome) }),
|
|
162
|
+
...(optionalString(summary.passRate) === undefined ? {} : { passRate: optionalString(summary.passRate) }),
|
|
163
|
+
...(optionalNumber(summary.passing) === undefined ? {} : { passing: optionalNumber(summary.passing) }),
|
|
164
|
+
...(optionalNumber(summary.skipped) === undefined ? {} : { skipped: optionalNumber(summary.skipped) }),
|
|
165
|
+
...(optionalString(summary.testExecutionTime) === undefined
|
|
166
|
+
? {}
|
|
167
|
+
: { testExecutionTime: optionalString(summary.testExecutionTime) }),
|
|
168
|
+
...(optionalString(summary.testRunCoverage) === undefined
|
|
169
|
+
? {}
|
|
170
|
+
: { testRunCoverage: optionalString(summary.testRunCoverage) }),
|
|
171
|
+
...(optionalString(summary.testRunId) === undefined ? {} : { testRunId: optionalString(summary.testRunId) }),
|
|
172
|
+
...(optionalString(summary.testStartTime) === undefined
|
|
173
|
+
? {}
|
|
174
|
+
: { testStartTime: optionalString(summary.testStartTime) }),
|
|
175
|
+
...(optionalString(summary.testTotalTime) === undefined ? {} : { testTotalTime: optionalString(summary.testTotalTime) }),
|
|
176
|
+
...(optionalNumber(summary.testsRan) === undefined ? {} : { testsRan: optionalNumber(summary.testsRan) }),
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function mapTestMethod(value) {
|
|
180
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
const record = value;
|
|
184
|
+
const apexClass = record.ApexClass !== null && typeof record.ApexClass === 'object' && !Array.isArray(record.ApexClass)
|
|
185
|
+
? record.ApexClass
|
|
186
|
+
: undefined;
|
|
187
|
+
const mapped = {
|
|
188
|
+
...(optionalString(apexClass?.Name) === undefined ? {} : { className: optionalString(apexClass?.Name) }),
|
|
189
|
+
...(optionalString(record.FullName) === undefined ? {} : { fullName: optionalString(record.FullName) }),
|
|
190
|
+
...(optionalString(record.Message) === undefined ? {} : { message: optionalString(record.Message) }),
|
|
191
|
+
...(optionalString(record.MethodName) === undefined ? {} : { methodName: optionalString(record.MethodName) }),
|
|
192
|
+
...(optionalString(record.Outcome) === undefined ? {} : { outcome: optionalString(record.Outcome) }),
|
|
193
|
+
...(optionalString(record.StackTrace) === undefined ? {} : { stackTrace: optionalString(record.StackTrace) }),
|
|
194
|
+
};
|
|
195
|
+
return Object.keys(mapped).length === 0 ? undefined : mapped;
|
|
196
|
+
}
|
|
197
|
+
function isTestRunFailed(result) {
|
|
198
|
+
if (result.tests.some((test) => isFailedOutcome(test.outcome))) {
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
const outcome = result.summary.outcome?.trim().toLowerCase();
|
|
202
|
+
return outcome === 'failed' || (result.summary.failing ?? 0) > 0;
|
|
203
|
+
}
|
|
204
|
+
function isFailedOutcome(outcome) {
|
|
205
|
+
return outcome !== undefined && FAILED_OUTCOMES.has(outcome.trim().toLowerCase());
|
|
206
|
+
}
|
|
207
|
+
function testLabel(test) {
|
|
208
|
+
if (test.fullName !== undefined && test.fullName.length > 0) {
|
|
209
|
+
return test.fullName;
|
|
210
|
+
}
|
|
211
|
+
const joined = [test.className, test.methodName]
|
|
212
|
+
.filter((part) => part !== undefined && part.length > 0)
|
|
213
|
+
.join('.');
|
|
214
|
+
return joined.length > 0 ? joined : 'unknown test';
|
|
215
|
+
}
|
|
216
|
+
function summaryLines(summary) {
|
|
217
|
+
const lines = [];
|
|
218
|
+
pushLine(lines, 'Tests ran', summary.testsRan);
|
|
219
|
+
pushLine(lines, 'Passing', summary.passing);
|
|
220
|
+
pushLine(lines, 'Failing', summary.failing);
|
|
221
|
+
pushLine(lines, 'Skipped', summary.skipped);
|
|
222
|
+
pushLine(lines, 'Pass rate', summary.passRate);
|
|
223
|
+
pushLine(lines, 'Fail rate', summary.failRate);
|
|
224
|
+
pushLine(lines, 'Test run coverage', summary.testRunCoverage);
|
|
225
|
+
pushLine(lines, 'Org-wide coverage', summary.orgWideCoverage);
|
|
226
|
+
pushLine(lines, 'Test execution time', summary.testExecutionTime);
|
|
227
|
+
return lines;
|
|
228
|
+
}
|
|
229
|
+
function pushLine(lines, label, value) {
|
|
230
|
+
if (value === undefined || value === '') {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
lines.push(`${label}: ${value}`);
|
|
234
|
+
}
|
|
235
|
+
function optionalString(value) {
|
|
236
|
+
if (typeof value !== 'string') {
|
|
237
|
+
return undefined;
|
|
238
|
+
}
|
|
239
|
+
const sanitized = sanitizeIdentity(value).trim();
|
|
240
|
+
return sanitized.length === 0 ? undefined : sanitized;
|
|
241
|
+
}
|
|
242
|
+
function optionalNumber(value) {
|
|
243
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
244
|
+
}
|
|
245
|
+
function sanitizeApexTestError(error) {
|
|
246
|
+
if (isExecFileError(error) && error.code === 'ENOENT') {
|
|
247
|
+
return 'Salesforce CLI (`sf`) is not installed or is not on PATH.';
|
|
248
|
+
}
|
|
249
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
250
|
+
return 'Apex test run was cancelled.';
|
|
251
|
+
}
|
|
252
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
253
|
+
const cleaned = sanitizeIdentity(message).trim();
|
|
254
|
+
if (cleaned.length === 0) {
|
|
255
|
+
return 'Salesforce CLI Apex test run failed.';
|
|
256
|
+
}
|
|
257
|
+
return `Salesforce CLI Apex test run failed: ${cleaned}`;
|
|
258
|
+
}
|
|
259
|
+
function sanitizeIdentity(value) {
|
|
260
|
+
return value.replaceAll(ORG_ID_PATTERN, '<org-id>').replaceAll(USER_ID_PATTERN, '<user-id>');
|
|
261
|
+
}
|
|
262
|
+
function isExecFileError(error) {
|
|
263
|
+
return error instanceof Error;
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=work-apex-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-apex-test.js","sourceRoot":"","sources":["../../src/lib/work-apex-test.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,3 +9,5 @@ export type WorkBranchMetadataResult = {
|
|
|
9
9
|
metadataList: WorkBranchMetadataItem[];
|
|
10
10
|
};
|
|
11
11
|
export declare function resolveWorkBranchMetadata(baseRef: string, moduleType?: ModuleType): Promise<WorkBranchMetadataResult>;
|
|
12
|
+
/** Local branch metadata when `work set` recorded lastBaseBranch; otherwise undefined. */
|
|
13
|
+
export declare function resolveRecordedWorkBranchMetadata(moduleType?: ModuleType): Promise<undefined | WorkBranchMetadataResult>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readLastBaseBranch } from './defaults-store.js';
|
|
1
2
|
import { resolvedSelectionsFromChangedFiles } from './dependency-from-changes.js';
|
|
2
3
|
const NO_METADATA_MESSAGES = [
|
|
3
4
|
'No changed files were found',
|
|
@@ -28,4 +29,12 @@ export async function resolveWorkBranchMetadata(baseRef, moduleType) {
|
|
|
28
29
|
return { baseRef, metadataList: [] };
|
|
29
30
|
}
|
|
30
31
|
}
|
|
32
|
+
/** Local branch metadata when `work set` recorded lastBaseBranch; otherwise undefined. */
|
|
33
|
+
export async function resolveRecordedWorkBranchMetadata(moduleType) {
|
|
34
|
+
const baseRef = (await readLastBaseBranch())?.trim();
|
|
35
|
+
if (!baseRef) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
return resolveWorkBranchMetadata(baseRef, moduleType);
|
|
39
|
+
}
|
|
31
40
|
//# sourceMappingURL=work-branch-metadata.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"work-branch-metadata.js","sourceRoot":"","sources":["../../src/lib/work-branch-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kCAAkC,EAAC,MAAM,8BAA8B,CAAA;AAc/E,MAAM,oBAAoB,GAAG;IAC3B,6BAA6B;IAC7B,8CAA8C;CAC/C,CAAA;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;AAClF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAe,EACf,UAAuB;IAEvB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,kCAAkC,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;QAEhF,OAAO;YACL,OAAO;YACP,YAAY,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,EAAC,UAAU,EAAE,SAAS,EAAC,EAAE,EAAE,CAAC,CAAC;gBACzD,UAAU;gBACV,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,IAAI,EAAE,SAAS,CAAC,IAAI;aACrB,CAAC,CAAC;SACJ,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAA;QACb,CAAC;QAED,OAAO,EAAC,OAAO,EAAE,YAAY,EAAE,EAAE,EAAC,CAAA;IACpC,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"work-branch-metadata.js","sourceRoot":"","sources":["../../src/lib/work-branch-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAC,kCAAkC,EAAC,MAAM,8BAA8B,CAAA;AAc/E,MAAM,oBAAoB,GAAG;IAC3B,6BAA6B;IAC7B,8CAA8C;CAC/C,CAAA;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;AAClF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAe,EACf,UAAuB;IAEvB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,kCAAkC,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;QAEhF,OAAO;YACL,OAAO;YACP,YAAY,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,EAAC,UAAU,EAAE,SAAS,EAAC,EAAE,EAAE,CAAC,CAAC;gBACzD,UAAU;gBACV,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,IAAI,EAAE,SAAS,CAAC,IAAI;aACrB,CAAC,CAAC;SACJ,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,KAAK,CAAA;QACb,CAAC;QAED,OAAO,EAAC,OAAO,EAAE,YAAY,EAAE,EAAE,EAAC,CAAA;IACpC,CAAC;AACH,CAAC;AAED,0FAA0F;AAC1F,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,UAAuB;IAEvB,MAAM,OAAO,GAAG,CAAC,MAAM,kBAAkB,EAAE,CAAC,EAAE,IAAI,EAAE,CAAA;IACpD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,OAAO,yBAAyB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;AACvD,CAAC"}
|
|
@@ -35,7 +35,7 @@ export declare function resolveWorkLocalCommitMessage(explicitMessage?: string):
|
|
|
35
35
|
workItem?: string;
|
|
36
36
|
}>;
|
|
37
37
|
/**
|
|
38
|
-
* Runs a plain `git commit` and records the Copado selections consumed later by `cicd work
|
|
38
|
+
* Runs a plain `git commit` and records the Copado selections consumed later by `cicd work publish`.
|
|
39
39
|
* No gateway call is made.
|
|
40
40
|
*/
|
|
41
41
|
export declare function performWorkLocalCommit(input: WorkLocalCommitInput): Promise<WorkLocalCommitResult>;
|
|
@@ -83,7 +83,7 @@ function gitFailureMessage(error) {
|
|
|
83
83
|
return detail.length > 0 ? detail : error instanceof Error ? error.message : String(error);
|
|
84
84
|
}
|
|
85
85
|
/**
|
|
86
|
-
* Runs a plain `git commit` and records the Copado selections consumed later by `cicd work
|
|
86
|
+
* Runs a plain `git commit` and records the Copado selections consumed later by `cicd work publish`.
|
|
87
87
|
* No gateway call is made.
|
|
88
88
|
*/
|
|
89
89
|
export async function performWorkLocalCommit(input) {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type WorkPushResult } from './work-types.js';
|
|
2
|
+
export declare const WORK_PUBLISH_DESCRIPTION: string;
|
|
3
|
+
export declare const workPublishFlags: {
|
|
4
|
+
readonly 'full-metadata': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
5
|
+
readonly permissions: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
|
+
readonly 'skip-nested-metadata-detection': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
};
|
|
8
|
+
export type WorkPublishFlagValues = {
|
|
9
|
+
'full-metadata'?: string;
|
|
10
|
+
permissions?: string;
|
|
11
|
+
'skip-nested-metadata-detection'?: boolean;
|
|
12
|
+
};
|
|
13
|
+
export type WorkPublishHost = {
|
|
14
|
+
config: {
|
|
15
|
+
bin: string;
|
|
16
|
+
};
|
|
17
|
+
display(render: () => void): void;
|
|
18
|
+
error(input: Error | string, options?: {
|
|
19
|
+
exit?: false | number;
|
|
20
|
+
suggestions?: string[];
|
|
21
|
+
}): never;
|
|
22
|
+
log(message?: string, ...args: string[]): void;
|
|
23
|
+
logElapsed(startedAtMs: number): void;
|
|
24
|
+
withSpinner<T>(message: string, action: () => Promise<T>): Promise<T>;
|
|
25
|
+
};
|
|
26
|
+
export declare function runWorkPublish(command: WorkPublishHost, flags: WorkPublishFlagValues): Promise<WorkPushResult>;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import { listPendingChanges } from './git-worktree.js';
|
|
3
|
+
import { performWorkPush, resolveWorkPushContext, WorkPushValidationError } from './work-push.js';
|
|
4
|
+
export const WORK_PUBLISH_DESCRIPTION = [
|
|
5
|
+
'Publish the current feature/<lastWorkItem> branch and register commits with Copado.',
|
|
6
|
+
'Requires a clean working tree, base branch, and dev org branch from `.agentia/config.user.json`.',
|
|
7
|
+
'Fetches origin/<lastBaseBranch>, then registers only commits in origin/<lastBaseBranch>..HEAD and diffs nested parent XML at merge-base(origin/<lastBaseBranch>, HEAD) versus HEAD, so origin/base-only history is ignored.',
|
|
8
|
+
'When there are no commits since origin/<lastBaseBranch>, or origin already has HEAD, fails with "No changes to publish" unless `--permissions` and/or `--full-metadata` is set, in which case it creates an empty commit so a tip commit id exists.',
|
|
9
|
+
'Applies Copado environment-variable then yaml replacements when needed, commits both as a single follow-up commit, locks the tip commit, runs `git push origin <branch>`,',
|
|
10
|
+
'reports the nested metadata changed across the branch, such as the CustomField behind a profile field-permission edit, plus the parent components it would ignore,',
|
|
11
|
+
'calls headless work/push with one changeListUpdate list of Action:MetadataType:MetadataName corrections: lastPermissionSelected and --permissions plus the nested metadata of the changed profiles and permission sets as RetrieveOnly, lastFullMetadataSelected and --full-metadata plus brand-new nested parent files as fullMetadata, the ignored parents as unchanged, the nested metadata deleted on the branch as Del, and the remaining nested metadata as Add, then merges the feature branch into the recorded dev org branch.',
|
|
12
|
+
'The changed profiles and permission sets themselves are never sent as corrections, so they stay in the change list and deploy only the permissions their RetrieveOnly entries select. Brand-new nested parent files are an exception: they are sent as fullMetadata so the complete file travels.',
|
|
13
|
+
'`cicd work push` is a compatibility alias of this command.',
|
|
14
|
+
].join(' ');
|
|
15
|
+
export const workPublishFlags = {
|
|
16
|
+
'full-metadata': Flags.string({
|
|
17
|
+
description: 'Comma-separated type-prefixed metadata such as Profile:Sales_User,PermissionSet:Sales_Onboarding, added for this publish and sent as headless push fullMetadata corrections. The named metadata is committed as a complete file, so it is never decomposed into nested metadata. Not stored.',
|
|
18
|
+
}),
|
|
19
|
+
permissions: Flags.string({
|
|
20
|
+
description: 'Comma-separated type-prefixed metadata such as CustomField:Account.SLA__c,ApexClass:AccountService, added for this publish and sent as headless push RetrieveOnly corrections. Not stored.',
|
|
21
|
+
}),
|
|
22
|
+
'skip-nested-metadata-detection': Flags.boolean({
|
|
23
|
+
default: false,
|
|
24
|
+
description: 'Do not detect the nested metadata changed across the branch (also configurable via skipNestedMetadataDetection in .agentia/config.json or .agentia/config.user.json)',
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
export async function runWorkPublish(command, flags) {
|
|
28
|
+
const startedAt = Date.now();
|
|
29
|
+
let context;
|
|
30
|
+
try {
|
|
31
|
+
context = await resolveWorkPushContext();
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
if (error instanceof WorkPushValidationError) {
|
|
35
|
+
command.error(error.message, {
|
|
36
|
+
exit: error.exit,
|
|
37
|
+
suggestions: error.suggestions,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
const { baseBranch, branch, devOrgBranch, workItem, workItemId } = context;
|
|
43
|
+
const pendingFiles = await listPendingChanges();
|
|
44
|
+
if (pendingFiles.length > 0) {
|
|
45
|
+
command.error([
|
|
46
|
+
'Uncommitted tracked changes present. Commit them, then try again:',
|
|
47
|
+
...pendingFiles.map((file) => ` ${file}`),
|
|
48
|
+
].join('\n'), {
|
|
49
|
+
exit: 2,
|
|
50
|
+
suggestions: ['git add -A && git commit', `${command.config.bin} cicd work publish`],
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
command.display(() => {
|
|
54
|
+
command.log(`Branch: ${branch}`);
|
|
55
|
+
command.log(`Work item: ${workItem}`);
|
|
56
|
+
command.log(`Base branch: ${baseBranch}`);
|
|
57
|
+
command.log(`Dev org branch: ${devOrgBranch}`);
|
|
58
|
+
});
|
|
59
|
+
try {
|
|
60
|
+
const result = await performWorkPush({
|
|
61
|
+
baseBranch,
|
|
62
|
+
branch,
|
|
63
|
+
devOrgBranch,
|
|
64
|
+
...(flags['full-metadata'] === undefined ? {} : { fullMetadata: flags['full-metadata'] }),
|
|
65
|
+
hooks: {
|
|
66
|
+
display: (render) => command.display(render),
|
|
67
|
+
log: (message) => command.log(message),
|
|
68
|
+
withSpinner: (message, action) => command.withSpinner(message, action),
|
|
69
|
+
},
|
|
70
|
+
...(flags.permissions === undefined ? {} : { permissions: flags.permissions }),
|
|
71
|
+
skipNestedMetadataDetection: flags['skip-nested-metadata-detection'],
|
|
72
|
+
workItem,
|
|
73
|
+
workItemId,
|
|
74
|
+
});
|
|
75
|
+
command.logElapsed(startedAt);
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
if (error instanceof WorkPushValidationError) {
|
|
80
|
+
command.error(error.message, {
|
|
81
|
+
exit: error.exit,
|
|
82
|
+
suggestions: error.suggestions,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=work-publish-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-publish-command.js","sourceRoot":"","sources":["../../src/lib/work-publish-command.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/work-push.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export type WorkPushNeed = {
|
|
|
40
40
|
* main must not count origin/base history as feature work.
|
|
41
41
|
*/
|
|
42
42
|
export declare function resolveWorkPushNeed(branch: string): Promise<WorkPushNeed>;
|
|
43
|
-
/** Resolve lastWorkItem / branch / lastBaseBranch / lastDevOrgBranch for work
|
|
43
|
+
/** Resolve lastWorkItem / branch / lastBaseBranch / lastDevOrgBranch for work publish. */
|
|
44
44
|
export declare function resolveWorkPushContext(): Promise<ResolvedWorkPushContext>;
|
|
45
45
|
export type SleepFn = (ms: number) => Promise<void>;
|
|
46
46
|
export declare function setSleepForTests(nextSleep: SleepFn): void;
|
|
@@ -57,8 +57,8 @@ export declare function readWorkPushRetrieveOnly(): Promise<string[]>;
|
|
|
57
57
|
/** Metadata recorded by `cicd work commit --full-metadata`, pushed as `fullMetadata` corrections. */
|
|
58
58
|
export declare function readWorkPushFullMetadata(): Promise<string[]>;
|
|
59
59
|
/**
|
|
60
|
-
* Selections recorded at commit time plus the ones passed to this
|
|
61
|
-
* duplicates. `cicd work
|
|
60
|
+
* Selections recorded at commit time plus the ones passed to this publish, in that order and without
|
|
61
|
+
* duplicates. `cicd work publish` never stores its own flag values, so a flag adds to the recorded
|
|
62
62
|
* selection for the current invocation only.
|
|
63
63
|
*/
|
|
64
64
|
export declare function mergeWorkPushSelections(storedSelections: readonly string[], requestedSelections: readonly string[]): string[];
|
package/dist/lib/work-push.js
CHANGED
|
@@ -86,13 +86,13 @@ export async function resolveWorkPushNeed(branch) {
|
|
|
86
86
|
suggestions: ['Make at least one commit on the feature branch.'],
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
|
-
/** Resolve lastWorkItem / branch / lastBaseBranch / lastDevOrgBranch for work
|
|
89
|
+
/** Resolve lastWorkItem / branch / lastBaseBranch / lastDevOrgBranch for work publish. */
|
|
90
90
|
export async function resolveWorkPushContext() {
|
|
91
91
|
const { branch, workItem } = await resolveActiveFeatureWorkItem();
|
|
92
92
|
const baseBranch = await resolveRecordedBaseBranch();
|
|
93
93
|
const devOrgBranch = (await readLastDevOrgBranch())?.trim();
|
|
94
94
|
if (devOrgBranch === undefined || devOrgBranch.length === 0) {
|
|
95
|
-
throw new WorkPushValidationError('No lastDevOrgBranch recorded in `.agentia/config.user.json`. Set it before
|
|
95
|
+
throw new WorkPushValidationError('No lastDevOrgBranch recorded in `.agentia/config.user.json`. Set it before publishing.');
|
|
96
96
|
}
|
|
97
97
|
let workItemId;
|
|
98
98
|
try {
|
|
@@ -183,7 +183,7 @@ export async function registerHeadlessPush(pushBody, hooks, timeoutSeconds = DEF
|
|
|
183
183
|
}
|
|
184
184
|
const delaySeconds = resolveWorkPushRetryDelaySeconds(retryAfterSeconds, waitedSeconds);
|
|
185
185
|
if (waitedSeconds + delaySeconds > timeoutSeconds) {
|
|
186
|
-
throw new CicdGatewayError(`CICD Gateway rate limited the work
|
|
186
|
+
throw new CicdGatewayError(`CICD Gateway rate limited the work publish request and the retry timeout of ${timeoutSeconds}s was exceeded.`, {
|
|
187
187
|
categories: error.categories,
|
|
188
188
|
code: error.code,
|
|
189
189
|
jobId: error.jobId,
|
|
@@ -197,9 +197,9 @@ export async function registerHeadlessPush(pushBody, hooks, timeoutSeconds = DEF
|
|
|
197
197
|
}
|
|
198
198
|
hooks.display(() => {
|
|
199
199
|
hooks.log(error.jobId === undefined
|
|
200
|
-
? `Rate limited (429). Retrying work
|
|
200
|
+
? `Rate limited (429). Retrying work publish in ${delaySeconds}s` +
|
|
201
201
|
` (${waitedSeconds + delaySeconds}s / ${timeoutSeconds}s waited).`
|
|
202
|
-
: `waiting for job id ${error.jobId}, Retrying work
|
|
202
|
+
: `waiting for job id ${error.jobId}, Retrying work publish in ${delaySeconds}s` +
|
|
203
203
|
` (${waitedSeconds + delaySeconds}s / ${timeoutSeconds}s waited).`);
|
|
204
204
|
});
|
|
205
205
|
// eslint-disable-next-line no-await-in-loop -- wait before the next retry
|
|
@@ -219,8 +219,8 @@ export async function readWorkPushFullMetadata() {
|
|
|
219
219
|
return stored === undefined ? [] : parseCommaSeparatedList(stored);
|
|
220
220
|
}
|
|
221
221
|
/**
|
|
222
|
-
* Selections recorded at commit time plus the ones passed to this
|
|
223
|
-
* duplicates. `cicd work
|
|
222
|
+
* Selections recorded at commit time plus the ones passed to this publish, in that order and without
|
|
223
|
+
* duplicates. `cicd work publish` never stores its own flag values, so a flag adds to the recorded
|
|
224
224
|
* selection for the current invocation only.
|
|
225
225
|
*/
|
|
226
226
|
export function mergeWorkPushSelections(storedSelections, requestedSelections) {
|
|
@@ -483,16 +483,16 @@ export async function performWorkPush(options) {
|
|
|
483
483
|
const needsEmptyCommit = commits.length === 0 || !(await hasUnpushedCommits(branch));
|
|
484
484
|
if (needsEmptyCommit) {
|
|
485
485
|
if (!hasSelectionFlags) {
|
|
486
|
-
throw new WorkPushValidationError('No changes to
|
|
486
|
+
throw new WorkPushValidationError('No changes to publish.', {
|
|
487
487
|
exit: 1,
|
|
488
488
|
suggestions: [
|
|
489
|
-
'Make at least one commit on the feature branch before
|
|
490
|
-
'Or pass --permissions and/or --full-metadata to
|
|
489
|
+
'Make at least one commit on the feature branch before publishing.',
|
|
490
|
+
'Or pass --permissions and/or --full-metadata to publish selection corrections with an empty commit.',
|
|
491
491
|
],
|
|
492
492
|
});
|
|
493
493
|
}
|
|
494
|
-
const emptyCommitMessage = `${workItem}: empty commit for work
|
|
495
|
-
await withSpinner('Creating empty commit for selection
|
|
494
|
+
const emptyCommitMessage = `${workItem}: empty commit for work publish selections`;
|
|
495
|
+
await withSpinner('Creating empty commit for selection publish', () => commitAllowEmpty(emptyCommitMessage));
|
|
496
496
|
logStdout = await withSpinner(`Collecting commits since origin/${baseBranch}`, () => getCommitsNameStatus(originBase));
|
|
497
497
|
commits = parseNameStatusLog(logStdout, workItem);
|
|
498
498
|
if (commits.length === 0) {
|