alleyinteractive / .github

https://alley.com
1 stars 1 forks source link

Apply Labels Universally #59

Closed kevinfodness closed 11 months ago

kevinfodness commented 11 months ago

Description

I would like our new default labels to be applied to all of our open source repositories plus any non-client private repos that we have (e.g., broadway, production-docs).

Use Case

As a member of the technology department, I want to be able to use consistent labeling on issues when preparing items for the tech department priorities board.

benpbolton commented 11 months ago

Using:

{
  "accessibility": {"description": "Improving the accessibility of an interface", "color": "ffffff"},
  "bug": {"description": "Something isn't working", "color": "d73a4a"},
  "ci/cd": {"description": "PR checks, deploys, automation", "color": "D1F31C"},
  "css": {"description": "Requires understanding CSS/SCSS", "color": "370936"},
  "devops": {"description": "Tooling and workflow improvements", "color": "424C47"},
  "documentation": {"description": "Improvements or additions to documentation", "color": "0075ca"},
  "elasticsearch": {"description": "Requires understanding Elasticsearch", "color": "FD2C0A"},
  "enhancement": {"description": "New feature or request", "color": "a2eeef"},
  "good first issue": {"description": "Good for newcomers", "color": "7057ff"},
  "gutenberg": {"description": "Requires understanding Gutenberg", "color": "2397C2"},
  "javascript": {"description": "Requires understanding JavaScript", "color": "168700"},
  "php": {"description": "Requires understanding PHP", "color": "435FEC"},
  "shell": {"description": "Requires understanding shell scripting", "color": "5D1D17"},
  "typescript": {"description": "Requires understanding TypeScript", "color": "0BF4A9"},
  "ux": {"description": "Designing and implementing user experience improvements", "color": "B69856"}
}

from https://github.com/alleyinteractive/production-docs/edit/main/general/department-project.md...

benpbolton commented 11 months ago

It's somewhat tedious/complex/error prone to exclude client private repos - I'll proceed updating all the labels (excepting archived), and if needed, we can go back after-the-fact and strip some labels out if needed.

benpbolton commented 11 months ago

Largely leveraged this python script:

import json
import requests

# Load repository defaults
with open("label_defaults.json", "r") as f:
    label_defaults = json.load(f)

# GitHub API token and org name
token = "SRSLY-THIS-IS-A-SECRET"
org_name = "alleyinteractive"
headers = {'Authorization': f'token {token}'}

# Initialize
repo_list_url = f"https://api.github.com/orgs/{org_name}/repos"
all_repos = []

# Pagination loop for fetching repositories
while repo_list_url:
    response = requests.get(repo_list_url, headers=headers)
    repos = response.json()
    all_repos.extend(repos)

    link_header = response.headers.get('Link', None)
    if link_header:
        links = {rel[6:-1]: url[url.index('<')+1:-1] for url, rel in
                 (link.split(';') for link in
                  link_header.split(','))}
        repo_list_url = links.get('next', None)
    else:
        repo_list_url = None

# Iterate over each repository
for repo in all_repos:
    # if the repo isn't archived...
    if not repo["archived"]:
        repo_name = repo["name"]
        # Get existing labels in the repo
        labels_url = f"https://api.github.com/repos/{org_name}/{repo_name}/labels"
        response = requests.get(labels_url, headers=headers)
        existing_labels = {label['name']: {'color': label['color'], 'description': label.get('description')} for label in response.json()}

        # Create or update labels
        for label, label_data in label_defaults.items():
            new_color = label_data["color"]
            new_description = label_data["description"]

            if label in existing_labels:
                existing_color = existing_labels[label]['color']
                existing_description = existing_labels[label].get('description')

                if existing_color != new_color or existing_description != new_description:
                    # Update label color and/or description
                    patch_url = f"https://api.github.com/repos/{org_name}/{repo_name}/labels/{label}"
                    # Output what we would change:
                    print(f"Would change {label} in {repo_name} from {existing_color} to {new_color} and from {existing_description} to {new_description}")
                    requests.patch(patch_url, headers=headers, json={"new_name": label, "color": new_color, "description": new_description})
            else:
                # Create new label
                post_url = f"https://api.github.com/repos/{org_name}/{repo_name}/labels"
                # Output what we would create:
                print(f"Would create {label} in {repo_name} with color {new_color} and description {new_description}")
                requests.post(post_url, headers=headers, json={"name": label, "color": new_color, "description": new_description})

took a long time to complete, but claims to be finished.