Skip to content

Add a rake docs:preview task serving the docs site locally - #534

Open
koic wants to merge 1 commit into
modelcontextprotocol:mainfrom
koic:add_a_docs_preview_rake_task
Open

Add a rake docs:preview task serving the docs site locally#534
koic wants to merge 1 commit into
modelcontextprotocol:mainfrom
koic:add_a_docs_preview_rake_task

Conversation

@koic

@koic koic commented Aug 25, 2026

Copy link
Copy Markdown
Member

Motivation and Context

The documentation site under docs/ had no development command: previewing a change meant hand-assembling a Jekyll environment, since the site only builds for real when a release publishes it through bin/generate-gh-pages.sh and the GitHub Pages runtime. rake docs:preview now builds and serves the site at http://localhost:4000 (override with PORT), with watch-based rebuilds on edit.

The preview dependencies live in their own docs/Gemfile rather than the gem's Gemfile: github-pages mirrors the runtime that builds the released site (jekyll-remote-theme, jekyll-redirect-from, and the Jekyll version Pages actually runs), which keeps the preview faithful but is far too heavy to impose on the gem itself. The task subshells into that bundle with Bundler.with_unbundled_env, the same delegation shape the conformance tasks use for npx. Two support pieces keep the pinned toolchain running on current Ruby. docs/_preview/taint_shim.rb restores the taint API as no-ops: Liquid 4.0.3 calls obj.tainted? on every variable render, ahead of its own lax-mode check (liquid/variable.rb:124), so on Ruby 3.2 and later, where the taint API was removed, the first layout render dies with NoMethodError, while on Ruby 3.1 and earlier the methods still exist as deprecated no-ops and the shim is inert. The shim is loaded only into the preview process via RUBYOPT. The former default gems the pinned Jekyll expects are listed in the docs Gemfile. The task also regenerates docs/_data/versions.yml from the version tags, mirroring what bin/generate-gh-pages.sh produces at deploy time, so the nav footer shows the released-gem version line exactly as it does on the published site. Build products and the generated data file are ignored.

How Has This Been Tested?

By running the task on a spare port and verifying the served pages, the footer's version line, and that a SIGINT stops it cleanly with exit 0; git status stays clean while it runs (all build products ignored). Verified on both Ruby 3.1.5 (shim inert) and Ruby 4.0.6, where a shimless build reproduces the NoMethodError and the task runs green with the shim. RuboCop and the full suite are green.

Breaking Changes

None. The task and its Gemfile are development-only additions; the gem and its dependencies are untouched.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

## Motivation and Context

The documentation site under `docs/` had no development command: previewing a change meant hand-assembling
a Jekyll environment, since the site only builds for real when a release publishes it through
`bin/generate-gh-pages.sh` and the GitHub Pages runtime. `rake docs:preview` now builds and serves
the site at http://localhost:4000 (override with `PORT`), with watch-based rebuilds on edit.

The preview dependencies live in their own `docs/Gemfile` rather than the gem's Gemfile:
`github-pages` mirrors the runtime that builds the released site (jekyll-remote-theme,
jekyll-redirect-from, and the Jekyll version Pages actually runs), which keeps the preview faithful
but is far too heavy to impose on the gem itself. The task subshells into that bundle with
`Bundler.with_unbundled_env`, the same delegation shape the conformance tasks use for npx.
Two support pieces keep the pinned toolchain running on current Ruby. `docs/_preview/taint_shim.rb` restores
the taint API as no-ops: Liquid 4.0.3 calls `obj.tainted?` on every variable render,
ahead of its own lax-mode check (`liquid/variable.rb:124`), so on Ruby 3.2 and later,
where the taint API was removed, the first layout render dies with NoMethodError, while on Ruby 3.1
and earlier the methods still exist as deprecated no-ops and the shim is inert. The shim is loaded only into
the preview process via RUBYOPT. The former default gems the pinned Jekyll expects are listed in the docs Gemfile.
The task also regenerates `docs/_data/versions.yml` from the version tags, mirroring what `bin/generate-gh-pages.sh`
produces at deploy time, so the nav footer shows the released-gem version line exactly as it does on the published site.
Build products and the generated data file are ignored.

## How Has This Been Tested?

By running the task on a spare port and verifying the served pages, the footer's version line,
and that a SIGINT stops it cleanly with exit 0; `git status` stays clean while it runs (all build products ignored).
Verified on both Ruby 3.1.5 (shim inert) and Ruby 4.0.6, where a shimless build reproduces the NoMethodError
and the task runs green with the shim. RuboCop and the full suite are green.

## Breaking Changes

None. The task and its Gemfile are development-only additions; the gem and its dependencies are untouched.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants