Capture reason if zstd fails unexpectedly
This commit is contained in:
parent
4d015b8cba
commit
0abc1ec90b
5 changed files with 226 additions and 3 deletions
125
.github/workflows/__zstd-bundle-fallback.yml
generated
vendored
Normal file
125
.github/workflows/__zstd-bundle-fallback.yml
generated
vendored
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
# Warning: This file is generated automatically, and should not be modified.
|
||||
# Instead, please modify the template in the pr-checks directory and run:
|
||||
# (cd pr-checks; pip install ruamel.yaml@0.17.31 && python3 sync.py)
|
||||
# to regenerate this file.
|
||||
|
||||
name: PR Check - Zstandard bundle fallback
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GO111MODULE: auto
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- releases/v*
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- ready_for_review
|
||||
schedule:
|
||||
- cron: '0 5 * * *'
|
||||
workflow_dispatch: {}
|
||||
jobs:
|
||||
zstd-bundle-fallback:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
version: linked
|
||||
name: Zstandard bundle fallback
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
timeout-minutes: 45
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Setup Python on MacOS
|
||||
uses: actions/setup-python@v5
|
||||
if: >-
|
||||
runner.os == 'macOS' && (
|
||||
|
||||
matrix.version == 'stable-v2.13.5' ||
|
||||
|
||||
matrix.version == 'stable-v2.14.6')
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Prepare test
|
||||
id: prepare-test
|
||||
uses: ./.github/actions/prepare-test
|
||||
with:
|
||||
version: ${{ matrix.version }}
|
||||
use-all-platform-bundle: 'false'
|
||||
setup-kotlin: 'true'
|
||||
- name: Remove CodeQL from toolcache
|
||||
run: |
|
||||
rm -rf $RUNNER_TOOL_CACHE/CodeQL
|
||||
- id: init
|
||||
uses: ./../action/init
|
||||
with:
|
||||
# Swift is not supported on Ubuntu so we manually exclude it from the list here
|
||||
languages: cpp,csharp,go,java,javascript,python,ruby
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: ./build.sh
|
||||
- uses: ./../action/analyze
|
||||
with:
|
||||
output: ${{ runner.temp }}/results
|
||||
upload-database: false
|
||||
- name: Upload SARIF
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: zstd-bundle.sarif
|
||||
path: ${{ runner.temp }}/results/cpp.sarif
|
||||
retention-days: 7
|
||||
- name: Check expected diagnostics
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
SARIF_PATH: ${{ runner.temp }}/results/cpp.sarif
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
|
||||
const sarif = JSON.parse(fs.readFileSync(process.env['SARIF_PATH'], 'utf8'));
|
||||
const run = sarif.runs[0];
|
||||
|
||||
const toolExecutionNotifications = run.invocations[0].toolExecutionNotifications;
|
||||
const downloadTelemetryNotifications = toolExecutionNotifications.filter(n =>
|
||||
n.descriptor.id === 'codeql-action/bundle-download-telemetry'
|
||||
);
|
||||
if (downloadTelemetryNotifications.length !== 1) {
|
||||
core.setFailed(
|
||||
'Expected exactly one reporting descriptor in the ' +
|
||||
`'runs[].invocations[].toolExecutionNotifications[]' SARIF property, but found ` +
|
||||
`${downloadTelemetryNotifications.length}. All notification reporting descriptors: ` +
|
||||
`${JSON.stringify(toolExecutionNotifications)}.`
|
||||
);
|
||||
}
|
||||
|
||||
const toolsUrl = downloadTelemetryNotifications[0].properties.attributes.toolsUrl;
|
||||
console.log(`Found tools URL: ${toolsUrl}`);
|
||||
|
||||
if (!toolsUrl.endsWith('.tar.gz')) {
|
||||
core.setFailed(
|
||||
`Expected the tools URL to be a .tar.gz file, but found '${toolsUrl}'.`
|
||||
);
|
||||
}
|
||||
|
||||
const zstdFailureReason = downloadTelemetryNotifications[0].properties.attributes.zstdFailureReason;
|
||||
console.log(`Found zstd failure reason: ${zstdFailureReason}`);
|
||||
|
||||
const expectedZstdFailureReason = 'Failing since CODEQL_ACTION_FORCE_ZSTD_FAILURE is true.';
|
||||
if (zstdFailureReason !== expectedZstdFailureReason) {
|
||||
core.setFailed(
|
||||
`Expected the zstd failure reason to be '${expectedZstdFailureReason}', but found '${zstdFailureReason}'.`
|
||||
);
|
||||
}
|
||||
env:
|
||||
CODEQL_ACTION_ZSTD_BUNDLE: true
|
||||
CODEQL_ACTION_FORCE_ZSTD_FAILURE: true
|
||||
CODEQL_ACTION_TEST_MODE: true
|
||||
12
lib/setup-codeql.js
generated
12
lib/setup-codeql.js
generated
|
|
@ -479,17 +479,27 @@ function getCanonicalToolcacheVersion(cliVersion, bundleVersion, logger) {
|
|||
*/
|
||||
async function setupCodeQLBundle(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger) {
|
||||
const zstdAvailability = await tar.isZstdAvailable(logger);
|
||||
let zstdFailureReason;
|
||||
// If we think the installed version of tar supports zstd, try to use zstd,
|
||||
// but be prepared to fall back to gzip in case we were wrong.
|
||||
if (zstdAvailability.available) {
|
||||
try {
|
||||
// To facilitate testing the fallback, fail here if a testing environment variable is set.
|
||||
if (process.env.CODEQL_ACTION_FORCE_ZSTD_FAILURE === "true") {
|
||||
throw new Error("Failing since CODEQL_ACTION_FORCE_ZSTD_FAILURE is true.");
|
||||
}
|
||||
return await setupCodeQLBundleWithCompressionMethod(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, zstdAvailability, true);
|
||||
}
|
||||
catch (e) {
|
||||
zstdFailureReason = util.getErrorMessage(e) || "unknown error";
|
||||
logger.warning(`Failed to set up CodeQL tools with zstd. Falling back to gzipped version. Error: ${util.getErrorMessage(e)}`);
|
||||
}
|
||||
}
|
||||
return await setupCodeQLBundleWithCompressionMethod(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, zstdAvailability, false);
|
||||
const result = await setupCodeQLBundleWithCompressionMethod(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, zstdAvailability, false);
|
||||
if (result.toolsDownloadStatusReport && zstdFailureReason) {
|
||||
result.toolsDownloadStatusReport.zstdFailureReason = zstdFailureReason;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
async function setupCodeQLBundleWithCompressionMethod(toolsInput, apiDetails, tempDir, variant, defaultCliVersion, features, logger, zstdAvailability, useTarIfAvailable) {
|
||||
const source = await getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, useTarIfAvailable, features, logger);
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
74
pr-checks/checks/zstd-bundle-fallback.yml
Normal file
74
pr-checks/checks/zstd-bundle-fallback.yml
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
name: "Zstandard bundle fallback"
|
||||
description: "Tests the fallback for when downloading a Zstandard-compressed CodeQL Bundle fails"
|
||||
versions:
|
||||
- linked
|
||||
operatingSystems:
|
||||
- ubuntu
|
||||
env:
|
||||
CODEQL_ACTION_ZSTD_BUNDLE: true
|
||||
CODEQL_ACTION_FORCE_ZSTD_FAILURE: true
|
||||
steps:
|
||||
- name: Remove CodeQL from toolcache
|
||||
run: |
|
||||
rm -rf $RUNNER_TOOL_CACHE/CodeQL
|
||||
- id: init
|
||||
uses: ./../action/init
|
||||
with:
|
||||
# Swift is not supported on Ubuntu so we manually exclude it from the list here
|
||||
languages: cpp,csharp,go,java,javascript,python,ruby
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
- name: Build code
|
||||
shell: bash
|
||||
run: ./build.sh
|
||||
- uses: ./../action/analyze
|
||||
with:
|
||||
output: ${{ runner.temp }}/results
|
||||
upload-database: false
|
||||
- name: Upload SARIF
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: zstd-bundle.sarif
|
||||
path: ${{ runner.temp }}/results/cpp.sarif
|
||||
retention-days: 7
|
||||
- name: Check expected diagnostics
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
SARIF_PATH: ${{ runner.temp }}/results/cpp.sarif
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
|
||||
const sarif = JSON.parse(fs.readFileSync(process.env['SARIF_PATH'], 'utf8'));
|
||||
const run = sarif.runs[0];
|
||||
|
||||
const toolExecutionNotifications = run.invocations[0].toolExecutionNotifications;
|
||||
const downloadTelemetryNotifications = toolExecutionNotifications.filter(n =>
|
||||
n.descriptor.id === 'codeql-action/bundle-download-telemetry'
|
||||
);
|
||||
if (downloadTelemetryNotifications.length !== 1) {
|
||||
core.setFailed(
|
||||
'Expected exactly one reporting descriptor in the ' +
|
||||
`'runs[].invocations[].toolExecutionNotifications[]' SARIF property, but found ` +
|
||||
`${downloadTelemetryNotifications.length}. All notification reporting descriptors: ` +
|
||||
`${JSON.stringify(toolExecutionNotifications)}.`
|
||||
);
|
||||
}
|
||||
|
||||
const toolsUrl = downloadTelemetryNotifications[0].properties.attributes.toolsUrl;
|
||||
console.log(`Found tools URL: ${toolsUrl}`);
|
||||
|
||||
if (!toolsUrl.endsWith('.tar.gz')) {
|
||||
core.setFailed(
|
||||
`Expected the tools URL to be a .tar.gz file, but found '${toolsUrl}'.`
|
||||
);
|
||||
}
|
||||
|
||||
const zstdFailureReason = downloadTelemetryNotifications[0].properties.attributes.zstdFailureReason;
|
||||
console.log(`Found zstd failure reason: ${zstdFailureReason}`);
|
||||
|
||||
const expectedZstdFailureReason = 'Failing since CODEQL_ACTION_FORCE_ZSTD_FAILURE is true.';
|
||||
if (zstdFailureReason !== expectedZstdFailureReason) {
|
||||
core.setFailed(
|
||||
`Expected the zstd failure reason to be '${expectedZstdFailureReason}', but found '${zstdFailureReason}'.`
|
||||
);
|
||||
}
|
||||
|
|
@ -486,6 +486,7 @@ export interface ToolsDownloadStatusReport {
|
|||
downloadDurationMs: number;
|
||||
extractionDurationMs: number;
|
||||
toolsUrl: string;
|
||||
zstdFailureReason?: string;
|
||||
}
|
||||
|
||||
// Exported using `export const` for testing purposes. Specifically, we want to
|
||||
|
|
@ -655,6 +656,7 @@ export interface SetupCodeQLResult {
|
|||
toolsSource: ToolsSource;
|
||||
toolsVersion: string;
|
||||
zstdAvailability: tar.ZstdAvailability;
|
||||
zstdFailureReason?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -672,11 +674,18 @@ export async function setupCodeQLBundle(
|
|||
logger: Logger,
|
||||
): Promise<SetupCodeQLResult> {
|
||||
const zstdAvailability = await tar.isZstdAvailable(logger);
|
||||
let zstdFailureReason: string | undefined;
|
||||
|
||||
// If we think the installed version of tar supports zstd, try to use zstd,
|
||||
// but be prepared to fall back to gzip in case we were wrong.
|
||||
if (zstdAvailability.available) {
|
||||
try {
|
||||
// To facilitate testing the fallback, fail here if a testing environment variable is set.
|
||||
if (process.env.CODEQL_ACTION_FORCE_ZSTD_FAILURE === "true") {
|
||||
throw new Error(
|
||||
"Failing since CODEQL_ACTION_FORCE_ZSTD_FAILURE is true.",
|
||||
);
|
||||
}
|
||||
return await setupCodeQLBundleWithCompressionMethod(
|
||||
toolsInput,
|
||||
apiDetails,
|
||||
|
|
@ -689,6 +698,7 @@ export async function setupCodeQLBundle(
|
|||
true,
|
||||
);
|
||||
} catch (e) {
|
||||
zstdFailureReason = util.getErrorMessage(e) || "unknown error";
|
||||
logger.warning(
|
||||
`Failed to set up CodeQL tools with zstd. Falling back to gzipped version. Error: ${util.getErrorMessage(
|
||||
e,
|
||||
|
|
@ -697,7 +707,7 @@ export async function setupCodeQLBundle(
|
|||
}
|
||||
}
|
||||
|
||||
return await setupCodeQLBundleWithCompressionMethod(
|
||||
const result = await setupCodeQLBundleWithCompressionMethod(
|
||||
toolsInput,
|
||||
apiDetails,
|
||||
tempDir,
|
||||
|
|
@ -708,6 +718,10 @@ export async function setupCodeQLBundle(
|
|||
zstdAvailability,
|
||||
false,
|
||||
);
|
||||
if (result.toolsDownloadStatusReport && zstdFailureReason) {
|
||||
result.toolsDownloadStatusReport.zstdFailureReason = zstdFailureReason;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
async function setupCodeQLBundleWithCompressionMethod(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue