Add documentation checks for every push and PR - #2
Conversation
There was a problem hiding this comment.
🔍 WarpFix PR Review
This pull request introduces a GitHub Actions workflow for automated documentation checks on every push and pull request. It includes a Python script that validates required documentation files, checks for empty Markdown files, and verifies the integrity of relative links.
📖 Walkthrough
The changes consist of three main components: a pull request template that outlines the documentation change requirements and a safety checklist, a Python script that performs various validation checks on Markdown files, and a GitHub Actions workflow that triggers the validation process on repository events. The workflow is configured to run on pushes and pull requests, ensuring that documentation is validated automatically, thus improving the quality and reliability of the documentation.
📁 File Changes
| File | Change | Impact |
|---|---|---|
.github/pull_request_template.md |
Added a template for pull requests that includes a summary section and a safety checklist. | 🟡 medium |
.github/scripts/check_docs.py |
Introduced a Python script that validates required documentation files, checks for empty Markdown files, and verifies relative links. | 🔴 high |
.github/workflows/documentation-checks.yml |
Created a GitHub Actions workflow to automate the documentation checks on push and pull request events. | 🔴 high |
📊 Sequence Diagram
sequenceDiagram
participant User
participant GitHub
participant Action
User->>GitHub: Push or PR
GitHub->>Action: Trigger workflow
Action->>check_docs.py: Run validation
check_docs.py-->>Action: Return results
Action-->>GitHub: Report status
GitHub-->>User: Show results
⏱ Review Effort & Risk
| Metric | Value |
|---|---|
| Effort | ███░░ 3/5 (Moderate) · ~30min |
| Risk | 🟡 MEDIUM |
Risk Factors
- Potential for false negatives in link validation
- Dependency on the correctness of the Python script
- Impact on the workflow if the script fails
Labels: documentation automation ci
💡 Key Observations
The pull request template encourages thorough documentation practices.
The Python script is dependency-free, which enhances portability.
The workflow is set to use read-only permissions, enhancing security.
🤖 Reviewed by WarpFix — AI-Powered Code Review + CI Repair · Security
| @@ -0,0 +1,15 @@ | |||
| ## Summary | |||
|
|
|||
| <!-- Explain the documentation change and why it is needed. --> | |||
There was a problem hiding this comment.
✨ Praise documentation
Great addition of a summary section to explain the documentation changes.
🤖 WarpFix
| - [ ] No victim, client, or active-case data is included | ||
| - [ ] No credentials, financial records, identity numbers, or private media are included | ||
| - [ ] New factual claims cite an authoritative source | ||
| - [ ] Official links were checked |
There was a problem hiding this comment.
✨ Praise documentation
The safety and privacy checklist is a valuable inclusion to ensure compliance.
🤖 WarpFix
| - [ ] Guidance is defensive and does not promise recovery or legal outcomes | ||
|
|
||
| ## Validation | ||
|
|
There was a problem hiding this comment.
✨ Praise documentation
Including a validation section is a good practice to ensure documentation quality.
🤖 WarpFix
| from pathlib import Path | ||
| from urllib.parse import unquote | ||
|
|
||
| ROOT = Path.cwd().resolve() |
There was a problem hiding this comment.
💅 Nitpick style
Consider adding type hints for the function return types for better clarity.
| ROOT = Path.cwd().resolve() | |
| def link_target(raw: str) -> str: |
🤖 WarpFix
| if not path.is_file(): | ||
| errors.append(f"missing required file: {relative}") | ||
|
|
||
| markdown_files = sorted( |
There was a problem hiding this comment.
bug
The script does not handle potential exceptions when reading files, which could lead to crashes.
| markdown_files = sorted( | |
| Wrap the file reading in a try-except block to handle IOError. |
🤖 WarpFix
| if not target: | ||
| continue | ||
|
|
||
| resolved = (path.parent / target).resolve() |
There was a problem hiding this comment.
logic
The regex pattern used for link matching could be improved to avoid false positives.
| resolved = (path.parent / target).resolve() | |
| Consider refining LINK_PATTERN to better match valid Markdown links. |
🤖 WarpFix
| if not resolved.exists(): | ||
| errors.append( | ||
| f"{relative}:{line_number}: broken relative link: {raw}" | ||
| ) |
There was a problem hiding this comment.
logic
The script currently does not provide detailed feedback on the types of broken links.
| ) | |
| Consider categorizing broken links into external vs internal for better debugging. |
🤖 WarpFix
|
|
||
| on: | ||
| push: | ||
| pull_request: |
There was a problem hiding this comment.
✨ Praise documentation
The use of workflow_dispatch allows for manual triggering of documentation checks, which is a great feature.
🤖 WarpFix
| group: docs-${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: |
There was a problem hiding this comment.
✨ Praise performance
Setting a timeout for the job is a good practice to prevent hanging processes.
🤖 WarpFix
| validate: | ||
| name: Validate documentation | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 5 |
There was a problem hiding this comment.
✨ Praise style
Using actions/checkout@v4 ensures that the latest version of the checkout action is used.
🤖 WarpFix
There was a problem hiding this comment.
Code Review
This pull request introduces a pull request template and a Python script (check_docs.py) to validate required documentation files and local Markdown links. The review feedback highlights three key issues in the script: an incorrect regular expression pattern that fails to match standard Markdown links, a potential IndexError when processing empty link targets, and incorrect resolution of root-relative paths which would resolve to the filesystem root instead of the repository root.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| Path("CONTRIBUTING.md"), | ||
| Path("docs/seo-metadata.md"), | ||
| ) | ||
| LINK_PATTERN = re.compile(r"!?[[^]]*](([^)]+))") |
There was a problem hiding this comment.
The regular expression is incorrect because the square brackets and parentheses are not escaped. In Python's re module, unescaped [ and ] define a character class, and unescaped ( and ) define capture groups. This causes the pattern to fail to match standard Markdown links like [text](url).
Escaping them properly ensures links are correctly identified and validated.
| LINK_PATTERN = re.compile(r"!?[[^]]*](([^)]+))") | |
| LINK_PATTERN = re.compile(r"!?\[[^\]]*\]\(([^)]+)\)") |
| def link_target(raw: str) -> str: | ||
| value = raw.strip() | ||
| if value.startswith("<") and ">" in value: | ||
| value = value[1 : value.index(">")] | ||
| else: | ||
| value = value.split(maxsplit=1)[0] | ||
| return unquote(value.split("#", 1)[0]) |
There was a problem hiding this comment.
If raw is empty or contains only whitespace (for example, an empty link like []()), value becomes "". Calling value.split(maxsplit=1)[0] will raise an IndexError: list index out of range because split() on an empty string returns an empty list, which crashes the script.
Adding an early return when value is empty prevents this crash.
| def link_target(raw: str) -> str: | |
| value = raw.strip() | |
| if value.startswith("<") and ">" in value: | |
| value = value[1 : value.index(">")] | |
| else: | |
| value = value.split(maxsplit=1)[0] | |
| return unquote(value.split("#", 1)[0]) | |
| def link_target(raw: str) -> str: | |
| value = raw.strip() | |
| if not value: | |
| return "" | |
| if value.startswith("<") and ">" in value: | |
| value = value[1 : value.index(">")] | |
| else: | |
| value = value.split(maxsplit=1)[0] | |
| return unquote(value.split("#", 1)[0]) |
| resolved = (path.parent / target).resolve() | ||
| try: | ||
| resolved.relative_to(ROOT) | ||
| except ValueError: | ||
| errors.append( | ||
| f"{relative}:{line_number}: link escapes repository: {raw}" | ||
| ) | ||
| continue |
There was a problem hiding this comment.
If a Markdown link uses a root-relative path (e.g., /docs/seo-metadata.md), path.parent / target will resolve to the root of the filesystem (e.g., /docs/seo-metadata.md on Unix-like systems) rather than the repository root. This is because pathlib.Path treats paths starting with / as absolute and discards the left-hand side.
Checking if target starts with / and resolving it relative to ROOT ensures root-relative links are validated correctly.
if target.startswith("/"):
resolved = (ROOT / target.lstrip("/")).resolve()
else:
resolved = (path.parent / target).resolve()
try:
resolved.relative_to(ROOT)
except ValueError:
errors.append(
f"{relative}:{line_number}: link escapes repository: {raw}"
)
continueThere was a problem hiding this comment.
🔍 WarpFix PR Review
This pull request introduces a GitHub Actions workflow for automated documentation checks on every push and pull request. It includes a Python script that validates required documentation files and checks for broken links in Markdown files.
📖 Walkthrough
The PR adds three main components: a pull request template that includes a safety and privacy checklist, a Python script that validates the presence of required documentation files and checks for broken links in Markdown files, and a GitHub Actions workflow that triggers these checks on every push and pull request. The workflow is designed to run with read-only permissions and includes concurrency cancellation and a timeout to ensure efficiency.
📁 File Changes
| File | Change | Impact |
|---|---|---|
.github/pull_request_template.md |
Added a template for pull requests that includes a summary section and a safety and privacy checklist. | 🟡 medium |
.github/scripts/check_docs.py |
Introduced a Python script to validate required documentation files and check for broken links in Markdown files. | 🔴 high |
.github/workflows/documentation-checks.yml |
Created a GitHub Actions workflow to automate the documentation checks on push and pull request events. | 🔴 high |
📊 Sequence Diagram
sequenceDiagram
participant User
participant GitHub
participant CI
User->>GitHub: Push or PR
GitHub->>CI: Trigger workflow
CI->>CI: Run check_docs.py
CI-->>GitHub: Report results
GitHub-->>User: Show results
⏱ Review Effort & Risk
| Metric | Value |
|---|---|
| Effort | ███░░ 3/5 (Moderate) · ~30min |
| Risk | 🟡 MEDIUM |
Risk Factors
- New automated checks may introduce false negatives/positives.
- Dependency on the correctness of the Python script for documentation validation.
Labels: documentation ci automation
💡 Key Observations
The pull request template encourages thorough documentation practices.
The Python script is dependency-free, which is beneficial for portability.
The workflow is well-structured with proper permissions and timeout settings.
🤖 Reviewed by WarpFix — AI-Powered Code Review + CI Repair · Security
| @@ -0,0 +1,18 @@ | |||
| ## Summary | |||
|
|
|||
| <!-- Explain the documentation change and why it is needed. Example: "Update the NCCIA complaint link and clarify the reporting steps." --> | |||
There was a problem hiding this comment.
✨ Praise documentation
Great addition of a summary section to clarify the purpose of the documentation change.
🤖 WarpFix
| - [ ] Official links were checked | ||
| - [ ] All added or changed documentation links work | ||
| - [ ] Guidance is defensive and does not promise recovery or legal outcomes | ||
|
|
There was a problem hiding this comment.
✨ Praise documentation
Including a validation section is a good practice to ensure documentation quality.
🤖 WarpFix
| except ValueError: | ||
| errors.append( | ||
| f"{relative}:{line_number}: link escapes repository: " | ||
| f"{raw} (use a path inside the repository)" |
There was a problem hiding this comment.
🚨 Critical bug
The link resolution logic could lead to a potential null pointer if the target is malformed.
| f"{raw} (use a path inside the repository)" | |
| Add a check to ensure 'target' is not None before proceeding with resolution. |
🤖 WarpFix
| print(f"- {error}") | ||
| return 1 | ||
|
|
||
| print( |
There was a problem hiding this comment.
✨ Praise documentation
The final output clearly indicates whether documentation checks passed or failed, which is helpful.
🤖 WarpFix
|
|
||
| on: | ||
| push: | ||
| pull_request: |
There was a problem hiding this comment.
✨ Praise documentation
The use of 'workflow_dispatch' allows for manual triggering of documentation checks, which is a great feature.
🤖 WarpFix
| runs-on: ubuntu-latest | ||
| timeout-minutes: 5 | ||
|
|
||
| steps: |
There was a problem hiding this comment.
✨ Praise performance
Setting a timeout for the job is a good practice to prevent hanging builds.
🤖 WarpFix
| steps: | ||
| - name: Check out repository | ||
| uses: actions/checkout@v4 | ||
|
|
There was a problem hiding this comment.
✨ Praise style
Using 'actions/checkout@v4' ensures that the latest version of the checkout action is used.
🤖 WarpFix
There was a problem hiding this comment.
🔍 WarpFix PR Review
This pull request introduces a GitHub Actions workflow for automated documentation checks on every push and pull request. It includes a Python script that validates required documentation files, checks for empty Markdown files, and verifies the integrity of relative links.
📖 Walkthrough
The changes consist of three main files: a pull request template that outlines a safety and privacy checklist, a Python script that performs various validation checks on Markdown documentation, and a GitHub Actions workflow configuration that triggers the validation checks on repository events. The pull request template encourages contributors to ensure that sensitive information is not included in their documentation. The Python script checks for the existence of required documentation files, ensures that Markdown files are not empty, and validates that all relative links are functional and do not escape the repository structure. The workflow is set to run on every push and pull request, providing immediate feedback on documentation quality.
📁 File Changes
| File | Change | Impact |
|---|---|---|
.github/pull_request_template.md |
Added a template for pull requests with a checklist for safety and privacy. | 🟡 medium |
.github/scripts/check_docs.py |
Introduced a Python script to validate documentation files and links. | 🔴 high |
.github/workflows/documentation-checks.yml |
Created a GitHub Actions workflow to automate documentation checks. | 🔴 high |
⏱ Review Effort & Risk
| Metric | Value |
|---|---|
| Effort | ███░░ 3/5 (Moderate) · ~30min |
| Risk | 🟡 MEDIUM |
Risk Factors
- Potential for false negatives in link validation if links are external or malformed
- Dependency on the correct structure of the repository for link resolution
Labels: documentation automation CI/CD
💡 Key Observations
The script relies solely on Python's standard library, which enhances portability.
The workflow is designed with read-only permissions, which is a good security practice.
The inclusion of a checklist in the pull request template promotes better documentation practices.
🤖 Reviewed by WarpFix — AI-Powered Code Review + CI Repair · Security
| @@ -0,0 +1,18 @@ | |||
| ## Summary | |||
|
|
|||
| <!-- Explain the documentation change and why it is needed. Example: "Update the NCCIA complaint link and clarify the reporting steps." --> | |||
There was a problem hiding this comment.
💅 Nitpick documentation
Consider providing a more specific example in the summary section to guide contributors.
🤖 WarpFix
|
|
||
| - [ ] No victim, client, or active-case data is included | ||
| - [ ] No credentials, financial records, identity numbers, or private media are included | ||
| - [ ] New factual claims cite an authoritative source |
There was a problem hiding this comment.
✨ Praise documentation
The safety and privacy checklist is a great addition to ensure compliance.
🤖 WarpFix
| - [ ] Official links were checked | ||
| - [ ] All added or changed documentation links work | ||
| - [ ] Guidance is defensive and does not promise recovery or legal outcomes | ||
|
|
There was a problem hiding this comment.
💅 Nitpick documentation
Consider adding a note about how to check if documentation links work.
🤖 WarpFix
|
|
||
| ROOT = Path(__file__).resolve().parents[2] | ||
| REQUIRED = ( | ||
| Path("README.md"), |
There was a problem hiding this comment.
💅 Nitpick style
Consider using a constant for the encoding type to avoid magic strings.
| Path("README.md"), | |
| ENCODING = 'utf-8' | |
| text = path.read_text(encoding=ENCODING) |
🤖 WarpFix
|
|
||
| def main() -> int: | ||
| """Validate required files and repository-local Markdown links.""" | ||
| errors: list[str] = [] |
There was a problem hiding this comment.
error handling
Ensure that the error handling for file reading is comprehensive to avoid silent failures.
| errors: list[str] = [] | |
| Log the error or raise an exception to notify users. |
🤖 WarpFix
| except (OSError, UnicodeError) as exc: | ||
| errors.append(f"unable to read {relative}: {exc}") | ||
| continue | ||
|
|
There was a problem hiding this comment.
🚨 Critical logic
The link escaping check may not cover all edge cases. Consider adding more robust validation.
| Add tests for various link formats to ensure they are handled correctly. |
🤖 WarpFix
| target = link_target(raw) | ||
| if not target: | ||
| errors.append( | ||
| f"{relative}:{line_number}: empty relative link target " |
There was a problem hiding this comment.
documentation
The error messages could be more user-friendly to assist in debugging.
| f"{relative}:{line_number}: empty relative link target " | |
| Consider providing suggestions for fixing broken links. |
🤖 WarpFix
| f"{relative}:{line_number}: link escapes repository: " | ||
| f"{raw} (use a path inside the repository)" | ||
| ) | ||
| continue |
There was a problem hiding this comment.
✨ Praise style
The use of pathlib for file handling is a good practice for cross-platform compatibility.
🤖 WarpFix
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read |
There was a problem hiding this comment.
✨ Praise documentation
The workflow setup is clear and well-structured for documentation checks.
🤖 WarpFix
| validate: | ||
| name: Validate documentation | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 5 |
There was a problem hiding this comment.
💅 Nitpick style
Consider specifying a specific version for the checkout action to avoid unexpected changes.
| timeout-minutes: 5 | |
| uses: actions/checkout@v4.0.0 |
🤖 WarpFix
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4425bfc2f5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Path("CONTRIBUTING.md"), | ||
| Path("docs/seo-metadata.md"), | ||
| ) | ||
| LINK_PATTERN = re.compile(r"!?[[^]]*](([^)]+))") |
There was a problem hiding this comment.
Match standard Markdown links here
This regex never matches normal Markdown links like the repo’s existing [CONTRIBUTING.md](CONTRIBUTING.md) or [README.md](README.md) references, so finditer() yields nothing and the job reports success even when a relative link is broken. As written, the new validation does not actually check the links it was added to protect.
Useful? React with 👍 / 👎.
What changed
Why
The repository had no GitHub Actions workflow, so merged documentation changes received no automated validation.
Validation