diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..784408b0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,32 @@ +.git +.dockerignore +.env +.vscode +node_modules/ +bundle/ +tmp/ +.env* +environment/artifacts + +.bundle +.env +.env.* +.git +.gitattributes +.gitignore +.github +public/system +public/assets +public/packs +node_modules +neo4j +vendor/bundle +.DS_Store +*.swp +*~ +postgres +postgres14 +redis +elasticsearch +chart +docker-compose* \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0764d7d7..d92443d8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,10 +11,10 @@ jobs: services: postgres: - image: postgres:11.7-alpine + image: postgres:13.7-alpine env: - POSTGRES_USER: outpost - POSTGRES_PASSWORD: password + POSTGRES_USER: outpost_test + POSTGRES_PASSWORD: outpost_test POSTGRES_DB: outpost_test ports: - 5432:5432 @@ -61,7 +61,9 @@ jobs: - name: Setup database env: RAILS_ENV: test + SECRET_TOKEN: ${{ secrets.SECRET_TOKEN }} DB_URI: mongodb://root:password@localhost:27017/outpost_development?authSource=admin + DATABASE_URL: postgresql://outpost_test:outpost_test@localhost:5432/outpost_test?timeout=5000 run: | bundle exec rails db:drop bundle exec rails db:create @@ -70,6 +72,8 @@ jobs: - name: Compile assets env: RAILS_ENV: test + SECRET_TOKEN: ${{ secrets.SECRET_TOKEN }} + DATABASE_URL: postgresql://outpost_test:outpost_test@localhost:5432/outpost_test?timeout=5000 run: | bundle exec rails assets:precompile @@ -78,6 +82,8 @@ jobs: RAILS_ENV: test GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} OFSTED_FEED_API_ENDPOINT: https://test-ofsted-feed.stub # this is not a real url, we just need an env variable set for the stub to work in tests + SECRET_TOKEN: ${{ secrets.SECRET_TOKEN }} + DATABASE_URL: postgresql://outpost_test:outpost_test@localhost:5432/outpost_test?timeout=5000 run: | bundle exec rspec diff --git a/.gitignore b/.gitignore index fddabc3f..5d22a410 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,7 @@ yarn-debug.log* .DS_Store yarn.lock -.vscode \ No newline at end of file +.vscode + +/environment/artifacts +.env* diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..16372996 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,89 @@ +# using docker image layers to save waiting for things to rebuild all the time +# base_image > build_rails > build_frontend > development + +FROM ruby:3.0.5-alpine as base_image +RUN apk add --no-cache git \ + build-base \ + libpq-dev \ + tzdata \ + gcompat \ + python3 + +# gcompat is for nokogiri - alpine doesnt include glibc it needs https://nokogiri.org/tutorials/installing_nokogiri.html#linux-musl-error-loading-shared-library +# python2 for node-sass drama + +# install node v16 +# see here for reference https://github.com/timbru31/docker-ruby-node/blob/master/3.0/16/alpine/Dockerfile +RUN apk -U upgrade \ + && apk add --repository https://dl-cdn.alpinelinux.org/alpine/v3.16/main/ --no-cache \ + "nodejs<18" \ + && apk add --no-cache \ + npm \ + yarn + +# install various gems +FROM base_image as build_app +COPY ./Gemfile /tmp/Gemfile +COPY ./Gemfile.lock /tmp/Gemfile.lock +COPY ./package.json /tmp/package.json +COPY ./yarn.lock /tmp/yarn.lock + +RUN cd /tmp && \ + bundle install && \ + yarn install && \ + apk add --no-cache git + + + +WORKDIR /app + +FROM build_app as base_env +COPY --from=build_app /tmp . + + +# build and install all the things for the development env +FROM base_env as development +COPY ./environment/docker-run-development.sh /rdebug_ide/runner.sh +RUN gem install ruby-debug-ide && \ + chmod +x /rdebug_ide/runner.sh + +ENV RAILS_ENV="development" \ + NODE_ENV="development" \ + RAILS_SERVE_STATIC_FILES="false" +EXPOSE 3000 +# ENTRYPOINT ["tail", "-f", "/dev/null"] +CMD ["/rdebug_ide/runner.sh"] +# CMD bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -u puma -p 3000 -b '0.0.0.0'" +# ENTRYPOINT ["tail", "-f", "/dev/null"] + + +FROM base_env as test +COPY ./environment/docker-run-production.sh /runner/runner.sh +COPY . . +RUN chmod +x /runner/runner.sh +RUN bundle exec rails assets:precompile +EXPOSE 3000 +ENV RAILS_ENV="test" \ + NODE_ENV="test" \ + RAILS_SERVE_STATIC_FILES="true" +CMD ["/runner/runner.sh"] + +# build and install all the things for the production env +FROM base_env as production +COPY ./environment/docker-run-production.sh /runner/runner.sh +COPY . . +RUN chmod +x /runner/runner.sh +EXPOSE 3000 + +ENV RAILS_ENV="production" \ + NODE_ENV="production" \ + RAILS_SERVE_STATIC_FILES="true" + +# ENTRYPOINT ["/usr/bin/tini", "--"] +CMD ["/runner/runner.sh"] +# ENTRYPOINT ["/usr/bin/tini", "--"] +# CMD bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -u puma -p 3000 -b '0.0.0.0'" +# ENTRYPOINT ['./environment/docker-run-production.sh'] +# CMD ["rails", "s", "-p", "3000"] +# ENTRYPOINT ["tail", "-f", "/dev/null"] + diff --git a/Gemfile.lock b/Gemfile.lock index 9932b3f2..c818fbb8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,81 +1,81 @@ GEM remote: https://rubygems.org/ specs: - actioncable (6.0.3.6) - actionpack (= 6.0.3.6) + actioncable (6.0.6.1) + actionpack (= 6.0.6.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.0.3.6) - actionpack (= 6.0.3.6) - activejob (= 6.0.3.6) - activerecord (= 6.0.3.6) - activestorage (= 6.0.3.6) - activesupport (= 6.0.3.6) + actionmailbox (6.0.6.1) + actionpack (= 6.0.6.1) + activejob (= 6.0.6.1) + activerecord (= 6.0.6.1) + activestorage (= 6.0.6.1) + activesupport (= 6.0.6.1) mail (>= 2.7.1) - actionmailer (6.0.3.6) - actionpack (= 6.0.3.6) - actionview (= 6.0.3.6) - activejob (= 6.0.3.6) + actionmailer (6.0.6.1) + actionpack (= 6.0.6.1) + actionview (= 6.0.6.1) + activejob (= 6.0.6.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.0.3.6) - actionview (= 6.0.3.6) - activesupport (= 6.0.3.6) + actionpack (6.0.6.1) + actionview (= 6.0.6.1) + activesupport (= 6.0.6.1) rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.0.3.6) - actionpack (= 6.0.3.6) - activerecord (= 6.0.3.6) - activestorage (= 6.0.3.6) - activesupport (= 6.0.3.6) + actiontext (6.0.6.1) + actionpack (= 6.0.6.1) + activerecord (= 6.0.6.1) + activestorage (= 6.0.6.1) + activesupport (= 6.0.6.1) nokogiri (>= 1.8.5) - actionview (6.0.3.6) - activesupport (= 6.0.3.6) + actionview (6.0.6.1) + activesupport (= 6.0.6.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - active_model_serializers (0.10.10) - actionpack (>= 4.1, < 6.1) - activemodel (>= 4.1, < 6.1) + active_model_serializers (0.10.13) + actionpack (>= 4.1, < 7.1) + activemodel (>= 4.1, < 7.1) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) - activejob (6.0.3.6) - activesupport (= 6.0.3.6) + activejob (6.0.6.1) + activesupport (= 6.0.6.1) globalid (>= 0.3.6) - activemodel (6.0.3.6) - activesupport (= 6.0.3.6) - activerecord (6.0.3.6) - activemodel (= 6.0.3.6) - activesupport (= 6.0.3.6) - activestorage (6.0.3.6) - actionpack (= 6.0.3.6) - activejob (= 6.0.3.6) - activerecord (= 6.0.3.6) - marcel (~> 1.0.0) - activesupport (6.0.3.6) + activemodel (6.0.6.1) + activesupport (= 6.0.6.1) + activerecord (6.0.6.1) + activemodel (= 6.0.6.1) + activesupport (= 6.0.6.1) + activestorage (6.0.6.1) + actionpack (= 6.0.6.1) + activejob (= 6.0.6.1) + activerecord (= 6.0.6.1) + marcel (~> 1.0) + activesupport (6.0.6.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) zeitwerk (~> 2.2, >= 2.2.2) - acts-as-taggable-on (8.1.0) - activerecord (>= 5.0, < 6.2) - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) - bcrypt (3.1.16) + acts-as-taggable-on (9.0.1) + activerecord (>= 6.0, < 7.1) + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) + bcrypt (3.1.18) bindex (0.8.1) - bootsnap (1.11.1) + bootsnap (1.16.0) msgpack (~> 1.2) - bson (4.9.2) + bson (4.15.0) builder (3.2.4) - bullet (6.1.0) + bullet (7.0.7) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) - byebug (11.1.1) - capybara (3.36.0) + byebug (11.1.3) + capybara (3.38.0) addressable matrix mini_mime (>= 0.1.3) @@ -86,64 +86,65 @@ GEM xpath (~> 3.2) case_transform (0.2) activesupport - childprocess (4.1.0) closure_tree (7.4.0) activerecord (>= 4.2.10) with_advisory_lock (>= 4.0.0) - codecov (0.5.2) + codecov (0.6.0) simplecov (>= 0.15, < 0.22) - concurrent-ruby (1.1.9) + concurrent-ruby (1.2.2) crass (1.0.6) - database_cleaner (1.7.0) + database_cleaner (2.0.2) + database_cleaner-active_record (>= 2, < 3) + database_cleaner-active_record (2.1.0) + activerecord (>= 5.a) + database_cleaner-core (~> 2.0.0) + database_cleaner-core (2.0.1) + date (3.3.3) declarative (0.0.20) - devise (4.8.1) + devise (4.9.0) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) responders warden (~> 1.2.3) - devise-security (0.14.3) - devise (>= 4.3.0, < 5.0) - rails (>= 4.2.0, < 7.0) + devise-security (0.17.0) + devise (>= 4.3.0) devise_lastseenable (0.0.6) devise rails (>= 3.0.4) - diff-lcs (1.4.4) - diffy (3.4.1) + diff-lcs (1.5.0) + diffy (3.4.2) digest-crc (0.6.4) rake (>= 12.0.0, < 14.0.0) - discard (1.2.0) - activerecord (>= 4.2, < 7) + discard (1.2.1) + activerecord (>= 4.2, < 8) docile (1.4.0) - doorkeeper (5.4.0) + doorkeeper (5.6.5) railties (>= 5) - dotenv (2.7.4) - dotenv-rails (2.7.4) - dotenv (= 2.7.4) - railties (>= 3.2, < 6.1) - email_address (0.1.16) - netaddr (>= 2.0.4, < 3) + dotenv (2.8.1) + dotenv-rails (2.8.1) + dotenv (= 2.8.1) + railties (>= 3.2) + email_address (0.2.4) simpleidn - erubi (1.10.0) - factory_bot (5.1.1) - activesupport (>= 4.2.0) - factory_bot_rails (5.1.1) - factory_bot (~> 5.1.0) - railties (>= 4.2.0) - faker (2.19.0) - i18n (>= 1.6, < 2) - faraday (1.3.0) - faraday-net_http (~> 1.0) - multipart-post (>= 1.2, < 3) - ruby2_keywords - faraday-net_http (1.0.1) + erubi (1.12.0) + factory_bot (6.2.1) + activesupport (>= 5.0.0) + factory_bot_rails (6.2.0) + factory_bot (~> 6.2.0) + railties (>= 5.0.0) + faker (3.1.1) + i18n (>= 1.8.11, < 2) + faraday (2.7.4) + faraday-net_http (>= 2.0, < 3.1) + ruby2_keywords (>= 0.0.4) + faraday-net_http (3.0.2) ffi (1.15.5) - ffi (1.15.5-x64-mingw32) - filterrific (5.2.1) - geocoder (1.6.2) - globalid (0.4.2) - activesupport (>= 4.2.0) - google-apis-core (0.6.0) + filterrific (5.2.5) + geocoder (1.8.1) + globalid (1.1.0) + activesupport (>= 5.0) + google-apis-core (0.11.0) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) httpclient (>= 2.8.1, < 3.a) @@ -152,260 +153,263 @@ GEM retriable (>= 2.0, < 4.a) rexml webrick - google-apis-iamcredentials_v1 (0.12.0) - google-apis-core (>= 0.6, < 2.a) - google-apis-storage_v1 (0.15.0) - google-apis-core (>= 0.5, < 2.a) + google-apis-iamcredentials_v1 (0.17.0) + google-apis-core (>= 0.11.0, < 2.a) + google-apis-storage_v1 (0.19.0) + google-apis-core (>= 0.9.0, < 2.a) google-cloud-core (1.6.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) google-cloud-env (1.6.0) faraday (>= 0.17.3, < 3.0) - google-cloud-errors (1.2.0) - google-cloud-storage (1.36.2) + google-cloud-errors (1.3.1) + google-cloud-storage (1.44.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.1) + google-apis-storage_v1 (~> 0.19.0) google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) - googleauth (1.1.3) + googleauth (1.3.0) faraday (>= 0.17.3, < 3.a) jwt (>= 1.4, < 3.0) memoist (~> 0.16) multi_json (~> 1.11) os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) - httparty (0.18.0) - mime-types (~> 3.0) + httparty (0.21.0) + mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) httpclient (2.8.3) - i18n (1.8.11) + i18n (1.12.0) concurrent-ruby (~> 1.0) - jbuilder (2.10.0) + jbuilder (2.11.5) + actionview (>= 5.0.0) activesupport (>= 5.0.0) jsonapi-renderer (0.2.2) - jwt (2.2.2) - kaminari (1.2.1) + jwt (2.7.0) + kaminari (1.2.2) activesupport (>= 4.1.0) - kaminari-actionview (= 1.2.1) - kaminari-activerecord (= 1.2.1) - kaminari-core (= 1.2.1) - kaminari-actionview (1.2.1) + kaminari-actionview (= 1.2.2) + kaminari-activerecord (= 1.2.2) + kaminari-core (= 1.2.2) + kaminari-actionview (1.2.2) actionview - kaminari-core (= 1.2.1) - kaminari-activerecord (1.2.1) + kaminari-core (= 1.2.2) + kaminari-activerecord (1.2.2) activerecord - kaminari-core (= 1.2.1) - kaminari-core (1.2.1) - launchy (2.5.0) - addressable (~> 2.7) - listen (3.7.1) + kaminari-core (= 1.2.2) + kaminari-core (1.2.2) + launchy (2.5.2) + addressable (~> 2.8) + listen (3.8.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.18.0) + loofah (2.19.1) crass (~> 1.0.2) nokogiri (>= 1.5.9) - mail (2.7.1) + mail (2.8.1) mini_mime (>= 0.1.1) - mail-notify (1.0.4) - actionmailer (>= 5.2.4.3) - actionpack (>= 5.2.4.3) - actionview (>= 5.2.4.3) - activesupport (>= 5.2.4.3) + net-imap + net-pop + net-smtp + mail-notify (1.1.0) + actionmailer (>= 5.2.4.6) + actionpack (>= 5.2.7.1) + actionview (>= 5.2.7.1) + activesupport (>= 5.2.4.6) notifications-ruby-client (~> 5.1) - rack (>= 2.1.4) - marcel (1.0.0) + rack (>= 2.1.4.1) + marcel (1.0.2) matrix (0.4.2) memoist (0.16.2) method_source (1.0.0) - mime-types (3.4.1) - mime-types-data (~> 3.2015) - mime-types-data (3.2021.1115) mini_mime (1.1.2) - mini_portile2 (2.8.0) - minitest (5.15.0) - mongo (2.12.1) - bson (>= 4.8.2, < 5.0.0) - msgpack (1.4.5) + mini_portile2 (2.8.1) + minitest (5.18.0) + mongo (2.18.2) + bson (>= 4.14.1, < 5.0.0) + msgpack (1.6.1) multi_json (1.15.0) multi_xml (0.6.0) - multipart-post (2.1.1) - netaddr (2.0.4) + net-imap (0.3.4) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.1) + timeout + net-smtp (0.3.3) + net-protocol nio4r (2.5.8) - nokogiri (1.13.9) + nokogiri (1.14.2) mini_portile2 (~> 2.8.0) racc (~> 1.4) - nokogiri (1.13.9-x64-mingw32) + nokogiri (1.14.2-aarch64-linux) racc (~> 1.4) - notifications-ruby-client (5.3.0) + nokogiri (1.14.2-x86_64-linux) + racc (~> 1.4) + notifications-ruby-client (5.4.0) jwt (>= 1.5, < 3) orm_adapter (0.5.0) os (1.1.4) - paper_trail (11.0.0) - activerecord (>= 5.2) - request_store (~> 1.1) - pg (1.2.2) - pg_search (2.3.2) + paper_trail (14.0.0) + activerecord (>= 6.0) + request_store (~> 1.4) + pg (1.4.6) + pg_search (2.3.6) activerecord (>= 5.2) activesupport (>= 5.2) - public_suffix (4.0.6) + public_suffix (5.0.1) puma (4.3.12) nio4r (~> 2.0) - racc (1.6.0) - rack (2.2.4) - rack-attack (6.6.0) + racc (1.6.2) + rack (2.2.6.3) + rack-attack (6.6.1) rack (>= 1.0, < 3) - rack-cors (1.1.1) + rack-cors (2.0.0) rack (>= 2.0.0) - rack-mini-profiler (2.0.1) + rack-mini-profiler (3.0.0) rack (>= 1.2.0) - rack-proxy (0.7.2) + rack-proxy (0.7.6) rack - rack-test (1.1.0) - rack (>= 1.0, < 3) - rails (6.0.3.6) - actioncable (= 6.0.3.6) - actionmailbox (= 6.0.3.6) - actionmailer (= 6.0.3.6) - actionpack (= 6.0.3.6) - actiontext (= 6.0.3.6) - actionview (= 6.0.3.6) - activejob (= 6.0.3.6) - activemodel (= 6.0.3.6) - activerecord (= 6.0.3.6) - activestorage (= 6.0.3.6) - activesupport (= 6.0.3.6) + rack-test (2.0.2) + rack (>= 1.3) + rails (6.0.6.1) + actioncable (= 6.0.6.1) + actionmailbox (= 6.0.6.1) + actionmailer (= 6.0.6.1) + actionpack (= 6.0.6.1) + actiontext (= 6.0.6.1) + actionview (= 6.0.6.1) + activejob (= 6.0.6.1) + activemodel (= 6.0.6.1) + activerecord (= 6.0.6.1) + activestorage (= 6.0.6.1) + activesupport (= 6.0.6.1) bundler (>= 1.3.0) - railties (= 6.0.3.6) + railties (= 6.0.6.1) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.4.3) - loofah (~> 2.3) - rails-settings-cached (2.8.2) - rails (>= 5.0.0) + rails-html-sanitizer (1.5.0) + loofah (~> 2.19, >= 2.19.1) + rails-settings-cached (2.8.3) + activerecord (>= 5.0.0) + railties (>= 5.0.0) rails_email_validator (0.1.4) activemodel (>= 3.0.0) - railties (6.0.3.6) - actionpack (= 6.0.3.6) - activesupport (= 6.0.3.6) + railties (6.0.6.1) + actionpack (= 6.0.6.1) + activesupport (= 6.0.6.1) method_source rake (>= 0.8.7) thor (>= 0.20.3, < 2.0) rake (13.0.6) - rb-fsevent (0.11.1) + rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) - regexp_parser (2.2.0) + regexp_parser (2.7.0) representable (3.2.0) declarative (< 0.1.0) trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) - request_store (1.5.0) + request_store (1.5.1) rack (>= 1.4) - responders (3.0.1) - actionpack (>= 5.0) - railties (>= 5.0) + responders (3.1.0) + actionpack (>= 5.2) + railties (>= 5.2) retriable (3.1.2) rexml (3.2.5) - rspec-core (3.9.2) - rspec-support (~> 3.9.3) - rspec-expectations (3.9.2) + rspec-core (3.12.1) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.9.0) - rspec-mocks (3.9.1) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.3) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.9.0) - rspec-rails (4.0.1) - actionpack (>= 4.2) - activesupport (>= 4.2) - railties (>= 4.2) - rspec-core (~> 3.9) - rspec-expectations (~> 3.9) - rspec-mocks (~> 3.9) - rspec-support (~> 3.9) - rspec-support (3.9.3) - ruby2_keywords (0.0.4) + rspec-support (~> 3.12.0) + rspec-rails (5.1.2) + actionpack (>= 5.2) + activesupport (>= 5.2) + railties (>= 5.2) + rspec-core (~> 3.10) + rspec-expectations (~> 3.10) + rspec-mocks (~> 3.10) + rspec-support (~> 3.10) + rspec-support (3.12.0) + ruby2_keywords (0.0.5) rubyzip (2.3.2) sass-rails (6.0.0) sassc-rails (~> 2.1, >= 2.1.1) sassc (2.4.0) ffi (~> 1.9) - sassc (2.4.0-x64-mingw32) - ffi (~> 1.9) sassc-rails (2.1.2) railties (>= 4.0.0) sassc (>= 2.0) sprockets (> 3.0) sprockets-rails tilt - selenium-webdriver (4.5.0) - childprocess (>= 0.5, < 5.0) + selenium-webdriver (4.8.1) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) semantic_range (3.0.0) - sentry-rails (4.3.3) + sentry-rails (5.8.0) railties (>= 5.0) - sentry-ruby-core (~> 4.3.0) - sentry-ruby (4.3.1) + sentry-ruby (~> 5.8.0) + sentry-ruby (5.8.0) concurrent-ruby (~> 1.0, >= 1.0.2) - faraday (>= 1.0) - sentry-ruby-core (= 4.3.1) - sentry-ruby-core (4.3.1) - concurrent-ruby - faraday - shoulda-matchers (4.3.0) - activesupport (>= 4.2.0) - signet (0.16.1) + shoulda-matchers (5.3.0) + activesupport (>= 5.2.0) + signet (0.17.0) addressable (~> 2.8) - faraday (>= 0.17.5, < 3.0) + faraday (>= 0.17.5, < 3.a) jwt (>= 1.5, < 3.0) multi_json (~> 1.10) simplecov (0.21.2) docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) - simplecov-cobertura (1.4.2) - simplecov (~> 0.8) + simplecov-cobertura (2.1.0) + rexml + simplecov (~> 0.19) simplecov-html (0.12.3) simplecov_json_formatter (0.1.4) - simpleidn (0.1.1) + simpleidn (0.2.1) unf (~> 0.1.4) - spring (2.1.0) + spring (2.1.1) spring-watcher-listen (2.0.1) listen (>= 2.7, < 4.0) spring (>= 1.2, < 3.0) - sprockets (4.0.2) + sprockets (4.2.0) concurrent-ruby (~> 1.0) - rack (> 1, < 3) - sprockets-rails (3.2.2) - actionpack (>= 4.0) - activesupport (>= 4.0) + rack (>= 2.2.4, < 4) + sprockets-rails (3.4.2) + actionpack (>= 5.2) + activesupport (>= 5.2) sprockets (>= 3.0.0) - thor (1.1.0) + thor (1.2.1) thread_safe (0.3.6) - tilt (2.0.10) + tilt (2.1.0) + timeout (0.3.2) trailblazer-option (0.1.2) turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) - tzinfo (1.2.10) + tzinfo (1.2.11) thread_safe (~> 0.1) - tzinfo-data (1.2020.1) - tzinfo (>= 1.0.0) uber (0.1.0) - uk_postcode (2.1.5) + uk_postcode (2.1.8) unf (0.1.4) unf_ext - unf_ext (0.0.7.7) - uniform_notifier (1.13.0) + unf_ext (0.0.8.2) + uniform_notifier (1.16.0) warden (1.2.9) rack (>= 2.0.9) - web-console (4.0.1) + web-console (4.2.0) actionview (>= 6.0.0) activemodel (>= 6.0.0) bindex (>= 0.4.0) @@ -414,25 +418,26 @@ GEM nokogiri (~> 1.6) rubyzip (>= 1.3.0) selenium-webdriver (~> 4.0) - webpacker (5.4.3) + webpacker (5.4.4) activesupport (>= 5.2) rack-proxy (>= 0.6.1) railties (>= 5.2) semantic_range (>= 2.3.0) - webrick (1.7.0) + webrick (1.8.1) websocket (1.2.9) - websocket-driver (0.7.3) + websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) with_advisory_lock (4.6.0) activerecord (>= 4.2) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.5.1) + zeitwerk (2.6.7) PLATFORMS + aarch64-linux-musl ruby - x64-mingw32 + x86_64-linux DEPENDENCIES active_model_serializers @@ -492,7 +497,7 @@ DEPENDENCIES webpacker (~> 5.0) RUBY VERSION - ruby 3.0.3p157 + ruby 3.0.5p211 BUNDLED WITH - 2.3.9 + 2.2.33 diff --git a/config/database.yml b/config/database.yml index 12ffb328..ab6be11d 100644 --- a/config/database.yml +++ b/config/database.yml @@ -2,19 +2,20 @@ default: &default adapter: postgresql encoding: unicode pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + timeout: <%= ENV.fetch("RAILS_TIMEOUT") { 5000 } %> development: <<: *default - url: postgresql://localhost/outpost_development - username: outpost - password: password + url: <%= ENV["DATABASE_URL"].gsub('?', '_development?') %> + test: <<: *default - url: postgresql://localhost/outpost_test - username: outpost - password: password + url: <%= ENV["DATABASE_URL"].gsub('?', '_test?') %> + +staging: + <<: *default + url: <%= ENV["DATABASE_URL"].gsub('?', '_staging?') %> + production: <<: *default - database: outpost_production - username: outpost - password: <%= ENV['OUTPOST_DATABASE_PASSWORD'] %> + url: <%= ENV["DATABASE_URL"].gsub('?', '_production?') %> diff --git a/config/secrets.yml b/config/secrets.yml new file mode 100644 index 00000000..1f321746 --- /dev/null +++ b/config/secrets.yml @@ -0,0 +1,11 @@ +development: &default + secret_key_base: <%= ENV['SECRET_TOKEN'] %> + +test: + <<: *default + +staging: + <<: *default + +production: + <<: *default diff --git a/db/_sample-data.yml b/db/_sample-data.yml new file mode 100644 index 00000000..b4df2c13 --- /dev/null +++ b/db/_sample-data.yml @@ -0,0 +1,51 @@ +locations: + - address_1: Buckingham Palace + city: London + postal_code: SW1A 1AA + latitude: 51.501009 + longitude: -0.141588 + - address_1: Broadcasting House, Peel Wing, Portland Pl + city: London + postal_code: W1A 1AA + latitude: 51.518561 + longitude: -0.143799 + - address_1: Town Hall Pinstone Street + city: Sheffield, GB + postal_code: S1 2HH + latitude: 53.380384 + longitude: -1.470006 + - address_1: Motorpoint Arena Cardiff, Mary Ann St + city: Cardiff + postal_code: CF10 2EQ + latitude: 51.478914 + longitude: -3.171759 + - address_1: 20 St Thomas Street + city: London + postal_code: SE1 9RG + latitude: 51.504642 + longitude: -0.08899 + - address_1: Edinburgh Waverley Station + city: Edinburgh + postal_code: EH8 8DL + latitude: 55.952623 + longitude: -3.18135 + - address_1: Brindleyplace, The Water's Edge + city: Birmingham, GB + postal_code: B1 2HL + latitude: 52.478182 + longitude: -1.912008 + - address_1: The Upper Mill, Kingston Road, Ewell + city: Surrey + postal_code: KT17 2AF + latitude: 51.352525 + longitude: -0.251579 + - address_1: Alexandra Palace, Wood Green + city: London, GB + postal_code: N22 7AY + latitude: 51.594481 + longitude: -0.130527 + - address_1: 55 Norfolk Street + city: Sheffield + postal_code: S1 1DA + latitude: 53.38108 + longitude: 1.466765 diff --git a/db/_seed.yml b/db/_seed.yml index 4ec90659..9b09f9c8 100644 --- a/db/_seed.yml +++ b/db/_seed.yml @@ -1,56 +1,4 @@ -locations: - - address_1: Buckingham Palace - city: London - postal_code: SW1A 1AA - latitude: 51.501009 - longitude: -0.141588 - - address_1: Broadcasting House, Peel Wing, Portland Pl - city: London - postal_code: W1A 1AA - latitude: 51.518561 - longitude: -0.143799 - - address_1: Town Hall Pinstone Street - city: Sheffield, GB - postal_code: S1 2HH - latitude: 53.380384 - longitude: -1.470006 - - address_1: Motorpoint Arena Cardiff, Mary Ann St - city: Cardiff - postal_code: CF10 2EQ - latitude: 51.478914 - longitude: -3.171759 - - address_1: 20 St Thomas Street - city: London - postal_code: SE1 9RG - latitude: 51.504642 - longitude: -0.08899 - - address_1: Edinburgh Waverley Station - city: Edinburgh - postal_code: EH8 8DL - latitude: 55.952623 - longitude: -3.18135 - - address_1: Brindleyplace, The Water's Edge - city: Birmingham, GB - postal_code: B1 2HL - latitude: 52.478182 - longitude: -1.912008 - - address_1: The Upper Mill, Kingston Road, Ewell - city: Surrey - postal_code: KT17 2AF - latitude: 51.352525 - longitude: -0.251579 - - address_1: Alexandra Palace, Wood Green - city: London, GB - postal_code: N22 7AY - latitude: 51.594481 - longitude: -0.130527 - - address_1: 55 Norfolk Street - city: Sheffield - postal_code: S1 1DA - latitude: 53.38108 - longitude: 1.466765 - -accessibilities: +accessibilities: - Accessible toilet facilities - Hearing loop - Car parking @@ -65,8 +13,7 @@ accessibilities: - Wheelchair accessible entrance - Partial wheelchair access - -send_needs: +send_needs: - Autism - Hearing impairment - Visual impairment @@ -80,4 +27,4 @@ suitabilities: - Visual and / or hearing impediment - Physical disabilities - Older people - - Dementia \ No newline at end of file + - Dementia diff --git a/db/seeds.rb b/db/seeds.rb index 0cfca2fe..cfd8dc33 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,17 +1,12 @@ yaml = Rails.root.join('db', '_seed.yml') data = YAML::load_file(yaml) -# use our realistic sample UK data - fake data won't correctly geocode -data["locations"].each do |l| - Location.create!({ - address_1: l["address_1"], - city: l["city"], - postal_code: l["postal_code"], - latitude: l["latitude"], - longitude: l["longitude"], - skip_mongo_callbacks: true - }) -end +sample_yaml = Rails.root.join('db', '_sample-data.yml') +sample_data = YAML::load_file(sample_yaml) + + +import_sample_data = ENV["IMPORT_SAMPLE_DATA"] || false; + data["accessibilities"].each do |n| Accessibility.create!({name: n}) @@ -25,49 +20,78 @@ Suitability.create!({name: n}) end -10.times do - taxon = Taxonomy.create!({ - name: Faker::Lorem.words(number: rand(1...5)).join(' ').capitalize - }) -end +#make a single admin user +User.create!({ + first_name: "Example", + last_name: "Admin", + admin: true, + admin_users: true, + admin_ofsted: true, + email: ENV["INITIAL_ADMIN_EMAIL"] || "example@example.com", + password: ENV["INITIAL_ADMIN_PASSWORD"] || "FakePassword1!" +}) -10.times do - org = Organisation.create!({ - name: Faker::Company.name, - skip_mongo_callbacks: true - }) - - rand(0...2).times do - user = User.create!({ - first_name: Faker::Name.first_name, - last_name: Faker::Name.last_name, - email: Faker::Internet.email(domain: "example.com"), - organisation: org, - password: "FakePassword1!" + +if import_sample_data + + # use our realistic sample UK data - fake data won't correctly geocode + sample_data["locations"].each do |l| + Location.create!({ + address_1: l["address_1"], + city: l["city"], + postal_code: l["postal_code"], + latitude: l["latitude"], + longitude: l["longitude"], + skip_mongo_callbacks: true }) end - rand(0...5).times do - service = Service.create!({ + 10.times do + taxon = Taxonomy.create!({ + name: Faker::Lorem.words(number: rand(1...5)).join(' ').capitalize + }) + end + + # subcategories + taxonomy_ids = Taxonomy.where.not(parent_id: nil).last(10).map(&:id) + taxonomy_ids.each do | t | + rand(0...10).times do + child_taxon = Taxonomy.create!({ + name: Faker::Lorem.words(number: rand(1...5)).join(' ').capitalize, + parent_id: t + }) + end + end + + 10.times do + org = Organisation.create!({ name: Faker::Company.name, - organisation: org, - description: Faker::Lorem.paragraph, skip_mongo_callbacks: true }) - # byebug - service.locations << Location.take - service.taxonomies << Taxonomy.take - service.save! + + rand(0...2).times do + user = User.create!({ + first_name: Faker::Name.first_name, + last_name: Faker::Name.last_name, + email: Faker::Internet.email(domain: "example.com"), + organisation: org, + password: "FakePassword1!" + }) + end + + rand(0...5).times do + service = Service.create!({ + name: Faker::Company.name, + organisation: org, + description: Faker::Lorem.paragraph, + skip_mongo_callbacks: true + }) + # byebug + service.locations << Location.take + service.taxonomies << Taxonomy.take + service.save! + end end -end -# make a single admin user -User.create!({ - first_name: "Example", - last_name: "Admin", - admin: true, - admin_users: true, - admin_ofsted: true, - email: "example@example.com", - password: ENV["INITIAL_ADMIN_PASSWORD"] || "FakePassword1!" -}) \ No newline at end of file + +end \ No newline at end of file diff --git a/docker-compose.development.yml b/docker-compose.development.yml new file mode 100644 index 00000000..a2358958 --- /dev/null +++ b/docker-compose.development.yml @@ -0,0 +1,58 @@ +version: "3.7" +services: + # Outpost app + + outpost: + image: "outpost:development" + container_name: outpost + init: true + depends_on: + - postgres + build: + target: development + ports: + - 3000:3000 + volumes: + - ./:/app:cached + environment: + PROJECT_NAME: ${PROJECT_NAME} + PUMA_WORKERS: 0 + RAILS_MAX_THREADS: 5 + networks: + - external_network + - internal_network + + # Databases + + postgres: + image: postgres:13.7-alpine + container_name: outpost-db-postgres + environment: + POSTGRES_USER: ${POSTGRES_DB_USER} + POSTGRES_PASSWORD: ${POSTGRES_DB_PASSWORD} + ports: + - 5432:5432 + volumes: + - outpost-postgres-volume:/var/lib/postgresql/data + networks: + - internal_network + + mongo: + image: mongo:6 + container_name: outpost-db-mongo + ports: + - 27017:27017 + volumes: + - outpost-mongo-volume:/data/db + networks: + - internal_network + - external_network + +volumes: + outpost-postgres-volume: + outpost-mongo-volume: + +networks: + external_network: + internal_network: + internal: true diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 0507fb19..00000000 --- a/docker-compose.yml +++ /dev/null @@ -1,21 +0,0 @@ -version: '3.1' - -services: - - db: - image: postgres - restart: always - environment: - POSTGRES_PASSWORD: password - POSTGRES_DB: outpost_development - POSTGRES_USER: outpost - ports: - - "5432:5432" - mongo: - image: mongo - restart: always - environment: - MONGO_INITDB_ROOT_USERNAME: root - MONGO_INITDB_ROOT_PASSWORD: password - ports: - - "27017:27017" \ No newline at end of file diff --git a/environment/docker-run-development.sh b/environment/docker-run-development.sh new file mode 100644 index 00000000..016d5626 --- /dev/null +++ b/environment/docker-run-development.sh @@ -0,0 +1,14 @@ +#!/bin/ash + +cd /app +rm -f /app/tmp/pids/server.pid + +#rails db:migrate RAILS_ENV=development +rails s -u puma -p 3000 -b=0.0.0.0 + +# TODO get debug version working +#bundle exec rdebug-ide --host 0.0.0.0 --dispatcher-port 33030 --port 13030 -- rails s -u puma -p 3000 -b=0.0.0.0 + + + +#cd /app && rm -f /app/tmp/pids/server.pid && rails s -u puma -p 3000 -b=0.0.0.0 \ No newline at end of file diff --git a/environment/docker-run-production.sh b/environment/docker-run-production.sh new file mode 100644 index 00000000..06458687 --- /dev/null +++ b/environment/docker-run-production.sh @@ -0,0 +1,5 @@ +#!/bin/ash + +cd /app +rm -f /app/tmp/pids/server.pid +rails s -u puma -p 3000 -b=0.0.0.0 diff --git a/package.json b/package.json index 1b8b7544..35aa0325 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "@rails/actioncable": "^6.0.0", "@rails/activestorage": "^6.0.0", "@rails/ujs": "^6.0.0", - "@rails/webpacker": "5.4.3", + "@rails/webpacker": "5.4.4", "@yaireo/tagify": "^3.8.0", "choices.js": "^9.0.1", "conglomerate-element-dataset": "^1.4.1", diff --git a/.env.example b/sample.env similarity index 65% rename from .env.example rename to sample.env index 2bc37848..5c95e84d 100644 --- a/.env.example +++ b/sample.env @@ -1,5 +1,13 @@ # Env vars +PROJECT_NAME=outpost_development +#IMPORT_SAMPLE_DATA=true + +# You would typically use rake secret to generate a secure token. It is +# critical that you keep this value private in production. +SECRET_TOKEN= + + # ------------------ deprecated #INSTANCE= @@ -11,8 +19,8 @@ FEEDBACK_FORM_URL= # ------------------ database connections -DATABASE_URL= -DB_URI= +DATABASE_URL=postgresql://outpost_development:outpost_development@postgres:5432/outpost?timeout=5000 +DB_URI=mongodb://mongo/outpost_api_development # ------------------ emails diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2a3f8724..27119e46 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -114,6 +114,12 @@ end config.before(:suite) do + DatabaseCleaner.url_allowlist = [ + %r{^postgresql://.*_development:.*_development@postgres:5432}, + %r{^postgresql://.*_test:.*_test@postgres:5432}, + %r{^postgresql://.*_development:.*_development@localhost:5432}, + %r{^postgresql://.*_test:.*_test@localhost:5432} + ] DatabaseCleaner.strategy = :transaction DatabaseCleaner.clean_with(:truncation) end