Elixir CI Cache Key: Typo & Management Issue?

by Viktoria Ivanova 46 views

Hey guys,

We've got a situation brewing in our Elixir CI setup, and I wanted to get your thoughts on it. We've been rocking the ultimate-elixir-ci configuration for a few months now, and it's been smooth sailing for the most part. But recently, I hit a snag when I needed to manually expire the hex cache. Let me tell you, the cache key threw me for a loop!

The Mystery of the Cache Key

Digging into the configuration file (ultimate-elixir-ci action.yml), I stumbled upon something that seems a bit off. The cache key for the hex packages looks like this:

key: build-${{ runner.os }}-${{ inputs.otp-version }}-${{ inputs.elixir-version }}-${{ hashFiles('**/mix.lock') }}

Now, here's where the confusion kicks in. We're using the build- prefix, which seems more fitting for the _build/ directory cache. Should this actually be hex-? It feels like a typo, right?

The Missing inputs.cache-key

But the plot thickens! The cache key doesn't include the inputs.cache-key value. This is a problem because we use inputs.cache-key to manually expire caches. Without it, we're stuck! The _build/ cache key, on the other hand, does include inputs.cache-key, making it easy to expire. This inconsistency makes it super tricky to differentiate between the caches in the GitHub Actions UI. More importantly, it makes manually expiring the hex cache a near-impossible task.

Diving Deeper into the Problem

To really understand the impact, let's break down why this cache key setup is causing headaches. The current configuration essentially lumps the hex package cache together with the build cache under the same build- prefix, but without the crucial inputs.cache-key component. This means:

  1. Confusion in the UI: When you look at your GitHub Actions, you see multiple caches with the build- prefix, making it hard to quickly identify which one is specifically for hex packages.
  2. Impossible Manual Expiration: The biggest issue is that you can't force a refresh of the hex package cache by simply changing the inputs.cache-key. This is because the current key doesn't incorporate this input, so any changes to inputs.cache-key won't affect the hex cache's key.

Why Manual Cache Expiration Matters

You might be wondering, why is manual cache expiration so important? Well, there are several scenarios where it becomes a lifesaver:

  • Dependency Updates: When you update your dependencies in mix.exs and run mix deps.get, you want to ensure that your CI environment reflects these changes. If the hex package cache isn't properly invalidated, you might end up with stale dependencies, leading to build errors or unexpected behavior.
  • Resolving Corrupted Cache Issues: Sometimes, caches can become corrupted due to various reasons. In such cases, manually expiring the cache is the quickest way to get your builds back on track.
  • Testing with Different Dependency Sets: You might want to test your application with different sets of dependencies, for example, to check compatibility or performance. Manual cache expiration allows you to easily switch between these sets.

Proposed Solution

So, what's the fix? I'm thinking we should update the hex key to something like this:

key: hex-${{ inputs.cache-key }}-${{ runner.os }}-${{ inputs.otp-version }}-${{ inputs.elixir-version }}-${{ hashFiles('**/mix.lock') }}

Let's break down why this proposed solution makes sense:

  • Distinct Prefix: By changing the prefix to hex-, we immediately create a clear separation between the hex package cache and the build cache. This makes it easier to identify and manage the caches in the GitHub Actions UI.
  • Inclusion of inputs.cache-key: Adding inputs.cache-key to the key gives us the ability to manually expire the hex cache. By changing the value of inputs.cache-key in our workflow configuration, we can force a cache refresh, ensuring that we're always using the latest dependencies.
  • Comprehensive Key: The proposed key includes all the relevant factors that should trigger a cache invalidation: the cache key input, the operating system, OTP and Elixir versions, and the mix.lock file. This ensures that the cache is only invalidated when necessary, optimizing build times.

Benefits of the Proposed Solution

Implementing this change would bring several key benefits:

  • Clear Cache Identification: The hex- prefix makes it immediately clear which cache is for hex packages, simplifying management and troubleshooting.
  • Manual Cache Expiration: The inclusion of inputs.cache-key allows for easy manual expiration, crucial for dependency updates and resolving cache issues.
  • Consistency: The hex cache key would align with the build cache key in terms of including inputs.cache-key, providing a consistent and predictable caching behavior.

Let's Discuss!

What do you guys think? Am I on the right track here? I'm open to suggestions and other ideas. Let's get this sorted out and make our Elixir CI setup even better!