diff --git a/.gitignore b/.gitignore index efcb4365403..73ada7f4c7d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ .generators *.pyc *.rbc +*.sassc **.orig .bundle .byebug_history diff --git a/Gemfile b/Gemfile index a4e3b0438af..9cbb44f0a69 100644 --- a/Gemfile +++ b/Gemfile @@ -44,7 +44,6 @@ gem 'pg' gem 'phonelib' gem 'premailer-rails', '>= 1.12.0' gem 'profanity_filter' -gem 'propshaft' gem 'rack', '>= 2.2.3.1' gem 'rack-attack', '>= 6.2.1' gem 'rack-cors', '>= 1.0.5', require: 'rack/cors' @@ -62,6 +61,7 @@ gem 'safe_target_blank', '>= 1.0.2' gem 'saml_idp', github: '18F/saml_idp', tag: '0.18.2-18f' gem 'scrypt' gem 'simple_form', '>= 5.0.2' +gem 'sprockets-rails' gem 'stringex', require: false gem 'strong_migrations', '>= 0.4.2' gem 'subprocess', require: false @@ -85,7 +85,6 @@ group :development do gem 'guard-rspec', require: false gem 'irb' gem 'letter_opener', '~> 1.8' - gem 'listen' gem 'octokit', '>= 4.25.0' gem 'rack-mini-profiler', '>= 1.1.3', require: false gem 'rails-erd', '>= 1.6.0' diff --git a/Gemfile.lock b/Gemfile.lock index 36f61680e8d..ca2dafb71fd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -451,11 +451,6 @@ GEM net-smtp premailer (~> 1.7, >= 1.7.9) profanity_filter (0.1.1) - propshaft (0.7.0) - actionpack (>= 7.0.0) - activesupport (>= 7.0.0) - rack - railties (>= 7.0.0) pry (0.14.1) coderay (~> 1.1) method_source (~> 1.0) @@ -640,6 +635,13 @@ GEM simpleidn (0.2.1) unf (~> 0.1.4) smart_properties (1.17.0) + sprockets (4.0.2) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-rails (3.4.2) + actionpack (>= 5.2) + activesupport (>= 5.2) + sprockets (>= 3.0.0) stringex (2.8.5) strong_migrations (0.8.0) activerecord (>= 5.2) @@ -764,7 +766,6 @@ DEPENDENCIES jwt knapsack letter_opener (~> 1.8) - listen lograge (>= 0.11.2) lookbook (~> 1.5.3) lru_redux @@ -780,7 +781,6 @@ DEPENDENCIES phonelib premailer-rails (>= 1.12.0) profanity_filter - propshaft pry-byebug pry-doc pry-rails @@ -819,6 +819,7 @@ DEPENDENCIES simplecov (~> 0.21.0) simplecov-cobertura simplecov_json_formatter + sprockets-rails stringex strong_migrations (>= 0.4.2) subprocess diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js new file mode 100644 index 00000000000..6b147d7d533 --- /dev/null +++ b/app/assets/config/manifest.js @@ -0,0 +1,10 @@ +//= link_tree ../images +//= link_tree ../fonts + +//= link intl-tel-input/build/css/intlTelInput.css +//= link intl-tel-input/build/img/flags.png +//= link intl-tel-input/build/img/flags@2x.png + +//= link_tree ../../../node_modules/@18f/identity-design-system/dist/assets/img +//= link_tree ../../../node_modules/@18f/identity-design-system/dist/assets/fonts +//= link_tree ../builds diff --git a/app/assets/stylesheets/_required.scss b/app/assets/stylesheets/_required.scss index 3862fa94264..248473430ec 100644 --- a/app/assets/stylesheets/_required.scss +++ b/app/assets/stylesheets/_required.scss @@ -1,7 +1,7 @@ @use 'uswds-core' with ( $theme-body-font-size: 'sm', - $theme-font-path: '', - $theme-image-path: '', + $theme-font-path: '.', + $theme-image-path: '@18f/identity-design-system/dist/assets/img', $theme-global-border-box-sizing: true, $theme-global-link-styles: true, $theme-grid-container-max-width: 'tablet-lg', diff --git a/app/assets/stylesheets/components/_alert.scss b/app/assets/stylesheets/components/_alert.scss index fc35acaffb5..506cafceb76 100644 --- a/app/assets/stylesheets/components/_alert.scss +++ b/app/assets/stylesheets/components/_alert.scss @@ -6,7 +6,7 @@ font-weight: bold; &::before { - background-image: url('/alert/info-white.svg'); + background-image: url('alert/info-white.svg'); } } diff --git a/app/assets/stylesheets/components/_icon.scss b/app/assets/stylesheets/components/_icon.scss index 708d8447270..05b22f6a71d 100644 --- a/app/assets/stylesheets/components/_icon.scss +++ b/app/assets/stylesheets/components/_icon.scss @@ -28,7 +28,7 @@ $icon-min-padding: 2px; &-success { &::before { - background-image: url('/alert/success.svg'); + background-image: url('alert/success.svg'); content: ''; display: block; height: $h4; diff --git a/app/assets/stylesheets/components/_language-picker.scss b/app/assets/stylesheets/components/_language-picker.scss index 5910f030e92..e6d14f6823b 100644 --- a/app/assets/stylesheets/components/_language-picker.scss +++ b/app/assets/stylesheets/components/_language-picker.scss @@ -66,10 +66,10 @@ } &::after { - background-image: url('/angle-arrow-up.svg'); + background-image: url(@18f/identity-design-system/dist/assets/img/angle-arrow-up.svg); @include at-media('tablet') { - background-image: url('/angle-arrow-up-white.svg'); + background-image: url(@18f/identity-design-system/dist/assets/img/angle-arrow-up-white.svg); } } } @@ -79,7 +79,7 @@ color: color('white'); &::after { - background-image: url('/angle-arrow-down-white.svg'); + background-image: url(@18f/identity-design-system/dist/assets/img/angle-arrow-down-white.svg); } } } diff --git a/app/assets/stylesheets/components/_list.scss b/app/assets/stylesheets/components/_list.scss index 389920d1e7b..5be58d778d2 100644 --- a/app/assets/stylesheets/components/_list.scss +++ b/app/assets/stylesheets/components/_list.scss @@ -3,7 +3,7 @@ padding: 1rem 1rem 1rem 0; &::before { - background-image: url('/alert/success.svg'); + background-image: url('alert/success.svg'); background-repeat: no-repeat; content: ''; display: inline-block; diff --git a/app/assets/stylesheets/components/_personal-key.scss b/app/assets/stylesheets/components/_personal-key.scss index c475e8c922f..27d55bc560e 100644 --- a/app/assets/stylesheets/components/_personal-key.scss +++ b/app/assets/stylesheets/components/_personal-key.scss @@ -2,7 +2,7 @@ .personal-key-block { @include u-padding-y(2); - background-image: url('/personal-key/pkey-block.svg'); + background-image: url('personal-key/pkey-block.svg'); background-position: center; background-repeat: no-repeat; @@ -28,7 +28,7 @@ .bg-personal-key { height: 145px; - background-image: url('/personal-key/shield.svg'); + background-image: url('personal-key/shield.svg'); background-position: center; background-repeat: no-repeat; background-size: 145px 145px; diff --git a/app/assets/stylesheets/components/_phone-input.scss b/app/assets/stylesheets/components/_phone-input.scss index b9a1deec9fd..07f0e973b95 100644 --- a/app/assets/stylesheets/components/_phone-input.scss +++ b/app/assets/stylesheets/components/_phone-input.scss @@ -8,11 +8,11 @@ lg-phone-input { } .iti__flag { - background-image: url('/flags.png'); + background-image: url('intl-tel-input/build/img/flags.png'); /* stylelint-disable-next-line media-feature-name-no-vendor-prefix */ @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { - background-image: url('/flags@2x.png'); + background-image: url('intl-tel-input/build/img/flags@2x.png'); } } diff --git a/app/assets/stylesheets/components/_step-indicator.scss b/app/assets/stylesheets/components/_step-indicator.scss index b10b9cb5212..95a3835e984 100644 --- a/app/assets/stylesheets/components/_step-indicator.scss +++ b/app/assets/stylesheets/components/_step-indicator.scss @@ -109,7 +109,7 @@ lg-step-indicator { .step-indicator__step--complete::before { background-color: color('white'); - background-image: url('/alert/success.svg'); + background-image: url('alert/success.svg'); } .step-indicator__step:not(:last-child)::after { diff --git a/app/components/icon_component.rb b/app/components/icon_component.rb index f0c679a5955..7976d647003 100644 --- a/app/components/icon_component.rb +++ b/app/components/icon_component.rb @@ -1,4 +1,6 @@ class IconComponent < BaseComponent + include AssetHelper + # See: https://github.com/uswds/uswds/tree/develop/src/img/usa-icons ICONS = %i[ accessibility_new @@ -254,7 +256,7 @@ def initialize(icon:, **tag_options) end def icon_path - asset_path([asset_path('sprite.svg'), '#', icon].join, host: asset_host) + asset_path([design_system_asset_path('img/sprite.svg'), '#', icon].join, host: asset_host) end private diff --git a/app/components/phone_input_component.html.erb b/app/components/phone_input_component.html.erb index a6d5ce7ecf9..24a495525de 100644 --- a/app/components/phone_input_component.html.erb +++ b/app/components/phone_input_component.html.erb @@ -53,4 +53,4 @@ }, ) %> <% end %> -<%= stylesheet_link_tag 'intlTelInput' %> +<%= stylesheet_link_tag 'intl-tel-input/build/css/intlTelInput' %> diff --git a/app/decorators/service_provider_session_decorator.rb b/app/decorators/service_provider_session_decorator.rb index d6aeca42be5..83ad7cce508 100644 --- a/app/decorators/service_provider_session_decorator.rb +++ b/app/decorators/service_provider_session_decorator.rb @@ -42,8 +42,6 @@ def s3_logo_url(service_provider) def legacy_logo_url logo = sp_logo ActionController::Base.helpers.image_path("sp-logos/#{logo}") - rescue Propshaft::MissingAssetError - '' end def new_session_heading diff --git a/app/helpers/asset_helper.rb b/app/helpers/asset_helper.rb new file mode 100644 index 00000000000..4a4d013ca9c --- /dev/null +++ b/app/helpers/asset_helper.rb @@ -0,0 +1,7 @@ +module AssetHelper + DESIGN_SYSTEM_ASSET_ROOT = '@18f/identity-design-system/dist/assets'.freeze + + def design_system_asset_path(path) + File.join(DESIGN_SYSTEM_ASSET_ROOT, path) + end +end diff --git a/app/helpers/script_helper.rb b/app/helpers/script_helper.rb index b2da5680250..1f7ba137b16 100644 --- a/app/helpers/script_helper.rb +++ b/app/helpers/script_helper.rb @@ -39,7 +39,7 @@ def render_javascript_pack_once_tags(*names) private SAME_ORIGIN_ASSETS = %w[ - sprite.svg + @18f/identity-design-system/dist/assets/img/sprite.svg ].to_set.freeze def local_crossorigin_sources? diff --git a/app/javascript/packages/components/icon.tsx b/app/javascript/packages/components/icon.tsx index a0b57b7e74e..5bd6d85083c 100644 --- a/app/javascript/packages/components/icon.tsx +++ b/app/javascript/packages/components/icon.tsx @@ -1,6 +1,6 @@ import { getAssetPath } from '@18f/identity-assets'; -const SPRITE_URL = getAssetPath('sprite.svg'); +const SPRITE_URL = getAssetPath('@18f/identity-design-system/dist/assets/img/sprite.svg'); export type DesignSystemIcon = | 'accessibility_new' diff --git a/app/views/accounts/_unphishable_badge.html.erb b/app/views/accounts/_unphishable_badge.html.erb index d93bdfe0130..ff2873288ba 100644 --- a/app/views/accounts/_unphishable_badge.html.erb +++ b/app/views/accounts/_unphishable_badge.html.erb @@ -1,6 +1,6 @@
<%= image_tag( - asset_path('alerts/unphishable.svg'), + design_system_asset_path('img/alerts/unphishable.svg'), size: 16, class: 'text-middle', alt: '', diff --git a/app/views/accounts/_verified_account_badge.html.erb b/app/views/accounts/_verified_account_badge.html.erb index 7a4df1b1628..f43f4f70768 100644 --- a/app/views/accounts/_verified_account_badge.html.erb +++ b/app/views/accounts/_verified_account_badge.html.erb @@ -1,6 +1,6 @@
<%= image_tag( - asset_path('alerts/success.svg'), + design_system_asset_path('img/alerts/success.svg'), size: 16, class: 'text-middle', alt: '', diff --git a/app/views/layouts/base.html.erb b/app/views/layouts/base.html.erb index 302e2562f11..ca6388bd659 100644 --- a/app/views/layouts/base.html.erb +++ b/app/views/layouts/base.html.erb @@ -29,25 +29,25 @@ <%= csrf_meta_tags %> <%= favicon_link_tag( - asset_path('favicons/apple-touch-icon.png'), + design_system_asset_path('img/favicons/apple-touch-icon.png'), rel: 'apple-touch-icon', sizes: '180x180', type: 'image/png', ) %> <%= favicon_link_tag( - asset_path('favicons/favicon-40.png'), + design_system_asset_path('img/favicons/favicon-40.png'), rel: 'icon', sizes: '40x40', type: 'image/png', ) %> <%= favicon_link_tag( - asset_path('favicons/favicon-16.png'), + design_system_asset_path('img/favicons/favicon-16.png'), rel: 'icon', sizes: '16x16', type: 'image/png', ) %> <%= favicon_link_tag( - asset_path('favicons/safari-pinned-tab.svg'), + design_system_asset_path('img/favicons/safari-pinned-tab.svg'), rel: 'mask-icon', color: '#e21c3d', type: nil, diff --git a/app/views/shared/_banner-lock-icon.html.erb b/app/views/shared/_banner-lock-icon.html.erb index e4da7888a37..feef6e8ee5a 100644 --- a/app/views/shared/_banner-lock-icon.html.erb +++ b/app/views/shared/_banner-lock-icon.html.erb @@ -1,5 +1,5 @@ <%= image_tag( - asset_path('lock.svg'), + design_system_asset_path('img/lock.svg'), width: 9, height: 12, class: 'usa-banner__lock-image', diff --git a/config/application.rb b/config/application.rb index c788559fec9..cb186ffee26 100644 --- a/config/application.rb +++ b/config/application.rb @@ -5,6 +5,7 @@ require 'action_view/railtie' require 'action_mailer/railtie' require 'rails/test_unit/railtie' +require 'sprockets/railtie' require 'identity/logging/railtie' require_relative '../lib/asset_sources' @@ -55,6 +56,8 @@ class Application < Rails::Application config.load_defaults '7.0' config.active_record.belongs_to_required_by_default = false config.active_record.legacy_connection_handling = false + config.assets.unknown_asset_fallback = true + config.assets.resolve_assets_in_css_urls = true config.active_job.queue_adapter = :good_job FileUtils.mkdir_p(Rails.root.join('log')) diff --git a/config/environments/development.rb b/config/environments/development.rb index 928cceb38fc..1306d3da830 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -4,7 +4,10 @@ config.consider_all_requests_local = true config.active_support.deprecation = :log config.active_record.migration_error = :page_load - config.file_watcher = ActiveSupport::EventedFileUpdateChecker + config.assets.debug = true + config.assets.digest = true + config.assets.gzip = false + config.assets.raise_runtime_errors = true config.i18n.raise_on_missing_translations = true # Raise exceptions for disallowed deprecations. diff --git a/config/environments/production.rb b/config/environments/production.rb index 4935e502264..330ac83cb27 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -6,7 +6,14 @@ config.action_controller.perform_caching = true config.force_ssl = true - config.asset_host = IdentityConfig.store.asset_host.presence || IdentityConfig.store.domain_name + config.asset_host = proc do |_source, request| + # we want precompiled assets to have domain-agnostic URLs + # and request is nil during asset precompilation + (IdentityConfig.store.asset_host.presence || IdentityConfig.store.domain_name) if request + end + config.assets.compile = false + config.assets.digest = true + config.assets.gzip = false config.i18n.fallbacks = true config.active_support.deprecation = :notify config.active_record.dump_schema_after_migration = false diff --git a/config/environments/test.rb b/config/environments/test.rb index cc6088fca3c..7a3bb2b6afa 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -12,12 +12,15 @@ config.action_controller.allow_forgery_protection = false config.active_support.test_order = :random config.active_support.deprecation = :stderr + config.assets.gzip = false config.i18n.raise_on_missing_translations = true config.action_mailer.delivery_method = :test config.action_mailer.default_url_options = { host: IdentityConfig.store.domain_name } config.action_mailer.asset_host = IdentityConfig.store.mailer_domain_name + config.assets.debug = false + # Raise exceptions for disallowed deprecations. config.active_support.disallowed_deprecation = :raise @@ -29,6 +32,8 @@ config.action_controller.asset_host = ENV['RAILS_ASSET_HOST'] if ENV.key?('RAILS_ASSET_HOST') + config.assets.digest = ENV.key?('RAILS_DISABLE_ASSET_DIGEST') ? false : true + config.middleware.use RackSessionAccess::Middleware config.after_initialize do diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 9d43c2aae76..cc0cc161230 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -5,8 +5,13 @@ # Add additional assets to the asset load path Rails.application.config.assets.paths.push( - 'node_modules/intl-tel-input/build/img', - 'node_modules/intl-tel-input/build/css', - 'node_modules/@18f/identity-design-system/dist/assets/img', + 'node_modules', 'node_modules/@18f/identity-design-system/dist/assets/fonts', ) + +# Fix sassc sometimes segfaulting +Rails.application.config.assets.configure do |env| + env.export_concurrent = false +end + +Sprockets.export_concurrent = Rails.env.test? diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 0867ca17ede..b40fcaab89f 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -85,6 +85,14 @@ Use Control+X to save the file. Restart your Mac to cause the .plist to take effect. Check the limits again and you should see both `ulimit -n` and `launchctl limit maxfiles` return a limit of 524288. +### Errors related to _sassc_ + +If you are getting the error: +``` +LoadError: cannot load such file -- sassc +``` +Try `make run` for a short time, then use Ctrl+C to kill it + ### Errors relating to OpenSSL versions If you get this error during test runs: diff --git a/scripts/artifact-upload b/scripts/artifact-upload index 99eae75e51a..10b4c467914 100755 --- a/scripts/artifact-upload +++ b/scripts/artifact-upload @@ -33,7 +33,7 @@ branch_environments.map do |upload_environment| raise 'artifact copy failed' unless status.success? assets_sync_command = <<-CMD - aws s3 sync --size-only --cache-control max-age=31536000 --exclude ".manifest.json" public/assets s3://#{static_bucket}/assets + aws s3 sync --size-only --cache-control max-age=31536000 --exclude .sprockets-manifest-*.json public/assets s3://#{static_bucket}/assets CMD _output, status = Open3.capture2(assets_sync_command) raise 'assets sync failed' unless status.success? diff --git a/spec/helpers/asset_helper_spec.rb b/spec/helpers/asset_helper_spec.rb new file mode 100644 index 00000000000..3952a2b34f2 --- /dev/null +++ b/spec/helpers/asset_helper_spec.rb @@ -0,0 +1,23 @@ +require 'rails_helper' + +RSpec.describe AssetHelper do + include AssetHelper + + describe 'design_system_asset_path' do + let(:path) { 'img/example.png' } + + subject(:asset_path) { design_system_asset_path(path) } + + it 'produces an asset path' do + expect(asset_path).to eq('@18f/identity-design-system/dist/assets/img/example.png') + end + + context 'with leading slash' do + let(:path) { '/img/example.png' } + + it 'produces an asset path' do + expect(asset_path).to eq('@18f/identity-design-system/dist/assets/img/example.png') + end + end + end +end diff --git a/spec/helpers/script_helper_spec.rb b/spec/helpers/script_helper_spec.rb index 5e82355dd38..f0abd0d6489 100644 --- a/spec/helpers/script_helper_spec.rb +++ b/spec/helpers/script_helper_spec.rb @@ -32,7 +32,7 @@ allow(AssetSources).to receive(:get_sources).with('application', 'document-capture'). and_return(['/application.js', '/document-capture.js']) allow(AssetSources).to receive(:get_assets).with('application', 'document-capture'). - and_return(['clock.svg', 'sprite.svg']) + and_return(['clock.svg', '@18f/identity-design-system/dist/assets/img/sprite.svg']) end it 'prints asset paths sources' do @@ -43,7 +43,8 @@ visible: :all, text: { 'clock.svg' => 'http://test.host/clock.svg', - 'sprite.svg' => 'http://test.host/sprite.svg', + '@18f/identity-design-system/dist/assets/img/sprite.svg' => + 'http://test.host/@18f/identity-design-system/dist/assets/img/sprite.svg', }.to_json, ) end @@ -65,7 +66,8 @@ visible: :all, text: { 'clock.svg' => 'http://assets.example.com/clock.svg', - 'sprite.svg' => 'http://example.com/sprite.svg', + '@18f/identity-design-system/dist/assets/img/sprite.svg' => + 'http://example.com/@18f/identity-design-system/dist/assets/img/sprite.svg', }.to_json, ) end