Skip to content

Fix: Make generate-implementation independent of preprocess to avoid … #29

Fix: Make generate-implementation independent of preprocess to avoid …

Fix: Make generate-implementation independent of preprocess to avoid … #29

name: Enhance Feature Requests
on:
issues:
types: [opened, labeled]
workflow_dispatch:
# Prevent parallel runs for the same issue
concurrency:
group: enhance-feature-request-${{ github.event.issue.number || inputs.issue_number }}
cancel-in-progress: false
inputs:

Check failure on line 12 in .github/workflows/feature-request-enhance.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/feature-request-enhance.yml

Invalid workflow file

You have an error in your yaml syntax on line 12
issue_number:
description: 'Issue number to process'
required: true
type: string
permissions:
issues: write
contents: write
pull-requests: write
jobs:
check-label:
runs-on: ubuntu-latest
outputs:
has_enhancement: ${{ steps.check.outputs.has_enhancement }}
already_enhanced: ${{ steps.check.outputs.already_enhanced }}
issue_number: ${{ steps.set_issue.outputs.issue_number }}
steps:
- name: Set issue number
id: set_issue
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "issue_number=${{ inputs.issue_number }}" >> "$GITHUB_OUTPUT"
else
echo "issue_number=${{ github.event.issue.number }}" >> "$GITHUB_OUTPUT"
fi
- name: Fetch and check issue
id: check
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ steps.set_issue.outputs.issue_number }}
run: |
set -e
# Fetch issue data
ISSUE_JSON=$(curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${{ github.repository }}/issues/$ISSUE_NUMBER")
# Write to temp file for safe parsing
echo "$ISSUE_JSON" > /tmp/issue.json
# Extract labels
LABELS=$(jq -r '.labels[].name' /tmp/issue.json)
# Check for enhancement label (word boundary, not exact line)
if echo "$LABELS" | grep -qw "enhancement"; then
echo "✅ Issue has enhancement label"
echo "has_enhancement=true" >> "$GITHUB_OUTPUT"
else
echo "❌ No enhancement label found"
echo "has_enhancement=false" >> "$GITHUB_OUTPUT"
fi
# Check if already enhanced
BODY=$(jq -r '.body // ""' /tmp/issue.json)
if echo "$BODY" | grep -qF "## 📝 Enhanced Feature Request"; then
echo "⚠️ Issue already enhanced - skipping"
echo "already_enhanced=true" >> "$GITHUB_OUTPUT"
else
echo "✅ Issue not yet enhanced"
echo "already_enhanced=false" >> "$GITHUB_OUTPUT"
fi
preprocess:
runs-on: ubuntu-latest
needs: check-label
if: needs.check-label.outputs.has_enhancement == 'true' && needs.check-label.outputs.already_enhanced == 'false'
outputs:
enhanced_task: ${{ steps.preprocess.outputs.enhanced_task }}
issue_title: ${{ steps.fetch.outputs.issue_title }}
issue_user: ${{ steps.fetch.outputs.issue_user }}
issue_body: ${{ steps.fetch.outputs.issue_body }}
issue_created: ${{ steps.fetch.outputs.issue_created }}
steps:
- uses: actions/checkout@v4
with:
ref: develop
- uses: actions/setup-node@v4
with:
node-version: '20.20.0'
cache: npm
- name: Install dependencies
working-directory: .github/agent
run: npm install
- name: Fetch full issue data
id: fetch
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ needs.check-label.outputs.issue_number }}
run: |
ISSUE_JSON=$(curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${{ github.repository }}/issues/$ISSUE_NUMBER")
TITLE=$(echo "$ISSUE_JSON" | jq -r '.title')
USER=$(echo "$ISSUE_JSON" | jq -r '.user.login')
BODY=$(echo "$ISSUE_JSON" | jq -r '.body // ""')
CREATED=$(echo "$ISSUE_JSON" | jq -r '.created_at')
echo "issue_title=$TITLE" >> "$GITHUB_OUTPUT"
echo "issue_user=$USER" >> "$GITHUB_OUTPUT"
echo "issue_created=$CREATED" >> "$GITHUB_OUTPUT"
{
echo "issue_body<<EOF"
echo "$BODY"
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Preprocess issue
id: preprocess
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
PREPROCESSING_MODEL: ${{ secrets.PREPROCESSING_MODEL }}
TASK: ${{ steps.fetch.outputs.issue_title }}
REQUESTER: ${{ steps.fetch.outputs.issue_user }}
GITHUB_RUN_ID: ${{ github.run_id }}
run: |
set -e
OUTPUT=$(node .github/agent/preprocess-task.mjs 2>&1)
echo "$OUTPUT"
if echo "$OUTPUT" | grep -q "ENHANCED_TASK_START"; then
ENHANCED=$(echo "$OUTPUT" | sed -n '/ENHANCED_TASK_START/,/ENHANCED_TASK_END/p' | sed '1d;$d')
else
ENHANCED="$TASK"
fi
{
echo "enhanced_task<<EOF"
echo "$ENHANCED"
echo "EOF"
} >> "$GITHUB_OUTPUT"
create-confluence:
runs-on: ubuntu-latest
needs: [check-label, preprocess]
outputs:
confluence_url: ${{ steps.confluence.outputs.confluence_url }}
steps:
- uses: actions/checkout@v4
with:
ref: develop
- uses: actions/setup-node@v4
with:
node-version: '20.20.0'
cache: npm
- name: Install dependencies
working-directory: .github/agent
run: npm install
- name: Create Confluence page
id: confluence
env:
TASK: ${{ needs.preprocess.outputs.issue_title }}
REQUESTER: ${{ needs.preprocess.outputs.issue_user }}
ISSUE_NUMBER: ${{ needs.check-label.outputs.issue_number }}
CONFLUENCE_URL: ${{ secrets.CONFLUENCE_URL }}
CONFLUENCE_EMAIL: ${{ secrets.CONFLUENCE_EMAIL }}
CONFLUENCE_API_TOKEN: ${{ secrets.CONFLUENCE_API_TOKEN }}
CONFLUENCE_SPACE_KEY: ${{ secrets.CONFLUENCE_SPACE_KEY }}
CONFLUENCE_PARENT_PAGE_ID: ${{ secrets.CONFLUENCE_PARENT_PAGE_ID }}
ENHANCED_TASK: ${{ needs.preprocess.outputs.enhanced_task }}
run: |
set -e
OUTPUT=$(node .github/agent/create-confluence.mjs 2>&1)
echo "$OUTPUT"
URL=$(echo "$OUTPUT" | grep "CONFLUENCE_URL:" | sed 's/CONFLUENCE_URL://' | tr -d '[:space:]')
echo "confluence_url=$URL" >> "$GITHUB_OUTPUT"
update-issue:
runs-on: ubuntu-latest
needs: [check-label, preprocess, create-confluence]
steps:
- name: Update issue body
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ needs.check-label.outputs.issue_number }}
run: |
set -euo pipefail
# Use jq to safely build JSON with proper escaping
jq -n \
--arg enhanced "${{ needs.preprocess.outputs.enhanced_task }}" \
--arg confluence "${{ needs.create-confluence.outputs.confluence_url }}" \
--arg original "${{ needs.preprocess.outputs.issue_body }}" \
--arg requester "${{ needs.preprocess.outputs.issue_user }}" \
--arg created "${{ needs.preprocess.outputs.issue_created }}" \
'{
body: (
"## 📝 Enhanced Feature Request\n\n" +
$enhanced +
"\n\n---\n\n" +
"📄 **Requirements documented:** " +
(if $confluence != "" then $confluence else "_Not available_" end) +
"\n\n---\n\n" +
"## 📋 Original Request\n\n" +
$original +
"\n\n---\n\n" +
"**Requested by:** " + $requester + "\n" +
"**Created:** " + $created
)
}' \
| curl -X PATCH \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
-H "Content-Type: application/json" \
-d @- \
"https://api.github.com/repos/${{ github.repository }}/issues/$ISSUE_NUMBER"
echo "✅ Issue updated with enhanced + original content"
add-comment:
runs-on: ubuntu-latest
needs: [check-label, update-issue]
steps:
- name: Comment
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ needs.check-label.outputs.issue_number }}
run: |
COMMENT="🤖 **Feature request enhanced!**
Issue description and requirements are now structured and documented."
jq -n --arg body "$COMMENT" '{body:$body}' \
| curl -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
-H "Content-Type: application/json" \
-d @- \
"https://api.github.com/repos/${{ github.repository }}/issues/$ISSUE_NUMBER/comments"
generate-implementation:
runs-on: ubuntu-latest
needs: [check-label]
# Run if issue has enhancement label and isn't already enhanced
# Don't depend on preprocess to avoid skipping if preprocess fails/is skipped
if: |
needs.check-label.outputs.has_enhancement == 'true' &&
needs.check-label.outputs.already_enhanced == 'false'
permissions:
contents: write
pull-requests: write
issues: write
steps:
- name: Checkout develop
uses: actions/checkout@v4
with:
ref: develop
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20.20.0'
cache: npm
- name: Install agent dependencies
working-directory: .github/agent
run: npm install
- name: Fetch issue data
id: fetch-issue
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ needs.check-label.outputs.issue_number }}
run: |
ISSUE_JSON=$(curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${{ github.repository }}/issues/$ISSUE_NUMBER")
TITLE=$(echo "$ISSUE_JSON" | jq -r '.title')
BODY=$(echo "$ISSUE_JSON" | jq -r '.body // ""')
{
echo "issue_title<<EOF"
echo "$TITLE"
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Generate implementation with Claude
id: generate
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
CLAUDE_MODEL: ${{ secrets.CLAUDE_MODEL }}
ENHANCED_TASK: ${{ steps.fetch-issue.outputs.issue_title }}
TASK: ${{ steps.fetch-issue.outputs.issue_title }}
ISSUE_NUMBER: ${{ needs.check-label.outputs.issue_number }}
run: |
set -e
OUTPUT=$(node .github/agent/generate-implementation.mjs 2>&1)
echo "$OUTPUT"
# Extract implementation file path
IMPL_FILE=$(echo "$OUTPUT" | grep "IMPLEMENTATION_FILE:" | sed 's/IMPLEMENTATION_FILE://' | tr -d '[:space:]')
echo "implementation_file=$IMPL_FILE" >> $GITHUB_OUTPUT
- name: Create implementation branch and PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ needs.check-label.outputs.issue_number }}
IMPL_FILE: ${{ steps.generate.outputs.implementation_file }}
run: |
set -e
# Configure git
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Create feature branch
BRANCH_NAME="feature/issue-$ISSUE_NUMBER-implementation"
git checkout -b "$BRANCH_NAME"
# Add the implementation file
if [ -f "$IMPL_FILE" ]; then
git add "$IMPL_FILE"
# Create commit with heredoc to handle multiline
git commit -m "$(cat <<EOF
Add implementation plan for issue #$ISSUE_NUMBER
This is an AI-generated implementation plan created by Claude.
Please review and adapt as needed.
Related issue: #$ISSUE_NUMBER
EOF
)"
# Push branch
git push -u origin "$BRANCH_NAME"
# Create PR body using heredoc
PR_BODY=$(cat <<'EOF'
## 🤖 AI-Generated Implementation Plan
This PR contains an implementation plan generated by Claude AI for issue #$ISSUE_NUMBER.
### 📋 Implementation Plan
See [implementation-$ISSUE_NUMBER.md](./implementation-$ISSUE_NUMBER.md) for details.
### ⚠️ Important
This is an **AI-generated proposal**. Please:
- Review the implementation plan carefully
- Adapt and modify as needed
- Add actual code changes based on the plan
- Test thoroughly before merging
Closes #$ISSUE_NUMBER
EOF
)
# Substitute environment variables in PR body
PR_BODY=$(echo "$PR_BODY" | sed "s/\$ISSUE_NUMBER/$ISSUE_NUMBER/g")
# Create PR
gh pr create \
--title "feat: Implementation plan for issue #$ISSUE_NUMBER" \
--body "$PR_BODY" \
--base develop \
--head "$BRANCH_NAME" \
--label "ai-generated,enhancement"
echo "✅ Created PR for branch $BRANCH_NAME"
else
echo "❌ Implementation file not found: $IMPL_FILE"
exit 1
fi
- name: Comment on issue with PR link
if: success()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ needs.check-label.outputs.issue_number }}
run: |
COMMENT="🚀 **Implementation PR Created!**
An AI-generated implementation plan has been created. Check the pull request for details.
Note: This is a starting point - please review and adapt the implementation as needed."
jq -n --arg body "$COMMENT" '{body:$body}' \
| curl -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
-H "Content-Type: application/json" \
-d @- \
"https://api.github.com/repos/${{ github.repository }}/issues/$ISSUE_NUMBER/comments"