Skip to content

Commit

Permalink
Get GitHub actions running green on 6.0 → 8.0 (#37)
Browse files Browse the repository at this point in the history
Co-authored-by: Frederik Erbs Spang Thomsen <[email protected]>
  • Loading branch information
timdiggins and frederikspang authored Nov 10, 2024
1 parent 87cc337 commit 8ebe558
Show file tree
Hide file tree
Showing 17 changed files with 293 additions and 96 deletions.
70 changes: 70 additions & 0 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: RSpec Test Matrix
on:
push:
pull_request:

jobs:
test:
runs-on: ubuntu-latest

services:
postgresql:
image: postgres
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
POSTGRES_DB: active_record_union
POSTGRES_USER: active_record_union
POSTGRES_PASSWORD: active_record_union

mysql2:
image: mysql:8.0
env:
MYSQL_DATABASE: active_record_union
MYSQL_ROOT_PASSWORD: active_record_union
options: >-
--health-cmd "mysqladmin ping"
--health-interval 10s
--health-timeout 5s
ports:
- "3306:3306"

strategy:
fail-fast: false
matrix:
# just define specific versions for each rails version
include:
- ruby: 2.6
rails: "6.0"
- ruby: "3.0"
rails: 6.1
- ruby: 3.1
rails: "7.0"
- ruby: 3.2
rails: 7.1
- ruby: 3.2
rails: 7.2
- ruby: 3.3
rails: "8.0"

env:
BUNDLE_GEMFILE: "rails_${{ matrix.rails }}.gemfile"
DB_HOST: 127.0.0.1
MYSQL_ROOT_HOST: "%"
MYSQL_DB: active_record_union
MYSQL_USER: root
MYSQL_PASSWORD: active_record_union
steps:
- uses: actions/checkout@v4

- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true # install gems and cache

- run: bundle exec rspec --force-color --format d
10 changes: 0 additions & 10 deletions .travis.yml

This file was deleted.

4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# this is just a convenience for out of the box development
source 'https://rubygems.org'

eval_gemfile File.expand_path('./rails_8.0.gemfile', __dir__)
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ user_1.posts.union(user_2.posts).union(Post.published)
user_1.posts.union_all(user_2.posts)
```

ActiveRecordUnion is tested against Rails 5.0, 5.1, and 5.2. It should also work on Rails 4.2. It may or may not work on Rails 4.0/4.1.
ActiveRecordUnion is tested against Rails 6.0, 6.1, 7.0, 7.1, 7.2 and 8.0.

If you are using Postgres, you might alternatively check out [ActiveRecordExtended](https://github.com/georgekaraszi/ActiveRecordExtended) which includes support for unions as well as other goodies.

Expand Down Expand Up @@ -216,9 +216,9 @@ This public domain dedication follows the the CC0 1.0 at https://creativecommons
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Run the tests:
1. Install MySQL and PostgreSQL.
2. You need to be able to connect to a local MySQL and Postgres database as the default user, so the specs can create a `test_active_record_union` database. From a vanilla install of MariaDB from Homebrew, this just works. For Postgres installed by Homebrew, you may need to run `$ echo "create database my_computer_user_name;" | psql postgres` since the initial database created by Homebrew is named "postgres" but PG defaults to connecting to a database named after your username.
2. You need to be able to connect to a local MySQL and Postgres database as the default user, so the specs can create a `test_active_record_union` database. To set up the users this test expects, execute `bin/create-db-users` (or set the environment variables referenced in `spec/support/databases.rb`).
3. Run `rake` to test with all supported Rails versions. All needed dependencies will be installed via Bundler (`gem install bundler` if you happen not to have Bundler yet).
4. Run `rake test_rails_4_2` or `rake test_rails_5_2` etc. to test a specific Rails version.
4. Run `rake test_rails_8_0` or `rake test_rails_7_2` etc. to test a specific Rails version.
4. There is also a `bin/console` command to load up a REPL for playing around
5. Commit your changes (`git commit -am 'Add some feature'`)
6. Push to the branch (`git push origin my-new-feature`)
Expand Down
8 changes: 4 additions & 4 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ end


TestTasks.gemfiles.each do |gemfile|
rails_version_underscored = gemfile[/rails_(.+)\.gemfile/, 1]
rails_version = gemfile[/rails_(.+)\.gemfile/, 1]

desc "Test Rails #{rails_version_underscored.gsub("_", ".")}"
task :"test_rails_#{rails_version_underscored}" do
desc "Test Rails #{rails_version}"
task :"test_rails_#{rails_version.gsub(".", "_")}" do
env = { 'BUNDLE_GEMFILE' => gemfile }
TestTasks.run_one(env)
end
end
end
2 changes: 1 addition & 1 deletion active_record_union.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) + spec.files.grep(%r{^bin/})
spec.require_paths = ["lib"]

spec.add_dependency "activerecord", ">= 4.0"
spec.add_dependency "activerecord", ">= 6.0"

spec.add_development_dependency "bundler"
spec.add_development_dependency "rake"
Expand Down
44 changes: 44 additions & 0 deletions bin/create-db-users
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env bash

GREEN='\033[0;32m'
RESET_COLOR='\033[0m'

if [ -n "$1" ]; then cat <<'HELP'; exit; fi
Usage: bin/create-db-users
Create the active_record_union database users for all the supported databases.
If the `DB` environment variable is set, do the above only for that database.
HELP

USER='active_record_union'
PASS='active_record_union'

set -e
log() { if [ -t 1 ]; then echo -e >&2 "${GREEN}create-db-users: $@${RESET_COLOR}"; else echo >&2 "$@"; fi }

create_mysql_user() {
if mysql -s -u"$USER" -p"$PASS" -e '' 2>/dev/null; then return; fi
log "Creating MySQL '$USER' user. MySQL root password required."
mysql --verbose -uroot -p <<SQL
CREATE USER '$USER'@'localhost' IDENTIFIED BY '$PASS';
GRANT ALL PRIVILEGES ON \`test_active_record_union\`.* TO '$USER'@'localhost';
SQL
}

create_postgresql_user() {
if PGPASSWORD="$PASS" psql -h 127.0.0.1 postgres -U $USER -c ''; then return; fi
log "Creating Postgres '$USER' user."
local cmd='psql postgres'
if ! $cmd -c '' 2>/dev/null; then
log "sudo required:"
cmd="sudo -u ${PG_DAEMON_USER:-postgres} psql postgres"
fi
# need to also create database first time
$cmd --echo-all <<SQL
CREATE ROLE $USER LOGIN PASSWORD '$PASS';
ALTER ROLE $USER CREATEDB;
CREATE DATABASE active_record_union;
SQL
}

[ -z "$DB" -o "$DB" = 'mysql2' ] && create_mysql_user
[ -z "$DB" -o "$DB" = 'postgresql' ] && create_postgresql_user
37 changes: 2 additions & 35 deletions lib/active_record_union/active_record/relation/union.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,41 +41,8 @@ def set_operation(operation, relation_or_where_arg, *args)
build_union_relation(from, other)
end

if ActiveRecord.gem_version >= Gem::Version.new('5.2.0.beta2')
# Since Rails 5.2, binds are maintained only in the Arel AST.
def build_union_relation(arel_table_alias, _other)
self.klass.unscoped.from(arel_table_alias)
end
elsif ActiveRecord::VERSION::MAJOR >= 5
# In Rails >= 5.0, < 5.2, binds are maintained only in ActiveRecord
# relations and clauses.
def build_union_relation(arel_table_alias, other)
relation = self.klass.unscoped.spawn
relation.from_clause =
UnionFromClause.new(arel_table_alias, nil,
self.bound_attributes + other.bound_attributes)
relation
end

class UnionFromClause < ActiveRecord::Relation::FromClause
def initialize(value, name, bound_attributes)
super(value, name)
@bound_attributes = bound_attributes
end

def binds
@bound_attributes
end
end
else
# In Rails 4.x, binds are maintained in both ActiveRecord relations and
# clauses and also in their Arel ASTs.
def build_union_relation(arel_table_alias, other)
relation = self.klass.unscoped.from(arel_table_alias)
relation.bind_values = self.arel.bind_values + self.bind_values +
other.arel.bind_values + other.bind_values
relation
end
def build_union_relation(arel_table_alias, _other)
self.klass.unscoped.from(arel_table_alias)
end

def verify_relations_for_set_operation!(operation, *relations)
Expand Down
16 changes: 16 additions & 0 deletions rails_6.0.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
source 'https://rubygems.org'

# Specify your gem's dependencies in active_record_union.gemspec
gemspec

gem 'rails', '~> 6.0.0'

# https://github.com/rails/rails/blob/v6.0.6.1/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
gem "pg", ">= 0.18", "< 2.0"

# https://github.com/rails/rails/blob/v6.0.2/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L13
gem "sqlite3", "~> 1.4"

# https://github.com/rails/rails/blob/v6.0.6.1/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
gem "mysql2", ">= 0.4.4"

16 changes: 16 additions & 0 deletions rails_6.1.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
source 'https://rubygems.org'

# Specify your gem's dependencies in active_record_union.gemspec
gemspec

gem 'rails', '~> 6.1.0'

# https://github.com/rails/rails/blob/v6.1.7.10/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
gem "pg", "~> 1.1"

# https://github.com/rails/rails/blob/v6.1.2/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L13
gem "sqlite3", "~> 1.4"

# https://github.com/rails/rails/blob/v6.1.7.10/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
gem "mysql2", "~> 0.5"

17 changes: 17 additions & 0 deletions rails_7.0.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

source 'https://rubygems.org'

# Specify your gem's dependencies in active_record_union.gemspec
gemspec

gem 'rails', '~> 7.0.0'

# https://github.com/rails/rails/blob/v7.0.2/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L13
gem 'sqlite3', '~> 1.4'

# https://github.com/rails/rails/blob/v7.0.2/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L4
gem 'pg', '~> 1.1'

# https://github.com/rails/rails/blob/v7.0.2/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L6
gem 'mysql2', '~> 0.5'
17 changes: 17 additions & 0 deletions rails_7.1.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

source 'https://rubygems.org'

# Specify your gem's dependencies in active_record_union.gemspec
gemspec

gem 'rails', '~> 7.1.0'

# https://github.com/rails/rails/blob/v7.1.2/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L13
gem 'sqlite3', '~> 1.4'

# https://github.com/rails/rails/blob/v7.1.2/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L4
gem 'pg', '~> 1.1'

# https://github.com/rails/rails/blob/v7.1.2/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L6
gem 'mysql2', '~> 0.5'
17 changes: 17 additions & 0 deletions rails_7.2.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

source 'https://rubygems.org'

# Specify your gem's dependencies in active_record_union.gemspec
gemspec

gem 'rails', '~> 7.2.0'

# https://github.com/rails/rails/blob/v7.2.0/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L13
gem 'sqlite3', '>= 1.4'

# https://github.com/rails/rails/blob/v7.2.0/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L4
gem 'pg', '~> 1.1'

# https://github.com/rails/rails/blob/v7.2.0/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L6
gem 'mysql2', '~> 0.5'
17 changes: 17 additions & 0 deletions rails_8.0.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

source 'https://rubygems.org'

# Specify your gem's dependencies in active_record_union.gemspec
gemspec

gem 'rails', '~> 8.0.0'

# https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L13
gem 'sqlite3', '>= 2.1'

# https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L4
gem 'pg', '~> 1.1'

# https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L6
gem 'mysql2', '~> 0.5'
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
RSpec.configure do |config|
config.backtrace_inclusion_patterns << %r{gems/([0-9.])+/gems/(?!rspec|capybara)} if ENV['BACKTRACE']
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
Expand Down
33 changes: 28 additions & 5 deletions spec/support/databases.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,47 @@ def connect_to_sqlite

def connect_to_postgres
ActiveRecord::Base.establish_connection(
adapter: "postgresql"
adapter: "postgresql",
host: ENV.fetch('DB_HOST', 'localhost'),
username: ENV.fetch("POSTGRES_USER", 'active_record_union'),
password: ENV.fetch("POSTGRES_PASSWORD", 'active_record_union')
)
ActiveRecord::Base.connection.recreate_database("test_active_record_union")
try_to_drop_database
ActiveRecord::Base.connection.create_database("test_active_record_union")
ActiveRecord::Base.establish_connection(
adapter: "postgresql",
database: "test_active_record_union"
host: ENV.fetch('DB_HOST', 'localhost'),
username: ENV.fetch("POSTGRES_USER", 'active_record_union'),
password: ENV.fetch("POSTGRES_PASSWORD", 'active_record_union'),
database: ENV.fetch("POSTGRES_DB", "test_active_record_union")
)
load("support/models.rb")
end

def try_to_drop_database
ActiveRecord::Base.connection.drop_database("test_active_record_union")
rescue ActiveRecord::NoDatabaseError
$stderr.puts "Can't drop database 'test_active_record_union' as it doesn't exist"
rescue ActiveRecord::ActiveRecordError => e
$stderr.puts "Can't drop database 'test_active_record_union' (but continuing anyway): #{e}"
rescue => e
$stderr.puts "Other error (#{e.class.name}) dropping database 'test_active_record_union' (but continuing anyway): #{e}"
end

def connect_to_mysql
ActiveRecord::Base.establish_connection(
adapter: "mysql2"
adapter: "mysql2",
host: ENV.fetch('DB_HOST', 'localhost'),
username: ENV.fetch("MYSQL_USER", "active_record_union"),
password: ENV.fetch("MYSQL_PASSWORD", "active_record_union")
)
ActiveRecord::Base.connection.recreate_database("test_active_record_union")
ActiveRecord::Base.establish_connection(
adapter: "mysql2",
database: "test_active_record_union"
host: ENV.fetch('DB_HOST', 'localhost'),
username: ENV.fetch("MYSQL_USER", "active_record_union"),
password: ENV.fetch("MYSQL_PASSWORD", "active_record_union"),
database: ENV.fetch("MYSQL_DB", "test_active_record_union")
)
load("support/models.rb")
end
Expand Down
Loading

0 comments on commit 8ebe558

Please sign in to comment.