Skip to content

feat: add prepare phase to autopilot workflow #3

feat: add prepare phase to autopilot workflow

feat: add prepare phase to autopilot workflow #3

name: Org Agent Autopilot
on:
workflow_call:
inputs:
issue_number:
description: 'Issue number to work on'
required: true
type: number
action:
description: 'Label action (labeled or unlabeled)'
required: true
type: string
label_name:
description: 'Label that triggered this workflow'
required: true
type: string
project_id:
description: 'GitHub Projects board ID'
required: false
type: string
default: ''
status_field_id:
description: 'Status field ID in project'
required: false
type: string
default: ''
status_planning_id:
description: 'Status option ID for "Planning"'
required: false
type: string
default: ''
status_in_progress_id:
description: 'Status option ID for "In Progress"'
required: false
type: string
default: ''
status_review_id:
description: 'Status option ID for "Review"'
required: false
type: string
default: ''
secrets:
CLAUDE_CODE_OAUTH_TOKEN:
description: 'Claude Code OAuth token'
required: true
GH_TOKEN:
description: 'GitHub token for API access'
required: true
permissions:
contents: write
pull-requests: write
issues: write
actions: read
id-token: write
concurrency:
group: autopilot-${{ github.repository }}-${{ inputs.issue_number }}
cancel-in-progress: false # Don't cancel ongoing work
jobs:
# Check if issue is ready for implementation
check-readiness:
if: inputs.action == 'labeled' && inputs.label_name == 'agent: claude'

Check failure on line 65 in .github/workflows/org-agent-autopilot.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/org-agent-autopilot.yml

Invalid workflow file

You have an error in your yaml syntax on line 65
runs-on: arc-happyvertical
timeout-minutes: 5
outputs:
ready: ${{ steps.check.outputs.ready }}
missing: ${{ steps.check.outputs.missing }}
steps:
- name: Check Definition of Ready
id: check
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
echo "Checking Definition of Ready for issue #${{ inputs.issue_number }}..."
ISSUE=$(gh issue view ${{ inputs.issue_number }} --json labels,body,title,state)
STATE=$(echo "$ISSUE" | jq -r '.state')
if [ "$STATE" != "OPEN" ]; then
echo "ready=false" >> $GITHUB_OUTPUT
echo "missing=Issue is closed" >> $GITHUB_OUTPUT
exit 0
fi
LABELS=$(echo "$ISSUE" | jq -r '.labels[].name' 2>/dev/null || echo "")
HAS_TYPE=$(echo "$LABELS" | grep -c "^type:" || true)
HAS_PRIORITY=$(echo "$LABELS" | grep -c "^priority:" || true)
HAS_SIZE=$(echo "$LABELS" | grep -c "^size:" || true)
BODY_LENGTH=$(echo "$ISSUE" | jq '.body | length // 0')
MISSING=""
if [ "$HAS_TYPE" -eq 0 ]; then
MISSING="${MISSING}type label, "
fi
if [ "$HAS_PRIORITY" -eq 0 ]; then
MISSING="${MISSING}priority label, "
fi
if [ "$HAS_SIZE" -eq 0 ]; then
MISSING="${MISSING}size label, "
fi
if [ "$BODY_LENGTH" -lt 50 ]; then
MISSING="${MISSING}detailed description, "
fi
if [ -n "$MISSING" ]; then
echo "ready=false" >> $GITHUB_OUTPUT
echo "missing=${MISSING%, }" >> $GITHUB_OUTPUT
else
echo "ready=true" >> $GITHUB_OUTPUT
echo "missing=" >> $GITHUB_OUTPUT
fi
# PREPARE: If not ready, Claude will prepare the issue
prepare:
needs: check-readiness
if: needs.check-readiness.outputs.ready == 'false' && needs.check-readiness.outputs.missing != 'Issue is closed'
runs-on: arc-happyvertical
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Post Preparation Comment
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
gh issue comment ${{ inputs.issue_number }} --body "## Preparing Issue for Implementation
This issue needs some preparation before I can implement it.
**Missing**: ${{ needs.check-readiness.outputs.missing }}
I'll analyze the issue and:
- Add appropriate labels (type, priority, size)
- Clarify requirements if needed
- Create an implementation plan
---
*Automated preparation by Claude*"
- name: Run Claude Preparation
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
timeout_minutes: 12
prompt: |
REPO: ${{ github.repository }}
ISSUE_NUMBER: ${{ inputs.issue_number }}
MISSING: ${{ needs.check-readiness.outputs.missing }}
This issue has the `agent: claude` label but is not ready for implementation.
Your job is to PREPARE it so it can be implemented.
## Step 1: Read and Understand
```bash
gh issue view ${{ inputs.issue_number }}
```
Read the issue thoroughly. Also read CLAUDE.md for repository context.
## Step 2: Add Missing Labels
Based on the issue content, apply appropriate labels:
**Type** (choose one):
- `type: bug` - Something broken
- `type: feature` - New functionality
- `type: docs` - Documentation
- `type: maintenance` - Refactoring, cleanup
- `type: research` - Investigation needed
**Priority** (choose one):
- `priority: critical` - Urgent, blocking
- `priority: high` - Important
- `priority: medium` - Normal (default)
- `priority: low` - Nice to have
**Size** (choose one based on complexity):
- `size: xs` - < 2 hours, trivial
- `size: s` - 2-4 hours, small
- `size: m` - ~1 day, moderate
- `size: l` - 2-3 days, significant
- `size: xl` - > 3 days, large
Apply labels:
```bash
gh issue edit ${{ inputs.issue_number }} --add-label "type: X,priority: Y,size: Z"
```
## Step 3: Clarify and Plan
If the issue description is vague or missing details, post a comment with:
1. Your understanding of what needs to be done
2. Any clarifying questions
3. A brief implementation plan
## Step 4: Completion
Post a summary comment:
```
## Issue Prepared
**Labels Applied**: [list labels]
**Implementation Plan**: [brief plan]
This issue is now ready for implementation. The `agent: claude` label will trigger
the implementation phase automatically.
If you'd like me to proceed with implementation now, just comment "@claude implement this".
Otherwise, I'll wait for manual review.
```
DO NOT start implementation yet - just prepare the issue.
allowed_tools: |
Bash(gh issue:*),Bash(gh search:*),Read,Grep,Glob
- name: Update Project Board to Planning
if: inputs.project_id != '' && inputs.status_planning_id != ''
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
ISSUE_NODE_ID=$(gh api graphql -f query='
query($owner: String!, $repo: String!, $number: Int!) {
repository(owner: $owner, name: $repo) {
issue(number: $number) {
id
projectItems(first: 10) {
nodes {
id
project { id }
}
}
}
}
}
' -f owner="${{ github.repository_owner }}" -f repo="${{ github.event.repository.name }}" -F number=${{ inputs.issue_number }} --jq '.data.repository.issue')
ITEM_ID=$(echo "$ISSUE_NODE_ID" | jq -r ".projectItems.nodes[] | select(.project.id == \"${{ inputs.project_id }}\") | .id" 2>/dev/null || echo "")
if [ -n "$ITEM_ID" ]; then
gh api graphql -f query='
mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) {
updateProjectV2ItemFieldValue(input: {
projectId: $projectId
itemId: $itemId
fieldId: $fieldId
value: { singleSelectOptionId: $optionId }
}) {
projectV2Item { id }
}
}
' -f projectId="${{ inputs.project_id }}" -f itemId="$ITEM_ID" -f fieldId="${{ inputs.status_field_id }}" -f optionId="${{ inputs.status_planning_id }}" || true
fi
# IMPLEMENT: If ready, Claude implements the issue
implement:
needs: check-readiness
if: needs.check-readiness.outputs.ready == 'true'
runs-on: arc-happyvertical
timeout-minutes: 60
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GH_TOKEN }}
- name: Configure Git
run: |
git config user.name "claude[bot]"
git config user.email "claude[bot]@users.noreply.github.com"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '24'
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Install dependencies
run: |
if [ -f "pnpm-lock.yaml" ]; then
pnpm install --frozen-lockfile
elif [ -f "package-lock.json" ]; then
npm ci
elif [ -f "package.json" ]; then
pnpm install || npm install
fi
continue-on-error: true
- name: Post Start Comment
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
gh issue comment ${{ inputs.issue_number }} --body "## Implementation Started
This issue is ready and I'm beginning implementation.
**Status**: In Progress
**Started**: $(date -u +"%Y-%m-%dT%H:%M:%SZ")
I'll post updates as I progress.
---
*Automated implementation by Claude*"
- name: Update Project Board to In Progress
if: inputs.project_id != '' && inputs.status_in_progress_id != ''
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
ISSUE_NODE_ID=$(gh api graphql -f query='
query($owner: String!, $repo: String!, $number: Int!) {
repository(owner: $owner, name: $repo) {
issue(number: $number) {
id
projectItems(first: 10) {
nodes {
id
project { id }
}
}
}
}
}
' -f owner="${{ github.repository_owner }}" -f repo="${{ github.event.repository.name }}" -F number=${{ inputs.issue_number }} --jq '.data.repository.issue')
ITEM_ID=$(echo "$ISSUE_NODE_ID" | jq -r ".projectItems.nodes[] | select(.project.id == \"${{ inputs.project_id }}\") | .id" 2>/dev/null || echo "")
if [ -n "$ITEM_ID" ]; then
gh api graphql -f query='
mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) {
updateProjectV2ItemFieldValue(input: {
projectId: $projectId
itemId: $itemId
fieldId: $fieldId
value: { singleSelectOptionId: $optionId }
}) {
projectV2Item { id }
}
}
' -f projectId="${{ inputs.project_id }}" -f itemId="$ITEM_ID" -f fieldId="${{ inputs.status_field_id }}" -f optionId="${{ inputs.status_in_progress_id }}" || true
fi
- name: Run Claude Implementation
id: implement
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
timeout_minutes: 55
track_progress: true
prompt: |
REPO: ${{ github.repository }}
ISSUE_NUMBER: ${{ inputs.issue_number }}
You are implementing issue #${{ inputs.issue_number }} autonomously.
## Workflow
1. **Read the issue**: `gh issue view ${{ inputs.issue_number }}`
2. **Read CLAUDE.md** for repository guidelines
3. **Create branch**: `git checkout -b feat/issue-${{ inputs.issue_number }}-[description]`
4. **Implement** following existing patterns
5. **Write/update tests**
6. **Quality checks**: `pnpm typecheck && pnpm lint && pnpm test && pnpm build`
7. **Commit**: `git commit -m "feat(scope): description\n\nCloses #${{ inputs.issue_number }}"`
8. **Push**: `git push -u origin [branch]`
9. **Create PR**: `gh pr create --title "..." --body "..."`
10. **Post completion** comment on the issue
If blocked, post a comment explaining why.
allowed_tools: |
Bash(git:*),Bash(gh pr:*),Bash(gh issue:*),Bash(pnpm:*),Bash(npm:*),Bash(npx:*),Bash(node:*),Bash(bun:*),Read,Write,Edit,Glob,Grep,Bash(ls:*),Bash(cat:*),Bash(mkdir:*),Bash(cp:*),Bash(mv:*),Bash(rm:*)
- name: Post Failure Comment
if: failure()
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
gh issue comment ${{ inputs.issue_number }} --body "## Implementation Failed
I encountered an error while implementing this issue.
[View workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
The \`agent: claude\` label remains - remove it if you want to stop automated attempts.
---
*Automated implementation by Claude*"