3 Commits

Author SHA1 Message Date
Arpad Borsos
2656b87321 2.5.0
Some checks failed
coverage / Test `cargo-llvm-cov` on ubuntu-latest (push) Failing after 0s
globbed-directories / Test `cargo check/test` on ubuntu-latest (push) Failing after 0s
install / Test `cargo install` on ubuntu-latest (push) Failing after 0s
simple / Test `cargo check/test` on ubuntu-latest (push) Failing after 0s
sparse-registry / Test `cargo check/test` with sparse registry on ubuntu-latest (push) Failing after 0s
target-dir / Test custom target-dir on ubuntu-latest (push) Failing after 0s
workspaces / Test multiple workspaces on ubuntu-latest (push) Failing after 0s
coverage / Test `cargo-llvm-cov` on macos-latest (push) Has been cancelled
coverage / Test `cargo-llvm-cov` on windows-latest (push) Has been cancelled
install / Test `cargo install` on macos-latest (push) Has been cancelled
install / Test `cargo install` on windows-latest (push) Has been cancelled
simple / Test `cargo check/test` on macos-latest (push) Has been cancelled
simple / Test `cargo check/test` on windows-latest (push) Has been cancelled
sparse-registry / Test `cargo check/test` with sparse registry on macos-latest (push) Has been cancelled
sparse-registry / Test `cargo check/test` with sparse registry on windows-latest (push) Has been cancelled
target-dir / Test custom target-dir on macos-latest (push) Has been cancelled
target-dir / Test custom target-dir on windows-latest (push) Has been cancelled
workspaces / Test multiple workspaces on macos-latest (push) Has been cancelled
workspaces / Test multiple workspaces on windows-latest (push) Has been cancelled
2023-06-18 15:32:29 +02:00
Jiahao XU
715970feed feat: Add hash of .cargo/config.toml to key (#149)
Also:
 - Add and use `sort_and_uniq` to make sure `globFile` resulting
   and `keyFiles` does not contain duplicates.
 - Only returns regular file in function `globFile`

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
2023-06-18 10:12:25 +02:00
Jiahao XU
3d4000164d feat: Rm workspace crates version before caching (#147)
Fixed #146

 - Set all `package.version` in `Cargo.toml` to `0.0.0`
 - Set `{build-, dev-, }dependencies` of workspace crates to `0.0.0`
 - Remove workspace crates from `Cargo.lock` before caching
 - Sort all toml objects before hashing them as json

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
2023-06-18 09:29:44 +02:00
5 changed files with 8481 additions and 27 deletions

4179
dist/restore/index.js vendored

File diff suppressed because it is too large Load Diff

4179
dist/save/index.js vendored

File diff suppressed because it is too large Load Diff

17
package-lock.json generated
View File

@@ -1,19 +1,20 @@
{
"name": "rust-cache",
"version": "2.4.0",
"version": "2.5.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "rust-cache",
"version": "2.4.0",
"version": "2.5.0",
"license": "LGPL-3.0",
"dependencies": {
"@actions/cache": "^3.2.1",
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"@actions/glob": "^0.4.0",
"@actions/io": "^1.1.3"
"@actions/io": "^1.1.3",
"toml": "^3.0.0"
},
"devDependencies": {
"@vercel/ncc": "^0.36.1",
@@ -507,6 +508,11 @@
"semver": "bin/semver.js"
}
},
"node_modules/toml": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz",
"integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w=="
},
"node_modules/tough-cookie": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
@@ -988,6 +994,11 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
},
"toml": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz",
"integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w=="
},
"tough-cookie": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "rust-cache",
"version": "2.4.0",
"version": "2.5.0",
"description": "A GitHub Action that implements smart caching for rust/cargo projects with sensible defaults.",
"keywords": [
"actions",
@@ -26,7 +26,8 @@
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"@actions/glob": "^0.4.0",
"@actions/io": "^1.1.3"
"@actions/io": "^1.1.3",
"toml": "^3.0.0"
},
"devDependencies": {
"@vercel/ncc": "^0.36.1",

View File

@@ -1,7 +1,9 @@
import * as core from "@actions/core";
import * as glob from "@actions/glob";
import * as toml from "toml";
import crypto from "crypto";
import fs from "fs";
import fs_promises from "fs/promises";
import os from "os";
import path from "path";
@@ -127,27 +129,97 @@ export class CacheConfig {
}
self.workspaces = workspaces;
let keyFiles = await globFiles("rust-toolchain\nrust-toolchain.toml");
let keyFiles = await globFiles(".cargo/config.toml\nrust-toolchain\nrust-toolchain.toml");
const parsedKeyFiles = []; // keyFiles that are parsed, pre-processed and hashed
hasher = crypto.createHash("sha1");
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`,
`${root}/**/.cargo/config.toml\n${root}/**/rust-toolchain\n${root}/**/rust-toolchain.toml`,
)),
);
}
keyFiles = keyFiles.filter(file => !fs.statSync(file).isDirectory());
keyFiles.sort((a, b) => a.localeCompare(b));
hasher = crypto.createHash("sha1");
const cargo_manifests = sort_and_uniq(await globFiles(`${root}/**/Cargo.toml`));
for (const cargo_manifest of cargo_manifests) {
try {
const content = await fs_promises.readFile(cargo_manifest, { encoding: 'utf8' });
const parsed = toml.parse(content);
if ("package" in parsed) {
const pack = parsed.package;
if ("version" in pack) {
pack.version = "0.0.0";
}
}
for (const prefix of ["", "build-", "dev-"]) {
const section_name = `${prefix}dependencies`;
if (!(section_name in parsed)) {
continue;
}
const deps = parsed[section_name];
for (const key of Object.keys(deps)) {
const dep = deps[key];
if ("path" in dep) {
dep.version = '0.0.0'
}
}
}
hasher.update(JSON.stringify(sort_object(parsed)));
parsedKeyFiles.push(cargo_manifest);
} catch (_e) { // Fallback to caching them as regular file
keyFiles.push(cargo_manifest);
}
}
const cargo_locks = sort_and_uniq(await globFiles(`${root}/**/Cargo.lock`));
for (const cargo_lock of cargo_locks) {
try {
const content = await fs_promises.readFile(cargo_lock, { encoding: 'utf8' });
const parsed = toml.parse(content);
if (parsed.version !== 3 || !("package" in parsed)) {
// Fallback to caching them as regular file since this action
// can only handle Cargo.lock format version 3
keyFiles.push(cargo_lock);
continue;
}
// Package without `[[package]].source` and `[[package]].checksum`
// are the one with `path = "..."` to crates within the workspace.
const packages = parsed.package.filter((p: any) => {
"source" in p || "checksum" in p
});
hasher.update(JSON.stringify(sort_object(packages)));
parsedKeyFiles.push(cargo_lock);
} catch (_e) { // Fallback to caching them as regular file
keyFiles.push(cargo_lock);
}
}
}
keyFiles = sort_and_uniq(keyFiles);
for (const file of keyFiles) {
for await (const chunk of fs.createReadStream(file)) {
hasher.update(chunk);
}
}
let lockHash = digest(hasher);
self.keyFiles = keyFiles;
keyFiles.push(...parsedKeyFiles);
self.keyFiles = sort_and_uniq(keyFiles);
key += `-${lockHash}`;
self.cacheKey = key;
@@ -270,5 +342,45 @@ async function globFiles(pattern: string): Promise<string[]> {
const globber = await glob.create(pattern, {
followSymbolicLinks: false,
});
return await globber.glob();
// fs.statSync resolve the symbolic link and returns stat for the
// file it pointed to, so isFile would make sure the resolved
// file is actually a regular file.
return (await globber.glob()).filter(file => fs.statSync(file).isFile());
}
function sort_and_uniq(a: string[]) {
return a
.sort((a, b) => a.localeCompare(b))
.reduce(
(accumulator: string[], currentValue: string) => {
const len = accumulator.length;
// If accumulator is empty or its last element != currentValue
// Since array is already sorted, elements with the same value
// are grouped together to be continugous in space.
//
// If currentValue != last element, then it must be unique.
if (len == 0 || accumulator[len - 1].localeCompare(currentValue) != 0) {
accumulator.push(currentValue);
}
return accumulator;
},
[]
);
}
function sort_object(o: any): any {
if (Array.isArray(o)) {
return o.sort().map(sort_object);
} else if (typeof o === 'object' && o != null) {
return Object
.keys(o)
.sort()
.reduce(function(a: any, k) {
a[k] = sort_object(o[k]);
return a;
}, {});
} else {
return o;
}
}