2020-03-19 11:09:41 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'fileutils'
|
|
|
|
|
|
|
|
module Tasks
|
|
|
|
module Gitlab
|
|
|
|
module Assets
|
2021-06-22 11:06:55 -04:00
|
|
|
FOSS_ASSET_FOLDERS = %w[app/assets fixtures/emojis vendor/assets/javascripts].freeze
|
|
|
|
EE_ASSET_FOLDERS = %w[ee/app/assets].freeze
|
2021-10-13 17:09:56 -04:00
|
|
|
JH_ASSET_FOLDERS = %w[jh/app/assets].freeze
|
2020-03-19 11:09:41 -04:00
|
|
|
JS_ASSET_PATTERNS = %w[*.js config/**/*.js].freeze
|
|
|
|
JS_ASSET_FILES = %w[package.json yarn.lock].freeze
|
2022-01-20 13:14:18 -05:00
|
|
|
MASTER_SHA256_HASH_FILE = 'master-assets-hash.txt'
|
|
|
|
HEAD_SHA256_HASH_FILE = 'assets-hash.txt'
|
2020-03-19 11:09:41 -04:00
|
|
|
PUBLIC_ASSETS_WEBPACK_DIR = 'public/assets/webpack'
|
|
|
|
|
2022-01-20 13:14:18 -05:00
|
|
|
def self.sha256_of_assets_impacting_webpack_compilation
|
2020-03-19 11:09:41 -04:00
|
|
|
start_time = Time.now
|
|
|
|
asset_files = assets_impacting_webpack_compilation
|
2022-01-20 13:14:18 -05:00
|
|
|
puts "Generating the SHA256 hash for #{assets_impacting_webpack_compilation.size} Webpack-related assets..."
|
2020-03-19 11:09:41 -04:00
|
|
|
|
2022-01-20 13:14:18 -05:00
|
|
|
asset_file_sha256s = asset_files.map do |asset_file|
|
|
|
|
Digest::SHA256.file(asset_file).hexdigest
|
2020-03-19 11:09:41 -04:00
|
|
|
end
|
|
|
|
|
2022-01-20 13:14:18 -05:00
|
|
|
Digest::SHA256.hexdigest(asset_file_sha256s.join).tap { |sha256| puts "=> SHA256 generated in #{Time.now - start_time}: #{sha256}" }
|
2020-03-19 11:09:41 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.assets_impacting_webpack_compilation
|
|
|
|
assets_folders = FOSS_ASSET_FOLDERS
|
|
|
|
assets_folders += EE_ASSET_FOLDERS if ::Gitlab.ee?
|
2021-10-13 17:09:56 -04:00
|
|
|
assets_folders += JH_ASSET_FOLDERS if ::Gitlab.jh?
|
2020-03-19 11:09:41 -04:00
|
|
|
|
|
|
|
asset_files = Dir.glob(JS_ASSET_PATTERNS)
|
|
|
|
asset_files += JS_ASSET_FILES
|
|
|
|
|
|
|
|
assets_folders.each do |folder|
|
|
|
|
asset_files.concat(Dir.glob(["#{folder}/**/*.*"]))
|
|
|
|
end
|
|
|
|
|
|
|
|
asset_files
|
|
|
|
end
|
2022-09-12 11:14:03 -04:00
|
|
|
|
2020-03-19 11:09:41 -04:00
|
|
|
private_class_method :assets_impacting_webpack_compilation
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-01-27 13:58:50 -05:00
|
|
|
namespace :gitlab do
|
|
|
|
namespace :assets do
|
|
|
|
desc 'GitLab | Assets | Compile all frontend assets'
|
2019-01-21 14:20:38 -05:00
|
|
|
task :compile do
|
|
|
|
require_dependency 'gitlab/task_helpers'
|
|
|
|
|
|
|
|
%w[
|
|
|
|
yarn:check
|
|
|
|
gettext:po_to_json
|
|
|
|
rake:assets:precompile
|
2020-03-19 11:09:41 -04:00
|
|
|
gitlab:assets:compile_webpack_if_needed
|
2019-01-21 14:20:38 -05:00
|
|
|
gitlab:assets:fix_urls
|
2020-08-26 14:11:43 -04:00
|
|
|
gitlab:assets:check_page_bundle_mixins_css_for_sideeffects
|
2020-03-19 11:09:41 -04:00
|
|
|
].each(&::Gitlab::TaskHelpers.method(:invoke_and_time_task))
|
|
|
|
end
|
|
|
|
|
|
|
|
desc 'GitLab | Assets | Compile all Webpack assets'
|
|
|
|
task :compile_webpack_if_needed do
|
2022-01-20 13:14:18 -05:00
|
|
|
FileUtils.mv(Tasks::Gitlab::Assets::HEAD_SHA256_HASH_FILE, Tasks::Gitlab::Assets::MASTER_SHA256_HASH_FILE, force: true)
|
2020-03-19 11:09:41 -04:00
|
|
|
|
2022-01-20 13:14:18 -05:00
|
|
|
master_assets_sha256 =
|
|
|
|
if File.exist?(Tasks::Gitlab::Assets::MASTER_SHA256_HASH_FILE)
|
|
|
|
File.read(Tasks::Gitlab::Assets::MASTER_SHA256_HASH_FILE)
|
2020-03-19 11:09:41 -04:00
|
|
|
else
|
|
|
|
'missing!'
|
|
|
|
end
|
|
|
|
|
2022-01-20 13:14:18 -05:00
|
|
|
head_assets_sha256 = Tasks::Gitlab::Assets.sha256_of_assets_impacting_webpack_compilation.tap do |sha256|
|
|
|
|
File.write(Tasks::Gitlab::Assets::HEAD_SHA256_HASH_FILE, sha256)
|
2020-03-19 11:09:41 -04:00
|
|
|
end
|
|
|
|
|
2022-01-20 13:14:18 -05:00
|
|
|
puts "Webpack assets SHA256 for `master`: #{master_assets_sha256}"
|
|
|
|
puts "Webpack assets SHA256 for `HEAD`: #{head_assets_sha256}"
|
2020-03-19 11:09:41 -04:00
|
|
|
|
|
|
|
public_assets_webpack_dir_exists = Dir.exist?(Tasks::Gitlab::Assets::PUBLIC_ASSETS_WEBPACK_DIR)
|
|
|
|
|
2022-01-20 13:14:18 -05:00
|
|
|
if head_assets_sha256 != master_assets_sha256 || !public_assets_webpack_dir_exists
|
2020-03-19 11:09:41 -04:00
|
|
|
FileUtils.rm_r(Tasks::Gitlab::Assets::PUBLIC_ASSETS_WEBPACK_DIR) if public_assets_webpack_dir_exists
|
2020-12-01 07:09:17 -05:00
|
|
|
|
2022-09-12 11:14:03 -04:00
|
|
|
log_path = ENV['WEBPACK_COMPILE_LOG_PATH']
|
|
|
|
|
|
|
|
cmd = 'yarn webpack'
|
|
|
|
cmd += " > #{log_path}" if log_path
|
|
|
|
|
|
|
|
unless system(cmd)
|
2020-12-01 07:09:17 -05:00
|
|
|
abort 'Error: Unable to compile webpack production bundle.'.color(:red)
|
|
|
|
end
|
2022-09-12 11:14:03 -04:00
|
|
|
|
|
|
|
puts "Written webpack stdout log to #{log_path}" if log_path
|
|
|
|
puts "You can inspect the webpack log here: #{ENV['CI_JOB_URL']}/artifacts/file/#{log_path}" if log_path && ENV['CI_JOB_URL']
|
2020-03-19 11:09:41 -04:00
|
|
|
end
|
2019-01-21 14:20:38 -05:00
|
|
|
end
|
2017-01-27 13:58:50 -05:00
|
|
|
|
|
|
|
desc 'GitLab | Assets | Clean up old compiled frontend assets'
|
2017-03-21 10:40:34 -04:00
|
|
|
task clean: ['rake:assets:clean']
|
2017-01-27 13:58:50 -05:00
|
|
|
|
|
|
|
desc 'GitLab | Assets | Remove all compiled frontend assets'
|
2017-03-21 10:40:34 -04:00
|
|
|
task purge: ['rake:assets:clobber']
|
2017-02-15 15:18:21 -05:00
|
|
|
|
|
|
|
desc 'GitLab | Assets | Uninstall frontend dependencies'
|
|
|
|
task purge_modules: ['yarn:clobber']
|
2017-01-27 13:58:50 -05:00
|
|
|
|
|
|
|
desc 'GitLab | Assets | Fix all absolute url references in CSS'
|
|
|
|
task :fix_urls do
|
|
|
|
css_files = Dir['public/assets/*.css']
|
2017-02-22 13:18:40 -05:00
|
|
|
css_files.each do |file|
|
2017-01-27 13:58:50 -05:00
|
|
|
# replace url(/assets/*) with url(./*)
|
|
|
|
puts "Fixing #{file}"
|
|
|
|
system "sed", "-i", "-e", 's/url(\([\"\']\?\)\/assets\//url(\1.\//g', file
|
|
|
|
|
|
|
|
# rewrite the corresponding gzip file (if it exists)
|
|
|
|
gzip = "#{file}.gz"
|
|
|
|
if File.exist?(gzip)
|
|
|
|
puts "Fixing #{gzip}"
|
|
|
|
|
|
|
|
FileUtils.rm(gzip)
|
|
|
|
mtime = File.stat(file).mtime
|
|
|
|
|
|
|
|
File.open(gzip, 'wb+') do |f|
|
|
|
|
gz = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION)
|
|
|
|
gz.mtime = mtime
|
|
|
|
gz.write IO.binread(file)
|
|
|
|
gz.close
|
|
|
|
|
|
|
|
File.utime(mtime, mtime, f.path)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-12-17 04:07:48 -05:00
|
|
|
|
|
|
|
desc 'GitLab | Assets | Compile vendor assets'
|
|
|
|
task :vendor do
|
|
|
|
unless system('yarn webpack-vendor')
|
|
|
|
abort 'Error: Unable to compile webpack DLL.'.color(:red)
|
|
|
|
end
|
|
|
|
end
|
2020-08-26 14:11:43 -04:00
|
|
|
|
|
|
|
desc 'GitLab | Assets | Check that scss mixins do not introduce any sideffects'
|
|
|
|
task :check_page_bundle_mixins_css_for_sideeffects do
|
|
|
|
system('./scripts/frontend/check_page_bundle_mixins_css_for_sideeffects.js')
|
|
|
|
end
|
2017-01-27 13:58:50 -05:00
|
|
|
end
|
|
|
|
end
|