rhales 0.4.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.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.github/renovate.json5 +52 -0
  3. data/.github/workflows/ci.yml +123 -0
  4. data/.github/workflows/claude-code-review.yml +69 -0
  5. data/.github/workflows/claude.yml +49 -0
  6. data/.github/workflows/code-smells.yml +146 -0
  7. data/.github/workflows/ruby-lint.yml +78 -0
  8. data/.github/workflows/yardoc.yml +126 -0
  9. data/.gitignore +55 -0
  10. data/.pr_agent.toml +63 -0
  11. data/.pre-commit-config.yaml +89 -0
  12. data/.prettierignore +8 -0
  13. data/.prettierrc +38 -0
  14. data/.reek.yml +98 -0
  15. data/.rubocop.yml +428 -0
  16. data/.serena/.gitignore +3 -0
  17. data/.yardopts +56 -0
  18. data/CHANGELOG.md +44 -0
  19. data/CLAUDE.md +1 -1
  20. data/Gemfile +29 -0
  21. data/Gemfile.lock +189 -0
  22. data/README.md +686 -868
  23. data/Rakefile +46 -0
  24. data/debug_context.rb +25 -0
  25. data/demo/rhales-roda-demo/.gitignore +7 -0
  26. data/demo/rhales-roda-demo/Gemfile +32 -0
  27. data/demo/rhales-roda-demo/Gemfile.lock +151 -0
  28. data/demo/rhales-roda-demo/MAIL.md +405 -0
  29. data/demo/rhales-roda-demo/README.md +376 -0
  30. data/demo/rhales-roda-demo/RODA-TEMPLATE-ENGINES.md +192 -0
  31. data/demo/rhales-roda-demo/Rakefile +49 -0
  32. data/demo/rhales-roda-demo/app.rb +325 -0
  33. data/demo/rhales-roda-demo/bin/rackup +26 -0
  34. data/demo/rhales-roda-demo/config.ru +13 -0
  35. data/demo/rhales-roda-demo/db/migrate/001_create_rodauth_tables.rb +266 -0
  36. data/demo/rhales-roda-demo/db/migrate/002_create_rodauth_password_tables.rb +79 -0
  37. data/demo/rhales-roda-demo/db/migrate/003_add_admin_account.rb +68 -0
  38. data/demo/rhales-roda-demo/templates/change_login.rue +31 -0
  39. data/demo/rhales-roda-demo/templates/change_password.rue +36 -0
  40. data/demo/rhales-roda-demo/templates/close_account.rue +31 -0
  41. data/demo/rhales-roda-demo/templates/create_account.rue +40 -0
  42. data/demo/rhales-roda-demo/templates/dashboard.rue +150 -0
  43. data/demo/rhales-roda-demo/templates/home.rue +78 -0
  44. data/demo/rhales-roda-demo/templates/layouts/main.rue +168 -0
  45. data/demo/rhales-roda-demo/templates/login.rue +65 -0
  46. data/demo/rhales-roda-demo/templates/logout.rue +25 -0
  47. data/demo/rhales-roda-demo/templates/reset_password.rue +26 -0
  48. data/demo/rhales-roda-demo/templates/verify_account.rue +27 -0
  49. data/demo/rhales-roda-demo/test_full_output.rb +27 -0
  50. data/demo/rhales-roda-demo/test_simple.rb +24 -0
  51. data/docs/.gitignore +9 -0
  52. data/docs/architecture/data-flow.md +499 -0
  53. data/examples/dashboard-with-charts.rue +271 -0
  54. data/examples/form-with-validation.rue +180 -0
  55. data/examples/simple-page.rue +61 -0
  56. data/examples/vue.rue +136 -0
  57. data/generate-json-schemas.ts +158 -0
  58. data/json_schemer_migration_summary.md +172 -0
  59. data/lib/rhales/adapters/base_auth.rb +2 -0
  60. data/lib/rhales/adapters/base_request.rb +2 -0
  61. data/lib/rhales/adapters/base_session.rb +2 -0
  62. data/lib/rhales/adapters.rb +7 -0
  63. data/lib/rhales/configuration.rb +47 -0
  64. data/lib/rhales/core/context.rb +354 -0
  65. data/lib/rhales/{rue_document.rb → core/rue_document.rb} +56 -38
  66. data/lib/rhales/{template_engine.rb → core/template_engine.rb} +66 -59
  67. data/lib/rhales/{view.rb → core/view.rb} +112 -135
  68. data/lib/rhales/{view_composition.rb → core/view_composition.rb} +78 -8
  69. data/lib/rhales/core.rb +9 -0
  70. data/lib/rhales/errors/hydration_collision_error.rb +2 -0
  71. data/lib/rhales/errors.rb +2 -0
  72. data/lib/rhales/{earliest_injection_detector.rb → hydration/earliest_injection_detector.rb} +4 -0
  73. data/lib/rhales/hydration/hydration_data_aggregator.rb +487 -0
  74. data/lib/rhales/{hydration_endpoint.rb → hydration/hydration_endpoint.rb} +16 -12
  75. data/lib/rhales/{hydration_injector.rb → hydration/hydration_injector.rb} +4 -0
  76. data/lib/rhales/{hydration_registry.rb → hydration/hydration_registry.rb} +2 -0
  77. data/lib/rhales/hydration/hydrator.rb +102 -0
  78. data/lib/rhales/{link_based_injection_detector.rb → hydration/link_based_injection_detector.rb} +4 -0
  79. data/lib/rhales/{mount_point_detector.rb → hydration/mount_point_detector.rb} +4 -0
  80. data/lib/rhales/{safe_injection_validator.rb → hydration/safe_injection_validator.rb} +4 -0
  81. data/lib/rhales/hydration.rb +13 -0
  82. data/lib/rhales/{refinements → integrations/refinements}/require_refinements.rb +3 -1
  83. data/lib/rhales/{tilt.rb → integrations/tilt.rb} +22 -15
  84. data/lib/rhales/integrations.rb +6 -0
  85. data/lib/rhales/middleware/json_responder.rb +191 -0
  86. data/lib/rhales/middleware/schema_validator.rb +300 -0
  87. data/lib/rhales/middleware.rb +6 -0
  88. data/lib/rhales/parsers/handlebars_parser.rb +2 -0
  89. data/lib/rhales/parsers/rue_format_parser.rb +9 -7
  90. data/lib/rhales/parsers.rb +9 -0
  91. data/lib/rhales/{csp.rb → security/csp.rb} +27 -3
  92. data/lib/rhales/utils/json_serializer.rb +114 -0
  93. data/lib/rhales/utils/logging_helpers.rb +75 -0
  94. data/lib/rhales/utils/schema_extractor.rb +132 -0
  95. data/lib/rhales/utils/schema_generator.rb +194 -0
  96. data/lib/rhales/utils.rb +40 -0
  97. data/lib/rhales/version.rb +3 -1
  98. data/lib/rhales.rb +41 -24
  99. data/lib/tasks/rhales_schema.rake +197 -0
  100. data/package.json +10 -0
  101. data/pnpm-lock.yaml +345 -0
  102. data/pnpm-workspace.yaml +2 -0
  103. data/proofs/error_handling.rb +79 -0
  104. data/proofs/expanded_object_inheritance.rb +82 -0
  105. data/proofs/partial_context_scoping_fix.rb +168 -0
  106. data/proofs/ui_context_partial_inheritance.rb +236 -0
  107. data/rhales.gemspec +14 -6
  108. data/schema_vs_data_comparison.md +254 -0
  109. data/test_direct_access.rb +36 -0
  110. metadata +141 -23
  111. data/CLAUDE.locale.txt +0 -7
  112. data/lib/rhales/context.rb +0 -239
  113. data/lib/rhales/hydration_data_aggregator.rb +0 -221
  114. data/lib/rhales/hydrator.rb +0 -141
  115. data/lib/rhales/parsers/handlebars-grammar-review.txt +0 -39
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d4de8c7caddc2eb408dbb631654a055785456d23a13f28498d426a5f558464d
4
- data.tar.gz: efe0545542afb04b016be65203ba8aede3e455b6075c6fe6d808764da4de6f93
3
+ metadata.gz: ad690a26efe57e8ff9f10abdcb05423516fbfc26be67ba579d07ea8d9bc2ede7
4
+ data.tar.gz: 7ce9893a2160814d2783bf6ae0a90809a4a240a3d44d69e4dd3b886bd1b89e65
5
5
  SHA512:
6
- metadata.gz: 7d9267703c89eff2da128aaecf692445e1b3533905b3c4218dd9feb5e855ecee037c52684b5d61bbb900a341d53bb14a4612bd27fc03d4f42733fa5c2621384d
7
- data.tar.gz: b239a232e8d146bb3de0691151a152d85dcf42fa3117eb6e0aa4ac37745078eff4887e5ef969ed975e205c92c6b43e9cfa270a1cf981733384235ba70635d858
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 }}"