diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 580719d474..96e7f52f63 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,4 +1,4 @@ - + ### Risk assessment diff --git a/.github/workflows/__all-platform-bundle.yml b/.github/workflows/__all-platform-bundle.yml index 45407c57b7..6715b0f771 100644 --- a/.github/workflows/__all-platform-bundle.yml +++ b/.github/workflows/__all-platform-bundle.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: all-platform-bundle: strategy: @@ -70,7 +73,6 @@ jobs: languages: cpp,csharp,go,java,javascript,python,ruby tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze env: diff --git a/.github/workflows/__analyze-ref-input.yml b/.github/workflows/__analyze-ref-input.yml index 5e03f49928..c7fb30b0f2 100644 --- a/.github/workflows/__analyze-ref-input.yml +++ b/.github/workflows/__analyze-ref-input.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: analyze-ref-input: strategy: @@ -74,7 +77,6 @@ jobs: config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze with: diff --git a/.github/workflows/__autobuild-action.yml b/.github/workflows/__autobuild-action.yml index aebf70fb23..2e70fb8539 100644 --- a/.github/workflows/__autobuild-action.yml +++ b/.github/workflows/__autobuild-action.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: autobuild-action: strategy: @@ -67,7 +70,6 @@ jobs: CORECLR_PROFILER_PATH_64: '' - uses: ./../action/analyze - name: Check database - shell: bash run: | cd "$RUNNER_TEMP/codeql_databases" if [[ ! -d csharp ]]; then diff --git a/.github/workflows/__autobuild-direct-tracing-with-working-dir.yml b/.github/workflows/__autobuild-direct-tracing-with-working-dir.yml index 0343a1c2a4..cc5af81562 100644 --- a/.github/workflows/__autobuild-direct-tracing-with-working-dir.yml +++ b/.github/workflows/__autobuild-direct-tracing-with-working-dir.yml @@ -34,6 +34,9 @@ on: description: The version of Java to install required: false default: '17' +defaults: + run: + shell: bash jobs: autobuild-direct-tracing-with-working-dir: strategy: @@ -70,7 +73,6 @@ jobs: java-version: ${{ inputs.java-version || '17' }} distribution: temurin - name: Test setup - shell: bash run: | # Make sure that Gradle build succeeds in autobuild-dir ... cp -a ../action/tests/java-repo autobuild-dir @@ -82,7 +84,6 @@ jobs: languages: java tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Check that indirect tracing is disabled - shell: bash run: | if [[ ! -z "${CODEQL_RUNNER}" ]]; then echo "Expected indirect tracing to be disabled, but the" \ diff --git a/.github/workflows/__autobuild-direct-tracing.yml b/.github/workflows/__autobuild-direct-tracing.yml index 0841d769a3..76b4f39064 100644 --- a/.github/workflows/__autobuild-direct-tracing.yml +++ b/.github/workflows/__autobuild-direct-tracing.yml @@ -34,6 +34,9 @@ on: description: The version of Java to install required: false default: '17' +defaults: + run: + shell: bash jobs: autobuild-direct-tracing: strategy: @@ -70,7 +73,6 @@ jobs: java-version: ${{ inputs.java-version || '17' }} distribution: temurin - name: Set up Java test repo configuration - shell: bash run: | mv * .github ../action/tests/multi-language-repo/ mv ../action/tests/multi-language-repo/.github/workflows .github @@ -85,7 +87,6 @@ jobs: tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Check that indirect tracing is disabled - shell: bash run: | if [[ ! -z "${CODEQL_RUNNER}" ]]; then echo "Expected indirect tracing to be disabled, but the" \ diff --git a/.github/workflows/__build-mode-autobuild.yml b/.github/workflows/__build-mode-autobuild.yml index f421721b63..5253c4bf5c 100644 --- a/.github/workflows/__build-mode-autobuild.yml +++ b/.github/workflows/__build-mode-autobuild.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: build-mode-autobuild: strategy: diff --git a/.github/workflows/__build-mode-manual.yml b/.github/workflows/__build-mode-manual.yml index efec3292bb..82256f969a 100644 --- a/.github/workflows/__build-mode-manual.yml +++ b/.github/workflows/__build-mode-manual.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: build-mode-manual: strategy: @@ -81,7 +84,6 @@ jobs: fi - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze diff --git a/.github/workflows/__build-mode-none.yml b/.github/workflows/__build-mode-none.yml index 5f649b972c..d079cc7641 100644 --- a/.github/workflows/__build-mode-none.yml +++ b/.github/workflows/__build-mode-none.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: build-mode-none: strategy: diff --git a/.github/workflows/__build-mode-rollback.yml b/.github/workflows/__build-mode-rollback.yml index 581f785383..3fc7530cc9 100644 --- a/.github/workflows/__build-mode-rollback.yml +++ b/.github/workflows/__build-mode-rollback.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: build-mode-rollback: strategy: diff --git a/.github/workflows/__bundle-toolcache.yml b/.github/workflows/__bundle-toolcache.yml index 7d9becc006..dcb1a9d478 100644 --- a/.github/workflows/__bundle-toolcache.yml +++ b/.github/workflows/__bundle-toolcache.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: bundle-toolcache: strategy: diff --git a/.github/workflows/__bundle-zstd.yml b/.github/workflows/__bundle-zstd.yml index 650a8617de..1c10f26128 100644 --- a/.github/workflows/__bundle-zstd.yml +++ b/.github/workflows/__bundle-zstd.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: bundle-zstd: strategy: diff --git a/.github/workflows/__cleanup-db-cluster-dir.yml b/.github/workflows/__cleanup-db-cluster-dir.yml index 037f0dfd65..1b7564c74a 100644 --- a/.github/workflows/__cleanup-db-cluster-dir.yml +++ b/.github/workflows/__cleanup-db-cluster-dir.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: cleanup-db-cluster-dir: strategy: diff --git a/.github/workflows/__config-export.yml b/.github/workflows/__config-export.yml index b3af26b4f2..f43d1c6a4f 100644 --- a/.github/workflows/__config-export.yml +++ b/.github/workflows/__config-export.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: config-export: strategy: diff --git a/.github/workflows/__config-input.yml b/.github/workflows/__config-input.yml index 160a61b81f..0cd73d0d8d 100644 --- a/.github/workflows/__config-input.yml +++ b/.github/workflows/__config-input.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: config-input: strategy: diff --git a/.github/workflows/__cpp-deptrace-disabled.yml b/.github/workflows/__cpp-deptrace-disabled.yml index 3e8c79a8b5..0c3f203c48 100644 --- a/.github/workflows/__cpp-deptrace-disabled.yml +++ b/.github/workflows/__cpp-deptrace-disabled.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: cpp-deptrace-disabled: strategy: @@ -53,7 +56,6 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Test setup - shell: bash run: | cp -a ../action/tests/cpp-autobuild autobuild-dir - uses: ./../action/init @@ -65,8 +67,7 @@ jobs: working-directory: autobuild-dir env: CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES: false - - shell: bash - run: | + - run: | if ls /usr/bin/errno; then echo "C/C++ autobuild installed errno, but it should not have since auto-install dependencies is disabled." exit 1 diff --git a/.github/workflows/__cpp-deptrace-enabled-on-macos.yml b/.github/workflows/__cpp-deptrace-enabled-on-macos.yml index 5995ab945e..161d4d4e05 100644 --- a/.github/workflows/__cpp-deptrace-enabled-on-macos.yml +++ b/.github/workflows/__cpp-deptrace-enabled-on-macos.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: cpp-deptrace-enabled-on-macos: strategy: @@ -51,7 +54,6 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Test setup - shell: bash run: | cp -a ../action/tests/cpp-autobuild autobuild-dir - uses: ./../action/init @@ -63,8 +65,7 @@ jobs: working-directory: autobuild-dir env: CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES: true - - shell: bash - run: | + - run: | if ! ls /usr/bin/errno; then echo "As expected, CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES is a no-op on macOS" else diff --git a/.github/workflows/__cpp-deptrace-enabled.yml b/.github/workflows/__cpp-deptrace-enabled.yml index 623244a57e..f4526f9a15 100644 --- a/.github/workflows/__cpp-deptrace-enabled.yml +++ b/.github/workflows/__cpp-deptrace-enabled.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: cpp-deptrace-enabled: strategy: @@ -53,7 +56,6 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Test setup - shell: bash run: | cp -a ../action/tests/cpp-autobuild autobuild-dir - uses: ./../action/init @@ -65,8 +67,7 @@ jobs: working-directory: autobuild-dir env: CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES: true - - shell: bash - run: | + - run: | if ! ls /usr/bin/errno; then echo "Did not autoinstall errno" exit 1 diff --git a/.github/workflows/__diagnostics-export.yml b/.github/workflows/__diagnostics-export.yml index e07aa5e962..e89c5ce831 100644 --- a/.github/workflows/__diagnostics-export.yml +++ b/.github/workflows/__diagnostics-export.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: diagnostics-export: strategy: @@ -64,7 +67,6 @@ jobs: languages: javascript tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Add test diagnostics - shell: bash env: CODEQL_PATH: ${{ steps.init.outputs.codeql-path }} run: | diff --git a/.github/workflows/__export-file-baseline-information.yml b/.github/workflows/__export-file-baseline-information.yml index 86c519d5a8..6dd51c3e22 100644 --- a/.github/workflows/__export-file-baseline-information.yml +++ b/.github/workflows/__export-file-baseline-information.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: export-file-baseline-information: strategy: @@ -73,7 +76,6 @@ jobs: languages: javascript tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze with: @@ -85,7 +87,6 @@ jobs: path: ${{ runner.temp }}/results/javascript.sarif retention-days: 7 - name: Check results - shell: bash run: | cd "$RUNNER_TEMP/results" expected_baseline_languages="c csharp go java kotlin javascript python ruby" diff --git a/.github/workflows/__extractor-ram-threads.yml b/.github/workflows/__extractor-ram-threads.yml index 212187b2e2..486b1cc6a8 100644 --- a/.github/workflows/__extractor-ram-threads.yml +++ b/.github/workflows/__extractor-ram-threads.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: extractor-ram-threads: strategy: @@ -54,7 +57,6 @@ jobs: ram: 230 threads: 1 - name: Assert Results - shell: bash run: | if [ "${CODEQL_RAM}" != "230" ]; then echo "CODEQL_RAM is '${CODEQL_RAM}' instead of 230" diff --git a/.github/workflows/__go-custom-queries.yml b/.github/workflows/__go-custom-queries.yml index a8b0658a63..9f815b237f 100644 --- a/.github/workflows/__go-custom-queries.yml +++ b/.github/workflows/__go-custom-queries.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: go-custom-queries: strategy: @@ -71,7 +74,6 @@ jobs: config-file: ./.github/codeql/custom-queries.yml tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze env: diff --git a/.github/workflows/__go-indirect-tracing-workaround-diagnostic.yml b/.github/workflows/__go-indirect-tracing-workaround-diagnostic.yml index 554bf86e15..2208a9590d 100644 --- a/.github/workflows/__go-indirect-tracing-workaround-diagnostic.yml +++ b/.github/workflows/__go-indirect-tracing-workaround-diagnostic.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: go-indirect-tracing-workaround-diagnostic: strategy: @@ -72,7 +75,6 @@ jobs: with: go-version: '1.20' - name: Build code - shell: bash run: go build main.go - uses: ./../action/analyze with: diff --git a/.github/workflows/__go-indirect-tracing-workaround-no-file-program.yml b/.github/workflows/__go-indirect-tracing-workaround-no-file-program.yml index 6af7dce43f..63772b5ddc 100644 --- a/.github/workflows/__go-indirect-tracing-workaround-no-file-program.yml +++ b/.github/workflows/__go-indirect-tracing-workaround-no-file-program.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: go-indirect-tracing-workaround-no-file-program: strategy: @@ -73,7 +76,6 @@ jobs: languages: go tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: go build main.go - uses: ./../action/analyze with: diff --git a/.github/workflows/__go-indirect-tracing-workaround.yml b/.github/workflows/__go-indirect-tracing-workaround.yml index 5e6b4e8a2a..c702b83354 100644 --- a/.github/workflows/__go-indirect-tracing-workaround.yml +++ b/.github/workflows/__go-indirect-tracing-workaround.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: go-indirect-tracing-workaround: strategy: @@ -68,11 +71,9 @@ jobs: languages: go tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: go build main.go - uses: ./../action/analyze - - shell: bash - run: | + - run: | if [[ -z "${CODEQL_ACTION_GO_BINARY}" ]]; then echo "Expected the workaround for indirect tracing of static binaries to trigger, but the" \ "CODEQL_ACTION_GO_BINARY environment variable is not set." diff --git a/.github/workflows/__go-tracing-autobuilder.yml b/.github/workflows/__go-tracing-autobuilder.yml index f761175d99..52cdec1837 100644 --- a/.github/workflows/__go-tracing-autobuilder.yml +++ b/.github/workflows/__go-tracing-autobuilder.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: go-tracing-autobuilder: strategy: @@ -99,8 +102,7 @@ jobs: tools: ${{ steps.prepare-test.outputs.tools-url }} - uses: ./../action/autobuild - uses: ./../action/analyze - - shell: bash - run: | + - run: | if [[ "${CODEQL_ACTION_DID_AUTOBUILD_GOLANG}" != true ]]; then echo "Expected the Go autobuilder to be run, but the" \ "CODEQL_ACTION_DID_AUTOBUILD_GOLANG environment variable was not true." diff --git a/.github/workflows/__go-tracing-custom-build-steps.yml b/.github/workflows/__go-tracing-custom-build-steps.yml index e061360802..f62984ee17 100644 --- a/.github/workflows/__go-tracing-custom-build-steps.yml +++ b/.github/workflows/__go-tracing-custom-build-steps.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: go-tracing-custom-build-steps: strategy: @@ -98,11 +101,9 @@ jobs: languages: go tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: go build main.go - uses: ./../action/analyze - - shell: bash - run: | + - run: | # Once we start running Bash 4.2 in all environments, we can replace the # `! -z` flag with the more elegant `-v` which confirms that the variable # is actually unset and not potentially set to a blank value. diff --git a/.github/workflows/__go-tracing-legacy-workflow.yml b/.github/workflows/__go-tracing-legacy-workflow.yml index f81fd1698d..23926a2470 100644 --- a/.github/workflows/__go-tracing-legacy-workflow.yml +++ b/.github/workflows/__go-tracing-legacy-workflow.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: go-tracing-legacy-workflow: strategy: @@ -98,8 +101,7 @@ jobs: languages: go tools: ${{ steps.prepare-test.outputs.tools-url }} - uses: ./../action/analyze - - shell: bash - run: | + - run: | cd "$RUNNER_TEMP/codeql_databases" if [[ ! -d go ]]; then echo "Did not find a Go database" diff --git a/.github/workflows/__init-with-registries.yml b/.github/workflows/__init-with-registries.yml index c0396cefa2..d8bc2dc090 100644 --- a/.github/workflows/__init-with-registries.yml +++ b/.github/workflows/__init-with-registries.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: init-with-registries: strategy: @@ -78,7 +81,6 @@ jobs: token: "${{ secrets.GITHUB_TOKEN }}" - name: Verify packages installed - shell: bash run: | PRIVATE_PACK="$HOME/.codeql/packages/codeql-testing/private-pack" CODEQL_PACK1="$HOME/.codeql/packages/codeql-testing/codeql-pack1" @@ -100,7 +102,6 @@ jobs: fi - name: Verify qlconfig.yml file was created - shell: bash run: | QLCONFIG_PATH=$RUNNER_TEMP/qlconfig.yml echo "Expected qlconfig.yml file to be created at $QLCONFIG_PATH" @@ -115,7 +116,6 @@ jobs: - name: Verify contents of qlconfig.yml # yq is not available on windows if: runner.os != 'Windows' - shell: bash run: | QLCONFIG_PATH=$RUNNER_TEMP/qlconfig.yml cat $QLCONFIG_PATH | yq -e '.registries[] | select(.url == "https://ghcr.io/v2/") | select(.packages == "*/*")' diff --git a/.github/workflows/__javascript-source-root.yml b/.github/workflows/__javascript-source-root.yml index c8bdfee621..873e068448 100644 --- a/.github/workflows/__javascript-source-root.yml +++ b/.github/workflows/__javascript-source-root.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: javascript-source-root: strategy: @@ -53,7 +56,6 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Move codeql-action - shell: bash run: | mkdir ../new-source-root mv * ../new-source-root @@ -66,7 +68,6 @@ jobs: with: skip-queries: true - name: Assert database exists - shell: bash run: | cd "$RUNNER_TEMP/codeql_databases" if [[ ! -d javascript ]]; then diff --git a/.github/workflows/__job-run-uuid-sarif.yml b/.github/workflows/__job-run-uuid-sarif.yml index 599f21d237..410c73f8fd 100644 --- a/.github/workflows/__job-run-uuid-sarif.yml +++ b/.github/workflows/__job-run-uuid-sarif.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: job-run-uuid-sarif: strategy: @@ -63,7 +66,6 @@ jobs: path: ${{ runner.temp }}/results/javascript.sarif retention-days: 7 - name: Check results - shell: bash run: | cd "$RUNNER_TEMP/results" actual=$(jq -r '.runs[0].properties.jobRunUuid' javascript.sarif) diff --git a/.github/workflows/__language-aliases.yml b/.github/workflows/__language-aliases.yml index 629967aee2..8ed3897a21 100644 --- a/.github/workflows/__language-aliases.yml +++ b/.github/workflows/__language-aliases.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: language-aliases: strategy: diff --git a/.github/workflows/__multi-language-autodetect.yml b/.github/workflows/__multi-language-autodetect.yml index e5f157881c..b134b1e33b 100644 --- a/.github/workflows/__multi-language-autodetect.yml +++ b/.github/workflows/__multi-language-autodetect.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: multi-language-autodetect: strategy: @@ -94,7 +97,6 @@ jobs: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false - name: Use Xcode 16 - shell: bash if: runner.os == 'macOS' && matrix.version != 'nightly-latest' run: sudo xcode-select -s "/Applications/Xcode_16.app" @@ -107,7 +109,6 @@ jobs: tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze @@ -116,7 +117,6 @@ jobs: upload-database: false - name: Check language autodetect for all languages excluding Swift - shell: bash run: | CPP_DB=${{ fromJson(steps.analysis.outputs.db-locations).cpp }} if [[ ! -d $CPP_DB ]] || [[ ! $CPP_DB == ${{ runner.temp }}/customDbLocation/* ]]; then @@ -156,7 +156,6 @@ jobs: - name: Check language autodetect for Swift on macOS if: runner.os == 'macOS' - shell: bash run: | SWIFT_DB=${{ fromJson(steps.analysis.outputs.db-locations).swift }} if [[ ! -d $SWIFT_DB ]] || [[ ! $SWIFT_DB == ${{ runner.temp }}/customDbLocation/* ]]; then @@ -164,4 +163,5 @@ jobs: exit 1 fi env: + CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI: true CODEQL_ACTION_TEST_MODE: true diff --git a/.github/workflows/__overlay-init-fallback.yml b/.github/workflows/__overlay-init-fallback.yml index ea40f4df12..ffaa6c5f8e 100644 --- a/.github/workflows/__overlay-init-fallback.yml +++ b/.github/workflows/__overlay-init-fallback.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: overlay-init-fallback: strategy: @@ -61,7 +64,6 @@ jobs: with: upload-database: false - name: Check database - shell: bash run: | cd "$RUNNER_TEMP/codeql_databases/actions" if ! grep -q 'overlayBaseDatabase: false' codeql-database.yml ; then diff --git a/.github/workflows/__packaging-codescanning-config-inputs-js.yml b/.github/workflows/__packaging-codescanning-config-inputs-js.yml index 185cccbc2d..f237529479 100644 --- a/.github/workflows/__packaging-codescanning-config-inputs-js.yml +++ b/.github/workflows/__packaging-codescanning-config-inputs-js.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: packaging-codescanning-config-inputs-js: strategy: @@ -93,7 +96,6 @@ jobs: languages: javascript tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze with: @@ -109,7 +111,6 @@ jobs: queries-not-run: foo,bar - name: Assert Results - shell: bash run: | cd "$RUNNER_TEMP/results" # We should have 4 hits from these rules diff --git a/.github/workflows/__packaging-config-inputs-js.yml b/.github/workflows/__packaging-config-inputs-js.yml index 810b85df3d..3f50849c86 100644 --- a/.github/workflows/__packaging-config-inputs-js.yml +++ b/.github/workflows/__packaging-config-inputs-js.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: packaging-config-inputs-js: strategy: @@ -93,7 +96,6 @@ jobs: languages: javascript tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze with: @@ -109,7 +111,6 @@ jobs: queries-not-run: foo,bar - name: Assert Results - shell: bash run: | cd "$RUNNER_TEMP/results" # We should have 4 hits from these rules diff --git a/.github/workflows/__packaging-config-js.yml b/.github/workflows/__packaging-config-js.yml index ea96e3149f..79ec372226 100644 --- a/.github/workflows/__packaging-config-js.yml +++ b/.github/workflows/__packaging-config-js.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: packaging-config-js: strategy: @@ -92,7 +95,6 @@ jobs: languages: javascript tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze with: @@ -108,7 +110,6 @@ jobs: queries-not-run: foo,bar - name: Assert Results - shell: bash run: | cd "$RUNNER_TEMP/results" # We should have 4 hits from these rules diff --git a/.github/workflows/__packaging-inputs-js.yml b/.github/workflows/__packaging-inputs-js.yml index e2db4c4431..ea7da1aabe 100644 --- a/.github/workflows/__packaging-inputs-js.yml +++ b/.github/workflows/__packaging-inputs-js.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: packaging-inputs-js: strategy: @@ -93,7 +96,6 @@ jobs: packs: codeql-testing/codeql-pack1@1.0.0, codeql-testing/codeql-pack2, codeql-testing/codeql-pack3:other-query.ql tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze with: @@ -108,7 +110,6 @@ jobs: queries-not-run: foo,bar - name: Assert Results - shell: bash run: | cd "$RUNNER_TEMP/results" # We should have 4 hits from these rules diff --git a/.github/workflows/__quality-queries.yml b/.github/workflows/__quality-queries.yml index 1260241cb2..53e1974360 100644 --- a/.github/workflows/__quality-queries.yml +++ b/.github/workflows/__quality-queries.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: quality-queries: strategy: @@ -32,16 +35,58 @@ jobs: include: - os: ubuntu-latest version: linked + analysis-kinds: code-scanning + - os: ubuntu-latest + version: linked + analysis-kinds: code-quality + - os: ubuntu-latest + version: linked + analysis-kinds: code-scanning,code-quality + - os: macos-latest + version: linked + analysis-kinds: code-scanning - os: macos-latest version: linked + analysis-kinds: code-quality + - os: macos-latest + version: linked + analysis-kinds: code-scanning,code-quality + - os: windows-latest + version: linked + analysis-kinds: code-scanning + - os: windows-latest + version: linked + analysis-kinds: code-quality - os: windows-latest version: linked + analysis-kinds: code-scanning,code-quality - os: ubuntu-latest version: nightly-latest + analysis-kinds: code-scanning + - os: ubuntu-latest + version: nightly-latest + analysis-kinds: code-quality + - os: ubuntu-latest + version: nightly-latest + analysis-kinds: code-scanning,code-quality + - os: macos-latest + version: nightly-latest + analysis-kinds: code-scanning - os: macos-latest version: nightly-latest + analysis-kinds: code-quality + - os: macos-latest + version: nightly-latest + analysis-kinds: code-scanning,code-quality + - os: windows-latest + version: nightly-latest + analysis-kinds: code-scanning + - os: windows-latest + version: nightly-latest + analysis-kinds: code-quality - os: windows-latest version: nightly-latest + analysis-kinds: code-scanning,code-quality name: Quality queries input permissions: contents: read @@ -61,25 +106,30 @@ jobs: - uses: ./../action/init with: languages: javascript - quality-queries: code-quality + analysis-kinds: ${{ matrix.analysis-kinds }} tools: ${{ steps.prepare-test.outputs.tools-url }} - uses: ./../action/analyze with: output: ${{ runner.temp }}/results upload-database: false - name: Upload security SARIF + if: contains(matrix.analysis-kinds, 'code-scanning') uses: actions/upload-artifact@v4 with: - name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.sarif.json + name: | + quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json path: ${{ runner.temp }}/results/javascript.sarif retention-days: 7 - name: Upload quality SARIF + if: contains(matrix.analysis-kinds, 'code-quality') uses: actions/upload-artifact@v4 with: - name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.quality.sarif.json + name: | + quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.quality.sarif.json path: ${{ runner.temp }}/results/javascript.quality.sarif retention-days: 7 - name: Check quality query does not appear in security SARIF + if: contains(matrix.analysis-kinds, 'code-scanning') uses: actions/github-script@v7 env: SARIF_PATH: ${{ runner.temp }}/results/javascript.sarif @@ -87,6 +137,7 @@ jobs: with: script: ${{ env.CHECK_SCRIPT }} - name: Check quality query appears in quality SARIF + if: contains(matrix.analysis-kinds, 'code-quality') uses: actions/github-script@v7 env: SARIF_PATH: ${{ runner.temp }}/results/javascript.quality.sarif diff --git a/.github/workflows/__remote-config.yml b/.github/workflows/__remote-config.yml index 4a3fd0efff..d83f4d43d9 100644 --- a/.github/workflows/__remote-config.yml +++ b/.github/workflows/__remote-config.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: remote-config: strategy: @@ -72,7 +75,6 @@ jobs: config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze env: diff --git a/.github/workflows/__resolve-environment-action.yml b/.github/workflows/__resolve-environment-action.yml index ef130ffa1e..4df9f29d6f 100644 --- a/.github/workflows/__resolve-environment-action.yml +++ b/.github/workflows/__resolve-environment-action.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: resolve-environment-action: strategy: diff --git a/.github/workflows/__rubocop-multi-language.yml b/.github/workflows/__rubocop-multi-language.yml index 783c3a4490..7e2fa6474e 100644 --- a/.github/workflows/__rubocop-multi-language.yml +++ b/.github/workflows/__rubocop-multi-language.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: rubocop-multi-language: strategy: @@ -53,13 +56,10 @@ jobs: with: ruby-version: 2.6 - name: Install Code Scanning integration - shell: bash run: bundle add code-scanning-rubocop --version 0.3.0 --skip-install - name: Install dependencies - shell: bash run: bundle install - name: RuboCop run - shell: bash run: | bash -c " bundle exec rubocop --require code_scanning --format CodeScanning::SarifFormatter -o rubocop.sarif diff --git a/.github/workflows/__ruby.yml b/.github/workflows/__ruby.yml index f389cd7b38..27a166b6a5 100644 --- a/.github/workflows/__ruby.yml +++ b/.github/workflows/__ruby.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: ruby: strategy: @@ -67,7 +70,6 @@ jobs: with: upload-database: false - name: Check database - shell: bash run: | RUBY_DB="${{ fromJson(steps.analysis.outputs.db-locations).ruby }}" if [[ ! -d "$RUBY_DB" ]]; then diff --git a/.github/workflows/__rust.yml b/.github/workflows/__rust.yml index f7470fd277..da7d73a173 100644 --- a/.github/workflows/__rust.yml +++ b/.github/workflows/__rust.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: rust: strategy: @@ -65,7 +68,6 @@ jobs: with: upload-database: false - name: Check database - shell: bash run: | RUST_DB="${{ fromJson(steps.analysis.outputs.db-locations).rust }}" if [[ ! -d "$RUST_DB" ]]; then diff --git a/.github/workflows/__split-workflow.yml b/.github/workflows/__split-workflow.yml index 869db07457..841e6b946f 100644 --- a/.github/workflows/__split-workflow.yml +++ b/.github/workflows/__split-workflow.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: split-workflow: strategy: @@ -80,7 +83,6 @@ jobs: languages: javascript tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze with: @@ -89,7 +91,6 @@ jobs: upload-database: false - name: Assert No Results - shell: bash run: | if [ "$(ls -A $RUNNER_TEMP/results)" ]; then echo "Expected results directory to be empty after skipping query execution!" @@ -100,7 +101,6 @@ jobs: output: ${{ runner.temp }}/results upload-database: false - name: Assert Results - shell: bash run: | cd "$RUNNER_TEMP/results" # We should have 4 hits from these rules diff --git a/.github/workflows/__start-proxy.yml b/.github/workflows/__start-proxy.yml index b6c23dfb71..52a5816142 100644 --- a/.github/workflows/__start-proxy.yml +++ b/.github/workflows/__start-proxy.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: start-proxy: strategy: diff --git a/.github/workflows/__submit-sarif-failure.yml b/.github/workflows/__submit-sarif-failure.yml index c89b63d2c4..d6547821c5 100644 --- a/.github/workflows/__submit-sarif-failure.yml +++ b/.github/workflows/__submit-sarif-failure.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: submit-sarif-failure: strategy: diff --git a/.github/workflows/__swift-autobuild.yml b/.github/workflows/__swift-autobuild.yml index 82045f1a44..116ae58375 100644 --- a/.github/workflows/__swift-autobuild.yml +++ b/.github/workflows/__swift-autobuild.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: swift-autobuild: strategy: @@ -55,7 +58,6 @@ jobs: build-mode: autobuild tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Check working directory - shell: bash run: pwd - uses: ./../action/autobuild timeout-minutes: 30 @@ -64,7 +66,6 @@ jobs: with: upload-database: false - name: Check database - shell: bash run: | SWIFT_DB="${{ fromJson(steps.analysis.outputs.db-locations).swift }}" if [[ ! -d "$SWIFT_DB" ]]; then diff --git a/.github/workflows/__swift-custom-build.yml b/.github/workflows/__swift-custom-build.yml index 8fdb34724f..a5b67baebb 100644 --- a/.github/workflows/__swift-custom-build.yml +++ b/.github/workflows/__swift-custom-build.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: swift-custom-build: strategy: @@ -68,7 +71,6 @@ jobs: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false - name: Use Xcode 16 - shell: bash if: runner.os == 'macOS' && matrix.version != 'nightly-latest' run: sudo xcode-select -s "/Applications/Xcode_16.app" - uses: ./../action/init @@ -77,17 +79,14 @@ jobs: languages: swift tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Check working directory - shell: bash run: pwd - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze id: analysis with: upload-database: false - name: Check database - shell: bash run: | SWIFT_DB="${{ fromJson(steps.analysis.outputs.db-locations).swift }}" if [[ ! -d "$SWIFT_DB" ]]; then diff --git a/.github/workflows/__test-autobuild-working-dir.yml b/.github/workflows/__test-autobuild-working-dir.yml index dc4d01917a..c2c230f860 100644 --- a/.github/workflows/__test-autobuild-working-dir.yml +++ b/.github/workflows/__test-autobuild-working-dir.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: test-autobuild-working-dir: strategy: @@ -49,7 +52,6 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Test setup - shell: bash run: | # Make sure that Gradle build succeeds in autobuild-dir ... cp -a ../action/tests/java-repo autobuild-dir @@ -64,7 +66,6 @@ jobs: working-directory: autobuild-dir - uses: ./../action/analyze - name: Check database - shell: bash run: | cd "$RUNNER_TEMP/codeql_databases" if [[ ! -d java ]]; then diff --git a/.github/workflows/__test-local-codeql.yml b/.github/workflows/__test-local-codeql.yml index 417515dfd2..f4d46ad3fa 100644 --- a/.github/workflows/__test-local-codeql.yml +++ b/.github/workflows/__test-local-codeql.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: test-local-codeql: strategy: @@ -64,7 +67,6 @@ jobs: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false - name: Fetch a CodeQL bundle - shell: bash env: CODEQL_URL: ${{ steps.prepare-test.outputs.tools-url }} run: | @@ -76,7 +78,6 @@ jobs: languages: cpp,csharp,go,java,javascript,python,ruby tools: ./codeql-bundle-linux64.tar.zst - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze env: diff --git a/.github/workflows/__test-proxy.yml b/.github/workflows/__test-proxy.yml index d2f9b3533c..9420ed1444 100644 --- a/.github/workflows/__test-proxy.yml +++ b/.github/workflows/__test-proxy.yml @@ -24,6 +24,9 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash jobs: test-proxy: strategy: diff --git a/.github/workflows/__unset-environment.yml b/.github/workflows/__unset-environment.yml index 772ac35b05..5d4ba448c0 100644 --- a/.github/workflows/__unset-environment.yml +++ b/.github/workflows/__unset-environment.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: unset-environment: strategy: @@ -73,14 +76,12 @@ jobs: languages: cpp,csharp,go,java,javascript,python,ruby tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: env -i PATH="$PATH" HOME="$HOME" ./build.sh - uses: ./../action/analyze id: analysis with: upload-database: false - - shell: bash - run: | + - run: | CPP_DB="${{ fromJson(steps.analysis.outputs.db-locations).cpp }}" if [[ ! -d "$CPP_DB" ]] || [[ ! "$CPP_DB" == "${RUNNER_TEMP}/customDbLocation/cpp" ]]; then echo "::error::Did not create a database for CPP, or created it in the wrong location." \ diff --git a/.github/workflows/__upload-quality-sarif.yml b/.github/workflows/__upload-quality-sarif.yml index d122d40861..ca3ffb9881 100644 --- a/.github/workflows/__upload-quality-sarif.yml +++ b/.github/workflows/__upload-quality-sarif.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: upload-quality-sarif: strategy: @@ -73,9 +76,8 @@ jobs: languages: cpp,csharp,java,javascript,python config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }} - quality-queries: code-quality + analysis-kinds: code-scanning,code-quality - name: Build code - shell: bash run: ./build.sh # Generate some SARIF we can upload with the upload-sarif step - uses: ./../action/analyze diff --git a/.github/workflows/__upload-ref-sha-input.yml b/.github/workflows/__upload-ref-sha-input.yml index b991e7d36f..67c54bf068 100644 --- a/.github/workflows/__upload-ref-sha-input.yml +++ b/.github/workflows/__upload-ref-sha-input.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: upload-ref-sha-input: strategy: @@ -74,7 +77,6 @@ jobs: config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }} - name: Build code - shell: bash run: ./build.sh # Generate some SARIF we can upload with the upload-sarif step - uses: ./../action/analyze diff --git a/.github/workflows/__with-checkout-path.yml b/.github/workflows/__with-checkout-path.yml index 223d376420..d2fd539c6f 100644 --- a/.github/workflows/__with-checkout-path.yml +++ b/.github/workflows/__with-checkout-path.yml @@ -34,6 +34,9 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash jobs: with-checkout-path: strategy: @@ -68,7 +71,6 @@ jobs: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false - name: Delete original checkout - shell: bash run: | # delete the original checkout so we don't accidentally use it. # Actions does not support deleting the current working directory, so we @@ -89,7 +91,6 @@ jobs: source-root: x/y/z/some-path/tests/multi-language-repo - name: Build code - shell: bash working-directory: x/y/z/some-path/tests/multi-language-repo run: | ./build.sh @@ -101,7 +102,6 @@ jobs: sha: 474bbf07f9247ffe1856c6a0f94aeeb10e7afee6 - name: Verify SARIF after upload - shell: bash run: | EXPECTED_COMMIT_OID="474bbf07f9247ffe1856c6a0f94aeeb10e7afee6" EXPECTED_REF="v1.1.0" diff --git a/.github/workflows/check-expected-release-files.yml b/.github/workflows/check-expected-release-files.yml index 3a78438883..edcc499dc8 100644 --- a/.github/workflows/check-expected-release-files.yml +++ b/.github/workflows/check-expected-release-files.yml @@ -9,6 +9,10 @@ on: # by other workflows. types: [opened, synchronize, reopened, ready_for_review] +defaults: + run: + shell: bash + jobs: check-expected-release-files: runs-on: ubuntu-latest diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e6a34ccc4b..1bb3f14b75 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -13,6 +13,10 @@ on: - cron: '30 1 * * 0' workflow_dispatch: +defaults: + run: + shell: bash + env: CODEQL_ACTION_TESTING_ENVIRONMENT: codeql-action-pr-checks @@ -95,7 +99,10 @@ jobs: tools: ${{ matrix.tools }} # confirm steps.init.outputs.codeql-path points to the codeql binary - name: Print CodeQL Version - run: ${{steps.init.outputs.codeql-path}} version --format=json + run: > + "$CODEQL" version --format=json + env: + CODEQL: ${{steps.init.outputs.codeql-path}} - name: Perform CodeQL Analysis uses: ./analyze with: diff --git a/.github/workflows/codescanning-config-cli.yml b/.github/workflows/codescanning-config-cli.yml index 925e5ce177..131c914dd7 100644 --- a/.github/workflows/codescanning-config-cli.yml +++ b/.github/workflows/codescanning-config-cli.yml @@ -22,6 +22,10 @@ on: - cron: '0 5 * * *' workflow_dispatch: {} +defaults: + run: + shell: bash + jobs: code-scanning-config-tests: continue-on-error: true diff --git a/.github/workflows/debug-artifacts-failure-safe.yml b/.github/workflows/debug-artifacts-failure-safe.yml index 6cba089004..5c40cf2a4b 100644 --- a/.github/workflows/debug-artifacts-failure-safe.yml +++ b/.github/workflows/debug-artifacts-failure-safe.yml @@ -17,6 +17,11 @@ on: schedule: - cron: '0 5 * * *' workflow_dispatch: {} + +defaults: + run: + shell: bash + jobs: upload-artifacts: strategy: @@ -55,7 +60,6 @@ jobs: debug-artifact-name: my-debug-artifacts debug-database-name: my-db - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze id: analysis @@ -75,7 +79,6 @@ jobs: - name: Download all artifacts uses: actions/download-artifact@v5 - name: Check expected artifacts exist - shell: bash run: | LANGUAGES="cpp csharp go java javascript python" for version in $VERSIONS; do diff --git a/.github/workflows/debug-artifacts-safe.yml b/.github/workflows/debug-artifacts-safe.yml index 25a9cecc58..c91bb4f87d 100644 --- a/.github/workflows/debug-artifacts-safe.yml +++ b/.github/workflows/debug-artifacts-safe.yml @@ -16,6 +16,11 @@ on: schedule: - cron: '0 5 * * *' workflow_dispatch: {} + +defaults: + run: + shell: bash + jobs: upload-artifacts: strategy: @@ -54,7 +59,6 @@ jobs: # We manually exclude Swift from the languages list here, as it is not supported on Ubuntu languages: cpp,csharp,go,java,javascript,python,ruby - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze id: analysis @@ -69,7 +73,6 @@ jobs: - name: Download all artifacts uses: actions/download-artifact@v5 - name: Check expected artifacts exist - shell: bash run: | VERSIONS="stable-v2.20.3 default linked nightly-latest" LANGUAGES="cpp csharp go java javascript python" diff --git a/.github/workflows/post-release-mergeback.yml b/.github/workflows/post-release-mergeback.yml index 67d7e9493f..bb52c1f6f5 100644 --- a/.github/workflows/post-release-mergeback.yml +++ b/.github/workflows/post-release-mergeback.yml @@ -18,6 +18,10 @@ on: branches: - releases/v* +defaults: + run: + shell: bash + jobs: merge-back: runs-on: ubuntu-latest diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 365b53a945..d4993b6cee 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -8,6 +8,10 @@ on: types: [opened, synchronize, reopened, ready_for_review] workflow_dispatch: +defaults: + run: + shell: bash + jobs: unit-tests: name: Unit Tests @@ -22,6 +26,10 @@ jobs: timeout-minutes: 45 steps: + - name: Prepare git (Windows) + if: runner.os == 'Windows' + run: git config --global core.autocrlf false + - uses: actions/checkout@v5 - name: Set up Node.js diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 7678870cc6..82fa18e3b8 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -22,6 +22,10 @@ on: paths: - .github/workflows/prepare-release.yml +defaults: + run: + shell: bash + jobs: prepare: name: "Prepare release" diff --git a/.github/workflows/publish-immutable-action.yml b/.github/workflows/publish-immutable-action.yml index 50acdbd346..effe2255a2 100644 --- a/.github/workflows/publish-immutable-action.yml +++ b/.github/workflows/publish-immutable-action.yml @@ -4,6 +4,10 @@ on: release: types: [published] +defaults: + run: + shell: bash + jobs: publish: runs-on: ubuntu-latest diff --git a/.github/workflows/python312-windows.yml b/.github/workflows/python312-windows.yml index 80944886ba..40061955b7 100644 --- a/.github/workflows/python312-windows.yml +++ b/.github/workflows/python312-windows.yml @@ -12,6 +12,10 @@ on: - cron: '0 0 * * 1' workflow_dispatch: +defaults: + run: + shell: bash + jobs: test-setup-python-scripts: env: diff --git a/.github/workflows/query-filters.yml b/.github/workflows/query-filters.yml index 1014b4e553..60212c918c 100644 --- a/.github/workflows/query-filters.yml +++ b/.github/workflows/query-filters.yml @@ -15,6 +15,10 @@ on: - cron: '0 5 * * *' workflow_dispatch: {} +defaults: + run: + shell: bash + jobs: query-filters: name: Query Filters Tests diff --git a/.github/workflows/rebuild.yml b/.github/workflows/rebuild.yml index 9ac5e64e0c..874ca7a4dc 100644 --- a/.github/workflows/rebuild.yml +++ b/.github/workflows/rebuild.yml @@ -5,6 +5,10 @@ on: types: [labeled] workflow_dispatch: +defaults: + run: + shell: bash + jobs: rebuild: name: Rebuild Action diff --git a/.github/workflows/rollback-release.yml b/.github/workflows/rollback-release.yml index e492ea870e..cf11d2ca1c 100644 --- a/.github/workflows/rollback-release.yml +++ b/.github/workflows/rollback-release.yml @@ -14,6 +14,10 @@ on: - .github/workflows/rollback-release.yml - .github/actions/prepare-mergeback-branch/** +defaults: + run: + shell: bash + jobs: prepare: name: "Prepare release" @@ -53,7 +57,6 @@ jobs: - name: Create tag for testing if: github.event_name != 'workflow_dispatch' - shell: bash run: git tag v0.0.0 # We start by preparing the mergeback branch, mainly so that we have the updated changelog @@ -96,7 +99,6 @@ jobs: echo "::endgroup::" - name: Create tags - shell: bash env: # We usually expect to checkout `inputs.rollback-tag` (required for `workflow_dispatch`), # but use `v0.0.0` for testing. @@ -111,7 +113,6 @@ jobs: - name: Push tags # skip when testing if: github.event_name == 'workflow_dispatch' - shell: bash env: RELEASE_TAG: ${{ needs.prepare.outputs.version }} MAJOR_VERSION_TAG: ${{ needs.prepare.outputs.major_version }} @@ -160,7 +161,6 @@ jobs: echo "Created draft rollback release at $RELEASE_URL" >> $GITHUB_STEP_SUMMARY - name: Update changelog - shell: bash env: NEW_CHANGELOG: "${{ runner.temp }}/new_changelog.md" NEW_BRANCH: "${{ steps.mergeback-branch.outputs.new-branch }}" diff --git a/.github/workflows/script/update-required-checks.sh b/.github/workflows/script/update-required-checks.sh index ec2aa1e355..950b13c5d4 100755 --- a/.github/workflows/script/update-required-checks.sh +++ b/.github/workflows/script/update-required-checks.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash # Update the required checks based on the current branch. -# Typically, this will be main. SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" REPO_DIR="$(dirname "$SCRIPT_DIR")" diff --git a/.github/workflows/test-codeql-bundle-all.yml b/.github/workflows/test-codeql-bundle-all.yml index 1d0cdfbe20..3ccfb4e637 100644 --- a/.github/workflows/test-codeql-bundle-all.yml +++ b/.github/workflows/test-codeql-bundle-all.yml @@ -16,6 +16,9 @@ on: schedule: - cron: '0 5 * * *' workflow_dispatch: {} +defaults: + run: + shell: bash jobs: test-codeql-bundle-all: strategy: @@ -46,7 +49,6 @@ jobs: languages: cpp,csharp,go,java,javascript,python,ruby tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze env: diff --git a/.github/workflows/update-bundle.yml b/.github/workflows/update-bundle.yml index 10f5be738d..3f49c2a14f 100644 --- a/.github/workflows/update-bundle.yml +++ b/.github/workflows/update-bundle.yml @@ -13,6 +13,10 @@ on: # to filter pre-release attribute. types: [published] +defaults: + run: + shell: bash + jobs: update-bundle: if: github.event.release.prerelease && startsWith(github.event.release.tag_name, 'codeql-bundle-') diff --git a/.github/workflows/update-proxy-release.yml b/.github/workflows/update-proxy-release.yml index 5fc3b14b54..bf08414d5f 100644 --- a/.github/workflows/update-proxy-release.yml +++ b/.github/workflows/update-proxy-release.yml @@ -7,6 +7,10 @@ on: type: string required: true +defaults: + run: + shell: bash + jobs: update: name: Update code and create PR @@ -20,7 +24,6 @@ jobs: steps: - name: Check release tag format id: checks - shell: bash run: | if ! [[ $RELEASE_TAG =~ ^codeql-bundle-v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "Invalid release tag: expected a CodeQL bundle tag in the 'codeql-bundle-vM.N.P' format." @@ -30,7 +33,6 @@ jobs: echo "target_branch=dependency-proxy/$RELEASE_TAG" >> $GITHUB_OUTPUT - name: Check that the release exists - shell: bash env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" run: | @@ -46,20 +48,17 @@ jobs: ref: main - name: Update git config - shell: bash run: | git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" git config --global user.name "github-actions[bot]" - name: Update release tag and version - shell: bash run: | NOW=$(date +"%Y%m%d%H%M%S") # only used to make sure we don't fetch stale binaries from the toolcache sed -i "s|https://github.com/github/codeql-action/releases/download/codeql-bundle-v[0-9.]\+/|https://github.com/github/codeql-action/releases/download/$RELEASE_TAG/|g" ./src/start-proxy-action.ts sed -i "s/\"v2.0.[0-9]\+\"/\"v2.0.$NOW\"/g" ./src/start-proxy-action.ts - name: Compile TypeScript and commit changes - shell: bash env: TARGET_BRANCH: ${{ steps.checks.outputs.target_branch }} run: | @@ -72,7 +71,6 @@ jobs: git commit -m "Update release used by \`start-proxy\` action" - name: Push changes and open PR - shell: bash env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" TARGET_BRANCH: ${{ steps.checks.outputs.target_branch }} diff --git a/.github/workflows/update-release-branch.yml b/.github/workflows/update-release-branch.yml index 8701d7122b..f850f6505d 100644 --- a/.github/workflows/update-release-branch.yml +++ b/.github/workflows/update-release-branch.yml @@ -11,6 +11,10 @@ on: branches: - releases/* +defaults: + run: + shell: bash + jobs: prepare: diff --git a/CHANGELOG.md b/CHANGELOG.md index 930bdb263f..1be12ea80d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,25 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th ## [UNRELEASED] +- We have improved the CodeQL Action's ability to validate that the workflow it is used in does not use different versions of the CodeQL Action for different workflow steps. Mixing different versions of the CodeQL Action in the same workflow is unsupported and can lead to unpredictable results. A warning will now be emitted from the `codeql-action/init` step if different versions of the CodeQL Action are detected in the workflow file. Additionally, an error will now be thrown by the other CodeQL Action steps if they load a configuration file that was generated by a different version of the `codeql-action/init` step. [#3099](https://github.com/github/codeql-action/pull/3099) and [#3100](https://github.com/github/codeql-action/pull/3100) +- We added support for reducing the size of dependency caches for Java analyses, which will reduce cache usage and speed up workflows. This will be enabled automatically at a later time. [#3107](https://github.com/github/codeql-action/pull/3107) + +## 3.30.3 - 10 Sep 2025 + No user facing changes. +## 3.30.2 - 09 Sep 2025 + +- Fixed a bug which could cause language autodetection to fail. [#3084](https://github.com/github/codeql-action/pull/3084) +- Experimental: The `quality-queries` input that was added in `3.29.2` as part of an internal experiment is now deprecated and will be removed in an upcoming version of the CodeQL Action. It has been superseded by a new `analysis-kinds` input, which is part of the same internal experiment. Do not use this in production as it is subject to change at any time. [#3064](https://github.com/github/codeql-action/pull/3064) + +## 3.30.1 - 05 Sep 2025 + +- Update default CodeQL bundle version to 2.23.0. [#3077](https://github.com/github/codeql-action/pull/3077) + ## 3.30.0 - 01 Sep 2025 -No user facing changes. +- Reduce the size of the CodeQL Action, speeding up workflows by approximately 4 seconds. [#3054](https://github.com/github/codeql-action/pull/3054) ## 3.29.11 - 21 Aug 2025 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 23b2f90656..83fff23936 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -60,7 +60,7 @@ Here are a few things you can do that will increase the likelihood of your pull You can start a release by triggering this workflow via [workflow dispatch](https://github.com/github/codeql-action/actions/workflows/update-release-branch.yml). 1. The workflow run will open a pull request titled "Merge main into releases/v3". Follow the steps on the checklist in the pull request. Once you've checked off all but the last two of these, approve the PR and automerge it. -1. When the "Merge main into releases/v3" pull request is merged into the `releases/v3` branch, a mergeback pull request to `main` will be automatically created. This mergeback pull request incorporates the changelog updates into `main`, tags the release using the merge commit of the "Merge main into releases/v3" pull request, and bumps the patch version of the CodeQL Action. +1. When the "Merge main into releases/v3" pull request is merged into the `releases/v3` branch, a mergeback pull request to `main` will be automatically created. This mergeback pull request incorporates the changelog updates into `main`, tags the release using the merge commit of the "Merge main into releases/v3" pull request, and bumps the patch version of the CodeQL Action. 1. If a backport to an older major version is required, a pull request targeting that version's branch will also be automatically created. 1. Approve the mergeback and backport pull request (if applicable) and automerge them. @@ -68,11 +68,12 @@ Once the mergeback and backport pull request have been merged, the release is co ## Keeping the PR checks up to date (admin access required) -Since the `codeql-action` runs most of its testing through individual Actions workflows, there are over two hundred jobs that need to pass in order for a PR to turn green. You can regenerate the checks automatically by running the [update-required-checks.sh](.github/workflows/script/update-required-checks.sh) script: +Since the `codeql-action` runs most of its testing through individual Actions workflows, there are over two hundred required jobs that need to pass in order for a PR to turn green. It would be too tedious to maintain that list manually. You can regenerate the set of required checks automatically by running the [update-required-checks.sh](.github/workflows/script/update-required-checks.sh) script: -1. By default, this script retrieves the checks from the latest SHA on `main`, so make sure that your `main` branch is up to date. -2. Run the script. If there's a reason to, you can pass in a different SHA as a CLI argument. -3. After running, go to the [branch protection rules settings page](https://github.com/github/codeql-action/settings/branches) and validate that the rules for `main`, `v3`, and any other currently supported major versions have been updated. +- If you run the script without an argument, it will retrieve the set of workflows that ran for the latest commit on `main`. Make sure that your local `main` branch is up to date before running the script. +- You can specify a commit SHA as argument to retrieve the set of workflows for that commit instead. You will likely want to use this if you have a PR that removes or adds PR checks. + +After running, go to the [branch protection rules settings page](https://github.com/github/codeql-action/settings/branches) and validate that the rules for `main`, `v3`, and any other currently supported major versions have been updated. Note that any updates to checks on `main` need to be backported to all currently supported major version branches, in order to maintain the same set of names for required checks. diff --git a/lib/analyze-action-post.js b/lib/analyze-action-post.js index 99d289f8f0..f15d2fdb22 100644 --- a/lib/analyze-action-post.js +++ b/lib/analyze-action-post.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -26438,7 +26438,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.1", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -26486,26 +26486,24 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^11.1.0" + uuid: "^12.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.34.0", + "@eslint/js": "^9.35.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@octokit/types": "^14.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", - "@types/get-folder-size": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/node": "20.19.9", "@types/node-forge": "^1.3.14", - "@types/semver": "^7.7.0", + "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", esbuild: "^0.25.9", @@ -26538,7 +26536,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -31823,14 +31822,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -31841,7 +31840,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -77687,7 +77686,7 @@ var require_brace_expansion2 = __commonJS({ var isSequence = isNumericSequence || isAlphaSequence; var isOptions = m.body.indexOf(",") >= 0; if (!isSequence && !isOptions) { - if (m.post.match(/,.*\}/)) { + if (m.post.match(/,(?!,).*\}/)) { str2 = m.pre + "{" + m.body + escClose + m.post; return expand(str2); } @@ -102912,7 +102911,7 @@ var require_dist_node16 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -102920,7 +102919,7 @@ var require_dist_node16 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -102930,12 +102929,12 @@ var require_dist_node16 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push(encodeValue(operator, value2, isKeyOperator(operator) ? key : "")); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -102943,12 +102942,12 @@ var require_dist_node16 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -102963,7 +102962,7 @@ var require_dist_node16 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -117688,7 +117687,7 @@ function withGroup(groupName, f) { // src/overlay-database-utils.ts var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; -var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 6e3; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 15e3; var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; async function writeBaseDatabaseOidsFile(config, sourceRoot) { const gitFileOids = await getFileOidsUnderPath(sourceRoot); @@ -117798,6 +117797,12 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["resolve_supported_languages_using_cli" /* ResolveSupportedLanguagesUsingCli */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI", + minimumVersion: void 0, + toolsFeature: "builtinExtractorsSpecifyDefaultQueries" /* BuiltinExtractorsSpecifyDefaultQueries */ + }, ["overlay_analysis" /* OverlayAnalysis */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS", @@ -117914,6 +117919,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_QA_TELEMETRY", legacyApi: true, minimumVersion: void 0 + }, + ["java_minimize_dependency_jars" /* JavaMinimizeDependencyJars */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS", + minimumVersion: "2.23.0" } }; @@ -117921,15 +117931,6 @@ var featureConfig = { var actionsCache2 = __toESM(require_cache3()); // src/config-utils.ts -var defaultAugmentationProperties = { - queriesInputCombines: false, - packsInputCombines: false, - packsInput: void 0, - queriesInput: void 0, - extraQueryExclusions: [], - overlayDatabaseMode: "none" /* None */, - useOverlayDatabaseCaching: false -}; var OVERLAY_ANALYSIS_FEATURES = { actions: "overlay_analysis_actions" /* OverlayAnalysisActions */, cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, @@ -117971,40 +117972,23 @@ async function getConfig(tempDir, logger) { const configString = fs3.readFileSync(configFile, "utf8"); logger.debug("Loaded config:"); logger.debug(configString); - return JSON.parse(configString); -} -function generateCodeScanningConfig(originalUserInput, augmentationProperties) { - const augmentedConfig = cloneObject(originalUserInput); - if (augmentationProperties.queriesInput) { - if (augmentationProperties.queriesInputCombines) { - augmentedConfig.queries = (augmentedConfig.queries || []).concat( - augmentationProperties.queriesInput - ); - } else { - augmentedConfig.queries = augmentationProperties.queriesInput; - } - } - if (augmentedConfig.queries?.length === 0) { - delete augmentedConfig.queries; + const config = JSON.parse(configString); + if (config.version === void 0) { + throw new ConfigurationError( + `Loaded configuration file, but it does not contain the expected 'version' field.` + ); } - if (augmentationProperties.packsInput) { - if (augmentationProperties.packsInputCombines) { - if (Array.isArray(augmentedConfig.packs)) { - augmentedConfig.packs = (augmentedConfig.packs || []).concat( - augmentationProperties.packsInput - ); - } else if (!augmentedConfig.packs) { - augmentedConfig.packs = augmentationProperties.packsInput; - } else { - const language = Object.keys(augmentedConfig.packs)[0]; - augmentedConfig.packs[language] = augmentedConfig.packs[language].concat(augmentationProperties.packsInput); - } - } else { - augmentedConfig.packs = augmentationProperties.packsInput; - } + if (config.version !== getActionVersion()) { + throw new ConfigurationError( + `Loaded a configuration file for version '${config.version}', but running version '${getActionVersion()}'` + ); } - if (Array.isArray(augmentedConfig.packs) && !augmentedConfig.packs.length) { - delete augmentedConfig.packs; + return config; +} +function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { + const augmentedConfig = cloneObject(cliConfig); + if (extraQueryExclusions.length === 0) { + return augmentedConfig; } augmentedConfig["query-filters"] = [ // Ordering matters. If the first filter is an inclusion, it implicitly @@ -118012,7 +117996,7 @@ function generateCodeScanningConfig(originalUserInput, augmentationProperties) { // it implicitly includes all queries that are not excluded. So user // filters (if any) should always be first to preserve intent. ...augmentedConfig["query-filters"] || [], - ...augmentationProperties.extraQueryExclusions + ...extraQueryExclusions ]; if (augmentedConfig["query-filters"]?.length === 0) { delete augmentedConfig["query-filters"]; @@ -118134,7 +118118,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { await this.getVersion(), "forceOverwrite" /* ForceOverwrite */ ) ? "--force-overwrite" : "--overwrite"; - const overlayDatabaseMode = config.augmentationProperties.overlayDatabaseMode; + const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode === "overlay" /* Overlay */) { const overlayChangesFile = await writeOverlayChangesFile( config, @@ -118245,13 +118229,16 @@ async function getCodeQLForCmd(cmd, checkVersion) { ); } }, - async betterResolveLanguages() { + async betterResolveLanguages({ + filterToLanguagesWithQueries + } = { filterToLanguagesWithQueries: false }) { const codeqlArgs = [ "resolve", "languages", "--format=betterjson", "--extractor-options-verbosity=4", "--extractor-include-aliases", + ...filterToLanguagesWithQueries ? ["--filter-to-languages-with-queries"] : [], ...getExtraOptionsFromEnv(["resolve", "languages"]) ]; const output = await runCli(cmd, codeqlArgs); @@ -118290,7 +118277,6 @@ ${output}` "run-queries", ...flags, databasePath, - "--intra-layer-parallelism", "--min-disk-free=1024", // Try to leave at least 1GB free "-v", @@ -118548,9 +118534,9 @@ async function runCli(cmd, args = [], opts = {}) { } async function writeCodeScanningConfigFile(config, logger) { const codeScanningConfigFile = getGeneratedCodeScanningConfigPath(config); - const augmentedConfig = generateCodeScanningConfig( - config.originalUserInput, - config.augmentationProperties + const augmentedConfig = appendExtraQueryExclusions( + config.extraQueryExclusions, + config.computedConfig ); logger.info( `Writing augmented user configuration file to ${codeScanningConfigFile}` diff --git a/lib/analyze-action.js b/lib/analyze-action.js index 29aef44a7a..0aafe30799 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -184,7 +184,7 @@ var require_file_command = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.prepareKeyValueMessage = exports2.issueFileCommand = void 0; - var crypto = __importStar4(require("crypto")); + var crypto2 = __importStar4(require("crypto")); var fs20 = __importStar4(require("fs")); var os5 = __importStar4(require("os")); var utils_1 = require_utils(); @@ -202,7 +202,7 @@ var require_file_command = __commonJS({ } exports2.issueFileCommand = issueFileCommand; function prepareKeyValueMessage(key, value) { - const delimiter = `ghadelimiter_${crypto.randomUUID()}`; + const delimiter = `ghadelimiter_${crypto2.randomUUID()}`; const convertedValue = (0, utils_1.toCommandValue)(value); if (key.includes(delimiter)) { throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); @@ -3637,11 +3637,11 @@ var require_util2 = __commonJS({ var assert = require("assert"); var { isUint8Array } = require("util/types"); var supportedHashes = []; - var crypto; + var crypto2; try { - crypto = require("crypto"); + crypto2 = require("crypto"); const possibleRelevantHashes = ["sha256", "sha384", "sha512"]; - supportedHashes = crypto.getHashes().filter((hash2) => possibleRelevantHashes.includes(hash2)); + supportedHashes = crypto2.getHashes().filter((hash2) => possibleRelevantHashes.includes(hash2)); } catch { } function responseURL(response) { @@ -3918,7 +3918,7 @@ var require_util2 = __commonJS({ } } function bytesMatch(bytes, metadataList) { - if (crypto === void 0) { + if (crypto2 === void 0) { return true; } const parsedMetadata = parseMetadata(metadataList); @@ -3933,7 +3933,7 @@ var require_util2 = __commonJS({ for (const item of metadata) { const algorithm = item.algo; const expectedValue = item.hash; - let actualValue = crypto.createHash(algorithm).update(bytes).digest("base64"); + let actualValue = crypto2.createHash(algorithm).update(bytes).digest("base64"); if (actualValue[actualValue.length - 1] === "=") { if (actualValue[actualValue.length - 2] === "=") { actualValue = actualValue.slice(0, -2); @@ -5279,8 +5279,8 @@ var require_body = __commonJS({ var { parseMIMEType, serializeAMimeType } = require_dataURL(); var random; try { - const crypto = require("node:crypto"); - random = (max) => crypto.randomInt(0, max); + const crypto2 = require("node:crypto"); + random = (max) => crypto2.randomInt(0, max); } catch { random = (max) => Math.floor(Math.random(max)); } @@ -16330,9 +16330,9 @@ var require_connection = __commonJS({ channels.open = diagnosticsChannel.channel("undici:websocket:open"); channels.close = diagnosticsChannel.channel("undici:websocket:close"); channels.socketError = diagnosticsChannel.channel("undici:websocket:socket_error"); - var crypto; + var crypto2; try { - crypto = require("crypto"); + crypto2 = require("crypto"); } catch { } function establishWebSocketConnection(url2, protocols, ws, onEstablish, options) { @@ -16351,7 +16351,7 @@ var require_connection = __commonJS({ const headersList = new Headers(options.headers)[kHeadersList]; request.headersList = headersList; } - const keyValue = crypto.randomBytes(16).toString("base64"); + const keyValue = crypto2.randomBytes(16).toString("base64"); request.headersList.append("sec-websocket-key", keyValue); request.headersList.append("sec-websocket-version", "13"); for (const protocol of protocols) { @@ -16380,7 +16380,7 @@ var require_connection = __commonJS({ return; } const secWSAccept = response.headersList.get("Sec-WebSocket-Accept"); - const digest = crypto.createHash("sha1").update(keyValue + uid).digest("base64"); + const digest = crypto2.createHash("sha1").update(keyValue + uid).digest("base64"); if (secWSAccept !== digest) { failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header."); return; @@ -16460,9 +16460,9 @@ var require_frame = __commonJS({ "node_modules/undici/lib/websocket/frame.js"(exports2, module2) { "use strict"; var { maxUnsigned16Bit } = require_constants5(); - var crypto; + var crypto2; try { - crypto = require("crypto"); + crypto2 = require("crypto"); } catch { } var WebsocketFrameSend = class { @@ -16471,7 +16471,7 @@ var require_frame = __commonJS({ */ constructor(data) { this.frameData = data; - this.maskKey = crypto.randomBytes(4); + this.maskKey = crypto2.randomBytes(4); } createFrame(opcode) { const bodyLength = this.frameData?.byteLength ?? 0; @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -32287,7 +32287,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.1", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -32335,26 +32335,24 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^11.1.0" + uuid: "^12.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.34.0", + "@eslint/js": "^9.35.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@octokit/types": "^14.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", - "@types/get-folder-size": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/node": "20.19.9", "@types/node-forge": "^1.3.14", - "@types/semver": "^7.7.0", + "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", esbuild: "^0.25.9", @@ -32387,7 +32385,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -36931,7 +36930,7 @@ var require_cacheUtils = __commonJS({ var exec2 = __importStar4(require_exec()); var glob2 = __importStar4(require_glob()); var io7 = __importStar4(require_io()); - var crypto = __importStar4(require("crypto")); + var crypto2 = __importStar4(require("crypto")); var fs20 = __importStar4(require("fs")); var path20 = __importStar4(require("path")); var semver8 = __importStar4(require_semver3()); @@ -36955,7 +36954,7 @@ var require_cacheUtils = __commonJS({ } tempDirectory = path20.join(baseLocation, "actions", "temp"); } - const dest = path20.join(tempDirectory, crypto.randomUUID()); + const dest = path20.join(tempDirectory, crypto2.randomUUID()); yield io7.mkdirP(dest); return dest; }); @@ -37071,7 +37070,7 @@ var require_cacheUtils = __commonJS({ components.push("windows-only"); } components.push(versionSalt); - return crypto.createHash("sha256").update(components.join("|")).digest("hex"); + return crypto2.createHash("sha256").update(components.join("|")).digest("hex"); } exports2.getCacheVersion = getCacheVersion; function getRuntimeToken() { @@ -37672,14 +37671,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -37690,7 +37689,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -48815,7 +48814,7 @@ var require_dist7 = __commonJS({ var coreXml = require_commonjs9(); var logger$1 = require_dist(); var abortController = require_commonjs10(); - var crypto = require("crypto"); + var crypto2 = require("crypto"); var coreTracing = require_commonjs4(); var stream2 = require("stream"); var coreLro = require_dist6(); @@ -50323,7 +50322,7 @@ ${key}:${decodeURIComponent(lowercaseQueries[key])}`; * @param stringToSign - */ computeHMACSHA256(stringToSign) { - return crypto.createHmac("sha256", this.accountKey).update(stringToSign, "utf8").digest("base64"); + return crypto2.createHmac("sha256", this.accountKey).update(stringToSign, "utf8").digest("base64"); } }; var AnonymousCredentialPolicy = class extends CredentialPolicy { @@ -50521,7 +50520,7 @@ ${key}:${decodeURIComponent(lowercaseQueries[key])}`; getHeaderValueToSign(request, HeaderConstants.IF_UNMODIFIED_SINCE), getHeaderValueToSign(request, HeaderConstants.RANGE) ].join("\n") + "\n" + getCanonicalizedHeadersString(request) + getCanonicalizedResourceString(request); - const signature = crypto.createHmac("sha256", options.accountKey).update(stringToSign, "utf8").digest("base64"); + const signature = crypto2.createHmac("sha256", options.accountKey).update(stringToSign, "utf8").digest("base64"); request.headers.set(HeaderConstants.AUTHORIZATION, `SharedKey ${options.accountName}:${signature}`); } function getHeaderValueToSign(request, headerName) { @@ -64280,7 +64279,7 @@ ${key}:${decodeURIComponent(lowercaseQueries[key])}`; * @param stringToSign - */ computeHMACSHA256(stringToSign) { - return crypto.createHmac("sha256", this.key).update(stringToSign, "utf8").digest("base64"); + return crypto2.createHmac("sha256", this.key).update(stringToSign, "utf8").digest("base64"); } }; function ipRangeToString(ipRange) { @@ -79551,7 +79550,7 @@ var require_tool_cache = __commonJS({ exports2.evaluateVersions = exports2.isExplicitVersion = exports2.findFromManifest = exports2.getManifestFromRepo = exports2.findAllVersions = exports2.find = exports2.cacheFile = exports2.cacheDir = exports2.extractZip = exports2.extractXar = exports2.extractTar = exports2.extract7z = exports2.downloadTool = exports2.HTTPError = void 0; var core15 = __importStar4(require_core()); var io7 = __importStar4(require_io()); - var crypto = __importStar4(require("crypto")); + var crypto2 = __importStar4(require("crypto")); var fs20 = __importStar4(require("fs")); var mm = __importStar4(require_manifest()); var os5 = __importStar4(require("os")); @@ -79576,7 +79575,7 @@ var require_tool_cache = __commonJS({ var userAgent = "actions/tool-cache"; function downloadTool2(url2, dest, auth, headers) { return __awaiter4(this, void 0, void 0, function* () { - dest = dest || path20.join(_getTempDirectory(), crypto.randomUUID()); + dest = dest || path20.join(_getTempDirectory(), crypto2.randomUUID()); yield io7.mkdirP(path20.dirname(dest)); core15.debug(`Downloading ${url2}`); core15.debug(`Destination ${dest}`); @@ -79957,7 +79956,7 @@ var require_tool_cache = __commonJS({ function _createExtractFolder(dest) { return __awaiter4(this, void 0, void 0, function* () { if (!dest) { - dest = path20.join(_getTempDirectory(), crypto.randomUUID()); + dest = path20.join(_getTempDirectory(), crypto2.randomUUID()); } yield io7.mkdirP(dest); return dest; @@ -81565,7 +81564,7 @@ var require_internal_hash_files = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.hashFiles = void 0; - var crypto = __importStar4(require("crypto")); + var crypto2 = __importStar4(require("crypto")); var core15 = __importStar4(require_core()); var fs20 = __importStar4(require("fs")); var stream2 = __importStar4(require("stream")); @@ -81578,7 +81577,7 @@ var require_internal_hash_files = __commonJS({ const writeDelegate = verbose ? core15.info : core15.debug; let hasMatch = false; const githubWorkspace = currentWorkspace ? currentWorkspace : (_d = process.env["GITHUB_WORKSPACE"]) !== null && _d !== void 0 ? _d : process.cwd(); - const result = crypto.createHash("sha256"); + const result = crypto2.createHash("sha256"); let count = 0; try { for (var _e = true, _f = __asyncValues4(globber.globGenerator()), _g; _g = yield _f.next(), _a = _g.done, !_a; _e = true) { @@ -81594,7 +81593,7 @@ var require_internal_hash_files = __commonJS({ writeDelegate(`Skip directory '${file}'.`); continue; } - const hash2 = crypto.createHash("sha256"); + const hash2 = crypto2.createHash("sha256"); const pipeline = util.promisify(stream2.pipeline); yield pipeline(fs20.createReadStream(file), hash2); result.write(hash2.digest()); @@ -90115,12 +90114,6 @@ function fixCodeQualityCategory(logger, category) { return category; } -// src/analyze.ts -var fs15 = __toESM(require("fs")); -var path16 = __toESM(require("path")); -var import_perf_hooks2 = require("perf_hooks"); -var io5 = __toESM(require_io()); - // src/analyses.ts var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { AnalysisKind2["CodeScanning"] = "code-scanning"; @@ -90129,6 +90122,28 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); var codeQualityQueries = ["code-quality"]; +var CodeScanning = { + kind: "code-scanning" /* CodeScanning */, + name: "code scanning", + target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, + sarifExtension: ".sarif", + sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name), + sentinelPrefix: "CODEQL_UPLOAD_SARIF_" +}; +var CodeQuality = { + kind: "code-quality" /* CodeQuality */, + name: "code quality", + target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, + sarifExtension: ".quality.sarif", + sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), + sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" +}; + +// src/analyze.ts +var fs15 = __toESM(require("fs")); +var path16 = __toESM(require("path")); +var import_perf_hooks2 = require("perf_hooks"); +var io5 = __toESM(require_io()); // src/api-client.ts var core5 = __toESM(require_core()); @@ -90239,6 +90254,11 @@ async function getAnalysisKey() { core5.exportVariable(analysisKeyEnvVar, analysisKey); return analysisKey; } +async function getAutomationID() { + const analysis_key = await getAnalysisKey(); + const environment = getRequiredInput("matrix"); + return computeAutomationID(analysis_key, environment); +} function computeAutomationID(analysis_key, environment) { let automationID = `${analysis_key}/`; const matrix = parseMatrixInput(environment); @@ -90559,10 +90579,11 @@ var path8 = __toESM(require("path")); var semver3 = __toESM(require_semver2()); // src/defaults.json -var bundleVersion = "codeql-bundle-v2.22.4"; -var cliVersion = "2.22.4"; +var bundleVersion = "codeql-bundle-v2.23.0"; +var cliVersion = "2.23.0"; // src/overlay-database-utils.ts +var crypto = __toESM(require("crypto")); var fs6 = __toESM(require("fs")); var path7 = __toESM(require("path")); var actionsCache = __toESM(require_cache3()); @@ -90791,7 +90812,7 @@ function formatDuration(durationMs) { // src/overlay-database-utils.ts var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; -var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 6e3; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 15e3; var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; async function writeBaseDatabaseOidsFile(config, sourceRoot) { const gitFileOids = await getFileOidsUnderPath(sourceRoot); @@ -90863,14 +90884,14 @@ function checkOverlayBaseDatabase(config, logger, warningPrefix) { return true; } async function uploadOverlayBaseDatabaseToCache(codeql, config, logger) { - const overlayDatabaseMode = config.augmentationProperties.overlayDatabaseMode; + const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode !== "overlay-base" /* OverlayBase */) { logger.debug( `Overlay database mode is ${overlayDatabaseMode}. Skip uploading overlay-base database to cache.` ); return false; } - if (!config.augmentationProperties.useOverlayDatabaseCaching) { + if (!config.useOverlayDatabaseCaching) { logger.debug( "Overlay database caching is disabled. Skip uploading overlay-base database to cache." ); @@ -90910,14 +90931,18 @@ async function uploadOverlayBaseDatabaseToCache(codeql, config, logger) { } const codeQlVersion = (await codeql.getVersion()).version; const checkoutPath = getRequiredInput("checkout_path"); - const cacheKey3 = await generateCacheKey(config, codeQlVersion, checkoutPath); + const cacheSaveKey = await getCacheSaveKey( + config, + codeQlVersion, + checkoutPath + ); logger.info( - `Uploading overlay-base database to Actions cache with key ${cacheKey3}` + `Uploading overlay-base database to Actions cache with key ${cacheSaveKey}` ); try { const cacheId = await withTimeout( MAX_CACHE_OPERATION_MS, - actionsCache.saveCache([dbLocation], cacheKey3), + actionsCache.saveCache([dbLocation], cacheSaveKey), () => { } ); @@ -90934,13 +90959,26 @@ async function uploadOverlayBaseDatabaseToCache(codeql, config, logger) { logger.info(`Successfully uploaded overlay-base database from ${dbLocation}`); return true; } -async function generateCacheKey(config, codeQlVersion, checkoutPath) { +async function getCacheSaveKey(config, codeQlVersion, checkoutPath) { const sha = await getCommitOid(checkoutPath); - return `${getCacheRestoreKey(config, codeQlVersion)}${sha}`; + const restoreKeyPrefix = await getCacheRestoreKeyPrefix( + config, + codeQlVersion + ); + return `${restoreKeyPrefix}${sha}`; } -function getCacheRestoreKey(config, codeQlVersion) { +async function getCacheRestoreKeyPrefix(config, codeQlVersion) { const languages = [...config.languages].sort().join("_"); - return `${CACHE_PREFIX}-${CACHE_VERSION}-${languages}-${codeQlVersion}-`; + const cacheKeyComponents = { + automationID: await getAutomationID() + // Add more components here as needed in the future + }; + const componentsHash = createCacheKeyHash(cacheKeyComponents); + return `${CACHE_PREFIX}-${CACHE_VERSION}-${componentsHash}-${languages}-${codeQlVersion}-`; +} +function createCacheKeyHash(components) { + const componentsJson = JSON.stringify(components); + return crypto.createHash("sha256").update(componentsJson).digest("hex").substring(0, 16); } // src/tools-features.ts @@ -90993,6 +91031,12 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["resolve_supported_languages_using_cli" /* ResolveSupportedLanguagesUsingCli */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI", + minimumVersion: void 0, + toolsFeature: "builtinExtractorsSpecifyDefaultQueries" /* BuiltinExtractorsSpecifyDefaultQueries */ + }, ["overlay_analysis" /* OverlayAnalysis */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS", @@ -91109,6 +91153,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_QA_TELEMETRY", legacyApi: true, minimumVersion: void 0 + }, + ["java_minimize_dependency_jars" /* JavaMinimizeDependencyJars */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS", + minimumVersion: "2.23.0" } }; var FEATURE_FLAGS_FILE_NAME = "cached-feature-flags.json"; @@ -91542,15 +91591,6 @@ async function cachePrefix(codeql, language) { } // src/config-utils.ts -var defaultAugmentationProperties = { - queriesInputCombines: false, - packsInputCombines: false, - packsInput: void 0, - queriesInput: void 0, - extraQueryExclusions: [], - overlayDatabaseMode: "none" /* None */, - useOverlayDatabaseCaching: false -}; var OVERLAY_ANALYSIS_FEATURES = { actions: "overlay_analysis_actions" /* OverlayAnalysisActions */, cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, @@ -91592,40 +91632,23 @@ async function getConfig(tempDir, logger) { const configString = fs9.readFileSync(configFile, "utf8"); logger.debug("Loaded config:"); logger.debug(configString); - return JSON.parse(configString); -} -function generateCodeScanningConfig(originalUserInput, augmentationProperties) { - const augmentedConfig = cloneObject(originalUserInput); - if (augmentationProperties.queriesInput) { - if (augmentationProperties.queriesInputCombines) { - augmentedConfig.queries = (augmentedConfig.queries || []).concat( - augmentationProperties.queriesInput - ); - } else { - augmentedConfig.queries = augmentationProperties.queriesInput; - } - } - if (augmentedConfig.queries?.length === 0) { - delete augmentedConfig.queries; + const config = JSON.parse(configString); + if (config.version === void 0) { + throw new ConfigurationError( + `Loaded configuration file, but it does not contain the expected 'version' field.` + ); } - if (augmentationProperties.packsInput) { - if (augmentationProperties.packsInputCombines) { - if (Array.isArray(augmentedConfig.packs)) { - augmentedConfig.packs = (augmentedConfig.packs || []).concat( - augmentationProperties.packsInput - ); - } else if (!augmentedConfig.packs) { - augmentedConfig.packs = augmentationProperties.packsInput; - } else { - const language = Object.keys(augmentedConfig.packs)[0]; - augmentedConfig.packs[language] = augmentedConfig.packs[language].concat(augmentationProperties.packsInput); - } - } else { - augmentedConfig.packs = augmentationProperties.packsInput; - } + if (config.version !== getActionVersion()) { + throw new ConfigurationError( + `Loaded a configuration file for version '${config.version}', but running version '${getActionVersion()}'` + ); } - if (Array.isArray(augmentedConfig.packs) && !augmentedConfig.packs.length) { - delete augmentedConfig.packs; + return config; +} +function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { + const augmentedConfig = cloneObject(cliConfig); + if (extraQueryExclusions.length === 0) { + return augmentedConfig; } augmentedConfig["query-filters"] = [ // Ordering matters. If the first filter is an inclusion, it implicitly @@ -91633,16 +91656,25 @@ function generateCodeScanningConfig(originalUserInput, augmentationProperties) { // it implicitly includes all queries that are not excluded. So user // filters (if any) should always be first to preserve intent. ...augmentedConfig["query-filters"] || [], - ...augmentationProperties.extraQueryExclusions + ...extraQueryExclusions ]; if (augmentedConfig["query-filters"]?.length === 0) { delete augmentedConfig["query-filters"]; } return augmentedConfig; } +function isCodeScanningEnabled(config) { + return config.analysisKinds.includes("code-scanning" /* CodeScanning */); +} function isCodeQualityEnabled(config) { return config.analysisKinds.includes("code-quality" /* CodeQuality */); } +function getPrimaryAnalysisKind(config) { + return isCodeScanningEnabled(config) ? "code-scanning" /* CodeScanning */ : "code-quality" /* CodeQuality */; +} +function getPrimaryAnalysisConfig(config) { + return getPrimaryAnalysisKind(config) === "code-scanning" /* CodeScanning */ ? CodeScanning : CodeQuality; +} // src/setup-codeql.ts var fs12 = __toESM(require("fs")); @@ -91651,7 +91683,7 @@ var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); var semver7 = __toESM(require_semver2()); -// node_modules/uuid/dist/esm/stringify.js +// node_modules/uuid/dist/stringify.js var byteToHex = []; for (let i = 0; i < 256; ++i) { byteToHex.push((i + 256).toString(16).slice(1)); @@ -91660,27 +91692,24 @@ function unsafeStringify(arr, offset = 0) { return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); } -// node_modules/uuid/dist/esm/rng.js -var import_crypto = require("crypto"); +// node_modules/uuid/dist/rng.js +var import_node_crypto = require("node:crypto"); var rnds8Pool = new Uint8Array(256); var poolPtr = rnds8Pool.length; function rng() { if (poolPtr > rnds8Pool.length - 16) { - (0, import_crypto.randomFillSync)(rnds8Pool); + (0, import_node_crypto.randomFillSync)(rnds8Pool); poolPtr = 0; } return rnds8Pool.slice(poolPtr, poolPtr += 16); } -// node_modules/uuid/dist/esm/native.js -var import_crypto2 = require("crypto"); -var native_default = { randomUUID: import_crypto2.randomUUID }; +// node_modules/uuid/dist/native.js +var import_node_crypto2 = require("node:crypto"); +var native_default = { randomUUID: import_node_crypto2.randomUUID }; -// node_modules/uuid/dist/esm/v4.js -function v4(options, buf, offset) { - if (native_default.randomUUID && !buf && !options) { - return native_default.randomUUID(); - } +// node_modules/uuid/dist/v4.js +function _v4(options, buf, offset) { options = options || {}; const rnds = options.random ?? options.rng?.() ?? rng(); if (rnds.length < 16) { @@ -91700,6 +91729,12 @@ function v4(options, buf, offset) { } return unsafeStringify(rnds); } +function v4(options, buf, offset) { + if (native_default.randomUUID && !buf && !options) { + return native_default.randomUUID(); + } + return _v4(options, buf, offset); +} var v4_default = v4; // src/tar.ts @@ -92646,7 +92681,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { await this.getVersion(), "forceOverwrite" /* ForceOverwrite */ ) ? "--force-overwrite" : "--overwrite"; - const overlayDatabaseMode = config.augmentationProperties.overlayDatabaseMode; + const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode === "overlay" /* Overlay */) { const overlayChangesFile = await writeOverlayChangesFile( config, @@ -92757,13 +92792,16 @@ async function getCodeQLForCmd(cmd, checkVersion) { ); } }, - async betterResolveLanguages() { + async betterResolveLanguages({ + filterToLanguagesWithQueries + } = { filterToLanguagesWithQueries: false }) { const codeqlArgs = [ "resolve", "languages", "--format=betterjson", "--extractor-options-verbosity=4", "--extractor-include-aliases", + ...filterToLanguagesWithQueries ? ["--filter-to-languages-with-queries"] : [], ...getExtraOptionsFromEnv(["resolve", "languages"]) ]; const output = await runCli(cmd, codeqlArgs); @@ -92802,7 +92840,6 @@ ${output}` "run-queries", ...flags, databasePath, - "--intra-layer-parallelism", "--min-disk-free=1024", // Try to leave at least 1GB free "-v", @@ -93060,9 +93097,9 @@ async function runCli(cmd, args = [], opts = {}) { } async function writeCodeScanningConfigFile(config, logger) { const codeScanningConfigFile = getGeneratedCodeScanningConfigPath(config); - const augmentedConfig = generateCodeScanningConfig( - config.originalUserInput, - config.augmentationProperties + const augmentedConfig = appendExtraQueryExclusions( + config.extraQueryExclusions, + config.computedConfig ); logger.info( `Writing augmented user configuration file to ${codeScanningConfigFile}` @@ -93210,7 +93247,7 @@ function getDefaultCacheConfig() { async function makeGlobber(patterns) { return glob.create(patterns.join("\n")); } -async function uploadDependencyCaches(config, logger) { +async function uploadDependencyCaches(config, logger, minimizeJavaJars) { for (const language of config.languages) { const cacheConfig = getDefaultCacheConfig()[language]; if (cacheConfig === void 0) { @@ -93233,7 +93270,7 @@ async function uploadDependencyCaches(config, logger) { ); continue; } - const key = await cacheKey2(language, cacheConfig); + const key = await cacheKey2(language, cacheConfig, minimizeJavaJars); logger.info( `Uploading cache of size ${size} for ${language} with key ${key}...` ); @@ -93251,17 +93288,20 @@ async function uploadDependencyCaches(config, logger) { } } } -async function cacheKey2(language, cacheConfig) { +async function cacheKey2(language, cacheConfig, minimizeJavaJars = false) { const hash2 = await glob.hashFiles(cacheConfig.hash.join("\n")); - return `${await cachePrefix2(language)}${hash2}`; + return `${await cachePrefix2(language, minimizeJavaJars)}${hash2}`; } -async function cachePrefix2(language) { +async function cachePrefix2(language, minimizeJavaJars) { const runnerOs = getRequiredEnvParam("RUNNER_OS"); const customPrefix = process.env["CODEQL_ACTION_DEPENDENCY_CACHE_PREFIX" /* DEPENDENCY_CACHING_PREFIX */]; let prefix = CODEQL_DEPENDENCY_CACHE_PREFIX; if (customPrefix !== void 0 && customPrefix.length > 0) { prefix = `${prefix}-${customPrefix}`; } + if (language === "java" /* java */ && minimizeJavaJars) { + prefix = `minify-${prefix}`; + } return `${prefix}-${CODEQL_DEPENDENCY_CACHE_VERSION}-${runnerOs}-${language}-`; } @@ -93599,11 +93639,14 @@ function resolveQuerySuiteAlias(language, maybeSuite) { } return maybeSuite; } +function addSarifExtension(analysis, base) { + return `${base}${analysis.sarifExtension}`; +} async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, diffRangePackDir, automationDetailsId, codeql, config, logger, features) { const statusReport = {}; const queryFlags = [memoryFlag, threadsFlag]; const incrementalMode = []; - if (config.augmentationProperties.overlayDatabaseMode !== "overlay-base" /* OverlayBase */) { + if (config.overlayDatabaseMode !== "overlay-base" /* OverlayBase */) { queryFlags.push("--expect-discarded-cache"); } statusReport.analysis_is_diff_informed = diffRangePackDir !== void 0; @@ -93612,20 +93655,22 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, queryFlags.push("--extension-packs=codeql-action/pr-diff-range"); incrementalMode.push("diff-informed"); } - statusReport.analysis_is_overlay = config.augmentationProperties.overlayDatabaseMode === "overlay" /* Overlay */; - statusReport.analysis_builds_overlay_base_database = config.augmentationProperties.overlayDatabaseMode === "overlay-base" /* OverlayBase */; - if (config.augmentationProperties.overlayDatabaseMode === "overlay" /* Overlay */) { + statusReport.analysis_is_overlay = config.overlayDatabaseMode === "overlay" /* Overlay */; + statusReport.analysis_builds_overlay_base_database = config.overlayDatabaseMode === "overlay-base" /* OverlayBase */; + if (config.overlayDatabaseMode === "overlay" /* Overlay */) { incrementalMode.push("overlay"); } const sarifRunPropertyFlag = incrementalMode.length > 0 ? `--sarif-run-property=incrementalMode=${incrementalMode.join(",")}` : void 0; + const dbAnalysisConfig = getPrimaryAnalysisConfig(config); for (const language of config.languages) { try { - const sarifFile = path16.join(sarifFolder, `${language}.sarif`); const queries = []; - if (isCodeQualityEnabled(config)) { + if (config.analysisKinds.length > 1) { queries.push(getGeneratedSuitePath(config, language)); - for (const qualityQuery of codeQualityQueries) { - queries.push(resolveQuerySuiteAlias(language, qualityQuery)); + if (isCodeQualityEnabled(config)) { + for (const qualityQuery of codeQualityQueries) { + queries.push(resolveQuerySuiteAlias(language, qualityQuery)); + } } } logger.startGroup(`Running queries for ${language}`); @@ -93634,35 +93679,24 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, await codeql.databaseRunQueries(databasePath, queryFlags, queries); logger.debug(`Finished running queries for ${language}.`); statusReport[`analyze_builtin_queries_${language}_duration_ms`] = (/* @__PURE__ */ new Date()).getTime() - startTimeRunQueries; - logger.startGroup(`Interpreting results for ${language}`); const startTimeInterpretResults = /* @__PURE__ */ new Date(); - const analysisSummary = await runInterpretResults( + const { summary: analysisSummary, sarifFile } = await runInterpretResultsFor( + dbAnalysisConfig, language, void 0, - sarifFile, - config.debugMode, - automationDetailsId + config.debugMode ); let qualityAnalysisSummary; - if (isCodeQualityEnabled(config)) { - logger.info(`Interpreting quality results for ${language}`); - const qualityCategory = fixCodeQualityCategory( - logger, - automationDetailsId - ); - const qualitySarifFile = path16.join( - sarifFolder, - `${language}.quality.sarif` - ); - qualityAnalysisSummary = await runInterpretResults( + if (config.analysisKinds.length > 1 && isCodeQualityEnabled(config)) { + const qualityResult = await runInterpretResultsFor( + CodeQuality, language, codeQualityQueries.map( (i) => resolveQuerySuiteAlias(language, i) ), - qualitySarifFile, - config.debugMode, - qualityCategory + config.debugMode ); + qualityAnalysisSummary = qualityResult.summary; } const endTimeInterpretResults = /* @__PURE__ */ new Date(); statusReport[`interpret_results_${language}_duration_ms`] = endTimeInterpretResults.getTime() - startTimeInterpretResults.getTime(); @@ -93698,6 +93732,25 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag, } } return statusReport; + async function runInterpretResultsFor(analysis, language, queries, enableDebugLogging) { + logger.info(`Interpreting ${analysis.name} results for ${language}`); + let category = automationDetailsId; + if (analysis.kind === "code-quality" /* CodeQuality */) { + category = fixCodeQualityCategory(logger, automationDetailsId); + } + const sarifFile = path16.join( + sarifFolder, + addSarifExtension(analysis, language) + ); + const summary = await runInterpretResults( + language, + queries, + sarifFile, + enableDebugLogging, + category + ); + return { summary, sarifFile }; + } async function runInterpretResults(language, queries, sarifFile, enableDebugLogging, category) { const databasePath = getCodeQLDatabasePath(config, language); return await codeql.databaseInterpretResults( @@ -95346,7 +95399,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo return JSON.parse(fs18.readFileSync(outputFile, "utf8")); } function populateRunAutomationDetails(sarif, category, analysis_key, environment) { - const automationID = getAutomationID(category, analysis_key, environment); + const automationID = getAutomationID2(category, analysis_key, environment); if (automationID !== void 0) { for (const run2 of sarif.runs || []) { if (run2.automationDetails === void 0) { @@ -95359,7 +95412,7 @@ function populateRunAutomationDetails(sarif, category, analysis_key, environment } return sarif; } -function getAutomationID(category, analysis_key, environment) { +function getAutomationID2(category, analysis_key, environment) { if (category !== void 0) { let automationID = category; if (!automationID.endsWith("/")) { @@ -95537,18 +95590,6 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo } return payloadObj; } -var CodeScanningTarget = { - name: "code scanning", - target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), - sentinelPrefix: "CODEQL_UPLOAD_SARIF_" -}; -var CodeQualityTarget = { - name: "code quality", - target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" -}; async function uploadFiles(inputSarifPath, checkoutPath, category, features, logger, uploadTarget) { const sarifPaths = getSarifFilePaths( inputSarifPath, @@ -95563,7 +95604,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log uploadTarget ); } -async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanningTarget) { +async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget) { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); const gitHubVersion = await getGitHubVersion(); @@ -95600,6 +95641,10 @@ async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features validateUniqueCategory(sarif, uploadTarget.sentinelPrefix); logger.debug(`Serializing SARIF for upload`); const sarifPayload = JSON.stringify(sarif); + const dumpDir = process.env["CODEQL_ACTION_SARIF_DUMP_DIR" /* SARIF_DUMP_DIR */]; + if (dumpDir) { + dumpSarifFile(sarifPayload, dumpDir, logger, uploadTarget); + } logger.debug(`Compressing serialized SARIF`); const zippedSarif = import_zlib.default.gzipSync(sarifPayload).toString("base64"); const checkoutURI = url.pathToFileURL(checkoutPath).href; @@ -95638,6 +95683,21 @@ async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features sarifID }; } +function dumpSarifFile(sarifPayload, outputDir, logger, uploadTarget) { + if (!fs18.existsSync(outputDir)) { + fs18.mkdirSync(outputDir, { recursive: true }); + } else if (!fs18.lstatSync(outputDir).isDirectory()) { + throw new ConfigurationError( + `The path specified by the ${"CODEQL_ACTION_SARIF_DUMP_DIR" /* SARIF_DUMP_DIR */} environment variable exists and is not a directory: ${outputDir}` + ); + } + const outputFile = path18.resolve( + outputDir, + `upload${uploadTarget.sarifExtension}` + ); + logger.info(`Dumping processed SARIF file to ${outputFile}`); + fs18.writeFileSync(outputFile, sarifPayload); +} var STATUS_CHECK_FREQUENCY_MILLISECONDS = 5 * 1e3; var STATUS_CHECK_TIMEOUT_MILLISECONDS = 2 * 60 * 1e3; async function waitForProcessing(repositoryNwo, sarifID, logger, options = { @@ -95734,7 +95794,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger assertNever(status); } } -function validateUniqueCategory(sarif, sentinelPrefix = CodeScanningTarget.sentinelPrefix) { +function validateUniqueCategory(sarif, sentinelPrefix) { const categories = {}; for (const run2 of sarif.runs) { const id = run2?.automationDetails?.id; @@ -95984,15 +96044,17 @@ async function run() { core14.setOutput("sarif-output", import_path4.default.resolve(outputDir)); const uploadInput = getOptionalInput("upload"); if (runStats && getUploadValue(uploadInput) === "always") { - uploadResult = await uploadFiles( - outputDir, - getRequiredInput("checkout_path"), - getOptionalInput("category"), - features, - logger, - CodeScanningTarget - ); - core14.setOutput("sarif-id", uploadResult.sarifID); + if (isCodeScanningEnabled(config)) { + uploadResult = await uploadFiles( + outputDir, + getRequiredInput("checkout_path"), + getOptionalInput("category"), + features, + logger, + CodeScanning + ); + core14.setOutput("sarif-id", uploadResult.sarifID); + } if (isCodeQualityEnabled(config)) { const qualityUploadResult = await uploadFiles( outputDir, @@ -96003,7 +96065,7 @@ async function run() { ), features, logger, - CodeQualityTarget + CodeQuality ); core14.setOutput("quality-sarif-id", qualityUploadResult.sarifID); } @@ -96021,7 +96083,11 @@ async function run() { logger ); if (shouldStoreCache(config.dependencyCachingEnabled)) { - await uploadDependencyCaches(config, logger); + const minimizeJavaJars = await features.getValue( + "java_minimize_dependency_jars" /* JavaMinimizeDependencyJars */, + codeql + ); + await uploadDependencyCaches(config, logger, minimizeJavaJars); } if (isInTestMode()) { logger.debug("In test mode. Waiting for processing is disabled."); diff --git a/lib/autobuild-action.js b/lib/autobuild-action.js index ca18e315a4..516fd8944c 100644 --- a/lib/autobuild-action.js +++ b/lib/autobuild-action.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -26438,7 +26438,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.1", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -26486,26 +26486,24 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^11.1.0" + uuid: "^12.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.34.0", + "@eslint/js": "^9.35.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@octokit/types": "^14.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", - "@types/get-folder-size": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/node": "20.19.9", "@types/node-forge": "^1.3.14", - "@types/semver": "^7.7.0", + "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", esbuild: "^0.25.9", @@ -26538,7 +26536,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -31823,14 +31822,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -31841,7 +31840,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -78249,8 +78248,8 @@ var path3 = __toESM(require("path")); var semver3 = __toESM(require_semver2()); // src/defaults.json -var bundleVersion = "codeql-bundle-v2.22.4"; -var cliVersion = "2.22.4"; +var bundleVersion = "codeql-bundle-v2.23.0"; +var cliVersion = "2.23.0"; // src/overlay-database-utils.ts var fs2 = __toESM(require("fs")); @@ -78428,7 +78427,7 @@ function getActionsLogger() { // src/overlay-database-utils.ts var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; -var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 6e3; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 15e3; var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; async function writeBaseDatabaseOidsFile(config, sourceRoot) { const gitFileOids = await getFileOidsUnderPath(sourceRoot); @@ -78536,6 +78535,12 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["resolve_supported_languages_using_cli" /* ResolveSupportedLanguagesUsingCli */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI", + minimumVersion: void 0, + toolsFeature: "builtinExtractorsSpecifyDefaultQueries" /* BuiltinExtractorsSpecifyDefaultQueries */ + }, ["overlay_analysis" /* OverlayAnalysis */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS", @@ -78652,6 +78657,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_QA_TELEMETRY", legacyApi: true, minimumVersion: void 0 + }, + ["java_minimize_dependency_jars" /* JavaMinimizeDependencyJars */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS", + minimumVersion: "2.23.0" } }; var FEATURE_FLAGS_FILE_NAME = "cached-feature-flags.json"; @@ -78923,15 +78933,6 @@ var GitHubFeatureFlags = class { var actionsCache2 = __toESM(require_cache3()); // src/config-utils.ts -var defaultAugmentationProperties = { - queriesInputCombines: false, - packsInputCombines: false, - packsInput: void 0, - queriesInput: void 0, - extraQueryExclusions: [], - overlayDatabaseMode: "none" /* None */, - useOverlayDatabaseCaching: false -}; var OVERLAY_ANALYSIS_FEATURES = { actions: "overlay_analysis_actions" /* OverlayAnalysisActions */, cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, @@ -78973,40 +78974,23 @@ async function getConfig(tempDir, logger) { const configString = fs4.readFileSync(configFile, "utf8"); logger.debug("Loaded config:"); logger.debug(configString); - return JSON.parse(configString); -} -function generateCodeScanningConfig(originalUserInput, augmentationProperties) { - const augmentedConfig = cloneObject(originalUserInput); - if (augmentationProperties.queriesInput) { - if (augmentationProperties.queriesInputCombines) { - augmentedConfig.queries = (augmentedConfig.queries || []).concat( - augmentationProperties.queriesInput - ); - } else { - augmentedConfig.queries = augmentationProperties.queriesInput; - } - } - if (augmentedConfig.queries?.length === 0) { - delete augmentedConfig.queries; + const config = JSON.parse(configString); + if (config.version === void 0) { + throw new ConfigurationError( + `Loaded configuration file, but it does not contain the expected 'version' field.` + ); } - if (augmentationProperties.packsInput) { - if (augmentationProperties.packsInputCombines) { - if (Array.isArray(augmentedConfig.packs)) { - augmentedConfig.packs = (augmentedConfig.packs || []).concat( - augmentationProperties.packsInput - ); - } else if (!augmentedConfig.packs) { - augmentedConfig.packs = augmentationProperties.packsInput; - } else { - const language = Object.keys(augmentedConfig.packs)[0]; - augmentedConfig.packs[language] = augmentedConfig.packs[language].concat(augmentationProperties.packsInput); - } - } else { - augmentedConfig.packs = augmentationProperties.packsInput; - } + if (config.version !== getActionVersion()) { + throw new ConfigurationError( + `Loaded a configuration file for version '${config.version}', but running version '${getActionVersion()}'` + ); } - if (Array.isArray(augmentedConfig.packs) && !augmentedConfig.packs.length) { - delete augmentedConfig.packs; + return config; +} +function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { + const augmentedConfig = cloneObject(cliConfig); + if (extraQueryExclusions.length === 0) { + return augmentedConfig; } augmentedConfig["query-filters"] = [ // Ordering matters. If the first filter is an inclusion, it implicitly @@ -79014,7 +78998,7 @@ function generateCodeScanningConfig(originalUserInput, augmentationProperties) { // it implicitly includes all queries that are not excluded. So user // filters (if any) should always be first to preserve intent. ...augmentedConfig["query-filters"] || [], - ...augmentationProperties.extraQueryExclusions + ...extraQueryExclusions ]; if (augmentedConfig["query-filters"]?.length === 0) { delete augmentedConfig["query-filters"]; @@ -79169,7 +79153,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { await this.getVersion(), "forceOverwrite" /* ForceOverwrite */ ) ? "--force-overwrite" : "--overwrite"; - const overlayDatabaseMode = config.augmentationProperties.overlayDatabaseMode; + const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode === "overlay" /* Overlay */) { const overlayChangesFile = await writeOverlayChangesFile( config, @@ -79280,13 +79264,16 @@ async function getCodeQLForCmd(cmd, checkVersion) { ); } }, - async betterResolveLanguages() { + async betterResolveLanguages({ + filterToLanguagesWithQueries + } = { filterToLanguagesWithQueries: false }) { const codeqlArgs = [ "resolve", "languages", "--format=betterjson", "--extractor-options-verbosity=4", "--extractor-include-aliases", + ...filterToLanguagesWithQueries ? ["--filter-to-languages-with-queries"] : [], ...getExtraOptionsFromEnv(["resolve", "languages"]) ]; const output = await runCli(cmd, codeqlArgs); @@ -79325,7 +79312,6 @@ ${output}` "run-queries", ...flags, databasePath, - "--intra-layer-parallelism", "--min-disk-free=1024", // Try to leave at least 1GB free "-v", @@ -79583,9 +79569,9 @@ async function runCli(cmd, args = [], opts = {}) { } async function writeCodeScanningConfigFile(config, logger) { const codeScanningConfigFile = getGeneratedCodeScanningConfigPath(config); - const augmentedConfig = generateCodeScanningConfig( - config.originalUserInput, - config.augmentationProperties + const augmentedConfig = appendExtraQueryExclusions( + config.extraQueryExclusions, + config.computedConfig ); logger.info( `Writing augmented user configuration file to ${codeScanningConfigFile}` diff --git a/lib/defaults.json b/lib/defaults.json index b90234b76b..712efc19fe 100644 --- a/lib/defaults.json +++ b/lib/defaults.json @@ -1,6 +1,6 @@ { - "bundleVersion": "codeql-bundle-v2.22.4", - "cliVersion": "2.22.4", - "priorBundleVersion": "codeql-bundle-v2.22.3", - "priorCliVersion": "2.22.3" + "bundleVersion": "codeql-bundle-v2.23.0", + "cliVersion": "2.23.0", + "priorBundleVersion": "codeql-bundle-v2.22.4", + "priorCliVersion": "2.22.4" } diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 1995591edc..2c2069e01a 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context3, operator, key, modifier) { var value = context3[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context3, operator, key, modifier) { var value = context3[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -32287,7 +32287,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.1", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -32335,26 +32335,24 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^11.1.0" + uuid: "^12.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.34.0", + "@eslint/js": "^9.35.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@octokit/types": "^14.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", - "@types/get-folder-size": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/node": "20.19.9", "@types/node-forge": "^1.3.14", - "@types/semver": "^7.7.0", + "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", esbuild: "^0.25.9", @@ -32387,7 +32385,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -37672,14 +37671,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -37690,7 +37689,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -83536,7 +83535,7 @@ var require_brace_expansion2 = __commonJS({ var isSequence = isNumericSequence || isAlphaSequence; var isOptions = m.body.indexOf(",") >= 0; if (!isSequence && !isOptions) { - if (m.post.match(/,.*\}/)) { + if (m.post.match(/,(?!,).*\}/)) { str2 = m.pre + "{" + m.body + escClose + m.post; return expand(str2); } @@ -108761,7 +108760,7 @@ var require_dist_node16 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -108769,7 +108768,7 @@ var require_dist_node16 = __commonJS({ } function getValues(context3, operator, key, modifier) { var value = context3[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -108779,12 +108778,12 @@ var require_dist_node16 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push(encodeValue(operator, value2, isKeyOperator(operator) ? key : "")); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -108792,12 +108791,12 @@ var require_dist_node16 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -108812,7 +108811,7 @@ var require_dist_node16 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -128756,6 +128755,22 @@ var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { return AnalysisKind2; })(AnalysisKind || {}); var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); +var CodeScanning = { + kind: "code-scanning" /* CodeScanning */, + name: "code scanning", + target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, + sarifExtension: ".sarif", + sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name), + sentinelPrefix: "CODEQL_UPLOAD_SARIF_" +}; +var CodeQuality = { + kind: "code-quality" /* CodeQuality */, + name: "code quality", + target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, + sarifExtension: ".quality.sarif", + sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), + sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" +}; // src/caching-utils.ts var core6 = __toESM(require_core()); @@ -128770,8 +128785,8 @@ var path8 = __toESM(require("path")); var semver3 = __toESM(require_semver2()); // src/defaults.json -var bundleVersion = "codeql-bundle-v2.22.4"; -var cliVersion = "2.22.4"; +var bundleVersion = "codeql-bundle-v2.23.0"; +var cliVersion = "2.23.0"; // src/overlay-database-utils.ts var fs6 = __toESM(require("fs")); @@ -129002,7 +129017,7 @@ function formatDuration(durationMs) { // src/overlay-database-utils.ts var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; -var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 6e3; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 15e3; var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; async function writeBaseDatabaseOidsFile(config, sourceRoot) { const gitFileOids = await getFileOidsUnderPath(sourceRoot); @@ -129115,6 +129130,12 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["resolve_supported_languages_using_cli" /* ResolveSupportedLanguagesUsingCli */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI", + minimumVersion: void 0, + toolsFeature: "builtinExtractorsSpecifyDefaultQueries" /* BuiltinExtractorsSpecifyDefaultQueries */ + }, ["overlay_analysis" /* OverlayAnalysis */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS", @@ -129231,6 +129252,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_QA_TELEMETRY", legacyApi: true, minimumVersion: void 0 + }, + ["java_minimize_dependency_jars" /* JavaMinimizeDependencyJars */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS", + minimumVersion: "2.23.0" } }; var FEATURE_FLAGS_FILE_NAME = "cached-feature-flags.json"; @@ -129520,15 +129546,6 @@ ${jsonContents}` var actionsCache2 = __toESM(require_cache3()); // src/config-utils.ts -var defaultAugmentationProperties = { - queriesInputCombines: false, - packsInputCombines: false, - packsInput: void 0, - queriesInput: void 0, - extraQueryExclusions: [], - overlayDatabaseMode: "none" /* None */, - useOverlayDatabaseCaching: false -}; var OVERLAY_ANALYSIS_FEATURES = { actions: "overlay_analysis_actions" /* OverlayAnalysisActions */, cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, @@ -129570,40 +129587,23 @@ async function getConfig(tempDir, logger) { const configString = fs9.readFileSync(configFile, "utf8"); logger.debug("Loaded config:"); logger.debug(configString); - return JSON.parse(configString); -} -function generateCodeScanningConfig(originalUserInput, augmentationProperties) { - const augmentedConfig = cloneObject(originalUserInput); - if (augmentationProperties.queriesInput) { - if (augmentationProperties.queriesInputCombines) { - augmentedConfig.queries = (augmentedConfig.queries || []).concat( - augmentationProperties.queriesInput - ); - } else { - augmentedConfig.queries = augmentationProperties.queriesInput; - } - } - if (augmentedConfig.queries?.length === 0) { - delete augmentedConfig.queries; + const config = JSON.parse(configString); + if (config.version === void 0) { + throw new ConfigurationError( + `Loaded configuration file, but it does not contain the expected 'version' field.` + ); } - if (augmentationProperties.packsInput) { - if (augmentationProperties.packsInputCombines) { - if (Array.isArray(augmentedConfig.packs)) { - augmentedConfig.packs = (augmentedConfig.packs || []).concat( - augmentationProperties.packsInput - ); - } else if (!augmentedConfig.packs) { - augmentedConfig.packs = augmentationProperties.packsInput; - } else { - const language = Object.keys(augmentedConfig.packs)[0]; - augmentedConfig.packs[language] = augmentedConfig.packs[language].concat(augmentationProperties.packsInput); - } - } else { - augmentedConfig.packs = augmentationProperties.packsInput; - } + if (config.version !== getActionVersion()) { + throw new ConfigurationError( + `Loaded a configuration file for version '${config.version}', but running version '${getActionVersion()}'` + ); } - if (Array.isArray(augmentedConfig.packs) && !augmentedConfig.packs.length) { - delete augmentedConfig.packs; + return config; +} +function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { + const augmentedConfig = cloneObject(cliConfig); + if (extraQueryExclusions.length === 0) { + return augmentedConfig; } augmentedConfig["query-filters"] = [ // Ordering matters. If the first filter is an inclusion, it implicitly @@ -129611,7 +129611,7 @@ function generateCodeScanningConfig(originalUserInput, augmentationProperties) { // it implicitly includes all queries that are not excluded. So user // filters (if any) should always be first to preserve intent. ...augmentedConfig["query-filters"] || [], - ...augmentationProperties.extraQueryExclusions + ...extraQueryExclusions ]; if (augmentedConfig["query-filters"]?.length === 0) { delete augmentedConfig["query-filters"]; @@ -129626,7 +129626,7 @@ var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); var semver7 = __toESM(require_semver2()); -// node_modules/uuid/dist/esm/stringify.js +// node_modules/uuid/dist/stringify.js var byteToHex = []; for (let i = 0; i < 256; ++i) { byteToHex.push((i + 256).toString(16).slice(1)); @@ -129635,27 +129635,24 @@ function unsafeStringify(arr, offset = 0) { return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); } -// node_modules/uuid/dist/esm/rng.js -var import_crypto = require("crypto"); +// node_modules/uuid/dist/rng.js +var import_node_crypto = require("node:crypto"); var rnds8Pool = new Uint8Array(256); var poolPtr = rnds8Pool.length; function rng() { if (poolPtr > rnds8Pool.length - 16) { - (0, import_crypto.randomFillSync)(rnds8Pool); + (0, import_node_crypto.randomFillSync)(rnds8Pool); poolPtr = 0; } return rnds8Pool.slice(poolPtr, poolPtr += 16); } -// node_modules/uuid/dist/esm/native.js -var import_crypto2 = require("crypto"); -var native_default = { randomUUID: import_crypto2.randomUUID }; +// node_modules/uuid/dist/native.js +var import_node_crypto2 = require("node:crypto"); +var native_default = { randomUUID: import_node_crypto2.randomUUID }; -// node_modules/uuid/dist/esm/v4.js -function v4(options, buf, offset) { - if (native_default.randomUUID && !buf && !options) { - return native_default.randomUUID(); - } +// node_modules/uuid/dist/v4.js +function _v4(options, buf, offset) { options = options || {}; const rnds = options.random ?? options.rng?.() ?? rng(); if (rnds.length < 16) { @@ -129675,6 +129672,12 @@ function v4(options, buf, offset) { } return unsafeStringify(rnds); } +function v4(options, buf, offset) { + if (native_default.randomUUID && !buf && !options) { + return native_default.randomUUID(); + } + return _v4(options, buf, offset); +} var v4_default = v4; // src/tar.ts @@ -130588,7 +130591,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { await this.getVersion(), "forceOverwrite" /* ForceOverwrite */ ) ? "--force-overwrite" : "--overwrite"; - const overlayDatabaseMode = config.augmentationProperties.overlayDatabaseMode; + const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode === "overlay" /* Overlay */) { const overlayChangesFile = await writeOverlayChangesFile( config, @@ -130699,13 +130702,16 @@ async function getCodeQLForCmd(cmd, checkVersion) { ); } }, - async betterResolveLanguages() { + async betterResolveLanguages({ + filterToLanguagesWithQueries + } = { filterToLanguagesWithQueries: false }) { const codeqlArgs = [ "resolve", "languages", "--format=betterjson", "--extractor-options-verbosity=4", "--extractor-include-aliases", + ...filterToLanguagesWithQueries ? ["--filter-to-languages-with-queries"] : [], ...getExtraOptionsFromEnv(["resolve", "languages"]) ]; const output = await runCli(cmd, codeqlArgs); @@ -130744,7 +130750,6 @@ ${output}` "run-queries", ...flags, databasePath, - "--intra-layer-parallelism", "--min-disk-free=1024", // Try to leave at least 1GB free "-v", @@ -131002,9 +131007,9 @@ async function runCli(cmd, args = [], opts = {}) { } async function writeCodeScanningConfigFile(config, logger) { const codeScanningConfigFile = getGeneratedCodeScanningConfigPath(config); - const augmentedConfig = generateCodeScanningConfig( - config.originalUserInput, - config.augmentationProperties + const augmentedConfig = appendExtraQueryExclusions( + config.extraQueryExclusions, + config.computedConfig ); logger.info( `Writing augmented user configuration file to ${codeScanningConfigFile}` @@ -132828,7 +132833,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo return JSON.parse(fs17.readFileSync(outputFile, "utf8")); } function populateRunAutomationDetails(sarif, category, analysis_key, environment) { - const automationID = getAutomationID(category, analysis_key, environment); + const automationID = getAutomationID2(category, analysis_key, environment); if (automationID !== void 0) { for (const run2 of sarif.runs || []) { if (run2.automationDetails === void 0) { @@ -132841,7 +132846,7 @@ function populateRunAutomationDetails(sarif, category, analysis_key, environment } return sarif; } -function getAutomationID(category, analysis_key, environment) { +function getAutomationID2(category, analysis_key, environment) { if (category !== void 0) { let automationID = category; if (!automationID.endsWith("/")) { @@ -133019,18 +133024,6 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo } return payloadObj; } -var CodeScanningTarget = { - name: "code scanning", - target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), - sentinelPrefix: "CODEQL_UPLOAD_SARIF_" -}; -var CodeQualityTarget = { - name: "code quality", - target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" -}; async function uploadFiles(inputSarifPath, checkoutPath, category, features, logger, uploadTarget) { const sarifPaths = getSarifFilePaths( inputSarifPath, @@ -133045,7 +133038,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log uploadTarget ); } -async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanningTarget) { +async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget) { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); const gitHubVersion = await getGitHubVersion(); @@ -133082,6 +133075,10 @@ async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features validateUniqueCategory(sarif, uploadTarget.sentinelPrefix); logger.debug(`Serializing SARIF for upload`); const sarifPayload = JSON.stringify(sarif); + const dumpDir = process.env["CODEQL_ACTION_SARIF_DUMP_DIR" /* SARIF_DUMP_DIR */]; + if (dumpDir) { + dumpSarifFile(sarifPayload, dumpDir, logger, uploadTarget); + } logger.debug(`Compressing serialized SARIF`); const zippedSarif = import_zlib.default.gzipSync(sarifPayload).toString("base64"); const checkoutURI = url.pathToFileURL(checkoutPath).href; @@ -133120,6 +133117,21 @@ async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features sarifID }; } +function dumpSarifFile(sarifPayload, outputDir, logger, uploadTarget) { + if (!fs17.existsSync(outputDir)) { + fs17.mkdirSync(outputDir, { recursive: true }); + } else if (!fs17.lstatSync(outputDir).isDirectory()) { + throw new ConfigurationError( + `The path specified by the ${"CODEQL_ACTION_SARIF_DUMP_DIR" /* SARIF_DUMP_DIR */} environment variable exists and is not a directory: ${outputDir}` + ); + } + const outputFile = path17.resolve( + outputDir, + `upload${uploadTarget.sarifExtension}` + ); + logger.info(`Dumping processed SARIF file to ${outputFile}`); + fs17.writeFileSync(outputFile, sarifPayload); +} var STATUS_CHECK_FREQUENCY_MILLISECONDS = 5 * 1e3; var STATUS_CHECK_TIMEOUT_MILLISECONDS = 2 * 60 * 1e3; async function waitForProcessing(repositoryNwo, sarifID, logger, options = { @@ -133216,7 +133228,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger assertNever(status); } } -function validateUniqueCategory(sarif, sentinelPrefix = CodeScanningTarget.sentinelPrefix) { +function validateUniqueCategory(sarif, sentinelPrefix) { const categories = {}; for (const run2 of sarif.runs) { const id = run2?.automationDetails?.id; @@ -133288,7 +133300,8 @@ function toCodedErrors(errors) { } var WorkflowErrors = toCodedErrors({ MissingPushHook: `Please specify an on.push hook to analyze and see code scanning alerts from the default branch on the Security tab.`, - CheckoutWrongHead: `git checkout HEAD^2 is no longer necessary. Please remove this step as Code Scanning recommends analyzing the merge commit for best results.` + CheckoutWrongHead: `git checkout HEAD^2 is no longer necessary. Please remove this step as Code Scanning recommends analyzing the merge commit for best results.`, + InconsistentActionVersion: `Not all workflow steps that use \`github/codeql-action\` actions use the same version. Please ensure that all such steps use the same version to avoid compatibility issues.` }); async function getWorkflow(logger) { const maybeWorkflow = process.env["CODE_SCANNING_WORKFLOW_FILE"]; @@ -133441,7 +133454,7 @@ async function maybeUploadFailedSarif(config, repositoryNwo, features, logger) { category, features, logger, - CodeScanningTarget + CodeScanning ); await waitForProcessing( repositoryNwo, diff --git a/lib/init-action.js b/lib/init-action.js index 2edef19804..2f2fc6a350 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -184,7 +184,7 @@ var require_file_command = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.prepareKeyValueMessage = exports2.issueFileCommand = void 0; - var crypto = __importStar4(require("crypto")); + var crypto2 = __importStar4(require("crypto")); var fs18 = __importStar4(require("fs")); var os5 = __importStar4(require("os")); var utils_1 = require_utils(); @@ -202,7 +202,7 @@ var require_file_command = __commonJS({ } exports2.issueFileCommand = issueFileCommand; function prepareKeyValueMessage(key, value) { - const delimiter = `ghadelimiter_${crypto.randomUUID()}`; + const delimiter = `ghadelimiter_${crypto2.randomUUID()}`; const convertedValue = (0, utils_1.toCommandValue)(value); if (key.includes(delimiter)) { throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); @@ -3637,11 +3637,11 @@ var require_util2 = __commonJS({ var assert = require("assert"); var { isUint8Array } = require("util/types"); var supportedHashes = []; - var crypto; + var crypto2; try { - crypto = require("crypto"); + crypto2 = require("crypto"); const possibleRelevantHashes = ["sha256", "sha384", "sha512"]; - supportedHashes = crypto.getHashes().filter((hash) => possibleRelevantHashes.includes(hash)); + supportedHashes = crypto2.getHashes().filter((hash) => possibleRelevantHashes.includes(hash)); } catch { } function responseURL(response) { @@ -3918,7 +3918,7 @@ var require_util2 = __commonJS({ } } function bytesMatch(bytes, metadataList) { - if (crypto === void 0) { + if (crypto2 === void 0) { return true; } const parsedMetadata = parseMetadata(metadataList); @@ -3933,7 +3933,7 @@ var require_util2 = __commonJS({ for (const item of metadata) { const algorithm = item.algo; const expectedValue = item.hash; - let actualValue = crypto.createHash(algorithm).update(bytes).digest("base64"); + let actualValue = crypto2.createHash(algorithm).update(bytes).digest("base64"); if (actualValue[actualValue.length - 1] === "=") { if (actualValue[actualValue.length - 2] === "=") { actualValue = actualValue.slice(0, -2); @@ -5279,8 +5279,8 @@ var require_body = __commonJS({ var { parseMIMEType, serializeAMimeType } = require_dataURL(); var random; try { - const crypto = require("node:crypto"); - random = (max) => crypto.randomInt(0, max); + const crypto2 = require("node:crypto"); + random = (max) => crypto2.randomInt(0, max); } catch { random = (max) => Math.floor(Math.random(max)); } @@ -16330,9 +16330,9 @@ var require_connection = __commonJS({ channels.open = diagnosticsChannel.channel("undici:websocket:open"); channels.close = diagnosticsChannel.channel("undici:websocket:close"); channels.socketError = diagnosticsChannel.channel("undici:websocket:socket_error"); - var crypto; + var crypto2; try { - crypto = require("crypto"); + crypto2 = require("crypto"); } catch { } function establishWebSocketConnection(url, protocols, ws, onEstablish, options) { @@ -16351,7 +16351,7 @@ var require_connection = __commonJS({ const headersList = new Headers(options.headers)[kHeadersList]; request.headersList = headersList; } - const keyValue = crypto.randomBytes(16).toString("base64"); + const keyValue = crypto2.randomBytes(16).toString("base64"); request.headersList.append("sec-websocket-key", keyValue); request.headersList.append("sec-websocket-version", "13"); for (const protocol of protocols) { @@ -16380,7 +16380,7 @@ var require_connection = __commonJS({ return; } const secWSAccept = response.headersList.get("Sec-WebSocket-Accept"); - const digest = crypto.createHash("sha1").update(keyValue + uid).digest("base64"); + const digest = crypto2.createHash("sha1").update(keyValue + uid).digest("base64"); if (secWSAccept !== digest) { failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header."); return; @@ -16460,9 +16460,9 @@ var require_frame = __commonJS({ "node_modules/undici/lib/websocket/frame.js"(exports2, module2) { "use strict"; var { maxUnsigned16Bit } = require_constants5(); - var crypto; + var crypto2; try { - crypto = require("crypto"); + crypto2 = require("crypto"); } catch { } var WebsocketFrameSend = class { @@ -16471,7 +16471,7 @@ var require_frame = __commonJS({ */ constructor(data) { this.frameData = data; - this.maskKey = crypto.randomBytes(4); + this.maskKey = crypto2.randomBytes(4); } createFrame(opcode) { const bodyLength = this.frameData?.byteLength ?? 0; @@ -22196,7 +22196,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -22204,7 +22204,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -22216,14 +22216,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -22231,12 +22231,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -22251,7 +22251,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -22936,7 +22936,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -22944,7 +22944,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -22956,14 +22956,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -22971,12 +22971,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -22991,7 +22991,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -32287,7 +32287,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.1", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -32335,26 +32335,24 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^11.1.0" + uuid: "^12.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.34.0", + "@eslint/js": "^9.35.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@octokit/types": "^14.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", - "@types/get-folder-size": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/node": "20.19.9", "@types/node-forge": "^1.3.14", - "@types/semver": "^7.7.0", + "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", esbuild: "^0.25.9", @@ -32387,7 +32385,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -36931,7 +36930,7 @@ var require_cacheUtils = __commonJS({ var exec2 = __importStar4(require_exec()); var glob2 = __importStar4(require_glob()); var io7 = __importStar4(require_io()); - var crypto = __importStar4(require("crypto")); + var crypto2 = __importStar4(require("crypto")); var fs18 = __importStar4(require("fs")); var path19 = __importStar4(require("path")); var semver9 = __importStar4(require_semver3()); @@ -36955,7 +36954,7 @@ var require_cacheUtils = __commonJS({ } tempDirectory = path19.join(baseLocation, "actions", "temp"); } - const dest = path19.join(tempDirectory, crypto.randomUUID()); + const dest = path19.join(tempDirectory, crypto2.randomUUID()); yield io7.mkdirP(dest); return dest; }); @@ -37071,7 +37070,7 @@ var require_cacheUtils = __commonJS({ components.push("windows-only"); } components.push(versionSalt); - return crypto.createHash("sha256").update(components.join("|")).digest("hex"); + return crypto2.createHash("sha256").update(components.join("|")).digest("hex"); } exports2.getCacheVersion = getCacheVersion; function getRuntimeToken() { @@ -37672,14 +37671,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -37690,7 +37689,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -48815,7 +48814,7 @@ var require_dist7 = __commonJS({ var coreXml = require_commonjs9(); var logger$1 = require_dist(); var abortController = require_commonjs10(); - var crypto = require("crypto"); + var crypto2 = require("crypto"); var coreTracing = require_commonjs4(); var stream2 = require("stream"); var coreLro = require_dist6(); @@ -50323,7 +50322,7 @@ ${key}:${decodeURIComponent(lowercaseQueries[key])}`; * @param stringToSign - */ computeHMACSHA256(stringToSign) { - return crypto.createHmac("sha256", this.accountKey).update(stringToSign, "utf8").digest("base64"); + return crypto2.createHmac("sha256", this.accountKey).update(stringToSign, "utf8").digest("base64"); } }; var AnonymousCredentialPolicy = class extends CredentialPolicy { @@ -50521,7 +50520,7 @@ ${key}:${decodeURIComponent(lowercaseQueries[key])}`; getHeaderValueToSign(request, HeaderConstants.IF_UNMODIFIED_SINCE), getHeaderValueToSign(request, HeaderConstants.RANGE) ].join("\n") + "\n" + getCanonicalizedHeadersString(request) + getCanonicalizedResourceString(request); - const signature = crypto.createHmac("sha256", options.accountKey).update(stringToSign, "utf8").digest("base64"); + const signature = crypto2.createHmac("sha256", options.accountKey).update(stringToSign, "utf8").digest("base64"); request.headers.set(HeaderConstants.AUTHORIZATION, `SharedKey ${options.accountName}:${signature}`); } function getHeaderValueToSign(request, headerName) { @@ -64280,7 +64279,7 @@ ${key}:${decodeURIComponent(lowercaseQueries[key])}`; * @param stringToSign - */ computeHMACSHA256(stringToSign) { - return crypto.createHmac("sha256", this.key).update(stringToSign, "utf8").digest("base64"); + return crypto2.createHmac("sha256", this.key).update(stringToSign, "utf8").digest("base64"); } }; function ipRangeToString(ipRange) { @@ -80225,7 +80224,7 @@ var require_internal_hash_files = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.hashFiles = void 0; - var crypto = __importStar4(require("crypto")); + var crypto2 = __importStar4(require("crypto")); var core14 = __importStar4(require_core()); var fs18 = __importStar4(require("fs")); var stream2 = __importStar4(require("stream")); @@ -80238,7 +80237,7 @@ var require_internal_hash_files = __commonJS({ const writeDelegate = verbose ? core14.info : core14.debug; let hasMatch = false; const githubWorkspace = currentWorkspace ? currentWorkspace : (_d = process.env["GITHUB_WORKSPACE"]) !== null && _d !== void 0 ? _d : process.cwd(); - const result = crypto.createHash("sha256"); + const result = crypto2.createHash("sha256"); let count = 0; try { for (var _e = true, _f = __asyncValues4(globber.globGenerator()), _g; _g = yield _f.next(), _a = _g.done, !_a; _e = true) { @@ -80254,7 +80253,7 @@ var require_internal_hash_files = __commonJS({ writeDelegate(`Skip directory '${file}'.`); continue; } - const hash = crypto.createHash("sha256"); + const hash = crypto2.createHash("sha256"); const pipeline = util.promisify(stream2.pipeline); yield pipeline(fs18.createReadStream(file), hash); result.write(hash.digest()); @@ -80648,7 +80647,7 @@ var require_tool_cache = __commonJS({ exports2.evaluateVersions = exports2.isExplicitVersion = exports2.findFromManifest = exports2.getManifestFromRepo = exports2.findAllVersions = exports2.find = exports2.cacheFile = exports2.cacheDir = exports2.extractZip = exports2.extractXar = exports2.extractTar = exports2.extract7z = exports2.downloadTool = exports2.HTTPError = void 0; var core14 = __importStar4(require_core()); var io7 = __importStar4(require_io()); - var crypto = __importStar4(require("crypto")); + var crypto2 = __importStar4(require("crypto")); var fs18 = __importStar4(require("fs")); var mm = __importStar4(require_manifest()); var os5 = __importStar4(require("os")); @@ -80673,7 +80672,7 @@ var require_tool_cache = __commonJS({ var userAgent = "actions/tool-cache"; function downloadTool2(url, dest, auth, headers) { return __awaiter4(this, void 0, void 0, function* () { - dest = dest || path19.join(_getTempDirectory(), crypto.randomUUID()); + dest = dest || path19.join(_getTempDirectory(), crypto2.randomUUID()); yield io7.mkdirP(path19.dirname(dest)); core14.debug(`Downloading ${url}`); core14.debug(`Destination ${dest}`); @@ -81054,7 +81053,7 @@ var require_tool_cache = __commonJS({ function _createExtractFolder(dest) { return __awaiter4(this, void 0, void 0, function* () { if (!dest) { - dest = path19.join(_getTempDirectory(), crypto.randomUUID()); + dest = path19.join(_getTempDirectory(), crypto2.randomUUID()); } yield io7.mkdirP(dest); return dest; @@ -81688,7 +81687,7 @@ var core13 = __toESM(require_core()); var io6 = __toESM(require_io()); var semver8 = __toESM(require_semver2()); -// node_modules/uuid/dist/esm/stringify.js +// node_modules/uuid/dist/stringify.js var byteToHex = []; for (let i = 0; i < 256; ++i) { byteToHex.push((i + 256).toString(16).slice(1)); @@ -81697,27 +81696,24 @@ function unsafeStringify(arr, offset = 0) { return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); } -// node_modules/uuid/dist/esm/rng.js -var import_crypto = require("crypto"); +// node_modules/uuid/dist/rng.js +var import_node_crypto = require("node:crypto"); var rnds8Pool = new Uint8Array(256); var poolPtr = rnds8Pool.length; function rng() { if (poolPtr > rnds8Pool.length - 16) { - (0, import_crypto.randomFillSync)(rnds8Pool); + (0, import_node_crypto.randomFillSync)(rnds8Pool); poolPtr = 0; } return rnds8Pool.slice(poolPtr, poolPtr += 16); } -// node_modules/uuid/dist/esm/native.js -var import_crypto2 = require("crypto"); -var native_default = { randomUUID: import_crypto2.randomUUID }; +// node_modules/uuid/dist/native.js +var import_node_crypto2 = require("node:crypto"); +var native_default = { randomUUID: import_node_crypto2.randomUUID }; -// node_modules/uuid/dist/esm/v4.js -function v4(options, buf, offset) { - if (native_default.randomUUID && !buf && !options) { - return native_default.randomUUID(); - } +// node_modules/uuid/dist/v4.js +function _v4(options, buf, offset) { options = options || {}; const rnds = options.random ?? options.rng?.() ?? rng(); if (rnds.length < 16) { @@ -81737,6 +81733,12 @@ function v4(options, buf, offset) { } return unsafeStringify(rnds); } +function v4(options, buf, offset) { + if (native_default.randomUUID && !buf && !options) { + return native_default.randomUUID(); + } + return _v4(options, buf, offset); +} var v4_default = v4; // src/actions-util.ts @@ -85651,6 +85653,12 @@ function isHostedRunner() { process.env["RUNNER_TOOL_CACHE"]?.includes("hostedtoolcache") ); } +function parseMatrixInput(matrixInput) { + if (matrixInput === void 0 || matrixInput === "null") { + return void 0; + } + return JSON.parse(matrixInput); +} function wrapError(error2) { return error2 instanceof Error ? error2 : new Error(String(error2)); } @@ -85780,6 +85788,9 @@ async function asyncSome(array, predicate) { const results = await Promise.all(array.map(predicate)); return results.some((result) => result); } +function isDefined(value) { + return value !== void 0 && value !== null; +} // src/actions-util.ts var pkg = require_package(); @@ -86098,6 +86109,25 @@ async function getAnalysisKey() { core5.exportVariable(analysisKeyEnvVar, analysisKey); return analysisKey; } +async function getAutomationID() { + const analysis_key = await getAnalysisKey(); + const environment = getRequiredInput("matrix"); + return computeAutomationID(analysis_key, environment); +} +function computeAutomationID(analysis_key, environment) { + let automationID = `${analysis_key}/`; + const matrix = parseMatrixInput(environment); + if (matrix !== void 0) { + for (const entry of Object.entries(matrix).sort()) { + if (typeof entry[1] === "string") { + automationID += `${entry[0]}:${entry[1]}/`; + } else { + automationID += `${entry[0]}:/`; + } + } + } + return automationID; +} // src/caching-utils.ts var core6 = __toESM(require_core()); @@ -86169,6 +86199,7 @@ async function parseAnalysisKinds(input) { new Set(components.map((component) => component)) ); } +var codeQualityQueries = ["code-quality"]; // src/feature-flags.ts var fs7 = __toESM(require("fs")); @@ -86176,10 +86207,11 @@ var path8 = __toESM(require("path")); var semver3 = __toESM(require_semver2()); // src/defaults.json -var bundleVersion = "codeql-bundle-v2.22.4"; -var cliVersion = "2.22.4"; +var bundleVersion = "codeql-bundle-v2.23.0"; +var cliVersion = "2.23.0"; // src/overlay-database-utils.ts +var crypto = __toESM(require("crypto")); var fs6 = __toESM(require("fs")); var path7 = __toESM(require("path")); var actionsCache = __toESM(require_cache3()); @@ -86386,7 +86418,7 @@ function formatDuration(durationMs) { // src/overlay-database-utils.ts var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; -var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 6e3; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 15e3; var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; async function writeBaseDatabaseOidsFile(config, sourceRoot) { const gitFileOids = await getFileOidsUnderPath(sourceRoot); @@ -86458,14 +86490,14 @@ function checkOverlayBaseDatabase(config, logger, warningPrefix) { return true; } async function downloadOverlayBaseDatabaseFromCache(codeql, config, logger) { - const overlayDatabaseMode = config.augmentationProperties.overlayDatabaseMode; + const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode !== "overlay" /* Overlay */) { logger.debug( `Overlay database mode is ${overlayDatabaseMode}. Skip downloading overlay-base database from cache.` ); return void 0; } - if (!config.augmentationProperties.useOverlayDatabaseCaching) { + if (!config.useOverlayDatabaseCaching) { logger.debug( "Overlay database caching is disabled. Skip downloading overlay-base database from cache." ); @@ -86479,16 +86511,19 @@ async function downloadOverlayBaseDatabaseFromCache(codeql, config, logger) { } const dbLocation = config.dbLocation; const codeQlVersion = (await codeql.getVersion()).version; - const restoreKey = getCacheRestoreKey(config, codeQlVersion); + const cacheRestoreKeyPrefix = await getCacheRestoreKeyPrefix( + config, + codeQlVersion + ); logger.info( - `Looking in Actions cache for overlay-base database with restore key ${restoreKey}` + `Looking in Actions cache for overlay-base database with restore key ${cacheRestoreKeyPrefix}` ); let databaseDownloadDurationMs = 0; try { const databaseDownloadStart = performance.now(); const foundKey = await withTimeout( MAX_CACHE_OPERATION_MS, - actionsCache.restoreCache([dbLocation], restoreKey), + actionsCache.restoreCache([dbLocation], cacheRestoreKeyPrefix), () => { logger.info("Timed out downloading overlay-base database from cache"); } @@ -86531,9 +86566,18 @@ async function downloadOverlayBaseDatabaseFromCache(codeql, config, logger) { databaseDownloadDurationMs }; } -function getCacheRestoreKey(config, codeQlVersion) { +async function getCacheRestoreKeyPrefix(config, codeQlVersion) { const languages = [...config.languages].sort().join("_"); - return `${CACHE_PREFIX}-${CACHE_VERSION}-${languages}-${codeQlVersion}-`; + const cacheKeyComponents = { + automationID: await getAutomationID() + // Add more components here as needed in the future + }; + const componentsHash = createCacheKeyHash(cacheKeyComponents); + return `${CACHE_PREFIX}-${CACHE_VERSION}-${componentsHash}-${languages}-${codeQlVersion}-`; +} +function createCacheKeyHash(components) { + const componentsJson = JSON.stringify(components); + return crypto.createHash("sha256").update(componentsJson).digest("hex").substring(0, 16); } // src/tools-features.ts @@ -86586,6 +86630,12 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["resolve_supported_languages_using_cli" /* ResolveSupportedLanguagesUsingCli */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI", + minimumVersion: void 0, + toolsFeature: "builtinExtractorsSpecifyDefaultQueries" /* BuiltinExtractorsSpecifyDefaultQueries */ + }, ["overlay_analysis" /* OverlayAnalysis */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS", @@ -86702,6 +86752,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_QA_TELEMETRY", legacyApi: true, minimumVersion: void 0 + }, + ["java_minimize_dependency_jars" /* JavaMinimizeDependencyJars */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS", + minimumVersion: "2.23.0" } }; var FEATURE_FLAGS_FILE_NAME = "cached-feature-flags.json"; @@ -87116,15 +87171,6 @@ async function cachePrefix(codeql, language) { // src/config-utils.ts var PACKS_PROPERTY = "packs"; -var defaultAugmentationProperties = { - queriesInputCombines: false, - packsInputCombines: false, - packsInput: void 0, - queriesInput: void 0, - extraQueryExclusions: [], - overlayDatabaseMode: "none" /* None */, - useOverlayDatabaseCaching: false -}; function getPacksStrInvalid(packStr, configFile) { return configFile ? getConfigFilePropertyError( configFile, @@ -87162,11 +87208,22 @@ function getNoLanguagesError() { function getUnknownLanguagesError(languages) { return `Did not recognize the following languages: ${languages.join(", ")}`; } -async function getSupportedLanguageMap(codeql) { - const resolveResult = await codeql.betterResolveLanguages(); +async function getSupportedLanguageMap(codeql, features, logger) { + const resolveSupportedLanguagesUsingCli = await features.getValue( + "resolve_supported_languages_using_cli" /* ResolveSupportedLanguagesUsingCli */, + codeql + ); + const resolveResult = await codeql.betterResolveLanguages({ + filterToLanguagesWithQueries: resolveSupportedLanguagesUsingCli + }); + if (resolveSupportedLanguagesUsingCli) { + logger.debug( + `The CodeQL CLI supports the following languages: ${Object.keys(resolveResult.extractors).join(", ")}` + ); + } const supportedLanguages = {}; for (const extractor of Object.keys(resolveResult.extractors)) { - if (KnownLanguage[extractor] !== void 0) { + if (resolveSupportedLanguagesUsingCli || KnownLanguage[extractor] !== void 0) { supportedLanguages[extractor] = extractor; } } @@ -87180,7 +87237,7 @@ async function getSupportedLanguageMap(codeql) { var baseWorkflowsPath = ".github/workflows"; function hasActionsWorkflows(sourceRoot) { const workflowsPath = path10.resolve(sourceRoot, baseWorkflowsPath); - const stats = fs9.lstatSync(workflowsPath); + const stats = fs9.lstatSync(workflowsPath, { throwIfNoEntry: false }); return stats !== void 0 && stats.isDirectory() && fs9.readdirSync(workflowsPath).length > 0; } async function getRawLanguagesInRepo(repository, sourceRoot, logger) { @@ -87202,14 +87259,14 @@ async function getRawLanguagesInRepo(repository, sourceRoot, logger) { logger.debug(`Raw languages in repository: ${result.join(", ")}`); return result; } -async function getLanguages(codeql, languagesInput, repository, sourceRoot, logger) { +async function getLanguages(codeql, languagesInput, repository, sourceRoot, features, logger) { const { rawLanguages, autodetected } = await getRawLanguages( languagesInput, repository, sourceRoot, logger ); - const languageMap = await getSupportedLanguageMap(codeql); + const languageMap = await getSupportedLanguageMap(codeql, features, logger); const languagesSet = /* @__PURE__ */ new Set(); const unknownLanguages = []; for (const language of rawLanguages) { @@ -87247,7 +87304,7 @@ async function getRawLanguages(languagesInput, repository, sourceRoot, logger) { autodetected: true }; } -async function getDefaultConfig({ +async function initActionState({ analysisKindsInput, languagesInput, queriesInput, @@ -87267,7 +87324,7 @@ async function getDefaultConfig({ githubVersion, features, logger -}) { +}, userConfig) { const analysisKinds = await parseAnalysisKinds(analysisKindsInput); if (!analysisKinds.includes("code-quality" /* CodeQuality */) && qualityQueriesInput !== void 0) { analysisKinds.push("code-quality" /* CodeQuality */); @@ -87277,6 +87334,7 @@ async function getDefaultConfig({ languagesInput, repository, sourceRoot, + features, logger ); const buildMode = await parseBuildModeInput( @@ -87296,11 +87354,17 @@ async function getDefaultConfig({ languages, logger ); + const computedConfig = generateCodeScanningConfig( + userConfig, + augmentationProperties + ); return { + version: getActionVersion(), analysisKinds, languages, buildMode, - originalUserInput: {}, + originalUserInput: userConfig, + computedConfig, tempDir, codeQLCmd: codeql.getPath(), gitHubVersion: githubVersion, @@ -87308,10 +87372,12 @@ async function getDefaultConfig({ debugMode, debugArtifactName, debugDatabaseName, - augmentationProperties, trapCaches, trapCacheDownloadTime, - dependencyCachingEnabled: getCachingKind(dependencyCachingEnabled) + dependencyCachingEnabled: getCachingKind(dependencyCachingEnabled), + extraQueryExclusions: [], + overlayDatabaseMode: "none" /* None */, + useOverlayDatabaseCaching: false }; } async function downloadCacheWithTime(trapCachingEnabled, codeQL, languages, logger) { @@ -87355,10 +87421,7 @@ async function calculateAugmentation(rawPacksInput, rawQueriesInput, languages) packsInputCombines, packsInput: packsInput?.[languages[0]], queriesInput, - queriesInputCombines, - extraQueryExclusions: [], - overlayDatabaseMode: "none" /* None */, - useOverlayDatabaseCaching: false + queriesInputCombines }; } function parseQueriesFromInput(rawQueriesInput, queriesInputCombines) { @@ -87585,6 +87648,9 @@ function dbLocationOrDefault(dbLocation, tempDir) { function userConfigFromActionPath(tempDir) { return path10.resolve(tempDir, "user-config-from-action.yml"); } +function hasQueryCustomisation(userConfig) { + return isDefined(userConfig["disable-default-queries"]) || isDefined(userConfig.queries) || isDefined(userConfig["query-filters"]); +} async function initConfig(inputs) { const { logger, tempDir } = inputs; if (inputs.configInput) { @@ -87609,9 +87675,18 @@ async function initConfig(inputs) { tempDir ); } - const config = await getDefaultConfig(inputs); - const augmentationProperties = config.augmentationProperties; - config.originalUserInput = userConfig; + const config = await initActionState(inputs, userConfig); + if (config.analysisKinds.length === 1 && isCodeQualityEnabled(config)) { + if (hasQueryCustomisation(config.computedConfig)) { + throw new ConfigurationError( + "Query customizations are unsupported, because only `code-quality` analysis is enabled." + ); + } + const queries = codeQualityQueries.map((v) => ({ uses: v })); + config.computedConfig["disable-default-queries"] = true; + config.computedConfig.queries = queries; + config.computedConfig["query-filters"] = []; + } const { overlayDatabaseMode, useOverlayDatabaseCaching } = await getOverlayDatabaseMode( inputs.codeql, inputs.repository, @@ -87619,24 +87694,23 @@ async function initConfig(inputs) { config.languages, inputs.sourceRoot, config.buildMode, - generateCodeScanningConfig(userConfig, augmentationProperties), + config.computedConfig, logger ); logger.info( `Using overlay database mode: ${overlayDatabaseMode} ${useOverlayDatabaseCaching ? "with" : "without"} caching.` ); - augmentationProperties.overlayDatabaseMode = overlayDatabaseMode; - augmentationProperties.useOverlayDatabaseCaching = useOverlayDatabaseCaching; + config.overlayDatabaseMode = overlayDatabaseMode; + config.useOverlayDatabaseCaching = useOverlayDatabaseCaching; if (overlayDatabaseMode === "overlay" /* Overlay */ || await shouldPerformDiffInformedAnalysis( inputs.codeql, inputs.features, logger )) { - augmentationProperties.extraQueryExclusions.push({ + config.extraQueryExclusions.push({ exclude: { tags: "exclude-from-incremental" } }); } - await saveConfig(config, logger); return config; } function parseRegistries(registriesInput) { @@ -87825,19 +87899,29 @@ function generateCodeScanningConfig(originalUserInput, augmentationProperties) { if (Array.isArray(augmentedConfig.packs) && !augmentedConfig.packs.length) { delete augmentedConfig.packs; } + return augmentedConfig; +} +function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { + const augmentedConfig = cloneObject(cliConfig); + if (extraQueryExclusions.length === 0) { + return augmentedConfig; + } augmentedConfig["query-filters"] = [ // Ordering matters. If the first filter is an inclusion, it implicitly // excludes all queries that are not included. If it is an exclusion, // it implicitly includes all queries that are not excluded. So user // filters (if any) should always be first to preserve intent. ...augmentedConfig["query-filters"] || [], - ...augmentationProperties.extraQueryExclusions + ...extraQueryExclusions ]; if (augmentedConfig["query-filters"]?.length === 0) { delete augmentedConfig["query-filters"]; } return augmentedConfig; } +function isCodeQualityEnabled(config) { + return config.analysisKinds.includes("code-quality" /* CodeQuality */); +} // src/dependency-caching.ts var os2 = __toESM(require("os")); @@ -87890,7 +87974,7 @@ function getDefaultCacheConfig() { async function makeGlobber(patterns) { return glob.create(patterns.join("\n")); } -async function downloadDependencyCaches(languages, logger) { +async function downloadDependencyCaches(languages, logger, minimizeJavaJars) { const restoredCaches = []; for (const language of languages) { const cacheConfig = getDefaultCacheConfig()[language]; @@ -87907,8 +87991,10 @@ async function downloadDependencyCaches(languages, logger) { ); continue; } - const primaryKey = await cacheKey2(language, cacheConfig); - const restoreKeys = [await cachePrefix2(language)]; + const primaryKey = await cacheKey2(language, cacheConfig, minimizeJavaJars); + const restoreKeys = [ + await cachePrefix2(language, minimizeJavaJars) + ]; logger.info( `Downloading cache for ${language} with key ${primaryKey} and restore keys ${restoreKeys.join( ", " @@ -87928,17 +88014,20 @@ async function downloadDependencyCaches(languages, logger) { } return restoredCaches; } -async function cacheKey2(language, cacheConfig) { +async function cacheKey2(language, cacheConfig, minimizeJavaJars = false) { const hash = await glob.hashFiles(cacheConfig.hash.join("\n")); - return `${await cachePrefix2(language)}${hash}`; + return `${await cachePrefix2(language, minimizeJavaJars)}${hash}`; } -async function cachePrefix2(language) { +async function cachePrefix2(language, minimizeJavaJars) { const runnerOs = getRequiredEnvParam("RUNNER_OS"); const customPrefix = process.env["CODEQL_ACTION_DEPENDENCY_CACHE_PREFIX" /* DEPENDENCY_CACHING_PREFIX */]; let prefix = CODEQL_DEPENDENCY_CACHE_PREFIX; if (customPrefix !== void 0 && customPrefix.length > 0) { prefix = `${prefix}-${customPrefix}`; } + if (language === "java" /* java */ && minimizeJavaJars) { + prefix = `minify-${prefix}`; + } return `${prefix}-${CODEQL_DEPENDENCY_CACHE_VERSION}-${runnerOs}-${language}-`; } @@ -89192,7 +89281,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { await this.getVersion(), "forceOverwrite" /* ForceOverwrite */ ) ? "--force-overwrite" : "--overwrite"; - const overlayDatabaseMode = config.augmentationProperties.overlayDatabaseMode; + const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode === "overlay" /* Overlay */) { const overlayChangesFile = await writeOverlayChangesFile( config, @@ -89303,13 +89392,16 @@ async function getCodeQLForCmd(cmd, checkVersion) { ); } }, - async betterResolveLanguages() { + async betterResolveLanguages({ + filterToLanguagesWithQueries + } = { filterToLanguagesWithQueries: false }) { const codeqlArgs = [ "resolve", "languages", "--format=betterjson", "--extractor-options-verbosity=4", "--extractor-include-aliases", + ...filterToLanguagesWithQueries ? ["--filter-to-languages-with-queries"] : [], ...getExtraOptionsFromEnv(["resolve", "languages"]) ]; const output = await runCli(cmd, codeqlArgs); @@ -89348,7 +89440,6 @@ ${output}` "run-queries", ...flags, databasePath, - "--intra-layer-parallelism", "--min-disk-free=1024", // Try to leave at least 1GB free "-v", @@ -89606,9 +89697,9 @@ async function runCli(cmd, args = [], opts = {}) { } async function writeCodeScanningConfigFile(config, logger) { const codeScanningConfigFile = getGeneratedCodeScanningConfigPath(config); - const augmentedConfig = generateCodeScanningConfig( - config.originalUserInput, - config.augmentationProperties + const augmentedConfig = appendExtraQueryExclusions( + config.extraQueryExclusions, + config.computedConfig ); logger.info( `Writing augmented user configuration file to ${codeScanningConfigFile}` @@ -89988,6 +90079,51 @@ async function sendStatusReport(statusReport) { ); } } +async function createInitWithConfigStatusReport(config, initStatusReport, configFile, totalCacheSize, overlayBaseDatabaseStats) { + const languages = config.languages.join(","); + const paths = (config.originalUserInput.paths || []).join(","); + const pathsIgnore = (config.originalUserInput["paths-ignore"] || []).join( + "," + ); + const disableDefaultQueries = config.originalUserInput["disable-default-queries"] ? languages : ""; + const queries = []; + let queriesInput = getOptionalInput("queries")?.trim(); + if (queriesInput === void 0 || queriesInput.startsWith("+")) { + queries.push( + ...(config.originalUserInput.queries || []).map((q) => q.uses) + ); + } + if (queriesInput !== void 0) { + queriesInput = queriesInput.startsWith("+") ? queriesInput.slice(1) : queriesInput; + queries.push(...queriesInput.split(",")); + } + let packs = {}; + if (Array.isArray(config.computedConfig.packs)) { + packs[config.languages[0]] = config.computedConfig.packs; + } else if (config.computedConfig.packs !== void 0) { + packs = config.computedConfig.packs; + } + return { + ...initStatusReport, + config_file: configFile ?? "", + disable_default_queries: disableDefaultQueries, + paths, + paths_ignore: pathsIgnore, + queries: queries.join(","), + packs: JSON.stringify(packs), + trap_cache_languages: Object.keys(config.trapCaches).join(","), + trap_cache_download_size_bytes: totalCacheSize, + trap_cache_download_duration_ms: Math.round(config.trapCacheDownloadTime), + overlay_base_database_download_size_bytes: overlayBaseDatabaseStats?.databaseSizeBytes, + overlay_base_database_download_duration_ms: overlayBaseDatabaseStats?.databaseDownloadDurationMs, + query_filters: JSON.stringify( + config.originalUserInput["query-filters"] ?? [] + ), + registries: JSON.stringify( + parseRegistriesWithoutCredentials(getOptionalInput("registries")) ?? [] + ) + }; +} // src/workflow.ts var fs16 = __toESM(require("fs")); @@ -90005,7 +90141,8 @@ function toCodedErrors(errors) { } var WorkflowErrors = toCodedErrors({ MissingPushHook: `Please specify an on.push hook to analyze and see code scanning alerts from the default branch on the Security tab.`, - CheckoutWrongHead: `git checkout HEAD^2 is no longer necessary. Please remove this step as Code Scanning recommends analyzing the merge commit for best results.` + CheckoutWrongHead: `git checkout HEAD^2 is no longer necessary. Please remove this step as Code Scanning recommends analyzing the merge commit for best results.`, + InconsistentActionVersion: `Not all workflow steps that use \`github/codeql-action\` actions use the same version. Please ensure that all such steps use the same version to avoid compatibility issues.` }); async function groupLanguagesByExtractor(languages, codeql) { const resolveResult = await codeql.betterResolveLanguages(); @@ -90059,6 +90196,22 @@ async function getWorkflowErrors(doc, codeql) { } } } + const codeqlStepRefs = []; + for (const job of Object.values(doc?.jobs || {})) { + if (Array.isArray(job.steps)) { + for (const step of job.steps) { + if (step.uses?.startsWith("github/codeql-action/")) { + const parts = step.uses.split("@"); + if (parts.length >= 2) { + codeqlStepRefs.push(parts[parts.length - 1]); + } + } + } + } + } + if (codeqlStepRefs.length > 0 && !codeqlStepRefs.every((ref) => ref === codeqlStepRefs[0])) { + errors.push(WorkflowErrors.InconsistentActionVersion); + } const hasPushTrigger = hasWorkflowTrigger("push", doc); const hasPullRequestTrigger = hasWorkflowTrigger("pull_request", doc); const hasWorkflowCallTrigger = hasWorkflowTrigger("workflow_call", doc); @@ -90175,64 +90328,15 @@ async function sendCompletedStatusReport(startedAt, config, configFile, toolsDow initToolsDownloadFields.tools_feature_flags_valid = toolsFeatureFlagsValid; } if (config !== void 0) { - const languages = config.languages.join(","); - const paths = (config.originalUserInput.paths || []).join(","); - const pathsIgnore = (config.originalUserInput["paths-ignore"] || []).join( - "," - ); - const disableDefaultQueries = config.originalUserInput["disable-default-queries"] ? languages : ""; - const queries = []; - let queriesInput = getOptionalInput("queries")?.trim(); - if (queriesInput === void 0 || queriesInput.startsWith("+")) { - queries.push( - ...(config.originalUserInput.queries || []).map((q) => q.uses) - ); - } - if (queriesInput !== void 0) { - queriesInput = queriesInput.startsWith("+") ? queriesInput.slice(1) : queriesInput; - queries.push(...queriesInput.split(",")); - } - let packs = {}; - if ((config.augmentationProperties.packsInputCombines || !config.augmentationProperties.packsInput) && config.originalUserInput.packs) { - const copyPacksFromOriginalUserInput = cloneObject( - config.originalUserInput.packs - ); - if (Array.isArray(copyPacksFromOriginalUserInput)) { - packs[config.languages[0]] = copyPacksFromOriginalUserInput; - } else { - packs = copyPacksFromOriginalUserInput; - } - } - if (config.augmentationProperties.packsInput) { - packs[config.languages[0]] ??= []; - packs[config.languages[0]].push( - ...config.augmentationProperties.packsInput - ); - } - const initWithConfigStatusReport = { - ...initStatusReport, - config_file: configFile ?? "", - disable_default_queries: disableDefaultQueries, - paths, - paths_ignore: pathsIgnore, - queries: queries.join(","), - packs: JSON.stringify(packs), - trap_cache_languages: Object.keys(config.trapCaches).join(","), - trap_cache_download_size_bytes: Math.round( + const initWithConfigStatusReport = await createInitWithConfigStatusReport( + config, + initStatusReport, + configFile, + Math.round( await getTotalCacheSize(Object.values(config.trapCaches), logger) ), - trap_cache_download_duration_ms: Math.round(config.trapCacheDownloadTime), - overlay_base_database_download_size_bytes: overlayBaseDatabaseStats?.databaseSizeBytes, - overlay_base_database_download_duration_ms: overlayBaseDatabaseStats?.databaseDownloadDurationMs, - query_filters: JSON.stringify( - config.originalUserInput["query-filters"] ?? [] - ), - registries: JSON.stringify( - parseRegistriesWithoutCredentials( - getOptionalInput("registries") - ) ?? [] - ) - }; + overlayBaseDatabaseStats + ); await sendStatusReport({ ...initWithConfigStatusReport, ...initToolsDownloadFields @@ -90391,20 +90495,20 @@ async function run() { } let overlayBaseDatabaseStats; try { - if (config.augmentationProperties.overlayDatabaseMode === "overlay" /* Overlay */ && config.augmentationProperties.useOverlayDatabaseCaching) { + if (config.overlayDatabaseMode === "overlay" /* Overlay */ && config.useOverlayDatabaseCaching) { overlayBaseDatabaseStats = await downloadOverlayBaseDatabaseFromCache( codeql, config, logger ); if (!overlayBaseDatabaseStats) { - config.augmentationProperties.overlayDatabaseMode = "none" /* None */; + config.overlayDatabaseMode = "none" /* None */; logger.info( `No overlay-base database found in cache, reverting overlay database mode to ${"none" /* None */}.` ); } } - if (config.augmentationProperties.overlayDatabaseMode !== "overlay" /* Overlay */) { + if (config.overlayDatabaseMode !== "overlay" /* Overlay */) { cleanupDatabaseClusterDirectory(config, logger); } if (zstdAvailability) { @@ -90529,8 +90633,16 @@ exec ${goBinaryPath} "$@"` core13.exportVariable(envVar, "false"); } } + const minimizeJavaJars = await features.getValue( + "java_minimize_dependency_jars" /* JavaMinimizeDependencyJars */, + codeql + ); if (shouldRestoreCache(config.dependencyCachingEnabled)) { - await downloadDependencyCaches(config.languages, logger); + await downloadDependencyCaches( + config.languages, + logger, + minimizeJavaJars + ); } if (await codeQlVersionAtLeast(codeql, "2.17.1")) { } else { @@ -90563,6 +90675,16 @@ exec ${goBinaryPath} "$@"` core13.exportVariable("CODEQL_EXTRACTOR_PYTHON_EXTRACT_STDLIB", "true"); } } + if (process.env["CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS" /* JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS */]) { + logger.debug( + `${"CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS" /* JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS */} is already set to '${process.env["CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS" /* JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS */]}', so the Action will not override it.` + ); + } else if (minimizeJavaJars && config.buildMode === "none" /* None */ && config.languages.includes("java" /* java */)) { + core13.exportVariable( + "CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS" /* JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS */, + "true" + ); + } const { registriesAuthTokens, qlconfigFile } = await generateRegistries( getOptionalInput("registries"), config.tempDir, @@ -90581,11 +90703,11 @@ exec ${goBinaryPath} "$@"` qlconfigFile, logger ); - if (config.augmentationProperties.overlayDatabaseMode !== "none" /* None */ && !await checkPacksForOverlayCompatibility(codeql, config, logger)) { + if (config.overlayDatabaseMode !== "none" /* None */ && !await checkPacksForOverlayCompatibility(codeql, config, logger)) { logger.info( "Reverting overlay database mode to None due to incompatible packs." ); - config.augmentationProperties.overlayDatabaseMode = "none" /* None */; + config.overlayDatabaseMode = "none" /* None */; cleanupDatabaseClusterDirectory(config, logger, { disableExistingDirectoryWarning: true }); @@ -90628,6 +90750,7 @@ exec ${goBinaryPath} "$@"` } finally { logUnwrittenDiagnostics(); } + await saveConfig(config, logger); await sendCompletedStatusReport( startedAt, config, diff --git a/lib/resolve-environment-action.js b/lib/resolve-environment-action.js index 7c46b8092b..05149433bd 100644 --- a/lib/resolve-environment-action.js +++ b/lib/resolve-environment-action.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -26438,7 +26438,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.1", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -26486,26 +26486,24 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^11.1.0" + uuid: "^12.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.34.0", + "@eslint/js": "^9.35.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@octokit/types": "^14.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", - "@types/get-folder-size": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/node": "20.19.9", "@types/node-forge": "^1.3.14", - "@types/semver": "^7.7.0", + "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", esbuild: "^0.25.9", @@ -26538,7 +26536,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -31823,14 +31822,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -31841,7 +31840,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -78421,7 +78420,7 @@ function getActionsLogger() { // src/overlay-database-utils.ts var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; -var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 6e3; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 15e3; var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; async function writeBaseDatabaseOidsFile(config, sourceRoot) { const gitFileOids = await getFileOidsUnderPath(sourceRoot); @@ -78527,6 +78526,12 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["resolve_supported_languages_using_cli" /* ResolveSupportedLanguagesUsingCli */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI", + minimumVersion: void 0, + toolsFeature: "builtinExtractorsSpecifyDefaultQueries" /* BuiltinExtractorsSpecifyDefaultQueries */ + }, ["overlay_analysis" /* OverlayAnalysis */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS", @@ -78643,6 +78648,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_QA_TELEMETRY", legacyApi: true, minimumVersion: void 0 + }, + ["java_minimize_dependency_jars" /* JavaMinimizeDependencyJars */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS", + minimumVersion: "2.23.0" } }; @@ -78650,15 +78660,6 @@ var featureConfig = { var actionsCache2 = __toESM(require_cache3()); // src/config-utils.ts -var defaultAugmentationProperties = { - queriesInputCombines: false, - packsInputCombines: false, - packsInput: void 0, - queriesInput: void 0, - extraQueryExclusions: [], - overlayDatabaseMode: "none" /* None */, - useOverlayDatabaseCaching: false -}; var OVERLAY_ANALYSIS_FEATURES = { actions: "overlay_analysis_actions" /* OverlayAnalysisActions */, cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, @@ -78700,40 +78701,23 @@ async function getConfig(tempDir, logger) { const configString = fs3.readFileSync(configFile, "utf8"); logger.debug("Loaded config:"); logger.debug(configString); - return JSON.parse(configString); -} -function generateCodeScanningConfig(originalUserInput, augmentationProperties) { - const augmentedConfig = cloneObject(originalUserInput); - if (augmentationProperties.queriesInput) { - if (augmentationProperties.queriesInputCombines) { - augmentedConfig.queries = (augmentedConfig.queries || []).concat( - augmentationProperties.queriesInput - ); - } else { - augmentedConfig.queries = augmentationProperties.queriesInput; - } - } - if (augmentedConfig.queries?.length === 0) { - delete augmentedConfig.queries; + const config = JSON.parse(configString); + if (config.version === void 0) { + throw new ConfigurationError( + `Loaded configuration file, but it does not contain the expected 'version' field.` + ); } - if (augmentationProperties.packsInput) { - if (augmentationProperties.packsInputCombines) { - if (Array.isArray(augmentedConfig.packs)) { - augmentedConfig.packs = (augmentedConfig.packs || []).concat( - augmentationProperties.packsInput - ); - } else if (!augmentedConfig.packs) { - augmentedConfig.packs = augmentationProperties.packsInput; - } else { - const language = Object.keys(augmentedConfig.packs)[0]; - augmentedConfig.packs[language] = augmentedConfig.packs[language].concat(augmentationProperties.packsInput); - } - } else { - augmentedConfig.packs = augmentationProperties.packsInput; - } + if (config.version !== getActionVersion()) { + throw new ConfigurationError( + `Loaded a configuration file for version '${config.version}', but running version '${getActionVersion()}'` + ); } - if (Array.isArray(augmentedConfig.packs) && !augmentedConfig.packs.length) { - delete augmentedConfig.packs; + return config; +} +function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { + const augmentedConfig = cloneObject(cliConfig); + if (extraQueryExclusions.length === 0) { + return augmentedConfig; } augmentedConfig["query-filters"] = [ // Ordering matters. If the first filter is an inclusion, it implicitly @@ -78741,7 +78725,7 @@ function generateCodeScanningConfig(originalUserInput, augmentationProperties) { // it implicitly includes all queries that are not excluded. So user // filters (if any) should always be first to preserve intent. ...augmentedConfig["query-filters"] || [], - ...augmentationProperties.extraQueryExclusions + ...extraQueryExclusions ]; if (augmentedConfig["query-filters"]?.length === 0) { delete augmentedConfig["query-filters"]; @@ -78869,7 +78853,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { await this.getVersion(), "forceOverwrite" /* ForceOverwrite */ ) ? "--force-overwrite" : "--overwrite"; - const overlayDatabaseMode = config.augmentationProperties.overlayDatabaseMode; + const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode === "overlay" /* Overlay */) { const overlayChangesFile = await writeOverlayChangesFile( config, @@ -78980,13 +78964,16 @@ async function getCodeQLForCmd(cmd, checkVersion) { ); } }, - async betterResolveLanguages() { + async betterResolveLanguages({ + filterToLanguagesWithQueries + } = { filterToLanguagesWithQueries: false }) { const codeqlArgs = [ "resolve", "languages", "--format=betterjson", "--extractor-options-verbosity=4", "--extractor-include-aliases", + ...filterToLanguagesWithQueries ? ["--filter-to-languages-with-queries"] : [], ...getExtraOptionsFromEnv(["resolve", "languages"]) ]; const output = await runCli(cmd, codeqlArgs); @@ -79025,7 +79012,6 @@ ${output}` "run-queries", ...flags, databasePath, - "--intra-layer-parallelism", "--min-disk-free=1024", // Try to leave at least 1GB free "-v", @@ -79283,9 +79269,9 @@ async function runCli(cmd, args = [], opts = {}) { } async function writeCodeScanningConfigFile(config, logger) { const codeScanningConfigFile = getGeneratedCodeScanningConfigPath(config); - const augmentedConfig = generateCodeScanningConfig( - config.originalUserInput, - config.augmentationProperties + const augmentedConfig = appendExtraQueryExclusions( + config.extraQueryExclusions, + config.computedConfig ); logger.info( `Writing augmented user configuration file to ${codeScanningConfigFile}` diff --git a/lib/start-proxy-action-post.js b/lib/start-proxy-action-post.js index c9317c4cd2..4a10f55679 100644 --- a/lib/start-proxy-action-post.js +++ b/lib/start-proxy-action-post.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -26438,7 +26438,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.1", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -26486,26 +26486,24 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^11.1.0" + uuid: "^12.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.34.0", + "@eslint/js": "^9.35.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@octokit/types": "^14.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", - "@types/get-folder-size": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/node": "20.19.9", "@types/node-forge": "^1.3.14", - "@types/semver": "^7.7.0", + "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", esbuild: "^0.25.9", @@ -26538,7 +26536,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -31823,14 +31822,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -31841,7 +31840,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -76347,7 +76346,7 @@ var require_brace_expansion2 = __commonJS({ var isSequence = isNumericSequence || isAlphaSequence; var isOptions = m.body.indexOf(",") >= 0; if (!isSequence && !isOptions) { - if (m.post.match(/,.*\}/)) { + if (m.post.match(/,(?!,).*\}/)) { str2 = m.pre + "{" + m.body + escClose + m.post; return expand(str2); } @@ -101572,7 +101571,7 @@ var require_dist_node16 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -101580,7 +101579,7 @@ var require_dist_node16 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -101590,12 +101589,12 @@ var require_dist_node16 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push(encodeValue(operator, value2, isKeyOperator(operator) ? key : "")); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -101603,12 +101602,12 @@ var require_dist_node16 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -101623,7 +101622,7 @@ var require_dist_node16 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -117160,7 +117159,7 @@ function getActionsLogger() { // src/overlay-database-utils.ts var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; -var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 6e3; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 15e3; var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; // src/tools-features.ts @@ -117207,6 +117206,12 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["resolve_supported_languages_using_cli" /* ResolveSupportedLanguagesUsingCli */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI", + minimumVersion: void 0, + toolsFeature: "builtinExtractorsSpecifyDefaultQueries" /* BuiltinExtractorsSpecifyDefaultQueries */ + }, ["overlay_analysis" /* OverlayAnalysis */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS", @@ -117323,6 +117328,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_QA_TELEMETRY", legacyApi: true, minimumVersion: void 0 + }, + ["java_minimize_dependency_jars" /* JavaMinimizeDependencyJars */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS", + minimumVersion: "2.23.0" } }; @@ -117330,15 +117340,6 @@ var featureConfig = { var actionsCache2 = __toESM(require_cache3()); // src/config-utils.ts -var defaultAugmentationProperties = { - queriesInputCombines: false, - packsInputCombines: false, - packsInput: void 0, - queriesInput: void 0, - extraQueryExclusions: [], - overlayDatabaseMode: "none" /* None */, - useOverlayDatabaseCaching: false -}; var OVERLAY_ANALYSIS_FEATURES = { actions: "overlay_analysis_actions" /* OverlayAnalysisActions */, cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, @@ -117380,7 +117381,18 @@ async function getConfig(tempDir, logger) { const configString = fs.readFileSync(configFile, "utf8"); logger.debug("Loaded config:"); logger.debug(configString); - return JSON.parse(configString); + const config = JSON.parse(configString); + if (config.version === void 0) { + throw new ConfigurationError( + `Loaded configuration file, but it does not contain the expected 'version' field.` + ); + } + if (config.version !== getActionVersion()) { + throw new ConfigurationError( + `Loaded a configuration file for version '${config.version}', but running version '${getActionVersion()}'` + ); + } + return config; } // src/debug-artifacts.ts diff --git a/lib/start-proxy-action.js b/lib/start-proxy-action.js index 853cde53b6..665f6ce095 100644 --- a/lib/start-proxy-action.js +++ b/lib/start-proxy-action.js @@ -19650,7 +19650,7 @@ var require_core = __commonJS({ ExitCode2[ExitCode2["Success"] = 0] = "Success"; ExitCode2[ExitCode2["Failure"] = 1] = "Failure"; })(ExitCode || (exports2.ExitCode = ExitCode = {})); - function exportVariable2(name, val) { + function exportVariable3(name, val) { const convertedVal = (0, utils_1.toCommandValue)(val); process.env[name] = convertedVal; const filePath = process.env["GITHUB_ENV"] || ""; @@ -19659,7 +19659,7 @@ var require_core = __commonJS({ } (0, command_1.issueCommand)("set-env", { name }, convertedVal); } - exports2.exportVariable = exportVariable2; + exports2.exportVariable = exportVariable3; function setSecret2(secret) { (0, command_1.issueCommand)("add-mask", {}, secret); } @@ -21915,7 +21915,7 @@ var require_retry_helper = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.RetryHelper = void 0; - var core8 = __importStar(require_core()); + var core9 = __importStar(require_core()); var RetryHelper = class { constructor(maxAttempts, minSeconds, maxSeconds) { if (maxAttempts < 1) { @@ -21938,10 +21938,10 @@ var require_retry_helper = __commonJS({ if (isRetryable && !isRetryable(err)) { throw err; } - core8.info(err.message); + core9.info(err.message); } const seconds = this.getSleepAmount(); - core8.info(`Waiting ${seconds} seconds before trying again`); + core9.info(`Waiting ${seconds} seconds before trying again`); yield this.sleep(seconds); attempt++; } @@ -22021,7 +22021,7 @@ var require_tool_cache = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.evaluateVersions = exports2.isExplicitVersion = exports2.findFromManifest = exports2.getManifestFromRepo = exports2.findAllVersions = exports2.find = exports2.cacheFile = exports2.cacheDir = exports2.extractZip = exports2.extractXar = exports2.extractTar = exports2.extract7z = exports2.downloadTool = exports2.HTTPError = void 0; - var core8 = __importStar(require_core()); + var core9 = __importStar(require_core()); var io3 = __importStar(require_io()); var crypto = __importStar(require("crypto")); var fs = __importStar(require("fs")); @@ -22050,8 +22050,8 @@ var require_tool_cache = __commonJS({ return __awaiter(this, void 0, void 0, function* () { dest = dest || path2.join(_getTempDirectory(), crypto.randomUUID()); yield io3.mkdirP(path2.dirname(dest)); - core8.debug(`Downloading ${url}`); - core8.debug(`Destination ${dest}`); + core9.debug(`Downloading ${url}`); + core9.debug(`Destination ${dest}`); const maxAttempts = 3; const minSeconds = _getGlobal("TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS", 10); const maxSeconds = _getGlobal("TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS", 20); @@ -22078,7 +22078,7 @@ var require_tool_cache = __commonJS({ allowRetries: false }); if (auth) { - core8.debug("set auth"); + core9.debug("set auth"); if (headers === void 0) { headers = {}; } @@ -22087,7 +22087,7 @@ var require_tool_cache = __commonJS({ const response = yield http.get(url, headers); if (response.message.statusCode !== 200) { const err = new HTTPError(response.message.statusCode); - core8.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); + core9.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); throw err; } const pipeline = util.promisify(stream.pipeline); @@ -22096,16 +22096,16 @@ var require_tool_cache = __commonJS({ let succeeded = false; try { yield pipeline(readStream, fs.createWriteStream(dest)); - core8.debug("download complete"); + core9.debug("download complete"); succeeded = true; return dest; } finally { if (!succeeded) { - core8.debug("download failed"); + core9.debug("download failed"); try { yield io3.rmRF(dest); } catch (err) { - core8.debug(`Failed to delete '${dest}'. ${err.message}`); + core9.debug(`Failed to delete '${dest}'. ${err.message}`); } } } @@ -22120,7 +22120,7 @@ var require_tool_cache = __commonJS({ process.chdir(dest); if (_7zPath) { try { - const logLevel = core8.isDebug() ? "-bb1" : "-bb0"; + const logLevel = core9.isDebug() ? "-bb1" : "-bb0"; const args = [ "x", logLevel, @@ -22170,7 +22170,7 @@ var require_tool_cache = __commonJS({ throw new Error("parameter 'file' is required"); } dest = yield _createExtractFolder(dest); - core8.debug("Checking tar --version"); + core9.debug("Checking tar --version"); let versionOutput = ""; yield (0, exec_1.exec)("tar --version", [], { ignoreReturnCode: true, @@ -22180,7 +22180,7 @@ var require_tool_cache = __commonJS({ stderr: (data) => versionOutput += data.toString() } }); - core8.debug(versionOutput.trim()); + core9.debug(versionOutput.trim()); const isGnuTar = versionOutput.toUpperCase().includes("GNU TAR"); let args; if (flags instanceof Array) { @@ -22188,7 +22188,7 @@ var require_tool_cache = __commonJS({ } else { args = [flags]; } - if (core8.isDebug() && !flags.includes("v")) { + if (core9.isDebug() && !flags.includes("v")) { args.push("-v"); } let destArg = dest; @@ -22220,7 +22220,7 @@ var require_tool_cache = __commonJS({ args = [flags]; } args.push("-x", "-C", dest, "-f", file); - if (core8.isDebug()) { + if (core9.isDebug()) { args.push("-v"); } const xarPath = yield io3.which("xar", true); @@ -22265,7 +22265,7 @@ var require_tool_cache = __commonJS({ "-Command", pwshCommand ]; - core8.debug(`Using pwsh at path: ${pwshPath}`); + core9.debug(`Using pwsh at path: ${pwshPath}`); yield (0, exec_1.exec)(`"${pwshPath}"`, args); } else { const powershellCommand = [ @@ -22285,7 +22285,7 @@ var require_tool_cache = __commonJS({ powershellCommand ]; const powershellPath = yield io3.which("powershell", true); - core8.debug(`Using powershell at path: ${powershellPath}`); + core9.debug(`Using powershell at path: ${powershellPath}`); yield (0, exec_1.exec)(`"${powershellPath}"`, args); } }); @@ -22294,7 +22294,7 @@ var require_tool_cache = __commonJS({ return __awaiter(this, void 0, void 0, function* () { const unzipPath = yield io3.which("unzip", true); const args = [file]; - if (!core8.isDebug()) { + if (!core9.isDebug()) { args.unshift("-q"); } args.unshift("-o"); @@ -22305,8 +22305,8 @@ var require_tool_cache = __commonJS({ return __awaiter(this, void 0, void 0, function* () { version = semver2.clean(version) || version; arch = arch || os.arch(); - core8.debug(`Caching tool ${tool} ${version} ${arch}`); - core8.debug(`source dir: ${sourceDir}`); + core9.debug(`Caching tool ${tool} ${version} ${arch}`); + core9.debug(`source dir: ${sourceDir}`); if (!fs.statSync(sourceDir).isDirectory()) { throw new Error("sourceDir is not a directory"); } @@ -22324,14 +22324,14 @@ var require_tool_cache = __commonJS({ return __awaiter(this, void 0, void 0, function* () { version = semver2.clean(version) || version; arch = arch || os.arch(); - core8.debug(`Caching tool ${tool} ${version} ${arch}`); - core8.debug(`source file: ${sourceFile}`); + core9.debug(`Caching tool ${tool} ${version} ${arch}`); + core9.debug(`source file: ${sourceFile}`); if (!fs.statSync(sourceFile).isFile()) { throw new Error("sourceFile is not a file"); } const destFolder = yield _createToolPath(tool, version, arch); const destPath = path2.join(destFolder, targetFile); - core8.debug(`destination file ${destPath}`); + core9.debug(`destination file ${destPath}`); yield io3.cp(sourceFile, destPath); _completeToolPath(tool, version, arch); return destFolder; @@ -22355,12 +22355,12 @@ var require_tool_cache = __commonJS({ if (versionSpec) { versionSpec = semver2.clean(versionSpec) || ""; const cachePath = path2.join(_getCacheDirectory(), toolName, versionSpec, arch); - core8.debug(`checking cache: ${cachePath}`); + core9.debug(`checking cache: ${cachePath}`); if (fs.existsSync(cachePath) && fs.existsSync(`${cachePath}.complete`)) { - core8.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`); + core9.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`); toolPath = cachePath; } else { - core8.debug("not found"); + core9.debug("not found"); } } return toolPath; @@ -22391,7 +22391,7 @@ var require_tool_cache = __commonJS({ const http = new httpm.HttpClient("tool-cache"); const headers = {}; if (auth) { - core8.debug("set auth"); + core9.debug("set auth"); headers.authorization = auth; } const response = yield http.getJson(treeUrl, headers); @@ -22412,7 +22412,7 @@ var require_tool_cache = __commonJS({ try { releases = JSON.parse(versionsRaw); } catch (_a) { - core8.debug("Invalid json"); + core9.debug("Invalid json"); } } return releases; @@ -22438,7 +22438,7 @@ var require_tool_cache = __commonJS({ function _createToolPath(tool, version, arch) { return __awaiter(this, void 0, void 0, function* () { const folderPath = path2.join(_getCacheDirectory(), tool, semver2.clean(version) || version, arch || ""); - core8.debug(`destination ${folderPath}`); + core9.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io3.rmRF(folderPath); yield io3.rmRF(markerPath); @@ -22450,19 +22450,19 @@ var require_tool_cache = __commonJS({ const folderPath = path2.join(_getCacheDirectory(), tool, semver2.clean(version) || version, arch || ""); const markerPath = `${folderPath}.complete`; fs.writeFileSync(markerPath, ""); - core8.debug("finished caching tool"); + core9.debug("finished caching tool"); } function isExplicitVersion(versionSpec) { const c = semver2.clean(versionSpec) || ""; - core8.debug(`isExplicit: ${c}`); + core9.debug(`isExplicit: ${c}`); const valid = semver2.valid(c) != null; - core8.debug(`explicit? ${valid}`); + core9.debug(`explicit? ${valid}`); return valid; } exports2.isExplicitVersion = isExplicitVersion; function evaluateVersions(versions, versionSpec) { let version = ""; - core8.debug(`evaluating ${versions.length} versions`); + core9.debug(`evaluating ${versions.length} versions`); versions = versions.sort((a, b) => { if (semver2.gt(a, b)) { return 1; @@ -22478,9 +22478,9 @@ var require_tool_cache = __commonJS({ } } if (version) { - core8.debug(`matched: ${version}`); + core9.debug(`matched: ${version}`); } else { - core8.debug("match not found"); + core9.debug("match not found"); } return version; } @@ -44905,7 +44905,7 @@ var require_utils4 = __commonJS({ } }; exports2.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(exports2.defaults); - function getOctokitOptions(token, options) { + function getOctokitOptions2(token, options) { const opts = Object.assign({}, options || {}); const auth = Utils.getAuthString(token, opts); if (auth) { @@ -44913,7 +44913,7 @@ var require_utils4 = __commonJS({ } return opts; } - exports2.getOctokitOptions = getOctokitOptions; + exports2.getOctokitOptions = getOctokitOptions2; } }); @@ -44966,7 +44966,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.1", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -45014,26 +45014,24 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^11.1.0" + uuid: "^12.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.34.0", + "@eslint/js": "^9.35.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@octokit/types": "^14.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", - "@types/get-folder-size": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/node": "20.19.9", "@types/node-forge": "^1.3.14", - "@types/semver": "^7.7.0", + "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", esbuild: "^0.25.9", @@ -45066,8 +45064,1579 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" + }, + "brace-expansion@2.0.1": "2.0.2" + } + }; + } +}); + +// node_modules/bottleneck/light.js +var require_light = __commonJS({ + "node_modules/bottleneck/light.js"(exports2, module2) { + (function(global2, factory) { + typeof exports2 === "object" && typeof module2 !== "undefined" ? module2.exports = factory() : typeof define === "function" && define.amd ? define(factory) : global2.Bottleneck = factory(); + })(exports2, (function() { + "use strict"; + var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {}; + function getCjsExportFromNamespace(n) { + return n && n["default"] || n; + } + var load2 = function(received, defaults, onto = {}) { + var k, ref, v; + for (k in defaults) { + v = defaults[k]; + onto[k] = (ref = received[k]) != null ? ref : v; + } + return onto; + }; + var overwrite = function(received, defaults, onto = {}) { + var k, v; + for (k in received) { + v = received[k]; + if (defaults[k] !== void 0) { + onto[k] = v; + } + } + return onto; + }; + var parser = { + load: load2, + overwrite + }; + var DLList; + DLList = class DLList { + constructor(incr, decr) { + this.incr = incr; + this.decr = decr; + this._first = null; + this._last = null; + this.length = 0; + } + push(value) { + var node; + this.length++; + if (typeof this.incr === "function") { + this.incr(); + } + node = { + value, + prev: this._last, + next: null + }; + if (this._last != null) { + this._last.next = node; + this._last = node; + } else { + this._first = this._last = node; + } + return void 0; + } + shift() { + var value; + if (this._first == null) { + return; + } else { + this.length--; + if (typeof this.decr === "function") { + this.decr(); + } + } + value = this._first.value; + if ((this._first = this._first.next) != null) { + this._first.prev = null; + } else { + this._last = null; + } + return value; + } + first() { + if (this._first != null) { + return this._first.value; + } + } + getArray() { + var node, ref, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, ref.value)); + } + return results; + } + forEachShift(cb) { + var node; + node = this.shift(); + while (node != null) { + cb(node), node = this.shift(); + } + return void 0; + } + debug() { + var node, ref, ref1, ref2, results; + node = this._first; + results = []; + while (node != null) { + results.push((ref = node, node = node.next, { + value: ref.value, + prev: (ref1 = ref.prev) != null ? ref1.value : void 0, + next: (ref2 = ref.next) != null ? ref2.value : void 0 + })); + } + return results; + } + }; + var DLList_1 = DLList; + var Events; + Events = class Events { + constructor(instance) { + this.instance = instance; + this._events = {}; + if (this.instance.on != null || this.instance.once != null || this.instance.removeAllListeners != null) { + throw new Error("An Emitter already exists for this object"); + } + this.instance.on = (name, cb) => { + return this._addListener(name, "many", cb); + }; + this.instance.once = (name, cb) => { + return this._addListener(name, "once", cb); + }; + this.instance.removeAllListeners = (name = null) => { + if (name != null) { + return delete this._events[name]; + } else { + return this._events = {}; + } + }; + } + _addListener(name, status, cb) { + var base; + if ((base = this._events)[name] == null) { + base[name] = []; + } + this._events[name].push({ cb, status }); + return this.instance; + } + listenerCount(name) { + if (this._events[name] != null) { + return this._events[name].length; + } else { + return 0; + } + } + async trigger(name, ...args) { + var e, promises; + try { + if (name !== "debug") { + this.trigger("debug", `Event triggered: ${name}`, args); + } + if (this._events[name] == null) { + return; + } + this._events[name] = this._events[name].filter(function(listener) { + return listener.status !== "none"; + }); + promises = this._events[name].map(async (listener) => { + var e2, returned; + if (listener.status === "none") { + return; + } + if (listener.status === "once") { + listener.status = "none"; + } + try { + returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; + if (typeof (returned != null ? returned.then : void 0) === "function") { + return await returned; + } else { + return returned; + } + } catch (error2) { + e2 = error2; + { + this.trigger("error", e2); + } + return null; + } + }); + return (await Promise.all(promises)).find(function(x) { + return x != null; + }); + } catch (error2) { + e = error2; + { + this.trigger("error", e); + } + return null; + } + } + }; + var Events_1 = Events; + var DLList$1, Events$1, Queues; + DLList$1 = DLList_1; + Events$1 = Events_1; + Queues = class Queues { + constructor(num_priorities) { + var i; + this.Events = new Events$1(this); + this._length = 0; + this._lists = (function() { + var j, ref, results; + results = []; + for (i = j = 1, ref = num_priorities; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) { + results.push(new DLList$1((() => { + return this.incr(); + }), (() => { + return this.decr(); + }))); + } + return results; + }).call(this); + } + incr() { + if (this._length++ === 0) { + return this.Events.trigger("leftzero"); + } + } + decr() { + if (--this._length === 0) { + return this.Events.trigger("zero"); + } + } + push(job) { + return this._lists[job.options.priority].push(job); + } + queued(priority) { + if (priority != null) { + return this._lists[priority].length; + } else { + return this._length; + } + } + shiftAll(fn) { + return this._lists.forEach(function(list) { + return list.forEachShift(fn); + }); + } + getFirst(arr = this._lists) { + var j, len, list; + for (j = 0, len = arr.length; j < len; j++) { + list = arr[j]; + if (list.length > 0) { + return list; + } + } + return []; + } + shiftLastFrom(priority) { + return this.getFirst(this._lists.slice(priority).reverse()).shift(); + } + }; + var Queues_1 = Queues; + var BottleneckError; + BottleneckError = class BottleneckError extends Error { + }; + var BottleneckError_1 = BottleneckError; + var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; + NUM_PRIORITIES = 10; + DEFAULT_PRIORITY = 5; + parser$1 = parser; + BottleneckError$1 = BottleneckError_1; + Job = class Job { + constructor(task, args, options, jobDefaults, rejectOnDrop, Events2, _states, Promise2) { + this.task = task; + this.args = args; + this.rejectOnDrop = rejectOnDrop; + this.Events = Events2; + this._states = _states; + this.Promise = Promise2; + this.options = parser$1.load(options, jobDefaults); + this.options.priority = this._sanitizePriority(this.options.priority); + if (this.options.id === jobDefaults.id) { + this.options.id = `${this.options.id}-${this._randomIndex()}`; + } + this.promise = new this.Promise((_resolve, _reject) => { + this._resolve = _resolve; + this._reject = _reject; + }); + this.retryCount = 0; + } + _sanitizePriority(priority) { + var sProperty; + sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; + if (sProperty < 0) { + return 0; + } else if (sProperty > NUM_PRIORITIES - 1) { + return NUM_PRIORITIES - 1; + } else { + return sProperty; + } + } + _randomIndex() { + return Math.random().toString(36).slice(2); + } + doDrop({ error: error2, message = "This job has been dropped by Bottleneck" } = {}) { + if (this._states.remove(this.options.id)) { + if (this.rejectOnDrop) { + this._reject(error2 != null ? error2 : new BottleneckError$1(message)); + } + this.Events.trigger("dropped", { args: this.args, options: this.options, task: this.task, promise: this.promise }); + return true; + } else { + return false; + } + } + _assertStatus(expected) { + var status; + status = this._states.jobStatus(this.options.id); + if (!(status === expected || expected === "DONE" && status === null)) { + throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); + } + } + doReceive() { + this._states.start(this.options.id); + return this.Events.trigger("received", { args: this.args, options: this.options }); + } + doQueue(reachedHWM, blocked) { + this._assertStatus("RECEIVED"); + this._states.next(this.options.id); + return this.Events.trigger("queued", { args: this.args, options: this.options, reachedHWM, blocked }); + } + doRun() { + if (this.retryCount === 0) { + this._assertStatus("QUEUED"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + return this.Events.trigger("scheduled", { args: this.args, options: this.options }); + } + async doExecute(chained, clearGlobalState, run, free) { + var error2, eventInfo, passed; + if (this.retryCount === 0) { + this._assertStatus("RUNNING"); + this._states.next(this.options.id); + } else { + this._assertStatus("EXECUTING"); + } + eventInfo = { args: this.args, options: this.options, retryCount: this.retryCount }; + this.Events.trigger("executing", eventInfo); + try { + passed = await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args)); + if (clearGlobalState()) { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._resolve(passed); + } + } catch (error1) { + error2 = error1; + return this._onFailure(error2, eventInfo, clearGlobalState, run, free); + } + } + doExpire(clearGlobalState, run, free) { + var error2, eventInfo; + if (this._states.jobStatus(this.options.id === "RUNNING")) { + this._states.next(this.options.id); + } + this._assertStatus("EXECUTING"); + eventInfo = { args: this.args, options: this.options, retryCount: this.retryCount }; + error2 = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); + return this._onFailure(error2, eventInfo, clearGlobalState, run, free); + } + async _onFailure(error2, eventInfo, clearGlobalState, run, free) { + var retry3, retryAfter; + if (clearGlobalState()) { + retry3 = await this.Events.trigger("failed", error2, eventInfo); + if (retry3 != null) { + retryAfter = ~~retry3; + this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); + this.retryCount++; + return run(retryAfter); + } else { + this.doDone(eventInfo); + await free(this.options, eventInfo); + this._assertStatus("DONE"); + return this._reject(error2); + } + } + } + doDone(eventInfo) { + this._assertStatus("EXECUTING"); + this._states.next(this.options.id); + return this.Events.trigger("done", eventInfo); + } + }; + var Job_1 = Job; + var BottleneckError$2, LocalDatastore, parser$2; + parser$2 = parser; + BottleneckError$2 = BottleneckError_1; + LocalDatastore = class LocalDatastore { + constructor(instance, storeOptions, storeInstanceOptions) { + this.instance = instance; + this.storeOptions = storeOptions; + this.clientId = this.instance._randomIndex(); + parser$2.load(storeInstanceOptions, storeInstanceOptions, this); + this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); + this._running = 0; + this._done = 0; + this._unblockTime = 0; + this.ready = this.Promise.resolve(); + this.clients = {}; + this._startHeartbeat(); + } + _startHeartbeat() { + var base; + if (this.heartbeat == null && (this.storeOptions.reservoirRefreshInterval != null && this.storeOptions.reservoirRefreshAmount != null || this.storeOptions.reservoirIncreaseInterval != null && this.storeOptions.reservoirIncreaseAmount != null)) { + return typeof (base = this.heartbeat = setInterval(() => { + var amount, incr, maximum, now, reservoir; + now = Date.now(); + if (this.storeOptions.reservoirRefreshInterval != null && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { + this._lastReservoirRefresh = now; + this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; + this.instance._drainAll(this.computeCapacity()); + } + if (this.storeOptions.reservoirIncreaseInterval != null && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { + ({ + reservoirIncreaseAmount: amount, + reservoirIncreaseMaximum: maximum, + reservoir + } = this.storeOptions); + this._lastReservoirIncrease = now; + incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; + if (incr > 0) { + this.storeOptions.reservoir += incr; + return this.instance._drainAll(this.computeCapacity()); + } + } + }, this.heartbeatInterval)).unref === "function" ? base.unref() : void 0; + } else { + return clearInterval(this.heartbeat); + } + } + async __publish__(message) { + await this.yieldLoop(); + return this.instance.Events.trigger("message", message.toString()); + } + async __disconnect__(flush) { + await this.yieldLoop(); + clearInterval(this.heartbeat); + return this.Promise.resolve(); + } + yieldLoop(t = 0) { + return new this.Promise(function(resolve2, reject) { + return setTimeout(resolve2, t); + }); + } + computePenalty() { + var ref; + return (ref = this.storeOptions.penalty) != null ? ref : 15 * this.storeOptions.minTime || 5e3; + } + async __updateSettings__(options) { + await this.yieldLoop(); + parser$2.overwrite(options, options, this.storeOptions); + this._startHeartbeat(); + this.instance._drainAll(this.computeCapacity()); + return true; + } + async __running__() { + await this.yieldLoop(); + return this._running; + } + async __queued__() { + await this.yieldLoop(); + return this.instance.queued(); + } + async __done__() { + await this.yieldLoop(); + return this._done; + } + async __groupCheck__(time) { + await this.yieldLoop(); + return this._nextRequest + this.timeout < time; + } + computeCapacity() { + var maxConcurrent, reservoir; + ({ maxConcurrent, reservoir } = this.storeOptions); + if (maxConcurrent != null && reservoir != null) { + return Math.min(maxConcurrent - this._running, reservoir); + } else if (maxConcurrent != null) { + return maxConcurrent - this._running; + } else if (reservoir != null) { + return reservoir; + } else { + return null; + } + } + conditionsCheck(weight) { + var capacity; + capacity = this.computeCapacity(); + return capacity == null || weight <= capacity; + } + async __incrementReservoir__(incr) { + var reservoir; + await this.yieldLoop(); + reservoir = this.storeOptions.reservoir += incr; + this.instance._drainAll(this.computeCapacity()); + return reservoir; + } + async __currentReservoir__() { + await this.yieldLoop(); + return this.storeOptions.reservoir; + } + isBlocked(now) { + return this._unblockTime >= now; + } + check(weight, now) { + return this.conditionsCheck(weight) && this._nextRequest - now <= 0; + } + async __check__(weight) { + var now; + await this.yieldLoop(); + now = Date.now(); + return this.check(weight, now); + } + async __register__(index, weight, expiration) { + var now, wait; + await this.yieldLoop(); + now = Date.now(); + if (this.conditionsCheck(weight)) { + this._running += weight; + if (this.storeOptions.reservoir != null) { + this.storeOptions.reservoir -= weight; + } + wait = Math.max(this._nextRequest - now, 0); + this._nextRequest = now + wait + this.storeOptions.minTime; + return { + success: true, + wait, + reservoir: this.storeOptions.reservoir + }; + } else { + return { + success: false + }; + } + } + strategyIsBlock() { + return this.storeOptions.strategy === 3; + } + async __submit__(queueLength, weight) { + var blocked, now, reachedHWM; + await this.yieldLoop(); + if (this.storeOptions.maxConcurrent != null && weight > this.storeOptions.maxConcurrent) { + throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); + } + now = Date.now(); + reachedHWM = this.storeOptions.highWater != null && queueLength === this.storeOptions.highWater && !this.check(weight, now); + blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); + if (blocked) { + this._unblockTime = now + this.computePenalty(); + this._nextRequest = this._unblockTime + this.storeOptions.minTime; + this.instance._dropAllQueued(); + } + return { + reachedHWM, + blocked, + strategy: this.storeOptions.strategy + }; + } + async __free__(index, weight) { + await this.yieldLoop(); + this._running -= weight; + this._done += weight; + this.instance._drainAll(this.computeCapacity()); + return { + running: this._running + }; + } + }; + var LocalDatastore_1 = LocalDatastore; + var BottleneckError$3, States; + BottleneckError$3 = BottleneckError_1; + States = class States { + constructor(status1) { + this.status = status1; + this._jobs = {}; + this.counts = this.status.map(function() { + return 0; + }); + } + next(id) { + var current, next; + current = this._jobs[id]; + next = current + 1; + if (current != null && next < this.status.length) { + this.counts[current]--; + this.counts[next]++; + return this._jobs[id]++; + } else if (current != null) { + this.counts[current]--; + return delete this._jobs[id]; + } + } + start(id) { + var initial; + initial = 0; + this._jobs[id] = initial; + return this.counts[initial]++; + } + remove(id) { + var current; + current = this._jobs[id]; + if (current != null) { + this.counts[current]--; + delete this._jobs[id]; + } + return current != null; + } + jobStatus(id) { + var ref; + return (ref = this.status[this._jobs[id]]) != null ? ref : null; + } + statusJobs(status) { + var k, pos, ref, results, v; + if (status != null) { + pos = this.status.indexOf(status); + if (pos < 0) { + throw new BottleneckError$3(`status must be one of ${this.status.join(", ")}`); + } + ref = this._jobs; + results = []; + for (k in ref) { + v = ref[k]; + if (v === pos) { + results.push(k); + } + } + return results; + } else { + return Object.keys(this._jobs); + } + } + statusCounts() { + return this.counts.reduce(((acc, v, i) => { + acc[this.status[i]] = v; + return acc; + }), {}); + } + }; + var States_1 = States; + var DLList$2, Sync; + DLList$2 = DLList_1; + Sync = class Sync { + constructor(name, Promise2) { + this.schedule = this.schedule.bind(this); + this.name = name; + this.Promise = Promise2; + this._running = 0; + this._queue = new DLList$2(); + } + isEmpty() { + return this._queue.length === 0; + } + async _tryToRun() { + var args, cb, error2, reject, resolve2, returned, task; + if (this._running < 1 && this._queue.length > 0) { + this._running++; + ({ task, args, resolve: resolve2, reject } = this._queue.shift()); + cb = await (async function() { + try { + returned = await task(...args); + return function() { + return resolve2(returned); + }; + } catch (error1) { + error2 = error1; + return function() { + return reject(error2); + }; + } + })(); + this._running--; + this._tryToRun(); + return cb(); + } + } + schedule(task, ...args) { + var promise, reject, resolve2; + resolve2 = reject = null; + promise = new this.Promise(function(_resolve, _reject) { + resolve2 = _resolve; + return reject = _reject; + }); + this._queue.push({ task, args, resolve: resolve2, reject }); + this._tryToRun(); + return promise; + } + }; + var Sync_1 = Sync; + var version = "2.19.5"; + var version$1 = { + version + }; + var version$2 = /* @__PURE__ */ Object.freeze({ + version, + default: version$1 + }); + var require$$2 = () => console.log("You must import the full version of Bottleneck in order to use this feature."); + var require$$3 = () => console.log("You must import the full version of Bottleneck in order to use this feature."); + var require$$4 = () => console.log("You must import the full version of Bottleneck in order to use this feature."); + var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; + parser$3 = parser; + Events$2 = Events_1; + RedisConnection$1 = require$$2; + IORedisConnection$1 = require$$3; + Scripts$1 = require$$4; + Group = (function() { + class Group2 { + constructor(limiterOptions = {}) { + this.deleteKey = this.deleteKey.bind(this); + this.limiterOptions = limiterOptions; + parser$3.load(this.limiterOptions, this.defaults, this); + this.Events = new Events$2(this); + this.instances = {}; + this.Bottleneck = Bottleneck_1; + this._startAutoCleanup(); + this.sharedConnection = this.connection != null; + if (this.connection == null) { + if (this.limiterOptions.datastore === "redis") { + this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, { Events: this.Events })); + } else if (this.limiterOptions.datastore === "ioredis") { + this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, { Events: this.Events })); + } + } + } + key(key = "") { + var ref; + return (ref = this.instances[key]) != null ? ref : (() => { + var limiter; + limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { + id: `${this.id}-${key}`, + timeout: this.timeout, + connection: this.connection + })); + this.Events.trigger("created", limiter, key); + return limiter; + })(); + } + async deleteKey(key = "") { + var deleted, instance; + instance = this.instances[key]; + if (this.connection) { + deleted = await this.connection.__runCommand__(["del", ...Scripts$1.allKeys(`${this.id}-${key}`)]); + } + if (instance != null) { + delete this.instances[key]; + await instance.disconnect(); + } + return instance != null || deleted > 0; + } + limiters() { + var k, ref, results, v; + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + results.push({ + key: k, + limiter: v + }); + } + return results; + } + keys() { + return Object.keys(this.instances); + } + async clusterKeys() { + var cursor, end, found, i, k, keys, len, next, start; + if (this.connection == null) { + return this.Promise.resolve(this.keys()); + } + keys = []; + cursor = null; + start = `b_${this.id}-`.length; + end = "_settings".length; + while (cursor !== 0) { + [next, found] = await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 1e4]); + cursor = ~~next; + for (i = 0, len = found.length; i < len; i++) { + k = found[i]; + keys.push(k.slice(start, -end)); + } + } + return keys; + } + _startAutoCleanup() { + var base; + clearInterval(this.interval); + return typeof (base = this.interval = setInterval(async () => { + var e, k, ref, results, time, v; + time = Date.now(); + ref = this.instances; + results = []; + for (k in ref) { + v = ref[k]; + try { + if (await v._store.__groupCheck__(time)) { + results.push(this.deleteKey(k)); + } else { + results.push(void 0); + } + } catch (error2) { + e = error2; + results.push(v.Events.trigger("error", e)); + } + } + return results; + }, this.timeout / 2)).unref === "function" ? base.unref() : void 0; + } + updateSettings(options = {}) { + parser$3.overwrite(options, this.defaults, this); + parser$3.overwrite(options, options, this.limiterOptions); + if (options.timeout != null) { + return this._startAutoCleanup(); + } + } + disconnect(flush = true) { + var ref; + if (!this.sharedConnection) { + return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; + } + } + } + Group2.prototype.defaults = { + timeout: 1e3 * 60 * 5, + connection: null, + Promise, + id: "group-key" + }; + return Group2; + }).call(commonjsGlobal); + var Group_1 = Group; + var Batcher, Events$3, parser$4; + parser$4 = parser; + Events$3 = Events_1; + Batcher = (function() { + class Batcher2 { + constructor(options = {}) { + this.options = options; + parser$4.load(this.options, this.defaults, this); + this.Events = new Events$3(this); + this._arr = []; + this._resetPromise(); + this._lastFlush = Date.now(); + } + _resetPromise() { + return this._promise = new this.Promise((res, rej) => { + return this._resolve = res; + }); + } + _flush() { + clearTimeout(this._timeout); + this._lastFlush = Date.now(); + this._resolve(); + this.Events.trigger("batch", this._arr); + this._arr = []; + return this._resetPromise(); + } + add(data) { + var ret; + this._arr.push(data); + ret = this._promise; + if (this._arr.length === this.maxSize) { + this._flush(); + } else if (this.maxTime != null && this._arr.length === 1) { + this._timeout = setTimeout(() => { + return this._flush(); + }, this.maxTime); + } + return ret; + } + } + Batcher2.prototype.defaults = { + maxTime: null, + maxSize: null, + Promise + }; + return Batcher2; + }).call(commonjsGlobal); + var Batcher_1 = Batcher; + var require$$4$1 = () => console.log("You must import the full version of Bottleneck in order to use this feature."); + var require$$8 = getCjsExportFromNamespace(version$2); + var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, splice = [].splice; + NUM_PRIORITIES$1 = 10; + DEFAULT_PRIORITY$1 = 5; + parser$5 = parser; + Queues$1 = Queues_1; + Job$1 = Job_1; + LocalDatastore$1 = LocalDatastore_1; + RedisDatastore$1 = require$$4$1; + Events$4 = Events_1; + States$1 = States_1; + Sync$1 = Sync_1; + Bottleneck = (function() { + class Bottleneck2 { + constructor(options = {}, ...invalid) { + var storeInstanceOptions, storeOptions; + this._addToQueue = this._addToQueue.bind(this); + this._validateOptions(options, invalid); + parser$5.load(options, this.instanceDefaults, this); + this._queues = new Queues$1(NUM_PRIORITIES$1); + this._scheduled = {}; + this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); + this._limiter = null; + this.Events = new Events$4(this); + this._submitLock = new Sync$1("submit", this.Promise); + this._registerLock = new Sync$1("register", this.Promise); + storeOptions = parser$5.load(options, this.storeDefaults, {}); + this._store = (function() { + if (this.datastore === "redis" || this.datastore === "ioredis" || this.connection != null) { + storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); + return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); + } else if (this.datastore === "local") { + storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); + return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); + } else { + throw new Bottleneck2.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); + } + }).call(this); + this._queues.on("leftzero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; + }); + this._queues.on("zero", () => { + var ref; + return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; + }); + } + _validateOptions(options, invalid) { + if (!(options != null && typeof options === "object" && invalid.length === 0)) { + throw new Bottleneck2.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); + } + } + ready() { + return this._store.ready; + } + clients() { + return this._store.clients; + } + channel() { + return `b_${this.id}`; + } + channel_client() { + return `b_${this.id}_${this._store.clientId}`; + } + publish(message) { + return this._store.__publish__(message); + } + disconnect(flush = true) { + return this._store.__disconnect__(flush); + } + chain(_limiter) { + this._limiter = _limiter; + return this; + } + queued(priority) { + return this._queues.queued(priority); + } + clusterQueued() { + return this._store.__queued__(); + } + empty() { + return this.queued() === 0 && this._submitLock.isEmpty(); + } + running() { + return this._store.__running__(); + } + done() { + return this._store.__done__(); + } + jobStatus(id) { + return this._states.jobStatus(id); + } + jobs(status) { + return this._states.statusJobs(status); + } + counts() { + return this._states.statusCounts(); + } + _randomIndex() { + return Math.random().toString(36).slice(2); + } + check(weight = 1) { + return this._store.__check__(weight); + } + _clearGlobalState(index) { + if (this._scheduled[index] != null) { + clearTimeout(this._scheduled[index].expiration); + delete this._scheduled[index]; + return true; + } else { + return false; + } + } + async _free(index, job, options, eventInfo) { + var e, running; + try { + ({ running } = await this._store.__free__(index, options.weight)); + this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); + if (running === 0 && this.empty()) { + return this.Events.trigger("idle"); + } + } catch (error1) { + e = error1; + return this.Events.trigger("error", e); + } + } + _run(index, job, wait) { + var clearGlobalState, free, run; + job.doRun(); + clearGlobalState = this._clearGlobalState.bind(this, index); + run = this._run.bind(this, index, job); + free = this._free.bind(this, index, job); + return this._scheduled[index] = { + timeout: setTimeout(() => { + return job.doExecute(this._limiter, clearGlobalState, run, free); + }, wait), + expiration: job.options.expiration != null ? setTimeout(function() { + return job.doExpire(clearGlobalState, run, free); + }, wait + job.options.expiration) : void 0, + job + }; + } + _drainOne(capacity) { + return this._registerLock.schedule(() => { + var args, index, next, options, queue; + if (this.queued() === 0) { + return this.Promise.resolve(null); + } + queue = this._queues.getFirst(); + ({ options, args } = next = queue.first()); + if (capacity != null && options.weight > capacity) { + return this.Promise.resolve(null); + } + this.Events.trigger("debug", `Draining ${options.id}`, { args, options }); + index = this._randomIndex(); + return this._store.__register__(index, options.weight, options.expiration).then(({ success, wait, reservoir }) => { + var empty; + this.Events.trigger("debug", `Drained ${options.id}`, { success, args, options }); + if (success) { + queue.shift(); + empty = this.empty(); + if (empty) { + this.Events.trigger("empty"); + } + if (reservoir === 0) { + this.Events.trigger("depleted", empty); + } + this._run(index, next, wait); + return this.Promise.resolve(options.weight); + } else { + return this.Promise.resolve(null); + } + }); + }); + } + _drainAll(capacity, total = 0) { + return this._drainOne(capacity).then((drained) => { + var newCapacity; + if (drained != null) { + newCapacity = capacity != null ? capacity - drained : capacity; + return this._drainAll(newCapacity, total + drained); + } else { + return this.Promise.resolve(total); + } + }).catch((e) => { + return this.Events.trigger("error", e); + }); + } + _dropAllQueued(message) { + return this._queues.shiftAll(function(job) { + return job.doDrop({ message }); + }); + } + stop(options = {}) { + var done, waitForExecuting; + options = parser$5.load(options, this.stopDefaults); + waitForExecuting = (at) => { + var finished; + finished = () => { + var counts; + counts = this._states.counts; + return counts[0] + counts[1] + counts[2] + counts[3] === at; + }; + return new this.Promise((resolve2, reject) => { + if (finished()) { + return resolve2(); + } else { + return this.on("done", () => { + if (finished()) { + this.removeAllListeners("done"); + return resolve2(); + } + }); + } + }); + }; + done = options.dropWaitingJobs ? (this._run = function(index, next) { + return next.doDrop({ + message: options.dropErrorMessage + }); + }, this._drainOne = () => { + return this.Promise.resolve(null); + }, this._registerLock.schedule(() => { + return this._submitLock.schedule(() => { + var k, ref, v; + ref = this._scheduled; + for (k in ref) { + v = ref[k]; + if (this.jobStatus(v.job.options.id) === "RUNNING") { + clearTimeout(v.timeout); + clearTimeout(v.expiration); + v.job.doDrop({ + message: options.dropErrorMessage + }); + } + } + this._dropAllQueued(options.dropErrorMessage); + return waitForExecuting(0); + }); + })) : this.schedule({ + priority: NUM_PRIORITIES$1 - 1, + weight: 0 + }, () => { + return waitForExecuting(1); + }); + this._receive = function(job) { + return job._reject(new Bottleneck2.prototype.BottleneckError(options.enqueueErrorMessage)); + }; + this.stop = () => { + return this.Promise.reject(new Bottleneck2.prototype.BottleneckError("stop() has already been called")); + }; + return done; + } + async _addToQueue(job) { + var args, blocked, error2, options, reachedHWM, shifted, strategy; + ({ args, options } = job); + try { + ({ reachedHWM, blocked, strategy } = await this._store.__submit__(this.queued(), options.weight)); + } catch (error1) { + error2 = error1; + this.Events.trigger("debug", `Could not queue ${options.id}`, { args, options, error: error2 }); + job.doDrop({ error: error2 }); + return false; + } + if (blocked) { + job.doDrop(); + return true; + } else if (reachedHWM) { + shifted = strategy === Bottleneck2.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck2.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck2.prototype.strategy.OVERFLOW ? job : void 0; + if (shifted != null) { + shifted.doDrop(); + } + if (shifted == null || strategy === Bottleneck2.prototype.strategy.OVERFLOW) { + if (shifted == null) { + job.doDrop(); + } + return reachedHWM; + } + } + job.doQueue(reachedHWM, blocked); + this._queues.push(job); + await this._drainAll(); + return reachedHWM; + } + _receive(job) { + if (this._states.jobStatus(job.options.id) != null) { + job._reject(new Bottleneck2.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); + return false; + } else { + job.doReceive(); + return this._submitLock.schedule(this._addToQueue, job); + } + } + submit(...args) { + var cb, fn, job, options, ref, ref1, task; + if (typeof args[0] === "function") { + ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); + options = parser$5.load({}, this.jobDefaults); + } else { + ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); + options = parser$5.load(options, this.jobDefaults); + } + task = (...args2) => { + return new this.Promise(function(resolve2, reject) { + return fn(...args2, function(...args3) { + return (args3[0] != null ? reject : resolve2)(args3); + }); + }); + }; + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + job.promise.then(function(args2) { + return typeof cb === "function" ? cb(...args2) : void 0; + }).catch(function(args2) { + if (Array.isArray(args2)) { + return typeof cb === "function" ? cb(...args2) : void 0; + } else { + return typeof cb === "function" ? cb(args2) : void 0; + } + }); + return this._receive(job); + } + schedule(...args) { + var job, options, task; + if (typeof args[0] === "function") { + [task, ...args] = args; + options = {}; + } else { + [options, task, ...args] = args; + } + job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); + this._receive(job); + return job.promise; + } + wrap(fn) { + var schedule, wrapped; + schedule = this.schedule.bind(this); + wrapped = function(...args) { + return schedule(fn.bind(this), ...args); + }; + wrapped.withOptions = function(options, ...args) { + return schedule(options, fn, ...args); + }; + return wrapped; + } + async updateSettings(options = {}) { + await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); + parser$5.overwrite(options, this.instanceDefaults, this); + return this; + } + currentReservoir() { + return this._store.__currentReservoir__(); + } + incrementReservoir(incr = 0) { + return this._store.__incrementReservoir__(incr); + } } + Bottleneck2.default = Bottleneck2; + Bottleneck2.Events = Events$4; + Bottleneck2.version = Bottleneck2.prototype.version = require$$8.version; + Bottleneck2.strategy = Bottleneck2.prototype.strategy = { + LEAK: 1, + OVERFLOW: 2, + OVERFLOW_PRIORITY: 4, + BLOCK: 3 + }; + Bottleneck2.BottleneckError = Bottleneck2.prototype.BottleneckError = BottleneckError_1; + Bottleneck2.Group = Bottleneck2.prototype.Group = Group_1; + Bottleneck2.RedisConnection = Bottleneck2.prototype.RedisConnection = require$$2; + Bottleneck2.IORedisConnection = Bottleneck2.prototype.IORedisConnection = require$$3; + Bottleneck2.Batcher = Bottleneck2.prototype.Batcher = Batcher_1; + Bottleneck2.prototype.jobDefaults = { + priority: DEFAULT_PRIORITY$1, + weight: 1, + expiration: null, + id: "" + }; + Bottleneck2.prototype.storeDefaults = { + maxConcurrent: null, + minTime: 0, + highWater: null, + strategy: Bottleneck2.prototype.strategy.LEAK, + penalty: null, + reservoir: null, + reservoirRefreshInterval: null, + reservoirRefreshAmount: null, + reservoirIncreaseInterval: null, + reservoirIncreaseAmount: null, + reservoirIncreaseMaximum: null + }; + Bottleneck2.prototype.localStoreDefaults = { + Promise, + timeout: null, + heartbeatInterval: 250 + }; + Bottleneck2.prototype.redisStoreDefaults = { + Promise, + timeout: null, + heartbeatInterval: 5e3, + clientTimeout: 1e4, + Redis: null, + clientOptions: {}, + clusterNodes: null, + clearDatastore: false, + connection: null + }; + Bottleneck2.prototype.instanceDefaults = { + datastore: "local", + connection: null, + id: "", + rejectOnDrop: true, + trackDoneStatus: false, + Promise + }; + Bottleneck2.prototype.stopDefaults = { + enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", + dropWaitingJobs: true, + dropErrorMessage: "This limiter has been stopped." + }; + return Bottleneck2; + }).call(commonjsGlobal); + var Bottleneck_1 = Bottleneck; + var lib = Bottleneck_1; + return lib; + })); + } +}); + +// node_modules/@octokit/plugin-retry/node_modules/@octokit/request-error/dist-node/index.js +var require_dist_node14 = __commonJS({ + "node_modules/@octokit/plugin-retry/node_modules/@octokit/request-error/dist-node/index.js"(exports2, module2) { + "use strict"; + var __create2 = Object.create; + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __getProtoOf2 = Object.getPrototypeOf; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __export = (target, all) => { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); } + return to; + }; + var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var dist_src_exports = {}; + __export(dist_src_exports, { + RequestError: () => RequestError + }); + module2.exports = __toCommonJS(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 RequestError = class extends Error { + constructor(message, statusCode, options) { + super(message); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + this.name = "HttpError"; + this.status = statusCode; + let headers; + if ("headers" in options && typeof options.headers !== "undefined") { + headers = options.headers; + } + if ("response" in options) { + this.response = options.response; + headers = options.response.headers; + } + const requestCopy = Object.assign({}, options.request); + if (options.request.headers.authorization) { + requestCopy.headers = Object.assign({}, options.request.headers, { + authorization: options.request.headers.authorization.replace( + /(? { + for (var name in all) + __defProp2(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var dist_src_exports = {}; + __export(dist_src_exports, { + VERSION: () => VERSION, + retry: () => retry3 + }); + module2.exports = __toCommonJS(dist_src_exports); + var import_core = require_dist_node11(); + async function errorRequest(state, octokit, error2, options) { + if (!error2.request || !error2.request.request) { + throw error2; + } + if (error2.status >= 400 && !state.doNotRetry.includes(error2.status)) { + const retries = options.request.retries != null ? options.request.retries : state.retries; + const retryAfter = Math.pow((options.request.retryCount || 0) + 1, 2); + throw octokit.retry.retryRequest(error2, retries, retryAfter); + } + throw error2; + } + var import_light = __toESM2(require_light()); + 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, info3) { + const maxRetries = ~~error2.request.request.retries; + const after = ~~error2.request.request.retryAfter; + options.request.retryCount = info3.retryCount + 1; + if (maxRetries > info3.retryCount) { + return after * state.retryAfterBaseValue; + } + }); + return limiter.schedule( + requestWithGraphqlErrorHandling.bind(null, state, octokit, request), + options + ); + } + async function requestWithGraphqlErrorHandling(state, octokit, request, options) { + const response = await request(request, options); + 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_error.RequestError(response.data.errors[0].message, 500, { + request: options, + response + }); + return errorRequest(state, octokit, error2, options); + } + return response; + } + var VERSION = "6.1.0"; + function retry3(octokit, octokitOptions) { + const state = Object.assign( + { + enabled: true, + retryAfterBaseValue: 1e3, + doNotRetry: [400, 401, 403, 404, 422, 451], + retries: 3 + }, + octokitOptions.retry + ); + if (state.enabled) { + octokit.hook.error("request", errorRequest.bind(null, state, octokit)); + octokit.hook.wrap("request", wrapRequest.bind(null, state, octokit)); + } + return { + retry: { + retryRequest: (error2, retries, retryAfter) => { + error2.request.request = Object.assign({}, error2.request.request, { + retries, + retryAfter + }); + return error2; + } + } + }; + } + retry3.VERSION = VERSION; + } +}); + +// node_modules/console-log-level/index.js +var require_console_log_level = __commonJS({ + "node_modules/console-log-level/index.js"(exports2, module2) { + "use strict"; + var util = require("util"); + var levels = ["trace", "debug", "info", "warn", "error", "fatal"]; + var noop = function() { + }; + module2.exports = function(opts) { + opts = opts || {}; + opts.level = opts.level || "info"; + var logger = {}; + var shouldLog = function(level) { + return levels.indexOf(level) >= levels.indexOf(opts.level); + }; + levels.forEach(function(level) { + logger[level] = shouldLog(level) ? log : noop; + function log() { + var prefix = opts.prefix; + var normalizedLevel; + if (opts.stderr) { + normalizedLevel = "error"; + } else { + switch (level) { + case "trace": + normalizedLevel = "info"; + break; + case "debug": + normalizedLevel = "info"; + break; + case "fatal": + normalizedLevel = "error"; + break; + default: + normalizedLevel = level; + } + } + if (prefix) { + if (typeof prefix === "function") prefix = prefix(level); + arguments[0] = util.format(prefix, arguments[0]); + } + console[normalizedLevel](util.format.apply(util, arguments)); + } + }); + return logger; }; } }); @@ -45075,7 +46644,7 @@ var require_package = __commonJS({ // src/start-proxy-action.ts var import_child_process = require("child_process"); var path = __toESM(require("path")); -var core7 = __toESM(require_core()); +var core8 = __toESM(require_core()); var toolcache = __toESM(require_tool_cache()); var import_node_forge = __toESM(require_lib2()); @@ -47755,9 +49324,19 @@ async function delay(milliseconds, opts) { function getErrorMessage(error2) { return error2 instanceof Error ? error2.message : String(error2); } +function isDefined(value) { + return value !== void 0 && value !== null; +} // src/actions-util.ts var pkg = require_package(); +var getRequiredInput = function(name) { + const value = core4.getInput(name); + if (!value) { + throw new ConfigurationError(`Input required and not supplied: ${name}`); + } + return value; +}; var getOptionalInput = function(name) { const value = core4.getInput(name); return value.length > 0 ? value : void 0; @@ -47766,6 +49345,9 @@ function getTemporaryDirectory() { const value = process.env["CODEQL_ACTION_TEMP"]; return value !== void 0 && value !== "" ? value : getRequiredEnvParam("RUNNER_TEMP"); } +function getActionVersion() { + return pkg.version; +} var persistedInputsKey = "persisted_inputs"; var persistInputs = function() { const inputEnvironmentVariables = Object.entries(process.env).filter( @@ -47781,7 +49363,38 @@ function getActionsLogger() { } // src/start-proxy.ts +var core7 = __toESM(require_core()); + +// src/api-client.ts var core6 = __toESM(require_core()); +var githubUtils = __toESM(require_utils4()); +var retry = __toESM(require_dist_node15()); +var import_console_log_level = __toESM(require_console_log_level()); +function createApiClientWithDetails(apiDetails, { allowExternal = false } = {}) { + const auth = allowExternal && apiDetails.externalRepoAuth || apiDetails.auth; + const retryingOctokit = githubUtils.GitHub.plugin(retry.retry); + return new retryingOctokit( + githubUtils.getOctokitOptions(auth, { + baseUrl: apiDetails.apiURL, + userAgent: `CodeQL-Action/${getActionVersion()}`, + log: (0, import_console_log_level.default)({ level: "debug" }) + }) + ); +} +function getApiDetails() { + return { + auth: getRequiredInput("token"), + url: getRequiredEnvParam("GITHUB_SERVER_URL"), + apiURL: getRequiredEnvParam("GITHUB_API_URL") + }; +} +function getApiClient() { + return createApiClientWithDetails(getApiDetails()); +} + +// src/defaults.json +var bundleVersion = "codeql-bundle-v2.23.0"; +var cliVersion = "2.23.0"; // src/languages.ts var KnownLanguage = /* @__PURE__ */ ((KnownLanguage2) => { @@ -47799,6 +49412,9 @@ var KnownLanguage = /* @__PURE__ */ ((KnownLanguage2) => { })(KnownLanguage || {}); // src/start-proxy.ts +var UPDATEJOB_PROXY = "update-job-proxy"; +var UPDATEJOB_PROXY_VERSION = "v2.0.20250624110901"; +var UPDATEJOB_PROXY_URL_PREFIX = "https://github.com/github/codeql-action/releases/download/codeql-bundle-v2.22.0/"; var LANGUAGE_ALIASES = { c: "cpp" /* cpp */, "c++": "cpp" /* cpp */, @@ -47819,17 +49435,14 @@ function parseLanguage(language) { return void 0; } var LANGUAGE_TO_REGISTRY_TYPE = { - java: "maven_repository", - csharp: "nuget_feed", - javascript: "npm_registry", - python: "python_index", - ruby: "rubygems_server", - rust: "cargo_registry", - go: "goproxy_server" + java: ["maven_repository"], + csharp: ["nuget_feed"], + javascript: ["npm_registry"], + python: ["python_index"], + ruby: ["rubygems_server"], + rust: ["cargo_registry"], + go: ["goproxy_server", "git_source"] }; -function isDefined(value) { - return value !== void 0 && value !== null; -} function getCredentials(logger, registrySecrets, registriesCredentials, languageString) { const language = languageString ? parseLanguage(languageString) : void 0; const registryTypeForLanguage = language ? LANGUAGE_TO_REGISTRY_TYPE[language] : void 0; @@ -47862,17 +49475,17 @@ function getCredentials(logger, registrySecrets, registriesCredentials, language throw new ConfigurationError("Invalid credentials - must be an object"); } if (isDefined(e.password)) { - core6.setSecret(e.password); + core7.setSecret(e.password); } if (isDefined(e.token)) { - core6.setSecret(e.token); + core7.setSecret(e.token); } if (!isDefined(e.url) && !isDefined(e.host)) { throw new ConfigurationError( "Invalid credentials - must specify host or url" ); } - if (registryTypeForLanguage && e.type !== registryTypeForLanguage) { + if (registryTypeForLanguage && !registryTypeForLanguage.some((t) => t === e.type)) { continue; } const isPrintable2 = (str2) => { @@ -47894,11 +49507,53 @@ function getCredentials(logger, registrySecrets, registriesCredentials, language } return out; } +function getProxyPackage() { + const platform = process.platform === "win32" ? "win64" : process.platform === "darwin" ? "osx64" : "linux64"; + return `${UPDATEJOB_PROXY}-${platform}.tar.gz`; +} +function getFallbackUrl(proxyPackage) { + return `${UPDATEJOB_PROXY_URL_PREFIX}${proxyPackage}`; +} +async function getLinkedRelease() { + return getApiClient().rest.repos.getReleaseByTag({ + owner: "github", + repo: "codeql-action", + tag: bundleVersion + }); +} +async function getDownloadUrl(logger) { + const proxyPackage = getProxyPackage(); + try { + const cliRelease = await getLinkedRelease(); + for (const asset of cliRelease.data.assets) { + if (asset.name === proxyPackage) { + logger.info( + `Found '${proxyPackage}' in release '${bundleVersion}' at '${asset.url}'` + ); + return { + url: asset.url, + // The `update-job-proxy` doesn't have a version as such. Since we now bundle it + // with CodeQL CLI bundle releases, we use the corresponding CLI version to + // differentiate between (potentially) different versions of `update-job-proxy`. + version: cliVersion + }; + } + } + } catch (ex) { + logger.warning( + `Failed to retrieve information about the linked release: ${getErrorMessage(ex)}` + ); + } + logger.info( + `Did not find '${proxyPackage}' in the linked release, falling back to hard-coded version.` + ); + return { + url: getFallbackUrl(proxyPackage), + version: UPDATEJOB_PROXY_VERSION + }; +} // src/start-proxy-action.ts -var UPDATEJOB_PROXY = "update-job-proxy"; -var UPDATEJOB_PROXY_VERSION = "v2.0.20250624110901"; -var UPDATEJOB_PROXY_URL_PREFIX = "https://github.com/github/codeql-action/releases/download/codeql-bundle-v2.22.0/"; var KEY_SIZE = 2048; var KEY_EXPIRY_YEARS = 2; var CERT_SUBJECT = [ @@ -47950,7 +49605,7 @@ async function runWrapper() { const logger = getActionsLogger(); const tempDir = getTemporaryDirectory(); const proxyLogFilePath = path.resolve(tempDir, "proxy.log"); - core7.saveState("proxy-log-file", proxyLogFilePath); + core8.saveState("proxy-log-file", proxyLogFilePath); const credentials = getCredentials( logger, getOptionalInput("registry_secrets"), @@ -47970,7 +49625,7 @@ async function runWrapper() { all_credentials: credentials, ca }; - const proxyBin = await getProxyBinaryPath(); + const proxyBin = await getProxyBinaryPath(logger); await startProxy(proxyBin, proxyConfig, proxyLogFilePath, logger); } async function startProxy(binPath, config, logFilePath, logger) { @@ -47991,7 +49646,7 @@ async function startProxy(binPath, config, logFilePath, logger) { ); subprocess.unref(); if (subprocess.pid) { - core7.saveState("proxy-process-pid", `${subprocess.pid}`); + core8.saveState("proxy-process-pid", `${subprocess.pid}`); } subprocess.on("error", (error2) => { subprocessError = error2; @@ -48010,31 +49665,29 @@ async function startProxy(binPath, config, logFilePath, logger) { throw subprocessError; } logger.info(`Proxy started on ${host}:${port}`); - core7.setOutput("proxy_host", host); - core7.setOutput("proxy_port", port.toString()); - core7.setOutput("proxy_ca_certificate", config.ca.cert); + core8.setOutput("proxy_host", host); + core8.setOutput("proxy_port", port.toString()); + core8.setOutput("proxy_ca_certificate", config.ca.cert); const registry_urls = config.all_credentials.filter((credential) => credential.url !== void 0).map((credential) => ({ type: credential.type, url: credential.url })); - core7.setOutput("proxy_urls", JSON.stringify(registry_urls)); + core8.setOutput("proxy_urls", JSON.stringify(registry_urls)); } catch (error2) { - core7.setFailed(`start-proxy action failed: ${getErrorMessage(error2)}`); + core8.setFailed(`start-proxy action failed: ${getErrorMessage(error2)}`); } } -async function getProxyBinaryPath() { +async function getProxyBinaryPath(logger) { const proxyFileName = process.platform === "win32" ? `${UPDATEJOB_PROXY}.exe` : UPDATEJOB_PROXY; - const platform = process.platform === "win32" ? "win64" : process.platform === "darwin" ? "osx64" : "linux64"; - const proxyPackage = `${UPDATEJOB_PROXY}-${platform}.tar.gz`; - const proxyURL = `${UPDATEJOB_PROXY_URL_PREFIX}${proxyPackage}`; - let proxyBin = toolcache.find(proxyFileName, UPDATEJOB_PROXY_VERSION); + const proxyInfo = await getDownloadUrl(logger); + let proxyBin = toolcache.find(proxyFileName, proxyInfo.version); if (!proxyBin) { - const temp = await toolcache.downloadTool(proxyURL); + const temp = await toolcache.downloadTool(proxyInfo.url); const extracted = await toolcache.extractTar(temp); proxyBin = await toolcache.cacheDir( extracted, proxyFileName, - UPDATEJOB_PROXY_VERSION + proxyInfo.version ); } proxyBin = path.join(proxyBin, proxyFileName); diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 825744e8d4..5401c8cd99 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -21585,7 +21585,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21593,7 +21593,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21605,14 +21605,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21620,12 +21620,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21640,7 +21640,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -22325,7 +22325,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -22333,7 +22333,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -22345,14 +22345,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -22360,12 +22360,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -22380,7 +22380,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -33584,7 +33584,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.1", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -33632,26 +33632,24 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^11.1.0" + uuid: "^12.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.34.0", + "@eslint/js": "^9.35.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@octokit/types": "^14.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", - "@types/get-folder-size": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/node": "20.19.9", "@types/node-forge": "^1.3.14", - "@types/semver": "^7.7.0", + "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", esbuild: "^0.25.9", @@ -33684,7 +33682,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -38969,14 +38968,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -38987,7 +38986,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -84780,10 +84779,7 @@ var require_sarif_schema_2_1_0 = __commonJS({ // src/upload-lib.ts var upload_lib_exports = {}; __export(upload_lib_exports, { - CodeQualityTarget: () => CodeQualityTarget, - CodeScanningTarget: () => CodeScanningTarget, InvalidSarifUploadError: () => InvalidSarifUploadError, - SARIF_UPLOAD_ENDPOINT: () => SARIF_UPLOAD_ENDPOINT, buildPayload: () => buildPayload, findSarifFilesInDir: () => findSarifFilesInDir, getSarifFilePaths: () => getSarifFilePaths, @@ -88898,8 +88894,8 @@ var path8 = __toESM(require("path")); var semver3 = __toESM(require_semver2()); // src/defaults.json -var bundleVersion = "codeql-bundle-v2.22.4"; -var cliVersion = "2.22.4"; +var bundleVersion = "codeql-bundle-v2.23.0"; +var cliVersion = "2.23.0"; // src/overlay-database-utils.ts var fs5 = __toESM(require("fs")); @@ -89119,7 +89115,7 @@ function formatDuration(durationMs) { // src/overlay-database-utils.ts var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; -var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 6e3; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 15e3; var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; async function writeBaseDatabaseOidsFile(config, sourceRoot) { const gitFileOids = await getFileOidsUnderPath(sourceRoot); @@ -89226,6 +89222,12 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["resolve_supported_languages_using_cli" /* ResolveSupportedLanguagesUsingCli */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI", + minimumVersion: void 0, + toolsFeature: "builtinExtractorsSpecifyDefaultQueries" /* BuiltinExtractorsSpecifyDefaultQueries */ + }, ["overlay_analysis" /* OverlayAnalysis */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS", @@ -89342,6 +89344,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_QA_TELEMETRY", legacyApi: true, minimumVersion: void 0 + }, + ["java_minimize_dependency_jars" /* JavaMinimizeDependencyJars */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS", + minimumVersion: "2.23.0" } }; @@ -89367,15 +89374,6 @@ ${jsonContents}` var actionsCache2 = __toESM(require_cache3()); // src/config-utils.ts -var defaultAugmentationProperties = { - queriesInputCombines: false, - packsInputCombines: false, - packsInput: void 0, - queriesInput: void 0, - extraQueryExclusions: [], - overlayDatabaseMode: "none" /* None */, - useOverlayDatabaseCaching: false -}; var OVERLAY_ANALYSIS_FEATURES = { actions: "overlay_analysis_actions" /* OverlayAnalysisActions */, cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, @@ -89417,40 +89415,23 @@ async function getConfig(tempDir, logger) { const configString = fs7.readFileSync(configFile, "utf8"); logger.debug("Loaded config:"); logger.debug(configString); - return JSON.parse(configString); -} -function generateCodeScanningConfig(originalUserInput, augmentationProperties) { - const augmentedConfig = cloneObject(originalUserInput); - if (augmentationProperties.queriesInput) { - if (augmentationProperties.queriesInputCombines) { - augmentedConfig.queries = (augmentedConfig.queries || []).concat( - augmentationProperties.queriesInput - ); - } else { - augmentedConfig.queries = augmentationProperties.queriesInput; - } - } - if (augmentedConfig.queries?.length === 0) { - delete augmentedConfig.queries; + const config = JSON.parse(configString); + if (config.version === void 0) { + throw new ConfigurationError( + `Loaded configuration file, but it does not contain the expected 'version' field.` + ); } - if (augmentationProperties.packsInput) { - if (augmentationProperties.packsInputCombines) { - if (Array.isArray(augmentedConfig.packs)) { - augmentedConfig.packs = (augmentedConfig.packs || []).concat( - augmentationProperties.packsInput - ); - } else if (!augmentedConfig.packs) { - augmentedConfig.packs = augmentationProperties.packsInput; - } else { - const language = Object.keys(augmentedConfig.packs)[0]; - augmentedConfig.packs[language] = augmentedConfig.packs[language].concat(augmentationProperties.packsInput); - } - } else { - augmentedConfig.packs = augmentationProperties.packsInput; - } + if (config.version !== getActionVersion()) { + throw new ConfigurationError( + `Loaded a configuration file for version '${config.version}', but running version '${getActionVersion()}'` + ); } - if (Array.isArray(augmentedConfig.packs) && !augmentedConfig.packs.length) { - delete augmentedConfig.packs; + return config; +} +function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { + const augmentedConfig = cloneObject(cliConfig); + if (extraQueryExclusions.length === 0) { + return augmentedConfig; } augmentedConfig["query-filters"] = [ // Ordering matters. If the first filter is an inclusion, it implicitly @@ -89458,7 +89439,7 @@ function generateCodeScanningConfig(originalUserInput, augmentationProperties) { // it implicitly includes all queries that are not excluded. So user // filters (if any) should always be first to preserve intent. ...augmentedConfig["query-filters"] || [], - ...augmentationProperties.extraQueryExclusions + ...extraQueryExclusions ]; if (augmentedConfig["query-filters"]?.length === 0) { delete augmentedConfig["query-filters"]; @@ -89473,7 +89454,7 @@ var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); var semver7 = __toESM(require_semver2()); -// node_modules/uuid/dist/esm/stringify.js +// node_modules/uuid/dist/stringify.js var byteToHex = []; for (let i = 0; i < 256; ++i) { byteToHex.push((i + 256).toString(16).slice(1)); @@ -89482,27 +89463,24 @@ function unsafeStringify(arr, offset = 0) { return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); } -// node_modules/uuid/dist/esm/rng.js -var import_crypto = require("crypto"); +// node_modules/uuid/dist/rng.js +var import_node_crypto = require("node:crypto"); var rnds8Pool = new Uint8Array(256); var poolPtr = rnds8Pool.length; function rng() { if (poolPtr > rnds8Pool.length - 16) { - (0, import_crypto.randomFillSync)(rnds8Pool); + (0, import_node_crypto.randomFillSync)(rnds8Pool); poolPtr = 0; } return rnds8Pool.slice(poolPtr, poolPtr += 16); } -// node_modules/uuid/dist/esm/native.js -var import_crypto2 = require("crypto"); -var native_default = { randomUUID: import_crypto2.randomUUID }; +// node_modules/uuid/dist/native.js +var import_node_crypto2 = require("node:crypto"); +var native_default = { randomUUID: import_node_crypto2.randomUUID }; -// node_modules/uuid/dist/esm/v4.js -function v4(options, buf, offset) { - if (native_default.randomUUID && !buf && !options) { - return native_default.randomUUID(); - } +// node_modules/uuid/dist/v4.js +function _v4(options, buf, offset) { options = options || {}; const rnds = options.random ?? options.rng?.() ?? rng(); if (rnds.length < 16) { @@ -89522,6 +89500,12 @@ function v4(options, buf, offset) { } return unsafeStringify(rnds); } +function v4(options, buf, offset) { + if (native_default.randomUUID && !buf && !options) { + return native_default.randomUUID(); + } + return _v4(options, buf, offset); +} var v4_default = v4; // src/tar.ts @@ -90435,7 +90419,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { await this.getVersion(), "forceOverwrite" /* ForceOverwrite */ ) ? "--force-overwrite" : "--overwrite"; - const overlayDatabaseMode = config.augmentationProperties.overlayDatabaseMode; + const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode === "overlay" /* Overlay */) { const overlayChangesFile = await writeOverlayChangesFile( config, @@ -90546,13 +90530,16 @@ async function getCodeQLForCmd(cmd, checkVersion) { ); } }, - async betterResolveLanguages() { + async betterResolveLanguages({ + filterToLanguagesWithQueries + } = { filterToLanguagesWithQueries: false }) { const codeqlArgs = [ "resolve", "languages", "--format=betterjson", "--extractor-options-verbosity=4", "--extractor-include-aliases", + ...filterToLanguagesWithQueries ? ["--filter-to-languages-with-queries"] : [], ...getExtraOptionsFromEnv(["resolve", "languages"]) ]; const output = await runCli(cmd, codeqlArgs); @@ -90591,7 +90578,6 @@ ${output}` "run-queries", ...flags, databasePath, - "--intra-layer-parallelism", "--min-disk-free=1024", // Try to leave at least 1GB free "-v", @@ -90849,9 +90835,9 @@ async function runCli(cmd, args = [], opts = {}) { } async function writeCodeScanningConfigFile(config, logger) { const codeScanningConfigFile = getGeneratedCodeScanningConfigPath(config); - const augmentedConfig = generateCodeScanningConfig( - config.originalUserInput, - config.augmentationProperties + const augmentedConfig = appendExtraQueryExclusions( + config.extraQueryExclusions, + config.computedConfig ); logger.info( `Writing augmented user configuration file to ${codeScanningConfigFile}` @@ -92219,7 +92205,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo return JSON.parse(fs13.readFileSync(outputFile, "utf8")); } function populateRunAutomationDetails(sarif, category, analysis_key, environment) { - const automationID = getAutomationID(category, analysis_key, environment); + const automationID = getAutomationID2(category, analysis_key, environment); if (automationID !== void 0) { for (const run of sarif.runs || []) { if (run.automationDetails === void 0) { @@ -92232,7 +92218,7 @@ function populateRunAutomationDetails(sarif, category, analysis_key, environment } return sarif; } -function getAutomationID(category, analysis_key, environment) { +function getAutomationID2(category, analysis_key, environment) { if (category !== void 0) { let automationID = category; if (!automationID.endsWith("/")) { @@ -92242,11 +92228,6 @@ function getAutomationID(category, analysis_key, environment) { } return computeAutomationID(analysis_key, environment); } -var SARIF_UPLOAD_ENDPOINT = /* @__PURE__ */ ((SARIF_UPLOAD_ENDPOINT2) => { - SARIF_UPLOAD_ENDPOINT2["CODE_SCANNING"] = "PUT /repos/:owner/:repo/code-scanning/analysis"; - SARIF_UPLOAD_ENDPOINT2["CODE_QUALITY"] = "PUT /repos/:owner/:repo/code-quality/analysis"; - return SARIF_UPLOAD_ENDPOINT2; -})(SARIF_UPLOAD_ENDPOINT || {}); async function uploadPayload(payload, repositoryNwo, logger, target) { logger.info("Uploading results"); if (isInTestMode()) { @@ -92415,18 +92396,6 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo } return payloadObj; } -var CodeScanningTarget = { - name: "code scanning", - target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), - sentinelPrefix: "CODEQL_UPLOAD_SARIF_" -}; -var CodeQualityTarget = { - name: "code quality", - target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" -}; async function uploadFiles(inputSarifPath, checkoutPath, category, features, logger, uploadTarget) { const sarifPaths = getSarifFilePaths( inputSarifPath, @@ -92441,7 +92410,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log uploadTarget ); } -async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanningTarget) { +async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget) { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); const gitHubVersion = await getGitHubVersion(); @@ -92478,6 +92447,10 @@ async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features validateUniqueCategory(sarif, uploadTarget.sentinelPrefix); logger.debug(`Serializing SARIF for upload`); const sarifPayload = JSON.stringify(sarif); + const dumpDir = process.env["CODEQL_ACTION_SARIF_DUMP_DIR" /* SARIF_DUMP_DIR */]; + if (dumpDir) { + dumpSarifFile(sarifPayload, dumpDir, logger, uploadTarget); + } logger.debug(`Compressing serialized SARIF`); const zippedSarif = import_zlib.default.gzipSync(sarifPayload).toString("base64"); const checkoutURI = url.pathToFileURL(checkoutPath).href; @@ -92516,6 +92489,21 @@ async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features sarifID }; } +function dumpSarifFile(sarifPayload, outputDir, logger, uploadTarget) { + if (!fs13.existsSync(outputDir)) { + fs13.mkdirSync(outputDir, { recursive: true }); + } else if (!fs13.lstatSync(outputDir).isDirectory()) { + throw new ConfigurationError( + `The path specified by the ${"CODEQL_ACTION_SARIF_DUMP_DIR" /* SARIF_DUMP_DIR */} environment variable exists and is not a directory: ${outputDir}` + ); + } + const outputFile = path14.resolve( + outputDir, + `upload${uploadTarget.sarifExtension}` + ); + logger.info(`Dumping processed SARIF file to ${outputFile}`); + fs13.writeFileSync(outputFile, sarifPayload); +} var STATUS_CHECK_FREQUENCY_MILLISECONDS = 5 * 1e3; var STATUS_CHECK_TIMEOUT_MILLISECONDS = 2 * 60 * 1e3; async function waitForProcessing(repositoryNwo, sarifID, logger, options = { @@ -92612,7 +92600,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger assertNever(status); } } -function validateUniqueCategory(sarif, sentinelPrefix = CodeScanningTarget.sentinelPrefix) { +function validateUniqueCategory(sarif, sentinelPrefix) { const categories = {}; for (const run of sarif.runs) { const id = run?.automationDetails?.id; @@ -92669,10 +92657,7 @@ function filterAlertsByDiffRange(logger, sarif) { } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { - CodeQualityTarget, - CodeScanningTarget, InvalidSarifUploadError, - SARIF_UPLOAD_ENDPOINT, buildPayload, findSarifFilesInDir, getSarifFilePaths, diff --git a/lib/upload-sarif-action-post.js b/lib/upload-sarif-action-post.js index 4e569eb512..32b6e23e75 100644 --- a/lib/upload-sarif-action-post.js +++ b/lib/upload-sarif-action-post.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -26438,7 +26438,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.1", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -26486,26 +26486,24 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^11.1.0" + uuid: "^12.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.34.0", + "@eslint/js": "^9.35.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@octokit/types": "^14.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", - "@types/get-folder-size": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/node": "20.19.9", "@types/node-forge": "^1.3.14", - "@types/semver": "^7.7.0", + "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", esbuild: "^0.25.9", @@ -26538,7 +26536,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -35660,14 +35659,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -35678,7 +35677,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -70469,7 +70468,7 @@ var require_brace_expansion = __commonJS({ var isSequence = isNumericSequence || isAlphaSequence; var isOptions = m.body.indexOf(",") >= 0; if (!isSequence && !isOptions) { - if (m.post.match(/,.*\}/)) { + if (m.post.match(/,(?!,).*\}/)) { str2 = m.pre + "{" + m.body + escClose + m.post; return expand(str2); } @@ -95694,7 +95693,7 @@ var require_dist_node16 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -95702,7 +95701,7 @@ var require_dist_node16 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -95712,12 +95711,12 @@ var require_dist_node16 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push(encodeValue(operator, value2, isKeyOperator(operator) ? key : "")); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -95725,12 +95724,12 @@ var require_dist_node16 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -95745,7 +95744,7 @@ var require_dist_node16 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -117321,7 +117320,7 @@ function withGroup(groupName, f) { // src/overlay-database-utils.ts var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; -var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 6e3; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 15e3; var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; // src/tools-features.ts @@ -117372,6 +117371,12 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["resolve_supported_languages_using_cli" /* ResolveSupportedLanguagesUsingCli */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI", + minimumVersion: void 0, + toolsFeature: "builtinExtractorsSpecifyDefaultQueries" /* BuiltinExtractorsSpecifyDefaultQueries */ + }, ["overlay_analysis" /* OverlayAnalysis */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS", @@ -117488,6 +117493,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_QA_TELEMETRY", legacyApi: true, minimumVersion: void 0 + }, + ["java_minimize_dependency_jars" /* JavaMinimizeDependencyJars */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS", + minimumVersion: "2.23.0" } }; @@ -117495,15 +117505,6 @@ var featureConfig = { var actionsCache2 = __toESM(require_cache3()); // src/config-utils.ts -var defaultAugmentationProperties = { - queriesInputCombines: false, - packsInputCombines: false, - packsInput: void 0, - queriesInput: void 0, - extraQueryExclusions: [], - overlayDatabaseMode: "none" /* None */, - useOverlayDatabaseCaching: false -}; var OVERLAY_ANALYSIS_FEATURES = { actions: "overlay_analysis_actions" /* OverlayAnalysisActions */, cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index e785cef377..5fb36a62c4 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -20288,7 +20288,7 @@ var require_dist_node2 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -20296,7 +20296,7 @@ var require_dist_node2 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -20308,14 +20308,14 @@ var require_dist_node2 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -20323,12 +20323,12 @@ var require_dist_node2 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -20343,7 +20343,7 @@ var require_dist_node2 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -21028,7 +21028,7 @@ var require_dist_node6 = __commonJS({ return value; } } - function isDefined(value) { + function isDefined2(value) { return value !== void 0 && value !== null; } function isKeyOperator(operator) { @@ -21036,7 +21036,7 @@ var require_dist_node6 = __commonJS({ } function getValues(context2, operator, key, modifier) { var value = context2[key], result = []; - if (isDefined(value) && value !== "") { + if (isDefined2(value) && value !== "") { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { value = value.toString(); if (modifier && modifier !== "*") { @@ -21048,14 +21048,14 @@ var require_dist_node6 = __commonJS({ } else { if (modifier === "*") { if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { result.push( encodeValue(operator, value2, isKeyOperator(operator) ? key : "") ); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { result.push(encodeValue(operator, value[k], k)); } }); @@ -21063,12 +21063,12 @@ var require_dist_node6 = __commonJS({ } else { const tmp = []; if (Array.isArray(value)) { - value.filter(isDefined).forEach(function(value2) { + value.filter(isDefined2).forEach(function(value2) { tmp.push(encodeValue(operator, value2)); }); } else { Object.keys(value).forEach(function(k) { - if (isDefined(value[k])) { + if (isDefined2(value[k])) { tmp.push(encodeUnreserved(k)); tmp.push(encodeValue(operator, value[k].toString())); } @@ -21083,7 +21083,7 @@ var require_dist_node6 = __commonJS({ } } else { if (operator === ";") { - if (isDefined(value)) { + if (isDefined2(value)) { result.push(encodeUnreserved(key)); } } else if (value === "" && (operator === "&" || operator === "?")) { @@ -32287,7 +32287,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.1", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -32335,26 +32335,24 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^11.1.0" + uuid: "^12.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.34.0", + "@eslint/js": "^9.35.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@octokit/types": "^14.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", - "@types/get-folder-size": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/node": "20.19.9", "@types/node-forge": "^1.3.14", - "@types/semver": "^7.7.0", + "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", esbuild: "^0.25.9", @@ -32387,7 +32385,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -37672,14 +37671,14 @@ var require_typeGuards = __commonJS({ "node_modules/@azure/core-util/dist/commonjs/typeGuards.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.isDefined = isDefined; + exports2.isDefined = isDefined2; exports2.isObjectWithProperties = isObjectWithProperties; exports2.objectHasProperty = objectHasProperty; - function isDefined(thing) { + function isDefined2(thing) { return typeof thing !== "undefined" && thing !== null; } function isObjectWithProperties(thing, properties) { - if (!isDefined(thing) || typeof thing !== "object") { + if (!isDefined2(thing) || typeof thing !== "object") { return false; } for (const property of properties) { @@ -37690,7 +37689,7 @@ var require_typeGuards = __commonJS({ return true; } function objectHasProperty(thing, property) { - return isDefined(thing) && typeof thing === "object" && property in thing; + return isDefined2(thing) && typeof thing === "object" && property in thing; } } }); @@ -88720,6 +88719,30 @@ function fixCodeQualityCategory(logger, category) { return category; } +// src/analyses.ts +var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { + AnalysisKind2["CodeScanning"] = "code-scanning"; + AnalysisKind2["CodeQuality"] = "code-quality"; + return AnalysisKind2; +})(AnalysisKind || {}); +var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); +var CodeScanning = { + kind: "code-scanning" /* CodeScanning */, + name: "code scanning", + target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, + sarifExtension: ".sarif", + sarifPredicate: (name) => name.endsWith(CodeScanning.sarifExtension) && !CodeQuality.sarifPredicate(name), + sentinelPrefix: "CODEQL_UPLOAD_SARIF_" +}; +var CodeQuality = { + kind: "code-quality" /* CodeQuality */, + name: "code quality", + target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, + sarifExtension: ".quality.sarif", + sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), + sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" +}; + // src/api-client.ts var core5 = __toESM(require_core()); var githubUtils = __toESM(require_utils4()); @@ -88862,8 +88885,8 @@ var path8 = __toESM(require("path")); var semver3 = __toESM(require_semver2()); // src/defaults.json -var bundleVersion = "codeql-bundle-v2.22.4"; -var cliVersion = "2.22.4"; +var bundleVersion = "codeql-bundle-v2.23.0"; +var cliVersion = "2.23.0"; // src/overlay-database-utils.ts var fs5 = __toESM(require("fs")); @@ -89086,7 +89109,7 @@ function formatDuration(durationMs) { // src/overlay-database-utils.ts var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; -var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 6e3; +var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 15e3; var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6; async function writeBaseDatabaseOidsFile(config, sourceRoot) { const gitFileOids = await getFileOidsUnderPath(sourceRoot); @@ -89195,6 +89218,12 @@ var featureConfig = { legacyApi: true, minimumVersion: void 0 }, + ["resolve_supported_languages_using_cli" /* ResolveSupportedLanguagesUsingCli */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI", + minimumVersion: void 0, + toolsFeature: "builtinExtractorsSpecifyDefaultQueries" /* BuiltinExtractorsSpecifyDefaultQueries */ + }, ["overlay_analysis" /* OverlayAnalysis */]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS", @@ -89311,6 +89340,11 @@ var featureConfig = { envVar: "CODEQL_ACTION_QA_TELEMETRY", legacyApi: true, minimumVersion: void 0 + }, + ["java_minimize_dependency_jars" /* JavaMinimizeDependencyJars */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS", + minimumVersion: "2.23.0" } }; var FEATURE_FLAGS_FILE_NAME = "cached-feature-flags.json"; @@ -89580,7 +89614,114 @@ var GitHubFeatureFlags = class { // src/status-report.ts var os = __toESM(require("os")); +var core9 = __toESM(require_core()); + +// src/config-utils.ts +var fs8 = __toESM(require("fs")); +var path10 = __toESM(require("path")); +var semver4 = __toESM(require_semver2()); + +// src/caching-utils.ts var core8 = __toESM(require_core()); + +// src/diff-informed-analysis-utils.ts +var fs7 = __toESM(require("fs")); +var path9 = __toESM(require("path")); +function getDiffRangesJsonFilePath() { + return path9.join(getTemporaryDirectory(), "pr-diff-range.json"); +} +function readDiffRangesJsonFile(logger) { + const jsonFilePath = getDiffRangesJsonFilePath(); + if (!fs7.existsSync(jsonFilePath)) { + logger.debug(`Diff ranges JSON file does not exist at ${jsonFilePath}`); + return void 0; + } + const jsonContents = fs7.readFileSync(jsonFilePath, "utf8"); + logger.debug( + `Read pr-diff-range JSON file from ${jsonFilePath}: +${jsonContents}` + ); + return JSON.parse(jsonContents); +} + +// src/trap-caching.ts +var actionsCache2 = __toESM(require_cache3()); + +// src/config-utils.ts +var OVERLAY_ANALYSIS_FEATURES = { + actions: "overlay_analysis_actions" /* OverlayAnalysisActions */, + cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, + csharp: "overlay_analysis_csharp" /* OverlayAnalysisCsharp */, + go: "overlay_analysis_go" /* OverlayAnalysisGo */, + java: "overlay_analysis_java" /* OverlayAnalysisJava */, + javascript: "overlay_analysis_javascript" /* OverlayAnalysisJavascript */, + python: "overlay_analysis_python" /* OverlayAnalysisPython */, + ruby: "overlay_analysis_ruby" /* OverlayAnalysisRuby */, + rust: "overlay_analysis_rust" /* OverlayAnalysisRust */, + swift: "overlay_analysis_swift" /* OverlayAnalysisSwift */ +}; +var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { + actions: "overlay_analysis_code_scanning_actions" /* OverlayAnalysisCodeScanningActions */, + cpp: "overlay_analysis_code_scanning_cpp" /* OverlayAnalysisCodeScanningCpp */, + csharp: "overlay_analysis_code_scanning_csharp" /* OverlayAnalysisCodeScanningCsharp */, + go: "overlay_analysis_code_scanning_go" /* OverlayAnalysisCodeScanningGo */, + java: "overlay_analysis_code_scanning_java" /* OverlayAnalysisCodeScanningJava */, + javascript: "overlay_analysis_code_scanning_javascript" /* OverlayAnalysisCodeScanningJavascript */, + python: "overlay_analysis_code_scanning_python" /* OverlayAnalysisCodeScanningPython */, + ruby: "overlay_analysis_code_scanning_ruby" /* OverlayAnalysisCodeScanningRuby */, + rust: "overlay_analysis_code_scanning_rust" /* OverlayAnalysisCodeScanningRust */, + swift: "overlay_analysis_code_scanning_swift" /* OverlayAnalysisCodeScanningSwift */ +}; +var PACK_IDENTIFIER_PATTERN = (function() { + const alphaNumeric = "[a-z0-9]"; + const alphaNumericDash = "[a-z0-9-]"; + const component = `${alphaNumeric}(${alphaNumericDash}*${alphaNumeric})?`; + return new RegExp(`^${component}/${component}$`); +})(); +function getPathToParsedConfigFile(tempDir) { + return path10.join(tempDir, "config"); +} +async function getConfig(tempDir, logger) { + const configFile = getPathToParsedConfigFile(tempDir); + if (!fs8.existsSync(configFile)) { + return void 0; + } + const configString = fs8.readFileSync(configFile, "utf8"); + logger.debug("Loaded config:"); + logger.debug(configString); + const config = JSON.parse(configString); + if (config.version === void 0) { + throw new ConfigurationError( + `Loaded configuration file, but it does not contain the expected 'version' field.` + ); + } + if (config.version !== getActionVersion()) { + throw new ConfigurationError( + `Loaded a configuration file for version '${config.version}', but running version '${getActionVersion()}'` + ); + } + return config; +} +function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { + const augmentedConfig = cloneObject(cliConfig); + if (extraQueryExclusions.length === 0) { + return augmentedConfig; + } + augmentedConfig["query-filters"] = [ + // Ordering matters. If the first filter is an inclusion, it implicitly + // excludes all queries that are not included. If it is an exclusion, + // it implicitly includes all queries that are not excluded. So user + // filters (if any) should always be first to preserve intent. + ...augmentedConfig["query-filters"] || [], + ...extraQueryExclusions + ]; + if (augmentedConfig["query-filters"]?.length === 0) { + delete augmentedConfig["query-filters"]; + } + return augmentedConfig; +} + +// src/status-report.ts function isFirstPartyAnalysis(actionName) { if (actionName !== "upload-sarif" /* UploadSarif */) { return true; @@ -89599,12 +89740,12 @@ function getActionsStatus(error2, otherFailureCause) { } function setJobStatusIfUnsuccessful(actionStatus) { if (actionStatus === "user-error") { - core8.exportVariable( + core9.exportVariable( "CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, process.env["CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */] ?? "JOB_STATUS_CONFIGURATION_ERROR" /* ConfigErrorStatus */ ); } else if (actionStatus === "failure" || actionStatus === "aborted") { - core8.exportVariable( + core9.exportVariable( "CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */, process.env["CODEQL_ACTION_JOB_STATUS" /* JOB_STATUS */] ?? "JOB_STATUS_FAILURE" /* FailureStatus */ ); @@ -89623,14 +89764,14 @@ async function createStatusReportBase(actionName, status, actionStartedAt, confi let workflowStartedAt = process.env["CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */]; if (workflowStartedAt === void 0) { workflowStartedAt = actionStartedAt.toISOString(); - core8.exportVariable("CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */, workflowStartedAt); + core9.exportVariable("CODEQL_WORKFLOW_STARTED_AT" /* WORKFLOW_STARTED_AT */, workflowStartedAt); } const runnerOs = getRequiredEnvParam("RUNNER_OS"); const codeQlCliVersion = getCachedCodeQlVersion(); const actionRef = process.env["GITHUB_ACTION_REF"] || ""; const testingEnvironment = getTestingEnvironment(); if (testingEnvironment) { - core8.exportVariable("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment); + core9.exportVariable("CODEQL_ACTION_TESTING_ENVIRONMENT" /* TESTING_ENVIRONMENT */, testingEnvironment); } const isSteadyStateDefaultSetupRun = process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true"; const statusReport = { @@ -89708,9 +89849,9 @@ var INCOMPATIBLE_MSG = "CodeQL Action version is incompatible with the code scan async function sendStatusReport(statusReport) { setJobStatusIfUnsuccessful(statusReport.status); const statusReportJSON = JSON.stringify(statusReport); - core8.debug(`Sending status report: ${statusReportJSON}`); + core9.debug(`Sending status report: ${statusReportJSON}`); if (isInTestMode()) { - core8.debug("In test mode. Status reports are not uploaded."); + core9.debug("In test mode. Status reports are not uploaded."); return; } const nwo = getRepositoryNwo(); @@ -89729,26 +89870,26 @@ async function sendStatusReport(statusReport) { switch (e.status) { case 403: if (getWorkflowEventName() === "push" && process.env["GITHUB_ACTOR"] === "dependabot[bot]") { - core8.warning( + 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 { - core8.warning(e.message); + core9.warning(e.message); } return; case 404: - core8.warning(e.message); + core9.warning(e.message); return; case 422: if (getRequiredEnvParam("GITHUB_SERVER_URL") !== GITHUB_DOTCOM_URL) { - core8.debug(INCOMPATIBLE_MSG); + core9.debug(INCOMPATIBLE_MSG); } else { - core8.debug(OUT_OF_DATE_MSG); + core9.debug(OUT_OF_DATE_MSG); } return; } } - core8.warning( + core9.warning( `An unexpected error occurred when sending code scanning status report: ${getErrorMessage( e )}` @@ -90007,145 +90148,6 @@ function wrapCliConfigurationError(cliError) { return new ConfigurationError(errorMessageBuilder); } -// src/config-utils.ts -var fs8 = __toESM(require("fs")); -var path10 = __toESM(require("path")); -var semver4 = __toESM(require_semver2()); - -// src/analyses.ts -var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { - AnalysisKind2["CodeScanning"] = "code-scanning"; - AnalysisKind2["CodeQuality"] = "code-quality"; - return AnalysisKind2; -})(AnalysisKind || {}); -var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); - -// src/caching-utils.ts -var core9 = __toESM(require_core()); - -// src/diff-informed-analysis-utils.ts -var fs7 = __toESM(require("fs")); -var path9 = __toESM(require("path")); -function getDiffRangesJsonFilePath() { - return path9.join(getTemporaryDirectory(), "pr-diff-range.json"); -} -function readDiffRangesJsonFile(logger) { - const jsonFilePath = getDiffRangesJsonFilePath(); - if (!fs7.existsSync(jsonFilePath)) { - logger.debug(`Diff ranges JSON file does not exist at ${jsonFilePath}`); - return void 0; - } - const jsonContents = fs7.readFileSync(jsonFilePath, "utf8"); - logger.debug( - `Read pr-diff-range JSON file from ${jsonFilePath}: -${jsonContents}` - ); - return JSON.parse(jsonContents); -} - -// src/trap-caching.ts -var actionsCache2 = __toESM(require_cache3()); - -// src/config-utils.ts -var defaultAugmentationProperties = { - queriesInputCombines: false, - packsInputCombines: false, - packsInput: void 0, - queriesInput: void 0, - extraQueryExclusions: [], - overlayDatabaseMode: "none" /* None */, - useOverlayDatabaseCaching: false -}; -var OVERLAY_ANALYSIS_FEATURES = { - actions: "overlay_analysis_actions" /* OverlayAnalysisActions */, - cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, - csharp: "overlay_analysis_csharp" /* OverlayAnalysisCsharp */, - go: "overlay_analysis_go" /* OverlayAnalysisGo */, - java: "overlay_analysis_java" /* OverlayAnalysisJava */, - javascript: "overlay_analysis_javascript" /* OverlayAnalysisJavascript */, - python: "overlay_analysis_python" /* OverlayAnalysisPython */, - ruby: "overlay_analysis_ruby" /* OverlayAnalysisRuby */, - rust: "overlay_analysis_rust" /* OverlayAnalysisRust */, - swift: "overlay_analysis_swift" /* OverlayAnalysisSwift */ -}; -var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { - actions: "overlay_analysis_code_scanning_actions" /* OverlayAnalysisCodeScanningActions */, - cpp: "overlay_analysis_code_scanning_cpp" /* OverlayAnalysisCodeScanningCpp */, - csharp: "overlay_analysis_code_scanning_csharp" /* OverlayAnalysisCodeScanningCsharp */, - go: "overlay_analysis_code_scanning_go" /* OverlayAnalysisCodeScanningGo */, - java: "overlay_analysis_code_scanning_java" /* OverlayAnalysisCodeScanningJava */, - javascript: "overlay_analysis_code_scanning_javascript" /* OverlayAnalysisCodeScanningJavascript */, - python: "overlay_analysis_code_scanning_python" /* OverlayAnalysisCodeScanningPython */, - ruby: "overlay_analysis_code_scanning_ruby" /* OverlayAnalysisCodeScanningRuby */, - rust: "overlay_analysis_code_scanning_rust" /* OverlayAnalysisCodeScanningRust */, - swift: "overlay_analysis_code_scanning_swift" /* OverlayAnalysisCodeScanningSwift */ -}; -var PACK_IDENTIFIER_PATTERN = (function() { - const alphaNumeric = "[a-z0-9]"; - const alphaNumericDash = "[a-z0-9-]"; - const component = `${alphaNumeric}(${alphaNumericDash}*${alphaNumeric})?`; - return new RegExp(`^${component}/${component}$`); -})(); -function getPathToParsedConfigFile(tempDir) { - return path10.join(tempDir, "config"); -} -async function getConfig(tempDir, logger) { - const configFile = getPathToParsedConfigFile(tempDir); - if (!fs8.existsSync(configFile)) { - return void 0; - } - const configString = fs8.readFileSync(configFile, "utf8"); - logger.debug("Loaded config:"); - logger.debug(configString); - return JSON.parse(configString); -} -function generateCodeScanningConfig(originalUserInput, augmentationProperties) { - const augmentedConfig = cloneObject(originalUserInput); - if (augmentationProperties.queriesInput) { - if (augmentationProperties.queriesInputCombines) { - augmentedConfig.queries = (augmentedConfig.queries || []).concat( - augmentationProperties.queriesInput - ); - } else { - augmentedConfig.queries = augmentationProperties.queriesInput; - } - } - if (augmentedConfig.queries?.length === 0) { - delete augmentedConfig.queries; - } - if (augmentationProperties.packsInput) { - if (augmentationProperties.packsInputCombines) { - if (Array.isArray(augmentedConfig.packs)) { - augmentedConfig.packs = (augmentedConfig.packs || []).concat( - augmentationProperties.packsInput - ); - } else if (!augmentedConfig.packs) { - augmentedConfig.packs = augmentationProperties.packsInput; - } else { - const language = Object.keys(augmentedConfig.packs)[0]; - augmentedConfig.packs[language] = augmentedConfig.packs[language].concat(augmentationProperties.packsInput); - } - } else { - augmentedConfig.packs = augmentationProperties.packsInput; - } - } - if (Array.isArray(augmentedConfig.packs) && !augmentedConfig.packs.length) { - delete augmentedConfig.packs; - } - augmentedConfig["query-filters"] = [ - // Ordering matters. If the first filter is an inclusion, it implicitly - // excludes all queries that are not included. If it is an exclusion, - // it implicitly includes all queries that are not excluded. So user - // filters (if any) should always be first to preserve intent. - ...augmentedConfig["query-filters"] || [], - ...augmentationProperties.extraQueryExclusions - ]; - if (augmentedConfig["query-filters"]?.length === 0) { - delete augmentedConfig["query-filters"]; - } - return augmentedConfig; -} - // src/setup-codeql.ts var fs11 = __toESM(require("fs")); var path12 = __toESM(require("path")); @@ -90153,7 +90155,7 @@ var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); var semver7 = __toESM(require_semver2()); -// node_modules/uuid/dist/esm/stringify.js +// node_modules/uuid/dist/stringify.js var byteToHex = []; for (let i = 0; i < 256; ++i) { byteToHex.push((i + 256).toString(16).slice(1)); @@ -90162,27 +90164,24 @@ function unsafeStringify(arr, offset = 0) { return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); } -// node_modules/uuid/dist/esm/rng.js -var import_crypto = require("crypto"); +// node_modules/uuid/dist/rng.js +var import_node_crypto = require("node:crypto"); var rnds8Pool = new Uint8Array(256); var poolPtr = rnds8Pool.length; function rng() { if (poolPtr > rnds8Pool.length - 16) { - (0, import_crypto.randomFillSync)(rnds8Pool); + (0, import_node_crypto.randomFillSync)(rnds8Pool); poolPtr = 0; } return rnds8Pool.slice(poolPtr, poolPtr += 16); } -// node_modules/uuid/dist/esm/native.js -var import_crypto2 = require("crypto"); -var native_default = { randomUUID: import_crypto2.randomUUID }; +// node_modules/uuid/dist/native.js +var import_node_crypto2 = require("node:crypto"); +var native_default = { randomUUID: import_node_crypto2.randomUUID }; -// node_modules/uuid/dist/esm/v4.js -function v4(options, buf, offset) { - if (native_default.randomUUID && !buf && !options) { - return native_default.randomUUID(); - } +// node_modules/uuid/dist/v4.js +function _v4(options, buf, offset) { options = options || {}; const rnds = options.random ?? options.rng?.() ?? rng(); if (rnds.length < 16) { @@ -90202,6 +90201,12 @@ function v4(options, buf, offset) { } return unsafeStringify(rnds); } +function v4(options, buf, offset) { + if (native_default.randomUUID && !buf && !options) { + return native_default.randomUUID(); + } + return _v4(options, buf, offset); +} var v4_default = v4; // src/tar.ts @@ -91115,7 +91120,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { await this.getVersion(), "forceOverwrite" /* ForceOverwrite */ ) ? "--force-overwrite" : "--overwrite"; - const overlayDatabaseMode = config.augmentationProperties.overlayDatabaseMode; + const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode === "overlay" /* Overlay */) { const overlayChangesFile = await writeOverlayChangesFile( config, @@ -91226,13 +91231,16 @@ async function getCodeQLForCmd(cmd, checkVersion) { ); } }, - async betterResolveLanguages() { + async betterResolveLanguages({ + filterToLanguagesWithQueries + } = { filterToLanguagesWithQueries: false }) { const codeqlArgs = [ "resolve", "languages", "--format=betterjson", "--extractor-options-verbosity=4", "--extractor-include-aliases", + ...filterToLanguagesWithQueries ? ["--filter-to-languages-with-queries"] : [], ...getExtraOptionsFromEnv(["resolve", "languages"]) ]; const output = await runCli(cmd, codeqlArgs); @@ -91271,7 +91279,6 @@ ${output}` "run-queries", ...flags, databasePath, - "--intra-layer-parallelism", "--min-disk-free=1024", // Try to leave at least 1GB free "-v", @@ -91529,9 +91536,9 @@ async function runCli(cmd, args = [], opts = {}) { } async function writeCodeScanningConfigFile(config, logger) { const codeScanningConfigFile = getGeneratedCodeScanningConfigPath(config); - const augmentedConfig = generateCodeScanningConfig( - config.originalUserInput, - config.augmentationProperties + const augmentedConfig = appendExtraQueryExclusions( + config.extraQueryExclusions, + config.computedConfig ); logger.info( `Writing augmented user configuration file to ${codeScanningConfigFile}` @@ -92899,7 +92906,7 @@ async function combineSarifFilesUsingCLI(sarifFiles, gitHubVersion, features, lo return JSON.parse(fs14.readFileSync(outputFile, "utf8")); } function populateRunAutomationDetails(sarif, category, analysis_key, environment) { - const automationID = getAutomationID(category, analysis_key, environment); + const automationID = getAutomationID2(category, analysis_key, environment); if (automationID !== void 0) { for (const run2 of sarif.runs || []) { if (run2.automationDetails === void 0) { @@ -92912,7 +92919,7 @@ function populateRunAutomationDetails(sarif, category, analysis_key, environment } return sarif; } -function getAutomationID(category, analysis_key, environment) { +function getAutomationID2(category, analysis_key, environment) { if (category !== void 0) { let automationID = category; if (!automationID.endsWith("/")) { @@ -93090,18 +93097,6 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo } return payloadObj; } -var CodeScanningTarget = { - name: "code scanning", - target: "PUT /repos/:owner/:repo/code-scanning/analysis" /* CODE_SCANNING */, - sarifPredicate: (name) => name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), - sentinelPrefix: "CODEQL_UPLOAD_SARIF_" -}; -var CodeQualityTarget = { - name: "code quality", - target: "PUT /repos/:owner/:repo/code-quality/analysis" /* CODE_QUALITY */, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_" -}; async function uploadFiles(inputSarifPath, checkoutPath, category, features, logger, uploadTarget) { const sarifPaths = getSarifFilePaths( inputSarifPath, @@ -93116,7 +93111,7 @@ async function uploadFiles(inputSarifPath, checkoutPath, category, features, log uploadTarget ); } -async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget = CodeScanningTarget) { +async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget) { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); const gitHubVersion = await getGitHubVersion(); @@ -93153,6 +93148,10 @@ async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features validateUniqueCategory(sarif, uploadTarget.sentinelPrefix); logger.debug(`Serializing SARIF for upload`); const sarifPayload = JSON.stringify(sarif); + const dumpDir = process.env["CODEQL_ACTION_SARIF_DUMP_DIR" /* SARIF_DUMP_DIR */]; + if (dumpDir) { + dumpSarifFile(sarifPayload, dumpDir, logger, uploadTarget); + } logger.debug(`Compressing serialized SARIF`); const zippedSarif = import_zlib.default.gzipSync(sarifPayload).toString("base64"); const checkoutURI = url.pathToFileURL(checkoutPath).href; @@ -93191,6 +93190,21 @@ async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features sarifID }; } +function dumpSarifFile(sarifPayload, outputDir, logger, uploadTarget) { + if (!fs14.existsSync(outputDir)) { + fs14.mkdirSync(outputDir, { recursive: true }); + } else if (!fs14.lstatSync(outputDir).isDirectory()) { + throw new ConfigurationError( + `The path specified by the ${"CODEQL_ACTION_SARIF_DUMP_DIR" /* SARIF_DUMP_DIR */} environment variable exists and is not a directory: ${outputDir}` + ); + } + const outputFile = path15.resolve( + outputDir, + `upload${uploadTarget.sarifExtension}` + ); + logger.info(`Dumping processed SARIF file to ${outputFile}`); + fs14.writeFileSync(outputFile, sarifPayload); +} var STATUS_CHECK_FREQUENCY_MILLISECONDS = 5 * 1e3; var STATUS_CHECK_TIMEOUT_MILLISECONDS = 2 * 60 * 1e3; async function waitForProcessing(repositoryNwo, sarifID, logger, options = { @@ -93287,7 +93301,7 @@ function handleProcessingResultForUnsuccessfulExecution(response, status, logger assertNever(status); } } -function validateUniqueCategory(sarif, sentinelPrefix = CodeScanningTarget.sentinelPrefix) { +function validateUniqueCategory(sarif, sentinelPrefix) { const categories = {}; for (const run2 of sarif.runs) { const id = run2?.automationDetails?.id; @@ -93396,13 +93410,13 @@ async function run() { category, features, logger, - CodeScanningTarget + CodeScanning ); core13.setOutput("sarif-id", uploadResult.sarifID); if (fs15.lstatSync(sarifPath).isDirectory()) { const qualitySarifFiles = findSarifFilesInDir( sarifPath, - CodeQualityTarget.sarifPredicate + CodeQuality.sarifPredicate ); if (qualitySarifFiles.length !== 0) { await uploadSpecifiedFiles( @@ -93411,7 +93425,7 @@ async function run() { fixCodeQualityCategory(logger, category), features, logger, - CodeQualityTarget + CodeQuality ); } } diff --git a/package-lock.json b/package-lock.json index b989f2d76f..a10909ccc3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codeql", - "version": "3.30.1", + "version": "3.30.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeql", - "version": "3.30.1", + "version": "3.30.4", "license": "MIT", "dependencies": { "@actions/artifact": "^2.3.1", @@ -34,26 +34,24 @@ "node-forge": "^1.3.1", "octokit": "^5.0.3", "semver": "^7.7.2", - "uuid": "^11.1.0" + "uuid": "^12.0.0" }, "devDependencies": { "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.34.0", + "@eslint/js": "^9.35.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@octokit/types": "^14.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", - "@types/get-folder-size": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/node": "20.19.9", "@types/node-forge": "^1.3.14", - "@types/semver": "^7.7.0", + "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.41.0", "ava": "^6.4.1", "esbuild": "^0.25.9", @@ -1332,9 +1330,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.34.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.34.0.tgz", - "integrity": "sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==", + "version": "9.35.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.35.0.tgz", + "integrity": "sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==", "dev": true, "license": "MIT", "engines": { @@ -2459,16 +2457,6 @@ "@types/node": "*" } }, - "node_modules/@types/get-folder-size": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/get-folder-size/-/get-folder-size-3.0.4.tgz", - "integrity": "sha512-tSf/k7Undx6jKRwpChR9tl+0ZPf0BVwkjBRtJ5qSnz6iWm2ZRYMAS2MktC2u7YaTAFHmxpL/LBxI85M7ioJCSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/js-yaml": { "version": "4.0.9", "dev": true, @@ -2510,10 +2498,11 @@ } }, "node_modules/@types/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==", - "dev": true + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/sinon": { "version": "17.0.4", @@ -2530,23 +2519,18 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/uuid": { - "version": "10.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.41.0.tgz", - "integrity": "sha512-8fz6oa6wEKZrhXWro/S3n2eRJqlRcIa6SlDh59FXJ5Wp5XRZ8B9ixpJDcjadHq47hMx0u+HW6SNa6LjJQ6NLtw==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.43.0.tgz", + "integrity": "sha512-8tg+gt7ENL7KewsKMKDHXR1vm8tt9eMxjJBYINf6swonlWgkYn5NwyIgXpbbDxTNU5DgpDFfj95prcTq2clIQQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.41.0", - "@typescript-eslint/type-utils": "8.41.0", - "@typescript-eslint/utils": "8.41.0", - "@typescript-eslint/visitor-keys": "8.41.0", + "@typescript-eslint/scope-manager": "8.43.0", + "@typescript-eslint/type-utils": "8.43.0", + "@typescript-eslint/utils": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -2560,20 +2544,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.41.0", + "@typescript-eslint/parser": "^8.43.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.41.0.tgz", - "integrity": "sha512-n6m05bXn/Cd6DZDGyrpXrELCPVaTnLdPToyhBoFkLIMznRUQUEQdSp96s/pcWSQdqOhrgR1mzJ+yItK7T+WPMQ==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.43.0.tgz", + "integrity": "sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/visitor-keys": "8.41.0" + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2584,9 +2568,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.41.0.tgz", - "integrity": "sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.43.0.tgz", + "integrity": "sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==", "dev": true, "license": "MIT", "engines": { @@ -2598,16 +2582,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.41.0.tgz", - "integrity": "sha512-D43UwUYJmGhuwHfY7MtNKRZMmfd8+p/eNSfFe6tH5mbVDto+VQCayeAt35rOx3Cs6wxD16DQtIKw/YXxt5E0UQ==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.43.0.tgz", + "integrity": "sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.41.0", - "@typescript-eslint/tsconfig-utils": "8.41.0", - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/visitor-keys": "8.41.0", + "@typescript-eslint/project-service": "8.43.0", + "@typescript-eslint/tsconfig-utils": "8.43.0", + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2627,16 +2611,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.41.0.tgz", - "integrity": "sha512-udbCVstxZ5jiPIXrdH+BZWnPatjlYwJuJkDA4Tbo3WyYLh8NvB+h/bKeSZHDOFKfphsZYJQqaFtLeXEqurQn1A==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.43.0.tgz", + "integrity": "sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.41.0", - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/typescript-estree": "8.41.0" + "@typescript-eslint/scope-manager": "8.43.0", + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/typescript-estree": "8.43.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2651,13 +2635,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.41.0.tgz", - "integrity": "sha512-+GeGMebMCy0elMNg67LRNoVnUFPIm37iu5CmHESVx56/9Jsfdpsvbv605DQ81Pi/x11IdKUsS5nzgTYbCQU9fg==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.43.0.tgz", + "integrity": "sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/types": "8.43.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -2730,16 +2714,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.41.0.tgz", - "integrity": "sha512-gTtSdWX9xiMPA/7MV9STjJOOYtWwIJIYxkQxnSV1U3xcE+mnJSH3f6zI0RYP+ew66WSlZ5ed+h0VCxsvdC1jJg==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.43.0.tgz", + "integrity": "sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.41.0", - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/typescript-estree": "8.41.0", - "@typescript-eslint/visitor-keys": "8.41.0", + "@typescript-eslint/scope-manager": "8.43.0", + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/typescript-estree": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0", "debug": "^4.3.4" }, "engines": { @@ -2755,14 +2739,14 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.41.0.tgz", - "integrity": "sha512-n6m05bXn/Cd6DZDGyrpXrELCPVaTnLdPToyhBoFkLIMznRUQUEQdSp96s/pcWSQdqOhrgR1mzJ+yItK7T+WPMQ==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.43.0.tgz", + "integrity": "sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/visitor-keys": "8.41.0" + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2773,9 +2757,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.41.0.tgz", - "integrity": "sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.43.0.tgz", + "integrity": "sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==", "dev": true, "license": "MIT", "engines": { @@ -2787,16 +2771,16 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.41.0.tgz", - "integrity": "sha512-D43UwUYJmGhuwHfY7MtNKRZMmfd8+p/eNSfFe6tH5mbVDto+VQCayeAt35rOx3Cs6wxD16DQtIKw/YXxt5E0UQ==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.43.0.tgz", + "integrity": "sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.41.0", - "@typescript-eslint/tsconfig-utils": "8.41.0", - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/visitor-keys": "8.41.0", + "@typescript-eslint/project-service": "8.43.0", + "@typescript-eslint/tsconfig-utils": "8.43.0", + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2816,13 +2800,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.41.0.tgz", - "integrity": "sha512-+GeGMebMCy0elMNg67LRNoVnUFPIm37iu5CmHESVx56/9Jsfdpsvbv605DQ81Pi/x11IdKUsS5nzgTYbCQU9fg==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.43.0.tgz", + "integrity": "sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/types": "8.43.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -2886,14 +2870,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.41.0.tgz", - "integrity": "sha512-b8V9SdGBQzQdjJ/IO3eDifGpDBJfvrNTp2QD9P2BeqWTGrRibgfgIlBSw6z3b6R7dPzg752tOs4u/7yCLxksSQ==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.43.0.tgz", + "integrity": "sha512-htB/+D/BIGoNTQYffZw4uM4NzzuolCoaA/BusuSIcC8YjmBYQioew5VUZAYdAETPjeed0hqCaW7EHg+Robq8uw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.41.0", - "@typescript-eslint/types": "^8.41.0", + "@typescript-eslint/tsconfig-utils": "^8.43.0", + "@typescript-eslint/types": "^8.43.0", "debug": "^4.3.4" }, "engines": { @@ -2908,9 +2892,9 @@ } }, "node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.41.0.tgz", - "integrity": "sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.43.0.tgz", + "integrity": "sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==", "dev": true, "license": "MIT", "engines": { @@ -2940,9 +2924,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.41.0.tgz", - "integrity": "sha512-TDhxYFPUYRFxFhuU5hTIJk+auzM/wKvWgoNYOPcOf6i4ReYlOoYN8q1dV5kOTjNQNJgzWN3TUUQMtlLOcUgdUw==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.43.0.tgz", + "integrity": "sha512-ALC2prjZcj2YqqL5X/bwWQmHA2em6/94GcbB/KKu5SX3EBDOsqztmmX1kMkvAJHzxk7TazKzJfFiEIagNV3qEA==", "dev": true, "license": "MIT", "engines": { @@ -2957,15 +2941,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.41.0.tgz", - "integrity": "sha512-63qt1h91vg3KsjVVonFJWjgSK7pZHSQFKH6uwqxAH9bBrsyRhO6ONoKyXxyVBzG1lJnFAJcKAcxLS54N1ee1OQ==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.43.0.tgz", + "integrity": "sha512-qaH1uLBpBuBBuRf8c1mLJ6swOfzCXryhKND04Igr4pckzSEW9JX5Aw9AgW00kwfjWJF0kk0ps9ExKTfvXfw4Qg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/typescript-estree": "8.41.0", - "@typescript-eslint/utils": "8.41.0", + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/typescript-estree": "8.43.0", + "@typescript-eslint/utils": "8.43.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -2982,14 +2966,14 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.41.0.tgz", - "integrity": "sha512-n6m05bXn/Cd6DZDGyrpXrELCPVaTnLdPToyhBoFkLIMznRUQUEQdSp96s/pcWSQdqOhrgR1mzJ+yItK7T+WPMQ==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.43.0.tgz", + "integrity": "sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/visitor-keys": "8.41.0" + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3000,9 +2984,9 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.41.0.tgz", - "integrity": "sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.43.0.tgz", + "integrity": "sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==", "dev": true, "license": "MIT", "engines": { @@ -3014,16 +2998,16 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.41.0.tgz", - "integrity": "sha512-D43UwUYJmGhuwHfY7MtNKRZMmfd8+p/eNSfFe6tH5mbVDto+VQCayeAt35rOx3Cs6wxD16DQtIKw/YXxt5E0UQ==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.43.0.tgz", + "integrity": "sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.41.0", - "@typescript-eslint/tsconfig-utils": "8.41.0", - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/visitor-keys": "8.41.0", + "@typescript-eslint/project-service": "8.43.0", + "@typescript-eslint/tsconfig-utils": "8.43.0", + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -3043,16 +3027,16 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.41.0.tgz", - "integrity": "sha512-udbCVstxZ5jiPIXrdH+BZWnPatjlYwJuJkDA4Tbo3WyYLh8NvB+h/bKeSZHDOFKfphsZYJQqaFtLeXEqurQn1A==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.43.0.tgz", + "integrity": "sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.41.0", - "@typescript-eslint/types": "8.41.0", - "@typescript-eslint/typescript-estree": "8.41.0" + "@typescript-eslint/scope-manager": "8.43.0", + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/typescript-estree": "8.43.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3067,13 +3051,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.41.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.41.0.tgz", - "integrity": "sha512-+GeGMebMCy0elMNg67LRNoVnUFPIm37iu5CmHESVx56/9Jsfdpsvbv605DQ81Pi/x11IdKUsS5nzgTYbCQU9fg==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.43.0.tgz", + "integrity": "sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.41.0", + "@typescript-eslint/types": "8.43.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -3180,9 +3164,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7808,9 +7792,9 @@ } }, "node_modules/readdir-glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -9092,16 +9076,16 @@ "license": "MIT" }, "node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-12.0.0.tgz", + "integrity": "sha512-USe1zesMYh4fjCA8ZH5+X5WIVD0J4V1Jksm1bFTVBX2F/cwSXt0RO5w/3UXbdLKmZX65MiWV+hwhSS8p6oBTGA==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], "license": "MIT", "bin": { - "uuid": "dist/esm/bin/uuid" + "uuid": "dist/bin/uuid" } }, "node_modules/webidl-conversions": { diff --git a/package.json b/package.json index 9db259b1af..e31ada62ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeql", - "version": "3.30.1", + "version": "3.30.4", "private": true, "description": "CodeQL action", "scripts": { @@ -48,26 +48,24 @@ "node-forge": "^1.3.1", "octokit": "^5.0.3", "semver": "^7.7.2", - "uuid": "^11.1.0" + "uuid": "^12.0.0" }, "devDependencies": { "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.34.0", + "@eslint/js": "^9.35.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@octokit/types": "^14.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", - "@types/get-folder-size": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/node": "20.19.9", "@types/node-forge": "^1.3.14", - "@types/semver": "^7.7.0", + "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.41.0", "ava": "^6.4.1", "esbuild": "^0.25.9", @@ -100,6 +98,7 @@ }, "eslint-plugin-jsx-a11y": { "semver": ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } } diff --git a/pr-checks/checks/all-platform-bundle.yml b/pr-checks/checks/all-platform-bundle.yml index d6cbc2c86e..332f129308 100644 --- a/pr-checks/checks/all-platform-bundle.yml +++ b/pr-checks/checks/all-platform-bundle.yml @@ -12,6 +12,5 @@ steps: languages: cpp,csharp,go,java,javascript,python,ruby tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze diff --git a/pr-checks/checks/analyze-ref-input.yml b/pr-checks/checks/analyze-ref-input.yml index 855af1cb02..1814b68083 100644 --- a/pr-checks/checks/analyze-ref-input.yml +++ b/pr-checks/checks/analyze-ref-input.yml @@ -9,7 +9,6 @@ steps: languages: cpp,csharp,java,javascript,python config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze with: diff --git a/pr-checks/checks/autobuild-action.yml b/pr-checks/checks/autobuild-action.yml index 5e0c0ee2a2..ac67a81fef 100644 --- a/pr-checks/checks/autobuild-action.yml +++ b/pr-checks/checks/autobuild-action.yml @@ -17,7 +17,6 @@ steps: CORECLR_PROFILER_PATH_64: "" - uses: ./../action/analyze - name: Check database - shell: bash run: | cd "$RUNNER_TEMP/codeql_databases" if [[ ! -d csharp ]]; then diff --git a/pr-checks/checks/autobuild-direct-tracing-with-working-dir.yml b/pr-checks/checks/autobuild-direct-tracing-with-working-dir.yml index 2cfab107c5..97c832a280 100644 --- a/pr-checks/checks/autobuild-direct-tracing-with-working-dir.yml +++ b/pr-checks/checks/autobuild-direct-tracing-with-working-dir.yml @@ -10,7 +10,6 @@ env: CODEQL_ACTION_AUTOBUILD_BUILD_MODE_DIRECT_TRACING: true steps: - name: Test setup - shell: bash run: | # Make sure that Gradle build succeeds in autobuild-dir ... cp -a ../action/tests/java-repo autobuild-dir @@ -22,7 +21,6 @@ steps: languages: java tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Check that indirect tracing is disabled - shell: bash run: | if [[ ! -z "${CODEQL_RUNNER}" ]]; then echo "Expected indirect tracing to be disabled, but the" \ diff --git a/pr-checks/checks/autobuild-direct-tracing.yml b/pr-checks/checks/autobuild-direct-tracing.yml index 9eb404459f..1e9d2d9002 100644 --- a/pr-checks/checks/autobuild-direct-tracing.yml +++ b/pr-checks/checks/autobuild-direct-tracing.yml @@ -7,7 +7,6 @@ env: CODEQL_ACTION_AUTOBUILD_BUILD_MODE_DIRECT_TRACING: true steps: - name: Set up Java test repo configuration - shell: bash run: | mv * .github ../action/tests/multi-language-repo/ mv ../action/tests/multi-language-repo/.github/workflows .github @@ -22,7 +21,6 @@ steps: tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Check that indirect tracing is disabled - shell: bash run: | if [[ ! -z "${CODEQL_RUNNER}" ]]; then echo "Expected indirect tracing to be disabled, but the" \ diff --git a/pr-checks/checks/build-mode-manual.yml b/pr-checks/checks/build-mode-manual.yml index b7c5012a3e..64009c2eeb 100644 --- a/pr-checks/checks/build-mode-manual.yml +++ b/pr-checks/checks/build-mode-manual.yml @@ -22,7 +22,6 @@ steps: fi - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze diff --git a/pr-checks/checks/cpp-deptrace-disabled.yml b/pr-checks/checks/cpp-deptrace-disabled.yml index 9018352c43..1073d0194a 100644 --- a/pr-checks/checks/cpp-deptrace-disabled.yml +++ b/pr-checks/checks/cpp-deptrace-disabled.yml @@ -6,7 +6,6 @@ env: DOTNET_GENERATE_ASPNET_CERTIFICATE: "false" steps: - name: Test setup - shell: bash run: | cp -a ../action/tests/cpp-autobuild autobuild-dir - uses: ./../action/init @@ -18,8 +17,7 @@ steps: working-directory: autobuild-dir env: CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES: false - - shell: bash - run: | + - run: | if ls /usr/bin/errno; then echo "C/C++ autobuild installed errno, but it should not have since auto-install dependencies is disabled." exit 1 diff --git a/pr-checks/checks/cpp-deptrace-enabled-on-macos.yml b/pr-checks/checks/cpp-deptrace-enabled-on-macos.yml index 33f1416bfc..7180be1724 100644 --- a/pr-checks/checks/cpp-deptrace-enabled-on-macos.yml +++ b/pr-checks/checks/cpp-deptrace-enabled-on-macos.yml @@ -6,7 +6,6 @@ env: DOTNET_GENERATE_ASPNET_CERTIFICATE: "false" steps: - name: Test setup - shell: bash run: | cp -a ../action/tests/cpp-autobuild autobuild-dir - uses: ./../action/init @@ -18,8 +17,7 @@ steps: working-directory: autobuild-dir env: CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES: true - - shell: bash - run: | + - run: | if ! ls /usr/bin/errno; then echo "As expected, CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES is a no-op on macOS" else diff --git a/pr-checks/checks/cpp-deptrace-enabled.yml b/pr-checks/checks/cpp-deptrace-enabled.yml index cad6d12bf7..f92f29d212 100644 --- a/pr-checks/checks/cpp-deptrace-enabled.yml +++ b/pr-checks/checks/cpp-deptrace-enabled.yml @@ -6,7 +6,6 @@ env: DOTNET_GENERATE_ASPNET_CERTIFICATE: "false" steps: - name: Test setup - shell: bash run: | cp -a ../action/tests/cpp-autobuild autobuild-dir - uses: ./../action/init @@ -18,8 +17,7 @@ steps: working-directory: autobuild-dir env: CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES: true - - shell: bash - run: | + - run: | if ! ls /usr/bin/errno; then echo "Did not autoinstall errno" exit 1 diff --git a/pr-checks/checks/diagnostics-export.yml b/pr-checks/checks/diagnostics-export.yml index c4e4f3d458..4324b35a99 100644 --- a/pr-checks/checks/diagnostics-export.yml +++ b/pr-checks/checks/diagnostics-export.yml @@ -10,7 +10,6 @@ steps: languages: javascript tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Add test diagnostics - shell: bash env: CODEQL_PATH: ${{ steps.init.outputs.codeql-path }} run: | diff --git a/pr-checks/checks/export-file-baseline-information.yml b/pr-checks/checks/export-file-baseline-information.yml index 6ba3498839..2eb0e6d525 100644 --- a/pr-checks/checks/export-file-baseline-information.yml +++ b/pr-checks/checks/export-file-baseline-information.yml @@ -11,7 +11,6 @@ steps: languages: javascript tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze with: @@ -23,7 +22,6 @@ steps: path: "${{ runner.temp }}/results/javascript.sarif" retention-days: 7 - name: Check results - shell: bash run: | cd "$RUNNER_TEMP/results" expected_baseline_languages="c csharp go java kotlin javascript python ruby" diff --git a/pr-checks/checks/extractor-ram-threads.yml b/pr-checks/checks/extractor-ram-threads.yml index 4cb1f11668..435c9f41e6 100644 --- a/pr-checks/checks/extractor-ram-threads.yml +++ b/pr-checks/checks/extractor-ram-threads.yml @@ -9,7 +9,6 @@ steps: ram: 230 threads: 1 - name: Assert Results - shell: bash run: | if [ "${CODEQL_RAM}" != "230" ]; then echo "CODEQL_RAM is '${CODEQL_RAM}' instead of 230" diff --git a/pr-checks/checks/go-custom-queries.yml b/pr-checks/checks/go-custom-queries.yml index 922d222de8..ca00fd81a9 100644 --- a/pr-checks/checks/go-custom-queries.yml +++ b/pr-checks/checks/go-custom-queries.yml @@ -16,6 +16,5 @@ steps: config-file: ./.github/codeql/custom-queries.yml tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze diff --git a/pr-checks/checks/go-indirect-tracing-workaround-diagnostic.yml b/pr-checks/checks/go-indirect-tracing-workaround-diagnostic.yml index bfe7afb383..e7cd79185a 100644 --- a/pr-checks/checks/go-indirect-tracing-workaround-diagnostic.yml +++ b/pr-checks/checks/go-indirect-tracing-workaround-diagnostic.yml @@ -16,7 +16,6 @@ steps: with: go-version: "1.20" - name: Build code - shell: bash run: go build main.go - uses: ./../action/analyze with: diff --git a/pr-checks/checks/go-indirect-tracing-workaround-no-file-program.yml b/pr-checks/checks/go-indirect-tracing-workaround-no-file-program.yml index 9db4cad641..3f2fa90b9f 100644 --- a/pr-checks/checks/go-indirect-tracing-workaround-no-file-program.yml +++ b/pr-checks/checks/go-indirect-tracing-workaround-no-file-program.yml @@ -17,7 +17,6 @@ steps: languages: go tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: go build main.go - uses: ./../action/analyze with: diff --git a/pr-checks/checks/go-indirect-tracing-workaround.yml b/pr-checks/checks/go-indirect-tracing-workaround.yml index 192d43bd73..5c6690128f 100644 --- a/pr-checks/checks/go-indirect-tracing-workaround.yml +++ b/pr-checks/checks/go-indirect-tracing-workaround.yml @@ -12,11 +12,9 @@ steps: languages: go tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: go build main.go - uses: ./../action/analyze - - shell: bash - run: | + - run: | if [[ -z "${CODEQL_ACTION_GO_BINARY}" ]]; then echo "Expected the workaround for indirect tracing of static binaries to trigger, but the" \ "CODEQL_ACTION_GO_BINARY environment variable is not set." diff --git a/pr-checks/checks/go-tracing-autobuilder.yml b/pr-checks/checks/go-tracing-autobuilder.yml index f5f8c42a32..d6860bce02 100644 --- a/pr-checks/checks/go-tracing-autobuilder.yml +++ b/pr-checks/checks/go-tracing-autobuilder.yml @@ -12,8 +12,7 @@ steps: tools: ${{ steps.prepare-test.outputs.tools-url }} - uses: ./../action/autobuild - uses: ./../action/analyze - - shell: bash - run: | + - run: | if [[ "${CODEQL_ACTION_DID_AUTOBUILD_GOLANG}" != true ]]; then echo "Expected the Go autobuilder to be run, but the" \ "CODEQL_ACTION_DID_AUTOBUILD_GOLANG environment variable was not true." diff --git a/pr-checks/checks/go-tracing-custom-build-steps.yml b/pr-checks/checks/go-tracing-custom-build-steps.yml index 74d5ee1cfa..9ddc8a87dc 100644 --- a/pr-checks/checks/go-tracing-custom-build-steps.yml +++ b/pr-checks/checks/go-tracing-custom-build-steps.yml @@ -9,11 +9,9 @@ steps: languages: go tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: go build main.go - uses: ./../action/analyze - - shell: bash - run: | + - run: | # Once we start running Bash 4.2 in all environments, we can replace the # `! -z` flag with the more elegant `-v` which confirms that the variable # is actually unset and not potentially set to a blank value. diff --git a/pr-checks/checks/go-tracing-legacy-workflow.yml b/pr-checks/checks/go-tracing-legacy-workflow.yml index 8a6275bc7a..a6b0da17d4 100644 --- a/pr-checks/checks/go-tracing-legacy-workflow.yml +++ b/pr-checks/checks/go-tracing-legacy-workflow.yml @@ -11,8 +11,7 @@ steps: languages: go tools: ${{ steps.prepare-test.outputs.tools-url }} - uses: ./../action/analyze - - shell: bash - run: | + - run: | cd "$RUNNER_TEMP/codeql_databases" if [[ ! -d go ]]; then echo "Did not find a Go database" diff --git a/pr-checks/checks/init-with-registries.yml b/pr-checks/checks/init-with-registries.yml index 8fda36c985..bc45d255aa 100644 --- a/pr-checks/checks/init-with-registries.yml +++ b/pr-checks/checks/init-with-registries.yml @@ -29,7 +29,6 @@ steps: token: "${{ secrets.GITHUB_TOKEN }}" - name: Verify packages installed - shell: bash run: | PRIVATE_PACK="$HOME/.codeql/packages/codeql-testing/private-pack" CODEQL_PACK1="$HOME/.codeql/packages/codeql-testing/codeql-pack1" @@ -51,7 +50,6 @@ steps: fi - name: Verify qlconfig.yml file was created - shell: bash run: | QLCONFIG_PATH=$RUNNER_TEMP/qlconfig.yml echo "Expected qlconfig.yml file to be created at $QLCONFIG_PATH" @@ -66,7 +64,6 @@ steps: - name: Verify contents of qlconfig.yml # yq is not available on windows if: runner.os != 'Windows' - shell: bash run: | QLCONFIG_PATH=$RUNNER_TEMP/qlconfig.yml cat $QLCONFIG_PATH | yq -e '.registries[] | select(.url == "https://ghcr.io/v2/") | select(.packages == "*/*")' diff --git a/pr-checks/checks/javascript-source-root.yml b/pr-checks/checks/javascript-source-root.yml index cbbfa2aa93..9c933576e1 100644 --- a/pr-checks/checks/javascript-source-root.yml +++ b/pr-checks/checks/javascript-source-root.yml @@ -4,7 +4,6 @@ versions: ["linked", "default", "nightly-latest"] # This feature is not compatib operatingSystems: ["ubuntu"] steps: - name: Move codeql-action - shell: bash run: | mkdir ../new-source-root mv * ../new-source-root @@ -17,7 +16,6 @@ steps: with: skip-queries: true - name: Assert database exists - shell: bash run: | cd "$RUNNER_TEMP/codeql_databases" if [[ ! -d javascript ]]; then diff --git a/pr-checks/checks/job-run-uuid-sarif.yml b/pr-checks/checks/job-run-uuid-sarif.yml index c1897cc12f..196e321780 100644 --- a/pr-checks/checks/job-run-uuid-sarif.yml +++ b/pr-checks/checks/job-run-uuid-sarif.yml @@ -18,7 +18,6 @@ steps: path: "${{ runner.temp }}/results/javascript.sarif" retention-days: 7 - name: Check results - shell: bash run: | cd "$RUNNER_TEMP/results" actual=$(jq -r '.runs[0].properties.jobRunUuid' javascript.sarif) diff --git a/pr-checks/checks/multi-language-autodetect.yml b/pr-checks/checks/multi-language-autodetect.yml index e663c4f8f8..a7609240ee 100644 --- a/pr-checks/checks/multi-language-autodetect.yml +++ b/pr-checks/checks/multi-language-autodetect.yml @@ -1,10 +1,11 @@ name: "Multi-language repository" description: "An end-to-end integration test of a multi-language repository using automatic language detection for macOS" operatingSystems: ["macos", "ubuntu"] +env: + CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI: true installGo: true steps: - name: Use Xcode 16 - shell: bash if: runner.os == 'macOS' && matrix.version != 'nightly-latest' run: sudo xcode-select -s "/Applications/Xcode_16.app" @@ -16,7 +17,6 @@ steps: tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze @@ -25,7 +25,6 @@ steps: upload-database: false - name: Check language autodetect for all languages excluding Swift - shell: bash run: | CPP_DB=${{ fromJson(steps.analysis.outputs.db-locations).cpp }} if [[ ! -d $CPP_DB ]] || [[ ! $CPP_DB == ${{ runner.temp }}/customDbLocation/* ]]; then @@ -65,7 +64,6 @@ steps: - name: Check language autodetect for Swift on macOS if: runner.os == 'macOS' - shell: bash run: | SWIFT_DB=${{ fromJson(steps.analysis.outputs.db-locations).swift }} if [[ ! -d $SWIFT_DB ]] || [[ ! $SWIFT_DB == ${{ runner.temp }}/customDbLocation/* ]]; then diff --git a/pr-checks/checks/overlay-init-fallback.yml b/pr-checks/checks/overlay-init-fallback.yml index c8720859a3..44d19d79c3 100644 --- a/pr-checks/checks/overlay-init-fallback.yml +++ b/pr-checks/checks/overlay-init-fallback.yml @@ -14,7 +14,6 @@ steps: with: upload-database: false - name: Check database - shell: bash run: | cd "$RUNNER_TEMP/codeql_databases/actions" if ! grep -q 'overlayBaseDatabase: false' codeql-database.yml ; then diff --git a/pr-checks/checks/packaging-codescanning-config-inputs-js.yml b/pr-checks/checks/packaging-codescanning-config-inputs-js.yml index 73facaf3fb..42710d9261 100644 --- a/pr-checks/checks/packaging-codescanning-config-inputs-js.yml +++ b/pr-checks/checks/packaging-codescanning-config-inputs-js.yml @@ -11,7 +11,6 @@ steps: languages: javascript tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze with: @@ -26,7 +25,6 @@ steps: queries-not-run: foo,bar - name: Assert Results - shell: bash run: | cd "$RUNNER_TEMP/results" # We should have 4 hits from these rules diff --git a/pr-checks/checks/packaging-config-inputs-js.yml b/pr-checks/checks/packaging-config-inputs-js.yml index cc812cd210..41275fd15c 100644 --- a/pr-checks/checks/packaging-config-inputs-js.yml +++ b/pr-checks/checks/packaging-config-inputs-js.yml @@ -11,7 +11,6 @@ steps: languages: javascript tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze with: @@ -26,7 +25,6 @@ steps: queries-not-run: foo,bar - name: Assert Results - shell: bash run: | cd "$RUNNER_TEMP/results" # We should have 4 hits from these rules diff --git a/pr-checks/checks/packaging-config-js.yml b/pr-checks/checks/packaging-config-js.yml index 8e1d70f229..906a3a7d93 100644 --- a/pr-checks/checks/packaging-config-js.yml +++ b/pr-checks/checks/packaging-config-js.yml @@ -10,7 +10,6 @@ steps: languages: javascript tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze with: @@ -25,7 +24,6 @@ steps: queries-not-run: foo,bar - name: Assert Results - shell: bash run: | cd "$RUNNER_TEMP/results" # We should have 4 hits from these rules diff --git a/pr-checks/checks/packaging-inputs-js.yml b/pr-checks/checks/packaging-inputs-js.yml index ee85d7253d..9d9fbe71f8 100644 --- a/pr-checks/checks/packaging-inputs-js.yml +++ b/pr-checks/checks/packaging-inputs-js.yml @@ -11,7 +11,6 @@ steps: packs: codeql-testing/codeql-pack1@1.0.0, codeql-testing/codeql-pack2, codeql-testing/codeql-pack3:other-query.ql tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze with: @@ -25,7 +24,6 @@ steps: queries-not-run: foo,bar - name: Assert Results - shell: bash run: | cd "$RUNNER_TEMP/results" # We should have 4 hits from these rules diff --git a/pr-checks/checks/quality-queries.yml b/pr-checks/checks/quality-queries.yml index 6cf07e2474..9eb578171e 100644 --- a/pr-checks/checks/quality-queries.yml +++ b/pr-checks/checks/quality-queries.yml @@ -1,6 +1,7 @@ name: "Quality queries input" description: "Tests that queries specified in the quality-queries input are used." versions: ["linked", "nightly-latest"] +analysisKinds: ["code-scanning", "code-quality", "code-scanning,code-quality"] env: CHECK_SCRIPT: | const fs = require('fs'); @@ -29,25 +30,30 @@ steps: - uses: ./../action/init with: languages: javascript - quality-queries: code-quality + analysis-kinds: ${{ matrix.analysis-kinds }} tools: ${{ steps.prepare-test.outputs.tools-url }} - uses: ./../action/analyze with: output: "${{ runner.temp }}/results" upload-database: false - name: Upload security SARIF + if: contains(matrix.analysis-kinds, 'code-scanning') uses: actions/upload-artifact@v4 with: - name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.sarif.json + name: | + quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json path: "${{ runner.temp }}/results/javascript.sarif" retention-days: 7 - name: Upload quality SARIF + if: contains(matrix.analysis-kinds, 'code-quality') uses: actions/upload-artifact@v4 with: - name: quality-queries-${{ matrix.os }}-${{ matrix.version }}.quality.sarif.json + name: | + quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.quality.sarif.json path: "${{ runner.temp }}/results/javascript.quality.sarif" retention-days: 7 - name: Check quality query does not appear in security SARIF + if: contains(matrix.analysis-kinds, 'code-scanning') uses: actions/github-script@v7 env: SARIF_PATH: "${{ runner.temp }}/results/javascript.sarif" @@ -55,6 +61,7 @@ steps: with: script: ${{ env.CHECK_SCRIPT }} - name: Check quality query appears in quality SARIF + if: contains(matrix.analysis-kinds, 'code-quality') uses: actions/github-script@v7 env: SARIF_PATH: "${{ runner.temp }}/results/javascript.quality.sarif" diff --git a/pr-checks/checks/remote-config.yml b/pr-checks/checks/remote-config.yml index 8bbe74066d..29629985ab 100644 --- a/pr-checks/checks/remote-config.yml +++ b/pr-checks/checks/remote-config.yml @@ -13,6 +13,5 @@ steps: languages: cpp,csharp,java,javascript,python config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze diff --git a/pr-checks/checks/rubocop-multi-language.yml b/pr-checks/checks/rubocop-multi-language.yml index d350d91aa5..b4439a2d39 100644 --- a/pr-checks/checks/rubocop-multi-language.yml +++ b/pr-checks/checks/rubocop-multi-language.yml @@ -9,13 +9,10 @@ steps: with: ruby-version: 2.6 - name: Install Code Scanning integration - shell: bash run: bundle add code-scanning-rubocop --version 0.3.0 --skip-install - name: Install dependencies - shell: bash run: bundle install - name: RuboCop run - shell: bash run: | bash -c " bundle exec rubocop --require code_scanning --format CodeScanning::SarifFormatter -o rubocop.sarif diff --git a/pr-checks/checks/ruby.yml b/pr-checks/checks/ruby.yml index 9b79eff721..e6208755d9 100644 --- a/pr-checks/checks/ruby.yml +++ b/pr-checks/checks/ruby.yml @@ -12,7 +12,6 @@ steps: with: upload-database: false - name: Check database - shell: bash run: | RUBY_DB="${{ fromJson(steps.analysis.outputs.db-locations).ruby }}" if [[ ! -d "$RUBY_DB" ]]; then diff --git a/pr-checks/checks/rust.yml b/pr-checks/checks/rust.yml index fa014806be..67920538d7 100644 --- a/pr-checks/checks/rust.yml +++ b/pr-checks/checks/rust.yml @@ -19,7 +19,6 @@ steps: with: upload-database: false - name: Check database - shell: bash run: | RUST_DB="${{ fromJson(steps.analysis.outputs.db-locations).rust }}" if [[ ! -d "$RUST_DB" ]]; then diff --git a/pr-checks/checks/split-workflow.yml b/pr-checks/checks/split-workflow.yml index da01c91d9c..fdcf1d5304 100644 --- a/pr-checks/checks/split-workflow.yml +++ b/pr-checks/checks/split-workflow.yml @@ -11,7 +11,6 @@ steps: languages: javascript tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze with: @@ -20,7 +19,6 @@ steps: upload-database: false - name: Assert No Results - shell: bash run: | if [ "$(ls -A $RUNNER_TEMP/results)" ]; then echo "Expected results directory to be empty after skipping query execution!" @@ -31,7 +29,6 @@ steps: output: "${{ runner.temp }}/results" upload-database: false - name: Assert Results - shell: bash run: | cd "$RUNNER_TEMP/results" # We should have 4 hits from these rules diff --git a/pr-checks/checks/swift-autobuild.yml b/pr-checks/checks/swift-autobuild.yml index d7575035fc..a9880149b4 100644 --- a/pr-checks/checks/swift-autobuild.yml +++ b/pr-checks/checks/swift-autobuild.yml @@ -10,7 +10,6 @@ steps: build-mode: autobuild tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Check working directory - shell: bash run: pwd - uses: ./../action/autobuild timeout-minutes: 30 @@ -19,7 +18,6 @@ steps: with: upload-database: false - name: Check database - shell: bash run: | SWIFT_DB="${{ fromJson(steps.analysis.outputs.db-locations).swift }}" if [[ ! -d "$SWIFT_DB" ]]; then diff --git a/pr-checks/checks/swift-custom-build.yml b/pr-checks/checks/swift-custom-build.yml index dc45c56b3f..2ad44ff3b9 100644 --- a/pr-checks/checks/swift-custom-build.yml +++ b/pr-checks/checks/swift-custom-build.yml @@ -7,7 +7,6 @@ env: DOTNET_GENERATE_ASPNET_CERTIFICATE: "false" steps: - name: Use Xcode 16 - shell: bash if: runner.os == 'macOS' && matrix.version != 'nightly-latest' run: sudo xcode-select -s "/Applications/Xcode_16.app" - uses: ./../action/init @@ -16,17 +15,14 @@ steps: languages: swift tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Check working directory - shell: bash run: pwd - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze id: analysis with: upload-database: false - name: Check database - shell: bash run: | SWIFT_DB="${{ fromJson(steps.analysis.outputs.db-locations).swift }}" if [[ ! -d "$SWIFT_DB" ]]; then diff --git a/pr-checks/checks/test-autobuild-working-dir.yml b/pr-checks/checks/test-autobuild-working-dir.yml index 468c4f23e4..eda3677f67 100644 --- a/pr-checks/checks/test-autobuild-working-dir.yml +++ b/pr-checks/checks/test-autobuild-working-dir.yml @@ -4,7 +4,6 @@ versions: ["linked"] operatingSystems: ["ubuntu"] steps: - name: Test setup - shell: bash run: | # Make sure that Gradle build succeeds in autobuild-dir ... cp -a ../action/tests/java-repo autobuild-dir @@ -19,7 +18,6 @@ steps: working-directory: autobuild-dir - uses: ./../action/analyze - name: Check database - shell: bash run: | cd "$RUNNER_TEMP/codeql_databases" if [[ ! -d java ]]; then diff --git a/pr-checks/checks/test-local-codeql.yml b/pr-checks/checks/test-local-codeql.yml index 5345a26c5e..a3c2c6a9c2 100644 --- a/pr-checks/checks/test-local-codeql.yml +++ b/pr-checks/checks/test-local-codeql.yml @@ -5,7 +5,6 @@ operatingSystems: ["ubuntu"] installGo: true steps: - name: Fetch a CodeQL bundle - shell: bash env: CODEQL_URL: ${{ steps.prepare-test.outputs.tools-url }} run: | @@ -17,6 +16,5 @@ steps: languages: cpp,csharp,go,java,javascript,python,ruby tools: ./codeql-bundle-linux64.tar.zst - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze diff --git a/pr-checks/checks/unset-environment.yml b/pr-checks/checks/unset-environment.yml index 705513f4b8..3615db5689 100644 --- a/pr-checks/checks/unset-environment.yml +++ b/pr-checks/checks/unset-environment.yml @@ -15,14 +15,12 @@ steps: languages: cpp,csharp,go,java,javascript,python,ruby tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: env -i PATH="$PATH" HOME="$HOME" ./build.sh - uses: ./../action/analyze id: analysis with: upload-database: false - - shell: bash - run: | + - run: | CPP_DB="${{ fromJson(steps.analysis.outputs.db-locations).cpp }}" if [[ ! -d "$CPP_DB" ]] || [[ ! "$CPP_DB" == "${RUNNER_TEMP}/customDbLocation/cpp" ]]; then echo "::error::Did not create a database for CPP, or created it in the wrong location." \ diff --git a/pr-checks/checks/upload-quality-sarif.yml b/pr-checks/checks/upload-quality-sarif.yml index 019654fa6e..9538505af2 100644 --- a/pr-checks/checks/upload-quality-sarif.yml +++ b/pr-checks/checks/upload-quality-sarif.yml @@ -8,9 +8,8 @@ steps: tools: ${{ steps.prepare-test.outputs.tools-url }} languages: cpp,csharp,java,javascript,python config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }} - quality-queries: code-quality + analysis-kinds: code-scanning,code-quality - name: Build code - shell: bash run: ./build.sh # Generate some SARIF we can upload with the upload-sarif step - uses: ./../action/analyze diff --git a/pr-checks/checks/upload-ref-sha-input.yml b/pr-checks/checks/upload-ref-sha-input.yml index b54651f874..e9307a143f 100644 --- a/pr-checks/checks/upload-ref-sha-input.yml +++ b/pr-checks/checks/upload-ref-sha-input.yml @@ -9,7 +9,6 @@ steps: languages: cpp,csharp,java,javascript,python config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }} - name: Build code - shell: bash run: ./build.sh # Generate some SARIF we can upload with the upload-sarif step - uses: ./../action/analyze diff --git a/pr-checks/checks/with-checkout-path.yml b/pr-checks/checks/with-checkout-path.yml index a25a7e3b94..641dcf2205 100644 --- a/pr-checks/checks/with-checkout-path.yml +++ b/pr-checks/checks/with-checkout-path.yml @@ -5,7 +5,6 @@ installGo: true steps: # This ensures we don't accidentally use the original checkout for any part of the test. - name: Delete original checkout - shell: bash run: | # delete the original checkout so we don't accidentally use it. # Actions does not support deleting the current working directory, so we @@ -26,7 +25,6 @@ steps: source-root: x/y/z/some-path/tests/multi-language-repo - name: Build code - shell: bash working-directory: x/y/z/some-path/tests/multi-language-repo run: | ./build.sh @@ -38,7 +36,6 @@ steps: sha: 474bbf07f9247ffe1856c6a0f94aeeb10e7afee6 - name: Verify SARIF after upload - shell: bash run: | EXPECTED_COMMIT_OID="474bbf07f9247ffe1856c6a0f94aeeb10e7afee6" EXPECTED_REF="v1.1.0" diff --git a/pr-checks/sync.py b/pr-checks/sync.py index beaa943985..8a03822d99 100755 --- a/pr-checks/sync.py +++ b/pr-checks/sync.py @@ -102,6 +102,18 @@ def writeHeader(checkStream): if checkSpecification.get('useAllPlatformBundle'): useAllPlatformBundle = checkSpecification['useAllPlatformBundle'] + + if 'analysisKinds' in checkSpecification: + newMatrix = [] + for matrixInclude in matrix: + for analysisKind in checkSpecification.get('analysisKinds'): + newMatrix.append( + matrixInclude | + { 'analysis-kinds': analysisKind } + ) + matrix = newMatrix + + # Construct the workflow steps needed for this check. steps = [ { 'name': 'Check out repository', @@ -228,7 +240,7 @@ def writeHeader(checkStream): }) raw_file = this_dir.parent / ".github" / "workflows" / f"__{checkName}.yml.raw" - with open(raw_file, 'w') as output_stream: + with open(raw_file, 'w', newline='\n') as output_stream: writeHeader(output_stream) yaml.dump({ 'name': f"PR Check - {checkSpecification['name']}", @@ -251,13 +263,18 @@ def writeHeader(checkStream): 'inputs': workflowInputs } }, + 'defaults': { + 'run': { + 'shell': 'bash', + }, + }, 'jobs': { checkName: checkJob } }, output_stream) with open(raw_file, 'r') as input_stream: - with open(this_dir.parent / ".github" / "workflows" / f"__{checkName}.yml", 'w') as output_stream: + with open(this_dir.parent / ".github" / "workflows" / f"__{checkName}.yml", 'w', newline='\n') as output_stream: content = input_stream.read() output_stream.write("\n".join(list(map(lambda x:x.rstrip(), content.splitlines()))+[''])) os.remove(raw_file) @@ -311,7 +328,7 @@ def writeHeader(checkStream): }, output_stream) with open(raw_file, 'r') as input_stream: - with open(this_dir.parent / ".github" / "workflows" / f"__{collection_name}.yml", 'w') as output_stream: + with open(this_dir.parent / ".github" / "workflows" / f"__{collection_name}.yml", 'w', newline='\n') as output_stream: content = input_stream.read() output_stream.write("\n".join(list(map(lambda x:x.rstrip(), content.splitlines()))+[''])) os.remove(raw_file) diff --git a/pr-checks/sync.sh b/pr-checks/sync.sh index 016e509399..85df3272ce 100755 --- a/pr-checks/sync.sh +++ b/pr-checks/sync.sh @@ -3,7 +3,7 @@ set -e cd "$(dirname "$0")" python3 -m venv env -source env/bin/activate +source env/*/activate pip3 install ruamel.yaml==0.17.31 python3 sync.py diff --git a/src/analyses.ts b/src/analyses.ts index e80cdfb20e..8d8cd1d616 100644 --- a/src/analyses.ts +++ b/src/analyses.ts @@ -41,3 +41,48 @@ export async function parseAnalysisKinds( /** The queries to use for Code Quality analyses. */ export const codeQualityQueries: string[] = ["code-quality"]; + +// Enumerates API endpoints that accept SARIF files. +export enum SARIF_UPLOAD_ENDPOINT { + CODE_SCANNING = "PUT /repos/:owner/:repo/code-scanning/analysis", + CODE_QUALITY = "PUT /repos/:owner/:repo/code-quality/analysis", +} + +// Represents configurations for different analysis kinds. +export interface AnalysisConfig { + /** The analysis kind the configuration is for. */ + kind: AnalysisKind; + /** A display friendly name for logs. */ + name: string; + /** The API endpoint to upload SARIF files to. */ + target: SARIF_UPLOAD_ENDPOINT; + /** The file extension for SARIF files generated by this kind of analysis. */ + sarifExtension: string; + /** A predicate on filenames to decide whether a SARIF file + * belongs to this kind of analysis. */ + sarifPredicate: (name: string) => boolean; + /** A prefix for environment variables used to track the uniqueness of SARIF uploads. */ + sentinelPrefix: string; +} + +// Represents the Code Scanning analysis configuration. +export const CodeScanning: AnalysisConfig = { + kind: AnalysisKind.CodeScanning, + name: "code scanning", + target: SARIF_UPLOAD_ENDPOINT.CODE_SCANNING, + sarifExtension: ".sarif", + sarifPredicate: (name) => + name.endsWith(CodeScanning.sarifExtension) && + !CodeQuality.sarifPredicate(name), + sentinelPrefix: "CODEQL_UPLOAD_SARIF_", +}; + +// Represents the Code Quality analysis configuration. +export const CodeQuality: AnalysisConfig = { + kind: AnalysisKind.CodeQuality, + name: "code quality", + target: SARIF_UPLOAD_ENDPOINT.CODE_QUALITY, + sarifExtension: ".quality.sarif", + sarifPredicate: (name) => name.endsWith(CodeQuality.sarifExtension), + sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", +}; diff --git a/src/analyze-action.ts b/src/analyze-action.ts index 87af6fcca7..31251be488 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -5,6 +5,7 @@ import { performance } from "perf_hooks"; import * as core from "@actions/core"; import * as actionsUtil from "./actions-util"; +import * as analyses from "./analyses"; import { CodeQLAnalysisError, dbIsFinalized, @@ -18,12 +19,17 @@ import { getApiDetails, getGitHubVersion } from "./api-client"; import { runAutobuild } from "./autobuild"; import { getTotalCacheSize, shouldStoreCache } from "./caching-utils"; import { getCodeQL } from "./codeql"; -import { Config, getConfig, isCodeQualityEnabled } from "./config-utils"; +import { + Config, + getConfig, + isCodeQualityEnabled, + isCodeScanningEnabled, +} from "./config-utils"; import { uploadDatabases } from "./database-upload"; import { uploadDependencyCaches } from "./dependency-caching"; import { getDiffInformedAnalysisBranches } from "./diff-informed-analysis-utils"; import { EnvVar } from "./environment"; -import { Features } from "./feature-flags"; +import { Feature, Features } from "./feature-flags"; import { KnownLanguage } from "./languages"; import { getActionsLogger, Logger } from "./logging"; import { uploadOverlayBaseDatabaseToCache } from "./overlay-database-utils"; @@ -326,15 +332,17 @@ async function run() { core.setOutput("sarif-output", path.resolve(outputDir)); const uploadInput = actionsUtil.getOptionalInput("upload"); if (runStats && actionsUtil.getUploadValue(uploadInput) === "always") { - uploadResult = await uploadLib.uploadFiles( - outputDir, - actionsUtil.getRequiredInput("checkout_path"), - actionsUtil.getOptionalInput("category"), - features, - logger, - uploadLib.CodeScanningTarget, - ); - core.setOutput("sarif-id", uploadResult.sarifID); + if (isCodeScanningEnabled(config)) { + uploadResult = await uploadLib.uploadFiles( + outputDir, + actionsUtil.getRequiredInput("checkout_path"), + actionsUtil.getOptionalInput("category"), + features, + logger, + analyses.CodeScanning, + ); + core.setOutput("sarif-id", uploadResult.sarifID); + } if (isCodeQualityEnabled(config)) { const qualityUploadResult = await uploadLib.uploadFiles( @@ -346,7 +354,7 @@ async function run() { ), features, logger, - uploadLib.CodeQualityTarget, + analyses.CodeQuality, ); core.setOutput("quality-sarif-id", qualityUploadResult.sarifID); } @@ -376,7 +384,11 @@ async function run() { // Store dependency cache(s) if dependency caching is enabled. if (shouldStoreCache(config.dependencyCachingEnabled)) { - await uploadDependencyCaches(config, logger); + const minimizeJavaJars = await features.getValue( + Feature.JavaMinimizeDependencyJars, + codeql, + ); + await uploadDependencyCaches(config, logger, minimizeJavaJars); } // We don't upload results in test mode, so don't wait for processing diff --git a/src/analyze.test.ts b/src/analyze.test.ts index e957b73843..305d41d241 100644 --- a/src/analyze.test.ts +++ b/src/analyze.test.ts @@ -5,11 +5,13 @@ import test from "ava"; import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; +import { CodeQuality, CodeScanning } from "./analyses"; import { exportedForTesting, runQueries, defaultSuites, resolveQuerySuiteAlias, + addSarifExtension, } from "./analyze"; import { createStubCodeQL } from "./codeql"; import { Feature } from "./feature-flags"; @@ -348,3 +350,13 @@ test("resolveQuerySuiteAlias", (t) => { t.deepEqual(resolveQuerySuiteAlias(KnownLanguage.go, name), name); } }); + +test("addSarifExtension", (t) => { + for (const language of Object.values(KnownLanguage)) { + t.deepEqual(addSarifExtension(CodeScanning, language), `${language}.sarif`); + t.deepEqual( + addSarifExtension(CodeQuality, language), + `${language}.quality.sarif`, + ); + } +}); diff --git a/src/analyze.ts b/src/analyze.ts index 19bfcf028f..b22e9c23da 100644 --- a/src/analyze.ts +++ b/src/analyze.ts @@ -608,6 +608,16 @@ export function resolveQuerySuiteAlias( return maybeSuite; } +/** + * Adds the appropriate file extension for the given analysis configuration to the given base filename. + */ +export function addSarifExtension( + analysis: analyses.AnalysisConfig, + base: string, +): string { + return `${base}${analysis.sarifExtension}`; +} + // Runs queries and creates sarif files in the given folder export async function runQueries( sarifFolder: string, @@ -626,10 +636,7 @@ export async function runQueries( const incrementalMode: string[] = []; // Preserve cached intermediate results for overlay-base databases. - if ( - config.augmentationProperties.overlayDatabaseMode !== - OverlayDatabaseMode.OverlayBase - ) { + if (config.overlayDatabaseMode !== OverlayDatabaseMode.OverlayBase) { queryFlags.push("--expect-discarded-cache"); } @@ -641,15 +648,10 @@ export async function runQueries( } statusReport.analysis_is_overlay = - config.augmentationProperties.overlayDatabaseMode === - OverlayDatabaseMode.Overlay; + config.overlayDatabaseMode === OverlayDatabaseMode.Overlay; statusReport.analysis_builds_overlay_base_database = - config.augmentationProperties.overlayDatabaseMode === - OverlayDatabaseMode.OverlayBase; - if ( - config.augmentationProperties.overlayDatabaseMode === - OverlayDatabaseMode.Overlay - ) { + config.overlayDatabaseMode === OverlayDatabaseMode.OverlayBase; + if (config.overlayDatabaseMode === OverlayDatabaseMode.Overlay) { incrementalMode.push("overlay"); } @@ -658,15 +660,25 @@ export async function runQueries( ? `--sarif-run-property=incrementalMode=${incrementalMode.join(",")}` : undefined; + const dbAnalysisConfig = configUtils.getPrimaryAnalysisConfig(config); + for (const language of config.languages) { try { - const sarifFile = path.join(sarifFolder, `${language}.sarif`); - + // This should be empty to run only the query suite that was generated when + // the database was initialised. const queries: string[] = []; - if (configUtils.isCodeQualityEnabled(config)) { + + // If multiple analysis kinds are enabled, the database is initialised for Code Scanning. + // To avoid duplicate work, we want to run queries for all analyses at the same time. + // To do this, we invoke `run-queries` once with the generated query suite that was created + // when the database was initialised + the queries for other analysis kinds. + if (config.analysisKinds.length > 1) { queries.push(util.getGeneratedSuitePath(config, language)); - for (const qualityQuery of analyses.codeQualityQueries) { - queries.push(resolveQuerySuiteAlias(language, qualityQuery)); + + if (configUtils.isCodeQualityEnabled(config)) { + for (const qualityQuery of analyses.codeQualityQueries) { + queries.push(resolveQuerySuiteAlias(language, qualityQuery)); + } } } @@ -684,48 +696,49 @@ export async function runQueries( statusReport[`analyze_builtin_queries_${language}_duration_ms`] = new Date().getTime() - startTimeRunQueries; - logger.startGroup(`Interpreting results for ${language}`); + // There is always at least one analysis kind enabled. Running `interpret-results` + // produces the SARIF file for the analysis kind that the database was initialised with. const startTimeInterpretResults = new Date(); - const analysisSummary = await runInterpretResults( - language, - undefined, - sarifFile, - config.debugMode, - automationDetailsId, - ); + const { summary: analysisSummary, sarifFile } = + await runInterpretResultsFor( + dbAnalysisConfig, + language, + undefined, + config.debugMode, + ); + // This case is only needed if Code Quality is not the sole analysis kind. + // In this case, we will have run queries for all analysis kinds. The previous call to + // `interpret-results` will have produced a SARIF file for Code Scanning and we now + // need to produce an additional SARIF file for Code Quality. let qualityAnalysisSummary: string | undefined; - if (configUtils.isCodeQualityEnabled(config)) { - logger.info(`Interpreting quality results for ${language}`); - const qualityCategory = fixCodeQualityCategory( - logger, - automationDetailsId, - ); - const qualitySarifFile = path.join( - sarifFolder, - `${language}.quality.sarif`, - ); - qualityAnalysisSummary = await runInterpretResults( + if ( + config.analysisKinds.length > 1 && + configUtils.isCodeQualityEnabled(config) + ) { + const qualityResult = await runInterpretResultsFor( + analyses.CodeQuality, language, analyses.codeQualityQueries.map((i) => resolveQuerySuiteAlias(language, i), ), - qualitySarifFile, config.debugMode, - qualityCategory, ); + qualityAnalysisSummary = qualityResult.summary; } const endTimeInterpretResults = new Date(); statusReport[`interpret_results_${language}_duration_ms`] = endTimeInterpretResults.getTime() - startTimeInterpretResults.getTime(); logger.endGroup(); - logger.info(analysisSummary); + logger.info(analysisSummary); if (qualityAnalysisSummary) { logger.info(qualityAnalysisSummary); } if (await features.getValue(Feature.QaTelemetryEnabled)) { + // Note: QA adds the `code-quality` query suite to the `queries` input, + // so this is fine since there is no `.quality.sarif`. const perQueryAlertCounts = getPerQueryAlertCounts(sarifFile); const perQueryAlertCountEventReport: EventReport = { @@ -756,6 +769,37 @@ export async function runQueries( return statusReport; + async function runInterpretResultsFor( + analysis: analyses.AnalysisConfig, + language: Language, + queries: string[] | undefined, + enableDebugLogging: boolean, + ): Promise<{ summary: string; sarifFile: string }> { + logger.info(`Interpreting ${analysis.name} results for ${language}`); + + // If this is a Code Quality analysis, correct the category to one + // accepted by the Code Quality backend. + let category = automationDetailsId; + if (analysis.kind === analyses.AnalysisKind.CodeQuality) { + category = fixCodeQualityCategory(logger, automationDetailsId); + } + + const sarifFile = path.join( + sarifFolder, + addSarifExtension(analysis, language), + ); + + const summary = await runInterpretResults( + language, + queries, + sarifFile, + enableDebugLogging, + category, + ); + + return { summary, sarifFile }; + } + async function runInterpretResults( language: Language, queries: string[] | undefined, diff --git a/src/codeql.test.ts b/src/codeql.test.ts index 29e4b27ef3..36775f6530 100644 --- a/src/codeql.test.ts +++ b/src/codeql.test.ts @@ -18,6 +18,7 @@ import { AugmentationProperties, Config, defaultAugmentationProperties, + generateCodeScanningConfig, } from "./config-utils"; import * as defaults from "./defaults.json"; import { DocUrl } from "./doc-url"; @@ -502,8 +503,11 @@ const injectedConfigMacro = test.macro({ ...stubConfig, ...configOverride, tempDir, - augmentationProperties, }; + thisStubConfig.computedConfig = generateCodeScanningConfig( + thisStubConfig.originalUserInput, + augmentationProperties, + ); await codeqlObject.databaseInitCluster( thisStubConfig, @@ -949,7 +953,7 @@ test("runTool recognizes fatal internal errors", async (t) => { await codeqlObject.databaseRunQueries(stubConfig.dbLocation, []), { instanceOf: CliError, - message: `Encountered a fatal error while running "codeql-for-testing database run-queries --intra-layer-parallelism --min-disk-free=1024 -v". Exit code was 1 and error was: Oops! A fatal internal error occurred. Details: + message: `Encountered a fatal error while running "codeql-for-testing database run-queries --min-disk-free=1024 -v". Exit code was 1 and error was: Oops! A fatal internal error occurred. Details: com.semmle.util.exception.CatastrophicError: An error occurred while evaluating ControlFlowGraph::ControlFlow::Root.isRootOf/1#dispred#f610e6ed/2@86282cc8 Severe disk cache trouble (corruption or out of space) at /home/runner/work/_temp/codeql_databases/go/db-go/default/cache/pages/28/33.pack: Failed to write item to disk. See the logs for more details.`, }, diff --git a/src/codeql.ts b/src/codeql.ts index 81c8e3decd..16b105a3df 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -13,7 +13,7 @@ import { } from "./actions-util"; import * as api from "./api-client"; import { CliError, wrapCliConfigurationError } from "./cli-errors"; -import { generateCodeScanningConfig, type Config } from "./config-utils"; +import { appendExtraQueryExclusions, type Config } from "./config-utils"; import { DocUrl } from "./doc-url"; import { EnvVar } from "./environment"; import { @@ -127,7 +127,9 @@ export interface CodeQL { /** * Run 'codeql resolve languages' with '--format=betterjson'. */ - betterResolveLanguages(): Promise; + betterResolveLanguages(options?: { + filterToLanguagesWithQueries: boolean; + }): Promise; /** * Run 'codeql resolve build-environment' */ @@ -593,8 +595,7 @@ export async function getCodeQLForCmd( ? "--force-overwrite" : "--overwrite"; - const overlayDatabaseMode = - config.augmentationProperties.overlayDatabaseMode; + const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode === OverlayDatabaseMode.Overlay) { const overlayChangesFile = await writeOverlayChangesFile( config, @@ -737,13 +738,22 @@ export async function getCodeQLForCmd( ); } }, - async betterResolveLanguages() { + async betterResolveLanguages( + { + filterToLanguagesWithQueries, + }: { + filterToLanguagesWithQueries: boolean; + } = { filterToLanguagesWithQueries: false }, + ) { const codeqlArgs = [ "resolve", "languages", "--format=betterjson", "--extractor-options-verbosity=4", "--extractor-include-aliases", + ...(filterToLanguagesWithQueries + ? ["--filter-to-languages-with-queries"] + : []), ...getExtraOptionsFromEnv(["resolve", "languages"]), ]; const output = await runCli(cmd, codeqlArgs); @@ -790,7 +800,6 @@ export async function getCodeQLForCmd( "run-queries", ...flags, databasePath, - "--intra-layer-parallelism", "--min-disk-free=1024", // Try to leave at least 1GB free "-v", ...queries, @@ -1150,20 +1159,26 @@ async function runCli( } /** - * Generates a code scanning configuration that is to be used for a scan. + * Writes the code scanning configuration that is to be used by the CLI. * * @param codeql The CodeQL object to use. - * @param config The configuration to use. - * @returns the path to the generated user configuration file. + * @param config The CodeQL Action state to use. + * @returns The path to the generated user configuration file. */ async function writeCodeScanningConfigFile( config: Config, logger: Logger, ): Promise { const codeScanningConfigFile = getGeneratedCodeScanningConfigPath(config); - const augmentedConfig = generateCodeScanningConfig( - config.originalUserInput, - config.augmentationProperties, + + // Apply the `extraQueryExclusions` from the CodeQL Action state to the CLI configuration. + // We do this here at the latest possible point before passing the CLI configuration on to + // the CLI so that the `extraQueryExclusions` appear after all user-configured `query-filters`. + // See the comment in `applyExtraQueryExclusions` for more information, as well as + // https://github.com/github/codeql-action/pull/2938 + const augmentedConfig = appendExtraQueryExclusions( + config.extraQueryExclusions, + config.computedConfig, ); logger.info( diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index e57cb5f6f4..b5ef777170 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -157,21 +157,79 @@ test("load empty config", async (t) => { }), ); - t.deepEqual( - config, - await configUtils.getDefaultConfig( - createTestInitConfigInputs({ - languagesInput: languages, - tempDir, - codeql, - logger, - }), - ), + const expectedConfig = await configUtils.initActionState( + createTestInitConfigInputs({ + languagesInput: languages, + tempDir, + codeql, + logger, + }), + {}, ); + + t.deepEqual(config, expectedConfig); }); }); -test("loading config saves config", async (t) => { +test("load code quality config", async (t) => { + return await withTmpDir(async (tempDir) => { + const logger = getRunnerLogger(true); + const languages = "actions"; + + const codeql = createStubCodeQL({ + async betterResolveLanguages() { + return { + extractors: { + actions: [{ extractor_root: "" }], + }, + }; + }, + }); + + const config = await configUtils.initConfig( + createTestInitConfigInputs({ + analysisKindsInput: "code-quality", + languagesInput: languages, + repository: { owner: "github", repo: "example" }, + tempDir, + codeql, + logger, + }), + ); + + // And the config we expect it to result in + 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, + queries: [{ uses: "code-quality" }], + "query-filters": [], + }, + tempDir, + codeQLCmd: codeql.getPath(), + gitHubVersion: githubVersion, + dbLocation: path.resolve(tempDir, "codeql_databases"), + debugMode: false, + debugArtifactName: "", + debugDatabaseName: "", + trapCaches: {}, + trapCacheDownloadTime: 0, + dependencyCachingEnabled: CachingKind.None, + extraQueryExclusions: [], + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, + }; + + t.deepEqual(config, expectedConfig); + }); +}); + +test("loading a saved config produces the same config", async (t) => { return await withTmpDir(async (tempDir) => { const logger = getRunnerLogger(true); @@ -201,6 +259,7 @@ test("loading config saves config", async (t) => { logger, }), ); + await configUtils.saveConfig(config1, logger); // The saved config file should now exist t.true(fs.existsSync(configUtils.getPathToParsedConfigFile(tempDir))); @@ -216,6 +275,57 @@ test("loading config saves config", async (t) => { }); }); +test("loading config with version mismatch throws", async (t) => { + return await withTmpDir(async (tempDir) => { + const logger = getRunnerLogger(true); + + const codeql = createStubCodeQL({ + async betterResolveLanguages() { + return { + extractors: { + javascript: [{ extractor_root: "" }], + python: [{ extractor_root: "" }], + }, + }; + }, + }); + + // Sanity check the saved config file does not already exist + t.false(fs.existsSync(configUtils.getPathToParsedConfigFile(tempDir))); + + // Sanity check that getConfig returns undefined before we have called initConfig + t.deepEqual(await configUtils.getConfig(tempDir, logger), undefined); + + // Stub `getActionVersion` to return some nonsense. + const getActionVersionStub = sinon + .stub(actionsUtil, "getActionVersion") + .returns("does-not-exist"); + + const config = await configUtils.initConfig( + createTestInitConfigInputs({ + languagesInput: "javascript,python", + tempDir, + codeql, + workspacePath: tempDir, + logger, + }), + ); + // initConfig does not save the config, so we do it here. + await configUtils.saveConfig(config, logger); + + // Restore `getActionVersion`. + getActionVersionStub.restore(); + + // The saved config file should now exist + t.true(fs.existsSync(configUtils.getPathToParsedConfigFile(tempDir))); + + // Trying to read the configuration should now throw an error. + await t.throwsAsync(configUtils.getConfig(tempDir, logger), { + instanceOf: ConfigurationError, + }); + }); +}); + test("load input outside of workspace", async (t) => { return await withTmpDir(async (tempDir) => { try { @@ -322,18 +432,22 @@ test("load non-empty input", async (t) => { fs.mkdirSync(path.join(tempDir, "foo")); + const userConfig: configUtils.UserConfig = { + name: "my config", + "disable-default-queries": true, + queries: [{ uses: "./foo" }], + "paths-ignore": ["a", "b"], + paths: ["c/d"], + }; + // And the config we expect it to parse to const expectedConfig: configUtils.Config = { + version: actionsUtil.getActionVersion(), analysisKinds: [AnalysisKind.CodeScanning], languages: [KnownLanguage.javascript], buildMode: BuildMode.None, - originalUserInput: { - name: "my config", - "disable-default-queries": true, - queries: [{ uses: "./foo" }], - "paths-ignore": ["a", "b"], - paths: ["c/d"], - }, + originalUserInput: userConfig, + computedConfig: userConfig, tempDir, codeQLCmd: codeql.getPath(), gitHubVersion: githubVersion, @@ -341,10 +455,12 @@ test("load non-empty input", async (t) => { debugMode: false, debugArtifactName: "my-artifact", debugDatabaseName: "my-db", - augmentationProperties: configUtils.defaultAugmentationProperties, trapCaches: {}, trapCacheDownloadTime: 0, dependencyCachingEnabled: CachingKind.None, + extraQueryExclusions: [], + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, }; const languagesInput = "javascript"; @@ -976,6 +1092,13 @@ const mockRepositoryNwo = parseRepositoryNwo("owner/repo"); expectedLanguages: ["javascript", "csharp", "cpp"], expectedApiCall: true, }, + { + name: "unsupported languages from github api", + languagesInput: "", + languagesInRepository: ["html"], + expectedApiCall: true, + expectedError: configUtils.getNoLanguagesError(), + }, { name: "no languages", languagesInput: "", @@ -1005,57 +1128,71 @@ const mockRepositoryNwo = parseRepositoryNwo("owner/repo"); expectedLanguages: ["javascript"], }, ].forEach((args) => { - test(`getLanguages: ${args.name}`, async (t) => { - const mockRequest = mockLanguagesInRepo(args.languagesInRepository); - const stubExtractorEntry = { - extractor_root: "", - }; - const codeQL = createStubCodeQL({ - betterResolveLanguages: () => - Promise.resolve({ - aliases: { - "c#": KnownLanguage.csharp, - c: KnownLanguage.cpp, - kotlin: KnownLanguage.java, - typescript: KnownLanguage.javascript, - }, - extractors: { - cpp: [stubExtractorEntry], - csharp: [stubExtractorEntry], - java: [stubExtractorEntry], - javascript: [stubExtractorEntry], - python: [stubExtractorEntry], - }, - }), - }); - - if (args.expectedLanguages) { - // happy path - const actualLanguages = await configUtils.getLanguages( - codeQL, - args.languagesInput, - mockRepositoryNwo, - ".", - mockLogger, + for (const resolveSupportedLanguagesUsingCli of [true, false]) { + test(`getLanguages${resolveSupportedLanguagesUsingCli ? " (supported languages via CLI)" : ""}: ${args.name}`, async (t) => { + const features = createFeatures( + resolveSupportedLanguagesUsingCli + ? [Feature.ResolveSupportedLanguagesUsingCli] + : [], ); + const mockRequest = mockLanguagesInRepo(args.languagesInRepository); + const stubExtractorEntry = { + extractor_root: "", + }; + const codeQL = createStubCodeQL({ + betterResolveLanguages: (options) => + Promise.resolve({ + aliases: { + "c#": KnownLanguage.csharp, + c: KnownLanguage.cpp, + kotlin: KnownLanguage.java, + typescript: KnownLanguage.javascript, + }, + extractors: { + cpp: [stubExtractorEntry], + csharp: [stubExtractorEntry], + java: [stubExtractorEntry], + javascript: [stubExtractorEntry], + python: [stubExtractorEntry], + ...(options?.filterToLanguagesWithQueries + ? {} + : { + html: [stubExtractorEntry], + }), + }, + }), + }); + + if (args.expectedLanguages) { + // happy path + const actualLanguages = await configUtils.getLanguages( + codeQL, + args.languagesInput, + mockRepositoryNwo, + ".", + features, + mockLogger, + ); - t.deepEqual(actualLanguages.sort(), args.expectedLanguages.sort()); - } else { - // there is an error - await t.throwsAsync( - async () => - await configUtils.getLanguages( - codeQL, - args.languagesInput, - mockRepositoryNwo, - ".", - mockLogger, - ), - { message: args.expectedError }, - ); - } - t.deepEqual(mockRequest.called, args.expectedApiCall); - }); + t.deepEqual(actualLanguages.sort(), args.expectedLanguages.sort()); + } else { + // there is an error + await t.throwsAsync( + async () => + await configUtils.getLanguages( + codeQL, + args.languagesInput, + mockRepositoryNwo, + ".", + features, + mockLogger, + ), + { message: args.expectedError }, + ); + } + t.deepEqual(mockRequest.called, args.expectedApiCall); + }); + } }); for (const { displayName, language, feature } of [ @@ -1750,3 +1887,9 @@ for (const language in KnownLanguage) { }, ); } + +test("hasActionsWorkflows doesn't throw if workflows folder doesn't exist", async (t) => { + return withTmpDir(async (tmpDir) => { + t.notThrows(() => configUtils.hasActionsWorkflows(tmpDir)); + }); +}); diff --git a/src/config-utils.ts b/src/config-utils.ts index 477cb20e6c..538c366e86 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -5,8 +5,15 @@ import { performance } from "perf_hooks"; import * as yaml from "js-yaml"; import * as semver from "semver"; -import { isAnalyzingPullRequest } from "./actions-util"; -import { AnalysisKind, parseAnalysisKinds } from "./analyses"; +import { getActionVersion, isAnalyzingPullRequest } from "./actions-util"; +import { + AnalysisConfig, + AnalysisKind, + CodeQuality, + codeQualityQueries, + CodeScanning, + parseAnalysisKinds, +} from "./analyses"; import * as api from "./api-client"; import { CachingKind, getCachingKind } from "./caching-utils"; import { type CodeQL } from "./codeql"; @@ -28,6 +35,7 @@ import { BuildMode, codeQlVersionAtLeast, cloneObject, + isDefined, } from "./util"; // Property names from the user-supplied config file. @@ -94,6 +102,10 @@ interface IncludeQueryFilter { * Format of the parsed config file. */ export interface Config { + /** + * The version of the CodeQL Action that the configuration is for. + */ + version: string; /** * Set of analysis kinds that are enabled. */ @@ -144,8 +156,11 @@ export interface Config { * Specifies the name of the database in the debugging artifact. */ debugDatabaseName: string; - - augmentationProperties: AugmentationProperties; + /** + * The configuration we computed by combining `originalUserInput` with `augmentationProperties`, + * as well as adjustments made to it based on unsupported or required options. + */ + computedConfig: UserConfig; /** * Partial map from languages to locations of TRAP caches for that language. @@ -160,6 +175,28 @@ export interface Config { /** A value indicating how dependency caching should be used. */ dependencyCachingEnabled: CachingKind; + + /** + * Extra query exclusions to append to the config. + */ + extraQueryExclusions: ExcludeQueryFilter[]; + + /** + * The overlay database mode to use. + */ + overlayDatabaseMode: OverlayDatabaseMode; + + /** + * Whether to use caching for overlay databases. If it is true, the action + * will upload the created overlay-base database to the actions cache, and + * download an overlay-base database from the actions cache before it creates + * a new overlay database. If it is false, the action assumes that the + * workflow will be responsible for managing database storage and retrieval. + * + * This property has no effect unless `overlayDatabaseMode` is `Overlay` or + * `OverlayBase`. + */ + useOverlayDatabaseCaching: boolean; } /** @@ -192,28 +229,6 @@ export interface AugmentationProperties { * The packs input from the `with` block of the action declaration */ packsInput?: string[]; - - /** - * Extra query exclusions to append to the config. - */ - extraQueryExclusions: ExcludeQueryFilter[]; - - /** - * The overlay database mode to use. - */ - overlayDatabaseMode: OverlayDatabaseMode; - - /** - * Whether to use caching for overlay databases. If it is true, the action - * will upload the created overlay-base database to the actions cache, and - * download an overlay-base database from the actions cache before it creates - * a new overlay database. If it is false, the action assumes that the - * workflow will be responsible for managing database storage and retrieval. - * - * This property has no effect unless `overlayDatabaseMode` is `Overlay` or - * `OverlayBase`. - */ - useOverlayDatabaseCaching: boolean; } /** @@ -225,9 +240,6 @@ export const defaultAugmentationProperties: AugmentationProperties = { packsInputCombines: false, packsInput: undefined, queriesInput: undefined, - extraQueryExclusions: [], - overlayDatabaseMode: OverlayDatabaseMode.None, - useOverlayDatabaseCaching: false, }; export type Packs = Partial>; @@ -304,16 +316,31 @@ export function getUnknownLanguagesError(languages: string[]): string { export async function getSupportedLanguageMap( codeql: CodeQL, + features: FeatureEnablement, + logger: Logger, ): Promise> { - const resolveResult = await codeql.betterResolveLanguages(); + const resolveSupportedLanguagesUsingCli = await features.getValue( + Feature.ResolveSupportedLanguagesUsingCli, + codeql, + ); + const resolveResult = await codeql.betterResolveLanguages({ + filterToLanguagesWithQueries: resolveSupportedLanguagesUsingCli, + }); + if (resolveSupportedLanguagesUsingCli) { + logger.debug( + `The CodeQL CLI supports the following languages: ${Object.keys(resolveResult.extractors).join(", ")}`, + ); + } const supportedLanguages: Record = {}; // Populate canonical language names for (const extractor of Object.keys(resolveResult.extractors)) { - // Require the language to be a known language. - // This is a temporary workaround since we have extractors that are not - // supported languages, such as `csv`, `html`, `properties`, `xml`, and - // `yaml`. We should replace this with a more robust solution in the future. - if (KnownLanguage[extractor] !== undefined) { + // If the CLI supports resolving languages with default queries, use these + // as the set of supported languages. Otherwise, require the language to be + // a known language. + if ( + resolveSupportedLanguagesUsingCli || + KnownLanguage[extractor] !== undefined + ) { supportedLanguages[extractor] = extractor; } } @@ -341,7 +368,7 @@ const baseWorkflowsPath = ".github/workflows"; */ export function hasActionsWorkflows(sourceRoot: string): boolean { const workflowsPath = path.resolve(sourceRoot, baseWorkflowsPath); - const stats = fs.lstatSync(workflowsPath); + const stats = fs.lstatSync(workflowsPath, { throwIfNoEntry: false }); return ( stats !== undefined && stats.isDirectory() && @@ -395,6 +422,7 @@ export async function getLanguages( languagesInput: string | undefined, repository: RepositoryNwo, sourceRoot: string, + features: FeatureEnablement, logger: Logger, ): Promise { // Obtain languages without filtering them. @@ -405,7 +433,7 @@ export async function getLanguages( logger, ); - const languageMap = await getSupportedLanguageMap(codeql); + const languageMap = await getSupportedLanguageMap(codeql, features, logger); const languagesSet = new Set(); const unknownLanguages: string[] = []; @@ -508,29 +536,33 @@ export interface InitConfigInputs { } /** - * Get the default config, populated without user configuration file. + * Initialise the CodeQL Action state, which includes the base configuration for the Action + * and computes the configuration for the CodeQL CLI. */ -export async function getDefaultConfig({ - analysisKindsInput, - languagesInput, - queriesInput, - qualityQueriesInput, - packsInput, - buildModeInput, - dbLocation, - trapCachingEnabled, - dependencyCachingEnabled, - debugMode, - debugArtifactName, - debugDatabaseName, - repository, - tempDir, - codeql, - sourceRoot, - githubVersion, - features, - logger, -}: InitConfigInputs): Promise { +export async function initActionState( + { + analysisKindsInput, + languagesInput, + queriesInput, + qualityQueriesInput, + packsInput, + buildModeInput, + dbLocation, + trapCachingEnabled, + dependencyCachingEnabled, + debugMode, + debugArtifactName, + debugDatabaseName, + repository, + tempDir, + codeql, + sourceRoot, + githubVersion, + features, + logger, + }: InitConfigInputs, + userConfig: UserConfig, +): Promise { const analysisKinds = await parseAnalysisKinds(analysisKindsInput); // For backwards compatibility, add Code Quality to the enabled analysis kinds @@ -548,6 +580,7 @@ export async function getDefaultConfig({ languagesInput, repository, sourceRoot, + features, logger, ); @@ -571,11 +604,20 @@ export async function getDefaultConfig({ logger, ); + // Compute the full Code Scanning configuration that combines the configuration from the + // configuration file / `config` input with other inputs, such as `queries`. + const computedConfig = generateCodeScanningConfig( + userConfig, + augmentationProperties, + ); + return { + version: getActionVersion(), analysisKinds, languages, buildMode, - originalUserInput: {}, + originalUserInput: userConfig, + computedConfig, tempDir, codeQLCmd: codeql.getPath(), gitHubVersion: githubVersion, @@ -583,10 +625,12 @@ export async function getDefaultConfig({ debugMode, debugArtifactName, debugDatabaseName, - augmentationProperties, trapCaches, trapCacheDownloadTime, dependencyCachingEnabled: getCachingKind(dependencyCachingEnabled), + extraQueryExclusions: [], + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, }; } @@ -673,9 +717,6 @@ export async function calculateAugmentation( packsInput: packsInput?.[languages[0]], queriesInput, queriesInputCombines, - extraQueryExclusions: [], - overlayDatabaseMode: OverlayDatabaseMode.None, - useOverlayDatabaseCaching: false, }; } @@ -1063,6 +1104,19 @@ function userConfigFromActionPath(tempDir: string): string { return path.resolve(tempDir, "user-config-from-action.yml"); } +/** + * Checks whether the given `UserConfig` contains any query customisations. + * + * @returns Returns `true` if the `UserConfig` customises which queries are run. + */ +function hasQueryCustomisation(userConfig: UserConfig): boolean { + return ( + isDefined(userConfig["disable-default-queries"]) || + isDefined(userConfig.queries) || + isDefined(userConfig["query-filters"]) + ); +} + /** * Load and return the config. * @@ -1097,9 +1151,26 @@ export async function initConfig(inputs: InitConfigInputs): Promise { ); } - const config = await getDefaultConfig(inputs); - const augmentationProperties = config.augmentationProperties; - config.originalUserInput = userConfig; + const config = await initActionState(inputs, userConfig); + + // If Code Quality analysis is the only enabled analysis kind, then we will initialise + // the database for Code Quality. That entails disabling the default queries and only + // running quality queries. We do not currently support query customisations in that case. + if (config.analysisKinds.length === 1 && isCodeQualityEnabled(config)) { + // Warn if any query customisations are present in the computed configuration. + if (hasQueryCustomisation(config.computedConfig)) { + throw new ConfigurationError( + "Query customizations are unsupported, because only `code-quality` analysis is enabled.", + ); + } + + const queries = codeQualityQueries.map((v) => ({ uses: v })); + + // Set the query customisation options for Code Quality only analysis. + config.computedConfig["disable-default-queries"] = true; + config.computedConfig.queries = queries; + config.computedConfig["query-filters"] = []; + } // The choice of overlay database mode depends on the selection of languages // and queries, which in turn depends on the user config and the augmentation @@ -1113,15 +1184,15 @@ export async function initConfig(inputs: InitConfigInputs): Promise { config.languages, inputs.sourceRoot, config.buildMode, - generateCodeScanningConfig(userConfig, augmentationProperties), + config.computedConfig, logger, ); logger.info( `Using overlay database mode: ${overlayDatabaseMode} ` + `${useOverlayDatabaseCaching ? "with" : "without"} caching.`, ); - augmentationProperties.overlayDatabaseMode = overlayDatabaseMode; - augmentationProperties.useOverlayDatabaseCaching = useOverlayDatabaseCaching; + config.overlayDatabaseMode = overlayDatabaseMode; + config.useOverlayDatabaseCaching = useOverlayDatabaseCaching; if ( overlayDatabaseMode === OverlayDatabaseMode.Overlay || @@ -1131,13 +1202,10 @@ export async function initConfig(inputs: InitConfigInputs): Promise { logger, )) ) { - augmentationProperties.extraQueryExclusions.push({ + config.extraQueryExclusions.push({ exclude: { tags: "exclude-from-incremental" }, }); } - - // Save the config so we can easily access it again in the future - await saveConfig(config, logger); return config; } @@ -1235,7 +1303,7 @@ export function getPathToParsedConfigFile(tempDir: string): string { /** * Store the given config to the path returned from getPathToParsedConfigFile. */ -async function saveConfig(config: Config, logger: Logger) { +export async function saveConfig(config: Config, logger: Logger) { const configString = JSON.stringify(config); const configFile = getPathToParsedConfigFile(config.tempDir); fs.mkdirSync(path.dirname(configFile), { recursive: true }); @@ -1259,7 +1327,21 @@ export async function getConfig( const configString = fs.readFileSync(configFile, "utf8"); logger.debug("Loaded config:"); logger.debug(configString); - return JSON.parse(configString) as Config; + + const config = JSON.parse(configString) as Partial; + + if (config.version === undefined) { + throw new ConfigurationError( + `Loaded configuration file, but it does not contain the expected 'version' field.`, + ); + } + if (config.version !== getActionVersion()) { + throw new ConfigurationError( + `Loaded a configuration file for version '${config.version}', but running version '${getActionVersion()}'`, + ); + } + + return config as Config; } /** @@ -1461,23 +1543,80 @@ export function generateCodeScanningConfig( delete augmentedConfig.packs; } + return augmentedConfig; +} + +/** + * Appends `extraQueryExclusions` to `cliConfig`'s `query-filters`. + * + * @param extraQueryExclusions The extra query exclusions to append to the `query-filters`. + * @param cliConfig The CodeQL CLI configuration to extend. + * @returns Returns `cliConfig` if there are no extra query exclusions + * or a copy of `cliConfig` where the extra query exclusions + * have been appended to `query-filters`. + */ +export function appendExtraQueryExclusions( + extraQueryExclusions: ExcludeQueryFilter[], + cliConfig: UserConfig, +): Readonly { + // make a copy so we can modify it and so that modifications to the input + // object do not affect the result that is marked as `Readonly`. + const augmentedConfig = cloneObject(cliConfig); + + if (extraQueryExclusions.length === 0) { + return augmentedConfig; + } + augmentedConfig["query-filters"] = [ // Ordering matters. If the first filter is an inclusion, it implicitly // excludes all queries that are not included. If it is an exclusion, // it implicitly includes all queries that are not excluded. So user // filters (if any) should always be first to preserve intent. ...(augmentedConfig["query-filters"] || []), - ...augmentationProperties.extraQueryExclusions, + ...extraQueryExclusions, ]; if (augmentedConfig["query-filters"]?.length === 0) { delete augmentedConfig["query-filters"]; } + return augmentedConfig; } +/** + * Returns `true` if Code Scanning analysis is enabled, or `false` if not. + */ +export function isCodeScanningEnabled(config: Config): boolean { + return config.analysisKinds.includes(AnalysisKind.CodeScanning); +} + /** * Returns `true` if Code Quality analysis is enabled, or `false` if not. */ export function isCodeQualityEnabled(config: Config): boolean { return config.analysisKinds.includes(AnalysisKind.CodeQuality); } + +/** + * Returns the primary analysis kind that the Action is initialised with. This is + * always `AnalysisKind.CodeScanning` unless `AnalysisKind.CodeScanning` is not enabled. + * + * @returns Returns `AnalysisKind.CodeScanning` if `AnalysisKind.CodeScanning` is enabled; + * otherwise `AnalysisKind.CodeQuality`. + */ +export function getPrimaryAnalysisKind(config: Config): AnalysisKind { + return isCodeScanningEnabled(config) + ? AnalysisKind.CodeScanning + : AnalysisKind.CodeQuality; +} + +/** + * Returns the primary analysis configuration that the Action is initialised with. This is + * always `CodeScanning` unless `CodeScanning` is not enabled. + * + * @returns Returns `CodeScanning` if `AnalysisKind.CodeScanning` is enabled; otherwise `CodeQuality`. + */ +export function getPrimaryAnalysisConfig(config: Config): AnalysisConfig { + return getPrimaryAnalysisKind(config) === AnalysisKind.CodeScanning + ? CodeScanning + : CodeQuality; +} diff --git a/src/defaults.json b/src/defaults.json index b90234b76b..712efc19fe 100644 --- a/src/defaults.json +++ b/src/defaults.json @@ -1,6 +1,6 @@ { - "bundleVersion": "codeql-bundle-v2.22.4", - "cliVersion": "2.22.4", - "priorBundleVersion": "codeql-bundle-v2.22.3", - "priorCliVersion": "2.22.3" + "bundleVersion": "codeql-bundle-v2.23.0", + "cliVersion": "2.23.0", + "priorBundleVersion": "codeql-bundle-v2.22.4", + "priorCliVersion": "2.22.4" } diff --git a/src/dependency-caching.ts b/src/dependency-caching.ts index ae6f215397..6289ca2f68 100644 --- a/src/dependency-caching.ts +++ b/src/dependency-caching.ts @@ -8,7 +8,7 @@ import { getTemporaryDirectory } from "./actions-util"; import { getTotalCacheSize } from "./caching-utils"; import { Config } from "./config-utils"; import { EnvVar } from "./environment"; -import { Language } from "./languages"; +import { KnownLanguage, Language } from "./languages"; import { Logger } from "./logging"; import { getRequiredEnvParam } from "./util"; @@ -89,11 +89,13 @@ async function makeGlobber(patterns: string[]): Promise { * * @param languages The languages being analyzed. * @param logger A logger to record some informational messages to. + * @param minimizeJavaJars Whether the Java extractor should rewrite downloaded JARs to minimize their size. * @returns A list of languages for which dependency caches were restored. */ export async function downloadDependencyCaches( languages: Language[], logger: Logger, + minimizeJavaJars: boolean, ): Promise { const restoredCaches: Language[] = []; @@ -118,8 +120,10 @@ export async function downloadDependencyCaches( continue; } - const primaryKey = await cacheKey(language, cacheConfig); - const restoreKeys: string[] = [await cachePrefix(language)]; + const primaryKey = await cacheKey(language, cacheConfig, minimizeJavaJars); + const restoreKeys: string[] = [ + await cachePrefix(language, minimizeJavaJars), + ]; logger.info( `Downloading cache for ${language} with key ${primaryKey} and restore keys ${restoreKeys.join( @@ -149,8 +153,13 @@ export async function downloadDependencyCaches( * * @param config The configuration for this workflow. * @param logger A logger to record some informational messages to. + * @param minimizeJavaJars Whether the Java extractor should rewrite downloaded JARs to minimize their size. */ -export async function uploadDependencyCaches(config: Config, logger: Logger) { +export async function uploadDependencyCaches( + config: Config, + logger: Logger, + minimizeJavaJars: boolean, +): Promise { for (const language of config.languages) { const cacheConfig = getDefaultCacheConfig()[language]; @@ -192,7 +201,7 @@ export async function uploadDependencyCaches(config: Config, logger: Logger) { continue; } - const key = await cacheKey(language, cacheConfig); + const key = await cacheKey(language, cacheConfig, minimizeJavaJars); logger.info( `Uploading cache of size ${size} for ${language} with key ${key}...`, @@ -222,14 +231,16 @@ export async function uploadDependencyCaches(config: Config, logger: Logger) { * * @param language The language being analyzed. * @param cacheConfig The cache configuration for the language. + * @param minimizeJavaJars Whether the Java extractor should rewrite downloaded JARs to minimize their size. * @returns A cache key capturing information about the project(s) being analyzed in the specified language. */ async function cacheKey( language: Language, cacheConfig: CacheConfig, + minimizeJavaJars: boolean = false, ): Promise { const hash = await glob.hashFiles(cacheConfig.hash.join("\n")); - return `${await cachePrefix(language)}${hash}`; + return `${await cachePrefix(language, minimizeJavaJars)}${hash}`; } /** @@ -237,9 +248,13 @@ async function cacheKey( * can be changed to invalidate old caches, the runner's operating system, and the specified language name. * * @param language The language being analyzed. + * @param minimizeJavaJars Whether the Java extractor should rewrite downloaded JARs to minimize their size. * @returns The prefix that identifies what a cache is for. */ -async function cachePrefix(language: Language): Promise { +async function cachePrefix( + language: Language, + minimizeJavaJars: boolean, +): Promise { const runnerOs = getRequiredEnvParam("RUNNER_OS"); const customPrefix = process.env[EnvVar.DEPENDENCY_CACHING_PREFIX]; let prefix = CODEQL_DEPENDENCY_CACHE_PREFIX; @@ -248,5 +263,10 @@ async function cachePrefix(language: Language): Promise { prefix = `${prefix}-${customPrefix}`; } + // To ensure a safe rollout of JAR minimization, we change the key when the feature is enabled. + if (language === KnownLanguage.java && minimizeJavaJars) { + prefix = `minify-${prefix}`; + } + return `${prefix}-${CODEQL_DEPENDENCY_CACHE_VERSION}-${runnerOs}-${language}-`; } diff --git a/src/environment.ts b/src/environment.ts index f25e7270da..e1daeedc2d 100644 --- a/src/environment.ts +++ b/src/environment.ts @@ -115,8 +115,17 @@ export enum EnvVar { */ DEPENDENCY_CACHING_PREFIX = "CODEQL_ACTION_DEPENDENCY_CACHE_PREFIX", + /** Used by the Java extractor option to enable minimizing dependency JARs. */ + JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS = "CODEQL_EXTRACTOR_JAVA_OPTION_MINIMIZE_DEPENDENCY_JARS", + /** * Whether to enable experimental extractors for CodeQL. */ EXPERIMENTAL_FEATURES = "CODEQL_ENABLE_EXPERIMENTAL_FEATURES", + + /** + * Whether and where to dump the processed SARIF file that would be uploaded, regardless of + * whether the upload is disabled. This is intended for testing and debugging purposes. + */ + SARIF_DUMP_DIR = "CODEQL_ACTION_SARIF_DUMP_DIR", } diff --git a/src/feature-flags.ts b/src/feature-flags.ts index d9f1a1cc3a..b7946d62f4 100644 --- a/src/feature-flags.ts +++ b/src/feature-flags.ts @@ -50,6 +50,7 @@ export enum Feature { DisableJavaBuildlessEnabled = "disable_java_buildless_enabled", DisableKotlinAnalysisEnabled = "disable_kotlin_analysis_enabled", ExportDiagnosticsEnabled = "export_diagnostics_enabled", + JavaMinimizeDependencyJars = "java_minimize_dependency_jars", OverlayAnalysis = "overlay_analysis", OverlayAnalysisActions = "overlay_analysis_actions", OverlayAnalysisCodeScanningActions = "overlay_analysis_code_scanning_actions", @@ -73,6 +74,7 @@ export enum Feature { OverlayAnalysisSwift = "overlay_analysis_swift", PythonDefaultIsToNotExtractStdlib = "python_default_is_to_not_extract_stdlib", QaTelemetryEnabled = "qa_telemetry_enabled", + ResolveSupportedLanguagesUsingCli = "resolve_supported_languages_using_cli", } export const featureConfig: Record< @@ -145,6 +147,12 @@ export const featureConfig: Record< legacyApi: true, minimumVersion: undefined, }, + [Feature.ResolveSupportedLanguagesUsingCli]: { + defaultValue: false, + envVar: "CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI", + minimumVersion: undefined, + toolsFeature: ToolsFeature.BuiltinExtractorsSpecifyDefaultQueries, + }, [Feature.OverlayAnalysis]: { defaultValue: false, envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS", @@ -262,6 +270,11 @@ export const featureConfig: Record< legacyApi: true, minimumVersion: undefined, }, + [Feature.JavaMinimizeDependencyJars]: { + defaultValue: false, + envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS", + minimumVersion: "2.23.0", + }, }; /** diff --git a/src/init-action-post-helper.ts b/src/init-action-post-helper.ts index b04e62c290..0d21bd3b66 100644 --- a/src/init-action-post-helper.ts +++ b/src/init-action-post-helper.ts @@ -4,6 +4,7 @@ import * as core from "@actions/core"; import * as github from "@actions/github"; 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"; @@ -104,7 +105,7 @@ async function maybeUploadFailedSarif( category, features, logger, - uploadLib.CodeScanningTarget, + CodeScanning, ); await uploadLib.waitForProcessing( repositoryNwo, diff --git a/src/init-action.ts b/src/init-action.ts index df22fe6a54..c28b1e72c9 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -51,7 +51,9 @@ import { getRepositoryNwo } from "./repository"; import { ToolsSource } from "./setup-codeql"; import { ActionName, - StatusReportBase, + InitStatusReport, + InitWithConfigStatusReport, + createInitWithConfigStatusReport, createStatusReportBase, getActionsStatus, sendStatusReport, @@ -75,52 +77,10 @@ import { ConfigurationError, wrapError, checkActionVersion, - cloneObject, getErrorMessage, + BuildMode, } from "./util"; import { validateWorkflow } from "./workflow"; -/** Fields of the init status report that can be sent before `config` is populated. */ -interface InitStatusReport extends StatusReportBase { - /** Value given by the user as the "tools" input. */ - tools_input: string; - /** Version of the bundle used. */ - tools_resolved_version: string; - /** Where the bundle originated from. */ - tools_source: ToolsSource; - /** Comma-separated list of languages specified explicitly in the workflow file. */ - workflow_languages: string; -} - -/** Fields of the init status report that are populated using values from `config`. */ -interface InitWithConfigStatusReport extends InitStatusReport { - /** Comma-separated list of languages where the default queries are disabled. */ - disable_default_queries: string; - /** Comma-separated list of paths, from the 'paths' config field. */ - paths: string; - /** Comma-separated list of paths, from the 'paths-ignore' config field. */ - paths_ignore: string; - /** Comma-separated list of queries sources, from the 'queries' config field or workflow input. */ - queries: string; - /** Stringified JSON object of packs, from the 'packs' config field or workflow input. */ - packs: string; - /** Comma-separated list of languages for which we are using TRAP caching. */ - trap_cache_languages: string; - /** Size of TRAP caches that we downloaded, in bytes. */ - trap_cache_download_size_bytes: number; - /** Time taken to download TRAP caches, in milliseconds. */ - trap_cache_download_duration_ms: number; - /** Size of the overlay-base database that we downloaded, in bytes. */ - overlay_base_database_download_size_bytes?: number; - /** Time taken to download the overlay-base database, in milliseconds. */ - overlay_base_database_download_duration_ms?: number; - /** Stringified JSON array of registry configuration objects, from the 'registries' config field - or workflow input. **/ - registries: string; - /** Stringified JSON object representing a query-filters, from the 'query-filters' config field. **/ - query_filters: string; - /** Path to the specified code scanning config file, from the 'config-file' config field. */ - config_file: string; -} /** Fields of the init status report populated when the tools source is `download`. */ interface InitToolsDownloadFields { @@ -180,83 +140,17 @@ async function sendCompletedStatusReport( } if (config !== undefined) { - const languages = config.languages.join(","); - const paths = (config.originalUserInput.paths || []).join(","); - const pathsIgnore = (config.originalUserInput["paths-ignore"] || []).join( - ",", - ); - const disableDefaultQueries = config.originalUserInput[ - "disable-default-queries" - ] - ? languages - : ""; - - const queries: string[] = []; - let queriesInput = getOptionalInput("queries")?.trim(); - if (queriesInput === undefined || queriesInput.startsWith("+")) { - queries.push( - ...(config.originalUserInput.queries || []).map((q) => q.uses), - ); - } - if (queriesInput !== undefined) { - queriesInput = queriesInput.startsWith("+") - ? queriesInput.slice(1) - : queriesInput; - queries.push(...queriesInput.split(",")); - } - - let packs: Record = {}; - if ( - (config.augmentationProperties.packsInputCombines || - !config.augmentationProperties.packsInput) && - config.originalUserInput.packs - ) { - // Make a copy, because we might modify `packs`. - const copyPacksFromOriginalUserInput = cloneObject( - config.originalUserInput.packs, - ); - // If it is an array, then assume there is only a single language being analyzed. - if (Array.isArray(copyPacksFromOriginalUserInput)) { - packs[config.languages[0]] = copyPacksFromOriginalUserInput; - } else { - packs = copyPacksFromOriginalUserInput; - } - } - - if (config.augmentationProperties.packsInput) { - packs[config.languages[0]] ??= []; - packs[config.languages[0]].push( - ...config.augmentationProperties.packsInput, - ); - } - // Append fields that are dependent on `config` - const initWithConfigStatusReport: InitWithConfigStatusReport = { - ...initStatusReport, - config_file: configFile ?? "", - disable_default_queries: disableDefaultQueries, - paths, - paths_ignore: pathsIgnore, - queries: queries.join(","), - packs: JSON.stringify(packs), - trap_cache_languages: Object.keys(config.trapCaches).join(","), - trap_cache_download_size_bytes: Math.round( - await getTotalCacheSize(Object.values(config.trapCaches), logger), - ), - trap_cache_download_duration_ms: Math.round(config.trapCacheDownloadTime), - overlay_base_database_download_size_bytes: - overlayBaseDatabaseStats?.databaseSizeBytes, - overlay_base_database_download_duration_ms: - overlayBaseDatabaseStats?.databaseDownloadDurationMs, - query_filters: JSON.stringify( - config.originalUserInput["query-filters"] ?? [], - ), - registries: JSON.stringify( - configUtils.parseRegistriesWithoutCredentials( - getOptionalInput("registries"), - ) ?? [], - ), - }; + const initWithConfigStatusReport: InitWithConfigStatusReport = + await createInitWithConfigStatusReport( + config, + initStatusReport, + configFile, + Math.round( + await getTotalCacheSize(Object.values(config.trapCaches), logger), + ), + overlayBaseDatabaseStats, + ); await sendStatusReport({ ...initWithConfigStatusReport, ...initToolsDownloadFields, @@ -449,9 +343,8 @@ async function run() { let overlayBaseDatabaseStats: OverlayBaseDatabaseDownloadStats | undefined; try { if ( - config.augmentationProperties.overlayDatabaseMode === - OverlayDatabaseMode.Overlay && - config.augmentationProperties.useOverlayDatabaseCaching + config.overlayDatabaseMode === OverlayDatabaseMode.Overlay && + config.useOverlayDatabaseCaching ) { // OverlayDatabaseMode.Overlay comes in two flavors: with database // caching, or without. The flavor with database caching is intended to be @@ -470,8 +363,7 @@ async function run() { logger, ); if (!overlayBaseDatabaseStats) { - config.augmentationProperties.overlayDatabaseMode = - OverlayDatabaseMode.None; + config.overlayDatabaseMode = OverlayDatabaseMode.None; logger.info( "No overlay-base database found in cache, " + `reverting overlay database mode to ${OverlayDatabaseMode.None}.`, @@ -479,10 +371,7 @@ async function run() { } } - if ( - config.augmentationProperties.overlayDatabaseMode !== - OverlayDatabaseMode.Overlay - ) { + if (config.overlayDatabaseMode !== OverlayDatabaseMode.Overlay) { cleanupDatabaseClusterDirectory(config, logger); } @@ -658,8 +547,16 @@ async function run() { } // Restore dependency cache(s), if they exist. + const minimizeJavaJars = await features.getValue( + Feature.JavaMinimizeDependencyJars, + codeql, + ); if (shouldRestoreCache(config.dependencyCachingEnabled)) { - await downloadDependencyCaches(config.languages, logger); + await downloadDependencyCaches( + config.languages, + logger, + minimizeJavaJars, + ); } // Suppress warnings about disabled Python library extraction. @@ -709,6 +606,24 @@ async function run() { } } + // If the feature flag to minimize Java dependency jars is enabled, and we are doing a Java + // `build-mode: none` analysis (i.e. the flag is relevant), then set the environment variable + // that enables the corresponding option in the Java extractor. + if (process.env[EnvVar.JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS]) { + logger.debug( + `${EnvVar.JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS} is already set to '${process.env[EnvVar.JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS]}', so the Action will not override it.`, + ); + } else if ( + minimizeJavaJars && + config.buildMode === BuildMode.None && + config.languages.includes(KnownLanguage.java) + ) { + core.exportVariable( + EnvVar.JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS, + "true", + ); + } + const { registriesAuthTokens, qlconfigFile } = await configUtils.generateRegistries( getOptionalInput("registries"), @@ -739,15 +654,13 @@ async function run() { // revert to `OverlayDatabaseMode.None`, re-initialize the database cluster // with the new overlay database mode. if ( - config.augmentationProperties.overlayDatabaseMode !== - OverlayDatabaseMode.None && + config.overlayDatabaseMode !== OverlayDatabaseMode.None && !(await checkPacksForOverlayCompatibility(codeql, config, logger)) ) { logger.info( "Reverting overlay database mode to None due to incompatible packs.", ); - config.augmentationProperties.overlayDatabaseMode = - OverlayDatabaseMode.None; + config.overlayDatabaseMode = OverlayDatabaseMode.None; cleanupDatabaseClusterDirectory(config, logger, { disableExistingDirectoryWarning: true, }); @@ -794,6 +707,12 @@ async function run() { } finally { logUnwrittenDiagnostics(); } + + // We save the config here instead of at the end of `initConfig` because we + // may have updated the config returned from `initConfig`, e.g. to revert to + // `OverlayDatabaseMode.None` if we failed to download an overlay-base + // database. + await configUtils.saveConfig(config, logger); await sendCompletedStatusReport( startedAt, config, diff --git a/src/overlay-database-utils.test.ts b/src/overlay-database-utils.test.ts index fb8a48d447..ca52f1d88a 100644 --- a/src/overlay-database-utils.test.ts +++ b/src/overlay-database-utils.test.ts @@ -6,6 +6,7 @@ import test from "ava"; import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; +import * as apiClient from "./api-client"; import * as gitUtils from "./git-utils"; import { getRunnerLogger } from "./logging"; import { @@ -120,10 +121,8 @@ const testDownloadOverlayBaseDatabaseFromCache = test.macro({ const testCase = { ...defaultDownloadTestCase, ...partialTestCase }; - config.augmentationProperties.overlayDatabaseMode = - testCase.overlayDatabaseMode; - config.augmentationProperties.useOverlayDatabaseCaching = - testCase.useOverlayDatabaseCaching; + config.overlayDatabaseMode = testCase.overlayDatabaseMode; + config.useOverlayDatabaseCaching = testCase.useOverlayDatabaseCaching; if (testCase.hasBaseDatabaseOidsFile) { const baseDatabaseOidsFile = path.join( @@ -135,6 +134,11 @@ const testDownloadOverlayBaseDatabaseFromCache = test.macro({ const stubs: sinon.SinonStub[] = []; + const getAutomationIDStub = sinon + .stub(apiClient, "getAutomationID") + .resolves("test-automation-id/"); + stubs.push(getAutomationIDStub); + const isInTestModeStub = sinon .stub(utils, "isInTestMode") .returns(testCase.isInTestMode); diff --git a/src/overlay-database-utils.ts b/src/overlay-database-utils.ts index a01546f067..ea43abcaa3 100644 --- a/src/overlay-database-utils.ts +++ b/src/overlay-database-utils.ts @@ -1,9 +1,11 @@ +import * as crypto from "crypto"; import * as fs from "fs"; import * as path from "path"; import * as actionsCache from "@actions/cache"; import { getRequiredInput, getTemporaryDirectory } from "./actions-util"; +import { getAutomationID } from "./api-client"; import { type CodeQL } from "./codeql"; import { type Config } from "./config-utils"; import { getCommitOid, getFileOidsUnderPath } from "./git-utils"; @@ -20,18 +22,23 @@ export const CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; /** * The maximum (uncompressed) size of the overlay base database that we will - * upload. Actions Cache has an overall capacity of 10 GB, and the Actions Cache - * client library uses zstd compression. + * upload. By default, the Actions Cache has an overall capacity of 10 GB, and + * the Actions Cache client library uses zstd compression. * * Ideally we would apply a size limit to the compressed overlay-base database, * but we cannot do so because compression is handled transparently by the * Actions Cache client library. Instead we place a limit on the uncompressed * size of the overlay-base database. * - * Assuming 2.5:1 compression ratio, the 6 GB limit on uncompressed data would - * translate to a limit of around 2.4 GB after compression. + * Assuming 2.5:1 compression ratio, the 15 GB limit on uncompressed data would + * translate to a limit of around 6 GB after compression. This is a high limit + * compared to the default 10GB Actions Cache capacity, but enforcement of Actions + * Cache quotas is not immediate. + * + * TODO: revisit this limit before removing the restriction for overlay analysis + * to the `github` and `dsp-testing` orgs. */ -const OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 6000; +const OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 15000; const OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1_000_000; @@ -192,7 +199,7 @@ export async function uploadOverlayBaseDatabaseToCache( config: Config, logger: Logger, ): Promise { - const overlayDatabaseMode = config.augmentationProperties.overlayDatabaseMode; + const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode !== OverlayDatabaseMode.OverlayBase) { logger.debug( `Overlay database mode is ${overlayDatabaseMode}. ` + @@ -200,7 +207,7 @@ export async function uploadOverlayBaseDatabaseToCache( ); return false; } - if (!config.augmentationProperties.useOverlayDatabaseCaching) { + if (!config.useOverlayDatabaseCaching) { logger.debug( "Overlay database caching is disabled. " + "Skip uploading overlay-base database to cache.", @@ -251,15 +258,19 @@ export async function uploadOverlayBaseDatabaseToCache( const codeQlVersion = (await codeql.getVersion()).version; const checkoutPath = getRequiredInput("checkout_path"); - const cacheKey = await generateCacheKey(config, codeQlVersion, checkoutPath); + const cacheSaveKey = await getCacheSaveKey( + config, + codeQlVersion, + checkoutPath, + ); logger.info( - `Uploading overlay-base database to Actions cache with key ${cacheKey}`, + `Uploading overlay-base database to Actions cache with key ${cacheSaveKey}`, ); try { const cacheId = await withTimeout( MAX_CACHE_OPERATION_MS, - actionsCache.saveCache([dbLocation], cacheKey), + actionsCache.saveCache([dbLocation], cacheSaveKey), () => {}, ); if (cacheId === undefined) { @@ -298,7 +309,7 @@ export async function downloadOverlayBaseDatabaseFromCache( config: Config, logger: Logger, ): Promise { - const overlayDatabaseMode = config.augmentationProperties.overlayDatabaseMode; + const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode !== OverlayDatabaseMode.Overlay) { logger.debug( `Overlay database mode is ${overlayDatabaseMode}. ` + @@ -306,7 +317,7 @@ export async function downloadOverlayBaseDatabaseFromCache( ); return undefined; } - if (!config.augmentationProperties.useOverlayDatabaseCaching) { + if (!config.useOverlayDatabaseCaching) { logger.debug( "Overlay database caching is disabled. " + "Skip downloading overlay-base database from cache.", @@ -322,10 +333,14 @@ export async function downloadOverlayBaseDatabaseFromCache( const dbLocation = config.dbLocation; const codeQlVersion = (await codeql.getVersion()).version; - const restoreKey = getCacheRestoreKey(config, codeQlVersion); + const cacheRestoreKeyPrefix = await getCacheRestoreKeyPrefix( + config, + codeQlVersion, + ); logger.info( - `Looking in Actions cache for overlay-base database with restore key ${restoreKey}`, + "Looking in Actions cache for overlay-base database with " + + `restore key ${cacheRestoreKeyPrefix}`, ); let databaseDownloadDurationMs = 0; @@ -333,7 +348,7 @@ export async function downloadOverlayBaseDatabaseFromCache( const databaseDownloadStart = performance.now(); const foundKey = await withTimeout( MAX_CACHE_OPERATION_MS, - actionsCache.restoreCache([dbLocation], restoreKey), + actionsCache.restoreCache([dbLocation], cacheRestoreKeyPrefix), () => { logger.info("Timed out downloading overlay-base database from cache"); }, @@ -387,25 +402,87 @@ export async function downloadOverlayBaseDatabaseFromCache( }; } -async function generateCacheKey( +/** + * Computes the cache key for saving the overlay-base database to the GitHub + * Actions cache. + * + * The key consists of the restore key prefix (which does not include the + * commit SHA) and the commit SHA of the current checkout. + */ +async function getCacheSaveKey( config: Config, codeQlVersion: string, checkoutPath: string, ): Promise { const sha = await getCommitOid(checkoutPath); - return `${getCacheRestoreKey(config, codeQlVersion)}${sha}`; + const restoreKeyPrefix = await getCacheRestoreKeyPrefix( + config, + codeQlVersion, + ); + return `${restoreKeyPrefix}${sha}`; } -function getCacheRestoreKey(config: Config, codeQlVersion: string): string { - // The restore key (prefix) specifies which cached overlay-base databases are - // compatible with the current analysis: the cached database must have the - // same cache version and the same CodeQL bundle version. - // - // Actions cache supports using multiple restore keys to indicate preference. - // Technically we prefer a cached overlay-base database with the same SHA as - // we are analyzing. However, since overlay-base databases are built from the - // default branch and used in PR analysis, it is exceedingly unlikely that - // the commit SHA will ever be the same, so we can just leave it out. +/** + * Computes the cache key prefix for restoring the overlay-base database from + * the GitHub Actions cache. + * + * Actions cache supports using multiple restore keys to indicate preference, + * and this function could in principle take advantage of that feature by + * returning a list of restore key prefixes. However, since overlay-base + * databases are built from the default branch and used in PR analysis, it is + * exceedingly unlikely that the commit SHA will ever be the same. + * + * Therefore, this function returns only a single restore key prefix, which does + * not include the commit SHA. This allows us to restore the most recent + * compatible overlay-base database. + */ +async function getCacheRestoreKeyPrefix( + config: Config, + codeQlVersion: string, +): Promise { const languages = [...config.languages].sort().join("_"); - return `${CACHE_PREFIX}-${CACHE_VERSION}-${languages}-${codeQlVersion}-`; + + const cacheKeyComponents = { + automationID: await getAutomationID(), + // Add more components here as needed in the future + }; + const componentsHash = createCacheKeyHash(cacheKeyComponents); + + // For a cached overlay-base database to be considered compatible for overlay + // analysis, all components in the cache restore key must match: + // + // CACHE_PREFIX: distinguishes overlay-base databases from other cache objects + // CACHE_VERSION: cache format version + // componentsHash: hash of additional components (see above for details) + // languages: the languages included in the overlay-base database + // codeQlVersion: CodeQL bundle version + // + // Technically we can also include languages and codeQlVersion in the + // componentsHash, but including them explicitly in the cache key makes it + // easier to debug and understand the cache key structure. + return `${CACHE_PREFIX}-${CACHE_VERSION}-${componentsHash}-${languages}-${codeQlVersion}-`; +} + +/** + * Creates a SHA-256 hash of the cache key components to ensure uniqueness + * while keeping the cache key length manageable. + * + * @param components Object containing all components that should influence cache key uniqueness + * @returns A short SHA-256 hash (first 16 characters) of the components + */ +function createCacheKeyHash(components: Record): string { + // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify + // + // "Properties are visited using the same algorithm as Object.keys(), which + // has a well-defined order and is stable across implementations. For example, + // JSON.stringify on the same object will always produce the same string, and + // JSON.parse(JSON.stringify(obj)) would produce an object with the same key + // ordering as the original (assuming the object is completely + // JSON-serializable)." + const componentsJson = JSON.stringify(components); + return crypto + .createHash("sha256") + .update(componentsJson) + .digest("hex") + .substring(0, 16); } diff --git a/src/start-proxy-action.ts b/src/start-proxy-action.ts index 1efedb7d5c..6ce3b70ff4 100644 --- a/src/start-proxy-action.ts +++ b/src/start-proxy-action.ts @@ -7,13 +7,14 @@ import { pki } from "node-forge"; import * as actionsUtil from "./actions-util"; import { getActionsLogger, Logger } from "./logging"; -import { Credential, getCredentials } from "./start-proxy"; +import { + Credential, + getCredentials, + getDownloadUrl, + UPDATEJOB_PROXY, +} from "./start-proxy"; import * as util from "./util"; -const UPDATEJOB_PROXY = "update-job-proxy"; -const UPDATEJOB_PROXY_VERSION = "v2.0.20250624110901"; -const UPDATEJOB_PROXY_URL_PREFIX = - "https://github.com/github/codeql-action/releases/download/codeql-bundle-v2.22.0/"; const KEY_SIZE = 2048; const KEY_EXPIRY_YEARS = 2; @@ -119,7 +120,7 @@ async function runWrapper() { }; // Start the Proxy - const proxyBin = await getProxyBinaryPath(); + const proxyBin = await getProxyBinaryPath(logger); await startProxy(proxyBin, proxyConfig, proxyLogFilePath, logger); } @@ -184,26 +185,19 @@ async function startProxy( } } -async function getProxyBinaryPath(): Promise { +async function getProxyBinaryPath(logger: Logger): Promise { const proxyFileName = process.platform === "win32" ? `${UPDATEJOB_PROXY}.exe` : UPDATEJOB_PROXY; - const platform = - process.platform === "win32" - ? "win64" - : process.platform === "darwin" - ? "osx64" - : "linux64"; - const proxyPackage = `${UPDATEJOB_PROXY}-${platform}.tar.gz`; - const proxyURL = `${UPDATEJOB_PROXY_URL_PREFIX}${proxyPackage}`; - - let proxyBin = toolcache.find(proxyFileName, UPDATEJOB_PROXY_VERSION); + const proxyInfo = await getDownloadUrl(logger); + + let proxyBin = toolcache.find(proxyFileName, proxyInfo.version); if (!proxyBin) { - const temp = await toolcache.downloadTool(proxyURL); + const temp = await toolcache.downloadTool(proxyInfo.url); const extracted = await toolcache.extractTar(temp); proxyBin = await toolcache.cacheDir( extracted, proxyFileName, - UPDATEJOB_PROXY_VERSION, + proxyInfo.version, ); } proxyBin = path.join(proxyBin, proxyFileName); diff --git a/src/start-proxy.test.ts b/src/start-proxy.test.ts index c9682edcf5..dfd55d72fc 100644 --- a/src/start-proxy.test.ts +++ b/src/start-proxy.test.ts @@ -1,5 +1,8 @@ import test from "ava"; +import sinon from "sinon"; +import * as apiClient from "./api-client"; +import * as defaults from "./defaults.json"; import { KnownLanguage } from "./languages"; import { getRunnerLogger } from "./logging"; import * as startProxyExports from "./start-proxy"; @@ -11,6 +14,14 @@ setupTests(test); const toEncodedJSON = (data: any) => Buffer.from(JSON.stringify(data)).toString("base64"); +const mixedCredentials = [ + { type: "npm_registry", host: "npm.pkg.github.com", token: "abc" }, + { type: "maven_repository", host: "maven.pkg.github.com", token: "def" }, + { type: "nuget_feed", host: "nuget.pkg.github.com", token: "ghi" }, + { type: "goproxy_server", host: "goproxy.example.com", token: "jkl" }, + { type: "git_source", host: "github.com/github", token: "mno" }, +]; + test("getCredentials prefers registriesCredentials over registrySecrets", async (t) => { const registryCredentials = Buffer.from( JSON.stringify([ @@ -94,13 +105,6 @@ test("getCredentials throws error when credential missing host and url", async ( }); test("getCredentials filters by language when specified", async (t) => { - const mixedCredentials = [ - { type: "npm_registry", host: "npm.pkg.github.com", token: "abc" }, - { type: "maven_repository", host: "maven.pkg.github.com", token: "def" }, - { type: "nuget_feed", host: "nuget.pkg.github.com", token: "ghi" }, - { type: "goproxy_server", host: "goproxy.example.com", token: "jkl" }, - ]; - const credentials = startProxyExports.getCredentials( getRunnerLogger(true), undefined, @@ -111,13 +115,21 @@ test("getCredentials filters by language when specified", async (t) => { t.is(credentials[0].type, "maven_repository"); }); +test("getCredentials returns all for a language when specified", async (t) => { + const credentials = startProxyExports.getCredentials( + getRunnerLogger(true), + undefined, + toEncodedJSON(mixedCredentials), + "go", + ); + t.is(credentials.length, 2); + + const credentialsTypes = credentials.map((c) => c.type); + t.assert(credentialsTypes.includes("goproxy_server")); + t.assert(credentialsTypes.includes("git_source")); +}); + test("getCredentials returns all credentials when no language specified", async (t) => { - const mixedCredentials = [ - { type: "npm_registry", host: "npm.pkg.github.com", token: "abc" }, - { type: "maven_repository", host: "maven.pkg.github.com", token: "def" }, - { type: "nuget_feed", host: "nuget.pkg.github.com", token: "ghi" }, - { type: "goproxy_server", host: "goproxy.example.com", token: "jkl" }, - ]; const credentialsInput = toEncodedJSON(mixedCredentials); const credentials = startProxyExports.getCredentials( @@ -188,3 +200,68 @@ test("parseLanguage", async (t) => { t.deepEqual(parseLanguage(" "), undefined); t.deepEqual(parseLanguage(""), undefined); }); + +function mockGetReleaseByTag(assets?: Array<{ name: string; url?: string }>) { + const mockClient = sinon.stub(apiClient, "getApiClient"); + const getReleaseByTag = + assets === undefined + ? sinon.stub().rejects() + : sinon.stub().resolves({ + status: 200, + data: { assets }, + headers: {}, + url: "GET /repos/:owner/:repo/releases/tags/:tag", + }); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + mockClient.returns({ + rest: { + repos: { + getReleaseByTag, + }, + }, + } as any); + return mockClient; +} + +test("getDownloadUrl returns fallback when `getLinkedRelease` rejects", async (t) => { + mockGetReleaseByTag(); + + const info = await startProxyExports.getDownloadUrl(getRunnerLogger(true)); + + t.is(info.version, startProxyExports.UPDATEJOB_PROXY_VERSION); + t.is( + info.url, + startProxyExports.getFallbackUrl(startProxyExports.getProxyPackage()), + ); +}); + +test("getDownloadUrl returns fallback when there's no matching release asset", async (t) => { + const testAssets = [[], [{ name: "foo" }]]; + + for (const assets of testAssets) { + const stub = mockGetReleaseByTag(assets); + const info = await startProxyExports.getDownloadUrl(getRunnerLogger(true)); + + t.is(info.version, startProxyExports.UPDATEJOB_PROXY_VERSION); + t.is( + info.url, + startProxyExports.getFallbackUrl(startProxyExports.getProxyPackage()), + ); + + stub.restore(); + } +}); + +test("getDownloadUrl returns matching release asset", async (t) => { + const assets = [ + { name: "foo", url: "other-url" }, + { name: startProxyExports.getProxyPackage(), url: "url-we-want" }, + ]; + mockGetReleaseByTag(assets); + + const info = await startProxyExports.getDownloadUrl(getRunnerLogger(true)); + + t.is(info.version, defaults.cliVersion); + t.is(info.url, "url-we-want"); +}); diff --git a/src/start-proxy.ts b/src/start-proxy.ts index d74884bfd4..dd1e443b76 100644 --- a/src/start-proxy.ts +++ b/src/start-proxy.ts @@ -1,8 +1,15 @@ import * as core from "@actions/core"; +import { getApiClient } from "./api-client"; +import * as defaults from "./defaults.json"; import { KnownLanguage } from "./languages"; import { Logger } from "./logging"; -import { ConfigurationError } from "./util"; +import { ConfigurationError, getErrorMessage, isDefined } from "./util"; + +export const UPDATEJOB_PROXY = "update-job-proxy"; +export const UPDATEJOB_PROXY_VERSION = "v2.0.20250624110901"; +export const UPDATEJOB_PROXY_URL_PREFIX = + "https://github.com/github/codeql-action/releases/download/codeql-bundle-v2.22.0/"; export type Credential = { type: string; @@ -55,25 +62,16 @@ export function parseLanguage(language: string): KnownLanguage | undefined { return undefined; } -const LANGUAGE_TO_REGISTRY_TYPE: Partial> = { - java: "maven_repository", - csharp: "nuget_feed", - javascript: "npm_registry", - python: "python_index", - ruby: "rubygems_server", - rust: "cargo_registry", - go: "goproxy_server", +const LANGUAGE_TO_REGISTRY_TYPE: Partial> = { + java: ["maven_repository"], + csharp: ["nuget_feed"], + javascript: ["npm_registry"], + python: ["python_index"], + ruby: ["rubygems_server"], + rust: ["cargo_registry"], + go: ["goproxy_server", "git_source"], } as const; -/** - * Checks that `value` is neither `undefined` nor `null`. - * @param value The value to test. - * @returns Narrows the type of `value` to exclude `undefined` and `null`. - */ -function isDefined(value: T | null | undefined): value is T { - return value !== undefined && value !== null; -} - // getCredentials returns registry credentials from action inputs. // It prefers `registries_credentials` over `registry_secrets`. // If neither is set, it returns an empty array. @@ -140,7 +138,10 @@ export function getCredentials( // Filter credentials based on language if specified. `type` is the registry type. // E.g., "maven_feed" for Java/Kotlin, "nuget_repository" for C#. - if (registryTypeForLanguage && e.type !== registryTypeForLanguage) { + if ( + registryTypeForLanguage && + !registryTypeForLanguage.some((t) => t === e.type) + ) { continue; } @@ -172,3 +173,87 @@ export function getCredentials( } return out; } + +/** + * Gets the name of the proxy release asset for the current platform. + */ +export function getProxyPackage(): string { + const platform = + process.platform === "win32" + ? "win64" + : process.platform === "darwin" + ? "osx64" + : "linux64"; + return `${UPDATEJOB_PROXY}-${platform}.tar.gz`; +} + +/** + * Gets the fallback URL for downloading the proxy release asset. + * + * @param proxyPackage The asset name. + * @returns The full URL to download the specified asset from the fallback release. + */ +export function getFallbackUrl(proxyPackage: string): string { + return `${UPDATEJOB_PROXY_URL_PREFIX}${proxyPackage}`; +} + +/** + * Uses the GitHub API to obtain information about the CodeQL CLI bundle release + * that is pointed at by `defaults.json`. + * + * @returns The response from the GitHub API. + */ +export async function getLinkedRelease() { + return getApiClient().rest.repos.getReleaseByTag({ + owner: "github", + repo: "codeql-action", + tag: defaults.bundleVersion, + }); +} + +/** + * Determines the URL of the proxy release asset that we should download if its not + * already in the toolcache, and its version. + * + * @param logger The logger to use. + * @returns Returns the download URL and version of the proxy package we plan to use. + */ +export async function getDownloadUrl( + logger: Logger, +): Promise<{ url: string; version: string }> { + const proxyPackage = getProxyPackage(); + + try { + // Try to retrieve information about the CLI bundle release pointed at by `defaults.json`. + const cliRelease = await getLinkedRelease(); + + // Search the release's assets to find the one we are looking for. + for (const asset of cliRelease.data.assets) { + if (asset.name === proxyPackage) { + logger.info( + `Found '${proxyPackage}' in release '${defaults.bundleVersion}' at '${asset.url}'`, + ); + return { + url: asset.url, + // The `update-job-proxy` doesn't have a version as such. Since we now bundle it + // with CodeQL CLI bundle releases, we use the corresponding CLI version to + // differentiate between (potentially) different versions of `update-job-proxy`. + version: defaults.cliVersion, + }; + } + } + } catch (ex) { + logger.warning( + `Failed to retrieve information about the linked release: ${getErrorMessage(ex)}`, + ); + } + + // Fallback to the hard-coded URL. + logger.info( + `Did not find '${proxyPackage}' in the linked release, falling back to hard-coded version.`, + ); + return { + url: getFallbackUrl(proxyPackage), + version: UPDATEJOB_PROXY_VERSION, + }; +} diff --git a/src/status-report.test.ts b/src/status-report.test.ts index 9a61fcee08..0d3292637c 100644 --- a/src/status-report.test.ts +++ b/src/status-report.test.ts @@ -2,13 +2,18 @@ import test from "ava"; import * as sinon from "sinon"; import * as actionsUtil from "./actions-util"; +import { Config } from "./config-utils"; import { EnvVar } from "./environment"; import { KnownLanguage } from "./languages"; import { getRunnerLogger } from "./logging"; +import { ToolsSource } from "./setup-codeql"; import { ActionName, + createInitWithConfigStatusReport, createStatusReportBase, getActionsStatus, + InitStatusReport, + InitWithConfigStatusReport, } from "./status-report"; import { setupTests, @@ -243,3 +248,103 @@ test("getActionStatus handling correctly various types of errors", (t) => { "We still recognise a wrapped ConfigurationError as a user error", ); }); + +const testCreateInitWithConfigStatusReport = test.macro({ + exec: async ( + t, + _title: string, + config: Config, + expectedReportProperties: Partial, + ) => { + await withTmpDir(async (tmpDir: string) => { + setupEnvironmentAndStub(tmpDir); + + const statusReportBase = await createStatusReportBase( + ActionName.Init, + "failure", + new Date("May 19, 2023 05:19:00"), + config, + { numAvailableBytes: 100, numTotalBytes: 500 }, + getRunnerLogger(false), + "failure cause", + "exception stack trace", + ); + + if (t.truthy(statusReportBase)) { + const initStatusReport: InitStatusReport = { + ...statusReportBase, + tools_input: "", + tools_resolved_version: "foo", + tools_source: ToolsSource.Unknown, + workflow_languages: "actions", + }; + + const initWithConfigStatusReport = + await createInitWithConfigStatusReport( + config, + initStatusReport, + undefined, + 1024, + undefined, + ); + + if (t.truthy(initWithConfigStatusReport)) { + t.like(initWithConfigStatusReport, expectedReportProperties); + } + } + }); + }, + title: (_, title) => `createInitWithConfigStatusReport: ${title}`, +}); + +test( + testCreateInitWithConfigStatusReport, + "returns a value", + createTestConfig({ + buildMode: BuildMode.None, + languages: [KnownLanguage.java, KnownLanguage.swift], + }), + { + trap_cache_download_size_bytes: 1024, + registries: "[]", + query_filters: "[]", + packs: "{}", + }, +); + +test( + testCreateInitWithConfigStatusReport, + "includes packs for a single language", + createTestConfig({ + buildMode: BuildMode.None, + languages: [KnownLanguage.java], + computedConfig: { + packs: ["foo", "bar"], + }, + }), + { + registries: "[]", + query_filters: "[]", + packs: JSON.stringify({ java: ["foo", "bar"] }), + }, +); + +test( + testCreateInitWithConfigStatusReport, + "includes packs for multiple languages", + createTestConfig({ + buildMode: BuildMode.None, + languages: [KnownLanguage.java, KnownLanguage.swift], + computedConfig: { + packs: { java: ["java-foo", "java-bar"], swift: ["swift-bar"] }, + }, + }), + { + registries: "[]", + query_filters: "[]", + packs: JSON.stringify({ + java: ["java-foo", "java-bar"], + swift: ["swift-bar"], + }), + }, +); diff --git a/src/status-report.ts b/src/status-report.ts index e75698e9e0..75f4002214 100644 --- a/src/status-report.ts +++ b/src/status-report.ts @@ -12,12 +12,14 @@ import { isSelfHostedRunner, } from "./actions-util"; import { getAnalysisKey, getApiClient } from "./api-client"; -import { type Config } from "./config-utils"; +import { parseRegistriesWithoutCredentials, type Config } from "./config-utils"; import { DocUrl } from "./doc-url"; import { EnvVar } from "./environment"; import { getRef } from "./git-utils"; import { Logger } from "./logging"; +import { OverlayBaseDatabaseDownloadStats } from "./overlay-database-utils"; import { getRepositoryNwo } from "./repository"; +import { ToolsSource } from "./setup-codeql"; import { ConfigurationError, isHTTPError, @@ -460,3 +462,119 @@ export async function sendStatusReport( ); } } + +/** Fields of the init status report that can be sent before `config` is populated. */ +export interface InitStatusReport extends StatusReportBase { + /** Value given by the user as the "tools" input. */ + tools_input: string; + /** Version of the bundle used. */ + tools_resolved_version: string; + /** Where the bundle originated from. */ + tools_source: ToolsSource; + /** Comma-separated list of languages specified explicitly in the workflow file. */ + workflow_languages: string; +} + +/** Fields of the init status report that are populated using values from `config`. */ +export interface InitWithConfigStatusReport extends InitStatusReport { + /** Comma-separated list of languages where the default queries are disabled. */ + disable_default_queries: string; + /** Comma-separated list of paths, from the 'paths' config field. */ + paths: string; + /** Comma-separated list of paths, from the 'paths-ignore' config field. */ + paths_ignore: string; + /** Comma-separated list of queries sources, from the 'queries' config field or workflow input. */ + queries: string; + /** Stringified JSON object of packs, from the 'packs' config field or workflow input. */ + packs: string; + /** Comma-separated list of languages for which we are using TRAP caching. */ + trap_cache_languages: string; + /** Size of TRAP caches that we downloaded, in bytes. */ + trap_cache_download_size_bytes: number; + /** Time taken to download TRAP caches, in milliseconds. */ + trap_cache_download_duration_ms: number; + /** Size of the overlay-base database that we downloaded, in bytes. */ + overlay_base_database_download_size_bytes?: number; + /** Time taken to download the overlay-base database, in milliseconds. */ + overlay_base_database_download_duration_ms?: number; + /** Stringified JSON array of registry configuration objects, from the 'registries' config field + or workflow input. **/ + registries: string; + /** Stringified JSON object representing a query-filters, from the 'query-filters' config field. **/ + query_filters: string; + /** Path to the specified code scanning config file, from the 'config-file' config field. */ + config_file: string; +} + +/** + * Composes a `InitWithConfigStatusReport` from the given values. + * + * @param config The CodeQL Action configuration whose values should be added to the base status report. + * @param initStatusReport The base status report. + * @param configFile Optionally, the filename of the configuration file that was read. + * @param totalCacheSize The computed total TRAP cache size. + * @param overlayBaseDatabaseStats Statistics about the overlay database, if any. + * @returns + */ +export async function createInitWithConfigStatusReport( + config: Config, + initStatusReport: InitStatusReport, + configFile: string | undefined, + totalCacheSize: number, + overlayBaseDatabaseStats: OverlayBaseDatabaseDownloadStats | undefined, +): Promise { + const languages = config.languages.join(","); + const paths = (config.originalUserInput.paths || []).join(","); + const pathsIgnore = (config.originalUserInput["paths-ignore"] || []).join( + ",", + ); + const disableDefaultQueries = config.originalUserInput[ + "disable-default-queries" + ] + ? languages + : ""; + + const queries: string[] = []; + let queriesInput = getOptionalInput("queries")?.trim(); + if (queriesInput === undefined || queriesInput.startsWith("+")) { + queries.push( + ...(config.originalUserInput.queries || []).map((q) => q.uses), + ); + } + if (queriesInput !== undefined) { + queriesInput = queriesInput.startsWith("+") + ? queriesInput.slice(1) + : queriesInput; + queries.push(...queriesInput.split(",")); + } + + let packs: Record = {}; + if (Array.isArray(config.computedConfig.packs)) { + packs[config.languages[0]] = config.computedConfig.packs; + } else if (config.computedConfig.packs !== undefined) { + packs = config.computedConfig.packs; + } + + return { + ...initStatusReport, + config_file: configFile ?? "", + disable_default_queries: disableDefaultQueries, + paths, + paths_ignore: pathsIgnore, + queries: queries.join(","), + packs: JSON.stringify(packs), + trap_cache_languages: Object.keys(config.trapCaches).join(","), + trap_cache_download_size_bytes: totalCacheSize, + trap_cache_download_duration_ms: Math.round(config.trapCacheDownloadTime), + overlay_base_database_download_size_bytes: + overlayBaseDatabaseStats?.databaseSizeBytes, + overlay_base_database_download_duration_ms: + overlayBaseDatabaseStats?.databaseDownloadDurationMs, + query_filters: JSON.stringify( + config.originalUserInput["query-filters"] ?? [], + ), + registries: JSON.stringify( + parseRegistriesWithoutCredentials(getOptionalInput("registries")) ?? [], + ), + }; +} diff --git a/src/testing-utils.ts b/src/testing-utils.ts index 624bb72cd5..c930d5350c 100644 --- a/src/testing-utils.ts +++ b/src/testing-utils.ts @@ -6,6 +6,7 @@ import { TestFn } from "ava"; import nock from "nock"; import * as sinon from "sinon"; +import { getActionVersion } from "./actions-util"; import { AnalysisKind } from "./analyses"; import * as apiClient from "./api-client"; import { GitHubApiDetails } from "./api-client"; @@ -356,10 +357,12 @@ export function createTestConfig(overrides: Partial): Config { return Object.assign( {}, { + version: getActionVersion(), analysisKinds: [AnalysisKind.CodeScanning], languages: [], buildMode: undefined, originalUserInput: {}, + computedConfig: {}, tempDir: "", codeQLCmd: "", gitHubVersion: { @@ -369,16 +372,12 @@ export function createTestConfig(overrides: Partial): Config { debugMode: false, debugArtifactName: DEFAULT_DEBUG_ARTIFACT_NAME, debugDatabaseName: DEFAULT_DEBUG_DATABASE_NAME, - augmentationProperties: { - packsInputCombines: false, - queriesInputCombines: false, - extraQueryExclusions: [], - overlayDatabaseMode: OverlayDatabaseMode.None, - useOverlayDatabaseCaching: false, - }, trapCaches: {}, trapCacheDownloadTime: 0, dependencyCachingEnabled: CachingKind.None, + extraQueryExclusions: [], + overlayDatabaseMode: OverlayDatabaseMode.None, + useOverlayDatabaseCaching: false, } satisfies Config, overrides, ); diff --git a/src/tools-features.ts b/src/tools-features.ts index 7db27edf1b..0e88ccd92f 100644 --- a/src/tools-features.ts +++ b/src/tools-features.ts @@ -4,11 +4,12 @@ import type { VersionInfo } from "./codeql"; export enum ToolsFeature { AnalysisSummaryV2IsDefault = "analysisSummaryV2Default", + BuiltinExtractorsSpecifyDefaultQueries = "builtinExtractorsSpecifyDefaultQueries", DatabaseInterpretResultsSupportsSarifRunProperty = "databaseInterpretResultsSupportsSarifRunProperty", - IndirectTracingSupportsStaticBinaries = "indirectTracingSupportsStaticBinaries", - SarifMergeRunsFromEqualCategory = "sarifMergeRunsFromEqualCategory", ForceOverwrite = "forceOverwrite", + IndirectTracingSupportsStaticBinaries = "indirectTracingSupportsStaticBinaries", PythonDefaultIsToNotExtractStdlib = "pythonDefaultIsToNotExtractStdlib", + SarifMergeRunsFromEqualCategory = "sarifMergeRunsFromEqualCategory", } /** diff --git a/src/upload-lib.test.ts b/src/upload-lib.test.ts index 96f132b210..bfa5e9844c 100644 --- a/src/upload-lib.test.ts +++ b/src/upload-lib.test.ts @@ -3,6 +3,7 @@ import * as path from "path"; import test from "ava"; +import { CodeQuality, CodeScanning } from "./analyses"; import { getRunnerLogger, Logger } from "./logging"; import { setupTests } from "./testing-utils"; import * as uploadLib from "./upload-lib"; @@ -128,7 +129,7 @@ test("finding SARIF files", async (t) => { const sarifFiles = uploadLib.findSarifFilesInDir( tmpDir, - uploadLib.CodeScanningTarget.sarifPredicate, + CodeScanning.sarifPredicate, ); t.deepEqual(sarifFiles, [ @@ -140,7 +141,7 @@ test("finding SARIF files", async (t) => { const qualitySarifFiles = uploadLib.findSarifFilesInDir( tmpDir, - uploadLib.CodeQualityTarget.sarifPredicate, + CodeQuality.sarifPredicate, ); t.deepEqual(qualitySarifFiles, [ @@ -211,109 +212,237 @@ test("populateRunAutomationDetails", (t) => { }); test("validateUniqueCategory when empty", (t) => { - t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif())); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif())); + t.notThrows(() => + uploadLib.validateUniqueCategory( + createMockSarif(), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif(), + CodeScanning.sentinelPrefix, + ), + ); }); test("validateUniqueCategory for automation details id", (t) => { - t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif("abc"))); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc"))); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("AbC"))); + t.notThrows(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("AbC"), + CodeScanning.sentinelPrefix, + ), + ); - t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif("def"))); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("def"))); + t.notThrows(() => + uploadLib.validateUniqueCategory( + createMockSarif("def"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("def"), + CodeScanning.sentinelPrefix, + ), + ); // Our category sanitization is not perfect. Here are some examples // of where we see false clashes t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("abc/def")), + uploadLib.validateUniqueCategory( + createMockSarif("abc/def"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc@def"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc_def"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc def"), + CodeScanning.sentinelPrefix, + ), ); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc@def"))); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc_def"))); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc def"))); // this one is fine t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("abc_ def")), + uploadLib.validateUniqueCategory( + createMockSarif("abc_ def"), + CodeScanning.sentinelPrefix, + ), ); }); test("validateUniqueCategory for tool name", (t) => { t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "abc"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "abc"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "AbC")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "AbC"), + CodeScanning.sentinelPrefix, + ), ); t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "def")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "def"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "def")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "def"), + CodeScanning.sentinelPrefix, + ), ); // Our category sanitization is not perfect. Here are some examples // of where we see false clashes t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc/def")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "abc/def"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc@def")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "abc@def"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc_def")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "abc_def"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif(undefined, "abc def")), + uploadLib.validateUniqueCategory( + createMockSarif(undefined, "abc def"), + CodeScanning.sentinelPrefix, + ), ); // this one is fine t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("abc_ def")), + uploadLib.validateUniqueCategory( + createMockSarif("abc_ def"), + CodeScanning.sentinelPrefix, + ), ); }); test("validateUniqueCategory for automation details id and tool name", (t) => { t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("abc", "abc")), + uploadLib.validateUniqueCategory( + createMockSarif("abc", "abc"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif("abc", "abc")), + uploadLib.validateUniqueCategory( + createMockSarif("abc", "abc"), + CodeScanning.sentinelPrefix, + ), ); t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("abc_", "def")), + uploadLib.validateUniqueCategory( + createMockSarif("abc_", "def"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif("abc_", "def")), + uploadLib.validateUniqueCategory( + createMockSarif("abc_", "def"), + CodeScanning.sentinelPrefix, + ), ); t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("ghi", "_jkl")), + uploadLib.validateUniqueCategory( + createMockSarif("ghi", "_jkl"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif("ghi", "_jkl")), + uploadLib.validateUniqueCategory( + createMockSarif("ghi", "_jkl"), + CodeScanning.sentinelPrefix, + ), ); // Our category sanitization is not perfect. Here are some examples // of where we see false clashes - t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif("abc"))); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc", "_"))); + t.notThrows(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc", "_"), + CodeScanning.sentinelPrefix, + ), + ); t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("abc", "def__")), + uploadLib.validateUniqueCategory( + createMockSarif("abc", "def__"), + CodeScanning.sentinelPrefix, + ), + ); + t.throws(() => + uploadLib.validateUniqueCategory( + createMockSarif("abc_def"), + CodeScanning.sentinelPrefix, + ), ); - t.throws(() => uploadLib.validateUniqueCategory(createMockSarif("abc_def"))); t.notThrows(() => - uploadLib.validateUniqueCategory(createMockSarif("mno_", "pqr")), + uploadLib.validateUniqueCategory( + createMockSarif("mno_", "pqr"), + CodeScanning.sentinelPrefix, + ), ); t.throws(() => - uploadLib.validateUniqueCategory(createMockSarif("mno", "_pqr")), + uploadLib.validateUniqueCategory( + createMockSarif("mno", "_pqr"), + CodeScanning.sentinelPrefix, + ), ); }); @@ -323,19 +452,30 @@ test("validateUniqueCategory for multiple runs", (t) => { // duplicate categories are allowed within the same sarif file const multiSarif = { runs: [sarif1.runs[0], sarif1.runs[0], sarif2.runs[0]] }; - t.notThrows(() => uploadLib.validateUniqueCategory(multiSarif)); + t.notThrows(() => + uploadLib.validateUniqueCategory(multiSarif, CodeScanning.sentinelPrefix), + ); // should throw if there are duplicate categories in separate validations - t.throws(() => uploadLib.validateUniqueCategory(sarif1)); - t.throws(() => uploadLib.validateUniqueCategory(sarif2)); + t.throws(() => + uploadLib.validateUniqueCategory(sarif1, CodeScanning.sentinelPrefix), + ); + t.throws(() => + uploadLib.validateUniqueCategory(sarif2, CodeScanning.sentinelPrefix), + ); }); test("validateUniqueCategory with different prefixes", (t) => { - t.notThrows(() => uploadLib.validateUniqueCategory(createMockSarif())); t.notThrows(() => uploadLib.validateUniqueCategory( createMockSarif(), - uploadLib.CodeQualityTarget.sentinelPrefix, + CodeScanning.sentinelPrefix, + ), + ); + t.notThrows(() => + uploadLib.validateUniqueCategory( + createMockSarif(), + CodeQuality.sentinelPrefix, ), ); }); diff --git a/src/upload-lib.ts b/src/upload-lib.ts index e87dad839f..650e7a803a 100644 --- a/src/upload-lib.ts +++ b/src/upload-lib.ts @@ -8,6 +8,7 @@ import { OctokitResponse } from "@octokit/types"; import * as jsonschema from "jsonschema"; import * as actionsUtil from "./actions-util"; +import * as analyses from "./analyses"; import * as api from "./api-client"; import { getGitHubVersion, wrapApiConfigurationError } from "./api-client"; import { CodeQL, getCodeQL } from "./codeql"; @@ -345,19 +346,13 @@ function getAutomationID( return api.computeAutomationID(analysis_key, environment); } -// Enumerates API endpoints that accept SARIF files. -export enum SARIF_UPLOAD_ENDPOINT { - CODE_SCANNING = "PUT /repos/:owner/:repo/code-scanning/analysis", - CODE_QUALITY = "PUT /repos/:owner/:repo/code-quality/analysis", -} - // Upload the given payload. // If the request fails then this will retry a small number of times. async function uploadPayload( payload: any, repositoryNwo: RepositoryNwo, logger: Logger, - target: SARIF_UPLOAD_ENDPOINT, + target: analyses.SARIF_UPLOAD_ENDPOINT, ): Promise { logger.info("Uploading results"); @@ -616,31 +611,6 @@ export function buildPayload( return payloadObj; } -// Represents configurations for different services that we can upload SARIF to. -export interface UploadTarget { - name: string; - target: SARIF_UPLOAD_ENDPOINT; - sarifPredicate: (name: string) => boolean; - sentinelPrefix: string; -} - -// Represents the Code Scanning upload target. -export const CodeScanningTarget: UploadTarget = { - name: "code scanning", - target: SARIF_UPLOAD_ENDPOINT.CODE_SCANNING, - sarifPredicate: (name) => - name.endsWith(".sarif") && !CodeQualityTarget.sarifPredicate(name), - sentinelPrefix: "CODEQL_UPLOAD_SARIF_", -}; - -// Represents the Code Quality upload target. -export const CodeQualityTarget: UploadTarget = { - name: "code quality", - target: SARIF_UPLOAD_ENDPOINT.CODE_QUALITY, - sarifPredicate: (name) => name.endsWith(".quality.sarif"), - sentinelPrefix: "CODEQL_UPLOAD_QUALITY_SARIF_", -}; - /** * Uploads a single SARIF file or a directory of SARIF files depending on what `inputSarifPath` refers * to. @@ -651,7 +621,7 @@ export async function uploadFiles( category: string | undefined, features: FeatureEnablement, logger: Logger, - uploadTarget: UploadTarget, + uploadTarget: analyses.AnalysisConfig, ): Promise { const sarifPaths = getSarifFilePaths( inputSarifPath, @@ -677,7 +647,7 @@ export async function uploadSpecifiedFiles( category: string | undefined, features: FeatureEnablement, logger: Logger, - uploadTarget: UploadTarget = CodeScanningTarget, + uploadTarget: analyses.AnalysisConfig, ): Promise { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); @@ -726,6 +696,12 @@ export async function uploadSpecifiedFiles( validateUniqueCategory(sarif, uploadTarget.sentinelPrefix); logger.debug(`Serializing SARIF for upload`); const sarifPayload = JSON.stringify(sarif); + + const dumpDir = process.env[EnvVar.SARIF_DUMP_DIR]; + if (dumpDir) { + dumpSarifFile(sarifPayload, dumpDir, logger, uploadTarget); + } + logger.debug(`Compressing serialized SARIF`); const zippedSarif = zlib.gzipSync(sarifPayload).toString("base64"); const checkoutURI = url.pathToFileURL(checkoutPath).href; @@ -772,6 +748,30 @@ export async function uploadSpecifiedFiles( }; } +/** + * Dumps the given processed SARIF file contents to `outputDir`. + */ +function dumpSarifFile( + sarifPayload: string, + outputDir: string, + logger: Logger, + uploadTarget: analyses.AnalysisConfig, +) { + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); + } else if (!fs.lstatSync(outputDir).isDirectory()) { + throw new ConfigurationError( + `The path specified by the ${EnvVar.SARIF_DUMP_DIR} environment variable exists and is not a directory: ${outputDir}`, + ); + } + const outputFile = path.resolve( + outputDir, + `upload${uploadTarget.sarifExtension}`, + ); + logger.info(`Dumping processed SARIF file to ${outputFile}`); + fs.writeFileSync(outputFile, sarifPayload); +} + const STATUS_CHECK_FREQUENCY_MILLISECONDS = 5 * 1000; const STATUS_CHECK_TIMEOUT_MILLISECONDS = 2 * 60 * 1000; @@ -943,7 +943,7 @@ function handleProcessingResultForUnsuccessfulExecution( export function validateUniqueCategory( sarif: SarifFile, - sentinelPrefix: string = CodeScanningTarget.sentinelPrefix, + sentinelPrefix: string, ): void { // duplicate categories are allowed in the same sarif file // but not across multiple sarif files diff --git a/src/upload-sarif-action.ts b/src/upload-sarif-action.ts index 25e884ea0f..a193e242a6 100644 --- a/src/upload-sarif-action.ts +++ b/src/upload-sarif-action.ts @@ -4,6 +4,7 @@ import * as core from "@actions/core"; import * as actionsUtil from "./actions-util"; import { getActionVersion, getTemporaryDirectory } from "./actions-util"; +import * as analyses from "./analyses"; import { getGitHubVersion } from "./api-client"; import { Features } from "./feature-flags"; import { Logger, getActionsLogger } from "./logging"; @@ -95,7 +96,7 @@ async function run() { category, features, logger, - upload_lib.CodeScanningTarget, + analyses.CodeScanning, ); core.setOutput("sarif-id", uploadResult.sarifID); @@ -105,7 +106,7 @@ async function run() { if (fs.lstatSync(sarifPath).isDirectory()) { const qualitySarifFiles = upload_lib.findSarifFilesInDir( sarifPath, - upload_lib.CodeQualityTarget.sarifPredicate, + analyses.CodeQuality.sarifPredicate, ); if (qualitySarifFiles.length !== 0) { @@ -115,7 +116,7 @@ async function run() { actionsUtil.fixCodeQualityCategory(logger, category), features, logger, - upload_lib.CodeQualityTarget, + analyses.CodeQuality, ); } } diff --git a/src/util.ts b/src/util.ts index 1ac24ad124..5ef037636f 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1278,3 +1278,12 @@ export async function asyncSome( const results = await Promise.all(array.map(predicate)); return results.some((result) => result); } + +/** + * Checks that `value` is neither `undefined` nor `null`. + * @param value The value to test. + * @returns Narrows the type of `value` to exclude `undefined` and `null`. + */ +export function isDefined(value: T | null | undefined): value is T { + return value !== undefined && value !== null; +} diff --git a/src/workflow.test.ts b/src/workflow.test.ts index 21a5874f02..9af81459ef 100644 --- a/src/workflow.test.ts +++ b/src/workflow.test.ts @@ -655,6 +655,65 @@ test("getWorkflowErrors() should not report a warning if there is a workflow_cal t.deepEqual(...errorCodes(errors, [])); }); +test("getWorkflowErrors() should report a warning if different versions of the CodeQL Action are used", async (t) => { + const errors = await getWorkflowErrors( + yaml.load(` + name: "CodeQL" + on: + push: + branches: [main] + jobs: + analyze: + steps: + - uses: github/codeql-action/init@v2 + - uses: github/codeql-action/analyze@v3 + `) as Workflow, + await getCodeQLForTesting(), + ); + + t.deepEqual( + ...errorCodes(errors, [WorkflowErrors.InconsistentActionVersion]), + ); +}); + +test("getWorkflowErrors() should not report a warning if the same versions of the CodeQL Action are used", async (t) => { + const errors = await getWorkflowErrors( + yaml.load(` + name: "CodeQL" + on: + push: + branches: [main] + jobs: + analyze: + steps: + - uses: github/codeql-action/init@v3 + - uses: github/codeql-action/analyze@v3 + `) as Workflow, + await getCodeQLForTesting(), + ); + + t.deepEqual(...errorCodes(errors, [])); +}); + +test("getWorkflowErrors() should not report a warning involving versions of other actions", async (t) => { + const errors = await getWorkflowErrors( + yaml.load(` + name: "CodeQL" + on: + push: + branches: [main] + jobs: + analyze: + steps: + - uses: actions/checkout@v5 + - uses: github/codeql-action/init@v3 + `) as Workflow, + await getCodeQLForTesting(), + ); + + t.deepEqual(...errorCodes(errors, [])); +}); + test("getCategoryInputOrThrow returns category for simple workflow with category", (t) => { process.env["GITHUB_REPOSITORY"] = "github/codeql-action-fake-repository"; t.is( diff --git a/src/workflow.ts b/src/workflow.ts index 37094154e1..ee95c337f5 100644 --- a/src/workflow.ts +++ b/src/workflow.ts @@ -72,6 +72,7 @@ function toCodedErrors(errors: { export const WorkflowErrors = toCodedErrors({ MissingPushHook: `Please specify an on.push hook to analyze and see code scanning alerts from the default branch on the Security tab.`, CheckoutWrongHead: `git checkout HEAD^2 is no longer necessary. Please remove this step as Code Scanning recommends analyzing the merge commit for best results.`, + InconsistentActionVersion: `Not all workflow steps that use \`github/codeql-action\` actions use the same version. Please ensure that all such steps use the same version to avoid compatibility issues.`, }); /** @@ -161,6 +162,29 @@ export async function getWorkflowErrors( } } + // Check that all `github/codeql-action` steps use the same ref, i.e. the same version. + // Mixing different versions of the actions can lead to unpredictable behaviour. + const codeqlStepRefs: string[] = []; + for (const job of Object.values(doc?.jobs || {})) { + if (Array.isArray(job.steps)) { + for (const step of job.steps) { + if (step.uses?.startsWith("github/codeql-action/")) { + const parts = step.uses.split("@"); + if (parts.length >= 2) { + codeqlStepRefs.push(parts[parts.length - 1]); + } + } + } + } + } + + if ( + codeqlStepRefs.length > 0 && + !codeqlStepRefs.every((ref) => ref === codeqlStepRefs[0]) + ) { + errors.push(WorkflowErrors.InconsistentActionVersion); + } + // If there is no push trigger, we will not be able to analyze the default branch. // So add a warning to the user to add a push trigger. // If there is a workflow_call trigger, we don't need a push trigger since we assume diff --git a/tests/multi-language-repo/.gitignore b/tests/multi-language-repo/.gitignore index 3b29812086..b8703de742 100644 --- a/tests/multi-language-repo/.gitignore +++ b/tests/multi-language-repo/.gitignore @@ -1,9 +1,11 @@ .DS_Store /.build /Packages +/obj /*.xcodeproj xcuserdata/ DerivedData/ .swiftpm/config/registries.json .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata .netrc +multi-language-repo.sln