Add markdownlint CI job and fix broken doc links#123
Conversation
Add a markdownlint job to CI that lints the top-level Markdown docs with
markdownlint-cli2, configured via .markdownlint-cli2.yaml. The config
disables noisy/stylistic rules (line-length, bold-as-heading,
table-pipe-spacing), sets MD024 to siblings-only for the CHANGELOG, and
globs *.{md,markdown} (non-recursive) so spec/ working notes and .github/
are excluded.
Fix the existing violations to establish a green baseline:
- README: repair the stale table of contents (drop entries with no
in-doc target, add the real sections), demote stray H1s to H2 with
subsections bumped one level, add languages to bare code fences.
- OPERATIONS: fix cross-reference anchors that omitted the heading's
"(N minutes)" suffix.
- Normalize blank lines around headings, fences, and lists.
Two OPERATIONS checklist links (#capacity-monitoring, #security-audit)
point to sections that do not exist yet; they are left in place with an
inline markdownlint-disable and a TODO referencing the issue.
Fixes #95
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reference rules by their readable names (line-length, no-emphasis-as-heading, table-column-style, no-duplicate-heading) instead of MD0xx IDs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A CI/docs-tooling change does not warrant a release note. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reference link-fragments instead of MD051 in the markdownlint-disable comments, matching the config style. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pre-existing MD032 violation surfaced by the new markdownlint baseline. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@greptileai the Also switched the markdownlint config and inline disable directives to rule-name aliases ( |
|
Both resolutions make sense. Dropping the CHANGELOG entry is the right call for a tooling-only change, and using rule-name aliases ( Tip: You can customize Greptile's behavior for this repo with |
sir-sigurd
left a comment
There was a problem hiding this comment.
Reviewed the markdownlint CI job and the doc fixes — no blockers. The CI job and config are correct: the rule aliases all resolve in the markdownlint version the action bundles (v23 → markdownlint 0.40), siblings_only is the right parameter for MD024, and the config's non-recursive glob is honored by the action rather than overridden, so a local markdownlint-cli2 run and CI lint the same files. The OPERATIONS anchor fixes and the README table-of-contents repair all resolve to real headings, and the H1→H2 demotions keep the text-derived slugs, so existing internal links still work.
Greptile's [#PR] placeholder flag is already resolved — the changelog entry was dropped in a later commit, so there's no broken link to ship.
Design: limited substantive surface — a CI lint job plus mechanical doc fixes, with one coherent goal (a green lint baseline). Everything below is optional polish and PR-description tidy-ups.
Nits / optional
- (reshape) Lint scope is top-level-only as a side effect, not by intent. The config comment frames the non-recursive
*.{md,markdown}glob as deliberately excludingspec/, but it equally (and silently) excludes any nested markdown —modules/*/README.md,examples/*.md. None exist today so nothing is missed now, but the next contributor who adds a module README gets no linting and no signal.
Alternatives: wouldglobs: ["**/*.md"]with an explicitignores: ["spec/**", ".github/**"]match the stated intent better and auto-cover future files? - (reshape) Config comment mislabels the disabled table rule.
table-column-styleis MD060 (column-style/padding consistency); the comment calls it "Table pipe spacing," which is MD055 (table-pipe-style), a different rule. The disabled rule is the right one — only the comment (and the PR body) name the wrong one.
PR description tidy-ups
- The doc-edits list names README and OPERATIONS, but VARIABLES.md (and a one-line CHANGELOG blank-line fix) also changed. Same goal — just an incomplete file inventory.
- The TODO still shows
[x] CHANGELOG entry, but the entry was dropped and the shipping diff carries no release note. The recent CI/test PRs (#114, #116) carried no changelog entry either, so skipping it is consistent — uncheck the box so the description matches what shipped.
The two deferred OPERATIONS links (#capacity-monitoring, #security-audit) are suppressed with a TODO referencing #95 rather than re-pointed to an unrelated section — fine to leave to that follow-up.
Reviewed against 597c87b
table-column-style (MD060) governs table cell padding consistency; the previous comment described it as "table pipe spacing," which is MD055. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for the review. Addressed:
Deferred / planned:
Holding this PR until #122 lands, then I'll do the recursive switch in one more commit. |
Restore the original table-of-contents entries verbatim and suppress the broken in-doc anchors with a markdownlint-disable block plus a TODO referencing #95, rather than deciding the TOC restructure here. The navigation/content decision (which sections belong, cross-doc links) belongs in a focused PR; this one stays scoped to the lint baseline. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
With spec/ removed (#122), there's no working-notes directory left to avoid, so widen the glob from top-level *.{md,markdown} to recursive **/*.{md,markdown} in both the config and the CI action (the action's default glob is non-recursive and overrides the config, so it's set explicitly). This auto-covers future nested docs like module READMEs. The only newly-linted file, .github/pull_request_template.md, opens with a section heading rather than an H1; skip first-line-heading inline since it's a template fragment, not a standalone document. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
MD041 is about the file's first line, so the exemption belongs to the whole file, not one line. disable-line was positional and would silently stop working if the template gained a line above the heading. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace DavidAnson/markdownlint-cli2-action@v23 with a pinned `npx markdownlint-cli2@0.22.1` run. A moving major action tag auto-adopts new releases that can add or tighten rules and break CI with no repo change; a pinned npm version is content-immutable, so the linter is reproducible. It also matches the local invocation, and lets the config's globs drive file selection without duplicating them in the workflow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@greptileai please re-review — the CI mechanism changed substantially since the last pass: the |
There was a problem hiding this comment.
Pull request overview
Adds repository-wide Markdown linting in CI (via markdownlint-cli2) and updates existing documentation files to conform to the lint rules, establishing a clean baseline for future doc changes.
Changes:
- Added a
markdownlintGitHub Actions job and a repo-level.markdownlint-cli2.yamlto centrally define rules and lint scope. - Normalized/cleaned up Markdown formatting across key docs (blank lines, heading levels, code fence languages) and fixed/annotated link fragments.
- Updated the PR template to opt out of the “first line must be a heading” rule.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/ci.yml |
Adds markdownlint job running npx markdownlint-cli2@0.22.1 in CI. |
.markdownlint-cli2.yaml |
Introduces markdownlint-cli2 configuration (rule toggles + repo-wide Markdown globs). |
.github/pull_request_template.md |
Disables first-line-heading lint rule for the PR template. |
README.md |
Markdown normalization, adds fenced-code languages, and suppresses known-broken TOC fragments with TODO notes. |
OPERATIONS.md |
Fixes anchor fragments to match headings; suppresses known-missing sections with TODO notes. |
VARIABLES.md |
Adds blank lines to satisfy linting around headings/lists/fences. |
CHANGELOG.md |
Minor formatting normalization (blank line for list separation). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Retarget Troubleshooting and Terraform Commands Reference to the real sections; only the five entries needing cross-doc decisions (#95) stay. - Switch the README disable block to per-line disables so a TOC entry added later still gets dead-anchor checking. - Reword the TODO: #95 tracks the broken links themselves, not a restructure. - Indent the suppression comments under the preceding list item so the TOC and checklists render as single lists (an unindented HTML comment between bullets splits the list). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Move the markdownlint-cli2 pin into package.json + package-lock.json and run `npm ci` in CI: a bare `npx <pkg>@<version>` still resolves deep transitive deps fresh on every run, while the lockfile freezes the whole tree and makes the pin visible to update tooling. - Add `ignores` for .terraform/ and node_modules/: markdownlint-cli2 has no default exclusions, and `terraform init` vendors registry modules whose READMEs would fail local runs. - Ignore node_modules in .gitignore. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Description
Adds a
markdownlintjob to CI that lints all Markdown docs with markdownlint-cli2, and fixes the existing violations to establish a green baseline.CI + config
markdownlintjob inci.yml:npm ciagainst a committedpackage.json+package-lock.json(markdownlint-cli2 0.22.1), thennpx --no-install markdownlint-cli2, on the runner's preinstalled Node. Runs on PRs and pushes tomain. (The lockfile freezes the whole dependency tree and makes the pin visible to update tooling — a moving action tag would auto-adopt new releases that can add/tighten rules and break CI with no repo change, and a barenpx <pkg>@<version>would still resolve transitive deps fresh on every run.).markdownlint-cli2.yamlso localmarkdownlint-cli2runs match CI:MD013(line-length),MD036(bold-as-heading),MD060(table-column-style) — stylistic and noisy on these docs.MD024set tosiblings_only— the CHANGELOG repeats Added/Changed/Fixed per release (Keep a Changelog convention).globs: **/*.{md,markdown}(recursive) — every Markdown file in the repo, so future nested docs (module READMEs, etc.) are covered automatically. Both local and CI runs invoke the tool with no glob args, so the config is the single source of truth. The PR template's loneMD041(no H1, it's a fragment) is skipped file-wide in that file.ignoresfor.terraform/andnode_modules/— markdownlint-cli2 has no default exclusions, and a localterraform initvendors registry modules whose READMEs would otherwise fail local runs.Doc fixes for a green baseline
*→-), and dropped a double space in one demoted heading.(N minutes)suffix; the cost-review link is repointed to#cost-optimization-recommendations.Deferred
Troubleshooting,Terraform Commands Reference) had unambiguous in-README targets and were retargeted; the remaining five need cross-doc decisions, so they are kept verbatim and suppressed with per-linemarkdownlint-disable-next-linecomments + aTODOreferencing last half of TOC references in readme are broken #95. Deciding which sections belong (and the cross-doc links) is left to a focused follow-up PR tracked by last half of TOC references in readme are broken #95. The suppression comments are indented under the preceding list item so the rendered lists stay whole.#capacity-monitoring,#security-audit): point to sections that don't exist yet. Left in place with an inlinemarkdownlint-disableand aTODO, rather than repointed to an unrelated section — a follow-up should add those sections or drop the links.TODO
🤖 Generated with Claude Code
Greptile Summary
This PR adds a
markdownlintCI job using version-pinnednpx markdownlint-cli2@0.22.1and fixes all existing violations across the docs to establish a green baseline.markdownlintjob inci.ymldriven entirely by.markdownlint-cli2.yaml, which disables noisy stylistic rules (line-length, bold-as-heading, table-column-style), relaxes duplicate-heading tosiblings_onlyfor Keep-a-Changelog convention, and recursively globs all*.{md,markdown}files.markdownlint-disable+TODO(#95)rather than restructured here.Confidence Score: 5/5
Safe to merge — adds a docs linting job and normalises existing Markdown without touching any Terraform or infrastructure logic.
All changes are confined to documentation, CI config, and the new markdownlint config file. The linter version is pinned so the job is reproducible, the config is the single source of truth for both local and CI runs, and the anchor fixes in OPERATIONS.md have been verified against the actual heading text. Dead links are properly suppressed with TODO markers rather than silently ignored.
No files require special attention.
Important Files Changed
npx markdownlint-cli2@0.22.1job; no glob args so the config file is the single source of truth; consistent with the existing job structure.globscovers all.md/.markdownfiles recursively.markdownlint-disable-file first-line-headingdirective added because the template intentionally starts with an H2 fragment rather than an H1.Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD trigger["PR / push to main"] --> fmt & markdownlint & validate & test fmt["fmt job\nactions/checkout@v6\nhashicorp/setup-terraform@v4\nterraform fmt -check -recursive -diff"] markdownlint["markdownlint job\nactions/checkout@v6\nnpx markdownlint-cli2@0.22.1"] markdownlint --> config[".markdownlint-cli2.yaml\n• globs: **/*.{md,markdown}\n• MD013 off\n• MD036 off\n• table-column-style off\n• MD024 siblings_only"] validate["validate job (matrix)\nterraform validate\n5 modules"] test["test job (matrix)\nterraform test\n2 modules"]Reviews (2): Last reviewed commit: "Lint Markdown via pinned npx instead of ..." | Re-trigger Greptile