Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Caching requirements works only first time #25

Open
Lipen opened this issue Feb 16, 2025 · 2 comments
Open

Caching requirements works only first time #25

Lipen opened this issue Feb 16, 2025 · 2 comments
Labels
bug Something isn't working

Comments

@Lipen
Copy link

Lipen commented Feb 16, 2025

I have the following setup:

- uses: typst-community/setup-typst@v4
  with:
    cache-dependency-path: requirements.typ

- run: typst compile ...

The requirements.typ looks as follows:

#import "@preview/numbly:0.1.0"
#import "@preview/cetz:0.3.2"
// and more

The cache of dependencies does not include the packages which I add to requirements.typ incrementally. This can be observed when running typst compile in the consequent workflow steps after a "successful cache hit".
For example, I have added wrap-it to requirements.typ, but still can see it being downloaded each time I compile:

> typst compile ...
downloading @preview/wrap-it:0.1.0
...

As far as I understand, the "problem" is in the following lines: https://github.com/typst-community/setup-typst/blob/main/src/main.ts#L92-L98
You are using typst-packages-${hash} as a primary key, and ["typst-packages-", "typst-"] as additional restore keys. When I add something to requirements.typ, its hash changes, and the cache lookup misses on the primary key. However, it hits on the restore key "typst-packages-", restoring the previous cache, lacking the newly added packages. After that, cacheKey != undefined, and the action interprets is as OK situation, without trying to refine the deps and re-upload the cache. But I would expect the cache to be updated each time I add something to requirements.typ.

I would be nice to distinguish between "hit on primary key, no need to update cache" vs "hit on restore key, probably need to update the cache". However I do not see such functionality in actions/cache -- it either returns the key on any hit, or undefined on a miss -- so probably you will have to do two separate restoreCache queries.

Actually, when we miss on the primary cache (with hash), we do not even need to try to restore the previous one: it is probably better to simply re-download all deps from skratch using the updated requirements.typ, since some deps could be removed and do not need to be cached anymore.

@yusancky yusancky added the bug Something isn't working label Feb 16, 2025
@yusancky
Copy link
Member

Thank you for raising this issue and providing a detailed explanation of the problem. I really appreciate your effort in helping us improve the action!

The issue arises from restoreKeys: when requirements.typ is modified, the hash changes, causing the primary cache key to miss. However, the action hits on restoreKeys, restoring an outdated cache without the new packages, leading it to incorrectly assume the cache is valid.

The core issue stems from the use of restoreKeys: when requirements.typ is modified, the hash changes, causing the primaryKey to miss. However, the action still hits on restoreKeys, restoring an older cache. This leads to the action incorrectly assuming the cache is valid, even though it’s outdated.

The reason we use a hash derived from requirements.typ is to ensure the cache is specific to the exact set of dependencies required at any given time. This is especially important in repo that might use multiple actions for different Typst files with different dependency requirements. If we simply uploaded the latest cache without considering the hash, unnecessary packages could be retained in the cache, even if they’re no longer needed. Additionally, GitHub automatically removes cache entries that haven’t been accessed in over 7 days, so any outdated caches tied to old requirements.typ files will eventually be removed.

To address this, I propose removing restoreKeys entirely. By only matching the primaryKey, we can ensure the cache is only used when it exactly matches the current requirements.typ. This avoids restoring outdated caches while keeping the implementation simple and robust. I believe this approach effectively resolves the issue.

I’d love to hear your thoughts—does this solution align with your expectations?

@Lipen
Copy link
Author

Lipen commented Feb 16, 2025

Yes, removing restore keys and relying only on a primary key (with hash) seems like a good solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants