3
0
Fork 0
mirror of https://github.com/Swatinem/rust-cache synced 2025-08-14 08:55:27 +00:00

Try explicitly exporting CACHE_ON_FAILURE

This commit is contained in:
Tom Parker-Shemilt 2021-06-27 18:11:38 +01:00
parent 91ffae15a8
commit d842616537
4 changed files with 549 additions and 547 deletions

View file

@ -24,7 +24,7 @@ runs:
using: "node12" using: "node12"
main: "dist/restore/index.js" main: "dist/restore/index.js"
post: "dist/save/index.js" post: "dist/save/index.js"
post-if: "success() || env.INPUT_CACHE_ON_FAILURE == 'true'" post-if: "success() || env.CACHE_ON_FAILURE == 'true'"
branding: branding:
icon: "archive" icon: "archive"
color: "gray-dark" color: "gray-dark"

453
dist/restore/index.js vendored
View file

@ -59794,234 +59794,235 @@ var external_os_default = /*#__PURE__*/__nccwpck_require__.n(external_os_);
var external_path_ = __nccwpck_require__(5622); var external_path_ = __nccwpck_require__(5622);
var external_path_default = /*#__PURE__*/__nccwpck_require__.n(external_path_); var external_path_default = /*#__PURE__*/__nccwpck_require__.n(external_path_);
;// CONCATENATED MODULE: ./src/common.ts ;// CONCATENATED MODULE: ./src/common.ts
process.on("uncaughtException", (e) => { process.on("uncaughtException", (e) => {
core.info(`[warning] ${e.message}`); core.info(`[warning] ${e.message}`);
}); });
const cwd = core.getInput("working-directory"); const cwd = core.getInput("working-directory");
// TODO: this could be read from .cargo config file directly // TODO: this could be read from .cargo config file directly
const targetDir = core.getInput("target-dir") || "./target"; const targetDir = core.getInput("target-dir") || "./target";
if (cwd) { if (cwd) {
process.chdir(cwd); process.chdir(cwd);
} }
const stateBins = "RUST_CACHE_BINS"; const stateBins = "RUST_CACHE_BINS";
const stateKey = "RUST_CACHE_KEY"; const stateKey = "RUST_CACHE_KEY";
const stateHash = "RUST_CACHE_HASH"; const stateHash = "RUST_CACHE_HASH";
const home = external_os_default().homedir(); const home = external_os_default().homedir();
const cargoHome = process.env.CARGO_HOME || external_path_default().join(home, ".cargo"); const cargoHome = process.env.CARGO_HOME || external_path_default().join(home, ".cargo");
const paths = { const paths = {
cargoHome, cargoHome,
index: external_path_default().join(cargoHome, "registry/index"), index: external_path_default().join(cargoHome, "registry/index"),
cache: external_path_default().join(cargoHome, "registry/cache"), cache: external_path_default().join(cargoHome, "registry/cache"),
git: external_path_default().join(cargoHome, "git"), git: external_path_default().join(cargoHome, "git"),
target: targetDir, target: targetDir,
}; };
const RefKey = "GITHUB_REF"; const RefKey = "GITHUB_REF";
function isValidEvent() { function isValidEvent() {
return RefKey in process.env && Boolean(process.env[RefKey]); return RefKey in process.env && Boolean(process.env[RefKey]);
} }
async function getCacheConfig() { async function getCacheConfig() {
let lockHash = core.getState(stateHash); let lockHash = core.getState(stateHash);
if (!lockHash) { if (!lockHash) {
lockHash = await getLockfileHash(); lockHash = await getLockfileHash();
core.saveState(stateHash, lockHash); core.saveState(stateHash, lockHash);
} }
let key = `v0-rust-`; let key = `v0-rust-`;
const sharedKey = core.getInput("sharedKey"); const sharedKey = core.getInput("sharedKey");
if (sharedKey) { if (sharedKey) {
key += `${sharedKey}-`; key += `${sharedKey}-`;
} }
else { else {
const inputKey = core.getInput("key"); const inputKey = core.getInput("key");
if (inputKey) { if (inputKey) {
key += `${inputKey}-`; key += `${inputKey}-`;
} }
const job = process.env.GITHUB_JOB; const job = process.env.GITHUB_JOB;
if (job) { if (job) {
key += `${job}-`; key += `${job}-`;
} }
} }
key += await getRustKey(); key += await getRustKey();
return { return {
paths: [ paths: [
external_path_default().join(cargoHome, "bin"), external_path_default().join(cargoHome, "bin"),
external_path_default().join(cargoHome, ".crates2.json"), external_path_default().join(cargoHome, ".crates2.json"),
external_path_default().join(cargoHome, ".crates.toml"), external_path_default().join(cargoHome, ".crates.toml"),
paths.git, paths.git,
paths.cache, paths.cache,
paths.index, paths.index,
paths.target, paths.target,
], ],
key: `${key}-${lockHash}`, key: `${key}-${lockHash}`,
restoreKeys: [key], restoreKeys: [key],
}; };
} }
async function getCargoBins() { async function getCargoBins() {
try { try {
const { installs } = JSON.parse(await external_fs_default().promises.readFile(external_path_default().join(paths.cargoHome, ".crates2.json"), "utf8")); const { installs } = JSON.parse(await external_fs_default().promises.readFile(external_path_default().join(paths.cargoHome, ".crates2.json"), "utf8"));
const bins = new Set(); const bins = new Set();
for (const pkg of Object.values(installs)) { for (const pkg of Object.values(installs)) {
for (const bin of pkg.bins) { for (const bin of pkg.bins) {
bins.add(bin); bins.add(bin);
} }
} }
return bins; return bins;
} }
catch { catch {
return new Set(); return new Set();
} }
} }
async function getRustKey() { async function getRustKey() {
const rustc = await getRustVersion(); const rustc = await getRustVersion();
return `${rustc.release}-${rustc.host}-${rustc["commit-hash"].slice(0, 12)}`; return `${rustc.release}-${rustc.host}-${rustc["commit-hash"].slice(0, 12)}`;
} }
async function getRustVersion() { async function getRustVersion() {
const stdout = await getCmdOutput("rustc", ["-vV"]); const stdout = await getCmdOutput("rustc", ["-vV"]);
let splits = stdout let splits = stdout
.split(/[\n\r]+/) .split(/[\n\r]+/)
.filter(Boolean) .filter(Boolean)
.map((s) => s.split(":").map((s) => s.trim())) .map((s) => s.split(":").map((s) => s.trim()))
.filter((s) => s.length === 2); .filter((s) => s.length === 2);
return Object.fromEntries(splits); return Object.fromEntries(splits);
} }
async function getCmdOutput(cmd, args = [], options = {}) { async function getCmdOutput(cmd, args = [], options = {}) {
let stdout = ""; let stdout = "";
await exec.exec(cmd, args, { await exec.exec(cmd, args, {
silent: true, silent: true,
listeners: { listeners: {
stdout(data) { stdout(data) {
stdout += data.toString(); stdout += data.toString();
}, },
}, },
...options, ...options,
}); });
return stdout; return stdout;
} }
async function getLockfileHash() { async function getLockfileHash() {
const globber = await glob.create("**/Cargo.toml\n**/Cargo.lock\nrust-toolchain\nrust-toolchain.toml", { const globber = await glob.create("**/Cargo.toml\n**/Cargo.lock\nrust-toolchain\nrust-toolchain.toml", {
followSymbolicLinks: false, followSymbolicLinks: false,
}); });
const files = await globber.glob(); const files = await globber.glob();
files.sort((a, b) => a.localeCompare(b)); files.sort((a, b) => a.localeCompare(b));
const hasher = external_crypto_default().createHash("sha1"); const hasher = external_crypto_default().createHash("sha1");
for (const file of files) { for (const file of files) {
for await (const chunk of external_fs_default().createReadStream(file)) { for await (const chunk of external_fs_default().createReadStream(file)) {
hasher.update(chunk); hasher.update(chunk);
} }
} }
return hasher.digest("hex").slice(0, 20); return hasher.digest("hex").slice(0, 20);
} }
async function getPackages() { async function getPackages() {
const cwd = process.cwd(); const cwd = process.cwd();
const meta = JSON.parse(await getCmdOutput("cargo", ["metadata", "--all-features", "--format-version", "1"])); const meta = JSON.parse(await getCmdOutput("cargo", ["metadata", "--all-features", "--format-version", "1"]));
return meta.packages return meta.packages
.filter((p) => !p.manifest_path.startsWith(cwd)) .filter((p) => !p.manifest_path.startsWith(cwd))
.map((p) => { .map((p) => {
const targets = p.targets.filter((t) => t.kind[0] === "lib").map((t) => t.name); const targets = p.targets.filter((t) => t.kind[0] === "lib").map((t) => t.name);
return { name: p.name, version: p.version, targets, path: external_path_default().dirname(p.manifest_path) }; return { name: p.name, version: p.version, targets, path: external_path_default().dirname(p.manifest_path) };
}); });
} }
async function cleanTarget(packages) { async function cleanTarget(packages) {
await external_fs_default().promises.unlink(external_path_default().join(targetDir, "./.rustc_info.json")); await external_fs_default().promises.unlink(external_path_default().join(targetDir, "./.rustc_info.json"));
await io.rmRF(external_path_default().join(targetDir, "./debug/examples")); await io.rmRF(external_path_default().join(targetDir, "./debug/examples"));
await io.rmRF(external_path_default().join(targetDir, "./debug/incremental")); await io.rmRF(external_path_default().join(targetDir, "./debug/incremental"));
let dir; let dir;
// remove all *files* from debug // remove all *files* from debug
dir = await external_fs_default().promises.opendir(external_path_default().join(targetDir, "./debug")); dir = await external_fs_default().promises.opendir(external_path_default().join(targetDir, "./debug"));
for await (const dirent of dir) { for await (const dirent of dir) {
if (dirent.isFile()) { if (dirent.isFile()) {
await rm(dir.path, dirent); await rm(dir.path, dirent);
} }
} }
const keepPkg = new Set(packages.map((p) => p.name)); const keepPkg = new Set(packages.map((p) => p.name));
await rmExcept(external_path_default().join(targetDir, "./debug/build"), keepPkg); await rmExcept(external_path_default().join(targetDir, "./debug/build"), keepPkg);
await rmExcept(external_path_default().join(targetDir, "./debug/.fingerprint"), keepPkg); await rmExcept(external_path_default().join(targetDir, "./debug/.fingerprint"), keepPkg);
const keepDeps = new Set(packages.flatMap((p) => { const keepDeps = new Set(packages.flatMap((p) => {
const names = []; const names = [];
for (const n of [p.name, ...p.targets]) { for (const n of [p.name, ...p.targets]) {
const name = n.replace(/-/g, "_"); const name = n.replace(/-/g, "_");
names.push(name, `lib${name}`); names.push(name, `lib${name}`);
} }
return names; return names;
})); }));
await rmExcept(external_path_default().join(targetDir, "./debug/deps"), keepDeps); await rmExcept(external_path_default().join(targetDir, "./debug/deps"), keepDeps);
} }
const oneWeek = 7 * 24 * 3600 * 1000; const oneWeek = 7 * 24 * 3600 * 1000;
async function rmExcept(dirName, keepPrefix) { async function rmExcept(dirName, keepPrefix) {
const dir = await external_fs_default().promises.opendir(dirName); const dir = await external_fs_default().promises.opendir(dirName);
for await (const dirent of dir) { for await (const dirent of dir) {
let name = dirent.name; let name = dirent.name;
const idx = name.lastIndexOf("-"); const idx = name.lastIndexOf("-");
if (idx !== -1) { if (idx !== -1) {
name = name.slice(0, idx); name = name.slice(0, idx);
} }
const fileName = external_path_default().join(dir.path, dirent.name); const fileName = external_path_default().join(dir.path, dirent.name);
const { mtime } = await external_fs_default().promises.stat(fileName); const { mtime } = await external_fs_default().promises.stat(fileName);
// we dont really know // we dont really know
if (!keepPrefix.has(name) || Date.now() - mtime.getTime() > oneWeek) { if (!keepPrefix.has(name) || Date.now() - mtime.getTime() > oneWeek) {
await rm(dir.path, dirent); await rm(dir.path, dirent);
} }
} }
} }
async function rm(parent, dirent) { async function rm(parent, dirent) {
try { try {
const fileName = external_path_default().join(parent, dirent.name); const fileName = external_path_default().join(parent, dirent.name);
core.debug(`deleting "${fileName}"`); core.debug(`deleting "${fileName}"`);
if (dirent.isFile()) { if (dirent.isFile()) {
await external_fs_default().promises.unlink(fileName); await external_fs_default().promises.unlink(fileName);
} }
else if (dirent.isDirectory()) { else if (dirent.isDirectory()) {
await io.rmRF(fileName); await io.rmRF(fileName);
} }
} }
catch { } catch { }
} }
;// CONCATENATED MODULE: ./src/restore.ts ;// CONCATENATED MODULE: ./src/restore.ts
async function run() { async function run() {
try { try {
core.exportVariable("CARGO_INCREMENTAL", 0); core.exportVariable("CACHE_ON_FAILURE", "true");
const { paths, key, restoreKeys } = await getCacheConfig(); core.exportVariable("CARGO_INCREMENTAL", 0);
const bins = await getCargoBins(); const { paths, key, restoreKeys } = await getCacheConfig();
core.saveState(stateBins, JSON.stringify([...bins])); const bins = await getCargoBins();
core.info(`Restoring paths:\n ${paths.join("\n ")}`); core.saveState(stateBins, JSON.stringify([...bins]));
core.info(`In directory:\n ${process.cwd()}`); core.info(`Restoring paths:\n ${paths.join("\n ")}`);
core.info(`Using keys:\n ${[key, ...restoreKeys].join("\n ")}`); core.info(`In directory:\n ${process.cwd()}`);
const restoreKey = await cache.restoreCache(paths, key, restoreKeys); core.info(`Using keys:\n ${[key, ...restoreKeys].join("\n ")}`);
if (restoreKey) { const restoreKey = await cache.restoreCache(paths, key, restoreKeys);
core.info(`Restored from cache key "${restoreKey}".`); if (restoreKey) {
core.saveState(stateKey, restoreKey); core.info(`Restored from cache key "${restoreKey}".`);
if (restoreKey !== key) { core.saveState(stateKey, restoreKey);
// pre-clean the target directory on cache mismatch if (restoreKey !== key) {
const packages = await getPackages(); // pre-clean the target directory on cache mismatch
await cleanTarget(packages); const packages = await getPackages();
} await cleanTarget(packages);
setCacheHitOutput(restoreKey === key); }
} setCacheHitOutput(restoreKey === key);
else { }
core.info("No cache found."); else {
setCacheHitOutput(false); core.info("No cache found.");
} setCacheHitOutput(false);
} }
catch (e) { }
setCacheHitOutput(false); catch (e) {
core.info(`[warning] ${e.message}`); setCacheHitOutput(false);
} core.info(`[warning] ${e.message}`);
} }
function setCacheHitOutput(cacheHit) { }
core.setOutput("cache-hit", cacheHit.toString()); function setCacheHitOutput(cacheHit) {
} core.setOutput("cache-hit", cacheHit.toString());
run(); }
run();
})(); })();

640
dist/save/index.js vendored
View file

@ -59794,328 +59794,328 @@ var external_crypto_default = /*#__PURE__*/__nccwpck_require__.n(external_crypto
var external_os_ = __nccwpck_require__(2087); var external_os_ = __nccwpck_require__(2087);
var external_os_default = /*#__PURE__*/__nccwpck_require__.n(external_os_); var external_os_default = /*#__PURE__*/__nccwpck_require__.n(external_os_);
;// CONCATENATED MODULE: ./src/common.ts ;// CONCATENATED MODULE: ./src/common.ts
process.on("uncaughtException", (e) => { process.on("uncaughtException", (e) => {
core.info(`[warning] ${e.message}`); core.info(`[warning] ${e.message}`);
}); });
const cwd = core.getInput("working-directory"); const cwd = core.getInput("working-directory");
// TODO: this could be read from .cargo config file directly // TODO: this could be read from .cargo config file directly
const targetDir = core.getInput("target-dir") || "./target"; const targetDir = core.getInput("target-dir") || "./target";
if (cwd) { if (cwd) {
process.chdir(cwd); process.chdir(cwd);
} }
const stateBins = "RUST_CACHE_BINS"; const stateBins = "RUST_CACHE_BINS";
const stateKey = "RUST_CACHE_KEY"; const stateKey = "RUST_CACHE_KEY";
const stateHash = "RUST_CACHE_HASH"; const stateHash = "RUST_CACHE_HASH";
const home = external_os_default().homedir(); const home = external_os_default().homedir();
const cargoHome = process.env.CARGO_HOME || external_path_default().join(home, ".cargo"); const cargoHome = process.env.CARGO_HOME || external_path_default().join(home, ".cargo");
const paths = { const paths = {
cargoHome, cargoHome,
index: external_path_default().join(cargoHome, "registry/index"), index: external_path_default().join(cargoHome, "registry/index"),
cache: external_path_default().join(cargoHome, "registry/cache"), cache: external_path_default().join(cargoHome, "registry/cache"),
git: external_path_default().join(cargoHome, "git"), git: external_path_default().join(cargoHome, "git"),
target: targetDir, target: targetDir,
}; };
const RefKey = "GITHUB_REF"; const RefKey = "GITHUB_REF";
function isValidEvent() { function isValidEvent() {
return RefKey in process.env && Boolean(process.env[RefKey]); return RefKey in process.env && Boolean(process.env[RefKey]);
} }
async function getCacheConfig() { async function getCacheConfig() {
let lockHash = core.getState(stateHash); let lockHash = core.getState(stateHash);
if (!lockHash) { if (!lockHash) {
lockHash = await getLockfileHash(); lockHash = await getLockfileHash();
core.saveState(stateHash, lockHash); core.saveState(stateHash, lockHash);
} }
let key = `v0-rust-`; let key = `v0-rust-`;
const sharedKey = core.getInput("sharedKey"); const sharedKey = core.getInput("sharedKey");
if (sharedKey) { if (sharedKey) {
key += `${sharedKey}-`; key += `${sharedKey}-`;
} }
else { else {
const inputKey = core.getInput("key"); const inputKey = core.getInput("key");
if (inputKey) { if (inputKey) {
key += `${inputKey}-`; key += `${inputKey}-`;
} }
const job = process.env.GITHUB_JOB; const job = process.env.GITHUB_JOB;
if (job) { if (job) {
key += `${job}-`; key += `${job}-`;
} }
} }
key += await getRustKey(); key += await getRustKey();
return { return {
paths: [ paths: [
external_path_default().join(cargoHome, "bin"), external_path_default().join(cargoHome, "bin"),
external_path_default().join(cargoHome, ".crates2.json"), external_path_default().join(cargoHome, ".crates2.json"),
external_path_default().join(cargoHome, ".crates.toml"), external_path_default().join(cargoHome, ".crates.toml"),
paths.git, paths.git,
paths.cache, paths.cache,
paths.index, paths.index,
paths.target, paths.target,
], ],
key: `${key}-${lockHash}`, key: `${key}-${lockHash}`,
restoreKeys: [key], restoreKeys: [key],
}; };
} }
async function getCargoBins() { async function getCargoBins() {
try { try {
const { installs } = JSON.parse(await external_fs_default().promises.readFile(external_path_default().join(paths.cargoHome, ".crates2.json"), "utf8")); const { installs } = JSON.parse(await external_fs_default().promises.readFile(external_path_default().join(paths.cargoHome, ".crates2.json"), "utf8"));
const bins = new Set(); const bins = new Set();
for (const pkg of Object.values(installs)) { for (const pkg of Object.values(installs)) {
for (const bin of pkg.bins) { for (const bin of pkg.bins) {
bins.add(bin); bins.add(bin);
} }
} }
return bins; return bins;
} }
catch { catch {
return new Set(); return new Set();
} }
} }
async function getRustKey() { async function getRustKey() {
const rustc = await getRustVersion(); const rustc = await getRustVersion();
return `${rustc.release}-${rustc.host}-${rustc["commit-hash"].slice(0, 12)}`; return `${rustc.release}-${rustc.host}-${rustc["commit-hash"].slice(0, 12)}`;
} }
async function getRustVersion() { async function getRustVersion() {
const stdout = await getCmdOutput("rustc", ["-vV"]); const stdout = await getCmdOutput("rustc", ["-vV"]);
let splits = stdout let splits = stdout
.split(/[\n\r]+/) .split(/[\n\r]+/)
.filter(Boolean) .filter(Boolean)
.map((s) => s.split(":").map((s) => s.trim())) .map((s) => s.split(":").map((s) => s.trim()))
.filter((s) => s.length === 2); .filter((s) => s.length === 2);
return Object.fromEntries(splits); return Object.fromEntries(splits);
} }
async function getCmdOutput(cmd, args = [], options = {}) { async function getCmdOutput(cmd, args = [], options = {}) {
let stdout = ""; let stdout = "";
await exec.exec(cmd, args, { await exec.exec(cmd, args, {
silent: true, silent: true,
listeners: { listeners: {
stdout(data) { stdout(data) {
stdout += data.toString(); stdout += data.toString();
}, },
}, },
...options, ...options,
}); });
return stdout; return stdout;
} }
async function getLockfileHash() { async function getLockfileHash() {
const globber = await glob.create("**/Cargo.toml\n**/Cargo.lock\nrust-toolchain\nrust-toolchain.toml", { const globber = await glob.create("**/Cargo.toml\n**/Cargo.lock\nrust-toolchain\nrust-toolchain.toml", {
followSymbolicLinks: false, followSymbolicLinks: false,
}); });
const files = await globber.glob(); const files = await globber.glob();
files.sort((a, b) => a.localeCompare(b)); files.sort((a, b) => a.localeCompare(b));
const hasher = external_crypto_default().createHash("sha1"); const hasher = external_crypto_default().createHash("sha1");
for (const file of files) { for (const file of files) {
for await (const chunk of external_fs_default().createReadStream(file)) { for await (const chunk of external_fs_default().createReadStream(file)) {
hasher.update(chunk); hasher.update(chunk);
} }
} }
return hasher.digest("hex").slice(0, 20); return hasher.digest("hex").slice(0, 20);
} }
async function getPackages() { async function getPackages() {
const cwd = process.cwd(); const cwd = process.cwd();
const meta = JSON.parse(await getCmdOutput("cargo", ["metadata", "--all-features", "--format-version", "1"])); const meta = JSON.parse(await getCmdOutput("cargo", ["metadata", "--all-features", "--format-version", "1"]));
return meta.packages return meta.packages
.filter((p) => !p.manifest_path.startsWith(cwd)) .filter((p) => !p.manifest_path.startsWith(cwd))
.map((p) => { .map((p) => {
const targets = p.targets.filter((t) => t.kind[0] === "lib").map((t) => t.name); const targets = p.targets.filter((t) => t.kind[0] === "lib").map((t) => t.name);
return { name: p.name, version: p.version, targets, path: external_path_default().dirname(p.manifest_path) }; return { name: p.name, version: p.version, targets, path: external_path_default().dirname(p.manifest_path) };
}); });
} }
async function cleanTarget(packages) { async function cleanTarget(packages) {
await external_fs_default().promises.unlink(external_path_default().join(targetDir, "./.rustc_info.json")); await external_fs_default().promises.unlink(external_path_default().join(targetDir, "./.rustc_info.json"));
await io.rmRF(external_path_default().join(targetDir, "./debug/examples")); await io.rmRF(external_path_default().join(targetDir, "./debug/examples"));
await io.rmRF(external_path_default().join(targetDir, "./debug/incremental")); await io.rmRF(external_path_default().join(targetDir, "./debug/incremental"));
let dir; let dir;
// remove all *files* from debug // remove all *files* from debug
dir = await external_fs_default().promises.opendir(external_path_default().join(targetDir, "./debug")); dir = await external_fs_default().promises.opendir(external_path_default().join(targetDir, "./debug"));
for await (const dirent of dir) { for await (const dirent of dir) {
if (dirent.isFile()) { if (dirent.isFile()) {
await rm(dir.path, dirent); await rm(dir.path, dirent);
} }
} }
const keepPkg = new Set(packages.map((p) => p.name)); const keepPkg = new Set(packages.map((p) => p.name));
await rmExcept(external_path_default().join(targetDir, "./debug/build"), keepPkg); await rmExcept(external_path_default().join(targetDir, "./debug/build"), keepPkg);
await rmExcept(external_path_default().join(targetDir, "./debug/.fingerprint"), keepPkg); await rmExcept(external_path_default().join(targetDir, "./debug/.fingerprint"), keepPkg);
const keepDeps = new Set(packages.flatMap((p) => { const keepDeps = new Set(packages.flatMap((p) => {
const names = []; const names = [];
for (const n of [p.name, ...p.targets]) { for (const n of [p.name, ...p.targets]) {
const name = n.replace(/-/g, "_"); const name = n.replace(/-/g, "_");
names.push(name, `lib${name}`); names.push(name, `lib${name}`);
} }
return names; return names;
})); }));
await rmExcept(external_path_default().join(targetDir, "./debug/deps"), keepDeps); await rmExcept(external_path_default().join(targetDir, "./debug/deps"), keepDeps);
} }
const oneWeek = 7 * 24 * 3600 * 1000; const oneWeek = 7 * 24 * 3600 * 1000;
async function rmExcept(dirName, keepPrefix) { async function rmExcept(dirName, keepPrefix) {
const dir = await external_fs_default().promises.opendir(dirName); const dir = await external_fs_default().promises.opendir(dirName);
for await (const dirent of dir) { for await (const dirent of dir) {
let name = dirent.name; let name = dirent.name;
const idx = name.lastIndexOf("-"); const idx = name.lastIndexOf("-");
if (idx !== -1) { if (idx !== -1) {
name = name.slice(0, idx); name = name.slice(0, idx);
} }
const fileName = external_path_default().join(dir.path, dirent.name); const fileName = external_path_default().join(dir.path, dirent.name);
const { mtime } = await external_fs_default().promises.stat(fileName); const { mtime } = await external_fs_default().promises.stat(fileName);
// we dont really know // we dont really know
if (!keepPrefix.has(name) || Date.now() - mtime.getTime() > oneWeek) { if (!keepPrefix.has(name) || Date.now() - mtime.getTime() > oneWeek) {
await rm(dir.path, dirent); await rm(dir.path, dirent);
} }
} }
} }
async function rm(parent, dirent) { async function rm(parent, dirent) {
try { try {
const fileName = external_path_default().join(parent, dirent.name); const fileName = external_path_default().join(parent, dirent.name);
core.debug(`deleting "${fileName}"`); core.debug(`deleting "${fileName}"`);
if (dirent.isFile()) { if (dirent.isFile()) {
await external_fs_default().promises.unlink(fileName); await external_fs_default().promises.unlink(fileName);
} }
else if (dirent.isDirectory()) { else if (dirent.isDirectory()) {
await io.rmRF(fileName); await io.rmRF(fileName);
} }
} }
catch { } catch { }
} }
;// CONCATENATED MODULE: ./src/save.ts ;// CONCATENATED MODULE: ./src/save.ts
async function run() { async function run() {
try { try {
const { paths: savePaths, key } = await getCacheConfig(); const { paths: savePaths, key } = await getCacheConfig();
if (core.getState(stateKey) === key) { if (core.getState(stateKey) === key) {
core.info(`Cache up-to-date.`); core.info(`Cache up-to-date.`);
return; return;
} }
// TODO: remove this once https://github.com/actions/toolkit/pull/553 lands // TODO: remove this once https://github.com/actions/toolkit/pull/553 lands
await macOsWorkaround(); await macOsWorkaround();
const registryName = await getRegistryName(); const registryName = await getRegistryName();
const packages = await getPackages(); const packages = await getPackages();
try { try {
await cleanRegistry(registryName, packages); await cleanRegistry(registryName, packages);
} }
catch { } catch { }
try { try {
await cleanBin(); await cleanBin();
} }
catch { } catch { }
try { try {
await cleanGit(packages); await cleanGit(packages);
} }
catch { } catch { }
try { try {
await cleanTarget(packages); await cleanTarget(packages);
} }
catch { } catch { }
core.info(`Saving paths:\n ${savePaths.join("\n ")}`); core.info(`Saving paths:\n ${savePaths.join("\n ")}`);
core.info(`In directory:\n ${process.cwd()}`); core.info(`In directory:\n ${process.cwd()}`);
core.info(`Using key:\n ${key}`); core.info(`Using key:\n ${key}`);
await cache.saveCache(savePaths, key); await cache.saveCache(savePaths, key);
} }
catch (e) { catch (e) {
core.info(`[warning] ${e.message}`); core.info(`[warning] ${e.message}`);
} }
} }
run(); run();
async function getRegistryName() { async function getRegistryName() {
const globber = await glob.create(`${paths.index}/**/.last-updated`, { followSymbolicLinks: false }); const globber = await glob.create(`${paths.index}/**/.last-updated`, { followSymbolicLinks: false });
const files = await globber.glob(); const files = await globber.glob();
if (files.length > 1) { if (files.length > 1) {
core.warning(`got multiple registries: "${files.join('", "')}"`); core.warning(`got multiple registries: "${files.join('", "')}"`);
} }
const first = files.shift(); const first = files.shift();
return external_path_default().basename(external_path_default().dirname(first)); return external_path_default().basename(external_path_default().dirname(first));
} }
async function cleanBin() { async function cleanBin() {
const bins = await getCargoBins(); const bins = await getCargoBins();
const oldBins = JSON.parse(core.getState(stateBins)); const oldBins = JSON.parse(core.getState(stateBins));
for (const bin of oldBins) { for (const bin of oldBins) {
bins.delete(bin); bins.delete(bin);
} }
const dir = await external_fs_default().promises.opendir(external_path_default().join(paths.cargoHome, "bin")); const dir = await external_fs_default().promises.opendir(external_path_default().join(paths.cargoHome, "bin"));
for await (const dirent of dir) { for await (const dirent of dir) {
if (dirent.isFile() && !bins.has(dirent.name)) { if (dirent.isFile() && !bins.has(dirent.name)) {
await rm(dir.path, dirent); await rm(dir.path, dirent);
} }
} }
} }
async function cleanRegistry(registryName, packages) { async function cleanRegistry(registryName, packages) {
await io.rmRF(external_path_default().join(paths.index, registryName, ".cache")); await io.rmRF(external_path_default().join(paths.index, registryName, ".cache"));
const pkgSet = new Set(packages.map((p) => `${p.name}-${p.version}.crate`)); const pkgSet = new Set(packages.map((p) => `${p.name}-${p.version}.crate`));
const dir = await external_fs_default().promises.opendir(external_path_default().join(paths.cache, registryName)); const dir = await external_fs_default().promises.opendir(external_path_default().join(paths.cache, registryName));
for await (const dirent of dir) { for await (const dirent of dir) {
if (dirent.isFile() && !pkgSet.has(dirent.name)) { if (dirent.isFile() && !pkgSet.has(dirent.name)) {
await rm(dir.path, dirent); await rm(dir.path, dirent);
} }
} }
} }
async function cleanGit(packages) { async function cleanGit(packages) {
const coPath = external_path_default().join(paths.git, "checkouts"); const coPath = external_path_default().join(paths.git, "checkouts");
const dbPath = external_path_default().join(paths.git, "db"); const dbPath = external_path_default().join(paths.git, "db");
const repos = new Map(); const repos = new Map();
for (const p of packages) { for (const p of packages) {
if (!p.path.startsWith(coPath)) { if (!p.path.startsWith(coPath)) {
continue; continue;
} }
const [repo, ref] = p.path.slice(coPath.length + 1).split((external_path_default()).sep); const [repo, ref] = p.path.slice(coPath.length + 1).split((external_path_default()).sep);
const refs = repos.get(repo); const refs = repos.get(repo);
if (refs) { if (refs) {
refs.add(ref); refs.add(ref);
} }
else { else {
repos.set(repo, new Set([ref])); repos.set(repo, new Set([ref]));
} }
} }
// we have to keep both the clone, and the checkout, removing either will // we have to keep both the clone, and the checkout, removing either will
// trigger a rebuild // trigger a rebuild
let dir; let dir;
// clean the db // clean the db
dir = await external_fs_default().promises.opendir(dbPath); dir = await external_fs_default().promises.opendir(dbPath);
for await (const dirent of dir) { for await (const dirent of dir) {
if (!repos.has(dirent.name)) { if (!repos.has(dirent.name)) {
await rm(dir.path, dirent); await rm(dir.path, dirent);
} }
} }
// clean the checkouts // clean the checkouts
dir = await external_fs_default().promises.opendir(coPath); dir = await external_fs_default().promises.opendir(coPath);
for await (const dirent of dir) { for await (const dirent of dir) {
const refs = repos.get(dirent.name); const refs = repos.get(dirent.name);
if (!refs) { if (!refs) {
await rm(dir.path, dirent); await rm(dir.path, dirent);
continue; continue;
} }
if (!dirent.isDirectory()) { if (!dirent.isDirectory()) {
continue; continue;
} }
const refsDir = await external_fs_default().promises.opendir(external_path_default().join(dir.path, dirent.name)); const refsDir = await external_fs_default().promises.opendir(external_path_default().join(dir.path, dirent.name));
for await (const dirent of refsDir) { for await (const dirent of refsDir) {
if (!refs.has(dirent.name)) { if (!refs.has(dirent.name)) {
await rm(refsDir.path, dirent); await rm(refsDir.path, dirent);
} }
} }
} }
} }
async function macOsWorkaround() { async function macOsWorkaround() {
try { try {
// Workaround for https://github.com/actions/cache/issues/403 // Workaround for https://github.com/actions/cache/issues/403
// Also see https://github.com/rust-lang/cargo/issues/8603 // Also see https://github.com/rust-lang/cargo/issues/8603
await exec.exec("sudo", ["/usr/sbin/purge"], { silent: true }); await exec.exec("sudo", ["/usr/sbin/purge"], { silent: true });
} }
catch { } catch { }
} }
})(); })();

View file

@ -4,6 +4,7 @@ import { cleanTarget, getCacheConfig, getCargoBins, getPackages, stateBins, stat
async function run() { async function run() {
try { try {
core.exportVariable("CACHE_ON_FAILURE", "true")
core.exportVariable("CARGO_INCREMENTAL", 0); core.exportVariable("CARGO_INCREMENTAL", 0);
const { paths, key, restoreKeys } = await getCacheConfig(); const { paths, key, restoreKeys } = await getCacheConfig();