55 types : [created]
66
77jobs :
8- # ============================================================================
9- # COMMENT VALIDATION JOB
10- # ============================================================================
11- # Validates that the comment:
12- # 1. Was NOT posted by the bot itself (prevents infinite loops)
13- # 2. Contains trigger words in actual content (not in quotes or code blocks)
14- # ============================================================================
15- validate- comment:
8+ continuous-reply :
9+ # Skip if comment author is a bot (workflow will show as "skipped")
10+ if : |
11+ github.event. comment.user.login != 'mirrobot' &&
12+ github.event.comment.user.login != 'mirrobot-agent' &&
13+ github.event.comment.user.login != 'mirrobot-agent[bot]' &&
14+ (contains(github.event.comment.body, '@mirrobot') ||
15+ contains(github.event. comment.body, '@mirrobot-agent'))
1616 runs-on : ubuntu-latest
17- outputs :
18- should_proceed : ${{ steps.validate.outputs.should_proceed }}
17+ permissions :
18+ contents : write
19+ issues : write
20+ pull-requests : write
21+
1922 env :
23+ THREAD_NUMBER : ${{ github.event.issue.number }}
2024 BOT_NAMES_JSON : ' ["mirrobot", "mirrobot-agent", "mirrobot-agent[bot]"]'
25+ IGNORE_BOT_NAMES_JSON : ' ["ellipsis-dev"]'
26+ COMMENT_FETCH_LIMIT : ' 20'
27+ REVIEW_FETCH_LIMIT : ' 15'
28+ REVIEW_THREAD_FETCH_LIMIT : ' 20'
29+ THREAD_COMMENT_FETCH_LIMIT : ' 5'
30+
2131 steps :
32+ # ========================================================================
33+ # COMMENT VALIDATION STEP
34+ # ========================================================================
35+ # Validates that trigger words are in actual content (not in quotes/code)
36+ # If validation fails, all subsequent steps are skipped
37+ # ========================================================================
2238 - name : Validate comment trigger
2339 id : validate
2440 env :
2541 COMMENT_BODY : ${{ github.event.comment.body }}
26- COMMENT_AUTHOR : ${{ github.event.comment.user.login }}
2742 run : |
2843 set -e
2944
30- echo "Validating comment from: $COMMENT_AUTHOR"
31-
32- # 1. Check if author is a bot
33- BOT_NAMES=("mirrobot" "mirrobot-agent" "mirrobot-agent[bot]")
34- for bot in "${BOT_NAMES[@]}"; do
35- if [[ "$COMMENT_AUTHOR" == "$bot" ]]; then
36- echo "::notice::Comment author is bot ($COMMENT_AUTHOR). Skipping to prevent loops."
37- echo "should_proceed=false" >> $GITHUB_OUTPUT
38- exit 0
39- fi
40- done
41-
42- echo "Author check passed: $COMMENT_AUTHOR is not a bot"
43-
44- # 2. Strip code blocks and quotes from comment body
45- # First, save comment to a temp file for processing
45+ # Save comment to temp file for processing
4646 TEMP_FILE=$(mktemp)
4747 echo "$COMMENT_BODY" > "$TEMP_FILE"
4848
49- # Remove fenced code blocks (```...```) - handles multiline
49+ # Remove fenced code blocks (```...```)
5050 CLEAN_BODY=$(awk '
5151 /^```/ { in_code = !in_code; next }
5252 !in_code { print }
5555 # Remove inline code (`...`)
5656 CLEAN_BODY=$(echo "$CLEAN_BODY" | sed 's/`[^`]*`//g')
5757
58- # Remove quoted lines (lines starting with > at any level, with optional leading whitespace )
58+ # Remove quoted lines (lines starting with >)
5959 CLEAN_BODY=$(echo "$CLEAN_BODY" | grep -v '^[[:space:]]*>' || true)
6060
6161 rm -f "$TEMP_FILE"
@@ -64,40 +64,22 @@ jobs:
6464 echo "$CLEAN_BODY"
6565 echo "---"
6666
67- # 3. Check for trigger words in clean text
67+ # Check for trigger words in clean text
6868 # Trigger: @mirrobot or @mirrobot-agent
6969 if echo "$CLEAN_BODY" | grep -qE '@mirrobot(-agent)?'; then
7070 echo "::notice::Valid trigger found in non-quoted, non-code text."
7171 echo "should_proceed=true" >> $GITHUB_OUTPUT
7272 else
73- echo "::notice::Trigger only found in quotes/code blocks or not present . Skipping."
73+ echo "::notice::Trigger only found in quotes/code blocks. Skipping."
7474 echo "should_proceed=false" >> $GITHUB_OUTPUT
7575 fi
7676
77- continuous-reply :
78- needs : [validate-comment]
79- if : needs.validate-comment.outputs.should_proceed == 'true'
80- runs-on : ubuntu-latest
81- permissions :
82- contents : write
83- issues : write
84- pull-requests : write
85-
86- env :
87- THREAD_NUMBER : ${{ github.event.issue.number }}
88- BOT_NAMES_JSON : ' ["mirrobot", "mirrobot-agent", "mirrobot-agent[bot]"]'
89- IGNORE_BOT_NAMES_JSON : ' ["ellipsis-dev"]'
90- COMMENT_FETCH_LIMIT : ' 20'
91- REVIEW_FETCH_LIMIT : ' 15'
92- REVIEW_THREAD_FETCH_LIMIT : ' 20'
93- THREAD_COMMENT_FETCH_LIMIT : ' 5'
94-
95- steps :
96-
9777 - name : Checkout repository
78+ if : steps.validate.outputs.should_proceed == 'true'
9879 uses : actions/checkout@v4
9980
10081 - name : Bot Setup
82+ if : steps.validate.outputs.should_proceed == 'true'
10183 id : setup
10284 uses : ./.github/actions/bot-setup
10385 with :
10991 custom-providers-json : ${{ secrets.CUSTOM_PROVIDERS_JSON }}
11092
11193 - name : Add reaction to comment
94+ if : steps.validate.outputs.should_proceed == 'true'
11295 env :
11396 GH_TOKEN : ${{ steps.setup.outputs.token }}
11497 run : |
@@ -119,6 +102,7 @@ jobs:
119102 -f content='eyes'
120103
121104 - name : Gather Full Thread Context
105+ if : steps.validate.outputs.should_proceed == 'true'
122106 id : context
123107 env :
124108 GH_TOKEN : ${{ steps.setup.outputs.token }}
@@ -474,7 +458,7 @@ jobs:
474458 fi
475459
476460 - name : Clear pending bot review
477- if : steps.context.outputs.IS_PR == 'true'
461+ if : steps.validate.outputs.should_proceed == 'true' && steps. context.outputs.IS_PR == 'true'
478462 env :
479463 GH_TOKEN : ${{ steps.setup.outputs.token }}
480464 BOT_NAMES_JSON : ${{ env.BOT_NAMES_JSON }}
@@ -502,7 +486,7 @@ jobs:
502486 done <<< "$pending_review_ids"
503487
504488 - name : Determine Review Type and Last Reviewed SHA
505- if : steps.context.outputs.IS_PR == 'true'
489+ if : steps.validate.outputs.should_proceed == 'true' && steps. context.outputs.IS_PR == 'true'
506490 id : review_type
507491 env :
508492 GH_TOKEN : ${{ steps.setup.outputs.token }}
@@ -544,18 +528,19 @@ jobs:
544528 fi
545529
546530 - name : Save secure prompt from base branch
531+ if : steps.validate.outputs.should_proceed == 'true'
547532 run : cp .github/prompts/bot-reply.md /tmp/bot-reply.md
548533
549534 - name : Checkout PR head
550- if : steps.context.outputs.IS_PR == 'true'
535+ if : steps.validate.outputs.should_proceed == 'true' && steps. context.outputs.IS_PR == 'true'
551536 uses : actions/checkout@v4
552537 with :
553538 ref : ${{ env.PR_HEAD_SHA }}
554539 token : ${{ steps.setup.outputs.token }}
555540 fetch-depth : 0 # Full history needed for git operations and code analysis
556541
557542 - name : Generate PR Diffs (Full and Incremental)
558- if : steps.context.outputs.IS_PR == 'true'
543+ if : steps.validate.outputs.should_proceed == 'true' && steps. context.outputs.IS_PR == 'true'
559544 id : generate_diffs
560545 env :
561546 BASE_BRANCH : ${{ env.BASE_BRANCH }}
@@ -610,13 +595,14 @@ jobs:
610595 fi
611596
612597 - name : Checkout repository (for issues)
613- if : steps.context.outputs.IS_PR == 'false'
598+ if : steps.validate.outputs.should_proceed == 'true' && steps. context.outputs.IS_PR == 'false'
614599 uses : actions/checkout@v4
615600 with :
616601 token : ${{ steps.setup.outputs.token }}
617602 fetch-depth : 0 # Full history needed for git operations and code analysis
618603
619604 - name : Analyze comment and respond
605+ if : steps.validate.outputs.should_proceed == 'true'
620606 env :
621607 GITHUB_TOKEN : ${{ steps.setup.outputs.token }}
622608 THREAD_CONTEXT : ${{ env.THREAD_CONTEXT }}
0 commit comments