Skip to content

Report GitHub API rate limits in logs output - #58793

Merged
pelikhan merged 10 commits into
mainfrom
copilot/track-gh-api-rate-limit
Sep 5, 2026
Merged

Report GitHub API rate limits in logs output#58793
pelikhan merged 10 commits into
mainfrom
copilot/track-gh-api-rate-limit

Conversation

Copilot AI commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Logs commands did not expose their API quota consumption or warn when quota was running low.

Changes

  • Capture: Record core API rate-limit state before and after log collection.
  • Report: Add snapshots to standard, cross-run, empty-result, and multi-host JSON output.
  • Multi-host: Track GitHub.com and GitHub Enterprise quotas independently.
  • Alert: Warn non-JSON users when 20% or less of the core quota remains.
{
  "github_api_rate_limit": {
    "host": "github.com",
    "start": { "limit": 5000, "remaining": 4200, "used": 800 },
    "end": { "limit": 5000, "remaining": 4100, "used": 900 }
  }
}

Copilot AI and others added 9 commits September 5, 2026 10:09
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Report GitHub API rate-limit usage for logs commands Report GitHub API rate limits in logs output Sep 5, 2026
Copilot AI requested a review from pelikhan September 5, 2026 10:40
@pelikhan
pelikhan marked this pull request as ready for review September 5, 2026 10:49
Copilot AI balanced review requested due to automatic review settings September 5, 2026 10:49

Copilot AI 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.

🟡 Changes recommended

Empty-host resolution can incorrectly query and label GitHub.com instead of the configured GHES host.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds GitHub API quota snapshots and low-quota warnings to logs reporting.

Changes:

  • Captures start and end core API quotas per host.
  • Includes quota data across JSON output paths.
  • Warns non-JSON users when 20% or less remains.

Required change: Resolve the effective configured or current-repository host when no host is provided instead of defaulting directly to github.com, which misreports GHES usage.

File summaries
File Description
pkg/cli/logs_report.go Adds rate-limit report fields.
pkg/cli/logs_rate_limit.go Implements quota capture, host handling, and warnings.
pkg/cli/logs_rate_limit_test.go Tests reports, warnings, and host deduplication.
pkg/cli/logs_orchestrator.go Wires reporting into standard downloads.
pkg/cli/logs_orchestrator_types.go Carries reports through rendering.
pkg/cli/logs_orchestrator_stdin.go Adds stdin and multi-host reporting.
pkg/cli/logs_orchestrator_render.go Includes quotas in rendered output.
pkg/cli/logs_orchestrator_download.go Includes quotas in empty results.
pkg/cli/logs_multi.go Tracks quotas across workflow targets.
pkg/cli/logs_models.go Defines the warning threshold.
pkg/cli/audit_cross_run.go Adds quotas to cross-run reports.
Review details

Suppressed comments (2)

pkg/cli/logs_rate_limit.go:199

  • Omitting --hostname for github.com still lets an inherited GH_HOST redirect this supposedly public-host snapshot to GHES. In a mixed-host report, that can duplicate the enterprise quota under the github.com label. Pin every non-empty host here; fetchRateLimit(ctx) continues to pass an empty host for callers that intentionally use the configured default.
	args := []string{"api", "rate_limit"}
	if host != "" && host != "github.com" {
		args = append(args, "--hostname", host)
	}

pkg/cli/logs_rate_limit.go:153

  • The --repo contract is [HOST/]owner/repo and does not require the host to contain a dot (see pkg/cli/flags.go:27 and the stdin parser above). For a valid single-label GHES host such as github/owner/repo, this falls back to github.com, so snapshots and low-quota warnings report the wrong account. Treat any three-part repo override as host-qualified.
func logsRateLimitHost(repoOverride string) string {
	parts := strings.SplitN(repoOverride, "/", 3)
	if len(parts) == 3 && strings.Contains(parts[0], ".") {
		return parts[0]
	}
	return ""
  • Files reviewed: 11/11 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment on lines +141 to +145
func normalizedGitHubAPIHost(host string) string {
if host == "" {
return "github.com"
}
return host
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

⚠️ Security scanning failed for Ponytail Reviewer. Review the logs for details.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • ab.chatgpt.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"

See Network Configuration for more information.

Generated by Ponytail Reviewer for #58793

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions github-actions 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.

Skills-Based Review 🧠

Applied /codebase-design and /tdd to the new rate-limit reporting code. There's already an existing review comment from Copilot on the host-resolution logic (logs_rate_limit.go:145) that I agree is worth addressing. My two additional comments are minor and non-blocking.

📋 Key Themes & Highlights

Key Themes

  • Naming duplication: rateLimitResource is kept as a type alias for the newly-introduced GitHubAPIRateLimitState, giving one concept two names in the same package.
  • Partition boundary untested: partitionGitHubAPIRateLimitReports's single-vs-multi-host branching isn't directly unit tested.

Positive Highlights

  • ✅ Good test coverage overall for warn/suppress/omit-on-error behavior (logs_rate_limit_test.go).
  • ✅ Sensible JSON shape (start/end snapshots) and clean threshold constant with a guarding unit test.
  • ✅ Host normalization and multi-host support are handled consistently across the three logs entry points.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 33.3 AIC · ⌖ 17.4 AIC · ⊞ 10.3K
Comment /matt to run again

Comments that could not be inline-anchored

pkg/cli/logs_rate_limit.go:304

[/codebase-design] Introducing type rateLimitResource = GitHubAPIRateLimitState gives the same concept two public-facing names in one package, which adds navigation friction (readers must learn both rateLimitResource and GitHubAPIRateLimitState refer to the same struct). This looks like it exists only to avoid touching call sites that still use rateLimitResource.

<details>
<summary>💡 Suggestion</summary>

Since this PR already touches every call site of fetchRateLimit/`fetchRate…

pkg/cli/logs_rate_limit.go:398

[/tdd] partitionGitHubAPIRateLimitReports (which decides whether a single-host report goes on GitHubAPIRateLimit or falls back to the GitHubAPIRateLimits array) has no direct test — only its callers are exercised indirectly through multi-host fixtures. The 2-vs-1 boundary is exactly the kind of edge case that regresses silently.

<details>
<summary>💡 Suggested test</summary>

func TestPartitionGitHubAPIRateLimitReports(t *testing.T) {
	one := populatedGitHubAPIRateLimitReport(&amp;…

</details>

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor
🏗️ ADR Required

I inferred an architectural decision from this PR and added a draft ADR at docs/adr/58793-report-github-api-rate-limits-in-logs-output.md.

Evidence used

  • PR title/body: "Report GitHub API rate limits in logs output" and the listed goals to capture, report, and warn on quota usage.
  • Diff: new GitHubAPIRateLimitReport/GitHubAPIRateLimitState types, propagation through single-run, multi-target, stdin, empty-result, and cross-run rendering paths, plus per-host handling and low-quota warnings.

Gate result

  • ADR enforcement was required because this PR adds 338 lines in business-logic directories (pkg/).
  • No existing ADR was present in the PR body or recent docs/adr/ records with the required Michael Nygard sections.
  • A draft ADR has been committed so the design can be reviewed explicitly before merge.

Next action

  • Review and refine docs/adr/58793-report-github-api-rate-limits-in-logs-output.md, then keep it with the PR as the decision record for this change.

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · pi · gpt54 · 20.8 AIC · ⌖ 9.83 AIC · ⊞ 10.1K ·
Comment /review to run again

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-09-05T11:03:45Z
review_event: COMMENT
top_themes:
  - no-blocking-issues-found
files_reviewed:
  - pkg/cli/audit_cross_run.go
  - pkg/cli/logs_models.go
  - pkg/cli/logs_multi.go
  - pkg/cli/logs_orchestrator.go
  - pkg/cli/logs_orchestrator_download.go
  - pkg/cli/logs_orchestrator_render.go
  - pkg/cli/logs_orchestrator_stdin.go
  - pkg/cli/logs_orchestrator_types.go
  - pkg/cli/logs_rate_limit.go
  - pkg/cli/logs_rate_limit_test.go
  - pkg/cli/logs_report.go
comment_count: 0

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 45.9 AIC · ⌖ 7.34 AIC · ⊞ 23.5K ·
Comment /review to run again

@github-actions github-actions 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.

Verdict

No blocking issues jumped out in the changed lines.

Why this stays non-blocking The new rate-limit reporting is wired through the single-run, stdin, multi-target, and cross-run JSON paths consistently, and the one candidate issue from the sub-agent does not hold up: the all-invalid-stdin branch already emits the JSON payload before returning. I did not find a changed-line correctness, crash, or quota-handling regression that clearly warrants blocking the PR.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 45.9 AIC · ⌖ 7.34 AIC · ⊞ 23.5K
Comment /review to run again

@github-actions github-actions 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.

The new rate-limit reporting adds a couple of helper layers that can be simplified without changing behavior. net: -16 lines possible.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • ab.chatgpt.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"

See Network Configuration for more information.

Generated by ✂️ Ponytail Reviewer for #58793 · codex · mai10 · 7.97 AIC · ⌖ 13.3 AIC · ⊞ 13.5K
Comment /ponytail to run again

int64(state.Remaining)*100 <= int64(state.Limit)*int64(RateLimitWarningThresholdPercent)
}

func populatedGitHubAPIRateLimitReport(report *GitHubAPIRateLimitReport) *GitHubAPIRateLimitReport {

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.

pkg/cli/logs_rate_limit.go:L161: yagni: three tiny helpers that only filter nil reports and choose a single report. Inline the nil handling at the call sites and drop this mini-API.

return fmt.Errorf("invalid repository format '%s': expected '[HOST/]owner/repo'", opts.RepoOverride)
}
}
rateLimitHosts := make([]string, 0, len(opts.RunURLs))

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.

pkg/cli/logs_orchestrator_stdin.go:L80: yagni: a host-dedup loop with a map just to build a short list of rate-limit hosts. A single pass or a direct fallback would keep this branch simpler.

@pelikhan
pelikhan merged commit f9adc4c into main Sep 5, 2026
32 checks passed
@pelikhan
pelikhan deleted the copilot/track-gh-api-rate-limit branch September 5, 2026 11:33
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.88.5

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.

3 participants