I have RSpec test suite which passes on my local machine.
However, when I run specs on CircleCI, it fails.
Here are the outputs:
1) Articles GET /articles/:id when article exists when article feedbacked behaves like success response and template behaves like normal request returns 200
Failure/Error: = javascript_pack_tag 'personal_comment/index'
ActionView::Template::Error:
Webpacker can't find personal_comment/index in /home/circleci/project/public/packs-test/manifest.json. Possible causes:
1. You want to set webpacker.yml value of compile to true for your environment
unless you are using the `webpack -w` or the webpack-dev-server.
2. webpack has not yet re-run to reflect updates.
3. You have misconfigured Webpacker's config/webpacker.yml file.
4. Your webpack configuration is not creating a manifest.
Your manifest contains:
{
}
Shared Example Group: "normal request" called from ./spec/support/requests/request_macros.rb:14
Shared Example Group: "success response and template" called from ./spec/requests/articles_spec.rb:19
# ./app/views/articles/feedbacked/show.html.haml:37:in `_app_views_articles_feedbacked_show_html_haml___803483453260433823_47067249050920'
It says our manifest is empty, but as far as I can confirm on my local machine it is not empty.
Here's our config file for CircleCI:
version: 2.1
references:
default_docker_ruby_executor: &default_docker_ruby_executor
image: circleci/ruby:2.6.5-stretch-node
environment:
BUNDLE_JOBS: 3
BUNDLE_RETRY: 3
BUNDLE_PATH: vendor/bundle
PGHOST: 127.0.0.1
PGUSER: root
PGPASSWORD: ""
RAILS_ENV: test
postgres: &postgres
image: circleci/postgres:11.6-alpine
environment:
POSTGRES_USER: root
POSTGRES_DB: app_test
POSTGRES_PASSWORD: ""
jobs:
build:
docker:
- *default_docker_ruby_executor
steps:
- checkout
# bundle cache
- restore_cache:
keys:
- app-bundle-v2-{{ checksum "Gemfile.lock" }}
- app-bundle-v2-
- run:
name: Bundle Install
command: bundle check || bundle install
# Store bundle cache
- save_cache:
key: rewrites-bundle-v2-{{ checksum "Gemfile.lock" }}
paths:
- vendor/bundle
# Only necessary if app uses webpacker or yarn in some other way
- restore_cache:
keys:
- app-yarn-{{ checksum "yarn.lock" }}
- app-yarn-
- run:
name: Yarn Install
command: yarn install --cache-folder ~/.cache/yarn
# Store yarn / webpacker cache
- save_cache:
key: app-yarn-{{ checksum "yarn.lock" }}
paths:
- ~/.cache/yarn
test:
parallelism: 2
docker:
- *default_docker_ruby_executor
- *postgres
steps:
- checkout
- restore_cache:
keys:
- app-bundle-v2-{{ checksum "Gemfile.lock" }}
- app-bundle-v2-
- run:
name: Bundle Install
command: bundle check || bundle install
- restore_cache:
keys:
- rewrites-yarn-{{ checksum "yarn.lock" }}
- rewrites-yarn-
- run:
name: Wait for DB
command: dockerize -wait tcp://localhost:5432 -timeout 1m
- run:
name: Database setup
command: bundle exec rails db:schema:load --trace
# Run rspec in parallel
- run:
command: |
mkdir /tmp/test-results
TESTFILES=$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)
bundle exec rspec $TESTFILES --profile 10 --format RspecJunitFormatter --out /tmp/test-results/rspec.xml --format progress
- store_test_results:
path: /tmp/test-results
- store_artifacts:
path: /tmp/test-results
destination: test-results
workflows:
version: 2
build_and_test:
jobs:
- build
- test:
requires:
- build
I think this is something related to Webpacker, but don't know what to do.
It seems like assets are not being compiled in CircleCI.
You may need to set NODE_ENV=test at the top, and another step to compile assets (which happen automatically in development, by default):
- run:
name: Build assets
command: bundle exec rails assets:precompile
This will run webpacker:compile in addition to some other tasks to configure youur environment correctly. Note, you will need config/webpack/test.js and a test section in config/webpacker.yaml. Looks like this documentation is not recorded here: https://circleci.com/docs/2.0/language-ruby/.
Some helpful links:
https://github.com/rails/webpacker#custom-rails-environments
https://prathamesh.tech/2019/08/26/understanding-webpacker-in-rails-6/
Related
I'm trying to configure a ruby.yml with github-actions but I'm getting this error at Setup database
PG::ConnectionBad: could not translate host name "db" to address: Temporary failure in name resolution
my yml file looks like this
name: CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres
env:
POSTGRES_PASSWORD: postgres
ports: ['5432:5432']
steps:
- uses: actions/checkout#v2
- name: Setup Ruby
uses: ruby/setup-ruby#v1
with:
bundler-cache: true
- name: Install Dependencies
run: |
sudo apt install -yqq libpq-dev
gem install bundler
- name: Install Gems
run: |
bundle install
- name: Setup database
env:
PG_DATABASE: postgres
PG_HOST: localhost
PG_USER: postgres
PG_PASSWORD: password
RAILS_ENV: test
WITH_COVERAGE: true
DISABLE_SPRING: 1
run: |
bundle exec rails db:setup
- name: Run Tests
env:
PGHOST: localhost
PGUSER: postgres
PGPASSWORD: postgres
RAILS_ENV: test
run: |
bundle exec rake test
I tried following this tutorial https://dev.to/buildwithallan/how-to-set-up-a-ci-workflow-using-github-actions-4818 but nothing it still doesn’t work. I'm not sure how I can fix this, would appreciate some help
double check this segment:
env:
PG_DATABASE: postgres
PG_HOST: localhost
PG_USER: postgres
PG_PASSWORD: password
RAILS_ENV: test
WITH_COVERAGE: true
DISABLE_SPRING: 1
check db in your config file. seems github action complaints it can not connect to db
has anyone noticed that new Rails apps seem to fail on circleCI with this error:
Sprockets::Rails::Helper::AssetNotFound in Home#index
The asset "application.js" is not present in the asset pipeline.
steps to reproduce:
rails new --javascript=esbuild so it uses JSBundling with ESbuild
• Install rspec
• configure CircleCI
• add app to your circle CI pipeline.
• Add a basic hello world controller that simply prints "Hello world"
• Add the root route to the hello world controller
• Add a spec:
require 'rails_helper'
describe "can load the homepage" do
it "should load the homepage" do
visit "/"
expect(page).to have_content("Hello world")
end
end
there’s a file in app/assets/config/manifest.js which tells Sprockets where to load assets from. I tried adding this
//= link_directory ../../javascript .js
(notice that the default location of the javascript folder is in app/ not in app/assets)
the app works fine locally and deploys to Heroku just fine, I only see this error on CircleCi. Anyone seen this before?
my CircleCI config looks like this:
version: 2.1 # Use 2.1 to enable using orbs and other features.
# Declare the orbs that we'll use in our config.
# read more about orbs: https://circleci.com/docs/2.0/using-orbs/
orbs:
ruby: circleci/ruby#1.0
node: circleci/node#2
browser-tools: circleci/browser-tools#1.2.3
jobs:
build: # our first job, named "build"
docker:
- image: cimg/ruby:3.1.2-browsers # use a tailored CircleCI docker image.
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
- image: redis:6.2.6
steps:
- checkout # pull down our git code.
- ruby/install-deps # use the ruby orb to install dependencies
# use the node orb to install our packages
# specifying that we use `yarn` and to cache dependencies with `yarn.lock`
# learn more: https://circleci.com/docs/2.0/caching/
- node/install-packages:
pkg-manager: yarn
cache-key: "yarn.lock"
- run:
name: Build assets
command: bundle exec rails assets:precompile
test: # our next job, called "test"
parallelism: 1
# here we set TWO docker images.
docker:
- image: cimg/ruby:3.1.2-browsers # this is our primary docker image, where step commands run.
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
- image: redis:6.2.6
- image: circleci/postgres:9.5-alpine
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
environment: # add POSTGRES environment variables.
POSTGRES_USER: circleci-demo-ruby
POSTGRES_DB: VDQApp_test
POSTGRES_PASSWORD: ""
# environment variables specific to Ruby/Rails, applied to the primary container.
environment:
BUNDLE_JOBS: "3"
BUNDLE_RETRY: "3"
PGHOST: 127.0.0.1
PGUSER: circleci-demo-ruby
PGPASSWORD: ""
RAILS_ENV: test
# A series of steps to run, some are similar to those in "build".
steps:
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- checkout
- ruby/install-deps
- node/install-packages:
pkg-manager: yarn
cache-key: "yarn.lock"
# Here we make sure that the secondary container boots
# up before we run operations on the database.
- run:
name: Wait for DB
command: dockerize -wait tcp://localhost:5432 -timeout 1m
- run:
name: Load schema
command: bin/rails db:schema:load RAILS_ENV=test
# Run rspec in parallel
- ruby/rspec-test
# We use workflows to orchestrate the jobs that we declared above.
workflows:
version: 2
build_and_test: # The name of our workflow is "build_and_test"
jobs: # The list of jobs we run as part of this workflow.
- build # Run build first.
- test: # Then run test,
requires: # Test requires that build passes for it to run.
- build # Finally, run the build job.
Ok I figured this out.
The Circle CI config must told to execute the esbuild, whih is done like so:
esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets
that command lives in your yarn package script, so you can run it as yarn build
In the .circleci/config file, look for the jobs > test > steps stanza
You will want to add this step for yarn build after the step for node/install-packages
- run:
name: Yarn build
command: yarn build
steps:
- browser-tools/install-chrome
- browser-tools/install-chromedriver
- checkout
- ruby/install-deps
- node/install-packages:
pkg-manager: yarn
cache-key: "yarn.lock"
- run:
name: yarn build
command: yarn build
# Here we make sure that the secondary container boots
# up before we run operations on the database.
- run:
name: Wait for DB
command: dockerize -wait tcp://localhost:5432 -timeout 1m
- run:
name: Load schema
command: bin/rails db:schema:load RAILS_ENV=test
# Run rspec in parallel
- ruby/rspec-test
Since multiple databases is still a relatively fresh topic on Rails I wasn't able to find good resources on how to integrate them with my github actions. As long as I had single database in my app those configs we correct:
name: CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:11
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: root
POSTGRES_DB: db_test
ports: ['5432:5432']
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout#v1
- name: Set up Ruby 2.6
uses: actions/setup-ruby#v1
with:
ruby-version: 2.6.x
- name: Build and test with Rake
env:
PGHOST: 127.0.0.1
PGUSER: postgres
PGPASSWORD: root
RAILS_ENV: test
run: |
sudo apt-get -yqq install libpq-dev
gem install bundler
bundle install --jobs 4 --retry 3
bundle exec rake db:test:prepare
bundle exec rails test
However after implementing a second db I got this error:
TypeError: no implicit conversion of nil into String
/opt/hostedtoolcache/Ruby/2.6.6/x64/bin/bundle:23:in load' /opt/hostedtoolcache/Ruby/2.6.6/x64/bin/bundle:23:in ' Tasks:
TOP => db:test:load => db:test:purge (See full trace by running task
with --trace) Error: Process completed with exit code 1.
I'm almost 100% positive that this error is related to the lack of credentials for the second db in my github action file. How can I fix it and include both my dbs there?
I'm in a problem right now and don't know how to solve this in Github Actions context.
Side context: I'm following a tutorial on setting up Rails-Postgres with GH actions for CI.
Normally when I run into this problem in dev environment, I'd delete a postmaster.pid file. But here, because I'm in a test environment in GH actions, I'm not sure how to solve it. I tried already doing how I would do it in dev env, it unfortunately did not work.
The solutions I've tried:
rm /usr/local/var/postgres/postmaster.pid
Changing the ports within postgres entry in the workflow
My GH Actions Workflow:
name: Test
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:12.1
ports:
- 6543:6543
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- name: Checkout repository
uses: actions/checkout#v2
- name: Install Ruby version specified in `.ruby-version`
uses: eregon/use-ruby-action#master
- name: Install required apt packages
run: |
sudo apt-get -y install libpq-dev
- name: Setup cache key and directory for gems cache
uses: actions/cache#v1
with:
path: vendor/bundle
key: ${{ runner.os }}-gem-use-ruby-${{ hashFiles('**/Gemfile.lock') }}
- name: Read Node.js version to install from `.nvmrc`
run: echo "##[set-output name=NVMRC;]$(cat .nvmrc)"
id: nvm
- name: Install required Node.js version
uses: actions/setup-node#v1
with:
node-version: "${{ steps.nvm.outputs.NVMRC }}"
- name: Get Yarn cache directory path
id: yarn-cache
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Setup cache key and directory for node_modules cache
uses: actions/cache#v1
with:
path: ${{ steps.yarn-cache.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- name: Bundle install
run: |
gem install bundler -v2.1.4
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- name: Yarn install
run: yarn --frozen-lockfile
- name: Run RSpec // ERRORS HERE
run: |
RUBYOPT='-W:no-deprecated -W:no-experimental' bundle exec rails db:prepare
RUBYOPT='-W:no-deprecated -W:no-experimental' bundle exec rspec
It breaks on the Run RSpec task.
Error message:
PG::ConnectionBad: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
Thanks for your help everyone😁
Found a fix!
I needed to add the host, username, and password entry in config/database.yml for the test DB
Because you specified the port for 6543, so PostgreSQL cannot find its default port 5432.
To fix this, specify the port under
services:
postgres:
ports:
- 5432/tcp
When I run CircleCI, the first few tests fail due to Elasticsearch not being fully set up yet.
Usually I would use the dockerize library to wait for Elasticsearch to be finished, however this does not seem to detect Elasticsearch. Any ideas why? The dockerize command simply times out. However, the Elasticsearch container seems to be running because if I do not wait, eventually Elasticsearch starts to work with the tests.
Here is my docker file
version: 2
jobs:
build:
parallelism: 3
working_directory: ~/export-opportunities
docker:
- image: circleci/ruby:2.5.5-node
environment:
BUNDLE_JOBS: 3
BUNDLE_RETRY: 3
BUNDLE_PATH: vendor/bundle
PGHOST: localhost
PGUSER: user
RAILS_ENV: test
- image: circleci/postgres:latest
environment:
POSTGRES_USER: user
POSTGRES_DB: circle_test
POSTGRES_PASSWORD: $POSTGRES_PASSWORD
- image: circleci/redis:4.0.9
environment:
REDIS_URL: "redis://localhost:6379/"
- image: docker.elastic.co/elasticsearch/elasticsearch:6.3.2
environment:
cluster.name: elasticsearch
xpack.security.enabled: false
transport.host: localhost
network.host: 127.0.0.1
http.port: 9200
discovery.type: single-node
branches:
only: chore/XOT-597-circleci
steps:
- checkout # check out the code in the project directory
# restore bundle cache
- restore_cache:
keys:
- exops-{{ checksum "Gemfile.lock" }}
- run:
name: Bundle Install
command: bundle check || bundle install
# store bundle cache
- save_cache:
key: exops-{{ checksum "Gemfile.lock" }}
paths:
- vendor/bundle
# Database setup
- run:
name: install dockerize
command: wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && sudo tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
environment:
DOCKERIZE_VERSION: v0.3.0
- run:
name: Wait for DB
command: dockerize -wait tcp://localhost:5432 -timeout 1m
- run:
name: Database setup
command: |
bundle exec rake db:create
bundle exec rake db:migrate
# Redis setup
- run:
name: Wait for Redis
command: dockerize -wait tcp://localhost:6379 -timeout 1m
# DOES NOT WORK:
- run:
name: Wait for Elasticsearch
command: dockerize -wait http://localhost:9200 -timeout 2m
# Run rspec in parallel
- run: |
echo Running test ...
bundle exec rspec --profile 10 \
--format RspecJunitFormatter \
--out test_results/rspec.xml \
--format progress \
$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)
# Save test results for timing analysis
- store_test_results:
path: test_results
Note I've also tried dockerize -wait tcp://localhost:9200 -timeout 2m, and dockerize -wait http://127.0.0.1:9200 -timeout 2m, and dockerize -wait tcp://127.0.0.1:9200 -timeout 2m to no effect.
I tried adding sleep 10 and sleep 100 however the issue persisted.
The issue was that the tests were running before the index was created. The index creation was being triggered by the first test to run, but took a few seconds, so the first few tests always failed.
My solution with this was to add the following code to trigger building the index, if not present, in rails_helper.rb which runs on starting the rails environment. For most other environments, the indices do exist so it does not slow down other processes.
# Build initial indices if not present, e.g. CircleCI
[Opportunity, Subscription].each do |model|
unless model.__elasticsearch__.index_exists? index: model.__elasticsearch__.index_name
model.__elasticsearch__.create_index!(force: true)
sleep 2
end
end