mirror of
https://github.com/github/codeql-action.git
synced 2026-11-05 20:49:49 +00:00
Merge branch 'main' into dependabot/npm_and_yarn/node-forge-1.4.1
This commit is contained in:
2
.github/workflows/__unsupported-macos.yml
generated
vendored
2
.github/workflows/__unsupported-macos.yml
generated
vendored
@@ -114,7 +114,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Download workflow artifact
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||
with:
|
||||
pattern: test-mode-sarif-*
|
||||
path: sarif
|
||||
|
||||
@@ -4,7 +4,14 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th
|
||||
|
||||
## [UNRELEASED]
|
||||
|
||||
No user facing changes.
|
||||
|
||||
## 4.39.2 - 03 Nov 2026
|
||||
|
||||
- Update default CodeQL bundle version to [2.27.4](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.4). [#4284](https://github.com/github/codeql-action/pull/4284)
|
||||
- _Upcoming breaking change_: CodeQL version 2.22.3 and earlier were discontinued on 16 October 2026 alongside GitHub Enterprise Server 3.18, and will be unsupported by the next minor release of the CodeQL Action. Added a deprecation warning for customers using these versions of CodeQL. [#4266](https://github.com/github/codeql-action/pull/4266)
|
||||
- Starting with macOS 27 and Xcode 27, traced analyses are unsupported. See [this blog post for more information](https://github.blog/changelog/2026-10-19-codeql-changes-for-macos-27-xcode-27-and-swift-6-4/). The CodeQL Action will now try to identify if a workflow is about to perform a traced analysis on version 27 or above of macOS or Xcode. If so, the CodeQL Action will emit a corresponding warning that will also be visible on the [Tool Status Page](https://docs.github.com/en/code-security/how-tos/find-and-fix-code-vulnerabilities/manage-your-configuration/use-the-tools-status-page-for-code-scanning). This check will be rolled out following this release of the CodeQL Action. [#4221](https://github.com/github/codeql-action/pull/4221)
|
||||
- The undocumented TRAP cache cleanup feature that could be enabled using the `CODEQL_ACTION_CLEANUP_TRAP_CACHES` environment variable has been removed, as announced in the release notes for CodeQL Action 4.35.2. The `analyze` Action now warns if this environment variable is set. If you used TRAP cache cleanup to limit Actions cache usage, we recommend disabling TRAP caching by passing the `trap-caching: false` input to the `init` Action. [#4243](https://github.com/github/codeql-action/pull/4243)
|
||||
|
||||
## 4.39.1 - 21 Oct 2026
|
||||
|
||||
|
||||
2
lib/entry-points.js
generated
2
lib/entry-points.js
generated
@@ -177993,7 +177993,7 @@ function getDiffRangesJsonFilePath(env = getEnv()) {
|
||||
return path2.join(getTemporaryDirectory(env), PR_DIFF_RANGE_JSON_FILENAME);
|
||||
}
|
||||
function getActionVersion() {
|
||||
return "4.39.2";
|
||||
return "4.39.3";
|
||||
}
|
||||
function getWorkflowEventName(env = getEnv()) {
|
||||
return env.getRequired("GITHUB_EVENT_NAME" /* GITHUB_EVENT_NAME */);
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "codeql",
|
||||
"version": "4.39.2",
|
||||
"version": "4.39.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "codeql",
|
||||
"version": "4.39.2",
|
||||
"version": "4.39.3",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"pr-checks"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "codeql",
|
||||
"version": "4.39.2",
|
||||
"version": "4.39.3",
|
||||
"private": true,
|
||||
"description": "CodeQL action",
|
||||
"scripts": {
|
||||
|
||||
@@ -48,7 +48,7 @@ validationJobs:
|
||||
installNode: true
|
||||
steps:
|
||||
- name: Download workflow artifact
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
||||
with:
|
||||
pattern: test-mode-sarif-*
|
||||
path: sarif
|
||||
|
||||
@@ -56,9 +56,18 @@ jobs:
|
||||
|
||||
const result = scanGeneratedWorkflows(workflowDir);
|
||||
|
||||
assert.equal(result["actions/checkout"], "v4");
|
||||
assert.equal(result["actions/setup-node"], "v5");
|
||||
assert.equal(result["actions/setup-go"], "v6");
|
||||
assert.deepEqual(
|
||||
result.actionVersions["actions/checkout"],
|
||||
new Set(["v4"]),
|
||||
);
|
||||
assert.deepEqual(
|
||||
result.actionVersions["actions/setup-node"],
|
||||
new Set(["v5"]),
|
||||
);
|
||||
assert.deepEqual(
|
||||
result.actionVersions["actions/setup-go"],
|
||||
new Set(["v6"]),
|
||||
);
|
||||
});
|
||||
|
||||
await it("scanning workflows with version comments", () => {
|
||||
@@ -78,12 +87,18 @@ jobs:
|
||||
|
||||
const result = scanGeneratedWorkflows(workflowDir);
|
||||
|
||||
assert.equal(result["actions/checkout"], "v4");
|
||||
assert.equal(
|
||||
result["ruby/setup-ruby"],
|
||||
"44511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0",
|
||||
assert.deepEqual(
|
||||
result.actionVersions["actions/checkout"],
|
||||
new Set(["v4"]),
|
||||
);
|
||||
assert.deepEqual(
|
||||
result.actionVersions["ruby/setup-ruby"],
|
||||
new Set(["44511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0"]),
|
||||
);
|
||||
assert.deepEqual(
|
||||
result.actionVersions["actions/setup-python"],
|
||||
new Set(["v6 # Latest Python"]),
|
||||
);
|
||||
assert.equal(result["actions/setup-python"], "v6 # Latest Python");
|
||||
});
|
||||
|
||||
await it("ignores local actions", () => {
|
||||
@@ -103,9 +118,15 @@ jobs:
|
||||
|
||||
const result = scanGeneratedWorkflows(workflowDir);
|
||||
|
||||
assert.equal(result["actions/checkout"], "v4");
|
||||
assert.equal("./.github/actions/local-action" in result, false);
|
||||
assert.equal("./another-local-action" in result, false);
|
||||
assert.deepEqual(
|
||||
result.actionVersions["actions/checkout"],
|
||||
new Set(["v4"]),
|
||||
);
|
||||
assert.equal(
|
||||
"./.github/actions/local-action" in result.actionVersions,
|
||||
false,
|
||||
);
|
||||
assert.equal("./another-local-action" in result.actionVersions, false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -128,8 +149,8 @@ const steps = [
|
||||
fs.writeFileSync(syncTsPath, syncTsContent);
|
||||
|
||||
const actionVersions = {
|
||||
"actions/setup-node": "v5",
|
||||
"actions/setup-go": "v6",
|
||||
"actions/setup-node": new Set(["v5"]),
|
||||
"actions/setup-go": new Set(["v6"]),
|
||||
};
|
||||
|
||||
const result = updateSyncTs(syncTsPath, actionVersions);
|
||||
@@ -155,7 +176,7 @@ const steps = [
|
||||
fs.writeFileSync(syncTsPath, syncTsContent);
|
||||
|
||||
const actionVersions = {
|
||||
"actions/setup-node": "v5 # Latest version",
|
||||
"actions/setup-node": new Set(["v5 # Latest version"]),
|
||||
};
|
||||
|
||||
const result = updateSyncTs(syncTsPath, actionVersions);
|
||||
@@ -182,7 +203,7 @@ const steps = [
|
||||
fs.writeFileSync(syncTsPath, syncTsContent);
|
||||
|
||||
const actionVersions = {
|
||||
"actions/setup-node": "v5",
|
||||
"actions/setup-node": new Set(["v5"]),
|
||||
};
|
||||
|
||||
const result = updateSyncTs(syncTsPath, actionVersions);
|
||||
@@ -206,7 +227,9 @@ const steps = [
|
||||
fs.writeFileSync(syncTsPath, syncTsContent);
|
||||
|
||||
const actionVersions = {
|
||||
"actions/setup-node": "48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0",
|
||||
"actions/setup-node": new Set([
|
||||
"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0",
|
||||
]),
|
||||
};
|
||||
|
||||
const result = updateSyncTs(syncTsPath, actionVersions);
|
||||
@@ -244,8 +267,9 @@ steps:
|
||||
"actions/checkout": "v4",
|
||||
"actions/setup-node": "v5 # Latest",
|
||||
};
|
||||
const byWorkflow = { ["test.yml"]: actionVersions };
|
||||
|
||||
const result = updateTemplateFiles(checksDir, actionVersions);
|
||||
const result = updateTemplateFiles(checksDir, byWorkflow);
|
||||
assert.equal(result.length, 1);
|
||||
assert.ok(result.includes(templatePath));
|
||||
|
||||
@@ -269,8 +293,9 @@ steps:
|
||||
const actionVersions = {
|
||||
"ruby/setup-ruby": "55511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0",
|
||||
};
|
||||
const byWorkflow = { ["test.yml"]: actionVersions };
|
||||
|
||||
const result = updateTemplateFiles(checksDir, actionVersions);
|
||||
const result = updateTemplateFiles(checksDir, byWorkflow);
|
||||
assert.equal(result.length, 1);
|
||||
|
||||
const updatedContent = fs.readFileSync(templatePath, "utf8");
|
||||
|
||||
@@ -27,16 +27,39 @@ const CHECKS_DIR = path.join(PR_CHECKS_DIR, "checks");
|
||||
const WORKFLOW_DIR = path.join(REPO_ROOT, ".github", "workflows");
|
||||
const SYNC_TS_PATH = path.join(PR_CHECKS_DIR, "sync.ts");
|
||||
|
||||
/** Type alias for action names. */
|
||||
type ActionName = string;
|
||||
|
||||
/** Type alias for action versions. May include a comment. */
|
||||
type ActionVersion = string;
|
||||
|
||||
/** Mappings of {@link ActionName}s to {@link ActionVersion}s. */
|
||||
type ActionVersions = Record<ActionName, ActionVersion>;
|
||||
|
||||
/** Mappings of workflow names to {@link ActionVersions}. */
|
||||
type ActionVersionsByWorkflow = Record<string, ActionVersions>;
|
||||
|
||||
/** The result of {@link scanGeneratedWorkflows}. */
|
||||
type ScanWorkflowResult = {
|
||||
/** A mapping of {@link ActionName}s to all encountered {@link ActionVersion}s. */
|
||||
actionVersions: Record<ActionName, Set<ActionVersion>>;
|
||||
|
||||
/** A mapping of workflow names to {@link ActionVersions}. */
|
||||
actionVersionsByWorkflow: ActionVersionsByWorkflow;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scan generated workflow files to extract the latest action versions.
|
||||
*
|
||||
* @param workflowDir - Path to .github/workflows directory
|
||||
* @returns Map from action names to their latest versions (including comments)
|
||||
*
|
||||
* @returns A {@link ScanWorkflowResult} object containing information about the extracted action versions.
|
||||
*/
|
||||
export function scanGeneratedWorkflows(
|
||||
workflowDir: string,
|
||||
): Record<string, string> {
|
||||
const actionVersions: Record<string, string> = {};
|
||||
): ScanWorkflowResult {
|
||||
const actionVersionsByWorkflow: ActionVersionsByWorkflow = {};
|
||||
const actionVersions: Record<ActionName, Set<ActionVersion>> = {};
|
||||
|
||||
const generatedFiles = fs
|
||||
.readdirSync(workflowDir)
|
||||
@@ -46,6 +69,10 @@ export function scanGeneratedWorkflows(
|
||||
for (const filePath of generatedFiles) {
|
||||
const content = fs.readFileSync(filePath, "utf8");
|
||||
|
||||
// Get the basename of the workflow and drop the leading `__` from it.
|
||||
const workflowName = path.basename(filePath).slice(2);
|
||||
actionVersionsByWorkflow[workflowName] = {};
|
||||
|
||||
// Find all action uses in the file, including potential comments
|
||||
// This pattern captures: action_name@version_with_possible_comment
|
||||
const pattern = /uses:\s+([^/\s]+\/[^@\s]+)@([^@\n]+)/g;
|
||||
@@ -57,13 +84,26 @@ export function scanGeneratedWorkflows(
|
||||
|
||||
// Only track non-local actions (those with / but not starting with ./)
|
||||
if (!actionName.startsWith("./")) {
|
||||
// Assume that version numbers are consistent (this should be the case on a Dependabot update PR)
|
||||
actionVersions[actionName] = versionWithComment;
|
||||
// Record the version of the action for this workflow.
|
||||
actionVersionsByWorkflow[workflowName][actionName] = versionWithComment;
|
||||
|
||||
// Record this version for the action so that we can write it to `sync.ts` if needed.
|
||||
// Usually we'd expect there to be exactly one version per action across all workflows,
|
||||
// but sometimes these can go out-of-sync if e.g. a workflow is added in a branch and a
|
||||
// Dependabot PR is merged in the meantime that changes the version of an action that is
|
||||
// used in the new workflow. Different versions of the same action across different
|
||||
// workflows is not fundamentally a problem, but we may need to pick one for `sync.ts`
|
||||
// so we warn there if we have multiple versions of an action.
|
||||
if (actionVersions[actionName] === undefined) {
|
||||
actionVersions[actionName] = new Set([versionWithComment]);
|
||||
} else if (!actionVersions[actionName].has(versionWithComment)) {
|
||||
actionVersions[actionName].add(versionWithComment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return actionVersions;
|
||||
return { actionVersions, actionVersionsByWorkflow };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,7 +119,7 @@ export function scanGeneratedWorkflows(
|
||||
*/
|
||||
export function updateSyncTs(
|
||||
syncTsPath: string,
|
||||
actionVersions: Record<string, string>,
|
||||
actionVersions: Record<ActionName, Set<ActionVersion>>,
|
||||
): boolean {
|
||||
if (!fs.existsSync(syncTsPath)) {
|
||||
throw new Error(`Could not find ${syncTsPath}`);
|
||||
@@ -89,9 +129,18 @@ export function updateSyncTs(
|
||||
const originalContent = content;
|
||||
|
||||
// Update hardcoded action versions
|
||||
for (const [actionName, versionWithComment] of Object.entries(
|
||||
for (const [actionName, versionsWithComments] of Object.entries(
|
||||
actionVersions,
|
||||
)) {
|
||||
// We usually expect `versionsWithComments` to contain one version. If there are multiple,
|
||||
// we arbitrarily pick one and warn about it.
|
||||
const versionsWithCommentsArray = Array.from(versionsWithComments);
|
||||
const versionWithComment = versionsWithCommentsArray[0];
|
||||
if (versionsWithComments.size > 1) {
|
||||
console.warn(
|
||||
`Inconsistent versions for ${actionName}. Arbitrarily picking '${versionWithComment}'. All found: ${versionsWithCommentsArray.join(", ")}`,
|
||||
);
|
||||
}
|
||||
// Split the scanned value into the ref (e.g. a commit SHA) and the optional
|
||||
// trailing version comment (e.g. `v6.0.3`).
|
||||
const ref = versionWithComment.includes("#")
|
||||
@@ -138,12 +187,12 @@ export function updateSyncTs(
|
||||
* Update action versions in template files in pr-checks/checks/
|
||||
*
|
||||
* @param checksDir - Path to pr-checks/checks directory
|
||||
* @param actionVersions - Map of action names to versions (may include comments)
|
||||
* @param actionVersionsByWorkflow - Map of workflows to maps of action names to versions (may include comments)
|
||||
* @returns List of files that were modified
|
||||
*/
|
||||
export function updateTemplateFiles(
|
||||
checksDir: string,
|
||||
actionVersions: Record<string, string>,
|
||||
actionVersionsByWorkflow: ActionVersionsByWorkflow,
|
||||
): string[] {
|
||||
const modifiedFiles: string[] = [];
|
||||
|
||||
@@ -156,6 +205,16 @@ export function updateTemplateFiles(
|
||||
let content = fs.readFileSync(filePath, "utf8");
|
||||
const originalContent = content;
|
||||
|
||||
const workflowName = path.basename(filePath);
|
||||
const actionVersions = actionVersionsByWorkflow[workflowName];
|
||||
|
||||
if (actionVersions === undefined) {
|
||||
console.info(
|
||||
`Found no action versions for workflow template '${filePath}'.`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Update action versions
|
||||
for (const [actionName, versionWithComment] of Object.entries(
|
||||
actionVersions,
|
||||
@@ -191,12 +250,15 @@ function main(): number {
|
||||
const verbose = values.verbose ?? false;
|
||||
|
||||
console.info("Scanning generated workflows for latest action versions...");
|
||||
const actionVersions = scanGeneratedWorkflows(WORKFLOW_DIR);
|
||||
const { actionVersions, actionVersionsByWorkflow } =
|
||||
scanGeneratedWorkflows(WORKFLOW_DIR);
|
||||
|
||||
if (verbose) {
|
||||
console.info("Found action versions:");
|
||||
for (const [action, version] of Object.entries(actionVersions)) {
|
||||
console.info(` ${action}@${version}`);
|
||||
for (const [action, versions] of Object.entries(actionVersions)) {
|
||||
for (const version of versions) {
|
||||
console.info(` ${action}@${version}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +277,10 @@ function main(): number {
|
||||
}
|
||||
|
||||
// Update template files
|
||||
const templateModified = updateTemplateFiles(CHECKS_DIR, actionVersions);
|
||||
const templateModified = updateTemplateFiles(
|
||||
CHECKS_DIR,
|
||||
actionVersionsByWorkflow,
|
||||
);
|
||||
modifiedFiles.push(...templateModified);
|
||||
|
||||
if (modifiedFiles.length > 0) {
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
- _Upcoming breaking change_: CodeQL version 2.22.3 and earlier were discontinued on 16 October 2026 alongside GitHub Enterprise Server 3.18, and will be unsupported by the next minor release of the CodeQL Action. Added a deprecation warning for customers using these versions of CodeQL. [#4266](https://github.com/github/codeql-action/pull/4266)
|
||||
@@ -1 +0,0 @@
|
||||
- Starting with macOS 27 and Xcode 27, traced analyses are unsupported. See [this blog post for more information](https://github.blog/changelog/2026-10-19-codeql-changes-for-macos-27-xcode-27-and-swift-6-4/). The CodeQL Action will now try to identify if a workflow is about to perform a traced analysis on version 27 or above of macOS or Xcode. If so, the CodeQL Action will emit a corresponding warning that will also be visible on the [Tool Status Page](https://docs.github.com/en/code-security/how-tos/find-and-fix-code-vulnerabilities/manage-your-configuration/use-the-tools-status-page-for-code-scanning). This check will be rolled out following this release of the CodeQL Action. [#4221](https://github.com/github/codeql-action/pull/4221)
|
||||
@@ -1 +0,0 @@
|
||||
- The undocumented TRAP cache cleanup feature that could be enabled using the `CODEQL_ACTION_CLEANUP_TRAP_CACHES` environment variable has been removed, as announced in the release notes for CodeQL Action 4.35.2. The `analyze` Action now warns if this environment variable is set. If you used TRAP cache cleanup to limit Actions cache usage, we recommend disabling TRAP caching by passing the `trap-caching: false` input to the `init` Action. [#4243](https://github.com/github/codeql-action/pull/4243)
|
||||
Reference in New Issue
Block a user