refactor: Extract command handlers and improve test coverage #23
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Enhance Feature Requests | ||
| on: | ||
| issues: | ||
| types: [opened, labeled] | ||
| workflow_dispatch: | ||
| inputs: | ||
| issue_number: | ||
| description: 'Issue number to process' | ||
| required: true | ||
| type: string | ||
| permissions: | ||
| issues: write | ||
| contents: read | ||
| 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 | ||
| 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 | ||
| 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 @- \ | ||
| <<<<<<< HEAD | ||
| "https://api.github.com/repos/${{ github.repository }}/issues/$ISSUE_NUMBER/comments" | ||
| ======= | ||
| "https://api.github.com/repos/${{ github.repository }}/issues/$ISSUE_NUMBER/comments" | ||
| >>>>>>> origin/master | ||