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>
This commit is contained in:
parent
988c164c3d
commit
3d4000164d
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,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",
|
||||
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
@ -128,25 +130,101 @@ export class CacheConfig {
|
|||
self.workspaces = workspaces;
|
||||
|
||||
let keyFiles = await globFiles("rust-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}/**/rust-toolchain\n${root}/**/rust-toolchain.toml`,
|
||||
)),
|
||||
);
|
||||
|
||||
const cargo_manifests = (await globFiles(`${root}/**/Cargo.toml`))
|
||||
.filter(file => !fs.statSync(file).isDirectory());
|
||||
cargo_manifests.sort((a, b) => a.localeCompare(b));
|
||||
|
||||
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 = (await globFiles(`${root}/**/Cargo.lock`))
|
||||
.filter(file => !fs.statSync(file).isDirectory());
|
||||
cargo_locks.sort((a, b) => a.localeCompare(b));
|
||||
|
||||
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 = keyFiles.filter(file => !fs.statSync(file).isDirectory());
|
||||
keyFiles.sort((a, b) => a.localeCompare(b));
|
||||
|
||||
hasher = crypto.createHash("sha1");
|
||||
for (const file of keyFiles) {
|
||||
for await (const chunk of fs.createReadStream(file)) {
|
||||
hasher.update(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
let lockHash = digest(hasher);
|
||||
|
||||
keyFiles.push(...parsedKeyFiles);
|
||||
keyFiles.sort((a, b) => a.localeCompare(b));
|
||||
self.keyFiles = keyFiles;
|
||||
|
||||
key += `-${lockHash}`;
|
||||
|
@ -272,3 +350,20 @@ async function globFiles(pattern: string): Promise<string[]> {
|
|||
});
|
||||
return await globber.glob();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue