@xn-intenton-z2a/agentic-lib 7.2.9 → 7.2.10
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.
|
@@ -82,8 +82,11 @@ jobs:
|
|
|
82
82
|
|
|
83
83
|
behaviour:
|
|
84
84
|
if: github.repository != 'xn-intenton-z2a/agentic-lib'
|
|
85
|
+
continue-on-error: true
|
|
85
86
|
runs-on: ubuntu-latest
|
|
86
87
|
container: mcr.microsoft.com/playwright:v1.58.2-noble
|
|
88
|
+
outputs:
|
|
89
|
+
tests-failed: ${{ steps.result.outputs.tests-failed }}
|
|
87
90
|
steps:
|
|
88
91
|
- uses: actions/checkout@v6
|
|
89
92
|
|
|
@@ -91,6 +94,7 @@ jobs:
|
|
|
91
94
|
run: npm ci
|
|
92
95
|
|
|
93
96
|
- name: Run behaviour tests (with retry)
|
|
97
|
+
id: run-tests
|
|
94
98
|
run: |
|
|
95
99
|
npm run test:behaviour || {
|
|
96
100
|
echo "::warning::Behaviour test attempt 1 failed — retrying"
|
|
@@ -100,6 +104,16 @@ jobs:
|
|
|
100
104
|
#env:
|
|
101
105
|
# HOME: /root
|
|
102
106
|
|
|
107
|
+
- name: Record test result
|
|
108
|
+
if: always()
|
|
109
|
+
id: result
|
|
110
|
+
run: |
|
|
111
|
+
if [ "${{ steps.run-tests.outcome }}" = "failure" ]; then
|
|
112
|
+
echo "tests-failed=true" >> $GITHUB_OUTPUT
|
|
113
|
+
else
|
|
114
|
+
echo "tests-failed=false" >> $GITHUB_OUTPUT
|
|
115
|
+
fi
|
|
116
|
+
|
|
103
117
|
- name: Upload screenshot
|
|
104
118
|
if: ${{ !cancelled() }}
|
|
105
119
|
uses: actions/upload-artifact@v7
|
|
@@ -132,15 +146,15 @@ jobs:
|
|
|
132
146
|
fi
|
|
133
147
|
done
|
|
134
148
|
|
|
135
|
-
# ─── Dispatch fix workflow when tests fail on main
|
|
149
|
+
# ─── Dispatch fix workflow when unit tests fail on main ─────────────
|
|
136
150
|
dispatch-fix:
|
|
137
|
-
needs: [test
|
|
151
|
+
needs: [test]
|
|
138
152
|
if: >-
|
|
139
153
|
!cancelled()
|
|
140
154
|
&& github.ref == 'refs/heads/main'
|
|
141
155
|
&& (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_call')
|
|
142
156
|
&& github.repository != 'xn-intenton-z2a/agentic-lib'
|
|
143
|
-
&&
|
|
157
|
+
&& needs.test.result == 'failure'
|
|
144
158
|
runs-on: ubuntu-latest
|
|
145
159
|
steps:
|
|
146
160
|
- name: Check circuit breaker
|
|
@@ -174,28 +188,17 @@ jobs:
|
|
|
174
188
|
-f mode=full \
|
|
175
189
|
-f message="Build broken on main: agentic-lib-test run ${{ github.run_id }} failed. Please fix."
|
|
176
190
|
|
|
177
|
-
# ─── Report instability:
|
|
191
|
+
# ─── Report instability: install or unit test failure → automated + instability ──
|
|
178
192
|
report-instability:
|
|
179
|
-
needs: [test
|
|
193
|
+
needs: [test]
|
|
180
194
|
if: >-
|
|
181
195
|
!cancelled()
|
|
182
196
|
&& github.ref == 'refs/heads/main'
|
|
183
197
|
&& github.repository != 'xn-intenton-z2a/agentic-lib'
|
|
184
|
-
&&
|
|
198
|
+
&& needs.test.result == 'failure'
|
|
185
199
|
runs-on: ubuntu-latest
|
|
186
200
|
steps:
|
|
187
|
-
-
|
|
188
|
-
id: failure-type
|
|
189
|
-
run: |
|
|
190
|
-
UNIT="${{ needs.test.result }}"
|
|
191
|
-
BEHAVIOUR="${{ needs.behaviour.result }}"
|
|
192
|
-
if [ "$UNIT" = "failure" ] && [ "$BEHAVIOUR" = "failure" ]; then
|
|
193
|
-
echo "type=both" >> $GITHUB_OUTPUT
|
|
194
|
-
elif [ "$UNIT" = "failure" ]; then
|
|
195
|
-
echo "type=unit" >> $GITHUB_OUTPUT
|
|
196
|
-
else
|
|
197
|
-
echo "type=behaviour" >> $GITHUB_OUTPUT
|
|
198
|
-
fi
|
|
201
|
+
- uses: actions/checkout@v6
|
|
199
202
|
|
|
200
203
|
- name: Install dependencies (non-blocking)
|
|
201
204
|
id: install-deps
|
|
@@ -207,7 +210,7 @@ jobs:
|
|
|
207
210
|
echo "exit-code=$EXIT_CODE" | tee -a $GITHUB_OUTPUT
|
|
208
211
|
ERROR_COUNT=$(echo "$OUTPUT" | grep -oP '\d+ error' | head -1 | grep -oP '\d+' || echo "0")
|
|
209
212
|
echo "error-count=$ERROR_COUNT" | tee -a $GITHUB_OUTPUT
|
|
210
|
-
echo "$OUTPUT"
|
|
213
|
+
echo "$OUTPUT" > /tmp/install-output.txt
|
|
211
214
|
echo "$OUTPUT"
|
|
212
215
|
exit 0
|
|
213
216
|
|
|
@@ -227,25 +230,7 @@ jobs:
|
|
|
227
230
|
FAIL_COUNT=$(echo "$OUTPUT" | grep -oP '\d+ fail' | head -1 | grep -oP '\d+' || echo "0")
|
|
228
231
|
echo "pass-count=$PASS_COUNT" | tee -a $GITHUB_OUTPUT
|
|
229
232
|
echo "fail-count=$FAIL_COUNT" | tee -a $GITHUB_OUTPUT
|
|
230
|
-
echo "$OUTPUT"
|
|
231
|
-
echo "$OUTPUT"
|
|
232
|
-
exit 0
|
|
233
|
-
|
|
234
|
-
- name: Run behaviour tests (non-blocking)
|
|
235
|
-
id: behaviour-tests
|
|
236
|
-
if: hashFiles('playwright.config.js') != '' || hashFiles('playwright.config.ts') != ''
|
|
237
|
-
run: |
|
|
238
|
-
set +e
|
|
239
|
-
npx playwright install --with-deps chromium 2>/dev/null || true
|
|
240
|
-
npm run build:web 2>/dev/null || true
|
|
241
|
-
OUTPUT=$(npm run --if-present test:behaviour 2>&1)
|
|
242
|
-
EXIT_CODE=$?
|
|
243
|
-
echo "exit-code=$EXIT_CODE" | tee -a $GITHUB_OUTPUT
|
|
244
|
-
PASS_COUNT=$(echo "$OUTPUT" | grep -oP '\d+ passed' | head -1 | grep -oP '\d+' || echo "0")
|
|
245
|
-
FAIL_COUNT=$(echo "$OUTPUT" | grep -oP '\d+ failed' | head -1 | grep -oP '\d+' || echo "0")
|
|
246
|
-
echo "pass-count=$PASS_COUNT" | tee -a $GITHUB_OUTPUT
|
|
247
|
-
echo "fail-count=$FAIL_COUNT" | tee -a $GITHUB_OUTPUT
|
|
248
|
-
echo "$OUTPUT" | tail -50 > /tmp/behaviour-test-output.txt
|
|
233
|
+
echo "$OUTPUT" > /tmp/unit-test-output.txt
|
|
249
234
|
echo "$OUTPUT"
|
|
250
235
|
exit 0
|
|
251
236
|
|
|
@@ -254,22 +239,20 @@ jobs:
|
|
|
254
239
|
with:
|
|
255
240
|
script: |
|
|
256
241
|
const fs = require('fs');
|
|
257
|
-
const failureType = '${{ steps.failure-type.outputs.type }}';
|
|
258
242
|
const runId = '${{ github.run_id }}';
|
|
259
243
|
const runUrl = `https://github.com/${{ github.repository }}/actions/runs/${runId}`;
|
|
260
|
-
|
|
261
|
-
// Live test results from earlier steps
|
|
244
|
+
|
|
262
245
|
const installOutput = fs.existsSync('/tmp/install-output.txt')
|
|
263
|
-
? fs.readFileSync('/tmp/install-output.txt', 'utf8')
|
|
246
|
+
? fs.readFileSync('/tmp/install-output.txt', 'utf8')
|
|
264
247
|
: '';
|
|
265
|
-
const unitOutput = fs.existsSync('/tmp/
|
|
266
|
-
? fs.readFileSync('/tmp/
|
|
267
|
-
: '';
|
|
268
|
-
const behaviourOutput = fs.existsSync('/tmp/behaviour-test-output.txt')
|
|
269
|
-
? fs.readFileSync('/tmp/behaviour-test-output.txt', 'utf8').slice(0, 2500)
|
|
248
|
+
const unitOutput = fs.existsSync('/tmp/unit-test-output.txt')
|
|
249
|
+
? fs.readFileSync('/tmp/unit-test-output.txt', 'utf8')
|
|
270
250
|
: '';
|
|
271
|
-
|
|
272
|
-
|
|
251
|
+
|
|
252
|
+
const installExit = '${{ steps.install-deps.outputs.exit-code }}';
|
|
253
|
+
const failureType = installExit !== '0' ? 'install' : 'unit';
|
|
254
|
+
const logs = `=== Install Output ===\n${installOutput}\n\n=== Unit Test Output ===\n${unitOutput}`;
|
|
255
|
+
|
|
273
256
|
const title = `instability: ${failureType} test failure on main`;
|
|
274
257
|
const body = [
|
|
275
258
|
`## Test Failure Report`,
|
|
@@ -293,14 +276,12 @@ jobs:
|
|
|
293
276
|
|
|
294
277
|
const match = existing.find(i => i.title.includes(failureType));
|
|
295
278
|
if (match) {
|
|
296
|
-
// Add a comment with the new failure logs instead of creating a duplicate
|
|
297
279
|
await github.rest.issues.createComment({
|
|
298
280
|
...context.repo, issue_number: match.number,
|
|
299
|
-
body: `## Recurrence — run [${runId}](${runUrl})\n\n**Trigger**: ${context.eventName}\n**Time**: ${new Date().toISOString()}\n\n` + '```\n' + logs
|
|
281
|
+
body: `## Recurrence — run [${runId}](${runUrl})\n\n**Trigger**: ${context.eventName}\n**Time**: ${new Date().toISOString()}\n\n` + '```\n' + logs + '\n```',
|
|
300
282
|
});
|
|
301
283
|
core.info(`Updated existing instability issue #${match.number}`);
|
|
302
284
|
} else {
|
|
303
|
-
// Ensure instability label exists
|
|
304
285
|
try {
|
|
305
286
|
await github.rest.issues.createLabel({
|
|
306
287
|
...context.repo, name: 'instability',
|
|
@@ -314,3 +295,92 @@ jobs:
|
|
|
314
295
|
});
|
|
315
296
|
core.info(`Created instability issue #${issue.number}`);
|
|
316
297
|
}
|
|
298
|
+
|
|
299
|
+
# ─── Report behaviour failure: behaviour test failure → automated only ──
|
|
300
|
+
report-behaviour:
|
|
301
|
+
needs: [behaviour]
|
|
302
|
+
if: >-
|
|
303
|
+
!cancelled()
|
|
304
|
+
&& github.ref == 'refs/heads/main'
|
|
305
|
+
&& github.repository != 'xn-intenton-z2a/agentic-lib'
|
|
306
|
+
&& needs.behaviour.outputs.tests-failed == 'true'
|
|
307
|
+
runs-on: ubuntu-latest
|
|
308
|
+
container: mcr.microsoft.com/playwright:v1.58.2-noble
|
|
309
|
+
steps:
|
|
310
|
+
- uses: actions/checkout@v6
|
|
311
|
+
|
|
312
|
+
- name: Install dependencies (non-blocking)
|
|
313
|
+
id: install-deps
|
|
314
|
+
run: |
|
|
315
|
+
set +e
|
|
316
|
+
OUTPUT=$(npm ci 2>&1)
|
|
317
|
+
echo "$OUTPUT" > /tmp/install-output.txt
|
|
318
|
+
echo "$OUTPUT"
|
|
319
|
+
exit 0
|
|
320
|
+
|
|
321
|
+
- name: Run behaviour tests (non-blocking)
|
|
322
|
+
id: behaviour-tests
|
|
323
|
+
run: |
|
|
324
|
+
set +e
|
|
325
|
+
npm run build:web 2>/dev/null || true
|
|
326
|
+
OUTPUT=$(npm run --if-present test:behaviour 2>&1)
|
|
327
|
+
EXIT_CODE=$?
|
|
328
|
+
echo "exit-code=$EXIT_CODE" | tee -a $GITHUB_OUTPUT
|
|
329
|
+
PASS_COUNT=$(echo "$OUTPUT" | grep -oP '\d+ passed' | head -1 | grep -oP '\d+' || echo "0")
|
|
330
|
+
FAIL_COUNT=$(echo "$OUTPUT" | grep -oP '\d+ failed' | head -1 | grep -oP '\d+' || echo "0")
|
|
331
|
+
echo "pass-count=$PASS_COUNT" | tee -a $GITHUB_OUTPUT
|
|
332
|
+
echo "fail-count=$FAIL_COUNT" | tee -a $GITHUB_OUTPUT
|
|
333
|
+
echo "$OUTPUT" > /tmp/behaviour-test-output.txt
|
|
334
|
+
echo "$OUTPUT"
|
|
335
|
+
exit 0
|
|
336
|
+
|
|
337
|
+
- name: Create or update behaviour failure issue
|
|
338
|
+
uses: actions/github-script@v8
|
|
339
|
+
with:
|
|
340
|
+
script: |
|
|
341
|
+
const fs = require('fs');
|
|
342
|
+
const runId = '${{ github.run_id }}';
|
|
343
|
+
const runUrl = `https://github.com/${{ github.repository }}/actions/runs/${runId}`;
|
|
344
|
+
|
|
345
|
+
const behaviourOutput = fs.existsSync('/tmp/behaviour-test-output.txt')
|
|
346
|
+
? fs.readFileSync('/tmp/behaviour-test-output.txt', 'utf8')
|
|
347
|
+
: '';
|
|
348
|
+
const passCount = '${{ steps.behaviour-tests.outputs.pass-count }}' || '0';
|
|
349
|
+
const failCount = '${{ steps.behaviour-tests.outputs.fail-count }}' || '0';
|
|
350
|
+
|
|
351
|
+
const title = `behaviour test failure on main`;
|
|
352
|
+
const body = [
|
|
353
|
+
`## Behaviour Test Failure Report`,
|
|
354
|
+
``,
|
|
355
|
+
`**Passed**: ${passCount}`,
|
|
356
|
+
`**Failed**: ${failCount}`,
|
|
357
|
+
`**Run**: [${runId}](${runUrl})`,
|
|
358
|
+
`**Trigger**: ${context.eventName}`,
|
|
359
|
+
`**Time**: ${new Date().toISOString()}`,
|
|
360
|
+
``,
|
|
361
|
+
`## Failure Logs`,
|
|
362
|
+
``,
|
|
363
|
+
'```',
|
|
364
|
+
behaviourOutput,
|
|
365
|
+
'```',
|
|
366
|
+
].join('\n');
|
|
367
|
+
|
|
368
|
+
// Check for existing open behaviour failure issue
|
|
369
|
+
const { data: existing } = await github.rest.issues.listForRepo({
|
|
370
|
+
...context.repo, state: 'open', labels: 'automated', per_page: 20,
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
const match = existing.find(i => i.title.includes('behaviour test failure'));
|
|
374
|
+
if (match) {
|
|
375
|
+
await github.rest.issues.createComment({
|
|
376
|
+
...context.repo, issue_number: match.number,
|
|
377
|
+
body: `## Recurrence — run [${runId}](${runUrl})\n\n**Passed**: ${passCount} | **Failed**: ${failCount}\n**Trigger**: ${context.eventName}\n**Time**: ${new Date().toISOString()}\n\n` + '```\n' + behaviourOutput + '\n```',
|
|
378
|
+
});
|
|
379
|
+
core.info(`Updated existing behaviour issue #${match.number}`);
|
|
380
|
+
} else {
|
|
381
|
+
const { data: issue } = await github.rest.issues.create({
|
|
382
|
+
...context.repo, title, body,
|
|
383
|
+
labels: ['ready', 'automated'],
|
|
384
|
+
});
|
|
385
|
+
core.info(`Created behaviour failure issue #${issue.number}`);
|
|
386
|
+
}
|
|
@@ -279,7 +279,7 @@ jobs:
|
|
|
279
279
|
echo "exit-code=$EXIT_CODE" | tee -a $GITHUB_OUTPUT
|
|
280
280
|
ERROR_COUNT=$(echo "$OUTPUT" | grep -oP '\d+ error' | head -1 | grep -oP '\d+' || echo "0")
|
|
281
281
|
echo "error-count=$ERROR_COUNT" | tee -a $GITHUB_OUTPUT
|
|
282
|
-
echo "$OUTPUT"
|
|
282
|
+
echo "$OUTPUT" > /tmp/install-output.txt
|
|
283
283
|
echo "$OUTPUT"
|
|
284
284
|
exit 0
|
|
285
285
|
|
|
@@ -299,7 +299,7 @@ jobs:
|
|
|
299
299
|
FAIL_COUNT=$(echo "$OUTPUT" | grep -oP '\d+ fail' | head -1 | grep -oP '\d+' || echo "0")
|
|
300
300
|
echo "pass-count=$PASS_COUNT" | tee -a $GITHUB_OUTPUT
|
|
301
301
|
echo "fail-count=$FAIL_COUNT" | tee -a $GITHUB_OUTPUT
|
|
302
|
-
echo "$OUTPUT"
|
|
302
|
+
echo "$OUTPUT" > /tmp/unit-test-output.txt
|
|
303
303
|
echo "$OUTPUT"
|
|
304
304
|
exit 0
|
|
305
305
|
|
|
@@ -317,7 +317,7 @@ jobs:
|
|
|
317
317
|
FAIL_COUNT=$(echo "$OUTPUT" | grep -oP '\d+ failed' | head -1 | grep -oP '\d+' || echo "0")
|
|
318
318
|
echo "pass-count=$PASS_COUNT" | tee -a $GITHUB_OUTPUT
|
|
319
319
|
echo "fail-count=$FAIL_COUNT" | tee -a $GITHUB_OUTPUT
|
|
320
|
-
echo "$OUTPUT"
|
|
320
|
+
echo "$OUTPUT" > /tmp/behaviour-test-output.txt
|
|
321
321
|
echo "$OUTPUT"
|
|
322
322
|
exit 0
|
|
323
323
|
|
|
@@ -442,13 +442,13 @@ jobs:
|
|
|
442
442
|
|
|
443
443
|
// Live test results from earlier steps
|
|
444
444
|
const installOutput = fs.existsSync('/tmp/install-output.txt')
|
|
445
|
-
? fs.readFileSync('/tmp/install-output.txt', 'utf8')
|
|
445
|
+
? fs.readFileSync('/tmp/install-output.txt', 'utf8')
|
|
446
446
|
: '';
|
|
447
|
-
const unitOutput = fs.existsSync('/tmp/
|
|
448
|
-
? fs.readFileSync('/tmp/
|
|
447
|
+
const unitOutput = fs.existsSync('/tmp/unit-test-output.txt')
|
|
448
|
+
? fs.readFileSync('/tmp/unit-test-output.txt', 'utf8')
|
|
449
449
|
: '';
|
|
450
450
|
const behaviourOutput = fs.existsSync('/tmp/behaviour-test-output.txt')
|
|
451
|
-
? fs.readFileSync('/tmp/behaviour-test-output.txt', 'utf8')
|
|
451
|
+
? fs.readFileSync('/tmp/behaviour-test-output.txt', 'utf8')
|
|
452
452
|
: '';
|
|
453
453
|
|
|
454
454
|
const telemetry = {
|
package/package.json
CHANGED