Skip to content

Conversation

cprecioso
Copy link
Member

Resolves #2919

Context:

  • Caches can be shared from a base branch to its parent branch. For example, a PR can pick up the cache for main. They can't be shared the opposite direction, nor between any other branches. (docs)
  • Caches are evicted if either: (a) haven't been accessed in 7 days, or (b) the repo goes over the 10GB limit for caches (LRU evicted first). (docs)

Therefore:

  • We want to ensure the cache for our main branch is never stale and never at risk of being evicted. An evicted main cache means un-cached runs for all the PRs.
  • Caches for branches that have been merged are immediately no longer useful, so we can remove them.
  • This lowers the risk of evicting other actually important caches (such as main's)

This PR:
Adds two new workflows:

  1. Runs every 6 days (so we don't go over the 7 days limit) and makes sure that our main caches are warm, by running waspc-ci and waspc-build
  2. Every time a PR is merged, goes through the caches and evicts the ones linked to no-longer-existing branches.

@cprecioso cprecioso self-assigned this Jul 10, 2025
@cprecioso cprecioso requested a review from infomiho July 10, 2025 18:44
Copy link
Contributor

@infomiho infomiho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments!

@cprecioso
Copy link
Member Author

cprecioso commented Jul 15, 2025

I felt the shell script inside the yaml was way too obtuse, so I moved it to a node.js script. (Made it with no dependencies and using the preinstalled Node version in ubuntu-latest so that it doesn't need to install node or run npm)

I made a dry-run at https://github.com/wasp-lang/wasp/actions/runs/16296955021/job/46021046403?pr=2944

@infomiho recheck pls

Copy link
Contributor

@infomiho infomiho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some suggestions

const lsRemoteOutput = listRemoteRefs(githubRepository);

// Find refs that have caches but do not exist in the remote repository anymore.
const remoteRefs = new Set(lsRemoteOutput.map(([, ref]) => ref));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not do the mapping in the listRemoteRefs?

);
console.log(`Found ${cachesToDelete.length} caches to delete`);

// Delete those cache keys
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant comment

const ghCachesOutput = listGitHubCaches();
const lsRemoteOutput = listRemoteRefs(githubRepository);

// Find refs that have caches but do not exist in the remote repository anymore.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is probably above the wrong line, and maybe it's even redundant since it's clear from the code that you are finding caches that are not in the remote refs.

for (const { key, ref } of cachesToDelete) {
try {
console.group(`Deleting cache "${key}" for ref "${ref}"`);
runCmd("gh", ["cache", "delete", key], { collectStdout: false });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd maybe even extract this into a function e.g. deleteGithubCache to make it cleaner.

// We use `git ls-remote` so we also receive refs such as `refs/pull/123/head`
// which are not downloaded by `git fetch` or `git pull`.
//
// According to https://git-scm.com/docs/git-ls-remote, the output is:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This format comment could go into parseTabSeparatedLines function if we rename the function to handle the remote refs format specifically. See the comment: https://github.com/wasp-lang/wasp/pull/2944/files#r2212842477

}

function listRemoteRefs(githubRepository) {
const lsRemoteOutput = /** @type {[objectId: string, ref: string][]} */ (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically this is not the lsRemoteOutput but the parsed output, maybe a better name would be remoteRefs since that's what you function says it lists.

});
}

function parseTabSeparatedLines(/** @type {string} */ str) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be specific here since the script is quite specific, name this helper parse git remotes output and put the explainer comment on top.

You can even make the output not be [str1, str2] but provide names for the values you already have names for in the format <oid> TAB <ref> LF -> { oid, ref }. I'm not sure what oid is in this case, maybe the name can reflect that.

@cprecioso
Copy link
Member Author

@infomiho ready

Copy link
Contributor

@infomiho infomiho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beautiful

@cprecioso cprecioso merged commit 65f1235 into main Jul 17, 2025
2 checks passed
@cprecioso cprecioso deleted the cprecioso/2919-ensure-warm-cache-for-ci branch July 17, 2025 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ensure warm cache for CI

2 participants