import * as crypto from "node:crypto"; import * as core from "@actions/core"; import * as fs from "node:fs"; import * as stream from "node:stream"; import * as util from "node:util"; import { create } from "@actions/glob"; /** * Hashes files matching the given glob pattern. * * Copied from https://github.com/actions/toolkit/blob/20ed2908f19538e9dfb66d8083f1171c0a50a87c/packages/glob/src/internal-hash-files.ts#L9-L49 * But supports hashing files outside the GITHUB_WORKSPACE. * @param pattern The glob pattern to match files. * @param verbose Whether to log the files being hashed. */ export async function hashFiles( pattern: string, verbose = false, ): Promise { const globber = await create(pattern); let hasMatch = false; const writeDelegate = verbose ? core.info : core.debug; const result = crypto.createHash("sha256"); let count = 0; for await (const file of globber.globGenerator()) { writeDelegate(file); if (fs.statSync(file).isDirectory()) { writeDelegate(`Skip directory '${file}'.`); continue; } const hash = crypto.createHash("sha256"); const pipeline = util.promisify(stream.pipeline); await pipeline(fs.createReadStream(file), hash); result.write(hash.digest()); count++; if (!hasMatch) { hasMatch = true; } } result.end(); if (hasMatch) { writeDelegate(`Found ${count} files to hash.`); return result.digest("hex"); } writeDelegate("No matches found for glob"); return ""; }