5 Commits

Author SHA1 Message Date
Arpad Borsos
359a70e43a 2.2.0 2022-11-09 20:14:41 +01:00
Lucas Fernandes Nogueira
ecee04e7b3 feat: add save-if option, closes #66 (#91) 2022-11-06 19:15:00 +01:00
Arpad Borsos
b894d59a8d 2.1.0 2022-11-06 10:06:04 +01:00
Arpad Borsos
e78327dd9e small code style improvements, README and CHANGELOG updates 2022-11-06 09:50:33 +01:00
Lucas Fernandes Nogueira
ccdddcc049 only hash Cargo.toml/Cargo.lock that belong to a configured workspace (#90) 2022-11-05 21:18:04 +01:00
9 changed files with 4620 additions and 4570 deletions

View File

@@ -1,8 +1,17 @@
# Changelog
## 2.2.0
- Add new `save-if` option to always restore, but only conditionally save the cache.
## 2.1.0
- Only hash `Cargo.{lock,toml}` files in the configured workspace directories.
## 2.0.2
- Avoid calling `cargo metadata` on pre-cleanup.
- Added `prefix-key`, `cache-directories` and `cache-targets` options.
## 2.0.1

View File

@@ -14,11 +14,12 @@ sensible defaults.
- uses: Swatinem/rust-cache@v2
with:
# The prefix cache key, this can be changed to start a new cache manually
# The prefix cache key, this can be changed to start a new cache manually.
# default: "v0-rust"
prefix-key: ""
# An additional cache key that is stable over multiple jobs
# A cache key that is used instead of the automatic `job`-based key,
# and is stable over multiple jobs.
# default: empty
shared-key: ""
@@ -41,16 +42,23 @@ sensible defaults.
# default: ". -> target"
workspaces: ""
# Additional non workspace directories, separated by newlines
# Additional non workspace directories to be cached, separated by newlines.
cache-directories: ""
# Determines whether workspace `target` directories are cached.
# If `false`, only the cargo registry will be cached.
# default: "true"
cache-targets: ""
# Determines if the cache should be saved even when the workflow has failed.
# default: "false"
cache-on-failure: ""
# Determiners whether the cache should be saved.
# If `false`, the cache is only restored.
# Useful for jobs where the matrix is additive e.g. additional Cargo features.
# default: "true"
save-if: ""
```
Further examples are available in the [.github/workflows](./.github/workflows/) directory.

View File

@@ -3,34 +3,38 @@ description: "A GitHub Action that implements smart caching for rust/cargo proje
author: "Arpad Borsos <swatinem@swatinem.de>"
inputs:
prefix-key:
description: "The prefix cache key, this can be changed to start a new cache manually"
description: "The prefix cache key, this can be changed to start a new cache manually."
required: false
default: "v0-rust"
shared-key:
description: "An additional cache key that is stable over multiple jobs"
description: "A cache key that is used instead of the automatic `job`-based key, and is stable over multiple jobs."
required: false
key:
description: "An additional key for the cache"
description: "An additional cache key that is added alongside the automatic `job`-based cache key and can be used to further differentiate jobs."
required: false
env-vars:
description: "Additional environment variables to include in the cache key, separated by spaces"
description: "Additional environment variables to include in the cache key, separated by spaces."
required: false
workspaces:
description: "Paths to multiple Cargo workspaces and their target directories, separated by newlines"
description: "Paths to multiple Cargo workspaces and their target directories, separated by newlines."
required: false
cache-directories:
description: "Additional non workspace directories, separated by newlines"
description: "Additional non workspace directories to be cached, separated by newlines."
required: false
cache-targets:
description: "Determines whether workspace targets are cached"
description: "Determines whether workspace targets are cached. If `false`, only the cargo registry will be cached."
required: false
default: "true"
cache-on-failure:
description: "Cache even if the build fails. Defaults to false"
description: "Cache even if the build fails. Defaults to false."
required: false
save-if:
description: "Determiners whether the cache should be saved. If `false`, the cache is only restored."
required: false
default: "true"
outputs:
cache-hit:
description: "A boolean value that indicates an exact match was found"
description: "A boolean value that indicates an exact match was found."
runs:
using: "node16"
main: "dist/restore/index.js"

4539
dist/restore/index.js vendored

File diff suppressed because it is too large Load Diff

4542
dist/save/index.js vendored

File diff suppressed because it is too large Load Diff

5
package-lock.json generated
View File

@@ -1,12 +1,11 @@
{
"name": "rust-cache",
"version": "2.0.2",
"version": "2.2.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "rust-cache",
"version": "2.0.2",
"version": "2.2.0",
"license": "LGPL-3.0",
"dependencies": {
"@actions/cache": "^3.0.6",

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "rust-cache",
"version": "2.0.2",
"version": "2.2.0",
"description": "A GitHub Action that implements smart caching for rust/cargo projects with sensible defaults.",
"keywords": [
"actions",

View File

@@ -50,7 +50,7 @@ export class CacheConfig {
// This uses either the `shared-key` input,
// or the `key` input combined with the `job` key.
let key = core.getInput("prefix-key");
let key = core.getInput("prefix-key") || "v0-rust";
const sharedKey = core.getInput("shared-key");
if (sharedKey) {
@@ -118,11 +118,29 @@ export class CacheConfig {
let lockHash = core.getState(STATE_LOCKFILE_HASH);
let keyFiles: Array<string> = JSON.parse(core.getState(STATE_LOCKFILES) || "[]");
// Constructs the workspace config and paths to restore:
// The workspaces are given using a `$workspace -> $target` syntax.
const workspaces: Array<Workspace> = [];
const workspacesInput = core.getInput("workspaces") || ".";
for (const workspace of workspacesInput.trim().split("\n")) {
let [root, target = "target"] = workspace.split("->").map((s) => s.trim());
root = path.resolve(root);
target = path.join(root, target);
workspaces.push(new Workspace(root, target));
}
self.workspaces = workspaces;
if (!lockHash) {
const globber = await glob.create("**/Cargo.toml\n**/Cargo.lock\nrust-toolchain\nrust-toolchain.toml", {
followSymbolicLinks: false,
});
keyFiles = await globber.glob();
keyFiles = keyFiles.concat(await globFiles("rust-toolchain\nrust-toolchain.toml"));
for (const workspace of workspaces) {
const root = workspace.root;
keyFiles.push(
...(await globFiles(
`${root}/**/Cargo.toml\n${root}/**/Cargo.lock\n${root}/**/rust-toolchain\n${root}/**/rust-toolchain.toml`,
)),
);
}
keyFiles.sort((a, b) => a.localeCompare(b));
hasher = crypto.createHash("sha1");
@@ -138,30 +156,18 @@ export class CacheConfig {
}
self.keyFiles = keyFiles;
key += `-${lockHash}`;
self.cacheKey = key;
// Constructs the workspace config and paths to restore:
// The workspaces are given using a `$workspace -> $target` syntax.
const workspaces: Array<Workspace> = [];
const workspacesInput = core.getInput("workspaces") || ".";
for (const workspace of workspacesInput.trim().split("\n")) {
let [root, target = "target"] = workspace.split("->").map((s) => s.trim());
root = path.resolve(root);
target = path.join(root, target);
workspaces.push(new Workspace(root, target));
}
self.workspaces = workspaces;
self.cachePaths = [CARGO_HOME];
const cacheTargets = core.getInput("cache-targets").toLowerCase();
const cacheTargets = core.getInput("cache-targets").toLowerCase() || "true";
if (cacheTargets === "true") {
self.cachePaths.push(...workspaces.map((ws) => ws.target));
}
const cacheDirectories = core.getInput("cache-directories");
for (const dir of cacheDirectories.trim().split("\n")) {
for (const dir of cacheDirectories.trim().split(/\s+/).filter(Boolean)) {
self.cachePaths.push(dir);
}
@@ -212,3 +218,10 @@ async function getRustVersion(): Promise<RustVersion> {
.filter((s) => s.length === 2);
return Object.fromEntries(splits);
}
async function globFiles(pattern: string): Promise<string[]> {
const globber = await glob.create(pattern, {
followSymbolicLinks: false,
});
return await globber.glob();
}

View File

@@ -13,7 +13,9 @@ process.on("uncaughtException", (e) => {
});
async function run() {
if (!cache.isFeatureAvailable()) {
const save = core.getInput("save-if").toLowerCase() || "true";
if (!(cache.isFeatureAvailable() && save === "true")) {
return;
}