ehmatthes/gh-profiler
GitHub: ehmatthes/gh-profiler
gh-profiler 是一款 GitHub 贡献者画像分析工具,通过评估用户的账号信息和近期 PR/issue 活动帮助维护者快速判断审查优先级。
Stars: 132 | Forks: 14
# gh-profiler
我们中很多人都会经历开源贡献的浪潮,其中许多新的“贡献”根本不值得去理会。gh-profiler 让你能够快速查看提交者的个人资料快照以及近期的 PR 活动。
这旨在为你提供一些快速的背景信息,让你了解在审查 PR 时应投入多少精力。它并不是为了提供立即关闭 PR 或 issue 的信号。
该工具不应标记任何出于善意努力为开源项目做贡献的人。如果你认为出现了这种情况,请提交一个 issue 并描述被标记的行为。
## 作为工具运行
如果你安装了 uv,你可以将其作为工具针对任何 GitHub 用户运行:
```
$ uvx gh-profiler --concise
GitHub user:
🟡 Some concerns found with user's profile.
🟢 No concerns found with recent PR activity.
🔴 Significant concerns found with recent issue activity.
For a more detailed report, run `gh-profiler `.
```
你可以将纯用户名(``)或完整的个人资料 URL(`https://github.com/`)作为目标传入。
这是简要输出,它能让你快速了解用户是否有表明其存在有问题的开源行为的近期活动。
完整输出会为你提供更具体的信息:
```
$ uvx gh-profiler
GitHub user:
🟡 Some concerns found with user's profile.
🟡 Account age: 6 months
🟢 Profile information:
name:
blog:
email:
Empty fields: company, location, bio
🟢 No concerns found with recent PR activity.
2 PRs opened in the last 21 days.
0 opened against repos the user owns.
0 opened against repos in publicly associated orgs.
2 opened against external repos.
🟢 1 of 2 external PRs merged in the last 21 days.
🟢 1 of 2 external PRs closed without merging in the last 21 days.
🔴 Significant concerns found with recent issue activity.
79 new issues opened in the last 21 days.
0 opened in repos the user owns.
0 opened in repos in publicly associated orgs.
79 opened in external repos.
🟢 1 external issue closed as NOT_PLANNED.
🔴 78 external issues opened with the same title:
📋 Documentation Enhancement Suggestion (70)
```
如果你在本地项目目录中工作,你可以直接提供 PR 或 issue 编号。该工具会查找 PR 或 issue,识别出提交它的用户,并生成关于该用户的报告:
```
$ uvx gh-profiler 8
Issue #8: Accept a username or an issue/ pr number.
Author: ehmatthes
🟢 Account age: 13 years
...
```
## 安装并运行
你也可以安装该项目,然后直接运行 `gh-profiler` 命令:
```
(.venv) $ pip install gh-profiler
(.venv) $ gh-profiler ehmatthes
GitHub user: ehmatthes
🟢 Account age: 13 years
...
```
安装项目后,你也可以将其作为模块运行:
```
$ python -m gh_profiler
```
## 详细输出
`-v` 或 `--verbose` 标志将打印一些用于评估标记的原因:
```
$ uv run gh-profiler -v
Flag adjusted: Set account age flag green. This user has a newer account,
but they have no other concerning activity.
Flags adjusted: Set profile info and overall profile flags green. This user has not
opened any recent PRs or issues, so they have no concerning activity.
--- Summary ---
GitHub user:
🟢 No concerns found with user's profile.
🟢 Account age: 20 minutes
🟢 Profile information:
Empty fields: name, company, blog, location, email, bio
...
```
## 简要输出
如果你只想要最简单的总结,可以传入 `--concise` 标志:
```
$ uvx gh-profiler --concise
GitHub user:
🟡 Some concerns found with user's profile.
🟢 No concerns found with recent PR activity.
🔴 Significant concerns found with recent issue activity.
For a more detailed report, run `gh-profiler `.
```
## 对近期 PR 进行批量分析
你可以通过将仓库 URL 作为目标传入,来对最近打开的 PR 运行简要分析:
```
$ uvx gh-profiler https://github.com/django/django
PR 21427: Fixed #37147 -- Fixed rendering empty values for models with db_default on primary key.
https://github.com/django/django/pull/21427
GitHub user:
🟢 No concerns found with user's profile.
...
PR 21426: Fixed #37130 -- Skip DB cache deletion when culling offset is zero.
https://github.com/django/django/pull/21426
GitHub user:
🟢 No concerns found with user's profile.
...
Comparison of gh-profiler results with final merged state:
┏━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ PR num ┃ gh-profiler ┃ Author ┃ PR link ┃
┡━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ 21427 │ 🟢🟢🟢 │ │ https://github.com/django/django/pull/21427 │
│ 21425 │ 🔴🟡🟢 │ │ https://github.com/django/django/pull/21425 │
...
│ 21416 │ 🟢🟢🟢 │ │ https://github.com/django/django/pull/21416 │
│ 21415 │ 🟡🟢🟢 │ │ https://github.com/django/django/pull/21415 │
└────────┴─────────────┴────────────┴─────────────────────────────────────────────┘
```
默认情况下,这将处理最近打开的 10 个 PR。如果你想处理不同数量,请使用 `-n` 参数:
```
$ uvx gh-profiler -n 3
```
你还可以回溯查看最近关闭的 PR,并仅请求最终的汇总表:
```
$ uv run gh-profiler https://github.com/django/django --back --table-only --redact
Fetching user profiles ..........
Comparison of gh-profiler results with final merged state:
┏━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ PR num ┃ Merged? ┃ gh-profiler ┃ Author ┃ PR link ┃
┡━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ 21428 │ 🔴 │ 🟢🟢🟢 │ │ https://github.com/django/django/pull/21428 │
│ 21423 │ 🔴 │ 🔴🟡🟢 │ │ https://github.com/django/django/pull/21423 │
│ 21197 │ 🟣 │ 🟢🟢🟢 │ │ https://github.com/django/django/pull/21197 │
...
│ 21401 │ 🟣 │ 🟢🟢🟢 │ │ https://github.com/django/django/pull/21401 │
└────────┴─────────┴─────────────┴────────────┴─────────────────────────────────────────────┘
```
## 误报
我们实施了一些检查,以确保那些没有明显参与问题行为的人不会被标记为红旗或黄旗。例如,如果一个新用户打开了一堆相同的 issue 或 PR,其账号年龄将会被标记为红旗。但是,如果一个新用户没有表现出任何其他问题行为的迹象,其账号年龄标记将被设置为绿旗。
如果你看到在没有任何明确的问题行为迹象下被标记为红旗或黄旗的例子,请考虑提交一个 issue。
## GitHub Actions
gh-profiler 可以编写一个 GitHub Action,每当你的项目有新的 PR 或 issue 被打开时,它会自动运行 `gh-profiler --concise`。你可以选择将生成的分析结果作为评论发布在新的 PR 或 issue 上,也可以让该工作流仅输出一个指向包含分析结果的 Action 日志的链接。
请看这个[实际演示](https://github.com/ehmatthes/workflow_sandbox),你可以在那里打开一个新的 issue 并查看这两种输出。
`--generate-workflow` 选项会询问你想使用哪种类型的工作流,然后会向 `.github/workflows` 写入一个 `profile_contributors.yml` 文件:
```
$ uvx gh-profiler --generate-workflow
Would you like to write the concise profile output as a comment on each new PR/issue,
or just write a link to the Actions log containing the profile output?
1) Write concise profile output as a comment.
2) Only write the link to the Actions log.
Workflow type:
...
```
## 演讲与讨论
这是与 gh-profiler 相关的演讲和讨论列表。
- PyCon US 2026 闪电演讲(视频尚未发布)
- Real Python [第 296 期](https://realpython.com/podcasts/rpp/296/#t=2296)(项目的简要概述)
## 维护
### `--redact`
用于现场演示和截图,你可以传入 `--redact` 标志。用户名和个人资料信息部分将显示 "\" 以代替身份识别信息:
```
$ uv run gh-profiler 39 --redact
Issue #39: Add a `--redact` flag
Author:
🟢 Account age: 13 years
🟢 Profile information:
name:
blog:
...
```
### 添加/修改依赖
- 通过修改 pyproject.toml 或运行 `uv add ` 来添加或修改依赖。
- 如果是开发依赖,请运行 `uv add --dev `。
- 然后运行 `uv lock`。
## 运行测试
运行除端到端测试之外的所有测试:
```
$ uv run pytest
```
端到端测试比较慢,因为它们会进行实际的 API 调用。你必须显式地运行它们:
```
$ uv run pytest tests/e2e_tests
```
有一个针对更广泛的实际用户列表运行的测试。它从不在此仓库存储的外部数据文件中提取数据,因为我们不想引起对任何特定用户的注意。在 `developer_resources/` 中有一个空的数据文件模板,供那些想要开始针对实际用户进行测试的人使用。
```
$ export PATH_ACTUAL_USERS=
$ uv run pytest developer_resources/test_actual_users.py -s
```
`-s` 标志有助于查看正在测试的每个用户账户。有关更完整的文档,请参阅 `test_actual_users.py` 中的注释。该测试可能会被移动到 `tests/e2e_tests/`,但用户名将始终保留在此仓库之外。
有一个 shell 脚本可以运行所有这些测试。它可以在 macOS 上运行,也可能在 linux 上运行,但在 Windows 上可能无法工作。
```
$ ./test_all.sh
```
## 性能分析
```
$ uv run python -m cProfile -s cumtime -m gh_profiler ehmatthes > profile.txt
```
## 风格说明
- 在编写输出消息时,请优先使用简洁的消息,而不是冗长的消息:
- 使用 "0 issues closed as NOT_PLANNED." 而不是 "0 issues have been closed as NOT_PLANNED."
## 性能基准测试
要跟踪一段时间内的整体实际性能,请使用基准测试脚本:
```
$ uv run developer_resources/benchmark.py
$ uv run developer_resources/benchmark.py
```
基准测试在以下情况时非常直接:
- 使用 `git switch` 在 main 和 dev 分支之间切换;
- 使用 Git 检出不同的 tag 和 commit。
- 使用 `uv run --python 3.14`、`uv run --python 3.14t` 等。
## 发布新版本
更新更新日志并提升版本号,然后:
```
$ uv lock
# 提交所有更改。
$ git tag vX.Y.Z
$ git push origin vX.Y.Z
$ rm -rf dist/*
$ uv build
$ uv publish
```
标签:Python, 代码审查, 安全规则引擎, 开发者分析, 开源治理, 无后门, 逆向工具