diff --git a/.github/workflows/ancient.yml b/.github/workflows/ancient.yml index 02e6d71..45a8bdd 100644 --- a/.github/workflows/ancient.yml +++ b/.github/workflows/ancient.yml @@ -1,4 +1,4 @@ -name: Ancient (EOL) Rubies +name: Ancient (EOL, Ruby 2.4, 2.5) Matrix on: push: @@ -20,29 +20,107 @@ concurrency: jobs: test: - name: Specs - Ruby ${{ matrix.ruby }}${{ matrix.name_extra || '' }} + name: Specs - Ruby ${{ matrix.ruby }} ${{ matrix.appraisal }}${{ matrix.name_extra || '' }} if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps - BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile + BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile + continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: gemfile: - - ancient - ruby: - - "2.4" - - "2.5" - - "2.6" - - "2.7" - runs-on: ubuntu-22.04 - continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} + - "Appraisal.root" + rubygems: + - '3.3.27' + bundler: + - '2.3.27' + include: + # Ruby 2.4 + - ruby: "2.4" + appraisal: "ar-4-2" + taskname: "spec:orm:active_record" + - ruby: "2.4" + appraisal: "ar-5-0" + taskname: "spec:orm:active_record" + - ruby: "2.4" + appraisal: "ar-5-1" + taskname: "spec:orm:active_record" + - ruby: "2.4" + appraisal: "ar-5-2" + taskname: "spec:orm:active_record" + - ruby: "2.4" + appraisal: "couch-1.17" + taskname: "spec:orm:couch_potato" + - ruby: "2.4" + appraisal: "mongoid-7.3" + taskname: "spec:orm:mongoid" + - ruby: "2.4" + appraisal: "sequel-5.86" + taskname: "spec:orm:sequel" + + # Ruby 2.5 + - ruby: "2.5" + appraisal: "ar-5-1" + taskname: "spec:orm:active_record" + - ruby: "2.5" + appraisal: "ar-5-2" + taskname: "spec:orm:active_record" + - ruby: "2.5" + appraisal: "ar-6-0" + taskname: "spec:orm:active_record" + - ruby: "2.5" + appraisal: "ar-6-1" + taskname: "spec:orm:active_record" + - ruby: "2.5" + appraisal: "couch-1.17" + taskname: "spec:orm:couch_potato" + - ruby: "2.5" + appraisal: "mongoid-7.3" + taskname: "spec:orm:mongoid" + - ruby: "2.5" + appraisal: "mongoid-7.4" + taskname: "spec:orm:mongoid" + - ruby: "2.5" + appraisal: "sequel-5.86" + taskname: "spec:orm:sequel" + steps: + ### COUCHDB + - name: Start CouchDB + uses: iamssen/couchdb-github-action@master + if: "endsWith(matrix.taskname, 'couch_potato')" + with: + couchdb-version: "3.4.1" + - name: Smoke CouchDB + if: "endsWith(matrix.taskname, 'couch_potato')" + run: | + curl -f http://127.0.0.1:5984/ + curl -X POST -H "Content-Type: application/json; charset=utf-8" -d '{"name": "admin", "password": "password"}' http://127.0.0.1:5984/_session + + ### MONGODB + - name: Start MongoDB + uses: supercharge/mongodb-github-action@1.11.0 + if: "endsWith(matrix.taskname, 'mongoid')" + with: + mongodb-version: "8.0" + - name: Checkout uses: actions/checkout@v4 + - name: Setup Ruby & RubyGems uses: ruby/setup-ruby@v1 with: - ruby-version: "${{ matrix.ruby }}" - bundler-cache: true # runs 'bundle install' and caches installed gems automatically - - name: Run tests - run: bundle exec rake test + ruby-version: ${{ matrix.ruby }} + rubygems: ${{ matrix.rubygems }} + bundler: ${{ matrix.bundler }} + bundler-cache: false + # This will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) + # We need to do this first to get appraisal installed. + # NOTE: This does not use the root Gemfile at all. + - name: Bundle for Appraisal ${{ matrix.appraisal }} (Rails v${{ matrix.rails}}) + run: bundle + - name: Install Appraisal ${{ matrix.appraisal }} (Rails v${{ matrix.rails}}) dependencies + run: bundle exec appraisal ${{ matrix.appraisal }} bundle + - name: Run ${{ matrix.appraisal }} tests via ${{ matrix.taskname }} (Rails v${{ matrix.rails}}) + run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec rake ${{ matrix.taskname }} diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 6deca4e..9ff76be 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -49,6 +49,25 @@ jobs: - '3.1' steps: + ### COUCHDB + - name: Start CouchDB + uses: iamssen/couchdb-github-action@master + if: "endsWith(matrix.taskname, 'couch_potato')" + with: + couchdb-version: "3.4.1" + - name: Smoke CouchDB + if: "endsWith(matrix.taskname, 'couch_potato')" + run: | + curl -f http://127.0.0.1:5984/ + curl -X POST -H "Content-Type: application/json; charset=utf-8" -d '{"name": "admin", "password": "password"}' http://127.0.0.1:5984/_session + + ### MONGODB + - name: Start MongoDB + uses: supercharge/mongodb-github-action@1.11.0 + if: "endsWith(matrix.taskname, 'mongoid')" + with: + mongodb-version: "8.0" + - uses: amancevice/setup-code-climate@v2 name: CodeClimate Install if: ${{ github.event_name != 'pull_request' }} @@ -72,7 +91,7 @@ jobs: continue-on-error: ${{ matrix.experimental != 'false' }} - name: Run RSpec tests - run: bundle exec rake test + run: bundle exec rake spec:orm:all - name: CodeClimate Post-build Notification run: cc-test-reporter after-build diff --git a/.github/workflows/heads.yml b/.github/workflows/heads.yml index 3f8f9c2..8e5d564 100644 --- a/.github/workflows/heads.yml +++ b/.github/workflows/heads.yml @@ -26,37 +26,100 @@ concurrency: jobs: test: - name: Specs - Ruby ${{ matrix.ruby }} ${{ matrix.name_extra || '' }} + name: Specs - Ruby ${{ matrix.ruby }} ${{ matrix.appraisal }}${{ matrix.name_extra || '' }} if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps - BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile + BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile runs-on: ubuntu-latest continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} strategy: fail-fast: true matrix: + gemfile: + - "Appraisal.root" rubygems: - latest bundler: - latest - gemfile: - - vanilla - ruby: - - head - - truffleruby-head - - jruby-head + include: + # ruby-head + - ruby: "head" + appraisal: "ar-8-0" + taskname: "spec:orm:active_record" + - ruby: "head" + appraisal: "couch-1.17" + taskname: "spec:orm:couch_potato" + - ruby: "head" + appraisal: "mongoid-9.0" + taskname: "spec:orm:mongoid" + - ruby: "head" + appraisal: "sequel-5.86" + taskname: "spec:orm:sequel" + + # truffleruby-head + - ruby: "truffleruby-head" + appraisal: "ar-8-0" + taskname: "spec:orm:active_record" + - ruby: "truffleruby-head" + appraisal: "couch-1.17" + taskname: "spec:orm:couch_potato" + - ruby: "truffleruby-head" + appraisal: "mongoid-9.0" + taskname: "spec:orm:mongoid" + - ruby: "truffleruby-head" + appraisal: "sequel-5.86" + taskname: "spec:orm:sequel" + + # jruby-head + - ruby: "jruby-head" + appraisal: "ar-8-0" + taskname: "spec:orm:active_record" + - ruby: "jruby-head" + appraisal: "couch-1.17" + taskname: "spec:orm:couch_potato" + - ruby: "jruby-head" + appraisal: "mongoid-9.0" + taskname: "spec:orm:mongoid" + - ruby: "jruby-head" + appraisal: "sequel-5.86" + taskname: "spec:orm:sequel" steps: + ### COUCHDB + - name: Start CouchDB + uses: iamssen/couchdb-github-action@master + if: "endsWith(matrix.taskname, 'couch_potato')" + with: + couchdb-version: "3.4.1" + - name: Smoke CouchDB + if: "endsWith(matrix.taskname, 'couch_potato')" + run: | + curl -f http://127.0.0.1:5984/ + curl -X POST -H "Content-Type: application/json; charset=utf-8" -d '{"name": "admin", "password": "password"}' http://127.0.0.1:5984/_session + + ### MONGODB + - name: Start MongoDB + uses: supercharge/mongodb-github-action@1.11.0 + if: "endsWith(matrix.taskname, 'mongoid')" + with: + mongodb-version: "8.0" + - name: Checkout uses: actions/checkout@v4 - name: Setup Ruby & RubyGems uses: ruby/setup-ruby@v1 with: - ruby-version: "${{ matrix.ruby }}" - rubygems: "${{ matrix.rubygems }}" - bundler: "${{ matrix.bundler }}" - bundler-cache: true # runs 'bundle install' and caches installed gems automatically - - - name: Run tests - run: bundle exec rake test + ruby-version: ${{ matrix.ruby }} + rubygems: ${{ matrix.rubygems }} + bundler: ${{ matrix.bundler }} + bundler-cache: false + # This will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) + # We need to do this first to get appraisal installed. + # NOTE: This does not use the root Gemfile at all. + - name: Bundle for Appraisal ${{ matrix.appraisal }} (Rails v${{ matrix.rails}}) + run: bundle + - name: Install Appraisal ${{ matrix.appraisal }} (Rails v${{ matrix.rails}}) dependencies + run: bundle exec appraisal ${{ matrix.appraisal }} bundle + - name: Run ${{ matrix.appraisal }} tests via ${{ matrix.taskname }} (Rails v${{ matrix.rails}}) + run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec rake ${{ matrix.taskname }} diff --git a/.github/workflows/legacy.yml b/.github/workflows/legacy.yml new file mode 100644 index 0000000..589d276 --- /dev/null +++ b/.github/workflows/legacy.yml @@ -0,0 +1,104 @@ +name: Legacy Support (EOL, Ruby 3.0) Matrix + +env: + K_SOUP_COV_DO: false + +on: + push: + branches: + - 'main' + tags: + - '!*' # Do not execute on tags + pull_request: + branches: + - '*' + # Allow manually triggering the workflow. + workflow_dispatch: + +permissions: + contents: read + +# Cancels all previous workflow runs for the same branch that have not yet completed. +concurrency: + # The concurrency group contains the workflow name and the branch name. + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + +jobs: + test: + name: Specs - Ruby ${{ matrix.ruby }} ${{ matrix.appraisal }}${{ matrix.name_extra || '' }} + if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" + env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps + BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile + continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + gemfile: + - "Appraisal.root" + rubygems: + - '3.5.23' + bundler: + - '2.5.23' + include: + - ruby: "3.0" + appraisal: "ar-6-1" + taskname: "spec:orm:active_record" + - ruby: "3.0" + appraisal: "ar-7-0" + taskname: "spec:orm:active_record" + - ruby: "3.0" + appraisal: "ar-7-1" + taskname: "spec:orm:active_record" + - ruby: "3.0" + appraisal: "couch-1.17" + taskname: "spec:orm:couch_potato" + - ruby: "3.0" + appraisal: "mongoid-8.1" + taskname: "spec:orm:mongoid" + - ruby: "3.0" + appraisal: "mongoid-9.0" + taskname: "spec:orm:mongoid" + - ruby: "3.0" + appraisal: "sequel-5.86" + taskname: "spec:orm:sequel" + steps: + ### COUCHDB + - name: Start CouchDB + uses: iamssen/couchdb-github-action@master + if: "endsWith(matrix.taskname, 'couch_potato')" + with: + couchdb-version: "3.4.1" + - name: Smoke CouchDB + if: "endsWith(matrix.taskname, 'couch_potato')" + run: | + curl -f http://127.0.0.1:5984/ + curl -X POST -H "Content-Type: application/json; charset=utf-8" -d '{"name": "admin", "password": "password"}' http://127.0.0.1:5984/_session + + ### MONGODB + - name: Start MongoDB + uses: supercharge/mongodb-github-action@1.11.0 + if: "endsWith(matrix.taskname, 'mongoid')" + with: + mongodb-version: "8.0" + + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Ruby & RubyGems + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + rubygems: ${{ matrix.rubygems }} + bundler: ${{ matrix.bundler }} + bundler-cache: false + # This will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) + # We need to do this first to get appraisal installed. + # NOTE: This does not use the root Gemfile at all. + - name: Bundle for Appraisal ${{ matrix.appraisal }} (Rails v${{ matrix.rails}}) + run: bundle + - name: Install Appraisal ${{ matrix.appraisal }} (Rails v${{ matrix.rails}}) dependencies + run: bundle exec appraisal ${{ matrix.appraisal }} bundle + - name: Run ${{ matrix.appraisal }} tests via ${{ matrix.taskname }} (Rails v${{ matrix.rails}}) + run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec rake ${{ matrix.taskname }} diff --git a/.github/workflows/supported.yml b/.github/workflows/supported.yml index aadd9af..7fcc5ae 100644 --- a/.github/workflows/supported.yml +++ b/.github/workflows/supported.yml @@ -26,32 +26,123 @@ concurrency: jobs: test: - name: Specs - Ruby ${{ matrix.ruby }}${{ matrix.name_extra || '' }} + name: Specs - Ruby ${{ matrix.ruby }} ${{ matrix.appraisal }}${{ matrix.name_extra || '' }} if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps - BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile + BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile runs-on: ubuntu-latest + continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} strategy: matrix: + gemfile: + - "Appraisal.root" + rubygems: + - latest + bundler: + - latest include: - - ruby: "3.3" - rubygems: latest - bundler: latest - gemfile: vanilla + # Ruby 3.1 + - ruby: "3.1" + appraisal: "ar-7-0" + taskname: "spec:orm:active_record" + - ruby: "3.1" + appraisal: "ar-7-1" + taskname: "spec:orm:active_record" + - ruby: "3.1" + appraisal: "ar-7-2" + taskname: "spec:orm:active_record" + - ruby: "3.1" + appraisal: "couch-1.17" + taskname: "spec:orm:couch_potato" + - ruby: "3.1" + appraisal: "mongoid-8.1" + taskname: "spec:orm:mongoid" + - ruby: "3.1" + appraisal: "mongoid-9.0" + taskname: "spec:orm:mongoid" + - ruby: "3.1" + appraisal: "sequel-5.86" + taskname: "spec:orm:sequel" + + # Ruby 3.2 + - ruby: "3.2" + appraisal: "ar-7-1" + taskname: "spec:orm:active_record" + - ruby: "3.2" + appraisal: "ar-7-2" + taskname: "spec:orm:active_record" + - ruby: "3.2" + appraisal: "ar-8-0" + taskname: "spec:orm:active_record" + - ruby: "3.2" + appraisal: "couch-1.17" + taskname: "spec:orm:couch_potato" - ruby: "3.2" - rubygems: latest - bundler: latest - gemfile: vanilla - #- Ruby 3.1 tests are run by coverage.yml + appraisal: "mongoid-8.1" + taskname: "spec:orm:mongoid" + - ruby: "3.2" + appraisal: "mongoid-9.0" + taskname: "spec:orm:mongoid" + - ruby: "3.2" + appraisal: "sequel-5.86" + taskname: "spec:orm:sequel" + + # Ruby 3.3 + - ruby: "3.3" + appraisal: "ar-7-2" + taskname: "spec:orm:active_record" + - ruby: "3.3" + appraisal: "ar-8-0" + taskname: "spec:orm:active_record" + - ruby: "3.3" + appraisal: "couch-1.17" + taskname: "spec:orm:couch_potato" + - ruby: "3.3" + appraisal: "mongoid-8.1" + taskname: "spec:orm:mongoid" + - ruby: "3.3" + appraisal: "mongoid-9.0" + taskname: "spec:orm:mongoid" + - ruby: "3.3" + appraisal: "sequel-5.86" + taskname: "spec:orm:sequel" + steps: + ### COUCHDB + - name: Start CouchDB + uses: iamssen/couchdb-github-action@master + if: "endsWith(matrix.taskname, 'couch_potato')" + with: + couchdb-version: "3.4.1" + - name: Smoke CouchDB + if: "endsWith(matrix.taskname, 'couch_potato')" + run: | + curl -f http://127.0.0.1:5984/ + curl -X POST -H "Content-Type: application/json; charset=utf-8" -d '{"name": "admin", "password": "password"}' http://127.0.0.1:5984/_session + + ### MONGODB + - name: Start MongoDB + uses: supercharge/mongodb-github-action@1.11.0 + if: "endsWith(matrix.taskname, 'mongoid')" + with: + mongodb-version: "8.0" + - name: Checkout uses: actions/checkout@v4 + - name: Setup Ruby & RubyGems uses: ruby/setup-ruby@v1 with: - ruby-version: "${{ matrix.ruby }}" - rubygems: "${{ matrix.rubygems }}" - bundler: "${{ matrix.bundler }}" - bundler-cache: true # runs 'bundle install' and caches installed gems automatically - - name: Run tests - run: bundle exec rake test + ruby-version: ${{ matrix.ruby }} + rubygems: ${{ matrix.rubygems }} + bundler: ${{ matrix.bundler }} + bundler-cache: false + # This will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) + # We need to do this first to get appraisal installed. + # NOTE: This does not use the root Gemfile at all. + - name: Bundle for Appraisal ${{ matrix.appraisal }} (Rails v${{ matrix.rails}}) + run: bundle + - name: Install Appraisal ${{ matrix.appraisal }} (Rails v${{ matrix.rails}}) dependencies + run: bundle exec appraisal ${{ matrix.appraisal }} bundle + - name: Run ${{ matrix.appraisal }} tests via ${{ matrix.taskname }} (Rails v${{ matrix.rails}}) + run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec rake ${{ matrix.taskname }} diff --git a/.github/workflows/unsupported.yml b/.github/workflows/unsupported.yml index 92e3990..8d0a6fa 100644 --- a/.github/workflows/unsupported.yml +++ b/.github/workflows/unsupported.yml @@ -1,4 +1,4 @@ -name: Unsupported (EOL) Ruby Matrix +name: Unsupported (EOL, Ruby 2.6, 2.7) Matrix env: K_SOUP_COV_DO: false @@ -15,6 +15,9 @@ on: # Allow manually triggering the workflow. workflow_dispatch: +permissions: + contents: read + # Cancels all previous workflow runs for the same branch that have not yet completed. concurrency: # The concurrency group contains the workflow name and the branch name. @@ -23,29 +26,112 @@ concurrency: jobs: test: - name: Specs - Ruby ${{ matrix.ruby }}${{ matrix.name_extra || '' }} + name: Specs - Ruby ${{ matrix.ruby }} ${{ matrix.appraisal }}${{ matrix.name_extra || '' }} if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')" env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps - BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile + BUNDLE_GEMFILE: ${{ github.workspace }}/${{ matrix.gemfile }}.gemfile + continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: + gemfile: + - "Appraisal.root" + rubygems: + - '3.4.22' + bundler: + - '2.4.22' include: - - ruby: "3.0" - rubygems: latest - bundler: latest - gemfile: vanilla - runs-on: ubuntu-22.04 - continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }} + # Ruby 2.6 + - ruby: "2.6" + appraisal: "ar-5-2" + taskname: "spec:orm:active_record" + - ruby: "2.6" + appraisal: "ar-6-0" + taskname: "spec:orm:active_record" + - ruby: "2.6" + appraisal: "ar-6-1" + taskname: "spec:orm:active_record" + - ruby: "2.6" + appraisal: "couch-1.17" + taskname: "spec:orm:couch_potato" + - ruby: "2.6" + appraisal: "mongoid-7.4" + taskname: "spec:orm:mongoid" + - ruby: "2.6" + appraisal: "mongoid-8.1" + taskname: "spec:orm:mongoid" + - ruby: "2.6" + appraisal: "sequel-5.86" + taskname: "spec:orm:sequel" + + # Ruby 2.7 + - ruby: "2.7" + appraisal: "ar-5-2" + taskname: "spec:orm:active_record" + - ruby: "2.7" + appraisal: "ar-6-0" + taskname: "spec:orm:active_record" + - ruby: "2.7" + appraisal: "ar-6-1" + taskname: "spec:orm:active_record" + - ruby: "2.7" + appraisal: "ar-7-0" + taskname: "spec:orm:active_record" + - ruby: "2.7" + appraisal: "ar-7-1" + taskname: "spec:orm:active_record" + - ruby: "2.7" + appraisal: "couch-1.17" + taskname: "spec:orm:couch_potato" + - ruby: "2.7" + appraisal: "mongoid-7.4" + taskname: "spec:orm:mongoid" + - ruby: "2.7" + appraisal: "mongoid-8.1" + taskname: "spec:orm:mongoid" + - ruby: "2.7" + appraisal: "mongoid-9.0" + taskname: "spec:orm:mongoid" + - ruby: "2.7" + appraisal: "sequel-5.86" + taskname: "spec:orm:sequel" steps: + ### COUCHDB + - name: Start CouchDB + uses: iamssen/couchdb-github-action@master + if: "endsWith(matrix.taskname, 'couch_potato')" + with: + couchdb-version: "3.4.1" + - name: Smoke CouchDB + if: "endsWith(matrix.taskname, 'couch_potato')" + run: | + curl -f http://127.0.0.1:5984/ + curl -X POST -H "Content-Type: application/json; charset=utf-8" -d '{"name": "admin", "password": "password"}' http://127.0.0.1:5984/_session + + ### MONGODB + - name: Start MongoDB + uses: supercharge/mongodb-github-action@1.11.0 + if: "endsWith(matrix.taskname, 'mongoid')" + with: + mongodb-version: "8.0" + - name: Checkout uses: actions/checkout@v4 + - name: Setup Ruby & RubyGems uses: ruby/setup-ruby@v1 with: - ruby-version: "${{ matrix.ruby }}" - rubygems: "${{ matrix.rubygems }}" - bundler: "${{ matrix.bundler }}" - bundler-cache: true # runs 'bundle install' and caches installed gems automatically - - name: Run tests - run: bundle exec rake test + ruby-version: ${{ matrix.ruby }} + rubygems: ${{ matrix.rubygems }} + bundler: ${{ matrix.bundler }} + bundler-cache: false + # This will use the BUNDLE_GEMFILE set to matrix.gemfile (i.e. Appraisal.root) + # We need to do this first to get appraisal installed. + # NOTE: This does not use the root Gemfile at all. + - name: Bundle for Appraisal ${{ matrix.appraisal }} (Rails v${{ matrix.rails}}) + run: bundle + - name: Install Appraisal ${{ matrix.appraisal }} (Rails v${{ matrix.rails}}) dependencies + run: bundle exec appraisal ${{ matrix.appraisal }} bundle + - name: Run ${{ matrix.appraisal }} tests via ${{ matrix.taskname }} (Rails v${{ matrix.rails}}) + run: bundle exec appraisal ${{ matrix.appraisal }} bundle exec rake ${{ matrix.taskname }} diff --git a/.rubocop_gradual.lock b/.rubocop_gradual.lock index fd2fbe4..b78ea9f 100644 --- a/.rubocop_gradual.lock +++ b/.rubocop_gradual.lock @@ -1,5 +1,5 @@ { - "README.md:2325237811": [ + "README.md:3252916395": [ [143, 3, 100, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 3592044714] ], "lib/omniauth/identity/model.rb:3893215304": [ @@ -29,27 +29,18 @@ [20, 13, 125, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 3604044426], [25, 13, 83, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 902334745] ], - "lib/omniauth/identity/models/sequel.rb:840895507": [ - [15, 9, 1395, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 4006650972], - [28, 13, 126, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 2564660912], - [38, 13, 79, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 851742457] + "lib/omniauth/identity/models/sequel.rb:2998546304": [ + [15, 9, 1815, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 496918361], + [32, 13, 126, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 2564660912], + [42, 13, 79, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 851742457] ], - "lib/omniauth/identity/secure_password.rb:372076116": [ + "lib/omniauth/identity/secure_password.rb:2767570368": [ [13, 7, 113, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 353293128], [23, 9, 23, "ThreadSafety/ClassAndModuleAttributes: Avoid mutating class and module attributes.", 1578198260] ], "spec/omniauth/identity/model_spec.rb:3920022856": [ [3, 1, 40, "RSpec/SpecFilePathFormat: Spec path should end with `omni_auth/identity/model*_spec.rb`.", 1316823397] ], - "spec/omniauth/identity/models/active_record_spec.rb:1806207275": [ - [9, 1, 66, "RSpec/SpecFilePathFormat: Spec path should end with `omni_auth/identity/models/active_record*_spec.rb`.", 3716735269], - [33, 7, 319, "RSpec/ExampleLength: Example has too many lines. [7/5]", 3315623106], - [39, 9, 70, "RSpec/SubjectStub: Do not stub methods of the object under test.", 2532937321] - ], - "spec/omniauth/identity/models/sequel_spec.rb:2663789046": [ - [8, 1, 60, "RSpec/SpecFilePathFormat: Spec path should end with `omni_auth/identity/models/sequel*_spec.rb`.", 36626431], - [34, 9, 70, "RSpec/SubjectStub: Do not stub methods of the object under test.", 2532937321] - ], "spec/omniauth/identity/secure_password_spec.rb:2012576649": [ [4, 3, 34, "Style/ClassMethodsDefinitions: Use `class << self` to define a class method.", 2989290855], [11, 1, 49, "RSpec/SpecFilePathFormat: Spec path should end with `omni_auth/identity/secure_password*_spec.rb`.", 2365105762], @@ -157,7 +148,16 @@ [3, 22, 19, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 3037799226], [19, 7, 54, "RSpec/NoExpectationExample: No expectation found in this example.", 3311828801] ], - "spec_orms/couch_potato_spec.rb:1682970380": [ + "spec_ignored/nobrainer_spec.rb:1725804559": [ + [19, 1, 65, "RSpec/SpecFilePathFormat: Spec path should end with `omni_auth/identity/models/no_brainer*_spec.rb`.", 1527957824], + [51, 9, 149, "RSpec/SubjectStub: Do not stub methods of the object under test.", 3043135007] + ], + "spec_orms/active_record_spec.rb:1988670090": [ + [9, 1, 66, "RSpec/SpecFilePathFormat: Spec path should end with `omni_auth/identity/models/active_record*_spec.rb`.", 3716735269], + [33, 7, 321, "RSpec/ExampleLength: Example has too many lines. [7/5]", 3315623106], + [39, 9, 71, "RSpec/SubjectStub: Do not stub methods of the object under test.", 399334056] + ], + "spec_orms/couch_potato_spec.rb:2493573521": [ [5, 1, 71, "RSpec/SpecFilePathFormat: Spec path should end with `omni_auth/identity/models/couch_potato_module*_spec.rb`.", 3681175308], [28, 9, 149, "RSpec/SubjectStub: Do not stub methods of the object under test.", 3043135007] ], @@ -166,8 +166,8 @@ [14, 14, 7, "RSpec/NamedSubject: Name your test subject if you need to reference it explicitly.", 1892732441], [21, 9, 149, "RSpec/SubjectStub: Do not stub methods of the object under test.", 3043135007] ], - "spec_orms/nobrainer_spec.rb:879699322": [ - [7, 1, 65, "RSpec/SpecFilePathFormat: Spec path should end with `omni_auth/identity/models/no_brainer*_spec.rb`.", 1527957824], - [39, 9, 149, "RSpec/SubjectStub: Do not stub methods of the object under test.", 3043135007] + "spec_orms/sequel_spec.rb:3336240631": [ + [8, 1, 60, "RSpec/SpecFilePathFormat: Spec path should end with `omni_auth/identity/models/sequel*_spec.rb`.", 36626431], + [34, 9, 71, "RSpec/SubjectStub: Do not stub methods of the object under test.", 399334056] ] } diff --git a/Appraisal.root.gemfile b/Appraisal.root.gemfile new file mode 100644 index 0000000..0fba9a0 --- /dev/null +++ b/Appraisal.root.gemfile @@ -0,0 +1,10 @@ +git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } + +source "https://rubygems.org" + +# Appraisal Root Gemfile is for running appraisal to generate the Appraisal Gemfiles +# in gemfiles/*gemfile. It is not loaded on CI. +# On CI we only run it for the Appraisal-based builds. +# We do not load the standard Gemfile, as it is tailored for local development. + +gemspec diff --git a/Appraisals b/Appraisals new file mode 100644 index 0000000..1c375cf --- /dev/null +++ b/Appraisals @@ -0,0 +1,194 @@ +# frozen_string_literal: true + +# Compat: Ruby >= 1.9.3 +# Test Matrix: +# - Ruby 2.4 +appraise "ar-4-2" do + gem "activerecord", "~> 4.2.11.3" +end + +# Compat: Ruby >= 2.2.2 +# Test Matrix: +# - Ruby 2.4 +appraise "ar-5-0" do + gem "activerecord", "~> 5.0.7.2" +end + +# Compat: Ruby >= 2.2.2 +# Test Matrix: +# - Ruby 2.4 +# - Ruby 2.5 +appraise "ar-5-1" do + gem "activerecord", "~> 5.1.7" +end + +# Compat: Ruby >= 2.2.2 +# Test Matrix: +# - Ruby 2.4 +# - Ruby 2.5 +# - Ruby 2.6 +# - Ruby 2.7 +appraise "ar-5-2" do + gem "activerecord", "~> 5.2.8.1" +end + +# Compat: Ruby >= 2.5 +# Test Matrix: +# - Ruby 2.5 +# - Ruby 2.6 +# - Ruby 2.7 +appraise "ar-6-0" do + gem "activerecord", "~> 6.0.6.1" +end + +# Compat: Ruby >= 2.5 +# Test Matrix: +# - Ruby 2.5 +# - Ruby 2.6 +# - Ruby 2.7 +# - Ruby 3.0 +appraise "ar-6-1" do + gem "activerecord", "~> 6.1.7.10" +end + +# Compat: Ruby >= 2.7 +# Test Matrix: +# - Ruby 2.7 +# - Ruby 3.0 +# - Ruby 3.1 +appraise "ar-7-0" do + gem "activerecord", "~> 7.0.8.6" +end + +# Compat: Ruby >= 2.7 +# Test Matrix: +# - Ruby 2.7 +# - Ruby 3.0 +# - Ruby 3.1 +# - Ruby 3.2 +appraise "ar-7-1" do + gem "activerecord", "~> 7.1.5" +end + +# Compat: Ruby >= 3.1 +# Test Matrix: +# - Ruby 3.1 +# - Ruby 3.2 +# - Ruby 3.3 +appraise "ar-7-2" do + gem "activerecord", "~> 7.2.2" +end + +# Compat: Ruby >= 3.2 +# Test Matrix: +# - Ruby 3.2 +# - Ruby 3.3 +# - ruby-head +# - truffleruby-head +# - jruby-head +appraise "ar-8-0" do + gem "activerecord", "~> 8.0.0" +end + +# Compat: Ruby >= 2.2.2 (due to AR >= 5) +# Test Matrix: +# - Ruby 2.4 +# - Ruby 2.5 +# - Ruby 2.6 +# - Ruby 2.7 +# - Ruby 3.0 +# - Ruby 3.1 +# - Ruby 3.2 +# - Ruby 3.3 +# - ruby-head +# - truffleruby-head +# - jruby-head +appraise "couch-1.17" do + gem "couch_potato", "~> 1.17" +end + +# Compat: Ruby >= 2.3 +# Test Matrix: +# - Ruby 2.4 +# - Ruby 2.5 +appraise "mongoid-7.3" do + gem "mongoid", "~> 7.3", ">= 7.3.5" +end + +# Compat: Ruby >= 2.5 +# Test Matrix: +# - Ruby 2.5 +# - Ruby 2.6 +# - Ruby 2.7 +appraise "mongoid-7.4" do + gem "mongoid", "~> 7.4", ">= 7.4.3" +end + +# Compat: Ruby >= 2.6 +# Test Matrix: +# - Ruby 2.6 +# - Ruby 2.7 +# - Ruby 3.0 +# - Ruby 3.1 +# - Ruby 3.2 +# - Ruby 3.3 +appraise "mongoid-8.1" do + gem "mongoid", "~> 8.1", ">= 8.1.7" +end + +# Compat: Ruby >= 2.7 +# Test Matrix: +# - Ruby 2.7 +# - Ruby 3.0 +# - Ruby 3.1 +# - Ruby 3.2 +# - Ruby 3.3 +# - ruby-head +# - truffleruby-head +# - jruby-head +appraise "mongoid-9.0" do + gem "mongoid", "~> 9.0", ">= 9.0.3" +end + +# 1. While the Ruby driver, nobrainer, is maintained, +# RethinkDB itself is currently a zombie project. +# 2. There are zero examples in the wild of a GitHub Actions workflow +# that sets up a RethinkDB service to test client code against. +# As long as above points remain current, no attempt will be made to get nobrainer specs running in CI, +# unless a RethinkDB-fan wants to take a shot at it. +# You might be inspired by the existing other services this library is currently +# tested against (e.g. CouchDB, MongoDB) +# See: https://github.com/rethinkdb/rethinkdb/issues/6981 +# Compat: Ruby >= 1.9 +# Test Matrix: +# - Ruby 2.4 +# - Ruby 2.5 +# - Ruby 2.6 +# - Ruby 2.7 +# - Ruby 3.0 +# - Ruby 3.1 +# - Ruby 3.2 +# - Ruby 3.3 +# - ruby-head +# - truffleruby-head +# - jruby-head +# appraise "nobrainer-0.44" do +# gem "nobrainer", "~> 0.44", ">= 0.44.1" +# end + +# Compat: Ruby >= 1.9.2 +# Test Matrix: +# - Ruby 2.4 +# - Ruby 2.5 +# - Ruby 2.6 +# - Ruby 2.7 +# - Ruby 3.0 +# - Ruby 3.1 +# - Ruby 3.2 +# - Ruby 3.3 +# - ruby-head +# - truffleruby-head +# - jruby-head +appraise "sequel-5.86" do + gem "sequel", "~> 5.86", ">= 5.86.0" +end diff --git a/Gemfile b/Gemfile index 6c9d017..f05e864 100644 --- a/Gemfile +++ b/Gemfile @@ -13,8 +13,8 @@ gemspec ### Documentation gem "yard", "~> 0.9.34", require: false gem "yard-junk", "~> 0.0.10" -gem "github-markup", platform: :mri -gem "redcarpet", platform: :mri +gem "github-markup" +gem "redcarpet" ### Linting gem "rubocop-lts", "~> 12.1", ">= 12.1.1" @@ -22,15 +22,15 @@ gem "rubocop-minitest" gem "rubocop-packaging", "~> 0.5", ">= 0.5.2" gem "rubocop-rspec", "~> 3.2" gem "rubocop-sequel" +gem "standard", ">= 1.35.1" ### ORMs gem "activerecord", ">= 6", require: false # rails 6 requires Ruby 2.5 or later -gem "anonymous_active_record", "~> 1", require: false -gem "couch_potato", github: "langalex/couch_potato", require: false +gem "couch_potato", "~> 1.17", require: false gem "mongoid", "~> 7", require: false -gem "mongoid-rspec", github: "mongoid/mongoid-rspec", require: false -gem "nobrainer", "~> 0", require: false -gem "sequel", "~> 5", require: false +gem "mongoid-rspec", "~> 4.2", require: false +gem "nobrainer", "~> 0.44", require: false +gem "sequel", "~> 5.86", require: false ### Local dev tools gem "growl" @@ -43,6 +43,7 @@ gem "rb-fsevent" gem "kettle-soup-cover", "~> 1.0", ">= 1.0.2" ### Testing +gem "anonymous_active_record", "~> 1", require: false gem "test-unit", ">= 3.0" platform :mri do diff --git a/Gemfile.lock b/Gemfile.lock index bbd4343..cded787 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,20 +1,3 @@ -GIT - remote: https://github.com/langalex/couch_potato - revision: 1ca5bfa39ff6d88f12f97c9ec2cae9d8cb5c2fe1 - specs: - couch_potato (1.7.1) - activemodel (>= 5.0, < 7.0) - couchrest (~> 2.0.1) - json (~> 2.3) - -GIT - remote: https://github.com/mongoid/mongoid-rspec - revision: d9d6639d9b65a7498d761d666570cc3e38901b22 - specs: - mongoid-rspec (4.2.0) - mongoid (>= 3.0, < 10.0) - mongoid-compatibility (>= 0.5.1) - PATH remote: . specs: @@ -26,22 +9,25 @@ PATH GEM remote: https://rubygems.org/ specs: - activemodel (6.1.7.10) - activesupport (= 6.1.7.10) - activerecord (6.1.7.10) - activemodel (= 6.1.7.10) - activesupport (= 6.1.7.10) - activesupport (6.1.7.10) + activemodel (7.0.8.6) + activesupport (= 7.0.8.6) + activerecord (7.0.8.6) + activemodel (= 7.0.8.6) + activesupport (= 7.0.8.6) + activesupport (7.0.8.6) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) - zeitwerk (~> 2.3) anonymous_active_record (1.0.9) activerecord (>= 5) activesupport (>= 5) version_gem (~> 1.1, >= 1.1.4) ansi (1.5.0) + appraisal (2.5.0) + bundler + rake + thor (>= 0.14.0) ast (2.4.2) backports (3.25.0) base64 (0.2.0) @@ -51,6 +37,10 @@ GEM byebug (11.1.3) coderay (1.1.3) concurrent-ruby (1.3.4) + couch_potato (1.17.0) + activemodel (>= 5.0, < 8.0) + couchrest (~> 2.0.0) + json (~> 2.3) couchrest (2.0.1) httpclient (~> 2.8) mime-types (>= 1.15) @@ -126,6 +116,9 @@ GEM mongoid-compatibility (1.0.0) activesupport mongoid (>= 2.0) + mongoid-rspec (4.2.0) + mongoid (>= 3.0, < 10.0) + mongoid-compatibility (>= 0.5.1) multi_json (1.15.0) nenv (0.3.0) nobrainer (0.44.1) @@ -291,7 +284,6 @@ GEM ostruct rainbow yard - zeitwerk (2.7.1) PLATFORMS aarch64-linux @@ -312,8 +304,9 @@ PLATFORMS DEPENDENCIES activerecord (>= 6) anonymous_active_record (~> 1) + appraisal (~> 2.5) byebug (>= 11) - couch_potato! + couch_potato (~> 1.17) github-markup growl guard @@ -321,8 +314,8 @@ DEPENDENCIES guard-rspec kettle-soup-cover (~> 1.0, >= 1.0.2) mongoid (~> 7) - mongoid-rspec! - nobrainer (~> 0) + mongoid-rspec (~> 4.2) + nobrainer (~> 0.44) omniauth-identity! rack-test (~> 1) rake (~> 13) @@ -335,8 +328,9 @@ DEPENDENCIES rubocop-packaging (~> 0.5, >= 0.5.2) rubocop-rspec (~> 3.2) rubocop-sequel - sequel (~> 5) + sequel (~> 5.86) sqlite3 (~> 1.4) + standard (>= 1.35.1) test-unit (>= 3.0) yard (~> 0.9.34) yard-junk (~> 0.0.10) diff --git a/README.md b/README.md index 19157c9..a0ecfe4 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,10 @@ basic construct for user management and then gets out of the way. ## Compatibility -This gem is compatible with, as of Feb 2021, version 3: +This gem is compatible with, as of Nov 2024, version 3: -* Latest released version of omniauth, v2.0.2 -* Ruby 2.4, 2.5, 2.6, 2.7, 3.0, ruby-head +* Latest released version of omniauth, v2+ +* Ruby 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, 3.3, ruby-head, truffleruby-head, jruby-head * At least 5 different database ORM adapters, which connect to 15 different database clients! | Databases | Adapter Libraries | @@ -296,9 +296,9 @@ Please contribute some documentation if you have the gumption! The maintainer's ``` 3. [CouchDB](https://couchdb.apache.org) (download the .app) - To run all tests on all databases: + To run all tests on all databases (except RethinkDB): ```bash - bundle exec rake + bundle exec rake spec ``` To run a specific DB: ```bash @@ -314,8 +314,8 @@ Please contribute some documentation if you have the gumption! The maintainer's # MongoDB / Mongoid bundle exec rspec spec_orms/mongoid_spec.rb - # RethinkDB / NoBrainer - bundle exec rspec spec_orms/nobrainer_spec.rb + # RethinkDB / NoBrainer (Ignored by CI! see spec file for more) + bundle exec rspec spec_ignored/nobrainer_spec.rb ``` 6. Create new Pull Request diff --git a/Rakefile b/Rakefile index fbce4a4..d42052f 100644 --- a/Rakefile +++ b/Rakefile @@ -4,20 +4,54 @@ require "bundler/gem_tasks" begin require "rspec/core/rake_task" + # Define a default test task which will run only ORM-agnostic specs + # This ignores the ORM-specific tests because they are in spec_orms/ + # which doesn't match the default RSpec test task pattern. RSpec::Core::RakeTask.new(:test) + + ### Combo Test Tasks for Continuous Integration + # Define a task for each ORM which will run all ORM-agnostic specs + the specs for a specific ORM. + # See spec_ignored/nobrainer_spec.rb for details on why that spec is skipped in CI. + %w(active_record couch_potato mongoid sequel).each do |orm| + RSpec::Core::RakeTask.new("spec:orm:#{orm}") do |task| + task.pattern = "{spec/**/*,spec_orms/#{orm}}_spec.rb" + end + end + ### Combo Test Task for Code Coverage Workflow in Continuous Integration + # Requires all services (CouchDB, and MongoDB) to be running. + # See spec_ignored/nobrainer_spec.rb for details on why that spec is skipped in CI. + RSpec::Core::RakeTask.new("spec:orm:all") do |task| + task.pattern = "{spec,spec_orms}/**/*_spec.rb" + end + + ### Combo Test Tasks for local development... + # Define tasks which only run the ORM-specific tests in isolation + active_record = RSpec::Core::RakeTask.new(:spec_orm_active_record) + active_record.pattern = "spec_orms/active_record_spec.rb" couch_potato = RSpec::Core::RakeTask.new(:spec_orm_couch_potato) couch_potato.pattern = "spec_orms/couch_potato_spec.rb" mongoid = RSpec::Core::RakeTask.new(:spec_orm_mongoid) mongoid.pattern = "spec_orms/mongoid_spec.rb" + sequel = RSpec::Core::RakeTask.new(:spec_orm_sequel) + sequel.pattern = "spec_orms/sequel_spec.rb" + + # See spec_ignored/nobrainer_spec.rb for details on why that spec is skipped in CI. nobrainer = RSpec::Core::RakeTask.new(:spec_orm_nobrainer) - nobrainer.pattern = "spec_orms/nobrainer_spec.rb" + nobrainer.pattern = "spec_ignored/nobrainer_spec.rb" - # When running all tests you must have RethinkDB, CouchDB, and MongoDB running. See README.md + # When running sqlite3-based tests you don't need any additional services running. + task("test:sqlite3": %i[ + test + spec_orm_active_record + spec_orm_sequel + ]) + # When running all tests you must have CouchDB, and MongoDB running. See README.md task(spec: %i[ test + spec_orm_active_record spec_orm_couch_potato spec_orm_mongoid - spec_orm_nobrainer + spec_orm_sequel ]) rescue LoadError task(:test) do @@ -34,5 +68,5 @@ rescue LoadError end end -# These tests do not require any services to be running, so this is what we run via Github Actions -task default: %i[test rubocop_gradual:autocorrect] +# These tests do not require any services to be running, so this is what we run as default +task default: %i[test:sqlite3 rubocop_gradual:autocorrect] diff --git a/gemfiles/ancient.gemfile b/gemfiles/ancient.gemfile deleted file mode 100644 index bf6653b..0000000 --- a/gemfiles/ancient.gemfile +++ /dev/null @@ -1,3 +0,0 @@ -gem "activerecord", "~> 5", require: false # rails 5 works with Ruby 2.4 - -gemspec path: "../" diff --git a/gemfiles/ar_4_2.gemfile b/gemfiles/ar_4_2.gemfile new file mode 100644 index 0000000..a3bb372 --- /dev/null +++ b/gemfiles/ar_4_2.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "activerecord", "~> 4.2.11.3" + +gemspec path: "../" diff --git a/gemfiles/ar_5_0.gemfile b/gemfiles/ar_5_0.gemfile new file mode 100644 index 0000000..6da234c --- /dev/null +++ b/gemfiles/ar_5_0.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "activerecord", "~> 5.0.7.2" + +gemspec path: "../" diff --git a/gemfiles/ar_5_1.gemfile b/gemfiles/ar_5_1.gemfile new file mode 100644 index 0000000..82000d4 --- /dev/null +++ b/gemfiles/ar_5_1.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "activerecord", "~> 5.1.7" + +gemspec path: "../" diff --git a/gemfiles/ar_5_2.gemfile b/gemfiles/ar_5_2.gemfile new file mode 100644 index 0000000..bcb66a2 --- /dev/null +++ b/gemfiles/ar_5_2.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "activerecord", "~> 5.2.8.1" + +gemspec path: "../" diff --git a/gemfiles/ar_6_0.gemfile b/gemfiles/ar_6_0.gemfile new file mode 100644 index 0000000..1248221 --- /dev/null +++ b/gemfiles/ar_6_0.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "activerecord", "~> 6.0.6.1" + +gemspec path: "../" diff --git a/gemfiles/ar_6_1.gemfile b/gemfiles/ar_6_1.gemfile new file mode 100644 index 0000000..9c37404 --- /dev/null +++ b/gemfiles/ar_6_1.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "activerecord", "~> 6.1.7.10" + +gemspec path: "../" diff --git a/gemfiles/ar_7_0.gemfile b/gemfiles/ar_7_0.gemfile new file mode 100644 index 0000000..e215ce7 --- /dev/null +++ b/gemfiles/ar_7_0.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "activerecord", "~> 7.0.8.6" + +gemspec path: "../" diff --git a/gemfiles/ar_7_1.gemfile b/gemfiles/ar_7_1.gemfile new file mode 100644 index 0000000..d6ce1b6 --- /dev/null +++ b/gemfiles/ar_7_1.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "activerecord", "~> 7.1.5" + +gemspec path: "../" diff --git a/gemfiles/ar_7_2.gemfile b/gemfiles/ar_7_2.gemfile new file mode 100644 index 0000000..b77fbe9 --- /dev/null +++ b/gemfiles/ar_7_2.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "activerecord", "~> 7.2.2" + +gemspec path: "../" diff --git a/gemfiles/ar_8_0.gemfile b/gemfiles/ar_8_0.gemfile new file mode 100644 index 0000000..c606dc0 --- /dev/null +++ b/gemfiles/ar_8_0.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "activerecord", "~> 8.0.0" + +gemspec path: "../" diff --git a/gemfiles/couch_1.17.gemfile b/gemfiles/couch_1.17.gemfile new file mode 100644 index 0000000..ea6be63 --- /dev/null +++ b/gemfiles/couch_1.17.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "couch_potato", "~> 1.17" + +gemspec path: "../" diff --git a/gemfiles/couch_1.gemfile b/gemfiles/couch_1.gemfile new file mode 100644 index 0000000..22fb0d7 --- /dev/null +++ b/gemfiles/couch_1.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "couch_potato", "~> 1" + +gemspec path: "../" diff --git a/gemfiles/coverage.gemfile b/gemfiles/coverage.gemfile index 7d410e2..1009663 100644 --- a/gemfiles/coverage.gemfile +++ b/gemfiles/coverage.gemfile @@ -6,8 +6,12 @@ source "https://rubygems.org" # On CI we only need the gemspecs' dependencies (including development dependencies). # Exceptions, if any, will be found here in gemfiles/*.gemfile -# Database -gem "activerecord", ">= 6", require: false # rails 6 requires Ruby 2.5 or later +### ORMs +gem "activerecord", "~> 8.0", require: false +gem "couch_potato", "~> 1.17", require: false +gem "mongoid", "~> 7.0", require: false +gem "mongoid-rspec", "~> 4.2", require: false +gem "sequel", "~> 5.86", require: false # Coverage gem "kettle-soup-cover", "~> 1.0", ">= 1.0.2" diff --git a/gemfiles/mongoid_7.3.gemfile b/gemfiles/mongoid_7.3.gemfile new file mode 100644 index 0000000..a6d474f --- /dev/null +++ b/gemfiles/mongoid_7.3.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "mongoid", "~> 7.3", ">= 7.3.5" + +gemspec path: "../" diff --git a/gemfiles/mongoid_7.4.gemfile b/gemfiles/mongoid_7.4.gemfile new file mode 100644 index 0000000..8faf426 --- /dev/null +++ b/gemfiles/mongoid_7.4.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "mongoid", "~> 7.4", ">= 7.4.3" + +gemspec path: "../" diff --git a/gemfiles/mongoid_8.1.gemfile b/gemfiles/mongoid_8.1.gemfile new file mode 100644 index 0000000..4cf23ca --- /dev/null +++ b/gemfiles/mongoid_8.1.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "mongoid", "~> 8.1", ">= 8.1.7" + +gemspec path: "../" diff --git a/gemfiles/mongoid_9.0.gemfile b/gemfiles/mongoid_9.0.gemfile new file mode 100644 index 0000000..644cd5a --- /dev/null +++ b/gemfiles/mongoid_9.0.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "mongoid", "~> 9.0", ">= 9.0.3" + +gemspec path: "../" diff --git a/gemfiles/sequel_5.86.gemfile b/gemfiles/sequel_5.86.gemfile new file mode 100644 index 0000000..3a7dae2 --- /dev/null +++ b/gemfiles/sequel_5.86.gemfile @@ -0,0 +1,7 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "sequel", "~> 5.86", ">= 5.86.0" + +gemspec path: "../" diff --git a/gemfiles/style.gemfile b/gemfiles/style.gemfile index a4392d6..a7be44f 100644 --- a/gemfiles/style.gemfile +++ b/gemfiles/style.gemfile @@ -15,5 +15,6 @@ gem "rubocop-minitest" gem "rubocop-packaging", "~> 0.5", ">= 0.5.2" gem "rubocop-rspec", "~> 3.2" gem "rubocop-sequel" +gem "standard", ">= 1.35.1" gemspec path: "../" diff --git a/lib/omniauth/identity/models/sequel.rb b/lib/omniauth/identity/models/sequel.rb index 5ac5b1e..8cb96de 100644 --- a/lib/omniauth/identity/models/sequel.rb +++ b/lib/omniauth/identity/models/sequel.rb @@ -22,8 +22,12 @@ def self.included(base) include(::OmniAuth::Identity::Model) include(::OmniAuth::Identity::SecurePassword) - # validations: true incurs a dependency on ActiveModel, so we turn it off here. - has_secure_password(validations: false) + # `validations: true` (default) would normally incur a dependency on ActiveModel. + # Starting in v3.1 we check if ActiveModel is defined before we actually set validations. + # If ActiveModel isn't defined, it may be unexpected that validations are not being set, + # so this will result in a warning deprecation until release of v4, + # at which point the default (for Sequel ORM only) will change to `validations: false` + has_secure_password(validations: OmniAuth::Identity::Version.major < 4) def self.auth_key=(key) super diff --git a/lib/omniauth/identity/secure_password.rb b/lib/omniauth/identity/secure_password.rb index ecc5aad..cec8dc8 100644 --- a/lib/omniauth/identity/secure_password.rb +++ b/lib/omniauth/identity/secure_password.rb @@ -17,7 +17,7 @@ def self.included(base) # BCrypt hash function can handle maximum 72 bytes, and if we pass # password of length more than 72 bytes it ignores extra characters. # Hence need to put a restriction on password length. - MAX_PASSWORD_LENGTH_ALLOWED = 72 + MAX_PASSWORD_LENGTH_ALLOWED = BCrypt::Engine::MAX_SECRET_BYTESIZE class << self attr_accessor :min_cost # :nodoc: @@ -96,6 +96,15 @@ def has_secure_password(attribute = :password, validations: true) include(InstanceMethodsOnActivation.new(attribute)) if validations + if !defined?(ActiveModel) + warn("[DEPRECATION][omniauth-identity v3.1][w/ Sequel ORM] has_secure_password(validations: true) is default, but incurs dependency on ActiveModel. v4 will default to `has_secure_password(validations: false)`.") + begin + require "active_model" + rescue LoadError + warn("You don't have active_model installed in your application. Please add it to your Gemfile and run bundle install") + raise + end + end include(ActiveModel::Validations) # This ensures the model has a password by checking whether the password_digest @@ -106,7 +115,7 @@ def has_secure_password(attribute = :password, validations: true) record.errors.add(attribute, :blank) unless record.public_send(:"#{attribute}_digest").present? end - validates_length_of(attribute, maximum: ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED) + validates_length_of(attribute, maximum: MAX_PASSWORD_LENGTH_ALLOWED) validates_confirmation_of(attribute, allow_blank: true) end end @@ -121,7 +130,11 @@ def initialize(attribute) public_send(:"#{attribute}_digest=", nil) elsif !unencrypted_password.empty? instance_variable_set(:"@#{attribute}", unencrypted_password) - cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost + cost = if defined?(ActiveModel::SecurePassword) + ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost + else + BCrypt::Engine.cost + end public_send(:"#{attribute}_digest=", BCrypt::Password.create(unencrypted_password, cost: cost)) end end diff --git a/omniauth-identity.gemspec b/omniauth-identity.gemspec index d35b284..ec3732f 100644 --- a/omniauth-identity.gemspec +++ b/omniauth-identity.gemspec @@ -39,6 +39,7 @@ Gem::Specification.new do |spec| spec.add_dependency("version_gem", "~> 1.1", ">= 1.1.4") ### Testing + spec.add_development_dependency("appraisal", "~> 2.5") spec.add_development_dependency("rack-test", "~> 1") spec.add_development_dependency("rake", "~> 13") spec.add_development_dependency("rspec", "~> 3") diff --git a/spec_orms/nobrainer_spec.rb b/spec_ignored/nobrainer_spec.rb similarity index 66% rename from spec_orms/nobrainer_spec.rb rename to spec_ignored/nobrainer_spec.rb index 61075ae..f57c948 100644 --- a/spec_orms/nobrainer_spec.rb +++ b/spec_ignored/nobrainer_spec.rb @@ -1,7 +1,19 @@ # frozen_string_literal: true +# 1. While the Ruby driver, nobrainer, is maintained, +# RethinkDB itself is currently a zombie project. +# 2. There are zero examples in the wild of a GitHub Actions workflow +# that sets up a RethinkDB service to test client code against. +# As long as above points remain current, no attempt will be made to get nobrainer specs running in CI, +# unless a RethinkDB-fan wants to take a shot at it. +# You might be inspired by the existing other services this library is currently +# tested against (e.g. CouchDB, MongoDB) +# See: https://github.com/rethinkdb/rethinkdb/issues/6981 +# # NOTE: mongoid and nobrainer can't be loaded at the same time. # If you try it, one or both of them will not work. +# +# However, if you have RethinkDB installed locally, this spec should work in isolation! require "nobrainer" RSpec.describe(OmniAuth::Identity::Models::NoBrainer, :rethinkdb) do diff --git a/spec/omniauth/identity/models/active_record_spec.rb b/spec_orms/active_record_spec.rb similarity index 84% rename from spec/omniauth/identity/models/active_record_spec.rb rename to spec_orms/active_record_spec.rb index a502df4..e4a7e47 100644 --- a/spec/omniauth/identity/models/active_record_spec.rb +++ b/spec_orms/active_record_spec.rb @@ -25,7 +25,7 @@ def flower describe "::table_name" do it "does not use STI rules for its table name" do - expect(TestIdentity.table_name).to eq("test_identities") + expect(TestIdentity.table_name).to(eq("test_identities")) end end @@ -36,8 +36,8 @@ def flower category: "sandwiches", provider: "identity", } - allow(model_klass).to receive(:where).with(args).and_return(["wakka"]) - expect(model_klass.locate(args)).to eq("wakka") + allow(model_klass).to(receive(:where).with(args).and_return(["wakka"])) + expect(model_klass.locate(args)).to(eq("wakka")) end end end diff --git a/spec_orms/couch_potato_spec.rb b/spec_orms/couch_potato_spec.rb index 6fbab4f..1145bd2 100644 --- a/spec_orms/couch_potato_spec.rb +++ b/spec_orms/couch_potato_spec.rb @@ -4,7 +4,7 @@ RSpec.describe(OmniAuth::Identity::Models::CouchPotatoModule, :couchdb) do before(:all) do - CouchPotato::Config.database_name = "http://admin:butterknuckles@127.0.0.1:5984/test" + CouchPotato::Config.database_name = "http://admin:password@127.0.0.1:5984/test" end before do diff --git a/spec/omniauth/identity/models/sequel_spec.rb b/spec_orms/sequel_spec.rb similarity index 82% rename from spec/omniauth/identity/models/sequel_spec.rb rename to spec_orms/sequel_spec.rb index a1e5d3f..33493a2 100644 --- a/spec/omniauth/identity/models/sequel_spec.rb +++ b/spec_orms/sequel_spec.rb @@ -8,7 +8,7 @@ RSpec.describe(OmniAuth::Identity::Models::Sequel, :sqlite3) do before(:all) do # Connect to an in-memory sqlite3 database. - DB.create_table :sequel_test_identities do + DB.create_table(:sequel_test_identities) do primary_key :id String :email, null: false String :password_digest, null: false @@ -31,8 +31,8 @@ describe "::locate" do it "delegates to the where query method" do args = {email: "open faced", category: "sandwiches"} - allow(model_klass).to receive(:where).with(args).and_return(["wakka"]) - expect(model_klass.locate(args)).to eq("wakka") + allow(model_klass).to(receive(:where).with(args).and_return(["wakka"])) + expect(model_klass.locate(args)).to(eq("wakka")) end end end