Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions .github/workflows/assigner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@
with:
python-version: 3.12

- name: Fetch west.yml from pull request
- name: Fetch west.yml/Maintainer.yml from pull request
if: >
github.event_name == 'pull_request_target'
run: |
git fetch origin pull/${{ github.event.pull_request.number }}/merge
git show FETCH_HEAD:west.yml > pr_west.yml
git show FETCH_HEAD:MAINTAINERS.yml > pr_MAINTAINERS.yml

- name: west setup
if: >
Expand All @@ -53,22 +54,31 @@
git config --global user.name "Your Name"
west init -l . || true

- name: Run assignment script
env:
GITHUB_TOKEN: ${{ secrets.ZB_PR_ASSIGNER_GITHUB_TOKEN }}
run: |
FLAGS="-v"
FLAGS+=" -o ${{ github.event.repository.owner.login }}"
FLAGS+=" -r ${{ github.event.repository.name }}"
FLAGS+=" -M MAINTAINERS.yml"
if [ "${{ github.event_name }}" = "pull_request_target" ]; then
FLAGS+=" -P ${{ github.event.pull_request.number }} --updated-manifest pr_west.yml"
FLAGS+=" -P ${{ github.event.pull_request.number }} --updated-manifest pr_west.yml --updated-mantainer-file pr_MAINTAINERS.yml"
elif [ "${{ github.event_name }}" = "issues" ]; then
FLAGS+=" -I ${{ github.event.issue.number }}"
elif [ "${{ github.event_name }}" = "schedule" ]; then
FLAGS+=" --modules"
else
echo "Unknown event: ${{ github.event_name }}"
exit 1
fi
python3 scripts/set_assignees.py $FLAGS
python3 scripts/ci/set_assignees.py $FLAGS

- name: Check maintainer file changes
if: >
github.event_name == 'pull_request_target'
env:
GITHUB_TOKEN: ${{ secrets.ZB_PR_ASSIGNER_GITHUB_TOKEN }}
run: |
python ./scripts/ci/check_maintainer_changes.py \
--repo zephyrproject-rtos/zephyr MAINTAINERS.yml pr_MAINTAINERS.yml
43 changes: 0 additions & 43 deletions .github/workflows/maintainer_check.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .ruff-excludes.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1397,7 +1397,7 @@ exclude = [
"./scripts/release/bug_bash.py",
"./scripts/release/list_backports.py",
"./scripts/release/list_devicetree_bindings_changes.py",
"./scripts/set_assignees.py",
"./scripts/ci/set_assignees.py",
"./scripts/snippets.py",
"./scripts/tests/twister/conftest.py",
"./scripts/tests/twister/pytest_integration/test_harness_pytest.py",
Expand Down
4 changes: 2 additions & 2 deletions MAINTAINERS.yml
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,7 @@ Continuous Integration:
- scripts/make_bugs_pickle.py
- .checkpatch.conf
- scripts/gitlint/
- scripts/set_assignees.py
- scripts/ci/set_assignees.py
labels:
- "area: Continuous Integration"

Expand Down Expand Up @@ -3259,7 +3259,7 @@ MAINTAINERS file:
files:
- MAINTAINERS.yml
- scripts/get_maintainer.py
- scripts/set_assignees.py
- scripts/ci/set_assignees.py
- scripts/check_maintainers.py
labels:
- "area: MAINTAINER File"
Expand Down
130 changes: 128 additions & 2 deletions scripts/set_assignees.py → scripts/ci/set_assignees.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,24 @@
import sys
import time
from collections import defaultdict
from pathlib import Path

import yaml
from github import Auth, Github, GithubException
from github.GithubException import UnknownObjectException
from west.manifest import Manifest, ManifestProject

TOP_DIR = os.path.join(os.path.dirname(__file__))
sys.path.insert(0, os.path.join(TOP_DIR, "scripts"))
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from get_maintainer import Maintainers # noqa: E402

zephyr_base = os.getenv('ZEPHYR_BASE', os.path.join(TOP_DIR, '..'))
ZEPHYR_BASE = os.environ.get('ZEPHYR_BASE')
if ZEPHYR_BASE:
ZEPHYR_BASE = Path(ZEPHYR_BASE)
else:
ZEPHYR_BASE = Path(__file__).resolve().parents[2]
# Propagate this decision to child processes.
os.environ['ZEPHYR_BASE'] = str(ZEPHYR_BASE)


def log(s):
Expand Down Expand Up @@ -71,10 +79,22 @@
help="Updated manifest file to compare against current west.yml",
)

parser.add_argument(
"--updated-maintainer-file",
default=None,
help="Updated maintainer file to compare against current MAINTAINERS.yml",
)

parser.add_argument("-v", "--verbose", action="count", default=0, help="Verbose Output")

args = parser.parse_args()

def load_areas(filename: str):
with open(filename) as f:
doc = yaml.safe_load(f)
return {
k: v for k, v in doc.items() if isinstance(v, dict) and ("files" in v or "files-regex" in v)
}

def process_manifest(old_manifest_file):
log("Processing manifest changes")
Expand Down Expand Up @@ -104,6 +124,93 @@
log(f'manifest areas: {areas}')
return areas

def set_or_empty(d, key):
return set(d.get(key, []) or [])

def compare_areas(old, new, repo_fullname=None, token=None):
old_areas = set(old.keys())
new_areas = set(new.keys())

changed_areas = set()
added_areas = new_areas - old_areas
removed_areas = old_areas - new_areas
common_areas = old_areas & new_areas

print("=== Areas Added ===")
for area in sorted(added_areas):
print(f"+ {area}")

print("\n=== Areas Removed ===")
for area in sorted(removed_areas):
print(f"- {area}")

print("\n=== Area Changes ===")
for area in sorted(common_areas):
changes = []
old_entry = old[area]
new_entry = new[area]

# Compare maintainers
old_maint = set_or_empty(old_entry, "maintainers")
new_maint = set_or_empty(new_entry, "maintainers")
added_maint = new_maint - old_maint
removed_maint = old_maint - new_maint
if added_maint:
changes.append(f" Maintainers added: {', '.join(sorted(added_maint))}")
if removed_maint:
changes.append(f" Maintainers removed: {', '.join(sorted(removed_maint))}")

# Compare collaborators
old_collab = set_or_empty(old_entry, "collaborators")
new_collab = set_or_empty(new_entry, "collaborators")
added_collab = new_collab - old_collab
removed_collab = old_collab - new_collab
if added_collab:
changes.append(f" Collaborators added: {', '.join(sorted(added_collab))}")
if removed_collab:
changes.append(f" Collaborators removed: {', '.join(sorted(removed_collab))}")

# Compare status
old_status = old_entry.get("status")
new_status = new_entry.get("status")
if old_status != new_status:
changes.append(f" Status changed: {old_status} -> {new_status}")

# Compare labels
old_labels = set_or_empty(old_entry, "labels")
new_labels = set_or_empty(new_entry, "labels")
added_labels = new_labels - old_labels
removed_labels = old_labels - new_labels
if added_labels:
changes.append(f" Labels added: {', '.join(sorted(added_labels))}")
if removed_labels:
changes.append(f" Labels removed: {', '.join(sorted(removed_labels))}")

# Compare files
old_files = set_or_empty(old_entry, "files")
new_files = set_or_empty(new_entry, "files")
added_files = new_files - old_files
removed_files = old_files - new_files
if added_files:
changes.append(f" Files added: {', '.join(sorted(added_files))}")
if removed_files:
changes.append(f" Files removed: {', '.join(sorted(removed_files))}")

# Compare files-regex
old_regex = set_or_empty(old_entry, "files-regex")
new_regex = set_or_empty(new_entry, "files-regex")
added_regex = new_regex - old_regex
removed_regex = old_regex - new_regex
if added_regex:
changes.append(f" files-regex added: {', '.join(sorted(added_regex))}")
if removed_regex:
changes.append(f" files-regex removed: {', '.join(sorted(removed_regex))}")

if changes:
changed_areas.add(area)
print(f"area changed: {area}")

return added_areas | removed_areas | changed_areas

def process_pr(gh, maintainer_file, number):
gh_repo = gh.get_repo(f"{args.org}/{args.repo}")
Expand All @@ -128,6 +235,7 @@
# areas where assignment happens if only said areas are affected
meta_areas = ['Release Notes', 'Documentation', 'Samples', 'Tests']

additional_reviews = set()
for changed_file in fn:
num_files += 1
log(f"file: {changed_file.filename}")
Expand All @@ -142,6 +250,22 @@
area_match = maintainer_file.name2areas(_area)
if area_match:
areas.extend(area_match)
elif changed_file.filename in ['MAINTAINERS.yml']:
areas = maintainer_file.path2areas(changed_file.filename)
if args.updated_maintainer_file:
log(
"No updated maintainer file, cannot process MAINTAINERS.yml changes, skipping..."

Check failure on line 257 in scripts/ci/set_assignees.py

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

Python lint error (E501) see https://docs.astral.sh/ruff/rules/line-too-long

scripts/ci/set_assignees.py:257 Line too long (101 > 100)
)

old_areas = load_areas(args.updated_maintainer_file)
new_areas = load_areas('MAINTAINERS.yml')
changed_areas = compare_areas(old_areas, new_areas)
for _area in changed_areas:
area_match = maintainer_file.name2areas(_area)
if area_match:
# get list of maintainers for changed area
additional_reviews.update(maintainer_file.areas[_area].maintainers)
log(f"MAINTAINERS.yml changed, adding reviewrs: {additional_reviews}")
else:
areas = maintainer_file.path2areas(changed_file.filename)

Expand Down Expand Up @@ -183,6 +307,8 @@
collab += maintainer_file.areas[area.name].maintainers
collab += maintainer_file.areas[area.name].collaborators
collab = list(dict.fromkeys(collab))
# add more reviewers based on maintainer file changes.
collab += list(additional_reviews)
log(f"collab: {collab}")

_all_maintainers = dict(
Expand Down
2 changes: 1 addition & 1 deletion scripts/ci/twister_ignore.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Add one pattern per line.

Check warning on line 1 in scripts/ci/twister_ignore.txt

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

Copyright missing

scripts/ci/twister_ignore.txt:1 File has no SPDX-FileCopyrightText header, consider adding one.

Check warning on line 1 in scripts/ci/twister_ignore.txt

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

License missing

scripts/ci/twister_ignore.txt:1 File has no SPDX-License-Identifier header, consider adding one.
#
# The patterns listed in this file will be compared with the list of files
# changed in a patch series (Pull Request) and if all files in the pull request
Expand Down Expand Up @@ -52,7 +52,7 @@
scripts/ci/pylintrc
scripts/footprint/*
scripts/make_bugs_pickle.py
scripts/set_assignees.py
scripts/ci/set_assignees.py
scripts/gitlint/zephyr_commit_rules.py
scripts/west_commands/runners/canopen_program.py
scripts/ci/check_maintainer_changes.py
Expand Down
Loading