test(ci): add unit-test seam for check-stuck-required-checks.mjs#7490
Conversation
The stuck/threshold detection (findStuckChecksForPr, minutesSince) and the watchdog's dry-run + marker-based idempotency only ran inside the un-guarded live-GitHub driver, so none of it was testable in isolation. Refactor githubApi into an injected dependency (a makeGithubApi factory for the live entrypoint), export minutesSince/findStuckChecksForPr/hasExistingWatchdogComment plus a runStuckCheckWatchdog driver, and gate the env-reading/live-call entrypoint behind import.meta.url === argv[1]. Add scripts/check-stuck-required-checks.d.mts (declaration pairing the imported .mjs) and test/unit/check-stuck-required-checks-script.test.ts covering: a check past threshold is flagged, one under threshold is not, a not-completed check with no started_at is excluded, non-required/completed checks are ignored, the marker makes the watchdog idempotent, and --dry-run never POSTs. Runtime behavior of the script when invoked directly is unchanged. Closes JSONbored#7455
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7490 +/- ##
=======================================
Coverage 91.41% 91.41%
=======================================
Files 717 717
Lines 73032 73032
Branches 21633 21633
=======================================
Hits 66762 66762
Misses 5227 5227
Partials 1043 1043
Flags with carried forward coverage won't be shown. Click here to find out more. |
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-20 12:51:09 UTC
Review summary Nits — 5 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
Closes #7455
What
check-stuck-required-checks.mjs'sfindStuckChecksForPr/minutesSincedetection and the watchdog's dry-run + marker-based idempotency only ran inside the un-guarded live-GitHub driver, so none of it was testable in isolation.githubApiinto an injected dependency (amakeGithubApi(token)factory used only by the live entrypoint), matching this repo's injectable-fetchImplscript-test pattern.minutesSince,findStuckChecksForPr,hasExistingWatchdogComment,MARKER,REQUIRED_CONTEXTS, and arunStuckCheckWatchdogdriver.import.meta.url === pathToFileURL(process.argv[1]).href, so importing for tests makes no network calls. Running the script directly is unchanged.scripts/check-stuck-required-checks.d.mts(the declaration that pairs with the imported.mjs) andtest/unit/check-stuck-required-checks-script.test.ts.Tests (green locally under
vitest run test/unit)started_at(elapsedMinutes === null, e.g. stillqueued) is excluded.MARKERmakes the watchdog idempotent (a PR already commented on is skipped — no POST).--dry-runnever calls the comment-post endpoint.Verified: importing with empty env neither throws nor fetches; the typed
.mjsimport resolves via the.d.mts(noTS7016).scripts/**isn't incoverage.include.