#! /usr/bin/env ruby # frozen_string_literal: true # It's important that our JS asset builds are reproducible so that users aren't forced to re-download # assets after every deploy. This script runs two builds and compares the output to ensure that they # are identical. require "digest" DIST_DIR = File.expand_path("#{__dir__}/../app/assets/javascripts/discourse/dist") def collect_asset_info files = Dir.glob("**/*", base: DIST_DIR).reject { |path| File.directory? "#{DIST_DIR}/#{path}" }.sort puts "Found #{files.length} files" raise "No files found" if files.empty? digests = files.map { |file| Digest::MD5.file("#{DIST_DIR}/#{file}").hexdigest } { files: files, digests: digests } end puts "Running first build..." system "#{__dir__}/../bin/yarn-app ember build -prod", exception: true first_build_info = collect_asset_info puts "Running second build..." system "#{__dir__}/../bin/yarn-app ember build -prod", exception: true second_build_info = collect_asset_info puts nil, nil, "Comparing builds...", nil, nil if first_build_info[:files] != second_build_info[:files] puts "Set of files is different" new_assets = first_build_info[:files].difference(second_build_info[:files]) puts "Second build had additional assets: #{new_assets.inspect}" missing_assets = second_build_info[:files].difference(first_build_info[:files]) puts "Second build was missing assets: #{missing_assets.inspect}" exit 1 else puts "Both builds produced the same file names" end if first_build_info[:digests] != second_build_info[:digests] puts "File digests are different" first_build_info[:files].each_with_index do |file, index| if first_build_info[:digests][index] != second_build_info[:digests][index] puts "File #{file} has different digest" end end exit 1 else puts "Files in both builds had identical digests" end puts nil, "Success!"