Skip to content

Commit 9ac9efd

Browse files
committed
Clear Zig cache directory when it grows too large
Resolves: #21
1 parent 0a889b2 commit 9ac9efd

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ with all of your matrix variables to ensure that every job is correctly cached.
5656
provide any means for the Action to automatically distinguish jobs in a matrix. However, variables which select
5757
the runner OS can be omitted from the `cache-key`, since the runner OS is included in the cache key by default.
5858

59+
Zig cache directories can get incredibly large over time. By default, this Action will clear the cache directory
60+
once its size exceeds 2 GiB. This threshold can be changed by setting the `cache-size-limit` option to a different
61+
value (in MiB); for instance, `cache-size-limit: 4096` for a 4 GiB limit. The limit can be disabled entirely by
62+
setting `cache-size-limit: 0`.
63+
5964
[mach-nominated]: https://machengine.org/about/nominated-zig/
6065
[matrix]: https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/running-variations-of-jobs-in-a-workflow
6166

action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ inputs:
1616
description: 'Additional cache key component to include when caching the global Zig cache directory. When using a matrix strategy, this should include the matrix variables to ensure all jobs are cached. Matrix variables which decide the OS can be omitted, since the OS is always included in the cache key.'
1717
required: false
1818
default: ''
19+
cache-size-limit:
20+
description: 'The maximum permitted size of the global Zig cache directory, in MiB. When the cache directory exceeds this size, it is cleared. Default is 2048 (2 GiB). 0 means no limit.'
21+
required: true
22+
default: 2048
1923
runs:
2024
using: 'node20'
2125
main: 'main.js'

post.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const path = require('path');
12
const fs = require('fs').promises;
23
const core = require('@actions/core');
34
const github = require('@actions/github');
@@ -17,6 +18,16 @@ async function main() {
1718
}
1819

1920
if (accessible) {
21+
const size = await totalSize(cache_path);
22+
const size_limit = core.getInput('cache-size-limit') * 1024 * 1024; // MiB -> bytes
23+
if (size_limit !== 0 && size > size_limit) {
24+
core.info(`Cache directory reached ${size} bytes, exceeding limit of ${size_limit} bytes; clearing cache`);
25+
// We want to clear the cache and start over. Unfortunately, we can't programmatically
26+
// remove the old cache entries, so we instead want to save an empty cache directory.
27+
// To do this, delete all the contents of the cache directory before saving the cache.
28+
await rmDirContents(cache_path);
29+
}
30+
2031
const prefix = await common.getCachePrefix();
2132
const name = prefix + github.context.runId;
2233
await cache.saveCache([cache_path], name);
@@ -27,4 +38,22 @@ async function main() {
2738
}
2839
}
2940

41+
async function totalSize(p) {
42+
const stat = await fs.stat(p);
43+
if (stat.isFile()) return stat.size;
44+
if (stat.isDirectory()) {
45+
let total = 0;
46+
for (const entry of await fs.readdir(p)) {
47+
total += await totalSize(path.join(p, entry));
48+
}
49+
return total;
50+
}
51+
return 0;
52+
}
53+
54+
async function rmDirContents(dir) {
55+
const entries = await fs.readdir(dir);
56+
await Promise.all(entries.map(e => fs.rm(path.join(dir, e), { recursive: true, force: true })));
57+
}
58+
3059
main();

0 commit comments

Comments
 (0)