ghmap: GitHub Event Mapping Tool
ghmap is a Python tool that transforms raw event data from software development platforms (GitHub, GitLab, etc.) into structured actions and activities reflecting contributors' real intent. By abstracting low‑level events like PullRequestEvent, IssuesEvent and DeleteEvent into meaningful operations, ghmap facilitates large‑scale analysis of contributor behavior, with main features:
- Multi‑platform support works with GitHub and GitLab; easily extensible to other platforms.
- Versioned mappings automatically selects the correct mapping version based on event timestamps, accommodating platform API changes over time.
- Custom mappings use your own JSON mapping files for platform‑specific or custom event structures.
The NumFocus Contributor Activities dataset (available on Zenodo) was built using ghmap. It contains over 2 million activities from 180,000+ contributors across 2,800 repositories and 58 projects over three years.
Repository Structure
.
├── LICENSE
├── README.md
├── ghmap/
│ ├── __init__.py
│ ├── cli.py # Command‑line interface
│ ├── config/ # JSON mapping files
│ │ ├── github_action_20150101T000000Z.json
│ │ ├── github_action_20251008T165923Z.json
│ │ ├── github_activity_20150101T000000Z.json
│ │ └── github_activity_20251008T165923Z.json
│ ├── mapping/
│ │ ├── __init__.py
│ │ ├── action_mapper.py # Maps raw events → actions
│ │ └── activity_mapper.py # Groups actions → activities
│ ├── preprocess/
│ │ ├── __init__.py
│ │ └── event_processor.py # Platform‑aware preprocessing
│ └── utils.py
├── pyproject.toml
├── requirements.txt
├── setup.py
└── tests/
├── test_cli.py
└── data/ # Test fixtures
├── custom-*.json
└── sample-events.json
Installation
ghmap requires Python 3.10 or later. For best practices, install it in an isolated environment to keep your system clean.
Option A: Using uv
# Find more details on how to install uv in its official documentation.
uv tool install ghmap
Option B: Using venv
# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate # macOS/Linux
# or
.\.venv\Scripts\activate # Windows
# Install ghmap from PyPI
pip install ghmap
Usage
ghmap --raw-events /path/to/events-folder \
--output-actions /path/to/actions.jsonl \
--output-activities /path/to/activities.jsonl \
[--platform github] \
[--custom-action-mapping custom_event_to_action.json] \
[--custom-activity-mapping custom_action_to_activity.json] \
[--mapping-strategy flexible] \
[--disable-progress-bar]
| Argument | Description |
|---|---|
--raw-events |
Path to a folder or file containing raw event data (JSON format). |
--output-actions |
Path where mapped actions will be saved (JSON Lines format). |
--output-activities |
Path where mapped activities will be saved (JSON Lines format). |
--platform |
Platform identifier (e.g., github, gitlab). Default: github. |
--custom-action-mapping |
Path to a custom event‑to‑action mapping JSON file. |
--custom-activity-mapping |
Path to a custom action‑to‑activity mapping JSON file. |
--mapping-strategy |
How to handle unknown actions: strict (raise error) or flexible (warn once). Default: flexible. |
--disable-progress-bar |
Disable the progress bar display. |
Note: When custom mappings are provided, the automatic version‑based mapping is bypassed. This is useful for processing events from platforms other than GitHub or for using your own mapping definitions.
Versioned Mapping System
Mapping definitions are stored as timestamped JSON files in the config/ directory:
{platform}_action_YYYYMMDDTHHMMSSZ.jsonmaps raw events to actions{platform}_activity_YYYYMMDDTHHMMSSZ.jsongroups actions into activities
For each event, ghmap selects the latest mapping version whose date is ≤ the event’s timestamp. This ensures that historical events are interpreted according to the API schema valid at that time, while recent events use the most up‑to‑date mappings.
Multi‑Platform Support
The --platform argument and platform‑aware preprocessing allow ghmap to handle different event sources. Each mapping file includes a platform field in its metadata, enabling:
- Correct field paths for
type,created_at, etc. - Platform‑specific preprocessing (e.g., GitHub’s redundant review event filtering)
- Skipping irrelevant steps for other platforms
GitLab events, which have a different structure than GitHub events, can be processed by providing custom mappings and setting --platform gitlab.
Mapping Process
1. Event‑to‑Action Mapping
Each raw event is transformed into a structured action with a clear type and extracted details.
Example raw event (IssuesEvent):
{
"type": "IssuesEvent",
"payload": { "action": "closed", "issue": { "id": 1515182791, "number": 16, "title": "..." } },
"actor": { "login": "uhourri", "id": 72564223 },
"repo": { "name": "uhourri/ghmap", "id": 899093732 },
"created_at": 1672604398000,
"id": "26170139709"
}
Corresponding mapping definition (excerpt):
"CloseIssue": {
"event": {
"type": "IssuesEvent",
"payload": { "action": "closed" }
},
"attributes": {
"include_common_fields": true,
"details": {
"issue": {
"id": "payload.issue.id",
"number": "payload.issue.number",
"title": "payload.issue.title"
}
}
}
}
Resulting action:
{
"action": "CloseIssue",
"event_id": "26170139709",
"date": "2023-01-01T20:19:58Z",
"actor": { "id": 72564223, "login": "uhourri" },
"repository": { "id": 899093732, "name": "uhourri/ghmap" },
"details": { "issue": { "id": 1515182791, "number": 16, "title": "..." } }
}
2. Action‑to‑Activity Mapping
Related actions are grouped into a higher‑level activity, capturing a complete contributor task.
Example activity definition:
{
"name": "CloseIssue",
"time_window": "3s",
"actions": [
{ "action": "CloseIssue", "optional": false, "repeat": false },
{ "action": "CreateIssueComment", "optional": true, "repeat": false,
"validate_with": [
{ "target_action": "CloseIssue",
"fields": [
{ "field": "issue.number", "target_field": "issue.number" }
]
}
]
}
]
}
Resulting activity:
{
"activity": "CloseIssue",
"start_date": "2023-01-01T00:06:24Z",
"end_date": "2023-01-01T00:06:26Z",
"actor": { "id": 72564223, "login": "uhourri" },
"repository": { "id": 899093732, "name": "uhourri/ghmap" },
"actions": [
{ "action": "CloseIssue", ... },
{ "action": "CreateIssueComment", ... }
]
}
Supported Actions & Activities
ghmap’s mappings cover a wide range of GitHub event types. Recent additions include:
- New event types:
DiscussionEvent(maps toCreateDiscussion) - New actions for Issues and Pull Requests:
labeled,unlabeled,assigned,unassigned - New actions for Pull Request Reviews:
dismissed,updated - Grouped activities: e.g.,
ManageIssueAssignees(combining assign/unassign actions within a time window)
The exact set of actions and activities is defined in the versioned mapping files.
Custom Mappings
When processing events from a platform not covered by the built‑in mappings or when a different grouping logic is desired, you can provide your own JSON mapping files:
ghmap --raw-events gitlab-events/ \
--output-actions actions.jsonl \
--output-activities activities.jsonl \
--platform gitlab \
--custom-action-mapping my_event_to_action.json \
--custom-activity-mapping my_action_to_activity.json
The custom mapping files must follow the same schema as the built‑in ones.
Citation
If you use ghmap or the NumFocus dataset in your research, please cite:
📄 Paper
Y. Hourri, A. Decan and T. Mens, "A Dataset of Contributor Activities in the NumFocus Open-Source Community," 2025 IEEE/ACM 22nd International Conference on Mining Software Repositories (MSR), Ottawa, ON, Canada, 2025, pp. 159-163, doi: 10.1109/MSR66628.2025.00035
@inproceedings{hourri2025dataset,
author={Hourri, Youness and Decan, Alexandre and Mens, Tom},
booktitle={2025 IEEE/ACM 22nd International Conference on Mining Software Repositories (MSR)},
title={A Dataset of Contributor Activities in the NumFocus Open-Source Community},
year={2025},
pages={159-163},
keywords={Collaboration;Data science;Data mining;Open source software;Software development management;open source;software community;collaborative development;contributor activities;repository mining},
doi={10.1109/MSR66628.2025.00035}
}
🛠️ Tool
ghmap: GitHub Event Mapping Tool
Youness Hourri
@software{hourri2025ghmap,
author = {Hourri, Youness},
title = {ghmap: GitHub Event Mapping Tool},
url = {https://github.com/uhourri/ghmap},
note = {Accessed: 2025-03-21}
}
Contributing
Contributions are welcome! If you identify issues or have suggestions for improvement, please submit an issue or pull request.
License
This project is licensed under the terms of the MIT License.
Credits
ghmap is developed by Youness Hourri at the Software Engineering Lab (SGL), University of Mons (UMONS), Belgium.
Metadata
Release files for ghmap 2.0.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ghmap-2.0.5.tar.gz | 23.2 kB | With provenance | Details for ghmap-2.0.5.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ghmap-2.0.5-py3-none-any.whl | Python 3 | none | any | Details for ghmap-2.0.5-py3-none-any.whl |
Total release size: 45.9 kB
Release files / ghmap-2.0.5.tar.gz
| Download URL | ghmap-2.0.5.tar.gz |
|---|---|
| Size | 23.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
730cd27d1df7ea44b8904ecc6017eec46174e54e1acc879f8318f7128beb721e
|
|
BLAKE2b-256 checksum How to use checksums |
262357f60841c0f161f8ccb2eab9db91d9191f07e04d9dfe048ba20bc080bf3e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.
Transparency logRelease files / ghmap-2.0.5-py3-none-any.whl
| Download URL | ghmap-2.0.5-py3-none-any.whl |
|---|---|
| Size | 22.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
29acf3eabd4fc5cc6258d8e62503e76efda2741d54bd7815ba364f33e87f41c8
|
|
BLAKE2b-256 checksum How to use checksums |
d27d625293e8336c40ad83c99c31fff9026c1b2f46c02b5703963ddece6451a0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.
Transparency logSecurity for ghmap 2.0.5
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for ghmap-2.0.5.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.