Skip to content

Overhaul CI/CD, specs, and release pipeline#3

Merged
Metalzoid merged 3 commits intomainfrom
feat/ci-cd-overhaul
May 2, 2026
Merged

Overhaul CI/CD, specs, and release pipeline#3
Metalzoid merged 3 commits intomainfrom
feat/ci-cd-overhaul

Conversation

@Metalzoid
Copy link
Copy Markdown
Owner

Summary

Aligns modal_stack's infrastructure with the sibling swal_rails gem so both share the same support matrix and release pipeline.

  • Multi-Rails CI — matrix Ruby 3.2 / 3.3 / 3.4 / 3.5 / 4.0 × Rails 7.2 / 8.0 / 8.1 / 8.1+sprockets via Appraisals (4 generated gemfiles/). Adds dedicated lint job and a ci-success aggregator for branch protection.
  • JS jobs in CIbun test, bun run build:check, and a bundle-freshness check that catches PRs editing JS source without rebuilding the importmap-friendly app/assets/javascripts/modal_stack.js.
  • Automated release on push to main via OIDC trusted publishing (.github/workflows/release.yml). Tag, GitHub Release, and gem push driven by lib/modal_stack/version.rb.
  • Spec infra — fleshed-out dummy Rails app (controllers, views, routes, importmap, sprockets manifest) + Cuprite rails_helper.rb. Full Capybara system suite under spec/system/ covering boot, push, pop (ESC + backdrop), depth-2 stack inertness, modal_replace with history: :push, browser back, all four drawer sides, and the dismissible flag.
  • RuboCop — adopts the swal_rails-style baseline (Metrics tuned for DSL helpers, Naming/PredicatePrefix exempt for the Capybara matchers, ParameterLists ignores keyword args). .rubocop_todo.yml deleted; residual offenses fixed in source (modal_link_to refactored into helpers; HTML fixtures hoisted out of the RSpec.describe block).
  • Bug fix bundledcapybara_spec now uses an around block to restore Capybara.app / current_driver so the unit specs stop polluting global state and breaking system specs that run after them.
  • Misc — Dependabot (bundler + github-actions, weekly), README rewritten with usage / dev / release sections, CHANGELOG reformatted to Keep a Changelog, gemspec exclusions extended (Appraisals, gemfiles/, examples/, CLAUDE.md, bunfig.toml).

Local verification

  • bundle exec rake (rspec + rubocop) green on all 4 appraisals — 105 examples, 0 failures, 38 files / no offenses each.
  • bun test — 61 pass / 0 fail.
  • bun run build:check clean.
  • bin/build && git diff --exit-code app/assets/javascripts/modal_stack.js — no drift.
  • gem build modal_stack.gemspec produces a 0.1.0 gem with only app/, lib/, CHANGELOG.md, CODE_OF_CONDUCT.md, LICENSE.txt, Rakefile, README.md (no bin/, spec/, gemfiles/, Appraisals, examples/, .github/, CLAUDE.md).

Test plan

  • All 19 matrix jobs (5 Ruby × 4 gemfile − Ruby 4.0 × Rails 7.2 exclusion) green.
  • lint, js-test, js-build-check, bundle-freshness, ci-success green.
  • After merge: confirm release.yml tags v0.1.0 (no-op since tag already exists) without errors.

Notes

  • Includes the orphan commit e22f2a7 from PR Force RuboCop to use the repository config in rake tasks #2 (Force RuboCop to use the repository config in rake tasks). The new CI calls bundle exec rubocop --no-server directly, so the rake-level override is no longer needed — this PR restores bare RuboCop::RakeTask.new. Merging this PR also closes out PR Force RuboCop to use the repository config in rake tasks #2.
  • Trusted Publishing for modal_stack is already configured on rubygems.org, per user confirmation. The release workflow will publish on the next push to main after merge if the version bumps.

🤖 Generated with Claude Code

Metalzoid and others added 3 commits May 2, 2026 09:37
This prevents CI runners from inheriting external/home RuboCop configs (like missing rubocop-discourse) and failing unrelated PR checks.

Co-authored-by: Cursor <cursoragent@cursor.com>
Aligns modal_stack's infrastructure with the swal_rails sibling gem so the
two share the same Ruby/Rails support matrix and release workflow.

Highlights:
- Multi-Rails CI: matrix Ruby 3.2-4.0 x Rails 7.2/8.0/8.1/8.1+sprockets
  via Appraisals. Adds dedicated lint job and ci-success aggregator for
  branch protection.
- modal_stack-specific CI jobs: bun test, bun build:check, and a
  bundle-freshness check that catches PRs editing JS source without
  rebuilding the importmap-friendly app/assets/javascripts/modal_stack.js.
- Automated release on push to main via OIDC trusted publishing
  (.github/workflows/release.yml). Tag, GitHub Release, and gem push
  driven by lib/modal_stack/version.rb.
- Dummy Rails app fleshed out with controllers/views/routes so we can
  drive a real Capybara+Cuprite suite. New rails_helper.rb registers the
  Cuprite driver and pulls in the gem's own Capybara matchers.
- Full system spec suite under spec/system/: boot, push, pop (ESC +
  backdrop), stack depth, modal_replace with history :push, browser
  history back, all four drawer sides, dismissible flag.
- RuboCop config replaced with the swal_rails-style baseline (Metrics
  tuned for DSL helpers, Naming/PredicatePrefix exempt for Capybara
  matchers, ParameterLists ignores keyword args). Old .rubocop_todo.yml
  deleted; residual offenses fixed in source (modal_link_to refactored
  into helpers; HTML fixtures hoisted out of the spec describe block).
- capybara_spec around-block restores Capybara.app/current_driver so the
  unit specs no longer pollute global state and break system specs that
  run after them.
- Dependabot enabled for bundler + github-actions (weekly).
- README rewritten with usage, dev, and release instructions.
- CHANGELOG reformatted to Keep a Changelog.
- gemspec exclusions extended (Appraisals, gemfiles/, examples/,
  CLAUDE.md, bunfig.toml) so the published .gem stays minimal.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
within_modal caches a Capybara reference to the layer element, then
morphTopLayer (replaceChildren) mutates the layer's children mid-test.
Cuprite/Ferrum then raises NodeNotFoundError when the cached node is
re-resolved on slow CI runners, even though the layer DIV itself
survives the morph.

Replace the post-click within_modal with a page-level have_css that
scopes via CSS selector. Capybara's matcher retries against fresh DOM
each tick, sidestepping the cached-node race entirely.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@Metalzoid Metalzoid merged commit b381b35 into main May 2, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant