alchemy_cms 5.0.0.beta1 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +48 -0
  4. data/CHANGELOG.md +19 -2
  5. data/Gemfile +2 -2
  6. data/README.md +3 -3
  7. data/Rakefile +11 -10
  8. data/alchemy_cms.gemspec +1 -1
  9. data/app/assets/stylesheets/alchemy/navigation.scss +1 -0
  10. data/app/assets/stylesheets/alchemy/tags.scss +2 -2
  11. data/app/controllers/alchemy/admin/pages_controller.rb +1 -1
  12. data/app/helpers/alchemy/admin/base_helper.rb +2 -0
  13. data/app/helpers/alchemy/admin/pictures_helper.rb +4 -6
  14. data/app/helpers/alchemy/url_helper.rb +2 -2
  15. data/app/models/alchemy/attachment.rb +4 -1
  16. data/app/models/alchemy/essence_file.rb +1 -1
  17. data/app/models/alchemy/essence_picture.rb +1 -1
  18. data/app/models/alchemy/essence_picture_view.rb +5 -1
  19. data/app/models/alchemy/picture.rb +22 -3
  20. data/app/models/alchemy/picture/preprocessor.rb +26 -0
  21. data/app/models/alchemy/picture/url.rb +4 -2
  22. data/app/views/alchemy/admin/pictures/index.html.erb +18 -3
  23. data/app/views/alchemy/admin/pictures/show.html.erb +1 -1
  24. data/app/views/alchemy/admin/resources/index.html.erb +21 -22
  25. data/app/views/alchemy/admin/sites/_form.html.erb +2 -2
  26. data/app/views/alchemy/essences/_essence_file_view.html.erb +1 -1
  27. data/config/alchemy/config.yml +10 -0
  28. data/lib/alchemy/admin/preview_url.rb +27 -6
  29. data/lib/alchemy/config.rb +5 -3
  30. data/lib/alchemy/deprecation.rb +1 -1
  31. data/lib/alchemy/install/tasks.rb +41 -0
  32. data/lib/alchemy/resource.rb +2 -2
  33. data/lib/alchemy/test_support/factories/language_factory.rb +8 -3
  34. data/lib/alchemy/version.rb +1 -1
  35. data/lib/generators/alchemy/install/install_generator.rb +60 -1
  36. data/lib/tasks/alchemy/install.rake +5 -49
  37. metadata +11 -9
  38. data/.github/workflows/ci.yml +0 -134
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a47529eb07ef956c81fe417efd5570b37a0d56e689ee3079c9bc623b91b8bc28
4
- data.tar.gz: 9bb8aa6ca4eab610212690d3630c223269d3d6cb28224e33a9a4838fb4869c81
3
+ metadata.gz: 6917c640c04335035e6dc96c947904226222acd26dec111b81da71496b40505e
4
+ data.tar.gz: d5e33e37d5d5cbacbbb6c3729468548155add079b131524880bdd9c8ff8fd35f
5
5
  SHA512:
6
- metadata.gz: df610fff48f0e7a30c0f348b20c452a8ade6226a9ce6457b497d76e3cdc7269d43cfe24da082687773de1c9a692df0116475b87469e9538899bc142e7d49397e
7
- data.tar.gz: 89281dc3a6bccd9d537adc2662143e61f023f38205a3474a1d4f6a63b40dea7374df95f7f40614aee771f14de7bec44f92afb68dfcffafb1df1028f416bb0c79
6
+ metadata.gz: e73a121ef1c1eee8c0dc065a585509cc55f3eeb457e89f4356ab112a6c8347e1209bb6b37f7f865a1f3589f3f4aae07158a8e842874e735e46ebbb1566a689c7
7
+ data.tar.gz: d82eb3375db6a20ac410051da9e476b50193b1a72337660a87bc8931d56b674369bb4f1bc9909511b85183f16949a854cdbed6301884db8c59c1016a8b6fa53d
@@ -227,7 +227,7 @@ Style/StringLiteralsInInterpolation:
227
227
  EnforcedStyle: double_quotes
228
228
 
229
229
  Style/TrailingCommaInArguments:
230
- EnforcedStyleForMultiline: comma
230
+ Enabled: false
231
231
 
232
232
  Style/TrailingCommaInArrayLiteral:
233
233
  EnforcedStyleForMultiline: comma
@@ -0,0 +1,48 @@
1
+ language: ruby
2
+ os: linux
3
+ dist: bionic
4
+ services:
5
+ - mysql
6
+ addons:
7
+ postgresql: "10"
8
+ cache:
9
+ bundler: true
10
+ yarn: true
11
+ directories:
12
+ - /home/travis/.webdrivers/
13
+ rvm:
14
+ - 2.6.6
15
+ - 2.7.1
16
+
17
+ before_script:
18
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
19
+ - chmod +x ./cc-test-reporter
20
+ - ./cc-test-reporter before-build
21
+ - nvm use 12
22
+
23
+ script: bundle exec rake
24
+
25
+ after_script:
26
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
27
+
28
+ jobs:
29
+ include:
30
+ - language: node_js
31
+ node_js: 12
32
+ install: yarn install
33
+ script: yarn jest --coverage
34
+ env: NODE_ENV=test
35
+ before_script: skip
36
+ after_script: skip
37
+
38
+ env:
39
+ global:
40
+ CC_TEST_REPORTER_ID=bca4349e32f97919210ac8a450b04904b90683fcdd57d65a22c0f5065482bc22
41
+ jobs:
42
+ - DB=mysql RAILS_VERSION=5.2
43
+ - DB=mysql RAILS_VERSION=6.0
44
+ - DB=postgresql RAILS_VERSION=5.2
45
+ - DB=postgresql RAILS_VERSION=6.0
46
+ notifications:
47
+ slack:
48
+ secure: QzOFw1Ph69pzwWBFgtIVkOnjbcRxB9HPRQ+RYjK+2tg+fsbiTJ+wYgHcZL49tPYcLAls4kymkFWzWBF3PCAXJMfKgUCqXzdQ2FuJC/JoVRTLll4wDnZFPG33jsm5tVznmycZ3ma4+ZWfJQ+C+elEBOba6v1kG9eGIy6sH2cvXfE=
@@ -1,5 +1,22 @@
1
- ## 5.0.0 (unreleased)
2
-
1
+ ## 5.0.1 (2020-09-29)
2
+
3
+ - Better image alt text support [#1940](https://github.com/AlchemyCMS/alchemy_cms/pull/1940) ([tvdeyen](https://github.com/tvdeyen))
4
+
5
+ ## 5.0.0 (2020-07-17)
6
+
7
+ - Do not convert JPEG images into JPG [#1904](https://github.com/AlchemyCMS/alchemy_cms/pull/1904) ([tvdeyen](https://github.com/tvdeyen))
8
+ - Do not enable image cropper if file is missing [#1903](https://github.com/AlchemyCMS/alchemy_cms/pull/1903) ([tvdeyen](https://github.com/tvdeyen))
9
+ - Always show original image as zoomed image [#1902](https://github.com/AlchemyCMS/alchemy_cms/pull/1902) ([tvdeyen](https://github.com/tvdeyen))
10
+ - Rename Attachment#urlname into slug [#1848](https://github.com/AlchemyCMS/alchemy_cms/pull/1848) ([tvdeyen](https://github.com/tvdeyen))
11
+ - Deprecate toolbar helper ([tvdeyen](https://github.com/tvdeyen))
12
+ - Deprecate redirect_to_public_child ([tvdeyen](https://github.com/tvdeyen))
13
+ - Add --auto-accept option to installer ([tvdeyen](https://github.com/tvdeyen))
14
+ - Move all installer code into install generator ([tvdeyen](https://github.com/tvdeyen))
15
+ - Language Factory: Create default language in host app's locale [#1884](https://github.com/AlchemyCMS/alchemy_cms/pull/1884) ([mamhoff](https://github.com/mamhoff))
16
+ - Respect filter and tagging params in picture archive size buttons [#1880](https://github.com/AlchemyCMS/alchemy_cms/pull/1880) ([tvdeyen](https://github.com/tvdeyen))
17
+ - Extract picture thumbnail sizes in a constant [#1879](https://github.com/AlchemyCMS/alchemy_cms/pull/1879) ([tvdeyen](https://github.com/tvdeyen))
18
+ - Configurable Image Preprocessor [#1878](https://github.com/AlchemyCMS/alchemy_cms/pull/1878) ([tvdeyen](https://github.com/tvdeyen))
19
+ - Configure edit page preview per site [#1877](https://github.com/AlchemyCMS/alchemy_cms/pull/1877) ([tvdeyen](https://github.com/tvdeyen))
3
20
  - Fix Page tree sorting after root page removal [#1876](https://github.com/AlchemyCMS/alchemy_cms/pull/1876) ([tvdeyen](https://github.com/tvdeyen))
4
21
  - 5.0 Upgrader fixes [#1874](https://github.com/AlchemyCMS/alchemy_cms/pull/1874) ([tvdeyen](https://github.com/tvdeyen))
5
22
  - Remove url_nesting config [#1872](https://github.com/AlchemyCMS/alchemy_cms/pull/1872) ([tvdeyen](https://github.com/tvdeyen))
data/Gemfile CHANGED
@@ -10,10 +10,10 @@ if ENV["DB"].nil? || ENV["DB"] == "sqlite"
10
10
  gem "sqlite3", "~> 1.4.1"
11
11
  end
12
12
  gem "mysql2", "~> 0.5.1" if ENV["DB"] == "mysql"
13
- gem "pg", "~> 1.0" if ENV["DB"] == "postgresql"
13
+ gem "pg", "~> 1.0" if ENV["DB"] == "postgresql"
14
14
 
15
15
  group :development, :test do
16
- if ENV["GITHUB_ACTIONS"]
16
+ if ENV["TRAVIS"]
17
17
  gem "sassc", "~> 2.4.0" # https://github.com/sass/sassc-ruby/issues/146
18
18
  else
19
19
  gem "launchy"
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # AlchemyCMS
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/alchemy_cms.svg)](http://badge.fury.io/rb/alchemy_cms)
4
- [![Build Status](https://github.com/AlchemyCMS/alchemy_cms/workflows/CI/badge.svg?branch=master)](https://github.com/AlchemyCMS/alchemy_cms/actions)
4
+ [![Build Status](https://travis-ci.com/AlchemyCMS/alchemy_cms.svg?branch=master)](https://travis-ci.com/AlchemyCMS/alchemy_cms)
5
5
  [![Maintainability](https://api.codeclimate.com/v1/badges/196c56c56568ed24a697/maintainability)](https://codeclimate.com/github/AlchemyCMS/alchemy_cms/maintainability)
6
6
  [![Test Coverage](https://api.codeclimate.com/v1/badges/196c56c56568ed24a697/test_coverage)](https://codeclimate.com/github/AlchemyCMS/alchemy_cms/test_coverage)
7
7
  [![Depfu](https://badges.depfu.com/badges/ebe56d2dd7b7044a8ae700cc81212a8e/overview.svg)](https://depfu.com/github/AlchemyCMS/alchemy_cms?project_id=4600)
@@ -125,7 +125,7 @@ $ bundle add alchemy-devise
125
125
  Then run the `alchemy-devise` installer:
126
126
 
127
127
  ```bash
128
- $ bin/rails g alchemy_devise:install
128
+ $ bin/rails g alchemy:devise:install
129
129
  ```
130
130
 
131
131
  ##### Use your User model
@@ -167,7 +167,7 @@ Please follow [this guide](http://guides.alchemy-cms.com/stable/custom_authentic
167
167
  **After** you set the user model you need to run the Alchemy install task:
168
168
 
169
169
  ```bash
170
- $ bin/rake alchemy:install
170
+ $ bin/rails alchemy:install
171
171
  ```
172
172
 
173
173
  Now everything should be set up and you should be able to visit the Alchemy Dashboard at:
data/Rakefile CHANGED
@@ -39,16 +39,17 @@ namespace :alchemy do
39
39
  namespace :spec do
40
40
  desc "Prepares database for testing Alchemy"
41
41
  task :prepare do
42
- result = system <<~BASH
43
- cd spec/dummy && \
44
- export RAILS_ENV=test && \
45
- bin/rake db:create && \
46
- bin/rake db:environment:set && \
47
- bin/rake db:migrate:reset && \
48
- bin/rails g alchemy:install --skip --skip-demo-files && \
49
- cd -
50
- BASH
51
- result || fail
42
+ system(
43
+ <<~BASH
44
+ cd spec/dummy && \
45
+ export RAILS_ENV=test && \
46
+ bin/rake db:create && \
47
+ bin/rake db:environment:set && \
48
+ bin/rake db:migrate:reset && \
49
+ bin/rails g alchemy:install --skip --skip-demo-files --auto-accept && \
50
+ cd -
51
+ BASH
52
+ ) || fail
52
53
  end
53
54
  end
54
55
 
@@ -45,7 +45,7 @@ Gem::Specification.new do |gem|
45
45
 
46
46
  gem.add_development_dependency 'capybara', ['~> 3.0']
47
47
  gem.add_development_dependency 'capybara-screenshot', ['~> 1.0']
48
- gem.add_development_dependency 'factory_bot_rails', ['~> 5.0']
48
+ gem.add_development_dependency 'factory_bot_rails', ['~> 6.0']
49
49
  gem.add_development_dependency 'puma', ['~> 4.0']
50
50
  gem.add_development_dependency 'rails-controller-testing', ['~> 1.0']
51
51
  gem.add_development_dependency 'rspec-activemodel-mocks', ['~> 1.0']
@@ -286,5 +286,6 @@
286
286
  color: $muted-text-color;
287
287
  margin-right: $default-margin;
288
288
  font-size: $small-font-size;
289
+ line-height: 31px;
289
290
  }
290
291
  }
@@ -3,14 +3,14 @@
3
3
  padding-bottom: 138px;
4
4
 
5
5
  &.filtered {
6
- padding-bottom: 164px;
6
+ padding-bottom: 178px;
7
7
  }
8
8
 
9
9
  &.with_filter_bar {
10
10
  padding-bottom: 218px;
11
11
 
12
12
  &.filtered {
13
- padding-bottom: 244px;
13
+ padding-bottom: 256px;
14
14
  }
15
15
  }
16
16
 
@@ -138,7 +138,7 @@ module Alchemy
138
138
 
139
139
  def link
140
140
  @attachments = Attachment.all.collect { |f|
141
- [f.name, download_attachment_path(id: f.id, name: f.urlname)]
141
+ [f.name, download_attachment_path(id: f.id, name: f.slug)]
142
142
  }
143
143
  end
144
144
 
@@ -314,6 +314,8 @@ module Alchemy
314
314
  end
315
315
  end
316
316
 
317
+ deprecate toolbar: "Please use `content_for(:toolbar)` instead", deprecator: Alchemy::Deprecation
318
+
317
319
  # (internal) Used by upload form
318
320
  def new_asset_path_with_session_information(asset_type)
319
321
  session_key = Rails.application.config.session_options[:key]
@@ -4,12 +4,10 @@ module Alchemy
4
4
  module Admin
5
5
  module PicturesHelper
6
6
  def preview_size(size)
7
- case size
8
- when "small" then "80x60"
9
- when "large" then "240x180"
10
- else
11
- "160x120"
12
- end
7
+ Alchemy::Picture::THUMBNAIL_SIZES.fetch(
8
+ size,
9
+ Alchemy::Picture::THUMBNAIL_SIZES[:medium]
10
+ )
13
11
  end
14
12
  end
15
13
  end
@@ -26,12 +26,12 @@ module Alchemy
26
26
 
27
27
  # Returns the path for downloading an alchemy attachment
28
28
  def download_alchemy_attachment_path(attachment)
29
- alchemy.download_attachment_path(attachment, attachment.urlname)
29
+ alchemy.download_attachment_path(attachment, attachment.slug)
30
30
  end
31
31
 
32
32
  # Returns the url for downloading an alchemy attachment
33
33
  def download_alchemy_attachment_url(attachment)
34
- alchemy.download_attachment_url(attachment, attachment.urlname)
34
+ alchemy.download_attachment_url(attachment, attachment.slug)
35
35
  end
36
36
 
37
37
  # Returns the full url containing host, page and anchor for the given element
@@ -77,10 +77,13 @@ module Alchemy
77
77
  end
78
78
 
79
79
  # An url save filename without format suffix
80
- def urlname
80
+ def slug
81
81
  CGI.escape(file_name.gsub(/\.#{extension}$/, "").tr(".", " "))
82
82
  end
83
83
 
84
+ alias_method :urlname, :slug
85
+ deprecate urlname: :slug, deprecator: Alchemy::Deprecation
86
+
84
87
  # Checks if the attachment is restricted, because it is attached on restricted pages only
85
88
  def restricted?
86
89
  pages.any? && pages.not_restricted.blank?
@@ -23,7 +23,7 @@ module Alchemy
23
23
 
24
24
  routes.download_attachment_path(
25
25
  id: attachment.id,
26
- name: attachment.urlname,
26
+ name: attachment.slug,
27
27
  format: attachment.suffix,
28
28
  )
29
29
  end
@@ -143,7 +143,7 @@ module Alchemy
143
143
  picture.can_be_cropped_to(
144
144
  content.settings[:size],
145
145
  content.settings[:upsample],
146
- )
146
+ ) && !!picture.image_file
147
147
  end
148
148
 
149
149
  def crop_values_present?
@@ -55,7 +55,7 @@ module Alchemy
55
55
  def img_tag
56
56
  @_img_tag ||= image_tag(
57
57
  essence.picture_url(options.except(*DEFAULT_OPTIONS.keys)), {
58
- alt: essence.alt_tag.presence,
58
+ alt: alt_text,
59
59
  title: essence.title.presence,
60
60
  class: caption ? nil : essence.css_class.presence,
61
61
  srcset: srcset.join(", ").presence,
@@ -79,5 +79,9 @@ module Alchemy
79
79
  width.present? ? "#{url} #{width}w" : "#{url} #{height}h"
80
80
  end
81
81
  end
82
+
83
+ def alt_text
84
+ essence.alt_tag.presence || html_options.delete(:alt) || essence.picture.name&.humanize
85
+ end
82
86
  end
83
87
  end
@@ -22,6 +22,12 @@
22
22
 
23
23
  module Alchemy
24
24
  class Picture < BaseRecord
25
+ THUMBNAIL_SIZES = {
26
+ small: "80x60",
27
+ medium: "160x120",
28
+ large: "240x180",
29
+ }.with_indifferent_access.freeze
30
+
25
31
  CONVERTIBLE_FILE_FORMATS = %w(gif jpg jpeg png).freeze
26
32
 
27
33
  include Alchemy::NameConversions
@@ -50,12 +56,25 @@ module Alchemy
50
56
  raise PictureInUseError, Alchemy.t(:cannot_delete_picture_notice) % { name: name }
51
57
  end
52
58
 
59
+ # Image preprocessing class
60
+ def self.preprocessor_class
61
+ @_preprocessor_class ||= Preprocessor
62
+ end
63
+
64
+ # Set a image preprocessing class
65
+ #
66
+ # # config/initializers/alchemy.rb
67
+ # Alchemy::Picture.preprocessor_class = My::ImagePreprocessor
68
+ #
69
+ def self.preprocessor_class=(klass)
70
+ @_preprocessor_class = klass
71
+ end
72
+
53
73
  # Enables Dragonfly image processing
54
74
  dragonfly_accessor :image_file, app: :alchemy_pictures do
55
75
  # Preprocess after uploading the picture
56
- after_assign do |p|
57
- resize = Config.get(:preprocess_image_resize)
58
- p.thumb!(resize) if resize.present?
76
+ after_assign do |image|
77
+ self.class.preprocessor_class.new(image).call
59
78
  end
60
79
  end
61
80
 
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ class Picture < BaseRecord
5
+ class Preprocessor
6
+ def initialize(image_file)
7
+ @image_file = image_file
8
+ end
9
+
10
+ # Preprocess images after upload
11
+ #
12
+ # Define preprocessing options in the Alchemy::Config
13
+ #
14
+ # preprocess_image_resize [String] - Downsizing example: '1000x1000>'
15
+ #
16
+ def call
17
+ max_image_size = Alchemy::Config.get(:preprocess_image_resize)
18
+ image_file.thumb!(max_image_size) if max_image_size.present?
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :image_file
24
+ end
25
+ end
26
+ end
@@ -71,7 +71,9 @@ module Alchemy
71
71
 
72
72
  encoding_options = []
73
73
 
74
- if target_format =~ /jpe?g/
74
+ convert_format = target_format != image_file_format.sub("jpeg", "jpg")
75
+
76
+ if target_format =~ /jpe?g/ && convert_format
75
77
  quality = options[:quality] || Config.get(:output_image_jpg_quality)
76
78
  encoding_options << "-quality #{quality}"
77
79
  end
@@ -80,7 +82,7 @@ module Alchemy
80
82
  encoding_options << "-flatten"
81
83
  end
82
84
 
83
- convertion_needed = target_format != image_file_format || encoding_options.present?
85
+ convertion_needed = convert_format || encoding_options.present?
84
86
 
85
87
  if has_convertible_format? && convertion_needed
86
88
  image = image.encode(target_format, encoding_options.join(" "))
@@ -14,7 +14,12 @@
14
14
  <div class="button_with_label">
15
15
  <%= link_to(
16
16
  render_icon('search-minus'),
17
- alchemy.admin_pictures_path(size: "small", q: search_filter_params[:q]),
17
+ alchemy.admin_pictures_path(
18
+ size: "small",
19
+ q: search_filter_params[:q],
20
+ filter: search_filter_params[:filter],
21
+ tagged_with: search_filter_params[:tagged_with]
22
+ ),
18
23
  title: Alchemy.t(:small_thumbnails),
19
24
  class: "icon_button"
20
25
  ) %>
@@ -22,7 +27,12 @@
22
27
  <div class="button_with_label">
23
28
  <%= link_to(
24
29
  render_icon('search'),
25
- alchemy.admin_pictures_path(size: "medium", q: search_filter_params[:q]),
30
+ alchemy.admin_pictures_path(
31
+ size: "medium",
32
+ q: search_filter_params[:q],
33
+ filter: search_filter_params[:filter],
34
+ tagged_with: search_filter_params[:tagged_with]
35
+ ),
26
36
  title: Alchemy.t(:medium_thumbnails),
27
37
  class: "icon_button"
28
38
  ) %>
@@ -30,7 +40,12 @@
30
40
  <div class="button_with_label">
31
41
  <%= link_to(
32
42
  render_icon('search-plus'),
33
- alchemy.admin_pictures_path(size: "large", q: search_filter_params[:q]),
43
+ alchemy.admin_pictures_path(
44
+ size: "large",
45
+ q: search_filter_params[:q],
46
+ filter: search_filter_params[:filter],
47
+ tagged_with: search_filter_params[:tagged_with]
48
+ ),
34
49
  title: Alchemy.t(:big_thumbnails),
35
50
  class: "icon_button"
36
51
  ) %>
@@ -1,5 +1,5 @@
1
1
  <div class="zoomed-picture-background">
2
- <%= image_tag @picture.url(format: @picture.image_file_format) %>
2
+ <%= image_tag @picture.url %>
3
3
  </div>
4
4
 
5
5
  <div class="picture-overlay-navigation">
@@ -1,29 +1,28 @@
1
1
  <% label_title = Alchemy.t("Create #{resource_name}", default: Alchemy.t('Create')) %>
2
2
 
3
- <% toolbar(
4
- buttons: [
5
- {
6
- icon: :plus,
7
- label: label_title,
8
- url: new_resource_path,
3
+ <% content_for(:toolbar) do %>
4
+ <%= toolbar_button(
5
+ icon: :plus,
6
+ label: label_title,
7
+ url: new_resource_path,
8
+ title: label_title,
9
+ hotkey: 'alt+n',
10
+ dialog_options: {
9
11
  title: label_title,
10
- hotkey: 'alt+n',
11
- dialog_options: {
12
- title: label_title,
13
- size: resource_window_size
14
- },
15
- if_permitted_to: [:create, resource_model]
12
+ size: resource_window_size
16
13
  },
17
- {
18
- icon: 'download',
19
- url: resource_url_proxy.url_for(action: 'index', format: 'csv', q: search_filter_params[:q], sort: params[:sort]),
20
- label: Alchemy.t(:download_csv),
21
- title: Alchemy.t(:download_csv),
22
- dialog: false,
23
- if_permitted_to: [:index, resource_model]
24
- }
25
- ]
26
- ) %>
14
+ if_permitted_to: [:create, resource_model]
15
+ ) %>
16
+ <%= toolbar_button(
17
+ icon: :download,
18
+ url: resource_url_proxy.url_for(action: 'index', format: 'csv', q: search_filter_params[:q], sort: params[:sort]),
19
+ label: Alchemy.t(:download_csv),
20
+ title: Alchemy.t(:download_csv),
21
+ dialog: false,
22
+ if_permitted_to: [:index, resource_model]
23
+ ) %>
24
+ <%= render 'alchemy/admin/partials/search_form' %>
25
+ <% end %>
27
26
 
28
27
  <div id="archive_all" class="resources-table-wrapper<%= ' with_tag_filter' if resource_has_tags || resource_has_filters %>">
29
28
  <%= render 'alchemy/admin/resources/table_header' %>
@@ -1,5 +1,5 @@
1
- <%= alchemy_form_for site, url: alchemy.admin_sites_path(site, search_filter_params) do |f| %>
2
- <%= f.input :host, hint: resource_handler.help_text_for(name: :host).html_safe %>
1
+ <%= alchemy_form_for site, url: resource_path(site, search_filter_params) do |f| %>
2
+ <%= f.input :host, hint: resource_handler.help_text_for(name: :host)&.html_safe %>
3
3
  <%= f.input :name %>
4
4
  <%= f.input :public %>
5
5
  <%= f.input :aliases, hint: resource_handler.help_text_for(name: :aliases), input_html: {rows: 4} %>
@@ -7,7 +7,7 @@
7
7
  attachment.name,
8
8
  alchemy.download_attachment_path(
9
9
  attachment,
10
- name: attachment.urlname,
10
+ name: attachment.slug,
11
11
  format: attachment.suffix
12
12
  ),
13
13
  {
@@ -55,6 +55,16 @@ items_per_page: 15
55
55
  # auth:
56
56
  # username: <%= ENV["BASIC_AUTH_USERNAME"] %>
57
57
  # password: <%= ENV["BASIC_AUTH_PASSWORD"] %>
58
+ #
59
+ # Preview config per site is supported as well.
60
+ #
61
+ # preview:
62
+ # My site name:
63
+ # host: https://www.my-static-site.com
64
+ # auth:
65
+ # username: <%= ENV["BASIC_AUTH_USERNAME"] %>
66
+ # password: <%= ENV["BASIC_AUTH_PASSWORD"] %>
67
+ #
58
68
 
59
69
  # === Picture rendering settings
60
70
  #
@@ -19,19 +19,31 @@ module Alchemy
19
19
  # username: <%= ENV["BASIC_AUTH_USERNAME"] %>
20
20
  # password: <%= ENV["BASIC_AUTH_PASSWORD"] %>
21
21
  #
22
+ # Preview config per site is supported as well.
23
+ #
24
+ # == Example config/alchemy/config.yml
25
+ #
26
+ # preview:
27
+ # My site name:
28
+ # host: https://www.my-static-site.com
29
+ # auth:
30
+ # username: <%= ENV["BASIC_AUTH_USERNAME"] %>
31
+ # password: <%= ENV["BASIC_AUTH_PASSWORD"] %>
32
+ #
22
33
  class PreviewUrl
23
34
  class MissingProtocolError < StandardError; end
24
35
 
25
36
  def initialize(routes:)
26
37
  @routes = routes.url_helpers
27
- @preview_config = Alchemy::Config.get(:preview)
28
38
  end
29
39
 
30
40
  def url_for(page)
31
- if preview_config
41
+ @preview_config = preview_config_for(page)
42
+
43
+ if @preview_config && uri
32
44
  uri_class.build(
33
45
  host: uri.host,
34
- path: "/#{page.urlname}",
46
+ path: page.url_path,
35
47
  userinfo: userinfo,
36
48
  ).to_s
37
49
  else
@@ -41,10 +53,19 @@ module Alchemy
41
53
 
42
54
  private
43
55
 
44
- attr_reader :preview_config, :routes
56
+ attr_reader :routes
57
+
58
+ def preview_config_for(page)
59
+ preview_config = Alchemy::Config.get(:preview)
60
+ return unless preview_config
61
+
62
+ preview_config[page.site.name] || preview_config
63
+ end
45
64
 
46
65
  def uri
47
- URI(preview_config["host"])
66
+ return unless @preview_config["host"]
67
+
68
+ URI(@preview_config["host"])
48
69
  end
49
70
 
50
71
  def uri_class
@@ -56,7 +77,7 @@ module Alchemy
56
77
  end
57
78
 
58
79
  def userinfo
59
- auth = preview_config["auth"]
80
+ auth = @preview_config["auth"]
60
81
  auth ? "#{auth["username"]}:#{auth["password"]}" : nil
61
82
  end
62
83
  end
@@ -31,7 +31,9 @@ module Alchemy
31
31
  # a value of nil means there is no new default
32
32
  # any not nil value is the new default
33
33
  def deprecated_configs
34
- {}
34
+ {
35
+ redirect_to_public_child: nil,
36
+ }
35
37
  end
36
38
 
37
39
  private
@@ -74,11 +76,11 @@ module Alchemy
74
76
  if deprecated_configs.key?(name.to_sym)
75
77
  config = deprecated_configs[name.to_sym]
76
78
  if config.nil?
77
- Alchemy::Deprecation.warn("#{name} configuration is deprecated and will be removed from Alchemy 5.0")
79
+ Alchemy::Deprecation.warn("#{name} configuration is deprecated and will be removed from Alchemy 5.1")
78
80
  else
79
81
  value = show[name.to_s]
80
82
  if value != config
81
- Alchemy::Deprecation.warn("Setting #{name} configuration to #{value} is deprecated and will be always #{config} in Alchemy 5.0")
83
+ Alchemy::Deprecation.warn("Setting #{name} configuration to #{value} is deprecated and will be always #{config} in Alchemy 5.1")
82
84
  end
83
85
  end
84
86
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Alchemy
3
- Deprecation = ActiveSupport::Deprecation.new("5.0", "Alchemy")
3
+ Deprecation = ActiveSupport::Deprecation.new("5.1", "Alchemy")
4
4
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+ require "thor"
3
+
4
+ module Alchemy
5
+ module Install
6
+ class Tasks < Thor
7
+ include Thor::Actions
8
+
9
+ no_tasks do
10
+ def inject_routes(auto_accept = false)
11
+ return if File.read("./config/routes.rb").match?("mount Alchemy::Engine")
12
+
13
+ mountpoint = "/"
14
+ unless auto_accept
15
+ mountpoint = ask("- At which path do you want to mount Alchemy CMS at?", default: mountpoint)
16
+ end
17
+ sentinel = /\.routes\.draw do(?:\s*\|map\|)?\s*$/
18
+ inject_into_file "./config/routes.rb", "\n mount Alchemy::Engine => '#{mountpoint}'\n", { after: sentinel, verbose: true }
19
+ end
20
+
21
+ def set_primary_language(auto_accept = false)
22
+ code = "en"
23
+ unless auto_accept
24
+ code = ask("- What is the language code of your site's primary language?", default: code)
25
+ end
26
+ name = "English"
27
+ unless auto_accept
28
+ name = ask("- What is the name of your site's primary language?", default: name)
29
+ end
30
+ gsub_file "./config/alchemy/config.yml", /default_language:\n\s\scode:\sen\n\s\sname:\sEnglish/m do
31
+ "default_language:\n code: #{code}\n name: #{name}"
32
+ end
33
+ end
34
+
35
+ def inject_seeder
36
+ append_file "./db/seeds.rb", "Alchemy::Seeder.seed!\n"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -210,7 +210,7 @@ module Alchemy
210
210
  @module_definition && @module_definition["engine_name"]
211
211
  end
212
212
 
213
- # Returns a help text for resource's form
213
+ # Returns a help text for resource's form or nil if no help text is available
214
214
  #
215
215
  # === Example:
216
216
  #
@@ -223,7 +223,7 @@ module Alchemy
223
223
  def help_text_for(attribute)
224
224
  ::I18n.translate!(attribute[:name], scope: [:alchemy, :resource_help_texts, resource_name])
225
225
  rescue ::I18n::MissingTranslationData
226
- false
226
+ nil
227
227
  end
228
228
 
229
229
  # Return attributes that should be viewable but not editable.
@@ -5,8 +5,8 @@ require "alchemy/test_support/factories/site_factory"
5
5
 
6
6
  FactoryBot.define do
7
7
  factory :alchemy_language, class: "Alchemy::Language" do
8
- name { "Deutsch" }
9
- code { "de" }
8
+ name { "Your Language" }
9
+ code { ::I18n.available_locales.first.to_s }
10
10
  default { true }
11
11
  frontpage_name { "Intro" }
12
12
  page_layout { Alchemy::Config.get(:default_language)["page_layout"] }
@@ -25,7 +25,12 @@ FactoryBot.define do
25
25
  trait :english do
26
26
  name { "English" }
27
27
  code { "en" }
28
- frontpage_name { "Intro" }
28
+ default { false }
29
+ end
30
+
31
+ trait :german do
32
+ name { "Deutsch" }
33
+ code { "de" }
29
34
  default { false }
30
35
  end
31
36
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alchemy
4
- VERSION = "5.0.0.beta1"
4
+ VERSION = "5.0.1"
5
5
 
6
6
  def self.version
7
7
  VERSION
@@ -1,11 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
  require "rails/generators"
3
+ require "alchemy/install/tasks"
3
4
 
4
5
  module Alchemy
5
6
  module Generators
6
7
  class InstallGenerator < ::Rails::Generators::Base
7
8
  desc "Installs Alchemy into your App."
8
9
 
10
+ class_option :auto_accept,
11
+ type: :boolean,
12
+ default: false,
13
+ desc: "Automatically accept defaults."
14
+
9
15
  class_option :skip_demo_files,
10
16
  type: :boolean,
11
17
  default: false,
@@ -18,6 +24,13 @@ module Alchemy
18
24
 
19
25
  source_root File.expand_path("files", __dir__)
20
26
 
27
+ def setup
28
+ header
29
+ say "Welcome to AlchemyCMS!"
30
+ say "Let's begin with some questions.\n\n"
31
+ install_tasks.inject_routes(options[:auto_accept])
32
+ end
33
+
21
34
  def copy_config
22
35
  copy_file "#{gem_config_path}/config.yml", app_config_path.join("alchemy", "config.yml")
23
36
  end
@@ -53,7 +66,11 @@ module Alchemy
53
66
  end
54
67
 
55
68
  def copy_dragonfly_config
56
- template "#{__dir__}/templates/dragonfly.rb.tt", app_config_path.join("initializers", "dragonfly.rb")
69
+ template(
70
+ "#{__dir__}/templates/dragonfly.rb.tt",
71
+ app_config_path.join("initializers", "dragonfly.rb"),
72
+ skip: options[:auto_accept]
73
+ )
57
74
  end
58
75
 
59
76
  def install_gutentag_migrations
@@ -80,8 +97,46 @@ module Alchemy
80
97
  app_root.join(webpack_config["source_path"], webpack_config["source_entry_path"], "alchemy/admin.js")
81
98
  end
82
99
 
100
+ def set_primary_language
101
+ header
102
+ install_tasks.set_primary_language(options[:auto_accept])
103
+ end
104
+
105
+ def setup_database
106
+ rake("db:create", abort_on_failure: true)
107
+ # We can't invoke this rake task, because Rails will use wrong engine names otherwise
108
+ rake("railties:install:migrations", abort_on_failure: true)
109
+ rake("db:migrate", abort_on_failure: true)
110
+ install_tasks.inject_seeder
111
+ rake("db:seed", abort_on_failure: true)
112
+ end
113
+
114
+ def finalize
115
+ header
116
+ say "Alchemy successfully installed!"
117
+ say "Now start the server with:\n\n"
118
+ say " bin/rails server\n\n"
119
+ say "and point your browser to\n\n"
120
+ say " http://localhost:3000/admin\n\n"
121
+ say "and follow the onscreen instructions to finalize the installation.\n\n"
122
+ end
123
+
83
124
  private
84
125
 
126
+ def header
127
+ return if options[:auto_accept]
128
+
129
+ puts "─────────────────────"
130
+ puts "* Alchemy Installer *"
131
+ puts "─────────────────────"
132
+ end
133
+
134
+ def say(something)
135
+ return if options[:auto_accept]
136
+
137
+ puts " #{something}"
138
+ end
139
+
85
140
  def gem_config_path
86
141
  @_config_path ||= File.expand_path("../../../../config/alchemy", __dir__)
87
142
  end
@@ -105,6 +160,10 @@ module Alchemy
105
160
  def app_root
106
161
  @_app_root ||= Rails.root
107
162
  end
163
+
164
+ def install_tasks
165
+ @_install_tasks ||= Alchemy::Install::Tasks.new
166
+ end
108
167
  end
109
168
  end
110
169
  end
@@ -1,59 +1,15 @@
1
1
  # frozen_string_literal: true
2
- require "thor"
3
-
4
- class Alchemy::InstallTask < Thor
5
- include Thor::Actions
6
-
7
- no_tasks do
8
- def inject_routes
9
- mountpoint = ask "\nAt which path do you want to mount Alchemy CMS at? (DEFAULT: At root path '/')"
10
- mountpoint = "/" if mountpoint.empty?
11
- sentinel = /\.routes\.draw do(?:\s*\|map\|)?\s*$/
12
- inject_into_file "./config/routes.rb", "\n mount Alchemy::Engine => '#{mountpoint}'\n", { after: sentinel, verbose: true }
13
- end
14
-
15
- def set_primary_language
16
- code = ask "\nWhat's the language code of your site's primary language? (DEFAULT: en)"
17
- code = "en" if code.empty?
18
- name = ask "What's the name of your site's primary language? (DEFAULT: English)"
19
- name = "English" if name.empty?
20
- gsub_file "./config/alchemy/config.yml", /default_language:\n\s\scode:\sen\n\s\sname:\sEnglish/m do
21
- "default_language:\n code: #{code}\n name: #{name}"
22
- end
23
- end
24
-
25
- def inject_seeder
26
- append_file "./db/seeds.rb", "Alchemy::Seeder.seed!\n"
27
- end
28
- end
29
- end
30
2
 
31
3
  namespace :alchemy do
32
4
  desc "Installs Alchemy CMS into your app."
33
- task install: "alchemy:yarn:install" do
34
- install_helper = Alchemy::InstallTask.new
35
-
36
- puts "\nAlchemy Installer"
37
- puts "-----------------"
38
-
39
- Rake::Task["alchemy:mount"].invoke
40
- system("rails g alchemy:install") || exit!(1)
41
- install_helper.set_primary_language
42
- Rake::Task["db:create"].invoke
43
- # We can't invoke this rake task, because Rails will use wrong engine names otherwise
44
- `bundle exec rake railties:install:migrations`
45
- Rake::Task["db:migrate"].invoke
46
- install_helper.inject_seeder
47
- Rake::Task["db:seed"].invoke
48
-
49
- puts "\nAlchemy successfully installed."
50
- puts "\nNow start the server with:"
51
- puts "\n$ bin/rails server"
52
- puts "\nand point your browser to http://localhost:3000/admin and follow the onscreen instructions to finalize the installation."
5
+ task :install do
6
+ require "generators/alchemy/install/install_generator"
7
+ Alchemy::Generators::InstallGenerator.start
53
8
  end
54
9
 
55
10
  desc "Mounts Alchemy into your routes."
56
11
  task :mount do
57
- Alchemy::InstallTask.new.inject_routes
12
+ require "alchemy/install/tasks"
13
+ Alchemy::InstallTasks.new.inject_routes
58
14
  end
59
15
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemy_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0.beta1
4
+ version: 5.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas von Deyen
@@ -10,10 +10,10 @@ authors:
10
10
  - Hendrik Mans
11
11
  - Carsten Fregin
12
12
  - Martin Meyerhoff
13
- autorequire:
13
+ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2020-06-11 00:00:00.000000000 Z
16
+ date: 2020-09-29 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: active_model_serializers
@@ -463,14 +463,14 @@ dependencies:
463
463
  requirements:
464
464
  - - "~>"
465
465
  - !ruby/object:Gem::Version
466
- version: '5.0'
466
+ version: '6.0'
467
467
  type: :development
468
468
  prerelease: false
469
469
  version_requirements: !ruby/object:Gem::Requirement
470
470
  requirements:
471
471
  - - "~>"
472
472
  - !ruby/object:Gem::Version
473
- version: '5.0'
473
+ version: '6.0'
474
474
  - !ruby/object:Gem::Dependency
475
475
  name: puma
476
476
  requirement: !ruby/object:Gem::Requirement
@@ -596,7 +596,6 @@ files:
596
596
  - ".github/ISSUE_TEMPLATE/Bug_report.md"
597
597
  - ".github/ISSUE_TEMPLATE/Feature_request.md"
598
598
  - ".github/PULL_REQUEST_TEMPLATE.md"
599
- - ".github/workflows/ci.yml"
600
599
  - ".github/workflows/greetings.yml"
601
600
  - ".github/workflows/stale.yml"
602
601
  - ".gitignore"
@@ -604,6 +603,7 @@ files:
604
603
  - ".localeapp/config.rb"
605
604
  - ".prettierrc"
606
605
  - ".rubocop.yml"
606
+ - ".travis.yml"
607
607
  - ".yardopts"
608
608
  - CHANGELOG.md
609
609
  - CODE_OF_CONDUCT.md
@@ -815,6 +815,7 @@ files:
815
815
  - app/models/alchemy/page/page_scopes.rb
816
816
  - app/models/alchemy/page/url_path.rb
817
817
  - app/models/alchemy/picture.rb
818
+ - app/models/alchemy/picture/preprocessor.rb
818
819
  - app/models/alchemy/picture/transformations.rb
819
820
  - app/models/alchemy/picture/url.rb
820
821
  - app/models/alchemy/site.rb
@@ -1086,6 +1087,7 @@ files:
1086
1087
  - lib/alchemy/forms/builder.rb
1087
1088
  - lib/alchemy/hints.rb
1088
1089
  - lib/alchemy/i18n.rb
1090
+ - lib/alchemy/install/tasks.rb
1089
1091
  - lib/alchemy/logger.rb
1090
1092
  - lib/alchemy/modules.rb
1091
1093
  - lib/alchemy/name_conversions.rb
@@ -1261,13 +1263,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
1261
1263
  version: 2.3.0
1262
1264
  required_rubygems_version: !ruby/object:Gem::Requirement
1263
1265
  requirements:
1264
- - - ">"
1266
+ - - ">="
1265
1267
  - !ruby/object:Gem::Version
1266
- version: 1.3.1
1268
+ version: '0'
1267
1269
  requirements:
1268
1270
  - ImageMagick (libmagick), v6.6 or greater.
1269
1271
  rubygems_version: 3.0.3
1270
- signing_key:
1272
+ signing_key:
1271
1273
  specification_version: 4
1272
1274
  summary: A powerful, userfriendly and flexible CMS for Rails
1273
1275
  test_files: []
@@ -1,134 +0,0 @@
1
- name: CI
2
-
3
- on: [push, pull_request]
4
-
5
- jobs:
6
- RSpec:
7
- runs-on: ubuntu-latest
8
- strategy:
9
- fail-fast: false
10
- matrix:
11
- rails:
12
- - '5.2'
13
- - '6.0'
14
- ruby:
15
- - '2.5.x'
16
- - '2.6.x'
17
- database:
18
- - mysql
19
- - postgresql
20
- env:
21
- DB: ${{ matrix.database }}
22
- DB_USER: alchemy_user
23
- DB_PASSWORD: password
24
- DB_HOST: '127.0.0.1'
25
- RAILS_ENV: test
26
- RAILS_VERSION: ${{ matrix.rails }}
27
- services:
28
- postgres:
29
- image: postgres:11
30
- env:
31
- POSTGRES_USER: alchemy_user
32
- POSTGRES_PASSWORD: password
33
- POSTGRES_DB: alchemy_cms_dummy_test
34
- ports: ['5432:5432']
35
- options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
36
- mysql:
37
- image: mysql:latest
38
- ports: ['3306:3306']
39
- env:
40
- MYSQL_USER: alchemy_user
41
- MYSQL_PASSWORD: password
42
- MYSQL_DATABASE: alchemy_cms_dummy_test
43
- MYSQL_ROOT_PASSWORD: password
44
- options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=5
45
- steps:
46
- - uses: actions/checkout@v1
47
- - name: Set up Ruby
48
- uses: actions/setup-ruby@v1
49
- with:
50
- ruby-version: ${{ matrix.ruby }}
51
- - name: Restore apt cache
52
- id: apt-cache
53
- uses: actions/cache@preview
54
- with:
55
- path: /home/runner/apt/cache
56
- key: ${{ runner.os }}-apt-${{ matrix.database }}
57
- restore-keys: |
58
- ${{ runner.os }}-apt-
59
- - name: Install Postgres headers
60
- if: matrix.database == 'postgresql'
61
- run: |
62
- mkdir -p /home/runner/apt/cache
63
- sudo apt update -qq
64
- sudo apt install -qq --fix-missing libpq-dev -o dir::cache::archives="/home/runner/apt/cache"
65
- sudo chown -R runner /home/runner/apt/cache
66
- - name: Install MySQL headers
67
- if: matrix.database == 'mysql'
68
- run: |
69
- mkdir -p /home/runner/apt/cache
70
- sudo apt update -qq
71
- sudo apt install -qq --fix-missing libmysqlclient-dev -o dir::cache::archives="/home/runner/apt/cache"
72
- sudo chown -R runner /home/runner/apt/cache
73
- - name: Install bundler
74
- run: |
75
- gem install bundler
76
- - name: Restore Ruby Gems cache
77
- id: cache
78
- uses: actions/cache@preview
79
- with:
80
- path: vendor/bundle
81
- key: ${{ runner.os }}-bundle-${{ matrix.ruby }}-${{ matrix.rails }}-${{ matrix.database }}-${{ hashFiles('**/Gemfile') }}
82
- restore-keys: |
83
- ${{ runner.os }}-bundle-
84
- - name: Install bundle
85
- timeout-minutes: 10
86
- run: |
87
- bundle install --jobs 4 --retry 3 --path vendor/bundle
88
- - name: Restore node modules cache
89
- id: yarn-cache
90
- uses: actions/cache@preview
91
- with:
92
- path: spec/dummy/node_modules
93
- key: ${{ runner.os }}-yarn-dummy-${{ hashFiles('./package.json') }}
94
- restore-keys: |
95
- ${{ runner.os }}-yarn-dummy-
96
- - name: Prepare database
97
- run: |
98
- bundle exec rake alchemy:spec:prepare
99
- - name: Run tests & publish code coverage
100
- uses: paambaati/codeclimate-action@v2.5.7
101
- env:
102
- CC_TEST_REPORTER_ID: bca4349e32f97919210ac8a450b04904b90683fcdd57d65a22c0f5065482bc22
103
- with:
104
- coverageCommand: bundle exec rspec
105
- - uses: actions/upload-artifact@master
106
- if: failure()
107
- with:
108
- name: Screenshots
109
- path: spec/dummy/tmp/screenshots
110
- Jest:
111
- runs-on: ubuntu-latest
112
- env:
113
- NODE_ENV: test
114
- steps:
115
- - uses: actions/checkout@v1
116
- - name: Restore node modules cache
117
- uses: actions/cache@preview
118
- with:
119
- path: node_modules
120
- key: ${{ runner.os }}-yarn-${{ hashFiles('./package.json') }}
121
- restore-keys: |
122
- ${{ runner.os }}-yarn-
123
- - name: Install yarn
124
- run: yarn install
125
- - name: Run jest
126
- run: yarn jest
127
- - name: Run jest & publish code coverage
128
- uses: paambaati/codeclimate-action@v2.5.7
129
- env:
130
- CC_TEST_REPORTER_ID: bca4349e32f97919210ac8a450b04904b90683fcdd57d65a22c0f5065482bc22
131
- with:
132
- coverageLocations:
133
- ./coverage/lcov.info:lcov
134
- coverageCommand: yarn jest --collectCoverage --coverageDirectory=coverage