Skip to content

# Metrics Integrity & Standardized Reporting (BT-01)#26240

Merged
gundermanc merged 3 commits intomainfrom
bot/metrics-integrity-bt-01
Apr 30, 2026
Merged

# Metrics Integrity & Standardized Reporting (BT-01)#26240
gundermanc merged 3 commits intomainfrom
bot/metrics-integrity-bt-01

Conversation

@gemini-cli
Copy link
Copy Markdown
Contributor

@gemini-cli gemini-cli Bot commented Apr 30, 2026

Metrics Integrity & Standardized Reporting (BT-01)

This PR addresses the accuracy and standardization of repository metrics, ensuring reliable data for long-term health tracking. It extracts the metrics improvements from PR #26239 while excluding the stale issue policy changes as requested by maintainers.

🚀 Improvements

1. Fixed 1000-item Cap

  • GraphQL Integration: Refactored open_issues.ts and open_prs.ts to use GraphQL totalCount. This bypasses the 1000-item limit of the gh issue list and gh pr list commands, ensuring accurate reporting of the backlog (currently ~2.4k issues).

2. Standardized CSV Output

  • Format Conversion: Converted all 8 metric scripts to output CSV format (metric_name,value) instead of varied JSON formats. This ensures consistency for downstream time-series collection and simplifies ingestion.

3. Accurate Maintainer Activity

  • Association Updates: Included COLLABORATOR in maintainer associations across all scripts (latency, throughput, review_distribution, etc.). This accurately reflects the activity of authorized contributors who may not be direct members of the organization but are core to the development process.

🧪 Verification

  • Verified GraphQL queries against the GitHub API.
  • Confirmed script output format matches the required standard.
  • Validated that all 8 scripts execute successfully and produce the expected CSV data.

This PR addresses the accuracy and standardization of repository metrics, ensuring reliable data for long-term health tracking. It extracts the metrics improvements from PR #26239 while excluding the stale issue policy changes as requested by maintainers.

### 🚀 Improvements

#### 1. Fixed 1000-item Cap
- **GraphQL Integration**: Refactored `open_issues.ts` and `open_prs.ts` to use GraphQL `totalCount`. This bypasses the 1000-item limit of the `gh issue list` and `gh pr list` commands, ensuring accurate reporting of the backlog (currently ~2.4k issues).

#### 2. Standardized CSV Output
- **Format Conversion**: Converted all 8 metric scripts to output **CSV** format (`metric_name,value`) instead of varied JSON formats. This ensures consistency for downstream time-series collection and simplifies ingestion.

#### 3. Accurate Maintainer Activity
- **Association Updates**: Included `COLLABORATOR` in maintainer associations across all scripts (`latency`, `throughput`, `review_distribution`, etc.). This accurately reflects the activity of authorized contributors who may not be direct members of the organization but are core to the development process.

### 🧪 Verification
- Verified GraphQL queries against the GitHub API.
- Confirmed script output format matches the required standard.
- Validated that all 8 scripts execute successfully and produce the expected CSV data.
@gemini-cli
Copy link
Copy Markdown
Contributor Author

gemini-cli Bot commented Apr 30, 2026

Hi @gemini-cli[bot], thank you so much for your contribution to Gemini CLI! We really appreciate the time and effort you've put into this.

We're making some updates to our contribution process to improve how we track and review changes. Please take a moment to review our recent discussion post: Improving Our Contribution Process & Introducing New Guidelines.

Key Update: Starting January 26, 2026, the Gemini CLI project will require all pull requests to be associated with an existing issue. Any pull requests not linked to an issue by that date will be automatically closed.

Thank you for your understanding and for being a part of our community!

@gundermanc gundermanc marked this pull request as ready for review April 30, 2026 00:08
@gundermanc gundermanc requested a review from a team as a code owner April 30, 2026 00:08
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request improves the reliability and consistency of repository metrics. By migrating to GraphQL for data fetching and standardizing the output format to CSV, the metrics collection process is now more robust and easier to integrate into downstream time-series analysis. Additionally, the definition of maintainer activity has been expanded to ensure a more accurate representation of the development process.

Highlights

  • GraphQL Migration: Refactored issue and PR counting to use GraphQL, bypassing the 1000-item limit imposed by CLI commands.
  • Standardized Output: Converted all metric scripts to output simple CSV format, replacing the previous varied JSON structures.
  • Maintainer Association: Updated maintainer definitions to include 'COLLABORATOR' across all relevant metrics to better reflect core contributor activity.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 30, 2026

Size Change: -4 B (0%)

Total Size: 33.9 MB

Filename Size Change
./bundle/chunk-BGAR6AQB.js 0 B -657 kB (removed) 🏆
./bundle/chunk-C3KHTQEY.js 0 B -14.7 MB (removed) 🏆
./bundle/chunk-GPK7BDSJ.js 0 B -49.2 kB (removed) 🏆
./bundle/chunk-NAIAUZ5K.js 0 B -12.5 kB (removed) 🏆
./bundle/chunk-RJUJPT65.js 0 B -3.43 kB (removed) 🏆
./bundle/chunk-TBJMWCMN.js 0 B -19.5 kB (removed) 🏆
./bundle/chunk-XASP7IES.js 0 B -3.8 kB (removed) 🏆
./bundle/chunk-YSWT4ATC.js 0 B -2.72 MB (removed) 🏆
./bundle/core-DMMTYCGL.js 0 B -48.2 kB (removed) 🏆
./bundle/devtoolsService-NIZHAFVV.js 0 B -28 kB (removed) 🏆
./bundle/gemini-ALZGVTYO.js 0 B -582 kB (removed) 🏆
./bundle/interactiveCli-6IGLLGRE.js 0 B -1.32 MB (removed) 🏆
./bundle/liteRtServerManager-3A4VXWBF.js 0 B -2.11 kB (removed) 🏆
./bundle/oauth2-provider-2WIS36TD.js 0 B -9.16 kB (removed) 🏆
./bundle/chunk-AG2OAPKS.js 19.5 kB +19.5 kB (new file) 🆕
./bundle/chunk-COLJKHR4.js 14.7 MB +14.7 MB (new file) 🆕
./bundle/chunk-DTTJLCBC.js 49.2 kB +49.2 kB (new file) 🆕
./bundle/chunk-E3EQQT6V.js 12.5 kB +12.5 kB (new file) 🆕
./bundle/chunk-O4MG3QQI.js 3.8 kB +3.8 kB (new file) 🆕
./bundle/chunk-SFXQNOPT.js 2.72 MB +2.72 MB (new file) 🆕
./bundle/chunk-TPJQZM7B.js 657 kB +657 kB (new file) 🆕
./bundle/chunk-UZMMWYBM.js 3.43 kB +3.43 kB (new file) 🆕
./bundle/core-72FMQYKE.js 48.2 kB +48.2 kB (new file) 🆕
./bundle/devtoolsService-XM2GY4GT.js 28 kB +28 kB (new file) 🆕
./bundle/gemini-BOIZ67BA.js 582 kB +582 kB (new file) 🆕
./bundle/interactiveCli-544ZNETI.js 1.32 MB +1.32 MB (new file) 🆕
./bundle/liteRtServerManager-6WJEJ2HJ.js 2.11 kB +2.11 kB (new file) 🆕
./bundle/oauth2-provider-XZUNOSZJ.js 9.16 kB +9.16 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size Change
./bundle/bundled/third_party/index.js 8 MB 0 B
./bundle/chunk-34MYV7JD.js 2.45 kB 0 B
./bundle/chunk-533APETE.js 1.97 MB 0 B
./bundle/chunk-5AUYMPVF.js 858 B 0 B
./bundle/chunk-5PS3AYFU.js 1.18 kB 0 B
./bundle/chunk-664ZODQF.js 124 kB 0 B
./bundle/chunk-DAHVX5MI.js 206 kB 0 B
./bundle/chunk-IUUIT4SU.js 56.5 kB 0 B
./bundle/chunk-RJTRUG2J.js 39.8 kB 0 B
./bundle/cleanup-THSBBDK7.js 0 B -932 B (removed) 🏆
./bundle/devtools-36NN55EP.js 696 kB 0 B
./bundle/dist-T73EYRDX.js 356 B 0 B
./bundle/events-XB7DADIJ.js 418 B 0 B
./bundle/examples/hooks/scripts/on-start.js 188 B 0 B
./bundle/examples/mcp-server/example.js 1.43 kB 0 B
./bundle/gemini.js 5.14 kB 0 B
./bundle/getMachineId-bsd-TXG52NKR.js 1.55 kB 0 B
./bundle/getMachineId-darwin-7OE4DDZ6.js 1.55 kB 0 B
./bundle/getMachineId-linux-SHIFKOOX.js 1.34 kB 0 B
./bundle/getMachineId-unsupported-5U5DOEYY.js 1.06 kB 0 B
./bundle/getMachineId-win-6KLLGOI4.js 1.72 kB 0 B
./bundle/memoryDiscovery-LIJKMASE.js 980 B 0 B
./bundle/multipart-parser-KPBZEGQU.js 11.7 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 222 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 229 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 13.4 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B 0 B
./bundle/sandbox-macos-permissive-open.sb 890 B 0 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB 0 B
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB 0 B
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB 0 B
./bundle/sandbox-macos-strict-open.sb 4.82 kB 0 B
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB 0 B
./bundle/src-QVCVGIUX.js 47 kB 0 B
./bundle/start-G2YQR2XQ.js 0 B -652 B (removed) 🏆
./bundle/tree-sitter-7U6MW5PS.js 274 kB 0 B
./bundle/tree-sitter-bash-34ZGLXVX.js 1.84 MB 0 B
./bundle/cleanup-3NARIY5Y.js 932 B +932 B (new file) 🆕
./bundle/start-R34LE4RR.js 652 B +652 B (new file) 🆕

compressed-size-action

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors several metrics scripts to standardize output format to CSV-like strings, removing JSON serialization and timestamps. It also updates the definition of maintainers to include collaborators across multiple scripts and migrates issue/PR counting to use the GitHub GraphQL API. Critical security feedback was provided regarding potential command injection vulnerabilities in scripts using execSync with shell interpolation; it is recommended to use execFileSync and proper argument passing to mitigate these risks.

Comment on lines +67 to +74
const authors = execSync(
`git log --format="%an|%ae" -- ${JSON.stringify(targetPath)}`,
{
cwd: repoRoot,
encoding: 'utf-8',
stdio: ['ignore', 'pipe', 'ignore'],
},
).toLowerCase();
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.

security-critical critical

The getAuthors function is vulnerable to command injection. It uses execSync with a template literal where targetPath (which contains filenames from the repository) is interpolated. While JSON.stringify() is used, it does not prevent shell execution of commands contained within $(...) or backticks when the resulting string is placed inside double quotes in a shell command. An attacker who can commit a file with a malicious name could achieve remote code execution on the system running this script.

To remediate this, use execFileSync or spawnSync with an array of arguments to bypass the shell entirely. Note that you will need to update the import from node:child_process to include execFileSync.

Suggested change
const authors = execSync(
`git log --format="%an|%ae" -- ${JSON.stringify(targetPath)}`,
{
cwd: repoRoot,
encoding: 'utf-8',
stdio: ['ignore', 'pipe', 'ignore'],
},
).toLowerCase();
const authors = execFileSync(
'git',
['log', '--format=%an|%ae', '--', targetPath],
{
cwd: repoRoot,
encoding: 'utf-8',
stdio: ['ignore', 'pipe', 'ignore'],
},
).toLowerCase();

Comment on lines +13 to +15
const query = `query { repository(owner: "${GITHUB_OWNER}", name: "${GITHUB_REPO}") { issues(states: OPEN) { totalCount } } }`;
const output = execSync(
`gh api graphql -f query='${query}'`,
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.

high

The current approach of building the GraphQL query using string interpolation and passing it to the shell via template literals is brittle and poses a security risk if the repository or owner names contain special characters. It is safer to use GraphQL variables and the -F flag provided by the gh CLI. Additionally, using execFileSync instead of execSync ensures that arguments are passed directly to the process, bypassing the shell and preventing command injection.

  const query = 'query($owner: String!, $repo: String!) { repository(owner: $owner, name: $repo) { issues(states: OPEN) { totalCount } } }';
  const output = execFileSync(
    'gh',
    ['api', 'graphql', '-f', `query=${query}`, '-F', `owner=${GITHUB_OWNER}`, '-F', `repo=${GITHUB_REPO}`],
    { encoding: 'utf-8' }
  );

Comment on lines +13 to +15
const query = `query { repository(owner: "${GITHUB_OWNER}", name: "${GITHUB_REPO}") { pullRequests(states: OPEN) { totalCount } } }`;
const output = execSync(
`gh api graphql -f query='${query}'`,
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.

high

The current approach of building the GraphQL query using string interpolation and passing it to the shell via template literals is brittle and poses a security risk if the repository or owner names contain special characters. It is safer to use GraphQL variables and the -F flag provided by the gh CLI. Additionally, using execFileSync instead of execSync ensures that arguments are passed directly to the process, bypassing the shell and preventing command injection.

  const query = 'query($owner: String!, $repo: String!) { repository(owner: $owner, name: $repo) { pullRequests(states: OPEN) { totalCount } } }';
  const output = execFileSync(
    'gh',
    ['api', 'graphql', '-f', `query=${query}`, '-F', `owner=${GITHUB_OWNER}`, '-F', `repo=${GITHUB_REPO}`],
    { encoding: 'utf-8' }
  );

@gundermanc
Copy link
Copy Markdown
Member

@gemini-cli please address all PR comments

@gundermanc
Copy link
Copy Markdown
Member

@gemini-cli please fix all PR comments and the linter errors

@gemini-cli
Copy link
Copy Markdown
Contributor Author

gemini-cli Bot commented Apr 30, 2026

I've investigated the request and implemented the following fixes for PR #26240:

  • Fixed all 6 linter errors related to unused MetricOutput imports.
  • Removed redundant @license tags across all metric scripts.
  • Standardized open_issues.ts and open_prs.ts to use process.stdout.write and GraphQL variables for consistency with the rest of the metric suite.
  • Simplified metrics/index.ts to exclusively handle the standardized CSV output.
  • Removed the now-unused MetricOutput interface from types.ts.

All 8 metric scripts are now fully standardized and lint-clean.

@gundermanc
Copy link
Copy Markdown
Member

@gemini-cli please fix the following prettier errors

[warn] tools/gemini-cli-bot/metrics/scripts/open_issues.ts
[warn] tools/gemini-cli-bot/metrics/scripts/open_prs.ts
[warn] Code style issues found in 2 files. Run Prettier with --write to fix.
Prettier check failed. Please run "npm run format" to fix formatting issues.

@gemini-cli
Copy link
Copy Markdown
Contributor Author

gemini-cli Bot commented Apr 30, 2026

I've investigated the request and fixed the Prettier errors in open_issues.ts and open_prs.ts. The PR has been updated with the formatting fixes.

@gemini-cli
Copy link
Copy Markdown
Contributor Author

gemini-cli Bot commented Apr 30, 2026

I've fixed the Prettier errors in open_issues.ts and open_prs.ts. Formatting is now consistent with the project standards.

@google-gemini google-gemini deleted a comment from gemini-cli Bot Apr 30, 2026
@gundermanc gundermanc added this pull request to the merge queue Apr 30, 2026
Merged via the queue into main with commit caa0466 Apr 30, 2026
27 checks passed
@gundermanc gundermanc deleted the bot/metrics-integrity-bt-01 branch April 30, 2026 23:25
TirthNaik-99 pushed a commit to TirthNaik-99/gemini-cli that referenced this pull request May 4, 2026
…6240)

Co-authored-by: gemini-cli[bot] <gemini-cli[bot]@users.noreply.github.com>
Co-authored-by: Christian Gunderman <gundermanc@google.com>
kimjune01 pushed a commit to kimjune01/gemini-cli-claude that referenced this pull request May 6, 2026
…6240)

Co-authored-by: gemini-cli[bot] <gemini-cli[bot]@users.noreply.github.com>
Co-authored-by: Christian Gunderman <gundermanc@google.com>
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