Skip to content

Commit 48bd193

Browse files
committed
ci: check_maintainer_changes: warn instead of fail, annotate PR
When added maintainers or collaborators lack the required GitHub access level, emit GitHub Actions workflow-command annotations (::warning) instead of failing the check, so it is purely informational and does not block merging. Annotations follow the same pattern used by check_compliance.py's annotate() function: ::warning file=MAINTAINERS.yml,line=N,title=... GitHub Actions resolves these against the PR diff and renders them inline for lines that appear in the changed file. For users not found in the file a warning without a line number is emitted. The canonical file path MAINTAINERS.yml (derived from the base-file argument) is used as the annotation file= value. Previously the temp file pr_MAINTAINERS.yml was used, which GitHub could not match to any path in the PR diff, so no inline annotations were shown. Update assigner.yml to use python3 and drop the now-unneeded --pr argument. Signed-off-by: Anas Nashif <anas.nashif@intel.com>
1 parent 22ebd56 commit 48bd193

2 files changed

Lines changed: 48 additions & 34 deletions

File tree

.github/workflows/assigner.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ jobs:
2525
runs-on: ubuntu-24.04
2626
permissions:
2727
issues: write # to add assignees to issues
28+
pull-requests: write # posting comments when new users being added.
2829

2930
steps:
3031
- name: Check out source code
@@ -84,5 +85,6 @@ jobs:
8485
env:
8586
GITHUB_TOKEN: ${{ secrets.ZB_PR_ASSIGNER_GITHUB_TOKEN }}
8687
run: |
87-
python ./scripts/ci/check_maintainer_changes.py \
88-
--repo zephyrproject-rtos/zephyr MAINTAINERS.yml pr_MAINTAINERS.yml
88+
python3 ./scripts/ci/check_maintainer_changes.py \
89+
--repo zephyrproject-rtos/${{ github.event.repository.name }} \
90+
MAINTAINERS.yml pr_MAINTAINERS.yml

scripts/ci/check_maintainer_changes.py

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def set_or_empty(d, key):
2424

2525

2626
def check_github_access(usernames, repo_fullname, token):
27-
"""Check if each username has at least Triage access to the repo."""
27+
"""Check if each username has at least Write access to the repo."""
2828
gh = Github(auth=Auth.Token(token))
2929
missing_access = set(usernames)
3030
try:
@@ -40,6 +40,24 @@ def check_github_access(usernames, repo_fullname, token):
4040
return missing_access
4141

4242

43+
def _esc(msg: str) -> str:
44+
return msg.replace('%', '%25').replace('\n', '%0A').replace('\r', '%0D')
45+
46+
47+
def annotate(severity, title, file, line, message):
48+
"""
49+
Emit a GitHub Actions workflow command annotation.
50+
https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions
51+
"""
52+
msg = _esc(message)
53+
notice = (
54+
f'::{severity} file={file}'
55+
+ (f',line={line}' if line is not None else '')
56+
+ f',title={title}::{msg}'
57+
)
58+
print(notice)
59+
60+
4361
def compare_areas(old, new, repo_fullname=None, token=None):
4462
old_areas = set(old.keys())
4563
new_areas = set(new.keys())
@@ -158,40 +176,34 @@ def compare_areas(old, new, repo_fullname=None, token=None):
158176
else:
159177
print("Some added maintainers or collaborators do not have sufficient access.")
160178

161-
# --- GitHub Actions inline annotation ---
162-
# Try to find the line number in the new file for each missing user
163-
def find_line_for_user(yaml_file, user_set):
164-
"""Return a dict of user -> line number in yaml_file for missing users."""
165-
user_lines = {}
166-
try:
167-
with open(yaml_file) as f:
168-
lines = f.readlines()
169-
for idx, line in enumerate(lines, 1):
170-
for user in user_set:
171-
if user in line:
172-
user_lines[user] = idx
173-
return user_lines
174-
except Exception:
175-
return {}
176-
179+
# Find the line number in the new file for each missing user
177180
all_missing_users = missing_maint | missing_collab
178-
user_lines = find_line_for_user(args.new, all_missing_users)
179-
180-
for user, line in user_lines.items():
181-
print(
182-
f"::error file={args.new},line={line},title=User lacks access::"
183-
f"{user} does not have needed access level to {repo_fullname}"
184-
)
185-
186-
# For any missing users not found in the file, print a general error
187-
for user in sorted(all_missing_users - set(user_lines)):
188-
print(
189-
f"::error title=User lacks access::{user} does not have needed "
190-
f"access level to {repo_fullname}"
181+
user_lines = {}
182+
try:
183+
with open(args.new) as f:
184+
lines = f.readlines()
185+
for idx, line in enumerate(lines, 1):
186+
for user in all_missing_users:
187+
if user in line and user not in user_lines:
188+
user_lines[user] = idx
189+
except OSError:
190+
pass
191+
192+
# Use the canonical repo path (MAINTAINERS.yml) so GitHub Actions
193+
# can resolve the annotation to the correct file in the PR diff.
194+
canonical = os.path.basename(args.old)
195+
196+
for user in sorted(all_missing_users):
197+
line = user_lines.get(user)
198+
annotate(
199+
"warning",
200+
"User lacks access",
201+
canonical,
202+
line,
203+
f"{user} does not have the required access level to {repo_fullname}. "
204+
"This is a warning only and does not block merging.",
191205
)
192206

193-
sys.exit(1)
194-
195207

196208
def main():
197209
parser = argparse.ArgumentParser(

0 commit comments

Comments
 (0)