gitlab-project-activity.py exports projects in a GitLab group and its nested subgroups to a CSV, ordered by GitLab's most-recent-activity sort. It also displays counts by activity age. Projects shared into the group are excluded.
You need Python, python-gitlab, and a GitLab personal access token with API scope and access to the group. With uv, the dependency can be supplied without project setup:
GITLAB_TOKEN=your-token uv run python gitlab-project-activity.py https://gitlab.example.com parent/groupThe second argument can also be a group ID. Use --output activity.csv to choose a filename; otherwise the script creates projects-YYYYMMDD-HHMMSS.csv in the current directory. The URL is the GitLab instance root, not an /api/v4 URL. Run uv run python gitlab-project-activity.py --help for the command's help text.
The CSV has one row per project, with these columns:
| Column | Meaning |
|---|---|
project_id |
Numeric GitLab project ID |
path |
Full project path |
last_activity_at |
GitLab's last-activity timestamp |
repository_size_bytes |
Repository size in bytes, when available |
web_url |
Project URL |
The terminal summary reports the total and six non-overlapping buckets: last 7 days, 7–30 days, 30–90 days, 90 days–6 months, 6–12 months, and older (including projects with no activity timestamp). The cutoffs are calculated when the run starts. GitLab's activity timestamp includes creation and other activity, not only commits or merge requests. Repository size can be unavailable without Reporter access.
The script writes and flushes each page as it arrives. It never overwrites an existing output file; if the run fails or is interrupted, the CSV may contain only the pages completed so far. Remove that file or choose a new name before retrying.