diff --git a/skills/github-repo-monitor/SKILL.md b/skills/github-repo-monitor/SKILL.md index 7de2e8f7..6f63d5d4 100644 --- a/skills/github-repo-monitor/SKILL.md +++ b/skills/github-repo-monitor/SKILL.md @@ -29,8 +29,11 @@ On every subsequent run: - When a conversation goes idle/finished/error the agent's final response is posted back as a GitHub comment. -> **Local mode only.** This automation targets the local OpenHands setup -> (`dev:automation` stack). A cloud/webhook variant is out of scope here. +> **Cron polling vs. event triggers:** This skill uses cron polling and works in +> any deployment. If `RUNTIME_URL` is set and does not contain `localhost` or +> `127.0.0.1`, the environment can receive GitHub webhook events directly — prefer +> an event-triggered automation (see the `openhands-automation` skill) rather than +> polling. Use this skill only when `RUNTIME_URL` is unset, empty, or local. --- @@ -69,6 +72,25 @@ function without GitHub credentials. Follow these steps in order. +### Step 0 - Check deployment environment + +Check whether the environment can receive GitHub webhook events: + +```bash +echo "RUNTIME_URL=${RUNTIME_URL}" +``` + +- If `RUNTIME_URL` is **set and does not contain `localhost` or `127.0.0.1`** → + tell the user: + *"Your environment has a reachable `RUNTIME_URL` (`$RUNTIME_URL`), so GitHub can + deliver events directly. An event-triggered automation (e.g. `pull_request.opened` + or `issue_comment.created`) using the `openhands-automation` skill would be more + immediate and efficient than cron polling. Continue with this skill only if you + specifically want polling."* + If the user confirms they want polling anyway, continue to Step 1. +- If `RUNTIME_URL` is **unset, empty, or contains `localhost`/`127.0.0.1`** → + proceed directly to Step 1. + ### Step 1 - Verify GITHUB_TOKEN Fetch the secret and run the `curl` check above. @@ -303,3 +325,5 @@ Each cron run executes `main.py`, which: | Same comment processed twice | `processed_comment_ids` cleared | State file was deleted; harmless but duplicate comment may appear | | Summary never posted | Conversation stuck in `running` | Open the conversation in the OpenHands UI; agent may need input | | No events detected after first run | `last_poll` in the future | Delete the state file to reset; it will be recreated on next run | +| `Callback error (non-fatal): HTTP Error 409: Conflict` in run logs | Automation service auto-marks the run complete on process exit; explicit `fire_callback("COMPLETED")` at script end then conflicts | Fixed in `scripts/main.py` ≥ this version — the 409 is now caught and ignored silently | +| Automation stops firing after updating it via PATCH | PATCH resets `enabled` to `false` | Follow every PATCH with `{"enabled": true}` to re-activate | diff --git a/skills/github-repo-monitor/scripts/main.py b/skills/github-repo-monitor/scripts/main.py index c0548e86..40a1b00a 100644 --- a/skills/github-repo-monitor/scripts/main.py +++ b/skills/github-repo-monitor/scripts/main.py @@ -98,6 +98,10 @@ def fire_callback(status: str = "COMPLETED", error: str | None = None) -> None: ) try: urllib.request.urlopen(req) + except urllib.error.HTTPError as exc: + if exc.code == 409: + return # Run already marked complete by the automation service — ignore. + print(f"Callback error (non-fatal): {exc}") except Exception as exc: print(f"Callback error (non-fatal): {exc}")