11name : Buddy Bot
22
33on :
4+ # Rebase checkbox: fires instantly when a PR body is edited (e.g. checkbox ticked).
5+ # No polling needed — this replaces the old every-minute cron for rebase detection.
6+ pull_request :
7+ types : [edited]
8+
49 schedule :
5- # Check for rebase requests every 20 minutes
6- - cron : ' */20 * * * *'
710 # Update dependencies every 2 hours
811 - cron : ' 0 */2 * * *'
912 # Update dashboard 15 minutes after dependency updates (ensures updates are reflected)
5861 type : boolean
5962
6063env :
61- # For workflow file updates, you need a Personal Access Token with 'repo' and 'workflow' scopes
62- # Create a PAT at: https://github.com/settings/tokens
63- # Add it as a repository secret named 'BUDDY_BOT_TOKEN'
64- # If BUDDY_BOT_TOKEN is not available, falls back to GITHUB_TOKEN (limited permissions)
64+ # Use the built-in GITHUB_TOKEN for commits and PRs — contributions are attributed
65+ # to github-actions[bot] instead of a personal account.
66+ # BUDDY_BOT_TOKEN (a PAT with 'repo' and 'workflow' scopes) is only used when
67+ # workflow file updates are needed. Create one at: https://github.com/settings/tokens
6568 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
6669 BUDDY_BOT_TOKEN : ${{ secrets.BUDDY_BOT_TOKEN }}
6770
@@ -73,10 +76,18 @@ permissions:
7376 checks : read
7477 statuses : read
7578
79+ # Serialize runs per ref so parallel scheduled + manual triggers don't race
80+ # on the same branches/PRs. cancel-in-progress: false lets the currently
81+ # running job finish cleanly instead of being killed mid-commit.
82+ concurrency :
83+ group : buddy-bot-${{ github.ref }}
84+ cancel-in-progress : false
85+
7686jobs :
7787 # Job to determine which jobs should run based on trigger
7888 determine-jobs :
7989 runs-on : ubuntu-latest
90+ timeout-minutes : 5
8091 outputs :
8192 run_check : ${{ steps.determine.outputs.run_check }}
8293 run_update : ${{ steps.determine.outputs.run_update }}
@@ -90,7 +101,23 @@ jobs:
90101 echo "run_update=false" >> $GITHUB_OUTPUT
91102 echo "run_dashboard=false" >> $GITHUB_OUTPUT
92103
93- if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
104+ if [ "${{ github.event_name }}" = "pull_request" ]; then
105+ # PR body was edited — check if it's a buddy-bot PR with rebase checkbox
106+ # Only run the check job (lightweight: just scans for the checkbox and rebases)
107+ ACTOR="${{ github.actor }}"
108+ BRANCH="${{ github.event.pull_request.head.ref }}"
109+
110+ # Skip if the edit was made by a bot (prevents cascade loops where
111+ # buddy-bot updates a PR body → fires edited event → re-triggers workflow)
112+ if [[ "$ACTOR" == *"[bot]"* ]] || [[ "$ACTOR" == "github-actions[bot]" ]] || [[ "$ACTOR" == "buddy-bot" ]]; then
113+ echo "ℹ️ Skipping — PR edit was made by bot actor: $ACTOR"
114+ elif [[ "$BRANCH" == buddy-bot/* ]]; then
115+ echo "run_check=true" >> $GITHUB_OUTPUT
116+ echo "ℹ️ buddy-bot PR edited by user — running rebase check for branch: $BRANCH"
117+ else
118+ echo "ℹ️ Non-buddy-bot PR edited — skipping (branch: $BRANCH)"
119+ fi
120+ elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
94121 JOB="${{ github.event.inputs.job || 'all' }}"
95122 if [ "$JOB" = "all" ] || [ "$JOB" = "check" ]; then
96123 echo "run_check=true" >> $GITHUB_OUTPUT
@@ -103,9 +130,7 @@ jobs:
103130 fi
104131 elif [ "${{ github.event_name }}" = "schedule" ]; then
105132 # Determine based on cron schedule
106- if [ "${{ github.event.schedule }}" = "5,25,45 * * * *" ]; then
107- echo "run_check=true" >> $GITHUB_OUTPUT
108- elif [ "${{ github.event.schedule }}" = "0 */2 * * *" ]; then
133+ if [ "${{ github.event.schedule }}" = "0 */2 * * *" ]; then
109134 echo "run_update=true" >> $GITHUB_OUTPUT
110135 elif [ "${{ github.event.schedule }}" = "15 */2 * * *" ]; then
111136 echo "run_dashboard=true" >> $GITHUB_OUTPUT
@@ -115,22 +140,23 @@ jobs:
115140 # Shared setup job for common dependencies
116141 setup :
117142 runs-on : ubuntu-latest
143+ timeout-minutes : 10
118144 needs : determine-jobs
119145 if : ${{ needs.determine-jobs.outputs.run_check == 'true' || needs.determine-jobs.outputs.run_update == 'true' || needs.determine-jobs.outputs.run_dashboard == 'true' }}
120146 steps :
121147 - name : Checkout repository
122- uses : actions/checkout@v6.0.2
148+ uses : actions/checkout@v4
123149 with :
124- token : ${{ secrets.BUDDY_BOT_TOKEN || secrets. GITHUB_TOKEN }}
150+ token : ${{ secrets.GITHUB_TOKEN }}
125151 fetch-depth : 0 # Fetch full history for rebasing
126152 persist-credentials : true
127153
128154 - name : Setup Bun
129- uses : oven-sh/setup-bun@v2.1.3
155+ uses : oven-sh/setup-bun@v2
130156
131157 - name : Setup PHP and Composer (if needed)
132158 if : ${{ hashFiles('composer.json') != '' }}
133- uses : shivammathur/setup-php@2.37.0
159+ uses : shivammathur/setup-php@v2
134160 with :
135161 php-version : ' 8.4'
136162 tools : composer
@@ -151,26 +177,24 @@ jobs:
151177 # Check job (handles both rebase requests and auto-closing PRs)
152178 check :
153179 runs-on : ubuntu-latest
180+ timeout-minutes : 30
154181 needs : [determine-jobs, setup]
155182 if : ${{ needs.determine-jobs.outputs.run_check == 'true' }}
156183
157184 steps :
158185 - name : Checkout repository
159- uses : actions/checkout@v6.0.2
186+ uses : actions/checkout@v4
160187 with :
161- token : ${{ secrets.BUDDY_BOT_TOKEN || secrets. GITHUB_TOKEN }}
188+ token : ${{ secrets.GITHUB_TOKEN }}
162189 fetch-depth : 0
163190 persist-credentials : true
164191
165192 - name : Setup Bun
166- uses : oven-sh/setup-bun@v2.1.3
193+ uses : oven-sh/setup-bun@v2
167194
168195 - name : Install dependencies
169196 run : bun install
170197
171- - name : Build local buddy-bot
172- run : bun run build
173-
174198 - name : Configure Git
175199 run : |
176200 git config --global user.name "github-actions[bot]"
@@ -190,16 +214,10 @@ jobs:
190214
191215 - name : Check for PRs that need attention
192216 run : |
193- echo "🔍 Checking for PRs that need attention..."
194- echo " - Rebase requests (checked checkbox)"
195- echo " - Satisfied dependencies (already at target version)"
196- echo " - Obsolete PRs (removed files)"
197- echo " - Stale branches cleanup"
198- echo ""
217+ echo "🔍 Checking for PRs that need attention (rebase requests or auto-closing)..."
199218 echo "🔧 Environment info:"
200219 echo "Current directory: $(pwd)"
201220 echo "GITHUB_TOKEN set: $([[ -n "$GITHUB_TOKEN" ]] && echo "Yes" || echo "No")"
202- echo "BUDDY_BOT_TOKEN set: $([[ -n "$BUDDY_BOT_TOKEN" ]] && echo "Yes" || echo "No")"
203221 echo "Repository: ${{ github.repository }}"
204222 echo "Event: ${{ github.event_name }}"
205223 echo ""
@@ -209,12 +227,16 @@ jobs:
209227
210228 if [ "${{ github.event.inputs.dry_run }}" = "true" ]; then
211229 echo "📋 Running in DRY RUN mode..."
212- bun run dist/bin/cli.js update-check --dry-run --verbose
230+ bunx buddy-bot update-check --dry-run --verbose
213231 else
214232 echo "🔄 Running in LIVE mode..."
215- bun run dist/bin/cli.js update-check --verbose
233+ bunx buddy-bot update-check --verbose
216234 fi
217235
236+ env :
237+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
238+ BUDDY_BOT_TOKEN : ${{ secrets.BUDDY_BOT_TOKEN }}
239+
218240 - name : Create check summary
219241 if : always()
220242 run : |
@@ -226,40 +248,35 @@ jobs:
226248 echo "" >> $GITHUB_STEP_SUMMARY
227249
228250 if [ "${{ github.event_name }}" = "schedule" ]; then
229- echo "⏰ **Scheduled Check**: Automatically checks every 20 minutes " >> $GITHUB_STEP_SUMMARY
251+ echo "⏰ **Scheduled Check**: Automatically checks every minute " >> $GITHUB_STEP_SUMMARY
230252 else
231253 echo "🖱️ **Manual Check**: Manually triggered from Actions tab" >> $GITHUB_STEP_SUMMARY
232254 fi
233255
234256 echo "" >> $GITHUB_STEP_SUMMARY
235- echo "📋 **What was checked:**" >> $GITHUB_STEP_SUMMARY
236- echo "- ✅ Rebase requests (PRs with checked rebase checkbox)" >> $GITHUB_STEP_SUMMARY
237- echo "- ✅ Satisfied dependencies (PRs where versions are already installed)" >> $GITHUB_STEP_SUMMARY
238- echo "- ✅ Obsolete PRs (references to removed dependency files)" >> $GITHUB_STEP_SUMMARY
239- echo "- ✅ Stale branches cleanup (orphaned branches older than 7 days)" >> $GITHUB_STEP_SUMMARY
240- echo "" >> $GITHUB_STEP_SUMMARY
241- echo "📋 View detailed logs above for check results." >> $GITHUB_STEP_SUMMARY
257+ echo "📋 View detailed logs above for check results (rebase requests, auto-closing, and branch cleanup)." >> $GITHUB_STEP_SUMMARY
242258
243259 # Dependency update job
244260 dependency-update :
245261 runs-on : ubuntu-latest
262+ timeout-minutes : 30
246263 needs : [determine-jobs, setup]
247264 if : ${{ needs.determine-jobs.outputs.run_update == 'true' }}
248265
249266 steps :
250267 - name : Checkout repository
251- uses : actions/checkout@v6.0.2
268+ uses : actions/checkout@v4
252269 with :
253- token : ${{ secrets.BUDDY_BOT_TOKEN || secrets. GITHUB_TOKEN }}
270+ token : ${{ secrets.GITHUB_TOKEN }}
254271 fetch-depth : 0
255272 persist-credentials : true
256273
257274 - name : Setup Bun
258- uses : oven-sh/setup-bun@v2.1.3
275+ uses : oven-sh/setup-bun@v2
259276
260277 - name : Setup PHP and Composer (if needed)
261278 if : ${{ hashFiles('composer.json') != '' }}
262- uses : shivammathur/setup-php@2.37.0
279+ uses : shivammathur/setup-php@v2
263280 with :
264281 php-version : ' 8.4'
265282 tools : composer
@@ -272,9 +289,6 @@ jobs:
272289 - name : Install dependencies
273290 run : bun install
274291
275- - name : Build local buddy-bot
276- run : bun run build
277-
278292 - name : Configure Git
279293 run : |
280294 git config --global user.name "github-actions[bot]"
@@ -306,20 +320,20 @@ jobs:
306320
307321 if [ "$PACKAGES" != "" ]; then
308322 if [ "$VERBOSE" = "true" ]; then
309- bun run dist/bin/cli.js update --packages "$PACKAGES" --verbose
323+ bunx buddy-bot update --packages "$PACKAGES" --verbose
310324 else
311- bun run dist/bin/cli.js update --packages "$PACKAGES"
325+ bunx buddy-bot update --packages "$PACKAGES"
312326 fi
313327 else
314328 if [ "$VERBOSE" = "true" ]; then
315- bun run dist/bin/cli.js update --strategy "$STRATEGY" --verbose
329+ bunx buddy-bot update --strategy "$STRATEGY" --verbose
316330 else
317- bun run dist/bin/cli.js update --strategy "$STRATEGY"
331+ bunx buddy-bot update --strategy "$STRATEGY"
318332 fi
319333 fi
320334
321335 env :
322- GITHUB_TOKEN : ${{ secrets.BUDDY_BOT_TOKEN || secrets. GITHUB_TOKEN }}
336+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
323337 BUDDY_BOT_TOKEN : ${{ secrets.BUDDY_BOT_TOKEN }}
324338
325339 - name : Dry run notification
@@ -355,17 +369,18 @@ jobs:
355369 # Dashboard update job
356370 dashboard-update :
357371 runs-on : ubuntu-latest
372+ timeout-minutes : 15
358373 needs : [determine-jobs, setup, dependency-update]
359374 if : ${{ needs.determine-jobs.outputs.run_dashboard == 'true' && always() }}
360375
361376 steps :
362377 - name : Checkout repository
363- uses : actions/checkout@v6.0.2
378+ uses : actions/checkout@v4
364379 with :
365- token : ${{ secrets.BUDDY_BOT_TOKEN || secrets. GITHUB_TOKEN }}
380+ token : ${{ secrets.GITHUB_TOKEN }}
366381
367382 - name : Setup Bun
368- uses : oven-sh/setup-bun@v2.1.3
383+ uses : oven-sh/setup-bun@v2
369384
370385 - name : Install dependencies
371386 run : bun install
@@ -428,11 +443,6 @@ jobs:
428443 # Build the command
429444 COMMAND="bunx buddy-bot dashboard"
430445
431- # TODO: Uncomment this when we have a way to pin the dashboard
432- # if [ "$PIN" = "true" ]; then
433- # COMMAND="$COMMAND --pin"
434- # fi
435-
436446 if [ "$TITLE" != "" ]; then
437447 COMMAND="$COMMAND --title \"$TITLE\""
438448 fi
@@ -466,7 +476,7 @@ jobs:
466476 fi
467477
468478 env :
469- GITHUB_TOKEN : ${{ secrets.BUDDY_BOT_TOKEN || secrets. GITHUB_TOKEN }}
479+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
470480 BUDDY_BOT_TOKEN : ${{ secrets.BUDDY_BOT_TOKEN }}
471481
472482 - name : Dry run notification
0 commit comments