Skip to content

Commit

Permalink
feat(CI): Add a new task to automatically assign a team label on a de…
Browse files Browse the repository at this point in the history
…pendabot PR. Add an associated workflow to assign at PR creation
  • Loading branch information
chouetz committed Jan 9, 2024
1 parent 51a1be1 commit f77fd6a
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 1 deletion.
28 changes: 28 additions & 0 deletions .github/workflows/assign-dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Assign Dependabot PRs

on:
pull_request:

jobs:
label_pr:
if: github.actor == 'dependabot[bot]'
permissions:
pull-requests: write
env:
GH_TOKEN: ${{ github.token }}
PR_ID: ${{ github.event.number }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: "pip"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Add label according to modified dependency
run: |
invoke add-team-label --pr-id $PR_ID
2 changes: 2 additions & 0 deletions tasks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
updater,
vscode,
)
from .assign_pr import add_team_labels
from .build_tags import audit_tag_impact, print_default_build_tags
from .components import lint_components, lint_fxutil_oneshot_test
from .fuzz import fuzz
Expand Down Expand Up @@ -123,6 +124,7 @@
ns.add_task(go_fix)
ns.add_task(build_messagetable)
ns.add_task(modules.go_work)
ns.add_task(add_team_labels)

ns.add_task(get_modified_packages)
ns.add_task(send_unit_tests_stats)
Expand Down
79 changes: 79 additions & 0 deletions tasks/assign_pr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import json
import os
import re
from collections import Counter

from invoke import task

from tasks.libs.pipeline_notifications import read_owners


@task
def add_team_labels(ctx, pr_id):
"""
Add team labels to a PR based on the changed dependencies
"""

codeowners = read_owners(".github/CODEOWNERS")

# Get what was changed according to PR title
title_words = ctx.run(f"gh pr view {pr_id} | head -n 1", hide=True).stdout.split()
dependency = title_words[2]
if "group" in title_words: # dependabot defines group. Currently dep name is part of the group name
group_index = title_words.index("group")
dependency = title_words[group_index - 1]
import_module = re.compile(rf"^[ \t]*\"{dependency}.*$")
folder = f"./{title_words[-1][1:]}" if title_words[-2] == "in" else "."

# Find the responsible person for each file
owners = []
for root, _, files in os.walk(folder):
if root == "./.git" or any(root.startswith(prefix) for prefix in ["./venv", "./.git/"]):
continue
for file in files:
file_path = os.path.join(root, file)
if "doc" in file_path.casefold():
continue
with open(file_path, "r") as f:
try:
for line in f:
if is_go_module(dependency):
if import_module.match(line):
owners.extend([owner[1] for owner in codeowners.of(file_path[2:])])
break
elif dependency in line:
owners.extend([owner[1] for owner in codeowners.of(file_path[2:])])
break
except UnicodeDecodeError:
continue
c = Counter(owners)
responsible = c.most_common(1)[0][0].replace('@Datadog/', '').replace('@DataDog/', '')
# Hardcode for USM as owner name does not match team label name
if responsible == "universal-service-monitoring":
responsible = "usm"

# Retrieve & assign labels
team_labels = [team["name"] for team in json.loads(ctx.run("gh label list -S team --json name", hide=True).stdout)]
try:
label = next(label for label in team_labels if responsible in label)
except StopIteration:
label = "team/agent-platform"
ctx.run(f"gh pr edit {pr_id} --remove-label \"team/triage\"")
ctx.run(f"gh pr edit {pr_id} --add-label \"{label}\"")


def is_go_module(module):
starts = [
"github.com",
"k8s.io",
"go.opentelemetry.io",
"golang.org",
"google.golang.org",
"gopkg.in",
"gotest.tools",
"go.uber.org",
"sigs.k8s.io",
]
if any(module.startswith(start) for start in starts):
return True
return False
2 changes: 1 addition & 1 deletion tasks/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def lint_components(ctx, fix=False):
current = f.read()
codeowners = '\n'.join(make_codeowners(current.splitlines(), bundles))
if fix:
with open(".github/CODEOWNERS", "w") as f:
with open(filename, "w") as f:
f.write(codeowners)
elif current != codeowners:
print(f"** {filename} differs")
Expand Down

0 comments on commit f77fd6a

Please sign in to comment.