Skip to content

feat: collect issues, reviews and opened-PR contribution stats#232

Merged
Progi1984 merged 7 commits into
PrestaShop:masterfrom
PrestaEdit:feat/contribution-stats
Jun 29, 2026
Merged

feat: collect issues, reviews and opened-PR contribution stats#232
Progi1984 merged 7 commits into
PrestaShop:masterfrom
PrestaEdit:feat/contribution-stats

Conversation

@PrestaEdit

Copy link
Copy Markdown
Contributor

Summary

Adds collection of three new contribution metrics to feed the TopContributors site (which already has the UI ready to display them):

  • traces:fetch:issuesgh_issues.json — every org repo's issues (GraphQL issues connection, which natively excludes pull requests).
  • traces:fetch:pullrequests:allgh_pullrequests_all.json — all pull requests (any state) with their reviewers, in a single pass (page size 25 to stay under GraphQL node limits given the reviews sub-query). Reviewers are de-duplicated per PR.
  • traces:generate:topstats — aggregates the two raw files, enriches contributors_prs.json with three per-contributor counters, and writes three pre-sorted leaderboard files (top_reviewers.json, top_issues.json, top_pullrequests.json).

Metric definitions

  • reviews = number of distinct PRs a person reviewed (self-reviews excluded; counted even when the PR author is a deleted/null account).
  • pullRequestsOpened = all PRs the person authored, any state.
  • issuesOpened = all issues the person authored (PRs excluded).

Identity for reviewers/reporters not already in contributors_prs.json is resolved via getUser (cached). Bot exclusions (config) and null authors are respected. Aggregation runs over all org repos, all history — consistent with the existing stats.

The aggregation core is a pure static method (GenerateTopStatsCommand::aggregate) so it can be verified without hitting the API.

Test Plan

  • phpstan analyse[OK] No errors (level 6)
  • php-cs-fixer fix --dry-run --diff — no diff
  • Offline aggregation assertion (distinct-PR reviews, self-review excluded, null-author handling) passes
  • All three commands registered in bin/console; Makefile generate/clean and README updated
  • Live run against GitHub with a token on a small repo (e.g. -r decimal), then full make generate

🤖 Generated with Claude Code

PrestaEdit and others added 6 commits June 29, 2026 10:25
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Aggregates issues + all-state PRs into per-contributor counters (reviews =
distinct PRs reviewed with self-review excluded, issuesOpened, pullRequestsOpened),
enriches contributors_prs.json, and writes the three ranking files. Reviews count
on every PR regardless of (possibly null) author; only PR/issue author counts skip
null authors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread src/Command/FetchIssuesCommand.php Outdated
];
}

file_put_contents(self::FILE_ISSUES, json_encode($issues, JSON_PRETTY_PRINT));

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.

you can write the file after the while

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 8901525 — the file is now written once after the pagination loop.

];
}

file_put_contents(self::FILE_PULLREQUESTS_ALL, json_encode($pullRequests, JSON_PRETTY_PRINT));

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.

idem

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 8901525 — same here, written after the loop.

Comment thread src/Command/GenerateTopStatsCommand.php Outdated
Comment on lines +34 to +39
$requiredFiles = [
self::FILE_PULLREQUESTS_ALL => 'traces:fetch:pullrequests:all',
self::FILE_ISSUES => 'traces:fetch:issues',
self::FILE_CONTRIBUTORS_PRS => 'traces:generate:topcompanies',
];
foreach ($requiredFiles as $required => $command) {

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.

Suggested change
$requiredFiles = [
self::FILE_PULLREQUESTS_ALL => 'traces:fetch:pullrequests:all',
self::FILE_ISSUES => 'traces:fetch:issues',
self::FILE_CONTRIBUTORS_PRS => 'traces:generate:topcompanies',
];
foreach ($requiredFiles as $required => $command) {
foreach ([
self::FILE_PULLREQUESTS_ALL => 'traces:fetch:pullrequests:all',
self::FILE_ISSUES => 'traces:fetch:issues',
self::FILE_CONTRIBUTORS_PRS => 'traces:generate:topcompanies',
] as $required => $command) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 8901525 — inlined the map directly in the foreach.

Comment thread src/Command/GenerateTopStatsCommand.php Outdated
/** @var array<string, mixed> $contributors */
$contributors = json_decode(file_get_contents(self::FILE_CONTRIBUTORS_PRS) ?: '', true);

$aggregate = self::aggregate($pullRequests, $issues);

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.

Doesn't need to have a static function

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 8901525 — aggregate() is now a plain (non-static) method.

Comment thread .gitignore Outdated
Comment on lines +26 to +28

# Superpowers workflow docs (kept local only)
docs/superpowers/

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.

Suggested change
# Superpowers workflow docs (kept local only)
docs/superpowers/

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed in 8901525.

@Progi1984 Progi1984 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.

Some feedbacks

- fetch:issues / fetch:pullrequests:all: write the output file once after the
  pagination loop instead of on every page
- generate:topstats: inline the required-files map in the foreach
- generate:topstats: aggregate() is a plain (non-static) method
- drop the docs/superpowers gitignore entry

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Progi1984
Progi1984 merged commit a3ca10d into PrestaShop:master Jun 29, 2026
3 checks passed
@github-project-automation github-project-automation Bot moved this from Ready for review to Merged in PR Dashboard Jun 29, 2026
Progi1984 pushed a commit to PrestaShop/TopContributors that referenced this pull request Jun 30, 2026
Add three new "Top" leaderboards (reviewers, issue reporters, PR authors)
alongside the existing contributors/companies sections, driven by a shared
ranking data contract.

- types: RankingEntry / Ranking + reviews / issuesOpened / pullRequestsOpened
  counters on Contributor
- TopRankingView: reusable leaderboard card built on the existing TopCard
  (rank medal, avatar, name, count column, GitHub profile link)
- app.vue / TopSectionView: fetch the three ranking files and render a card
  per metric, hidden when its ranking is empty
- deterministic mock-data generator (scripts/generate-mock-stats.mjs) so the
  UI can be reviewed before the data pipeline lands
- vitest coverage for the new components

Note: ranking data is currently mocked. Real data comes from the Traces
pipeline — see PrestaShop/traces#232.

🤖 Generated with Claude Code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants