Fix pr-maintenance cron — prepend user bins to PATH so archon is found#1283
Fix pr-maintenance cron — prepend user bins to PATH so archon is found#1283alexsiri7 wants to merge 1 commit intocoleam00:devfrom
Conversation
When cron invoked the script every 15 min, PATH was the minimal
/usr/bin:/bin. archon (installed at ~/.bun/bin/archon) was not
findable, so every "launching archon" step died with:
/mnt/ext-fast/archon/scripts/pr-maintenance-cron.sh: line 59:
archon: command not found
As a result PRs that needed conflict resolution stopped being
processed — they just accumulated as DIRTY or UNKNOWN.
Prepend $HOME/.bun/bin, $HOME/.local/bin, and /usr/local/bin to PATH
at the top of the script. Works from cron and from an interactive
shell unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughUpdated Homebrew formula to target Archon CLI version 0.3.6 with updated SHA256 checksums for macOS and Linux binaries. Added a new cron script for automated PR maintenance that handles merging clean PRs and triggering workflows for PRs needing attention. Changes
Sequence Diagram(s)sequenceDiagram
participant Cron as Cron Scheduler
participant Script as pr-maintenance-cron.sh
participant Git as Git Repository
participant GH as GitHub CLI
participant Archon as Archon Workflow
Cron->>Script: Execute every 15 minutes
Script->>Git: Check if .git exists
Git-->>Script: Confirm repo exists
Script->>GH: List open, non-draft PRs
GH-->>Script: Return PR list with mergeStateStatus
loop For each CLEAN PR
Script->>GH: Auto-merge with --squash --auto
GH-->>Script: PR merged (or skip on failure)
end
loop Find actionable PR
Script->>GH: Query for BEHIND/DIRTY/UNSTABLE/UNKNOWN
GH-->>Script: Return actionable PR (if exists)
alt PR found
Script->>Archon: Launch workflow run in background
Archon-->>Script: Workflow started
end
end
Script->>Script: Wait for background jobs
Script-->>Cron: Complete with timestamp logging
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
scripts/pr-maintenance-cron.sh (1)
49-51: Consider not silencing stderr ongh pr merge.Given the whole point of this PR is that silent failures in cron masked a real problem for a long time, redirecting
gh pr mergestderr to/dev/nullon both the primary and fallback attempts makes future diagnosis equally painful — thecould not merge, skippinglog line is the only signal you’ll have. At minimum capture the error into the log.🛠 Suggested change
for PR in $CLEAN_PRS; do log "$PROJECT: PR #$PR is CLEAN — merging directly" - gh pr merge "$PR" --squash --auto --delete-branch 2>/dev/null \ - || gh pr merge "$PR" --squash --delete-branch 2>/dev/null \ - || log "$PROJECT: PR #$PR — could not merge, skipping" + gh pr merge "$PR" --squash --auto --delete-branch \ + || gh pr merge "$PR" --squash --delete-branch \ + || log "$PROJECT: PR #$PR — could not merge, skipping" done🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/pr-maintenance-cron.sh` around lines 49 - 51, The merge command currently silences stderr by redirecting gh pr merge "$PR" ... 2>/dev/null, which hides useful error output; change both occurrences of the gh pr merge call so stderr is captured and included in the failure log (e.g., capture command output and exit status, or redirect stderr into a variable or temp file) and update the fallback branch that calls log "$PROJECT: PR #$PR — could not merge, skipping" to include the captured error details; target the gh pr merge "$PR" invocations and the log function usage so any merge failure surfaces the underlying gh error message.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@scripts/pr-maintenance-cron.sh`:
- Around line 36-39: The current check if [ ! -d "$REPO_DIR/.git" ] in the
repository loop rejects git worktrees because .git may be a file; update the
check to detect a git worktree by running git -C "$REPO_DIR" rev-parse
--is-inside-work-tree >/dev/null 2>&1 (or at minimum test -e "$REPO_DIR/.git"
instead of -d) and keep the same log call (log "$PROJECT: not a git repo,
skipping") and continue behavior when the git check fails; reference the
REPO_DIR variable and the existing log/continue logic when making the change.
- Around line 33-69: Add a non-blocking flock guard at the top of the script so
concurrent cron ticks exit immediately: create a lockfile (e.g.
LOCKFILE="$BASE_DIR/pr-maintenance.lock"), open it (exec 9>"$LOCKFILE") and call
flock -n 9 || { log "another run in progress, exiting"; exit 0; } before the
PROJECTS loop; leave the rest of the logic (variables like ACTIONABLE, CLEAN_PRS
and the archon workflow run invocation) unchanged so only one instance can
choose and launch archon workflows at a time.
---
Nitpick comments:
In `@scripts/pr-maintenance-cron.sh`:
- Around line 49-51: The merge command currently silences stderr by redirecting
gh pr merge "$PR" ... 2>/dev/null, which hides useful error output; change both
occurrences of the gh pr merge call so stderr is captured and included in the
failure log (e.g., capture command output and exit status, or redirect stderr
into a variable or temp file) and update the fallback branch that calls log
"$PROJECT: PR #$PR — could not merge, skipping" to include the captured error
details; target the gh pr merge "$PR" invocations and the log function usage so
any merge failure surfaces the underlying gh error message.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 751e6786-78db-4653-a49b-590178bc6441
📒 Files selected for processing (2)
homebrew/archon.rbscripts/pr-maintenance-cron.sh
| for PROJECT in "${PROJECTS[@]}"; do | ||
| REPO_DIR="$BASE_DIR/$PROJECT" | ||
|
|
||
| if [ ! -d "$REPO_DIR/.git" ]; then | ||
| log "$PROJECT: not a git repo, skipping" | ||
| continue | ||
| fi | ||
|
|
||
| cd "$REPO_DIR" | ||
|
|
||
| # --- Phase 1: Merge CLEAN PRs directly (bash only, zero AI cost) --- | ||
| CLEAN_PRS=$(gh pr list --state open --json number,mergeStateStatus,isDraft \ | ||
| --jq '[.[] | select(.isDraft == false and .mergeStateStatus == "CLEAN")] | .[].number' 2>/dev/null || true) | ||
|
|
||
| for PR in $CLEAN_PRS; do | ||
| log "$PROJECT: PR #$PR is CLEAN — merging directly" | ||
| gh pr merge "$PR" --squash --auto --delete-branch 2>/dev/null \ | ||
| || gh pr merge "$PR" --squash --delete-branch 2>/dev/null \ | ||
| || log "$PROJECT: PR #$PR — could not merge, skipping" | ||
| done | ||
|
|
||
| # --- Phase 2: Check for one PR needing AI attention --- | ||
| ACTIONABLE=$(gh pr list --state open --json number,mergeStateStatus,isDraft \ | ||
| --jq '[.[] | select(.isDraft == false and (.mergeStateStatus == "BEHIND" or .mergeStateStatus == "DIRTY" or .mergeStateStatus == "UNSTABLE" or .mergeStateStatus == "UNKNOWN"))] | .[0].number // empty' 2>/dev/null || true) | ||
|
|
||
| if [ -z "$ACTIONABLE" ]; then | ||
| log "$PROJECT: no PRs need AI maintenance" | ||
| continue | ||
| fi | ||
|
|
||
| log "$PROJECT: PR #$ACTIONABLE needs maintenance — launching archon" | ||
| archon workflow run archon-pr-maintenance --cwd "$REPO_DIR" "PR #$ACTIONABLE" & | ||
|
|
||
| done | ||
|
|
||
| # Wait for any background archon runs to complete | ||
| wait |
There was a problem hiding this comment.
Add a run lock to prevent overlapping cron invocations.
archon workflow run archon-pr-maintenance can easily exceed the 15‑minute cadence, and wait on line 69 only blocks the current invocation — the next cron tick will start regardless. With no lock, two runs can pick the same ACTIONABLE PR from gh pr list and launch duplicate archon workflows against it (wasted AI cost, potential push races on the branch).
Consider a flock-based guard at the top of the script so overlapping ticks exit immediately:
🔒 Proposed flock guard
set -euo pipefail
+# Prevent overlapping cron runs — archon workflows often outlive the 15-min cadence.
+LOCKFILE="/tmp/pr-maintenance-cron.lock"
+exec 9>"$LOCKFILE"
+if ! flock -n 9; then
+ echo "$(date -Is) [pr-maintenance] previous run still active, skipping" >&2
+ exit 0
+fi
+
# Cron runs with a minimal PATH (/usr/bin:/bin). archon, gh, bun, git🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@scripts/pr-maintenance-cron.sh` around lines 33 - 69, Add a non-blocking
flock guard at the top of the script so concurrent cron ticks exit immediately:
create a lockfile (e.g. LOCKFILE="$BASE_DIR/pr-maintenance.lock"), open it (exec
9>"$LOCKFILE") and call flock -n 9 || { log "another run in progress, exiting";
exit 0; } before the PROJECTS loop; leave the rest of the logic (variables like
ACTIONABLE, CLEAN_PRS and the archon workflow run invocation) unchanged so only
one instance can choose and launch archon workflows at a time.
| if [ ! -d "$REPO_DIR/.git" ]; then | ||
| log "$PROJECT: not a git repo, skipping" | ||
| continue | ||
| fi |
There was a problem hiding this comment.
.git directory check rejects git worktrees.
[ ! -d "$REPO_DIR/.git" ] is false for a linked worktree, where .git is a file pointing at the main repo's gitdir. If any of the target projects ever end up checked out as a worktree the script will silently skip them. Prefer git -C "$REPO_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1 or test for -e instead of -d.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@scripts/pr-maintenance-cron.sh` around lines 36 - 39, The current check if [
! -d "$REPO_DIR/.git" ] in the repository loop rejects git worktrees because
.git may be a file; update the check to detect a git worktree by running git -C
"$REPO_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1 (or at minimum test
-e "$REPO_DIR/.git" instead of -d) and keep the same log call (log "$PROJECT:
not a git repo, skipping") and continue behavior when the git check fails;
reference the REPO_DIR variable and the existing log/continue logic when making
the change.
|
Hi @alexsiri7 — thanks for opening this PR. This repository uses a PR template at
Could you fill those out (even briefly)? The template helps reviewers understand scope, risk, and rollback — it speeds up review significantly. If a section genuinely doesn't apply, just write "N/A" in it rather than leaving it blank. |
Summary
Cron runs with a minimal PATH (
/usr/bin:/bin). The PR-maintenance script tries to invokearchon(installed at~/.bun/bin/archon) and dies with:Every maintenance run silently failed to launch archon on DIRTY / BEHIND / UNKNOWN PRs. Backlog in cosmic-match grew to 16+ open PRs because nothing was resolving conflicts.
Fix: prepend
$HOME/.bun/bin,$HOME/.local/bin, and/usr/local/bintoPATHat the top of the script.Test plan
crontab -e→ let the existing*/15 * * * *trigger run once./tmp/pr-maintenance.logno longer containscommand not found.ps aux | grep archon-pr-maintenanceshows activity after a cron fire.Summary by CodeRabbit