I keep getting errors with RSpec on Github Actions. Not sure what's going on.
I'm on Rails 7 and Ruby 3.
Locally Rspec runs fine. I'm new to Github actions and have been fumbling around with it for a few hours now. It seems like an environment issue where Rails isn't loaded correctly but I'm not sure where the problem could be. Does anyone have a working Github actions example with Rails 7, Ruby 3 and RSpec?
Here's my github actions config:
# This workflow uses actions that are not certified by GitHub. They are
# provided by a third-party and are governed by separate terms of service,
# privacy policy, and support documentation.
#
# This workflow will install a prebuilt Ruby version, install dependencies, and
# run tests and linters.
name: "Ruby on Rails CI"
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:14-alpine
ports:
- "5432:5432"
env:
POSTGRES_DB: starter_rails_api_test
POSTGRES_USER: rails
POSTGRES_PASSWORD: password
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
RAILS_ENV: test
DATABASE_URL: "postgres://rails:password#localhost:5432/starter_rails_api_test"
steps:
- name: Checkout code
uses: actions/checkout#v3
# Add or replace dependency steps here
- name: Install Ruby and gems
uses: ruby/setup-ruby#v1
with:
bundler: default
# bundler-cache: true
- name: Install gems
run: bin/bundle install
# Add or replace database setup steps here
- name: Create database tables
run: bin/rails db:create
- name: Set up database schema
run: bin/rails db:schema:load
# Add or replace test runners here
- name: Run tests
run: bin/bundle exec rspec spec
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout#v3
- name: Install Ruby and gems
uses: ruby/setup-ruby#v1
with:
bundler-cache: true
# Add or replace any other lints here
# - name: Security audit dependencies
# run: bin/bundler-audit --update
# - name: Security audit application code
# run: bin/brakeman -q -w2
- name: Lint Ruby files
run: bin/bundle exec rubocop --parallel
Output:
Run bin/bundle exec rspec spec
An error occurred while loading ./spec/models/widget_spec.rb.
Failure/Error: rescue_from ActiveModel::ValidationError, with: ->(e) { handle_validation_error(e) }
NameError:
uninitialized constant ActiveModel::ValidationError
rescue_from ActiveModel::ValidationError, with: ->(e) { handle_validation_error(e) }
^^^^^^^^^^^^^^^^^
Did you mean? ActiveModel::Validator
# ./app/controllers/application_controller.rb:21:in `<class:ApplicationController>'
# ./app/controllers/application_controller.rb:3:in `<top (required)>'
# ./config/environment.rb:7:in `<top (required)>'
# ./spec/rails_helper.rb:5:in `require'
# ./spec/rails_helper.rb:5:in `<top (required)>'
# ./spec/models/widget_spec.rb:3:in `require'
# ./spec/models/widget_spec.rb:3:in `<top (required)>'
An error occurred while loading ./spec/requests/api/v1/widgets_spec.rb.
Failure/Error: require File.expand_path('../config/environment', __dir__)
FrozenError:
can't modify frozen Array: ["/home/runner/work/starter-rails-api/starter-rails-api/app/controllers", "/home/runner/work/starter-rails-api/starter-rails-api/app/controllers/concerns", "/home/runner/work/starter-rails-api/starter-rails-api/app/lib", "/home/runner/work/starter-rails-api/starter-rails-api/app/models", "/home/runner/work/starter-rails-api/starter-rails-api/app/models/concerns", "/home/runner/work/starter-rails-api/starter-rails-api/app/serializers"]
# ./config/environment.rb:7:in `<top (required)>'
# ./spec/rails_helper.rb:5:in `<top (required)>'
# ./spec/requests/api/v1/widgets_spec.rb:3:in `<top (required)>'
An error occurred while loading ./spec/routing/api/v1/widgets_routing_spec.rb.
Failure/Error: require File.expand_path('../config/environment', __dir__)
FrozenError:
can't modify frozen Array: ["/home/runner/work/starter-rails-api/starter-rails-api/app/controllers", "/home/runner/work/starter-rails-api/starter-rails-api/app/controllers/concerns", "/home/runner/work/starter-rails-api/starter-rails-api/app/lib", "/home/runner/work/starter-rails-api/starter-rails-api/app/models", "/home/runner/work/starter-rails-api/starter-rails-api/app/models/concerns", "/home/runner/work/starter-rails-api/starter-rails-api/app/serializers"]
# ./config/environment.rb:7:in `<top (required)>'
# ./spec/rails_helper.rb:5:in `<top (required)>'
# ./spec/routing/api/v1/widgets_routing_spec.rb:3:in `<top (required)>'
Finished in 0.00006 seconds (files took 1.3 seconds to load)
0 examples, 0 failures, 3 errors occurred outside of examples
Error: Process completed with exit code 1.
Fiddled around a lot with the github actions config. No luck. Always getting errors.
Turned out to be a Rails issue not Github actions. Weird that it only happens on linux and not on osx.
Fixed it by adding require 'active_model/validations' to my application_controller.rb file. Not sure why it's not already required automatically.
If anyone can shed some light on this I'd appreciate it.
For reference this is where the class is defined:
https://github.com/rails/rails/blob/8015c2c2cf5c8718449677570f372ceb01318a32/activemodel/lib/active_model/validations.rb#L425
Related
For a Rails app, I have a gitlab CI/CD set up with three stages. First stage is caching of gems and assets.
cache: &default-cache
untracked: true
key: "assets-compile:vendor_ruby:.yarn-cache:tmp_cache_assets_sprockets:v3"
paths:
- vendor/ruby/
- .yarn-cache/
- public/assets/
- node_modules/
policy: pull-push
In the next stage, I pull from the cached gems in vendor/ruby folder.
testing:
cache:
<<: *default-cache
policy: pull
stage: test
image: "ruby:3.0"
timeout: one hour
script:
- apt-get update -qq && apt-get install -y -qq nodejs
- export PATH="/usr/local/bundle/bin:$PATH"
- bundle config set --local path 'vendor/ruby'
- RAILS_ENV=test bundle install -j $(nproc)
This works well, but for a gem 'ox', throws a LoadError
Failure/Error: require 'ox'
LoadError:
cannot load such file -- ox/ox
# ./vendor/ruby/ruby/3.0.0/gems/zeitwerk-2.6.6/lib/zeitwerk/kernel.rb:38:in `require'
# ./vendor/ruby/ruby/3.0.0/gems/zeitwerk-2.6.6/lib/zeitwerk/kernel.rb:38:in `require'
# ./vendor/ruby/ruby/3.0.0/gems/ox-2.14.11/lib/ox.rb:79:in `<top (required)>'
My understanding is that it is unable to load ox.rb which would be created after the C extension is compiled, which is not happening during caching.
How do I solve this?
I tried removing require: false from the Gemfile, but didn't work.
My rails 4 app uses postgis with the activerecord-postgis-adapter. I'm attempting to use Heroku CI. The ci run fails when it is loading the database structure when it reaches a geometry column description in the schema.rb file.
-----> Preparing test database
Running: rake db:schema:load_if_ruby
The PGconn, PGresult, and PGError constants are deprecated, and will be
removed as of version 1.0.
You should use PG::Connection, PG::Result, and PG::Error instead, respectively.
Called from /app/vendor/bundle/ruby/2.5.0/gems/activesupport-4.2.11.1/lib/active_support/dependencies.rb:240:in `load_dependency'
rake aborted!
NoMethodError: undefined method `geometry' for #<ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition:0x000055bd614ea1a0>
/app/db/schema.rb:105:in `block (2 levels) in <top (required)>'
/app/vendor/bundle/ruby/2.5.0/gems/activerecord-4.2.11.1/lib/active_record/connection_adapters/abstract/schema_statements.rb:216:in `create_table'
...
My database.yml file specifies the postgis adapter for all environments, so I'm surprised to see it using the postgresql adapter.
Any suggestions?
I previously recorded the database schema in sql. I found a suggestion on the heroku site to switch to ruby. That didn't help.
The tests run fine locally.
I think this is just an issue with HerokuCI. A workaround is to overwrite the DATABASE_URL to specify postgis. Below are two different ways to accomplish that:
Add a .profile file (documented here) in your project root with the following contents:
export DATABASE_URL=`echo $DATABASE_URL | sed s/postgres/postgis/g`
OR Update the test command in your app.json:
{
"environments": {
"test": {
"scripts": {
"test": "export DATABASE_URL=`echo $DATABASE_URL | sed s/postgres/postgis/g`; <other test commands here>",
...
So, for example: if the DATABASE_URL was postgres://foo:bar#example:5432/my-app, that would update it to postgis://foo:bar#example:5432/my-app before any of the relevant commands are invoked.
Im trying to set up my app to run in production mode and Ive hit a problem with building the assets folder specifically this line in my Dockerfile:
RUN bundle exec rake RAILS_ENV=production DATABASE_URL=postgresql://user:pass#127.0.0.1/dbname SECRET_TOKEN=dummytoken assets:precompile
The database is just a dummy line. The problem is when it runs the rake it seems to not see the env variables and I get the following errors when it goes to initialize carrierwave.rb
rake aborted!
ArgumentError: Missing required arguments: aws_access_key_id, aws_secret_access_key
/usr/local/bundle/gems/fog-core-1.42.0/lib/fog/core/service.rb:244:in `validate_options'
/usr/local/bundle/gems/fog-core-1.42.0/lib/fog/core/service.rb:268:in `handle_settings'
/usr/local/bundle/gems/fog-core-1.42.0/lib/fog/core/service.rb:98:in `new'
/usr/local/bundle/gems/fog-core-1.42.0/lib/fog/core/services_mixin.rb:16:in `new'
/usr/local/bundle/gems/fog-core-1.42.0/lib/fog/storage.rb:27:in `new'
/usr/local/bundle/gems/carrierwave-0.11.2/lib/carrierwave/uploader/configuration.rb:83:in `eager_load_fog'
/usr/local/bundle/gems/carrierwave-0.11.2/lib/carrierwave/uploader/configuration.rb:96:in `fog_credentials='
/mnt/hgfs/Projects/livingrecipe/config/initializers/carrierwave.rb:3:in `block in <top (required)>'
/usr/local/bundle/gems/carrierwave-0.11.2/lib/carrierwave/uploader/configuration.rb:118:in `configure'
/usr/local/bundle/gems/carrierwave-0.11.2/lib/carrierwave.rb:14:in `configure'
/mnt/hgfs/Projects/livingrecipe/config/initializers/carrierwave.rb:1:in `<top (required)>'
Theres a few more lines to the error but the first line says it all and the ENV variables for the aws_access_key_id and aws_secret_access_key dont seem to load up. If I run this without trying to precompile the assets everything works but I need to precompile the assets to make them visible to nginx
I did find that for a fix I could replace the ENV variables with what they are, this is the code that is having the trouble:
CarrierWave.configure do |config|
config.fog_credentials = {
provider: 'AWS', # required
aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'], # required
aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'], # required
region: 'us-west-2' # optional, defaults to 'us-east-1'
}
config.fog_directory = ENV['S3_BUCKET_NAME'] # required
#config.fog_host = 'https://assets.example.com' # optional, defaults to nil
#config.fog_public = false # optional, defaults to true
config.fog_attributes = {'Cache-Control'=>'max-age=315576000'} # optional, defaults to {}
end
So I got it to work with just typing in the keys...but obviously that isnt a good solution long term to have the keys programmed in.
Your question has shifted a bit, so I'm going to address your last sentence:
So I got it to work with just typing in the keys...but obviously that isn't a good solution long term to have the keys programmed in.
If you're sure you want to handle this during your build, as opposed to adding your rake task to your command entry, you can set build args in your docker-compose.yml config file.
# compose.yml
version: '2'
services:
app:
# ...
build:
context: .
args:
# This will make your variables available during the
# "build" phase.
# You can hardcode these values here, or better,
# add them to a .env file, whose contents
# Docker/Compose will make available during the build.
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- DATABASE_URL
- SECRET_TOKEN
environment:
# You should also add these values to your application's
# environment.
# You can hardcode these values here, or better,
# add them to a .env file, whose contents
# Docker/Compose will make available to your running container.
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- DATABASE_URL
- SECRET_TOKEN
You can then declare and use the build args in your Dockerfile:
# Dockerfile
# ...
ARG AWS_ACCESS_KEY_ID
ARG AWS_SECRET_ACCESS_KEY
ARG DATABASE_URL
ARG SECRET_TOKEN
# these values will now be available to your rake task
# in ENV['AWS_ACCESS_KEY_ID'], etc.
RUN bundle exec rake RAILS_ENV=production assets:precompile
I clone rails app (our company project) and then install everything that related to mongo db and mongoid gem. Then I run the rake db:setup and then rails s. Its working fine, I can access all the sites and do everything. But I got problem in the rails console.
Whenever I do this:
rails c
then
User.first
I will get this error
Loading development environment (Rails 4.1.1) irb(main):001:0>
User.first Mongoid::Errors::NoSessionConfig: Problem: No
configuration could be found for a session named 'default'. Summary:
When attempting to create the new session, Mongoid could not find a
session configuration for the name: 'default'. This is necessary in
order to know the host, port, and options needed to connect.
Resolution: Double check your mongoid.yml to make sure under the
sessions key that a configuration exists for 'default'. If you have
set the configuration programatically, ensure that 'default' exists in
the configuration hash. from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mongoid-4.0.0.beta2/lib/mongoid/sessions/factory.rb:27:in
create' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mongoid-4.0.0.beta2/lib/mongoid/sessions.rb:65:in
with_name' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mongoid-4.0.0.beta2/lib/mongoid/sessions.rb:105:in
mongo_session' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mongoid-4.0.0.beta2/lib/mongoid/sessions.rb:121:in
collection' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mongoid-4.0.0.beta2/lib/mongoid/sessions/options.rb:161:in
method_missing' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mongoid-4.0.0.beta2/lib/mongoid/contextual/mongo.rb:263:in
initialize' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mongoid-4.0.0.beta2/lib/mongoid/contextual.rb:53:in
new' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mongoid-4.0.0.beta2/lib/mongoid/contextual.rb:53:in
create_context' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mongoid-4.0.0.beta2/lib/mongoid/contextual.rb:35:in
context' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mongoid-4.0.0.beta2/lib/mongoid/contextual.rb:20:in
first' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/mongoid-4.0.0.beta2/lib/mongoid/findable.rb:122:in
first' from (irb):1 from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/railties-4.1.1/lib/rails/commands/console.rb:90:in
start' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/railties-4.1.1/lib/rails/commands/console.rb:9:in
start' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/railties-4.1.1/lib/rails/commands/commands_tasks.rb:69:in
console' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/railties-4.1.1/lib/rails/commands/commands_tasks.rb:40:in
run_command!' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/railties-4.1.1/lib/rails/commands.rb:17:in
' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:247:in require' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:247:inblock in require' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:232:in load_dependency' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:247:inrequire' from
/Users/rizalmuthi/Documents/Sites/WORK/tapway/bin/rails:8:in <top
(required)>' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:241:inload' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:241:in block in load' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:232:inload_dependency' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:241:in load' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in
require' from
/Users/rizalmuthi/.rbenv/versions/2.1.1/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in
require' from -e:1:in'irb(main):002:0>
And FYI, this is the mongoid.yml that I generated by run
rails g mongoid:config
mongoid.yml
development:
sessions:
default:
database: mongo_demo_development
hosts:
- localhost:27017
options:
options:
test:
sessions:
default:
database: mongo_demo_test
hosts:
- localhost:27017
options:
consistency: :strong
max_retries: 1
retry_interval: 0
I have been looking all over google and some blogs, could not figure it out how to fix this.
Besides that, we dont use the Rspec tho.
change your config/application.rb file:
replace it Bundler.require(*Rails.groups)
to it Bundler.require(*Rails.groups(assets: %w(development test)))
In the latest mongoid -5.0.0 version you can simply solve by placing the below code in application.rb
config.generators do |g|
g.orm :mongoid
end
In config/application.rb change
Bundler.require(*Rails.groups)
to:
Bundler.require(:default, Rails.env)
Rails is trying to eager load the group of gems by environment and the stock config/mongoid.yml file you get when you run rails g mongoid:config only gives you a test and development namespace. Even though you're only running development, it's looking at all the groups. If you add the production namespace to the yml file it will load but my answer above works without you needing to do that.
Just make sure that on application initialization you do the following (in Rails console)
Mongoid.load!("path/to/your/mongoid.yml")
For more details visit http://mongoid.org/en/mongoid/docs/installation.html
With MongoId version 5.x, You will change config in Rails application follow:
File: application.rb
# Add line.
config.generators do |g|
g.orm :mongoid
end
I was set it and it working in rails console.
See more at:
https://docs.mongodb.com/ecosystem/tutorial/mongoid-installation/#rails-applications
may be The problem is in the gem file, you did't mention the version of mongoid gem.
in gem file change
gem "mongoid"
to
gem "mongoid" , '~> 4.0.2'
and run bundle install
restart server and console.
I've set up Faye on localhost, and works fine.
I'm now trying to deploy it on DigitalOcean VPS, with Cloud66 deployment service.
To run the command I use an "after_rails" hook.
rackup $RAILS_STACK_PATH/faye.ru -s thin -E production
This gives me the error:
Error during deployment: Error during after_rails hook: Server: not_specified. Failed to run command: /usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in require': cannot load such file -- faye (LoadError) from /usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:inrequire' from /var/deploy/anabol/web_head/current/faye.ru:1:in block in <main>' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/builder.rb:55:ininstance_eval' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/builder.rb:55:in initialize' from /var/deploy/anabol/web_head/current/faye.ru:innew' from /var/deploy/anabol/web_head/current/faye.ru:in <main>' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/builder.rb:49:ineval' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/builder.rb:49:in new_from_string' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/builder.rb:40:inparse_file' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/server.rb:277:in build_app_and_options_from_config' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/server.rb:199:inapp' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/server.rb:314:in wrapped_app' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/server.rb:250:instart' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/server.rb:141:in start' from /usr/local/lib/ruby/gems/1.9.1/gems/rack-1.5.2/bin/rackup:4:in' from /usr/local/bin/rackup:23:in load' from /usr/local/bin/rackup:23:in'
github repo:
https://github.com/gwuix2/anabol
Any suggestions what could be the problem? Don't know where to start.
I've written up some documentation on how to solve this problem in case anyone else runs into it. You can find it here: http://community.cloud66.com/articles/faye-on-cloud-66
Disclaimer: I work for Cloud 66.
Cloud 66 Support solved my problem:
Hi there,
We run faye on our own stack. We actually run it behind thin - and monitor it as a process on the stack. The way we do this is with four files - see their details below:
1) RAILS_ROOT/.cloud66/deploy_hooks.yml
production:
before_rails:
- source: /.cloud66/files/add_thin_and_faye.sh
destination: ~/add_thin_and_faye.sh
target: rails
execute: true
sudo: true
apply_during: build_only
run_on: all_servers
2) RAILS_ROOT/.cloud66/files/add_thin_and_faye.sh
#!/bin/bash
sudo gem install thin --no-ri --no-rdoc
sudo gem install faye --no-ri --no-rdoc
3) RAILS_ROOT/Procfile
faye: thin -R $RAILS_STACK_PATH/faye/config.ru start
4) RAILS_ROOT/faye/config.ru
require 'faye'
faye_server = Faye::RackAdapter.new(:mount => '/your_faye_mount', :timeout => 45)
Faye::WebSocket.load_adapter('thin')
faye_server.listen(<<PUT-YOUR-PORT-HERE>>)
Note that for part 4) the settings will be different based on your requirements of course.
If you follow the setup above, you'll have faye running alongside your stack, and it will be available as a process on your stack.