C#: Cache temporary dependency directory for BMN#3286
Conversation
And also clean it up.
There was a problem hiding this comment.
Pull Request Overview
This PR extends dependency caching for C# build-mode: none analysis by configuring a stable temporary directory path for the C# extractor, similar to the existing Java implementation. The feature is controlled by the CsharpCacheBuildModeNone feature flag and is designed to be safe to merge before the corresponding C# extractor support is available.
Key changes:
- Added new feature flag
CsharpCacheBuildModeNonewith environment variableCODEQL_ACTION_CSHARP_CACHE_BMN - Implemented C# dependency directory caching with conditional inclusion based on feature flag
- Extended cleanup logic to remove C# temporary dependency directories alongside Java directories
Reviewed Changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/feature-flags.ts | Adds the CsharpCacheBuildModeNone feature flag configuration |
| src/dependency-caching.ts | Implements getCsharpTempDependencyDir() and getCsharpDependencyDirs() functions, updates getDependencyPaths signature to be async, and includes the feature in the cache key hash |
| src/dependency-caching.test.ts | Adds tests verifying C# dependency directory inclusion based on feature flag state, and tests for feature prefix generation |
| src/analyze.ts | Sets CODEQL_EXTRACTOR_CSHARP_OPTION_BUILDLESS_DEPENDENCY_DIR environment variable when feature is enabled for C# build-mode: none, and threads features parameter through extraction functions |
| src/analyze-action.ts | Passes features parameter to runFinalize() |
| src/analyze-action-post.ts | Extends cleanup logic to remove both Java and C# temporary dependency directories |
| src/analyze-action-input.test.ts | Updates test assertions to account for new features parameter in runFinalize() |
| src/analyze-action-env.test.ts | Updates test assertions to account for new features parameter in runFinalize() |
| lib/*.js | Generated JavaScript files reflecting TypeScript changes |
| /** | ||
| * Returns an array of paths of directories on the runner that should be included in a dependency cache | ||
| * for a C# analysis. | ||
| * | ||
| * @returns The paths of directories on the runner that should be included in a dependency cache | ||
| * for a C# analysis. | ||
| */ |
There was a problem hiding this comment.
[nitpick] Consider adding a note similar to the one in getJavaDependencyDirs documentation (lines 54-56) explaining why this needs to be a function: "It is important that this is a function, because we call getTemporaryDirectory which would otherwise fail in tests if we haven't had a chance to initialise RUNNER_TEMP." This would improve consistency and help future maintainers understand the design decision.
|
@mbg : If the action only requires being able to communicate the dependency directory via an environment variable - then maybe we shouldn't expose the functionality as an extractor option? |
I have no strong feelings about this and just mirrored what we did for the Java extractor. IIRC the team there explicitly suggested making it an extractor option. Personally, I see no harm in it being an extractor option, but I am happy for you to make that decision and just let me know what environment variable we should set here |
Let's do the same as for Java for consistency. |
michaelnebel
left a comment
There was a problem hiding this comment.
Looks plausible to me, but it is probably a good idea to a get a review from someone that knows more about the actions code.
| t.assert( | ||
| runFinalizeStub.calledOnceWith( | ||
| sinon.match.any, | ||
| sinon.match.any, | ||
| "--threads=-1", | ||
| "--ram=4992", | ||
| ), | ||
| ); | ||
| t.assert( | ||
| runQueriesStub.calledOnceWith( | ||
| sinon.match.any, | ||
| "--ram=4992", | ||
| "--threads=-1", | ||
| ), | ||
| ); |
There was a problem hiding this comment.
Nice! Is it worth also worth putting the RAM and threads arguments in the same order?
There was a problem hiding this comment.
Probably -- I would lie if I said I didn't get this wrong after initially copying it from one to the other. Not sure if this PR is the best place to do it though.
| const features = createFeatures([Feature.CsharpCacheBuildModeNone]); | ||
|
|
||
| const result = await getFeaturePrefix(codeql, features, KnownLanguage.csharp); | ||
| t.notDeepEqual(result, ""); |
There was a problem hiding this comment.
Minor: why deep equality here?
There was a problem hiding this comment.
IIRC I just followed what other tests did for asserting string equality. I didn't check/try whether is would be enough.
| continue; | ||
| } | ||
| const result = await getFeaturePrefix(codeql, features, knownLanguage); | ||
| t.deepEqual(result, "", `Expected no feature prefix for ${knownLanguage}`); |
| * Returns an array of paths of directories on the runner that should be included in a dependency cache | ||
| * for a C# analysis. | ||
| * | ||
| * @returns The paths of directories on the runner that should be included in a dependency cache | ||
| * for a C# analysis. |
There was a problem hiding this comment.
Nit, here and elsewhere: avoid duplicating doc comments by just keeping the @returns paragraph.
There was a problem hiding this comment.
Probably not worth the effort of changing here, but happy to reduce duplication going forward.
|
@mbg : The extractor part has been merged. I suppose it needs to be released before being testable in conjunction with this change? |
@michaelnebel We can test this with a nightly (or a custom CLI build) in a test repo. To actually be more widely usable, we do have to release the CLI and this change. |
henrymercer
left a comment
There was a problem hiding this comment.
Reapproving after main was merged.
Follow-up from #3117. This PR extends the paths we cache for C# BMN with a similar solution as for Java BMN by configuring a particular, stable path for the extractor to store dependencies in.
There are four key parts to this:
This change depends on support for the
CODEQL_EXTRACTOR_CSHARP_OPTION_BUILDLESS_DEPENDENCY_DIRenvironment variable in the C# extractor, but is designed to be safe to merge as-is before that is available.Risk assessment
For internal use only. Please select the risk level of this change:
Which use cases does this change impact?
analysis-kinds: code-scanning).analysis-kinds: code-quality).How did/will you validate this change?
.test.tsfiles).pr-checks).If something goes wrong after this change is released, what are the mitigation and rollback strategies?
How will you know if something goes wrong after this change is released?
Merge / deployment checklist