From dea279df4d48268653ed96a95461b73256555020 Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 6 Aug 2026 10:48:17 +0200 Subject: [PATCH 1/3] docs: add new-package checklist to CLAUDE.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codifies the checklist for scaffolding a new packages/* gem — version.rb format, .rubocop.yml exclusions, .releaserc.js entries, and build.yml CI matrix — after PR #343 missed the rubocop exclusion and shipped a version.rb format that silently breaks the release version-bump sed. Co-Authored-By: Claude Sonnet 5 --- CLAUDE.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..51fd9dad5 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,42 @@ +# CLAUDE.md + +## Adding a new package to the monorepo + +When scaffolding a new `packages/forest_admin_datasource_*` (or any new) +package, mirror an existing package's scaffold (`Gemfile`, `Gemfile-test`, +`Rakefile`, `.rspec`, gemspec, `LICENSE`, `spec/spec_helper.rb`, `.gitignore`) +and update every one of these in the same PR — missing one breaks CI or +releases silently, not loudly: + +1. **`lib//version.rb`** — must be exactly: + ```ruby + module + VERSION = "0.1.0" + end + ``` + Double quotes, no `.freeze`. The release sed in `.releaserc.js` only + matches this exact format. + +2. **`.rubocop.yml`** — add the new `version.rb` to: + - `Style/MutableConstant` Exclude + - `Style/StringLiterals` Exclude + + And the new `.gemspec` to `Gemspec/RequireMFA` Exclude. + + (Other per-file excludes — `Metrics/MethodLength`, `Metrics/BlockLength`, + `Naming/PredicatePrefix` — are added case-by-case only if the cop actually + fires; don't copy them blindly.) + +3. **`.releaserc.js`** — add the package in all three spots: + - `prepareCmd`: `sed -i 's/VERSION = ".*"/VERSION = "${nextRelease.version}"/g' packages//lib//version.rb;` + - `successCmd`: `( cd packages/ && gem build && gem push -*.gem );` + - `@semantic-release/git` `assets`: `packages//lib//version.rb` + +4. **`.github/workflows/build.yml`** — add the package name to: + - the `lint` job's `packages` matrix + - the `test` job's `packages` matrix + - the codecov step's `files:` list (`...//coverage.json`) + +After merging, verify the next release actually bumps the new `version.rb` — +the sed in step 3 silently no-ops if the format from step 1 is off, with no +CI failure to catch it. From 6ee9b00e6081cede1dbf4590efecba0d62357e93 Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 6 Aug 2026 11:00:09 +0200 Subject: [PATCH 2/3] docs: cover gemspec MFA opt-out in new-package checklist Per bexchauveto's review on #345: the .rubocop.yml Gemspec/RequireMFA exclusion only exists because the gemspec explicitly opts out of MFA (spec.metadata['rubygems_mfa_required'] = 'false') since gem publishing runs unattended from CI. Document that step, not just its rubocop suppression. Co-Authored-By: Claude Sonnet 5 --- CLAUDE.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 51fd9dad5..b549f740f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -17,22 +17,31 @@ releases silently, not loudly: Double quotes, no `.freeze`. The release sed in `.releaserc.js` only matches this exact format. -2. **`.rubocop.yml`** — add the new `version.rb` to: +2. **New `.gemspec`** — explicitly opt out of RubyGems MFA, matching every + other package: + ```ruby + spec.metadata['rubygems_mfa_required'] = 'false' + ``` + Gem publishing runs unattended from CI (`.releaserc.js`), so it can't + satisfy an MFA prompt. + +3. **`.rubocop.yml`** — add the new `version.rb` to: - `Style/MutableConstant` Exclude - `Style/StringLiterals` Exclude - And the new `.gemspec` to `Gemspec/RequireMFA` Exclude. + And the new `.gemspec` to `Gemspec/RequireMFA` Exclude — the cop flags + the `'false'` opt-out from step 2 as an offense, so it needs suppressing. (Other per-file excludes — `Metrics/MethodLength`, `Metrics/BlockLength`, `Naming/PredicatePrefix` — are added case-by-case only if the cop actually fires; don't copy them blindly.) -3. **`.releaserc.js`** — add the package in all three spots: +4. **`.releaserc.js`** — add the package in all three spots: - `prepareCmd`: `sed -i 's/VERSION = ".*"/VERSION = "${nextRelease.version}"/g' packages//lib//version.rb;` - `successCmd`: `( cd packages/ && gem build && gem push -*.gem );` - `@semantic-release/git` `assets`: `packages//lib//version.rb` -4. **`.github/workflows/build.yml`** — add the package name to: +5. **`.github/workflows/build.yml`** — add the package name to: - the `lint` job's `packages` matrix - the `test` job's `packages` matrix - the codecov step's `files:` list (`...//coverage.json`) From bf1bcfbdf0e4b8299d1b55790f56cf88123dcc2b Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 6 Aug 2026 11:04:52 +0200 Subject: [PATCH 3/3] docs: fix step cross-reference in new-package checklist Macroscope flagged on PR #345 that the closing note pointed to step 3 (rubocop excludes) for the release sed, but the sed lives in step 4 (.releaserc.js). Co-Authored-By: Claude Sonnet 5 --- CLAUDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index b549f740f..111a82097 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -47,5 +47,5 @@ releases silently, not loudly: - the codecov step's `files:` list (`...//coverage.json`) After merging, verify the next release actually bumps the new `version.rb` — -the sed in step 3 silently no-ops if the format from step 1 is off, with no +the sed in step 4 silently no-ops if the format from step 1 is off, with no CI failure to catch it.