Add packs and queries from input
This commit adds the packs and queries from the actions input to the config file used by the CodeQL CLI. When the `+` is used, the actions input value is combined with the config value and when it is not used, the input value overrides the config value. This commit also adds a bunch of integration tests for this feature. In order to avoid adding too many new jobs, all of the tests are run sequentially in a single job (matrixed across relevant operating systems and OSes).
This commit is contained in:
parent
237260b693
commit
6fabde2be8
53 changed files with 2072 additions and 219 deletions
60
.github/check-codescanning-config/action.yml
vendored
Normal file
60
.github/check-codescanning-config/action.yml
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
name: Check Code-Scanning Config
|
||||||
|
description: |
|
||||||
|
Checks the code scanning configuration file generated by the
|
||||||
|
action to ensure it contains the expected contents
|
||||||
|
inputs:
|
||||||
|
languages:
|
||||||
|
required: false
|
||||||
|
description: The languages field passed to the init action.
|
||||||
|
|
||||||
|
packs:
|
||||||
|
required: false
|
||||||
|
description: The packs field passed to the init action.
|
||||||
|
|
||||||
|
queries:
|
||||||
|
required: false
|
||||||
|
description: The queries field passed to the init action.
|
||||||
|
|
||||||
|
config-file-test:
|
||||||
|
required: false
|
||||||
|
description: |
|
||||||
|
The location of the config file to use. If empty,
|
||||||
|
then no config file is used.
|
||||||
|
|
||||||
|
expected-config-file-contents:
|
||||||
|
required: true
|
||||||
|
description: |
|
||||||
|
A JSON string containing the exact contents of the config file.
|
||||||
|
|
||||||
|
tools:
|
||||||
|
required: true
|
||||||
|
description: |
|
||||||
|
The url of codeql to use.
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- uses: ./../action/init
|
||||||
|
with:
|
||||||
|
languages: ${{ inputs.languages }}
|
||||||
|
config-file: ${{ inputs.config-file-test }}
|
||||||
|
queries: ${{ inputs.queries }}
|
||||||
|
packs: ${{ inputs.packs }}
|
||||||
|
tools: ${{ inputs.tools }}
|
||||||
|
db-location: ${{ runner.temp }}/codescanning-config-cli-test
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
shell: bash
|
||||||
|
run: npm install --location=global ts-node js-yaml
|
||||||
|
|
||||||
|
- name: Check config
|
||||||
|
working-directory: ${{ github.action_path }}
|
||||||
|
shell: bash
|
||||||
|
run: ts-node ./index.ts "${{ runner.temp }}/user-config.yaml" '${{ inputs.expected-config-file-contents }}'
|
||||||
|
|
||||||
|
- name: Clean up
|
||||||
|
shell: bash
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
rm -rf ${{ runner.temp }}/codescanning-config-cli-test
|
||||||
|
rm -rf ${{ runner.temp }}/user-config.yaml
|
||||||
39
.github/check-codescanning-config/index.ts
vendored
Normal file
39
.github/check-codescanning-config/index.ts
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import * as yaml from 'js-yaml'
|
||||||
|
import * as fs from 'fs'
|
||||||
|
import * as assert from 'assert'
|
||||||
|
|
||||||
|
const actualConfig = loadActualConfig()
|
||||||
|
|
||||||
|
const rawExpectedConfig = process.argv[3].trim()
|
||||||
|
if (!rawExpectedConfig) {
|
||||||
|
core.info('No expected configuration provided')
|
||||||
|
} else {
|
||||||
|
core.startGroup('Expected generated user config')
|
||||||
|
core.info(yaml.dump(JSON.parse(rawExpectedConfig)))
|
||||||
|
core.endGroup()
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectedConfig = rawExpectedConfig ? JSON.parse(rawExpectedConfig) : undefined;
|
||||||
|
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
actualConfig,
|
||||||
|
expectedConfig,
|
||||||
|
'Expected configuration does not match actual configuration'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
function loadActualConfig() {
|
||||||
|
if (!fs.existsSync(process.argv[2])) {
|
||||||
|
core.info('No configuration file found')
|
||||||
|
return undefined
|
||||||
|
} else {
|
||||||
|
const rawActualConfig = fs.readFileSync(process.argv[2], 'utf8')
|
||||||
|
core.startGroup('Actual generated user config')
|
||||||
|
core.info(rawActualConfig)
|
||||||
|
core.endGroup()
|
||||||
|
|
||||||
|
return yaml.load(rawActualConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
2
.github/query-filter-test/action.yml
vendored
2
.github/query-filter-test/action.yml
vendored
|
|
@ -49,4 +49,4 @@ runs:
|
||||||
queries-not-run: ${{ inputs.queries-not-run}}
|
queries-not-run: ${{ inputs.queries-not-run}}
|
||||||
- name: Cleanup after test
|
- name: Cleanup after test
|
||||||
shell: bash
|
shell: bash
|
||||||
run: rm -rf "$RUNNER_TEMP/results" "$RUNNER_TEMP//query-filter-test"
|
run: rm -rf "$RUNNER_TEMP/results" "$RUNNER_TEMP/query-filter-test"
|
||||||
|
|
|
||||||
9
.github/workflows/__ml-powered-queries.yml
generated
vendored
9
.github/workflows/__ml-powered-queries.yml
generated
vendored
|
|
@ -81,6 +81,15 @@ jobs:
|
||||||
path: ${{ runner.temp }}/results/javascript.sarif
|
path: ${{ runner.temp }}/results/javascript.sarif
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
|
||||||
|
- name: Check sarif
|
||||||
|
uses: ./../action/.github/check-sarif
|
||||||
|
if: matrix.os != 'windows-latest' || matrix.version == 'latest' || matrix.version
|
||||||
|
== 'nightly-latest'
|
||||||
|
with:
|
||||||
|
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||||
|
queries-run: js/ml-powered/nosql-injection,js/ml-powered/path-injection,js/ml-powered/sql-injection,js/ml-powered/xss
|
||||||
|
queries-not-run: foo,bar
|
||||||
|
|
||||||
- name: Check results
|
- name: Check results
|
||||||
# Running ML-powered queries on Windows requires CodeQL CLI 2.9.0+. We don't run these checks
|
# Running ML-powered queries on Windows requires CodeQL CLI 2.9.0+. We don't run these checks
|
||||||
# against Windows and `cached` while CodeQL CLI 2.9.0 makes its way into `cached` to avoid the
|
# against Windows and `cached` while CodeQL CLI 2.9.0 makes its way into `cached` to avoid the
|
||||||
|
|
|
||||||
100
.github/workflows/__packaging-codescanning-config-inputs-js.yml
generated
vendored
Normal file
100
.github/workflows/__packaging-codescanning-config-inputs-js.yml
generated
vendored
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
# Warning: This file is generated automatically, and should not be modified.
|
||||||
|
# Instead, please modify the template in the pr-checks directory and run:
|
||||||
|
# pip install ruamel.yaml && python3 sync.py
|
||||||
|
# to regenerate this file.
|
||||||
|
|
||||||
|
name: 'PR Check - Packaging: Config and input passed to the CLI'
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GO111MODULE: auto
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- releases/v1
|
||||||
|
- releases/v2
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- synchronize
|
||||||
|
- reopened
|
||||||
|
- ready_for_review
|
||||||
|
workflow_dispatch: {}
|
||||||
|
jobs:
|
||||||
|
packaging-codescanning-config-inputs-js:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
version: latest
|
||||||
|
- os: macos-latest
|
||||||
|
version: latest
|
||||||
|
- os: windows-2019
|
||||||
|
version: latest
|
||||||
|
- os: windows-2022
|
||||||
|
version: latest
|
||||||
|
- os: ubuntu-latest
|
||||||
|
version: cached
|
||||||
|
- os: macos-latest
|
||||||
|
version: cached
|
||||||
|
- os: windows-2019
|
||||||
|
version: cached
|
||||||
|
- os: ubuntu-latest
|
||||||
|
version: nightly-latest
|
||||||
|
- os: macos-latest
|
||||||
|
version: nightly-latest
|
||||||
|
- os: windows-2019
|
||||||
|
version: nightly-latest
|
||||||
|
- os: windows-2022
|
||||||
|
version: nightly-latest
|
||||||
|
name: 'Packaging: Config and input passed to the CLI'
|
||||||
|
timeout-minutes: 45
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Prepare test
|
||||||
|
id: prepare-test
|
||||||
|
uses: ./.github/prepare-test
|
||||||
|
with:
|
||||||
|
version: ${{ matrix.version }}
|
||||||
|
- uses: ./../action/init
|
||||||
|
with:
|
||||||
|
config-file: .github/codeql/codeql-config-packaging3.yml
|
||||||
|
packs: +dsp-testing/codeql-pack1@1.0.0
|
||||||
|
languages: javascript
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
- name: Build code
|
||||||
|
shell: bash
|
||||||
|
run: ./build.sh
|
||||||
|
- uses: ./../action/analyze
|
||||||
|
with:
|
||||||
|
output: ${{ runner.temp }}/results
|
||||||
|
env:
|
||||||
|
TEST_MODE: true
|
||||||
|
|
||||||
|
- name: Check results
|
||||||
|
uses: ./../action/.github/check-sarif
|
||||||
|
with:
|
||||||
|
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||||
|
queries-run: javascript/example/empty-or-one-block,javascript/example/empty-or-one-block,javascript/example/other-query-block,javascript/example/two-block
|
||||||
|
queries-not-run: foo,bar
|
||||||
|
|
||||||
|
- name: Assert Results
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd "$RUNNER_TEMP/results"
|
||||||
|
# We should have 4 hits from these rules
|
||||||
|
EXPECTED_RULES="javascript/example/empty-or-one-block javascript/example/empty-or-one-block javascript/example/other-query-block javascript/example/two-block"
|
||||||
|
|
||||||
|
# use tr to replace newlines with spaces and xargs to trim leading and trailing whitespace
|
||||||
|
RULES="$(cat javascript.sarif | jq -r '.runs[0].results[].ruleId' | sort | tr "\n\r" " " | xargs)"
|
||||||
|
echo "Found matching rules '$RULES'"
|
||||||
|
if [ "$RULES" != "$EXPECTED_RULES" ]; then
|
||||||
|
echo "Did not match expected rules '$EXPECTED_RULES'."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
env:
|
||||||
|
CODEQL_PASS_CONFIG_TO_CLI: true
|
||||||
|
|
||||||
|
INTERNAL_CODEQL_ACTION_DEBUG_LOC: true
|
||||||
8
.github/workflows/__packaging-config-inputs-js.yml
generated
vendored
8
.github/workflows/__packaging-config-inputs-js.yml
generated
vendored
|
|
@ -72,6 +72,14 @@ jobs:
|
||||||
output: ${{ runner.temp }}/results
|
output: ${{ runner.temp }}/results
|
||||||
env:
|
env:
|
||||||
TEST_MODE: true
|
TEST_MODE: true
|
||||||
|
|
||||||
|
- name: Check results
|
||||||
|
uses: ./../action/.github/check-sarif
|
||||||
|
with:
|
||||||
|
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||||
|
queries-run: javascript/example/empty-or-one-block,javascript/example/empty-or-one-block,javascript/example/other-query-block,javascript/example/two-block
|
||||||
|
queries-not-run: foo,bar
|
||||||
|
|
||||||
- name: Assert Results
|
- name: Assert Results
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
8
.github/workflows/__packaging-config-js.yml
generated
vendored
8
.github/workflows/__packaging-config-js.yml
generated
vendored
|
|
@ -71,6 +71,14 @@ jobs:
|
||||||
output: ${{ runner.temp }}/results
|
output: ${{ runner.temp }}/results
|
||||||
env:
|
env:
|
||||||
TEST_MODE: true
|
TEST_MODE: true
|
||||||
|
|
||||||
|
- name: Check results
|
||||||
|
uses: ./../action/.github/check-sarif
|
||||||
|
with:
|
||||||
|
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||||
|
queries-run: javascript/example/empty-or-one-block,javascript/example/empty-or-one-block,javascript/example/other-query-block,javascript/example/two-block
|
||||||
|
queries-not-run: foo,bar
|
||||||
|
|
||||||
- name: Assert Results
|
- name: Assert Results
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
8
.github/workflows/__packaging-inputs-js.yml
generated
vendored
8
.github/workflows/__packaging-inputs-js.yml
generated
vendored
|
|
@ -72,6 +72,14 @@ jobs:
|
||||||
output: ${{ runner.temp }}/results
|
output: ${{ runner.temp }}/results
|
||||||
env:
|
env:
|
||||||
TEST_MODE: true
|
TEST_MODE: true
|
||||||
|
|
||||||
|
- name: Check results
|
||||||
|
uses: ./../action/.github/check-sarif
|
||||||
|
with:
|
||||||
|
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||||
|
queries-run: javascript/example/empty-or-one-block,javascript/example/empty-or-one-block,javascript/example/other-query-block,javascript/example/two-block
|
||||||
|
queries-not-run: foo,bar
|
||||||
|
|
||||||
- name: Assert Results
|
- name: Assert Results
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
1
.github/workflows/__split-workflow.yml
generated
vendored
1
.github/workflows/__split-workflow.yml
generated
vendored
|
|
@ -63,6 +63,7 @@ jobs:
|
||||||
output: ${{ runner.temp }}/results
|
output: ${{ runner.temp }}/results
|
||||||
env:
|
env:
|
||||||
TEST_MODE: true
|
TEST_MODE: true
|
||||||
|
|
||||||
- name: Assert No Results
|
- name: Assert No Results
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
220
.github/workflows/codescanning-config-cli.yml
vendored
Normal file
220
.github/workflows/codescanning-config-cli.yml
vendored
Normal file
|
|
@ -0,0 +1,220 @@
|
||||||
|
# Tests that the generated code scanning config file contains the expected contents
|
||||||
|
|
||||||
|
name: Code-Scanning config CLI tests
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
CODEQL_PASS_CONFIG_TO_CLI: true
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- releases/v1
|
||||||
|
- releases/v2
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- synchronize
|
||||||
|
- reopened
|
||||||
|
- ready_for_review
|
||||||
|
workflow_dispatch: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
code-scanning-config-tests:
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
version: latest
|
||||||
|
- os: macos-latest
|
||||||
|
version: latest
|
||||||
|
- os: ubuntu-latest
|
||||||
|
version: cached
|
||||||
|
- os: macos-latest
|
||||||
|
version: cached
|
||||||
|
- os: ubuntu-latest
|
||||||
|
version: nightly-latest
|
||||||
|
- os: macos-latest
|
||||||
|
version: nightly-latest
|
||||||
|
|
||||||
|
# Code-Scanning config not created because environment variable is not set
|
||||||
|
name: Code Scanning Configuration tests
|
||||||
|
timeout-minutes: 45
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Prepare test
|
||||||
|
id: prepare-test
|
||||||
|
uses: ./.github/prepare-test
|
||||||
|
with:
|
||||||
|
version: ${{ matrix.version }}
|
||||||
|
|
||||||
|
- name: Empty file
|
||||||
|
uses: ./../action/.github/check-codescanning-config
|
||||||
|
with:
|
||||||
|
expected-config-file-contents: "{}"
|
||||||
|
languages: javascript
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
|
||||||
|
- name: Packs from input
|
||||||
|
if: success() || failure()
|
||||||
|
uses: ./../action/.github/check-codescanning-config
|
||||||
|
with:
|
||||||
|
expected-config-file-contents: |
|
||||||
|
{
|
||||||
|
"packs": ["dsp-testing/codeql-pack1@1.0.0", "dsp-testing/codeql-pack2" ]
|
||||||
|
}
|
||||||
|
languages: javascript
|
||||||
|
packs: dsp-testing/codeql-pack1@1.0.0, dsp-testing/codeql-pack2
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
|
||||||
|
- name: Packs from input with +
|
||||||
|
if: success() || failure()
|
||||||
|
uses: ./../action/.github/check-codescanning-config
|
||||||
|
with:
|
||||||
|
expected-config-file-contents: |
|
||||||
|
{
|
||||||
|
"packs": ["dsp-testing/codeql-pack1@1.0.0", "dsp-testing/codeql-pack2" ]
|
||||||
|
}
|
||||||
|
languages: javascript
|
||||||
|
packs: + dsp-testing/codeql-pack1@1.0.0, dsp-testing/codeql-pack2
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
|
||||||
|
- name: Queries from input
|
||||||
|
if: success() || failure()
|
||||||
|
uses: ./../action/.github/check-codescanning-config
|
||||||
|
with:
|
||||||
|
expected-config-file-contents: |
|
||||||
|
{
|
||||||
|
"queries": [{ "uses": "./codeql-qlpacks/complex-javascript-qlpack/show_ifs.ql" }]
|
||||||
|
}
|
||||||
|
languages: javascript
|
||||||
|
queries: ./codeql-qlpacks/complex-javascript-qlpack/show_ifs.ql
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
|
||||||
|
- name: Queries from input with +
|
||||||
|
if: success() || failure()
|
||||||
|
uses: ./../action/.github/check-codescanning-config
|
||||||
|
with:
|
||||||
|
expected-config-file-contents: |
|
||||||
|
{
|
||||||
|
"queries": [{ "uses": "./codeql-qlpacks/complex-javascript-qlpack/show_ifs.ql" }]
|
||||||
|
}
|
||||||
|
languages: javascript
|
||||||
|
queries: + ./codeql-qlpacks/complex-javascript-qlpack/show_ifs.ql
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
|
||||||
|
- name: Queries and packs from input with +
|
||||||
|
if: success() || failure()
|
||||||
|
uses: ./../action/.github/check-codescanning-config
|
||||||
|
with:
|
||||||
|
expected-config-file-contents: |
|
||||||
|
{
|
||||||
|
"queries": [{ "uses": "./codeql-qlpacks/complex-javascript-qlpack/show_ifs.ql" }],
|
||||||
|
"packs": ["dsp-testing/codeql-pack1@1.0.0", "dsp-testing/codeql-pack2" ]
|
||||||
|
}
|
||||||
|
languages: javascript
|
||||||
|
queries: + ./codeql-qlpacks/complex-javascript-qlpack/show_ifs.ql
|
||||||
|
packs: + dsp-testing/codeql-pack1@1.0.0, dsp-testing/codeql-pack2
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
|
||||||
|
- name: Queries and packs from config
|
||||||
|
if: success() || failure()
|
||||||
|
uses: ./../action/.github/check-codescanning-config
|
||||||
|
with:
|
||||||
|
expected-config-file-contents: |
|
||||||
|
{
|
||||||
|
"queries": [{ "uses": "./codeql-qlpacks/complex-javascript-qlpack/foo2/show_ifs.ql" }],
|
||||||
|
"packs": {
|
||||||
|
"javascript": ["dsp-testing/codeql-pack1@1.0.0", "dsp-testing/codeql-pack2" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
languages: javascript
|
||||||
|
config-file-test: .github/codeql/queries-and-packs-config.yml
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
|
||||||
|
- name: Queries and packs from config overriden by input
|
||||||
|
if: success() || failure()
|
||||||
|
uses: ./../action/.github/check-codescanning-config
|
||||||
|
with:
|
||||||
|
expected-config-file-contents: |
|
||||||
|
{
|
||||||
|
"queries": [{ "uses": "./codeql-qlpacks/complex-javascript-qlpack/show_ifs.ql" }],
|
||||||
|
"packs": ["codeql/javascript-queries"]
|
||||||
|
}
|
||||||
|
languages: javascript
|
||||||
|
queries: ./codeql-qlpacks/complex-javascript-qlpack/show_ifs.ql
|
||||||
|
packs: codeql/javascript-queries
|
||||||
|
config-file-test: .github/codeql/queries-and-packs-config.yml
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
|
||||||
|
- name: Queries and packs from config merging with input
|
||||||
|
if: success() || failure()
|
||||||
|
uses: ./../action/.github/check-codescanning-config
|
||||||
|
with:
|
||||||
|
expected-config-file-contents: |
|
||||||
|
{
|
||||||
|
"queries": [
|
||||||
|
{ "uses": "./codeql-qlpacks/complex-javascript-qlpack/foo2/show_ifs.ql" },
|
||||||
|
{ "uses": "./codeql-qlpacks/complex-javascript-qlpack/show_ifs.ql" }
|
||||||
|
],
|
||||||
|
"packs": {
|
||||||
|
"javascript": ["dsp-testing/codeql-pack1@1.0.0", "dsp-testing/codeql-pack2", "codeql/javascript-queries" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
languages: javascript
|
||||||
|
queries: + ./codeql-qlpacks/complex-javascript-qlpack/show_ifs.ql
|
||||||
|
packs: + codeql/javascript-queries
|
||||||
|
config-file-test: .github/codeql/queries-and-packs-config.yml
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
|
||||||
|
- name: Multi-language packs from config
|
||||||
|
if: success() || failure()
|
||||||
|
uses: ./../action/.github/check-codescanning-config
|
||||||
|
with:
|
||||||
|
expected-config-file-contents: |
|
||||||
|
{
|
||||||
|
"packs": {
|
||||||
|
"javascript": ["dsp-testing/codeql-pack1@1.0.0", "dsp-testing/codeql-pack2" ],
|
||||||
|
"ruby": ["codeql/ruby-queries"]
|
||||||
|
},
|
||||||
|
"queries": [
|
||||||
|
{ "uses": "./codeql-qlpacks/complex-javascript-qlpack/foo2/show_ifs.ql" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
languages: javascript,ruby
|
||||||
|
config-file-test: .github/codeql/multi-language-packs-config.yml
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
|
||||||
|
- name: Other config properties
|
||||||
|
if: success() || failure()
|
||||||
|
uses: ./../action/.github/check-codescanning-config
|
||||||
|
with:
|
||||||
|
expected-config-file-contents: |
|
||||||
|
{
|
||||||
|
"name": "Config using all properties",
|
||||||
|
"packs": ["codeql/javascript-queries" ],
|
||||||
|
"disable-default-queries": true,
|
||||||
|
"paths-ignore": ["xxx"],
|
||||||
|
"paths": ["yyy"]
|
||||||
|
}
|
||||||
|
languages: javascript
|
||||||
|
packs: + codeql/javascript-queries
|
||||||
|
config-file-test: .github/codeql/other-config-properties.yml
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
|
||||||
|
- name: Config not generated when env var is not set
|
||||||
|
if: success() || failure()
|
||||||
|
env:
|
||||||
|
CODEQL_PASS_CONFIG_TO_CLI: false
|
||||||
|
uses: ./../action/.github/check-codescanning-config
|
||||||
|
with:
|
||||||
|
expected-config-file-contents: ""
|
||||||
|
languages: javascript
|
||||||
|
packs: + codeql/javascript-queries
|
||||||
|
config-file-test: .github/codeql/other-config-properties.yml
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
18
lib/analysis-paths.test.js
generated
18
lib/analysis-paths.test.js
generated
|
|
@ -45,7 +45,11 @@ const util = __importStar(require("./util"));
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
||||||
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
|
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
|
||||||
|
|
@ -70,7 +74,11 @@ const util = __importStar(require("./util"));
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
||||||
t.is(process.env["LGTM_INDEX_INCLUDE"], "path1\npath2");
|
t.is(process.env["LGTM_INDEX_INCLUDE"], "path1\npath2");
|
||||||
|
|
@ -96,7 +104,11 @@ const util = __importStar(require("./util"));
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
||||||
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
|
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
{"version":3,"file":"analysis-paths.test.js","sourceRoot":"","sources":["../src/analysis-paths.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAE7B,8CAAuB;AAEvB,gEAAkD;AAClD,mDAA6C;AAC7C,6CAA+B;AAE/B,IAAA,0BAAU,EAAC,aAAI,CAAC,CAAC;AAEjB,IAAA,aAAI,EAAC,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC7B,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,EAAE;YACf,KAAK,EAAE,EAAE;YACT,iBAAiB,EAAE,EAAE;YACrB,OAAO,EAAE,MAAM;YACf,YAAY,EAAE,MAAM;YACpB,SAAS,EAAE,EAAE;YACb,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAwB;YACxE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,kBAAkB,CAAC;YACpD,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,KAAK;YAChB,iBAAiB,EAAE,IAAI,CAAC,2BAA2B;YACnD,iBAAiB,EAAE,IAAI,CAAC,2BAA2B;YACnD,iBAAiB,EAAE,KAAK;SACzB,CAAC;QACF,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAChC,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;YACrC,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;YAC3C,iBAAiB,EAAE,EAAE;YACrB,OAAO,EAAE,MAAM;YACf,YAAY,EAAE,MAAM;YACpB,SAAS,EAAE,EAAE;YACb,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAwB;YACxE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,kBAAkB,CAAC;YACpD,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,KAAK;YAChB,iBAAiB,EAAE,IAAI,CAAC,2BAA2B;YACnD,iBAAiB,EAAE,IAAI,CAAC,2BAA2B;YACnD,iBAAiB,EAAE,KAAK;SACzB,CAAC;QACF,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,cAAc,CAAC,CAAC;QACxD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,cAAc,CAAC,CAAC;QACxD,CAAC,CAAC,EAAE,CACF,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EACjC,gGAAgG,CACjG,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACnC,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,EAAE;YACf,KAAK,EAAE,EAAE;YACT,iBAAiB,EAAE,EAAE;YACrB,OAAO;YACP,YAAY;YACZ,SAAS,EAAE,EAAE;YACb,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAwB;YACxE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,kBAAkB,CAAC;YACrD,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,KAAK;YAChB,iBAAiB,EAAE,IAAI,CAAC,2BAA2B;YACnD,iBAAiB,EAAE,IAAI,CAAC,2BAA2B;YACnD,iBAAiB,EAAE,KAAK;SACzB,CAAC;QACF,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC,CAAC;QAC9D,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
{"version":3,"file":"analysis-paths.test.js","sourceRoot":"","sources":["../src/analysis-paths.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAE7B,8CAAuB;AAEvB,gEAAkD;AAClD,mDAA6C;AAC7C,6CAA+B;AAE/B,IAAA,0BAAU,EAAC,aAAI,CAAC,CAAC;AAEjB,IAAA,aAAI,EAAC,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC7B,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,EAAE;YACf,KAAK,EAAE,EAAE;YACT,iBAAiB,EAAE,EAAE;YACrB,OAAO,EAAE,MAAM;YACf,YAAY,EAAE,MAAM;YACpB,SAAS,EAAE,EAAE;YACb,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAwB;YACxE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,kBAAkB,CAAC;YACpD,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,KAAK;YAChB,iBAAiB,EAAE,IAAI,CAAC,2BAA2B;YACnD,iBAAiB,EAAE,IAAI,CAAC,2BAA2B;YACnD,sBAAsB,EAAE;gBACtB,iBAAiB,EAAE,KAAK;gBACxB,kBAAkB,EAAE,KAAK;gBACzB,oBAAoB,EAAE,KAAK;aAC5B;SACF,CAAC;QACF,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAChC,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;YACrC,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;YAC3C,iBAAiB,EAAE,EAAE;YACrB,OAAO,EAAE,MAAM;YACf,YAAY,EAAE,MAAM;YACpB,SAAS,EAAE,EAAE;YACb,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAwB;YACxE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,kBAAkB,CAAC;YACpD,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,KAAK;YAChB,iBAAiB,EAAE,IAAI,CAAC,2BAA2B;YACnD,iBAAiB,EAAE,IAAI,CAAC,2BAA2B;YACnD,sBAAsB,EAAE;gBACtB,iBAAiB,EAAE,KAAK;gBACxB,kBAAkB,EAAE,KAAK;gBACzB,oBAAoB,EAAE,KAAK;aAC5B;SACF,CAAC;QACF,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,cAAc,CAAC,CAAC;QACxD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,cAAc,CAAC,CAAC;QACxD,CAAC,CAAC,EAAE,CACF,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EACjC,gGAAgG,CACjG,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACnC,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,EAAE;YACf,KAAK,EAAE,EAAE;YACT,iBAAiB,EAAE,EAAE;YACrB,OAAO;YACP,YAAY;YACZ,SAAS,EAAE,EAAE;YACb,aAAa,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAwB;YACxE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,kBAAkB,CAAC;YACrD,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,KAAK;YAChB,iBAAiB,EAAE,IAAI,CAAC,2BAA2B;YACnD,iBAAiB,EAAE,IAAI,CAAC,2BAA2B;YACnD,sBAAsB,EAAE;gBACtB,iBAAiB,EAAE,KAAK;gBACxB,kBAAkB,EAAE,KAAK;gBACzB,oBAAoB,EAAE,KAAK;aAC5B;SACF,CAAC;QACF,aAAa,CAAC,8BAA8B,CAAC,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC,CAAC;QAC9D,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
||||||
2
lib/analyze.js
generated
2
lib/analyze.js
generated
|
|
@ -138,7 +138,7 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag,
|
||||||
const codeql = await (0, codeql_1.getCodeQL)(config.codeQLCmd);
|
const codeql = await (0, codeql_1.getCodeQL)(config.codeQLCmd);
|
||||||
try {
|
try {
|
||||||
if (hasPackWithCustomQueries &&
|
if (hasPackWithCustomQueries &&
|
||||||
!(await util.codeQlVersionAbove(codeql, codeql_1.CODEQL_VERSION_CONFIG_FILES))) {
|
!(await util.useCodeScanningConfigInCli(codeql))) {
|
||||||
logger.info("Performing analysis with custom CodeQL Packs.");
|
logger.info("Performing analysis with custom CodeQL Packs.");
|
||||||
logger.startGroup(`Downloading custom packs for ${language}`);
|
logger.startGroup(`Downloading custom packs for ${language}`);
|
||||||
const results = await codeql.packDownload(packsWithVersion);
|
const results = await codeql.packDownload(packsWithVersion);
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
12
lib/analyze.test.js
generated
12
lib/analyze.test.js
generated
|
|
@ -119,7 +119,11 @@ const util = __importStar(require("./util"));
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
fs.mkdirSync(util.getCodeQLDatabasePath(config, language), {
|
fs.mkdirSync(util.getCodeQLDatabasePath(config, language), {
|
||||||
recursive: true,
|
recursive: true,
|
||||||
|
|
@ -229,7 +233,11 @@ const stubConfig = {
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
for (const options of [
|
for (const options of [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
95
lib/codeql.js
generated
95
lib/codeql.js
generated
|
|
@ -486,25 +486,8 @@ async function getCodeQLForCmd(cmd, checkVersion) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (await util.codeQlVersionAbove(codeql, exports.CODEQL_VERSION_CONFIG_FILES)) {
|
const configLocation = await generateCodescanningConfig(codeql, config);
|
||||||
const configLocation = path.resolve(config.tempDir, "user-config.yaml");
|
if (configLocation) {
|
||||||
const augmentedConfig = config.originalUserInput;
|
|
||||||
if (config.injectedMlQueries) {
|
|
||||||
// We need to inject the ML queries into the original user input before
|
|
||||||
// we pass this on to the CLI, to make sure these get run.
|
|
||||||
const packString = await util.getMlPoweredJsQueriesPack(codeql);
|
|
||||||
if (augmentedConfig.packs === undefined)
|
|
||||||
augmentedConfig.packs = [];
|
|
||||||
if (Array.isArray(augmentedConfig.packs)) {
|
|
||||||
augmentedConfig.packs.push(packString);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!augmentedConfig.packs.javascript)
|
|
||||||
augmentedConfig.packs["javascript"] = [];
|
|
||||||
augmentedConfig.packs["javascript"].push(packString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fs.writeFileSync(configLocation, yaml.dump(augmentedConfig));
|
|
||||||
extraArgs.push(`--codescanning-config=${configLocation}`);
|
extraArgs.push(`--codescanning-config=${configLocation}`);
|
||||||
}
|
}
|
||||||
await runTool(cmd, [
|
await runTool(cmd, [
|
||||||
|
|
@ -637,7 +620,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
|
||||||
if (extraSearchPath !== undefined) {
|
if (extraSearchPath !== undefined) {
|
||||||
codeqlArgs.push("--additional-packs", extraSearchPath);
|
codeqlArgs.push("--additional-packs", extraSearchPath);
|
||||||
}
|
}
|
||||||
if (!(await util.codeQlVersionAbove(this, exports.CODEQL_VERSION_CONFIG_FILES))) {
|
if (!(await util.useCodeScanningConfigInCli(this))) {
|
||||||
codeqlArgs.push(querySuitePath);
|
codeqlArgs.push(querySuitePath);
|
||||||
}
|
}
|
||||||
await runTool(cmd, codeqlArgs);
|
await runTool(cmd, codeqlArgs);
|
||||||
|
|
@ -666,7 +649,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
|
||||||
codeqlArgs.push("--sarif-category", automationDetailsId);
|
codeqlArgs.push("--sarif-category", automationDetailsId);
|
||||||
}
|
}
|
||||||
codeqlArgs.push(databasePath);
|
codeqlArgs.push(databasePath);
|
||||||
if (!(await util.codeQlVersionAbove(this, exports.CODEQL_VERSION_CONFIG_FILES))) {
|
if (!(await util.useCodeScanningConfigInCli(this))) {
|
||||||
codeqlArgs.push(...querySuitePaths);
|
codeqlArgs.push(...querySuitePaths);
|
||||||
}
|
}
|
||||||
// capture stdout, which contains analysis summaries
|
// capture stdout, which contains analysis summaries
|
||||||
|
|
@ -827,4 +810,74 @@ async function runTool(cmd, args = []) {
|
||||||
throw new CommandInvocationError(cmd, args, exitCode, error);
|
throw new CommandInvocationError(cmd, args, exitCode, error);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* If appropriate, generates a code scanning configuration that is to be used for a scan.
|
||||||
|
* If the configuration is not to be generated, returns undefined.
|
||||||
|
*
|
||||||
|
* @param codeql The CodeQL object to use.
|
||||||
|
* @param config The configuration to use.
|
||||||
|
* @returns the path to the generated user configuration file.
|
||||||
|
*/
|
||||||
|
async function generateCodescanningConfig(codeql, config) {
|
||||||
|
var _a;
|
||||||
|
if (!(await util.useCodeScanningConfigInCli(codeql))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const configLocation = path.resolve(config.tempDir, "user-config.yaml");
|
||||||
|
// make a copy so we can modify it
|
||||||
|
const augmentedConfig = JSON.parse(JSON.stringify(config.originalUserInput));
|
||||||
|
// Inject the queries from the input
|
||||||
|
if (config.augmentationProperties.queriesInput) {
|
||||||
|
if (config.augmentationProperties.queriesInputCombines) {
|
||||||
|
augmentedConfig.queries = (augmentedConfig.queries || []).concat(config.augmentationProperties.queriesInput);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
augmentedConfig.queries = config.augmentationProperties.queriesInput;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (((_a = augmentedConfig.queries) === null || _a === void 0 ? void 0 : _a.length) === 0) {
|
||||||
|
delete augmentedConfig.queries;
|
||||||
|
}
|
||||||
|
// Inject the packs from the input
|
||||||
|
if (config.augmentationProperties.packsInput) {
|
||||||
|
if (config.augmentationProperties.packsInputCombines) {
|
||||||
|
// At this point, we already know that this is a single-language analysis
|
||||||
|
if (Array.isArray(augmentedConfig.packs)) {
|
||||||
|
augmentedConfig.packs = (augmentedConfig.packs || []).concat(config.augmentationProperties.packsInput);
|
||||||
|
}
|
||||||
|
else if (!augmentedConfig.packs) {
|
||||||
|
augmentedConfig.packs = config.augmentationProperties.packsInput;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// At this point, we know there is only one language.
|
||||||
|
// If there were more than one language, an error would already have been thrown.
|
||||||
|
const language = Object.keys(augmentedConfig.packs)[0];
|
||||||
|
augmentedConfig.packs[language] = augmentedConfig.packs[language].concat(config.augmentationProperties.packsInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
augmentedConfig.packs = config.augmentationProperties.packsInput;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Array.isArray(augmentedConfig.packs) && !augmentedConfig.packs.length) {
|
||||||
|
delete augmentedConfig.packs;
|
||||||
|
}
|
||||||
|
if (config.augmentationProperties.injectedMlQueries) {
|
||||||
|
// We need to inject the ML queries into the original user input before
|
||||||
|
// we pass this on to the CLI, to make sure these get run.
|
||||||
|
const packString = await util.getMlPoweredJsQueriesPack(codeql);
|
||||||
|
if (augmentedConfig.packs === undefined)
|
||||||
|
augmentedConfig.packs = [];
|
||||||
|
if (Array.isArray(augmentedConfig.packs)) {
|
||||||
|
augmentedConfig.packs.push(packString);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!augmentedConfig.packs.javascript)
|
||||||
|
augmentedConfig.packs["javascript"] = [];
|
||||||
|
augmentedConfig.packs["javascript"].push(packString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fs.writeFileSync(configLocation, yaml.dump(augmentedConfig));
|
||||||
|
return configLocation;
|
||||||
|
}
|
||||||
//# sourceMappingURL=codeql.js.map
|
//# sourceMappingURL=codeql.js.map
|
||||||
File diff suppressed because one or more lines are too long
299
lib/codeql.test.js
generated
299
lib/codeql.test.js
generated
|
|
@ -23,10 +23,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.stubToolRunnerConstructor = void 0;
|
exports.stubToolRunnerConstructor = void 0;
|
||||||
|
const fs = __importStar(require("fs"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||||
const toolcache = __importStar(require("@actions/tool-cache"));
|
const toolcache = __importStar(require("@actions/tool-cache"));
|
||||||
const ava_1 = __importDefault(require("ava"));
|
const ava_1 = __importDefault(require("ava"));
|
||||||
|
const del_1 = __importDefault(require("del"));
|
||||||
|
const yaml = __importStar(require("js-yaml"));
|
||||||
const nock_1 = __importDefault(require("nock"));
|
const nock_1 = __importDefault(require("nock"));
|
||||||
const sinon = __importStar(require("sinon"));
|
const sinon = __importStar(require("sinon"));
|
||||||
const codeql = __importStar(require("./codeql"));
|
const codeql = __importStar(require("./codeql"));
|
||||||
|
|
@ -46,8 +49,32 @@ const sampleGHAEApiDetails = {
|
||||||
auth: "token",
|
auth: "token",
|
||||||
url: "https://example.githubenterprise.com",
|
url: "https://example.githubenterprise.com",
|
||||||
};
|
};
|
||||||
|
let stubConfig;
|
||||||
ava_1.default.beforeEach(() => {
|
ava_1.default.beforeEach(() => {
|
||||||
(0, util_1.initializeEnvironment)(util_1.Mode.actions, "1.2.3");
|
(0, util_1.initializeEnvironment)(util_1.Mode.actions, "1.2.3");
|
||||||
|
stubConfig = {
|
||||||
|
languages: [languages_1.Language.cpp],
|
||||||
|
queries: {},
|
||||||
|
pathsIgnore: [],
|
||||||
|
paths: [],
|
||||||
|
originalUserInput: {},
|
||||||
|
tempDir: "",
|
||||||
|
toolCacheDir: "",
|
||||||
|
codeQLCmd: "",
|
||||||
|
gitHubVersion: {
|
||||||
|
type: util.GitHubVariant.DOTCOM,
|
||||||
|
},
|
||||||
|
dbLocation: "",
|
||||||
|
packs: {},
|
||||||
|
debugMode: false,
|
||||||
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
});
|
});
|
||||||
(0, ava_1.default)("download codeql bundle cache", async (t) => {
|
(0, ava_1.default)("download codeql bundle cache", async (t) => {
|
||||||
await util.withTmpDir(async (tmpDir) => {
|
await util.withTmpDir(async (tmpDir) => {
|
||||||
|
|
@ -236,25 +263,6 @@ ava_1.default.beforeEach(() => {
|
||||||
await codeqlObject.databaseInterpretResults("", [], "", "", "", "");
|
await codeqlObject.databaseInterpretResults("", [], "", "", "", "");
|
||||||
t.true(runnerConstructorStub.firstCall.args[1].includes("--sarif-add-query-help"), "--sarif-add-query-help should be present, but it is absent");
|
t.true(runnerConstructorStub.firstCall.args[1].includes("--sarif-add-query-help"), "--sarif-add-query-help should be present, but it is absent");
|
||||||
});
|
});
|
||||||
const stubConfig = {
|
|
||||||
languages: [languages_1.Language.cpp],
|
|
||||||
queries: {},
|
|
||||||
pathsIgnore: [],
|
|
||||||
paths: [],
|
|
||||||
originalUserInput: {},
|
|
||||||
tempDir: "",
|
|
||||||
toolCacheDir: "",
|
|
||||||
codeQLCmd: "",
|
|
||||||
gitHubVersion: {
|
|
||||||
type: util.GitHubVariant.DOTCOM,
|
|
||||||
},
|
|
||||||
dbLocation: "",
|
|
||||||
packs: {},
|
|
||||||
debugMode: false,
|
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
|
||||||
injectedMlQueries: false,
|
|
||||||
};
|
|
||||||
(0, ava_1.default)("databaseInitCluster() Lua feature flag enabled, but old CLI", async (t) => {
|
(0, ava_1.default)("databaseInitCluster() Lua feature flag enabled, but old CLI", async (t) => {
|
||||||
const runnerConstructorStub = stubToolRunnerConstructor();
|
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
|
|
@ -285,6 +293,259 @@ const stubConfig = {
|
||||||
await codeqlObject.databaseInitCluster(stubConfig, "", undefined, undefined, (0, feature_flags_1.createFeatureFlags)([]));
|
await codeqlObject.databaseInitCluster(stubConfig, "", undefined, undefined, (0, feature_flags_1.createFeatureFlags)([]));
|
||||||
t.true(runnerConstructorStub.firstCall.args[1].includes("--no-internal-use-lua-tracing"), "--no-internal-use-lua-tracing should be present, but it is absent");
|
t.true(runnerConstructorStub.firstCall.args[1].includes("--no-internal-use-lua-tracing"), "--no-internal-use-lua-tracing should be present, but it is absent");
|
||||||
});
|
});
|
||||||
|
(0, ava_1.default)("databaseInitCluster() without injected codescanning config", async (t) => {
|
||||||
|
await util.withTmpDir(async (tempDir) => {
|
||||||
|
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||||
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
|
sinon.stub(codeqlObject, "getVersion").resolves("2.8.1");
|
||||||
|
const thisStubConfig = {
|
||||||
|
...stubConfig,
|
||||||
|
tempDir,
|
||||||
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
await codeqlObject.databaseInitCluster(thisStubConfig, "", undefined, undefined, (0, feature_flags_1.createFeatureFlags)([]));
|
||||||
|
const args = runnerConstructorStub.firstCall.args[1];
|
||||||
|
// should NOT have used an config file
|
||||||
|
const configArg = args.find((arg) => arg.startsWith("--codescanning-config="));
|
||||||
|
t.falsy(configArg, "Should have injected a codescanning config");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// Test macro for ensuring different variants of injected augmented configurations
|
||||||
|
const injectedConfigMacro = ava_1.default.macro({
|
||||||
|
exec: async (t, augmentationProperties, configOverride, expectedConfig) => {
|
||||||
|
const origCODEQL_PASS_CONFIG_TO_CLI = process.env.CODEQL_PASS_CONFIG_TO_CLI;
|
||||||
|
process.env["CODEQL_PASS_CONFIG_TO_CLI"] = "true";
|
||||||
|
try {
|
||||||
|
await util.withTmpDir(async (tempDir) => {
|
||||||
|
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||||
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
|
sinon
|
||||||
|
.stub(codeqlObject, "getVersion")
|
||||||
|
.resolves(codeql.CODEQL_VERSION_CONFIG_FILES);
|
||||||
|
const thisStubConfig = {
|
||||||
|
...stubConfig,
|
||||||
|
...configOverride,
|
||||||
|
tempDir,
|
||||||
|
augmentationProperties,
|
||||||
|
};
|
||||||
|
await codeqlObject.databaseInitCluster(thisStubConfig, "", undefined, undefined, (0, feature_flags_1.createFeatureFlags)([]));
|
||||||
|
const args = runnerConstructorStub.firstCall.args[1];
|
||||||
|
// should have used an config file
|
||||||
|
const configArg = args.find((arg) => arg.startsWith("--codescanning-config="));
|
||||||
|
t.truthy(configArg, "Should have injected a codescanning config");
|
||||||
|
const configFile = configArg.split("=")[1];
|
||||||
|
const augmentedConfig = yaml.load(fs.readFileSync(configFile, "utf8"));
|
||||||
|
t.deepEqual(augmentedConfig, expectedConfig);
|
||||||
|
await (0, del_1.default)(configFile, { force: true });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
process.env["CODEQL_PASS_CONFIG_TO_CLI"] = origCODEQL_PASS_CONFIG_TO_CLI;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title: (providedTitle = "") => `databaseInitCluster() injected config: ${providedTitle}`,
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("basic", injectedConfigMacro, {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
}, {}, {});
|
||||||
|
(0, ava_1.default)("injected ML queries", injectedConfigMacro, {
|
||||||
|
injectedMlQueries: true,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
}, {}, {
|
||||||
|
packs: ["codeql/javascript-experimental-atm-queries@~0.1.0"],
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("injected ML queries with existing packs", injectedConfigMacro, {
|
||||||
|
injectedMlQueries: true,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
}, {
|
||||||
|
originalUserInput: {
|
||||||
|
packs: { javascript: ["codeql/something-else"] },
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
packs: {
|
||||||
|
javascript: [
|
||||||
|
"codeql/something-else",
|
||||||
|
"codeql/javascript-experimental-atm-queries@~0.1.0",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("injected ML queries with existing packs of different language", injectedConfigMacro, {
|
||||||
|
injectedMlQueries: true,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
}, {
|
||||||
|
originalUserInput: {
|
||||||
|
packs: { cpp: ["codeql/something-else"] },
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
packs: {
|
||||||
|
cpp: ["codeql/something-else"],
|
||||||
|
javascript: ["codeql/javascript-experimental-atm-queries@~0.1.0"],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("injected packs from input", injectedConfigMacro, {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
packsInput: ["xxx", "yyy"],
|
||||||
|
}, {}, {
|
||||||
|
packs: ["xxx", "yyy"],
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("injected packs from input with existing packs combines", injectedConfigMacro, {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: true,
|
||||||
|
packsInput: ["xxx", "yyy"],
|
||||||
|
}, {
|
||||||
|
originalUserInput: {
|
||||||
|
packs: {
|
||||||
|
cpp: ["codeql/something-else"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
packs: {
|
||||||
|
cpp: ["codeql/something-else", "xxx", "yyy"],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("injected packs from input with existing packs overrides", injectedConfigMacro, {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
packsInput: ["xxx", "yyy"],
|
||||||
|
}, {
|
||||||
|
originalUserInput: {
|
||||||
|
packs: {
|
||||||
|
cpp: ["codeql/something-else"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
packs: ["xxx", "yyy"],
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("injected packs from input with existing packs overrides and ML model inject", injectedConfigMacro, {
|
||||||
|
injectedMlQueries: true,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
packsInput: ["xxx", "yyy"],
|
||||||
|
}, {
|
||||||
|
originalUserInput: {
|
||||||
|
packs: {
|
||||||
|
cpp: ["codeql/something-else"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
packs: ["xxx", "yyy", "codeql/javascript-experimental-atm-queries@~0.1.0"],
|
||||||
|
});
|
||||||
|
// similar, but with queries
|
||||||
|
(0, ava_1.default)("injected queries from input", injectedConfigMacro, {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInput: [{ uses: "xxx" }, { uses: "yyy" }],
|
||||||
|
}, {}, {
|
||||||
|
queries: [
|
||||||
|
{
|
||||||
|
uses: "xxx",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uses: "yyy",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("injected queries from input overrides", injectedConfigMacro, {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInput: [{ uses: "xxx" }, { uses: "yyy" }],
|
||||||
|
}, {
|
||||||
|
originalUserInput: {
|
||||||
|
queries: [{ uses: "zzz" }],
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
queries: [
|
||||||
|
{
|
||||||
|
uses: "xxx",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uses: "yyy",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("injected queries from input combines", injectedConfigMacro, {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: true,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInput: [{ uses: "xxx" }, { uses: "yyy" }],
|
||||||
|
}, {
|
||||||
|
originalUserInput: {
|
||||||
|
queries: [{ uses: "zzz" }],
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
queries: [
|
||||||
|
{
|
||||||
|
uses: "zzz",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uses: "xxx",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uses: "yyy",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("injected queries from input combines 2", injectedConfigMacro, {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: true,
|
||||||
|
packsInputCombines: true,
|
||||||
|
queriesInput: [{ uses: "xxx" }, { uses: "yyy" }],
|
||||||
|
}, {}, {
|
||||||
|
queries: [
|
||||||
|
{
|
||||||
|
uses: "xxx",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uses: "yyy",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("injected queries and packs, but empty", injectedConfigMacro, {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: true,
|
||||||
|
packsInputCombines: true,
|
||||||
|
queriesInput: [],
|
||||||
|
packsInput: [],
|
||||||
|
}, {
|
||||||
|
originalUserInput: {
|
||||||
|
packs: [],
|
||||||
|
queries: [],
|
||||||
|
},
|
||||||
|
}, {});
|
||||||
|
(0, ava_1.default)("does not use injected confg", async (t) => {
|
||||||
|
const origCODEQL_PASS_CONFIG_TO_CLI = process.env.CODEQL_PASS_CONFIG_TO_CLI;
|
||||||
|
process.env["CODEQL_PASS_CONFIG_TO_CLI"] = "false";
|
||||||
|
try {
|
||||||
|
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||||
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
|
sinon
|
||||||
|
.stub(codeqlObject, "getVersion")
|
||||||
|
.resolves(codeql.CODEQL_VERSION_CONFIG_FILES);
|
||||||
|
await codeqlObject.databaseInitCluster(stubConfig, "", undefined, undefined, (0, feature_flags_1.createFeatureFlags)([]));
|
||||||
|
const args = runnerConstructorStub.firstCall.args[1];
|
||||||
|
// should have used an config file
|
||||||
|
const configArg = args.find((arg) => arg.startsWith("--codescanning-config="));
|
||||||
|
t.falsy(configArg, "Should NOT have injected a codescanning config");
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
process.env["CODEQL_PASS_CONFIG_TO_CLI"] = origCODEQL_PASS_CONFIG_TO_CLI;
|
||||||
|
}
|
||||||
|
});
|
||||||
function stubToolRunnerConstructor() {
|
function stubToolRunnerConstructor() {
|
||||||
const runnerObjectStub = sinon.createStubInstance(toolrunner.ToolRunner);
|
const runnerObjectStub = sinon.createStubInstance(toolrunner.ToolRunner);
|
||||||
runnerObjectStub.exec.resolves(0);
|
runnerObjectStub.exec.resolves(0);
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
120
lib/config-utils.js
generated
120
lib/config-utils.js
generated
|
|
@ -19,7 +19,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.getConfig = exports.getPathToParsedConfigFile = exports.initConfig = exports.parsePacks = exports.validatePacksSpecification = exports.parsePacksFromConfig = exports.getDefaultConfig = exports.getUnknownLanguagesError = exports.getNoLanguagesError = exports.getConfigFileDirectoryGivenMessage = exports.getConfigFileFormatInvalidMessage = exports.getConfigFileRepoFormatInvalidMessage = exports.getConfigFileDoesNotExistErrorMessage = exports.getConfigFileOutsideWorkspaceErrorMessage = exports.getLocalPathDoesNotExist = exports.getLocalPathOutsideOfRepository = exports.getPacksStrInvalid = exports.getPacksInvalid = exports.getPacksInvalidSplit = exports.getPathsInvalid = exports.getPathsIgnoreInvalid = exports.getQueryUsesInvalid = exports.getQueriesInvalid = exports.getDisableDefaultQueriesInvalid = exports.getNameInvalid = exports.validateAndSanitisePath = void 0;
|
exports.getConfig = exports.getPathToParsedConfigFile = exports.initConfig = exports.parsePacks = exports.validatePacksSpecification = exports.parsePacksFromConfig = exports.calculateAugmentation = exports.getDefaultConfig = exports.getUnknownLanguagesError = exports.getNoLanguagesError = exports.getConfigFileDirectoryGivenMessage = exports.getConfigFileFormatInvalidMessage = exports.getConfigFileRepoFormatInvalidMessage = exports.getConfigFileDoesNotExistErrorMessage = exports.getConfigFileOutsideWorkspaceErrorMessage = exports.getLocalPathDoesNotExist = exports.getLocalPathOutsideOfRepository = exports.getPacksStrInvalid = exports.getPacksInvalid = exports.getPacksInvalidSplit = exports.getPathsInvalid = exports.getPathsIgnoreInvalid = exports.getQueryUsesInvalid = exports.getQueriesInvalid = exports.getDisableDefaultQueriesInvalid = exports.getNameInvalid = exports.validateAndSanitisePath = void 0;
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
const yaml = __importStar(require("js-yaml"));
|
const yaml = __importStar(require("js-yaml"));
|
||||||
|
|
@ -462,8 +462,7 @@ function shouldAddConfigFileQueries(queriesInput) {
|
||||||
/**
|
/**
|
||||||
* Get the default config for when the user has not supplied one.
|
* Get the default config for when the user has not supplied one.
|
||||||
*/
|
*/
|
||||||
async function getDefaultConfig(languagesInput, queriesInput, packsInput, dbLocation, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, toolCacheDir, codeQL, workspacePath, gitHubVersion, apiDetails, featureFlags, logger) {
|
async function getDefaultConfig(languagesInput, rawQueriesInput, rawPacksInput, dbLocation, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, toolCacheDir, codeQL, workspacePath, gitHubVersion, apiDetails, featureFlags, logger) {
|
||||||
var _a;
|
|
||||||
const languages = await getLanguages(codeQL, languagesInput, repository, apiDetails, logger);
|
const languages = await getLanguages(codeQL, languagesInput, repository, apiDetails, logger);
|
||||||
const queries = {};
|
const queries = {};
|
||||||
for (const language of languages) {
|
for (const language of languages) {
|
||||||
|
|
@ -473,10 +472,15 @@ async function getDefaultConfig(languagesInput, queriesInput, packsInput, dbLoca
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
await addDefaultQueries(codeQL, languages, queries);
|
await addDefaultQueries(codeQL, languages, queries);
|
||||||
const packs = (_a = parsePacksFromInput(packsInput, languages)) !== null && _a !== void 0 ? _a : {};
|
const augmentationProperties = calculateAugmentation(rawPacksInput, rawQueriesInput, languages);
|
||||||
let injectedMlQueries = false;
|
const packs = augmentationProperties.packsInput
|
||||||
if (queriesInput) {
|
? {
|
||||||
injectedMlQueries = await addQueriesAndPacksFromWorkflow(codeQL, queriesInput, languages, queries, packs, tempDir, workspacePath, apiDetails, featureFlags, logger);
|
[languages[0]]: augmentationProperties.packsInput,
|
||||||
|
}
|
||||||
|
: {};
|
||||||
|
if (rawQueriesInput) {
|
||||||
|
augmentationProperties.injectedMlQueries =
|
||||||
|
await addQueriesAndPacksFromWorkflow(codeQL, rawQueriesInput, languages, queries, packs, tempDir, workspacePath, apiDetails, featureFlags, logger);
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
languages,
|
languages,
|
||||||
|
|
@ -493,14 +497,14 @@ async function getDefaultConfig(languagesInput, queriesInput, packsInput, dbLoca
|
||||||
debugMode,
|
debugMode,
|
||||||
debugArtifactName,
|
debugArtifactName,
|
||||||
debugDatabaseName,
|
debugDatabaseName,
|
||||||
injectedMlQueries,
|
augmentationProperties,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.getDefaultConfig = getDefaultConfig;
|
exports.getDefaultConfig = getDefaultConfig;
|
||||||
/**
|
/**
|
||||||
* Load the config from the given file.
|
* Load the config from the given file.
|
||||||
*/
|
*/
|
||||||
async function loadConfig(languagesInput, queriesInput, packsInput, configFile, dbLocation, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, toolCacheDir, codeQL, workspacePath, gitHubVersion, apiDetails, featureFlags, logger) {
|
async function loadConfig(languagesInput, rawQueriesInput, rawPacksInput, configFile, dbLocation, debugMode, debugArtifactName, debugDatabaseName, repository, tempDir, toolCacheDir, codeQL, workspacePath, gitHubVersion, apiDetails, featureFlags, logger) {
|
||||||
var _a;
|
var _a;
|
||||||
let parsedYAML;
|
let parsedYAML;
|
||||||
if (isLocal(configFile)) {
|
if (isLocal(configFile)) {
|
||||||
|
|
@ -541,16 +545,17 @@ async function loadConfig(languagesInput, queriesInput, packsInput, configFile,
|
||||||
if (!disableDefaultQueries) {
|
if (!disableDefaultQueries) {
|
||||||
await addDefaultQueries(codeQL, languages, queries);
|
await addDefaultQueries(codeQL, languages, queries);
|
||||||
}
|
}
|
||||||
const packs = parsePacks((_a = parsedYAML[PACKS_PROPERTY]) !== null && _a !== void 0 ? _a : {}, packsInput, languages, configFile, logger);
|
const augmentationProperties = calculateAugmentation(rawPacksInput, rawQueriesInput, languages);
|
||||||
|
const packs = parsePacks((_a = parsedYAML[PACKS_PROPERTY]) !== null && _a !== void 0 ? _a : {}, rawPacksInput, augmentationProperties.packsInputCombines, languages, configFile, logger);
|
||||||
// If queries were provided using `with` in the action configuration,
|
// If queries were provided using `with` in the action configuration,
|
||||||
// they should take precedence over the queries in the config file
|
// they should take precedence over the queries in the config file
|
||||||
// unless they're prefixed with "+", in which case they supplement those
|
// unless they're prefixed with "+", in which case they supplement those
|
||||||
// in the config file.
|
// in the config file.
|
||||||
let injectedMlQueries = false;
|
if (rawQueriesInput) {
|
||||||
if (queriesInput) {
|
augmentationProperties.injectedMlQueries =
|
||||||
injectedMlQueries = await addQueriesAndPacksFromWorkflow(codeQL, queriesInput, languages, queries, packs, tempDir, workspacePath, apiDetails, featureFlags, logger);
|
await addQueriesAndPacksFromWorkflow(codeQL, rawQueriesInput, languages, queries, packs, tempDir, workspacePath, apiDetails, featureFlags, logger);
|
||||||
}
|
}
|
||||||
if (shouldAddConfigFileQueries(queriesInput) &&
|
if (shouldAddConfigFileQueries(rawQueriesInput) &&
|
||||||
QUERIES_PROPERTY in parsedYAML) {
|
QUERIES_PROPERTY in parsedYAML) {
|
||||||
const queriesArr = parsedYAML[QUERIES_PROPERTY];
|
const queriesArr = parsedYAML[QUERIES_PROPERTY];
|
||||||
if (!Array.isArray(queriesArr)) {
|
if (!Array.isArray(queriesArr)) {
|
||||||
|
|
@ -601,9 +606,54 @@ async function loadConfig(languagesInput, queriesInput, packsInput, configFile,
|
||||||
debugMode,
|
debugMode,
|
||||||
debugArtifactName,
|
debugArtifactName,
|
||||||
debugDatabaseName,
|
debugDatabaseName,
|
||||||
injectedMlQueries,
|
augmentationProperties,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Calculates how the codeql config file needs to be augmented before passing
|
||||||
|
* it to the CLI. The reason this is necessary is the codeql-action can be called
|
||||||
|
* with extra inputs from the workflow. These inputs are not part of the config
|
||||||
|
* and the CLI does not know about these inputs so we need to inject them into
|
||||||
|
* the config file sent to the CLI.
|
||||||
|
*
|
||||||
|
* @param rawPacksInput The packs input from the action configuration.
|
||||||
|
* @param rawQueriesInput The queries input from the action configuration.
|
||||||
|
* @param languages The languages that the config file is for. If the packs input
|
||||||
|
* is non-empty, then there must be exactly one language. Otherwise, an
|
||||||
|
* error is thrown.
|
||||||
|
*
|
||||||
|
* @returns The properties that need to be augmented in the config file.
|
||||||
|
*
|
||||||
|
* @throws An error if the packs input is non-empty and the languages input does
|
||||||
|
* not have exactly one language.
|
||||||
|
*/
|
||||||
|
// exported for testing.
|
||||||
|
function calculateAugmentation(rawPacksInput, rawQueriesInput, languages) {
|
||||||
|
const packsInputCombines = shouldCombine(rawPacksInput);
|
||||||
|
const packsInput = parsePacksFromInput(rawPacksInput, languages, packsInputCombines);
|
||||||
|
const queriesInputCombines = shouldCombine(rawQueriesInput);
|
||||||
|
const queriesInput = parseQueriesFromInput(rawQueriesInput, queriesInputCombines);
|
||||||
|
return {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines,
|
||||||
|
packsInput: packsInput === null || packsInput === void 0 ? void 0 : packsInput[languages[0]],
|
||||||
|
queriesInput,
|
||||||
|
queriesInputCombines,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
exports.calculateAugmentation = calculateAugmentation;
|
||||||
|
function parseQueriesFromInput(rawQueriesInput, queriesInputCombines) {
|
||||||
|
if (!rawQueriesInput) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const trimmedInput = queriesInputCombines
|
||||||
|
? rawQueriesInput.trim().slice(1).trim()
|
||||||
|
: rawQueriesInput === null || rawQueriesInput === void 0 ? void 0 : rawQueriesInput.trim();
|
||||||
|
if (queriesInputCombines && trimmedInput.length === 0) {
|
||||||
|
throw new Error(getConfigFilePropertyError(undefined, "queries", "A '+' was used in the 'queries' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs."));
|
||||||
|
}
|
||||||
|
return trimmedInput.split(",").map((query) => ({ uses: query.trim() }));
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Pack names must be in the form of `scope/name`, with only alpha-numeric characters,
|
* Pack names must be in the form of `scope/name`, with only alpha-numeric characters,
|
||||||
* and `-` allowed as long as not the first or last char.
|
* and `-` allowed as long as not the first or last char.
|
||||||
|
|
@ -653,8 +703,8 @@ function parsePacksFromConfig(packsByLanguage, languages, configFile, logger) {
|
||||||
return packs;
|
return packs;
|
||||||
}
|
}
|
||||||
exports.parsePacksFromConfig = parsePacksFromConfig;
|
exports.parsePacksFromConfig = parsePacksFromConfig;
|
||||||
function parsePacksFromInput(packsInput, languages) {
|
function parsePacksFromInput(rawPacksInput, languages, packsInputCombines) {
|
||||||
if (!(packsInput === null || packsInput === void 0 ? void 0 : packsInput.trim())) {
|
if (!(rawPacksInput === null || rawPacksInput === void 0 ? void 0 : rawPacksInput.trim())) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
if (languages.length > 1) {
|
if (languages.length > 1) {
|
||||||
|
|
@ -663,16 +713,16 @@ function parsePacksFromInput(packsInput, languages) {
|
||||||
else if (languages.length === 0) {
|
else if (languages.length === 0) {
|
||||||
throw new Error("No languages specified. Cannot process the packs input.");
|
throw new Error("No languages specified. Cannot process the packs input.");
|
||||||
}
|
}
|
||||||
packsInput = packsInput.trim();
|
rawPacksInput = rawPacksInput.trim();
|
||||||
if (packsInput.startsWith("+")) {
|
if (packsInputCombines) {
|
||||||
packsInput = packsInput.substring(1).trim();
|
rawPacksInput = rawPacksInput.trim().substring(1).trim();
|
||||||
if (!packsInput) {
|
if (!rawPacksInput) {
|
||||||
throw new Error("A '+' was used in the 'packs' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs.");
|
throw new Error(getConfigFilePropertyError(undefined, "packs", "A '+' was used in the 'packs' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
[languages[0]]: packsInput.split(",").reduce((packs, pack) => {
|
[languages[0]]: rawPacksInput.split(",").reduce((packs, pack) => {
|
||||||
packs.push(validatePacksSpecification(pack, ""));
|
packs.push(validatePacksSpecification(pack));
|
||||||
return packs;
|
return packs;
|
||||||
}, []),
|
}, []),
|
||||||
};
|
};
|
||||||
|
|
@ -741,20 +791,32 @@ function validatePacksSpecification(packStr, configFile) {
|
||||||
}
|
}
|
||||||
exports.validatePacksSpecification = validatePacksSpecification;
|
exports.validatePacksSpecification = validatePacksSpecification;
|
||||||
// exported for testing
|
// exported for testing
|
||||||
function parsePacks(rawPacksFromConfig, rawPacksInput, languages, configFile, logger) {
|
function parsePacks(rawPacksFromConfig, rawPacksFromInput, packsInputCombines, languages, configFile, logger) {
|
||||||
const packsFromInput = parsePacksFromInput(rawPacksInput, languages);
|
|
||||||
const packsFomConfig = parsePacksFromConfig(rawPacksFromConfig, languages, configFile, logger);
|
const packsFomConfig = parsePacksFromConfig(rawPacksFromConfig, languages, configFile, logger);
|
||||||
|
const packsFromInput = parsePacksFromInput(rawPacksFromInput, languages, packsInputCombines);
|
||||||
if (!packsFromInput) {
|
if (!packsFromInput) {
|
||||||
return packsFomConfig;
|
return packsFomConfig;
|
||||||
}
|
}
|
||||||
if (!shouldCombinePacks(rawPacksInput)) {
|
if (!packsInputCombines) {
|
||||||
|
if (!packsFromInput) {
|
||||||
|
throw new Error(getPacksInvalid(configFile));
|
||||||
|
}
|
||||||
return packsFromInput;
|
return packsFromInput;
|
||||||
}
|
}
|
||||||
return combinePacks(packsFromInput, packsFomConfig);
|
return combinePacks(packsFromInput, packsFomConfig);
|
||||||
}
|
}
|
||||||
exports.parsePacks = parsePacks;
|
exports.parsePacks = parsePacks;
|
||||||
function shouldCombinePacks(packsInput) {
|
/**
|
||||||
return !!(packsInput === null || packsInput === void 0 ? void 0 : packsInput.trim().startsWith("+"));
|
* The convention in this action is that an input value that is prefixed with a '+' will
|
||||||
|
* be combined with the corresponding value in the config file.
|
||||||
|
*
|
||||||
|
* Without a '+', an input value will override the corresponding value in the config file.
|
||||||
|
*
|
||||||
|
* @param inputValue The input value to process.
|
||||||
|
* @returns true if the input value should replace the corresponding value in the config file, false if it should be appended.
|
||||||
|
*/
|
||||||
|
function shouldCombine(inputValue) {
|
||||||
|
return !!(inputValue === null || inputValue === void 0 ? void 0 : inputValue.trim().startsWith("+"));
|
||||||
}
|
}
|
||||||
function combinePacks(packs1, packs2) {
|
function combinePacks(packs1, packs2) {
|
||||||
const packs = {};
|
const packs = {};
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
79
lib/config-utils.test.js
generated
79
lib/config-utils.test.js
generated
|
|
@ -118,7 +118,9 @@ function mockListLanguages(languages) {
|
||||||
const config2 = await configUtils.getConfig(tmpDir, logger);
|
const config2 = await configUtils.getConfig(tmpDir, logger);
|
||||||
t.not(config2, undefined);
|
t.not(config2, undefined);
|
||||||
if (config2 !== undefined) {
|
if (config2 !== undefined) {
|
||||||
t.deepEqual(config1, config2);
|
// removes properties assigned to undefined.
|
||||||
|
const expectedConfig = JSON.parse(JSON.stringify(config1));
|
||||||
|
t.deepEqual(expectedConfig, config2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -220,7 +222,13 @@ function mockListLanguages(languages) {
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: "my-artifact",
|
debugArtifactName: "my-artifact",
|
||||||
debugDatabaseName: "my-db",
|
debugDatabaseName: "my-db",
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInput: undefined,
|
||||||
|
queriesInput: undefined,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const languages = "javascript";
|
const languages = "javascript";
|
||||||
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
const configFilePath = createConfigFile(inputFileContents, tmpDir);
|
||||||
|
|
@ -837,7 +845,7 @@ const invalidPackNameMacro = ava_1.default.macro({
|
||||||
* Test macro for testing the packs block and the packs input
|
* Test macro for testing the packs block and the packs input
|
||||||
*/
|
*/
|
||||||
function parseInputAndConfigMacro(t, packsFromConfig, packsFromInput, languages, expected) {
|
function parseInputAndConfigMacro(t, packsFromConfig, packsFromInput, languages, expected) {
|
||||||
t.deepEqual(configUtils.parsePacks(packsFromConfig, packsFromInput, languages, "/a/b", mockLogger), expected);
|
t.deepEqual(configUtils.parsePacks(packsFromConfig, packsFromInput, !!(packsFromInput === null || packsFromInput === void 0 ? void 0 : packsFromInput.trim().startsWith("+")), languages, "/a/b", mockLogger), expected);
|
||||||
}
|
}
|
||||||
parseInputAndConfigMacro.title = (providedTitle) => `Parse Packs input and config: ${providedTitle}`;
|
parseInputAndConfigMacro.title = (providedTitle) => `Parse Packs input and config: ${providedTitle}`;
|
||||||
const mockLogger = {
|
const mockLogger = {
|
||||||
|
|
@ -845,9 +853,9 @@ const mockLogger = {
|
||||||
console.log(message);
|
console.log(message);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
function parseInputAndConfigErrorMacro(t, packsFromConfig, packsFromInput, languages, expected) {
|
function parseInputAndConfigErrorMacro(t, packsFromConfig, packsFromInput, languages, packsFromInputOverride, expected) {
|
||||||
t.throws(() => {
|
t.throws(() => {
|
||||||
configUtils.parsePacks(packsFromConfig, packsFromInput, languages, "/a/b", mockLogger);
|
configUtils.parsePacks(packsFromConfig, packsFromInput, packsFromInputOverride, languages, "/a/b", mockLogger);
|
||||||
}, {
|
}, {
|
||||||
message: expected,
|
message: expected,
|
||||||
});
|
});
|
||||||
|
|
@ -871,10 +879,10 @@ parseInputAndConfigErrorMacro.title = (providedTitle) => `Parse Packs input and
|
||||||
(0, ava_1.default)("input and config", parseInputAndConfigMacro, ["a/b", "c/d"], " +e/f, g/h@1.2.3 ", [languages_1.Language.cpp], {
|
(0, ava_1.default)("input and config", parseInputAndConfigMacro, ["a/b", "c/d"], " +e/f, g/h@1.2.3 ", [languages_1.Language.cpp], {
|
||||||
[languages_1.Language.cpp]: ["e/f", "g/h@1.2.3", "a/b", "c/d"],
|
[languages_1.Language.cpp]: ["e/f", "g/h@1.2.3", "a/b", "c/d"],
|
||||||
});
|
});
|
||||||
(0, ava_1.default)("input with no language", parseInputAndConfigErrorMacro, {}, "c/d", [], /No languages specified/);
|
(0, ava_1.default)("input with no language", parseInputAndConfigErrorMacro, {}, "c/d", [], false, /No languages specified/);
|
||||||
(0, ava_1.default)("input with two languages", parseInputAndConfigErrorMacro, {}, "c/d", [languages_1.Language.cpp, languages_1.Language.csharp], /multi-language analysis/);
|
(0, ava_1.default)("input with two languages", parseInputAndConfigErrorMacro, {}, "c/d", [languages_1.Language.cpp, languages_1.Language.csharp], false, /multi-language analysis/);
|
||||||
(0, ava_1.default)("input with + only", parseInputAndConfigErrorMacro, {}, " + ", [languages_1.Language.cpp], /remove the '\+'/);
|
(0, ava_1.default)("input with + only", parseInputAndConfigErrorMacro, {}, " + ", [languages_1.Language.cpp], true, /remove the '\+'/);
|
||||||
(0, ava_1.default)("input with invalid pack name", parseInputAndConfigErrorMacro, {}, " xxx", [languages_1.Language.cpp], /"xxx" is not a valid pack/);
|
(0, ava_1.default)("input with invalid pack name", parseInputAndConfigErrorMacro, {}, " xxx", [languages_1.Language.cpp], false, /"xxx" is not a valid pack/);
|
||||||
const mlPoweredQueriesMacro = ava_1.default.macro({
|
const mlPoweredQueriesMacro = ava_1.default.macro({
|
||||||
exec: async (t, codeQLVersion, isMlPoweredQueriesFlagEnabled, packsInput, queriesInput, expectedVersionString) => {
|
exec: async (t, codeQLVersion, isMlPoweredQueriesFlagEnabled, packsInput, queriesInput, expectedVersionString) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
|
|
@ -941,4 +949,57 @@ const mlPoweredQueriesMacro = ava_1.default.macro({
|
||||||
// Test that ML-powered queries are run on all platforms running `security-and-quality` on CodeQL
|
// Test that ML-powered queries are run on all platforms running `security-and-quality` on CodeQL
|
||||||
// CLI 2.9.3+.
|
// CLI 2.9.3+.
|
||||||
(0, ava_1.default)(mlPoweredQueriesMacro, "2.9.3", true, undefined, "security-and-quality", "~0.3.0");
|
(0, ava_1.default)(mlPoweredQueriesMacro, "2.9.3", true, undefined, "security-and-quality", "~0.3.0");
|
||||||
|
const calculateAugmentationMacro = ava_1.default.macro({
|
||||||
|
exec: async (t, _title, rawPacksInput, rawQueriesInput, languages, expectedAugmentationProperties) => {
|
||||||
|
const actualAugmentationProperties = configUtils.calculateAugmentation(rawPacksInput, rawQueriesInput, languages);
|
||||||
|
t.deepEqual(actualAugmentationProperties, expectedAugmentationProperties);
|
||||||
|
},
|
||||||
|
title: (_, title) => `Calculate Augmentation: ${title}`,
|
||||||
|
});
|
||||||
|
(0, ava_1.default)(calculateAugmentationMacro, "All empty", undefined, undefined, [languages_1.Language.javascript], {
|
||||||
|
queriesInputCombines: false,
|
||||||
|
queriesInput: undefined,
|
||||||
|
packsInputCombines: false,
|
||||||
|
packsInput: undefined,
|
||||||
|
injectedMlQueries: false,
|
||||||
|
});
|
||||||
|
(0, ava_1.default)(calculateAugmentationMacro, "With queries", undefined, " a, b , c, d", [languages_1.Language.javascript], {
|
||||||
|
queriesInputCombines: false,
|
||||||
|
queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }],
|
||||||
|
packsInputCombines: false,
|
||||||
|
packsInput: undefined,
|
||||||
|
injectedMlQueries: false,
|
||||||
|
});
|
||||||
|
(0, ava_1.default)(calculateAugmentationMacro, "With queries combining", undefined, " + a, b , c, d ", [languages_1.Language.javascript], {
|
||||||
|
queriesInputCombines: true,
|
||||||
|
queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }],
|
||||||
|
packsInputCombines: false,
|
||||||
|
packsInput: undefined,
|
||||||
|
injectedMlQueries: false,
|
||||||
|
});
|
||||||
|
(0, ava_1.default)(calculateAugmentationMacro, "With packs", " codeql/a , codeql/b , codeql/c , codeql/d ", undefined, [languages_1.Language.javascript], {
|
||||||
|
queriesInputCombines: false,
|
||||||
|
queriesInput: undefined,
|
||||||
|
packsInputCombines: false,
|
||||||
|
packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"],
|
||||||
|
injectedMlQueries: false,
|
||||||
|
});
|
||||||
|
(0, ava_1.default)(calculateAugmentationMacro, "With packs combining", " + codeql/a, codeql/b, codeql/c, codeql/d", undefined, [languages_1.Language.javascript], {
|
||||||
|
queriesInputCombines: false,
|
||||||
|
queriesInput: undefined,
|
||||||
|
packsInputCombines: true,
|
||||||
|
packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"],
|
||||||
|
injectedMlQueries: false,
|
||||||
|
});
|
||||||
|
const calculateAugmentationErrorMacro = ava_1.default.macro({
|
||||||
|
exec: async (t, _title, rawPacksInput, rawQueriesInput, languages, expectedError) => {
|
||||||
|
t.throws(() => configUtils.calculateAugmentation(rawPacksInput, rawQueriesInput, languages), { message: expectedError });
|
||||||
|
},
|
||||||
|
title: (_, title) => `Calculate Augmentation Error: ${title}`,
|
||||||
|
});
|
||||||
|
(0, ava_1.default)(calculateAugmentationErrorMacro, "Plus (+) with nothing else (queries)", undefined, " + ", [languages_1.Language.javascript], /The workflow property "queries" is invalid/);
|
||||||
|
(0, ava_1.default)(calculateAugmentationErrorMacro, "Plus (+) with nothing else (packs)", " + ", undefined, [languages_1.Language.javascript], /The workflow property "packs" is invalid/);
|
||||||
|
(0, ava_1.default)(calculateAugmentationErrorMacro, "Packs input with multiple languages", " + a/b, c/d ", undefined, [languages_1.Language.javascript, languages_1.Language.java], /Cannot specify a 'packs' input in a multi-language analysis/);
|
||||||
|
(0, ava_1.default)(calculateAugmentationErrorMacro, "Packs input with no languages", " + a/b, c/d ", undefined, [], /No languages specified/);
|
||||||
|
(0, ava_1.default)(calculateAugmentationErrorMacro, "Invalid packs", " a-pack-without-a-scope ", undefined, [languages_1.Language.javascript], /"a-pack-without-a-scope" is not a valid pack/);
|
||||||
//# sourceMappingURL=config-utils.test.js.map
|
//# sourceMappingURL=config-utils.test.js.map
|
||||||
File diff suppressed because one or more lines are too long
6
lib/database-upload.test.js
generated
6
lib/database-upload.test.js
generated
|
|
@ -58,7 +58,11 @@ function getTestConfig(tmpDir) {
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util_1.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util_1.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util_1.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util_1.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
async function mockHttpRequests(databaseUploadStatusCode) {
|
async function mockHttpRequests(databaseUploadStatusCode) {
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
6
lib/tracer-config.test.js
generated
6
lib/tracer-config.test.js
generated
|
|
@ -47,7 +47,11 @@ function getTestConfig(tmpDir) {
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// A very minimal setup
|
// A very minimal setup
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
18
lib/util.js
generated
18
lib/util.js
generated
|
|
@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.isInTestMode = exports.checkActionVersion = exports.getMlPoweredJsQueriesStatus = exports.getMlPoweredJsQueriesPack = exports.ML_POWERED_JS_QUERIES_PACK_NAME = exports.isGoodVersion = exports.delay = exports.bundleDb = exports.codeQlVersionAbove = exports.getCachedCodeQlVersion = exports.cacheCodeQlVersion = exports.isGitHubGhesVersionBelow = exports.isHTTPError = exports.UserError = exports.HTTPError = exports.getRequiredEnvParam = exports.isActions = exports.getMode = exports.enrichEnvironment = exports.initializeEnvironment = exports.Mode = exports.assertNever = exports.getGitHubAuth = exports.apiVersionInRange = exports.DisallowedAPIVersionReason = exports.checkGitHubVersionInRange = exports.getGitHubVersion = exports.GitHubVariant = exports.parseGitHubUrl = exports.getCodeQLDatabasePath = exports.getThreadsFlag = exports.getThreadsFlagValue = exports.getAddSnippetsFlag = exports.getMemoryFlag = exports.getMemoryFlagValue = exports.withTmpDir = exports.getToolNames = exports.getExtraOptionsEnvParam = exports.DEFAULT_DEBUG_DATABASE_NAME = exports.DEFAULT_DEBUG_ARTIFACT_NAME = exports.GITHUB_DOTCOM_URL = void 0;
|
exports.useCodeScanningConfigInCli = exports.isInTestMode = exports.checkActionVersion = exports.getMlPoweredJsQueriesStatus = exports.getMlPoweredJsQueriesPack = exports.ML_POWERED_JS_QUERIES_PACK_NAME = exports.isGoodVersion = exports.delay = exports.bundleDb = exports.codeQlVersionAbove = exports.getCachedCodeQlVersion = exports.cacheCodeQlVersion = exports.isGitHubGhesVersionBelow = exports.isHTTPError = exports.UserError = exports.HTTPError = exports.getRequiredEnvParam = exports.isActions = exports.getMode = exports.enrichEnvironment = exports.initializeEnvironment = exports.Mode = exports.assertNever = exports.getGitHubAuth = exports.apiVersionInRange = exports.DisallowedAPIVersionReason = exports.checkGitHubVersionInRange = exports.getGitHubVersion = exports.GitHubVariant = exports.parseGitHubUrl = exports.getCodeQLDatabasePath = exports.getThreadsFlag = exports.getThreadsFlagValue = exports.getAddSnippetsFlag = exports.getMemoryFlag = exports.getMemoryFlagValue = exports.withTmpDir = exports.getToolNames = exports.getExtraOptionsEnvParam = exports.DEFAULT_DEBUG_DATABASE_NAME = exports.DEFAULT_DEBUG_ARTIFACT_NAME = exports.GITHUB_DOTCOM_URL = void 0;
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const os = __importStar(require("os"));
|
const os = __importStar(require("os"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
|
|
@ -419,6 +419,12 @@ var EnvVar;
|
||||||
* own sandwiched workflow mechanism
|
* own sandwiched workflow mechanism
|
||||||
*/
|
*/
|
||||||
EnvVar["FEATURE_SANDWICH"] = "CODEQL_ACTION_FEATURE_SANDWICH";
|
EnvVar["FEATURE_SANDWICH"] = "CODEQL_ACTION_FEATURE_SANDWICH";
|
||||||
|
/**
|
||||||
|
* If set to the "true" string and the codeql CLI version is greater than
|
||||||
|
* `CODEQL_VERSION_CONFIG_FILES`, then the codeql-action will pass the
|
||||||
|
* the codeql-config file to the codeql CLI to be processed there.
|
||||||
|
*/
|
||||||
|
EnvVar["CODEQL_PASS_CONFIG_TO_CLI"] = "CODEQL_PASS_CONFIG_TO_CLI";
|
||||||
})(EnvVar || (EnvVar = {}));
|
})(EnvVar || (EnvVar = {}));
|
||||||
const exportVar = (mode, name, value) => {
|
const exportVar = (mode, name, value) => {
|
||||||
if (mode === Mode.actions) {
|
if (mode === Mode.actions) {
|
||||||
|
|
@ -642,4 +648,14 @@ function isInTestMode() {
|
||||||
return process.env["TEST_MODE"] === "true" || false;
|
return process.env["TEST_MODE"] === "true" || false;
|
||||||
}
|
}
|
||||||
exports.isInTestMode = isInTestMode;
|
exports.isInTestMode = isInTestMode;
|
||||||
|
/**
|
||||||
|
* @returns true if the action should generate a conde-scanning config file
|
||||||
|
* that gets passed to the CLI.
|
||||||
|
*/
|
||||||
|
async function useCodeScanningConfigInCli(codeql) {
|
||||||
|
return ((process.env[EnvVar.CODEQL_PASS_CONFIG_TO_CLI] === "true" &&
|
||||||
|
(await codeQlVersionAbove(codeql, codeql_1.CODEQL_VERSION_CONFIG_FILES))) ||
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
exports.useCodeScanningConfigInCli = useCodeScanningConfigInCli;
|
||||||
//# sourceMappingURL=util.js.map
|
//# sourceMappingURL=util.js.map
|
||||||
File diff suppressed because one or more lines are too long
6
lib/util.test.js
generated
6
lib/util.test.js
generated
|
|
@ -257,7 +257,11 @@ for (const [packs, expectedStatus] of ML_POWERED_JS_STATUS_TESTS) {
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
t.is(util.getMlPoweredJsQueriesStatus(config), expectedStatus);
|
t.is(util.getMlPoweredJsQueriesStatus(config), expectedStatus);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -31,6 +31,14 @@ steps:
|
||||||
path: "${{ runner.temp }}/results/javascript.sarif"
|
path: "${{ runner.temp }}/results/javascript.sarif"
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
|
||||||
|
- name: Check sarif
|
||||||
|
uses: ./../action/.github/check-sarif
|
||||||
|
if: matrix.os != 'windows-latest' || matrix.version == 'latest' || matrix.version == 'nightly-latest'
|
||||||
|
with:
|
||||||
|
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||||
|
queries-run: js/ml-powered/nosql-injection,js/ml-powered/path-injection,js/ml-powered/sql-injection,js/ml-powered/xss
|
||||||
|
queries-not-run: foo,bar
|
||||||
|
|
||||||
- name: Check results
|
- name: Check results
|
||||||
# Running ML-powered queries on Windows requires CodeQL CLI 2.9.0+. We don't run these checks
|
# Running ML-powered queries on Windows requires CodeQL CLI 2.9.0+. We don't run these checks
|
||||||
# against Windows and `cached` while CodeQL CLI 2.9.0 makes its way into `cached` to avoid the
|
# against Windows and `cached` while CodeQL CLI 2.9.0 makes its way into `cached` to avoid the
|
||||||
|
|
|
||||||
44
pr-checks/checks/packaging-codescanning-config-inputs-js.yml
Normal file
44
pr-checks/checks/packaging-codescanning-config-inputs-js.yml
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
name: "Packaging: Config and input passed to the CLI"
|
||||||
|
description: "Checks that specifying packages using a combination of a config file and input to the Action works"
|
||||||
|
versions: ["latest", "cached", "nightly-latest"] # This feature is not compatible with old CLIs
|
||||||
|
|
||||||
|
env:
|
||||||
|
CODEQL_PASS_CONFIG_TO_CLI: true
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: ./../action/init
|
||||||
|
with:
|
||||||
|
config-file: ".github/codeql/codeql-config-packaging3.yml"
|
||||||
|
packs: +dsp-testing/codeql-pack1@1.0.0
|
||||||
|
languages: javascript
|
||||||
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
- name: Build code
|
||||||
|
shell: bash
|
||||||
|
run: ./build.sh
|
||||||
|
- uses: ./../action/analyze
|
||||||
|
with:
|
||||||
|
output: "${{ runner.temp }}/results"
|
||||||
|
env:
|
||||||
|
TEST_MODE: true
|
||||||
|
|
||||||
|
- name: Check results
|
||||||
|
uses: ./../action/.github/check-sarif
|
||||||
|
with:
|
||||||
|
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||||
|
queries-run: javascript/example/empty-or-one-block,javascript/example/empty-or-one-block,javascript/example/other-query-block,javascript/example/two-block
|
||||||
|
queries-not-run: foo,bar
|
||||||
|
|
||||||
|
- name: Assert Results
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd "$RUNNER_TEMP/results"
|
||||||
|
# We should have 4 hits from these rules
|
||||||
|
EXPECTED_RULES="javascript/example/empty-or-one-block javascript/example/empty-or-one-block javascript/example/other-query-block javascript/example/two-block"
|
||||||
|
|
||||||
|
# use tr to replace newlines with spaces and xargs to trim leading and trailing whitespace
|
||||||
|
RULES="$(cat javascript.sarif | jq -r '.runs[0].results[].ruleId' | sort | tr "\n\r" " " | xargs)"
|
||||||
|
echo "Found matching rules '$RULES'"
|
||||||
|
if [ "$RULES" != "$EXPECTED_RULES" ]; then
|
||||||
|
echo "Did not match expected rules '$EXPECTED_RULES'."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
@ -16,6 +16,14 @@ steps:
|
||||||
output: "${{ runner.temp }}/results"
|
output: "${{ runner.temp }}/results"
|
||||||
env:
|
env:
|
||||||
TEST_MODE: true
|
TEST_MODE: true
|
||||||
|
|
||||||
|
- name: Check results
|
||||||
|
uses: ./../action/.github/check-sarif
|
||||||
|
with:
|
||||||
|
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||||
|
queries-run: javascript/example/empty-or-one-block,javascript/example/empty-or-one-block,javascript/example/other-query-block,javascript/example/two-block
|
||||||
|
queries-not-run: foo,bar
|
||||||
|
|
||||||
- name: Assert Results
|
- name: Assert Results
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,14 @@ steps:
|
||||||
output: "${{ runner.temp }}/results"
|
output: "${{ runner.temp }}/results"
|
||||||
env:
|
env:
|
||||||
TEST_MODE: true
|
TEST_MODE: true
|
||||||
|
|
||||||
|
- name: Check results
|
||||||
|
uses: ./../action/.github/check-sarif
|
||||||
|
with:
|
||||||
|
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||||
|
queries-run: javascript/example/empty-or-one-block,javascript/example/empty-or-one-block,javascript/example/other-query-block,javascript/example/two-block
|
||||||
|
queries-not-run: foo,bar
|
||||||
|
|
||||||
- name: Assert Results
|
- name: Assert Results
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,14 @@ steps:
|
||||||
output: "${{ runner.temp }}/results"
|
output: "${{ runner.temp }}/results"
|
||||||
env:
|
env:
|
||||||
TEST_MODE: true
|
TEST_MODE: true
|
||||||
|
|
||||||
|
- name: Check results
|
||||||
|
uses: ./../action/.github/check-sarif
|
||||||
|
with:
|
||||||
|
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||||
|
queries-run: javascript/example/empty-or-one-block,javascript/example/empty-or-one-block,javascript/example/other-query-block,javascript/example/two-block
|
||||||
|
queries-not-run: foo,bar
|
||||||
|
|
||||||
- name: Assert Results
|
- name: Assert Results
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ steps:
|
||||||
output: "${{ runner.temp }}/results"
|
output: "${{ runner.temp }}/results"
|
||||||
env:
|
env:
|
||||||
TEST_MODE: true
|
TEST_MODE: true
|
||||||
|
|
||||||
- name: Assert No Results
|
- name: Assert No Results
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,11 @@ test("emptyPaths", async (t) => {
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
||||||
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
|
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
|
||||||
|
|
@ -51,7 +55,11 @@ test("nonEmptyPaths", async (t) => {
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
||||||
t.is(process.env["LGTM_INDEX_INCLUDE"], "path1\npath2");
|
t.is(process.env["LGTM_INDEX_INCLUDE"], "path1\npath2");
|
||||||
|
|
@ -81,7 +89,11 @@ test("exclude temp dir", async (t) => {
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
||||||
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
|
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,11 @@ test("status report fields and search path setting", async (t) => {
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
fs.mkdirSync(util.getCodeQLDatabasePath(config, language), {
|
fs.mkdirSync(util.getCodeQLDatabasePath(config, language), {
|
||||||
recursive: true,
|
recursive: true,
|
||||||
|
|
@ -269,7 +273,11 @@ const stubConfig: Config = {
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const options of [
|
for (const options of [
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import * as yaml from "js-yaml";
|
||||||
import * as analysisPaths from "./analysis-paths";
|
import * as analysisPaths from "./analysis-paths";
|
||||||
import {
|
import {
|
||||||
CodeQL,
|
CodeQL,
|
||||||
CODEQL_VERSION_CONFIG_FILES,
|
|
||||||
CODEQL_VERSION_COUNTS_LINES,
|
CODEQL_VERSION_COUNTS_LINES,
|
||||||
CODEQL_VERSION_NEW_TRACING,
|
CODEQL_VERSION_NEW_TRACING,
|
||||||
getCodeQL,
|
getCodeQL,
|
||||||
|
|
@ -246,7 +245,7 @@ export async function runQueries(
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
hasPackWithCustomQueries &&
|
hasPackWithCustomQueries &&
|
||||||
!(await util.codeQlVersionAbove(codeql, CODEQL_VERSION_CONFIG_FILES))
|
!(await util.useCodeScanningConfigInCli(codeql))
|
||||||
) {
|
) {
|
||||||
logger.info("Performing analysis with custom CodeQL Packs.");
|
logger.info("Performing analysis with custom CodeQL Packs.");
|
||||||
logger.startGroup(`Downloading custom packs for ${language}`);
|
logger.startGroup(`Downloading custom packs for ${language}`);
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
|
import * as fs from "fs";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
|
|
||||||
import * as toolrunner from "@actions/exec/lib/toolrunner";
|
import * as toolrunner from "@actions/exec/lib/toolrunner";
|
||||||
import * as toolcache from "@actions/tool-cache";
|
import * as toolcache from "@actions/tool-cache";
|
||||||
import test from "ava";
|
import test, { ExecutionContext } from "ava";
|
||||||
|
import del from "del";
|
||||||
|
import * as yaml from "js-yaml";
|
||||||
import nock from "nock";
|
import nock from "nock";
|
||||||
import * as sinon from "sinon";
|
import * as sinon from "sinon";
|
||||||
|
|
||||||
import * as codeql from "./codeql";
|
import * as codeql from "./codeql";
|
||||||
import { Config } from "./config-utils";
|
import { AugmentationProperties, Config } from "./config-utils";
|
||||||
import * as defaults from "./defaults.json";
|
import * as defaults from "./defaults.json";
|
||||||
import { createFeatureFlags, FeatureFlag } from "./feature-flags";
|
import { createFeatureFlags, FeatureFlag } from "./feature-flags";
|
||||||
import { Language } from "./languages";
|
import { Language } from "./languages";
|
||||||
|
|
@ -28,8 +31,34 @@ const sampleGHAEApiDetails = {
|
||||||
url: "https://example.githubenterprise.com",
|
url: "https://example.githubenterprise.com",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let stubConfig: Config;
|
||||||
|
|
||||||
test.beforeEach(() => {
|
test.beforeEach(() => {
|
||||||
initializeEnvironment(Mode.actions, "1.2.3");
|
initializeEnvironment(Mode.actions, "1.2.3");
|
||||||
|
|
||||||
|
stubConfig = {
|
||||||
|
languages: [Language.cpp],
|
||||||
|
queries: {},
|
||||||
|
pathsIgnore: [],
|
||||||
|
paths: [],
|
||||||
|
originalUserInput: {},
|
||||||
|
tempDir: "",
|
||||||
|
toolCacheDir: "",
|
||||||
|
codeQLCmd: "",
|
||||||
|
gitHubVersion: {
|
||||||
|
type: util.GitHubVariant.DOTCOM,
|
||||||
|
} as util.GitHubVersion,
|
||||||
|
dbLocation: "",
|
||||||
|
packs: {},
|
||||||
|
debugMode: false,
|
||||||
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
test("download codeql bundle cache", async (t) => {
|
test("download codeql bundle cache", async (t) => {
|
||||||
|
|
@ -428,26 +457,6 @@ test("databaseInterpretResults() sets --sarif-add-query-help for 2.7.1", async (
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const stubConfig: Config = {
|
|
||||||
languages: [Language.cpp],
|
|
||||||
queries: {},
|
|
||||||
pathsIgnore: [],
|
|
||||||
paths: [],
|
|
||||||
originalUserInput: {},
|
|
||||||
tempDir: "",
|
|
||||||
toolCacheDir: "",
|
|
||||||
codeQLCmd: "",
|
|
||||||
gitHubVersion: {
|
|
||||||
type: util.GitHubVariant.DOTCOM,
|
|
||||||
} as util.GitHubVersion,
|
|
||||||
dbLocation: "",
|
|
||||||
packs: {},
|
|
||||||
debugMode: false,
|
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
|
||||||
injectedMlQueries: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
test("databaseInitCluster() Lua feature flag enabled, but old CLI", async (t) => {
|
test("databaseInitCluster() Lua feature flag enabled, but old CLI", async (t) => {
|
||||||
const runnerConstructorStub = stubToolRunnerConstructor();
|
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
|
|
@ -540,6 +549,392 @@ test("databaseInitCluster() Lua feature flag disabled, compatible CLI", async (t
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("databaseInitCluster() without injected codescanning config", async (t) => {
|
||||||
|
await util.withTmpDir(async (tempDir) => {
|
||||||
|
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||||
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
|
sinon.stub(codeqlObject, "getVersion").resolves("2.8.1");
|
||||||
|
|
||||||
|
const thisStubConfig: Config = {
|
||||||
|
...stubConfig,
|
||||||
|
tempDir,
|
||||||
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await codeqlObject.databaseInitCluster(
|
||||||
|
thisStubConfig,
|
||||||
|
"",
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
createFeatureFlags([])
|
||||||
|
);
|
||||||
|
|
||||||
|
const args = runnerConstructorStub.firstCall.args[1];
|
||||||
|
// should NOT have used an config file
|
||||||
|
const configArg = args.find((arg: string) =>
|
||||||
|
arg.startsWith("--codescanning-config=")
|
||||||
|
);
|
||||||
|
t.falsy(configArg, "Should have injected a codescanning config");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test macro for ensuring different variants of injected augmented configurations
|
||||||
|
const injectedConfigMacro = test.macro({
|
||||||
|
exec: async (
|
||||||
|
t: ExecutionContext<unknown>,
|
||||||
|
augmentationProperties: AugmentationProperties,
|
||||||
|
configOverride: Partial<Config>,
|
||||||
|
expectedConfig: any
|
||||||
|
) => {
|
||||||
|
const origCODEQL_PASS_CONFIG_TO_CLI = process.env.CODEQL_PASS_CONFIG_TO_CLI;
|
||||||
|
process.env["CODEQL_PASS_CONFIG_TO_CLI"] = "true";
|
||||||
|
try {
|
||||||
|
await util.withTmpDir(async (tempDir) => {
|
||||||
|
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||||
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
|
sinon
|
||||||
|
.stub(codeqlObject, "getVersion")
|
||||||
|
.resolves(codeql.CODEQL_VERSION_CONFIG_FILES);
|
||||||
|
|
||||||
|
const thisStubConfig: Config = {
|
||||||
|
...stubConfig,
|
||||||
|
...configOverride,
|
||||||
|
tempDir,
|
||||||
|
augmentationProperties,
|
||||||
|
};
|
||||||
|
|
||||||
|
await codeqlObject.databaseInitCluster(
|
||||||
|
thisStubConfig,
|
||||||
|
"",
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
createFeatureFlags([])
|
||||||
|
);
|
||||||
|
|
||||||
|
const args = runnerConstructorStub.firstCall.args[1];
|
||||||
|
// should have used an config file
|
||||||
|
const configArg = args.find((arg: string) =>
|
||||||
|
arg.startsWith("--codescanning-config=")
|
||||||
|
);
|
||||||
|
t.truthy(configArg, "Should have injected a codescanning config");
|
||||||
|
const configFile = configArg.split("=")[1];
|
||||||
|
const augmentedConfig = yaml.load(fs.readFileSync(configFile, "utf8"));
|
||||||
|
t.deepEqual(augmentedConfig, expectedConfig);
|
||||||
|
|
||||||
|
await del(configFile, { force: true });
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
process.env["CODEQL_PASS_CONFIG_TO_CLI"] = origCODEQL_PASS_CONFIG_TO_CLI;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
title: (providedTitle = "") =>
|
||||||
|
`databaseInitCluster() injected config: ${providedTitle}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
"basic",
|
||||||
|
injectedConfigMacro,
|
||||||
|
{
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
"injected ML queries",
|
||||||
|
injectedConfigMacro,
|
||||||
|
{
|
||||||
|
injectedMlQueries: true,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
packs: ["codeql/javascript-experimental-atm-queries@~0.1.0"],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
"injected ML queries with existing packs",
|
||||||
|
injectedConfigMacro,
|
||||||
|
{
|
||||||
|
injectedMlQueries: true,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
originalUserInput: {
|
||||||
|
packs: { javascript: ["codeql/something-else"] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
packs: {
|
||||||
|
javascript: [
|
||||||
|
"codeql/something-else",
|
||||||
|
"codeql/javascript-experimental-atm-queries@~0.1.0",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
"injected ML queries with existing packs of different language",
|
||||||
|
injectedConfigMacro,
|
||||||
|
{
|
||||||
|
injectedMlQueries: true,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
originalUserInput: {
|
||||||
|
packs: { cpp: ["codeql/something-else"] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
packs: {
|
||||||
|
cpp: ["codeql/something-else"],
|
||||||
|
javascript: ["codeql/javascript-experimental-atm-queries@~0.1.0"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
"injected packs from input",
|
||||||
|
injectedConfigMacro,
|
||||||
|
{
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
packsInput: ["xxx", "yyy"],
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
packs: ["xxx", "yyy"],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
"injected packs from input with existing packs combines",
|
||||||
|
injectedConfigMacro,
|
||||||
|
{
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: true,
|
||||||
|
packsInput: ["xxx", "yyy"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
originalUserInput: {
|
||||||
|
packs: {
|
||||||
|
cpp: ["codeql/something-else"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
packs: {
|
||||||
|
cpp: ["codeql/something-else", "xxx", "yyy"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
"injected packs from input with existing packs overrides",
|
||||||
|
injectedConfigMacro,
|
||||||
|
{
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
packsInput: ["xxx", "yyy"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
originalUserInput: {
|
||||||
|
packs: {
|
||||||
|
cpp: ["codeql/something-else"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
packs: ["xxx", "yyy"],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
"injected packs from input with existing packs overrides and ML model inject",
|
||||||
|
injectedConfigMacro,
|
||||||
|
{
|
||||||
|
injectedMlQueries: true,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
packsInput: ["xxx", "yyy"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
originalUserInput: {
|
||||||
|
packs: {
|
||||||
|
cpp: ["codeql/something-else"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
packs: ["xxx", "yyy", "codeql/javascript-experimental-atm-queries@~0.1.0"],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// similar, but with queries
|
||||||
|
test(
|
||||||
|
"injected queries from input",
|
||||||
|
injectedConfigMacro,
|
||||||
|
{
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInput: [{ uses: "xxx" }, { uses: "yyy" }],
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
queries: [
|
||||||
|
{
|
||||||
|
uses: "xxx",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uses: "yyy",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
"injected queries from input overrides",
|
||||||
|
injectedConfigMacro,
|
||||||
|
{
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInput: [{ uses: "xxx" }, { uses: "yyy" }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
originalUserInput: {
|
||||||
|
queries: [{ uses: "zzz" }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
queries: [
|
||||||
|
{
|
||||||
|
uses: "xxx",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uses: "yyy",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
"injected queries from input combines",
|
||||||
|
injectedConfigMacro,
|
||||||
|
{
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: true,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInput: [{ uses: "xxx" }, { uses: "yyy" }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
originalUserInput: {
|
||||||
|
queries: [{ uses: "zzz" }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
queries: [
|
||||||
|
{
|
||||||
|
uses: "zzz",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uses: "xxx",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uses: "yyy",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
"injected queries from input combines 2",
|
||||||
|
injectedConfigMacro,
|
||||||
|
{
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: true,
|
||||||
|
packsInputCombines: true,
|
||||||
|
queriesInput: [{ uses: "xxx" }, { uses: "yyy" }],
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
queries: [
|
||||||
|
{
|
||||||
|
uses: "xxx",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uses: "yyy",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
"injected queries and packs, but empty",
|
||||||
|
injectedConfigMacro,
|
||||||
|
{
|
||||||
|
injectedMlQueries: false,
|
||||||
|
queriesInputCombines: true,
|
||||||
|
packsInputCombines: true,
|
||||||
|
queriesInput: [],
|
||||||
|
packsInput: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
originalUserInput: {
|
||||||
|
packs: [],
|
||||||
|
queries: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
test("does not use injected confg", async (t: ExecutionContext<unknown>) => {
|
||||||
|
const origCODEQL_PASS_CONFIG_TO_CLI = process.env.CODEQL_PASS_CONFIG_TO_CLI;
|
||||||
|
process.env["CODEQL_PASS_CONFIG_TO_CLI"] = "false";
|
||||||
|
|
||||||
|
try {
|
||||||
|
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||||
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
|
sinon
|
||||||
|
.stub(codeqlObject, "getVersion")
|
||||||
|
.resolves(codeql.CODEQL_VERSION_CONFIG_FILES);
|
||||||
|
|
||||||
|
await codeqlObject.databaseInitCluster(
|
||||||
|
stubConfig,
|
||||||
|
"",
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
createFeatureFlags([])
|
||||||
|
);
|
||||||
|
|
||||||
|
const args = runnerConstructorStub.firstCall.args[1];
|
||||||
|
// should have used an config file
|
||||||
|
const configArg = args.find((arg: string) =>
|
||||||
|
arg.startsWith("--codescanning-config=")
|
||||||
|
);
|
||||||
|
t.falsy(configArg, "Should NOT have injected a codescanning config");
|
||||||
|
} finally {
|
||||||
|
process.env["CODEQL_PASS_CONFIG_TO_CLI"] = origCODEQL_PASS_CONFIG_TO_CLI;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export function stubToolRunnerConstructor(): sinon.SinonStub<
|
export function stubToolRunnerConstructor(): sinon.SinonStub<
|
||||||
any[],
|
any[],
|
||||||
toolrunner.ToolRunner
|
toolrunner.ToolRunner
|
||||||
|
|
|
||||||
|
|
@ -763,26 +763,12 @@ async function getCodeQLForCmd(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (await util.codeQlVersionAbove(codeql, CODEQL_VERSION_CONFIG_FILES)) {
|
|
||||||
const configLocation = path.resolve(config.tempDir, "user-config.yaml");
|
|
||||||
const augmentedConfig = config.originalUserInput;
|
|
||||||
if (config.injectedMlQueries) {
|
|
||||||
// We need to inject the ML queries into the original user input before
|
|
||||||
// we pass this on to the CLI, to make sure these get run.
|
|
||||||
const packString = await util.getMlPoweredJsQueriesPack(codeql);
|
|
||||||
|
|
||||||
if (augmentedConfig.packs === undefined) augmentedConfig.packs = [];
|
const configLocation = await generateCodescanningConfig(codeql, config);
|
||||||
if (Array.isArray(augmentedConfig.packs)) {
|
if (configLocation) {
|
||||||
augmentedConfig.packs.push(packString);
|
|
||||||
} else {
|
|
||||||
if (!augmentedConfig.packs.javascript)
|
|
||||||
augmentedConfig.packs["javascript"] = [];
|
|
||||||
augmentedConfig.packs["javascript"].push(packString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fs.writeFileSync(configLocation, yaml.dump(augmentedConfig));
|
|
||||||
extraArgs.push(`--codescanning-config=${configLocation}`);
|
extraArgs.push(`--codescanning-config=${configLocation}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
await runTool(cmd, [
|
await runTool(cmd, [
|
||||||
"database",
|
"database",
|
||||||
"init",
|
"init",
|
||||||
|
|
@ -955,7 +941,7 @@ async function getCodeQLForCmd(
|
||||||
if (extraSearchPath !== undefined) {
|
if (extraSearchPath !== undefined) {
|
||||||
codeqlArgs.push("--additional-packs", extraSearchPath);
|
codeqlArgs.push("--additional-packs", extraSearchPath);
|
||||||
}
|
}
|
||||||
if (!(await util.codeQlVersionAbove(this, CODEQL_VERSION_CONFIG_FILES))) {
|
if (!(await util.useCodeScanningConfigInCli(this))) {
|
||||||
codeqlArgs.push(querySuitePath);
|
codeqlArgs.push(querySuitePath);
|
||||||
}
|
}
|
||||||
await runTool(cmd, codeqlArgs);
|
await runTool(cmd, codeqlArgs);
|
||||||
|
|
@ -993,7 +979,7 @@ async function getCodeQLForCmd(
|
||||||
codeqlArgs.push("--sarif-category", automationDetailsId);
|
codeqlArgs.push("--sarif-category", automationDetailsId);
|
||||||
}
|
}
|
||||||
codeqlArgs.push(databasePath);
|
codeqlArgs.push(databasePath);
|
||||||
if (!(await util.codeQlVersionAbove(this, CODEQL_VERSION_CONFIG_FILES))) {
|
if (!(await util.useCodeScanningConfigInCli(this))) {
|
||||||
codeqlArgs.push(...querySuitePaths);
|
codeqlArgs.push(...querySuitePaths);
|
||||||
}
|
}
|
||||||
// capture stdout, which contains analysis summaries
|
// capture stdout, which contains analysis summaries
|
||||||
|
|
@ -1187,3 +1173,77 @@ async function runTool(cmd: string, args: string[] = []) {
|
||||||
throw new CommandInvocationError(cmd, args, exitCode, error);
|
throw new CommandInvocationError(cmd, args, exitCode, error);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If appropriate, generates a code scanning configuration that is to be used for a scan.
|
||||||
|
* If the configuration is not to be generated, returns undefined.
|
||||||
|
*
|
||||||
|
* @param codeql The CodeQL object to use.
|
||||||
|
* @param config The configuration to use.
|
||||||
|
* @returns the path to the generated user configuration file.
|
||||||
|
*/
|
||||||
|
async function generateCodescanningConfig(codeql: CodeQL, config: Config) {
|
||||||
|
if (!(await util.useCodeScanningConfigInCli(codeql))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const configLocation = path.resolve(config.tempDir, "user-config.yaml");
|
||||||
|
// make a copy so we can modify it
|
||||||
|
const augmentedConfig = JSON.parse(JSON.stringify(config.originalUserInput));
|
||||||
|
|
||||||
|
// Inject the queries from the input
|
||||||
|
if (config.augmentationProperties.queriesInput) {
|
||||||
|
if (config.augmentationProperties.queriesInputCombines) {
|
||||||
|
augmentedConfig.queries = (augmentedConfig.queries || []).concat(
|
||||||
|
config.augmentationProperties.queriesInput
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
augmentedConfig.queries = config.augmentationProperties.queriesInput;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (augmentedConfig.queries?.length === 0) {
|
||||||
|
delete augmentedConfig.queries;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inject the packs from the input
|
||||||
|
if (config.augmentationProperties.packsInput) {
|
||||||
|
if (config.augmentationProperties.packsInputCombines) {
|
||||||
|
// At this point, we already know that this is a single-language analysis
|
||||||
|
if (Array.isArray(augmentedConfig.packs)) {
|
||||||
|
augmentedConfig.packs = (augmentedConfig.packs || []).concat(
|
||||||
|
config.augmentationProperties.packsInput
|
||||||
|
);
|
||||||
|
} else if (!augmentedConfig.packs) {
|
||||||
|
augmentedConfig.packs = config.augmentationProperties.packsInput;
|
||||||
|
} else {
|
||||||
|
// At this point, we know there is only one language.
|
||||||
|
// If there were more than one language, an error would already have been thrown.
|
||||||
|
const language = Object.keys(augmentedConfig.packs)[0];
|
||||||
|
augmentedConfig.packs[language] = augmentedConfig.packs[
|
||||||
|
language
|
||||||
|
].concat(config.augmentationProperties.packsInput);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
augmentedConfig.packs = config.augmentationProperties.packsInput;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Array.isArray(augmentedConfig.packs) && !augmentedConfig.packs.length) {
|
||||||
|
delete augmentedConfig.packs;
|
||||||
|
}
|
||||||
|
if (config.augmentationProperties.injectedMlQueries) {
|
||||||
|
// We need to inject the ML queries into the original user input before
|
||||||
|
// we pass this on to the CLI, to make sure these get run.
|
||||||
|
const packString = await util.getMlPoweredJsQueriesPack(codeql);
|
||||||
|
|
||||||
|
if (augmentedConfig.packs === undefined) augmentedConfig.packs = [];
|
||||||
|
if (Array.isArray(augmentedConfig.packs)) {
|
||||||
|
augmentedConfig.packs.push(packString);
|
||||||
|
} else {
|
||||||
|
if (!augmentedConfig.packs.javascript)
|
||||||
|
augmentedConfig.packs["javascript"] = [];
|
||||||
|
augmentedConfig.packs["javascript"].push(packString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(configLocation, yaml.dump(augmentedConfig));
|
||||||
|
return configLocation;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,9 @@ test("loading config saves config", async (t) => {
|
||||||
const config2 = await configUtils.getConfig(tmpDir, logger);
|
const config2 = await configUtils.getConfig(tmpDir, logger);
|
||||||
t.not(config2, undefined);
|
t.not(config2, undefined);
|
||||||
if (config2 !== undefined) {
|
if (config2 !== undefined) {
|
||||||
t.deepEqual(config1, config2);
|
// removes properties assigned to undefined.
|
||||||
|
const expectedConfig = JSON.parse(JSON.stringify(config1));
|
||||||
|
t.deepEqual(expectedConfig, config2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -356,7 +358,13 @@ test("load non-empty input", async (t) => {
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: "my-artifact",
|
debugArtifactName: "my-artifact",
|
||||||
debugDatabaseName: "my-db",
|
debugDatabaseName: "my-db",
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
packsInput: undefined,
|
||||||
|
queriesInput: undefined,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const languages = "javascript";
|
const languages = "javascript";
|
||||||
|
|
@ -1598,6 +1606,7 @@ function parseInputAndConfigMacro(
|
||||||
configUtils.parsePacks(
|
configUtils.parsePacks(
|
||||||
packsFromConfig,
|
packsFromConfig,
|
||||||
packsFromInput,
|
packsFromInput,
|
||||||
|
!!packsFromInput?.trim().startsWith("+"),
|
||||||
languages,
|
languages,
|
||||||
"/a/b",
|
"/a/b",
|
||||||
mockLogger
|
mockLogger
|
||||||
|
|
@ -1619,6 +1628,7 @@ function parseInputAndConfigErrorMacro(
|
||||||
packsFromConfig: string[] | Record<string, string[]>,
|
packsFromConfig: string[] | Record<string, string[]>,
|
||||||
packsFromInput: string | undefined,
|
packsFromInput: string | undefined,
|
||||||
languages: Language[],
|
languages: Language[],
|
||||||
|
packsFromInputOverride: boolean,
|
||||||
expected: RegExp
|
expected: RegExp
|
||||||
) {
|
) {
|
||||||
t.throws(
|
t.throws(
|
||||||
|
|
@ -1626,6 +1636,7 @@ function parseInputAndConfigErrorMacro(
|
||||||
configUtils.parsePacks(
|
configUtils.parsePacks(
|
||||||
packsFromConfig,
|
packsFromConfig,
|
||||||
packsFromInput,
|
packsFromInput,
|
||||||
|
packsFromInputOverride,
|
||||||
languages,
|
languages,
|
||||||
"/a/b",
|
"/a/b",
|
||||||
mockLogger
|
mockLogger
|
||||||
|
|
@ -1704,6 +1715,7 @@ test(
|
||||||
{},
|
{},
|
||||||
"c/d",
|
"c/d",
|
||||||
[],
|
[],
|
||||||
|
false,
|
||||||
/No languages specified/
|
/No languages specified/
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1713,6 +1725,7 @@ test(
|
||||||
{},
|
{},
|
||||||
"c/d",
|
"c/d",
|
||||||
[Language.cpp, Language.csharp],
|
[Language.cpp, Language.csharp],
|
||||||
|
false,
|
||||||
/multi-language analysis/
|
/multi-language analysis/
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1722,6 +1735,7 @@ test(
|
||||||
{},
|
{},
|
||||||
" + ",
|
" + ",
|
||||||
[Language.cpp],
|
[Language.cpp],
|
||||||
|
true,
|
||||||
/remove the '\+'/
|
/remove the '\+'/
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1731,6 +1745,7 @@ test(
|
||||||
{},
|
{},
|
||||||
" xxx",
|
" xxx",
|
||||||
[Language.cpp],
|
[Language.cpp],
|
||||||
|
false,
|
||||||
/"xxx" is not a valid pack/
|
/"xxx" is not a valid pack/
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1910,3 +1925,164 @@ test(
|
||||||
"security-and-quality",
|
"security-and-quality",
|
||||||
"~0.3.0"
|
"~0.3.0"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const calculateAugmentationMacro = test.macro({
|
||||||
|
exec: async (
|
||||||
|
t: ExecutionContext,
|
||||||
|
_title: string,
|
||||||
|
rawPacksInput: string | undefined,
|
||||||
|
rawQueriesInput: string | undefined,
|
||||||
|
languages: Language[],
|
||||||
|
expectedAugmentationProperties: configUtils.AugmentationProperties
|
||||||
|
) => {
|
||||||
|
const actualAugmentationProperties = configUtils.calculateAugmentation(
|
||||||
|
rawPacksInput,
|
||||||
|
rawQueriesInput,
|
||||||
|
languages
|
||||||
|
);
|
||||||
|
t.deepEqual(actualAugmentationProperties, expectedAugmentationProperties);
|
||||||
|
},
|
||||||
|
title: (_, title) => `Calculate Augmentation: ${title}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
calculateAugmentationMacro,
|
||||||
|
"All empty",
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
[Language.javascript],
|
||||||
|
{
|
||||||
|
queriesInputCombines: false,
|
||||||
|
queriesInput: undefined,
|
||||||
|
packsInputCombines: false,
|
||||||
|
packsInput: undefined,
|
||||||
|
injectedMlQueries: false,
|
||||||
|
} as configUtils.AugmentationProperties
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
calculateAugmentationMacro,
|
||||||
|
"With queries",
|
||||||
|
undefined,
|
||||||
|
" a, b , c, d",
|
||||||
|
[Language.javascript],
|
||||||
|
{
|
||||||
|
queriesInputCombines: false,
|
||||||
|
queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }],
|
||||||
|
packsInputCombines: false,
|
||||||
|
packsInput: undefined,
|
||||||
|
injectedMlQueries: false,
|
||||||
|
} as configUtils.AugmentationProperties
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
calculateAugmentationMacro,
|
||||||
|
"With queries combining",
|
||||||
|
undefined,
|
||||||
|
" + a, b , c, d ",
|
||||||
|
[Language.javascript],
|
||||||
|
{
|
||||||
|
queriesInputCombines: true,
|
||||||
|
queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }],
|
||||||
|
packsInputCombines: false,
|
||||||
|
packsInput: undefined,
|
||||||
|
injectedMlQueries: false,
|
||||||
|
} as configUtils.AugmentationProperties
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
calculateAugmentationMacro,
|
||||||
|
"With packs",
|
||||||
|
" codeql/a , codeql/b , codeql/c , codeql/d ",
|
||||||
|
undefined,
|
||||||
|
[Language.javascript],
|
||||||
|
{
|
||||||
|
queriesInputCombines: false,
|
||||||
|
queriesInput: undefined,
|
||||||
|
packsInputCombines: false,
|
||||||
|
packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"],
|
||||||
|
injectedMlQueries: false,
|
||||||
|
} as configUtils.AugmentationProperties
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
calculateAugmentationMacro,
|
||||||
|
"With packs combining",
|
||||||
|
" + codeql/a, codeql/b, codeql/c, codeql/d",
|
||||||
|
undefined,
|
||||||
|
[Language.javascript],
|
||||||
|
{
|
||||||
|
queriesInputCombines: false,
|
||||||
|
queriesInput: undefined,
|
||||||
|
packsInputCombines: true,
|
||||||
|
packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"],
|
||||||
|
injectedMlQueries: false,
|
||||||
|
} as configUtils.AugmentationProperties
|
||||||
|
);
|
||||||
|
|
||||||
|
const calculateAugmentationErrorMacro = test.macro({
|
||||||
|
exec: async (
|
||||||
|
t: ExecutionContext,
|
||||||
|
_title: string,
|
||||||
|
rawPacksInput: string | undefined,
|
||||||
|
rawQueriesInput: string | undefined,
|
||||||
|
languages: Language[],
|
||||||
|
expectedError: RegExp | string
|
||||||
|
) => {
|
||||||
|
t.throws(
|
||||||
|
() =>
|
||||||
|
configUtils.calculateAugmentation(
|
||||||
|
rawPacksInput,
|
||||||
|
rawQueriesInput,
|
||||||
|
languages
|
||||||
|
),
|
||||||
|
{ message: expectedError }
|
||||||
|
);
|
||||||
|
},
|
||||||
|
title: (_, title) => `Calculate Augmentation Error: ${title}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
calculateAugmentationErrorMacro,
|
||||||
|
"Plus (+) with nothing else (queries)",
|
||||||
|
undefined,
|
||||||
|
" + ",
|
||||||
|
[Language.javascript],
|
||||||
|
/The workflow property "queries" is invalid/
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
calculateAugmentationErrorMacro,
|
||||||
|
"Plus (+) with nothing else (packs)",
|
||||||
|
" + ",
|
||||||
|
undefined,
|
||||||
|
[Language.javascript],
|
||||||
|
/The workflow property "packs" is invalid/
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
calculateAugmentationErrorMacro,
|
||||||
|
"Packs input with multiple languages",
|
||||||
|
" + a/b, c/d ",
|
||||||
|
undefined,
|
||||||
|
[Language.javascript, Language.java],
|
||||||
|
/Cannot specify a 'packs' input in a multi-language analysis/
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
calculateAugmentationErrorMacro,
|
||||||
|
"Packs input with no languages",
|
||||||
|
" + a/b, c/d ",
|
||||||
|
undefined,
|
||||||
|
[],
|
||||||
|
/No languages specified/
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
calculateAugmentationErrorMacro,
|
||||||
|
"Invalid packs",
|
||||||
|
" a-pack-without-a-scope ",
|
||||||
|
undefined,
|
||||||
|
[Language.javascript],
|
||||||
|
/"a-pack-without-a-scope" is not a valid pack/
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,39 @@ export interface Config {
|
||||||
* Specifies the name of the database in the debugging artifact.
|
* Specifies the name of the database in the debugging artifact.
|
||||||
*/
|
*/
|
||||||
debugDatabaseName: string;
|
debugDatabaseName: string;
|
||||||
|
|
||||||
|
augmentationProperties: AugmentationProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes how to augment the user config with inputs from the action.
|
||||||
|
*
|
||||||
|
* When running a CodeQL analysis, the user can supply a config file. When
|
||||||
|
* running a CodeQL analysis from a GitHub action, the user can supply a
|
||||||
|
* config file _and_ a set of inputs.
|
||||||
|
*
|
||||||
|
* The inputs from the action are used to augment the user config before
|
||||||
|
* passing the user config to the CodeQL CLI invocation.
|
||||||
|
*/
|
||||||
|
export interface AugmentationProperties {
|
||||||
|
/**
|
||||||
|
* Whether or not the queries input combines with the queries in the config.
|
||||||
|
*/
|
||||||
|
queriesInputCombines: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The queries input from the `with` block of the action declaration
|
||||||
|
*/
|
||||||
|
queriesInput?: Array<{ uses: string }>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the packs input combines with the packs in the config.
|
||||||
|
*/
|
||||||
|
packsInputCombines: boolean;
|
||||||
|
/**
|
||||||
|
* The packs input from the `with` block of the action declaration
|
||||||
|
*/
|
||||||
|
packsInput?: string[];
|
||||||
/**
|
/**
|
||||||
* Whether we injected ML queries into this configuration.
|
* Whether we injected ML queries into this configuration.
|
||||||
*/
|
*/
|
||||||
|
|
@ -880,8 +913,8 @@ function shouldAddConfigFileQueries(queriesInput: string | undefined): boolean {
|
||||||
*/
|
*/
|
||||||
export async function getDefaultConfig(
|
export async function getDefaultConfig(
|
||||||
languagesInput: string | undefined,
|
languagesInput: string | undefined,
|
||||||
queriesInput: string | undefined,
|
rawQueriesInput: string | undefined,
|
||||||
packsInput: string | undefined,
|
rawPacksInput: string | undefined,
|
||||||
dbLocation: string | undefined,
|
dbLocation: string | undefined,
|
||||||
debugMode: boolean,
|
debugMode: boolean,
|
||||||
debugArtifactName: string,
|
debugArtifactName: string,
|
||||||
|
|
@ -911,21 +944,30 @@ export async function getDefaultConfig(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
await addDefaultQueries(codeQL, languages, queries);
|
await addDefaultQueries(codeQL, languages, queries);
|
||||||
const packs = parsePacksFromInput(packsInput, languages) ?? {};
|
const augmentationProperties = calculateAugmentation(
|
||||||
let injectedMlQueries = false;
|
rawPacksInput,
|
||||||
if (queriesInput) {
|
rawQueriesInput,
|
||||||
injectedMlQueries = await addQueriesAndPacksFromWorkflow(
|
languages
|
||||||
codeQL,
|
);
|
||||||
queriesInput,
|
const packs = augmentationProperties.packsInput
|
||||||
languages,
|
? {
|
||||||
queries,
|
[languages[0]]: augmentationProperties.packsInput,
|
||||||
packs,
|
}
|
||||||
tempDir,
|
: {};
|
||||||
workspacePath,
|
if (rawQueriesInput) {
|
||||||
apiDetails,
|
augmentationProperties.injectedMlQueries =
|
||||||
featureFlags,
|
await addQueriesAndPacksFromWorkflow(
|
||||||
logger
|
codeQL,
|
||||||
);
|
rawQueriesInput,
|
||||||
|
languages,
|
||||||
|
queries,
|
||||||
|
packs,
|
||||||
|
tempDir,
|
||||||
|
workspacePath,
|
||||||
|
apiDetails,
|
||||||
|
featureFlags,
|
||||||
|
logger
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -943,7 +985,7 @@ export async function getDefaultConfig(
|
||||||
debugMode,
|
debugMode,
|
||||||
debugArtifactName,
|
debugArtifactName,
|
||||||
debugDatabaseName,
|
debugDatabaseName,
|
||||||
injectedMlQueries,
|
augmentationProperties,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -952,8 +994,8 @@ export async function getDefaultConfig(
|
||||||
*/
|
*/
|
||||||
async function loadConfig(
|
async function loadConfig(
|
||||||
languagesInput: string | undefined,
|
languagesInput: string | undefined,
|
||||||
queriesInput: string | undefined,
|
rawQueriesInput: string | undefined,
|
||||||
packsInput: string | undefined,
|
rawPacksInput: string | undefined,
|
||||||
configFile: string,
|
configFile: string,
|
||||||
dbLocation: string | undefined,
|
dbLocation: string | undefined,
|
||||||
debugMode: boolean,
|
debugMode: boolean,
|
||||||
|
|
@ -1018,10 +1060,15 @@ async function loadConfig(
|
||||||
if (!disableDefaultQueries) {
|
if (!disableDefaultQueries) {
|
||||||
await addDefaultQueries(codeQL, languages, queries);
|
await addDefaultQueries(codeQL, languages, queries);
|
||||||
}
|
}
|
||||||
|
const augmentationProperties = calculateAugmentation(
|
||||||
|
rawPacksInput,
|
||||||
|
rawQueriesInput,
|
||||||
|
languages
|
||||||
|
);
|
||||||
const packs = parsePacks(
|
const packs = parsePacks(
|
||||||
parsedYAML[PACKS_PROPERTY] ?? {},
|
parsedYAML[PACKS_PROPERTY] ?? {},
|
||||||
packsInput,
|
rawPacksInput,
|
||||||
|
augmentationProperties.packsInputCombines,
|
||||||
languages,
|
languages,
|
||||||
configFile,
|
configFile,
|
||||||
logger
|
logger
|
||||||
|
|
@ -1031,23 +1078,23 @@ async function loadConfig(
|
||||||
// they should take precedence over the queries in the config file
|
// they should take precedence over the queries in the config file
|
||||||
// unless they're prefixed with "+", in which case they supplement those
|
// unless they're prefixed with "+", in which case they supplement those
|
||||||
// in the config file.
|
// in the config file.
|
||||||
let injectedMlQueries = false;
|
if (rawQueriesInput) {
|
||||||
if (queriesInput) {
|
augmentationProperties.injectedMlQueries =
|
||||||
injectedMlQueries = await addQueriesAndPacksFromWorkflow(
|
await addQueriesAndPacksFromWorkflow(
|
||||||
codeQL,
|
codeQL,
|
||||||
queriesInput,
|
rawQueriesInput,
|
||||||
languages,
|
languages,
|
||||||
queries,
|
queries,
|
||||||
packs,
|
packs,
|
||||||
tempDir,
|
tempDir,
|
||||||
workspacePath,
|
workspacePath,
|
||||||
apiDetails,
|
apiDetails,
|
||||||
featureFlags,
|
featureFlags,
|
||||||
logger
|
logger
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
shouldAddConfigFileQueries(queriesInput) &&
|
shouldAddConfigFileQueries(rawQueriesInput) &&
|
||||||
QUERIES_PROPERTY in parsedYAML
|
QUERIES_PROPERTY in parsedYAML
|
||||||
) {
|
) {
|
||||||
const queriesArr = parsedYAML[QUERIES_PROPERTY];
|
const queriesArr = parsedYAML[QUERIES_PROPERTY];
|
||||||
|
|
@ -1125,10 +1172,78 @@ async function loadConfig(
|
||||||
debugMode,
|
debugMode,
|
||||||
debugArtifactName,
|
debugArtifactName,
|
||||||
debugDatabaseName,
|
debugDatabaseName,
|
||||||
injectedMlQueries,
|
augmentationProperties,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates how the codeql config file needs to be augmented before passing
|
||||||
|
* it to the CLI. The reason this is necessary is the codeql-action can be called
|
||||||
|
* with extra inputs from the workflow. These inputs are not part of the config
|
||||||
|
* and the CLI does not know about these inputs so we need to inject them into
|
||||||
|
* the config file sent to the CLI.
|
||||||
|
*
|
||||||
|
* @param rawPacksInput The packs input from the action configuration.
|
||||||
|
* @param rawQueriesInput The queries input from the action configuration.
|
||||||
|
* @param languages The languages that the config file is for. If the packs input
|
||||||
|
* is non-empty, then there must be exactly one language. Otherwise, an
|
||||||
|
* error is thrown.
|
||||||
|
*
|
||||||
|
* @returns The properties that need to be augmented in the config file.
|
||||||
|
*
|
||||||
|
* @throws An error if the packs input is non-empty and the languages input does
|
||||||
|
* not have exactly one language.
|
||||||
|
*/
|
||||||
|
// exported for testing.
|
||||||
|
export function calculateAugmentation(
|
||||||
|
rawPacksInput: string | undefined,
|
||||||
|
rawQueriesInput: string | undefined,
|
||||||
|
languages: Language[]
|
||||||
|
): AugmentationProperties {
|
||||||
|
const packsInputCombines = shouldCombine(rawPacksInput);
|
||||||
|
const packsInput = parsePacksFromInput(
|
||||||
|
rawPacksInput,
|
||||||
|
languages,
|
||||||
|
packsInputCombines
|
||||||
|
);
|
||||||
|
const queriesInputCombines = shouldCombine(rawQueriesInput);
|
||||||
|
const queriesInput = parseQueriesFromInput(
|
||||||
|
rawQueriesInput,
|
||||||
|
queriesInputCombines
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
injectedMlQueries: false, // filled in later
|
||||||
|
packsInputCombines,
|
||||||
|
packsInput: packsInput?.[languages[0]],
|
||||||
|
queriesInput,
|
||||||
|
queriesInputCombines,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseQueriesFromInput(
|
||||||
|
rawQueriesInput: string | undefined,
|
||||||
|
queriesInputCombines: boolean
|
||||||
|
) {
|
||||||
|
if (!rawQueriesInput) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const trimmedInput = queriesInputCombines
|
||||||
|
? rawQueriesInput.trim().slice(1).trim()
|
||||||
|
: rawQueriesInput?.trim();
|
||||||
|
if (queriesInputCombines && trimmedInput.length === 0) {
|
||||||
|
throw new Error(
|
||||||
|
getConfigFilePropertyError(
|
||||||
|
undefined,
|
||||||
|
"queries",
|
||||||
|
"A '+' was used in the 'queries' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs."
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return trimmedInput.split(",").map((query) => ({ uses: query.trim() }));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pack names must be in the form of `scope/name`, with only alpha-numeric characters,
|
* Pack names must be in the form of `scope/name`, with only alpha-numeric characters,
|
||||||
* and `-` allowed as long as not the first or last char.
|
* and `-` allowed as long as not the first or last char.
|
||||||
|
|
@ -1187,10 +1302,11 @@ export function parsePacksFromConfig(
|
||||||
}
|
}
|
||||||
|
|
||||||
function parsePacksFromInput(
|
function parsePacksFromInput(
|
||||||
packsInput: string | undefined,
|
rawPacksInput: string | undefined,
|
||||||
languages: Language[]
|
languages: Language[],
|
||||||
|
packsInputCombines: boolean
|
||||||
): Packs | undefined {
|
): Packs | undefined {
|
||||||
if (!packsInput?.trim()) {
|
if (!rawPacksInput?.trim()) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1202,19 +1318,23 @@ function parsePacksFromInput(
|
||||||
throw new Error("No languages specified. Cannot process the packs input.");
|
throw new Error("No languages specified. Cannot process the packs input.");
|
||||||
}
|
}
|
||||||
|
|
||||||
packsInput = packsInput.trim();
|
rawPacksInput = rawPacksInput.trim();
|
||||||
if (packsInput.startsWith("+")) {
|
if (packsInputCombines) {
|
||||||
packsInput = packsInput.substring(1).trim();
|
rawPacksInput = rawPacksInput.trim().substring(1).trim();
|
||||||
if (!packsInput) {
|
if (!rawPacksInput) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"A '+' was used in the 'packs' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs."
|
getConfigFilePropertyError(
|
||||||
|
undefined,
|
||||||
|
"packs",
|
||||||
|
"A '+' was used in the 'packs' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs."
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[languages[0]]: packsInput.split(",").reduce((packs, pack) => {
|
[languages[0]]: rawPacksInput.split(",").reduce((packs, pack) => {
|
||||||
packs.push(validatePacksSpecification(pack, ""));
|
packs.push(validatePacksSpecification(pack));
|
||||||
return packs;
|
return packs;
|
||||||
}, [] as string[]),
|
}, [] as string[]),
|
||||||
};
|
};
|
||||||
|
|
@ -1302,12 +1422,12 @@ export function validatePacksSpecification(
|
||||||
// exported for testing
|
// exported for testing
|
||||||
export function parsePacks(
|
export function parsePacks(
|
||||||
rawPacksFromConfig: string[] | Record<string, string[]>,
|
rawPacksFromConfig: string[] | Record<string, string[]>,
|
||||||
rawPacksInput: string | undefined,
|
rawPacksFromInput: string | undefined,
|
||||||
|
packsInputCombines: boolean,
|
||||||
languages: Language[],
|
languages: Language[],
|
||||||
configFile: string,
|
configFile: string,
|
||||||
logger: Logger
|
logger: Logger
|
||||||
) {
|
): Packs {
|
||||||
const packsFromInput = parsePacksFromInput(rawPacksInput, languages);
|
|
||||||
const packsFomConfig = parsePacksFromConfig(
|
const packsFomConfig = parsePacksFromConfig(
|
||||||
rawPacksFromConfig,
|
rawPacksFromConfig,
|
||||||
languages,
|
languages,
|
||||||
|
|
@ -1315,18 +1435,35 @@ export function parsePacks(
|
||||||
logger
|
logger
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const packsFromInput = parsePacksFromInput(
|
||||||
|
rawPacksFromInput,
|
||||||
|
languages,
|
||||||
|
packsInputCombines
|
||||||
|
);
|
||||||
if (!packsFromInput) {
|
if (!packsFromInput) {
|
||||||
return packsFomConfig;
|
return packsFomConfig;
|
||||||
}
|
}
|
||||||
if (!shouldCombinePacks(rawPacksInput)) {
|
if (!packsInputCombines) {
|
||||||
|
if (!packsFromInput) {
|
||||||
|
throw new Error(getPacksInvalid(configFile));
|
||||||
|
}
|
||||||
return packsFromInput;
|
return packsFromInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
return combinePacks(packsFromInput, packsFomConfig);
|
return combinePacks(packsFromInput, packsFomConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldCombinePacks(packsInput?: string): boolean {
|
/**
|
||||||
return !!packsInput?.trim().startsWith("+");
|
* The convention in this action is that an input value that is prefixed with a '+' will
|
||||||
|
* be combined with the corresponding value in the config file.
|
||||||
|
*
|
||||||
|
* Without a '+', an input value will override the corresponding value in the config file.
|
||||||
|
*
|
||||||
|
* @param inputValue The input value to process.
|
||||||
|
* @returns true if the input value should replace the corresponding value in the config file, false if it should be appended.
|
||||||
|
*/
|
||||||
|
function shouldCombine(inputValue?: string): boolean {
|
||||||
|
return !!inputValue?.trim().startsWith("+");
|
||||||
}
|
}
|
||||||
|
|
||||||
function combinePacks(packs1: Packs, packs2: Packs): Packs {
|
function combinePacks(packs1: Packs, packs2: Packs): Packs {
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,11 @@ function getTestConfig(tmpDir: string): Config {
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,11 @@ function getTestConfig(tmpDir: string): configUtils.Config {
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -347,7 +347,11 @@ for (const [packs, expectedStatus] of ML_POWERED_JS_STATUS_TESTS) {
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
debugArtifactName: util.DEFAULT_DEBUG_ARTIFACT_NAME,
|
||||||
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
debugDatabaseName: util.DEFAULT_DEBUG_DATABASE_NAME,
|
||||||
injectedMlQueries: false,
|
augmentationProperties: {
|
||||||
|
injectedMlQueries: false,
|
||||||
|
packsInputCombines: false,
|
||||||
|
queriesInputCombines: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
t.is(util.getMlPoweredJsQueriesStatus(config), expectedStatus);
|
t.is(util.getMlPoweredJsQueriesStatus(config), expectedStatus);
|
||||||
|
|
|
||||||
27
src/util.ts
27
src/util.ts
|
|
@ -10,7 +10,11 @@ import * as semver from "semver";
|
||||||
import * as api from "./api-client";
|
import * as api from "./api-client";
|
||||||
import { getApiClient, GitHubApiDetails } from "./api-client";
|
import { getApiClient, GitHubApiDetails } from "./api-client";
|
||||||
import * as apiCompatibility from "./api-compatibility.json";
|
import * as apiCompatibility from "./api-compatibility.json";
|
||||||
import { CodeQL, CODEQL_VERSION_NEW_TRACING } from "./codeql";
|
import {
|
||||||
|
CodeQL,
|
||||||
|
CODEQL_VERSION_CONFIG_FILES,
|
||||||
|
CODEQL_VERSION_NEW_TRACING,
|
||||||
|
} from "./codeql";
|
||||||
import { Config } from "./config-utils";
|
import { Config } from "./config-utils";
|
||||||
import { Language } from "./languages";
|
import { Language } from "./languages";
|
||||||
import { Logger } from "./logging";
|
import { Logger } from "./logging";
|
||||||
|
|
@ -510,6 +514,13 @@ enum EnvVar {
|
||||||
* own sandwiched workflow mechanism
|
* own sandwiched workflow mechanism
|
||||||
*/
|
*/
|
||||||
FEATURE_SANDWICH = "CODEQL_ACTION_FEATURE_SANDWICH",
|
FEATURE_SANDWICH = "CODEQL_ACTION_FEATURE_SANDWICH",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set to the "true" string and the codeql CLI version is greater than
|
||||||
|
* `CODEQL_VERSION_CONFIG_FILES`, then the codeql-action will pass the
|
||||||
|
* the codeql-config file to the codeql CLI to be processed there.
|
||||||
|
*/
|
||||||
|
CODEQL_PASS_CONFIG_TO_CLI = "CODEQL_PASS_CONFIG_TO_CLI",
|
||||||
}
|
}
|
||||||
|
|
||||||
const exportVar = (mode: Mode, name: string, value: string) => {
|
const exportVar = (mode: Mode, name: string, value: string) => {
|
||||||
|
|
@ -760,3 +771,17 @@ export async function checkActionVersion(version: string) {
|
||||||
export function isInTestMode(): boolean {
|
export function isInTestMode(): boolean {
|
||||||
return process.env["TEST_MODE"] === "true" || false;
|
return process.env["TEST_MODE"] === "true" || false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns true if the action should generate a conde-scanning config file
|
||||||
|
* that gets passed to the CLI.
|
||||||
|
*/
|
||||||
|
export async function useCodeScanningConfigInCli(
|
||||||
|
codeql: CodeQL
|
||||||
|
): Promise<boolean> {
|
||||||
|
return (
|
||||||
|
(process.env[EnvVar.CODEQL_PASS_CONFIG_TO_CLI] === "true" &&
|
||||||
|
(await codeQlVersionAbove(codeql, CODEQL_VERSION_CONFIG_FILES))) ||
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,6 @@ packs:
|
||||||
- dsp-testing/codeql-pack1@1.0.0
|
- dsp-testing/codeql-pack1@1.0.0
|
||||||
- dsp-testing/codeql-pack2
|
- dsp-testing/codeql-pack2
|
||||||
- dsp-testing/codeql-pack3:other-query.ql
|
- dsp-testing/codeql-pack3:other-query.ql
|
||||||
ruby:
|
|
||||||
- dsp-testing/hucairz
|
|
||||||
- dsp-testing/i-dont-exist@1.0.0
|
|
||||||
|
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- tests
|
- tests
|
||||||
|
|
|
||||||
9
tests/multi-language-repo/.github/codeql/multi-language-packs-config.yml
vendored
Normal file
9
tests/multi-language-repo/.github/codeql/multi-language-packs-config.yml
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
packs:
|
||||||
|
javascript:
|
||||||
|
- dsp-testing/codeql-pack1@1.0.0
|
||||||
|
- dsp-testing/codeql-pack2
|
||||||
|
ruby:
|
||||||
|
- codeql/ruby-queries
|
||||||
|
|
||||||
|
queries:
|
||||||
|
- uses: ./codeql-qlpacks/complex-javascript-qlpack/foo2/show_ifs.ql
|
||||||
9
tests/multi-language-repo/.github/codeql/other-config-properties.yml
vendored
Normal file
9
tests/multi-language-repo/.github/codeql/other-config-properties.yml
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
name: Config using all properties
|
||||||
|
|
||||||
|
disable-default-queries: true
|
||||||
|
|
||||||
|
paths-ignore:
|
||||||
|
- xxx
|
||||||
|
|
||||||
|
paths:
|
||||||
|
- yyy
|
||||||
7
tests/multi-language-repo/.github/codeql/queries-and-packs-config.yml
vendored
Normal file
7
tests/multi-language-repo/.github/codeql/queries-and-packs-config.yml
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
packs:
|
||||||
|
javascript:
|
||||||
|
- dsp-testing/codeql-pack1@1.0.0
|
||||||
|
- dsp-testing/codeql-pack2
|
||||||
|
|
||||||
|
queries:
|
||||||
|
- uses: ./codeql-qlpacks/complex-javascript-qlpack/foo2/show_ifs.ql
|
||||||
Loading…
Add table
Add a link
Reference in a new issue