Unify gem and docs into a monorepo

Merged
CI
6mo ago
+19114-699

Summary

Consolidates ruby-ui/ruby_ui (the gem) and ruby-ui/web (the docs Rails app at rubyui.com) into a single repository with a symmetric layout:

ruby_ui/
├── gem/    # the ruby_ui gem (lib/, generators, tests, gemspec)
└── docs/   # the Rails app powering rubyui.com, consumes the local gem via path: "../gem"

The motivating problem: every component change required two coordinated PRs (one in the gem, one in web), and the docs app already mirrored the entire gem under app/components/ruby_ui/. With this change, a single PR can touch both the component and its documentation example, and the docs app reads from gem/lib/ directly — no copy step, no version skew.

Key decisions

  • Repo: kept ruby-ui/ruby_ui so the gem URL, issues, and stars stay put. ruby-ui/web will be archived after cutover.
  • History: web/ imported via git subtree add (no squash). git log -- docs/ preserves the original commits, authors, and dates from web.
  • Mirror eliminated: dropped docs/app/components/ruby_ui/ entirely. The docs app's autoloader pushes the gem's lib/ruby_ui/ directory into the RubyUI namespace; *_docs.rb and lib/ruby_ui/docs/ are ignored to avoid Zeitwerk namespace conflicts (the docs app keeps its own richer Components::Docs::* and Views::Docs::* implementations).
  • CI unified: new .github/workflows/ci.yml at the root runs three jobs — gem (Ruby 3.3 + 3.4 matrix), docs (Rails app), and docker-build for the devcontainer image. The previous verify_components job is deleted (no mirror to verify).
  • Docker build context is now the monorepo root so gem/ is visible to bundle install (resolves path: "../gem" from inside /rails/). Run from the repo root: flyctl deploy --config docs/fly.toml --dockerfile docs/Dockerfile ..
  • Gemspec packaging unchanged: s.files = Dir["README.md", "LICENSE.txt", "lib/**/*"] continues to be the explicit allowlist. gem build from gem/ still ships exactly the same 289 files (only lib/, README, LICENSE) — nothing from docs/ leaks. A new gem/test/gemspec_test.rb regression test guards this.

What changed

  • Move: all gem source (lib/, test/, bin/, Gemfile*, ruby_ui.gemspec, Rakefile, .devcontainer/, .tool-versions, etc.) → gem/ (preserves per-file blame).
  • Import: entire ruby-ui/web history merged in under docs/.
  • docs/Gemfile: gem "ruby_ui", github: ... → gem "ruby_ui", path: "../gem".
  • docs/config/initializers/ruby_ui.rb: push the gem's lib path into the autoloader, ignore *_docs.rb and docs/ subfolder.
  • URLs: github.com/ruby-ui/ruby_ui/blob/main/lib/ruby_ui/... updated to gem/lib/ruby_ui/... in views and theme grids (external ruby_ui_pro / ruby_ui_stimulus refs left alone).
  • Root files: new README.md (monorepo overview), new CONTRIBUTING.md (unified workflow), .github/CODEOWNERS, .github/dependabot.yml (covering bundler in /gem and /docs, npm in /docs, github-actions, devcontainers in both), .github/pull_request_template.md.
  • gem/AGENTS.md / gem/CONTRIBUTING.md: updated to describe the monorepo context; dropped the obsolete instruction to also open a PR on ruby-ui/web.

Verified locally

  • cd gem && bundle exec rake → 106 runs, 469 assertions, 0 failures, 0 errors. Standardrb: 309 files, no offenses.
  • cd gem && gem build ruby_ui.gemspec → 289 files in the .gem; only README.md, LICENSE.txt, and lib/**/*. Nothing from docs/, test/, or .github/ leaks.
  • cd docs && bundle lock → resolves PATH remote: ../gem correctly. (Full bundle install failed locally on sqlite3 native build due to host env — CI will exercise this with proper system deps.)

Test plan

  • CI is green on this PR (gem matrix on 3.3 + 3.4, docs Rails, docker-build).
  • cd docs && bin/dev renders the documentation site locally; spot-check /docs/button, /docs/combobox, /docs/changelog, /docs/getting_started/*.
  • docker build -f docs/Dockerfile -t rubyui-docs . from the repo root completes successfully.
  • After merge, dry-run a Fly deploy from a branch: flyctl deploy --config docs/fly.toml --dockerfile docs/Dockerfile . --build-only.

Cutover (post-merge, separate steps)

  1. Deploy docs/ to Fly (rubyui.com) and verify production.
  2. Tag v1.2.0 of the gem from gem/: cd gem && bundle exec rake release.
  3. Archive ruby-ui/web on GitHub and update its README to point here. Don't delete — preserves external links, issues, and PRs as read-only.
  4. Coordinate with any open PRs on ruby-ui/web (offer rebase paths into docs/).

🤖 Generated with Claude Code