Compare commits

..

1 Commits

Author SHA1 Message Date
Michael B. Gale
1cf30a546e Add global.json 2025-11-13 19:18:54 +00:00
89 changed files with 7134 additions and 7507 deletions

View File

@@ -18,25 +18,14 @@ For internal use only. Please select the risk level of this change:
#### Which use cases does this change impact?
<!-- Delete options that don't apply. If in doubt, do not delete an option. -->
<!-- Delete options that don't apply. -->
Workflow types:
- **Advanced setup** - Impacts users who have custom CodeQL workflows.
- **Managed** - Impacts users with `dynamic` workflows (Default Setup, CCR, ...).
Products:
- **Code Scanning** - The changes impact analyses when `analysis-kinds: code-scanning`.
- **Code Quality** - The changes impact analyses when `analysis-kinds: code-quality`.
- **CCR** - The changes impact analyses for Copilot Code Reviews.
- **Third-party analyses** - The changes affect the `upload-sarif` action.
Environments:
- **Dotcom** - Impacts CodeQL workflows on `github.com`.
- **GHES** - Impacts CodeQL workflows on GitHub Enterprise Server.
- **Testing/None** - This change does not impact any CodeQL workflows in production.
- **Advanced setup** - Impacts users who have custom workflows.
- **Default setup** - Impacts users who use default setup.
- **Code Scanning** - Impacts Code Scanning (i.e. `analysis-kinds: code-scanning`).
- **Code Quality** - Impacts Code Quality (i.e. `analysis-kinds: code-quality`).
- **Third-party analyses** - Impacts third-party analyses (i.e. `upload-sarif`).
- **GHES** - Impacts GitHub Enterprise Server.
#### How did/will you validate this change?
@@ -65,15 +54,6 @@ Environments:
- **Alerts** - New or existing monitors will trip if something goes wrong with this change.
- **Other** - Please provide details.
#### Are there any special considerations for merging or releasing this change?
<!--
Consider whether this change depends on a different change in another repository that should be released first.
-->
- **No special considerations** - This change can be merged at any time.
- **Special considerations** - This change should only be merged once certain preconditions are met. Please provide details of those or link to this PR from an internal issue.
### Merge / deployment checklist
- Confirm this change is backwards compatible with existing workflows.

View File

@@ -27,11 +27,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -39,11 +34,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -84,10 +74,6 @@ jobs:
with:
go-version: ${{ inputs.go-version || '>=1.21.0' }}
cache: false
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- id: init
uses: ./../action/init
with:

View File

@@ -32,11 +32,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -49,11 +44,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -95,10 +85,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python-version || '3.13' }}
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- uses: ./../action/init
with:
tools: ${{ steps.prepare-test.outputs.tools-url }}

View File

@@ -21,19 +21,9 @@ on:
schedule:
- cron: '0 5 * * *'
workflow_dispatch:
inputs:
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
inputs: {}
workflow_call:
inputs:
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
inputs: {}
defaults:
run:
shell: bash
@@ -69,10 +59,6 @@ jobs:
version: ${{ matrix.version }}
use-all-platform-bundle: 'false'
setup-kotlin: 'true'
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- uses: ./../action/init
with:
languages: csharp

View File

@@ -27,11 +27,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -39,11 +34,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -80,10 +70,6 @@ jobs:
with:
go-version: ${{ inputs.go-version || '>=1.21.0' }}
cache: false
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- uses: ./../action/init
id: init
with:

View File

@@ -27,11 +27,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -39,11 +34,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -84,10 +74,6 @@ jobs:
with:
go-version: ${{ inputs.go-version || '>=1.21.0' }}
cache: false
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- uses: ./../action/init
id: init
with:

View File

@@ -27,11 +27,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -39,11 +34,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -82,10 +72,6 @@ jobs:
with:
go-version: ${{ inputs.go-version || '>=1.21.0' }}
cache: false
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- uses: ./../action/init
with:
languages: go

6
.github/workflows/__go.yml generated vendored
View File

@@ -18,11 +18,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
jobs:
go-custom-queries:
name: 'Go: Custom queries'
@@ -32,7 +27,6 @@ jobs:
uses: ./.github/workflows/__go-custom-queries.yml
with:
go-version: ${{ inputs.go-version }}
dotnet-version: ${{ inputs.dotnet-version }}
go-indirect-tracing-workaround-diagnostic:
name: 'Go: diagnostic when Go is changed after init step'
permissions:

14
.github/workflows/__local-bundle.yml generated vendored
View File

@@ -32,11 +32,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -49,11 +44,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -95,10 +85,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python-version || '3.13' }}
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- name: Fetch latest CodeQL bundle
run: |
wget https://github.com/github/codeql-action/releases/latest/download/codeql-bundle-linux64.tar.zst

View File

@@ -32,11 +32,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -49,11 +44,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -129,10 +119,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python-version || '3.13' }}
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- name: Use Xcode 16
if: runner.os == 'macOS' && matrix.version != 'nightly-latest'
run: sudo xcode-select -s "/Applications/Xcode_16.app"

View File

@@ -32,11 +32,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -49,11 +44,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -106,10 +96,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python-version || '3.13' }}
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- uses: ./../action/init
with:
config-file: .github/codeql/codeql-config-packaging3.yml

View File

@@ -27,11 +27,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -39,11 +34,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -91,10 +81,6 @@ jobs:
with:
go-version: ${{ inputs.go-version || '>=1.21.0' }}
cache: false
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- uses: ./../action/init
with:
config-file: .github/codeql/codeql-config-packaging3.yml

View File

@@ -27,11 +27,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -39,11 +34,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -91,10 +81,6 @@ jobs:
with:
go-version: ${{ inputs.go-version || '>=1.21.0' }}
cache: false
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- uses: ./../action/init
with:
config-file: .github/codeql/codeql-config-packaging.yml

View File

@@ -27,11 +27,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -39,11 +34,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -91,10 +81,6 @@ jobs:
with:
go-version: ${{ inputs.go-version || '>=1.21.0' }}
cache: false
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- uses: ./../action/init
with:
config-file: .github/codeql/codeql-config-packaging2.yml

View File

@@ -32,11 +32,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -49,11 +44,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -97,10 +87,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python-version || '3.13' }}
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- uses: ./../action/init
with:
tools: ${{ steps.prepare-test.outputs.tools-url }}

View File

@@ -56,7 +56,7 @@ jobs:
use-all-platform-bundle: 'false'
setup-kotlin: 'true'
- name: Set up Ruby
uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0
uses: ruby/setup-ruby@d5126b9b3579e429dd52e51e68624dda2e05be25 # v1.267.0
with:
ruby-version: 2.6
- name: Install Code Scanning integration

View File

@@ -27,11 +27,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -39,11 +34,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -90,10 +80,6 @@ jobs:
with:
go-version: ${{ inputs.go-version || '>=1.21.0' }}
cache: false
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- uses: ./../action/init
with:
config-file: .github/codeql/codeql-config-packaging3.yml

View File

@@ -27,11 +27,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -39,11 +34,6 @@ on:
description: The version of Go to install
required: false
default: '>=1.21.0'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -84,10 +74,6 @@ jobs:
with:
go-version: ${{ inputs.go-version || '>=1.21.0' }}
cache: false
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- name: Use Xcode 16
if: runner.os == 'macOS' && matrix.version != 'nightly-latest'
run: sudo xcode-select -s "/Applications/Xcode_16.app"

View File

@@ -32,11 +32,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -49,11 +44,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -97,10 +87,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python-version || '3.13' }}
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- uses: ./../action/init
id: init
with:

View File

@@ -32,11 +32,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -49,11 +44,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -95,10 +85,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python-version || '3.13' }}
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- uses: ./../action/init
with:
tools: ${{ steps.prepare-test.outputs.tools-url }}

14
.github/workflows/__upload-sarif.yml generated vendored
View File

@@ -32,11 +32,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -49,11 +44,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -102,10 +92,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python-version || '3.13' }}
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- uses: ./../action/init
with:
tools: ${{ steps.prepare-test.outputs.tools-url }}

View File

@@ -32,11 +32,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
workflow_call:
inputs:
go-version:
@@ -49,11 +44,6 @@ on:
description: The version of Python to install
required: false
default: '3.13'
dotnet-version:
type: string
description: The version of .NET to install
required: false
default: 9.x
defaults:
run:
shell: bash
@@ -95,10 +85,6 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python-version || '3.13' }}
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version || '9.x' }}
- name: Delete original checkout
run: |
# delete the original checkout so we don't accidentally use it.

View File

@@ -54,10 +54,6 @@ jobs:
- uses: actions/setup-go@v6
with:
go-version: ^1.13.1
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: '9.x'
- uses: ./../action/init
with:
tools: ${{ steps.prepare-test.outputs.tools-url }}

View File

@@ -50,10 +50,6 @@ jobs:
- uses: actions/setup-go@v6
with:
go-version: ^1.13.1
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: '9.x'
- uses: ./../action/init
id: init
with:

View File

@@ -43,10 +43,6 @@ jobs:
with:
version: ${{ matrix.version }}
use-all-platform-bundle: true
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: '9.x'
- id: init
uses: ./../action/init
with:

View File

@@ -4,16 +4,7 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th
## [UNRELEASED]
No user facing changes.
## 4.31.4 - 18 Nov 2025
No user facing changes.
## 4.31.3 - 13 Nov 2025
- CodeQL Action v3 will be deprecated in December 2026. The Action now logs a warning for customers who are running v3 but could be running v4. For more information, see [Upcoming deprecation of CodeQL Action v3](https://github.blog/changelog/2025-10-28-upcoming-deprecation-of-codeql-action-v3/).
- Update default CodeQL bundle version to 2.23.5. [#3288](https://github.com/github/codeql-action/pull/3288)
## 4.31.2 - 30 Oct 2025

File diff suppressed because it is too large Load Diff

840
lib/analyze-action.js generated

File diff suppressed because it is too large Load Diff

756
lib/autobuild-action.js generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"bundleVersion": "codeql-bundle-v2.23.5",
"cliVersion": "2.23.5",
"priorBundleVersion": "codeql-bundle-v2.23.3",
"priorCliVersion": "2.23.3"
"bundleVersion": "codeql-bundle-v2.23.3",
"cliVersion": "2.23.3",
"priorBundleVersion": "codeql-bundle-v2.23.2",
"priorCliVersion": "2.23.2"
}

1465
lib/init-action-post.js generated

File diff suppressed because it is too large Load Diff

871
lib/init-action.js generated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1268
lib/start-proxy-action.js generated

File diff suppressed because it is too large Load Diff

750
lib/upload-lib.js generated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

894
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "codeql",
"version": "4.31.5",
"version": "4.31.3",
"private": true,
"description": "CodeQL action",
"scripts": {
@@ -35,21 +35,23 @@
"@actions/io": "^2.0.0",
"@actions/tool-cache": "^2.0.2",
"@octokit/plugin-retry": "^6.0.0",
"@octokit/request-error": "^7.0.2",
"@schemastore/package": "0.0.10",
"archiver": "^7.0.1",
"fast-deep-equal": "^3.1.3",
"follow-redirects": "^1.15.11",
"get-folder-size": "^5.0.0",
"js-yaml": "^4.1.1",
"js-yaml": "^4.1.0",
"jsonschema": "1.4.1",
"long": "^5.3.2",
"node-forge": "^1.3.1",
"octokit": "^5.0.5",
"semver": "^7.7.3",
"uuid": "^13.0.0"
},
"devDependencies": {
"@ava/typescript": "6.0.0",
"@eslint/compat": "^2.0.0",
"@eslint/compat": "^1.4.1",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.39.1",
"@microsoft/eslint-formatter-sarif": "^3.1.0",
@@ -57,10 +59,10 @@
"@types/archiver": "^7.0.0",
"@types/follow-redirects": "^1.14.4",
"@types/js-yaml": "^4.0.9",
"@types/node": "^20.19.9",
"@types/node": "20.19.9",
"@types/node-forge": "^1.3.14",
"@types/semver": "^7.7.1",
"@types/sinon": "^21.0.0",
"@types/sinon": "^17.0.4",
"@typescript-eslint/eslint-plugin": "^8.46.4",
"@typescript-eslint/parser": "^8.41.0",
"ava": "^6.4.1",
@@ -70,9 +72,9 @@
"eslint-plugin-filenames": "^1.3.2",
"eslint-plugin-github": "^5.1.8",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-jsdoc": "^61.2.1",
"eslint-plugin-jsdoc": "^61.1.12",
"eslint-plugin-no-async-foreach": "^0.1.1",
"glob": "^11.1.0",
"glob": "^11.0.3",
"nock": "^14.0.10",
"sinon": "^21.0.0",
"typescript": "^5.9.3"
@@ -96,7 +98,6 @@
"eslint-plugin-jsx-a11y": {
"semver": ">=6.3.1"
},
"brace-expansion@2.0.1": "2.0.2",
"glob": "^11.1.0"
"brace-expansion@2.0.1": "2.0.2"
}
}

View File

@@ -4,7 +4,6 @@ operatingSystems: ["ubuntu", "macos", "windows"]
versions: ["nightly-latest"]
useAllPlatformBundle: "true"
installGo: true
installDotNet: true
steps:
- id: init
uses: ./../action/init

View File

@@ -3,7 +3,6 @@ description: "Checks that specifying 'ref' and 'sha' as inputs works"
versions: ["default"]
installGo: true
installPython: true
installDotNet: true
steps:
- uses: ./../action/init
with:

View File

@@ -2,7 +2,6 @@ name: "autobuild-action"
description: "Tests that the C# autobuild action works"
operatingSystems: ["ubuntu", "macos", "windows"]
versions: ["linked"]
installDotNet: true
steps:
- uses: ./../action/init
with:

View File

@@ -2,7 +2,6 @@ name: "Build mode manual"
description: "An end-to-end integration test of a Java repository built using 'build-mode: manual'"
versions: ["nightly-latest"]
installGo: true
installDotNet: true
steps:
- uses: ./../action/init
id: init

View File

@@ -3,7 +3,6 @@ description: "Tests that file baseline information is exported when the feature
operatingSystems: ["ubuntu", "macos", "windows"]
versions: ["nightly-latest"]
installGo: true
installDotNet: true
env:
CODEQL_ACTION_SUBLANGUAGE_FILE_COVERAGE: true
steps:

View File

@@ -7,7 +7,6 @@ versions:
- linked
- nightly-latest
installGo: true
installDotNet: true
env:
DOTNET_GENERATE_ASPNET_CERTIFICATE: "false"
steps:

View File

@@ -3,7 +3,6 @@ description: "Tests using a CodeQL bundle from a local file rather than a URL"
versions: ["linked"]
installGo: true
installPython: true
installDotNet: true
steps:
- name: Fetch latest CodeQL bundle
run: |

View File

@@ -5,7 +5,6 @@ env:
CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI: true
installGo: true
installPython: true
installDotNet: true
steps:
- name: Use Xcode 16
if: runner.os == 'macOS' && matrix.version != 'nightly-latest'

View File

@@ -4,7 +4,6 @@ versions: ["linked", "default", "nightly-latest"] # This feature is not compatib
installGo: true
installNode: true
installPython: true
installDotNet: true
steps:
- uses: ./../action/init
with:

View File

@@ -3,7 +3,6 @@ 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
installDotNet: true
steps:
- uses: ./../action/init
with:

View File

@@ -3,7 +3,6 @@ description: "Checks that specifying packages using only a config file works"
versions: ["linked", "default", "nightly-latest"] # This feature is not compatible with old CLIs
installGo: true
installNode: true
installDotNet: true
steps:
- uses: ./../action/init
with:

View File

@@ -3,7 +3,6 @@ description: "Checks that specifying packages using the input to the Action work
versions: ["linked", "default", "nightly-latest"] # This feature is not compatible with old CLIs
installGo: true
installNode: true
installDotNet: true
steps:
- uses: ./../action/init
with:

View File

@@ -7,7 +7,6 @@ versions:
- nightly-latest
installGo: true
installPython: true
installDotNet: true
steps:
- uses: ./../action/init
with:

View File

@@ -4,7 +4,7 @@ description: "Tests using RuboCop to analyze a multi-language repository and the
versions: ["default"]
steps:
- name: Set up Ruby
uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0
uses: ruby/setup-ruby@d5126b9b3579e429dd52e51e68624dda2e05be25 # v1.267.0
with:
ruby-version: 2.6
- name: Install Code Scanning integration

View File

@@ -3,7 +3,6 @@ description: "Tests a split-up workflow in which we first build a database and l
operatingSystems: ["ubuntu", "macos"]
versions: ["linked", "default", "nightly-latest"] # This feature is not compatible with old CLIs
installGo: true
installDotNet: true
steps:
- uses: ./../action/init
with:

View File

@@ -3,7 +3,6 @@ description: "Tests creation of a Swift database using custom build"
versions: ["linked", "default", "nightly-latest"]
operatingSystems: ["macos"]
installGo: true
installDotNet: true
env:
DOTNET_GENERATE_ASPNET_CERTIFICATE: "false"
steps:

View File

@@ -7,7 +7,6 @@ versions:
- nightly-latest
installGo: true
installPython: true
installDotNet: true
steps:
- uses: ./../action/init
id: init

View File

@@ -3,7 +3,6 @@ description: "Checks that specifying 'ref' and 'sha' as inputs works"
versions: ["default"]
installGo: true
installPython: true
installDotNet: true
steps:
- uses: ./../action/init
with:

View File

@@ -4,7 +4,6 @@ versions: ["default"]
analysisKinds: ["code-scanning", "code-quality", "code-scanning,code-quality"]
installGo: true
installPython: true
installDotNet: true
steps:
- uses: ./../action/init
with:

View File

@@ -3,7 +3,6 @@ description: "Checks that a custom `checkout_path` will find the proper commit_o
versions: ["linked"]
installGo: true
installPython: true
installDotNet: true
steps:
# This ensures we don't accidentally use the original checkout for any part of the test.
- name: Delete original checkout

View File

@@ -204,25 +204,6 @@ for file in sorted((this_dir / 'checks').glob('*.yml')):
}
})
installDotNet = is_truthy(checkSpecification.get('installDotNet', ''))
if installDotNet:
baseDotNetVersionExpr = '9.x'
workflowInputs['dotnet-version'] = {
'type': 'string',
'description': 'The version of .NET to install',
'required': False,
'default': baseDotNetVersionExpr,
}
steps.append({
'name': 'Install .NET',
'uses': 'actions/setup-dotnet@v5',
'with': {
'dotnet-version': '${{ inputs.dotnet-version || \'' + baseDotNetVersionExpr + '\' }}'
}
})
# 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:

View File

@@ -80,7 +80,7 @@ export function isRunningLocalAction(): boolean {
*
* This can be used to get the Action's name or tell if we're running a local Action.
*/
function getRelativeScriptPath(): string {
export function getRelativeScriptPath(): string {
const runnerTemp = getRequiredEnvParam("RUNNER_TEMP");
const actionsDirectory = path.join(path.dirname(runnerTemp), "_actions");
return path.relative(actionsDirectory, __filename);

View File

@@ -98,7 +98,7 @@ export async function getAnalysisKinds(
export const codeQualityQueries: string[] = ["code-quality"];
// Enumerates API endpoints that accept SARIF files.
enum SARIF_UPLOAD_ENDPOINT {
export enum SARIF_UPLOAD_ENDPOINT {
CODE_SCANNING = "PUT /repos/:owner/:repo/code-scanning/analysis",
CODE_QUALITY = "PUT /repos/:owner/:repo/code-quality/analysis",
}

View File

@@ -25,7 +25,7 @@ import {
isCodeQualityEnabled,
isCodeScanningEnabled,
} from "./config-utils";
import { cleanupAndUploadDatabases } from "./database-upload";
import { uploadDatabases } from "./database-upload";
import {
DependencyCacheUploadStatusReport,
uploadDependencyCaches,
@@ -35,7 +35,7 @@ import { EnvVar } from "./environment";
import { Feature, Features } from "./feature-flags";
import { KnownLanguage } from "./languages";
import { getActionsLogger, Logger } from "./logging";
import { cleanupAndUploadOverlayBaseDatabaseToCache } from "./overlay-database-utils";
import { uploadOverlayBaseDatabaseToCache } from "./overlay-database-utils";
import { getRepositoryNwo } from "./repository";
import * as statusReport from "./status-report";
import {
@@ -417,21 +417,12 @@ async function run() {
}
// Possibly upload the overlay-base database to actions cache.
// Note: Take care with the ordering of this call since databases may be cleaned up
// at the `overlay` level.
await cleanupAndUploadOverlayBaseDatabaseToCache(codeql, config, logger);
// If databases are to be uploaded, they will first be cleaned up at the overlay level.
await uploadOverlayBaseDatabaseToCache(codeql, config, logger);
// Possibly upload the database bundles for remote queries.
// Note: Take care with the ordering of this call since databases may be cleaned up
// at the `overlay` or `clear` level.
await cleanupAndUploadDatabases(
repositoryNwo,
codeql,
config,
apiDetails,
features,
logger,
);
// If databases are to be uploaded, they will first be cleaned up at the clear level.
await uploadDatabases(repositoryNwo, codeql, config, apiDetails, logger);
// Possibly upload the TRAP caches for later re-use
const trapCacheUploadStartTime = performance.now();

View File

@@ -18,6 +18,11 @@ import {
const GITHUB_ENTERPRISE_VERSION_HEADER = "x-github-enterprise-version";
export enum DisallowedAPIVersionReason {
ACTION_TOO_OLD,
ACTION_TOO_NEW,
}
export type GitHubApiCombinedDetails = GitHubApiDetails &
GitHubApiExternalRepoDetails;

View File

@@ -159,7 +159,10 @@ type CliErrorConfiguration = {
* All of our caught CLI error messages that we handle specially: ie. if we
* would like to categorize an error as a configuration error or not.
*/
const cliErrorsConfig: Record<CliConfigErrorCategory, CliErrorConfiguration> = {
export const cliErrorsConfig: Record<
CliConfigErrorCategory,
CliErrorConfiguration
> = {
[CliConfigErrorCategory.AutobuildError]: {
cliErrorMessageCandidates: [
new RegExp("We were unable to automatically build your code"),

View File

@@ -35,7 +35,7 @@ import { ToolsDownloadStatusReport } from "./tools-download";
import { ToolsFeature, isSupportedToolsFeature } from "./tools-features";
import { shouldEnableIndirectTracing } from "./tracer-config";
import * as util from "./util";
import { BuildMode, CleanupLevel, getErrorMessage } from "./util";
import { BuildMode, getErrorMessage } from "./util";
type Options = Array<string | number | boolean>;
@@ -141,10 +141,7 @@ export interface CodeQL {
/**
* Clean up all the databases within a database cluster.
*/
databaseCleanupCluster(
config: Config,
cleanupLevel: CleanupLevel,
): Promise<void>;
databaseCleanupCluster(config: Config, cleanupLevel: string): Promise<void>;
/**
* Run 'codeql database bundle'.
*/
@@ -516,7 +513,7 @@ export async function getCodeQLForTesting(
* version requirement. Must be set to true outside tests.
* @returns A new CodeQL object
*/
async function getCodeQLForCmd(
export async function getCodeQLForCmd(
cmd: string,
checkVersion: boolean,
): Promise<CodeQL> {
@@ -881,7 +878,7 @@ async function getCodeQLForCmd(
},
async databaseCleanupCluster(
config: Config,
cleanupLevel: CleanupLevel,
cleanupLevel: string,
): Promise<void> {
const cacheCleanupFlag = (await util.codeQlVersionAtLeast(
this,
@@ -1225,7 +1222,7 @@ export async function getTrapCachingExtractorConfigArgsForLang(
*
* This will not exist if the configuration is being parsed in the Action.
*/
function getGeneratedCodeScanningConfigPath(config: Config): string {
export function getGeneratedCodeScanningConfigPath(config: Config): string {
return path.resolve(config.tempDir, "user-config.yaml");
}

View File

@@ -37,9 +37,7 @@ import {
ConfigurationError,
withTmpDir,
BuildMode,
DiskUsage,
} from "./util";
import * as util from "./util";
setupTests(test);
@@ -202,9 +200,12 @@ test("load code quality config", async (t) => {
);
// And the config we expect it to result in
const expectedConfig = createTestConfig({
const expectedConfig: configUtils.Config = {
version: actionsUtil.getActionVersion(),
analysisKinds: [AnalysisKind.CodeQuality],
languages: [KnownLanguage.actions],
buildMode: undefined,
originalUserInput: {},
// This gets set because we only have `AnalysisKind.CodeQuality`
computedConfig: {
"disable-default-queries": true,
@@ -218,7 +219,14 @@ test("load code quality config", async (t) => {
debugMode: false,
debugArtifactName: "",
debugDatabaseName: "",
});
trapCaches: {},
trapCacheDownloadTime: 0,
dependencyCachingEnabled: CachingKind.None,
extraQueryExclusions: [],
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
repositoryProperties: {},
};
t.deepEqual(config, expectedConfig);
});
@@ -499,7 +507,9 @@ test("load non-empty input", async (t) => {
};
// And the config we expect it to parse to
const expectedConfig = createTestConfig({
const expectedConfig: configUtils.Config = {
version: actionsUtil.getActionVersion(),
analysisKinds: [AnalysisKind.CodeScanning],
languages: [KnownLanguage.javascript],
buildMode: BuildMode.None,
originalUserInput: userConfig,
@@ -511,7 +521,14 @@ test("load non-empty input", async (t) => {
debugMode: false,
debugArtifactName: "my-artifact",
debugDatabaseName: "my-db",
});
trapCaches: {},
trapCacheDownloadTime: 0,
dependencyCachingEnabled: CachingKind.None,
extraQueryExclusions: [],
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
repositoryProperties: {},
};
const languagesInput = "javascript";
const configFilePath = createConfigFile(inputFileContents, tempDir);
@@ -973,12 +990,12 @@ interface OverlayDatabaseModeTestSetup {
features: Feature[];
isPullRequest: boolean;
isDefaultBranch: boolean;
repositoryOwner: string;
buildMode: BuildMode | undefined;
languages: Language[];
codeqlVersion: string;
gitRoot: string | undefined;
codeScanningConfig: configUtils.UserConfig;
diskUsage: DiskUsage | undefined;
}
const defaultOverlayDatabaseModeTestSetup: OverlayDatabaseModeTestSetup = {
@@ -986,15 +1003,12 @@ const defaultOverlayDatabaseModeTestSetup: OverlayDatabaseModeTestSetup = {
features: [],
isPullRequest: false,
isDefaultBranch: false,
repositoryOwner: "github",
buildMode: BuildMode.None,
languages: [KnownLanguage.javascript],
codeqlVersion: CODEQL_OVERLAY_MINIMUM_VERSION,
gitRoot: "/some/git/root",
codeScanningConfig: {},
diskUsage: {
numAvailableBytes: 50_000_000_000,
numTotalBytes: 100_000_000_000,
},
};
const getOverlayDatabaseModeMacro = test.macro({
@@ -1027,8 +1041,6 @@ const getOverlayDatabaseModeMacro = test.macro({
setup.overlayDatabaseEnvVar;
}
sinon.stub(util, "checkDiskUsage").resolves(setup.diskUsage);
// Mock feature flags
const features = createFeatures(setup.features);
@@ -1037,6 +1049,12 @@ const getOverlayDatabaseModeMacro = test.macro({
.stub(actionsUtil, "isAnalyzingPullRequest")
.returns(setup.isPullRequest);
// Mock repository owner
const repository = {
owner: setup.repositoryOwner,
repo: "test-repo",
};
// Set up CodeQL mock
const codeql = mockCodeQLVersion(setup.codeqlVersion);
@@ -1059,6 +1077,7 @@ const getOverlayDatabaseModeMacro = test.macro({
const result = await configUtils.getOverlayDatabaseMode(
codeql,
repository,
features,
setup.languages,
tempDir, // sourceRoot
@@ -1186,45 +1205,6 @@ test(
},
);
test(
getOverlayDatabaseModeMacro,
"No overlay-base database on default branch if runner disk space is too low",
{
languages: [KnownLanguage.javascript],
features: [
Feature.OverlayAnalysis,
Feature.OverlayAnalysisCodeScanningJavascript,
],
isDefaultBranch: true,
diskUsage: {
numAvailableBytes: 1_000_000_000,
numTotalBytes: 100_000_000_000,
},
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
},
);
test(
getOverlayDatabaseModeMacro,
"No overlay-base database on default branch if we can't determine runner disk space",
{
languages: [KnownLanguage.javascript],
features: [
Feature.OverlayAnalysis,
Feature.OverlayAnalysisCodeScanningJavascript,
],
isDefaultBranch: true,
diskUsage: undefined,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
},
);
test(
getOverlayDatabaseModeMacro,
"No overlay-base database on default branch when code-scanning feature enabled with disable-default-queries",
@@ -1395,45 +1375,6 @@ test(
},
);
test(
getOverlayDatabaseModeMacro,
"No overlay analysis on PR if runner disk space is too low",
{
languages: [KnownLanguage.javascript],
features: [
Feature.OverlayAnalysis,
Feature.OverlayAnalysisCodeScanningJavascript,
],
isPullRequest: true,
diskUsage: {
numAvailableBytes: 1_000_000_000,
numTotalBytes: 100_000_000_000,
},
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
},
);
test(
getOverlayDatabaseModeMacro,
"No overlay analysis on PR if we can't determine runner disk space",
{
languages: [KnownLanguage.javascript],
features: [
Feature.OverlayAnalysis,
Feature.OverlayAnalysisCodeScanningJavascript,
],
isPullRequest: true,
diskUsage: undefined,
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
},
);
test(
getOverlayDatabaseModeMacro,
"No overlay analysis on PR when code-scanning feature enabled with disable-default-queries",
@@ -1558,9 +1499,10 @@ test(
test(
getOverlayDatabaseModeMacro,
"Overlay PR analysis by env",
"Overlay PR analysis by env for dsp-testing",
{
overlayDatabaseEnvVar: "overlay",
repositoryOwner: "dsp-testing",
},
{
overlayDatabaseMode: OverlayDatabaseMode.Overlay,
@@ -1570,10 +1512,10 @@ test(
test(
getOverlayDatabaseModeMacro,
"Overlay PR analysis by env on a runner with low disk space",
"Overlay PR analysis by env for other-org",
{
overlayDatabaseEnvVar: "overlay",
diskUsage: { numAvailableBytes: 0, numTotalBytes: 100_000_000_000 },
repositoryOwner: "other-org",
},
{
overlayDatabaseMode: OverlayDatabaseMode.Overlay,
@@ -1583,11 +1525,12 @@ test(
test(
getOverlayDatabaseModeMacro,
"Overlay PR analysis by feature flag",
"Overlay PR analysis by feature flag for dsp-testing",
{
languages: [KnownLanguage.javascript],
features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript],
isPullRequest: true,
repositoryOwner: "dsp-testing",
},
{
overlayDatabaseMode: OverlayDatabaseMode.Overlay,
@@ -1595,6 +1538,21 @@ test(
},
);
test(
getOverlayDatabaseModeMacro,
"No overlay PR analysis by feature flag for other-org",
{
languages: [KnownLanguage.javascript],
features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript],
isPullRequest: true,
repositoryOwner: "other-org",
},
{
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
},
);
test(
getOverlayDatabaseModeMacro,
"Fallback due to autobuild with traced language",

View File

@@ -43,22 +43,10 @@ import {
codeQlVersionAtLeast,
cloneObject,
isDefined,
checkDiskUsage,
} from "./util";
export * from "./config/db-config";
/**
* The minimum available disk space (in MB) required to perform overlay analysis.
* If the available disk space on the runner is below the threshold when deciding
* whether to perform overlay analysis, then the action will not perform overlay
* analysis unless overlay analysis has been explicitly enabled via environment
* variable.
*/
const OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB = 20000;
const OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_BYTES =
OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB * 1_000_000;
export type RegistryConfigWithCredentials = RegistryConfigNoCredentials & {
// Token to use when downloading packs from this registry.
token: string;
@@ -160,9 +148,6 @@ export interface Config {
/** A value indicating how dependency caching should be used. */
dependencyCachingEnabled: CachingKind;
/** The keys of caches that we restored, if any. */
dependencyCachingRestoredKeys: string[];
/**
* Extra query exclusions to append to the config.
*/
@@ -191,7 +176,7 @@ export interface Config {
repositoryProperties: RepositoryProperties;
}
async function getSupportedLanguageMap(
export async function getSupportedLanguageMap(
codeql: CodeQL,
logger: Logger,
): Promise<Record<string, string>> {
@@ -254,7 +239,7 @@ export function hasActionsWorkflows(sourceRoot: string): boolean {
/**
* Gets the set of languages in the current repository.
*/
async function getRawLanguagesInRepo(
export async function getRawLanguagesInRepo(
repository: RepositoryNwo,
sourceRoot: string,
logger: Logger,
@@ -363,7 +348,7 @@ export function getRawLanguagesNoAutodetect(
* @returns A tuple containing a list of languages in this repository that might be
* analyzable and whether or not this list was determined automatically.
*/
async function getRawLanguages(
export async function getRawLanguages(
languagesInput: string | undefined,
repository: RepositoryNwo,
sourceRoot: string,
@@ -511,7 +496,6 @@ export async function initActionState(
trapCaches,
trapCacheDownloadTime,
dependencyCachingEnabled: getCachingKind(dependencyCachingEnabled),
dependencyCachingRestoredKeys: [],
extraQueryExclusions: [],
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,
@@ -595,11 +579,17 @@ const OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES: Record<Language, Feature> = {
};
async function isOverlayAnalysisFeatureEnabled(
repository: RepositoryNwo,
features: FeatureEnablement,
codeql: CodeQL,
languages: Language[],
codeScanningConfig: UserConfig,
): Promise<boolean> {
// TODO: Remove the repository owner check once support for overlay analysis
// stabilizes, and no more backward-incompatible changes are expected.
if (!["github", "dsp-testing"].includes(repository.owner)) {
return false;
}
if (!(await features.getValue(Feature.OverlayAnalysis, codeql))) {
return false;
}
@@ -657,6 +647,7 @@ async function isOverlayAnalysisFeatureEnabled(
*/
export async function getOverlayDatabaseMode(
codeql: CodeQL,
repository: RepositoryNwo,
features: FeatureEnablement,
languages: Language[],
sourceRoot: string,
@@ -685,43 +676,27 @@ export async function getOverlayDatabaseMode(
);
} else if (
await isOverlayAnalysisFeatureEnabled(
repository,
features,
codeql,
languages,
codeScanningConfig,
)
) {
const diskUsage = await checkDiskUsage(logger);
if (
diskUsage === undefined ||
diskUsage.numAvailableBytes < OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_BYTES
) {
const diskSpaceMb =
diskUsage === undefined
? 0
: Math.round(diskUsage.numAvailableBytes / 1_000_000);
overlayDatabaseMode = OverlayDatabaseMode.None;
useOverlayDatabaseCaching = false;
if (isAnalyzingPullRequest()) {
overlayDatabaseMode = OverlayDatabaseMode.Overlay;
useOverlayDatabaseCaching = true;
logger.info(
`Setting overlay database mode to ${overlayDatabaseMode} ` +
`due to insufficient disk space (${diskSpaceMb} MB).`,
"with caching because we are analyzing a pull request.",
);
} else if (await isAnalyzingDefaultBranch()) {
overlayDatabaseMode = OverlayDatabaseMode.OverlayBase;
useOverlayDatabaseCaching = true;
logger.info(
`Setting overlay database mode to ${overlayDatabaseMode} ` +
"with caching because we are analyzing the default branch.",
);
} else {
if (isAnalyzingPullRequest()) {
overlayDatabaseMode = OverlayDatabaseMode.Overlay;
useOverlayDatabaseCaching = true;
logger.info(
`Setting overlay database mode to ${overlayDatabaseMode} ` +
"with caching because we are analyzing a pull request.",
);
} else if (await isAnalyzingDefaultBranch()) {
overlayDatabaseMode = OverlayDatabaseMode.OverlayBase;
useOverlayDatabaseCaching = true;
logger.info(
`Setting overlay database mode to ${overlayDatabaseMode} ` +
"with caching because we are analyzing the default branch.",
);
}
}
}
@@ -871,6 +846,7 @@ export async function initConfig(
const { overlayDatabaseMode, useOverlayDatabaseCaching } =
await getOverlayDatabaseMode(
inputs.codeql,
inputs.repository,
inputs.features,
config.languages,
inputs.sourceRoot,
@@ -1259,7 +1235,7 @@ export function isCodeQualityEnabled(config: Config): boolean {
* @returns Returns `AnalysisKind.CodeScanning` if `AnalysisKind.CodeScanning` is enabled;
* otherwise `AnalysisKind.CodeQuality`.
*/
function getPrimaryAnalysisKind(config: Config): AnalysisKind {
export function getPrimaryAnalysisKind(config: Config): AnalysisKind {
return isCodeScanningEnabled(config)
? AnalysisKind.CodeScanning
: AnalysisKind.CodeQuality;

View File

@@ -10,12 +10,11 @@ import { GitHubApiDetails } from "./api-client";
import * as apiClient from "./api-client";
import { createStubCodeQL } from "./codeql";
import { Config } from "./config-utils";
import { cleanupAndUploadDatabases } from "./database-upload";
import { uploadDatabases } from "./database-upload";
import * as gitUtils from "./git-utils";
import { KnownLanguage } from "./languages";
import { RepositoryNwo } from "./repository";
import {
createFeatures,
createTestConfig,
getRecordingLogger,
LoggedMessage,
@@ -92,12 +91,11 @@ test("Abort database upload if 'upload-database' input set to false", async (t)
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
const loggedMessages = [];
await cleanupAndUploadDatabases(
await uploadDatabases(
testRepoName,
getCodeQL(),
getTestConfig(tmpDir),
testApiDetails,
createFeatures([]),
getRecordingLogger(loggedMessages),
);
t.assert(
@@ -123,7 +121,7 @@ test("Abort database upload if 'analysis-kinds: code-scanning' is not enabled",
await mockHttpRequests(201);
const loggedMessages = [];
await cleanupAndUploadDatabases(
await uploadDatabases(
testRepoName,
getCodeQL(),
{
@@ -131,7 +129,6 @@ test("Abort database upload if 'analysis-kinds: code-scanning' is not enabled",
analysisKinds: [AnalysisKind.CodeQuality],
},
testApiDetails,
createFeatures([]),
getRecordingLogger(loggedMessages),
);
t.assert(
@@ -158,12 +155,11 @@ test("Abort database upload if running against GHES", async (t) => {
config.gitHubVersion = { type: GitHubVariant.GHES, version: "3.0" };
const loggedMessages = [];
await cleanupAndUploadDatabases(
await uploadDatabases(
testRepoName,
getCodeQL(),
config,
testApiDetails,
createFeatures([]),
getRecordingLogger(loggedMessages),
);
t.assert(
@@ -187,12 +183,11 @@ test("Abort database upload if not analyzing default branch", async (t) => {
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(false);
const loggedMessages = [];
await cleanupAndUploadDatabases(
await uploadDatabases(
testRepoName,
getCodeQL(),
getTestConfig(tmpDir),
testApiDetails,
createFeatures([]),
getRecordingLogger(loggedMessages),
);
t.assert(
@@ -217,12 +212,11 @@ test("Don't crash if uploading a database fails", async (t) => {
await mockHttpRequests(500);
const loggedMessages = [] as LoggedMessage[];
await cleanupAndUploadDatabases(
await uploadDatabases(
testRepoName,
getCodeQL(),
getTestConfig(tmpDir),
testApiDetails,
createFeatures([]),
getRecordingLogger(loggedMessages),
);
@@ -249,12 +243,11 @@ test("Successfully uploading a database to github.com", async (t) => {
await mockHttpRequests(201);
const loggedMessages = [] as LoggedMessage[];
await cleanupAndUploadDatabases(
await uploadDatabases(
testRepoName,
getCodeQL(),
getTestConfig(tmpDir),
testApiDetails,
createFeatures([]),
getRecordingLogger(loggedMessages),
);
t.assert(
@@ -279,7 +272,7 @@ test("Successfully uploading a database to GHEC-DR", async (t) => {
const databaseUploadSpy = await mockHttpRequests(201);
const loggedMessages = [] as LoggedMessage[];
await cleanupAndUploadDatabases(
await uploadDatabases(
testRepoName,
getCodeQL(),
getTestConfig(tmpDir),
@@ -288,7 +281,6 @@ test("Successfully uploading a database to GHEC-DR", async (t) => {
url: "https://tenant.ghe.com",
apiURL: undefined,
},
createFeatures([]),
getRecordingLogger(loggedMessages),
);
t.assert(

View File

@@ -5,20 +5,17 @@ import { AnalysisKind } from "./analyses";
import { getApiClient, GitHubApiDetails } from "./api-client";
import { type CodeQL } from "./codeql";
import { Config } from "./config-utils";
import { Feature, FeatureEnablement } from "./feature-flags";
import * as gitUtils from "./git-utils";
import { Logger, withGroupAsync } from "./logging";
import { OverlayDatabaseMode } from "./overlay-database-utils";
import { RepositoryNwo } from "./repository";
import * as util from "./util";
import { bundleDb, CleanupLevel, parseGitHubUrl } from "./util";
import { bundleDb, parseGitHubUrl } from "./util";
export async function cleanupAndUploadDatabases(
export async function uploadDatabases(
repositoryNwo: RepositoryNwo,
codeql: CodeQL,
config: Config,
apiDetails: GitHubApiDetails,
features: FeatureEnablement,
logger: Logger,
): Promise<void> {
if (actionsUtil.getRequiredInput("upload-database") !== "true") {
@@ -53,16 +50,10 @@ export async function cleanupAndUploadDatabases(
return;
}
const cleanupLevel =
config.overlayDatabaseMode === OverlayDatabaseMode.OverlayBase &&
(await features.getValue(Feature.UploadOverlayDbToApi))
? CleanupLevel.Overlay
: CleanupLevel.Clear;
// Clean up the database, since intermediate results may still be written to the
// database if there is high RAM pressure.
await withGroupAsync("Cleaning up databases", async () => {
await codeql.databaseCleanupCluster(config, cleanupLevel);
await codeql.databaseCleanupCluster(config, "clear");
});
const client = getApiClient();

View File

@@ -1,6 +1,6 @@
{
"bundleVersion": "codeql-bundle-v2.23.5",
"cliVersion": "2.23.5",
"priorBundleVersion": "codeql-bundle-v2.23.3",
"priorCliVersion": "2.23.3"
"bundleVersion": "codeql-bundle-v2.23.3",
"cliVersion": "2.23.3",
"priorBundleVersion": "codeql-bundle-v2.23.2",
"priorCliVersion": "2.23.2"
}

View File

@@ -7,7 +7,6 @@ import test from "ava";
import * as sinon from "sinon";
import { cacheKeyHashLength } from "./caching-utils";
import * as cachingUtils from "./caching-utils";
import { createStubCodeQL } from "./codeql";
import {
CacheConfig,
@@ -21,8 +20,6 @@ import {
downloadDependencyCaches,
CacheHitKind,
cacheKey,
uploadDependencyCaches,
CacheStoreResult,
} from "./dependency-caching";
import { Feature } from "./feature-flags";
import { KnownLanguage } from "./languages";
@@ -32,7 +29,6 @@ import {
getRecordingLogger,
checkExpectedLogMessages,
LoggedMessage,
createTestConfig,
} from "./testing-utils";
import { withTmpDir } from "./util";
@@ -241,17 +237,15 @@ test("downloadDependencyCaches - does not restore caches with feature keys if no
.resolves(CSHARP_BASE_PATTERNS);
makePatternCheckStub.withArgs(CSHARP_EXTRA_PATTERNS).resolves(undefined);
const result = await downloadDependencyCaches(
const results = await downloadDependencyCaches(
codeql,
createFeatures([]),
[KnownLanguage.csharp],
logger,
);
const statusReport = result.statusReport;
t.is(statusReport.length, 1);
t.is(statusReport[0].language, KnownLanguage.csharp);
t.is(statusReport[0].hit_kind, CacheHitKind.Miss);
t.deepEqual(result.restoredKeys, []);
t.is(results.length, 1);
t.is(results[0].language, KnownLanguage.csharp);
t.is(results[0].hit_kind, CacheHitKind.Miss);
t.assert(restoreCacheStub.calledOnce);
});
@@ -263,8 +257,7 @@ test("downloadDependencyCaches - restores caches with feature keys if features a
const logger = getRecordingLogger(messages);
const features = createFeatures([Feature.CsharpNewCacheKey]);
const mockHash = "abcdef";
sinon.stub(glob, "hashFiles").resolves(mockHash);
sinon.stub(glob, "hashFiles").resolves("abcdef");
const keyWithFeature = await cacheKey(
codeql,
@@ -284,28 +277,15 @@ test("downloadDependencyCaches - restores caches with feature keys if features a
.resolves(CSHARP_BASE_PATTERNS);
makePatternCheckStub.withArgs(CSHARP_EXTRA_PATTERNS).resolves(undefined);
const result = await downloadDependencyCaches(
const results = await downloadDependencyCaches(
codeql,
features,
[KnownLanguage.csharp],
logger,
);
// Check that the status report for telemetry indicates that one cache was restored with an exact match.
const statusReport = result.statusReport;
t.is(statusReport.length, 1);
t.is(statusReport[0].language, KnownLanguage.csharp);
t.is(statusReport[0].hit_kind, CacheHitKind.Exact);
// Check that the restored key has been returned.
const restoredKeys = result.restoredKeys;
t.is(restoredKeys.length, 1);
t.assert(
restoredKeys[0].endsWith(mockHash),
"Expected restored key to end with hash returned by `hashFiles`",
);
// `restoreCache` should have been called exactly once.
t.is(results.length, 1);
t.is(results[0].language, KnownLanguage.csharp);
t.is(results[0].hit_kind, CacheHitKind.Exact);
t.assert(restoreCacheStub.calledOnce);
});
@@ -317,14 +297,8 @@ test("downloadDependencyCaches - restores caches with feature keys if features a
const logger = getRecordingLogger(messages);
const features = createFeatures([Feature.CsharpNewCacheKey]);
// We expect two calls to `hashFiles`: the first by the call to `cacheKey` below,
// and the second by `downloadDependencyCaches`. We use the result of the first
// call as part of the cache key that identifies a mock, existing cache. The result
// of the second call is for the primary restore key, which we don't want to match
// the first key so that we can test the restore keys logic.
const restoredHash = "abcdef";
const hashFilesStub = sinon.stub(glob, "hashFiles");
hashFilesStub.onFirstCall().resolves(restoredHash);
hashFilesStub.onFirstCall().resolves("abcdef");
hashFilesStub.onSecondCall().resolves("123456");
const keyWithFeature = await cacheKey(
@@ -345,230 +319,18 @@ test("downloadDependencyCaches - restores caches with feature keys if features a
.resolves(CSHARP_BASE_PATTERNS);
makePatternCheckStub.withArgs(CSHARP_EXTRA_PATTERNS).resolves(undefined);
const result = await downloadDependencyCaches(
const results = await downloadDependencyCaches(
codeql,
features,
[KnownLanguage.csharp],
logger,
);
// Check that the status report for telemetry indicates that one cache was restored with a partial match.
const statusReport = result.statusReport;
t.is(statusReport.length, 1);
t.is(statusReport[0].language, KnownLanguage.csharp);
t.is(statusReport[0].hit_kind, CacheHitKind.Partial);
// Check that the restored key has been returned.
const restoredKeys = result.restoredKeys;
t.is(restoredKeys.length, 1);
t.assert(
restoredKeys[0].endsWith(restoredHash),
"Expected restored key to end with hash returned by `hashFiles`",
);
t.is(results.length, 1);
t.is(results[0].language, KnownLanguage.csharp);
t.is(results[0].hit_kind, CacheHitKind.Partial);
t.assert(restoreCacheStub.calledOnce);
});
test("uploadDependencyCaches - skips upload for a language with no cache config", async (t) => {
const codeql = createStubCodeQL({});
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
const features = createFeatures([]);
const config = createTestConfig({
languages: [KnownLanguage.actions],
});
const result = await uploadDependencyCaches(codeql, features, config, logger);
t.is(result.length, 0);
checkExpectedLogMessages(t, messages, [
"Skipping upload of dependency cache for actions",
]);
});
test("uploadDependencyCaches - skips upload if no files for the hash exist", async (t) => {
const codeql = createStubCodeQL({});
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
const features = createFeatures([]);
const config = createTestConfig({
languages: [KnownLanguage.go],
});
const makePatternCheckStub = sinon.stub(internal, "makePatternCheck");
makePatternCheckStub.resolves(undefined);
const result = await uploadDependencyCaches(codeql, features, config, logger);
t.is(result.length, 1);
t.is(result[0].language, KnownLanguage.go);
t.is(result[0].result, CacheStoreResult.NoHash);
});
test("uploadDependencyCaches - skips upload if we know the cache already exists", async (t) => {
process.env["RUNNER_OS"] = "Linux";
const codeql = createStubCodeQL({});
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
const features = createFeatures([]);
const mockHash = "abcdef";
sinon.stub(glob, "hashFiles").resolves(mockHash);
const makePatternCheckStub = sinon.stub(internal, "makePatternCheck");
makePatternCheckStub
.withArgs(CSHARP_BASE_PATTERNS)
.resolves(CSHARP_BASE_PATTERNS);
const primaryCacheKey = await cacheKey(
codeql,
features,
KnownLanguage.csharp,
CSHARP_BASE_PATTERNS,
);
const config = createTestConfig({
languages: [KnownLanguage.csharp],
dependencyCachingRestoredKeys: [primaryCacheKey],
});
const result = await uploadDependencyCaches(codeql, features, config, logger);
t.is(result.length, 1);
t.is(result[0].language, KnownLanguage.csharp);
t.is(result[0].result, CacheStoreResult.Duplicate);
});
test("uploadDependencyCaches - skips upload if cache size is 0", async (t) => {
process.env["RUNNER_OS"] = "Linux";
const codeql = createStubCodeQL({});
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
const features = createFeatures([]);
const mockHash = "abcdef";
sinon.stub(glob, "hashFiles").resolves(mockHash);
const makePatternCheckStub = sinon.stub(internal, "makePatternCheck");
makePatternCheckStub
.withArgs(CSHARP_BASE_PATTERNS)
.resolves(CSHARP_BASE_PATTERNS);
sinon.stub(cachingUtils, "getTotalCacheSize").resolves(0);
const config = createTestConfig({
languages: [KnownLanguage.csharp],
});
const result = await uploadDependencyCaches(codeql, features, config, logger);
t.is(result.length, 1);
t.is(result[0].language, KnownLanguage.csharp);
t.is(result[0].result, CacheStoreResult.Empty);
checkExpectedLogMessages(t, messages, [
"Skipping upload of dependency cache",
]);
});
test("uploadDependencyCaches - uploads caches when all requirements are met", async (t) => {
process.env["RUNNER_OS"] = "Linux";
const codeql = createStubCodeQL({});
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
const features = createFeatures([]);
const mockHash = "abcdef";
sinon.stub(glob, "hashFiles").resolves(mockHash);
const makePatternCheckStub = sinon.stub(internal, "makePatternCheck");
makePatternCheckStub
.withArgs(CSHARP_BASE_PATTERNS)
.resolves(CSHARP_BASE_PATTERNS);
sinon.stub(cachingUtils, "getTotalCacheSize").resolves(1024);
sinon.stub(actionsCache, "saveCache").resolves();
const config = createTestConfig({
languages: [KnownLanguage.csharp],
});
const result = await uploadDependencyCaches(codeql, features, config, logger);
t.is(result.length, 1);
t.is(result[0].language, KnownLanguage.csharp);
t.is(result[0].result, CacheStoreResult.Stored);
t.is(result[0].upload_size_bytes, 1024);
checkExpectedLogMessages(t, messages, ["Uploading cache of size"]);
});
test("uploadDependencyCaches - catches `ReserveCacheError` exceptions", async (t) => {
process.env["RUNNER_OS"] = "Linux";
const codeql = createStubCodeQL({});
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
const features = createFeatures([]);
const mockHash = "abcdef";
sinon.stub(glob, "hashFiles").resolves(mockHash);
const makePatternCheckStub = sinon.stub(internal, "makePatternCheck");
makePatternCheckStub
.withArgs(CSHARP_BASE_PATTERNS)
.resolves(CSHARP_BASE_PATTERNS);
sinon.stub(cachingUtils, "getTotalCacheSize").resolves(1024);
sinon
.stub(actionsCache, "saveCache")
.throws(new actionsCache.ReserveCacheError("Already in use"));
const config = createTestConfig({
languages: [KnownLanguage.csharp],
});
await t.notThrowsAsync(async () => {
const result = await uploadDependencyCaches(
codeql,
features,
config,
logger,
);
t.is(result.length, 1);
t.is(result[0].language, KnownLanguage.csharp);
t.is(result[0].result, CacheStoreResult.Duplicate);
checkExpectedLogMessages(t, messages, ["Not uploading cache for"]);
});
});
test("uploadDependencyCaches - throws other exceptions", async (t) => {
process.env["RUNNER_OS"] = "Linux";
const codeql = createStubCodeQL({});
const messages: LoggedMessage[] = [];
const logger = getRecordingLogger(messages);
const features = createFeatures([]);
const mockHash = "abcdef";
sinon.stub(glob, "hashFiles").resolves(mockHash);
const makePatternCheckStub = sinon.stub(internal, "makePatternCheck");
makePatternCheckStub
.withArgs(CSHARP_BASE_PATTERNS)
.resolves(CSHARP_BASE_PATTERNS);
sinon.stub(cachingUtils, "getTotalCacheSize").resolves(1024);
sinon.stub(actionsCache, "saveCache").throws();
const config = createTestConfig({
languages: [KnownLanguage.csharp],
});
await t.throwsAsync(async () => {
await uploadDependencyCaches(codeql, features, config, logger);
});
});
test("getFeaturePrefix - returns empty string if no features are enabled", async (t) => {
const codeql = createStubCodeQL({});
const features = createFeatures([]);

View File

@@ -55,7 +55,7 @@ export function getJavaTempDependencyDir(): string {
* @returns The paths of directories on the runner that should be included in a dependency cache
* for a Java analysis.
*/
function getJavaDependencyDirs(): string[] {
export function getJavaDependencyDirs(): string[] {
return [
// Maven
join(os.homedir(), ".m2", "repository"),
@@ -193,14 +193,6 @@ export interface DependencyCacheRestoreStatus {
/** An array of `DependencyCacheRestoreStatus` objects for each analysed language with a caching configuration. */
export type DependencyCacheRestoreStatusReport = DependencyCacheRestoreStatus[];
/** Represents the results of `downloadDependencyCaches`. */
export interface DownloadDependencyCachesResult {
/** The status report for telemetry */
statusReport: DependencyCacheRestoreStatusReport;
/** An array of cache keys that we have restored and therefore know to exist. */
restoredKeys: string[];
}
/**
* A wrapper around `cacheConfig.getHashPatterns` which logs when there are no files to calculate
* a hash for the cache key from.
@@ -247,9 +239,8 @@ export async function downloadDependencyCaches(
features: FeatureEnablement,
languages: Language[],
logger: Logger,
): Promise<DownloadDependencyCachesResult> {
): Promise<DependencyCacheRestoreStatusReport> {
const status: DependencyCacheRestoreStatusReport = [];
const restoredKeys: string[] = [];
for (const language of languages) {
const cacheConfig = defaultCacheConfigs[language];
@@ -297,27 +288,16 @@ export async function downloadDependencyCaches(
if (hitKey !== undefined) {
logger.info(`Cache hit on key ${hitKey} for ${language}.`);
// We have a partial cache hit, unless the key of the restored cache matches the
// primary restore key.
let hit_kind = CacheHitKind.Partial;
if (hitKey === primaryKey) {
hit_kind = CacheHitKind.Exact;
}
status.push({
language,
hit_kind,
download_duration_ms,
});
restoredKeys.push(hitKey);
const hit_kind =
hitKey === primaryKey ? CacheHitKind.Exact : CacheHitKind.Partial;
status.push({ language, hit_kind, download_duration_ms });
} else {
status.push({ language, hit_kind: CacheHitKind.Miss });
logger.info(`No suitable cache found for ${language}.`);
}
}
return { statusReport: status, restoredKeys };
return status;
}
/** Enumerates possible outcomes for storing caches. */
@@ -385,18 +365,6 @@ export async function uploadDependencyCaches(
continue;
}
// Now that we have verified that there are suitable files, compute the hash for the cache key.
const key = await cacheKey(codeql, features, language, patterns);
// Check that we haven't previously restored this exact key. If a cache with this key
// already exists in the Actions Cache, performing the next steps is pointless as the cache
// will not get overwritten. We can therefore skip the expensive work of measuring the size
// of the cache contents and attempting to upload it if we know that the cache already exists.
if (config.dependencyCachingRestoredKeys.includes(key)) {
status.push({ language, result: CacheStoreResult.Duplicate });
continue;
}
// Calculate the size of the files that we would store in the cache. We use this to determine whether the
// cache should be saved or not. For example, if there are no files to store, then we skip creating the
// cache. In the future, we could also:
@@ -422,6 +390,8 @@ export async function uploadDependencyCaches(
continue;
}
const key = await cacheKey(codeql, features, language, patterns);
logger.info(
`Uploading cache of size ${size} for ${language} with key ${key}...`,
);

View File

@@ -20,6 +20,12 @@ export enum EnvVar {
/** Whether the CodeQL Action has invoked the Go autobuilder. */
DID_AUTOBUILD_GOLANG = "CODEQL_ACTION_DID_AUTOBUILD_GOLANG",
/**
* Whether to disable the SARIF post-processing in the Action that removes duplicate locations from
* notifications in the `run[].invocations[].toolExecutionNotifications` SARIF property.
*/
DISABLE_DUPLICATE_LOCATION_FIX = "CODEQL_ACTION_DISABLE_DUPLICATE_LOCATION_FIX",
/**
* Whether the CodeQL Action is using its own deprecated and non-standard way of scanning for
* multiple languages.
@@ -50,12 +56,20 @@ export enum EnvVar {
/** Whether the error for a deprecated version of the CodeQL Action was logged. */
LOG_VERSION_DEPRECATION = "CODEQL_ACTION_DID_LOG_VERSION_DEPRECATION",
/**
* For macOS. Result of `csrutil status` to determine whether System Integrity
* Protection is enabled.
*/
IS_SIP_ENABLED = "CODEQL_ACTION_IS_SIP_ENABLED",
/** UUID representing the current job run. */
JOB_RUN_UUID = "JOB_RUN_UUID",
/** Status for the entire job, submitted to the status report in `init-post` */
JOB_STATUS = "CODEQL_ACTION_JOB_STATUS",
ODASA_TRACER_CONFIGURATION = "ODASA_TRACER_CONFIGURATION",
/** The value of the `output` input for the analyze action. */
SARIF_RESULTS_OUTPUT_DIR = "CODEQL_ACTION_SARIF_RESULTS_OUTPUT_DIR",

View File

@@ -77,7 +77,6 @@ export enum Feature {
OverlayAnalysisSwift = "overlay_analysis_swift",
PythonDefaultIsToNotExtractStdlib = "python_default_is_to_not_extract_stdlib",
QaTelemetryEnabled = "qa_telemetry_enabled",
UploadOverlayDbToApi = "upload_overlay_db_to_api",
UseRepositoryProperties = "use_repository_properties",
ValidateDbConfig = "validate_db_config",
}
@@ -167,11 +166,6 @@ export const featureConfig: Record<
legacyApi: true,
minimumVersion: undefined,
},
[Feature.JavaMinimizeDependencyJars]: {
defaultValue: false,
envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS",
minimumVersion: "2.23.0",
},
[Feature.OverlayAnalysis]: {
defaultValue: false,
envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS",
@@ -283,21 +277,21 @@ export const featureConfig: Record<
minimumVersion: undefined,
toolsFeature: ToolsFeature.PythonDefaultIsToNotExtractStdlib,
},
[Feature.UseRepositoryProperties]: {
defaultValue: false,
envVar: "CODEQL_ACTION_USE_REPOSITORY_PROPERTIES",
minimumVersion: undefined,
},
[Feature.QaTelemetryEnabled]: {
defaultValue: false,
envVar: "CODEQL_ACTION_QA_TELEMETRY",
legacyApi: true,
minimumVersion: undefined,
},
[Feature.UploadOverlayDbToApi]: {
[Feature.JavaMinimizeDependencyJars]: {
defaultValue: false,
envVar: "CODEQL_ACTION_UPLOAD_OVERLAY_DB_TO_API",
minimumVersion: undefined,
},
[Feature.UseRepositoryProperties]: {
defaultValue: false,
envVar: "CODEQL_ACTION_USE_REPOSITORY_PROPERTIES",
minimumVersion: undefined,
envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS",
minimumVersion: "2.23.0",
},
[Feature.ValidateDbConfig]: {
defaultValue: false,

View File

@@ -122,6 +122,67 @@ export const determineBaseBranchHeadCommitOid = async function (
}
};
/**
* Deepen the git history of HEAD by one level. Errors are logged.
*
* This function uses the `checkout_path` to determine the repository path and
* works only when called from `analyze` or `upload-sarif`.
*/
export const deepenGitHistory = async function () {
try {
await runGitCommand(
getOptionalInput("checkout_path"),
[
"fetch",
"origin",
"HEAD",
"--no-tags",
"--no-recurse-submodules",
"--deepen=1",
],
"Cannot deepen the shallow repository.",
);
} catch {
// Errors are already logged by runGitCommand()
}
};
/**
* Fetch the given remote branch. Errors are logged.
*
* This function uses the `checkout_path` to determine the repository path and
* works only when called from `analyze` or `upload-sarif`.
*/
export const gitFetch = async function (branch: string, extraFlags: string[]) {
try {
await runGitCommand(
getOptionalInput("checkout_path"),
["fetch", "--no-tags", ...extraFlags, "origin", `${branch}:${branch}`],
`Cannot fetch ${branch}.`,
);
} catch {
// Errors are already logged by runGitCommand()
}
};
/**
* Repack the git repository, using with the given flags. Errors are logged.
*
* This function uses the `checkout_path` to determine the repository path and
* works only when called from `analyze` or `upload-sarif`.
*/
export const gitRepack = async function (flags: string[]) {
try {
await runGitCommand(
getOptionalInput("checkout_path"),
["repack", ...flags],
"Cannot repack the repository.",
);
} catch {
// Errors are already logged by runGitCommand()
}
};
/**
* Decode, if necessary, a file path produced by Git. See
* https://git-scm.com/docs/git-config#Documentation/git-config.txt-corequotePath

View File

@@ -371,7 +371,7 @@ async function run() {
}
let overlayBaseDatabaseStats: OverlayBaseDatabaseDownloadStats | undefined;
let dependencyCachingStatus: DependencyCacheRestoreStatusReport | undefined;
let dependencyCachingResults: DependencyCacheRestoreStatusReport | undefined;
try {
if (
config.overlayDatabaseMode === OverlayDatabaseMode.Overlay &&
@@ -579,15 +579,12 @@ async function run() {
// Restore dependency cache(s), if they exist.
if (shouldRestoreCache(config.dependencyCachingEnabled)) {
const dependencyCachingResult = await downloadDependencyCaches(
dependencyCachingResults = await downloadDependencyCaches(
codeql,
features,
config.languages,
logger,
);
dependencyCachingStatus = dependencyCachingResult.statusReport;
config.dependencyCachingRestoredKeys =
dependencyCachingResult.restoredKeys;
}
// Suppress warnings about disabled Python library extraction.
@@ -735,7 +732,7 @@ async function run() {
toolsSource,
toolsVersion,
overlayBaseDatabaseStats,
dependencyCachingStatus,
dependencyCachingResults,
logger,
error,
);
@@ -758,7 +755,7 @@ async function run() {
toolsSource,
toolsVersion,
overlayBaseDatabaseStats,
dependencyCachingStatus,
dependencyCachingResults,
logger,
);
}

View File

@@ -16,7 +16,6 @@ import { type Config } from "./config-utils";
import { getCommitOid, getFileOidsUnderPath } from "./git-utils";
import { Logger, withGroupAsync } from "./logging";
import {
CleanupLevel,
getErrorMessage,
isInTestMode,
tryGetFolderBytes,
@@ -29,7 +28,7 @@ export enum OverlayDatabaseMode {
None = "none",
}
export const CODEQL_OVERLAY_MINIMUM_VERSION = "2.23.5";
export const CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.4";
/**
* The maximum (uncompressed) size of the overlay base database that we will
@@ -176,7 +175,7 @@ const MAX_CACHE_OPERATION_MS = 600_000;
* @param warningPrefix Prefix for the check failure warning message
* @returns True if the verification succeeded, false otherwise
*/
function checkOverlayBaseDatabase(
export function checkOverlayBaseDatabase(
config: Config,
logger: Logger,
warningPrefix: string,
@@ -205,7 +204,7 @@ function checkOverlayBaseDatabase(
* @returns A promise that resolves to true if the upload was performed and
* successfully completed, or false otherwise
*/
export async function cleanupAndUploadOverlayBaseDatabaseToCache(
export async function uploadOverlayBaseDatabaseToCache(
codeql: CodeQL,
config: Config,
logger: Logger,
@@ -243,7 +242,7 @@ export async function cleanupAndUploadOverlayBaseDatabaseToCache(
// Clean up the database using the overlay cleanup level.
await withGroupAsync("Cleaning up databases", async () => {
await codeql.databaseCleanupCluster(config, CleanupLevel.Overlay);
await codeql.databaseCleanupCluster(config, "overlay");
});
const dbLocation = config.dbLocation;

View File

@@ -34,7 +34,7 @@ export enum ToolsSource {
Download = "DOWNLOAD",
}
const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action";
export const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action";
const CODEQL_NIGHTLIES_REPOSITORY_OWNER = "dsp-testing";
const CODEQL_NIGHTLIES_REPOSITORY_NAME = "codeql-cli-nightlies";
@@ -180,6 +180,17 @@ export function tryGetTagNameFromUrl(
return match[1];
}
export function tryGetBundleVersionFromUrl(
url: string,
logger: Logger,
): string | undefined {
const tagName = tryGetTagNameFromUrl(url, logger);
if (tagName === undefined) {
return undefined;
}
return tryGetBundleVersionFromTagName(tagName, logger);
}
export function convertToSemVer(version: string, logger: Logger): string {
if (!semver.valid(version)) {
logger.debug(
@@ -569,7 +580,7 @@ export async function getCodeQLSource(
* Gets a fallback version number to use when looking for CodeQL in the toolcache if we didn't find
* the `x.y.z` version. This is to support old versions of the toolcache.
*/
async function tryGetFallbackToolcacheVersion(
export async function tryGetFallbackToolcacheVersion(
cliVersion: string | undefined,
tagName: string,
logger: Logger,
@@ -718,7 +729,7 @@ function getCanonicalToolcacheVersion(
return cliVersion;
}
interface SetupCodeQLResult {
export interface SetupCodeQLResult {
codeqlFolder: string;
toolsDownloadStatusReport?: ToolsDownloadStatusReport;
toolsSource: ToolsSource;
@@ -739,7 +750,7 @@ export async function setupCodeQLBundle(
defaultCliVersion: CodeQLDefaultVersionInfo,
features: FeatureEnablement,
logger: Logger,
): Promise<SetupCodeQLResult> {
) {
if (!(await util.isBinaryAccessible("tar", logger))) {
throw new util.ConfigurationError(
"Could not find tar in PATH, so unable to extract CodeQL bundle.",

View File

@@ -8,7 +8,7 @@ import { ConfigurationError, getErrorMessage, isDefined } from "./util";
export const UPDATEJOB_PROXY = "update-job-proxy";
export const UPDATEJOB_PROXY_VERSION = "v2.0.20250624110901";
const UPDATEJOB_PROXY_URL_PREFIX =
export const UPDATEJOB_PROXY_URL_PREFIX =
"https://github.com/github/codeql-action/releases/download/codeql-bundle-v2.22.0/";
export type Credential = {
@@ -202,7 +202,7 @@ export function getFallbackUrl(proxyPackage: string): string {
*
* @returns The response from the GitHub API.
*/
async function getLinkedRelease() {
export async function getLinkedRelease() {
return getApiClient().rest.repos.getReleaseByTag({
owner: "github",
repo: "codeql-action",

View File

@@ -54,7 +54,7 @@ export enum ActionName {
* considered to be a third party analysis and is treated differently when calculating SLOs. To ensure
* misconfigured workflows are not treated as third party, only the upload-sarif action can return false.
*/
function isFirstPartyAnalysis(actionName: ActionName): boolean {
export function isFirstPartyAnalysis(actionName: ActionName): boolean {
if (actionName !== ActionName.UploadSarif) {
return true;
}

View File

@@ -392,7 +392,6 @@ export function createTestConfig(overrides: Partial<Config>): Config {
trapCaches: {},
trapCacheDownloadTime: 0,
dependencyCachingEnabled: CachingKind.None,
dependencyCachingRestoredKeys: [],
extraQueryExclusions: [],
overlayDatabaseMode: OverlayDatabaseMode.None,
useOverlayDatabaseCaching: false,

View File

@@ -17,7 +17,7 @@ import { cleanUpPath, getErrorMessage, getRequiredEnvParam } from "./util";
/**
* High watermark to use when streaming the download and extraction of the CodeQL tools.
*/
const STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; // 4 MiB
export const STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024; // 4 MiB
/**
* The name of the tool cache directory for the CodeQL tools.

View File

@@ -76,7 +76,7 @@ export async function endTracingForCluster(
}
}
async function getTracerConfigForCluster(
export async function getTracerConfigForCluster(
config: Config,
): Promise<TracerConfig> {
const tracingEnvVariables = JSON.parse(

View File

@@ -412,7 +412,7 @@ export function findSarifFilesInDir(
return sarifFiles;
}
function getSarifFilePaths(
export function getSarifFilePaths(
sarifPath: string,
isSarif: (name: string) => boolean,
) {

View File

@@ -476,7 +476,7 @@ for (const [
githubVersion,
)}`;
test(`checkActionVersion ${reportErrorDescription} for ${versionsDescription}`, async (t) => {
const warningSpy = sinon.spy(core, "warning");
const warningSpy = sinon.spy(core, "error");
const versionStub = sinon
.stub(api, "getGitHubVersion")
.resolves(githubVersion);

View File

@@ -4,6 +4,7 @@ import * as os from "os";
import * as path from "path";
import * as core from "@actions/core";
import * as exec from "@actions/exec/lib/exec";
import * as io from "@actions/io";
import getFolderSize from "get-folder-size";
import * as yaml from "js-yaml";
@@ -1025,6 +1026,34 @@ export function fixInvalidNotifications(
return newSarif;
}
/**
* Removes duplicates from the sarif file.
*
* When `CODEQL_ACTION_DISABLE_DUPLICATE_LOCATION_FIX` is set to true, this will
* simply rename the input file to the output file. Otherwise, it will parse the
* input file as JSON, remove duplicate locations from the SARIF notification
* objects, and write the result to the output file.
*
* For context, see documentation of:
* `CODEQL_ACTION_DISABLE_DUPLICATE_LOCATION_FIX`. */
export function fixInvalidNotificationsInFile(
inputPath: string,
outputPath: string,
logger: Logger,
): void {
if (process.env[EnvVar.DISABLE_DUPLICATE_LOCATION_FIX] === "true") {
logger.info(
"SARIF notification object duplicate location fix disabled by the " +
`${EnvVar.DISABLE_DUPLICATE_LOCATION_FIX} environment variable.`,
);
fs.renameSync(inputPath, outputPath);
} else {
let sarif = JSON.parse(fs.readFileSync(inputPath, "utf8")) as SarifFile;
sarif = fixInvalidNotifications(sarif, logger);
fs.writeFileSync(outputPath, JSON.stringify(sarif));
}
}
export function wrapError(error: unknown): Error {
return error instanceof Error ? error : new Error(String(error));
}
@@ -1112,7 +1141,7 @@ export function checkActionVersion(
">=3.20",
))
) {
core.warning(
core.error(
"CodeQL Action v3 will be deprecated in December 2026. " +
"Please update all occurrences of the CodeQL Action in your workflow files to v4. " +
"For more information, see " +
@@ -1168,6 +1197,49 @@ export function cloneObject<T>(obj: T): T {
return JSON.parse(JSON.stringify(obj)) as T;
}
// The first time this function is called, it runs `csrutil status` to determine
// whether System Integrity Protection is enabled; and saves the result in an
// environment variable. Afterwards, simply return the value of the environment
// variable.
export async function checkSipEnablement(
logger: Logger,
): Promise<boolean | undefined> {
if (
process.env[EnvVar.IS_SIP_ENABLED] !== undefined &&
["true", "false"].includes(process.env[EnvVar.IS_SIP_ENABLED])
) {
return process.env[EnvVar.IS_SIP_ENABLED] === "true";
}
try {
const sipStatusOutput = await exec.getExecOutput("csrutil status");
if (sipStatusOutput.exitCode === 0) {
if (
sipStatusOutput.stdout.includes(
"System Integrity Protection status: enabled.",
)
) {
core.exportVariable(EnvVar.IS_SIP_ENABLED, "true");
return true;
}
if (
sipStatusOutput.stdout.includes(
"System Integrity Protection status: disabled.",
)
) {
core.exportVariable(EnvVar.IS_SIP_ENABLED, "false");
return false;
}
}
return undefined;
} catch (e) {
logger.warning(
`Failed to determine if System Integrity Protection was enabled: ${e}`,
);
return undefined;
}
}
export async function cleanUpPath(file: string, name: string, logger: Logger) {
logger.debug(`Cleaning up ${name}.`);
try {
@@ -1219,6 +1291,17 @@ export function isDefined<T>(value: T | null | undefined): value is T {
return value !== undefined && value !== null;
}
/** Like `Object.keys`, but typed so that the elements of the resulting array have the
* same type as the keys of the input object. Note that this may not be sound if the input
* object has been cast to `T` from a subtype of `T` and contains additional keys that
* are not represented by `keyof T`.
*/
export function unsafeKeysInvariant<T extends Record<string, any>>(
object: T,
): Array<keyof T> {
return Object.keys(object) as Array<keyof T>;
}
/** Like `Object.entries`, but typed so that the key elements of the result have the
* same type as the keys of the input object. Note that this may not be sound if the input
* object has been cast to `T` from a subtype of `T` and contains additional keys that
@@ -1231,8 +1314,3 @@ export function unsafeEntriesInvariant<T extends Record<string, any>>(
([_, val]) => val !== undefined,
) as Array<[keyof T, Exclude<T[keyof T], undefined>]>;
}
export enum CleanupLevel {
Clear = "clear",
Overlay = "overlay",
}