Skip to content

ci: split busy hours in the runner demand report instead of failing - #34324

Merged
OrcaWin merged 1 commit into
mainfrom
ci/runner-demand-split-interval
Oct 27, 2026
Merged

OrcaWin merged 1 commit into
mainfrom
ci/runner-demand-split-interval

Conversation

@OrcaWin

@OrcaWin OrcaWin commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator
Files Added Deleted Net
Test 0 0 0 0
Prod 1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​25 $\color{#cf222e}{\Huge{\mathbf{−}}}$​12 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​13

What

The daily CI runner demand report failed for the first time today (run):

Error: Hourly run inventory exceeds API limit; split the interval

PR volume now goes past 1000 workflow runs in some hours (12,132 runs on 2026-10-26). The runs API serves at most 1000 results per query, so hourly windows no longer fit.

This change keeps the 24 hourly windows. Any window with total_count > 1000 is halved recursively until each half fits. Ranges stay inclusive at second granularity, with no overlap and no gaps.

Verification

I ran the patched script locally against the live API for the window that failed (CI_METRICS_END=2026-10-27T04:00:00Z):

  • Collected 12,132 runs, all unique run ids.
  • Sampled 501 runs and produced the full markdown report.
  • pnpm test config/scripts/ci-runner-metrics.test.mjs passes.

After merge, I'll dispatch the workflow once to confirm it on CI.

The runs API serves at most 1000 results per query. On 2026-10-27 one hour
crossed that and the daily report threw. Halve any oversized interval until
each query fits.
@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Walkthrough

The runner demand script now uses collectRuns for each hourly interval. The helper paginates queries with no more than 1,000 runs. When a query exceeds that limit, it divides the interval and combines results. It throws an error when an over-limit interval is shorter than two seconds.

Priority: Normal

Merge Risk: Low · up to 30dde

The report’s new oversized-window behavior lacks a test that would catch dropped runs. Add that targeted test before merging, or accept the bounded coverage gap.

Pre-merge checks: Passed 3 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Description check Warning The description explains the failure, the recursive interval-splitting change, and verification results. It does not follow the required template because it omits ELI5, Why, Linked Issue, Visual Proof… Add the required template sections. Include an actual linked issue, or explain the applicable maintainer exception. Add a Visual Proof section with N/A and a reason if there is no UI change. Complete Testing, AI Disclosure when applicable, …
Docstring Coverage Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surv… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 3 passed
Check name Status Explanation
Title check Passed The title clearly summarizes the main change: splitting busy hourly windows in the runner demand report instead of failing.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description explains the failure, the recursive interval-splitting change, and verification results. It does not follow the required template because it omits ELI5, Why, Linked Issue, Visual Proof or N/A, AI Disclosure, Review, Agent skill upstream boundary, Notes, and Checklist sections.

Resolution

Add the required template sections. Include an actual linked issue, or explain the applicable maintainer exception. Add a Visual Proof section with N/A and a reason if there is no UI change. Complete Testing, AI Disclosure when applicable, Review, Agent skill upstream boundary, Notes, and Checklist items. Rename or map the existing What and Verification content to the corresponding template sections.

Full details: Docstring Coverage

Explanation

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 2 functions across 1 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick comments: 1
config/scripts/ci-runner-demand.mjs: 1

29-38: Trivial · Maintainability & Code Quality · Quick win

Cover the successful oversized-window split.

collectRunnerDemand returns runs, and the existing run fixture is in scope. The suggested test can pass against the current implementation. Add it to ensure both recursive halves reach the returned inventory.

Suggested fix
 it('paginates jobs and bounds run discovery to 24 complete hours', async () => {
@@
   expect(result.report.workflows[0].runnerMinutes).toBe(505)
 })
 
+it('combines runs from both halves of an oversized window', async () => {
+  const requests = []
+  const firstRun = { ...run, id: 11 }
+  const secondRun = { ...run, id: 12 }
+  const createdRange = (path) => decodeURIComponent(path.match(/created=([^&]+)/)[1])
+
+  const result = await collectRunnerDemand(
+    { CI_METRICS_END: '2026-09-28T04:59:00Z' },
+    async (path) => {
+      requests.push(path)
+      if (path.includes('/jobs')) {
+        return { total_count: 0, jobs: [] }
+      }
+      const runRequests = requests.filter((request) => request.startsWith('actions/runs?'))
+      if (runRequests.length === 1) {
+        return { total_count: 1001, workflow_runs: [] }
+      }
+      if (runRequests.length === 2) {
+        return { total_count: 1, workflow_runs: [firstRun] }
+      }
+      if (runRequests.length === 3) {
+        return { total_count: 1, workflow_runs: [secondRun] }
+      }
+      return { total_count: 0, workflow_runs: [] }
+    }
+  )
+
+  const runRequests = requests.filter((path) => path.startsWith('actions/runs?'))
+  expect(runRequests).toHaveLength(26)
+  expect(runRequests.slice(0, 3).map(createdRange)).toEqual([
+    '2026-09-28T03:00:00.000Z..2026-09-28T03:59:59.000Z',
+    '2026-09-28T03:00:00.000Z..2026-09-28T03:29:59.000Z',
+    '2026-09-28T03:30:00.000Z..2026-09-28T03:59:59.000Z'
+  ])
+  expect(result.runs.map(({ id }) => id)).toEqual([11, 12])
+})

Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 394ddc5a-20d6-4e51-9c5a-05e014e15ca6
Commits

Reviewing files that changed from the base of the PR and between 755bbfa and 30dde6e.

Files selected for processing: 1
  • config/scripts/ci-runner-demand.mjs

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.

@OrcaWin
OrcaWin merged commit 8b9f878 into main Oct 27, 2026
55 of 57 checks passed
@OrcaWin
OrcaWin deleted the ci/runner-demand-split-interval branch October 27, 2026 08:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant