@plainconceptsplatform/workflows 1.8.3 → 1.9.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/loops/actions/verify-route-matrix/verify-route-matrix.sh +13 -0
- package/loops/templates/agentics/agentics-app-errors.yml +2 -1
- package/loops/templates/agentics/agentics-error-report.yml +2 -1
- package/loops/workflows/authorize-bot-work.yml +107 -105
- package/loops/workflows/release-tag.yml +2 -0
- package/loops/workflows/work-router.yml +6 -0
- package/package.json +1 -1
|
@@ -2950,6 +2950,19 @@ grep -qF -- '--base "$STACK_BRANCH" --limit 100 --json number,body' "${WORKFLOWS
|
|
|
2950
2950
|
grep -qF 'releasedFeatures' "${HERE}/../housekeeping/action.yml" ||
|
|
2951
2951
|
{ ONE_AT_A_TIME_OK=0; echo "FAIL: housekeeping releases several children of one feature in a sweep" >&2; }
|
|
2952
2952
|
if [ "$ONE_AT_A_TIME_OK" -eq 1 ]; then PASS=$((PASS + 1)); else FAIL=$((FAIL + 1)); fi
|
|
2953
|
+
# A repository variable AGENTIC_WORKFLOWS_DISABLED turns everything off: the router's two root jobs
|
|
2954
|
+
# (every other job needs one of them) and every workflow with a trigger of its own.
|
|
2955
|
+
OFF_OK=1
|
|
2956
|
+
for job in authorize classify; do
|
|
2957
|
+
sed -n "/^ ${job}:\$/,/^ runs-on:/p" "${WORKFLOWS_DIR}/work-router.yml" | grep -qF "if: vars.AGENTIC_WORKFLOWS_DISABLED == ''" ||
|
|
2958
|
+
{ OFF_OK=0; echo "FAIL: the router's ${job} job ignores AGENTIC_WORKFLOWS_DISABLED" >&2; }
|
|
2959
|
+
done
|
|
2960
|
+
for f in "${WORKFLOWS_DIR}/authorize-bot-work.yml" "${WORKFLOWS_DIR}/release-tag.yml"; do
|
|
2961
|
+
[ -f "$f" ] || continue
|
|
2962
|
+
grep -qF "vars.AGENTIC_WORKFLOWS_DISABLED == ''" "$f" ||
|
|
2963
|
+
{ OFF_OK=0; echo "FAIL: $(basename "$f") ignores AGENTIC_WORKFLOWS_DISABLED" >&2; }
|
|
2964
|
+
done
|
|
2965
|
+
if [ "$OFF_OK" -eq 1 ]; then PASS=$((PASS + 1)); else FAIL=$((FAIL + 1)); fi
|
|
2953
2966
|
# A stack child runs the feature branch's copy of the workflows, so the router brings the default
|
|
2954
2967
|
# branch in before it dispatches one.
|
|
2955
2968
|
if grep -qF 'bring $DEFAULT_BRANCH into $STACK_BRANCH before a child runs' "${WORKFLOWS_DIR}/work-router.yml"; then
|
|
@@ -87,7 +87,8 @@ env:
|
|
|
87
87
|
jobs:
|
|
88
88
|
collect:
|
|
89
89
|
# Fork of a consumer: not their Azure, not their issues.
|
|
90
|
-
|
|
90
|
+
# AGENTIC_WORKFLOWS_DISABLED, a repository variable with any value, turns the automation off.
|
|
91
|
+
if: "!github.event.repository.fork && vars.AGENTIC_WORKFLOWS_DISABLED == ''"
|
|
91
92
|
runs-on: agents-arc
|
|
92
93
|
timeout-minutes: 20
|
|
93
94
|
# Load bearing, not decoration. The federated credential on the deploy identity trusts the
|
|
@@ -58,7 +58,8 @@ env:
|
|
|
58
58
|
jobs:
|
|
59
59
|
report:
|
|
60
60
|
# Fork of a consumer: the fleet is not theirs and neither is the report.
|
|
61
|
-
|
|
61
|
+
# AGENTIC_WORKFLOWS_DISABLED, a repository variable with any value, turns the automation off.
|
|
62
|
+
if: "!github.event.repository.fork && vars.AGENTIC_WORKFLOWS_DISABLED == ''"
|
|
62
63
|
runs-on: agents-arc
|
|
63
64
|
timeout-minutes: 20
|
|
64
65
|
concurrency:
|
|
@@ -1,105 +1,107 @@
|
|
|
1
|
-
# Managed by @plainconceptsplatform/workflows. Source: loops/workflows/authorize-bot-work.yml. Update with `workflows update --force`; consumer edits may be overwritten.
|
|
2
|
-
# Human adds implement/refine/direct/feature label → validates permission → bot adds bot-working
|
|
3
|
-
# This ensures the bot is the actor for all agentic workflows.
|
|
4
|
-
#
|
|
5
|
-
# IMPORTANT: Only triggers for HUMAN actors. When the bot transitions refine→implement,
|
|
6
|
-
# it adds bot-working itself, so authorize-bot-work must not fire again.
|
|
7
|
-
name: "Authorize Bot Work"
|
|
8
|
-
|
|
9
|
-
run-name: "Authorizing: ${{ github.event.issue.title }} (#${{ github.event.issue.number }})"
|
|
10
|
-
|
|
11
|
-
on:
|
|
12
|
-
issues:
|
|
13
|
-
types: [labeled]
|
|
14
|
-
|
|
15
|
-
permissions:
|
|
16
|
-
contents: read
|
|
17
|
-
|
|
18
|
-
jobs:
|
|
19
|
-
authorize:
|
|
20
|
-
# Only trigger for work labels from HUMANS (not bots), and only if another bot run does not
|
|
21
|
-
# already own the issue.
|
|
22
|
-
#
|
|
23
|
-
# `review` is deliberately NOT excluded. It used to be, and that made the label a one-way
|
|
24
|
-
# door: the classifier refuses to route while `review` is set, so a person adding `refine`
|
|
25
|
-
# to a parked issue got no run, no comment and no error anywhere. Triage's own
|
|
26
|
-
# needs-maintainer verdict tells the maintainer to add `refine`, which could not work.
|
|
27
|
-
#
|
|
28
|
-
# A person adding a work label IS the human review the label was waiting for, so this
|
|
29
|
-
# workflow clears it below before handing the issue to the bot. The classifier's own guard
|
|
30
|
-
# stays as it is: it exists to stop the *bot* re-triggering itself, and by the time
|
|
31
|
-
# bot-working is added `review` is already gone.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
1
|
+
# Managed by @plainconceptsplatform/workflows. Source: loops/workflows/authorize-bot-work.yml. Update with `workflows update --force`; consumer edits may be overwritten.
|
|
2
|
+
# Human adds implement/refine/direct/feature label → validates permission → bot adds bot-working
|
|
3
|
+
# This ensures the bot is the actor for all agentic workflows.
|
|
4
|
+
#
|
|
5
|
+
# IMPORTANT: Only triggers for HUMAN actors. When the bot transitions refine→implement,
|
|
6
|
+
# it adds bot-working itself, so authorize-bot-work must not fire again.
|
|
7
|
+
name: "Authorize Bot Work"
|
|
8
|
+
|
|
9
|
+
run-name: "Authorizing: ${{ github.event.issue.title }} (#${{ github.event.issue.number }})"
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
issues:
|
|
13
|
+
types: [labeled]
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
authorize:
|
|
20
|
+
# Only trigger for work labels from HUMANS (not bots), and only if another bot run does not
|
|
21
|
+
# already own the issue.
|
|
22
|
+
#
|
|
23
|
+
# `review` is deliberately NOT excluded. It used to be, and that made the label a one-way
|
|
24
|
+
# door: the classifier refuses to route while `review` is set, so a person adding `refine`
|
|
25
|
+
# to a parked issue got no run, no comment and no error anywhere. Triage's own
|
|
26
|
+
# needs-maintainer verdict tells the maintainer to add `refine`, which could not work.
|
|
27
|
+
#
|
|
28
|
+
# A person adding a work label IS the human review the label was waiting for, so this
|
|
29
|
+
# workflow clears it below before handing the issue to the bot. The classifier's own guard
|
|
30
|
+
# stays as it is: it exists to stop the *bot* re-triggering itself, and by the time
|
|
31
|
+
# bot-working is added `review` is already gone.
|
|
32
|
+
# AGENTIC_WORKFLOWS_DISABLED, a repository variable with any value, turns the automation off.
|
|
33
|
+
if: >
|
|
34
|
+
vars.AGENTIC_WORKFLOWS_DISABLED == '' &&
|
|
35
|
+
(github.event.label.name == 'implement' ||
|
|
36
|
+
github.event.label.name == 'refine') &&
|
|
37
|
+
!contains(github.event.issue.labels.*.name, 'bot-working') &&
|
|
38
|
+
!endsWith(github.actor, '[bot]')
|
|
39
|
+
runs-on: [agents-aw, "affinity-${{ github.repository_id }}-${{ github.run_id }}-${{ github.run_attempt }}"]
|
|
40
|
+
timeout-minutes: 5
|
|
41
|
+
concurrency:
|
|
42
|
+
group: authorize-${{ github.event.issue.number }}
|
|
43
|
+
cancel-in-progress: false
|
|
44
|
+
permissions:
|
|
45
|
+
contents: read
|
|
46
|
+
issues: write
|
|
47
|
+
steps:
|
|
48
|
+
- name: Check actor permission
|
|
49
|
+
id: check
|
|
50
|
+
env:
|
|
51
|
+
GH_TOKEN: ${{ github.token }}
|
|
52
|
+
ACTOR: ${{ github.actor }}
|
|
53
|
+
run: |
|
|
54
|
+
set -euo pipefail
|
|
55
|
+
|
|
56
|
+
permission=$(gh api "repos/$GITHUB_REPOSITORY/collaborators/$ACTOR/permission" \
|
|
57
|
+
--jq '.permission' 2>/dev/null || echo "none")
|
|
58
|
+
|
|
59
|
+
case "$permission" in
|
|
60
|
+
admin | maintain | write)
|
|
61
|
+
echo "authorized=true" >> "$GITHUB_OUTPUT"
|
|
62
|
+
echo "::notice::$ACTOR has $permission permission - authorized"
|
|
63
|
+
;;
|
|
64
|
+
*)
|
|
65
|
+
echo "authorized=false" >> "$GITHUB_OUTPUT"
|
|
66
|
+
echo "::warning::$ACTOR has '$permission' permission - not authorized"
|
|
67
|
+
;;
|
|
68
|
+
esac
|
|
69
|
+
|
|
70
|
+
- name: Checkout for App token action
|
|
71
|
+
if: steps.check.outputs.authorized == 'true'
|
|
72
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
73
|
+
with:
|
|
74
|
+
persist-credentials: false
|
|
75
|
+
|
|
76
|
+
- name: Generate App token
|
|
77
|
+
if: steps.check.outputs.authorized == 'true'
|
|
78
|
+
id: app-token
|
|
79
|
+
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
|
80
|
+
with:
|
|
81
|
+
app-id: ${{ secrets.BOT_APP_ID }}
|
|
82
|
+
private-key: ${{ secrets.BOT_PRIVATE_KEY }}
|
|
83
|
+
|
|
84
|
+
- name: Bot takes the issue over
|
|
85
|
+
if: steps.check.outputs.authorized == 'true'
|
|
86
|
+
env:
|
|
87
|
+
GH_TOKEN: ${{ steps.app-token.outputs.token }}
|
|
88
|
+
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
89
|
+
LABEL: ${{ github.event.label.name }}
|
|
90
|
+
run: |
|
|
91
|
+
set -euo pipefail
|
|
92
|
+
|
|
93
|
+
# Clear review FIRST. A person adding a work label is the human review the label was
|
|
94
|
+
# waiting for, and the classifier refuses to route an issue that still carries it, so
|
|
95
|
+
# removing it here is what makes the hand-off work at all. It also has to happen
|
|
96
|
+
# before bot-working, because that is the event the classifier reads: adding
|
|
97
|
+
# bot-working first would raise an event whose payload still shows review.
|
|
98
|
+
# --remove-label on an absent label is a no-op, so this is safe on a fresh issue.
|
|
99
|
+
# `stalled` goes with it: a person taking the issue on restarts the work, so the
|
|
100
|
+
# marker the janitor retries on must not survive into the new run.
|
|
101
|
+
gh issue edit "$ISSUE_NUMBER" --remove-label "review" --remove-label "stalled" 2>/dev/null ||
|
|
102
|
+
echo "::notice::no review or stalled label to clear on #$ISSUE_NUMBER"
|
|
103
|
+
|
|
104
|
+
echo "Adding bot-working label to issue #$ISSUE_NUMBER (triggered by $LABEL)"
|
|
105
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "bot-working"
|
|
106
|
+
|
|
107
|
+
echo "::notice::bot-working label added - bot will now own the $LABEL workflow"
|
|
@@ -27,7 +27,9 @@ concurrency:
|
|
|
27
27
|
jobs:
|
|
28
28
|
tag:
|
|
29
29
|
name: Tag and publish the release
|
|
30
|
+
# AGENTIC_WORKFLOWS_DISABLED, a repository variable with any value, turns the automation off.
|
|
30
31
|
if: >-
|
|
32
|
+
vars.AGENTIC_WORKFLOWS_DISABLED == '' &&
|
|
31
33
|
startsWith(github.event.head_commit.message, 'chore(release): v')
|
|
32
34
|
runs-on: agents-arc
|
|
33
35
|
timeout-minutes: 10
|
|
@@ -307,6 +307,10 @@ permissions:
|
|
|
307
307
|
jobs:
|
|
308
308
|
# Public repositories must check repository permission before an event can start a model.
|
|
309
309
|
authorize:
|
|
310
|
+
# Off switch: a repository variable AGENTIC_WORKFLOWS_DISABLED, with any value, stops every
|
|
311
|
+
# route. Every other job needs this one or classify, so nothing runs. For a repository that has
|
|
312
|
+
# the workflows installed but is not ready for them.
|
|
313
|
+
if: vars.AGENTIC_WORKFLOWS_DISABLED == ''
|
|
310
314
|
runs-on: [agents-aw, "affinity-${{ github.repository_id }}-${{ github.run_id }}-${{ github.run_attempt }}"]
|
|
311
315
|
timeout-minutes: 5
|
|
312
316
|
permissions:
|
|
@@ -371,6 +375,8 @@ jobs:
|
|
|
371
375
|
esac
|
|
372
376
|
|
|
373
377
|
classify:
|
|
378
|
+
# The same off switch as authorize; jobs that need only classify stop here.
|
|
379
|
+
if: vars.AGENTIC_WORKFLOWS_DISABLED == ''
|
|
374
380
|
runs-on: [agents-aw, "affinity-${{ github.repository_id }}-${{ github.run_id }}-${{ github.run_attempt }}"]
|
|
375
381
|
timeout-minutes: 5
|
|
376
382
|
permissions:
|