1+ # Managed by eqdmc/.github — do not edit. Changes overwritten on next sync.
12name : " Agent: Process Issue"
23
34on :
45 issues :
56 types : [labeled]
67
7- concurrency :
8- group : agent-issue-${{ github.event.issue.number }}
9- cancel-in-progress : false
10-
118jobs :
12- validate :
9+ process :
1310 if : github.event.label.name == 'agent-work'
14- runs-on : ubuntu-latest
15- permissions :
16- issues : write
17- outputs :
18- proceed : ${{ steps.check.outputs.proceed }}
19- issue : ${{ steps.check.outputs.issue }}
20- steps :
21- - name : Check safety labels
22- id : check
23- env :
24- GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
25- ISSUE : ${{ github.event.issue.number }}
26- run : |
27- set -euo pipefail
28- labels=$(gh issue view "$ISSUE" \
29- -R "${{ github.repository }}" \
30- --json labels --jq '.labels[].name' | tr '\n' ',')
31-
32- if echo "$labels" | grep -qE '(^|,)risk:high(,|$)'; then
33- gh issue comment "$ISSUE" -R "${{ github.repository }}" \
34- --body "Agent refused: \`risk:high\` requires human execution."
35- echo "proceed=false" >> "$GITHUB_OUTPUT"
36- exit 0
37- fi
38-
39- if echo "$labels" | grep -qE '(^|,)role:founder-only(,|$)'; then
40- gh issue comment "$ISSUE" -R "${{ github.repository }}" \
41- --body "Agent refused: \`role:founder-only\` is author-inline work, not dispatchable."
42- echo "proceed=false" >> "$GITHUB_OUTPUT"
43- exit 0
44- fi
45-
46- if echo "$labels" | grep -qE '(^|,)needs-human(,|$)'; then
47- echo "Issue has needs-human label, waiting for human response"
48- echo "proceed=false" >> "$GITHUB_OUTPUT"
49- exit 0
50- fi
51-
52- echo "proceed=true" >> "$GITHUB_OUTPUT"
53- echo "issue=$ISSUE" >> "$GITHUB_OUTPUT"
54-
55- implement :
56- needs : validate
57- if : needs.validate.outputs.proceed == 'true'
58- runs-on : ubuntu-latest
59- timeout-minutes : 30
60- permissions :
61- contents : write
62- pull-requests : write
63- issues : write
64-
65- steps :
66- - name : Checkout repository
67- uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
68- with :
69- fetch-depth : 0
70-
71- - name : Derive branch name from issue
72- id : branch
73- env :
74- GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
75- ISSUE : ${{ needs.validate.outputs.issue }}
76- REPO : ${{ github.repository }}
77- run : |
78- set -euo pipefail
79- title=$(gh issue view "$ISSUE" --repo "$REPO" --json title --jq '.title')
80- slug=$(echo "$title" \
81- | sed -E 's/^(feat|fix|chore|docs|test|refactor|ci|style|perf|build|revert): *//' \
82- | tr '[:upper:]' '[:lower:]' \
83- | tr -cs 'a-z0-9' '-' \
84- | sed 's/^-//;s/-$//' \
85- | cut -c1-50)
86- branch="agent/${ISSUE}-${slug}"
87- echo "branch=$branch" >> "$GITHUB_OUTPUT"
88- echo "title=$title" >> "$GITHUB_OUTPUT"
89-
90- if echo "$title" | grep -qE '^(feat|fix|chore|docs|test|refactor|ci|style|perf|build|revert):'; then
91- echo "pr_title=$title" >> "$GITHUB_OUTPUT"
92- else
93- echo "pr_title=feat: $title" >> "$GITHUB_OUTPUT"
94- fi
95-
96- - name : Process issue with OpenCode
97- uses : anomalyco/opencode/github@77fc88c8ade8e5a620ebbe1197f3a572d29ae91a # latest
98- env :
99- ANTHROPIC_API_KEY : ${{ secrets.ANTHROPIC_API_KEY }}
100- GITHUB_TOKEN : ${{ secrets.ORG_CONFIG_TOKEN }}
101- GH_TOKEN : ${{ secrets.ORG_CONFIG_TOKEN }}
102- with :
103- model : anthropic/claude-haiku-4-5-20251001
104- use_github_token : " true"
105- prompt : |
106- You are an autonomous agent processing issue #${{ needs.validate.outputs.issue }} on ${{ github.repository }}.
107-
108- BRANCH NAME (use exactly): ${{ steps.branch.outputs.branch }}
109- PR TITLE (use exactly): ${{ steps.branch.outputs.pr_title }}
110-
111- Step 1 — Read the issue (body AND all comments):
112- gh issue view ${{ needs.validate.outputs.issue }} -R ${{ github.repository }} --json title,body,comments
113-
114- If a "## Human Response" comment exists, continue from where
115- the previous agent left off using that response.
116-
117- Step 2 — Create your branch:
118- git checkout -b ${{ steps.branch.outputs.branch }}
119-
120- Step 3 — Implement the task. Follow "## Task" and "## Acceptance
121- criteria" sections exactly. Do NOT expand scope.
122-
123- Step 4 — Commit and push:
124- git add -A
125- git commit -m "${{ steps.branch.outputs.pr_title }} (#${{ needs.validate.outputs.issue }})"
126- git push -u origin ${{ steps.branch.outputs.branch }}
127-
128- Step 5 — Create the PR. This is non-negotiable. Run exactly:
129- gh pr create \
130- --title "${{ steps.branch.outputs.pr_title }}" \
131- --body "Closes #${{ needs.validate.outputs.issue }}" \
132- --label "agent-work,risk:low,ready-to-merge" \
133- --head "${{ steps.branch.outputs.branch }}"
134-
135- Constraints:
136- - Do NOT change the branch name, PR title, or labels above.
137- - Do NOT self-merge.
138- - Do NOT assume infrastructure creates the PR for you.
139- - Do NOT modify .github/workflows/ or settings.json.
140- - If stuck, comment "## Needs Human Input" on the issue,
141- add the needs-human label, and stop.
142-
143- - name : Verify PR was created
144- id : verify-pr
145- env :
146- GH_TOKEN : ${{ secrets.ORG_CONFIG_TOKEN }}
147- ISSUE : ${{ needs.validate.outputs.issue }}
148- REPO : ${{ github.repository }}
149- run : |
150- set -euo pipefail
151- pr=$(gh pr list --repo "$REPO" --state open --json number,body \
152- --jq "[.[] | select(.body | test(\"(?i)(close[sd]?|fix(e[sd])?|resolve[sd]?) #$ISSUE\"))] | first | .number" 2>/dev/null)
153- if [ -z "$pr" ] || [ "$pr" = "null" ]; then
154- echo "::error::Agent did not create a PR for issue #$ISSUE"
155- gh issue comment "$ISSUE" --repo "$REPO" \
156- --body "Agent completed but did not create a PR. Marking for retry." || true
157- exit 1
158- fi
159- echo "pr=$pr" >> "$GITHUB_OUTPUT"
160- echo "Agent created PR #$pr for issue #$ISSUE"
161-
162- - name : Apply org PR conventions
163- if : steps.verify-pr.outputs.pr != ''
164- env :
165- GH_TOKEN : ${{ secrets.ORG_CONFIG_TOKEN }}
166- ISSUE : ${{ needs.validate.outputs.issue }}
167- REPO : ${{ github.repository }}
168- PR : ${{ steps.verify-pr.outputs.pr }}
169- run : |
170- set -euo pipefail
171- gh pr edit "$PR" --repo "$REPO" \
172- --add-label "agent-work" --add-label "risk:low" --add-label "ready-to-merge" || true
173-
174- title=$(gh issue view "$ISSUE" --repo "$REPO" --json title --jq '.title')
175- current=$(gh pr view "$PR" --repo "$REPO" --json title --jq '.title')
176- if ! echo "$current" | grep -qE '^(feat|fix|chore|docs|test|refactor|ci|style|perf|build|revert):'; then
177- if echo "$title" | grep -qE '^(feat|fix|chore|docs|test|refactor|ci|style|perf|build|revert):'; then
178- gh pr edit "$PR" --repo "$REPO" --title "$title" || true
179- else
180- gh pr edit "$PR" --repo "$REPO" --title "feat: $title" || true
181- fi
182- fi
11+ uses : eqdmc/.github/.github/workflows/_agent-process-issue.yml@main
12+ with :
13+ issue-number : ${{ github.event.issue.number }}
14+ secrets : inherit
0 commit comments