@xn-intenton-z2a/agentic-lib 7.4.27 → 7.4.28
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/.github/workflows/agentic-lib-bot.yml +2 -2
- package/.github/workflows/agentic-lib-flow.yml +38 -1
- package/.github/workflows/agentic-lib-init.yml +40 -13
- package/.github/workflows/agentic-lib-schedule.yml +40 -13
- package/.github/workflows/agentic-lib-update.yml +40 -13
- package/.github/workflows/agentic-lib-workflow.yml +14 -13
- package/package.json +1 -1
- package/src/actions/agentic-step/tasks/direct.js +38 -14
- package/src/actions/commit-if-changed/action.yml +71 -29
- package/src/seeds/zero-package.json +1 -1
|
@@ -87,7 +87,7 @@ jobs:
|
|
|
87
87
|
steps:
|
|
88
88
|
- uses: actions/checkout@v6
|
|
89
89
|
with:
|
|
90
|
-
ref: ${{ inputs.ref || github.
|
|
90
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
91
91
|
sparse-checkout: ${{ env.configPath }}
|
|
92
92
|
sparse-checkout-cone-mode: false
|
|
93
93
|
- name: Normalise params
|
|
@@ -116,7 +116,7 @@ jobs:
|
|
|
116
116
|
- uses: actions/checkout@v6
|
|
117
117
|
with:
|
|
118
118
|
fetch-depth: 0
|
|
119
|
-
ref: ${{ inputs.ref || github.
|
|
119
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
120
120
|
|
|
121
121
|
- uses: actions/setup-node@v6
|
|
122
122
|
with:
|
|
@@ -96,6 +96,8 @@ jobs:
|
|
|
96
96
|
update:
|
|
97
97
|
if: inputs.mode != 'skip'
|
|
98
98
|
uses: ./.github/workflows/agentic-lib-update.yml
|
|
99
|
+
with:
|
|
100
|
+
skip-tests: 'true'
|
|
99
101
|
secrets: inherit
|
|
100
102
|
|
|
101
103
|
# ── Phase 0b: Init (purge/reseed/update) ───────────────────────────
|
|
@@ -693,7 +695,42 @@ jobs:
|
|
|
693
695
|
git add BENCHMARK_REPORT_FLOW_*.md
|
|
694
696
|
git diff --staged --quiet && echo "No report to commit" && exit 0
|
|
695
697
|
git commit -m "flow: benchmark report for ${{ inputs.mission-seed }} (${{ inputs.workflow-runs }} runs) [skip ci]"
|
|
696
|
-
|
|
698
|
+
MAX_RETRIES=3
|
|
699
|
+
PUSH_SUCCESS=""
|
|
700
|
+
for attempt in $(seq 1 $MAX_RETRIES); do
|
|
701
|
+
case $attempt in
|
|
702
|
+
1)
|
|
703
|
+
echo "=== Attempt 1: rebase (cleanest) ==="
|
|
704
|
+
git pull --rebase origin main || {
|
|
705
|
+
git rebase --abort 2>/dev/null || true
|
|
706
|
+
sleep $((10 + RANDOM % 10))
|
|
707
|
+
continue
|
|
708
|
+
}
|
|
709
|
+
;;
|
|
710
|
+
2)
|
|
711
|
+
echo "=== Attempt 2: merge (handles non-overlapping changes) ==="
|
|
712
|
+
git pull --no-rebase origin main || {
|
|
713
|
+
git merge --abort 2>/dev/null || true
|
|
714
|
+
sleep $((20 + RANDOM % 10))
|
|
715
|
+
continue
|
|
716
|
+
}
|
|
717
|
+
;;
|
|
718
|
+
3)
|
|
719
|
+
echo "=== Attempt 3: merge -X theirs (accept remote on conflict) ==="
|
|
720
|
+
git pull -X theirs --no-rebase origin main || {
|
|
721
|
+
git merge --abort 2>/dev/null || true
|
|
722
|
+
sleep $((30 + RANDOM % 10))
|
|
723
|
+
continue
|
|
724
|
+
}
|
|
725
|
+
;;
|
|
726
|
+
esac
|
|
727
|
+
git push origin main && { PUSH_SUCCESS="true"; break; }
|
|
728
|
+
echo "Push failed on attempt $attempt"
|
|
729
|
+
sleep $((attempt * 10 + RANDOM % 10))
|
|
730
|
+
done
|
|
731
|
+
if [ "$PUSH_SUCCESS" != "true" ]; then
|
|
732
|
+
echo "::warning::Failed to push report after $MAX_RETRIES attempts — saved as artifact"
|
|
733
|
+
fi
|
|
697
734
|
|
|
698
735
|
- name: Upload report artifact
|
|
699
736
|
uses: actions/upload-artifact@v4
|
|
@@ -350,20 +350,47 @@ jobs:
|
|
|
350
350
|
else
|
|
351
351
|
git commit -m "init ${INIT_MODE} (agentic-lib@${VERSION}) [skip ci]"
|
|
352
352
|
fi
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
353
|
+
MAX_RETRIES=3
|
|
354
|
+
PUSH_SUCCESS=""
|
|
355
|
+
for attempt in $(seq 1 $MAX_RETRIES); do
|
|
356
|
+
# Tiered conflict resolution (mirrors fix-stuck strategy)
|
|
357
|
+
case $attempt in
|
|
358
|
+
1)
|
|
359
|
+
echo "=== Attempt 1: rebase (cleanest) ==="
|
|
360
|
+
git pull --rebase origin main || {
|
|
361
|
+
echo "Rebase conflict on attempt 1 — aborting rebase"
|
|
362
|
+
git rebase --abort 2>/dev/null || true
|
|
363
|
+
sleep $((10 + RANDOM % 10))
|
|
364
|
+
continue
|
|
365
|
+
}
|
|
366
|
+
;;
|
|
367
|
+
2)
|
|
368
|
+
echo "=== Attempt 2: merge (handles non-overlapping changes) ==="
|
|
369
|
+
git pull --no-rebase origin main || {
|
|
370
|
+
echo "Merge conflict on attempt 2 — aborting merge"
|
|
371
|
+
git merge --abort 2>/dev/null || true
|
|
372
|
+
sleep $((20 + RANDOM % 10))
|
|
373
|
+
continue
|
|
374
|
+
}
|
|
375
|
+
;;
|
|
376
|
+
3)
|
|
377
|
+
echo "=== Attempt 3: merge -X theirs (accept remote on conflict) ==="
|
|
378
|
+
git pull -X theirs --no-rebase origin main || {
|
|
379
|
+
echo "Merge -X theirs failed on attempt 3"
|
|
380
|
+
git merge --abort 2>/dev/null || true
|
|
381
|
+
sleep $((30 + RANDOM % 10))
|
|
382
|
+
continue
|
|
383
|
+
}
|
|
384
|
+
;;
|
|
385
|
+
esac
|
|
386
|
+
git push origin HEAD:refs/heads/main && { PUSH_SUCCESS="true"; break; }
|
|
387
|
+
echo "Push failed on attempt $attempt"
|
|
388
|
+
sleep $((attempt * 10 + RANDOM % 10))
|
|
366
389
|
done
|
|
390
|
+
if [ "$PUSH_SUCCESS" != "true" ]; then
|
|
391
|
+
echo "::error::Failed to push after $MAX_RETRIES attempts"
|
|
392
|
+
exit 1
|
|
393
|
+
fi
|
|
367
394
|
|
|
368
395
|
- name: "Verify schedule registered with GitHub"
|
|
369
396
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && inputs.schedule != '' && inputs.dry-run != 'true' && inputs.dry-run != true
|
|
@@ -269,20 +269,47 @@ jobs:
|
|
|
269
269
|
else
|
|
270
270
|
git commit -m "schedule: set to ${FREQUENCY}, model ${MODEL:-gpt-5-mini}"
|
|
271
271
|
fi
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
272
|
+
MAX_RETRIES=3
|
|
273
|
+
PUSH_SUCCESS=""
|
|
274
|
+
for attempt in $(seq 1 $MAX_RETRIES); do
|
|
275
|
+
# Tiered conflict resolution (mirrors fix-stuck strategy)
|
|
276
|
+
case $attempt in
|
|
277
|
+
1)
|
|
278
|
+
echo "=== Attempt 1: rebase (cleanest) ==="
|
|
279
|
+
git pull --rebase origin main || {
|
|
280
|
+
echo "Rebase conflict on attempt 1 — aborting rebase"
|
|
281
|
+
git rebase --abort 2>/dev/null || true
|
|
282
|
+
sleep $((10 + RANDOM % 10))
|
|
283
|
+
continue
|
|
284
|
+
}
|
|
285
|
+
;;
|
|
286
|
+
2)
|
|
287
|
+
echo "=== Attempt 2: merge (handles non-overlapping changes) ==="
|
|
288
|
+
git pull --no-rebase origin main || {
|
|
289
|
+
echo "Merge conflict on attempt 2 — aborting merge"
|
|
290
|
+
git merge --abort 2>/dev/null || true
|
|
291
|
+
sleep $((20 + RANDOM % 10))
|
|
292
|
+
continue
|
|
293
|
+
}
|
|
294
|
+
;;
|
|
295
|
+
3)
|
|
296
|
+
echo "=== Attempt 3: merge -X theirs (accept remote on conflict) ==="
|
|
297
|
+
git pull -X theirs --no-rebase origin main || {
|
|
298
|
+
echo "Merge -X theirs failed on attempt 3"
|
|
299
|
+
git merge --abort 2>/dev/null || true
|
|
300
|
+
sleep $((30 + RANDOM % 10))
|
|
301
|
+
continue
|
|
302
|
+
}
|
|
303
|
+
;;
|
|
304
|
+
esac
|
|
305
|
+
git push origin HEAD:refs/heads/main && { PUSH_SUCCESS="true"; break; }
|
|
306
|
+
echo "Push failed on attempt $attempt"
|
|
307
|
+
sleep $((attempt * 10 + RANDOM % 10))
|
|
285
308
|
done
|
|
309
|
+
if [ "$PUSH_SUCCESS" != "true" ]; then
|
|
310
|
+
echo "::error::Failed to push after $MAX_RETRIES attempts"
|
|
311
|
+
exit 1
|
|
312
|
+
fi
|
|
286
313
|
|
|
287
314
|
- name: "Problem 2 fix: Verify schedule registered with GitHub"
|
|
288
315
|
if: github.repository != 'xn-intenton-z2a/agentic-lib' && inputs.dry-run != 'true' && inputs.dry-run != true
|
|
@@ -107,20 +107,47 @@ jobs:
|
|
|
107
107
|
git diff --cached --quiet && echo "No changes" && exit 0
|
|
108
108
|
VERSION=$(npx @xn-intenton-z2a/agentic-lib version 2>/dev/null || echo "latest")
|
|
109
109
|
git commit -m "update agentic-lib@${VERSION} [skip ci]"
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
110
|
+
MAX_RETRIES=3
|
|
111
|
+
PUSH_SUCCESS=""
|
|
112
|
+
for attempt in $(seq 1 $MAX_RETRIES); do
|
|
113
|
+
# Tiered conflict resolution (mirrors fix-stuck strategy)
|
|
114
|
+
case $attempt in
|
|
115
|
+
1)
|
|
116
|
+
echo "=== Attempt 1: rebase (cleanest) ==="
|
|
117
|
+
git pull --rebase origin main || {
|
|
118
|
+
echo "Rebase conflict on attempt 1 — aborting rebase"
|
|
119
|
+
git rebase --abort 2>/dev/null || true
|
|
120
|
+
sleep $((10 + RANDOM % 10))
|
|
121
|
+
continue
|
|
122
|
+
}
|
|
123
|
+
;;
|
|
124
|
+
2)
|
|
125
|
+
echo "=== Attempt 2: merge (handles non-overlapping changes) ==="
|
|
126
|
+
git pull --no-rebase origin main || {
|
|
127
|
+
echo "Merge conflict on attempt 2 — aborting merge"
|
|
128
|
+
git merge --abort 2>/dev/null || true
|
|
129
|
+
sleep $((20 + RANDOM % 10))
|
|
130
|
+
continue
|
|
131
|
+
}
|
|
132
|
+
;;
|
|
133
|
+
3)
|
|
134
|
+
echo "=== Attempt 3: merge -X theirs (accept remote on conflict) ==="
|
|
135
|
+
git pull -X theirs --no-rebase origin main || {
|
|
136
|
+
echo "Merge -X theirs failed on attempt 3"
|
|
137
|
+
git merge --abort 2>/dev/null || true
|
|
138
|
+
sleep $((30 + RANDOM % 10))
|
|
139
|
+
continue
|
|
140
|
+
}
|
|
141
|
+
;;
|
|
142
|
+
esac
|
|
143
|
+
git push origin HEAD:refs/heads/main && { PUSH_SUCCESS="true"; break; }
|
|
144
|
+
echo "Push failed on attempt $attempt"
|
|
145
|
+
sleep $((attempt * 10 + RANDOM % 10))
|
|
123
146
|
done
|
|
147
|
+
if [ "$PUSH_SUCCESS" != "true" ]; then
|
|
148
|
+
echo "::error::Failed to push after $MAX_RETRIES attempts"
|
|
149
|
+
exit 1
|
|
150
|
+
fi
|
|
124
151
|
|
|
125
152
|
- name: Job Summary
|
|
126
153
|
if: always()
|
|
@@ -139,7 +139,7 @@ jobs:
|
|
|
139
139
|
steps:
|
|
140
140
|
- uses: actions/checkout@v6
|
|
141
141
|
with:
|
|
142
|
-
ref: ${{ inputs.ref || github.
|
|
142
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
143
143
|
sparse-checkout: |
|
|
144
144
|
${{ env.configPath }}
|
|
145
145
|
MISSION_COMPLETE.md
|
|
@@ -308,7 +308,7 @@ jobs:
|
|
|
308
308
|
steps:
|
|
309
309
|
- uses: actions/checkout@v6
|
|
310
310
|
with:
|
|
311
|
-
ref: ${{ inputs.ref || github.
|
|
311
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
312
312
|
|
|
313
313
|
- uses: actions/setup-node@v6
|
|
314
314
|
with:
|
|
@@ -351,7 +351,7 @@ jobs:
|
|
|
351
351
|
steps:
|
|
352
352
|
- uses: actions/checkout@v6
|
|
353
353
|
with:
|
|
354
|
-
ref: ${{ inputs.ref || github.
|
|
354
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
355
355
|
|
|
356
356
|
- uses: actions/setup-node@v6
|
|
357
357
|
with:
|
|
@@ -623,7 +623,7 @@ jobs:
|
|
|
623
623
|
- uses: actions/checkout@v6
|
|
624
624
|
with:
|
|
625
625
|
fetch-depth: 0
|
|
626
|
-
ref: ${{ inputs.ref || github.
|
|
626
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
627
627
|
|
|
628
628
|
- name: Fetch log and screenshot from log branch
|
|
629
629
|
env:
|
|
@@ -735,6 +735,7 @@ jobs:
|
|
|
735
735
|
with:
|
|
736
736
|
commit-message: "agentic-step: maintain features and library"
|
|
737
737
|
push-ref: ${{ github.ref_name }}
|
|
738
|
+
fail-on-conflict: "false"
|
|
738
739
|
|
|
739
740
|
- name: Capture commit SHA
|
|
740
741
|
id: get-sha
|
|
@@ -762,7 +763,7 @@ jobs:
|
|
|
762
763
|
- uses: actions/checkout@v6
|
|
763
764
|
with:
|
|
764
765
|
fetch-depth: 0
|
|
765
|
-
ref: ${{ inputs.ref || github.
|
|
766
|
+
ref: ${{ inputs.ref || github.ref }}
|
|
766
767
|
|
|
767
768
|
- name: Fetch log and agent logs from log branch
|
|
768
769
|
env:
|
|
@@ -830,7 +831,7 @@ jobs:
|
|
|
830
831
|
- uses: actions/checkout@v6
|
|
831
832
|
with:
|
|
832
833
|
fetch-depth: 0
|
|
833
|
-
ref: ${{ needs.maintain.outputs.commit-sha || github.
|
|
834
|
+
ref: ${{ needs.maintain.outputs.commit-sha || github.ref }}
|
|
834
835
|
|
|
835
836
|
- name: Fetch log and screenshot from log branch
|
|
836
837
|
env:
|
|
@@ -895,7 +896,7 @@ jobs:
|
|
|
895
896
|
- uses: actions/checkout@v6
|
|
896
897
|
with:
|
|
897
898
|
fetch-depth: 0
|
|
898
|
-
ref: ${{ needs.maintain.outputs.commit-sha || github.
|
|
899
|
+
ref: ${{ needs.maintain.outputs.commit-sha || github.ref }}
|
|
899
900
|
|
|
900
901
|
- name: Fetch log, screenshot and state from log branch
|
|
901
902
|
env:
|
|
@@ -980,7 +981,7 @@ jobs:
|
|
|
980
981
|
- uses: actions/checkout@v6
|
|
981
982
|
with:
|
|
982
983
|
fetch-depth: 0
|
|
983
|
-
ref: ${{ needs.maintain.outputs.commit-sha || github.
|
|
984
|
+
ref: ${{ needs.maintain.outputs.commit-sha || github.ref }}
|
|
984
985
|
|
|
985
986
|
- uses: actions/setup-node@v6
|
|
986
987
|
with:
|
|
@@ -1366,7 +1367,7 @@ jobs:
|
|
|
1366
1367
|
steps:
|
|
1367
1368
|
- uses: actions/checkout@v6
|
|
1368
1369
|
with:
|
|
1369
|
-
ref: ${{ needs.maintain.outputs.commit-sha || github.
|
|
1370
|
+
ref: ${{ needs.maintain.outputs.commit-sha || github.ref }}
|
|
1370
1371
|
|
|
1371
1372
|
- uses: actions/setup-node@v6
|
|
1372
1373
|
with:
|
|
@@ -1421,7 +1422,7 @@ jobs:
|
|
|
1421
1422
|
with:
|
|
1422
1423
|
fetch-depth: 0
|
|
1423
1424
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
1424
|
-
ref: ${{ needs.maintain.outputs.commit-sha || github.
|
|
1425
|
+
ref: ${{ needs.maintain.outputs.commit-sha || github.ref }}
|
|
1425
1426
|
|
|
1426
1427
|
- name: Fetch log and screenshot from log branch
|
|
1427
1428
|
env:
|
|
@@ -1722,7 +1723,7 @@ jobs:
|
|
|
1722
1723
|
- uses: actions/checkout@v6
|
|
1723
1724
|
with:
|
|
1724
1725
|
fetch-depth: 0
|
|
1725
|
-
ref: ${{ needs.maintain.outputs.commit-sha || github.
|
|
1726
|
+
ref: ${{ needs.maintain.outputs.commit-sha || github.ref }}
|
|
1726
1727
|
|
|
1727
1728
|
- name: Summary
|
|
1728
1729
|
run: |
|
|
@@ -1815,7 +1816,7 @@ jobs:
|
|
|
1815
1816
|
&& needs.params.result == 'success'
|
|
1816
1817
|
uses: ./.github/workflows/agentic-lib-test.yml
|
|
1817
1818
|
with:
|
|
1818
|
-
ref: ${{ needs.maintain.outputs.commit-sha || github.
|
|
1819
|
+
ref: ${{ needs.maintain.outputs.commit-sha || github.ref }}
|
|
1819
1820
|
secrets: inherit
|
|
1820
1821
|
|
|
1821
1822
|
# ─── Schedule change (if requested) ────────────────────────────────
|
|
@@ -1824,7 +1825,7 @@ jobs:
|
|
|
1824
1825
|
if: ${{ !cancelled() && needs.params.outputs.dry-run != 'true' && needs.params.outputs.schedule != '' && needs.params.result == 'success' }}
|
|
1825
1826
|
uses: ./.github/workflows/agentic-lib-schedule.yml
|
|
1826
1827
|
with:
|
|
1827
|
-
ref: ${{ needs.maintain.outputs.commit-sha || github.
|
|
1828
|
+
ref: ${{ needs.maintain.outputs.commit-sha || github.ref }}
|
|
1828
1829
|
frequency: ${{ needs.params.outputs.schedule }}
|
|
1829
1830
|
model: ${{ needs.params.outputs.model }}
|
|
1830
1831
|
profile: ${{ needs.params.outputs.profile }}
|
package/package.json
CHANGED
|
@@ -228,14 +228,26 @@ async function executeMissionComplete(octokit, repo, reason) {
|
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
// W3: Disable schedule on mission-complete (Benchmark 011 FINDING-4)
|
|
231
|
+
// W6: Skip dispatch if schedule is already at target frequency
|
|
231
232
|
try {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
233
|
+
let skipDispatch = false;
|
|
234
|
+
try {
|
|
235
|
+
const tomlContent = readFileSync("agentic-lib.toml", "utf8");
|
|
236
|
+
const supervisorMatch = tomlContent.match(/^\s*supervisor\s*=\s*"([^"]*)"/m);
|
|
237
|
+
if (supervisorMatch && supervisorMatch[1] === "off") {
|
|
238
|
+
core.info("Schedule already off — skipping dispatch");
|
|
239
|
+
skipDispatch = true;
|
|
240
|
+
}
|
|
241
|
+
} catch { /* toml read failed — dispatch anyway */ }
|
|
242
|
+
if (!skipDispatch) {
|
|
243
|
+
await octokit.rest.actions.createWorkflowDispatch({
|
|
244
|
+
...repo,
|
|
245
|
+
workflow_id: "agentic-lib-schedule.yml",
|
|
246
|
+
ref: "main",
|
|
247
|
+
inputs: { frequency: "off" },
|
|
248
|
+
});
|
|
249
|
+
core.info("Dispatched schedule change to off after mission-complete");
|
|
250
|
+
}
|
|
239
251
|
} catch (err) {
|
|
240
252
|
core.warning(`Could not dispatch schedule change: ${err.message}`);
|
|
241
253
|
}
|
|
@@ -315,14 +327,26 @@ async function executeMissionFailed(octokit, repo, reason, metricAssessment) {
|
|
|
315
327
|
}
|
|
316
328
|
|
|
317
329
|
// C3: Dispatch schedule change to weekly
|
|
330
|
+
// W6: Skip dispatch if schedule is already at target frequency
|
|
318
331
|
try {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
332
|
+
let skipDispatch = false;
|
|
333
|
+
try {
|
|
334
|
+
const tomlContent = readFileSync("agentic-lib.toml", "utf8");
|
|
335
|
+
const supervisorMatch = tomlContent.match(/^\s*supervisor\s*=\s*"([^"]*)"/m);
|
|
336
|
+
if (supervisorMatch && supervisorMatch[1] === "weekly") {
|
|
337
|
+
core.info("Schedule already weekly — skipping dispatch");
|
|
338
|
+
skipDispatch = true;
|
|
339
|
+
}
|
|
340
|
+
} catch { /* toml read failed — dispatch anyway */ }
|
|
341
|
+
if (!skipDispatch) {
|
|
342
|
+
await octokit.rest.actions.createWorkflowDispatch({
|
|
343
|
+
...repo,
|
|
344
|
+
workflow_id: "agentic-lib-schedule.yml",
|
|
345
|
+
ref: "main",
|
|
346
|
+
inputs: { frequency: "weekly" },
|
|
347
|
+
});
|
|
348
|
+
core.info("Dispatched schedule change to weekly after mission-failed");
|
|
349
|
+
}
|
|
326
350
|
} catch (err) {
|
|
327
351
|
core.warning(`Could not dispatch schedule change: ${err.message}`);
|
|
328
352
|
}
|
|
@@ -16,6 +16,10 @@ inputs:
|
|
|
16
16
|
description: "Branch ref to push to (default: current ref_name)"
|
|
17
17
|
required: false
|
|
18
18
|
default: ""
|
|
19
|
+
fail-on-conflict:
|
|
20
|
+
description: "Fail the step if push conflicts cannot be resolved (default: true)"
|
|
21
|
+
required: false
|
|
22
|
+
default: "true"
|
|
19
23
|
|
|
20
24
|
runs:
|
|
21
25
|
using: "composite"
|
|
@@ -32,6 +36,13 @@ runs:
|
|
|
32
36
|
git reset HEAD -- 'intentïon.md' 'SCREENSHOT_INDEX.png' 2>/dev/null || true
|
|
33
37
|
git reset HEAD -- agent-log-*.md 2>/dev/null || true
|
|
34
38
|
git reset HEAD -- agentic-lib-state.toml 2>/dev/null || true
|
|
39
|
+
# W1: Validate test files — reject empty test suites that break vitest
|
|
40
|
+
for f in $(git diff --cached --name-only --diff-filter=ACM -- '*.test.js' '*.test.ts' '*.test.mjs'); do
|
|
41
|
+
if [ -f "$f" ] && ! grep -qE '(describe|test|it)\s*\(' "$f"; then
|
|
42
|
+
echo "::warning::${f} has no test suite (no describe/test/it blocks) — removing from commit"
|
|
43
|
+
git reset HEAD -- "$f"
|
|
44
|
+
fi
|
|
45
|
+
done
|
|
35
46
|
if git diff --cached --quiet; then
|
|
36
47
|
echo "No changes to commit"
|
|
37
48
|
fi
|
|
@@ -49,44 +60,75 @@ runs:
|
|
|
49
60
|
else
|
|
50
61
|
REMOTE_REF_EXISTS="true"
|
|
51
62
|
fi
|
|
63
|
+
# Determine push command based on ref
|
|
64
|
+
if [ -n "$REF" ]; then
|
|
65
|
+
PUSH_CMD="git push origin HEAD:refs/heads/$REF"
|
|
66
|
+
else
|
|
67
|
+
PUSH_CMD="git push"
|
|
68
|
+
fi
|
|
69
|
+
PULL_TARGET="${REF:+origin $REF}"
|
|
52
70
|
for attempt in $(seq 1 $MAX_RETRIES); do
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
71
|
+
# New branch — no pull needed, just push
|
|
72
|
+
if [ -n "$REF" ] && [ "$REMOTE_REF_EXISTS" != "true" ]; then
|
|
73
|
+
$PUSH_CMD && { REMOTE_REF_EXISTS="true"; PUSH_SUCCESS="true"; break; } || true
|
|
74
|
+
sleep $((attempt * 10 + RANDOM % 10))
|
|
75
|
+
continue
|
|
76
|
+
fi
|
|
77
|
+
# Tiered conflict resolution (mirrors fix-stuck strategy)
|
|
78
|
+
case $attempt in
|
|
79
|
+
1)
|
|
80
|
+
echo "=== Attempt 1: rebase (cleanest) ==="
|
|
81
|
+
git pull --rebase $PULL_TARGET || {
|
|
82
|
+
echo "Rebase conflict on attempt 1 — aborting rebase"
|
|
57
83
|
git rebase --abort 2>/dev/null || true
|
|
58
|
-
sleep $((
|
|
84
|
+
sleep $((10 + RANDOM % 10))
|
|
59
85
|
continue
|
|
60
86
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
echo "
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
87
|
+
;;
|
|
88
|
+
2)
|
|
89
|
+
echo "=== Attempt 2: merge (handles non-overlapping changes) ==="
|
|
90
|
+
git pull --no-rebase $PULL_TARGET || {
|
|
91
|
+
echo "Merge conflict on attempt 2 — aborting merge"
|
|
92
|
+
git merge --abort 2>/dev/null || true
|
|
93
|
+
sleep $((20 + RANDOM % 10))
|
|
94
|
+
continue
|
|
95
|
+
}
|
|
96
|
+
;;
|
|
97
|
+
3)
|
|
98
|
+
echo "=== Attempt 3: merge -X theirs (accept remote on conflict) ==="
|
|
99
|
+
git pull -X theirs --no-rebase $PULL_TARGET || {
|
|
100
|
+
echo "Merge -X theirs failed on attempt 3"
|
|
101
|
+
git merge --abort 2>/dev/null || true
|
|
102
|
+
sleep $((30 + RANDOM % 10))
|
|
103
|
+
continue
|
|
104
|
+
}
|
|
105
|
+
;;
|
|
106
|
+
esac
|
|
107
|
+
# Check if rebase/merge dropped our commit (already on remote)
|
|
108
|
+
if [ -n "$REF" ]; then
|
|
109
|
+
LOCAL_SHA=$(git rev-parse HEAD)
|
|
110
|
+
REMOTE_SHA=$(git rev-parse "origin/$REF" 2>/dev/null || echo "")
|
|
111
|
+
if [ "$LOCAL_SHA" = "$REMOTE_SHA" ]; then
|
|
112
|
+
echo "Rebase/merge dropped local commit (already on remote) — nothing to push"
|
|
113
|
+
PUSH_SUCCESS="true"
|
|
114
|
+
break
|
|
69
115
|
fi
|
|
70
|
-
# Use HEAD:refs/heads/$REF to handle detached HEAD state
|
|
71
|
-
# (actions/checkout with a SHA puts us in detached HEAD, so
|
|
72
|
-
# "git push origin main" fails with "src refspec main does not match any")
|
|
73
|
-
git push origin "HEAD:refs/heads/$REF" && { REMOTE_REF_EXISTS="true"; PUSH_SUCCESS="true"; break; }
|
|
74
|
-
else
|
|
75
|
-
git pull --rebase || {
|
|
76
|
-
echo "Rebase conflict on attempt $attempt — aborting rebase and retrying"
|
|
77
|
-
git rebase --abort 2>/dev/null || true
|
|
78
|
-
sleep $((attempt * 2))
|
|
79
|
-
continue
|
|
80
|
-
}
|
|
81
|
-
git push && { PUSH_SUCCESS="true"; break; }
|
|
82
116
|
fi
|
|
83
|
-
|
|
84
|
-
|
|
117
|
+
$PUSH_CMD && { REMOTE_REF_EXISTS="true"; PUSH_SUCCESS="true"; break; }
|
|
118
|
+
echo "Push failed on attempt $attempt"
|
|
119
|
+
sleep $((attempt * 10 + RANDOM % 10))
|
|
85
120
|
done
|
|
86
121
|
# Restore stashed unstaged changes
|
|
87
122
|
git stash pop 2>/dev/null || true
|
|
88
123
|
if [ "$PUSH_SUCCESS" != "true" ]; then
|
|
89
|
-
|
|
90
|
-
|
|
124
|
+
FAIL_ON_CONFLICT="${{ inputs.fail-on-conflict }}"
|
|
125
|
+
if [ "$FAIL_ON_CONFLICT" = "false" ]; then
|
|
126
|
+
echo "::warning::Failed to push after $MAX_RETRIES attempts — skipping (fail-on-conflict=false)"
|
|
127
|
+
git rebase --abort 2>/dev/null || true
|
|
128
|
+
git merge --abort 2>/dev/null || true
|
|
129
|
+
else
|
|
130
|
+
echo "::error::Failed to push after $MAX_RETRIES attempts"
|
|
131
|
+
exit 1
|
|
132
|
+
fi
|
|
91
133
|
fi
|
|
92
134
|
fi
|