Compare commits
9 Commits
docusaurus
...
list_maint
Author | SHA1 | Date | |
---|---|---|---|
|
295cb5c60a | ||
|
610111583b | ||
|
1db04e4622 | ||
|
40e8ab382c | ||
|
eee765d454 | ||
|
771c47ab99 | ||
|
405e200ca2 | ||
|
65fd33ec0e | ||
|
c4a891d425 |
28
.github/workflows/maintainers.yaml
vendored
Normal file
28
.github/workflows/maintainers.yaml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: Ping maintainers
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
maintainer_ping:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container: qmkfm/qmk_cli
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: trilom/file-changes-action@v1.2.4
|
||||
id: file_changes
|
||||
with:
|
||||
output: " "
|
||||
fileOutput: " "
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip3 install -r requirements-dev.txt
|
||||
|
||||
- name: Ping maintainers and request reviews
|
||||
shell: "bash {0}"
|
||||
run: qmk ping-maintainers --pr ${{ github.event.number }} ${{ steps.file_changes.outputs.files }}
|
2
CODEOWNERS
Normal file
2
CODEOWNERS
Normal file
@ -0,0 +1,2 @@
|
||||
* @qmk/collaborators
|
||||
/lib/python/* @qmk/python
|
@ -60,10 +60,12 @@ subcommands = [
|
||||
'qmk.cli.lint',
|
||||
'qmk.cli.list.keyboards',
|
||||
'qmk.cli.list.keymaps',
|
||||
'qmk.cli.list.maintainers',
|
||||
'qmk.cli.kle2json',
|
||||
'qmk.cli.multibuild',
|
||||
'qmk.cli.new.keyboard',
|
||||
'qmk.cli.new.keymap',
|
||||
'qmk.cli.ping.maintainers',
|
||||
'qmk.cli.pyformat',
|
||||
'qmk.cli.pytest',
|
||||
]
|
||||
|
16
lib/python/qmk/cli/list/maintainers.py
Normal file
16
lib/python/qmk/cli/list/maintainers.py
Normal file
@ -0,0 +1,16 @@
|
||||
"""List the keymaps for a specific keyboard
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
from milc import cli
|
||||
|
||||
from qmk.maintainers import maintainers
|
||||
|
||||
|
||||
@cli.argument("files", type=Path, arg_only=True, nargs='*', help="File to check")
|
||||
@cli.subcommand("List the maintainers for a file.")
|
||||
def list_maintainers(cli):
|
||||
"""List the maintainers for a file.
|
||||
"""
|
||||
for file in cli.args.files:
|
||||
cli.echo('%s: %s', file, ', '.join(maintainers(file)))
|
51
lib/python/qmk/cli/ping/maintainers.py
Normal file
51
lib/python/qmk/cli/ping/maintainers.py
Normal file
@ -0,0 +1,51 @@
|
||||
"""Generate a message to ping people responsible for one or more files.
|
||||
"""
|
||||
from pathlib import Path
|
||||
|
||||
from milc import cli
|
||||
|
||||
from qmk.maintainers import maintainers
|
||||
|
||||
|
||||
@cli.argument('--pr', type=int, arg_only=True, help="PR to send ping to (optional)")
|
||||
@cli.argument('--owner', default='qmk', arg_only=True, help="Owner for the repo (Default: qmk)")
|
||||
@cli.argument('--repo', default='qmk_firmware', arg_only=True, help="Repo to send pings to (Default: qmk_firmware)")
|
||||
@cli.argument("files", type=Path, arg_only=True, nargs='*', help="File to ping maintainers for.")
|
||||
@cli.subcommand("Ping the maintainers and request reviews for one or more files.")
|
||||
def ping_maintainers(cli):
|
||||
"""Ping the maintainers for one or more files.
|
||||
"""
|
||||
github_maintainers = set()
|
||||
github_teams = set()
|
||||
|
||||
for file in cli.args.files:
|
||||
for maintainer in maintainers(file):
|
||||
if '/' in maintainer:
|
||||
github_teams.add(maintainer)
|
||||
else:
|
||||
github_maintainers.add(maintainer)
|
||||
|
||||
if cli.args.pr:
|
||||
from ghapi.all import GhApi
|
||||
|
||||
ghapi = GhApi(owner=cli.args.owner, repo=cli.args.repo)
|
||||
pr = ghapi.pulls.get(cli.args.pr)
|
||||
|
||||
if not pr.draft:
|
||||
for team in pr.requested_teams:
|
||||
team_name = f'@{cli.args.owner}/{team.slug}'
|
||||
|
||||
if team_name in github_teams:
|
||||
cli.log.info('Found %s in reviews already, skipping', team_name)
|
||||
github_teams.remove(team_name)
|
||||
|
||||
for team in github_teams:
|
||||
cli.log.info('Requesting review from team %s', team.split('/', 1)[1])
|
||||
ghapi.pulls.request_reviewers(pull_number=cli.args.pr, team_reviewers=team.split('/', 1)[1])
|
||||
|
||||
if github_maintainers:
|
||||
ghapi.issues.create_comment(cli.args.pr, f'If you were pinged by this comment you have one or more files being changed by this PR: {" ".join(sorted(github_maintainers))}')
|
||||
|
||||
else:
|
||||
print(f'Team Reviews: {" ".join(sorted(github_teams))}')
|
||||
print(f'Individual Reviews: {" ".join(sorted(github_maintainers))}')
|
27
lib/python/qmk/maintainers.py
Normal file
27
lib/python/qmk/maintainers.py
Normal file
@ -0,0 +1,27 @@
|
||||
from pathlib import Path
|
||||
|
||||
from qmk.json_schema import json_load
|
||||
|
||||
|
||||
def maintainers(file):
|
||||
"""Yields maintainers for a file.
|
||||
"""
|
||||
from codeowners import CodeOwners
|
||||
|
||||
codeowners_file = Path('CODEOWNERS')
|
||||
codeowners = CodeOwners(codeowners_file.read_text())
|
||||
maintainers = [owner[1] for owner in codeowners.of(str(file))]
|
||||
file_dir = file if file.is_dir() else file.parent
|
||||
|
||||
cur_path = Path('.')
|
||||
|
||||
for path_part in file_dir.parts:
|
||||
cur_path = cur_path / path_part
|
||||
info_file = cur_path / 'info.json'
|
||||
if info_file.exists():
|
||||
new_info_data = json_load(info_file)
|
||||
maintainers = new_info_data.get('maintainer').replace(',', ' ').split()
|
||||
maintainers = ['@' + maintainer for maintainer in maintainers]
|
||||
|
||||
for maintainer in maintainers:
|
||||
yield '@qmk/collaborators' if maintainer == 'qmk' else maintainer
|
@ -2,7 +2,9 @@
|
||||
-r requirements.txt
|
||||
|
||||
# Python development requirements
|
||||
nose2
|
||||
codeowners
|
||||
flake8
|
||||
ghapi
|
||||
nose2
|
||||
pep8-naming
|
||||
yapf
|
||||
|
Reference in New Issue
Block a user