potassium 6.0.0 → 6.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +103 -38
  3. data/.circleci/setup-rubygems.sh +3 -0
  4. data/.gitignore +2 -1
  5. data/.rubocop.yml +530 -0
  6. data/CHANGELOG.md +57 -0
  7. data/README.md +51 -45
  8. data/lib/potassium/assets/.circleci/config.yml.erb +83 -34
  9. data/lib/potassium/assets/.eslintrc.json +13 -4
  10. data/lib/potassium/assets/.github/pull_request_template.md +9 -0
  11. data/lib/potassium/assets/.rubocop.yml +13 -0
  12. data/lib/potassium/assets/README.yml +7 -7
  13. data/lib/potassium/assets/app/graphql/graphql_controller.rb +55 -0
  14. data/lib/potassium/assets/app/graphql/mutations/login_mutation.rb +23 -0
  15. data/lib/potassium/assets/app/graphql/queries/base_query.rb +4 -0
  16. data/lib/potassium/assets/app/graphql/types/base/base_argument.rb +4 -0
  17. data/lib/potassium/assets/app/graphql/types/base/base_enum.rb +4 -0
  18. data/lib/potassium/assets/app/graphql/types/base/base_field.rb +5 -0
  19. data/lib/potassium/assets/app/graphql/types/base/base_input_object.rb +5 -0
  20. data/lib/potassium/assets/app/graphql/types/base/base_interface.rb +7 -0
  21. data/lib/potassium/assets/app/graphql/types/base/base_object.rb +5 -0
  22. data/lib/potassium/assets/app/graphql/types/base/base_scalar.rb +4 -0
  23. data/lib/potassium/assets/app/graphql/types/base/base_union.rb +4 -0
  24. data/lib/potassium/assets/app/graphql/types/mutation_type.rb +10 -0
  25. data/lib/potassium/assets/app/graphql/types/query_type.rb +13 -0
  26. data/lib/potassium/assets/app/javascript/app.spec.js +1 -1
  27. data/lib/potassium/assets/app/uploaders/base_uploader.rb +1 -3
  28. data/lib/potassium/assets/app/views/shared/_gtm_body.html.erb +4 -0
  29. data/lib/potassium/assets/app/views/shared/_gtm_head.html.erb +7 -0
  30. data/lib/potassium/assets/config/graphql_playground.rb +20 -0
  31. data/lib/potassium/assets/config/puma.rb +1 -1
  32. data/lib/potassium/assets/config/shrine.rb +4 -1
  33. data/lib/potassium/assets/redis.yml +1 -2
  34. data/lib/potassium/assets/testing/rails_helper.rb +2 -0
  35. data/lib/potassium/cli/commands/create.rb +11 -19
  36. data/lib/potassium/cli_options.rb +70 -10
  37. data/lib/potassium/helpers/template-helpers.rb +4 -0
  38. data/lib/potassium/newest_version_ensurer.rb +19 -36
  39. data/lib/potassium/node_version_ensurer.rb +30 -0
  40. data/lib/potassium/recipes/admin.rb +26 -16
  41. data/lib/potassium/recipes/api.rb +92 -27
  42. data/lib/potassium/recipes/background_processor.rb +62 -18
  43. data/lib/potassium/recipes/ci.rb +9 -39
  44. data/lib/potassium/recipes/database.rb +4 -0
  45. data/lib/potassium/recipes/draper.rb +0 -9
  46. data/lib/potassium/recipes/file_storage.rb +2 -1
  47. data/lib/potassium/recipes/front_end.rb +84 -9
  48. data/lib/potassium/recipes/github.rb +93 -15
  49. data/lib/potassium/recipes/google_tag_manager.rb +94 -0
  50. data/lib/potassium/recipes/heroku.rb +42 -29
  51. data/lib/potassium/recipes/mailer.rb +18 -5
  52. data/lib/potassium/recipes/monitoring.rb +5 -0
  53. data/lib/potassium/recipes/schedule.rb +16 -1
  54. data/lib/potassium/recipes/style.rb +2 -2
  55. data/lib/potassium/templates/application.rb +5 -2
  56. data/lib/potassium/version.rb +5 -2
  57. data/potassium.gemspec +5 -2
  58. data/spec/features/api_spec.rb +25 -0
  59. data/spec/features/background_processor_spec.rb +19 -6
  60. data/spec/features/ci_spec.rb +7 -4
  61. data/spec/features/draper_spec.rb +1 -6
  62. data/spec/features/file_storage_spec.rb +5 -0
  63. data/spec/features/front_end_spec.rb +32 -1
  64. data/spec/features/github_spec.rb +53 -8
  65. data/spec/features/google_tag_manager_spec.rb +36 -0
  66. data/spec/features/graphql_spec.rb +71 -0
  67. data/spec/features/mailer_spec.rb +16 -0
  68. data/spec/features/schedule_spec.rb +11 -4
  69. data/spec/spec_helper.rb +1 -0
  70. data/spec/support/fake_octokit.rb +31 -0
  71. data/spec/support/potassium_test_helpers.rb +0 -1
  72. data/tmp/.keep +0 -0
  73. metadata +80 -15
  74. data/lib/potassium/assets/Dockerfile.ci +0 -6
  75. data/lib/potassium/assets/api/api_error_concern.rb +0 -32
  76. data/lib/potassium/assets/api/base_controller.rb +0 -7
  77. data/lib/potassium/assets/api/draper_responder.rb +0 -62
  78. data/lib/potassium/assets/api/responder.rb +0 -41
  79. data/lib/potassium/assets/bin/cibuild.erb +0 -117
  80. data/lib/potassium/assets/docker-compose.ci.yml +0 -12
  81. data/lib/potassium/assets/sidekiq_scheduler.yml +0 -9
@@ -1,32 +0,0 @@
1
- module ApiErrorConcern
2
- extend ActiveSupport::Concern
3
-
4
- included do
5
- rescue_from "Exception" do |exception|
6
- logger.error exception.message
7
- logger.error exception.backtrace.join("\n")
8
- respond_api_error(:internal_server_error, message: "server_error",
9
- type: exception.class.to_s,
10
- detail: exception.message)
11
- end
12
-
13
- rescue_from "ActiveRecord::RecordNotFound" do |exception|
14
- respond_api_error(:not_found, message: "record_not_found",
15
- detail: exception.message)
16
- end
17
-
18
- rescue_from "ActiveModel::ForbiddenAttributesError" do |exception|
19
- respond_api_error(:bad_request, message: "protected_attributes",
20
- detail: exception.message)
21
- end
22
-
23
- rescue_from "ActiveRecord::RecordInvalid" do |exception|
24
- respond_api_error(:bad_request, message: "invalid_attributes",
25
- errors: exception.record.errors)
26
- end
27
- end
28
-
29
- def respond_api_error(status, error = {})
30
- render json: error, status: status
31
- end
32
- end
@@ -1,7 +0,0 @@
1
- class Api::V1::BaseController < ApplicationController
2
- include ApiErrorConcern
3
-
4
- self.responder = ApiResponder
5
-
6
- respond_to :json
7
- end
@@ -1,62 +0,0 @@
1
- class ApiResponder < ActionController::Responder
2
- def respond
3
- return display_errors if has_errors?
4
- return head :no_content if delete?
5
-
6
- display resource, status_code: status_code
7
- end
8
-
9
- private
10
-
11
- def display(_resource, given_options = {})
12
- controller.render options.merge(given_options).merge(
13
- json: serializer.as_json
14
- )
15
- end
16
-
17
- def serializer
18
- serializer_class = ActiveModel::Serializer.serializer_for(resource)
19
- if serializer_class.present?
20
- serializer_options = infer_serializer(serializer_class).merge(options)
21
- serializer_class.new(decorated_resource, serializer_options)
22
- else
23
- decorated_resource
24
- end
25
- end
26
-
27
- def status_code
28
- return :created if post?
29
- :ok
30
- end
31
-
32
- def display_errors
33
- controller.render(
34
- status: :unprocessable_entity,
35
- json: { msg: "invalid_attributes", errors: format_errors }
36
- )
37
- end
38
-
39
- def format_errors
40
- resource.errors.as_json
41
- end
42
-
43
- def infer_serializer(serializer_class)
44
- if serializer_class == ActiveModel::ArraySerializer
45
- s = options.delete(:each_serializer) || "#{resource.klass}Serializer".constantize
46
- { each_serializer: s }
47
- else
48
- s = options.delete(:serializer) || "#{resource.class}Serializer".constantize
49
- { serializer: s }
50
- end
51
- end
52
-
53
- def decorated_resource
54
- if resource.respond_to?(:decorate)
55
- resource.decorate
56
- else
57
- resource
58
- end
59
- rescue Draper::UninferrableDecoratorError
60
- resource
61
- end
62
- end
@@ -1,41 +0,0 @@
1
- class ApiResponder < ActionController::Responder
2
- def respond
3
- return display_errors if has_errors?
4
- return head :no_content if delete?
5
-
6
- display resource, status_code: status_code
7
- end
8
-
9
- private
10
-
11
- def display(_resource, given_options = {})
12
- controller.render options.merge(given_options).merge(
13
- json: serializer.as_json
14
- )
15
- end
16
-
17
- def serializer
18
- serializer_class = ActiveModel::Serializer.serializer_for(resource)
19
- if serializer_class.present?
20
- serializer_class.new(resource, options)
21
- else
22
- resource
23
- end
24
- end
25
-
26
- def status_code
27
- return :created if post?
28
- :ok
29
- end
30
-
31
- def display_errors
32
- controller.render(
33
- status: :unprocessable_entity,
34
- json: { msg: "invalid_attributes", errors: format_errors }
35
- )
36
- end
37
-
38
- def format_errors
39
- resource.errors.as_json
40
- end
41
- end
@@ -1,117 +0,0 @@
1
- #!/usr/bin/env bash
2
- trap "exit" SIGINT SIGTERM
3
-
4
- command -v docker >/dev/null 2>&1 && docker info >/dev/null || {
5
- printf >&2 "\e[31mI require docker but it's not installed. Aborting.\e[0m\n"; exit 1;
6
- }
7
-
8
- DOCKER_COMPOSE_ARGS="-f docker-compose.ci.yml"
9
-
10
- # Build Image
11
- build(){
12
- docker-compose $DOCKER_COMPOSE_ARGS build test
13
- }
14
-
15
- # Wait services to be ready
16
- wait_services(){
17
- function test_service {
18
- docker-compose $DOCKER_COMPOSE_ARGS run --rm test sh -c "nc -z $1 $2"
19
- }
20
-
21
- count=0
22
- # Chain tests together by using &&
23
- until (
24
- <% if(selected?(:database, :mysql) || selected?(:database, :postgresql))-%>
25
- test_service '$DB_HOST' '$DB_PORT' && \
26
- <% end-%>
27
- echo "Services ready"
28
- )
29
- do
30
- ((count++))
31
- if [ $count -gt 50 ]
32
- then
33
- echo "Services didn't become ready in time"
34
- exit 1
35
- else
36
- echo "Waiting for services to become ready..."
37
- fi
38
- sleep 0.5
39
- done
40
- }
41
-
42
- # Prepare dependencies
43
- dependencies(){
44
- docker-compose $DOCKER_COMPOSE_ARGS run --rm test bundle install
45
- }
46
-
47
- <% if selected?(:front_end, :vue) %>
48
- yarn_dependencies(){
49
- docker-compose $DOCKER_COMPOSE_ARGS run --rm test yarn install
50
- }
51
- <% end %>
52
-
53
- assets() {
54
- docker-compose $DOCKER_COMPOSE_ARGS run --rm test /bin/bash -c "bin/setup && bundle exec rake assets:precompile"
55
- }
56
-
57
- # Prepare database
58
- database(){
59
- docker-compose $DOCKER_COMPOSE_ARGS run --rm test bundle exec rake db:create db:schema:load
60
- }
61
-
62
- # Run the specs
63
- tests(){
64
- [ -n "$CI" ] && {
65
- RSPEC_JUNIT_ARGS="-r rspec_junit_formatter --format RspecJunitFormatter -o $HOME/.rspec_reports/junit.xml"
66
- RSPEC_FORMAT_ARGS="--format progress --no-color"
67
- }
68
- docker-compose $DOCKER_COMPOSE_ARGS run --rm test bundle exec rspec spec $RSPEC_FORMAT_ARGS $RSPEC_JUNIT_ARGS
69
- }
70
-
71
- <% if selected?(:front_end, :vue) %>
72
- js_tests(){
73
- docker-compose $DOCKER_COMPOSE_ARGS run --rm test yarn run test
74
- }
75
- <% end %>
76
-
77
- # Run the complete ci build
78
- no_ci(){
79
- build
80
- wait_services
81
- dependencies
82
- assets
83
- database
84
- tests
85
- }
86
-
87
- case "$1" in
88
- "")
89
- no_ci
90
- ;;
91
- "services")
92
- wait_services
93
- ;;
94
- "deps"|"dependencies")
95
- dependencies <% if selected?(:front_end, :vue) %>&& yarn_dependencies<% end %>
96
- ;;
97
- "assets")
98
- assets
99
- ;;
100
- "db"|"database")
101
- database
102
- ;;
103
- <% if selected?(:front_end, :vue) %>
104
- "js_tests")
105
- js_tests
106
- ;;
107
- <% end %>
108
- "specs"|"tests")
109
- tests
110
- ;;
111
- "build")
112
- build
113
- ;;
114
- *)
115
- echo "Usage: cibuild [services|deps|assets|db|specs|build]"
116
- ;;
117
- esac
@@ -1,12 +0,0 @@
1
- version: '3.4'
2
-
3
- services:
4
- test:
5
- build:
6
- context: "."
7
- dockerfile: Dockerfile.ci
8
- volumes:
9
- - "test_data:/usr/local/bundle"
10
- - "./node_modules:/app/node_modules"
11
- environment:
12
- RACK_ENV: test
@@ -1,9 +0,0 @@
1
- production:
2
- :concurrency: 5
3
- :queues:
4
- - default
5
- # :schedule:
6
- # an_scheduled_task:
7
- # cron: '0 * * * * *' # Runs once per minute
8
- # class: ExampleJob
9
- # args: ['a', 'b']