Cache multiple target directories from 'target-dir'

This commit is contained in:
Nick Mosher 2021-07-16 16:58:46 -04:00 committed by Arpad Borsos
parent fa61956921
commit 260a713186
No known key found for this signature in database
GPG Key ID: FC7BCA77824B3298
15 changed files with 195 additions and 41 deletions

View File

@ -24,8 +24,13 @@ jobs:
- uses: ./
with:
cache-on-failure: true
workspace-paths: |
./
wasm-workspace/
- run: |
cargo install cargo-deny --locked
cargo check
cargo test
cargo test
rustup target install wasm32-unknown-unknown
cd wasm-workspace && cargo check

10
.gitignore vendored
View File

@ -1,2 +1,8 @@
node_modules
/target
node_modules/
target/
# Editors
.idea/
# Mac
.DS_Store

96
Cargo.lock generated
View File

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "actix-codec"
version = "0.4.0-beta.1"
@ -228,6 +230,17 @@ dependencies = [
"memchr",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.1"
@ -328,9 +341,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.66"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cfg-if"
@ -338,6 +351,30 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "3.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "190814073e85d238f31ff738fcb0bf6910cedeb73376c87cd69291028966fd83"
dependencies = [
"atty",
"bitflags",
"clap_lex",
"indexmap",
"strsim",
"termcolor",
"textwrap",
]
[[package]]
name = "clap_lex"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "const_fn"
version = "0.4.5"
@ -701,9 +738,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.86"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "lock_api"
@ -813,9 +850,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.5.2"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "opaque-debug"
@ -856,6 +893,12 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "os_str_bytes"
version = "6.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa"
[[package]]
name = "parking_lot"
version = "0.11.1"
@ -1090,6 +1133,7 @@ name = "rust-cache"
version = "0.1.0"
dependencies = [
"actix-web",
"clap",
"reqwest",
]
@ -1314,6 +1358,12 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.60"
@ -1340,10 +1390,25 @@ dependencies = [
]
[[package]]
name = "thread_local"
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
[[package]]
name = "thread_local"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
dependencies = [
"once_cell",
]
@ -1462,11 +1527,11 @@ dependencies = [
[[package]]
name = "tracing-core"
version = "0.1.17"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f"
checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7"
dependencies = [
"lazy_static",
"once_cell",
]
[[package]]
@ -1649,6 +1714,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"

View File

@ -7,4 +7,5 @@ edition = "2018"
[dev-dependencies]
reqwest = "0.11.0"
clap = "3"
actix-web = { git = "https://github.com/actix/actix-web.git", rev = "bd26083f333ecf63e3eb444748250364ce124f5e" }

View File

@ -17,6 +17,9 @@ inputs:
target-dir:
description: "The target dir that should be cleaned and persisted, defaults to `./target`"
required: false
workspace-paths:
description: "Paths to multiple Cargo workspaces, separated by newlines"
required: false
cache-on-failure:
description: "Cache even if the build fails. Defaults to false"
required: false

View File

@ -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 {

View File

@ -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);

View File

@ -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 { }
}

View File

@ -0,0 +1,2 @@
[build]
target = "wasm32-unknown-unknown"

1
wasm-workspace/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
Cargo.lock

View File

@ -0,0 +1,5 @@
[workspace]
members = [
"crates/one",
"crates/two",
]

View File

@ -0,0 +1,14 @@
[package]
name = "wasm-one"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
reqwest = "0.11.0"
async-std = "1"
tracing = "0.1"
tracing-futures = "0.2"
serde = "1"
serde_json = "1"

View File

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

View File

@ -0,0 +1,9 @@
[package]
name = "wasm-two"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = "3"

View File

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}