Generate machine-actionable reports from the information contained in a GitHub organization.
Developed using Python 3.13.0
- Create an environment variable
RR_ORG_NAME, with the name of the organization-to-scrape - Create an environment variable
RR_GITHUB_TOKEN, which should be a GitHub personal access token.- For fine-grained tokens (preferred):
- Make the organization-to-scrape the resource owner
- Provide accesss to All repositories
- Under repository permissions, provide read-only access to Metadata.
- Under organization permissions, provide read-only access to Members and Custom organization roles.
- For classic tokens (not recommended), select the scopes
repoandadmin:org
- For fine-grained tokens (preferred):
- Clone this repo to your device
- Install the libraries in
requirements.txt.
Run 01.a.scrape_governance.py. This script produces two output files:
data-out/governance.clean.json, which contains the organization snapshot. See details of this file below.data-out/governance.raw.json, which contains raw headers and data for each request made by the script to the GitHUB REST API.
Run 01.b.scrape_provenance.py. This script produces two output files:
data-out/provenance.clean.json, which contains the provenance snapshot. I haven't documented this file yet.data-out/provenance.raw.json, which contains raw headers and data for each request made by the script to the GitHUB REST API.
This file is a JSON data structure containing a snapshot of the governance of the GitHub organization. Below is a summary of the information you can find in here, using JSONPath syntax to point to different parts of the file.
$.repos[*]lists each repository of the organization. See the API documentation at List organization repositories$.repos[*].full_nameidentifies this repo by its name (<login/organization>/<repo>)$.repos[*].collaboratorslists each collaborator for this repo. See the API documentation at List repository collaborators and a guide at Repository roles for an organization$.repos[*].collaborators[*].loginidentifies this collaborator by their GitHub login name$.repos[*].collaborators[*].admincorresponds to repository role Admin$.repos[*].collaborators[*].maintaincorresponds to repository role Maintain$.repos[*].collaborators[*].pushcorresponds to repository role Write$.repos[*].collaborators[*].triagecorresponds to repository role Triage$.repos[*].collaborators[*].pullcorresponds to repository role Read
$.membersEach member of the organization. See the API documentation at List organization members and a guide at Managing membership in your organization$.members[*].loginidentifies this member via their GitHub login name$.members[*].roleidentifies their role in relation to organization resources. For instance, normal members have the rolememberand organization ownersadmin. See the API documentation at Get organization membership for a user and a guide at Roles in an organization$.members[*].stateidentifies whether user is a full-fledged member (active) or not (any other value, such aspending?). I have not managed to have a user listed as anything else than non-active, neither after (1) removing a member from the organization, (2) inviting a user to become a member (without the invite being accepted yet), (3) same as 2 but for an outside collaborator.
$.outside_collaboratorsEach outside collaborator of the organization. See the API documentation at List outside collaborators for an organization and a guide at Managing outside collaborators. To find the particular repos that an outside collaborator is collaborator of, look for (private) the repos listed under the outside collaborator or see the repos where$.repos[*].collaborators[*].loginmatches a collaborator login.$.outside_collaborators[*].loginidentifies this outside collaborator via their GitHub login name
$.teamsEach team of the organization. See the API documentation at List teams and a guide at About teams$.teams[*].ididentifies this team by its ID$.teams[*].nameidentifies this team by its name$.teams[*].parentidentifies this team's parent, if any$.teams[*].parent.ididentifies this team's parent by its ID$.teams[*].parent.nameidentifies this team's parent by its name
$.teams[*].memberslists this team's members$.teams[*].members[*].loginidentifies this team member via their GitHub login name$.teams[*].members[*].rolethe team member role, being a standard member (member) or a team maintainer (maintainer). See a guide at Assigning the team maintainer role to a team member$.teams[*].members[*].stateidentifies whether user is a full-fledged member (active) or not (any other value, such aspending?). See$.members[*].state
$.teams[*].reposlists this team's repos. See a guide at Repository roles for an organization$.teams[*].repos[*].full_nameidentifies this repo by its name (<login/organization>/<repo>)$.teams[*].repos[*].admincorresponds to repository role Admin$.teams[*].repos[*].maintaincorresponds to repository role Maintain$.teams[*].repos[*].pushcorresponds to repository role Write$.teams[*].repos[*].triagecorresponds to repository role Triage$.teams[*].repos[*].pullcorresponds to repository role Read
$.organization_rolesEach custom organization role. See the API documentation at Get all organization roles for an organization and a guide at About pre-defined organization roles$.organization_roles[*].ididentifies this organization role via its ID$.organization_roles[*].nameis the name of this organization roleall_repo_readcorresponds to All-repository read: Grants read access to all repositories in the organization.all_repo_writecorresponds to All-repository write: Grants write access to all repositories in the organization.all_repo_triagecorresponds to All-repository triage: Grants triage access to all repositories in the organization.all_repo_maintaincorresponds to All-repository maintain: Grants maintenance access to all repositories in the organization.all_repo_admincorresponds to All-repository admin: Grants admin access to all repositories in the organization.ci_cd_admincorresponds to CI/CD admin: Grants admin access to manage Actions policies, runners, runner groups, hosted compute network configurations, secrets, variables, and usage metrics for an organization.
$.organization_roles[*].teamslists teams that have this organization role$.organization_roles[*].teams[*].ididentifies this team by its ID$.organization_roles[*].teams[*].nameidentifies this team by its name
$.organization_roles[*].userslists users that have this organization role$.organization_roles[*].users[*].ididentifies this user by its ID$.organization_roles[*].users[*].loginidentifies this user by its login