Precompiled assets with digest strings are ignored in CI
While debugging gitlab-org/gitlab-ce!14533 I ran across a strange revelation. While we currently pre-compile our sprockets-managed static assets in the prepare
CI stage, these assets are not actually served in our RSpec feature tests.
Assets with digest strings (e.g. application-8c49f0a0dd1c10e71c936541134af1f0b9a8faaa13b70dbe86e33d8b2a0cbf1d.css
) are being generated, but the asset paths being output in our test environment don't match them (e.g. application.css
). This causes sprockets to re-generate them on-demand, potentially wasting a ton of time in our later CI steps.
From the original discussion:
the pre-compiled assets from the prepare CI step were being ignored (except the webpack ones which use their own manifest) because when the sprockets
assets:precompile
task is run, digests are always included in the filenames regardless of theconfig.assets.digest
setting, but when asset paths were generated in our haml views using rails helpers, theconfig.assets.digest = false
setting was honored meaning the precompiled assets have digest strings and the generated paths did not.the reason the tests didn't all blow up before is because
config.assets.compile = true
for development and test environments, meaning sprockets will see a request for something like/assets/application.css
and when the asset doesn't already exist it will lazily compile it on-demand.I've removed the
config.assets.digest = false
setting and addedconfig.assets.compile = false
for the test environment when run in CI. This means it should now use the precompiled assets instead of generating them on-demand (this might just save a TON of cpu cycles in our rspec test suite!)The errors we're now seeing in the pipeline are due to tests which were written presuming digest strings do not exist. e.g.
1) Projects::JobsController GET status.json return a detailed job status in json Failure/Error: expect(json_response['favicon']).to eq "/assets/ci_favicons/#{status.favicon}.ico" expected: "/assets/ci_favicons/favicon_status_pending.ico" got: "/assets/ci_favicons/favicon_status_pending-5ecc554aa46a62bdb293a698e37f1fa6e2eda95f130ef8a311a5d800147ba257.ico"
I think we ought to update these failing tests manually, to account for the presence of digest strings. The potential performance improvement vastly outweighs the inconvenience of fixing these tests.
Solution:
We remove config.assets.digest = false
from our test environment config, and we conditionally add config.assets.compile = false
when it is run in CI. This will ensure that:
- Assets will not be compiled on-demand (and errors will be thrown for malformed asset paths)
- Asset paths will correctly match those generated in the precompile process
A few tests which assumed non-digest paths will need to be corrected, but this should not be a problem.