Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th
## [UNRELEASED]

- We have improved the CodeQL Action's ability to validate that the workflow it is used in does not use different versions of the CodeQL Action for different workflow steps. Mixing different versions of the CodeQL Action in the same workflow is unsupported and can lead to unpredictable results. A warning will now be emitted from the `codeql-action/init` step if different versions of the CodeQL Action are detected in the workflow file. Additionally, an error will now be thrown by the other CodeQL Action steps if they load a configuration file that was generated by a different version of the `codeql-action/init` step. [#3099](https://github.com/github/codeql-action/pull/3099) and [#3100](https://github.com/github/codeql-action/pull/3100)
- We added support for reducing the size of dependency caches for Java analyses, which will reduce cache usage and speed up workflows. This will be enabled automatically at a later time. [#3107](https://github.com/github/codeql-action/pull/3107)

## 3.30.3 - 10 Sep 2025

Expand Down
5 changes: 5 additions & 0 deletions lib/analyze-action-post.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 18 additions & 6 deletions lib/analyze-action.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions lib/autobuild-action.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions lib/init-action-post.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 35 additions & 7 deletions lib/init-action.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions lib/resolve-environment-action.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions lib/start-proxy-action-post.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions lib/upload-lib.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions lib/upload-sarif-action-post.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions lib/upload-sarif-action.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions src/analyze-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { uploadDatabases } from "./database-upload";
import { uploadDependencyCaches } from "./dependency-caching";
import { getDiffInformedAnalysisBranches } from "./diff-informed-analysis-utils";
import { EnvVar } from "./environment";
import { Features } from "./feature-flags";
import { Feature, Features } from "./feature-flags";
import { KnownLanguage } from "./languages";
import { getActionsLogger, Logger } from "./logging";
import { uploadOverlayBaseDatabaseToCache } from "./overlay-database-utils";
Expand Down Expand Up @@ -384,7 +384,11 @@ async function run() {

// Store dependency cache(s) if dependency caching is enabled.
if (shouldStoreCache(config.dependencyCachingEnabled)) {
await uploadDependencyCaches(config, logger);
const minimizeJavaJars = await features.getValue(
Feature.JavaMinimizeDependencyJars,
codeql,
);
await uploadDependencyCaches(config, logger, minimizeJavaJars);
}

// We don't upload results in test mode, so don't wait for processing
Expand Down
34 changes: 27 additions & 7 deletions src/dependency-caching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { getTemporaryDirectory } from "./actions-util";
import { getTotalCacheSize } from "./caching-utils";
import { Config } from "./config-utils";
import { EnvVar } from "./environment";
import { Language } from "./languages";
import { KnownLanguage, Language } from "./languages";
import { Logger } from "./logging";
import { getRequiredEnvParam } from "./util";

Expand Down Expand Up @@ -89,11 +89,13 @@ async function makeGlobber(patterns: string[]): Promise<glob.Globber> {
*
* @param languages The languages being analyzed.
* @param logger A logger to record some informational messages to.
* @param minimizeJavaJars Whether the Java extractor should rewrite downloaded JARs to minimize their size.
* @returns A list of languages for which dependency caches were restored.
*/
export async function downloadDependencyCaches(
languages: Language[],
logger: Logger,
minimizeJavaJars: boolean,
): Promise<Language[]> {
const restoredCaches: Language[] = [];

Expand All @@ -118,8 +120,10 @@ export async function downloadDependencyCaches(
continue;
}

const primaryKey = await cacheKey(language, cacheConfig);
const restoreKeys: string[] = [await cachePrefix(language)];
const primaryKey = await cacheKey(language, cacheConfig, minimizeJavaJars);
const restoreKeys: string[] = [
await cachePrefix(language, minimizeJavaJars),
];

logger.info(
`Downloading cache for ${language} with key ${primaryKey} and restore keys ${restoreKeys.join(
Expand Down Expand Up @@ -149,8 +153,13 @@ export async function downloadDependencyCaches(
*
* @param config The configuration for this workflow.
* @param logger A logger to record some informational messages to.
* @param minimizeJavaJars Whether the Java extractor should rewrite downloaded JARs to minimize their size.
*/
export async function uploadDependencyCaches(config: Config, logger: Logger) {
export async function uploadDependencyCaches(
config: Config,
logger: Logger,
minimizeJavaJars: boolean,
): Promise<void> {
for (const language of config.languages) {
const cacheConfig = getDefaultCacheConfig()[language];

Expand Down Expand Up @@ -192,7 +201,7 @@ export async function uploadDependencyCaches(config: Config, logger: Logger) {
continue;
}

const key = await cacheKey(language, cacheConfig);
const key = await cacheKey(language, cacheConfig, minimizeJavaJars);

logger.info(
`Uploading cache of size ${size} for ${language} with key ${key}...`,
Expand Down Expand Up @@ -222,24 +231,30 @@ export async function uploadDependencyCaches(config: Config, logger: Logger) {
*
* @param language The language being analyzed.
* @param cacheConfig The cache configuration for the language.
* @param minimizeJavaJars Whether the Java extractor should rewrite downloaded JARs to minimize their size.
* @returns A cache key capturing information about the project(s) being analyzed in the specified language.
*/
async function cacheKey(
language: Language,
cacheConfig: CacheConfig,
minimizeJavaJars: boolean = false,
): Promise<string> {
const hash = await glob.hashFiles(cacheConfig.hash.join("\n"));
return `${await cachePrefix(language)}${hash}`;
return `${await cachePrefix(language, minimizeJavaJars)}${hash}`;
}

/**
* Constructs a prefix for the cache key, comprised of a CodeQL-specific prefix, a version number that
* can be changed to invalidate old caches, the runner's operating system, and the specified language name.
*
* @param language The language being analyzed.
* @param minimizeJavaJars Whether the Java extractor should rewrite downloaded JARs to minimize their size.
* @returns The prefix that identifies what a cache is for.
*/
async function cachePrefix(language: Language): Promise<string> {
async function cachePrefix(
language: Language,
minimizeJavaJars: boolean,
): Promise<string> {
const runnerOs = getRequiredEnvParam("RUNNER_OS");
const customPrefix = process.env[EnvVar.DEPENDENCY_CACHING_PREFIX];
let prefix = CODEQL_DEPENDENCY_CACHE_PREFIX;
Expand All @@ -248,5 +263,10 @@ async function cachePrefix(language: Language): Promise<string> {
prefix = `${prefix}-${customPrefix}`;
}

// To ensure a safe rollout of JAR minimization, we change the key when the feature is enabled.
if (language === KnownLanguage.java && minimizeJavaJars) {
prefix = `minify-${prefix}`;
}

return `${prefix}-${CODEQL_DEPENDENCY_CACHE_VERSION}-${runnerOs}-${language}-`;
}
3 changes: 3 additions & 0 deletions src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ export enum EnvVar {
*/
DEPENDENCY_CACHING_PREFIX = "CODEQL_ACTION_DEPENDENCY_CACHE_PREFIX",

/** Used by the Java extractor option to enable minimizing dependency JARs. */
JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS = "CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS",

/**
* Whether to enable experimental extractors for CodeQL.
*/
Expand Down
Loading
Loading