diff --git a/.github/scripts/hip_validate_pr_description.py b/.github/scripts/hip_validate_pr_description.py new file mode 100644 index 0000000000..356e067789 --- /dev/null +++ b/.github/scripts/hip_validate_pr_description.py @@ -0,0 +1,71 @@ +import os, re, sys +from typing import List, Optional + + +def is_checkbox(line: str) -> bool: + return bool(re.match(r"^\s*-\s*\[[ xX]\]\s*.+", line)) + + +def is_checked(line: str) -> bool: + return bool(re.match(r"^\s*-\s*\[\s*[xX]\s*\]\s*.+", line)) + + +def is_comment(line: str) -> bool: + return bool(re.match(r"^\s*\s*$", line)) + + +def text_clean(lines: List[str]) -> str: + text = [line for line in lines if not is_comment(line)] + return "".join("".join(text).strip().split()) + + +def validate_section(section_name: str, lines: List[str]) -> Optional[str]: + has_checkboxes = any(is_checkbox(line) for line in lines) + if has_checkboxes: + if not any(is_checked(line) for line in lines): + return f"Section {section_name} is a checklist without selections" + return None + if not text_clean(lines): + return f"Section {section_name} is empty text section" + return None + + +def check_description(description: str) -> List[str]: + sections = [] + current_section = None + current_lines = [] + errors = [] + + for line in description.splitlines(): + header_match = re.match(r"^\s*##\s*(.+?)\s*$", line) + if header_match: + if current_section: + sections.append((current_section, current_lines)) + current_section = header_match.group(1) + current_lines = [] + elif current_section: + current_lines.append(line) + + if current_section: + sections.append((current_section, current_lines)) + + if not sections: + return ["No sections available, template is empty"] + + for section_name, section_lines in sections: + error = validate_section(section_name, section_lines) + if error: + errors.append(error) + + return errors + + +if __name__ == "__main__": + pr_description = os.getenv("PR_DESCRIPTION", "") + + errors = check_description(pr_description) + if not errors: + print("All good") + exit(0) + print("\n".join(errors)) + exit(1) diff --git a/.github/workflows/hip-validate-pr-description.yml b/.github/workflows/hip-validate-pr-description.yml new file mode 100644 index 0000000000..ad37a92fdb --- /dev/null +++ b/.github/workflows/hip-validate-pr-description.yml @@ -0,0 +1,27 @@ +name: Validate HIP PR description + +on: + pull_request: + types: [opened, edited, synchronize] + paths: + - "projects/hip/**" + - "projects/clr/**" + - "projects/hipother/**" + - "projects/hip-tests/**" + +jobs: + validate-pr-description: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Validate PR description + env: + PR_DESCRIPTION: ${{ github.event.pull_request.body }} + run: python .github/scripts/hip_validate_pr_description.py