Umbraco-CMS icon indicating copy to clipboard operation
Umbraco-CMS copied to clipboard

"AppDomain" cachebuster still uses the value of "Version" in it's generated URLs.

Open shropgov-neil opened this issue 1 year ago • 15 comments

Which Umbraco version are you using? (Please write the exact version, example: 10.1.0)

12.3.1

Bug summary

The generated URL for a Smidge bundle will always use the "Umbraco.CMS.RuntimeMinification.Version" value, regardless of the value of "Umbraco.CMS.RuntimeMinification.CacheBuster".

Specifics

I've had an ongoing issue since v10 where all my bundles are generated with the URL "/sb/{bundle}.v1.{css/js}", despite "CacheBuster" being set to "AppDomain" - the only way to change "v1" is to set the "Umbraco.CMS.RuntimeMinification.Version" value manually.

We do not want to be setting the version string manually, but need the URL to change on each deploy to avoid browsers aggressivly caching out of date assets.

It doesn't matter what value I set "CacheBuster" to (AppDomain or Timestamp), the version value will always be the value of "Version" (or "v1", if you leave it blank).

This happens in both Debug and Production, and the values of "Umbraco.CMS.RuntimeMinification.UseInMemoryCache" and "Umbraco.CMS.RuntimeMinification.KeepFileExtensions" do not make a difference.

Steps to reproduce

Create a custom Smidge bundle (with SmidgeHelper.Create{Js/Css}Bundle()), add at least one file to the bundle (with Require{Js/Css}()).

Set "Umbraco.CMS.RuntimeMinification.CacheBuster" to "AppDomain". Do not set a value for ""Umbraco.CMS.RuntimeMinification.Version".

Render the reference with one of the SmidgeLinkTagHelper / SmidgeScriptTagHelper, with debug set to false.

Check the href/src value outputted in the source code.

Try setting a value of Version (while keeping it set to "AppDomain"), and check the source again.

Expected result / actual result

I would expect to see a unique filename for every cycle of the AppPool, what I actually see is "style.v1.css" every single time (or whatever the value of "Version" is).


This item has been added to our backlog AB#35172

shropgov-neil avatar Nov 08 '23 15:11 shropgov-neil

Hi there @shropgov-neil!

Firstly, a big thank you for raising this issue. Every piece of feedback we receive helps us to make Umbraco better.

We really appreciate your patience while we wait for our team to have a look at this but we wanted to let you know that we see this and share with you the plan for what comes next.

  • We'll assess whether this issue relates to something that has already been fixed in a later version of the release that it has been raised for.
  • If it's a bug, is it related to a release that we are actively supporting or is it related to a release that's in the end-of-life or security-only phase?
  • We'll replicate the issue to ensure that the problem is as described.
  • We'll decide whether the behavior is an issue or if the behavior is intended.

We wish we could work with everyone directly and assess your issue immediately but we're in the fortunate position of having lots of contributions to work with and only a few humans who are able to do it. We are making progress though and in the meantime, we will keep you in the loop and let you know when we have any questions.

Thanks, from your friendly Umbraco GitHub bot :robot: :slightly_smiling_face:

github-actions[bot] avatar Nov 08 '23 15:11 github-actions[bot]

I've done some more digging and it appears it's something to do with not passing the configuration options to the native smidge functions - so the built in SmidgeHelper isn't using them.

I trawled the source code and found an undocumented Umbraco.Cms.Web.Common.RuntimeMinification.SmidgeRuntimeMinifier which re-implements CreateCssBundle and CreateJsBundle for the back office - if I inject this into my view and use those functions, the files are generated with the correct AppDomain cachebuster. This then works for the first page load, but subsequent page loads crash with "The bundle name {bundle} already exists" which persists until the cache is cleared.

Can we either get the config options passed to the native functions, or (if this is the supported way to do it) get the SmidgeRuntimeMinifier method documented somewhere?

shropgov-neil avatar Nov 08 '23 16:11 shropgov-neil

Thank you for raising this issue. I was pulling my hair out about this myself as well. I hope this can be fixed soon.

dhymik avatar Nov 17 '23 09:11 dhymik

If it helps, as a workaround I created my own service, injected IRuntimeMinifier and IBundleManager so that I could overload the functions to check the bundles didn't already exist before creating them. Then just injected that into my view to keep that cleaner.

Seems awfully hacky, but it works until a proper documented resolution is provided.

shropgov-neil avatar Nov 17 '23 09:11 shropgov-neil

A slightly better, but no less hacky fix was to go back to using the proper SmidgeHelper class, but with this in Startup.cs

  services.Configure<SmidgeOptions>(options =>
      {
        string cachebuster = _config.GetSection("Umbraco:CMS:RuntimeMinification").GetValue<string>("CacheBuster") ?? "AppDomain";
        Type cacheBusterType = Enum.Parse<RuntimeMinificationCacheBuster>(cachebuster) switch
        {
          RuntimeMinificationCacheBuster.AppDomain => typeof(AppDomainLifetimeCacheBuster),
          RuntimeMinificationCacheBuster.Version => typeof(ConfigCacheBuster),
          RuntimeMinificationCacheBuster.Timestamp => typeof(TimestampCacheBuster),
          _ => throw new NotImplementedException(),
        };

        options.DefaultBundleOptions.DebugOptions.FileWatchOptions.Enabled = true;
        options.DefaultBundleOptions.DebugOptions.SetCacheBusterType(cacheBusterType);
        options.DefaultBundleOptions.ProductionOptions.SetCacheBusterType(cacheBusterType);
        options.DefaultBundleOptions.ProductionOptions.ProcessAsCompositeFile = true;
      });

Hope that helps someone while we wait for an official answer.

shropgov-neil avatar Nov 17 '23 15:11 shropgov-neil

  • [x] verified on v10 and v12
  • version number stays the same when using AppDomain cachebuster
  • doesn't matter if you use the smidge taghelper or the umbraco generic wrapper
<link rel="stylesheet" href="pageBundle" debug="false"/>
@Html.Raw(await runtimeMinifier.RenderCssHereAsync("pageBundle"))

Migaroez avatar Nov 20 '23 10:11 Migaroez

Any news here ?

nhaberl avatar Jan 23 '24 08:01 nhaberl

Hi, Also not seeing caching being updated when "AppDomain" set and restarting an application pool.

thenexus00 avatar Feb 08 '24 07:02 thenexus00

❌ There was a problem linking to Azure Boards work item(s):

  • 35172

Please check the IDs and try again using the AB# syntax. Learn more

azure-boards[bot] avatar Feb 08 '24 08:02 azure-boards[bot]

❌ There was a problem linking to Azure Boards work item(s):

  • 35172

Please check the IDs and try again using the AB# syntax. Learn more

azure-boards[bot] avatar Feb 08 '24 09:02 azure-boards[bot]

❌ There was a problem linking to Azure Boards work item(s):

  • 35172

Please check the IDs and try again using the AB# syntax. Learn more

azure-boards[bot] avatar Feb 08 '24 10:02 azure-boards[bot]

❌ There was a problem linking to Azure Boards work item(s):

  • 35172

Please check the IDs and try again using the AB# syntax. Learn more

azure-boards[bot] avatar Feb 08 '24 11:02 azure-boards[bot]

❌ There was a problem linking to Azure Boards work item(s):

  • 35172

Please check the IDs and try again using the AB# syntax. Learn more

azure-boards[bot] avatar Feb 08 '24 12:02 azure-boards[bot]

@UmbracoHQ Can someone pelase disable the azure-boards bot (or fix the issue) so we're not getting spammed hourly?

shropgov-neil avatar Feb 08 '24 12:02 shropgov-neil

A slightly better, but no less hacky fix was to go back to using the proper SmidgeHelper class, but with this in Startup.cs

  services.Configure<SmidgeOptions>(options =>
      {
        string cachebuster = _config.GetSection("Umbraco:CMS:RuntimeMinification").GetValue<string>("CacheBuster") ?? "AppDomain";
        Type cacheBusterType = Enum.Parse<RuntimeMinificationCacheBuster>(cachebuster) switch
        {
          RuntimeMinificationCacheBuster.AppDomain => typeof(AppDomainLifetimeCacheBuster),
          RuntimeMinificationCacheBuster.Version => typeof(ConfigCacheBuster),
          RuntimeMinificationCacheBuster.Timestamp => typeof(TimestampCacheBuster),
          _ => throw new NotImplementedException(),
        };

        options.DefaultBundleOptions.DebugOptions.FileWatchOptions.Enabled = true;
        options.DefaultBundleOptions.DebugOptions.SetCacheBusterType(cacheBusterType);
        options.DefaultBundleOptions.ProductionOptions.SetCacheBusterType(cacheBusterType);
        options.DefaultBundleOptions.ProductionOptions.ProcessAsCompositeFile = true;
      });

Hope that helps someone while we wait for an official answer.

This code helped me. Thanks! I'm actually using "Version" mode but I'm wondering if there's also a way I could also influence the version number instead of using what's in the appConfig. I'm trying to obtain it from a SharedAssembly class.

kikodev714 avatar Feb 13 '24 09:02 kikodev714