Restore bin/docs-lint and bin/install-hooks#38
Conversation
The .github/workflows/docs-lint.yaml job runs `bin/docs-lint` on every
PR touching docs/, but the script wasn't tracked -- it lived in a
stash. Restoring it.
The script enforces the docs-site rules:
1. No legacy /docs/... links, no ./ or ../ relative links
2. Filenames match ^[a-z0-9][a-z0-9\-]*\.md$ (except _index.md)
3. Every directory under docs/ has _index.md
4. Every .md file starts with YAML frontmatter
5. Every page has a title; non-root pages have a weight
6. Every /documentation/{pkg}/{ver}/{slug} link resolves on disk
Also fixed two relative ../advanced/livewire-widgets.md links in
api-reference/widget-contract.md (introduced in the dual-render
docs commit) -- replaced with absolute /documentation/layup/v1/...
links to match the established convention.
Restored bin/install-hooks alongside since it installs the pre-commit
hook that runs bin/docs-lint locally for the same trigger condition
the CI workflow uses.
bin/docs-lint passes: 32 files clean.
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📝 WalkthroughWalkthroughThe PR introduces a documentation linting system consisting of a new PHP script ( Changes
Possibly Related PRs
Poem
🎯 3 (Moderate) | ⏱️ ~22 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 31 minutes and 50 seconds.Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@bin/docs-lint`:
- Around line 74-77: The code calls file_get_contents($path) into $content and
then uses str_starts_with on it, which can throw if file_get_contents returned
false; update the logic around file_get_contents/$content (and references to
$path/$rel) to first detect unreadable files (e.g., if $content === false) and
push a file-level error into $errors[] (like "{$rel}: unreadable file") and skip
the YAML frontmatter checks; only call str_starts_with when $content is a string
to avoid the TypeError.
- Line 83: $isVersionRoot comparison mixes normalized $path with an unnormalized
$docsRoot, causing false negatives on Windows; normalize both sides before
comparing (e.g., run str_replace(DIRECTORY_SEPARATOR, '/', ...) on $docsRoot or
build the expected index path using DIRECTORY_SEPARATOR) so $isVersionRoot =
(normalized($path) === normalized("{$docsRoot}/_index.md")); update the check
that uses $isVersionRoot to use the normalized comparison and ensure any
trailing slashes are handled consistently.
- Around line 200-208: The code constructs $slug from $slugParts and then checks
$candidates with is_file(), but $slugParts can contain traversal segments like
".." allowing paths outside the docs root; update the link-resolution logic in
bin/docs-lint to sanitize/validate $slugParts before joining (reject or remove
"." and ".." and empty segments) or resolve the final candidate path (e.g. with
a realpath-equivalent) and ensure it is inside $docsRoot before calling
is_file(); reference the variables $slugParts, $slug, $candidates and the
is_file() check and enforce that resolved paths start with $docsRoot to prevent
traversal.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1c5af2da-58da-42b9-8506-28232dcd8527
📒 Files selected for processing (3)
bin/docs-lintbin/install-hooksdocs/api-reference/widget-contract.md
- Path traversal in /documentation/{pkg}/{ver}/... slug resolution.
parse_url() yields raw URL segments; '..' could reach files outside
$docsRoot via is_file(), silently validating a broken link. Reject
'.' / '..' / empty segments before building the candidate path, and
add a defence-in-depth realpath check that the resolved file is
actually inside $docsRoot.
- Windows path comparison for $isVersionRoot. The LHS was normalized
(DIRECTORY_SEPARATOR -> '/') but the RHS embedded the un-normalized
$docsRoot, so the comparison never matched on Windows -- the version
root would be falsely flagged as missing `weight`. Normalize both
sides via $normalizedDocsRoot once, then compare normalized paths.
- file_get_contents() returning false. Under declare(strict_types=1),
passing false to str_starts_with() throws TypeError, crashing the
linter on any unreadable file (permission/race). Detect false
explicitly and emit a per-file 'unreadable file' error instead.
Verified all three behaviours with throwaway fixtures:
- traversal link -> 'broken link' error (not silent acceptance)
- chmod 000 file -> 'unreadable file' error (not TypeError)
- clean docs/ tree -> still passes (32 files)
The .github/workflows/docs-lint.yaml job runs
bin/docs-linton every PR touching docs/, but the script wasn't tracked -- it lived in a stash. Restoring it.The script enforces the docs-site rules:
Also fixed two relative ../advanced/livewire-widgets.md links in api-reference/widget-contract.md (introduced in the dual-render docs commit) -- replaced with absolute /documentation/layup/v1/... links to match the established convention.
Restored bin/install-hooks alongside since it installs the pre-commit hook that runs bin/docs-lint locally for the same trigger condition the CI workflow uses.
bin/docs-lint passes: 32 files clean.
Summary by CodeRabbit
New Features
Documentation