Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd05243424 | ||
|
|
65dbc54a5d | ||
|
|
be7377e68e | ||
|
|
2656b87321 | ||
|
|
715970feed | ||
|
|
3d4000164d |
@@ -1,5 +1,14 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2.5.1
|
||||||
|
|
||||||
|
- Fix hash contribution of `Cargo.lock`.
|
||||||
|
|
||||||
|
## 2.5.0
|
||||||
|
|
||||||
|
- feat: Rm workspace crates version before caching.
|
||||||
|
- feat: Add hash of `.cargo/config.toml` to key.
|
||||||
|
|
||||||
## 2.4.0
|
## 2.4.0
|
||||||
|
|
||||||
- Fix cache key stability.
|
- Fix cache key stability.
|
||||||
|
|||||||
4162
dist/restore/index.js
vendored
4162
dist/restore/index.js
vendored
File diff suppressed because it is too large
Load Diff
4162
dist/save/index.js
vendored
4162
dist/save/index.js
vendored
File diff suppressed because it is too large
Load Diff
17
package-lock.json
generated
17
package-lock.json
generated
@@ -1,19 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "rust-cache",
|
"name": "rust-cache",
|
||||||
"version": "2.4.0",
|
"version": "2.5.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "rust-cache",
|
"name": "rust-cache",
|
||||||
"version": "2.4.0",
|
"version": "2.5.1",
|
||||||
"license": "LGPL-3.0",
|
"license": "LGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/cache": "^3.2.1",
|
"@actions/cache": "^3.2.1",
|
||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^1.1.1",
|
||||||
"@actions/glob": "^0.4.0",
|
"@actions/glob": "^0.4.0",
|
||||||
"@actions/io": "^1.1.3"
|
"@actions/io": "^1.1.3",
|
||||||
|
"toml": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vercel/ncc": "^0.36.1",
|
"@vercel/ncc": "^0.36.1",
|
||||||
@@ -507,6 +508,11 @@
|
|||||||
"semver": "bin/semver.js"
|
"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": {
|
"node_modules/tough-cookie": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
|
"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": {
|
"tough-cookie": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"name": "rust-cache",
|
"name": "rust-cache",
|
||||||
"version": "2.4.0",
|
"version": "2.5.1",
|
||||||
"description": "A GitHub Action that implements smart caching for rust/cargo projects with sensible defaults.",
|
"description": "A GitHub Action that implements smart caching for rust/cargo projects with sensible defaults.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"actions",
|
"actions",
|
||||||
@@ -26,7 +26,8 @@
|
|||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^1.1.1",
|
||||||
"@actions/glob": "^0.4.0",
|
"@actions/glob": "^0.4.0",
|
||||||
"@actions/io": "^1.1.3"
|
"@actions/io": "^1.1.3",
|
||||||
|
"toml": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vercel/ncc": "^0.36.1",
|
"@vercel/ncc": "^0.36.1",
|
||||||
|
|||||||
111
src/config.ts
111
src/config.ts
@@ -1,7 +1,9 @@
|
|||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
import * as glob from "@actions/glob";
|
import * as glob from "@actions/glob";
|
||||||
|
import * as toml from "toml";
|
||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
import fs_promises from "fs/promises";
|
||||||
import os from "os";
|
import os from "os";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
||||||
@@ -127,27 +129,97 @@ export class CacheConfig {
|
|||||||
}
|
}
|
||||||
self.workspaces = workspaces;
|
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) {
|
for (const workspace of workspaces) {
|
||||||
const root = workspace.root;
|
const root = workspace.root;
|
||||||
keyFiles.push(
|
keyFiles.push(
|
||||||
...(await globFiles(
|
...(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(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(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 (const file of keyFiles) {
|
||||||
for await (const chunk of fs.createReadStream(file)) {
|
for await (const chunk of fs.createReadStream(file)) {
|
||||||
hasher.update(chunk);
|
hasher.update(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let lockHash = digest(hasher);
|
let lockHash = digest(hasher);
|
||||||
|
|
||||||
self.keyFiles = keyFiles;
|
keyFiles.push(...parsedKeyFiles);
|
||||||
|
self.keyFiles = sort_and_uniq(keyFiles);
|
||||||
|
|
||||||
key += `-${lockHash}`;
|
key += `-${lockHash}`;
|
||||||
self.cacheKey = key;
|
self.cacheKey = key;
|
||||||
@@ -270,5 +342,28 @@ async function globFiles(pattern: string): Promise<string[]> {
|
|||||||
const globber = await glob.create(pattern, {
|
const globber = await glob.create(pattern, {
|
||||||
followSymbolicLinks: false,
|
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;
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user