diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 88c0c2ec6..f2561f9ff 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -91080,6 +91080,26 @@ async function makePatternCheck(patterns) { } return patterns; } +async function getCsharpHashPatterns(codeql, features) { + const basePatterns = [ + // NuGet + "**/packages.lock.json", + // Paket + "**/paket.lock" + ]; + const globber = await makeGlobber(basePatterns); + if ((await globber.glob()).length > 0) { + return basePatterns; + } + if (await features.getValue("csharp_new_cache_key" /* CsharpNewCacheKey */, codeql)) { + return makePatternCheck([ + "**/*.csproj", + "**/packages.config", + "**/nuget.config" + ]); + } + throw new NoMatchingFilesError(); +} var defaultCacheConfigs = { java: { getDependencyPaths: getJavaDependencyDirs, @@ -91097,12 +91117,7 @@ var defaultCacheConfigs = { }, csharp: { getDependencyPaths: () => [(0, import_path.join)(os3.homedir(), ".nuget", "packages")], - getHashPatterns: async () => makePatternCheck([ - // NuGet - "**/packages.lock.json", - // Paket - "**/paket.lock" - ]) + getHashPatterns: getCsharpHashPatterns }, go: { getDependencyPaths: () => [(0, import_path.join)(os3.homedir(), "go", "pkg", "mod")], diff --git a/lib/init-action.js b/lib/init-action.js index a8d951d20..cfa9250e4 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -87267,6 +87267,26 @@ async function makePatternCheck(patterns) { } return patterns; } +async function getCsharpHashPatterns(codeql, features) { + const basePatterns = [ + // NuGet + "**/packages.lock.json", + // Paket + "**/paket.lock" + ]; + const globber = await makeGlobber(basePatterns); + if ((await globber.glob()).length > 0) { + return basePatterns; + } + if (await features.getValue("csharp_new_cache_key" /* CsharpNewCacheKey */, codeql)) { + return makePatternCheck([ + "**/*.csproj", + "**/packages.config", + "**/nuget.config" + ]); + } + throw new NoMatchingFilesError(); +} var defaultCacheConfigs = { java: { getDependencyPaths: getJavaDependencyDirs, @@ -87284,12 +87304,7 @@ var defaultCacheConfigs = { }, csharp: { getDependencyPaths: () => [(0, import_path.join)(os2.homedir(), ".nuget", "packages")], - getHashPatterns: async () => makePatternCheck([ - // NuGet - "**/packages.lock.json", - // Paket - "**/paket.lock" - ]) + getHashPatterns: getCsharpHashPatterns }, go: { getDependencyPaths: () => [(0, import_path.join)(os2.homedir(), "go", "pkg", "mod")], diff --git a/src/dependency-caching.ts b/src/dependency-caching.ts index b852fa0d4..bf2b0244b 100644 --- a/src/dependency-caching.ts +++ b/src/dependency-caching.ts @@ -88,6 +88,54 @@ async function makePatternCheck(patterns: string[]): Promise { return patterns; } +/** + * Returns the list of glob patterns that should be used to calculate the cache key hash + * for a C# dependency cache. + * + * @param codeql The CodeQL instance to use. + * @param features Information about which FFs are enabled. + * @returns A list of glob patterns to use for hashing. + */ +async function getCsharpHashPatterns( + codeql: CodeQL, + features: Features, +): Promise { + // These files contain accurate information about dependencies, including the exact versions + // that the relevant package manager has determined for the project. Using these gives us + // stable hashes unless the dependencies change. + const basePatterns = [ + // NuGet + "**/packages.lock.json", + // Paket + "**/paket.lock", + ]; + const globber = await makeGlobber(basePatterns); + + if ((await globber.glob()).length > 0) { + return basePatterns; + } + + if (await features.getValue(Feature.CsharpNewCacheKey, codeql)) { + // These are less accurate for use in cache key calculations, because they: + // + // - Don't contain the exact versions used. They may only contain version ranges or none at all. + // - They contain information unrelated to dependencies, which we don't care about. + // + // As a result, the hash we compute from these files may change, even if + // the dependencies haven't changed. + return makePatternCheck([ + "**/*.csproj", + "**/packages.config", + "**/nuget.config", + ]); + } + + // If we get to this point, the `basePatterns` didn't find any files, + // and `Feature.CsharpNewCacheKey` is either not enabled or we didn't + // find any files using those patterns either. + throw new NoMatchingFilesError(); +} + /** * Default caching configurations per language. */ @@ -109,13 +157,7 @@ const defaultCacheConfigs: { [language: string]: CacheConfig } = { }, csharp: { getDependencyPaths: () => [join(os.homedir(), ".nuget", "packages")], - getHashPatterns: async () => - makePatternCheck([ - // NuGet - "**/packages.lock.json", - // Paket - "**/paket.lock", - ]), + getHashPatterns: getCsharpHashPatterns, }, go: { getDependencyPaths: () => [join(os.homedir(), "go", "pkg", "mod")],