[PATCH b4 12/12] Add local CI review check
Tamir Duberstein <[email protected]>
| Newsgroups | org.kernel.linux.tools |
|---|---|
| Message-ID | <[email protected]> |
Configure b4's review TUI to run the project's local checks as a per-series check command. The helper emits the JSON shape expected by b4 and records the input message headers so results show which series was checked. Signed-off-by: Tamir Duberstein <[email protected]> --- .b4-config | 1 + misc/b4-ci.py | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/.b4-config b/.b4-config index ea95e4a..9fcebab 100644 --- a/.b4-config +++ b/.b4-config @@ -5,3 +5,4 @@ send-series-cc = Konstantin Ryabitsev <[email protected]> send-endpoint-web = https://lkml.kernel.org/_b4_submit send-prefixes = b4 + review-series-check-cmd = uv run --all-extras completion --all-groups python misc/b4-ci.py diff --git a/misc/b4-ci.py b/misc/b4-ci.py new file mode 100644 index 0000000..c65863c --- /dev/null +++ b/misc/b4-ci.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +"""Run b4's local CI checks for the review TUI.""" + +import json +import subprocess +import sys +from email.parser import BytesParser +from email.policy import default +from typing import Dict, List + +CHECKS = [ + ('ruff', ['ruff', 'check', '.']), + ('mypy', ['mypy', '.']), + ('pyright', ['pyright', '.']), + ('ty', ['ty', 'check', '.']), + ('pytest', ['pytest', '--durations=20']), +] + + +def read_input_details() -> List[str]: + msg = BytesParser(policy=default).parse(sys.stdin.buffer, headersonly=True) + details: List[str] = [] + if subject := msg.get('Subject'): + details.append(f'Input-Subject: {subject}') + if msgid := msg.get('Message-ID'): + details.append(f'Input-Message-ID: {msgid}') + return details + + +def run_check(tool: str, cmd: List[str], input_details: List[str]) -> Dict[str, str]: + proc = subprocess.run(cmd, capture_output=True, text=True, check=False) + details = [f'$ {" ".join(cmd)}'] + if input_details: + details.extend(['', *input_details]) + if proc.stdout: + details.extend(['', proc.stdout.rstrip()]) + if proc.stderr: + details.extend(['', proc.stderr.rstrip()]) + + return { + 'tool': tool, + 'status': 'pass' if proc.returncode == 0 else 'fail', + 'summary': 'passed' if proc.returncode == 0 else f'failed with exit code {proc.returncode}', + 'details': '\n'.join(details), + } + + +def main() -> None: + input_details = read_input_details() + results = [run_check(tool, cmd, input_details) for tool, cmd in CHECKS] + json.dump(results, sys.stdout, indent=2) + sys.stdout.write('\n') + + +if __name__ == '__main__': + main() -- 2.53.0