From 05ebbe95ed38cc0d218b5eae790a08244a524058 Mon Sep 17 00:00:00 2001 From: Toshimaru Date: Tue, 11 Aug 2026 18:20:35 +0900 Subject: [PATCH 1/3] docs: add upgrade-rails skill Documents the default_rails_version bump procedure from PR #225, including the rails submodule dirty-worktree behavior after `rake build` that's easy to mistake for a problem. --- .claude/skills/upgrade-rails/SKILL.md | 152 ++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 .claude/skills/upgrade-rails/SKILL.md diff --git a/.claude/skills/upgrade-rails/SKILL.md b/.claude/skills/upgrade-rails/SKILL.md new file mode 100644 index 0000000000..f44ad5a9ef --- /dev/null +++ b/.claude/skills/upgrade-rails/SKILL.md @@ -0,0 +1,152 @@ +--- +name: upgrade-rails +description: Use when upgrading the Rails version this site documents — bumping default_rails_version in _config.yml, pointing the rails submodule at a new tag, or regenerating src/ docs after a new Rails patch or security release. +--- + +# Upgrading the default Rails version + +Reference execution: PR [#225](https://github.com/railsdoc/railsdoc.github.io/pull/225) +("Update Rails from v8.1.0 to v8.1.3"). This skill only covers **patch-level bumps** +within the current minor series (e.g. `8.1.3` → `8.1.3.1`). A minor/major bump (e.g. +`8.1` → `8.2`) needs a different, larger set of edits — see the stop condition in step 1. + +## 1. Resolve the target version and gate scope + +- Version passed as an argument → use it verbatim. +- No argument → look up the latest release: + ```sh + curl -s https://rubygems.org/api/v1/versions/rails/latest.json + ``` + Confirm the result with the user before proceeding. + +Read the current version from `_config.yml:5` (`default_rails_version`). + +**Stop conditions — check both before doing any other work:** + +- Target equals current version → nothing to do, stop. +- Target's `major.minor` differs from current's (e.g. current is `8.1.x`, target is + `8.2.0`) → **stop**, this is out of scope for this skill. `rubygems.org`'s + `latest.json` returns the highest version overall, not the highest patch in the current + series, so this will eventually happen. A minor bump additionally needs: a new + `rails_versions` entry in `_config.yml`, moving `latest: true` off the old series, a new + `defaults:` scope + `src//` directory for the demoted series (via + `rake 'build_multi[]'`), and a new row in `.github/workflows/ci.yml`'s + `doc-build-others` matrix. Explain this to the user rather than attempting it. + +## 2. Pre-flight the tag before the expensive build + +`switch_rails` (`Rakefile`) does `git fetch` then `git switch refs/tags/v` — but +it only runs *inside* `rake build`, after which `bundle install` and a full `rake rdoc` +regeneration (several minutes) will have already happened even if the tag is bad. Check +the tag resolves first: + +```sh +git -C rails fetch --tags +git -C rails rev-parse "refs/tags/v" # must print a sha, not error +``` + +## 3. Branch and edit `_config.yml` + +```sh +git switch -c rails- +``` + +Exactly two lines change on a patch bump — edit them directly, don't sed the whole file: + +- `default_rails_version: ""` +- under `rails_versions:` → the current minor key (e.g. `"8.1":`) → `specific_version: ""` + +Keep both values **quoted** — an unquoted `8.1` parses as a YAML float. Leave everything +else alone: `latest: true` stays on the current series, and the `defaults:` block keys on +the minor series so it doesn't need touching for a patch bump. + +Commit (unprefixed, matching #225 exactly): + +``` +Update Rails from v to v +``` + +## 4. Regenerate the docs + +```sh +rake build +``` + +This switches the `rails` submodule to the new tag, swaps in the `toshimaru/sdoc` fork, +regenerates rdoc, copies output into `src/`, and finishes with `bundle exec jekyll build` +— so the Jekyll build is already validated once this completes. Uses Ruby 3.4 per +`mise.toml`. This is the long step. + +## 5. Commit the submodule pointer — mind the dirty worktree + +`rake build` rewrites `rails/Gemfile` (to point `sdoc` at the fork) and runs +`bundle install` *inside* the submodule. After the build, `git status` in the superproject +will show `rails` as having **both new commits and modified content**. That looks like it +violates "don't keep uncommitted work in the submodule" from `AGENTS.md`, but it's +expected and harmless — the next `switch_rails` run `git reset --hard`s it away. + +**Do not commit, stash, or clean anything inside `rails/`.** Stage only the pointer at the +superproject level and verify it's a clean pointer move: + +```sh +git add rails +git diff --cached rails +``` + +The diff must show only `-Subproject commit ... / +Subproject commit ...` — nothing else. + +Commit: + +``` +Use rails v +``` + +## 6. Commit the regenerated docs + +```sh +git diff --check +git add src +``` + +Commit (this one *is* conventional-prefixed, matching #225): + +``` +docs: Generate docs for Rails v +``` + +## 7. Push and open the PR + +Confirm with the user before pushing. PR body, matching #225's style: + +``` +Generate Rails v docs. +``` + +## Verify before/after opening the PR + +- `git diff --check` is clean (already run in step 6). +- Version string landed in generated output — every generated page carries it near the + top: + ```sh + grep -c 'Ruby on Rails ' src/index.html + ``` +- Diff shape matches the reference PR: `_config.yml` (2 lines), `rails` (pointer only, + per step 5), `src/**` (generated). No `src//` directory should appear for a + patch bump. + +## Quick reference + +| Step | Commit message | Prefixed? | +|---|---|---| +| `_config.yml` edit | `Update Rails from v to v` | no | +| submodule pointer | `Use rails v` | no | +| regenerated `src/` | `docs: Generate docs for Rails v` | yes | + +## Common mistakes + +- Normalizing all three commit messages to `feat:`/`chore:` prefixes — only the third + one is prefixed in the reference PR. +- Trying to clean up the `rails/` submodule's dirty worktree after `rake build` — leave it; + see step 5. +- Running the full `rake build` before confirming the target tag exists — see step 2. +- Treating a minor-series bump (`8.1` → `8.2`) the same as a patch bump — see step 1. From 3f3f26f467b8fd529c23cc5abd40c7e5fcf9a73c Mon Sep 17 00:00:00 2001 From: Toshimaru Date: Tue, 11 Aug 2026 18:24:16 +0900 Subject: [PATCH 2/3] fix: correct rake build tag-validation claim in upgrade-rails skill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit switch_default_rails is a prerequisite of the build task, so a bad tag already fails fast before the expensive bundle install / rake rdoc regeneration runs — no separate pre-flight gate is needed. Addresses review comment: https://github.com/railsdoc/railsdoc.github.io/pull/227#discussion_r3756706756 --- .claude/skills/upgrade-rails/SKILL.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.claude/skills/upgrade-rails/SKILL.md b/.claude/skills/upgrade-rails/SKILL.md index f44ad5a9ef..55dbfa654e 100644 --- a/.claude/skills/upgrade-rails/SKILL.md +++ b/.claude/skills/upgrade-rails/SKILL.md @@ -33,12 +33,14 @@ Read the current version from `_config.yml:5` (`default_rails_version`). `rake 'build_multi[]'`), and a new row in `.github/workflows/ci.yml`'s `doc-build-others` matrix. Explain this to the user rather than attempting it. -## 2. Pre-flight the tag before the expensive build +## 2. Optionally confirm the tag exists -`switch_rails` (`Rakefile`) does `git fetch` then `git switch refs/tags/v` — but -it only runs *inside* `rake build`, after which `bundle install` and a full `rake rdoc` -regeneration (several minutes) will have already happened even if the tag is bad. Check -the tag resolves first: +`rake build` depends on the `switch_default_rails` task, which runs `switch_rails` +(`git fetch` + `git switch refs/tags/v`) as a prerequisite *before* the build +task's own actions. So a missing tag already fails fast — Rake aborts at the switch step, +before the expensive `bundle install` + `rake rdoc` regeneration in `generate_rails_rdoc` +ever runs. No separate gate is required. If you want to confirm the tag ahead of time +anyway (e.g. to fail with a clearer message), check manually: ```sh git -C rails fetch --tags @@ -148,5 +150,6 @@ Generate Rails v docs. one is prefixed in the reference PR. - Trying to clean up the `rails/` submodule's dirty worktree after `rake build` — leave it; see step 5. -- Running the full `rake build` before confirming the target tag exists — see step 2. +- Assuming a bad tag wastes the full `rake build` run — it doesn't; `switch_default_rails` + fails fast before the expensive regeneration starts (see step 2). - Treating a minor-series bump (`8.1` → `8.2`) the same as a patch bump — see step 1. From b753fef95b3e62a44862b30d696675dba99a9216 Mon Sep 17 00:00:00 2001 From: Toshimaru Date: Tue, 11 Aug 2026 18:31:37 +0900 Subject: [PATCH 3/3] fix: don't tie upgrade-rails skill to mise.toml mise is a personal toolchain choice, not a repo-wide requirement. Point to ci.yml's ruby-version instead, which is the actual source of truth for the Ruby version this repo targets. --- .claude/skills/upgrade-rails/SKILL.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.claude/skills/upgrade-rails/SKILL.md b/.claude/skills/upgrade-rails/SKILL.md index 55dbfa654e..46543d84d0 100644 --- a/.claude/skills/upgrade-rails/SKILL.md +++ b/.claude/skills/upgrade-rails/SKILL.md @@ -76,8 +76,9 @@ rake build This switches the `rails` submodule to the new tag, swaps in the `toshimaru/sdoc` fork, regenerates rdoc, copies output into `src/`, and finishes with `bundle exec jekyll build` -— so the Jekyll build is already validated once this completes. Uses Ruby 3.4 per -`mise.toml`. This is the long step. +— so the Jekyll build is already validated once this completes. Use the Ruby version this +repo targets (currently 3.4, see `ruby-version` in `.github/workflows/ci.yml`). This is +the long step. ## 5. Commit the submodule pointer — mind the dirty worktree