Skip to content

feat(scorecard): add new GitHub metrics for issues, opened/closed prs and GitHub actions - #3472

Open
fullsend-ai-coder[bot] wants to merge 7 commits into
mainfrom
agent/3468-extend-github-metrics
Open

feat(scorecard): add new GitHub metrics for issues, opened/closed prs and GitHub actions#3472
fullsend-ai-coder[bot] wants to merge 7 commits into
mainfrom
agent/3468-extend-github-metrics

Conversation

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor

Extend the scorecard GitHub module with 13 new metrics across four domains:

Issue/PR counts (5 metrics):

  • Currently open issues
  • Opened issues in last 7 days
  • Opened PRs in last 7 days
  • Closed issues in last 7 days
  • Closed PRs in last 7 days

PR lifecycle timing (3 metrics, batch provider):

  • Time to first review (average hours)
  • Time to first approval (average hours)
  • Time to merge (average hours)
    All computed from PRs updated in the last 7 days.

GitHub Actions (5 metrics, batch provider):

  • Started workflow runs in last 7 days
  • Successfully completed runs in last 7 days
  • Failed runs in last 7 days
  • Success ratio for 7 days (percentage)
  • Success ratio for 24 hours (percentage)
    Non-terminal runs (pending/running/cancelled) are excluded from success/failure counts and ratio calculations.

CI pass rate (2 metrics, batch provider):

  • First-time CI pass rate for 7 days (percentage)
  • First-time CI pass rate for 24 hours (percentage)
    Checks CI status on the last commit of the first push to each PR. PRs without CI checks are excluded.

New GithubClient methods use GraphQL for issue/PR queries and REST API (fetch) for workflow runs. All providers follow the existing MetricProvider pattern and are registered in the module init. Batch providers use getMetrics/calculateMetrics for efficient multi-metric computation.


Closes #3468

Post-script verification

  • Branch is not main/master (agent/3468-extend-github-metrics)
  • Secret scan passed (gitleaks — 7ccaff17753df64c7ab288cdcba34cee5a657254..HEAD)
  • Pre-commit hooks passed (authoritative run on runner)
  • Tests ran inside sandbox

@rhdh-gh-app

rhdh-gh-app Bot commented Jun 19, 2026

Copy link
Copy Markdown

Missing Changesets

The following package(s) are changed by this PR but do not have a changeset:

  • @red-hat-developer-hub/backstage-plugin-scorecard-backend-module-github
  • @red-hat-developer-hub/backstage-plugin-scorecard-common

See CONTRIBUTING.md for more information about how to add changesets.

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-scorecard-backend-module-github workspaces/scorecard/plugins/scorecard-backend-module-github none v3.0.0
@red-hat-developer-hub/backstage-plugin-scorecard-common workspaces/scorecard/plugins/scorecard-common none v3.0.0

@codecov

codecov Bot commented Jun 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 68.48635% with 127 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.97%. Comparing base (0695f02) to head (8e2436f).
⚠️ Report is 4 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3472      +/-   ##
==========================================
+ Coverage   57.93%   57.97%   +0.04%     
==========================================
  Files        2396     2405       +9     
  Lines       96104    96507     +403     
  Branches    26803    26824      +21     
==========================================
+ Hits        55675    55951     +276     
- Misses      40233    40360     +127     
  Partials      196      196              
Flag Coverage Δ *Carryforward flag
adoption-insights 84.54% <ø> (ø) Carriedforward from 0695f02
ai-integrations 69.06% <ø> (ø) Carriedforward from 0695f02
app-defaults 69.79% <ø> (ø) Carriedforward from 0695f02
augment 46.67% <ø> (ø) Carriedforward from 0695f02
boost 76.77% <ø> (ø) Carriedforward from 0695f02
bulk-import 72.55% <ø> (ø) Carriedforward from 0695f02
cost-management 13.55% <ø> (ø) Carriedforward from 0695f02
dcm 60.72% <ø> (ø) Carriedforward from 0695f02
extensions 56.48% <ø> (ø) Carriedforward from 0695f02
global-floating-action-button 71.18% <ø> (ø) Carriedforward from 0695f02
global-header 62.17% <ø> (ø) Carriedforward from 0695f02
homepage 47.54% <ø> (ø) Carriedforward from 0695f02
install-dynamic-plugins 56.77% <ø> (ø) Carriedforward from 0695f02
intelligent-assistant 74.53% <ø> (ø) Carriedforward from 0695f02
konflux 91.98% <ø> (ø) Carriedforward from 0695f02
lightspeed 69.02% <ø> (ø) Carriedforward from 0695f02
mcp-integrations 83.40% <ø> (ø) Carriedforward from 0695f02
orchestrator 66.79% <ø> (ø) Carriedforward from 0695f02
quickstart 65.04% <ø> (ø) Carriedforward from 0695f02
sandbox 79.56% <ø> (ø) Carriedforward from 0695f02
scorecard 83.70% <68.48%> (-1.65%) ⬇️
theme 87.90% <ø> (ø) Carriedforward from 0695f02
translations 5.12% <ø> (ø) Carriedforward from 0695f02
x2a 79.31% <ø> (ø) Carriedforward from 0695f02

*This pull request uses carry forward flags. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0695f02...8e2436f. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 19, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 11:49 AM UTC · Completed 12:02 PM UTC
Commit: 7ccaff1 · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 19, 2026

Copy link
Copy Markdown

Review

Findings

Medium

  • [edge-case] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:124 — GraphQL search queries in getPullRequestsWithReviews and getPullRequestsWithCommitStatuses use first: 100 without cursor-based pagination. For active repositories with more than 100 PRs updated (or created) in the last 7 days, results are silently truncated, skewing all downstream metric calculations (time-to-review, time-to-approve, time-to-merge, and CI pass rate). Nested collections (reviews first: 100, commits first: 100) are also limited. In contrast, getWorkflowRuns correctly implements REST API pagination.
    Remediation: Add cursor-based pagination using pageInfo { hasNextPage endCursor } with after cursors, looping until all results are fetched.

  • [logic-error] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsRatioProvider.ts:48computeSuccessRatio and computePassRate use Math.round(x * 1000) / 10 which produces one-decimal-place percentages (e.g., 66.7). However, the threshold expressions use integer ranges like >=80, 50-79, <50. A value of 79.9 would not match 50-79 (if range is inclusive to 79) and would not match >=80, potentially falling through all threshold rules depending on how the threshold evaluator parses ranges. This creates a gap between integer threshold boundaries.
    Remediation: Either use Math.round(x * 100) for whole-number percentages to align with integer threshold expressions, or verify that the ThresholdEvaluator correctly handles decimal values in range expressions and adjust thresholds if needed.

  • [api-contract] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsCountProvider.ts:30 — The GithubActionsCountProvider returns a single ThresholdConfig (COUNT_THRESHOLDS with <10 = success, 10-50 = warning, >50 = error) applied to all three metrics (started, successful, failed). These thresholds are semantically wrong for some metrics: >50 successful runs being rated 'error' is counterintuitive. The same issue applies to GithubPRLifecycleProvider where identical DURATION_THRESHOLDS apply to time-to-review, time-to-approve, and time-to-merge, which have different expected ranges.
    Remediation: Split into separate providers with distinct thresholds, or choose threshold values that are reasonable defaults for the most critical metric in each batch.

  • [logic-error] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:249 — The "first push" commit identification heuristic in getPullRequestsWithCommitStatuses uses committedDate <= prCreatedAt + 60000 (1-minute tolerance). committedDate is the git commit timestamp (when committed locally), not when pushed to GitHub. Commits authored days before PR creation will all pass the filter. Force-pushed commits replacing the first push use their own committedDate, creating false matches. If no commits match the window, lastFirstPushCommit is null and the PR is excluded from pass rate calculation rather than counted.
    Remediation: Consider using push events or the first commit's status rollup instead, or document this as a known approximation.

  • [injection] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:169 — The since parameter in getWorkflowRuns is interpolated directly into the REST API URL query string without encoding (created=>${since}). While current callers always pass safe YYYY-MM-DD date strings, the method accepts an arbitrary string. The owner and repo values are properly encoded with encodeURIComponent, but since is not.
    Remediation: Apply encodeURIComponent to since or validate it matches /^\d{4}-\d{2}-\d{2}$/.

  • [missing-error-handling] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:170 — In getWorkflowRuns, the response.json() result is cast to { workflow_runs: WorkflowRun[]; total_count: number } without validation. If the GitHub API returns an unexpected shape (e.g., rate-limit response with HTTP 200), data.workflow_runs could be undefined, causing allRuns.push(...data.workflow_runs) to throw at runtime.
    Remediation: Add a guard: if (!data.workflow_runs) { throw new Error('Unexpected GitHub API response'); }

Low

  • [test-inadequate] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsRatioProvider.test.ts — No test case exercises a non-integer ratio result (e.g., 2 success / 3 completed = 66.7%) to verify and document the one-decimal-place rounding behavior. All current test values happen to produce integer percentages.
    Remediation: Add a test case with a non-integer ratio to explicitly verify rounding behavior.

  • [missing-test] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts — The five new GithubClient methods have no direct unit tests. They are only tested indirectly through provider tests that mock the entire client, so the actual GraphQL queries, REST URL construction, response parsing, and pagination logic are never exercised.

  • [injection] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:93getSearchCount accepts an unrestricted searchQuery: string that is concatenated into a GitHub search query. A future caller could inject additional search qualifiers (e.g., repo:other-org/other-repo) to query data outside the intended scope. Current callers pass only hardcoded strings.

  • [edge-case] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:160getWorkflowRuns paginates without an upper bound. For repositories with tens of thousands of workflow runs in 7 days, this could exhaust memory. Both GithubActionsCountProvider and GithubActionsRatioProvider independently call getWorkflowRuns for the same entity and window, doubling API calls.

  • [edge-case] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsRatioProvider.ts:48computeSuccessRatio returns 100 when no success+failure runs exist (all cancelled or in-progress). A repository with many cancelled runs and zero successes reporting 100% could be misleading.

Previous run

Review

Findings

Medium

  • [edge-case] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:125 — The getPullRequestsWithReviews and getPullRequestsWithCommitStatuses GraphQL queries use search(first: 100) which limits results to 100 PRs. For active repositories with many PRs updated in the last 7 days, this will silently truncate the dataset, producing inaccurate metrics. No pagination is implemented for these GraphQL search queries, unlike getWorkflowRuns which does paginate via REST.
    Remediation: Implement GraphQL cursor-based pagination using pageInfo { hasNextPage endCursor } and the after parameter, or document the 100-item limit and add a log warning when the result count equals 100.

  • [injection-vuln] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:93 — The getSearchCount, getPullRequestsWithReviews, and getPullRequestsWithCommitStatuses methods interpolate repository.owner and repository.repo directly into GitHub search query strings (e.g., repo:${repository.owner}/${repository.repo}). The getRepositoryInformationFromEntity utility splits the github.com/project-slug annotation on / but does not validate that the resulting owner/repo values contain only valid GitHub username characters. A catalog entity with a malicious annotation value containing spaces or GitHub search qualifiers (e.g., org:victim) could manipulate the search scope to query unintended repositories. Risk is mitigated by catalog entity registration being typically admin-controlled and queries being read-only.
    Remediation: Validate that owner and repo values match a strict regex (e.g., /^[a-zA-Z0-9._-]+$/) in getRepositoryInformationFromEntity, rejecting values containing spaces, colons, or other special characters.

  • [edge-case] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:165 — The getWorkflowRuns method pages through all GitHub Actions workflow runs using a while (hasMore) loop with no upper bound on page count or total results. For high-activity repositories with thousands of workflow runs in the 7-day window, this will make an unbounded number of HTTP requests, accumulate all results in memory, and potentially exhaust GitHub API rate limits or cause backend timeouts.
    Remediation: Add a maximum page count (e.g., 10 pages = 1000 runs) or maximum total result count to cap the loop. Consider logging a warning when the cap is reached.

Low

  • [logic-error] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsRatioProvider.ts:48 — The computeSuccessRatio and computePassRate functions use Math.round(x * 1000) / 10 producing one-decimal-place precision (e.g., 66.7), but metric descriptions say "percentage." Consider documenting the one-decimal-place convention or standardizing on integer percentages.

  • [edge-case] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:249 — The first-push commit detection logic in getPullRequestsWithCommitStatuses uses a 1-minute tolerance heuristic with committedDate (git author date, which is committer-controlled). This is a reasonable approach given GitHub GraphQL API limitations but should be documented.

  • [edge-case] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:166 — The since parameter in getWorkflowRuns is interpolated into the URL query string without encodeURIComponent, while owner and repo are encoded. Current callers pass URL-safe ISO date strings, but applying encoding would be a trivial defensive fix.

  • [pattern-inconsistency] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsCountProvider.ts:59 — Batch providers are the first in the codebase to use the optional getMetricIds()/getMetrics()/calculateMetrics() batch interface from MetricProvider. This conforms to the interface contract but is a new pattern worth verifying consumers handle correctly.

  • [test-inadequate] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubPRLifecycleProvider.test.ts — Lifecycle test assertions use integer values (18, 24, 60) that don't exercise the one-decimal-place rounding logic. Missing test for PRs with reviews but no APPROVED reviews.

  • [missing-test] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts — GithubClient's new methods have no unit tests; all test files mock the entire class. This follows the existing convention but leaves the API integration layer (query construction, response parsing, pagination) untested.

Info

  • [design-direction] The PR introduces the first use of the batch provider pattern (getMetricIds/getMetrics/calculateMetrics) from the MetricProvider interface. This is architecturally sound for metrics sharing a single API call.

  • [scope-exceeded] GithubClient.ts introduces a second credential/integration path via getRestConfig() using raw fetch() alongside the existing Octokit-based getOctokitClient(). This is pragmatically necessary since the GitHub Actions workflow runs API is REST-only.

Previous run (2)

Review

Findings

Medium

  • [logic-error] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsRatioProvider.ts:48computeSuccessRatio uses Math.round(x * 1000) / 10 producing one-decimal percentages (e.g., 79.6), but threshold expressions use integer boundaries (>=80, 50-79, <50). Verified against ThresholdEvaluator: the range operator uses a >= min && a <= max, so a value of 79.6 fails both 50-79 (79.6 > 79) and >=80 (79.6 < 80), falling through all rules and returning undefined status. Same issue exists in GithubPRPassRateProvider.ts computePassRate.
    Remediation: Use Math.round(x * 100) for integer percentages, or adjust threshold expressions to cover the full range (e.g., 50-79.9).

  • [logic-error] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:166getWorkflowRuns paginates through all GitHub Actions workflow runs without an upper bound on page count. While the loop does terminate when allRuns.length >= data.total_count, very active repositories could trigger many REST API calls per metric calculation, risking rate limit exhaustion and long response times.
    Remediation: Add a maximum page count (e.g., const MAX_PAGES = 10) and break out of the loop when reached.

Low

  • [logic-error] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:126getPullRequestsWithReviews and getPullRequestsWithCommitStatuses GraphQL queries use first: 100 without cursor-based pagination, silently dropping PRs beyond the first 100. For high-activity repos this means metrics are computed from an incomplete sample with no warning. This follows the existing pattern in getOpenPullRequestsCount.

  • [edge-case] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:248 — The heuristic to identify first-push commits in getPullRequestsWithCommitStatuses uses a 1-minute tolerance on committedDate, which can differ from push time for long-lived branches. This is a known limitation of the GitHub GraphQL API with no better alternative.

  • [api-contract] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsCountProvider.ts:41 — Multi-metric providers implement optional MetricProvider interface methods (getMetricIds, getMetrics, calculateMetrics) as required. Tests use non-null assertions (provider.calculateMetrics!(mockEntity)). Valid TypeScript but a minor style concern.

  • [error-handling-gap] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:55getRestConfig duplicates the credential-fetching logic from getOctokitClient. Both create a new DefaultGithubCredentialsProvider per call, consistent with existing patterns but increasingly visible with 10+ providers.

  • [test-inadequate] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubPRLifecycleProvider.test.ts — All test durations are exact hour multiples (12h, 24h, etc.). No test exercises the fractional-hour rounding path in computeAverageHours.

  • [test-inadequate] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsRatioProvider.test.tsfilterRunsByWindow uses new Date() internally. Tests create timestamps relative to their own new Date(), creating a theoretical (but practically unlikely) race between the two calls. Consider jest.useFakeTimers().

Info

  • [scope-alignment] All 13 new metrics match the scope requested in issue Extend the scorecard github module with some new metrics #3468. No scope creep detected.
  • [injection] All interpolated values in GraphQL queries are passed as variables (not inline). REST URL uses encodeURIComponent for owner/repo. No injection vectors found.
Previous run (3)

Review

Findings

High

  • [logic-error] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsProvider.ts:137GithubActionsProvider.getMetricThresholds() returns COUNT_THRESHOLDS (e.g., <10 = success, >50 = error), but this single threshold config is applied to ALL metrics exposed by the batch provider, including the ratio metrics (actions_success_ratio_7d and actions_success_ratio_24h) which produce percentage values (0–100). A healthy 80% success ratio would be evaluated as "error" (>50) under count thresholds. Verified against ThresholdResolver.ts and PullMetricsByProviderTask.ts: the framework resolves one ThresholdConfig per provider and applies it uniformly to all metrics in the batch. RATIO_THRESHOLDS is defined at line 38 but never returned by getMetricThresholds().
    Remediation: Split GithubActionsProvider into two separate providers (one for counts using COUNT_THRESHOLDS, one for ratios using RATIO_THRESHOLDS), or extend the MetricProvider interface to support per-metric thresholds.

Medium

  • [unbounded-loop] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:165getWorkflowRuns() paginates through ALL workflow runs with no upper bound. For very active repositories (CI-heavy monorepos) this could cause excessive API calls and memory consumption. The 7-day since parameter provides some natural bound but is insufficient for high-volume repos.
    Remediation: Add a maximum page count or total results limit.

  • [data-truncation] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:125getPullRequestsWithReviews() uses first: 100 in the GraphQL search query but does not paginate. If a repository has more than 100 PRs updated in the last 7 days, results will be silently truncated, producing inaccurate metrics. Same issue in getPullRequestsWithCommitStatuses() at line 202.
    Remediation: Implement cursor-based pagination or document the 100-PR cap as a known limitation.

  • [ssrf] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:166 — In getWorkflowRuns(), repository.owner and repository.repo are interpolated directly into a REST API URL path without encoding. A malicious catalog entity could supply a slug with path traversal characters to redirect the REST request to an unintended GitHub API endpoint, sending configured credentials to the manipulated path. See also: [unbounded-loop] and [architectural-coherence] findings at this location.
    Remediation: Apply encodeURIComponent() to both repository.owner and repository.repo.

  • [architectural-coherence] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:160getWorkflowRuns uses raw fetch() while every other method uses Octokit GraphQL. This creates two distinct credential resolution paths (getRestConfig vs getOctokitClient), introducing maintenance risk in security-adjacent code. See also: [ssrf] finding at this location.
    Remediation: Use Octokit REST API client (which shares credential management) or document why the raw fetch path is necessary.

Low

  • [logic-error] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsProvider.ts:63computeSuccessRatio() excludes runs with conclusions other than success or failure from the denominator. This is explicitly tested and intentional, but the metric description could clarify that cancelled/skipped runs are excluded.

  • [error-handling] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:167getWorkflowRuns() only checks response.ok. Does not handle rate limiting (HTTP 403 with X-RateLimit headers) or guard against non-JSON responses.

  • [edge-case] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts:243getPullRequestsWithCommitStatuses() uses a 1-minute tolerance to identify "first push" commits and assumes GitHub returns commits in chronological order (not guaranteed by API docs).

  • [test-inadequate] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsProvider.test.ts:120 — Test "should return 100% ratio when no completed runs" only tests 7d ratio but not 24h ratio.

  • [scope-accuracy] PR body claims "13 new metrics" but the change actually adds 15.

  • [naming-convention] workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/types.ts:31WorkflowRun type uses snake_case field created_at while all other types use camelCase.

  • [api-shape-pattern] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsProvider.ts:88getProviderId() returns a metric ID rather than a provider-scoped identifier. Matches existing convention but could be documented.

  • [code-organization] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsProvider.ts:196RATIO_THRESHOLDS and COUNT_THRESHOLDS exported but not imported anywhere. GithubCIPassRateProvider redefines RATIO_THRESHOLDS locally with identical values.

  • [code-organization] workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubClosedIssuesProvider.ts — Four search-count providers are nearly identical ~87-line files. A factory function could reduce duplication.

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

See the review comment for full details.

@christoph-jerolimov christoph-jerolimov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Address the following issues:

  1. GitHubActionsProvider needs to be splitted because it includes metrics that counts actions and then metrics that creates a ratio. But the MetricProvider API only supports one ThresholdConfig for all metrics, at the moment. So splitting this into two providers would allow to define the right ThresholdConfig for these metrics.
  2. GithubCIPassRateProvider should be renamed to GitHubPRPassRateProvider and the metrics should be named something like "GitHub PR CI first time pass rate (7d)". The description should also include that this is about FTPR (first time pass rate).
  3. Add unit tests for GitHubClosedIssuesProvider.ts, GitHubClosedPRsProvider.ts, GitHubOpenedIssuesProvider.ts and GitHubOpenedPRsProvider.ts

@christoph-jerolimov

Copy link
Copy Markdown
Member

/fs-fix

@fullsend-ai-coder

fullsend-ai-coder Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 12:51 PM UTC · Completed 1:10 PM UTC
Commit: 7ccaff1 · View workflow run →

fullsend-ai-coder Bot added a commit that referenced this pull request Jun 19, 2026
- Split GithubActionsProvider into GithubActionsCountProvider (with
  COUNT_THRESHOLDS) and GithubActionsRatioProvider (with
  RATIO_THRESHOLDS) so each provider gets the correct ThresholdConfig
- Rename GithubCIPassRateProvider to GithubPRPassRateProvider with
  updated metric IDs (github.pr_ci_first_time_pass_rate_*) and titles
  mentioning FTPR (first time pass rate)
- Add individual unit test files for GithubClosedIssuesProvider,
  GithubClosedPRsProvider, GithubOpenedIssuesProvider, and
  GithubOpenedPRsProvider
- Apply encodeURIComponent to owner/repo in REST URL construction

Addresses review feedback on #3472
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 1 (human-triggered)

Addressed all 3 human review requests: (1) split GithubActionsProvider into count and ratio providers with correct thresholds, (2) renamed GithubCIPassRateProvider to GithubPRPassRateProvider with FTPR naming, (3) added individual unit tests for 4 search-count providers. Also fixed SSRF vulnerability with encodeURIComponent. Disagreed with 4 bot-only findings as out of scope or unnecessary.

Fixed (4):

  1. Split GithubActionsProvider into count and ratio providers (workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubActionsProvider.ts): Split GithubActionsProvider into GithubActionsCountProvider (with COUNT_THRESHOLDS for started/successful/failed metrics) and GithubActionsRatioProvider (with RATIO_THRESHOLDS for success ratio metrics). This fixes the logic error where ratio metrics producing percentage values were evaluated against count thresholds.
  2. Rename GithubCIPassRateProvider to GithubPRPassRateProvider with FTPR naming (workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubCIPassRateProvider.ts): Renamed GithubCIPassRateProvider to GithubPRPassRateProvider. Updated metric IDs to github.pr_ci_first_time_pass_rate_7d/24h, titles to 'GitHub PR CI first time pass rate', and descriptions to mention FTPR (first time pass rate).
  3. Add unit tests for search-count providers (workspaces/scorecard/plugins/scorecard-backend-module-github/src/metricProviders/GithubClosedIssuesProvider.test.ts): Added individual unit test files for GithubClosedIssuesProvider, GithubClosedPRsProvider, GithubOpenedIssuesProvider, and GithubOpenedPRsProvider. Tests cover fromConfig with default thresholds and calculateMetric with mocked GithubClient.
  4. SSRF via unencoded owner/repo in REST URL (workspaces/scorecard/plugins/scorecard-backend-module-github/src/github/GithubClient.ts): Applied encodeURIComponent() to repository.owner and repository.repo in the getWorkflowRuns REST URL construction to prevent path traversal.

Disagreed (4):

  1. Unbounded pagination in getWorkflowRuns: The 7-day since parameter provides a natural bound. Adding an artificial page limit could silently truncate real data. This is a minor concern for a scorecard metrics provider and can be addressed in a follow-up if needed.
  2. Data truncation with first:100 in GraphQL queries: Implementing cursor-based pagination would significantly increase complexity. The 100-PR cap is a reasonable default for most repositories. This is better addressed as a separate enhancement.
  3. Architectural coherence - raw fetch vs Octokit: The GitHub Actions workflow runs API is a REST endpoint not available via GraphQL. Using raw fetch with getRestConfig is the appropriate approach. Both paths use the same credential provider.
  4. Factory function for search-count providers to reduce duplication: Out of scope for this PR. The current pattern with individual provider files is explicit and follows existing conventions in the codebase.

Tests: passed

Updated by fullsend fix agent

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 19, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 1:13 PM UTC · Completed 1:26 PM UTC
Commit: 7ccaff1 · View workflow run →

@christoph-jerolimov

Copy link
Copy Markdown
Member

/fs-fix inspect and fix e2e playwright tests

@fullsend-ai-coder

fullsend-ai-coder Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Fix · ❌ Terminated · Started 6:50 AM UTC · Ended 8:25 AM UTC
Commit: c0783eb · View workflow run →

fullsend-ai-coder Bot added a commit that referenced this pull request Jun 20, 2026
- Split GithubActionsProvider into GithubActionsCountProvider (with
  COUNT_THRESHOLDS) and GithubActionsRatioProvider (with
  RATIO_THRESHOLDS) so each provider gets the correct ThresholdConfig
- Rename GithubCIPassRateProvider to GithubPRPassRateProvider with
  updated metric IDs (github.pr_ci_first_time_pass_rate_*) and titles
  mentioning FTPR (first time pass rate)
- Add individual unit test files for GithubClosedIssuesProvider,
  GithubClosedPRsProvider, GithubOpenedIssuesProvider, and
  GithubOpenedPRsProvider
- Apply encodeURIComponent to owner/repo in REST URL construction

Addresses review feedback on #3472
@fullsend-ai-coder
fullsend-ai-coder Bot force-pushed the agent/3468-extend-github-metrics branch from 006906c to 5f9d7ac Compare June 20, 2026 06:50
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ❌ Failure · Started 6:50 AM UTC · Completed 8:25 AM UTC
Commit: c0783eb · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 20, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:27 AM UTC · Completed 8:40 AM UTC
Commit: c0783eb · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

See the review comment for full details.

}
}
}
`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] edge-case

The getPullRequestsWithReviews and getPullRequestsWithCommitStatuses GraphQL queries use search(first: 100) which limits results to 100 PRs. For active repositories, this silently truncates the dataset, producing inaccurate metrics. No pagination is implemented unlike getWorkflowRuns.

Suggested fix: Implement GraphQL cursor-based pagination or document the 100-item limit and add a log warning when the result count equals 100.

}>(query, {
q: fullQuery,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[medium] edge-case

getWorkflowRuns pages through all workflow runs using a while loop with no upper bound on page count or total results. High-activity repos could cause unbounded HTTP requests, memory exhaustion, and rate limit depletion.

Suggested fix: Add a maximum page count (e.g., 10 pages = 1000 runs) to cap the loop.

fullsend-ai-coder Bot added a commit that referenced this pull request Jul 28, 2026
Rebase on main and migrate all new metric providers to the updated
MetricProvider interface from #3560. Remove deprecated single-metric
methods (getMetricType, getMetric, getMetricThresholds, calculateMetric,
getMetricIds) and use only getMetrics() with thresholds on each Metric
object and calculateMetrics() returning a Map.

All 10 test suites (37 tests) pass.

Addresses review feedback on #3472
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 7 (human-triggered)

Rebased PR branch onto latest origin/main per human instruction. Resolved one merge conflict in GithubClient.ts (combined graphql import from main with type imports from branch). All tests and type checks pass.

Fixed (1):

  1. rebase branch onto main: Rebased agent/3468-extend-github-metrics onto origin/main (43 new commits on main). Resolved one merge conflict in GithubClient.ts imports — kept both the graphql import from main and the additional type imports from the branch. All 7 branch commits replayed successfully. Tests pass (13 suites, 47 tests). TypeScript type check passes.

Tests: passed

Updated by fullsend fix agent

fullsend-ai-coder Bot added a commit that referenced this pull request Jul 28, 2026
Align all new metric provider IDs with the lowerCamelCase naming
convention established in the codebase. The providers were using
snake_case IDs which is inconsistent with the existing pattern
(e.g. github.openPRs).

Renames:
- github.open_issues -> github.openIssues
- github.opened_issues_7d -> github.openedIssues7d
- github.closed_issues_7d -> github.closedIssues7d
- github.opened_prs_7d -> github.openedPRs7d
- github.closed_prs_7d -> github.closedPRs7d
- github.time_to_review -> github.timeToReview
- github.time_to_approve -> github.timeToApprove
- github.time_to_merge -> github.timeToMerge
- github.actions_started_7d -> github.actionsStarted7d
- github.actions_successful_7d -> github.actionsSuccessful7d
- github.actions_failed_7d -> github.actionsFailed7d
- github.actions_success_ratio_7d -> github.actionsSuccessRatio7d
- github.actions_success_ratio_24h -> github.actionsSuccessRatio24h
- github.pr_ci_first_time_pass_rate_7d -> github.prCiFirstTimePassRate7d
- github.pr_ci_first_time_pass_rate_24h -> github.prCiFirstTimePassRate24h

Addresses review feedback on #3472
fullsend-ai-coder Bot added a commit that referenced this pull request Jul 28, 2026
- Fix RATIO_THRESHOLDS gap in GithubActionsRatioProvider and
  GithubPRPassRateProvider: change warning from '50-79' to '>=50'
  to prevent backend crash from uncovered threshold range
- Add cursor-based pagination to getPullRequestsWithReviews and
  getPullRequestsWithCommitStatuses GraphQL queries (max 10 pages)
- Cap getWorkflowRuns REST pagination at 10 pages to prevent
  unbounded API calls on active repos
- Update getProviderId() in all new providers to return a unique
  identifier matching the filename without the Github prefix
- Decouple metric IDs from provider IDs in single-metric providers
  by introducing METRIC_ID constants

Addresses review feedback on #3472
fullsend-ai-coder Bot added a commit that referenced this pull request Jul 28, 2026
Add explicit type annotations to `response` variables in
getPullRequestsWithReviews and getPullRequestsWithCommitStatuses.
The `cursor` variable created a circular type dependency (response
depends on cursor as argument, cursor is reassigned from response),
causing TS7022 "implicitly has type 'any'". Moving the type from a
generic parameter to a variable annotation breaks the cycle.

Addresses review feedback on #3472
@fullsend-ai-coder
fullsend-ai-coder Bot force-pushed the agent/3468-extend-github-metrics branch from c29495f to 1f85327 Compare July 28, 2026 10:20
fullsend-ai-coder Bot added a commit that referenced this pull request Jul 28, 2026
1. Remove all const METRIC_IDS / METRIC_ID and inline metric IDs directly
   into getMetrics() and calculateMetrics() calls across all new providers.

2. Split GithubActionsCountProvider thresholds: started and successful
   metrics use ACTIVITY_THRESHOLDS (Success >=0, Warning ==0), while
   failed metric keeps FAILED_COUNT_THRESHOLDS (<10/10-50/>50).

3. Switch GithubClosedIssuesProvider, GithubClosedPRsProvider,
   GithubOpenedIssuesProvider, and GithubOpenedPRsProvider to new
   INFORMATIONAL_NUMBER_THRESHOLD (info status for any value >=0)
   added to scorecard-common threshold.ts.

4. Change GithubPRLifecycleProvider duration from hours to days,
   update DURATION_THRESHOLDS to Success <7, Warning 7-14, Error >14,
   and prefix all metric titles with "GitHub PR".

Addresses review feedback on #3472
@christoph-jerolimov

Copy link
Copy Markdown
Member

/fs-fix

Change the new provider ids to be prefixed with "github." And then start with a lower case character. snakeCase

@christoph-jerolimov

Copy link
Copy Markdown
Member

/fs-fix

Change the new provider ids to be prefixed with "github." And then start with a lower case character. snakeCase

@fullsend-ai-coder

fullsend-ai-coder Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 6:38 PM UTC · Completed 6:54 PM UTC
Commit: 1f85327 · View workflow run →

fullsend-ai-coder Bot added a commit that referenced this pull request Jul 29, 2026
Convert all new metric IDs from camelCase to snake_case as requested:
- github.openIssues -> github.open_issues
- github.openedIssues7d -> github.opened_issues_7d
- github.openedPRs7d -> github.opened_prs_7d
- github.closedIssues7d -> github.closed_issues_7d
- github.closedPRs7d -> github.closed_prs_7d
- github.actionsStarted7d -> github.actions_started_7d
- github.actionsSuccessful7d -> github.actions_successful_7d
- github.actionsFailed7d -> github.actions_failed_7d
- github.actionsSuccessRatio7d -> github.actions_success_ratio_7d
- github.actionsSuccessRatio24h -> github.actions_success_ratio_24h
- github.prCiFirstTimePassRate7d -> github.pr_ci_first_time_pass_rate_7d
- github.prCiFirstTimePassRate24h -> github.pr_ci_first_time_pass_rate_24h
- github.timeToReview -> github.time_to_review
- github.timeToApprove -> github.time_to_approve
- github.timeToMerge -> github.time_to_merge

Addresses human review feedback on #3472
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 7 (human-triggered)

Renamed all 15 new GitHub metric IDs from camelCase to snake_case as requested by human reviewer. All IDs now use the format github.<snake_case_name>. Updated 19 files (10 provider source files and 9 test files). All 47 tests pass across 13 test suites.

Fixed (1):

  1. rename new GitHub metric IDs to snake_case with github. prefix: Converted all 15 new metric IDs from camelCase to snake_case per human instruction: github.openIssues->github.open_issues, github.openedIssues7d->github.opened_issues_7d, github.openedPRs7d->github.opened_prs_7d, github.closedIssues7d->github.closed_issues_7d, github.closedPRs7d->github.closed_prs_7d, github.actionsStarted7d->github.actions_started_7d, github.actionsSuccessful7d->github.actions_successful_7d, github.actionsFailed7d->github.actions_failed_7d, github.actionsSuccessRatio7d->github.actions_success_ratio_7d, github.actionsSuccessRatio24h->github.actions_success_ratio_24h, github.prCiFirstTimePassRate7d->github.pr_ci_first_time_pass_rate_7d, github.prCiFirstTimePassRate24h->github.pr_ci_first_time_pass_rate_24h, github.timeToReview->github.time_to_review, github.timeToApprove->github.time_to_approve, github.timeToMerge->github.time_to_merge. Updated all provider source files and their corresponding test files.

Tests: passed

Updated by fullsend fix agent

@christoph-jerolimov

Copy link
Copy Markdown
Member

/fs-fix rebase

@fullsend-ai-coder

fullsend-ai-coder Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 9:25 PM UTC · Completed 9:38 PM UTC
Commit: 47c4936 · View workflow run →

Extend the scorecard GitHub module with 13 new metrics across
four domains:

Issue/PR counts (5 metrics):
- Currently open issues
- Opened issues in last 7 days
- Opened PRs in last 7 days
- Closed issues in last 7 days
- Closed PRs in last 7 days

PR lifecycle timing (3 metrics, batch provider):
- Time to first review (average hours)
- Time to first approval (average hours)
- Time to merge (average hours)
All computed from PRs updated in the last 7 days.

GitHub Actions (5 metrics, batch provider):
- Started workflow runs in last 7 days
- Successfully completed runs in last 7 days
- Failed runs in last 7 days
- Success ratio for 7 days (percentage)
- Success ratio for 24 hours (percentage)
Non-terminal runs (pending/running/cancelled) are excluded
from success/failure counts and ratio calculations.

CI pass rate (2 metrics, batch provider):
- First-time CI pass rate for 7 days (percentage)
- First-time CI pass rate for 24 hours (percentage)
Checks CI status on the last commit of the first push to
each PR. PRs without CI checks are excluded.

New GithubClient methods use GraphQL for issue/PR queries
and REST API (fetch) for workflow runs. All providers follow
the existing MetricProvider pattern and are registered in the
module init. Batch providers use getMetrics/calculateMetrics
for efficient multi-metric computation.

Closes #3468
- Split GithubActionsProvider into GithubActionsCountProvider (with
  COUNT_THRESHOLDS) and GithubActionsRatioProvider (with
  RATIO_THRESHOLDS) so each provider gets the correct ThresholdConfig
- Rename GithubCIPassRateProvider to GithubPRPassRateProvider with
  updated metric IDs (github.pr_ci_first_time_pass_rate_*) and titles
  mentioning FTPR (first time pass rate)
- Add individual unit test files for GithubClosedIssuesProvider,
  GithubClosedPRsProvider, GithubOpenedIssuesProvider, and
  GithubOpenedPRsProvider
- Apply encodeURIComponent to owner/repo in REST URL construction

Addresses review feedback on #3472
Rebase on main and migrate all new metric providers to the updated
MetricProvider interface from #3560. Remove deprecated single-metric
methods (getMetricType, getMetric, getMetricThresholds, calculateMetric,
getMetricIds) and use only getMetrics() with thresholds on each Metric
object and calculateMetrics() returning a Map.

All 10 test suites (37 tests) pass.

Addresses review feedback on #3472
Align all new metric provider IDs with the lowerCamelCase naming
convention established in the codebase. The providers were using
snake_case IDs which is inconsistent with the existing pattern
(e.g. github.openPRs).

Renames:
- github.open_issues -> github.openIssues
- github.opened_issues_7d -> github.openedIssues7d
- github.closed_issues_7d -> github.closedIssues7d
- github.opened_prs_7d -> github.openedPRs7d
- github.closed_prs_7d -> github.closedPRs7d
- github.time_to_review -> github.timeToReview
- github.time_to_approve -> github.timeToApprove
- github.time_to_merge -> github.timeToMerge
- github.actions_started_7d -> github.actionsStarted7d
- github.actions_successful_7d -> github.actionsSuccessful7d
- github.actions_failed_7d -> github.actionsFailed7d
- github.actions_success_ratio_7d -> github.actionsSuccessRatio7d
- github.actions_success_ratio_24h -> github.actionsSuccessRatio24h
- github.pr_ci_first_time_pass_rate_7d -> github.prCiFirstTimePassRate7d
- github.pr_ci_first_time_pass_rate_24h -> github.prCiFirstTimePassRate24h

Addresses review feedback on #3472
- Fix RATIO_THRESHOLDS gap in GithubActionsRatioProvider and
  GithubPRPassRateProvider: change warning from '50-79' to '>=50'
  to prevent backend crash from uncovered threshold range
- Add cursor-based pagination to getPullRequestsWithReviews and
  getPullRequestsWithCommitStatuses GraphQL queries (max 10 pages)
- Cap getWorkflowRuns REST pagination at 10 pages to prevent
  unbounded API calls on active repos
- Update getProviderId() in all new providers to return a unique
  identifier matching the filename without the Github prefix
- Decouple metric IDs from provider IDs in single-metric providers
  by introducing METRIC_ID constants

Addresses review feedback on #3472
Add explicit type annotations to `response` variables in
getPullRequestsWithReviews and getPullRequestsWithCommitStatuses.
The `cursor` variable created a circular type dependency (response
depends on cursor as argument, cursor is reassigned from response),
causing TS7022 "implicitly has type 'any'". Moving the type from a
generic parameter to a variable annotation breaks the cycle.

Addresses review feedback on #3472
1. Remove all const METRIC_IDS / METRIC_ID and inline metric IDs directly
   into getMetrics() and calculateMetrics() calls across all new providers.

2. Split GithubActionsCountProvider thresholds: started and successful
   metrics use ACTIVITY_THRESHOLDS (Success >=0, Warning ==0), while
   failed metric keeps FAILED_COUNT_THRESHOLDS (<10/10-50/>50).

3. Switch GithubClosedIssuesProvider, GithubClosedPRsProvider,
   GithubOpenedIssuesProvider, and GithubOpenedPRsProvider to new
   INFORMATIONAL_NUMBER_THRESHOLD (info status for any value >=0)
   added to scorecard-common threshold.ts.

4. Change GithubPRLifecycleProvider duration from hours to days,
   update DURATION_THRESHOLDS to Success <7, Warning 7-14, Error >14,
   and prefix all metric titles with "GitHub PR".

Addresses review feedback on #3472
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 8 (human-triggered)

Rebased branch onto latest origin/main per human instruction. No conflicts. All tests pass.

Fixed (1):

  1. rebase branch onto latest main: Rebased 8 commits from agent/3468-extend-github-metrics onto latest origin/main (16 new commits on main). Rebase completed cleanly with no conflicts. All 13 test suites (47 tests) pass. TypeScript type check passes. Secret scan clean.

Tests: passed

Updated by fullsend fix agent

@fullsend-ai-coder
fullsend-ai-coder Bot force-pushed the agent/3468-extend-github-metrics branch from 47c4936 to 85e383a Compare July 29, 2026 21:38
fullsend-ai-coder Bot added a commit that referenced this pull request Jul 29, 2026
Convert all new metric IDs from camelCase to snake_case as requested:
- github.openIssues -> github.open_issues
- github.openedIssues7d -> github.opened_issues_7d
- github.openedPRs7d -> github.opened_prs_7d
- github.closedIssues7d -> github.closed_issues_7d
- github.closedPRs7d -> github.closed_prs_7d
- github.actionsStarted7d -> github.actions_started_7d
- github.actionsSuccessful7d -> github.actions_successful_7d
- github.actionsFailed7d -> github.actions_failed_7d
- github.actionsSuccessRatio7d -> github.actions_success_ratio_7d
- github.actionsSuccessRatio24h -> github.actions_success_ratio_24h
- github.prCiFirstTimePassRate7d -> github.pr_ci_first_time_pass_rate_7d
- github.prCiFirstTimePassRate24h -> github.pr_ci_first_time_pass_rate_24h
- github.timeToReview -> github.time_to_review
- github.timeToApprove -> github.time_to_approve
- github.timeToMerge -> github.time_to_merge

Addresses human review feedback on #3472
@christoph-jerolimov

Copy link
Copy Markdown
Member

/fs-fix

Drop the last commit and force push the changes to use csmelCase instead of snake_case

@fullsend-ai-coder

fullsend-ai-coder Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 4:17 AM UTC · Completed 4:31 AM UTC
Commit: 85e383a · View workflow run →

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 8 (human-triggered)

Dropped the snake_case rename commit per human instruction. All metric IDs are now lowerCamelCase as per workspace conventions. 47 tests pass. The post-script will force push the branch to exclude the dropped commit.

Fixed (1):

  1. Drop last commit and use camelCase instead of snake_case: Dropped the last commit (85e383a 'fix: rename new GitHub metric IDs to snake_case per human review') via git reset --hard HEAD~1, restoring all metric IDs to lowerCamelCase format (e.g., github.actionsStarted7d, github.openIssues, github.timeToReview). This aligns with the workspace AGENTS.md convention: 'All metric IDs use lowerCamelCase' and 'Never use snake_case for metric IDs'. All 47 tests pass across 13 test suites.

Tests: passed

Updated by fullsend fix agent

@fullsend-ai-coder
fullsend-ai-coder Bot force-pushed the agent/3468-extend-github-metrics branch from 85e383a to 8e2436f Compare July 30, 2026 04:30
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
11.9% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extend the scorecard github module with some new metrics

4 participants