modulorails 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca0e2fc9ce5fff20082c0b6f659c1a8a554a61fac4040c99e8986b091d65991b
4
- data.tar.gz: 728e081a2e54eab2cfc489ef6f2af22596433ac6fbf0d708635c70ab55846b10
3
+ metadata.gz: 1be41ee3e5898a6e283359c6df4525cd77cec83e6a37d255996316a305511722
4
+ data.tar.gz: dec467bed1e055a3c0d11c948563eaa6eead755be40e6b7185cbb2678f54e180
5
5
  SHA512:
6
- metadata.gz: cbbbd39d4a47ccdce1d5d19f781420738d97d53396c293d11bddbe9c33ae01fcf936cb0e02e5dd06e9ba9ea1fb05fcffbe97733632b5adfb006b266aba74e70f
7
- data.tar.gz: 5d29bad917de52d4860ccb6c64d946904f25df9becfd902ba034e619f0bce0e9fd26dc629b75b9e6fa7ad3266bf48aa6d3e9bf1c6d2f4488edf0dc54c8f0cc53
6
+ metadata.gz: a69ef3ab27fd2e422e5bc7ce588bfa46ca273281ca2e43de7336048b038c1328b22a970066856bd7320df0b144e637348e7d1139cce614c2d068083247d3f666
7
+ data.tar.gz: 7952e968f9bdf475bfe2806933e7e5e5114e8418891dc4dc09809438eb20c804e48a1d85bca8ed558636db64c1b0eca501ea57da5ae03b0eaf4b943a0c466478
@@ -0,0 +1,150 @@
1
+ ---
2
+ name: release-modulorails
3
+ description: Release a new version of the Modulorails Ruby gem to RubyGems. Handles version bump, CHANGELOG, commit, tag, push, GitHub release, and gem publication. Trigger this skill whenever the user asks to release, publish, ship, bump, or cut a new version of modulorails — even if they don't explicitly mention "release" or specify a version (ask for it if missing).
4
+ ---
5
+
6
+ # Release the Modulorails gem
7
+
8
+ Run the full release pipeline for the `modulorails` gem. The user provides the version number (e.g. `1.7.0`) without the `v` prefix. If they omit it, ask before proceeding.
9
+
10
+ ## Conventions
11
+
12
+ - `<version>`: the version number without `v` prefix (e.g. `1.7.0`)
13
+ - All commands run from the project root: `/home/claude/modulorails`
14
+ - GitHub repo: `https://github.com/moduloTech/modulorails`
15
+ - Gem published to: `https://rubygems.org/gems/modulorails`
16
+ - Tag format: `v<version>` (e.g. `v1.7.0`)
17
+ - The gemspec has `rubygems_mfa_required = 'true'`, so `gem push` will prompt for an OTP. Tell the user to have their authenticator app ready before step 7.
18
+
19
+ ## Steps
20
+
21
+ ### 1. Pre-flight check
22
+
23
+ - Run `git status` and `git diff` to surface any uncommitted changes.
24
+ - The release commit should only touch `lib/modulorails/version.rb` and `CHANGELOG.md`. If unrelated changes are pending, ask the user whether to include them, stash them, or abort.
25
+ - Confirm the current branch is `master` (the project's main branch) unless the user specified otherwise.
26
+
27
+ ### 2. Bump the version constant
28
+
29
+ - Edit `lib/modulorails/version.rb` and replace the value of `VERSION` with `<version>`.
30
+ - The constant looks like: `VERSION = '1.6.0'.freeze` — keep the single quotes and `.freeze` to match the existing style.
31
+
32
+ ### 3. Update CHANGELOG.md
33
+
34
+ The Modulorails CHANGELOG uses its own format — **do not** convert it to Keep-a-Changelog. The structure is:
35
+
36
+ ```
37
+ # Unreleased
38
+
39
+ # <version>
40
+
41
+ <one-line summary, optional>
42
+
43
+ ## Features
44
+ - ...
45
+
46
+ ## Improvements
47
+ - ...
48
+
49
+ ## Fixes
50
+ - ...
51
+
52
+ ## Deprecations (will be removed in <next major>)
53
+ - ...
54
+ ```
55
+
56
+ To update:
57
+
58
+ - Replace the `# Unreleased` heading with `# <version>` (and add a fresh `# Unreleased` line above it for the next cycle).
59
+ - Categorize changes under `## Features`, `## Improvements`, `## Fixes`, or `## Deprecations` as appropriate. Omit sections that have no entries.
60
+ - Run `git log --oneline <last-tag>..HEAD` to find the commits since the previous release; use those as the source of changelog entries. Phrase entries as user-facing descriptions, not commit-message echoes.
61
+
62
+ ### 4. Commit the bump
63
+
64
+ Stage **only** `lib/modulorails/version.rb` and `CHANGELOG.md`, then commit. Match the project's existing release commit style — prior bumps use messages like `Bump modulorails to 1.6.0`:
65
+
66
+ ```bash
67
+ git add lib/modulorails/version.rb CHANGELOG.md
68
+ git commit -m "$(cat <<'EOF'
69
+ Bump modulorails to <version>
70
+
71
+ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
72
+ EOF
73
+ )"
74
+ ```
75
+
76
+ (Use whichever Co-Authored-By trailer matches the model running the session — don't hardcode an older one.)
77
+
78
+ ### 5. Tag
79
+
80
+ ```bash
81
+ git tag -a v<version> -m "v<version>"
82
+ ```
83
+
84
+ ### 6. Push commit and tag
85
+
86
+ ```bash
87
+ git push origin master
88
+ git push origin v<version>
89
+ ```
90
+
91
+ ### 7. Build and push the gem to RubyGems
92
+
93
+ ```bash
94
+ gem build modulorails.gemspec
95
+ gem push modulorails-<version>.gem
96
+ ```
97
+
98
+ `gem push` will prompt for the OTP because `rubygems_mfa_required` is set in the gemspec. The user must enter it interactively — surface the prompt to them.
99
+
100
+ If the user is unauthenticated (`You don't have any sources that contain this gem.` or similar), they need to run `gem signin` first. Don't try to manage their RubyGems credentials.
101
+
102
+ After a successful push, delete the local `.gem` artifact: `rm modulorails-<version>.gem`.
103
+
104
+ ### 8. Create the GitHub release
105
+
106
+ ```bash
107
+ gh release create v<version> --title "v<version>" --notes "<notes>"
108
+ ```
109
+
110
+ Notes should mirror the CHANGELOG section for this version (markdown-formatted). Pass the body via a HEREDOC if it's multi-line, e.g.:
111
+
112
+ ```bash
113
+ gh release create v<version> --title "v<version>" --notes "$(cat <<'EOF'
114
+ ## Features
115
+ - ...
116
+
117
+ ## Fixes
118
+ - ...
119
+ EOF
120
+ )"
121
+ ```
122
+
123
+ ### 9. Confirm
124
+
125
+ - Print the GitHub release URL (`gh release view v<version> --json url -q .url`).
126
+ - Print the RubyGems URL: `https://rubygems.org/gems/modulorails/versions/<version>`.
127
+ - Remind the user that downstream apps can pull the new version via `bundle update modulorails`.
128
+
129
+ ## Alternative: `bundle exec rake release`
130
+
131
+ The Rakefile already loads `bundler/gem_tasks`, so `bundle exec rake release` will, in one shot:
132
+
133
+ 1. Verify the working tree is clean.
134
+ 2. Build `modulorails-<version>.gem`.
135
+ 3. Tag `v<version>` from the current HEAD.
136
+ 4. Push the tag to `origin`.
137
+ 5. `gem push` to RubyGems.
138
+
139
+ Use this only when:
140
+ - The version bump and CHANGELOG are already committed and pushed (it does **not** create the bump commit).
141
+ - The user explicitly asks for the shortcut.
142
+
143
+ The downsides vs. the step-by-step flow: if `gem push` fails (bad OTP, network), the tag is already pushed and you need to clean up manually. The manual flow keeps tag and gem push independent so each failure mode is recoverable on its own.
144
+
145
+ ## Troubleshooting
146
+
147
+ - **`gem push` fails with 401 / OTP rejected**: the OTP window is short — re-run with a fresh code. Don't re-tag or re-commit; just retry the `gem push` step.
148
+ - **Tag already exists locally but push fails**: `git tag -d v<version>` and recreate after fixing the underlying issue. Never force-push a tag that's already on RubyGems.
149
+ - **`gem build` complains about missing files**: the gemspec uses `git ls-files` to enumerate files, so untracked files won't be in the gem. Stage them first if they belong, or `.gitignore` them if not.
150
+ - **GitHub release notes don't render properly**: HEREDOC quoting matters — use `<<'EOF'` (with quotes) to prevent shell expansion in the notes body.
data/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@ This file is used to list changes made in each version of the gem.
4
4
 
5
5
  # Unreleased
6
6
 
7
+ # 1.7.0
8
+
9
+ ## Improvements
10
+
11
+ - Make the Rubocop generator idempotent: `.rubocop.yml` is no longer rewritten on every Rails boot. Like the other generators, `RubocopGenerator` now uses the `.modulorails.yml` keepfile and a `VERSION` constant — the config is only (re)generated on the first run or when the generator's version is bumped.
12
+
13
+ ## Fixes
14
+
15
+ - Fix `initialize_from_git` when the git repository is not available (no `.git`, missing `git` binary, or no `origin` remote): rescue the error, warn, and leave `repository` as `nil` instead of crashing the application boot.
16
+ - Fix `send_data` and `self_update` crashing with `NoMethodError` when `Rails.logger` is `nil` (e.g. early initialization or minimal apps): use safe navigation on debug logging.
17
+
18
+ ## Internal
19
+
20
+ - Add `release-modulorails` Claude Code skill (`.claude/skills/release-modulorails/`) to standardize the gem release workflow.
21
+
7
22
  # 1.6.0
8
23
 
9
24
  The devcontainer release.
data/Gemfile.lock CHANGED
@@ -1,12 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- modulorails (0.4.0)
4
+ modulorails (1.6.0)
5
+ bundler-audit (~> 0.9.1)
5
6
  git (~> 1.7, >= 1.7.0)
6
7
  health_check (~> 3.1)
7
- httparty
8
- i18n
8
+ httparty (>= 0.13.3)
9
+ i18n (>= 0.9.5)
9
10
  railties (>= 4.2.0)
11
+ rubocop (>= 1.28.2)
12
+ rubocop-rails (>= 2.14.2)
10
13
 
11
14
  GEM
12
15
  remote: https://rubygems.org/
@@ -34,44 +37,64 @@ GEM
34
37
  i18n (>= 1.6, < 2)
35
38
  minitest (>= 5.1)
36
39
  tzinfo (~> 2.0)
40
+ addressable (2.9.0)
41
+ public_suffix (>= 2.0.2, < 8.0)
37
42
  appraisal (2.4.1)
38
43
  bundler
39
44
  rake
40
45
  thor (>= 0.14.0)
41
- builder (3.2.4)
46
+ ast (2.4.3)
47
+ bigdecimal (4.1.2)
48
+ builder (3.3.0)
49
+ bundler-audit (0.9.3)
50
+ bundler (>= 1.2.0)
51
+ thor (~> 1.0)
42
52
  concurrent-ruby (1.1.9)
43
53
  crass (1.0.6)
54
+ csv (3.3.5)
44
55
  diff-lcs (1.5.0)
45
- erubi (1.10.0)
46
- git (1.10.2)
56
+ erubi (1.13.1)
57
+ git (1.19.1)
58
+ addressable (~> 2.8)
47
59
  rchardet (~> 1.8)
48
60
  health_check (3.1.0)
49
61
  railties (>= 5.0)
50
- httparty (0.20.0)
51
- mime-types (~> 3.0)
62
+ httparty (0.24.2)
63
+ csv
64
+ mini_mime (>= 1.0.0)
52
65
  multi_xml (>= 0.5.2)
53
66
  i18n (1.8.11)
54
67
  concurrent-ruby (~> 1.0)
55
- loofah (2.13.0)
68
+ json (2.19.4)
69
+ language_server-protocol (3.17.0.5)
70
+ lint_roller (1.1.0)
71
+ loofah (2.25.1)
56
72
  crass (~> 1.0.2)
57
- nokogiri (>= 1.5.9)
58
- method_source (1.0.0)
59
- mime-types (3.4.1)
60
- mime-types-data (~> 3.2015)
61
- mime-types-data (3.2022.0105)
73
+ nokogiri (>= 1.12.0)
74
+ method_source (1.1.0)
75
+ mini_mime (1.1.5)
62
76
  minitest (5.15.0)
63
- multi_xml (0.6.0)
64
- nokogiri (1.13.1-aarch64-linux)
77
+ multi_xml (0.8.1)
78
+ bigdecimal (>= 3.1, < 5)
79
+ nokogiri (1.19.3-aarch64-linux-gnu)
65
80
  racc (~> 1.4)
66
- racc (1.6.0)
67
- rack (2.2.3)
68
- rack-test (1.1.0)
69
- rack (>= 1.0, < 3)
70
- rails-dom-testing (2.0.3)
71
- activesupport (>= 4.2.0)
81
+ parallel (1.28.0)
82
+ parser (3.3.11.1)
83
+ ast (~> 2.4.1)
84
+ racc
85
+ prism (1.9.0)
86
+ public_suffix (7.0.5)
87
+ racc (1.8.1)
88
+ rack (2.2.23)
89
+ rack-test (2.2.0)
90
+ rack (>= 1.3)
91
+ rails-dom-testing (2.3.0)
92
+ activesupport (>= 5.0.0)
93
+ minitest
72
94
  nokogiri (>= 1.6)
73
- rails-html-sanitizer (1.4.2)
74
- loofah (~> 2.3)
95
+ rails-html-sanitizer (1.7.0)
96
+ loofah (~> 2.25)
97
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
75
98
  railties (7.0.0)
76
99
  actionpack (= 7.0.0)
77
100
  activesupport (= 7.0.0)
@@ -79,8 +102,10 @@ GEM
79
102
  rake (>= 12.2)
80
103
  thor (~> 1.0)
81
104
  zeitwerk (~> 2.5)
105
+ rainbow (3.1.1)
82
106
  rake (12.3.3)
83
- rchardet (1.8.0)
107
+ rchardet (1.10.0)
108
+ regexp_parser (2.12.0)
84
109
  rspec (3.10.0)
85
110
  rspec-core (~> 3.10.0)
86
111
  rspec-expectations (~> 3.10.0)
@@ -94,10 +119,34 @@ GEM
94
119
  diff-lcs (>= 1.2.0, < 2.0)
95
120
  rspec-support (~> 3.10.0)
96
121
  rspec-support (3.10.3)
122
+ rubocop (1.86.1)
123
+ json (~> 2.3)
124
+ language_server-protocol (~> 3.17.0.2)
125
+ lint_roller (~> 1.1.0)
126
+ parallel (>= 1.10)
127
+ parser (>= 3.3.0.2)
128
+ rainbow (>= 2.2.2, < 4.0)
129
+ regexp_parser (>= 2.9.3, < 3.0)
130
+ rubocop-ast (>= 1.49.0, < 2.0)
131
+ ruby-progressbar (~> 1.7)
132
+ unicode-display_width (>= 2.4.0, < 4.0)
133
+ rubocop-ast (1.49.1)
134
+ parser (>= 3.3.7.2)
135
+ prism (~> 1.7)
136
+ rubocop-rails (2.34.3)
137
+ activesupport (>= 4.2.0)
138
+ lint_roller (~> 1.1)
139
+ rack (>= 1.1)
140
+ rubocop (>= 1.75.0, < 2.0)
141
+ rubocop-ast (>= 1.44.0, < 2.0)
142
+ ruby-progressbar (1.13.0)
97
143
  thor (1.2.1)
98
144
  tzinfo (2.0.4)
99
145
  concurrent-ruby (~> 1.0)
100
- zeitwerk (2.5.3)
146
+ unicode-display_width (3.2.0)
147
+ unicode-emoji (~> 4.1)
148
+ unicode-emoji (4.2.0)
149
+ zeitwerk (2.7.5)
101
150
 
102
151
  PLATFORMS
103
152
  aarch64-linux
@@ -1,18 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rails/generators'
3
+ require 'modulorails/generators/base'
4
4
 
5
- class Modulorails::RubocopGenerator < Rails::Generators::Base
5
+ class Modulorails::RubocopGenerator < Modulorails::Generators::Base
6
+
7
+ VERSION = 1
6
8
 
7
9
  source_root File.expand_path('templates', __dir__)
8
10
  desc 'This generator creates a configuration for Rubocop'
9
11
 
10
- def create_config_files
12
+ protected
13
+
14
+ def create_config
11
15
  rubocop_config_path = Rails.root.join('.rubocop.yml')
12
16
  gitlab_config_path = Rails.root.join('.gitlab-ci.yml')
13
17
 
14
18
  template 'rubocop.yml', rubocop_config_path, force: true
15
19
 
20
+ return unless File.exist?(gitlab_config_path)
16
21
  return if File.read(gitlab_config_path).match?(/\s+extends:\s+.lint\s*$/)
17
22
 
18
23
  append_file gitlab_config_path do
@@ -166,6 +166,8 @@ module Modulorails
166
166
  # Theorically, origin is the main repository of the project and git is the sole VCS we use
167
167
  # at Modulotech
168
168
  @repository = Git.open(::Rails.root).config('remote.origin.url')
169
+ rescue ArgumentError, Git::GitExecuteError => e
170
+ warn("[Modulorails] Error: #{e.message}")
169
171
  end
170
172
 
171
173
  def to_project_data_params
@@ -1,6 +1,6 @@
1
1
  module Modulorails
2
2
 
3
- VERSION = '1.6.0'.freeze
3
+ VERSION = '1.7.0'.freeze
4
4
 
5
5
  # Useful to compare the current Ruby version
6
6
  COMPARABLE_RUBY_VERSION = Gem::Version.new(RUBY_VERSION)
data/lib/modulorails.rb CHANGED
@@ -98,14 +98,14 @@ module Modulorails
98
98
  # went wrong with an `errors` field. We do not want to raise since the gem's user is not
99
99
  # (necessarily) responsible for the error but we still need to display it somewhere to warn
100
100
  # the user something went wrong.
101
- Rails.logger.debug { "[Modulorails] Error: #{response['errors'].join(', ')}" } if response.code == 400
101
+ Rails.logger&.debug { "[Modulorails] Error: #{response['errors'].join(', ')}" } if response.code == 400
102
102
 
103
103
  # Return the response to allow users to do some more
104
104
  response
105
105
  rescue StandardError => e
106
106
  # Still need to notify the user
107
- Rails.logger.debug { "[Modulorails] Error: Could not post to #{configuration.endpoint}" }
108
- Rails.logger.debug e.message
107
+ Rails.logger&.debug { "[Modulorails] Error: Could not post to #{configuration.endpoint}" }
108
+ Rails.logger&.debug e.message
109
109
  nil
110
110
  end
111
111
  end
@@ -135,7 +135,7 @@ module Modulorails
135
135
 
136
136
  Modulorails::SelfUpdateGenerator.new([], {}, {}).invoke_all
137
137
  rescue StandardError => e
138
- Rails.logger.debug { "[Modulorails] An error occured: #{e.class} - #{e.message}" }
138
+ Rails.logger&.debug { "[Modulorails] An error occured: #{e.class} - #{e.message}" }
139
139
  end
140
140
 
141
141
  # @author Matthieu 'ciappa_m' Ciappara
@@ -148,7 +148,8 @@ module Modulorails
148
148
 
149
149
  # @author Matthieu 'ciappa_m' Ciappara
150
150
  #
151
- # Generate a rubocop configuration.
151
+ # Generate a rubocop configuration unless it was already done.
152
+ # The check is done using a 'keepfile'.
152
153
  def generate_rubocop_template
153
154
  Modulorails::RubocopGenerator.new([], {}, {}).invoke_all
154
155
  end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modulorails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthieu Ciappara
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-04-28 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: bundler-audit
@@ -139,6 +140,7 @@ executables: []
139
140
  extensions: []
140
141
  extra_rdoc_files: []
141
142
  files:
143
+ - ".claude/skills/release-modulorails/SKILL.md"
142
144
  - ".dockerignore"
143
145
  - ".gitignore"
144
146
  - ".rspec"
@@ -241,6 +243,7 @@ metadata:
241
243
  source_code_uri: https://github.com/moduloTech/modulorails
242
244
  changelog_uri: https://github.com/moduloTech/modulorails/blob/master/CHANGELOG.md
243
245
  rubygems_mfa_required: 'true'
246
+ post_install_message:
244
247
  rdoc_options: []
245
248
  require_paths:
246
249
  - lib
@@ -255,7 +258,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
255
258
  - !ruby/object:Gem::Version
256
259
  version: '0'
257
260
  requirements: []
258
- rubygems_version: 4.0.3
261
+ rubygems_version: 3.4.19
262
+ signing_key:
259
263
  specification_version: 4
260
264
  summary: Common base for Ruby on Rails projects at Modulotech
261
265
  test_files: []