ci: lint the shell commands printed in the manual - #866
Merged
Conversation
Adds scripts/check_docs_commands.py, wired into pr_check.yml. Two checks, both aimed at the same failure: a farmer copies a command out of the manual and it does not work. 1. Lints every shell block with shellcheck (severity=error), falling back to bash -n when shellcheck is unavailable. shellcheck rather than bash -n because bash -n only checks syntax. The disk-wipe loop that silently wiped nothing was syntactically VALID and failed at runtime; bash -n passes it, shellcheck catches it (SC1108). Verified by re-injecting that exact loop: the check fails with the correct file and line. Covers untagged blocks too, not just ```bash -- most of the manual's commands are untagged, and that wipe loop lived in one. Respects the manual's conventions: <placeholder> is normalised, pasted terminal sessions are skipped, and heredoc blocks are skipped because their body is data that shellcheck mis-parses out of context. 2. Flags command blocks that have drifted between the farmers/ and labs/ copies of the five shared build pages. Those pages are deliberately different documents for different audiences -- the prose is meant to diverge, the commands are not. Verified by changing a flag in one tree only: the check fails. Fixes the six issues the new check found: - message.md and db_testing.md ended a command with a trailing backslash and nothing after it, so a copied command hangs waiting for input - docker_basics.md had a dangling backtick: --filter "until=`" , with prose reading 'replace ` with the complete date' - api_token.md tagged JSON output as bash, ssh_wsl.md tagged a Windows path as sh, farmerbot_information.md tagged --help output as bash, and cloud_provider_farming.md tagged a terminal session as sh
mik-tf
requested review from
AhmedHanafy725,
ramezsaeed,
scottyeager and
xmonader
as code owners
July 28, 2026 21:20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Answers the farmers/ vs labs/ duplication question, and fixes six real bugs found while building the check.
On the duplication itself: leave it alone
Those five pages are not a stale copy.
farmers/6_boot_3nodeis a 22-line summary with its own prose; the labs version is 166 lines of detail. Only 2–7 lines are unique to farmers, but the farmers pages are condensations written for a different reader, not excerpts. Merging them would destroy the simple manual.What can be fixed is the actual risk: a fix lands in one tree and not the other. That produced the V4-screenshots-on-a-V3-page bug, and I hit it three times in this session — the wipe guide, the
ddcommand, the bootstrap page — each time fixing both copies by hand with nothing enforcing it.The check
scripts/check_docs_commands.py, run inpr_check.yml:Why shellcheck and not
bash -nI originally proposed
bash -n, tested it, and it did not catch the original bug. That loop —— is syntactically valid. It fails at runtime (
unary operator expected).bash -npasses it. shellcheck catches it:SC1108, you need a space before and after the =.It also only looked at ```bash blocks — but that loop lived in an untagged block, and most of the manual's commands are untagged. Both gaps are fixed.
Tested, not assumed
Severity is , not : warning level flags 36 blocks, mostly
cdwithout|| exit, which is noise for documentation. Error level sits at zero.Conventions are respected rather than fought —
<placeholder>is normalised, pasted terminal sessions are skipped, and heredoc blocks are skipped because their body is data that shellcheck mis-parses out of context.Six bugs the check found
Real breakage:
message.md\and nothing after — a copied command hangs waiting for inputdb_testing.md--reset \docker_basics.md--filter "until=", with prose reading "replacewith the complete date"Mislabelled blocks (output tagged as runnable shell):
api_token.md(JSON),ssh_wsl.md(a Windows path),farmerbot_information.md(--helpoutput, ×2),cloud_provider_farming.md(a terminal session).The
docker_basics.mdone is notable: my earlier full-manual scan missed it, because that scan did not normalise placeholders and the real error was masked among ~30 false positives.Net effect
Broken commands and cross-tree drift are now build failures instead of something a farmer discovers with a dead node.