rhales 0.3.0 → 0.5.3
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/.github/renovate.json5 +52 -0
- data/.github/workflows/ci.yml +123 -0
- data/.github/workflows/claude-code-review.yml +69 -0
- data/.github/workflows/claude.yml +49 -0
- data/.github/workflows/code-smells.yml +146 -0
- data/.github/workflows/ruby-lint.yml +78 -0
- data/.github/workflows/yardoc.yml +126 -0
- data/.gitignore +55 -0
- data/.pr_agent.toml +63 -0
- data/.pre-commit-config.yaml +89 -0
- data/.prettierignore +8 -0
- data/.prettierrc +38 -0
- data/.reek.yml +98 -0
- data/.rubocop.yml +428 -0
- data/.serena/.gitignore +3 -0
- data/.yardopts +56 -0
- data/CHANGELOG.md +44 -0
- data/CLAUDE.md +1 -2
- data/Gemfile +29 -0
- data/Gemfile.lock +189 -0
- data/README.md +706 -589
- data/Rakefile +46 -0
- data/debug_context.rb +25 -0
- data/demo/rhales-roda-demo/.gitignore +7 -0
- data/demo/rhales-roda-demo/Gemfile +32 -0
- data/demo/rhales-roda-demo/Gemfile.lock +151 -0
- data/demo/rhales-roda-demo/MAIL.md +405 -0
- data/demo/rhales-roda-demo/README.md +376 -0
- data/demo/rhales-roda-demo/RODA-TEMPLATE-ENGINES.md +192 -0
- data/demo/rhales-roda-demo/Rakefile +49 -0
- data/demo/rhales-roda-demo/app.rb +325 -0
- data/demo/rhales-roda-demo/bin/rackup +26 -0
- data/demo/rhales-roda-demo/config.ru +13 -0
- data/demo/rhales-roda-demo/db/migrate/001_create_rodauth_tables.rb +266 -0
- data/demo/rhales-roda-demo/db/migrate/002_create_rodauth_password_tables.rb +79 -0
- data/demo/rhales-roda-demo/db/migrate/003_add_admin_account.rb +68 -0
- data/demo/rhales-roda-demo/templates/change_login.rue +31 -0
- data/demo/rhales-roda-demo/templates/change_password.rue +36 -0
- data/demo/rhales-roda-demo/templates/close_account.rue +31 -0
- data/demo/rhales-roda-demo/templates/create_account.rue +40 -0
- data/demo/rhales-roda-demo/templates/dashboard.rue +150 -0
- data/demo/rhales-roda-demo/templates/home.rue +78 -0
- data/demo/rhales-roda-demo/templates/layouts/main.rue +168 -0
- data/demo/rhales-roda-demo/templates/login.rue +65 -0
- data/demo/rhales-roda-demo/templates/logout.rue +25 -0
- data/demo/rhales-roda-demo/templates/reset_password.rue +26 -0
- data/demo/rhales-roda-demo/templates/verify_account.rue +27 -0
- data/demo/rhales-roda-demo/test_full_output.rb +27 -0
- data/demo/rhales-roda-demo/test_simple.rb +24 -0
- data/docs/.gitignore +9 -0
- data/docs/architecture/data-flow.md +499 -0
- data/examples/dashboard-with-charts.rue +271 -0
- data/examples/form-with-validation.rue +180 -0
- data/examples/simple-page.rue +61 -0
- data/examples/vue.rue +136 -0
- data/generate-json-schemas.ts +158 -0
- data/json_schemer_migration_summary.md +172 -0
- data/lib/rhales/adapters/base_auth.rb +2 -0
- data/lib/rhales/adapters/base_request.rb +2 -0
- data/lib/rhales/adapters/base_session.rb +2 -0
- data/lib/rhales/adapters.rb +7 -0
- data/lib/rhales/configuration.rb +161 -1
- data/lib/rhales/core/context.rb +354 -0
- data/lib/rhales/{rue_document.rb → core/rue_document.rb} +59 -43
- data/lib/rhales/{template_engine.rb → core/template_engine.rb} +80 -33
- data/lib/rhales/core/view.rb +529 -0
- data/lib/rhales/{view_composition.rb → core/view_composition.rb} +81 -9
- data/lib/rhales/core.rb +9 -0
- data/lib/rhales/errors/hydration_collision_error.rb +2 -0
- data/lib/rhales/errors.rb +2 -0
- data/lib/rhales/hydration/earliest_injection_detector.rb +153 -0
- data/lib/rhales/hydration/hydration_data_aggregator.rb +487 -0
- data/lib/rhales/hydration/hydration_endpoint.rb +215 -0
- data/lib/rhales/hydration/hydration_injector.rb +175 -0
- data/lib/rhales/{hydration_registry.rb → hydration/hydration_registry.rb} +2 -0
- data/lib/rhales/hydration/hydrator.rb +102 -0
- data/lib/rhales/hydration/link_based_injection_detector.rb +195 -0
- data/lib/rhales/hydration/mount_point_detector.rb +109 -0
- data/lib/rhales/hydration/safe_injection_validator.rb +103 -0
- data/lib/rhales/hydration.rb +13 -0
- data/lib/rhales/{refinements → integrations/refinements}/require_refinements.rb +7 -13
- data/lib/rhales/{tilt.rb → integrations/tilt.rb} +26 -18
- data/lib/rhales/integrations.rb +6 -0
- data/lib/rhales/middleware/json_responder.rb +191 -0
- data/lib/rhales/middleware/schema_validator.rb +300 -0
- data/lib/rhales/middleware.rb +6 -0
- data/lib/rhales/parsers/handlebars_parser.rb +2 -0
- data/lib/rhales/parsers/rue_format_parser.rb +55 -36
- data/lib/rhales/parsers.rb +9 -0
- data/lib/rhales/{csp.rb → security/csp.rb} +27 -3
- data/lib/rhales/utils/json_serializer.rb +114 -0
- data/lib/rhales/utils/logging_helpers.rb +75 -0
- data/lib/rhales/utils/schema_extractor.rb +132 -0
- data/lib/rhales/utils/schema_generator.rb +194 -0
- data/lib/rhales/utils.rb +40 -0
- data/lib/rhales/version.rb +5 -1
- data/lib/rhales.rb +47 -19
- data/lib/tasks/rhales_schema.rake +197 -0
- data/package.json +10 -0
- data/pnpm-lock.yaml +345 -0
- data/pnpm-workspace.yaml +2 -0
- data/proofs/error_handling.rb +79 -0
- data/proofs/expanded_object_inheritance.rb +82 -0
- data/proofs/partial_context_scoping_fix.rb +168 -0
- data/proofs/ui_context_partial_inheritance.rb +236 -0
- data/rhales.gemspec +14 -6
- data/schema_vs_data_comparison.md +254 -0
- data/test_direct_access.rb +36 -0
- metadata +142 -18
- data/CLAUDE.locale.txt +0 -7
- data/lib/rhales/context.rb +0 -240
- data/lib/rhales/hydration_data_aggregator.rb +0 -220
- data/lib/rhales/hydrator.rb +0 -141
- data/lib/rhales/parsers/handlebars-grammar-review.txt +0 -39
- data/lib/rhales/view.rb +0 -412
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ad690a26efe57e8ff9f10abdcb05423516fbfc26be67ba579d07ea8d9bc2ede7
|
|
4
|
+
data.tar.gz: 7ce9893a2160814d2783bf6ae0a90809a4a240a3d44d69e4dd3b886bd1b89e65
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9083d11f2d75d1d301191f29f783488894adb322db93e51071c784f141bcf124b34c9fcc28deb77e8382d159ab82b75cb12f5584523feb8ccb55e883c02ee99d
|
|
7
|
+
data.tar.gz: 57a9d7c3f95b02a960488cf2ade3cf4203e98bf70174d6fcc6c29fd3be6d75447bb5b41869ab1991f33b31202599a0c4635aa514d5aa0b410b24dd4ea26abf11
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
|
3
|
+
|
|
4
|
+
// Core presets
|
|
5
|
+
"extends": [
|
|
6
|
+
"config:recommended",
|
|
7
|
+
"docker:pinDigests",
|
|
8
|
+
"helpers:pinGitHubActionDigests",
|
|
9
|
+
":pinDevDependencies",
|
|
10
|
+
":pinDependencies"
|
|
11
|
+
],
|
|
12
|
+
|
|
13
|
+
// Update control and scheduling
|
|
14
|
+
"timezone": "America/Vancouver",
|
|
15
|
+
"schedule": ["before 5am on Monday"],
|
|
16
|
+
"separateMinorPatch": false,
|
|
17
|
+
"separateMultipleMajor": true,
|
|
18
|
+
"separateMultipleMinor": true,
|
|
19
|
+
"recreateWhen": "auto",
|
|
20
|
+
"rebaseWhen": "auto",
|
|
21
|
+
|
|
22
|
+
// PR management
|
|
23
|
+
"prConcurrentLimit": 15,
|
|
24
|
+
"prHourlyLimit": 10,
|
|
25
|
+
"labels": ["auto-update"],
|
|
26
|
+
"assignees": ["delano"],
|
|
27
|
+
"reviewers": [],
|
|
28
|
+
|
|
29
|
+
// Branch settings
|
|
30
|
+
"branchPrefix": "deps/",
|
|
31
|
+
"branchNameStrict": true,
|
|
32
|
+
|
|
33
|
+
// Automerge settings
|
|
34
|
+
"automerge": true,
|
|
35
|
+
"automergeType": "branch",
|
|
36
|
+
"automergeStrategy": "merge-commit",
|
|
37
|
+
"major": { "automerge": false },
|
|
38
|
+
"minor": { "automerge": false },
|
|
39
|
+
"patch": { "automerge": true },
|
|
40
|
+
"pin": { "automerge": true },
|
|
41
|
+
"lockFileMaintenance": { "automerge": true },
|
|
42
|
+
|
|
43
|
+
// Security settings
|
|
44
|
+
"vulnerabilityAlerts": {
|
|
45
|
+
"labels": ["security"],
|
|
46
|
+
"assignees": ["delano"],
|
|
47
|
+
"schedule": "at any time"
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
// Additional settings
|
|
51
|
+
"forkProcessing": "enabled"
|
|
52
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
pull_request:
|
|
9
|
+
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
inputs:
|
|
12
|
+
debug_enabled:
|
|
13
|
+
type: boolean
|
|
14
|
+
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
|
15
|
+
required: false
|
|
16
|
+
default: false
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
test:
|
|
23
|
+
timeout-minutes: 15
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
name: Tests (Ruby ${{ matrix.ruby }})
|
|
26
|
+
strategy:
|
|
27
|
+
fail-fast: true
|
|
28
|
+
matrix:
|
|
29
|
+
ruby: ['3.4', '3.5']
|
|
30
|
+
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
|
|
34
|
+
- name: Set up Ruby
|
|
35
|
+
uses: ruby/setup-ruby@v1
|
|
36
|
+
with:
|
|
37
|
+
ruby-version: ${{ matrix.ruby }}
|
|
38
|
+
bundler-cache: true
|
|
39
|
+
|
|
40
|
+
- name: Run RSpec tests
|
|
41
|
+
run: bundle exec rspec
|
|
42
|
+
|
|
43
|
+
- name: Run Rhales-specific tests
|
|
44
|
+
run: bundle exec rake rhales:test
|
|
45
|
+
|
|
46
|
+
gem-build:
|
|
47
|
+
timeout-minutes: 10
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
name: Gem Build Test (Ruby ${{ matrix.ruby }})
|
|
50
|
+
strategy:
|
|
51
|
+
fail-fast: true
|
|
52
|
+
matrix:
|
|
53
|
+
ruby: ['3.4', '3.5']
|
|
54
|
+
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/checkout@v4
|
|
57
|
+
|
|
58
|
+
- name: Set up Ruby
|
|
59
|
+
uses: ruby/setup-ruby@v1
|
|
60
|
+
with:
|
|
61
|
+
ruby-version: ${{ matrix.ruby }}
|
|
62
|
+
bundler-cache: true
|
|
63
|
+
|
|
64
|
+
- name: Build gem
|
|
65
|
+
run: gem build rhales.gemspec
|
|
66
|
+
|
|
67
|
+
- name: Install gem locally
|
|
68
|
+
run: gem install rhales-*.gem
|
|
69
|
+
|
|
70
|
+
- name: Test gem installation
|
|
71
|
+
run: ruby -e "require 'rhales'; puts Rhales::VERSION"
|
|
72
|
+
|
|
73
|
+
template-validation:
|
|
74
|
+
timeout-minutes: 10
|
|
75
|
+
runs-on: ubuntu-latest
|
|
76
|
+
name: Template Validation (Ruby ${{ matrix.ruby }})
|
|
77
|
+
strategy:
|
|
78
|
+
fail-fast: false
|
|
79
|
+
matrix:
|
|
80
|
+
ruby: ['3.4', '3.5']
|
|
81
|
+
|
|
82
|
+
steps:
|
|
83
|
+
- uses: actions/checkout@v4
|
|
84
|
+
|
|
85
|
+
- name: Set up Ruby
|
|
86
|
+
uses: ruby/setup-ruby@v1
|
|
87
|
+
with:
|
|
88
|
+
ruby-version: ${{ matrix.ruby }}
|
|
89
|
+
bundler-cache: true
|
|
90
|
+
|
|
91
|
+
- name: Validate example templates
|
|
92
|
+
run: bundle exec rake rhales:validate
|
|
93
|
+
|
|
94
|
+
demo-integration:
|
|
95
|
+
timeout-minutes: 15
|
|
96
|
+
runs-on: ubuntu-latest
|
|
97
|
+
name: Demo Integration (Ruby ${{ matrix.ruby }})
|
|
98
|
+
continue-on-error: true
|
|
99
|
+
strategy:
|
|
100
|
+
fail-fast: false
|
|
101
|
+
matrix:
|
|
102
|
+
ruby: ['3.4', '3.5']
|
|
103
|
+
|
|
104
|
+
steps:
|
|
105
|
+
- uses: actions/checkout@v4
|
|
106
|
+
|
|
107
|
+
- name: Set up Ruby
|
|
108
|
+
uses: ruby/setup-ruby@v1
|
|
109
|
+
with:
|
|
110
|
+
ruby-version: ${{ matrix.ruby }}
|
|
111
|
+
bundler-cache: true
|
|
112
|
+
|
|
113
|
+
- name: Install demo dependencies
|
|
114
|
+
working-directory: demo/rhales-roda-demo
|
|
115
|
+
run: bundle install
|
|
116
|
+
|
|
117
|
+
- name: Test demo app startup
|
|
118
|
+
working-directory: demo/rhales-roda-demo
|
|
119
|
+
run: |
|
|
120
|
+
timeout 30s bundle exec rackup -p 9393 &
|
|
121
|
+
sleep 5
|
|
122
|
+
curl -f http://localhost:9393/ || exit 1
|
|
123
|
+
pkill -f rackup || true
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
name: Claude Code Review
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize, labeled]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
claude-review:
|
|
10
|
+
# Optional: Filter by PR author
|
|
11
|
+
# if: |
|
|
12
|
+
# github.event.pull_request.user.login == 'external-contributor' ||
|
|
13
|
+
# github.event.pull_request.user.login == 'new-developer' ||
|
|
14
|
+
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
|
|
15
|
+
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
if: |
|
|
18
|
+
(github.event.action == 'opened') ||
|
|
19
|
+
(github.event.action == 'labeled' && github.event.label.name == 'claude-review') ||
|
|
20
|
+
(github.event.action == 'synchronize' && contains(github.event.pull_request.labels.*.name, 'claude-review'))
|
|
21
|
+
|
|
22
|
+
permissions:
|
|
23
|
+
contents: read
|
|
24
|
+
pull-requests: read
|
|
25
|
+
issues: read
|
|
26
|
+
id-token: write
|
|
27
|
+
|
|
28
|
+
steps:
|
|
29
|
+
- name: Checkout repository
|
|
30
|
+
uses: actions/checkout@v5
|
|
31
|
+
with:
|
|
32
|
+
fetch-depth: 1
|
|
33
|
+
|
|
34
|
+
- name: Run Claude Code Review
|
|
35
|
+
id: claude-review
|
|
36
|
+
uses: anthropics/claude-code-action@beta
|
|
37
|
+
with:
|
|
38
|
+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
39
|
+
|
|
40
|
+
# Direct prompt for automated review (no @claude mention needed)
|
|
41
|
+
direct_prompt: |
|
|
42
|
+
Please review this pull request and provide feedback on:
|
|
43
|
+
- Code quality and best practices
|
|
44
|
+
- Potential bugs or issues
|
|
45
|
+
- Performance considerations
|
|
46
|
+
- Security concerns
|
|
47
|
+
- Test coverage
|
|
48
|
+
|
|
49
|
+
Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.
|
|
50
|
+
|
|
51
|
+
# Use sticky comments to reuse the same comment on subsequent pushes to the same PR
|
|
52
|
+
use_sticky_comment: true
|
|
53
|
+
|
|
54
|
+
- name: Remove claude-review label
|
|
55
|
+
# Remove label whether success or failure - prevents getting stuck
|
|
56
|
+
if: always() && github.event.action != 'opened'
|
|
57
|
+
uses: actions/github-script@v7
|
|
58
|
+
with:
|
|
59
|
+
script: |
|
|
60
|
+
try {
|
|
61
|
+
await github.rest.issues.removeLabel({
|
|
62
|
+
owner: context.repo.owner,
|
|
63
|
+
repo: context.repo.repo,
|
|
64
|
+
issue_number: context.issue.number,
|
|
65
|
+
name: 'claude-review'
|
|
66
|
+
});
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.log('Label not found or already removed');
|
|
69
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Claude Code
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issue_comment:
|
|
5
|
+
types: [created]
|
|
6
|
+
pull_request_review_comment:
|
|
7
|
+
types: [created]
|
|
8
|
+
issues:
|
|
9
|
+
types: [opened, assigned]
|
|
10
|
+
pull_request_review:
|
|
11
|
+
types: [submitted]
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
claude:
|
|
15
|
+
if: |
|
|
16
|
+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
17
|
+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
18
|
+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
|
19
|
+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
pull-requests: read
|
|
24
|
+
issues: read
|
|
25
|
+
id-token: write
|
|
26
|
+
actions: read # Required for Claude to read CI results on PRs
|
|
27
|
+
steps:
|
|
28
|
+
- name: Checkout repository
|
|
29
|
+
uses: actions/checkout@v5
|
|
30
|
+
with:
|
|
31
|
+
fetch-depth: 1
|
|
32
|
+
|
|
33
|
+
- name: Run Claude Code
|
|
34
|
+
id: claude
|
|
35
|
+
uses: anthropics/claude-code-action@v1
|
|
36
|
+
with:
|
|
37
|
+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
38
|
+
|
|
39
|
+
# This is an optional setting that allows Claude to read CI results on PRs
|
|
40
|
+
additional_permissions: |
|
|
41
|
+
actions: read
|
|
42
|
+
|
|
43
|
+
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
|
|
44
|
+
# prompt: 'Update the pull request description to include a summary of changes.'
|
|
45
|
+
|
|
46
|
+
# Optional: Add claude_args to customize behavior and configuration
|
|
47
|
+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
|
|
48
|
+
# or https://docs.anthropic.com/en/docs/claude-code/sdk#command-line for available options
|
|
49
|
+
# claude_args: '--model claude-opus-4-1-20250805 --allowed-tools Bash(gh pr:*)'
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# .github/workflows/code-quality.yml
|
|
2
|
+
---
|
|
3
|
+
name: Code Smells
|
|
4
|
+
|
|
5
|
+
on:
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
push:
|
|
9
|
+
branches: [main]
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
pull-requests: write # Needed to post comments on PRs
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
reek-analysis:
|
|
18
|
+
name: Reek Code Analysis
|
|
19
|
+
runs-on: ubuntu-24.04
|
|
20
|
+
timeout-minutes: 5
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- name: Checkout code
|
|
24
|
+
uses: actions/checkout@v4
|
|
25
|
+
|
|
26
|
+
- name: Set up Ruby
|
|
27
|
+
uses: ruby/setup-ruby@v1
|
|
28
|
+
with:
|
|
29
|
+
ruby-version: 3.4
|
|
30
|
+
bundler-cache: true
|
|
31
|
+
|
|
32
|
+
- name: Configure Bundler for secure gem installation
|
|
33
|
+
run: |
|
|
34
|
+
bundle config set --local path 'vendor/bundle'
|
|
35
|
+
bundle config set --local deployment 'false'
|
|
36
|
+
|
|
37
|
+
- name: Install dependencies
|
|
38
|
+
run: bundle install --jobs 4 --retry 3
|
|
39
|
+
|
|
40
|
+
- name: Run Reek analysis
|
|
41
|
+
run: |
|
|
42
|
+
echo "=== Running Reek code analysis ==="
|
|
43
|
+
echo "This analysis identifies code smells and potential improvements."
|
|
44
|
+
echo "Results are informational and won't fail the build."
|
|
45
|
+
echo ""
|
|
46
|
+
|
|
47
|
+
# Run reek and capture output (don't fail on warnings)
|
|
48
|
+
# Use success-exit-code to prevent failures from stopping the analysis
|
|
49
|
+
bundle exec reek --format=text --success-exit-code 0 --failure-exit-code 0 || true
|
|
50
|
+
|
|
51
|
+
echo ""
|
|
52
|
+
echo "=== Reek analysis complete ==="
|
|
53
|
+
continue-on-error: true # Don't fail the build on code smells
|
|
54
|
+
|
|
55
|
+
- name: Generate Reek report
|
|
56
|
+
run: |
|
|
57
|
+
echo "=== Generating detailed Reek report ==="
|
|
58
|
+
|
|
59
|
+
# Generate JSON report for potential future processing
|
|
60
|
+
bundle exec reek --format=json --success-exit-code 0 --failure-exit-code 0 > reek-report.json || true
|
|
61
|
+
|
|
62
|
+
# If no JSON was generated, create an empty valid JSON array
|
|
63
|
+
if [ ! -s reek-report.json ]; then
|
|
64
|
+
echo "[]" > reek-report.json
|
|
65
|
+
echo "No code smells detected - created empty report"
|
|
66
|
+
else
|
|
67
|
+
echo "Reek JSON report generated: $(wc -l < reek-report.json) lines"
|
|
68
|
+
echo "Top code smell types found:"
|
|
69
|
+
jq -r '.[].smells[].smell_type' reek-report.json 2>/dev/null | sort | uniq -c | sort -rn | head -10 || echo "Unable to parse JSON report"
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# Also generate a human-readable HTML report for easier viewing
|
|
73
|
+
bundle exec reek --format=html --success-exit-code 0 --failure-exit-code 0 > reek-report.html || echo "<!-- No code smells detected -->" > reek-report.html
|
|
74
|
+
continue-on-error: true
|
|
75
|
+
|
|
76
|
+
- name: Upload Reek report as artifact
|
|
77
|
+
uses: actions/upload-artifact@v4
|
|
78
|
+
if: always()
|
|
79
|
+
with:
|
|
80
|
+
name: reek-report
|
|
81
|
+
path: |
|
|
82
|
+
reek-report.json
|
|
83
|
+
reek-report.html
|
|
84
|
+
if-no-files-found: ignore
|
|
85
|
+
retention-days: 30
|
|
86
|
+
|
|
87
|
+
additional-checks:
|
|
88
|
+
name: Additional Quality Checks
|
|
89
|
+
runs-on: ubuntu-24.04
|
|
90
|
+
timeout-minutes: 5
|
|
91
|
+
|
|
92
|
+
steps:
|
|
93
|
+
- name: Checkout code
|
|
94
|
+
uses: actions/checkout@v4
|
|
95
|
+
|
|
96
|
+
- name: Set up Ruby
|
|
97
|
+
uses: ruby/setup-ruby@v1
|
|
98
|
+
with:
|
|
99
|
+
ruby-version: 3.4
|
|
100
|
+
bundler-cache: true
|
|
101
|
+
|
|
102
|
+
- name: Configure Bundler for secure gem installation
|
|
103
|
+
run: |
|
|
104
|
+
bundle config set --local path 'vendor/bundle'
|
|
105
|
+
bundle config set --local deployment 'false'
|
|
106
|
+
|
|
107
|
+
- name: Install dependencies
|
|
108
|
+
run: bundle install --jobs 4 --retry 3
|
|
109
|
+
|
|
110
|
+
- name: Check for TODO/FIXME comments
|
|
111
|
+
run: |
|
|
112
|
+
echo "=== Scanning for TODO/FIXME comments ==="
|
|
113
|
+
echo "This helps track technical debt and action items."
|
|
114
|
+
echo ""
|
|
115
|
+
|
|
116
|
+
# Find TODO/FIXME comments (excluding vendor and tmp directories)
|
|
117
|
+
find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
|
|
118
|
+
xargs grep -Hn -i -E "(TODO|FIXME|HACK|XXX|NOTE):" 2>/dev/null | \
|
|
119
|
+
head -20 || echo "No TODO/FIXME comments found"
|
|
120
|
+
continue-on-error: true
|
|
121
|
+
|
|
122
|
+
- name: Check Ruby file syntax
|
|
123
|
+
run: |
|
|
124
|
+
echo "=== Checking Ruby syntax ==="
|
|
125
|
+
echo "Validates that all Ruby files have correct syntax."
|
|
126
|
+
echo ""
|
|
127
|
+
|
|
128
|
+
find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
|
|
129
|
+
while read -r file; do
|
|
130
|
+
if ! ruby -c "$file" > /dev/null 2>&1; then
|
|
131
|
+
echo "Syntax error in: $file"
|
|
132
|
+
ruby -c "$file" || true
|
|
133
|
+
fi
|
|
134
|
+
done
|
|
135
|
+
continue-on-error: true
|
|
136
|
+
|
|
137
|
+
- name: Check for long lines
|
|
138
|
+
run: |
|
|
139
|
+
echo "=== Checking for long lines (>120 characters) ==="
|
|
140
|
+
echo "Identifies potentially hard-to-read code lines."
|
|
141
|
+
echo ""
|
|
142
|
+
|
|
143
|
+
find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
|
|
144
|
+
xargs grep -Hn "^.\{121,\}$" | \
|
|
145
|
+
head -10 || echo "No overly long lines found"
|
|
146
|
+
continue-on-error: true
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# .github/workflows/ruby-lint.yml
|
|
2
|
+
|
|
3
|
+
name: Ruby Lint
|
|
4
|
+
|
|
5
|
+
# This GitHub Actions workflow runs Ruby linting using Rubocop.
|
|
6
|
+
#
|
|
7
|
+
# The workflow is triggered by push events on branches starting with "fix/" or
|
|
8
|
+
# "rel/", pull requests on main/develop/feature/* branches, and manual dispatch.
|
|
9
|
+
#
|
|
10
|
+
# The workflow has a single job named "lint" that runs on Ubuntu 24.04
|
|
11
|
+
# with a strategy matrix to test multiple Ruby versions.
|
|
12
|
+
#
|
|
13
|
+
# The steps in the job are:
|
|
14
|
+
# 1. Checkout code using the actions/checkout@v4 action.
|
|
15
|
+
# 2. Set up the specified version of Ruby using the ruby/setup-ruby@v1 action.
|
|
16
|
+
# 3. Install dependencies using Bundler.
|
|
17
|
+
# 4. Run Rubocop linting with JSON output and warning-level failures.
|
|
18
|
+
#
|
|
19
|
+
# This workflow ensures that Ruby code follows style guidelines and best practices.
|
|
20
|
+
|
|
21
|
+
on:
|
|
22
|
+
push:
|
|
23
|
+
branches:
|
|
24
|
+
- fix/*
|
|
25
|
+
- rel/*
|
|
26
|
+
pull_request:
|
|
27
|
+
branches:
|
|
28
|
+
- main
|
|
29
|
+
- develop
|
|
30
|
+
- feature/*
|
|
31
|
+
workflow_dispatch:
|
|
32
|
+
inputs:
|
|
33
|
+
debug_enabled:
|
|
34
|
+
type: boolean
|
|
35
|
+
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
|
36
|
+
required: false
|
|
37
|
+
default: false
|
|
38
|
+
|
|
39
|
+
permissions:
|
|
40
|
+
contents: read
|
|
41
|
+
|
|
42
|
+
jobs:
|
|
43
|
+
lint:
|
|
44
|
+
timeout-minutes: 10 # prevent hung jobs
|
|
45
|
+
|
|
46
|
+
runs-on: ubuntu-24.04
|
|
47
|
+
|
|
48
|
+
strategy:
|
|
49
|
+
fail-fast: true
|
|
50
|
+
matrix:
|
|
51
|
+
ruby: ['3.4', '3.5']
|
|
52
|
+
continue-on-error: [true]
|
|
53
|
+
|
|
54
|
+
steps:
|
|
55
|
+
- name: Checkout code
|
|
56
|
+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
|
57
|
+
|
|
58
|
+
- uses: ruby/setup-ruby@v1
|
|
59
|
+
with:
|
|
60
|
+
ruby-version: ${{ matrix.ruby }}
|
|
61
|
+
bundler-cache: true
|
|
62
|
+
|
|
63
|
+
- name: Setup tmate session
|
|
64
|
+
uses: mxschmitt/action-tmate@7b6a61a73bbb9793cb80ad69b8dd8ac19261834c # v3
|
|
65
|
+
if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
|
|
66
|
+
with:
|
|
67
|
+
detached: true
|
|
68
|
+
|
|
69
|
+
- name: Install dependencies
|
|
70
|
+
continue-on-error: ${{ matrix.continue-on-error }}
|
|
71
|
+
run: |
|
|
72
|
+
bundle config path vendor/bundle
|
|
73
|
+
bundle install --jobs 4 --retry 3
|
|
74
|
+
|
|
75
|
+
- name: Run Rubocop
|
|
76
|
+
continue-on-error: ${{ matrix.continue-on-error }}
|
|
77
|
+
run: |
|
|
78
|
+
bundle exec rubocop --config .rubocop.yml --format json --fail-level warning
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
name: Generate and Deploy YARD Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
paths:
|
|
8
|
+
- 'lib/**/*'
|
|
9
|
+
- 'README.md'
|
|
10
|
+
- 'CHANGELOG.md'
|
|
11
|
+
- '.yardopts'
|
|
12
|
+
- '.github/workflows/yardoc.yml'
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
pages: write
|
|
18
|
+
id-token: write
|
|
19
|
+
|
|
20
|
+
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
|
21
|
+
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
|
22
|
+
concurrency:
|
|
23
|
+
group: "pages"
|
|
24
|
+
cancel-in-progress: false
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
build-docs:
|
|
28
|
+
timeout-minutes: 10
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
name: Generate YARD Documentation
|
|
31
|
+
|
|
32
|
+
steps:
|
|
33
|
+
- name: Checkout repository
|
|
34
|
+
uses: actions/checkout@v4
|
|
35
|
+
with:
|
|
36
|
+
fetch-depth: 0
|
|
37
|
+
|
|
38
|
+
- name: Set up Ruby environment
|
|
39
|
+
uses: ruby/setup-ruby@v1
|
|
40
|
+
with:
|
|
41
|
+
ruby-version: '3.4'
|
|
42
|
+
bundler-cache: true
|
|
43
|
+
|
|
44
|
+
- name: Configure YARD documentation parameters
|
|
45
|
+
run: |
|
|
46
|
+
# Create comprehensive .yardopts configuration
|
|
47
|
+
cat > .yardopts << 'EOF'
|
|
48
|
+
--protected
|
|
49
|
+
--private
|
|
50
|
+
--markup markdown
|
|
51
|
+
--markup-provider kramdown
|
|
52
|
+
--output-dir doc
|
|
53
|
+
--readme README.md
|
|
54
|
+
--files CHANGELOG.md,LICENSE.txt
|
|
55
|
+
--exclude spec/**/*
|
|
56
|
+
--exclude demo/**/*
|
|
57
|
+
--exclude examples/**/*
|
|
58
|
+
--exclude apps/**/*
|
|
59
|
+
lib/**/*.rb
|
|
60
|
+
-
|
|
61
|
+
README.md
|
|
62
|
+
CHANGELOG.md
|
|
63
|
+
EOF
|
|
64
|
+
|
|
65
|
+
- name: Generate comprehensive documentation
|
|
66
|
+
run: |
|
|
67
|
+
echo "::group::YARD Documentation Generation"
|
|
68
|
+
bundle exec yard stats --list-undoc
|
|
69
|
+
bundle exec yard doc
|
|
70
|
+
echo "::endgroup::"
|
|
71
|
+
|
|
72
|
+
- name: Validate documentation completeness
|
|
73
|
+
run: |
|
|
74
|
+
echo "::group::Documentation Validation"
|
|
75
|
+
if [ ! -d "doc" ]; then
|
|
76
|
+
echo "Error: Documentation directory not generated"
|
|
77
|
+
exit 1
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# Check for essential files
|
|
81
|
+
required_files=("index.html" "file.README.html" "file.CHANGELOG.html")
|
|
82
|
+
for file in "${required_files[@]}"; do
|
|
83
|
+
if [ ! -f "doc/$file" ]; then
|
|
84
|
+
echo "Warning: Expected file doc/$file not found"
|
|
85
|
+
fi
|
|
86
|
+
done
|
|
87
|
+
|
|
88
|
+
# Display documentation statistics
|
|
89
|
+
echo "Generated documentation files:"
|
|
90
|
+
find doc -name "*.html" | wc -l
|
|
91
|
+
echo "Total documentation size:"
|
|
92
|
+
du -sh doc/
|
|
93
|
+
echo "::endgroup::"
|
|
94
|
+
|
|
95
|
+
- name: Setup GitHub Pages configuration
|
|
96
|
+
uses: actions/configure-pages@v4
|
|
97
|
+
|
|
98
|
+
- name: Upload documentation artifact
|
|
99
|
+
uses: actions/upload-pages-artifact@v3
|
|
100
|
+
with:
|
|
101
|
+
path: './doc'
|
|
102
|
+
|
|
103
|
+
deploy-pages:
|
|
104
|
+
timeout-minutes: 10
|
|
105
|
+
environment:
|
|
106
|
+
name: github-pages
|
|
107
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
108
|
+
runs-on: ubuntu-latest
|
|
109
|
+
needs: build-docs
|
|
110
|
+
|
|
111
|
+
steps:
|
|
112
|
+
- name: Deploy to GitHub Pages
|
|
113
|
+
id: deployment
|
|
114
|
+
uses: actions/deploy-pages@v4
|
|
115
|
+
|
|
116
|
+
notify-completion:
|
|
117
|
+
timeout-minutes: 5
|
|
118
|
+
runs-on: ubuntu-latest
|
|
119
|
+
needs: [build-docs, deploy-pages]
|
|
120
|
+
if: success()
|
|
121
|
+
|
|
122
|
+
steps:
|
|
123
|
+
- name: Documentation deployment summary
|
|
124
|
+
run: |
|
|
125
|
+
echo "::notice title=Documentation Deployed::YARD documentation successfully deployed to GitHub Pages"
|
|
126
|
+
echo "::notice title=Access URL::Documentation available at: ${{ needs.deploy-pages.outputs.page_url }}"
|