rolemodel-rails 0.26.0 → 1.1.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 +4 -4
- data/README.md +15 -4
- data/lib/generators/rolemodel/all_generator.rb +2 -1
- data/lib/generators/rolemodel/editors/editors_generator.rb +1 -1
- data/lib/generators/rolemodel/github/README.md +14 -17
- data/lib/generators/rolemodel/github/USAGE +4 -1
- data/lib/generators/rolemodel/github/github_generator.rb +24 -18
- data/lib/generators/rolemodel/github/templates/CODEOWNERS +8 -0
- data/lib/generators/rolemodel/github/templates/dependabot.yml +87 -0
- data/lib/generators/rolemodel/github/templates/instructions +1 -0
- data/lib/generators/rolemodel/github/templates/pull_request_template.md +18 -0
- data/lib/generators/rolemodel/github/templates/workflows/ci.yml.tt +81 -0
- data/lib/generators/rolemodel/good_job/good_job_generator.rb +1 -1
- data/lib/generators/rolemodel/heroku/heroku_generator.rb +1 -1
- data/lib/generators/rolemodel/kaminari/kaminari_generator.rb +1 -1
- data/lib/generators/rolemodel/linters/all_generator.rb +1 -1
- data/lib/generators/rolemodel/linters/eslint/eslint_generator.rb +1 -1
- data/lib/generators/rolemodel/linters/rubocop/rubocop_generator.rb +1 -1
- data/lib/generators/rolemodel/lograge/lograge_generator.rb +1 -1
- data/lib/generators/rolemodel/mailers/mailers_generator.rb +1 -1
- data/lib/generators/rolemodel/mcp/README.md +13 -0
- data/lib/generators/rolemodel/mcp/USAGE +8 -0
- data/lib/generators/rolemodel/mcp/mcp_generator.rb +110 -0
- data/lib/generators/rolemodel/mcp/templates/app/assets/stylesheets/components/doorkeeper.css +140 -0
- data/lib/generators/rolemodel/mcp/templates/app/controllers/doorkeeper/base_controller.rb +7 -0
- data/lib/generators/rolemodel/mcp/templates/app/controllers/mcp_controller.rb.tt +91 -0
- data/lib/generators/rolemodel/mcp/templates/app/controllers/oauth_registrations_controller.rb +46 -0
- data/lib/generators/rolemodel/mcp/templates/app/controllers/well_known_controller.rb +39 -0
- data/lib/generators/rolemodel/mcp/templates/app/mcp/prompts/sample.rb +36 -0
- data/lib/generators/rolemodel/mcp/templates/app/mcp/resources/controller.rb +57 -0
- data/lib/generators/rolemodel/mcp/templates/app/mcp/resources/docs/SAMPLE_DOC.md +4 -0
- data/lib/generators/rolemodel/mcp/templates/app/mcp/resources/docs_controller.rb +46 -0
- data/lib/generators/rolemodel/mcp/templates/app/mcp/tools/sample.rb +42 -0
- data/lib/generators/rolemodel/mcp/templates/app/views/doorkeeper/authorizations/error.html.slim.tt +13 -0
- data/lib/generators/rolemodel/mcp/templates/app/views/doorkeeper/authorizations/new.html.slim.tt +41 -0
- data/lib/generators/rolemodel/mcp/templates/app/views/layouts/doorkeeper.html.slim +7 -0
- data/lib/generators/rolemodel/mcp/templates/config/initializers/doorkeeper.rb +537 -0
- data/lib/generators/rolemodel/mcp/templates/spec/mcp/prompts/sample_spec.rb +15 -0
- data/lib/generators/rolemodel/mcp/templates/spec/mcp/resources/controller_spec.rb +16 -0
- data/lib/generators/rolemodel/mcp/templates/spec/mcp/resources/docs_controller_spec.rb +55 -0
- data/lib/generators/rolemodel/mcp/templates/spec/mcp/tools/sample_spec.rb +15 -0
- data/lib/generators/rolemodel/mcp/templates/spec/requests/mcp_controller_spec.rb +84 -0
- data/lib/generators/rolemodel/mcp/templates/spec/requests/oauth_registrations_controller_spec.rb +62 -0
- data/lib/generators/rolemodel/mcp/templates/spec/requests/well_known_controller_spec.rb +30 -0
- data/lib/generators/rolemodel/optics/all_generator.rb +1 -1
- data/lib/generators/rolemodel/optics/base/base_generator.rb +2 -2
- data/lib/generators/rolemodel/optics/icons/icons_generator.rb +1 -1
- data/lib/generators/rolemodel/react/react_generator.rb +1 -1
- data/lib/generators/rolemodel/readme/readme_generator.rb +1 -1
- data/lib/generators/rolemodel/saas/all_generator.rb +1 -1
- data/lib/generators/rolemodel/saas/devise/devise_generator.rb +1 -1
- data/lib/generators/rolemodel/semaphore/semaphore_generator.rb +1 -1
- data/lib/generators/rolemodel/simple_form/simple_form_generator.rb +1 -1
- data/lib/generators/rolemodel/slim/slim_generator.rb +1 -1
- data/lib/generators/rolemodel/soft_destroyable/soft_destroyable_generator.rb +1 -1
- data/lib/generators/rolemodel/source_map/source_map_generator.rb +1 -1
- data/lib/generators/rolemodel/tailored_select/tailored_select_generator.rb +1 -1
- data/lib/generators/rolemodel/testing/all_generator.rb +1 -1
- data/lib/generators/rolemodel/testing/factory_bot/factory_bot_generator.rb +1 -1
- data/lib/generators/rolemodel/testing/jasmine_playwright/jasmine_playwright_generator.rb +1 -1
- data/lib/generators/rolemodel/testing/parallel_tests/parallel_tests_generator.rb +1 -1
- data/lib/generators/rolemodel/testing/rspec/rspec_generator.rb +1 -2
- data/lib/generators/rolemodel/testing/rspec/templates/rails_helper.rb +4 -0
- data/lib/generators/rolemodel/testing/rspec/templates/support/capybara_drivers.rb +0 -2
- data/lib/generators/rolemodel/testing/rspec/templates/support/helpers/capybara_helper.rb +0 -46
- data/lib/generators/rolemodel/testing/rspec/templates/support/helpers/playwright_helper.rb +0 -60
- data/lib/generators/rolemodel/testing/test_prof/test_prof_generator.rb +1 -1
- data/lib/generators/rolemodel/testing/vitest/vitest_generator.rb +1 -1
- data/lib/generators/rolemodel/ui_components/all_generator.rb +1 -1
- data/lib/generators/rolemodel/ui_components/flash/flash_generator.rb +1 -1
- data/lib/generators/rolemodel/ui_components/modals/modals_generator.rb +1 -1
- data/lib/generators/rolemodel/ui_components/navbar/navbar_generator.rb +1 -1
- data/lib/generators/rolemodel/webpack/webpack_generator.rb +1 -1
- data/lib/rolemodel/engine.rb +3 -1
- data/lib/rolemodel/generator_base.rb +17 -0
- data/lib/rolemodel/version.rb +1 -1
- data/lib/rolemodel-rails.rb +2 -0
- metadata +32 -7
- data/lib/generators/rolemodel/base_generator.rb +0 -14
- data/lib/generators/templates/generator/%filename%.rb.tt +0 -11
- data/lib/generators/templates/generator/README.md.tt +0 -11
- data/lib/generators/templates/generator/USAGE.tt +0 -5
- data/lib/generators/templates/generator_spec/%filename%_spec.rb.tt +0 -5
- /data/lib/{generators/rolemodel → rolemodel}/replace_content_helper.rb +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d3e11cf41b7d9e5afb68a8eaca61a30785b10dcb9032fc327a52f40ea8271a2e
|
|
4
|
+
data.tar.gz: 4b4388ba6e3b2608135be47000bc9ba655b32bd4936e096d2e3ba8cafe4904c3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 173f38c6b5f5f0101a143aaf8a5301afd7a69295d68e1c8eb54a5bd2cf06b57254f658e312a19a3a2605f6920ddab05f6f8941a0797ce7400e83c2e3ff13ac38
|
|
7
|
+
data.tar.gz: 77b6be040efd20cd738c14c44c92c57ac84241a75685cc157bfa86ddc3b6b7b6675eec3b2ad8a3b8c6dfb83c7e568aca7420746b6b81ef7d1172d6392c490c47
|
data/README.md
CHANGED
|
@@ -28,9 +28,7 @@ rails db:create
|
|
|
28
28
|
Add this line to your application's Gemfile:
|
|
29
29
|
|
|
30
30
|
```ruby
|
|
31
|
-
group :development
|
|
32
|
-
gem 'rolemodel-rails', github: 'RoleModel/rolemodel_rails'
|
|
33
|
-
end
|
|
31
|
+
gem 'rolemodel-rails', group: :development
|
|
34
32
|
```
|
|
35
33
|
|
|
36
34
|
And then execute:
|
|
@@ -115,7 +113,7 @@ e.g.
|
|
|
115
113
|
bin/new_generator testing/fantasitic_specs 'A Fantastic Testing Framework'
|
|
116
114
|
```
|
|
117
115
|
|
|
118
|
-
We use the embeded Rails apps (`
|
|
116
|
+
We use the embeded Rails apps (`example_rails_current` & `example_rails_legacy`) to test generators against. They reference the rolemodel-rails gem by local path,
|
|
119
117
|
so you can navigate into one of them and run your generator for immediate feedback while developing.
|
|
120
118
|
|
|
121
119
|
> [!IMPORTANT]
|
|
@@ -146,6 +144,19 @@ RSpec.describe Rolemodel::Testing::JasminePlaywrightGenerator, type: :generator
|
|
|
146
144
|
end
|
|
147
145
|
```
|
|
148
146
|
|
|
147
|
+
If the generator you're testing depends on being run after another generator, you should run that one first.
|
|
148
|
+
|
|
149
|
+
e.g.
|
|
150
|
+
|
|
151
|
+
```ruby
|
|
152
|
+
RSpec.describe Rolemodel::MyGenerator, type: :generator do
|
|
153
|
+
before do
|
|
154
|
+
run_generator_against_test_app(generator: ::Rolemodel::PrereqGenerator)
|
|
155
|
+
run_generator_against_test_app
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
```
|
|
159
|
+
|
|
149
160
|
Additional information about testing generators and the available assertions & matchers can be found at the following resources.
|
|
150
161
|
|
|
151
162
|
* [Rails Guide](https://guides.rubyonrails.org/generators.html#testing-generators)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module Rolemodel
|
|
2
|
-
class AllGenerator <
|
|
2
|
+
class AllGenerator < GeneratorBase
|
|
3
3
|
source_root File.expand_path('templates', __dir__)
|
|
4
4
|
|
|
5
5
|
def run_all_the_generators
|
|
@@ -24,6 +24,7 @@ module Rolemodel
|
|
|
24
24
|
generate 'rolemodel:editors'
|
|
25
25
|
# generate 'rolemodel:tailored_select' # Not production ready
|
|
26
26
|
generate 'rolemodel:lograge'
|
|
27
|
+
generate 'rolemodel:mcp'
|
|
27
28
|
end
|
|
28
29
|
end
|
|
29
30
|
end
|
|
@@ -4,7 +4,7 @@ require_relative 'vscode_helpers'
|
|
|
4
4
|
|
|
5
5
|
module Rolemodel
|
|
6
6
|
# Add standard editorconfig and any extensions to enable it
|
|
7
|
-
class EditorsGenerator <
|
|
7
|
+
class EditorsGenerator < GeneratorBase
|
|
8
8
|
include Rolemodel::VSCodeHelpers
|
|
9
9
|
|
|
10
10
|
# This is bringing in the root from this gem, so we only modify
|
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
# Github Generator
|
|
2
2
|
|
|
3
3
|
## Prerequisites
|
|
4
|
-
You will need the parallel_tests generator to run the CI tests.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
### ci.yml
|
|
9
|
-
A sensible default `ci.yml` to get you started with Github Actions. This will run linters, model tests, and system tests.
|
|
10
|
-
|
|
11
|
-
Along with the `ci.yml`, your `database.yml` will be modified to be able to be run in GHA.
|
|
12
|
-
|
|
13
|
-
### Pull Request Template
|
|
5
|
+
It doesn't need to be run first, but the parallel_tests generator must be run in order for the CI workflow to run successfully on GitHub.
|
|
14
6
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Helpful for reminding collaborators to add specific details to the PR.
|
|
18
|
-
|
|
19
|
-
### Copilot Instructions
|
|
7
|
+
## What you get
|
|
20
8
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
- CI workflow
|
|
10
|
+
- A sensible default `ci.yml` to get you started with Github Actions. This will run linters, model tests, and system tests.
|
|
11
|
+
- Along with the `ci.yml`, your `database.yml` will be modified to be able to be run in GHA.
|
|
12
|
+
- Pull Request Template
|
|
13
|
+
- When you open a Pull Request in Github it will use the Markdown file as a [template](./templates/pull_request_template.md) for the content of the PR.
|
|
14
|
+
- Helpful for reminding collaborators to add specific details to the PR.
|
|
15
|
+
- Copilot Instructions
|
|
16
|
+
- Installed into `.github/instructions`, these are context-specific instructions for Copilot to help it give more accurate
|
|
17
|
+
and relevant results. These are a good starting point but they should be tweaked for your project's frameworks and
|
|
18
|
+
standards.
|
|
19
|
+
- Dependabot Configuration
|
|
20
|
+
- defines a set of rules that dependabot will use to keep your applications dependencies up-to-date on a weekly basis.
|
|
@@ -1,31 +1,37 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Rolemodel
|
|
4
|
-
class GithubGenerator <
|
|
5
|
-
|
|
6
|
-
#
|
|
7
|
-
|
|
4
|
+
class GithubGenerator < GeneratorBase
|
|
5
|
+
GITHUB_ACTIONS_REPO = 'https://github.com/RoleModel/actions.git'
|
|
6
|
+
# Files which are both used by the gem source and copied to the target app without modification
|
|
7
|
+
# are placed in the `.github` folder at the top level of this repository. This folder is then
|
|
8
|
+
# symlinked to the `templates` folder relative to this generator so they can still be copied over.
|
|
9
|
+
# Any files which are significantly different or not used by the gem source are just in `templates`.
|
|
10
|
+
source_root File.expand_path('templates', __dir__)
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
class_option :playwright, type: :boolean, default: true,
|
|
13
|
+
desc: 'Request Playwright Setup in CI workflow for system tests?'
|
|
14
|
+
|
|
15
|
+
def set_rm_actions_version
|
|
16
|
+
tags = `git ls-remote --tags #{GITHUB_ACTIONS_REPO}` rescue 'refs/tags/v3'
|
|
17
|
+
@rm_actions_version = tags.scan(%r{refs/tags/v(\d+)\s*$}).flatten.max_by(&:to_i)
|
|
11
18
|
end
|
|
12
19
|
|
|
13
|
-
def
|
|
14
|
-
|
|
15
|
-
"* [ ] Run `bin/bump_version` or `bin/bump_version --patch`\n",
|
|
16
|
-
''
|
|
20
|
+
def set_webdriver
|
|
21
|
+
@webdriver = options.playwright? ? 'playwright' : 'selenium'
|
|
17
22
|
end
|
|
18
23
|
|
|
19
|
-
def
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
copy_file 'instructions/ruby.instructions.md', '.github/instructions/ruby.instructions.md'
|
|
24
|
-
copy_file 'instructions/slim.instructions.md', '.github/instructions/slim.instructions.md'
|
|
24
|
+
def install_github_config
|
|
25
|
+
directory 'instructions', '.github/instructions'
|
|
26
|
+
directory 'workflows', '.github/workflows', force: true
|
|
27
|
+
template 'pull_request_template.md', '.github/pull_request_template.md'
|
|
25
28
|
end
|
|
26
29
|
|
|
27
|
-
def
|
|
28
|
-
copy_file '
|
|
30
|
+
def install_dependabot_and_codeowners
|
|
31
|
+
copy_file 'dependabot.yml', '.github/dependabot.yml', force: true
|
|
32
|
+
copy_file 'CODEOWNERS', '.github/CODEOWNERS'
|
|
33
|
+
|
|
34
|
+
say '👉 See CODEOWNERS file for important instructions.', %i[bold red on_blue]
|
|
29
35
|
end
|
|
30
36
|
|
|
31
37
|
def update_database_yml_for_ci
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# This file is used by Dependabot (and more broadly GitHub) to determine who needs to review
|
|
2
|
+
# pull requests which contain changes to specific files. Specifically, the setup below allows
|
|
3
|
+
# for the dependabot PRs to automatically assign (and notify) the Craftsman and Support Dev.
|
|
4
|
+
|
|
5
|
+
# Dependabot / Dependency reviewers:
|
|
6
|
+
# TODO: Update and uncomment the following lines.
|
|
7
|
+
# yarn.lock @craftsman @supportdev
|
|
8
|
+
# Gemfile.lock @craftsman @supportdev
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
registries:
|
|
3
|
+
ruby-github:
|
|
4
|
+
type: rubygems-server
|
|
5
|
+
url: https://rubygems.pkg.github.com/RoleModel
|
|
6
|
+
token: ${{ secrets.ROLEMODEL_PACKAGE_REPO_READ_TOKEN }}
|
|
7
|
+
|
|
8
|
+
updates:
|
|
9
|
+
- package-ecosystem: bundler
|
|
10
|
+
insecure-external-code-execution: allow
|
|
11
|
+
registries:
|
|
12
|
+
- ruby-github
|
|
13
|
+
directory: /
|
|
14
|
+
schedule:
|
|
15
|
+
interval: weekly
|
|
16
|
+
day: monday
|
|
17
|
+
# Ignore specific dependencies or update types which may cause issues. For example:
|
|
18
|
+
# ignore:
|
|
19
|
+
# - dependency-name: 'some-gem'
|
|
20
|
+
# - update-types: ['version-update:semver-major']
|
|
21
|
+
groups:
|
|
22
|
+
production-security:
|
|
23
|
+
dependency-type: production
|
|
24
|
+
applies-to: security-updates
|
|
25
|
+
production-major-updates:
|
|
26
|
+
dependency-type: production
|
|
27
|
+
applies-to: version-updates
|
|
28
|
+
update-types:
|
|
29
|
+
- major
|
|
30
|
+
production-minor-updates:
|
|
31
|
+
dependency-type: production
|
|
32
|
+
applies-to: version-updates
|
|
33
|
+
update-types:
|
|
34
|
+
- minor
|
|
35
|
+
- patch
|
|
36
|
+
development-security:
|
|
37
|
+
dependency-type: development
|
|
38
|
+
applies-to: security-updates
|
|
39
|
+
development-major-updates:
|
|
40
|
+
dependency-type: development
|
|
41
|
+
applies-to: version-updates
|
|
42
|
+
update-types:
|
|
43
|
+
- major
|
|
44
|
+
development-minor-updates:
|
|
45
|
+
dependency-type: development
|
|
46
|
+
applies-to: version-updates
|
|
47
|
+
update-types:
|
|
48
|
+
- minor
|
|
49
|
+
- patch
|
|
50
|
+
- package-ecosystem: npm
|
|
51
|
+
directory: /
|
|
52
|
+
schedule:
|
|
53
|
+
interval: weekly
|
|
54
|
+
day: monday
|
|
55
|
+
# Ignore specific dependencies or update types which may cause issues. For example:
|
|
56
|
+
# ignore:
|
|
57
|
+
# - dependency-name: 'some-package'
|
|
58
|
+
# - update-types: ['version-update:semver-major']
|
|
59
|
+
groups:
|
|
60
|
+
production-security:
|
|
61
|
+
dependency-type: production
|
|
62
|
+
applies-to: security-updates
|
|
63
|
+
production-major-updates:
|
|
64
|
+
dependency-type: production
|
|
65
|
+
applies-to: version-updates
|
|
66
|
+
update-types:
|
|
67
|
+
- major
|
|
68
|
+
production-minor-updates:
|
|
69
|
+
dependency-type: production
|
|
70
|
+
applies-to: version-updates
|
|
71
|
+
update-types:
|
|
72
|
+
- minor
|
|
73
|
+
- patch
|
|
74
|
+
development-security:
|
|
75
|
+
dependency-type: development
|
|
76
|
+
applies-to: security-updates
|
|
77
|
+
development-major-updates:
|
|
78
|
+
dependency-type: development
|
|
79
|
+
applies-to: version-updates
|
|
80
|
+
update-types:
|
|
81
|
+
- major
|
|
82
|
+
development-minor-updates:
|
|
83
|
+
dependency-type: development
|
|
84
|
+
applies-to: version-updates
|
|
85
|
+
update-types:
|
|
86
|
+
- minor
|
|
87
|
+
- patch
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../../../../../.github/instructions
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## Why?
|
|
2
|
+
|
|
3
|
+
Why were the changes needed? What issues were the changes addressing?
|
|
4
|
+
(Note: some changes may seem unrelated to the ticket, this is a great place to explain further.)
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
What changed in this PR?
|
|
9
|
+
|
|
10
|
+
* [ ] Change 1
|
|
11
|
+
|
|
12
|
+
## Pre-merge checklist
|
|
13
|
+
|
|
14
|
+
* [ ] Update relevant READMEs
|
|
15
|
+
|
|
16
|
+
## Screenshots
|
|
17
|
+
|
|
18
|
+
If any UI changes need to be shown off, please add screenshots here.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
concurrency:
|
|
8
|
+
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
|
|
9
|
+
cancel-in-progress: true
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
CI: true
|
|
13
|
+
RAILS_ENV: test
|
|
14
|
+
POSTGRES_USER: postgres
|
|
15
|
+
POSTGRES_PASSWORD: password
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
project-stats:
|
|
19
|
+
name: Project Stats
|
|
20
|
+
runs-on: blacksmith-4vcpu-ubuntu-2404
|
|
21
|
+
timeout-minutes: 3
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v6
|
|
24
|
+
- uses: RoleModel/actions/project-stats@v<%= @rm_actions_version %>
|
|
25
|
+
|
|
26
|
+
compile-assets:
|
|
27
|
+
name: Compile Assets
|
|
28
|
+
runs-on: blacksmith-8vcpu-ubuntu-2404
|
|
29
|
+
timeout-minutes: 5
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v6
|
|
32
|
+
- uses: RoleModel/actions/compile-assets@v<%= @rm_actions_version %>
|
|
33
|
+
id: check-asset-cache
|
|
34
|
+
|
|
35
|
+
non-system-test:
|
|
36
|
+
name: Linting & Ruby Non-System Tests
|
|
37
|
+
runs-on: blacksmith-4vcpu-ubuntu-2404
|
|
38
|
+
timeout-minutes: 5
|
|
39
|
+
services:
|
|
40
|
+
postgres:
|
|
41
|
+
image: postgres:17
|
|
42
|
+
ports: [ "5432:5432" ]
|
|
43
|
+
env:
|
|
44
|
+
POSTGRES_USER: postgres
|
|
45
|
+
POSTGRES_PASSWORD: password
|
|
46
|
+
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@v6
|
|
49
|
+
- uses: ruby/setup-ruby@v1
|
|
50
|
+
with: { bundler-cache: true }
|
|
51
|
+
- run: bin/bundler-audit
|
|
52
|
+
- run: bin/brakeman --quiet --no-pager --exit-on-warn --exit-on-error
|
|
53
|
+
- run: bundle exec rubocop --format github
|
|
54
|
+
- uses: RoleModel/actions/linting-and-non-system-tests@v<%= @rm_actions_version %>
|
|
55
|
+
with:
|
|
56
|
+
needs-compiled-assets: false
|
|
57
|
+
|
|
58
|
+
system-test:
|
|
59
|
+
name: Ruby System Tests
|
|
60
|
+
runs-on: blacksmith-8vcpu-ubuntu-2404
|
|
61
|
+
timeout-minutes: 15
|
|
62
|
+
needs: compile-assets
|
|
63
|
+
services:
|
|
64
|
+
postgres:
|
|
65
|
+
image: postgres:17
|
|
66
|
+
ports: [ "5432:5432" ]
|
|
67
|
+
env:
|
|
68
|
+
POSTGRES_USER: postgres
|
|
69
|
+
POSTGRES_PASSWORD: password
|
|
70
|
+
|
|
71
|
+
steps:
|
|
72
|
+
- uses: actions/checkout@v6
|
|
73
|
+
# Uncomment the following if your app require VIPS for processing ActiveStorage variant images in system tests.
|
|
74
|
+
# - name: Setup vips
|
|
75
|
+
# run: |
|
|
76
|
+
# sudo apt-get update
|
|
77
|
+
# sudo apt-get install -y libvips
|
|
78
|
+
- uses: RoleModel/actions/system-tests@v<%= @rm_actions_version %>
|
|
79
|
+
with:
|
|
80
|
+
web-driver: <%= @webdriver %>
|
|
81
|
+
# failure-screenshot-dir: tmp/screenshots
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# MCP Generator
|
|
2
|
+
|
|
3
|
+
Install boilerplate for your very own MCP server.
|
|
4
|
+
|
|
5
|
+
## What you get
|
|
6
|
+
|
|
7
|
+
### Doorkeeper
|
|
8
|
+
|
|
9
|
+
OAuth 2.1-enabled flow with dynamic application registration.
|
|
10
|
+
|
|
11
|
+
### MCP
|
|
12
|
+
|
|
13
|
+
A basic MCP controller that you can build on to serve tools, resources, and prompts.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rolemodel
|
|
4
|
+
class McpGenerator < GeneratorBase
|
|
5
|
+
source_root File.expand_path('templates', __dir__)
|
|
6
|
+
|
|
7
|
+
def update_inflections
|
|
8
|
+
inflections_path = File.join(destination_root, 'config/initializers/inflections.rb')
|
|
9
|
+
block_start = "\nActiveSupport::Inflector.inflections(:en) do |inflect|\n"
|
|
10
|
+
|
|
11
|
+
return if File.read(inflections_path).include?("inflect.acronym 'MCP'")
|
|
12
|
+
|
|
13
|
+
if File.read(inflections_path).include?(block_start)
|
|
14
|
+
inject_into_file inflections_path, " inflect.acronym 'MCP'\n", after: block_start
|
|
15
|
+
else
|
|
16
|
+
append_to_file inflections_path, <<~RUBY
|
|
17
|
+
|
|
18
|
+
ActiveSupport::Inflector.inflections(:en) do |inflect|
|
|
19
|
+
inflect.acronym 'MCP'
|
|
20
|
+
end
|
|
21
|
+
RUBY
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def install_mcp
|
|
26
|
+
bundle_command 'add mcp'
|
|
27
|
+
template 'app/controllers/mcp_controller.rb'
|
|
28
|
+
copy_file 'spec/requests/mcp_controller_spec.rb'
|
|
29
|
+
|
|
30
|
+
route <<~RUBY
|
|
31
|
+
match '/mcp', to: 'mcp#handle', via: %i[get post delete]
|
|
32
|
+
RUBY
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def add_sample_mcp_resource
|
|
36
|
+
copy_file 'app/mcp/resources/controller.rb'
|
|
37
|
+
copy_file 'spec/mcp/resources/controller_spec.rb'
|
|
38
|
+
|
|
39
|
+
copy_file 'app/mcp/resources/docs/SAMPLE_DOC.md'
|
|
40
|
+
copy_file 'app/mcp/resources/docs_controller.rb'
|
|
41
|
+
copy_file 'spec/mcp/resources/docs_controller_spec.rb'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def add_sample_mcp_prompt
|
|
45
|
+
copy_file 'app/mcp/prompts/sample.rb'
|
|
46
|
+
copy_file 'spec/mcp/prompts/sample_spec.rb'
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def add_sample_mcp_tool
|
|
50
|
+
copy_file 'app/mcp/tools/sample.rb'
|
|
51
|
+
copy_file 'spec/mcp/tools/sample_spec.rb'
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def install_doorkeeper
|
|
55
|
+
bundle_command 'add doorkeeper'
|
|
56
|
+
run_bundle
|
|
57
|
+
generate 'doorkeeper:install'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def configure_doorkeeper
|
|
61
|
+
copy_file 'config/initializers/doorkeeper.rb', force: true
|
|
62
|
+
copy_file 'app/controllers/doorkeeper/base_controller.rb'
|
|
63
|
+
|
|
64
|
+
copy_file 'app/views/layouts/doorkeeper.html.slim'
|
|
65
|
+
template 'app/views/doorkeeper/authorizations/new.html.slim'
|
|
66
|
+
template 'app/views/doorkeeper/authorizations/error.html.slim'
|
|
67
|
+
|
|
68
|
+
copy_file 'app/assets/stylesheets/components/doorkeeper.css'
|
|
69
|
+
|
|
70
|
+
route 'use_doorkeeper'
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def apply_doorkeeper_css
|
|
74
|
+
css_manifest = if File.exist?(File.join(destination_root, 'app/assets/stylesheets/application.scss'))
|
|
75
|
+
'app/assets/stylesheets/application.scss'
|
|
76
|
+
else
|
|
77
|
+
'app/assets/stylesheets/application.css'
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
return if File.read(File.join(destination_root, css_manifest)).include?("@import 'components/doorkeeper.css';")
|
|
81
|
+
|
|
82
|
+
append_to_file css_manifest, <<~CSS
|
|
83
|
+
@import 'components/doorkeeper.css';
|
|
84
|
+
CSS
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def add_oauth_dynamic_registrations
|
|
88
|
+
copy_file 'app/controllers/oauth_registrations_controller.rb'
|
|
89
|
+
copy_file 'spec/requests/oauth_registrations_controller_spec.rb'
|
|
90
|
+
route <<~RUBY
|
|
91
|
+
post '/oauth/register', to: 'oauth_registrations#create'
|
|
92
|
+
RUBY
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def add_well_known_route
|
|
96
|
+
copy_file 'app/controllers/well_known_controller.rb'
|
|
97
|
+
copy_file 'spec/requests/well_known_controller_spec.rb'
|
|
98
|
+
route <<~RUBY
|
|
99
|
+
get '/.well-known/oauth-protected-resource', to: 'well_known#oauth_protected_resource'
|
|
100
|
+
get '/.well-known/oauth-authorization-server', to: 'well_known#oauth_authorization_server'
|
|
101
|
+
RUBY
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
private
|
|
105
|
+
|
|
106
|
+
def application_name
|
|
107
|
+
Rails.application.name
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|