mirror of
https://github.com/github/codeql-action.git
synced 2026-04-27 09:18:47 +00:00
Merge branch 'main' into mbg/analyze/use-upload-sarif
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
labeling:
|
||||
applyCategoryLabels: true
|
||||
categoryLabelPrefix: "size/"
|
||||
|
||||
commenting:
|
||||
addCommentWhenScoreThresholdHasBeenExceeded: false
|
||||
|
||||
sizeup:
|
||||
categories:
|
||||
- name: extra small
|
||||
lte: 25
|
||||
label:
|
||||
name: XS
|
||||
description: Should be very easy to review
|
||||
color: 3cbf00
|
||||
- name: small
|
||||
lte: 100
|
||||
label:
|
||||
name: S
|
||||
description: Should be easy to review
|
||||
color: 5d9801
|
||||
- name: medium
|
||||
lte: 250
|
||||
label:
|
||||
name: M
|
||||
description: Should be of average difficulty to review
|
||||
color: 7f7203
|
||||
- name: large
|
||||
lte: 500
|
||||
label:
|
||||
name: L
|
||||
description: May be hard to review
|
||||
color: a14c05
|
||||
- name: extra large
|
||||
lte: 1000
|
||||
label:
|
||||
name: XL
|
||||
description: May be very hard to review
|
||||
color: c32607
|
||||
- name: extra extra large
|
||||
label:
|
||||
name: XXL
|
||||
description: May be extremely hard to review
|
||||
color: e50009
|
||||
ignoredFilePatterns:
|
||||
- ".github/workflows/__*"
|
||||
- "lib/**/*"
|
||||
- "package-lock.json"
|
||||
testFilePatterns:
|
||||
- "**/*.test.ts"
|
||||
scoring:
|
||||
# This formula and the aliases below it are written in prefix notation.
|
||||
# For an explanation of how this works, please see:
|
||||
# https://github.com/lerebear/sizeup-core/blob/main/README.md#prefix-notation
|
||||
formula: "- - + additions deletions comments whitespace"
|
||||
+15
@@ -27,6 +27,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
workflow_call:
|
||||
inputs:
|
||||
go-version:
|
||||
@@ -34,6 +39,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
@@ -70,6 +80,11 @@ jobs:
|
||||
with:
|
||||
go-version: ${{ inputs.go-version || '>=1.21.0' }}
|
||||
cache: false
|
||||
- name: Install Python
|
||||
if: matrix.version != 'nightly-latest'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python-version || '3.13' }}
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
|
||||
+2
-3
@@ -67,10 +67,9 @@ jobs:
|
||||
if (allCodeqlVersions.length === 0) {
|
||||
throw new Error(`CodeQL could not be found in the toolcache`);
|
||||
}
|
||||
- id: init
|
||||
uses: ./../action/init
|
||||
- id: setup-codeql
|
||||
uses: ./../action/setup-codeql
|
||||
with:
|
||||
languages: javascript
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
- name: Check CodeQL is installed within the toolcache
|
||||
uses: actions/github-script@v8
|
||||
|
||||
Generated
+1
-1
@@ -49,7 +49,7 @@ jobs:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v5
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v5
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20.x
|
||||
cache: npm
|
||||
|
||||
Generated
+15
@@ -27,6 +27,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
workflow_call:
|
||||
inputs:
|
||||
go-version:
|
||||
@@ -34,6 +39,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
@@ -70,6 +80,11 @@ jobs:
|
||||
with:
|
||||
go-version: ${{ inputs.go-version || '>=1.21.0' }}
|
||||
cache: false
|
||||
- name: Install Python
|
||||
if: matrix.version != 'nightly-latest'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python-version || '3.13' }}
|
||||
- name: Fetch latest CodeQL bundle
|
||||
run: |
|
||||
wget https://github.com/github/codeql-action/releases/latest/download/codeql-bundle-linux64.tar.zst
|
||||
|
||||
+15
@@ -27,6 +27,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
workflow_call:
|
||||
inputs:
|
||||
go-version:
|
||||
@@ -34,6 +39,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
@@ -104,6 +114,11 @@ jobs:
|
||||
with:
|
||||
go-version: ${{ inputs.go-version || '>=1.21.0' }}
|
||||
cache: false
|
||||
- name: Install Python
|
||||
if: matrix.version != 'nightly-latest'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python-version || '3.13' }}
|
||||
- name: Use Xcode 16
|
||||
if: runner.os == 'macOS' && matrix.version != 'nightly-latest'
|
||||
run: sudo xcode-select -s "/Applications/Xcode_16.app"
|
||||
|
||||
+16
-1
@@ -27,6 +27,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
workflow_call:
|
||||
inputs:
|
||||
go-version:
|
||||
@@ -34,6 +39,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
@@ -63,7 +73,7 @@ jobs:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v5
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v5
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20.x
|
||||
cache: npm
|
||||
@@ -81,6 +91,11 @@ jobs:
|
||||
with:
|
||||
go-version: ${{ inputs.go-version || '>=1.21.0' }}
|
||||
cache: false
|
||||
- name: Install Python
|
||||
if: matrix.version != 'nightly-latest'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python-version || '3.13' }}
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
config-file: .github/codeql/codeql-config-packaging3.yml
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ jobs:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v5
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v5
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20.x
|
||||
cache: npm
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ jobs:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v5
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v5
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20.x
|
||||
cache: npm
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ jobs:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v5
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v5
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20.x
|
||||
cache: npm
|
||||
|
||||
Generated
+15
@@ -27,6 +27,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
workflow_call:
|
||||
inputs:
|
||||
go-version:
|
||||
@@ -34,6 +39,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
@@ -72,6 +82,11 @@ jobs:
|
||||
with:
|
||||
go-version: ${{ inputs.go-version || '>=1.21.0' }}
|
||||
cache: false
|
||||
- name: Install Python
|
||||
if: matrix.version != 'nightly-latest'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python-version || '3.13' }}
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
|
||||
+15
@@ -27,6 +27,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
workflow_call:
|
||||
inputs:
|
||||
go-version:
|
||||
@@ -34,6 +39,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
@@ -72,6 +82,11 @@ jobs:
|
||||
with:
|
||||
go-version: ${{ inputs.go-version || '>=1.21.0' }}
|
||||
cache: false
|
||||
- name: Install Python
|
||||
if: matrix.version != 'nightly-latest'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python-version || '3.13' }}
|
||||
- uses: ./../action/init
|
||||
id: init
|
||||
with:
|
||||
|
||||
+15
@@ -27,6 +27,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
workflow_call:
|
||||
inputs:
|
||||
go-version:
|
||||
@@ -34,6 +39,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
@@ -70,6 +80,11 @@ jobs:
|
||||
with:
|
||||
go-version: ${{ inputs.go-version || '>=1.21.0' }}
|
||||
cache: false
|
||||
- name: Install Python
|
||||
if: matrix.version != 'nightly-latest'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python-version || '3.13' }}
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
|
||||
Generated
+15
@@ -27,6 +27,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
workflow_call:
|
||||
inputs:
|
||||
go-version:
|
||||
@@ -34,6 +39,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
@@ -77,6 +87,11 @@ jobs:
|
||||
with:
|
||||
go-version: ${{ inputs.go-version || '>=1.21.0' }}
|
||||
cache: false
|
||||
- name: Install Python
|
||||
if: matrix.version != 'nightly-latest'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python-version || '3.13' }}
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
|
||||
+15
@@ -27,6 +27,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
workflow_call:
|
||||
inputs:
|
||||
go-version:
|
||||
@@ -34,6 +39,11 @@ on:
|
||||
description: The version of Go to install
|
||||
required: false
|
||||
default: '>=1.21.0'
|
||||
python-version:
|
||||
type: string
|
||||
description: The version of Python to install
|
||||
required: false
|
||||
default: '3.13'
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
@@ -70,6 +80,11 @@ jobs:
|
||||
with:
|
||||
go-version: ${{ inputs.go-version || '>=1.21.0' }}
|
||||
cache: false
|
||||
- name: Install Python
|
||||
if: matrix.version != 'nightly-latest'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ inputs.python-version || '3.13' }}
|
||||
- name: Delete original checkout
|
||||
run: |
|
||||
# delete the original checkout so we don't accidentally use it.
|
||||
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v5
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: 'npm'
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
name: Label PR with size
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- edited
|
||||
- ready_for_review
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
sizeup:
|
||||
name: Label PR with size
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Run sizeup
|
||||
uses: lerebear/sizeup-action@b7beb3dd273e36039e16e48e7bc690c189e61951 # 0.8.12
|
||||
with:
|
||||
token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
configuration-file-path: ".github/sizeup.yml"
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0 # ensure we have all tags and can push commits
|
||||
- uses: actions/setup-node@v5
|
||||
- uses: actions/setup-node@v6
|
||||
|
||||
- name: Update git config
|
||||
run: |
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v5
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v5
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: npm
|
||||
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
git config --global user.name "github-actions[bot]"
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v5
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: 'npm'
|
||||
|
||||
@@ -6,6 +6,11 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th
|
||||
|
||||
No user facing changes.
|
||||
|
||||
## 4.30.9 - 17 Oct 2025
|
||||
|
||||
- Update default CodeQL bundle version to 2.23.3. [#3205](https://github.com/github/codeql-action/pull/3205)
|
||||
- Experimental: A new `setup-codeql` action has been added which is similar to `init`, except it only installs the CodeQL CLI and does not initialize a database. Do not use this in production as it is part of an internal experiment and subject to change at any time. [#3204](https://github.com/github/codeql-action/pull/3204)
|
||||
|
||||
## 4.30.8 - 10 Oct 2025
|
||||
|
||||
No user facing changes.
|
||||
|
||||
@@ -34,6 +34,7 @@ Actions with special purposes and unlikely to be used directly:
|
||||
- `autobuild`: Attempts to automatically build the code. Only used for analyzing languages that require a build. Use the `build-mode: autobuild` input in the `init` action instead. For information about input parameters, see the [autobuild action definition](https://github.com/github/codeql-action/blob/main/autobuild/action.yml).
|
||||
- `resolve-environment`: [Experimental] Attempts to infer a build environment suitable for automatic builds. For information about input parameters, see the [resolve-environment action definition](https://github.com/github/codeql-action/blob/main/resolve-environment/action.yml).
|
||||
- `start-proxy`: [Experimental] Start the HTTP proxy server. Internal use only and will change without notice. For information about input parameters, see the [start-proxy action definition](https://github.com/github/codeql-action/blob/main/start-proxy/action.yml).
|
||||
- `setup-codeql`: [Experimental] Similar to `init`, except it only installs the CodeQL CLI and does not initialize a database.
|
||||
|
||||
### Workflow Permissions
|
||||
|
||||
|
||||
Generated
+1327
-21
File diff suppressed because it is too large
Load Diff
Generated
+1403
-1399
File diff suppressed because it is too large
Load Diff
Generated
+1351
-28
File diff suppressed because it is too large
Load Diff
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"bundleVersion": "codeql-bundle-v2.23.2",
|
||||
"cliVersion": "2.23.2",
|
||||
"priorBundleVersion": "codeql-bundle-v2.23.1",
|
||||
"priorCliVersion": "2.23.1"
|
||||
"bundleVersion": "codeql-bundle-v2.23.3",
|
||||
"cliVersion": "2.23.3",
|
||||
"priorBundleVersion": "codeql-bundle-v2.23.2",
|
||||
"priorCliVersion": "2.23.2"
|
||||
}
|
||||
|
||||
Generated
+1413
-1407
File diff suppressed because it is too large
Load Diff
Generated
+1688
-152
File diff suppressed because it is too large
Load Diff
Generated
+1346
-24
File diff suppressed because it is too large
Load Diff
Generated
+88985
File diff suppressed because one or more lines are too long
Generated
+1327
-21
File diff suppressed because it is too large
Load Diff
Generated
+1345
-26
File diff suppressed because it is too large
Load Diff
Generated
+104
-108
@@ -20885,19 +20885,19 @@ var require_validator = __commonJS({
|
||||
var SchemaError = helpers.SchemaError;
|
||||
var SchemaContext = helpers.SchemaContext;
|
||||
var anonymousBase = "/";
|
||||
var Validator2 = function Validator3() {
|
||||
this.customFormats = Object.create(Validator3.prototype.customFormats);
|
||||
var Validator3 = function Validator4() {
|
||||
this.customFormats = Object.create(Validator4.prototype.customFormats);
|
||||
this.schemas = {};
|
||||
this.unresolvedRefs = [];
|
||||
this.types = Object.create(types);
|
||||
this.attributes = Object.create(attribute.validators);
|
||||
};
|
||||
Validator2.prototype.customFormats = {};
|
||||
Validator2.prototype.schemas = null;
|
||||
Validator2.prototype.types = null;
|
||||
Validator2.prototype.attributes = null;
|
||||
Validator2.prototype.unresolvedRefs = null;
|
||||
Validator2.prototype.addSchema = function addSchema(schema2, base) {
|
||||
Validator3.prototype.customFormats = {};
|
||||
Validator3.prototype.schemas = null;
|
||||
Validator3.prototype.types = null;
|
||||
Validator3.prototype.attributes = null;
|
||||
Validator3.prototype.unresolvedRefs = null;
|
||||
Validator3.prototype.addSchema = function addSchema(schema2, base) {
|
||||
var self2 = this;
|
||||
if (!schema2) {
|
||||
return null;
|
||||
@@ -20915,25 +20915,25 @@ var require_validator = __commonJS({
|
||||
});
|
||||
return this.schemas[ourUri];
|
||||
};
|
||||
Validator2.prototype.addSubSchemaArray = function addSubSchemaArray(baseuri, schemas) {
|
||||
Validator3.prototype.addSubSchemaArray = function addSubSchemaArray(baseuri, schemas) {
|
||||
if (!Array.isArray(schemas)) return;
|
||||
for (var i = 0; i < schemas.length; i++) {
|
||||
this.addSubSchema(baseuri, schemas[i]);
|
||||
}
|
||||
};
|
||||
Validator2.prototype.addSubSchemaObject = function addSubSchemaArray(baseuri, schemas) {
|
||||
Validator3.prototype.addSubSchemaObject = function addSubSchemaArray(baseuri, schemas) {
|
||||
if (!schemas || typeof schemas != "object") return;
|
||||
for (var p in schemas) {
|
||||
this.addSubSchema(baseuri, schemas[p]);
|
||||
}
|
||||
};
|
||||
Validator2.prototype.setSchemas = function setSchemas(schemas) {
|
||||
Validator3.prototype.setSchemas = function setSchemas(schemas) {
|
||||
this.schemas = schemas;
|
||||
};
|
||||
Validator2.prototype.getSchema = function getSchema(urn) {
|
||||
Validator3.prototype.getSchema = function getSchema(urn) {
|
||||
return this.schemas[urn];
|
||||
};
|
||||
Validator2.prototype.validate = function validate(instance, schema2, options, ctx) {
|
||||
Validator3.prototype.validate = function validate(instance, schema2, options, ctx) {
|
||||
if (typeof schema2 !== "boolean" && typeof schema2 !== "object" || schema2 === null) {
|
||||
throw new SchemaError("Expected `schema` to be an object or boolean");
|
||||
}
|
||||
@@ -20971,7 +20971,7 @@ var require_validator = __commonJS({
|
||||
if (typeof ref == "string") return ref;
|
||||
return false;
|
||||
}
|
||||
Validator2.prototype.validateSchema = function validateSchema(instance, schema2, options, ctx) {
|
||||
Validator3.prototype.validateSchema = function validateSchema(instance, schema2, options, ctx) {
|
||||
var result = new ValidatorResult(instance, schema2, options, ctx);
|
||||
if (typeof schema2 === "boolean") {
|
||||
if (schema2 === true) {
|
||||
@@ -21021,17 +21021,17 @@ var require_validator = __commonJS({
|
||||
}
|
||||
return result;
|
||||
};
|
||||
Validator2.prototype.schemaTraverser = function schemaTraverser(schemaobj, s) {
|
||||
Validator3.prototype.schemaTraverser = function schemaTraverser(schemaobj, s) {
|
||||
schemaobj.schema = helpers.deepMerge(schemaobj.schema, this.superResolve(s, schemaobj.ctx));
|
||||
};
|
||||
Validator2.prototype.superResolve = function superResolve(schema2, ctx) {
|
||||
Validator3.prototype.superResolve = function superResolve(schema2, ctx) {
|
||||
var ref = shouldResolve(schema2);
|
||||
if (ref) {
|
||||
return this.resolve(schema2, ref, ctx).subschema;
|
||||
}
|
||||
return schema2;
|
||||
};
|
||||
Validator2.prototype.resolve = function resolve6(schema2, switchSchema, ctx) {
|
||||
Validator3.prototype.resolve = function resolve6(schema2, switchSchema, ctx) {
|
||||
switchSchema = ctx.resolve(switchSchema);
|
||||
if (ctx.schemas[switchSchema]) {
|
||||
return { subschema: ctx.schemas[switchSchema], switchSchema };
|
||||
@@ -21048,7 +21048,7 @@ var require_validator = __commonJS({
|
||||
}
|
||||
return { subschema, switchSchema };
|
||||
};
|
||||
Validator2.prototype.testType = function validateType(instance, schema2, options, ctx, type2) {
|
||||
Validator3.prototype.testType = function validateType(instance, schema2, options, ctx, type2) {
|
||||
if (type2 === void 0) {
|
||||
return;
|
||||
} else if (type2 === null) {
|
||||
@@ -21063,7 +21063,7 @@ var require_validator = __commonJS({
|
||||
}
|
||||
return true;
|
||||
};
|
||||
var types = Validator2.prototype.types = {};
|
||||
var types = Validator3.prototype.types = {};
|
||||
types.string = function testString(instance) {
|
||||
return typeof instance == "string";
|
||||
};
|
||||
@@ -21091,7 +21091,7 @@ var require_validator = __commonJS({
|
||||
types.object = function testObject(instance) {
|
||||
return instance && typeof instance === "object" && !Array.isArray(instance) && !(instance instanceof Date);
|
||||
};
|
||||
module2.exports = Validator2;
|
||||
module2.exports = Validator3;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -21099,7 +21099,7 @@ var require_validator = __commonJS({
|
||||
var require_lib2 = __commonJS({
|
||||
"node_modules/jsonschema/lib/index.js"(exports2, module2) {
|
||||
"use strict";
|
||||
var Validator2 = module2.exports.Validator = require_validator();
|
||||
var Validator3 = module2.exports.Validator = require_validator();
|
||||
module2.exports.ValidatorResult = require_helpers().ValidatorResult;
|
||||
module2.exports.ValidatorResultError = require_helpers().ValidatorResultError;
|
||||
module2.exports.ValidationError = require_helpers().ValidationError;
|
||||
@@ -21107,7 +21107,7 @@ var require_lib2 = __commonJS({
|
||||
module2.exports.SchemaScanResult = require_scan().SchemaScanResult;
|
||||
module2.exports.scan = require_scan().scan;
|
||||
module2.exports.validate = function(instance, schema2, options) {
|
||||
var v = new Validator2();
|
||||
var v = new Validator3();
|
||||
return v.validate(instance, schema2, options);
|
||||
};
|
||||
}
|
||||
@@ -21899,14 +21899,14 @@ var require_dist_node4 = __commonJS({
|
||||
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
||||
var dist_src_exports = {};
|
||||
__export2(dist_src_exports, {
|
||||
RequestError: () => RequestError2
|
||||
RequestError: () => RequestError
|
||||
});
|
||||
module2.exports = __toCommonJS2(dist_src_exports);
|
||||
var import_deprecation = require_dist_node3();
|
||||
var import_once = __toESM2(require_once());
|
||||
var logOnceCode = (0, import_once.default)((deprecation) => console.warn(deprecation));
|
||||
var logOnceHeaders = (0, import_once.default)((deprecation) => console.warn(deprecation));
|
||||
var RequestError2 = class extends Error {
|
||||
var RequestError = class extends Error {
|
||||
constructor(message, statusCode, options) {
|
||||
super(message);
|
||||
if (Error.captureStackTrace) {
|
||||
@@ -21998,7 +21998,7 @@ var require_dist_node5 = __commonJS({
|
||||
const Ctor = Object.prototype.hasOwnProperty.call(proto, "constructor") && proto.constructor;
|
||||
return typeof Ctor === "function" && Ctor instanceof Ctor && Function.prototype.call(Ctor) === Function.prototype.call(value);
|
||||
}
|
||||
var import_request_error2 = require_dist_node4();
|
||||
var import_request_error = require_dist_node4();
|
||||
function getBufferResponse(response) {
|
||||
return response.arrayBuffer();
|
||||
}
|
||||
@@ -22050,7 +22050,7 @@ var require_dist_node5 = __commonJS({
|
||||
if (status < 400) {
|
||||
return;
|
||||
}
|
||||
throw new import_request_error2.RequestError(response.statusText, status, {
|
||||
throw new import_request_error.RequestError(response.statusText, status, {
|
||||
response: {
|
||||
url: url2,
|
||||
status,
|
||||
@@ -22061,7 +22061,7 @@ var require_dist_node5 = __commonJS({
|
||||
});
|
||||
}
|
||||
if (status === 304) {
|
||||
throw new import_request_error2.RequestError("Not modified", status, {
|
||||
throw new import_request_error.RequestError("Not modified", status, {
|
||||
response: {
|
||||
url: url2,
|
||||
status,
|
||||
@@ -22073,7 +22073,7 @@ var require_dist_node5 = __commonJS({
|
||||
}
|
||||
if (status >= 400) {
|
||||
const data = await getResponseData(response);
|
||||
const error2 = new import_request_error2.RequestError(toErrorMessage(data), status, {
|
||||
const error2 = new import_request_error.RequestError(toErrorMessage(data), status, {
|
||||
response: {
|
||||
url: url2,
|
||||
status,
|
||||
@@ -22093,7 +22093,7 @@ var require_dist_node5 = __commonJS({
|
||||
data
|
||||
};
|
||||
}).catch((error2) => {
|
||||
if (error2 instanceof import_request_error2.RequestError)
|
||||
if (error2 instanceof import_request_error.RequestError)
|
||||
throw error2;
|
||||
else if (error2.name === "AbortError")
|
||||
throw error2;
|
||||
@@ -22105,7 +22105,7 @@ var require_dist_node5 = __commonJS({
|
||||
message = error2.cause;
|
||||
}
|
||||
}
|
||||
throw new import_request_error2.RequestError(message, 500, {
|
||||
throw new import_request_error.RequestError(message, 500, {
|
||||
request: requestOptions
|
||||
});
|
||||
});
|
||||
@@ -22547,14 +22547,14 @@ var require_dist_node7 = __commonJS({
|
||||
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
||||
var dist_src_exports = {};
|
||||
__export2(dist_src_exports, {
|
||||
RequestError: () => RequestError2
|
||||
RequestError: () => RequestError
|
||||
});
|
||||
module2.exports = __toCommonJS2(dist_src_exports);
|
||||
var import_deprecation = require_dist_node3();
|
||||
var import_once = __toESM2(require_once());
|
||||
var logOnceCode = (0, import_once.default)((deprecation) => console.warn(deprecation));
|
||||
var logOnceHeaders = (0, import_once.default)((deprecation) => console.warn(deprecation));
|
||||
var RequestError2 = class extends Error {
|
||||
var RequestError = class extends Error {
|
||||
constructor(message, statusCode, options) {
|
||||
super(message);
|
||||
if (Error.captureStackTrace) {
|
||||
@@ -22646,7 +22646,7 @@ var require_dist_node8 = __commonJS({
|
||||
const Ctor = Object.prototype.hasOwnProperty.call(proto, "constructor") && proto.constructor;
|
||||
return typeof Ctor === "function" && Ctor instanceof Ctor && Function.prototype.call(Ctor) === Function.prototype.call(value);
|
||||
}
|
||||
var import_request_error2 = require_dist_node7();
|
||||
var import_request_error = require_dist_node7();
|
||||
function getBufferResponse(response) {
|
||||
return response.arrayBuffer();
|
||||
}
|
||||
@@ -22698,7 +22698,7 @@ var require_dist_node8 = __commonJS({
|
||||
if (status < 400) {
|
||||
return;
|
||||
}
|
||||
throw new import_request_error2.RequestError(response.statusText, status, {
|
||||
throw new import_request_error.RequestError(response.statusText, status, {
|
||||
response: {
|
||||
url: url2,
|
||||
status,
|
||||
@@ -22709,7 +22709,7 @@ var require_dist_node8 = __commonJS({
|
||||
});
|
||||
}
|
||||
if (status === 304) {
|
||||
throw new import_request_error2.RequestError("Not modified", status, {
|
||||
throw new import_request_error.RequestError("Not modified", status, {
|
||||
response: {
|
||||
url: url2,
|
||||
status,
|
||||
@@ -22721,7 +22721,7 @@ var require_dist_node8 = __commonJS({
|
||||
}
|
||||
if (status >= 400) {
|
||||
const data = await getResponseData(response);
|
||||
const error2 = new import_request_error2.RequestError(toErrorMessage(data), status, {
|
||||
const error2 = new import_request_error.RequestError(toErrorMessage(data), status, {
|
||||
response: {
|
||||
url: url2,
|
||||
status,
|
||||
@@ -22741,7 +22741,7 @@ var require_dist_node8 = __commonJS({
|
||||
data
|
||||
};
|
||||
}).catch((error2) => {
|
||||
if (error2 instanceof import_request_error2.RequestError)
|
||||
if (error2 instanceof import_request_error.RequestError)
|
||||
throw error2;
|
||||
else if (error2.name === "AbortError")
|
||||
throw error2;
|
||||
@@ -22753,7 +22753,7 @@ var require_dist_node8 = __commonJS({
|
||||
message = error2.cause;
|
||||
}
|
||||
}
|
||||
throw new import_request_error2.RequestError(message, 500, {
|
||||
throw new import_request_error.RequestError(message, 500, {
|
||||
request: requestOptions
|
||||
});
|
||||
});
|
||||
@@ -33606,7 +33606,7 @@ var require_package = __commonJS({
|
||||
"package.json"(exports2, module2) {
|
||||
module2.exports = {
|
||||
name: "codeql",
|
||||
version: "4.30.9",
|
||||
version: "4.30.10",
|
||||
private: true,
|
||||
description: "CodeQL action",
|
||||
scripts: {
|
||||
@@ -33654,7 +33654,7 @@ var require_package = __commonJS({
|
||||
jsonschema: "1.4.1",
|
||||
long: "^5.3.2",
|
||||
"node-forge": "^1.3.1",
|
||||
octokit: "^5.0.3",
|
||||
octokit: "^5.0.4",
|
||||
semver: "^7.7.3",
|
||||
uuid: "^13.0.0"
|
||||
},
|
||||
@@ -33662,7 +33662,7 @@ var require_package = __commonJS({
|
||||
"@ava/typescript": "6.0.0",
|
||||
"@eslint/compat": "^1.4.0",
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@eslint/js": "^9.37.0",
|
||||
"@eslint/js": "^9.38.0",
|
||||
"@microsoft/eslint-formatter-sarif": "^3.1.0",
|
||||
"@octokit/types": "^15.0.0",
|
||||
"@types/archiver": "^6.0.3",
|
||||
@@ -33673,10 +33673,10 @@ var require_package = __commonJS({
|
||||
"@types/node-forge": "^1.3.14",
|
||||
"@types/semver": "^7.7.1",
|
||||
"@types/sinon": "^17.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^8.46.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.46.1",
|
||||
"@typescript-eslint/parser": "^8.41.0",
|
||||
ava: "^6.4.1",
|
||||
esbuild: "^0.25.10",
|
||||
esbuild: "^0.25.11",
|
||||
eslint: "^8.57.1",
|
||||
"eslint-import-resolver-typescript": "^3.8.7",
|
||||
"eslint-plugin-filenames": "^1.3.2",
|
||||
@@ -35065,14 +35065,14 @@ var require_dist_node14 = __commonJS({
|
||||
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
||||
var dist_src_exports = {};
|
||||
__export2(dist_src_exports, {
|
||||
RequestError: () => RequestError2
|
||||
RequestError: () => RequestError
|
||||
});
|
||||
module2.exports = __toCommonJS2(dist_src_exports);
|
||||
var import_deprecation = require_dist_node3();
|
||||
var import_once = __toESM2(require_once());
|
||||
var logOnceCode = (0, import_once.default)((deprecation) => console.warn(deprecation));
|
||||
var logOnceHeaders = (0, import_once.default)((deprecation) => console.warn(deprecation));
|
||||
var RequestError2 = class extends Error {
|
||||
var RequestError = class extends Error {
|
||||
constructor(message, statusCode, options) {
|
||||
super(message);
|
||||
if (Error.captureStackTrace) {
|
||||
@@ -35174,7 +35174,7 @@ var require_dist_node15 = __commonJS({
|
||||
throw error2;
|
||||
}
|
||||
var import_light = __toESM2(require_light());
|
||||
var import_request_error2 = require_dist_node14();
|
||||
var import_request_error = require_dist_node14();
|
||||
async function wrapRequest(state, octokit, request, options) {
|
||||
const limiter = new import_light.default();
|
||||
limiter.on("failed", function(error2, info4) {
|
||||
@@ -35195,7 +35195,7 @@ var require_dist_node15 = __commonJS({
|
||||
if (response.data && response.data.errors && response.data.errors.length > 0 && /Something went wrong while executing your query/.test(
|
||||
response.data.errors[0].message
|
||||
)) {
|
||||
const error2 = new import_request_error2.RequestError(response.data.errors[0].message, 500, {
|
||||
const error2 = new import_request_error.RequestError(response.data.errors[0].message, 500, {
|
||||
request: options,
|
||||
response
|
||||
});
|
||||
@@ -80921,14 +80921,14 @@ var require_tool_cache = __commonJS({
|
||||
var assert_1 = require("assert");
|
||||
var exec_1 = require_exec();
|
||||
var retry_helper_1 = require_retry_helper();
|
||||
var HTTPError = class extends Error {
|
||||
var HTTPError2 = class extends Error {
|
||||
constructor(httpStatusCode) {
|
||||
super(`Unexpected HTTP response: ${httpStatusCode}`);
|
||||
this.httpStatusCode = httpStatusCode;
|
||||
Object.setPrototypeOf(this, new.target.prototype);
|
||||
}
|
||||
};
|
||||
exports2.HTTPError = HTTPError;
|
||||
exports2.HTTPError = HTTPError2;
|
||||
var IS_WINDOWS = process.platform === "win32";
|
||||
var IS_MAC = process.platform === "darwin";
|
||||
var userAgent = "actions/tool-cache";
|
||||
@@ -80945,7 +80945,7 @@ var require_tool_cache = __commonJS({
|
||||
return yield retryHelper.execute(() => __awaiter4(this, void 0, void 0, function* () {
|
||||
return yield downloadToolAttempt(url2, dest || "", auth, headers);
|
||||
}), (err) => {
|
||||
if (err instanceof HTTPError && err.httpStatusCode) {
|
||||
if (err instanceof HTTPError2 && err.httpStatusCode) {
|
||||
if (err.httpStatusCode < 500 && err.httpStatusCode !== 408 && err.httpStatusCode !== 429) {
|
||||
return false;
|
||||
}
|
||||
@@ -80972,7 +80972,7 @@ var require_tool_cache = __commonJS({
|
||||
}
|
||||
const response = yield http.get(url2, headers);
|
||||
if (response.message.statusCode !== 200) {
|
||||
const err = new HTTPError(response.message.statusCode);
|
||||
const err = new HTTPError2(response.message.statusCode);
|
||||
core12.debug(`Failed to download from "${url2}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`);
|
||||
throw err;
|
||||
}
|
||||
@@ -84865,7 +84865,7 @@ var path14 = __toESM(require("path"));
|
||||
var url = __toESM(require("url"));
|
||||
var import_zlib = __toESM(require("zlib"));
|
||||
var core11 = __toESM(require_core());
|
||||
var jsonschema = __toESM(require_lib2());
|
||||
var jsonschema2 = __toESM(require_lib2());
|
||||
|
||||
// src/actions-util.ts
|
||||
var fs4 = __toESM(require("fs"));
|
||||
@@ -88328,13 +88328,28 @@ function getRequiredEnvParam(paramName) {
|
||||
}
|
||||
return value;
|
||||
}
|
||||
var HTTPError = class extends Error {
|
||||
constructor(message, status) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
}
|
||||
};
|
||||
var ConfigurationError = class extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
}
|
||||
};
|
||||
function isHTTPError(arg) {
|
||||
return arg?.status !== void 0 && Number.isInteger(arg.status);
|
||||
function asHTTPError(arg) {
|
||||
if (typeof arg !== "object" || arg === null || typeof arg.message !== "string") {
|
||||
return void 0;
|
||||
}
|
||||
if (Number.isInteger(arg.status)) {
|
||||
return new HTTPError(arg.message, arg.status);
|
||||
}
|
||||
if (Number.isInteger(arg.httpStatusCode)) {
|
||||
return new HTTPError(arg.message, arg.httpStatusCode);
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
var cachedCodeQlVersion = void 0;
|
||||
function cacheCodeQlVersion(version) {
|
||||
@@ -88747,14 +88762,24 @@ function computeAutomationID(analysis_key, environment) {
|
||||
return automationID;
|
||||
}
|
||||
function wrapApiConfigurationError(e) {
|
||||
if (isHTTPError(e)) {
|
||||
if (e.message.includes("API rate limit exceeded for installation") || e.message.includes("commit not found") || e.message.includes("Resource not accessible by integration") || /ref .* not found in this repository/.test(e.message)) {
|
||||
return new ConfigurationError(e.message);
|
||||
} else if (e.message.includes("Bad credentials") || e.message.includes("Not Found")) {
|
||||
const httpError = asHTTPError(e);
|
||||
if (httpError !== void 0) {
|
||||
if ([
|
||||
/API rate limit exceeded/,
|
||||
/commit not found/,
|
||||
/Resource not accessible by integration/,
|
||||
/ref .* not found in this repository/
|
||||
].some((pattern) => pattern.test(httpError.message))) {
|
||||
return new ConfigurationError(httpError.message);
|
||||
}
|
||||
if (httpError.message.includes("Bad credentials") || httpError.message.includes("Not Found")) {
|
||||
return new ConfigurationError(
|
||||
"Please check that your token is valid and has the required permissions: contents: read, security-events: write"
|
||||
);
|
||||
}
|
||||
if (httpError.status === 429) {
|
||||
return new ConfigurationError("API rate limit exceeded");
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
@@ -88765,45 +88790,6 @@ var path12 = __toESM(require("path"));
|
||||
var core10 = __toESM(require_core());
|
||||
var toolrunner3 = __toESM(require_toolrunner());
|
||||
|
||||
// node_modules/@octokit/request-error/dist-src/index.js
|
||||
var RequestError = class extends Error {
|
||||
name;
|
||||
/**
|
||||
* http status code
|
||||
*/
|
||||
status;
|
||||
/**
|
||||
* Request options that lead to the error.
|
||||
*/
|
||||
request;
|
||||
/**
|
||||
* Response object if a response was received
|
||||
*/
|
||||
response;
|
||||
constructor(message, statusCode, options) {
|
||||
super(message);
|
||||
this.name = "HttpError";
|
||||
this.status = Number.parseInt(statusCode);
|
||||
if (Number.isNaN(this.status)) {
|
||||
this.status = 0;
|
||||
}
|
||||
if ("response" in options) {
|
||||
this.response = options.response;
|
||||
}
|
||||
const requestCopy = Object.assign({}, options.request);
|
||||
if (options.request.headers.authorization) {
|
||||
requestCopy.headers = Object.assign({}, options.request.headers, {
|
||||
authorization: options.request.headers.authorization.replace(
|
||||
/(?<! ) .*$/,
|
||||
" [REDACTED]"
|
||||
)
|
||||
});
|
||||
}
|
||||
requestCopy.url = requestCopy.url.replace(/\bclient_secret=\w+/g, "client_secret=[REDACTED]").replace(/\baccess_token=\w+/g, "access_token=[REDACTED]");
|
||||
this.request = requestCopy;
|
||||
}
|
||||
};
|
||||
|
||||
// src/cli-errors.ts
|
||||
var SUPPORTED_PLATFORMS = [
|
||||
["linux", "x64"],
|
||||
@@ -88971,6 +88957,9 @@ var cliErrorsConfig = {
|
||||
cliErrorMessageCandidates: [
|
||||
new RegExp(
|
||||
"Query pack .* cannot be found\\. Check the spelling of the pack\\."
|
||||
),
|
||||
new RegExp(
|
||||
"is not a .ql file, .qls file, a directory, or a query pack specification."
|
||||
)
|
||||
]
|
||||
},
|
||||
@@ -89049,6 +89038,7 @@ var path9 = __toESM(require("path"));
|
||||
var core6 = __toESM(require_core());
|
||||
|
||||
// src/config/db-config.ts
|
||||
var jsonschema = __toESM(require_lib2());
|
||||
var semver2 = __toESM(require_semver2());
|
||||
var PACK_IDENTIFIER_PATTERN = (function() {
|
||||
const alphaNumeric = "[a-z0-9]";
|
||||
@@ -89065,8 +89055,8 @@ var path8 = __toESM(require("path"));
|
||||
var semver4 = __toESM(require_semver2());
|
||||
|
||||
// src/defaults.json
|
||||
var bundleVersion = "codeql-bundle-v2.23.2";
|
||||
var cliVersion = "2.23.2";
|
||||
var bundleVersion = "codeql-bundle-v2.23.3";
|
||||
var cliVersion = "2.23.3";
|
||||
|
||||
// src/overlay-database-utils.ts
|
||||
var fs5 = __toESM(require("fs"));
|
||||
@@ -89530,6 +89520,11 @@ var featureConfig = {
|
||||
defaultValue: false,
|
||||
envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS",
|
||||
minimumVersion: "2.23.0"
|
||||
},
|
||||
["validate_db_config" /* ValidateDbConfig */]: {
|
||||
defaultValue: false,
|
||||
envVar: "CODEQL_ACTION_VALIDATE_DB_CONFIG",
|
||||
minimumVersion: void 0
|
||||
}
|
||||
};
|
||||
|
||||
@@ -90598,9 +90593,9 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV
|
||||
toolsVersion,
|
||||
zstdAvailability
|
||||
};
|
||||
} catch (e) {
|
||||
const ErrorClass = e instanceof ConfigurationError || e instanceof Error && e.message.includes("ENOSPC") || // out of disk space
|
||||
e instanceof RequestError && e.status === 429 ? ConfigurationError : Error;
|
||||
} catch (rawError) {
|
||||
const e = wrapApiConfigurationError(rawError);
|
||||
const ErrorClass = e instanceof ConfigurationError || e instanceof Error && e.message.includes("ENOSPC") ? ConfigurationError : Error;
|
||||
throw new ErrorClass(
|
||||
`Unable to download and extract CodeQL CLI: ${getErrorMessage(e)}${e instanceof Error && e.stack ? `
|
||||
|
||||
@@ -92520,16 +92515,17 @@ async function uploadPayload(payload, repositoryNwo, logger, analysis) {
|
||||
logger.info("Successfully uploaded results");
|
||||
return response.data.id;
|
||||
} catch (e) {
|
||||
if (isHTTPError(e)) {
|
||||
switch (e.status) {
|
||||
const httpError = asHTTPError(e);
|
||||
if (httpError !== void 0) {
|
||||
switch (httpError.status) {
|
||||
case 403:
|
||||
core11.warning(e.message || GENERIC_403_MSG);
|
||||
core11.warning(httpError.message || GENERIC_403_MSG);
|
||||
break;
|
||||
case 404:
|
||||
core11.warning(e.message || GENERIC_404_MSG);
|
||||
core11.warning(httpError.message || GENERIC_404_MSG);
|
||||
break;
|
||||
default:
|
||||
core11.warning(e.message);
|
||||
core11.warning(httpError.message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -92651,7 +92647,7 @@ function validateSarifFileSchema(sarif, sarifFilePath, logger) {
|
||||
}
|
||||
logger.info(`Validating ${sarifFilePath}`);
|
||||
const schema2 = require_sarif_schema_2_1_0();
|
||||
const result = new jsonschema.Validator().validate(sarif, schema2);
|
||||
const result = new jsonschema2.Validator().validate(sarif, schema2);
|
||||
const warningAttributes = ["uri-reference", "uri"];
|
||||
const errors = (result.errors ?? []).filter(
|
||||
(err) => !(err.name === "format" && typeof err.argument === "string" && warningAttributes.includes(err.argument))
|
||||
|
||||
Generated
+1311
-5
File diff suppressed because it is too large
Load Diff
Generated
+112
-114
@@ -20602,14 +20602,14 @@ var require_dist_node4 = __commonJS({
|
||||
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
||||
var dist_src_exports = {};
|
||||
__export2(dist_src_exports, {
|
||||
RequestError: () => RequestError2
|
||||
RequestError: () => RequestError
|
||||
});
|
||||
module2.exports = __toCommonJS2(dist_src_exports);
|
||||
var import_deprecation = require_dist_node3();
|
||||
var import_once = __toESM2(require_once());
|
||||
var logOnceCode = (0, import_once.default)((deprecation) => console.warn(deprecation));
|
||||
var logOnceHeaders = (0, import_once.default)((deprecation) => console.warn(deprecation));
|
||||
var RequestError2 = class extends Error {
|
||||
var RequestError = class extends Error {
|
||||
constructor(message, statusCode, options) {
|
||||
super(message);
|
||||
if (Error.captureStackTrace) {
|
||||
@@ -20701,7 +20701,7 @@ var require_dist_node5 = __commonJS({
|
||||
const Ctor = Object.prototype.hasOwnProperty.call(proto, "constructor") && proto.constructor;
|
||||
return typeof Ctor === "function" && Ctor instanceof Ctor && Function.prototype.call(Ctor) === Function.prototype.call(value);
|
||||
}
|
||||
var import_request_error2 = require_dist_node4();
|
||||
var import_request_error = require_dist_node4();
|
||||
function getBufferResponse(response) {
|
||||
return response.arrayBuffer();
|
||||
}
|
||||
@@ -20753,7 +20753,7 @@ var require_dist_node5 = __commonJS({
|
||||
if (status < 400) {
|
||||
return;
|
||||
}
|
||||
throw new import_request_error2.RequestError(response.statusText, status, {
|
||||
throw new import_request_error.RequestError(response.statusText, status, {
|
||||
response: {
|
||||
url: url2,
|
||||
status,
|
||||
@@ -20764,7 +20764,7 @@ var require_dist_node5 = __commonJS({
|
||||
});
|
||||
}
|
||||
if (status === 304) {
|
||||
throw new import_request_error2.RequestError("Not modified", status, {
|
||||
throw new import_request_error.RequestError("Not modified", status, {
|
||||
response: {
|
||||
url: url2,
|
||||
status,
|
||||
@@ -20776,7 +20776,7 @@ var require_dist_node5 = __commonJS({
|
||||
}
|
||||
if (status >= 400) {
|
||||
const data = await getResponseData(response);
|
||||
const error2 = new import_request_error2.RequestError(toErrorMessage(data), status, {
|
||||
const error2 = new import_request_error.RequestError(toErrorMessage(data), status, {
|
||||
response: {
|
||||
url: url2,
|
||||
status,
|
||||
@@ -20796,7 +20796,7 @@ var require_dist_node5 = __commonJS({
|
||||
data
|
||||
};
|
||||
}).catch((error2) => {
|
||||
if (error2 instanceof import_request_error2.RequestError)
|
||||
if (error2 instanceof import_request_error.RequestError)
|
||||
throw error2;
|
||||
else if (error2.name === "AbortError")
|
||||
throw error2;
|
||||
@@ -20808,7 +20808,7 @@ var require_dist_node5 = __commonJS({
|
||||
message = error2.cause;
|
||||
}
|
||||
}
|
||||
throw new import_request_error2.RequestError(message, 500, {
|
||||
throw new import_request_error.RequestError(message, 500, {
|
||||
request: requestOptions
|
||||
});
|
||||
});
|
||||
@@ -21250,14 +21250,14 @@ var require_dist_node7 = __commonJS({
|
||||
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
||||
var dist_src_exports = {};
|
||||
__export2(dist_src_exports, {
|
||||
RequestError: () => RequestError2
|
||||
RequestError: () => RequestError
|
||||
});
|
||||
module2.exports = __toCommonJS2(dist_src_exports);
|
||||
var import_deprecation = require_dist_node3();
|
||||
var import_once = __toESM2(require_once());
|
||||
var logOnceCode = (0, import_once.default)((deprecation) => console.warn(deprecation));
|
||||
var logOnceHeaders = (0, import_once.default)((deprecation) => console.warn(deprecation));
|
||||
var RequestError2 = class extends Error {
|
||||
var RequestError = class extends Error {
|
||||
constructor(message, statusCode, options) {
|
||||
super(message);
|
||||
if (Error.captureStackTrace) {
|
||||
@@ -21349,7 +21349,7 @@ var require_dist_node8 = __commonJS({
|
||||
const Ctor = Object.prototype.hasOwnProperty.call(proto, "constructor") && proto.constructor;
|
||||
return typeof Ctor === "function" && Ctor instanceof Ctor && Function.prototype.call(Ctor) === Function.prototype.call(value);
|
||||
}
|
||||
var import_request_error2 = require_dist_node7();
|
||||
var import_request_error = require_dist_node7();
|
||||
function getBufferResponse(response) {
|
||||
return response.arrayBuffer();
|
||||
}
|
||||
@@ -21401,7 +21401,7 @@ var require_dist_node8 = __commonJS({
|
||||
if (status < 400) {
|
||||
return;
|
||||
}
|
||||
throw new import_request_error2.RequestError(response.statusText, status, {
|
||||
throw new import_request_error.RequestError(response.statusText, status, {
|
||||
response: {
|
||||
url: url2,
|
||||
status,
|
||||
@@ -21412,7 +21412,7 @@ var require_dist_node8 = __commonJS({
|
||||
});
|
||||
}
|
||||
if (status === 304) {
|
||||
throw new import_request_error2.RequestError("Not modified", status, {
|
||||
throw new import_request_error.RequestError("Not modified", status, {
|
||||
response: {
|
||||
url: url2,
|
||||
status,
|
||||
@@ -21424,7 +21424,7 @@ var require_dist_node8 = __commonJS({
|
||||
}
|
||||
if (status >= 400) {
|
||||
const data = await getResponseData(response);
|
||||
const error2 = new import_request_error2.RequestError(toErrorMessage(data), status, {
|
||||
const error2 = new import_request_error.RequestError(toErrorMessage(data), status, {
|
||||
response: {
|
||||
url: url2,
|
||||
status,
|
||||
@@ -21444,7 +21444,7 @@ var require_dist_node8 = __commonJS({
|
||||
data
|
||||
};
|
||||
}).catch((error2) => {
|
||||
if (error2 instanceof import_request_error2.RequestError)
|
||||
if (error2 instanceof import_request_error.RequestError)
|
||||
throw error2;
|
||||
else if (error2.name === "AbortError")
|
||||
throw error2;
|
||||
@@ -21456,7 +21456,7 @@ var require_dist_node8 = __commonJS({
|
||||
message = error2.cause;
|
||||
}
|
||||
}
|
||||
throw new import_request_error2.RequestError(message, 500, {
|
||||
throw new import_request_error.RequestError(message, 500, {
|
||||
request: requestOptions
|
||||
});
|
||||
});
|
||||
@@ -32309,7 +32309,7 @@ var require_package = __commonJS({
|
||||
"package.json"(exports2, module2) {
|
||||
module2.exports = {
|
||||
name: "codeql",
|
||||
version: "4.30.9",
|
||||
version: "4.30.10",
|
||||
private: true,
|
||||
description: "CodeQL action",
|
||||
scripts: {
|
||||
@@ -32357,7 +32357,7 @@ var require_package = __commonJS({
|
||||
jsonschema: "1.4.1",
|
||||
long: "^5.3.2",
|
||||
"node-forge": "^1.3.1",
|
||||
octokit: "^5.0.3",
|
||||
octokit: "^5.0.4",
|
||||
semver: "^7.7.3",
|
||||
uuid: "^13.0.0"
|
||||
},
|
||||
@@ -32365,7 +32365,7 @@ var require_package = __commonJS({
|
||||
"@ava/typescript": "6.0.0",
|
||||
"@eslint/compat": "^1.4.0",
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@eslint/js": "^9.37.0",
|
||||
"@eslint/js": "^9.38.0",
|
||||
"@microsoft/eslint-formatter-sarif": "^3.1.0",
|
||||
"@octokit/types": "^15.0.0",
|
||||
"@types/archiver": "^6.0.3",
|
||||
@@ -32376,10 +32376,10 @@ var require_package = __commonJS({
|
||||
"@types/node-forge": "^1.3.14",
|
||||
"@types/semver": "^7.7.1",
|
||||
"@types/sinon": "^17.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^8.46.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.46.1",
|
||||
"@typescript-eslint/parser": "^8.41.0",
|
||||
ava: "^6.4.1",
|
||||
esbuild: "^0.25.10",
|
||||
esbuild: "^0.25.11",
|
||||
eslint: "^8.57.1",
|
||||
"eslint-import-resolver-typescript": "^3.8.7",
|
||||
"eslint-plugin-filenames": "^1.3.2",
|
||||
@@ -33768,14 +33768,14 @@ var require_dist_node14 = __commonJS({
|
||||
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
||||
var dist_src_exports = {};
|
||||
__export2(dist_src_exports, {
|
||||
RequestError: () => RequestError2
|
||||
RequestError: () => RequestError
|
||||
});
|
||||
module2.exports = __toCommonJS2(dist_src_exports);
|
||||
var import_deprecation = require_dist_node3();
|
||||
var import_once = __toESM2(require_once());
|
||||
var logOnceCode = (0, import_once.default)((deprecation) => console.warn(deprecation));
|
||||
var logOnceHeaders = (0, import_once.default)((deprecation) => console.warn(deprecation));
|
||||
var RequestError2 = class extends Error {
|
||||
var RequestError = class extends Error {
|
||||
constructor(message, statusCode, options) {
|
||||
super(message);
|
||||
if (Error.captureStackTrace) {
|
||||
@@ -33877,7 +33877,7 @@ var require_dist_node15 = __commonJS({
|
||||
throw error2;
|
||||
}
|
||||
var import_light = __toESM2(require_light());
|
||||
var import_request_error2 = require_dist_node14();
|
||||
var import_request_error = require_dist_node14();
|
||||
async function wrapRequest(state, octokit, request, options) {
|
||||
const limiter = new import_light.default();
|
||||
limiter.on("failed", function(error2, info4) {
|
||||
@@ -33898,7 +33898,7 @@ var require_dist_node15 = __commonJS({
|
||||
if (response.data && response.data.errors && response.data.errors.length > 0 && /Something went wrong while executing your query/.test(
|
||||
response.data.errors[0].message
|
||||
)) {
|
||||
const error2 = new import_request_error2.RequestError(response.data.errors[0].message, 500, {
|
||||
const error2 = new import_request_error.RequestError(response.data.errors[0].message, 500, {
|
||||
request: options,
|
||||
response
|
||||
});
|
||||
@@ -80374,19 +80374,19 @@ var require_validator2 = __commonJS({
|
||||
var SchemaError = helpers.SchemaError;
|
||||
var SchemaContext = helpers.SchemaContext;
|
||||
var anonymousBase = "/";
|
||||
var Validator2 = function Validator3() {
|
||||
this.customFormats = Object.create(Validator3.prototype.customFormats);
|
||||
var Validator3 = function Validator4() {
|
||||
this.customFormats = Object.create(Validator4.prototype.customFormats);
|
||||
this.schemas = {};
|
||||
this.unresolvedRefs = [];
|
||||
this.types = Object.create(types);
|
||||
this.attributes = Object.create(attribute.validators);
|
||||
};
|
||||
Validator2.prototype.customFormats = {};
|
||||
Validator2.prototype.schemas = null;
|
||||
Validator2.prototype.types = null;
|
||||
Validator2.prototype.attributes = null;
|
||||
Validator2.prototype.unresolvedRefs = null;
|
||||
Validator2.prototype.addSchema = function addSchema(schema2, base) {
|
||||
Validator3.prototype.customFormats = {};
|
||||
Validator3.prototype.schemas = null;
|
||||
Validator3.prototype.types = null;
|
||||
Validator3.prototype.attributes = null;
|
||||
Validator3.prototype.unresolvedRefs = null;
|
||||
Validator3.prototype.addSchema = function addSchema(schema2, base) {
|
||||
var self2 = this;
|
||||
if (!schema2) {
|
||||
return null;
|
||||
@@ -80404,25 +80404,25 @@ var require_validator2 = __commonJS({
|
||||
});
|
||||
return this.schemas[ourUri];
|
||||
};
|
||||
Validator2.prototype.addSubSchemaArray = function addSubSchemaArray(baseuri, schemas) {
|
||||
Validator3.prototype.addSubSchemaArray = function addSubSchemaArray(baseuri, schemas) {
|
||||
if (!Array.isArray(schemas)) return;
|
||||
for (var i = 0; i < schemas.length; i++) {
|
||||
this.addSubSchema(baseuri, schemas[i]);
|
||||
}
|
||||
};
|
||||
Validator2.prototype.addSubSchemaObject = function addSubSchemaArray(baseuri, schemas) {
|
||||
Validator3.prototype.addSubSchemaObject = function addSubSchemaArray(baseuri, schemas) {
|
||||
if (!schemas || typeof schemas != "object") return;
|
||||
for (var p in schemas) {
|
||||
this.addSubSchema(baseuri, schemas[p]);
|
||||
}
|
||||
};
|
||||
Validator2.prototype.setSchemas = function setSchemas(schemas) {
|
||||
Validator3.prototype.setSchemas = function setSchemas(schemas) {
|
||||
this.schemas = schemas;
|
||||
};
|
||||
Validator2.prototype.getSchema = function getSchema(urn) {
|
||||
Validator3.prototype.getSchema = function getSchema(urn) {
|
||||
return this.schemas[urn];
|
||||
};
|
||||
Validator2.prototype.validate = function validate(instance, schema2, options, ctx) {
|
||||
Validator3.prototype.validate = function validate(instance, schema2, options, ctx) {
|
||||
if (typeof schema2 !== "boolean" && typeof schema2 !== "object" || schema2 === null) {
|
||||
throw new SchemaError("Expected `schema` to be an object or boolean");
|
||||
}
|
||||
@@ -80460,7 +80460,7 @@ var require_validator2 = __commonJS({
|
||||
if (typeof ref == "string") return ref;
|
||||
return false;
|
||||
}
|
||||
Validator2.prototype.validateSchema = function validateSchema(instance, schema2, options, ctx) {
|
||||
Validator3.prototype.validateSchema = function validateSchema(instance, schema2, options, ctx) {
|
||||
var result = new ValidatorResult(instance, schema2, options, ctx);
|
||||
if (typeof schema2 === "boolean") {
|
||||
if (schema2 === true) {
|
||||
@@ -80510,17 +80510,17 @@ var require_validator2 = __commonJS({
|
||||
}
|
||||
return result;
|
||||
};
|
||||
Validator2.prototype.schemaTraverser = function schemaTraverser(schemaobj, s) {
|
||||
Validator3.prototype.schemaTraverser = function schemaTraverser(schemaobj, s) {
|
||||
schemaobj.schema = helpers.deepMerge(schemaobj.schema, this.superResolve(s, schemaobj.ctx));
|
||||
};
|
||||
Validator2.prototype.superResolve = function superResolve(schema2, ctx) {
|
||||
Validator3.prototype.superResolve = function superResolve(schema2, ctx) {
|
||||
var ref = shouldResolve(schema2);
|
||||
if (ref) {
|
||||
return this.resolve(schema2, ref, ctx).subschema;
|
||||
}
|
||||
return schema2;
|
||||
};
|
||||
Validator2.prototype.resolve = function resolve6(schema2, switchSchema, ctx) {
|
||||
Validator3.prototype.resolve = function resolve6(schema2, switchSchema, ctx) {
|
||||
switchSchema = ctx.resolve(switchSchema);
|
||||
if (ctx.schemas[switchSchema]) {
|
||||
return { subschema: ctx.schemas[switchSchema], switchSchema };
|
||||
@@ -80537,7 +80537,7 @@ var require_validator2 = __commonJS({
|
||||
}
|
||||
return { subschema, switchSchema };
|
||||
};
|
||||
Validator2.prototype.testType = function validateType(instance, schema2, options, ctx, type2) {
|
||||
Validator3.prototype.testType = function validateType(instance, schema2, options, ctx, type2) {
|
||||
if (type2 === void 0) {
|
||||
return;
|
||||
} else if (type2 === null) {
|
||||
@@ -80552,7 +80552,7 @@ var require_validator2 = __commonJS({
|
||||
}
|
||||
return true;
|
||||
};
|
||||
var types = Validator2.prototype.types = {};
|
||||
var types = Validator3.prototype.types = {};
|
||||
types.string = function testString(instance) {
|
||||
return typeof instance == "string";
|
||||
};
|
||||
@@ -80580,7 +80580,7 @@ var require_validator2 = __commonJS({
|
||||
types.object = function testObject(instance) {
|
||||
return instance && typeof instance === "object" && !Array.isArray(instance) && !(instance instanceof Date);
|
||||
};
|
||||
module2.exports = Validator2;
|
||||
module2.exports = Validator3;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -80588,7 +80588,7 @@ var require_validator2 = __commonJS({
|
||||
var require_lib2 = __commonJS({
|
||||
"node_modules/jsonschema/lib/index.js"(exports2, module2) {
|
||||
"use strict";
|
||||
var Validator2 = module2.exports.Validator = require_validator2();
|
||||
var Validator3 = module2.exports.Validator = require_validator2();
|
||||
module2.exports.ValidatorResult = require_helpers3().ValidatorResult;
|
||||
module2.exports.ValidatorResultError = require_helpers3().ValidatorResultError;
|
||||
module2.exports.ValidationError = require_helpers3().ValidationError;
|
||||
@@ -80596,7 +80596,7 @@ var require_lib2 = __commonJS({
|
||||
module2.exports.SchemaScanResult = require_scan2().SchemaScanResult;
|
||||
module2.exports.scan = require_scan2().scan;
|
||||
module2.exports.validate = function(instance, schema2, options) {
|
||||
var v = new Validator2();
|
||||
var v = new Validator3();
|
||||
return v.validate(instance, schema2, options);
|
||||
};
|
||||
}
|
||||
@@ -80921,14 +80921,14 @@ var require_tool_cache = __commonJS({
|
||||
var assert_1 = require("assert");
|
||||
var exec_1 = require_exec();
|
||||
var retry_helper_1 = require_retry_helper();
|
||||
var HTTPError = class extends Error {
|
||||
var HTTPError2 = class extends Error {
|
||||
constructor(httpStatusCode) {
|
||||
super(`Unexpected HTTP response: ${httpStatusCode}`);
|
||||
this.httpStatusCode = httpStatusCode;
|
||||
Object.setPrototypeOf(this, new.target.prototype);
|
||||
}
|
||||
};
|
||||
exports2.HTTPError = HTTPError;
|
||||
exports2.HTTPError = HTTPError2;
|
||||
var IS_WINDOWS = process.platform === "win32";
|
||||
var IS_MAC = process.platform === "darwin";
|
||||
var userAgent = "actions/tool-cache";
|
||||
@@ -80945,7 +80945,7 @@ var require_tool_cache = __commonJS({
|
||||
return yield retryHelper.execute(() => __awaiter4(this, void 0, void 0, function* () {
|
||||
return yield downloadToolAttempt(url2, dest || "", auth, headers);
|
||||
}), (err) => {
|
||||
if (err instanceof HTTPError && err.httpStatusCode) {
|
||||
if (err instanceof HTTPError2 && err.httpStatusCode) {
|
||||
if (err.httpStatusCode < 500 && err.httpStatusCode !== 408 && err.httpStatusCode !== 429) {
|
||||
return false;
|
||||
}
|
||||
@@ -80972,7 +80972,7 @@ var require_tool_cache = __commonJS({
|
||||
}
|
||||
const response = yield http.get(url2, headers);
|
||||
if (response.message.statusCode !== 200) {
|
||||
const err = new HTTPError(response.message.statusCode);
|
||||
const err = new HTTPError2(response.message.statusCode);
|
||||
core14.debug(`Failed to download from "${url2}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`);
|
||||
throw err;
|
||||
}
|
||||
@@ -88444,13 +88444,28 @@ function getRequiredEnvParam(paramName) {
|
||||
}
|
||||
return value;
|
||||
}
|
||||
var HTTPError = class extends Error {
|
||||
constructor(message, status) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
}
|
||||
};
|
||||
var ConfigurationError = class extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
}
|
||||
};
|
||||
function isHTTPError(arg) {
|
||||
return arg?.status !== void 0 && Number.isInteger(arg.status);
|
||||
function asHTTPError(arg) {
|
||||
if (typeof arg !== "object" || arg === null || typeof arg.message !== "string") {
|
||||
return void 0;
|
||||
}
|
||||
if (Number.isInteger(arg.status)) {
|
||||
return new HTTPError(arg.message, arg.status);
|
||||
}
|
||||
if (Number.isInteger(arg.httpStatusCode)) {
|
||||
return new HTTPError(arg.message, arg.httpStatusCode);
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
var cachedCodeQlVersion = void 0;
|
||||
function cacheCodeQlVersion(version) {
|
||||
@@ -88958,14 +88973,24 @@ function computeAutomationID(analysis_key, environment) {
|
||||
return automationID;
|
||||
}
|
||||
function wrapApiConfigurationError(e) {
|
||||
if (isHTTPError(e)) {
|
||||
if (e.message.includes("API rate limit exceeded for installation") || e.message.includes("commit not found") || e.message.includes("Resource not accessible by integration") || /ref .* not found in this repository/.test(e.message)) {
|
||||
return new ConfigurationError(e.message);
|
||||
} else if (e.message.includes("Bad credentials") || e.message.includes("Not Found")) {
|
||||
const httpError = asHTTPError(e);
|
||||
if (httpError !== void 0) {
|
||||
if ([
|
||||
/API rate limit exceeded/,
|
||||
/commit not found/,
|
||||
/Resource not accessible by integration/,
|
||||
/ref .* not found in this repository/
|
||||
].some((pattern) => pattern.test(httpError.message))) {
|
||||
return new ConfigurationError(httpError.message);
|
||||
}
|
||||
if (httpError.message.includes("Bad credentials") || httpError.message.includes("Not Found")) {
|
||||
return new ConfigurationError(
|
||||
"Please check that your token is valid and has the required permissions: contents: read, security-events: write"
|
||||
);
|
||||
}
|
||||
if (httpError.status === 429) {
|
||||
return new ConfigurationError("API rate limit exceeded");
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
@@ -88976,8 +89001,8 @@ var path8 = __toESM(require("path"));
|
||||
var semver3 = __toESM(require_semver2());
|
||||
|
||||
// src/defaults.json
|
||||
var bundleVersion = "codeql-bundle-v2.23.2";
|
||||
var cliVersion = "2.23.2";
|
||||
var bundleVersion = "codeql-bundle-v2.23.3";
|
||||
var cliVersion = "2.23.3";
|
||||
|
||||
// src/overlay-database-utils.ts
|
||||
var fs5 = __toESM(require("fs"));
|
||||
@@ -89446,6 +89471,11 @@ var featureConfig = {
|
||||
defaultValue: false,
|
||||
envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS",
|
||||
minimumVersion: "2.23.0"
|
||||
},
|
||||
["validate_db_config" /* ValidateDbConfig */]: {
|
||||
defaultValue: false,
|
||||
envVar: "CODEQL_ACTION_VALIDATE_DB_CONFIG",
|
||||
minimumVersion: void 0
|
||||
}
|
||||
};
|
||||
var FEATURE_FLAGS_FILE_NAME = "cached-feature-flags.json";
|
||||
@@ -89698,9 +89728,10 @@ var GitHubFeatureFlags = class {
|
||||
this.hasAccessedRemoteFeatureFlags = true;
|
||||
return remoteFlags;
|
||||
} catch (e) {
|
||||
if (isHTTPError(e) && e.status === 403) {
|
||||
const httpError = asHTTPError(e);
|
||||
if (httpError?.status === 403) {
|
||||
this.logger.warning(
|
||||
`This run of the CodeQL Action does not have permission to access Code Scanning API endpoints. As a result, it will not be opted into any experimental features. This could be because the Action is running on a pull request from a fork. If not, please ensure the Action has the 'security-events: write' permission. Details: ${e.message}`
|
||||
`This run of the CodeQL Action does not have permission to access Code Scanning API endpoints. As a result, it will not be opted into any experimental features. This could be because the Action is running on a pull request from a fork. If not, please ensure the Action has the 'security-events: write' permission. Details: ${httpError.message}`
|
||||
);
|
||||
this.hasAccessedRemoteFeatureFlags = false;
|
||||
return {};
|
||||
@@ -89725,6 +89756,7 @@ var path10 = __toESM(require("path"));
|
||||
var core8 = __toESM(require_core());
|
||||
|
||||
// src/config/db-config.ts
|
||||
var jsonschema = __toESM(require_lib2());
|
||||
var semver4 = __toESM(require_semver2());
|
||||
var PACK_IDENTIFIER_PATTERN = (function() {
|
||||
const alphaNumeric = "[a-z0-9]";
|
||||
@@ -89972,19 +90004,20 @@ async function sendStatusReport(statusReport) {
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
if (isHTTPError(e)) {
|
||||
switch (e.status) {
|
||||
const httpError = asHTTPError(e);
|
||||
if (httpError !== void 0) {
|
||||
switch (httpError.status) {
|
||||
case 403:
|
||||
if (getWorkflowEventName() === "push" && process.env["GITHUB_ACTOR"] === "dependabot[bot]") {
|
||||
core9.warning(
|
||||
`Workflows triggered by Dependabot on the "push" event run with read-only access. Uploading Code Scanning results requires write access. To use Code Scanning with Dependabot, please ensure you are using the "pull_request" event for this workflow and avoid triggering on the "push" event for Dependabot branches. See ${"https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning#scanning-on-push" /* SCANNING_ON_PUSH */} for more information on how to configure these events.`
|
||||
);
|
||||
} else {
|
||||
core9.warning(e.message);
|
||||
core9.warning(httpError.message);
|
||||
}
|
||||
return;
|
||||
case 404:
|
||||
core9.warning(e.message);
|
||||
core9.warning(httpError.message);
|
||||
return;
|
||||
case 422:
|
||||
if (getRequiredEnvParam("GITHUB_SERVER_URL") !== GITHUB_DOTCOM_URL) {
|
||||
@@ -90009,7 +90042,7 @@ var path15 = __toESM(require("path"));
|
||||
var url = __toESM(require("url"));
|
||||
var import_zlib = __toESM(require("zlib"));
|
||||
var core12 = __toESM(require_core());
|
||||
var jsonschema = __toESM(require_lib2());
|
||||
var jsonschema2 = __toESM(require_lib2());
|
||||
|
||||
// src/codeql.ts
|
||||
var fs12 = __toESM(require("fs"));
|
||||
@@ -90017,45 +90050,6 @@ var path13 = __toESM(require("path"));
|
||||
var core11 = __toESM(require_core());
|
||||
var toolrunner3 = __toESM(require_toolrunner());
|
||||
|
||||
// node_modules/@octokit/request-error/dist-src/index.js
|
||||
var RequestError = class extends Error {
|
||||
name;
|
||||
/**
|
||||
* http status code
|
||||
*/
|
||||
status;
|
||||
/**
|
||||
* Request options that lead to the error.
|
||||
*/
|
||||
request;
|
||||
/**
|
||||
* Response object if a response was received
|
||||
*/
|
||||
response;
|
||||
constructor(message, statusCode, options) {
|
||||
super(message);
|
||||
this.name = "HttpError";
|
||||
this.status = Number.parseInt(statusCode);
|
||||
if (Number.isNaN(this.status)) {
|
||||
this.status = 0;
|
||||
}
|
||||
if ("response" in options) {
|
||||
this.response = options.response;
|
||||
}
|
||||
const requestCopy = Object.assign({}, options.request);
|
||||
if (options.request.headers.authorization) {
|
||||
requestCopy.headers = Object.assign({}, options.request.headers, {
|
||||
authorization: options.request.headers.authorization.replace(
|
||||
/(?<! ) .*$/,
|
||||
" [REDACTED]"
|
||||
)
|
||||
});
|
||||
}
|
||||
requestCopy.url = requestCopy.url.replace(/\bclient_secret=\w+/g, "client_secret=[REDACTED]").replace(/\baccess_token=\w+/g, "access_token=[REDACTED]");
|
||||
this.request = requestCopy;
|
||||
}
|
||||
};
|
||||
|
||||
// src/cli-errors.ts
|
||||
var SUPPORTED_PLATFORMS = [
|
||||
["linux", "x64"],
|
||||
@@ -90223,6 +90217,9 @@ var cliErrorsConfig = {
|
||||
cliErrorMessageCandidates: [
|
||||
new RegExp(
|
||||
"Query pack .* cannot be found\\. Check the spelling of the pack\\."
|
||||
),
|
||||
new RegExp(
|
||||
"is not a .ql file, .qls file, a directory, or a query pack specification."
|
||||
)
|
||||
]
|
||||
},
|
||||
@@ -91269,9 +91266,9 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV
|
||||
toolsVersion,
|
||||
zstdAvailability
|
||||
};
|
||||
} catch (e) {
|
||||
const ErrorClass = e instanceof ConfigurationError || e instanceof Error && e.message.includes("ENOSPC") || // out of disk space
|
||||
e instanceof RequestError && e.status === 429 ? ConfigurationError : Error;
|
||||
} catch (rawError) {
|
||||
const e = wrapApiConfigurationError(rawError);
|
||||
const ErrorClass = e instanceof ConfigurationError || e instanceof Error && e.message.includes("ENOSPC") ? ConfigurationError : Error;
|
||||
throw new ErrorClass(
|
||||
`Unable to download and extract CodeQL CLI: ${getErrorMessage(e)}${e instanceof Error && e.stack ? `
|
||||
|
||||
@@ -93191,16 +93188,17 @@ async function uploadPayload(payload, repositoryNwo, logger, analysis) {
|
||||
logger.info("Successfully uploaded results");
|
||||
return response.data.id;
|
||||
} catch (e) {
|
||||
if (isHTTPError(e)) {
|
||||
switch (e.status) {
|
||||
const httpError = asHTTPError(e);
|
||||
if (httpError !== void 0) {
|
||||
switch (httpError.status) {
|
||||
case 403:
|
||||
core12.warning(e.message || GENERIC_403_MSG);
|
||||
core12.warning(httpError.message || GENERIC_403_MSG);
|
||||
break;
|
||||
case 404:
|
||||
core12.warning(e.message || GENERIC_404_MSG);
|
||||
core12.warning(httpError.message || GENERIC_404_MSG);
|
||||
break;
|
||||
default:
|
||||
core12.warning(e.message);
|
||||
core12.warning(httpError.message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -93305,7 +93303,7 @@ function validateSarifFileSchema(sarif, sarifFilePath, logger) {
|
||||
}
|
||||
logger.info(`Validating ${sarifFilePath}`);
|
||||
const schema2 = require_sarif_schema_2_1_0();
|
||||
const result = new jsonschema.Validator().validate(sarif, schema2);
|
||||
const result = new jsonschema2.Validator().validate(sarif, schema2);
|
||||
const warningAttributes = ["uri-reference", "uri"];
|
||||
const errors = (result.errors ?? []).filter(
|
||||
(err) => !(err.name === "format" && typeof err.argument === "string" && warningAttributes.includes(err.argument))
|
||||
|
||||
Generated
+418
-540
File diff suppressed because it is too large
Load Diff
+5
-5
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "codeql",
|
||||
"version": "4.30.9",
|
||||
"version": "4.30.10",
|
||||
"private": true,
|
||||
"description": "CodeQL action",
|
||||
"scripts": {
|
||||
@@ -48,7 +48,7 @@
|
||||
"jsonschema": "1.4.1",
|
||||
"long": "^5.3.2",
|
||||
"node-forge": "^1.3.1",
|
||||
"octokit": "^5.0.3",
|
||||
"octokit": "^5.0.4",
|
||||
"semver": "^7.7.3",
|
||||
"uuid": "^13.0.0"
|
||||
},
|
||||
@@ -56,7 +56,7 @@
|
||||
"@ava/typescript": "6.0.0",
|
||||
"@eslint/compat": "^1.4.0",
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@eslint/js": "^9.37.0",
|
||||
"@eslint/js": "^9.38.0",
|
||||
"@microsoft/eslint-formatter-sarif": "^3.1.0",
|
||||
"@octokit/types": "^15.0.0",
|
||||
"@types/archiver": "^6.0.3",
|
||||
@@ -67,10 +67,10 @@
|
||||
"@types/node-forge": "^1.3.14",
|
||||
"@types/semver": "^7.7.1",
|
||||
"@types/sinon": "^17.0.4",
|
||||
"@typescript-eslint/eslint-plugin": "^8.46.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.46.1",
|
||||
"@typescript-eslint/parser": "^8.41.0",
|
||||
"ava": "^6.4.1",
|
||||
"esbuild": "^0.25.10",
|
||||
"esbuild": "^0.25.11",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-import-resolver-typescript": "^3.8.7",
|
||||
"eslint-plugin-filenames": "^1.3.2",
|
||||
|
||||
@@ -2,6 +2,7 @@ name: "Analyze: 'ref' and 'sha' from inputs"
|
||||
description: "Checks that specifying 'ref' and 'sha' as inputs works"
|
||||
versions: ["default"]
|
||||
installGo: true
|
||||
installPython: true
|
||||
steps:
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
|
||||
@@ -15,10 +15,9 @@ steps:
|
||||
if (allCodeqlVersions.length === 0) {
|
||||
throw new Error(`CodeQL could not be found in the toolcache`);
|
||||
}
|
||||
- id: init
|
||||
uses: ./../action/init
|
||||
- id: setup-codeql
|
||||
uses: ./../action/setup-codeql
|
||||
with:
|
||||
languages: javascript
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
- name: Check CodeQL is installed within the toolcache
|
||||
uses: actions/github-script@v8
|
||||
|
||||
@@ -2,6 +2,7 @@ name: "Local CodeQL bundle"
|
||||
description: "Tests using a CodeQL bundle from a local file rather than a URL"
|
||||
versions: ["linked"]
|
||||
installGo: true
|
||||
installPython: true
|
||||
steps:
|
||||
- name: Fetch latest CodeQL bundle
|
||||
run: |
|
||||
|
||||
@@ -4,6 +4,7 @@ operatingSystems: ["macos", "ubuntu"]
|
||||
env:
|
||||
CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI: true
|
||||
installGo: true
|
||||
installPython: true
|
||||
steps:
|
||||
- name: Use Xcode 16
|
||||
if: runner.os == 'macOS' && matrix.version != 'nightly-latest'
|
||||
|
||||
@@ -3,6 +3,7 @@ description: "Checks that specifying packages using a combination of a config fi
|
||||
versions: ["linked", "default", "nightly-latest"] # This feature is not compatible with old CLIs
|
||||
installGo: true
|
||||
installNode: true
|
||||
installPython: true
|
||||
steps:
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
|
||||
@@ -6,6 +6,7 @@ versions:
|
||||
- linked
|
||||
- nightly-latest
|
||||
installGo: true
|
||||
installPython: true
|
||||
steps:
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
|
||||
@@ -6,6 +6,7 @@ versions:
|
||||
- linked
|
||||
- nightly-latest
|
||||
installGo: true
|
||||
installPython: true
|
||||
steps:
|
||||
- uses: ./../action/init
|
||||
id: init
|
||||
|
||||
@@ -2,6 +2,7 @@ name: "Upload-sarif: 'ref' and 'sha' from inputs"
|
||||
description: "Checks that specifying 'ref' and 'sha' as inputs works"
|
||||
versions: ["default"]
|
||||
installGo: true
|
||||
installPython: true
|
||||
steps:
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
|
||||
@@ -3,6 +3,7 @@ description: "Checks that uploading SARIFs to the code quality endpoint works"
|
||||
versions: ["default"]
|
||||
analysisKinds: ["code-scanning", "code-quality", "code-scanning,code-quality"]
|
||||
installGo: true
|
||||
installPython: true
|
||||
steps:
|
||||
- uses: ./../action/init
|
||||
with:
|
||||
|
||||
@@ -2,6 +2,7 @@ name: "Use a custom `checkout_path`"
|
||||
description: "Checks that a custom `checkout_path` will find the proper commit_oid"
|
||||
versions: ["linked"]
|
||||
installGo: true
|
||||
installPython: true
|
||||
steps:
|
||||
# This ensures we don't accidentally use the original checkout for any part of the test.
|
||||
- name: Delete original checkout
|
||||
|
||||
+21
-1
@@ -117,7 +117,7 @@ for file in sorted((this_dir / 'checks').glob('*.yml')):
|
||||
steps.extend([
|
||||
{
|
||||
'name': 'Install Node.js',
|
||||
'uses': 'actions/setup-node@v5',
|
||||
'uses': 'actions/setup-node@v6',
|
||||
'with': {
|
||||
'node-version': '20.x',
|
||||
'cache': 'npm',
|
||||
@@ -184,6 +184,26 @@ for file in sorted((this_dir / 'checks').glob('*.yml')):
|
||||
}
|
||||
})
|
||||
|
||||
installPython = is_truthy(checkSpecification.get('installPython', ''))
|
||||
|
||||
if installPython:
|
||||
basePythonVersionExpr = '3.13'
|
||||
workflowInputs['python-version'] = {
|
||||
'type': 'string',
|
||||
'description': 'The version of Python to install',
|
||||
'required': False,
|
||||
'default': basePythonVersionExpr,
|
||||
}
|
||||
|
||||
steps.append({
|
||||
'name': 'Install Python',
|
||||
'if': 'matrix.version != \'nightly-latest\'',
|
||||
'uses': 'actions/setup-python@v6',
|
||||
'with': {
|
||||
'python-version': '${{ inputs.python-version || \'' + basePythonVersionExpr + '\' }}'
|
||||
}
|
||||
})
|
||||
|
||||
# If container initialisation steps are present in the check specification,
|
||||
# make sure to execute them first.
|
||||
if 'container' in checkSpecification and 'container-init-steps' in checkSpecification:
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
name: 'CodeQL: Setup'
|
||||
description: 'Installs the CodeQL CLI'
|
||||
author: 'GitHub'
|
||||
inputs:
|
||||
tools:
|
||||
description: >-
|
||||
By default, the Action will use the recommended version of the CodeQL
|
||||
Bundle to analyze your project. You can override this choice using this
|
||||
input. One of:
|
||||
|
||||
- A local path to a CodeQL Bundle tarball, or
|
||||
- The URL of a CodeQL Bundle tarball GitHub release asset, or
|
||||
- A special value `linked` which uses the version of the CodeQL tools
|
||||
that the Action has been bundled with.
|
||||
- A special value `nightly` which uses the latest nightly version of the
|
||||
CodeQL tools. Note that this is unstable and not recommended for
|
||||
production use.
|
||||
|
||||
If not specified, the Action will check in several places until it finds
|
||||
the CodeQL tools.
|
||||
required: false
|
||||
token:
|
||||
description: GitHub token to use for authenticating with this instance of GitHub.
|
||||
default: ${{ github.token }}
|
||||
required: false
|
||||
matrix:
|
||||
default: ${{ toJson(matrix) }}
|
||||
required: false
|
||||
external-repository-token:
|
||||
description: A token for fetching additional files from private repositories in the same GitHub instance that is running this action.
|
||||
required: false
|
||||
outputs:
|
||||
codeql-path:
|
||||
description: The path of the CodeQL binary that was installed.
|
||||
codeql-version:
|
||||
description: The version of the CodeQL binary that was installed.
|
||||
runs:
|
||||
using: node24
|
||||
main: '../lib/setup-codeql-action.js'
|
||||
@@ -1,12 +1,19 @@
|
||||
import test from "ava";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import {
|
||||
AnalysisKind,
|
||||
getAnalysisKinds,
|
||||
parseAnalysisKinds,
|
||||
supportedAnalysisKinds,
|
||||
} from "./analyses";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { setupTests } from "./testing-utils";
|
||||
import { ConfigurationError } from "./util";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
test("All known analysis kinds can be parsed successfully", async (t) => {
|
||||
for (const analysisKind of supportedAnalysisKinds) {
|
||||
t.deepEqual(await parseAnalysisKinds(analysisKind), [analysisKind]);
|
||||
@@ -34,3 +41,29 @@ test("Parsing analysis kinds requires at least one analysis kind", async (t) =>
|
||||
instanceOf: ConfigurationError,
|
||||
});
|
||||
});
|
||||
|
||||
test("getAnalysisKinds - returns expected analysis kinds for `analysis-kinds` input", async (t) => {
|
||||
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
||||
requiredInputStub
|
||||
.withArgs("analysis-kinds")
|
||||
.returns("code-scanning,code-quality");
|
||||
const result = await getAnalysisKinds(getRunnerLogger(true), true);
|
||||
t.assert(result.includes(AnalysisKind.CodeScanning));
|
||||
t.assert(result.includes(AnalysisKind.CodeQuality));
|
||||
});
|
||||
|
||||
test("getAnalysisKinds - includes `code-quality` when deprecated `quality-queries` input is used", async (t) => {
|
||||
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
||||
requiredInputStub.withArgs("analysis-kinds").returns("code-scanning");
|
||||
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
|
||||
optionalInputStub.withArgs("quality-queries").returns("code-quality");
|
||||
const result = await getAnalysisKinds(getRunnerLogger(true), true);
|
||||
t.assert(result.includes(AnalysisKind.CodeScanning));
|
||||
t.assert(result.includes(AnalysisKind.CodeQuality));
|
||||
});
|
||||
|
||||
test("getAnalysisKinds - throws if `analysis-kinds` input is invalid", async (t) => {
|
||||
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
||||
requiredInputStub.withArgs("analysis-kinds").returns("no-such-thing");
|
||||
await t.throwsAsync(getAnalysisKinds(getRunnerLogger(true), true));
|
||||
});
|
||||
|
||||
+54
-1
@@ -1,4 +1,8 @@
|
||||
import { fixCodeQualityCategory } from "./actions-util";
|
||||
import {
|
||||
fixCodeQualityCategory,
|
||||
getOptionalInput,
|
||||
getRequiredInput,
|
||||
} from "./actions-util";
|
||||
import { Logger } from "./logging";
|
||||
import { ConfigurationError } from "./util";
|
||||
|
||||
@@ -41,6 +45,55 @@ export async function parseAnalysisKinds(
|
||||
);
|
||||
}
|
||||
|
||||
// Used to avoid re-parsing the input after we have done it once.
|
||||
let cachedAnalysisKinds: AnalysisKind[] | undefined;
|
||||
|
||||
/**
|
||||
* Initialises the analysis kinds for the analysis based on the `analysis-kinds` input.
|
||||
* This function will also use the deprecated `quality-queries` input as an indicator to enable `code-quality`.
|
||||
* If the `analysis-kinds` input cannot be parsed, a `ConfigurationError` is thrown.
|
||||
*
|
||||
* @param logger The logger to use.
|
||||
* @param skipCache For testing, whether to ignore the cached values (default: false).
|
||||
*
|
||||
* @returns The array of enabled analysis kinds.
|
||||
* @throws A `ConfigurationError` if the `analysis-kinds` input cannot be parsed.
|
||||
*/
|
||||
export async function getAnalysisKinds(
|
||||
logger: Logger,
|
||||
skipCache: boolean = false,
|
||||
): Promise<AnalysisKind[]> {
|
||||
if (!skipCache && cachedAnalysisKinds !== undefined) {
|
||||
return cachedAnalysisKinds;
|
||||
}
|
||||
|
||||
cachedAnalysisKinds = await parseAnalysisKinds(
|
||||
getRequiredInput("analysis-kinds"),
|
||||
);
|
||||
|
||||
// Warn that `quality-queries` is deprecated if there is an argument for it.
|
||||
const qualityQueriesInput = getOptionalInput("quality-queries");
|
||||
|
||||
if (qualityQueriesInput !== undefined) {
|
||||
logger.warning(
|
||||
"The `quality-queries` input is deprecated and will be removed in a future version of the CodeQL Action. " +
|
||||
"Use the `analysis-kinds` input to configure different analysis kinds instead.",
|
||||
);
|
||||
}
|
||||
|
||||
// For backwards compatibility, add Code Quality to the enabled analysis kinds
|
||||
// if an input to `quality-queries` was specified. We should remove this once
|
||||
// `quality-queries` is no longer used.
|
||||
if (
|
||||
!cachedAnalysisKinds.includes(AnalysisKind.CodeQuality) &&
|
||||
qualityQueriesInput !== undefined
|
||||
) {
|
||||
cachedAnalysisKinds.push(AnalysisKind.CodeQuality);
|
||||
}
|
||||
|
||||
return cachedAnalysisKinds;
|
||||
}
|
||||
|
||||
/** The queries to use for Code Quality analyses. */
|
||||
export const codeQualityQueries: string[] = ["code-quality"];
|
||||
|
||||
|
||||
+17
-10
@@ -7,12 +7,12 @@ import { getActionVersion, getRequiredInput } from "./actions-util";
|
||||
import { Logger } from "./logging";
|
||||
import { getRepositoryNwo, RepositoryNwo } from "./repository";
|
||||
import {
|
||||
asHTTPError,
|
||||
ConfigurationError,
|
||||
getRequiredEnvParam,
|
||||
GITHUB_DOTCOM_URL,
|
||||
GitHubVariant,
|
||||
GitHubVersion,
|
||||
isHTTPError,
|
||||
parseGitHubUrl,
|
||||
parseMatrixInput,
|
||||
} from "./util";
|
||||
@@ -280,22 +280,29 @@ export async function getRepositoryProperties(repositoryNwo: RepositoryNwo) {
|
||||
}
|
||||
|
||||
export function wrapApiConfigurationError(e: unknown) {
|
||||
if (isHTTPError(e)) {
|
||||
const httpError = asHTTPError(e);
|
||||
if (httpError !== undefined) {
|
||||
if (
|
||||
e.message.includes("API rate limit exceeded for installation") ||
|
||||
e.message.includes("commit not found") ||
|
||||
e.message.includes("Resource not accessible by integration") ||
|
||||
/ref .* not found in this repository/.test(e.message)
|
||||
[
|
||||
/API rate limit exceeded/,
|
||||
/commit not found/,
|
||||
/Resource not accessible by integration/,
|
||||
/ref .* not found in this repository/,
|
||||
].some((pattern) => pattern.test(httpError.message))
|
||||
) {
|
||||
return new ConfigurationError(e.message);
|
||||
} else if (
|
||||
e.message.includes("Bad credentials") ||
|
||||
e.message.includes("Not Found")
|
||||
return new ConfigurationError(httpError.message);
|
||||
}
|
||||
if (
|
||||
httpError.message.includes("Bad credentials") ||
|
||||
httpError.message.includes("Not Found")
|
||||
) {
|
||||
return new ConfigurationError(
|
||||
"Please check that your token is valid and has the required permissions: contents: read, security-events: write",
|
||||
);
|
||||
}
|
||||
if (httpError.status === 429) {
|
||||
return new ConfigurationError("API rate limit exceeded");
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -310,6 +310,20 @@ test("wrapCliConfigurationError - pack cannot be found", (t) => {
|
||||
t.true(wrappedError instanceof ConfigurationError);
|
||||
});
|
||||
|
||||
test("wrapCliConfigurationError - unknown query file", (t) => {
|
||||
const commandError = new CommandInvocationError(
|
||||
"codeql",
|
||||
["database", "init"],
|
||||
2,
|
||||
"my-query-file is not a .ql file, .qls file, a directory, or a query pack specification. See the logs for more details.",
|
||||
);
|
||||
const cliError = new CliError(commandError);
|
||||
|
||||
const wrappedError = wrapCliConfigurationError(cliError);
|
||||
|
||||
t.true(wrappedError instanceof ConfigurationError);
|
||||
});
|
||||
|
||||
test("wrapCliConfigurationError - pack missing auth", (t) => {
|
||||
const commandError = new CommandInvocationError(
|
||||
"codeql",
|
||||
|
||||
@@ -264,6 +264,9 @@ export const cliErrorsConfig: Record<
|
||||
new RegExp(
|
||||
"Query pack .* cannot be found\\. Check the spelling of the pack\\.",
|
||||
),
|
||||
new RegExp(
|
||||
"is not a .ql file, .qls file, a directory, or a query pack specification.",
|
||||
),
|
||||
],
|
||||
},
|
||||
[CliConfigErrorCategory.PackMissingAuth]: {
|
||||
|
||||
+3
-4
@@ -3,7 +3,6 @@ import * as path from "path";
|
||||
|
||||
import * as core from "@actions/core";
|
||||
import * as toolrunner from "@actions/exec/lib/toolrunner";
|
||||
import { RequestError } from "@octokit/request-error";
|
||||
import * as yaml from "js-yaml";
|
||||
|
||||
import {
|
||||
@@ -371,11 +370,11 @@ export async function setupCodeQL(
|
||||
toolsVersion,
|
||||
zstdAvailability,
|
||||
};
|
||||
} catch (e) {
|
||||
} catch (rawError) {
|
||||
const e = api.wrapApiConfigurationError(rawError);
|
||||
const ErrorClass =
|
||||
e instanceof util.ConfigurationError ||
|
||||
(e instanceof Error && e.message.includes("ENOSPC")) || // out of disk space
|
||||
(e instanceof RequestError && e.status === 429) // rate limited
|
||||
(e instanceof Error && e.message.includes("ENOSPC")) // out of disk space
|
||||
? util.ConfigurationError
|
||||
: Error;
|
||||
|
||||
|
||||
@@ -49,10 +49,9 @@ function createTestInitConfigInputs(
|
||||
return Object.assign(
|
||||
{},
|
||||
{
|
||||
analysisKindsInput: "code-scanning",
|
||||
analysisKinds: [AnalysisKind.CodeScanning],
|
||||
languagesInput: undefined,
|
||||
queriesInput: undefined,
|
||||
qualityQueriesInput: undefined,
|
||||
packsInput: undefined,
|
||||
configFile: undefined,
|
||||
dbLocation: undefined,
|
||||
@@ -149,6 +148,7 @@ test("load empty config", async (t) => {
|
||||
});
|
||||
|
||||
const config = await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
languagesInput: languages,
|
||||
repository: { owner: "github", repo: "example" },
|
||||
@@ -188,8 +188,9 @@ test("load code quality config", async (t) => {
|
||||
});
|
||||
|
||||
const config = await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
analysisKindsInput: "code-quality",
|
||||
analysisKinds: [AnalysisKind.CodeQuality],
|
||||
languagesInput: languages,
|
||||
repository: { owner: "github", repo: "example" },
|
||||
tempDir,
|
||||
@@ -272,8 +273,9 @@ test("initActionState doesn't throw if there are queries configured in the repos
|
||||
|
||||
await t.notThrowsAsync(async () => {
|
||||
const config = await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
analysisKindsInput: "code-quality",
|
||||
analysisKinds: [AnalysisKind.CodeQuality],
|
||||
languagesInput: languages,
|
||||
repository: { owner: "github", repo: "example" },
|
||||
tempDir,
|
||||
@@ -310,6 +312,7 @@ test("loading a saved config produces the same config", async (t) => {
|
||||
t.deepEqual(await configUtils.getConfig(tempDir, logger), undefined);
|
||||
|
||||
const config1 = await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
languagesInput: "javascript,python",
|
||||
tempDir,
|
||||
@@ -361,6 +364,7 @@ test("loading config with version mismatch throws", async (t) => {
|
||||
.returns("does-not-exist");
|
||||
|
||||
const config = await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
languagesInput: "javascript,python",
|
||||
tempDir,
|
||||
@@ -389,6 +393,7 @@ test("load input outside of workspace", async (t) => {
|
||||
return await withTmpDir(async (tempDir) => {
|
||||
try {
|
||||
await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
configFile: "../input",
|
||||
tempDir,
|
||||
@@ -416,6 +421,7 @@ test("load non-local input with invalid repo syntax", async (t) => {
|
||||
|
||||
try {
|
||||
await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
configFile,
|
||||
tempDir,
|
||||
@@ -444,6 +450,7 @@ test("load non-existent input", async (t) => {
|
||||
|
||||
try {
|
||||
await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
languagesInput,
|
||||
configFile,
|
||||
@@ -527,6 +534,7 @@ test("load non-empty input", async (t) => {
|
||||
const configFilePath = createConfigFile(inputFileContents, tempDir);
|
||||
|
||||
const actualConfig = await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
languagesInput,
|
||||
buildModeInput: "none",
|
||||
@@ -583,6 +591,7 @@ test("Using config input and file together, config input should be used.", async
|
||||
const languagesInput = "javascript";
|
||||
|
||||
const config = await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
languagesInput,
|
||||
configFile: configFilePath,
|
||||
@@ -633,6 +642,7 @@ test("API client used when reading remote config", async (t) => {
|
||||
const languagesInput = "javascript";
|
||||
|
||||
await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
languagesInput,
|
||||
configFile,
|
||||
@@ -653,6 +663,7 @@ test("Remote config handles the case where a directory is provided", async (t) =
|
||||
const repoReference = "octo-org/codeql-config/config.yaml@main";
|
||||
try {
|
||||
await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
configFile: repoReference,
|
||||
tempDir,
|
||||
@@ -681,6 +692,7 @@ test("Invalid format of remote config handled correctly", async (t) => {
|
||||
const repoReference = "octo-org/codeql-config/config.yaml@main";
|
||||
try {
|
||||
await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
configFile: repoReference,
|
||||
tempDir,
|
||||
@@ -710,6 +722,7 @@ test("No detected languages", async (t) => {
|
||||
|
||||
try {
|
||||
await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
tempDir,
|
||||
codeql,
|
||||
@@ -732,6 +745,7 @@ test("Unknown languages", async (t) => {
|
||||
|
||||
try {
|
||||
await configUtils.initConfig(
|
||||
createFeatures([]),
|
||||
createTestInitConfigInputs({
|
||||
languagesInput,
|
||||
tempDir,
|
||||
|
||||
+37
-24
@@ -11,7 +11,6 @@ import {
|
||||
CodeQuality,
|
||||
codeQualityQueries,
|
||||
CodeScanning,
|
||||
parseAnalysisKinds,
|
||||
} from "./analyses";
|
||||
import * as api from "./api-client";
|
||||
import { CachingKind, getCachingKind } from "./caching-utils";
|
||||
@@ -20,6 +19,7 @@ import {
|
||||
calculateAugmentation,
|
||||
ExcludeQueryFilter,
|
||||
generateCodeScanningConfig,
|
||||
parseUserConfig,
|
||||
UserConfig,
|
||||
} from "./config/db-config";
|
||||
import { shouldPerformDiffInformedAnalysis } from "./diff-informed-analysis-utils";
|
||||
@@ -373,10 +373,8 @@ export async function getRawLanguages(
|
||||
|
||||
/** Inputs required to initialize a configuration. */
|
||||
export interface InitConfigInputs {
|
||||
analysisKindsInput: string;
|
||||
languagesInput: string | undefined;
|
||||
queriesInput: string | undefined;
|
||||
qualityQueriesInput: string | undefined;
|
||||
packsInput: string | undefined;
|
||||
configFile: string | undefined;
|
||||
dbLocation: string | undefined;
|
||||
@@ -396,6 +394,7 @@ export interface InitConfigInputs {
|
||||
apiDetails: api.GitHubApiCombinedDetails;
|
||||
features: FeatureEnablement;
|
||||
repositoryProperties: RepositoryProperties;
|
||||
analysisKinds: AnalysisKind[];
|
||||
logger: Logger;
|
||||
}
|
||||
|
||||
@@ -405,10 +404,8 @@ export interface InitConfigInputs {
|
||||
*/
|
||||
export async function initActionState(
|
||||
{
|
||||
analysisKindsInput,
|
||||
languagesInput,
|
||||
queriesInput,
|
||||
qualityQueriesInput,
|
||||
packsInput,
|
||||
buildModeInput,
|
||||
dbLocation,
|
||||
@@ -424,22 +421,11 @@ export async function initActionState(
|
||||
githubVersion,
|
||||
features,
|
||||
repositoryProperties,
|
||||
analysisKinds,
|
||||
logger,
|
||||
}: InitConfigInputs,
|
||||
userConfig: UserConfig,
|
||||
): Promise<Config> {
|
||||
const analysisKinds = await parseAnalysisKinds(analysisKindsInput);
|
||||
|
||||
// For backwards compatibility, add Code Quality to the enabled analysis kinds
|
||||
// if an input to `quality-queries` was specified. We should remove this once
|
||||
// `quality-queries` is no longer used.
|
||||
if (
|
||||
!analysisKinds.includes(AnalysisKind.CodeQuality) &&
|
||||
qualityQueriesInput !== undefined
|
||||
) {
|
||||
analysisKinds.push(AnalysisKind.CodeQuality);
|
||||
}
|
||||
|
||||
const languages = await getLanguages(
|
||||
codeql,
|
||||
languagesInput,
|
||||
@@ -540,10 +526,12 @@ async function downloadCacheWithTime(
|
||||
}
|
||||
|
||||
async function loadUserConfig(
|
||||
logger: Logger,
|
||||
configFile: string,
|
||||
workspacePath: string,
|
||||
apiDetails: api.GitHubApiCombinedDetails,
|
||||
tempDir: string,
|
||||
validateConfig: boolean,
|
||||
): Promise<UserConfig> {
|
||||
if (isLocal(configFile)) {
|
||||
if (configFile !== userConfigFromActionPath(tempDir)) {
|
||||
@@ -556,9 +544,14 @@ async function loadUserConfig(
|
||||
);
|
||||
}
|
||||
}
|
||||
return getLocalConfig(configFile);
|
||||
return getLocalConfig(logger, configFile, validateConfig);
|
||||
} else {
|
||||
return await getRemoteConfig(configFile, apiDetails);
|
||||
return await getRemoteConfig(
|
||||
logger,
|
||||
configFile,
|
||||
apiDetails,
|
||||
validateConfig,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -794,7 +787,10 @@ function hasQueryCustomisation(userConfig: UserConfig): boolean {
|
||||
* This will parse the config from the user input if present, or generate
|
||||
* a default config. The parsed config is then stored to a known location.
|
||||
*/
|
||||
export async function initConfig(inputs: InitConfigInputs): Promise<Config> {
|
||||
export async function initConfig(
|
||||
features: FeatureEnablement,
|
||||
inputs: InitConfigInputs,
|
||||
): Promise<Config> {
|
||||
const { logger, tempDir } = inputs;
|
||||
|
||||
// if configInput is set, it takes precedence over configFile
|
||||
@@ -814,11 +810,14 @@ export async function initConfig(inputs: InitConfigInputs): Promise<Config> {
|
||||
logger.debug("No configuration file was provided");
|
||||
} else {
|
||||
logger.debug(`Using configuration file: ${inputs.configFile}`);
|
||||
const validateConfig = await features.getValue(Feature.ValidateDbConfig);
|
||||
userConfig = await loadUserConfig(
|
||||
logger,
|
||||
inputs.configFile,
|
||||
inputs.workspacePath,
|
||||
inputs.apiDetails,
|
||||
tempDir,
|
||||
validateConfig,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -912,7 +911,11 @@ function isLocal(configPath: string): boolean {
|
||||
return configPath.indexOf("@") === -1;
|
||||
}
|
||||
|
||||
function getLocalConfig(configFile: string): UserConfig {
|
||||
function getLocalConfig(
|
||||
logger: Logger,
|
||||
configFile: string,
|
||||
validateConfig: boolean,
|
||||
): UserConfig {
|
||||
// Error if the file does not exist
|
||||
if (!fs.existsSync(configFile)) {
|
||||
throw new ConfigurationError(
|
||||
@@ -920,12 +923,19 @@ function getLocalConfig(configFile: string): UserConfig {
|
||||
);
|
||||
}
|
||||
|
||||
return yaml.load(fs.readFileSync(configFile, "utf8")) as UserConfig;
|
||||
return parseUserConfig(
|
||||
logger,
|
||||
configFile,
|
||||
fs.readFileSync(configFile, "utf-8"),
|
||||
validateConfig,
|
||||
);
|
||||
}
|
||||
|
||||
async function getRemoteConfig(
|
||||
logger: Logger,
|
||||
configFile: string,
|
||||
apiDetails: api.GitHubApiCombinedDetails,
|
||||
validateConfig: boolean,
|
||||
): Promise<UserConfig> {
|
||||
// retrieve the various parts of the config location, and ensure they're present
|
||||
const format = new RegExp(
|
||||
@@ -961,9 +971,12 @@ async function getRemoteConfig(
|
||||
);
|
||||
}
|
||||
|
||||
return yaml.load(
|
||||
return parseUserConfig(
|
||||
logger,
|
||||
configFile,
|
||||
Buffer.from(fileContents, "base64").toString("binary"),
|
||||
) as UserConfig;
|
||||
validateConfig,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,13 @@ import test, { ExecutionContext } from "ava";
|
||||
|
||||
import { RepositoryProperties } from "../feature-flags/properties";
|
||||
import { KnownLanguage, Language } from "../languages";
|
||||
import { prettyPrintPack } from "../util";
|
||||
import { getRunnerLogger } from "../logging";
|
||||
import {
|
||||
checkExpectedLogMessages,
|
||||
getRecordingLogger,
|
||||
LoggedMessage,
|
||||
} from "../testing-utils";
|
||||
import { ConfigurationError, prettyPrintPack } from "../util";
|
||||
|
||||
import * as dbConfig from "./db-config";
|
||||
|
||||
@@ -391,3 +397,111 @@ test(
|
||||
{},
|
||||
/"a-pack-without-a-scope" is not a valid pack/,
|
||||
);
|
||||
|
||||
test("parseUserConfig - successfully parses valid YAML", (t) => {
|
||||
const result = dbConfig.parseUserConfig(
|
||||
getRunnerLogger(true),
|
||||
"test",
|
||||
`
|
||||
paths-ignore:
|
||||
- "some/path"
|
||||
queries:
|
||||
- uses: foo
|
||||
some-unknown-option: true
|
||||
`,
|
||||
true,
|
||||
);
|
||||
t.truthy(result);
|
||||
if (t.truthy(result["paths-ignore"])) {
|
||||
t.is(result["paths-ignore"].length, 1);
|
||||
t.is(result["paths-ignore"][0], "some/path");
|
||||
}
|
||||
if (t.truthy(result["queries"])) {
|
||||
t.is(result["queries"].length, 1);
|
||||
t.deepEqual(result["queries"][0], { uses: "foo" });
|
||||
}
|
||||
});
|
||||
|
||||
test("parseUserConfig - throws a ConfigurationError if the file is not valid YAML", (t) => {
|
||||
t.throws(
|
||||
() =>
|
||||
dbConfig.parseUserConfig(
|
||||
getRunnerLogger(true),
|
||||
"test",
|
||||
`
|
||||
paths-ignore:
|
||||
- "some/path"
|
||||
queries:
|
||||
- foo
|
||||
`,
|
||||
true,
|
||||
),
|
||||
{
|
||||
instanceOf: ConfigurationError,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test("parseUserConfig - validation isn't picky about `query-filters`", (t) => {
|
||||
const loggedMessages: LoggedMessage[] = [];
|
||||
const logger = getRecordingLogger(loggedMessages);
|
||||
|
||||
t.notThrows(() =>
|
||||
dbConfig.parseUserConfig(
|
||||
logger,
|
||||
"test",
|
||||
`
|
||||
query-filters:
|
||||
- something
|
||||
- include: foo
|
||||
- exclude: bar
|
||||
`,
|
||||
true,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
test("parseUserConfig - throws a ConfigurationError if validation fails", (t) => {
|
||||
const loggedMessages: LoggedMessage[] = [];
|
||||
const logger = getRecordingLogger(loggedMessages);
|
||||
|
||||
t.throws(
|
||||
() =>
|
||||
dbConfig.parseUserConfig(
|
||||
logger,
|
||||
"test",
|
||||
`
|
||||
paths-ignore:
|
||||
- "some/path"
|
||||
queries: true
|
||||
`,
|
||||
true,
|
||||
),
|
||||
{
|
||||
instanceOf: ConfigurationError,
|
||||
message:
|
||||
'The configuration file "test" is invalid: instance.queries is not of a type(s) array.',
|
||||
},
|
||||
);
|
||||
|
||||
const expectedMessages = ["instance.queries is not of a type(s) array"];
|
||||
checkExpectedLogMessages(t, loggedMessages, expectedMessages);
|
||||
});
|
||||
|
||||
test("parseUserConfig - throws no ConfigurationError if validation should fail, but feature is disabled", (t) => {
|
||||
const loggedMessages: LoggedMessage[] = [];
|
||||
const logger = getRecordingLogger(loggedMessages);
|
||||
|
||||
t.notThrows(() =>
|
||||
dbConfig.parseUserConfig(
|
||||
logger,
|
||||
"test",
|
||||
`
|
||||
paths-ignore:
|
||||
- "some/path"
|
||||
queries: true
|
||||
`,
|
||||
false,
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import * as path from "path";
|
||||
|
||||
import * as yaml from "js-yaml";
|
||||
import * as jsonschema from "jsonschema";
|
||||
import * as semver from "semver";
|
||||
|
||||
import * as errorMessages from "../error-messages";
|
||||
@@ -474,3 +476,53 @@ export function generateCodeScanningConfig(
|
||||
|
||||
return augmentedConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to parse `contents` into a `UserConfig` value.
|
||||
*
|
||||
* @param logger The logger to use.
|
||||
* @param pathInput The path to the file where `contents` was obtained from, for use in error messages.
|
||||
* @param contents The string contents of a YAML file to try and parse as a `UserConfig`.
|
||||
* @param validateConfig Whether to validate the configuration file against the schema.
|
||||
* @returns The `UserConfig` corresponding to `contents`, if parsing was successful.
|
||||
* @throws A `ConfigurationError` if parsing failed.
|
||||
*/
|
||||
export function parseUserConfig(
|
||||
logger: Logger,
|
||||
pathInput: string,
|
||||
contents: string,
|
||||
validateConfig: boolean,
|
||||
): UserConfig {
|
||||
try {
|
||||
const schema =
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
require("../../src/db-config-schema.json") as jsonschema.Schema;
|
||||
|
||||
const doc = yaml.load(contents);
|
||||
|
||||
if (validateConfig) {
|
||||
const result = new jsonschema.Validator().validate(doc, schema);
|
||||
|
||||
if (result.errors.length > 0) {
|
||||
for (const error of result.errors) {
|
||||
logger.error(error.stack);
|
||||
}
|
||||
throw new ConfigurationError(
|
||||
errorMessages.getInvalidConfigFileMessage(
|
||||
pathInput,
|
||||
result.errors.map((e) => e.stack),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return doc as UserConfig;
|
||||
} catch (error) {
|
||||
if (error instanceof yaml.YAMLException) {
|
||||
throw new ConfigurationError(
|
||||
errorMessages.getConfigFileParseErrorMessage(pathInput, error.message),
|
||||
);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import test from "ava";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import { AnalysisKind } from "./analyses";
|
||||
import { GitHubApiDetails } from "./api-client";
|
||||
import * as apiClient from "./api-client";
|
||||
import { createStubCodeQL } from "./codeql";
|
||||
@@ -108,6 +109,39 @@ test("Abort database upload if 'upload-database' input set to false", async (t)
|
||||
});
|
||||
});
|
||||
|
||||
test("Abort database upload if 'analysis-kinds: code-scanning' is not enabled", async (t) => {
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
sinon
|
||||
.stub(actionsUtil, "getRequiredInput")
|
||||
.withArgs("upload-database")
|
||||
.returns("true");
|
||||
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
|
||||
|
||||
await mockHttpRequests(201);
|
||||
|
||||
const loggedMessages = [];
|
||||
await uploadDatabases(
|
||||
testRepoName,
|
||||
getCodeQL(),
|
||||
{
|
||||
...getTestConfig(tmpDir),
|
||||
analysisKinds: [AnalysisKind.CodeQuality],
|
||||
},
|
||||
testApiDetails,
|
||||
getRecordingLogger(loggedMessages),
|
||||
);
|
||||
t.assert(
|
||||
loggedMessages.find(
|
||||
(v: LoggedMessage) =>
|
||||
v.type === "debug" &&
|
||||
v.message ===
|
||||
"Not uploading database because 'analysis-kinds: code-scanning' is not enabled.",
|
||||
) !== undefined,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test("Abort database upload if running against GHES", async (t) => {
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as fs from "fs";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import { AnalysisKind } from "./analyses";
|
||||
import { getApiClient, GitHubApiDetails } from "./api-client";
|
||||
import { type CodeQL } from "./codeql";
|
||||
import { Config } from "./config-utils";
|
||||
@@ -22,6 +23,13 @@ export async function uploadDatabases(
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config.analysisKinds.includes(AnalysisKind.CodeScanning)) {
|
||||
logger.debug(
|
||||
`Not uploading database because 'analysis-kinds: ${AnalysisKind.CodeScanning}' is not enabled.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (util.isInTestMode()) {
|
||||
logger.debug("In test mode. Skipping database upload.");
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "CodeQL Database Configuration",
|
||||
"description": "Format of the config file supplied by the user for CodeQL analysis",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Name of the configuration"
|
||||
},
|
||||
"disable-default-queries": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to disable default queries"
|
||||
},
|
||||
"queries": {
|
||||
"type": "array",
|
||||
"description": "List of additional queries to run",
|
||||
"items": {
|
||||
"$ref": "#/definitions/QuerySpec"
|
||||
}
|
||||
},
|
||||
"paths-ignore": {
|
||||
"type": "array",
|
||||
"description": "Paths to ignore during analysis",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"paths": {
|
||||
"type": "array",
|
||||
"description": "Paths to include in analysis",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"packs": {
|
||||
"description": "Query packs to include. Can be a simple array for single-language analysis or an object with language-specific arrays for multi-language analysis",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"query-filters": {
|
||||
"type": "array",
|
||||
"description": "Set of query filters to include and exclude extra queries based on CodeQL query suite include and exclude properties",
|
||||
"items": {
|
||||
"$ref": "#/definitions/QueryFilter"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": true,
|
||||
"definitions": {
|
||||
"QuerySpec": {
|
||||
"type": "object",
|
||||
"description": "Detailed query specification object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Optional name for the query"
|
||||
},
|
||||
"uses": {
|
||||
"type": "string",
|
||||
"description": "The query or query suite to use"
|
||||
}
|
||||
},
|
||||
"required": ["uses"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"QueryFilter": {
|
||||
"description": "Query filter that can either include or exclude queries",
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ExcludeQueryFilter"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/IncludeQueryFilter"
|
||||
},
|
||||
{}
|
||||
]
|
||||
},
|
||||
"ExcludeQueryFilter": {
|
||||
"type": "object",
|
||||
"description": "Filter to exclude queries",
|
||||
"properties": {
|
||||
"exclude": {
|
||||
"type": "object",
|
||||
"description": "Queries to exclude",
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["exclude"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"IncludeQueryFilter": {
|
||||
"type": "object",
|
||||
"description": "Filter to include queries",
|
||||
"properties": {
|
||||
"include": {
|
||||
"type": "object",
|
||||
"description": "Queries to include",
|
||||
"additionalProperties": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["include"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"bundleVersion": "codeql-bundle-v2.23.2",
|
||||
"cliVersion": "2.23.2",
|
||||
"priorBundleVersion": "codeql-bundle-v2.23.1",
|
||||
"priorCliVersion": "2.23.1"
|
||||
"bundleVersion": "codeql-bundle-v2.23.3",
|
||||
"cliVersion": "2.23.3",
|
||||
"priorBundleVersion": "codeql-bundle-v2.23.2",
|
||||
"priorCliVersion": "2.23.2"
|
||||
}
|
||||
|
||||
@@ -47,6 +47,9 @@ export enum EnvVar {
|
||||
/** Whether the CodeQL Action has already warned the user about low disk space. */
|
||||
HAS_WARNED_ABOUT_DISK_SPACE = "CODEQL_ACTION_HAS_WARNED_ABOUT_DISK_SPACE",
|
||||
|
||||
/** Whether the `setup-codeql` action has been run. */
|
||||
SETUP_CODEQL_ACTION_HAS_RUN = "CODEQL_ACTION_SETUP_CODEQL_HAS_RUN",
|
||||
|
||||
/** Whether the init action has been run. */
|
||||
INIT_ACTION_HAS_RUN = "CODEQL_ACTION_INIT_HAS_RUN",
|
||||
|
||||
|
||||
@@ -14,6 +14,22 @@ export function getConfigFileDoesNotExistErrorMessage(
|
||||
return `The configuration file "${configFile}" does not exist`;
|
||||
}
|
||||
|
||||
export function getConfigFileParseErrorMessage(
|
||||
configFile: string,
|
||||
message: string,
|
||||
): string {
|
||||
return `Cannot parse "${configFile}": ${message}`;
|
||||
}
|
||||
|
||||
export function getInvalidConfigFileMessage(
|
||||
configFile: string,
|
||||
messages: string[],
|
||||
): string {
|
||||
const andMore =
|
||||
messages.length > 10 ? `, and ${messages.length - 10} more.` : ".";
|
||||
return `The configuration file "${configFile}" is invalid: ${messages.slice(0, 10).join(", ")}${andMore}`;
|
||||
}
|
||||
|
||||
export function getConfigFileRepoFormatInvalidMessage(
|
||||
configFile: string,
|
||||
): string {
|
||||
|
||||
@@ -77,6 +77,7 @@ export enum Feature {
|
||||
QaTelemetryEnabled = "qa_telemetry_enabled",
|
||||
ResolveSupportedLanguagesUsingCli = "resolve_supported_languages_using_cli",
|
||||
UseRepositoryProperties = "use_repository_properties",
|
||||
ValidateDbConfig = "validate_db_config",
|
||||
}
|
||||
|
||||
export const featureConfig: Record<
|
||||
@@ -287,6 +288,11 @@ export const featureConfig: Record<
|
||||
envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS",
|
||||
minimumVersion: "2.23.0",
|
||||
},
|
||||
[Feature.ValidateDbConfig]: {
|
||||
defaultValue: false,
|
||||
envVar: "CODEQL_ACTION_VALIDATE_DB_CONFIG",
|
||||
minimumVersion: undefined,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -651,12 +657,13 @@ class GitHubFeatureFlags {
|
||||
this.hasAccessedRemoteFeatureFlags = true;
|
||||
return remoteFlags;
|
||||
} catch (e) {
|
||||
if (util.isHTTPError(e) && e.status === 403) {
|
||||
const httpError = util.asHTTPError(e);
|
||||
if (httpError?.status === 403) {
|
||||
this.logger.warning(
|
||||
"This run of the CodeQL Action does not have permission to access Code Scanning API endpoints. " +
|
||||
"As a result, it will not be opted into any experimental features. " +
|
||||
"This could be because the Action is running on a pull request from a fork. If not, " +
|
||||
`please ensure the Action has the 'security-events: write' permission. Details: ${e.message}`,
|
||||
`please ensure the Action has the 'security-events: write' permission. Details: ${httpError.message}`,
|
||||
);
|
||||
this.hasAccessedRemoteFeatureFlags = false;
|
||||
return {};
|
||||
|
||||
@@ -2,6 +2,7 @@ import test, { ExecutionContext } from "ava";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import { AnalysisKind } from "./analyses";
|
||||
import * as codeql from "./codeql";
|
||||
import * as configUtils from "./config-utils";
|
||||
import { Feature } from "./feature-flags";
|
||||
@@ -28,12 +29,13 @@ test("post: init action with debug mode off", async (t) => {
|
||||
const gitHubVersion: util.GitHubVersion = {
|
||||
type: util.GitHubVariant.DOTCOM,
|
||||
};
|
||||
sinon.stub(configUtils, "getConfig").resolves({
|
||||
debugMode: false,
|
||||
gitHubVersion,
|
||||
languages: [],
|
||||
packs: [],
|
||||
} as unknown as configUtils.Config);
|
||||
sinon.stub(configUtils, "getConfig").resolves(
|
||||
createTestConfig({
|
||||
debugMode: false,
|
||||
gitHubVersion,
|
||||
languages: [],
|
||||
}),
|
||||
);
|
||||
|
||||
const uploadAllAvailableDebugArtifactsSpy = sinon.spy();
|
||||
const printDebugLogsSpy = sinon.spy();
|
||||
@@ -295,6 +297,17 @@ test("uploading failed SARIF run fails when workflow does not reference github/c
|
||||
t.truthy(result.upload_failed_run_stack_trace);
|
||||
});
|
||||
|
||||
test("not uploading failed SARIF when `code-scanning` is not an enabled analysis kind", async (t) => {
|
||||
const result = await testFailedSarifUpload(t, createTestWorkflow([]), {
|
||||
analysisKinds: [AnalysisKind.CodeQuality],
|
||||
expectUpload: false,
|
||||
});
|
||||
t.is(
|
||||
result.upload_failed_run_skipped_because,
|
||||
"Code Scanning is not enabled.",
|
||||
);
|
||||
});
|
||||
|
||||
function createTestWorkflow(
|
||||
steps: workflow.WorkflowJobStep[],
|
||||
): workflow.Workflow {
|
||||
@@ -327,20 +340,22 @@ async function testFailedSarifUpload(
|
||||
expectUpload = true,
|
||||
exportDiagnosticsEnabled = false,
|
||||
matrix = {},
|
||||
analysisKinds = [AnalysisKind.CodeScanning],
|
||||
}: {
|
||||
category?: string;
|
||||
databaseExists?: boolean;
|
||||
expectUpload?: boolean;
|
||||
exportDiagnosticsEnabled?: boolean;
|
||||
matrix?: { [key: string]: string };
|
||||
analysisKinds?: AnalysisKind[];
|
||||
} = {},
|
||||
): Promise<initActionPostHelper.UploadFailedSarifResult> {
|
||||
const config = {
|
||||
const config = createTestConfig({
|
||||
analysisKinds,
|
||||
codeQLCmd: "codeql",
|
||||
debugMode: true,
|
||||
languages: [],
|
||||
packs: [],
|
||||
} as unknown as configUtils.Config;
|
||||
});
|
||||
if (databaseExists) {
|
||||
config.dbLocation = "path/to/database";
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import * as actionsUtil from "./actions-util";
|
||||
import { CodeScanning } from "./analyses";
|
||||
import { getApiClient } from "./api-client";
|
||||
import { CodeQL, getCodeQL } from "./codeql";
|
||||
import { Config } from "./config-utils";
|
||||
import { Config, isCodeScanningEnabled } from "./config-utils";
|
||||
import * as dependencyCaching from "./dependency-caching";
|
||||
import { EnvVar } from "./environment";
|
||||
import { Feature, FeatureEnablement } from "./feature-flags";
|
||||
@@ -139,6 +139,15 @@ export async function tryUploadSarifIfRunFailed(
|
||||
EnvVar.JOB_STATUS,
|
||||
process.env[EnvVar.JOB_STATUS] ?? JobStatus.ConfigErrorStatus,
|
||||
);
|
||||
|
||||
// If the only enabled analysis kind is `code-quality`, then we shouldn't
|
||||
// upload the failed SARIF to Code Scanning.
|
||||
if (!isCodeScanningEnabled(config)) {
|
||||
return {
|
||||
upload_failed_run_skipped_because: "Code Scanning is not enabled.",
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
return await maybeUploadFailedSarif(
|
||||
config,
|
||||
|
||||
+52
-31
@@ -15,6 +15,7 @@ import {
|
||||
getTemporaryDirectory,
|
||||
persistInputs,
|
||||
} from "./actions-util";
|
||||
import { AnalysisKind, getAnalysisKinds } from "./analyses";
|
||||
import { getGitHubVersion } from "./api-client";
|
||||
import {
|
||||
getDependencyCachingEnabled,
|
||||
@@ -56,6 +57,7 @@ import { ToolsSource } from "./setup-codeql";
|
||||
import {
|
||||
ActionName,
|
||||
InitStatusReport,
|
||||
InitToolsDownloadFields,
|
||||
InitWithConfigStatusReport,
|
||||
createInitWithConfigStatusReport,
|
||||
createStatusReportBase,
|
||||
@@ -86,14 +88,29 @@ import {
|
||||
} from "./util";
|
||||
import { validateWorkflow } from "./workflow";
|
||||
|
||||
/** Fields of the init status report populated when the tools source is `download`. */
|
||||
interface InitToolsDownloadFields {
|
||||
/** Time taken to download the bundle, in milliseconds. */
|
||||
tools_download_duration_ms?: number;
|
||||
/**
|
||||
* Whether the relevant tools dotcom feature flags have been misconfigured.
|
||||
* Only populated if we attempt to determine the default version based on the dotcom feature flags. */
|
||||
tools_feature_flags_valid?: boolean;
|
||||
/**
|
||||
* Sends a status report indicating that the `init` Action is starting.
|
||||
*
|
||||
* @param startedAt
|
||||
* @param config
|
||||
* @param logger
|
||||
*/
|
||||
async function sendStartingStatusReport(
|
||||
startedAt: Date,
|
||||
config: Partial<configUtils.Config> | undefined,
|
||||
logger: Logger,
|
||||
) {
|
||||
const statusReportBase = await createStatusReportBase(
|
||||
ActionName.Init,
|
||||
"starting",
|
||||
startedAt,
|
||||
config,
|
||||
await checkDiskUsage(logger),
|
||||
logger,
|
||||
);
|
||||
if (statusReportBase !== undefined) {
|
||||
await sendStatusReport(statusReportBase);
|
||||
}
|
||||
}
|
||||
|
||||
async function sendCompletedStatusReport(
|
||||
@@ -210,6 +227,7 @@ async function run() {
|
||||
? await loadPropertiesFromApi(gitHubVersion, logger, repositoryNwo)
|
||||
: {};
|
||||
|
||||
// Create a unique identifier for this run.
|
||||
const jobRunUuid = uuidV4();
|
||||
logger.info(`Job run UUID is ${jobRunUuid}.`);
|
||||
core.exportVariable(EnvVar.JOB_RUN_UUID, jobRunUuid);
|
||||
@@ -227,17 +245,30 @@ async function run() {
|
||||
);
|
||||
|
||||
try {
|
||||
const statusReportBase = await createStatusReportBase(
|
||||
ActionName.Init,
|
||||
"starting",
|
||||
startedAt,
|
||||
config,
|
||||
await checkDiskUsage(logger),
|
||||
logger,
|
||||
);
|
||||
if (statusReportBase !== undefined) {
|
||||
await sendStatusReport(statusReportBase);
|
||||
// Parsing the `analysis-kinds` input may throw a `ConfigurationError`, which we don't want before
|
||||
// we have called `sendStartingStatusReport` below. However, we want the analysis kinds for that status
|
||||
// report. To work around this, we ignore exceptions that are thrown here and then call `getAnalysisKinds`
|
||||
// a second time later. The second call will then throw the exception again. If `getAnalysisKinds` is
|
||||
// successful, the results are cached so that we don't duplicate the work in normal runs.
|
||||
let analysisKinds: AnalysisKind[] | undefined;
|
||||
try {
|
||||
analysisKinds = await getAnalysisKinds(logger);
|
||||
} catch (err) {
|
||||
logger.debug(
|
||||
`Failed to parse analysis kinds for 'starting' status report: ${getErrorMessage(err)}`,
|
||||
);
|
||||
}
|
||||
|
||||
// Send a status report indicating that an analysis is starting.
|
||||
await sendStartingStatusReport(startedAt, { analysisKinds }, logger);
|
||||
|
||||
// Throw a `ConfigurationError` if the `setup-codeql` action has been run.
|
||||
if (process.env[EnvVar.SETUP_CODEQL_ACTION_HAS_RUN] === "true") {
|
||||
throw new ConfigurationError(
|
||||
`The 'init' action should not be run in the same workflow as 'setup-codeql'.`,
|
||||
);
|
||||
}
|
||||
|
||||
const codeQLDefaultVersionInfo = await features.getDefaultCliVersion(
|
||||
gitHubVersion.type,
|
||||
);
|
||||
@@ -293,21 +324,11 @@ async function run() {
|
||||
}
|
||||
}
|
||||
|
||||
// Warn that `quality-queries` is deprecated if there is an argument for it.
|
||||
const qualityQueriesInput = getOptionalInput("quality-queries");
|
||||
|
||||
if (qualityQueriesInput !== undefined) {
|
||||
logger.warning(
|
||||
"The `quality-queries` input is deprecated and will be removed in a future version of the CodeQL Action. " +
|
||||
"Use the `analysis-kinds` input to configure different analysis kinds instead.",
|
||||
);
|
||||
}
|
||||
|
||||
config = await initConfig({
|
||||
analysisKindsInput: getRequiredInput("analysis-kinds"),
|
||||
analysisKinds = await getAnalysisKinds(logger);
|
||||
config = await initConfig(features, {
|
||||
analysisKinds,
|
||||
languagesInput: getOptionalInput("languages"),
|
||||
queriesInput: getOptionalInput("queries"),
|
||||
qualityQueriesInput,
|
||||
packsInput: getOptionalInput("packs"),
|
||||
buildModeInput: getOptionalInput("build-mode"),
|
||||
configFile,
|
||||
|
||||
+2
-1
@@ -61,10 +61,11 @@ export async function initCodeQL(
|
||||
}
|
||||
|
||||
export async function initConfig(
|
||||
features: FeatureEnablement,
|
||||
inputs: configUtils.InitConfigInputs,
|
||||
): Promise<configUtils.Config> {
|
||||
return await withGroupAsync("Load language configuration", async () => {
|
||||
return await configUtils.initConfig(inputs);
|
||||
return await configUtils.initConfig(features, inputs);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
import * as core from "@actions/core";
|
||||
import { v4 as uuidV4 } from "uuid";
|
||||
|
||||
import {
|
||||
getActionVersion,
|
||||
getOptionalInput,
|
||||
getRequiredInput,
|
||||
getTemporaryDirectory,
|
||||
} from "./actions-util";
|
||||
import { getGitHubVersion } from "./api-client";
|
||||
import { CodeQL } from "./codeql";
|
||||
import { EnvVar } from "./environment";
|
||||
import { Features } from "./feature-flags";
|
||||
import { initCodeQL } from "./init";
|
||||
import { getActionsLogger, Logger } from "./logging";
|
||||
import { getRepositoryNwo } from "./repository";
|
||||
import { ToolsSource } from "./setup-codeql";
|
||||
import {
|
||||
ActionName,
|
||||
InitStatusReport,
|
||||
InitToolsDownloadFields,
|
||||
createStatusReportBase,
|
||||
getActionsStatus,
|
||||
sendStatusReport,
|
||||
} from "./status-report";
|
||||
import { ToolsDownloadStatusReport } from "./tools-download";
|
||||
import {
|
||||
checkDiskUsage,
|
||||
checkForTimeout,
|
||||
checkGitHubVersionInRange,
|
||||
getRequiredEnvParam,
|
||||
initializeEnvironment,
|
||||
ConfigurationError,
|
||||
wrapError,
|
||||
checkActionVersion,
|
||||
getErrorMessage,
|
||||
} from "./util";
|
||||
|
||||
/**
|
||||
* Helper function to send a full status report for this action.
|
||||
*/
|
||||
async function sendCompletedStatusReport(
|
||||
startedAt: Date,
|
||||
toolsDownloadStatusReport: ToolsDownloadStatusReport | undefined,
|
||||
toolsFeatureFlagsValid: boolean | undefined,
|
||||
toolsSource: ToolsSource,
|
||||
toolsVersion: string,
|
||||
logger: Logger,
|
||||
error?: Error,
|
||||
): Promise<void> {
|
||||
const statusReportBase = await createStatusReportBase(
|
||||
ActionName.SetupCodeQL,
|
||||
getActionsStatus(error),
|
||||
startedAt,
|
||||
undefined,
|
||||
await checkDiskUsage(logger),
|
||||
logger,
|
||||
error?.message,
|
||||
error?.stack,
|
||||
);
|
||||
|
||||
if (statusReportBase === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const initStatusReport: InitStatusReport = {
|
||||
...statusReportBase,
|
||||
tools_input: getOptionalInput("tools") || "",
|
||||
tools_resolved_version: toolsVersion,
|
||||
tools_source: toolsSource || ToolsSource.Unknown,
|
||||
workflow_languages: "",
|
||||
};
|
||||
|
||||
const initToolsDownloadFields: InitToolsDownloadFields = {};
|
||||
|
||||
if (toolsDownloadStatusReport?.downloadDurationMs !== undefined) {
|
||||
initToolsDownloadFields.tools_download_duration_ms =
|
||||
toolsDownloadStatusReport.downloadDurationMs;
|
||||
}
|
||||
if (toolsFeatureFlagsValid !== undefined) {
|
||||
initToolsDownloadFields.tools_feature_flags_valid = toolsFeatureFlagsValid;
|
||||
}
|
||||
|
||||
await sendStatusReport({ ...initStatusReport, ...initToolsDownloadFields });
|
||||
}
|
||||
|
||||
/** The main behaviour of this action. */
|
||||
async function run(): Promise<void> {
|
||||
const startedAt = new Date();
|
||||
const logger = getActionsLogger();
|
||||
initializeEnvironment(getActionVersion());
|
||||
|
||||
let codeql: CodeQL;
|
||||
let toolsDownloadStatusReport: ToolsDownloadStatusReport | undefined;
|
||||
let toolsFeatureFlagsValid: boolean | undefined;
|
||||
let toolsSource: ToolsSource;
|
||||
let toolsVersion: string;
|
||||
|
||||
const apiDetails = {
|
||||
auth: getRequiredInput("token"),
|
||||
externalRepoAuth: getOptionalInput("external-repository-token"),
|
||||
url: getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||
apiURL: getRequiredEnvParam("GITHUB_API_URL"),
|
||||
};
|
||||
|
||||
const gitHubVersion = await getGitHubVersion();
|
||||
checkGitHubVersionInRange(gitHubVersion, logger);
|
||||
checkActionVersion(getActionVersion(), gitHubVersion);
|
||||
|
||||
const repositoryNwo = getRepositoryNwo();
|
||||
|
||||
const features = new Features(
|
||||
gitHubVersion,
|
||||
repositoryNwo,
|
||||
getTemporaryDirectory(),
|
||||
logger,
|
||||
);
|
||||
|
||||
const jobRunUuid = uuidV4();
|
||||
logger.info(`Job run UUID is ${jobRunUuid}.`);
|
||||
core.exportVariable(EnvVar.JOB_RUN_UUID, jobRunUuid);
|
||||
|
||||
try {
|
||||
const statusReportBase = await createStatusReportBase(
|
||||
ActionName.SetupCodeQL,
|
||||
"starting",
|
||||
startedAt,
|
||||
undefined,
|
||||
await checkDiskUsage(logger),
|
||||
logger,
|
||||
);
|
||||
if (statusReportBase !== undefined) {
|
||||
await sendStatusReport(statusReportBase);
|
||||
}
|
||||
const codeQLDefaultVersionInfo = await features.getDefaultCliVersion(
|
||||
gitHubVersion.type,
|
||||
);
|
||||
toolsFeatureFlagsValid = codeQLDefaultVersionInfo.toolsFeatureFlagsValid;
|
||||
const initCodeQLResult = await initCodeQL(
|
||||
getOptionalInput("tools"),
|
||||
apiDetails,
|
||||
getTemporaryDirectory(),
|
||||
gitHubVersion.type,
|
||||
codeQLDefaultVersionInfo,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
codeql = initCodeQLResult.codeql;
|
||||
toolsDownloadStatusReport = initCodeQLResult.toolsDownloadStatusReport;
|
||||
toolsVersion = initCodeQLResult.toolsVersion;
|
||||
toolsSource = initCodeQLResult.toolsSource;
|
||||
|
||||
core.setOutput("codeql-path", codeql.getPath());
|
||||
core.setOutput("codeql-version", (await codeql.getVersion()).version);
|
||||
|
||||
core.exportVariable(EnvVar.SETUP_CODEQL_ACTION_HAS_RUN, "true");
|
||||
} catch (unwrappedError) {
|
||||
const error = wrapError(unwrappedError);
|
||||
core.setFailed(error.message);
|
||||
const statusReportBase = await createStatusReportBase(
|
||||
ActionName.SetupCodeQL,
|
||||
error instanceof ConfigurationError ? "user-error" : "failure",
|
||||
startedAt,
|
||||
undefined,
|
||||
await checkDiskUsage(logger),
|
||||
logger,
|
||||
error.message,
|
||||
error.stack,
|
||||
);
|
||||
if (statusReportBase !== undefined) {
|
||||
await sendStatusReport(statusReportBase);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
await sendCompletedStatusReport(
|
||||
startedAt,
|
||||
toolsDownloadStatusReport,
|
||||
toolsFeatureFlagsValid,
|
||||
toolsSource,
|
||||
toolsVersion,
|
||||
logger,
|
||||
);
|
||||
}
|
||||
|
||||
/** Run the action and catch any unhandled errors. */
|
||||
async function runWrapper(): Promise<void> {
|
||||
try {
|
||||
await run();
|
||||
} catch (error) {
|
||||
core.setFailed(`setup-codeql action failed: ${getErrorMessage(error)}`);
|
||||
}
|
||||
await checkForTimeout();
|
||||
}
|
||||
|
||||
void runWrapper();
|
||||
+17
-5
@@ -23,7 +23,6 @@ import { getRepositoryNwo } from "./repository";
|
||||
import { ToolsSource } from "./setup-codeql";
|
||||
import {
|
||||
ConfigurationError,
|
||||
isHTTPError,
|
||||
getRequiredEnvParam,
|
||||
getCachedCodeQlVersion,
|
||||
isInTestMode,
|
||||
@@ -33,6 +32,7 @@ import {
|
||||
BuildMode,
|
||||
getErrorMessage,
|
||||
getTestingEnvironment,
|
||||
asHTTPError,
|
||||
} from "./util";
|
||||
|
||||
export enum ActionName {
|
||||
@@ -41,6 +41,7 @@ export enum ActionName {
|
||||
Init = "init",
|
||||
InitPost = "init-post",
|
||||
ResolveEnvironment = "resolve-environment",
|
||||
SetupCodeQL = "setup-codeql",
|
||||
StartProxy = "start-proxy",
|
||||
UploadSarif = "upload-sarif",
|
||||
}
|
||||
@@ -428,8 +429,9 @@ export async function sendStatusReport<S extends StatusReportBase>(
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
if (isHTTPError(e)) {
|
||||
switch (e.status) {
|
||||
const httpError = asHTTPError(e);
|
||||
if (httpError !== undefined) {
|
||||
switch (httpError.status) {
|
||||
case 403:
|
||||
if (
|
||||
getWorkflowEventName() === "push" &&
|
||||
@@ -442,11 +444,11 @@ export async function sendStatusReport<S extends StatusReportBase>(
|
||||
`See ${DocUrl.SCANNING_ON_PUSH} for more information on how to configure these events.`,
|
||||
);
|
||||
} else {
|
||||
core.warning(e.message);
|
||||
core.warning(httpError.message);
|
||||
}
|
||||
return;
|
||||
case 404:
|
||||
core.warning(e.message);
|
||||
core.warning(httpError.message);
|
||||
return;
|
||||
case 422:
|
||||
// schema incompatibility when reporting status
|
||||
@@ -516,6 +518,16 @@ export interface InitWithConfigStatusReport extends InitStatusReport {
|
||||
config_file: string;
|
||||
}
|
||||
|
||||
/** Fields of the init status report populated when the tools source is `download`. */
|
||||
export interface InitToolsDownloadFields {
|
||||
/** Time taken to download the bundle, in milliseconds. */
|
||||
tools_download_duration_ms?: number;
|
||||
/**
|
||||
* Whether the relevant tools dotcom feature flags have been misconfigured.
|
||||
* Only populated if we attempt to determine the default version based on the dotcom feature flags. */
|
||||
tools_feature_flags_valid?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Composes a `InitWithConfigStatusReport` from the given values.
|
||||
*
|
||||
|
||||
+18
-1
@@ -2,7 +2,7 @@ import { TextDecoder } from "node:util";
|
||||
import path from "path";
|
||||
|
||||
import * as github from "@actions/github";
|
||||
import { TestFn } from "ava";
|
||||
import { ExecutionContext, TestFn } from "ava";
|
||||
import nock from "nock";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
@@ -180,6 +180,23 @@ export function getRecordingLogger(messages: LoggedMessage[]): Logger {
|
||||
};
|
||||
}
|
||||
|
||||
export function checkExpectedLogMessages(
|
||||
t: ExecutionContext<any>,
|
||||
messages: LoggedMessage[],
|
||||
expectedMessages: string[],
|
||||
) {
|
||||
for (const expectedMessage of expectedMessages) {
|
||||
t.assert(
|
||||
messages.some(
|
||||
(msg) =>
|
||||
typeof msg.message === "string" &&
|
||||
msg.message.includes(expectedMessage),
|
||||
),
|
||||
`Expected '${expectedMessage}' in the logger output, but didn't find it in:\n ${messages.map((m) => ` - '${m.message}'`).join("\n")}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/** Mock the HTTP request to the feature flags enablement API endpoint. */
|
||||
export function mockFeatureFlagApiEndpoint(
|
||||
responseStatusCode: number,
|
||||
|
||||
+2
-2
@@ -13,8 +13,8 @@ import * as gitUtils from "./git-utils";
|
||||
import { Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import {
|
||||
asHTTPError,
|
||||
getErrorMessage,
|
||||
isHTTPError,
|
||||
tryGetFolderBytes,
|
||||
waitForResultWithTimeLimit,
|
||||
} from "./util";
|
||||
@@ -236,7 +236,7 @@ export async function cleanupTrapCaches(
|
||||
}
|
||||
return { trap_cache_cleanup_size_bytes: totalBytesCleanedUp };
|
||||
} catch (e) {
|
||||
if (isHTTPError(e) && e.status === 403) {
|
||||
if (asHTTPError(e)?.status === 403) {
|
||||
logger.warning(
|
||||
"Could not cleanup TRAP caches as the token did not have the required permissions. " +
|
||||
'To clean up TRAP caches, ensure the token has the "actions:write" permission. ' +
|
||||
|
||||
+6
-5
@@ -386,16 +386,17 @@ export async function uploadPayload(
|
||||
logger.info("Successfully uploaded results");
|
||||
return response.data.id as string;
|
||||
} catch (e) {
|
||||
if (util.isHTTPError(e)) {
|
||||
switch (e.status) {
|
||||
const httpError = util.asHTTPError(e);
|
||||
if (httpError !== undefined) {
|
||||
switch (httpError.status) {
|
||||
case 403:
|
||||
core.warning(e.message || GENERIC_403_MSG);
|
||||
core.warning(httpError.message || GENERIC_403_MSG);
|
||||
break;
|
||||
case 404:
|
||||
core.warning(e.message || GENERIC_404_MSG);
|
||||
core.warning(httpError.message || GENERIC_404_MSG);
|
||||
break;
|
||||
default:
|
||||
core.warning(e.message);
|
||||
core.warning(httpError.message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+16
-2
@@ -692,8 +692,22 @@ export class ConfigurationError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
export function isHTTPError(arg: any): arg is HTTPError {
|
||||
return arg?.status !== undefined && Number.isInteger(arg.status);
|
||||
export function asHTTPError(arg: any): HTTPError | undefined {
|
||||
if (
|
||||
typeof arg !== "object" ||
|
||||
arg === null ||
|
||||
typeof arg.message !== "string"
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
if (Number.isInteger(arg.status)) {
|
||||
return new HTTPError(arg.message as string, arg.status as number);
|
||||
}
|
||||
// See https://github.com/actions/toolkit/blob/acb230b99a46ed33a3f04a758cd68b47b9a82908/packages/tool-cache/src/tool-cache.ts#L19
|
||||
if (Number.isInteger(arg.httpStatusCode)) {
|
||||
return new HTTPError(arg.message as string, arg.httpStatusCode as number);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let cachedCodeQlVersion: undefined | VersionInfo = undefined;
|
||||
|
||||
Reference in New Issue
Block a user