Skip to content

Commit 7594a73

Browse files
committed
Add rubocop and GitHub Actions to plugin generator
When creating new Rails plugins, rubocop and GitHub Actions are now included to make linting and testing easier.
1 parent b708a1b commit 7594a73

File tree

9 files changed

+179
-7
lines changed

9 files changed

+179
-7
lines changed

railties/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
* Add Rubocop and GitHub Actions to plugin generator.
2+
This can be skipped using --skip-rubocop and --skip-ci.
3+
4+
*Chris Oliver*
5+
16
* Use Kamal for deployment by default, which includes generating a Rails-specific config/deploy.yml.
27
This can be skipped using --skip-kamal. See more: https://kamal-deploy.org/
38

railties/lib/rails/generators/rails/plugin/plugin_generator.rb

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ def gitignore
6666
template "gitignore", ".gitignore"
6767
end
6868

69+
def cifiles
70+
empty_directory ".github/workflows"
71+
template "github/ci.yml", ".github/workflows/ci.yml"
72+
template "github/dependabot.yml", ".github/dependabot.yml"
73+
end
74+
75+
def rubocop
76+
template "rubocop.yml", ".rubocop.yml"
77+
end
78+
6979
def version_control
7080
if !options[:skip_git] && !options[:pretend]
7181
run git_init_command, capture: options[:quiet], abort_on_failure: false
@@ -171,12 +181,12 @@ def stylesheets
171181
end
172182
end
173183

174-
def bin(force = false)
175-
bin_file = engine? ? "bin/rails.tt" : "bin/test.tt"
176-
template bin_file, force: force do |content|
184+
def bin
185+
exclude_pattern = Regexp.union([(engine? ? /test\.tt/ : /rails\.tt/), (/rubocop/ if skip_rubocop?)].compact)
186+
directory "bin", { exclude_pattern: exclude_pattern } do |content|
177187
"#{shebang}\n" + content
178188
end
179-
chmod "bin", 0755, verbose: false
189+
chmod "bin", 0755 & ~File.umask, verbose: false
180190
end
181191

182192
def gemfile_entry
@@ -247,6 +257,16 @@ def create_app_files
247257
build(:app)
248258
end
249259

260+
def create_rubocop_file
261+
return if skip_rubocop?
262+
build(:rubocop)
263+
end
264+
265+
def create_cifiles
266+
return if skip_ci?
267+
build(:cifiles)
268+
end
269+
250270
def create_config_files
251271
build(:config)
252272
end
@@ -345,7 +365,7 @@ def create_dummy_app(path = nil)
345365
build(:test_dummy_sprocket_assets) unless skip_sprockets?
346366
build(:test_dummy_clean)
347367
# ensure that bin/rails has proper dummy_path
348-
build(:bin, true)
368+
build(:bin)
349369
end
350370
end
351371

@@ -469,6 +489,14 @@ def relative_path
469489
return unless inside_application?
470490
app_path.delete_prefix("#{rails_app_path}/")
471491
end
492+
493+
def test_command
494+
if engine? && !options[:skip_active_record] && with_dummy_app?
495+
"db:test:prepare test"
496+
else
497+
"test"
498+
end
499+
end
472500
end
473501
end
474502
end

railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ require_relative "lib/<%= namespaced_name %>/version"
33
Gem::Specification.new do |spec|
44
spec.name = <%= name.inspect %>
55
spec.version = <%= camelized_modules %>::VERSION
6-
spec.authors = [<%= author.inspect %>]
7-
spec.email = [<%= email.inspect %>]
6+
spec.authors = [ <%= author.inspect %> ]
7+
spec.email = [ <%= email.inspect %> ]
88
spec.homepage = "TODO"
99
spec.summary = "TODO: Summary of <%= camelized_modules %>."
1010
spec.description = "TODO: Description of <%= camelized_modules %>."

railties/lib/rails/generators/rails/plugin/templates/Gemfile.tt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ gemspec
77
<% gemfile_entries.each do |gemfile_entry| %>
88
<%= gemfile_entry %>
99
<% end -%>
10+
<%- unless options.skip_rubocop? -%>
11+
12+
# Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/]
13+
gem "rubocop-rails-omakase", require: false
14+
<%- end -%>
1015
<% if RUBY_ENGINE == "ruby" -%>
1116

1217
# Start debugger with binding.b [https://github.com/ruby/debug]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
require "rubygems"
2+
require "bundler/setup"
3+
4+
# explicit rubocop config increases performance slightly while avoiding config confusion.
5+
ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__))
6+
7+
load Gem.bin_path("rubocop", "rubocop")
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches: [ main ]
7+
8+
jobs:
9+
<%- unless skip_rubocop? -%>
10+
lint:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v4
15+
16+
- name: Set up Ruby
17+
uses: ruby/setup-ruby@v1
18+
with:
19+
ruby-version: <%= ENV["RBENV_VERSION"] || ENV["rvm_ruby_string"] || "#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}" %>
20+
bundler-cache: true
21+
22+
- name: Lint code for consistent style
23+
run: bin/rubocop -f github
24+
25+
<% end -%>
26+
<% unless options[:skip_test] -%>
27+
test:
28+
runs-on: ubuntu-latest
29+
30+
<%- if options[:database] == "sqlite3" -%>
31+
# services:
32+
# redis:
33+
# image: redis
34+
# ports:
35+
# - 6379:6379
36+
# options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
37+
<%- else -%>
38+
services:
39+
<%- if options[:database] == "mysql" || options[:database] == "trilogy" -%>
40+
mysql:
41+
image: mysql
42+
env:
43+
MYSQL_ALLOW_EMPTY_PASSWORD: true
44+
ports:
45+
- 3306:3306
46+
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
47+
<%- elsif options[:database] == "postgresql" -%>
48+
postgres:
49+
image: postgres
50+
env:
51+
POSTGRES_USER: postgres
52+
POSTGRES_PASSWORD: postgres
53+
ports:
54+
- 5432:5432
55+
options: --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=3
56+
<%- end -%>
57+
58+
# redis:
59+
# image: redis
60+
# ports:
61+
# - 6379:6379
62+
# options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
63+
64+
<%- end -%>
65+
steps:
66+
- name: Install packages
67+
run: sudo apt-get update && sudo apt-get install --no-install-recommends -y google-chrome-stable <%= (dockerfile_base_packages + [database.base_package]).join(" ") %>
68+
69+
- name: Checkout code
70+
uses: actions/checkout@v4
71+
72+
- name: Set up Ruby
73+
uses: ruby/setup-ruby@v1
74+
with:
75+
ruby-version: <%= ENV["RBENV_VERSION"] || ENV["rvm_ruby_string"] || "#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}" %>
76+
bundler-cache: true
77+
<%- if using_bun? -%>
78+
79+
- uses: oven-sh/setup-bun@v1
80+
with:
81+
bun-version: <%= dockerfile_bun_version %>
82+
<%- end -%>
83+
84+
- name: Run tests
85+
env:
86+
RAILS_ENV: test
87+
<%- if options[:database] == "mysql" || options[:database] == "trilogy" -%>
88+
DATABASE_URL: mysql2://127.0.0.1:3306
89+
<%- elsif options[:database] == "postgresql" -%>
90+
DATABASE_URL: postgres://postgres:postgres@localhost:5432
91+
<%- end -%>
92+
# REDIS_URL: redis://localhost:6379/0
93+
run: bin/rails <%= test_command %>
94+
95+
- name: Keep screenshots from failed system tests
96+
uses: actions/upload-artifact@v4
97+
if: failure()
98+
with:
99+
name: screenshots
100+
path: ${{ github.workspace }}/tmp/screenshots
101+
if-no-files-found: ignore
102+
<% end -%>
103+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: bundler
4+
directory: "/"
5+
schedule:
6+
interval: daily
7+
open-pull-requests-limit: 10
8+
- package-ecosystem: github-actions
9+
directory: "/"
10+
schedule:
11+
interval: daily
12+
open-pull-requests-limit: 10
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Omakase Ruby styling for Rails
2+
inherit_gem: { rubocop-rails-omakase: rubocop.yml }
3+
4+
# Overwrite or add rules to create your own house style
5+
#
6+
# # Use `[a, [b, c]]` not `[ a, [ b, c ] ]`
7+
# Layout/SpaceInsideArrayLiteralBrackets:
8+
# Enabled: false

railties/test/generators/plugin_generator_test.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@
88

99
DEFAULT_PLUGIN_FILES = %w(
1010
.git
11+
.github/dependabot.yml
12+
.github/workflows/ci.yml
1113
.gitignore
14+
.rubocop.yml
1215
Gemfile
1316
MIT-LICENSE
1417
README.md
1518
Rakefile
19+
bin/rubocop
1620
bin/test
1721
bukkits.gemspec
1822
lib/bukkits.rb

0 commit comments

Comments
 (0)