Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: github/codeql-action
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v3.26.3
Choose a base ref
...
head repository: github/codeql-action
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v3.26.4
Choose a head ref

Commits on Jul 30, 2024

  1. Verified

    This commit was signed with the committer’s verified signature.
    crazy-max CrazyMax
    Copy the full SHA
    dc92ab6 View commit details

Commits on Aug 2, 2024

  1. Clean-up logging

    marcogario committed Aug 2, 2024
    Copy the full SHA
    3b3012e View commit details

Commits on Aug 13, 2024

  1. Copy the full SHA
    e4afb79 View commit details
  2. Support URL

    marcogario committed Aug 13, 2024
    Copy the full SHA
    f736881 View commit details
  3. Copy the full SHA
    1bd7fdc View commit details

Commits on Aug 15, 2024

  1. Validate credentials input

    marcogario committed Aug 15, 2024
    Copy the full SHA
    5b34615 View commit details
  2. fixes

    marcogario committed Aug 15, 2024
    Copy the full SHA
    7baf392 View commit details
  3. Try upload teh proxy logs

    marcogario committed Aug 15, 2024
    Copy the full SHA
    0b84d89 View commit details

Commits on Aug 19, 2024

  1. Copy the full SHA
    02328f9 View commit details
  2. Copy the full SHA
    d615d5c View commit details
  3. Merge pull request #2432 from github/mergeback/v3.26.3-to-main-883d8588

    Mergeback v3.26.3 refs/heads/releases/v3 into main
    henrymercer authored Aug 19, 2024
    Copy the full SHA
    339aada View commit details

Commits on Aug 20, 2024

  1. Merge pull request #2404 from github/marcogario/proxy_64

    Registries Proxy: Support feeding a base64 encoded configuration
    aibaars authored Aug 20, 2024
    Copy the full SHA
    512e306 View commit details
  2. Stop checking disk usage for MacOS ARM with SIP disabled (#2434)

    * Stop checking disk usage for MacOS ARM with SIP disabled
    
    On MacOS ARM machines where SIP is disabled, after the build tracer is initialized in the `init` Action, we receive warnings when we run send status reports due to the `df` binary. This change will make it so that we no longer run `df` for those machines.
    angelapwen authored Aug 20, 2024
    Copy the full SHA
    202b3b9 View commit details

Commits on Aug 21, 2024

  1. Copy the full SHA
    4067cda View commit details
  2. Copy the full SHA
    ec21b8f View commit details
  3. Add link to PR deprecating add-snippets to CHANGELOG.md

    Co-authored-by: Andrew Eisenberg <aeisenberg@github.com>
    rvermeulen and aeisenberg authored Aug 21, 2024
    Copy the full SHA
    d7c48ef View commit details
  4. Copy the full SHA
    7388c47 View commit details
  5. Copy the full SHA
    72bc3f7 View commit details
  6. Merge pull request #2436 from rvermeulen/rvermeulen/deprecate-add-sni…

    …ppets
    
    Deprecate `add-snippets` input.
    rvermeulen authored Aug 21, 2024
    Copy the full SHA
    ae01f80 View commit details
  7. Copy the full SHA
    e354359 View commit details
  8. Merge main into releases/v3 (#2437)

    * Consider registries_credentials as input
    
    * Clean-up logging
    
    * More debugging of credentials
    
    * Support URL
    
    * Validate credentials input
    
    * fixes
    
    * Try upload teh proxy logs
    
    * Update changelog and version after v3.26.3
    
    * Update checked-in dependencies
    
    * Stop checking disk usage for MacOS ARM with SIP disabled (#2434)
    
    * Stop checking disk usage for MacOS ARM with SIP disabled
    
    On MacOS ARM machines where SIP is disabled, after the build tracer is initialized in the `init` Action, we receive warnings when we run send status reports due to the `df` binary. This change will make it so that we no longer run `df` for those machines.
    
    * Add deprecation message to `add-snippets` input.
    
    * Update changelog with deprecation.
    
    * Add link to PR deprecating `add-snippets` to CHANGELOG.md
    
    Co-authored-by: Andrew Eisenberg <aeisenberg@github.com>
    
    * Address incorrect changelog location
    
    * Update changelog for v3.26.4
    
    ---------
    
    Co-authored-by: Marco Gario <marcogario@github.com>
    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    Co-authored-by: Henry Mercer <henry@henrymercer.name>
    Co-authored-by: Arthur Baars <aibaars@github.com>
    Co-authored-by: Angela P Wen <angelapwen@github.com>
    Co-authored-by: Remco Vermeulen <rvermeulen@github.com>
    Co-authored-by: Remco Vermeulen <rvermeulen@users.noreply.github.com>
    Co-authored-by: Andrew Eisenberg <aeisenberg@github.com>
    8 people authored Aug 21, 2024
    Copy the full SHA
    f0f3afe View commit details
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -4,6 +4,11 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th

Note that the only difference between `v2` and `v3` of the CodeQL Action is the node version they support, with `v3` running on node 20 while we continue to release `v2` to support running on node 16. For example `3.22.11` was the first `v3` release and is functionally identical to `2.22.11`. This approach ensures an easy way to track exactly which features are included in different versions, indicated by the minor and patch version numbers.

## 3.26.4 - 21 Aug 2024

- _Deprecation:_ The `add-snippets` input on the `analyze` Action is deprecated and will be removed in the first release in August 2025. [#2436](https://github.com/github/codeql-action/pull/2436)
- Fix an issue where the disk usage system call used for telemetry would fail on MacOS ARM machines with System Integrity Protection disabled, and then surface a warning. The system call is now disabled for these machines. [#2434](https://github.com/github/codeql-action/pull/2434)

## 3.26.3 - 19 Aug 2024

- Fix an issue where the CodeQL Action could not write diagnostic messages on Windows. This issue did not impact analysis quality. [#2430](https://github.com/github/codeql-action/pull/2430)
5 changes: 5 additions & 0 deletions analyze/action.yml
Original file line number Diff line number Diff line change
@@ -34,6 +34,11 @@ inputs:
description: Specify whether or not to add code snippets to the output sarif file.
required: false
default: "false"
deprecationMessage: >-
The input "add-snippets" is deprecated and will be removed on the first release in August 2025.
When this input is set to true it is expected to add code snippets with an alert to the SARIF file.
However, since Code Scanning ignores code snippets provided as part of a SARIF file this is currently
a no operation. No alternative is available.
skip-queries:
description: If this option is set, the CodeQL database will be built but no queries will be run on it. Thus, no results will be produced.
required: false
2 changes: 1 addition & 1 deletion lib/analyze-action.js

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

2 changes: 1 addition & 1 deletion lib/analyze-action.js.map

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

4 changes: 2 additions & 2 deletions lib/init-action-post.js
2 changes: 1 addition & 1 deletion lib/init-action-post.js.map
4 changes: 2 additions & 2 deletions lib/init-action.js
2 changes: 1 addition & 1 deletion lib/init-action.js.map

Large diffs are not rendered by default.

22 changes: 0 additions & 22 deletions lib/init.js
2 changes: 1 addition & 1 deletion lib/init.js.map
6 changes: 3 additions & 3 deletions lib/resolve-environment-action.js
2 changes: 1 addition & 1 deletion lib/resolve-environment-action.js.map
17 changes: 13 additions & 4 deletions lib/start-proxy-action-post.js
2 changes: 1 addition & 1 deletion lib/start-proxy-action-post.js.map
106 changes: 82 additions & 24 deletions lib/start-proxy-action.js
2 changes: 1 addition & 1 deletion lib/start-proxy-action.js.map
6 changes: 3 additions & 3 deletions lib/upload-sarif-action.js
2 changes: 1 addition & 1 deletion lib/upload-sarif-action.js.map
34 changes: 30 additions & 4 deletions lib/util.js
2 changes: 1 addition & 1 deletion lib/util.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion node_modules/.package-lock.json
4 changes: 2 additions & 2 deletions package-lock.json
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codeql",
"version": "3.26.3",
"version": "3.26.4",
"private": true,
"description": "CodeQL action",
"scripts": {
2 changes: 1 addition & 1 deletion src/analyze-action.ts
Original file line number Diff line number Diff line change
@@ -75,7 +75,7 @@ async function sendStatusReport(
status,
startedAt,
config,
await util.checkDiskUsage(),
await util.checkDiskUsage(logger),
logger,
error?.message,
error?.stack,
4 changes: 2 additions & 2 deletions src/init-action-post.ts
Original file line number Diff line number Diff line change
@@ -81,7 +81,7 @@ async function runWrapper() {
getActionsStatus(error),
startedAt,
config,
await checkDiskUsage(),
await checkDiskUsage(logger),
logger,
error.message,
error.stack,
@@ -99,7 +99,7 @@ async function runWrapper() {
"success",
startedAt,
config,
await checkDiskUsage(),
await checkDiskUsage(logger),
logger,
);
if (statusReportBase !== undefined) {
4 changes: 2 additions & 2 deletions src/init-action.ts
Original file line number Diff line number Diff line change
@@ -29,7 +29,6 @@ import {
cleanupDatabaseClusterDirectory,
initCodeQL,
initConfig,
isSipEnabled,
runInit,
} from "./init";
import { Language } from "./languages";
@@ -57,6 +56,7 @@ import {
getThreadsFlagValue,
initializeEnvironment,
isHostedRunner,
isSipEnabled,
ConfigurationError,
wrapError,
checkActionVersion,
@@ -355,7 +355,7 @@ async function run() {
error instanceof ConfigurationError ? "user-error" : "aborted",
startedAt,
config,
await checkDiskUsage(),
await checkDiskUsage(logger),
logger,
error.message,
error.stack,
33 changes: 0 additions & 33 deletions src/init.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as fs from "fs";
import * as path from "path";

import * as exec from "@actions/exec/lib/exec";
import * as toolrunner from "@actions/exec/lib/toolrunner";
import * as safeWhich from "@chrisgavin/safe-which";

@@ -141,38 +140,6 @@ export async function checkInstallPython311(
}
}

// For MacOS runners: runs `csrutil status` to determine whether System
// Integrity Protection is enabled.
export async function isSipEnabled(
logger: Logger,
): Promise<boolean | undefined> {
try {
const sipStatusOutput = await exec.getExecOutput("csrutil status");
if (sipStatusOutput.exitCode === 0) {
if (
sipStatusOutput.stdout.includes(
"System Integrity Protection status: enabled.",
)
) {
return true;
}
if (
sipStatusOutput.stdout.includes(
"System Integrity Protection status: disabled.",
)
) {
return false;
}
}
return undefined;
} catch (e) {
logger.warning(
`Failed to determine if System Integrity Protection was enabled: ${e}`,
);
return undefined;
}
}

export function cleanupDatabaseClusterDirectory(
config: configUtils.Config,
logger: Logger,
6 changes: 3 additions & 3 deletions src/resolve-environment-action.ts
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ async function run() {
"starting",
startedAt,
config,
await checkDiskUsage(),
await checkDiskUsage(logger),
logger,
);
if (statusReportBase !== undefined) {
@@ -86,7 +86,7 @@ async function run() {
getActionsStatus(error),
startedAt,
config,
await checkDiskUsage(),
await checkDiskUsage(logger),
logger,
error.message,
error.stack,
@@ -104,7 +104,7 @@ async function run() {
"success",
startedAt,
config,
await checkDiskUsage(),
await checkDiskUsage(logger),
logger,
);
if (statusReportBase !== undefined) {
24 changes: 19 additions & 5 deletions src/start-proxy-action-post.ts
Original file line number Diff line number Diff line change
@@ -3,8 +3,7 @@
* It will run after the all steps in this job, in reverse order in relation to
* other `post:` hooks.
*/
import * as fs from "fs";

import * as artifact from "@actions/artifact";
import * as core from "@actions/core";

import * as actionsUtil from "./actions-util";
@@ -29,9 +28,24 @@ async function runWrapper() {

if ((config && config.debugMode) || core.isDebug()) {
const logFilePath = core.getState("proxy-log-file");
if (logFilePath) {
const readStream = fs.createReadStream(logFilePath);
readStream.pipe(process.stdout, { end: true });
core.info(
"Debug mode is on. Uploading proxy log as Actions debugging artifact...",
);
try {
await artifact
.create()
.uploadArtifact(
"proxy-log-file",
[logFilePath],
actionsUtil.getTemporaryDirectory(),
{
continueOnError: true,
retentionDays: 7,
},
);
} catch (e) {
// A failure to upload debug artifacts should not fail the entire action.
core.warning(`Failed to upload debug artifacts: ${e}`);
}
}
}
145 changes: 112 additions & 33 deletions src/start-proxy-action.ts
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ import * as toolcache from "@actions/tool-cache";
import { pki } from "node-forge";

import * as actionsUtil from "./actions-util";
import { getActionsLogger, Logger } from "./logging";
import * as util from "./util";

const UPDATEJOB_PROXY = "update-job-proxy";
@@ -16,25 +17,26 @@ const PROXY_USER = "proxy_user";
const KEY_SIZE = 2048;
const KEY_EXPIRY_YEARS = 2;

export type CertificateAuthority = {
type CertificateAuthority = {
cert: string;
key: string;
};

export type Credential = {
type Credential = {
type: string;
host: string;
host?: string;
url?: string;
username?: string;
password?: string;
token?: string;
};

export type BasicAuthCredentials = {
type BasicAuthCredentials = {
username: string;
password: string;
};

export type ProxyConfig = {
type ProxyConfig = {
all_credentials: Credential[];
ca: CertificateAuthority;
proxy_auth?: BasicAuthCredentials;
@@ -89,46 +91,50 @@ function generateCertificateAuthority(): CertificateAuthority {
}

async function runWrapper() {
const logger = getActionsLogger();

// Setup logging for the proxy
const tempDir = actionsUtil.getTemporaryDirectory();
const logFilePath = path.resolve(tempDir, "proxy.log");
const input = actionsUtil.getOptionalInput("registry_secrets") || "[]";
const credentials = JSON.parse(input) as Credential[];
const proxyLogFilePath = path.resolve(tempDir, "proxy.log");
core.saveState("proxy-log-file", proxyLogFilePath);

// Get the configuration options
const credentials = getCredentials(logger);
logger.info(
`Credentials loaded for the following registries:\n ${credentials
.map((c) => credentialToStr(c))
.join("\n")}`,
);

const ca = generateCertificateAuthority();
const proxy_password = actionsUtil.getOptionalInput("proxy_password");
core.saveState("proxy-log-file", logFilePath);
const proxyAuth = getProxyAuth();

let proxy_auth: BasicAuthCredentials | undefined = undefined;
if (proxy_password) {
proxy_auth = {
username: PROXY_USER,
password: proxy_password,
};
}
const proxyConfig: ProxyConfig = {
all_credentials: credentials,
ca,
proxy_auth,
proxy_auth: proxyAuth,
};

// Start the Proxy
const proxyBin = await getProxyBinaryPath();
await startProxy(proxyBin, proxyConfig, proxyLogFilePath, logger);
}

async function startProxy(
binPath: string,
config: ProxyConfig,
logFilePath: string,
logger: Logger,
) {
const host = "127.0.0.1";
let proxyBin = toolcache.find(UPDATEJOB_PROXY, UPDATEJOB_PROXY_VERSION);
if (!proxyBin) {
const temp = await toolcache.downloadTool(UPDATEJOB_PROXY_URL);
const extracted = await toolcache.extractTar(temp);
proxyBin = await toolcache.cacheDir(
extracted,
UPDATEJOB_PROXY,
UPDATEJOB_PROXY_VERSION,
);
}
proxyBin = path.join(proxyBin, UPDATEJOB_PROXY);
let port = 49152;
try {
let subprocess: ChildProcess | undefined = undefined;
let tries = 5;
let subprocessError: Error | undefined = undefined;
while (tries-- > 0 && !subprocess && !subprocessError) {
subprocess = spawn(
proxyBin,
binPath,
["-addr", `${host}:${port}`, "-config", "-", "-logfile", logFilePath],
{
detached: true,
@@ -149,7 +155,7 @@ async function runWrapper() {
subprocess = undefined;
}
});
subprocess.stdin?.write(JSON.stringify(proxyConfig));
subprocess.stdin?.write(JSON.stringify(config));
subprocess.stdin?.end();
// Wait a little to allow the proxy to start
await util.delay(1000);
@@ -158,15 +164,88 @@ async function runWrapper() {
// eslint-disable-next-line @typescript-eslint/only-throw-error
throw subprocessError;
}
core.info(`Proxy started on ${host}:${port}`);
logger.info(`Proxy started on ${host}:${port}`);
core.setOutput("proxy_host", host);
core.setOutput("proxy_port", port.toString());
core.setOutput("proxy_ca_certificate", ca.cert);
core.setOutput("proxy_ca_certificate", config.ca.cert);
} catch (error) {
core.setFailed(
`start-proxy action failed: ${util.wrapError(error).message}`,
);
}
}

// getCredentials returns registry credentials from action inputs.
// It prefers `registries_credentials` over `registry_secrets`.
// If neither is set, it returns an empty array.
function getCredentials(logger: Logger): Credential[] {
const registriesCredentials = actionsUtil.getOptionalInput(
"registries_credentials",
);
const registrySecrets = actionsUtil.getOptionalInput("registry_secrets");

let credentialsStr: string;
if (registriesCredentials !== undefined) {
logger.info(`Using registries_credentials input.`);
credentialsStr = Buffer.from(registriesCredentials, "base64").toString();
} else if (registrySecrets !== undefined) {
logger.info(`Using registry_secrets input.`);
credentialsStr = registrySecrets;
} else {
logger.info(`No credentials defined.`);
return [];
}

// Parse and validate the credentials
const parsed = JSON.parse(credentialsStr) as Credential[];
const out: Credential[] = [];
for (const e of parsed) {
if (e.url === undefined && e.host === undefined) {
throw new Error("Invalid credentials - must specify host or url");
}
out.push({
type: e.type,
host: e.host,
url: e.url,
username: e.username,
password: e.password,
token: e.token,
});
}
return out;
}

// getProxyAuth returns the authentication information for the proxy itself.
function getProxyAuth(): BasicAuthCredentials | undefined {
const proxy_password = actionsUtil.getOptionalInput("proxy_password");
if (proxy_password) {
return {
username: PROXY_USER,
password: proxy_password,
};
}
return;
}

async function getProxyBinaryPath(): Promise<string> {
let proxyBin = toolcache.find(UPDATEJOB_PROXY, UPDATEJOB_PROXY_VERSION);
if (!proxyBin) {
const temp = await toolcache.downloadTool(UPDATEJOB_PROXY_URL);
const extracted = await toolcache.extractTar(temp);
proxyBin = await toolcache.cacheDir(
extracted,
UPDATEJOB_PROXY,
UPDATEJOB_PROXY_VERSION,
);
}
proxyBin = path.join(proxyBin, UPDATEJOB_PROXY);
return proxyBin;
}

function credentialToStr(c: Credential): string {
return `Type: ${c.type}; Host: ${c.host}; Url: ${c.url} Username: ${
c.username
}; Password: ${c.password !== undefined}; Token: ${c.token !== undefined}`;
}

void runWrapper();
6 changes: 3 additions & 3 deletions src/upload-sarif-action.ts
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ async function sendSuccessStatusReport(
"success",
startedAt,
undefined,
await checkDiskUsage(),
await checkDiskUsage(logger),
logger,
);
if (statusReportBase !== undefined) {
@@ -74,7 +74,7 @@ async function run() {
"starting",
startedAt,
undefined,
await checkDiskUsage(),
await checkDiskUsage(logger),
logger,
);
if (startingStatusReportBase !== undefined) {
@@ -116,7 +116,7 @@ async function run() {
getActionsStatus(error),
startedAt,
undefined,
await checkDiskUsage(),
await checkDiskUsage(logger),
logger,
message,
error.stack,
54 changes: 47 additions & 7 deletions src/util.ts
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ import * as path from "path";
import { promisify } from "util";

import * as core from "@actions/core";
import * as exec from "@actions/exec/lib/exec";
import checkDiskSpace from "check-disk-space";
import del from "del";
import getFolderSize from "get-folder-size";
@@ -1013,14 +1014,23 @@ export interface DiskUsage {
}

export async function checkDiskUsage(
logger?: Logger,
logger: Logger,
): Promise<DiskUsage | undefined> {
try {
// We avoid running the `df` binary under the hood for macOS ARM runners with SIP disabled.
if (
process.platform === "darwin" &&
(process.arch === "arm" || process.arch === "arm64") &&
!(await isSipEnabled(logger))
) {
return undefined;
}

const diskUsage = await checkDiskSpace(
getRequiredEnvParam("GITHUB_WORKSPACE"),
);
const gbInBytes = 1024 * 1024 * 1024;
if (logger && diskUsage.free < 2 * gbInBytes) {
if (diskUsage.free < 2 * gbInBytes) {
const message =
"The Actions runner is running low on disk space " +
`(${(diskUsage.free / gbInBytes).toPrecision(4)} GB available).`;
@@ -1036,11 +1046,9 @@ export async function checkDiskUsage(
numTotalBytes: diskUsage.size,
};
} catch (error) {
if (logger) {
logger.warning(
`Failed to check available disk space: ${getErrorMessage(error)}`,
);
}
logger.warning(
`Failed to check available disk space: ${getErrorMessage(error)}`,
);
return undefined;
}
}
@@ -1104,3 +1112,35 @@ export enum BuildMode {
export function cloneObject<T>(obj: T): T {
return JSON.parse(JSON.stringify(obj)) as T;
}

// For MacOS runners: runs `csrutil status` to determine whether System
// Integrity Protection is enabled.
export async function isSipEnabled(
logger: Logger,
): Promise<boolean | undefined> {
try {
const sipStatusOutput = await exec.getExecOutput("csrutil status");
if (sipStatusOutput.exitCode === 0) {
if (
sipStatusOutput.stdout.includes(
"System Integrity Protection status: enabled.",
)
) {
return true;
}
if (
sipStatusOutput.stdout.includes(
"System Integrity Protection status: disabled.",
)
) {
return false;
}
}
return undefined;
} catch (e) {
logger.warning(
`Failed to determine if System Integrity Protection was enabled: ${e}`,
);
return undefined;
}
}
5 changes: 4 additions & 1 deletion start-proxy/action.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
name: "CodeQL: Start proxy"
description: "[Experimental] Start HTTP proxy server"
description: "[Experimental] Start HTTP proxy server. This action is for internal GitHub used only and will change without notice."
author: "GitHub"
inputs:
registry_secrets:
description: The URLs and credentials of package registries
required: false
default: "[]"
registries_credentials:
description: Base64 encoded JSON configuration for the URLs and credentials of the package registries
required: false
proxy_password:
required: false
description: The password of the proxy