GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Cache CLI extractor paths across Actions steps by mario-campos · Pull Request #3950 · github/codeql-action

Conversation

@mario-campos

@mario-campos mario-campos commented Jun 4, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Similar to #3943, this PR caches the output of codeql resolve languages, which contains the paths to the various extractors so that repeated calls to resolveLanguages() are idempotent. Additionally, re-implement resolveExtractor() as a wrapper over resolveLanguages() (to re-use the cached output) rather than shell out to codeql resolve extractor.

In one experiment, I counted seven instances of shelling out to codeql resolve extractor. When you dig into the code, you can see why: resolveExtractor() is not called often or from many places; But one caller is isTracedLanguage(), which is wrapped by isScannedLanguage(). And these functions are often used in a loop/map over all/some languages. This can explain why we see consecutive executions of codeql resolve extractor.

In support of the above goals, this PR also adds some additional functions to the json module, to enable validation of the codeql version output.

Risk assessment

For internal use only. Please select the risk level of this change:

  • Low risk: Changes are fully under feature flags, or have been fully tested and validated in pre-production environments and are highly observable, or are documentation or test only.

Which use cases does this change impact?

Workflow types:

  • Advanced setup - Impacts users who have custom CodeQL workflows.
  • Managed - Impacts users with dynamic workflows (Default Setup, Code Quality, ...).

Products:

  • Code Scanning - The changes impact analyses when analysis-kinds: code-scanning.
  • Code Quality - The changes impact analyses when analysis-kinds: code-quality.
  • Other first-party - The changes impact other first-party analyses.
  • Third-party analyses - The changes affect the upload-sarif action.

Environments:

  • Dotcom - Impacts CodeQL workflows on github.com and/or GitHub Enterprise Cloud with Data Residency.
  • GHES - Impacts CodeQL workflows on GitHub Enterprise Server.
  • Testing/None - This change does not impact any CodeQL workflows in production.

How did/will you validate this change?

  • Unit tests - I am depending on unit test coverage (i.e. tests in .test.ts files).
  • End-to-end tests - I am depending on PR checks (i.e. tests in pr-checks).
  • Other - Manual/local testing

If something goes wrong after this change is released, what are the mitigation and rollback strategies?

  • Feature flags - All new or changed code paths can be fully disabled with corresponding feature flags.
  • Rollback - Change can only be disabled by rolling back the release or releasing a new version with a fix.
  • Development/testing only - This change cannot cause any failures in production.
  • Other - Please provide details.

How will you know if something goes wrong after this change is released?

  • Telemetry - I rely on existing telemetry or have made changes to the telemetry.
    • Dashboards - I will watch relevant dashboards for issues after the release. Consider whether this requires this change to be released at a particular time rather than as part of a regular release.
    • Alerts - New or existing monitors will trip if something goes wrong with this change.
  • Other - Please provide details.

Are there any special considerations for merging or releasing this change?

  • No special considerations - This change can be merged at any time.
  • Special considerations - This change should only be merged once certain preconditions are met. Please provide details of those or link to this PR from an internal issue.

Merge / deployment checklist

  • Confirm this change is backwards compatible with existing workflows.
  • Consider adding a changelog entry for this change.
  • Confirm the readme and docs have been updated if necessary.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@github-actions github-actions Bot added the size/S Should be easy to review label Jun 4, 2026
henrymercer
henrymercer reviewed Jun 5, 2026
View reviewed changes

@henrymercer henrymercer left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caching these invocations makes a lot of sense! I have a high level comment and a couple of lower level comments.

The main point is that now that we're caching multiple invocations, it might be a good opportunity to generalise the design. For instance, you could imagine something like:

const versionCache = createPersistedCliCache({ envVar: EnvVar.CODEQL_VERSION_INFO, validate: isVersionInfo });
const resolveLanguagesCache = createPersistedCliCache({ envVar: EnvVar.CODEQL_RESOLVE_LANGUAGES, validate: isResolveLanguagesOutput });

where createPersistedCliCache handles memoising in the Action and persisting between Actions steps with an environment variable.

Some smaller things:

  • Ideally the cache entry would also depend on getExtraOptionsFromEnv(["resolve","languages"])
  • We should remove the cache in testing-utils.ts like we do for the CodeQL version cache

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/codeql.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

mbg
mbg reviewed Jun 10, 2026
View reviewed changes

@mbg mbg left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @henrymercer's comments regarding a more generalised design for this. I am wondering about the use of environment variables here vs using a file on disk. I don't know if you have already considered this, but we store e.g. the Action configuration on disk as a file. Perhaps that would make sense for these cached CLI results as well.

A general point: could we also make sure to add doc comments for new top-level definitions before merging?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/environment.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/util.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

mario-campos added 8 commits June 18, 2026 09:58
@mario-campos
Cache the output of codeql resolve languages
311292c
Repeated calls to `resolveLanguages()` will only pay the performance penalty of executing `codeql resolve languages` once.
@mario-campos
Reimplement resolveExtractor() as wrapper over resolveLanguages()
6010f85
By wrapping `resolveLanguages()`, which is memoized, we can avoid executing `codeql resolve extractor` several times over the course of an analysis.
@mario-campos
Validate numbers, objects, and undefinables in the json module
445107e
This commit adds a `number` validator`, an `object` validator, an `isNumber` predicate, and `undefinable()` to test optional-but-not-null properties.
@mario-campos
Refactor isVersionInfo() to use json` module
587fcb3
@mario-campos
Refactor CLI executions into helper functions
889ae42
This provides a separation of concerns between the memoization and the execution.
@mario-campos
Refactor CLI JSON handling into a dedicated runCliJson function
dc8e1e9
@mario-campos
Refactor CLI caching with in-memory and file storage
a602287
@mario-campos
Rebased onto main; fixups were needed
b18df17
@mario-campos
mario-campos force-pushed the mario-campos/cache-cli-resolve-langs branch from c218fd6 to b18df17 Compare June 18, 2026 15:25
@github-actions github-actions Bot added size/XL May be very hard to review and removed size/S Should be easy to review labels Jun 18, 2026
@mario-campos
Add error handling for undefined extractors in language resolution
553eef0
@mario-campos

mario-campos commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

I've taken your comments into consideration and overhauled the design to be more comprehensive and unified. The design now backs to a temporary file instead of the environment. I also identified a few opportunities to refactor some duplicated code into helper functions.

I kept the use of cmd as a key in the cache, but I question whether it's really necessary. I think it's safe to assume that, in most cases, there will only be one instance of codeql in use per job. And, even in the event that there's more than one instance, how likely is it that init would use a different version than autobuild or analyze? If it's not necessary, I would opt to delete it to simplify the code a bit.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mario-campos
mario-campos marked this pull request as ready for review June 18, 2026 15:44
@mario-campos
mario-campos requested a review from a team as a code owner June 18, 2026 15:44
Copilot AI review requested due to automatic review settings June 18, 2026 15:44
Copilot started reviewing on behalf of mario-campos June 18, 2026 15:45
View session
Copilot AI reviewed Jun 18, 2026
View reviewed changes

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

  • Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.

Pull request overview

This PR introduces a cross-step cache for selected CodeQL CLI command outputs (notably codeql version and codeql resolve languages) to reduce repeated JVM startups and improve performance across GitHub Actions steps. It also refactors extractor resolution to derive extractor roots from resolve languages (reusing the cached output) and extends the internal JSON validation helpers to support stronger runtime validation of CLI JSON output.

Changes:

  • Add a new 2-tier command-output cache (in-memory + temp-file) and wire it into codeql.ts for version and resolve languages.
  • Refactor resolveExtractor() to use resolveLanguages() rather than invoking codeql resolve extractor.
  • Extend src/json validation helpers (number/object validators and undefinable) and add unit tests; remove now-obsolete util-based version cache.
Show a summary per file
File Description
src/util.ts Removes the prior in-process/env-var version cache helpers.
src/util.test.ts Removes tests for the old version-caching behavior.
src/testing-utils.ts Updates test setup to reset the new command-output cache between tests.
src/status-report.ts Switches telemetry version lookup to the new cache + isVersionInfo guard.
src/json/index.ts Adds number, object, and undefinable validators to support schema checks.
src/json/index.test.ts Adds tests for undefinable semantics (rejecting null).
src/environment.ts Removes the env var used for the old persisted version cache.
src/codeql.ts Adds caching wrappers/type guards and refactors extractor resolution and JSON parsing.
src/cache.ts New: implements the command-output cache (memo + temp file).
src/cache.test.ts New: tests cache persistence/memo behavior and validation.
lib/entry-points.js Generated output (content excluded by policy; not reviewed).

Copilot's findings

Files excluded by content exclusion policy (1)
  • lib/entry-points.js
  • Files reviewed: 10/11 changed files
  • Comments generated: 3

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/cache.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/codeql.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/codeql.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

@mario-campos
Refactor resolveLanguages() to cache output according to CLI featur…
c8e32e4
…e support

The output of `resolveLanguages()` can vary based on whether the flag `--filter-to-languages-with-queries` is included, but not all versions of the CLI support that. This makes caching a single execution problematic, so I opted to cache it based on whether it's supported. If it's supported, it's used; otherwise, it's not.
@mario-campos
mario-campos force-pushed the mario-campos/cache-cli-resolve-langs branch from 2f4495a to c8e32e4 Compare June 18, 2026 19:46
henrymercer
henrymercer reviewed Jun 19, 2026
View reviewed changes

@henrymercer henrymercer left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for implementing the generic cache mechanism, that's a nice simplification! To make this PR easier to review and get merged, what do you think about splitting this PR into two: the first would implement the generic cache mechanism just for codeql version, and the second would use it to cache codeql resolve languages?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

mario-campos reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
mbg
mbg requested changes Jun 19, 2026
View reviewed changes

@mbg mbg left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't finished reviewing everything (particularly the new tests as well as codeql.ts), but I already have a bunch of comments that I think should be addressed. So to not end up with too much noise in one go, I am submitting my review without reviewing those last bits.

The main thing to look at is that the on-disk cache is repeatedly written to and read from, which obviously has unnecessary overheads. It would be better if the on-disk cache was only read once (if it exists) to initialise the in-memory cache. It should then only be written to when the Action is about to exit.

Secondly, it would be nice (but is not essential) if we could avoid having the in-memory cache as global state and instead propagate it between the relevant use sites. Since we already have a CodeQL object, we could probably make the command cache part of it. That would make the data flow more explicit and simplify the tests, which then don't have to clear the global cache and can additionally run in parallel.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/json/index.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/cache.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/json/index.test.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/config-utils.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/config-utils.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/cache.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/cache.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/cache.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/cache.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/cache.ts Outdated
Comment on lines +141 to +147
/**
* Clears the in-process memo (tier 1). Only for use in tests, which exercise
* multiple "steps" within a single process.
*/
export function resetCachedCommandOutputs(): void {
inMemoryCache.clear();
}

@mbg mbg Jun 19, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some other files, we export these test-only functions in a nested object to make it clearer that they are for test-use only.

That said, my general preference for global state in the CodeQL Action is to try and make it explicit in the way I have done recently in e.g. #3963

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mario-campos mario-campos Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of not using global state as a cache, but I wonder if that might be a big shift from the current implementation. And, in the spirit of keeping this PR "small" and tightly-scoped, I think that should be a separate PR.

I'd like to keep this PR focused on generalizing the caching implementation into memory and file backings.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
mario-campos added 5 commits June 19, 2026 13:55
@mario-campos
Rename optional and undefinable functions for clarity; update rel…
defcf1b
…ated schemas to use `optionalOrNull`
@mario-campos
Improve documentation for cache file and command keys in CLI
420c97e
@mario-campos
Replace string with CommandCacheKey for better type safety
dd7ff30
@mario-campos
Rename CacheEntry to CommandCacheEntry for consistency
126166c
@mario-campos
Refactor cache file reading to check for existence before attempting …
94b1260
…to read
mario-campos added 10 commits June 19, 2026 16:07
@mario-campos
Add logging for command cache file read/write failures
d1bd5ec
@mario-campos
Remove duplicate key check in cacheCommandOutput and related tests
805b590
This key-check is unnecessary because this function is only ever called if the key does NOT exist in the cache already. In that case, why check again?
@mario-campos
Front-load caching and rear-load saving to disk
895ffe7
This implementation saves CPU and I/O by not trying to write to the file on every set-cache.
@mario-campos
Refactor cache storage to use cacheCommandOutput for consistency
649baba
@mario-campos
Add warning log for invalid data in command cache retrieval
b3c7aa7
@mario-campos
Move cache.ts to cli/output-cache.ts
41965b0
This change should hopefully make the purpose of this module clear.
@mario-campos
Refactor CommandCacheKey as a string union
c2f4379
@mario-campos
Move output type validators to output-cache.ts module
0d69817
This move simplifies the consumer-side of the module. And, also, the validators should be an internal implementation detail—not the concern of those who wish to "get" a cached output.
@mario-campos
Switch CommandCacheKey back to an enum
da14981
The code reads better/simpler as an `enum`.
@mario-campos
Revert JSON module changes
bba0d6c
These have been spun off into #3980.
This was referenced Jul 1, 2026
Create wrapper runCliJson #3981
Merged
Support undefined, number in JSON module #3980
Merged
mario-campos added 5 commits July 1, 2026 09:41
@mario-campos
Revert change to resolveExtractor
7f4f27e
This is secondary work that will follow from the main purpose of this PR.
@mario-campos
Perform deep validation of VersionInfo.features
252ad66
@mario-campos
Revert runCliJson implementation
5110948
It's been forked off into #3981
@mario-campos
Merge branch 'main' into mario-campos/cache-cli-resolve-langs
d4b99ad
# Conflicts:
#	lib/entry-points.js
#	src/codeql.ts
#	src/environment.ts
#	src/status-report.ts
@mario-campos
Revert src/config-utils.ts
8f1212f
These hunks were related to another hunk elsewhere, that has since now been reverted in favor of a separate/distinct PR.
@mario-campos
mario-campos force-pushed the mario-campos/cache-cli-resolve-langs branch from 0419782 to 8f1212f Compare July 14, 2026 03:31
mario-campos added 4 commits July 13, 2026 22:37
@mario-campos
Delete uncached codeql.resolveLanguages() function call
ec96b52
This CLI command was cached, at one point, but that's been saved for another PR, so this change will too.
@mario-campos
Validate CLI memory-backed cached objects against CLI path
0daa052
@mario-campos
Merge remote-tracking branch 'origin/main' into mario-campos/cache-cl…
ecf4e52
…i-resolve-langs
@mario-campos
Update isVersionInfo validation function with check lambda
a35a8ac
@mario-campos
mario-campos requested review from henrymercer and mbg July 14, 2026 05:01
ellisonantoniafelicia-star
ellisonantoniafelicia-star approved these changes Jul 14, 2026
View reviewed changes
mbg
mbg requested changes Jul 14, 2026
View reviewed changes

@mbg mbg left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for continuing to work on this, and addressing earlier feedback.

Unfortunately, I still don't think this is ready. There are a few things going on which suggest that the changes aren't finished yet, such as that the caching is not used for resolveLanguages and that only the init action stores the on-disk cache.

Further, there continue to be two high-level design points that I am concerned about:

  1. The cache is only restored from disk on a per-command basis in getCachedCommandOutput. Restoring all cache entries from the on-disk cache would make sense. This could reasonably be done in either runInActions or the first time that readCommandCacheFile is called and successfully reads the on-disk cache.
  2. Cache entries are keyed by the command and CLI path, but not the arguments. This probably doesn't matter for version and maybe not even for resolve languages, but would make sense to avoid potential surprises now or later. To make this change, entries in the cache shouldn't primarily be indexed by CommandCacheKey values, but by keys derived (i.e. hashes computed) from the CLI path, command, arguments, and possibly even other factors such as environment variables.

A concern is also self-hosted runners, where the on-disk cache may persist between workflows. We should make sure that this either doesn't happen (by explicitly deleting the file in e.g. init-post) or storing e.g. the analysis UUID in the file and deleting it if it doesn't match.

I'd also like us to be careful with the new validators you've added. These shouldn't accidentally end up in the path of direct CLI output, because that would make this a high-risk change.

To get on with things and have something that can be merged sooner-than-later, perhaps it would be good to break this down into at least two parts (each as separate PR):

  1. An implementation of only "Tier 1" and "Tier 3". I.e. no on-disk cache at all, but addressing my concern about the cache keys.
  2. Adding "Tier 2" back in, and addressing my concerns about reading/writing the on-disk cache and potential issues on self-hosted runners.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/cli/output-cache.ts
Comment on lines +20 to +32
export interface VersionInfo {
version: string;
features?: { [name: string]: boolean };
/**
* The overlay version helps deal with backward incompatible changes for
* overlay analysis. When a precompiled query pack reports the same overlay
* version as the CodeQL CLI, we can use the CodeQL CLI to perform overlay
* analysis with that pack. Otherwise, if the overlay versions are different,
* or if either the pack or the CLI does not report an overlay version,
* we need to revert to non-overlay analysis.
*/
overlayVersion?: number;
}

@mbg mbg Jul 14, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type doesn't seem like it really belongs here; i.e. it has nothing to do with the output caching specifically. I assume that you've moved it to avoid a circular dependency. There are two ways of addressing this:

  1. (Preferably) Moving this into a location that avoids the cycle. For example, a new cli/types.ts file.
  2. Importing just type { VersionInfo } from "../codeql.ts which (afaik) is also fine.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/cli/output-cache.ts
Comment on lines +45 to +53
features: {
validate: isBooleanRecord,
check: (obj) => ({
unknownKeys: [],
invalidKeys: [],
valid: isBooleanRecord(obj),
}),
required: false,
},

@mbg mbg Jul 14, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could probably be turned into a reusable record validator in json/index.ts. It would also be good to populate invalidKeys correctly.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/cli/output-cache.ts
Comment on lines +232 to +238
/**
* Clears the in-process memo (tier 1). Only for use in tests, which exercise
* multiple "steps" within a single process.
*/
export function resetCachedCommandOutputs(): void {
inMemoryCache.clear();
}

@mbg mbg Jul 14, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my earlier comment about exporting this via an object named to indicate that this is for testing only.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/cli/output-cache.ts
/**
* Returns the cached output for `key`, or `undefined` if it isn't cached.
*
* Resolves tier 1 (in-memory memo) first, then tier 2 (temporary file). A value

@mbg mbg Jul 14, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: The phrase "in-memory memo" is used a few times. This seems odd to me for two reasons:

  1. Memoisation isn't usually abbreviated like that (unless it is a function name or similar where the length becomes a problem)
  2. Memoisation implies "in-memory", so the "in-memory" part is redundant.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mario-campos mario-campos Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... that's Copilot 😞

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/cli/output-cache.ts
key: K,
cmd?: string,
): CommandCacheKeyOutputMap[K] | undefined {
// Tier 1: the in-memory variable.

@mbg mbg Jul 14, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Tier 1: the in-memory variable.
// Try to retrieve the result from memory first.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/init-action.ts
core.setOutput("codeql-version", (await codeql.getVersion()).version);

// Persist the command cache to disk at the end of a successful init.
writeCommandCacheFile();

@mbg mbg Jul 14, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this only done for the init action? Consider hooking this into runInActions in action-common.ts.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mario-campos mario-campos Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking here is that many (most?) of the CLI commands that codeql-action invokes are not worth caching—either because we won't need the output again or because the value of the command is in the side-effect, not the output (e.g. ,codeql database create).

Therefore, I think it would make sense to invoke all of the cache-able CLI commands in init, either as-needed or pre-emptively. Once that's done, the cache would presumably be set for the life of the workflow run. There would be no need to write the cache to file in autobuild or analyze or upload-sarif.

I could be wrong here, of course, but I cannot think of a CLI command that we would invoke for the first time in those steps that we'd want to cache.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mbg mbg Jul 15, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Therefore, I think it would make sense to invoke all of the cache-able CLI commands in init, either as-needed or pre-emptively. Once that's done, the cache would presumably be set for the life of the workflow run. There would be no need to write the cache to file in autobuild or analyze or upload-sarif.

I agree with your assessment that probably not all actions run CLI commands that are worth caching. If you don't have this already, it would be good to put together an overview of which CLI commands are used by which action. That can then guide us.

That said, I'd also like to avoid an unintuitive implementation where restoring/storing the on-disk cache is handled in a fairly ad-hoc manner that may not be transparent when making changes down the line.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/init-action.ts
Comment on lines +330 to +332
// Populate the in-memory command cache with CLI version.
// This result will be persisted to disk at the end of the init action.
await codeql.getVersion();

@mbg mbg Jul 14, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have any benefit over just waiting for the first, existing getVersion call?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mario-campos mario-campos Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now, no.

I was setting this up for a subsequent PR in which the cache is pre-loaded concurrently at the start of init, to avoid some of the "waiting" penalty of executing these commands.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/codeql.ts

@mbg mbg Jul 14, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should resolveLanguages use getCachedOrRun as well?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mario-campos mario-campos Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but that's for a follow-up PR, per @henrymercer's comment.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mbg mbg Jul 15, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this PR still includes other resolveLanguages-related changes (like moving the output type and adding the validator). Either leave them all for a follow-up PR as per Henry's suggestion, or do it all in this PR.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/cli/output-cache.ts
Comment on lines +61 to +71
export interface ResolveLanguagesOutput {
aliases?: {
[alias: string]: string;
};
extractors: {
[language: string]: Array<{
extractor_root: string;
extractor_options?: any;
}>;
};
}

@mbg mbg Jul 14, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as for VersionInfo.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread src/cli/output-cache.ts
Comment on lines +109 to +123
interface StoredCommandCacheEntry {
cmd: string;
output: unknown;
}

/** A single cached command output together with the CLI path it came from. */
export interface CommandCacheEntry<K extends CommandCacheKey> {
/**
* The path to the CodeQL CLI that produced `output`. Persisted so that a
* different step using a different CodeQL bundle doesn't pick up a stale
* value.
*/
cmd: string;
output: CommandCacheKeyOutputMap[K];
}

@mbg mbg Jul 14, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two types are identical except for the type of output. Could you simplify this down by making the type of output polymorphic in a type variable?

If the K extends CommandCacheKey constraint is hard to lift, then perhaps just the following might work:

Suggested change
interface StoredCommandCacheEntry {
cmd: string;
output: unknown;
}
/** A single cached command output together with the CLI path it came from. */
export interface CommandCacheEntry<K extends CommandCacheKey> {
/**
* The path to the CodeQL CLI that produced `output`. Persisted so that a
* different step using a different CodeQL bundle doesn't pick up a stale
* value.
*/
cmd: string;
output: CommandCacheKeyOutputMap[K];
}
/** A single cached command output together with the CLI path it came from. */
interface BaseCommandCacheEntry<O = unknown> {
/**
* The path to the CodeQL CLI that produced `output`. Persisted so that a
* different step using a different CodeQL bundle doesn't pick up a stale
* value.
*/
cmd: string;
output: O;
}
export type CommandCacheEntry<K extends CommandCacheKey> = BaseCommandCacheEntry<CommandCacheKeyOutputMap[K]>;

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@mario-campos

mario-campos commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

This PR is too big and vast. Per the recommendations, I've been broken it up into several smaller PRs:

  • Use json module for JSON validation in output-cache #4096
  • Persist CodeQL version output to file rather than environment #4081
  • Create wrapper runCliJson #3981
  • Support undefined, number in JSON module #3980
  • and a few more that have yet to be created...
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mario-campos mario-campos closed this Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@mbg mbg mbg requested changes
Copilot code review Copilot
Copilot review effort
Applies to this pull request for everyone.Learn more about Copilot code review.
Copilot left review comments
@henrymercer henrymercer Awaiting requested review from henrymercer
+1 more reviewer
@ellisonantoniafelicia-star ellisonantoniafelicia-star ellisonantoniafelicia-star approved these changes
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

size/XL May be very hard to review

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

5 participants

@mario-campos @mbg @henrymercer @ellisonantoniafelicia-star
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.