mirror of
https://github.com/Swatinem/rust-cache
synced 2025-08-25 22:26:06 +00:00
Cache multiple target directories from 'target-dir'
This commit is contained in:
parent
fa61956921
commit
260a713186
15 changed files with 195 additions and 41 deletions
|
@ -15,8 +15,12 @@ process.on("uncaughtException", (e) => {
|
|||
});
|
||||
|
||||
const cwd = core.getInput("working-directory");
|
||||
|
||||
// Read each line of workspace-paths as a unique path
|
||||
// TODO: this could be read from .cargo config file directly
|
||||
const targetDir = core.getInput("target-dir") || "./target";
|
||||
const workspacePathsInput = core.getInput("workspace-paths") || "./";
|
||||
const workspacePaths = workspacePathsInput.trim().split("\n");
|
||||
|
||||
if (cwd) {
|
||||
process.chdir(cwd);
|
||||
}
|
||||
|
@ -32,13 +36,16 @@ export const paths = {
|
|||
index: path.join(cargoHome, "registry/index"),
|
||||
cache: path.join(cargoHome, "registry/cache"),
|
||||
git: path.join(cargoHome, "git"),
|
||||
target: targetDir,
|
||||
workspaces: workspacePaths,
|
||||
};
|
||||
|
||||
interface CacheConfig {
|
||||
// A list of common paths needing caching
|
||||
paths: Array<string>;
|
||||
key: string;
|
||||
restoreKeys: Array<string>;
|
||||
// A list of one or more workspace directories
|
||||
workspaces: Array<string>;
|
||||
}
|
||||
|
||||
const RefKey = "GITHUB_REF";
|
||||
|
@ -84,10 +91,10 @@ export async function getCacheConfig(): Promise<CacheConfig> {
|
|||
paths.git,
|
||||
paths.cache,
|
||||
paths.index,
|
||||
paths.target,
|
||||
],
|
||||
key: `${key}-${lockHash}`,
|
||||
restoreKeys: [key],
|
||||
workspaces: paths.workspaces,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -191,6 +198,7 @@ async function getLockfileHash(): Promise<string> {
|
|||
followSymbolicLinks: false,
|
||||
});
|
||||
const files = await globber.glob();
|
||||
core.debug("Lockfile Hash includes: " + JSON.stringify(files));
|
||||
files.sort((a, b) => a.localeCompare(b));
|
||||
|
||||
const hasher = crypto.createHash("sha1");
|
||||
|
@ -220,26 +228,34 @@ interface Meta {
|
|||
}>;
|
||||
}
|
||||
|
||||
export async function getPackages(): Promise<Packages> {
|
||||
export async function getPackages(workspacePaths: Array<string>): Promise<Packages> {
|
||||
const cwd = process.cwd();
|
||||
const meta: Meta = JSON.parse(await getCmdOutput("cargo", ["metadata", "--all-features", "--format-version", "1"]));
|
||||
|
||||
return meta.packages
|
||||
.filter((p) => !p.manifest_path.startsWith(cwd))
|
||||
.map((p) => {
|
||||
const targets = p.targets.filter((t) => t.kind[0] === "lib").map((t) => t.name);
|
||||
return { name: p.name, version: p.version, targets, path: path.dirname(p.manifest_path) };
|
||||
});
|
||||
let allPackages: Packages = [];
|
||||
for (const workspacePath of workspacePaths) {
|
||||
process.chdir(workspacePath);
|
||||
const meta: Meta = JSON.parse(await getCmdOutput("cargo", ["metadata", "--all-features", "--format-version", "1"]));
|
||||
const workspacePackages = meta.packages
|
||||
.filter((p) => !p.manifest_path.startsWith(cwd))
|
||||
.map((p) => {
|
||||
const targets = p.targets.filter((t) => t.kind[0] === "lib").map((t) => t.name);
|
||||
return { name: p.name, version: p.version, targets, path: path.dirname(p.manifest_path) };
|
||||
});
|
||||
allPackages = allPackages.concat(workspacePackages);
|
||||
}
|
||||
|
||||
process.chdir(cwd);
|
||||
return allPackages;
|
||||
}
|
||||
|
||||
export async function cleanTarget(packages: Packages) {
|
||||
export async function cleanTarget(targetDir: string, packages: Packages) {
|
||||
await fs.promises.unlink(path.join(targetDir, "./.rustc_info.json"));
|
||||
|
||||
await cleanProfileTarget(packages, "debug");
|
||||
await cleanProfileTarget(packages, "release");
|
||||
await cleanProfileTarget(targetDir, packages, "debug");
|
||||
await cleanProfileTarget(targetDir, packages, "release");
|
||||
}
|
||||
|
||||
async function cleanProfileTarget(packages: Packages, profile: string) {
|
||||
async function cleanProfileTarget(targetDir: string, packages: Packages, profile: string) {
|
||||
try {
|
||||
await fs.promises.access(path.join(targetDir, profile));
|
||||
} catch {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as cache from "@actions/cache";
|
||||
import * as core from "@actions/core";
|
||||
import path from "path";
|
||||
import { cleanTarget, getCacheConfig, getCargoBins, getPackages, stateBins, stateKey } from "./common";
|
||||
|
||||
async function run() {
|
||||
|
@ -16,24 +17,29 @@ async function run() {
|
|||
core.exportVariable("CACHE_ON_FAILURE", cacheOnFailure);
|
||||
core.exportVariable("CARGO_INCREMENTAL", 0);
|
||||
|
||||
const { paths, key, restoreKeys } = await getCacheConfig();
|
||||
const { paths, key, restoreKeys, workspaces } = await getCacheConfig();
|
||||
const restorePaths = paths.concat(workspaces);
|
||||
|
||||
const bins = await getCargoBins();
|
||||
core.saveState(stateBins, JSON.stringify([...bins]));
|
||||
|
||||
core.info(`Restoring paths:\n ${paths.join("\n ")}`);
|
||||
core.info(`Restoring paths:\n ${restorePaths.join("\n ")}`);
|
||||
core.info(`In directory:\n ${process.cwd()}`);
|
||||
core.info(`Using keys:\n ${[key, ...restoreKeys].join("\n ")}`);
|
||||
const restoreKey = await cache.restoreCache(paths, key, restoreKeys);
|
||||
const restoreKey = await cache.restoreCache(restorePaths, key, restoreKeys);
|
||||
if (restoreKey) {
|
||||
core.info(`Restored from cache key "${restoreKey}".`);
|
||||
core.saveState(stateKey, restoreKey);
|
||||
|
||||
if (restoreKey !== key) {
|
||||
// pre-clean the target directory on cache mismatch
|
||||
const packages = await getPackages();
|
||||
const packages = await getPackages(workspaces);
|
||||
core.info("Restoring the following repository packages: " + JSON.stringify(packages));
|
||||
|
||||
await cleanTarget(packages);
|
||||
for (const workspace of workspaces) {
|
||||
const target = path.join(workspace, "target");
|
||||
await cleanTarget(target, packages);
|
||||
}
|
||||
}
|
||||
|
||||
setCacheHitOutput(restoreKey === key);
|
||||
|
|
20
src/save.ts
20
src/save.ts
|
@ -23,7 +23,8 @@ async function run() {
|
|||
}
|
||||
|
||||
try {
|
||||
const { paths: savePaths, key } = await getCacheConfig();
|
||||
const { paths, workspaces, key } = await getCacheConfig();
|
||||
const savePaths = paths.concat(workspaces);
|
||||
|
||||
if (core.getState(stateKey) === key) {
|
||||
core.info(`Cache up-to-date.`);
|
||||
|
@ -34,7 +35,8 @@ async function run() {
|
|||
await macOsWorkaround();
|
||||
|
||||
const registryName = await getRegistryName();
|
||||
const packages = await getPackages();
|
||||
const packages = await getPackages(workspaces);
|
||||
core.info("Detected repository packages to cache: " + JSON.stringify(packages));
|
||||
|
||||
if (registryName) {
|
||||
try {
|
||||
|
@ -56,10 +58,14 @@ async function run() {
|
|||
core.info(`[warning] ${(e as any).stack}`);
|
||||
}
|
||||
|
||||
try {
|
||||
await cleanTarget(packages);
|
||||
} catch (e) {
|
||||
core.info(`[warning] ${(e as any).stack}`);
|
||||
for (const workspace of workspaces) {
|
||||
const target = path.join(workspace, "target");
|
||||
try {
|
||||
await cleanTarget(target, packages);
|
||||
}
|
||||
catch (e) {
|
||||
core.info(`[warning] ${(e as any).stack}`);
|
||||
}
|
||||
}
|
||||
|
||||
core.info(`Saving paths:\n ${savePaths.join("\n ")}`);
|
||||
|
@ -170,5 +176,5 @@ async function macOsWorkaround() {
|
|||
// Workaround for https://github.com/actions/cache/issues/403
|
||||
// Also see https://github.com/rust-lang/cargo/issues/8603
|
||||
await exec.exec("sudo", ["/usr/sbin/purge"], { silent: true });
|
||||
} catch {}
|
||||
} catch { }
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue