diff --git a/.github/actions/check-codescanning-config/index.ts b/.github/actions/check-codescanning-config/index.ts index 0596e4fe9b..ea99ca3653 100644 --- a/.github/actions/check-codescanning-config/index.ts +++ b/.github/actions/check-codescanning-config/index.ts @@ -6,6 +6,16 @@ import * as assert from 'assert' const actualConfig = loadActualConfig() +function sortConfigArrays(config) { + for (const key of Object.keys(config)) { + const value = config[key]; + if (key === 'queries' && Array.isArray(value)) { + config[key] = value.sort(); + } + } + return config; +} + const rawExpectedConfig = process.argv[3].trim() if (!rawExpectedConfig) { core.setFailed('No expected configuration provided') @@ -18,8 +28,8 @@ if (!rawExpectedConfig) { const expectedConfig = rawExpectedConfig ? JSON.parse(rawExpectedConfig) : undefined; assert.deepStrictEqual( - actualConfig, - expectedConfig, + sortConfigArrays(actualConfig), + sortConfigArrays(expectedConfig), 'Expected configuration does not match actual configuration' ); diff --git a/.github/actions/prepare-test/action.yml b/.github/actions/prepare-test/action.yml index 8e8227c3ac..ecabaa69f3 100644 --- a/.github/actions/prepare-test/action.yml +++ b/.github/actions/prepare-test/action.yml @@ -2,7 +2,7 @@ name: "Prepare test" description: Performs some preparation to run tests inputs: version: - description: "The version of the CodeQL CLI to use. Can be 'linked', 'default', 'nightly-latest', 'nightly-YYYYMMDD', or 'stable-vX.Y.Z" + description: "The version of the CodeQL CLI to use. Can be 'linked', 'default', 'nightly', 'nightly-latest', 'nightly-YYYYMMDD', or 'stable-vX.Y.Z" required: true use-all-platform-bundle: description: "If true, we output a tools URL with codeql-bundle.tar.gz file rather than platform-specific URL" @@ -35,7 +35,10 @@ runs: run: | set -e # Fail this Action if `gh release list` fails. - if [[ "$VERSION" == "linked" ]]; then + if [[ "$VERSION" == "nightly" || "$VERSION" == "nightly-latest" ]]; then + echo "tools-url=nightly" >> "$GITHUB_OUTPUT" + exit 0 + elif [[ "$VERSION" == "linked" ]]; then echo "tools-url=linked" >> "$GITHUB_OUTPUT" exit 0 elif [[ "$VERSION" == "default" ]]; then @@ -43,29 +46,20 @@ runs: exit 0 fi - if [[ "$VERSION" == "nightly-latest" && "$RUNNER_OS" != "Windows" ]]; then - extension="tar.zst" - else - extension="tar.gz" - fi - if [[ "$USE_ALL_PLATFORM_BUNDLE" == "true" ]]; then - artifact_name="codeql-bundle.$extension" + artifact_name="codeql-bundle.tar.gz" elif [[ "$RUNNER_OS" == "Linux" ]]; then - artifact_name="codeql-bundle-linux64.$extension" + artifact_name="codeql-bundle-linux64.tar.gz" elif [[ "$RUNNER_OS" == "macOS" ]]; then - artifact_name="codeql-bundle-osx64.$extension" + artifact_name="codeql-bundle-osx64.tar.gz" elif [[ "$RUNNER_OS" == "Windows" ]]; then - artifact_name="codeql-bundle-win64.$extension" + artifact_name="codeql-bundle-win64.tar.gz" else echo "::error::Unrecognized OS $RUNNER_OS" exit 1 fi - if [[ "$VERSION" == "nightly-latest" ]]; then - tag=`gh release list --repo dsp-testing/codeql-cli-nightlies -L 1 | cut -f 3` - echo "tools-url=https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/$tag/$artifact_name" >> $GITHUB_OUTPUT - elif [[ "$VERSION" == *"nightly"* ]]; then + if [[ "$VERSION" == *"nightly"* ]]; then version=`echo "$VERSION" | sed -e 's/^.*\-//'` echo "tools-url=https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/codeql-bundle-$version/$artifact_name" >> $GITHUB_OUTPUT elif [[ "$VERSION" == *"stable"* ]]; then diff --git a/.github/codeql/codeql-actions-config.yml b/.github/codeql/codeql-actions-config.yml deleted file mode 100644 index 7f3b3f3a84..0000000000 --- a/.github/codeql/codeql-actions-config.yml +++ /dev/null @@ -1,4 +0,0 @@ -# Configuration for the CodeQL Actions Queries -name: "CodeQL Actions Queries config" -queries: - - uses: security-and-quality diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config-javascript.yml similarity index 100% rename from .github/codeql/codeql-config.yml rename to .github/codeql/codeql-config-javascript.yml index 124be804aa..d946c415fd 100644 --- a/.github/codeql/codeql-config.yml +++ b/.github/codeql/codeql-config-javascript.yml @@ -7,9 +7,9 @@ queries: # we include both even though one is a superset of the # other, because we're testing the parsing logic and # that the suites exist in the codeql bundle. + - uses: security-and-quality - uses: security-experimental - uses: security-extended - - uses: security-and-quality paths-ignore: - - tests - lib + - tests diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 82313bc87b..8953919b9f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -20,18 +20,14 @@ updates: patterns: - "*" - package-ecosystem: github-actions - directory: "/" + directories: + - "/.github/workflows" + - "/.github/actions" schedule: interval: weekly + labels: + - Rebuild groups: actions: patterns: - "*" - - package-ecosystem: github-actions - directory: "/.github/actions/setup-swift/" # All subdirectories outside of "/.github/workflows" must be explicitly included. - schedule: - interval: weekly - groups: - actions-setup-swift: - patterns: - - "*" diff --git a/.github/workflows/__all-platform-bundle.yml b/.github/workflows/__all-platform-bundle.yml index 45407c57b7..499b123165 100644 --- a/.github/workflows/__all-platform-bundle.yml +++ b/.github/workflows/__all-platform-bundle.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: all-platform-bundle: strategy: @@ -43,6 +49,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: All-platform bundle + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -59,7 +66,7 @@ jobs: use-all-platform-bundle: 'true' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -70,7 +77,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..2159072adf 100644 --- a/.github/workflows/__analyze-ref-input.yml +++ b/.github/workflows/__analyze-ref-input.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: analyze-ref-input: strategy: @@ -47,6 +53,7 @@ jobs: - os: windows-latest version: default name: "Analyze: 'ref' and 'sha' from inputs" + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -63,7 +70,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -74,7 +81,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..c315763391 100644 --- a/.github/workflows/__autobuild-action.yml +++ b/.github/workflows/__autobuild-action.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: autobuild-action: strategy: @@ -37,6 +43,7 @@ jobs: - os: windows-latest version: linked name: autobuild-action + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -67,7 +74,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..c1de5c19de 100644 --- a/.github/workflows/__autobuild-direct-tracing-with-working-dir.yml +++ b/.github/workflows/__autobuild-direct-tracing-with-working-dir.yml @@ -34,6 +34,12 @@ on: description: The version of Java to install required: false default: '17' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: autobuild-direct-tracing-with-working-dir: strategy: @@ -49,6 +55,7 @@ jobs: - os: windows-latest version: nightly-latest name: Autobuild direct tracing (custom working directory) + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -70,7 +77,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 +88,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..9294edfb84 100644 --- a/.github/workflows/__autobuild-direct-tracing.yml +++ b/.github/workflows/__autobuild-direct-tracing.yml @@ -34,6 +34,12 @@ on: description: The version of Java to install required: false default: '17' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: autobuild-direct-tracing: strategy: @@ -49,6 +55,7 @@ jobs: - os: windows-latest version: nightly-latest name: Autobuild direct tracing + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -70,7 +77,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 +91,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..a6e880cf00 100644 --- a/.github/workflows/__build-mode-autobuild.yml +++ b/.github/workflows/__build-mode-autobuild.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: build-mode-autobuild: strategy: @@ -33,6 +39,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: Build mode autobuild + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read diff --git a/.github/workflows/__build-mode-manual.yml b/.github/workflows/__build-mode-manual.yml index efec3292bb..e0dc25f889 100644 --- a/.github/workflows/__build-mode-manual.yml +++ b/.github/workflows/__build-mode-manual.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: build-mode-manual: strategy: @@ -43,6 +49,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: Build mode manual + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -59,7 +66,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -81,7 +88,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..7584f90650 100644 --- a/.github/workflows/__build-mode-none.yml +++ b/.github/workflows/__build-mode-none.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: build-mode-none: strategy: @@ -35,6 +41,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: Build mode none + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read diff --git a/.github/workflows/__build-mode-rollback.yml b/.github/workflows/__build-mode-rollback.yml index 581f785383..c1f3ccd0c2 100644 --- a/.github/workflows/__build-mode-rollback.yml +++ b/.github/workflows/__build-mode-rollback.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: build-mode-rollback: strategy: @@ -33,6 +39,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: Build mode rollback + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read diff --git a/.github/workflows/__bundle-toolcache.yml b/.github/workflows/__bundle-toolcache.yml index 7d9becc006..de3826b656 100644 --- a/.github/workflows/__bundle-toolcache.yml +++ b/.github/workflows/__bundle-toolcache.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: bundle-toolcache: strategy: @@ -37,6 +43,7 @@ jobs: - os: windows-latest version: linked name: 'Bundle: Caching checks' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -53,7 +60,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Remove CodeQL from toolcache - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | const fs = require('fs'); @@ -63,7 +70,7 @@ jobs: - name: Install @actions/tool-cache run: npm install @actions/tool-cache - name: Check toolcache does not contain CodeQL - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | const toolcache = require('@actions/tool-cache'); @@ -82,7 +89,7 @@ jobs: output: ${{ runner.temp }}/results upload-database: false - name: Check CodeQL is installed within the toolcache - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | const toolcache = require('@actions/tool-cache'); diff --git a/.github/workflows/__bundle-zstd.yml b/.github/workflows/__bundle-zstd.yml index 650a8617de..0139fdc140 100644 --- a/.github/workflows/__bundle-zstd.yml +++ b/.github/workflows/__bundle-zstd.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: bundle-zstd: strategy: @@ -37,6 +43,7 @@ jobs: - os: windows-latest version: linked name: 'Bundle: Zstandard checks' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -53,7 +60,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Remove CodeQL from toolcache - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | const fs = require('fs'); @@ -78,7 +85,7 @@ jobs: path: ${{ runner.temp }}/results/javascript.sarif retention-days: 7 - name: Check diagnostic with expected tools URL appears in SARIF - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: SARIF_PATH: ${{ runner.temp }}/results/javascript.sarif with: diff --git a/.github/workflows/__cleanup-db-cluster-dir.yml b/.github/workflows/__cleanup-db-cluster-dir.yml index 037f0dfd65..dfe53c67ce 100644 --- a/.github/workflows/__cleanup-db-cluster-dir.yml +++ b/.github/workflows/__cleanup-db-cluster-dir.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: cleanup-db-cluster-dir: strategy: @@ -33,6 +39,7 @@ jobs: - os: ubuntu-latest version: linked name: Clean up database cluster directory + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read diff --git a/.github/workflows/__config-export.yml b/.github/workflows/__config-export.yml index b3af26b4f2..1b89d3a186 100644 --- a/.github/workflows/__config-export.yml +++ b/.github/workflows/__config-export.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: config-export: strategy: @@ -43,6 +49,7 @@ jobs: - os: windows-latest version: nightly-latest name: Config export + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -74,7 +81,7 @@ jobs: path: ${{ runner.temp }}/results/javascript.sarif retention-days: 7 - name: Check config properties appear in SARIF - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: SARIF_PATH: ${{ runner.temp }}/results/javascript.sarif with: diff --git a/.github/workflows/__config-input.yml b/.github/workflows/__config-input.yml index 160a61b81f..30b2cfaec3 100644 --- a/.github/workflows/__config-input.yml +++ b/.github/workflows/__config-input.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: config-input: strategy: @@ -33,6 +39,7 @@ jobs: - os: ubuntu-latest version: linked name: Config input + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -42,7 +49,7 @@ jobs: - name: Check out repository uses: actions/checkout@v5 - name: Install Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: 20.x cache: npm diff --git a/.github/workflows/__cpp-deptrace-disabled.yml b/.github/workflows/__cpp-deptrace-disabled.yml index 3e8c79a8b5..1221592366 100644 --- a/.github/workflows/__cpp-deptrace-disabled.yml +++ b/.github/workflows/__cpp-deptrace-disabled.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: cpp-deptrace-disabled: strategy: @@ -37,6 +43,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: 'C/C++: disabling autoinstalling dependencies (Linux)' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -53,7 +60,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 +71,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..b9669b8703 100644 --- a/.github/workflows/__cpp-deptrace-enabled-on-macos.yml +++ b/.github/workflows/__cpp-deptrace-enabled-on-macos.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: cpp-deptrace-enabled-on-macos: strategy: @@ -35,6 +41,7 @@ jobs: - os: macos-latest version: nightly-latest name: 'C/C++: autoinstalling dependencies is skipped (macOS)' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -51,7 +58,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 +69,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..bf155a64d2 100644 --- a/.github/workflows/__cpp-deptrace-enabled.yml +++ b/.github/workflows/__cpp-deptrace-enabled.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: cpp-deptrace-enabled: strategy: @@ -37,6 +43,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: 'C/C++: autoinstalling dependencies (Linux)' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -53,7 +60,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 +71,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..f9f29ff4fa 100644 --- a/.github/workflows/__diagnostics-export.yml +++ b/.github/workflows/__diagnostics-export.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: diagnostics-export: strategy: @@ -43,6 +49,7 @@ jobs: - os: windows-latest version: nightly-latest name: Diagnostic export + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -64,7 +71,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: | @@ -86,7 +92,7 @@ jobs: path: ${{ runner.temp }}/results/javascript.sarif retention-days: 7 - name: Check diagnostics appear in SARIF - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: SARIF_PATH: ${{ runner.temp }}/results/javascript.sarif with: diff --git a/.github/workflows/__export-file-baseline-information.yml b/.github/workflows/__export-file-baseline-information.yml index 86c519d5a8..b2d9b72c74 100644 --- a/.github/workflows/__export-file-baseline-information.yml +++ b/.github/workflows/__export-file-baseline-information.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: export-file-baseline-information: strategy: @@ -47,6 +53,7 @@ jobs: - os: windows-latest version: nightly-latest name: Export file baseline information + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -63,7 +70,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -73,7 +80,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 +91,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..2d8316f52a 100644 --- a/.github/workflows/__extractor-ram-threads.yml +++ b/.github/workflows/__extractor-ram-threads.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: extractor-ram-threads: strategy: @@ -33,6 +39,7 @@ jobs: - os: ubuntu-latest version: linked name: Extractor ram and threads options test + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -54,7 +61,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..1b5b7b9150 100644 --- a/.github/workflows/__go-custom-queries.yml +++ b/.github/workflows/__go-custom-queries.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: go-custom-queries: strategy: @@ -45,6 +51,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: 'Go: Custom queries' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -61,7 +68,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -71,7 +78,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..061ad42549 100644 --- a/.github/workflows/__go-indirect-tracing-workaround-diagnostic.yml +++ b/.github/workflows/__go-indirect-tracing-workaround-diagnostic.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: go-indirect-tracing-workaround-diagnostic: strategy: @@ -43,6 +49,7 @@ jobs: - os: ubuntu-latest version: default name: 'Go: diagnostic when Go is changed after init step' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -59,7 +66,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -68,18 +75,17 @@ jobs: languages: go tools: ${{ steps.prepare-test.outputs.tools-url }} # Deliberately change Go after the `init` step - - uses: actions/setup-go@v5 + - uses: actions/setup-go@v6 with: go-version: '1.20' - name: Build code - shell: bash run: go build main.go - uses: ./../action/analyze with: output: ${{ runner.temp }}/results upload-database: false - name: Check diagnostic appears in SARIF - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: SARIF_PATH: ${{ runner.temp }}/results/go.sarif 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..0a347c65c7 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,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: go-indirect-tracing-workaround-no-file-program: strategy: @@ -43,6 +49,7 @@ jobs: - os: ubuntu-latest version: default name: 'Go: diagnostic when `file` is not installed' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -59,7 +66,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -73,14 +80,13 @@ jobs: languages: go tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: go build main.go - uses: ./../action/analyze with: output: ${{ runner.temp }}/results upload-database: false - name: Check diagnostic appears in SARIF - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: SARIF_PATH: ${{ runner.temp }}/results/go.sarif with: diff --git a/.github/workflows/__go-indirect-tracing-workaround.yml b/.github/workflows/__go-indirect-tracing-workaround.yml index 5e6b4e8a2a..bb811d4d51 100644 --- a/.github/workflows/__go-indirect-tracing-workaround.yml +++ b/.github/workflows/__go-indirect-tracing-workaround.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: go-indirect-tracing-workaround: strategy: @@ -43,6 +49,7 @@ jobs: - os: ubuntu-latest version: default name: 'Go: workaround for indirect tracing' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -59,7 +66,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -68,11 +75,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..6d4cc91cc9 100644 --- a/.github/workflows/__go-tracing-autobuilder.yml +++ b/.github/workflows/__go-tracing-autobuilder.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: go-tracing-autobuilder: strategy: @@ -60,6 +66,10 @@ jobs: version: stable-v2.21.4 - os: macos-latest version: stable-v2.21.4 + - os: ubuntu-latest + version: stable-v2.22.4 + - os: macos-latest + version: stable-v2.22.4 - os: ubuntu-latest version: default - os: macos-latest @@ -73,6 +83,7 @@ jobs: - os: macos-latest version: nightly-latest name: 'Go: tracing with autobuilder step' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -89,7 +100,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -99,8 +110,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..634b074c08 100644 --- a/.github/workflows/__go-tracing-custom-build-steps.yml +++ b/.github/workflows/__go-tracing-custom-build-steps.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: go-tracing-custom-build-steps: strategy: @@ -60,6 +66,10 @@ jobs: version: stable-v2.21.4 - os: macos-latest version: stable-v2.21.4 + - os: ubuntu-latest + version: stable-v2.22.4 + - os: macos-latest + version: stable-v2.22.4 - os: ubuntu-latest version: default - os: macos-latest @@ -73,6 +83,7 @@ jobs: - os: macos-latest version: nightly-latest name: 'Go: tracing with custom build steps' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -89,7 +100,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -98,11 +109,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..8168e3b108 100644 --- a/.github/workflows/__go-tracing-legacy-workflow.yml +++ b/.github/workflows/__go-tracing-legacy-workflow.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: go-tracing-legacy-workflow: strategy: @@ -60,6 +66,10 @@ jobs: version: stable-v2.21.4 - os: macos-latest version: stable-v2.21.4 + - os: ubuntu-latest + version: stable-v2.22.4 + - os: macos-latest + version: stable-v2.22.4 - os: ubuntu-latest version: default - os: macos-latest @@ -73,6 +83,7 @@ jobs: - os: macos-latest version: nightly-latest name: 'Go: tracing with legacy workflow' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -89,7 +100,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -98,8 +109,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..5d98643b09 100644 --- a/.github/workflows/__init-with-registries.yml +++ b/.github/workflows/__init-with-registries.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: init-with-registries: strategy: @@ -49,6 +55,7 @@ jobs: - os: windows-latest version: nightly-latest name: 'Packaging: Download using registries' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read packages: read @@ -78,7 +85,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 +106,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 +120,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..e6c883966e 100644 --- a/.github/workflows/__javascript-source-root.yml +++ b/.github/workflows/__javascript-source-root.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: javascript-source-root: strategy: @@ -37,6 +43,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: Custom source root + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -53,7 +60,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 +72,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..4df3b0d1ca 100644 --- a/.github/workflows/__job-run-uuid-sarif.yml +++ b/.github/workflows/__job-run-uuid-sarif.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: job-run-uuid-sarif: strategy: @@ -33,6 +39,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: Job run UUID added to SARIF + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -63,7 +70,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..5f95caa131 100644 --- a/.github/workflows/__language-aliases.yml +++ b/.github/workflows/__language-aliases.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: language-aliases: strategy: @@ -33,6 +39,7 @@ jobs: - os: ubuntu-latest version: linked name: Language aliases + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read diff --git a/.github/workflows/__multi-language-autodetect.yml b/.github/workflows/__multi-language-autodetect.yml index e5f157881c..ee5d10c818 100644 --- a/.github/workflows/__multi-language-autodetect.yml +++ b/.github/workflows/__multi-language-autodetect.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: multi-language-autodetect: strategy: @@ -60,6 +66,10 @@ jobs: version: stable-v2.21.4 - os: ubuntu-latest version: stable-v2.21.4 + - os: macos-latest + version: stable-v2.22.4 + - os: ubuntu-latest + version: stable-v2.22.4 - os: macos-latest version: default - os: ubuntu-latest @@ -73,6 +83,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: Multi-language repository + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -89,12 +100,11 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: 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 +117,6 @@ jobs: tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: ./build.sh - uses: ./../action/analyze @@ -116,7 +125,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 +164,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 +171,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..d85e58aa17 100644 --- a/.github/workflows/__overlay-init-fallback.yml +++ b/.github/workflows/__overlay-init-fallback.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: overlay-init-fallback: strategy: @@ -35,6 +41,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: Overlay database init fallback + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -61,7 +68,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..8917e4a0eb 100644 --- a/.github/workflows/__packaging-codescanning-config-inputs-js.yml +++ b/.github/workflows/__packaging-codescanning-config-inputs-js.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: packaging-codescanning-config-inputs-js: strategy: @@ -59,6 +65,7 @@ jobs: - os: windows-latest version: nightly-latest name: 'Packaging: Config and input passed to the CLI' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -68,7 +75,7 @@ jobs: - name: Check out repository uses: actions/checkout@v5 - name: Install Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: 20.x cache: npm @@ -82,7 +89,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -93,7 +100,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 +115,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..777683b0f3 100644 --- a/.github/workflows/__packaging-config-inputs-js.yml +++ b/.github/workflows/__packaging-config-inputs-js.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: packaging-config-inputs-js: strategy: @@ -59,6 +65,7 @@ jobs: - os: windows-latest version: nightly-latest name: 'Packaging: Config and input' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -68,7 +75,7 @@ jobs: - name: Check out repository uses: actions/checkout@v5 - name: Install Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: 20.x cache: npm @@ -82,7 +89,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -93,7 +100,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 +115,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..d1abda7e3a 100644 --- a/.github/workflows/__packaging-config-js.yml +++ b/.github/workflows/__packaging-config-js.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: packaging-config-js: strategy: @@ -59,6 +65,7 @@ jobs: - os: windows-latest version: nightly-latest name: 'Packaging: Config file' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -68,7 +75,7 @@ jobs: - name: Check out repository uses: actions/checkout@v5 - name: Install Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: 20.x cache: npm @@ -82,7 +89,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -92,7 +99,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 +114,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..711a600bc0 100644 --- a/.github/workflows/__packaging-inputs-js.yml +++ b/.github/workflows/__packaging-inputs-js.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: packaging-inputs-js: strategy: @@ -59,6 +65,7 @@ jobs: - os: windows-latest version: nightly-latest name: 'Packaging: Action input' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -68,7 +75,7 @@ jobs: - name: Check out repository uses: actions/checkout@v5 - name: Install Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: 20.x cache: npm @@ -82,7 +89,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -93,7 +100,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 +114,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 bbd5decf78..1b5cd0c393 100644 --- a/.github/workflows/__quality-queries.yml +++ b/.github/workflows/__quality-queries.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: quality-queries: strategy: @@ -85,6 +91,7 @@ jobs: version: nightly-latest analysis-kinds: code-scanning,code-quality name: Quality queries input + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -127,7 +134,7 @@ jobs: 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 + uses: actions/github-script@v8 env: SARIF_PATH: ${{ runner.temp }}/results/javascript.sarif EXPECT_PRESENT: 'false' @@ -135,7 +142,7 @@ jobs: script: ${{ env.CHECK_SCRIPT }} - name: Check quality query appears in quality SARIF if: contains(matrix.analysis-kinds, 'code-quality') - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: SARIF_PATH: ${{ runner.temp }}/results/javascript.quality.sarif EXPECT_PRESENT: 'true' diff --git a/.github/workflows/__remote-config.yml b/.github/workflows/__remote-config.yml index 4a3fd0efff..fb76dbc676 100644 --- a/.github/workflows/__remote-config.yml +++ b/.github/workflows/__remote-config.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: remote-config: strategy: @@ -45,6 +51,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: Remote config file + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -61,7 +68,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -72,7 +79,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..7ddd6e663d 100644 --- a/.github/workflows/__resolve-environment-action.yml +++ b/.github/workflows/__resolve-environment-action.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: resolve-environment-action: strategy: @@ -49,6 +55,7 @@ jobs: - os: windows-latest version: nightly-latest name: Resolve environment + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read diff --git a/.github/workflows/__rubocop-multi-language.yml b/.github/workflows/__rubocop-multi-language.yml index 783c3a4490..48694e902c 100644 --- a/.github/workflows/__rubocop-multi-language.yml +++ b/.github/workflows/__rubocop-multi-language.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: rubocop-multi-language: strategy: @@ -33,6 +39,7 @@ jobs: - os: ubuntu-latest version: default name: RuboCop multi-language + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -49,17 +56,14 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Set up Ruby - uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0 + uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a # v1.263.0 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..769a119253 100644 --- a/.github/workflows/__ruby.yml +++ b/.github/workflows/__ruby.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: ruby: strategy: @@ -43,6 +49,7 @@ jobs: - os: macos-latest version: nightly-latest name: Ruby analysis + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -67,7 +74,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..d788e5226d 100644 --- a/.github/workflows/__rust.yml +++ b/.github/workflows/__rust.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: rust: strategy: @@ -41,6 +47,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: Rust analysis + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -65,7 +72,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..e916b36ccc 100644 --- a/.github/workflows/__split-workflow.yml +++ b/.github/workflows/__split-workflow.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: split-workflow: strategy: @@ -53,6 +59,7 @@ jobs: - os: macos-latest version: nightly-latest name: Split workflow + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -69,7 +76,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -80,7 +87,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 +95,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 +105,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..26f1184608 100644 --- a/.github/workflows/__start-proxy.yml +++ b/.github/workflows/__start-proxy.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: start-proxy: strategy: @@ -37,6 +43,7 @@ jobs: - os: windows-latest version: linked name: Start proxy + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read diff --git a/.github/workflows/__submit-sarif-failure.yml b/.github/workflows/__submit-sarif-failure.yml index c89b63d2c4..7383b52a8d 100644 --- a/.github/workflows/__submit-sarif-failure.yml +++ b/.github/workflows/__submit-sarif-failure.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: submit-sarif-failure: strategy: @@ -37,6 +43,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: Submit SARIF after failure + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: write # needed to upload the SARIF file diff --git a/.github/workflows/__swift-autobuild.yml b/.github/workflows/__swift-autobuild.yml index 82045f1a44..9d18d0c978 100644 --- a/.github/workflows/__swift-autobuild.yml +++ b/.github/workflows/__swift-autobuild.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: swift-autobuild: strategy: @@ -33,6 +39,7 @@ jobs: - os: macos-latest version: nightly-latest name: Swift analysis using autobuild + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -55,7 +62,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 +70,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..32ce33a7f0 100644 --- a/.github/workflows/__swift-custom-build.yml +++ b/.github/workflows/__swift-custom-build.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: swift-custom-build: strategy: @@ -47,6 +53,7 @@ jobs: - os: macos-latest version: nightly-latest name: Swift analysis using a custom build command + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -63,12 +70,11 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: 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 +83,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..b55018c736 100644 --- a/.github/workflows/__test-autobuild-working-dir.yml +++ b/.github/workflows/__test-autobuild-working-dir.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: test-autobuild-working-dir: strategy: @@ -33,6 +39,7 @@ jobs: - os: ubuntu-latest version: linked name: Autobuild working directory + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -49,7 +56,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 +70,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..eee756a2a8 100644 --- a/.github/workflows/__test-local-codeql.yml +++ b/.github/workflows/__test-local-codeql.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: test-local-codeql: strategy: @@ -41,8 +47,9 @@ jobs: matrix: include: - os: ubuntu-latest - version: nightly-latest + version: linked name: Local CodeQL bundle + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -59,16 +66,13 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: 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 }} + - name: Fetch latest CodeQL bundle run: | - wget "$CODEQL_URL" + wget https://github.com/github/codeql-action/releases/latest/download/codeql-bundle-linux64.tar.zst - id: init uses: ./../action/init with: @@ -76,7 +80,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..8504a44010 100644 --- a/.github/workflows/__test-proxy.yml +++ b/.github/workflows/__test-proxy.yml @@ -24,6 +24,12 @@ on: inputs: {} workflow_call: inputs: {} +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: test-proxy: strategy: @@ -35,6 +41,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: Proxy test + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read diff --git a/.github/workflows/__unset-environment.yml b/.github/workflows/__unset-environment.yml index 772ac35b05..8b8d156547 100644 --- a/.github/workflows/__unset-environment.yml +++ b/.github/workflows/__unset-environment.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: unset-environment: strategy: @@ -45,6 +51,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: Test unsetting environment variables + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -61,7 +68,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -73,14 +80,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 2332aff841..15bc871d94 100644 --- a/.github/workflows/__upload-quality-sarif.yml +++ b/.github/workflows/__upload-quality-sarif.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: upload-quality-sarif: strategy: @@ -47,6 +53,7 @@ jobs: - os: windows-latest version: default name: 'Upload-sarif: code quality endpoint' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -63,19 +70,16 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false - uses: ./../action/init with: 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 }} - analysis-kinds: code-scanning,code-quality + languages: csharp,java,javascript,python + analysis-kinds: code-quality - name: Build code - shell: bash run: ./build.sh # Generate some SARIF we can upload with the upload-sarif step - uses: ./../action/analyze @@ -84,8 +88,12 @@ jobs: sha: 5e235361806c361d4d3f8859e3c897658025a9a2 upload: never - uses: ./../action/upload-sarif + id: upload-sarif with: ref: refs/heads/main sha: 5e235361806c361d4d3f8859e3c897658025a9a2 + - name: Check output from `upload-sarif` step + if: fromJSON(steps.upload-sarif.outputs.sarif-ids)[0].analysis != 'code-quality' + run: exit 1 env: CODEQL_ACTION_TEST_MODE: true diff --git a/.github/workflows/__upload-ref-sha-input.yml b/.github/workflows/__upload-ref-sha-input.yml index b991e7d36f..d6970ea18d 100644 --- a/.github/workflows/__upload-ref-sha-input.yml +++ b/.github/workflows/__upload-ref-sha-input.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: upload-ref-sha-input: strategy: @@ -47,6 +53,7 @@ jobs: - os: windows-latest version: default name: "Upload-sarif: 'ref' and 'sha' from inputs" + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -63,7 +70,7 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version || '>=1.21.0' }} cache: false @@ -74,7 +81,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..aa6c9651df 100644 --- a/.github/workflows/__with-checkout-path.yml +++ b/.github/workflows/__with-checkout-path.yml @@ -34,6 +34,12 @@ on: description: The version of Go to install required: false default: '>=1.21.0' +defaults: + run: + shell: bash +concurrency: + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + group: ${{ github.workflow }}-${{ github.ref }} jobs: with-checkout-path: strategy: @@ -47,6 +53,7 @@ jobs: - os: windows-latest version: linked name: Use a custom `checkout_path` + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -63,12 +70,11 @@ jobs: use-all-platform-bundle: 'false' setup-kotlin: 'true' - name: Install Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: 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 +95,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 +106,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..1af109a765 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -13,12 +13,17 @@ on: - cron: '30 1 * * 0' workflow_dispatch: +defaults: + run: + shell: bash + env: CODEQL_ACTION_TESTING_ENVIRONMENT: codeql-action-pr-checks jobs: # Identify the CodeQL tool versions to use in the analysis job. check-codeql-versions: + if: github.triggering_actor != 'dependabot[bot]' runs-on: ubuntu-latest outputs: versions: ${{ steps.compare.outputs.versions }} @@ -71,6 +76,7 @@ jobs: echo "versions=${VERSIONS_JSON}" >> $GITHUB_OUTPUT analyze-javascript: + if: github.triggering_actor != 'dependabot[bot]' needs: [check-codeql-versions] strategy: fail-fast: false @@ -91,22 +97,30 @@ jobs: id: init with: languages: javascript - config-file: ./.github/codeql/codeql-config.yml + config-file: ./.github/codeql/codeql-config-javascript.yml 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: category: "/language:javascript" + upload: ${{ (matrix.os == 'ubuntu-24.04' && !matrix.tools && 'always') || 'never' }} - - analyze-actions: + analyze-other: + if: github.triggering_actor != 'dependabot[bot]' runs-on: ubuntu-latest strategy: fail-fast: false + matrix: + include: + - language: actions + - language: python permissions: contents: read @@ -118,9 +132,15 @@ jobs: - name: Initialize CodeQL uses: ./init with: - languages: actions - config-file: ./.github/codeql/codeql-actions-config.yml + languages: ${{ matrix.language }} + build-mode: none + config: > + paths-ignore: + - lib + - tests + queries: + - uses: security-and-quality - name: Perform CodeQL Analysis uses: ./analyze with: - category: "/language:actions" + category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/codescanning-config-cli.yml b/.github/workflows/codescanning-config-cli.yml index 925e5ce177..c11f479718 100644 --- a/.github/workflows/codescanning-config-cli.yml +++ b/.github/workflows/codescanning-config-cli.yml @@ -22,8 +22,13 @@ on: - cron: '0 5 * * *' workflow_dispatch: {} +defaults: + run: + shell: bash + jobs: code-scanning-config-tests: + if: github.triggering_actor != 'dependabot[bot]' continue-on-error: true permissions: @@ -57,7 +62,7 @@ jobs: uses: actions/checkout@v5 - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: '20' cache: 'npm' @@ -176,13 +181,13 @@ jobs: with: expected-config-file-contents: | { - "queries": [ - { "uses": "./codeql-qlpacks/complex-javascript-qlpack/foo2/show_ifs.ql" }, - { "uses": "./codeql-qlpacks/complex-javascript-qlpack/show_ifs.ql" } - ], "packs": { "javascript": ["codeql-testing/codeql-pack1@1.0.0", "codeql-testing/codeql-pack2", "codeql/javascript-queries" ] - } + }, + "queries": [ + { "uses": "./codeql-qlpacks/complex-javascript-qlpack/show_ifs.ql" }, + { "uses": "./codeql-qlpacks/complex-javascript-qlpack/foo2/show_ifs.ql" } + ] } languages: javascript queries: + ./codeql-qlpacks/complex-javascript-qlpack/show_ifs.ql diff --git a/.github/workflows/debug-artifacts-failure-safe.yml b/.github/workflows/debug-artifacts-failure-safe.yml index 6cba089004..c938c51e65 100644 --- a/.github/workflows/debug-artifacts-failure-safe.yml +++ b/.github/workflows/debug-artifacts-failure-safe.yml @@ -17,8 +17,14 @@ on: schedule: - cron: '0 5 * * *' workflow_dispatch: {} + +defaults: + run: + shell: bash + jobs: upload-artifacts: + if: github.triggering_actor != 'dependabot[bot]' strategy: fail-fast: false matrix: @@ -45,7 +51,7 @@ jobs: uses: ./.github/actions/prepare-test with: version: ${{ matrix.version }} - - uses: actions/setup-go@v5 + - uses: actions/setup-go@v6 with: go-version: ^1.13.1 - uses: ./../action/init @@ -55,7 +61,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 @@ -66,6 +71,7 @@ jobs: expect-error: true download-and-check-artifacts: name: Download and check debug artifacts after failure in analyze + if: github.triggering_actor != 'dependabot[bot]' needs: upload-artifacts timeout-minutes: 45 permissions: @@ -75,7 +81,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..3e7282f820 100644 --- a/.github/workflows/debug-artifacts-safe.yml +++ b/.github/workflows/debug-artifacts-safe.yml @@ -16,8 +16,14 @@ on: schedule: - cron: '0 5 * * *' workflow_dispatch: {} + +defaults: + run: + shell: bash + jobs: upload-artifacts: + if: github.triggering_actor != 'dependabot[bot]' strategy: fail-fast: false matrix: @@ -41,7 +47,7 @@ jobs: uses: ./.github/actions/prepare-test with: version: ${{ matrix.version }} - - uses: actions/setup-go@v5 + - uses: actions/setup-go@v6 with: go-version: ^1.13.1 - uses: ./../action/init @@ -54,12 +60,12 @@ 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 download-and-check-artifacts: name: Download and check debug artifacts + if: github.triggering_actor != 'dependabot[bot]' needs: upload-artifacts timeout-minutes: 45 permissions: @@ -69,7 +75,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..03efc0c33a 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 @@ -43,7 +47,7 @@ jobs: - uses: actions/checkout@v5 with: fetch-depth: 0 # ensure we have all tags and can push commits - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v5 - name: Update git config run: | @@ -135,7 +139,7 @@ jobs: token: "${{ secrets.GITHUB_TOKEN }}" - name: Generate token - uses: actions/create-github-app-token@v2.1.1 + uses: actions/create-github-app-token@v2.1.4 id: app-token with: app-id: ${{ vars.AUTOMATION_APP_ID }} diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index 365b53a945..fa80525f90 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -8,9 +8,14 @@ on: types: [opened, synchronize, reopened, ready_for_review] workflow_dispatch: +defaults: + run: + shell: bash + jobs: unit-tests: name: Unit Tests + if: github.triggering_actor != 'dependabot[bot]' strategy: fail-fast: false matrix: @@ -22,16 +27,20 @@ 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 - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: '20.x' cache: 'npm' - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.11 @@ -51,6 +60,10 @@ jobs: - name: Run unit tests run: npm test + - name: Run pr-checks tests + working-directory: pr-checks + run: python -m unittest discover + - name: Lint if: matrix.os != 'windows-latest' run: npm run lint-ci @@ -63,7 +76,7 @@ jobs: category: eslint check-node-version: - if: github.event.pull_request + if: github.event.pull_request && github.triggering_actor != 'dependabot[bot]' name: Check Action Node versions runs-on: ubuntu-latest timeout-minutes: 45 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..aa2a034200 100644 --- a/.github/workflows/python312-windows.yml +++ b/.github/workflows/python312-windows.yml @@ -12,8 +12,13 @@ on: - cron: '0 0 * * 1' workflow_dispatch: +defaults: + run: + shell: bash + jobs: test-setup-python-scripts: + if: github.triggering_actor != 'dependabot[bot]' env: CODEQL_ACTION_TEST_MODE: true timeout-minutes: 45 @@ -22,7 +27,7 @@ jobs: runs-on: windows-latest steps: - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: 3.12 diff --git a/.github/workflows/query-filters.yml b/.github/workflows/query-filters.yml index 1014b4e553..aabcc144b0 100644 --- a/.github/workflows/query-filters.yml +++ b/.github/workflows/query-filters.yml @@ -15,9 +15,14 @@ on: - cron: '0 5 * * *' workflow_dispatch: {} +defaults: + run: + shell: bash + jobs: query-filters: name: Query Filters Tests + if: github.triggering_actor != 'dependabot[bot]' timeout-minutes: 45 runs-on: ubuntu-latest permissions: @@ -27,7 +32,7 @@ jobs: uses: actions/checkout@v5 - name: Install Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: 20.x cache: npm diff --git a/.github/workflows/rebuild.yml b/.github/workflows/rebuild.yml index 9ac5e64e0c..e7b9022be9 100644 --- a/.github/workflows/rebuild.yml +++ b/.github/workflows/rebuild.yml @@ -5,12 +5,20 @@ on: types: [labeled] workflow_dispatch: +defaults: + run: + shell: bash + jobs: rebuild: name: Rebuild Action runs-on: ubuntu-latest if: github.event.label.name == 'Rebuild' || github.event_name == 'workflow_dispatch' + env: + HEAD_REF: ${{ github.event.pull_request.head.ref || github.event.ref }} + BASE_BRANCH: ${{ github.event.pull_request.base.ref || 'main' }} + permissions: contents: write # needed to push rebuilt commit pull-requests: write # needed to comment on the PR @@ -19,7 +27,7 @@ jobs: uses: actions/checkout@v5 with: fetch-depth: 0 - ref: ${{ github.event.pull_request.head.ref || github.event.ref }} + ref: ${{ env.HEAD_REF }} - name: Remove label if: github.event_name == 'pull_request' @@ -37,8 +45,6 @@ jobs: - name: Merge in changes from base branch id: merge - env: - BASE_BRANCH: ${{ github.event.pull_request.base.ref || 'main' }} run: | git fetch origin "$BASE_BRANCH" @@ -68,13 +74,20 @@ jobs: npm run build - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.11 + - name: Sync back version updates to generated workflows + # Only sync back versions on Dependabot update PRs + if: startsWith(env.HEAD_REF, 'dependabot/') + working-directory: pr-checks + run: | + python3 sync_back.py -v + - name: Generate workflows + working-directory: pr-checks run: | - cd pr-checks python -m pip install --upgrade pip pip install ruamel.yaml==0.17.31 python3 sync.py diff --git a/.github/workflows/rollback-release.yml b/.github/workflows/rollback-release.yml index e492ea870e..937c413f90 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 }} @@ -132,7 +133,7 @@ jobs: - name: Generate token if: github.event_name == 'workflow_dispatch' - uses: actions/create-github-app-token@v2.1.1 + uses: actions/create-github-app-token@v2.1.4 id: app-token with: app-id: ${{ vars.AUTOMATION_APP_ID }} @@ -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 950b13c5d4..30a39731b1 100755 --- a/.github/workflows/script/update-required-checks.sh +++ b/.github/workflows/script/update-required-checks.sh @@ -1,6 +1,8 @@ #!/usr/bin/env bash # Update the required checks based on the current branch. +set -euo pipefail + SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" REPO_DIR="$(dirname "$SCRIPT_DIR")" GRANDPARENT_DIR="$(dirname "$REPO_DIR")" @@ -31,6 +33,12 @@ CHECKS="$(gh api repos/github/codeql-action/commits/"${GITHUB_SHA}"/check-runs - echo "$CHECKS" | jq +# Fail if there are no checks +if [ -z "$CHECKS" ] || [ "$(echo "$CHECKS" | jq '. | length')" -eq 0 ]; then + echo "No checks found for $GITHUB_SHA" + exit 1 +fi + echo "{\"contexts\": ${CHECKS}}" > checks.json echo "Updating main" diff --git a/.github/workflows/test-codeql-bundle-all.yml b/.github/workflows/test-codeql-bundle-all.yml index 1d0cdfbe20..4b7fdca817 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: @@ -25,6 +28,7 @@ jobs: - os: ubuntu-latest version: nightly-latest name: 'CodeQL Bundle All' + if: github.triggering_actor != 'dependabot[bot]' permissions: contents: read security-events: read @@ -43,10 +47,9 @@ jobs: uses: ./../action/init with: # We manually exclude Swift from the languages list here, as it is not supported on Ubuntu - languages: cpp,csharp,go,java,javascript,python,ruby + 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..e64135d841 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-') @@ -37,7 +41,7 @@ jobs: git config --global user.name "github-actions[bot]" - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: '20.x' cache: 'npm' diff --git a/.github/workflows/update-proxy-release.yml b/.github/workflows/update-proxy-release.yml index 5fc3b14b54..f693ac9397 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,14 +33,13 @@ 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: | (gh release view --repo "$GITHUB_REPOSITORY" --json "assets" "$RELEASE_TAG" && echo "Release found.") || exit 1 - name: Install Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 - name: Checkout repository uses: actions/checkout@v5 @@ -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..69700a35f6 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: @@ -89,7 +93,7 @@ jobs: pull-requests: write # needed to create pull request steps: - name: Generate token - uses: actions/create-github-app-token@v2.1.1 + uses: actions/create-github-app-token@v2.1.4 id: app-token with: app-id: ${{ vars.AUTOMATION_APP_ID }} diff --git a/.github/workflows/update-supported-enterprise-server-versions.yml b/.github/workflows/update-supported-enterprise-server-versions.yml index 80785a826b..35d4ba01f4 100644 --- a/.github/workflows/update-supported-enterprise-server-versions.yml +++ b/.github/workflows/update-supported-enterprise-server-versions.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.13" - name: Checkout CodeQL Action diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c2a103678..c9e4e8a184 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs. +## 3.30.4 - 25 Sep 2025 + +- 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) +- You can now run the latest CodeQL nightly bundle by passing `tools: nightly` to the `init` action. In general, the nightly bundle is unstable and we only recommend running it when directed by GitHub staff. [#3130](https://github.com/github/codeql-action/pull/3130) +- Update default CodeQL bundle version to 2.23.1. [#3118](https://github.com/github/codeql-action/pull/3118) + ## 3.30.3 - 10 Sep 2025 No user facing changes. diff --git a/analyze/action.yml b/analyze/action.yml index e4c6b9daec..b7880be179 100644 --- a/analyze/action.yml +++ b/analyze/action.yml @@ -58,7 +58,7 @@ inputs: # If changing this, make sure to update workflow.ts accordingly. default: ${{ github.workspace }} ref: - description: "The ref where results will be uploaded. If not provided, the Action will use the GITHUB_REF environment variable. If provided, the sha input must be provided as well. This input is ignored for pull requests from forks." + description: "The ref where results will be uploaded. If not provided, the Action will use the GITHUB_REF environment variable. If provided, the sha input must be provided as well. This input is ignored for pull requests from forks. Expected format: refs/heads/, refs/tags/, refs/pull//merge, or refs/pull//head." required: false sha: description: "The sha of the HEAD of the ref where results will be uploaded. If not provided, the Action will use the GITHUB_SHA environment variable. If provided, the ref input must be provided as well. This input is ignored for pull requests from forks." diff --git a/init/action.yml b/init/action.yml index 49a3cc6503..ba5d6efcc1 100644 --- a/init/action.yml +++ b/init/action.yml @@ -12,6 +12,9 @@ inputs: - The URL of a CodeQL Bundle tarball GitHub release asset, or - A special value `linked` which uses the version of the CodeQL tools that the Action has been bundled with. + - A special value `nightly` which uses the latest nightly version of the + CodeQL tools. Note that this is unstable and not recommended for + production use. If not specified, the Action will check in several places until it finds the CodeQL tools. diff --git a/justfile b/justfile index f146ed9b48..c951b4b063 100644 --- a/justfile +++ b/justfile @@ -22,7 +22,7 @@ test: build # Run the tests for a single file test_file filename: build - npx ava --verbose {{filename}} + npx ava --serial --verbose {{filename}} [doc("Refresh the .js build artefacts in the lib directory")] [confirm] diff --git a/lib/analyze-action-post.js b/lib/analyze-action-post.js index 312e02135d..4a01511046 100644 --- a/lib/analyze-action-post.js +++ b/lib/analyze-action-post.js @@ -26438,7 +26438,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.3", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -26447,7 +26447,7 @@ var require_package = __commonJS({ lint: "eslint --report-unused-disable-directives --max-warnings=0 .", "lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif", "lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix", - test: "npm run transpile && ava src/**.test.ts --serial --verbose", + test: "npm run transpile && ava src/ --serial --verbose", "test-debug": "npm run test -- --timeout=20m", transpile: "tsc --build --verbose" }, @@ -26463,7 +26463,7 @@ var require_package = __commonJS({ dependencies: { "@actions/artifact": "^2.3.1", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^4.0.5", + "@actions/cache": "^4.1.0", "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", @@ -26486,15 +26486,15 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^12.0.0" + uuid: "^13.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", - "@eslint/compat": "^1.3.2", + "@eslint/compat": "^1.4.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.35.0", + "@eslint/js": "^9.36.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", - "@octokit/types": "^14.1.0", + "@octokit/types": "^15.0.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", @@ -26503,10 +26503,10 @@ var require_package = __commonJS({ "@types/node-forge": "^1.3.14", "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.43.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", - esbuild: "^0.25.9", + esbuild: "^0.25.10", eslint: "^8.57.1", "eslint-import-resolver-typescript": "^3.8.7", "eslint-plugin-filenames": "^1.3.2", @@ -26536,7 +26536,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -67281,7 +67282,7 @@ var require_package2 = __commonJS({ "node_modules/@actions/cache/package.json"(exports2, module2) { module2.exports = { name: "@actions/cache", - version: "4.0.5", + version: "4.1.0", preview: true, description: "Actions cache lib", keywords: [ @@ -72090,11 +72091,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 9 /*ScalarType.STRING*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, signedUploadUrl: "" }; + const message = { ok: false, signedUploadUrl: "", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -72113,6 +72121,10 @@ var require_cache2 = __commonJS({ 2: message.signedUploadUrl = reader.string(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -72129,6 +72141,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.signedUploadUrl !== "") writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.signedUploadUrl); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -72234,11 +72248,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 3 /*ScalarType.INT64*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, entryId: "0" }; + const message = { ok: false, entryId: "0", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -72257,6 +72278,10 @@ var require_cache2 = __commonJS({ 2: message.entryId = reader.int64().toString(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -72273,6 +72298,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.entryId !== "0") writer.tag(2, runtime_1.WireType.Varint).int64(message.entryId); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -73036,7 +73063,7 @@ var require_cache3 = __commonJS({ }); }; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.ReserveCacheError = exports2.ValidationError = void 0; + exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; var core14 = __importStar4(require_core()); var path6 = __importStar4(require("path")); var utils = __importStar4(require_cacheUtils()); @@ -73044,7 +73071,6 @@ var require_cache3 = __commonJS({ var cacheTwirpClient = __importStar4(require_cacheTwirpClient()); var config_1 = require_config(); var tar_1 = require_tar(); - var constants_1 = require_constants7(); var http_client_1 = require_lib(); var ValidationError = class _ValidationError extends Error { constructor(message) { @@ -73062,6 +73088,14 @@ var require_cache3 = __commonJS({ } }; exports2.ReserveCacheError = ReserveCacheError2; + var FinalizeCacheError = class _FinalizeCacheError extends Error { + constructor(message) { + super(message); + this.name = "FinalizeCacheError"; + Object.setPrototypeOf(this, _FinalizeCacheError.prototype); + } + }; + exports2.FinalizeCacheError = FinalizeCacheError; function checkPaths(paths) { if (!paths || paths.length === 0) { throw new ValidationError(`Path Validation Error: At least one directory or file path is required`); @@ -73333,9 +73367,6 @@ var require_cache3 = __commonJS({ } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); core14.debug(`File Size: ${archiveFileSize}`); - if (archiveFileSize > constants_1.CacheFileSizeLimit && !(0, config_1.isGhes)()) { - throw new Error(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`); - } options.archiveSizeBytes = archiveFileSize; core14.debug("Reserving Cache"); const version = utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive); @@ -73347,7 +73378,10 @@ var require_cache3 = __commonJS({ try { const response = yield twirpClient.CreateCacheEntry(request); if (!response.ok) { - throw new Error("Response was not ok"); + if (response.message) { + core14.warning(`Cache reservation failed: ${response.message}`); + } + throw new Error(response.message || "Response was not ok"); } signedUploadUrl = response.signedUploadUrl; } catch (error2) { @@ -73364,6 +73398,9 @@ var require_cache3 = __commonJS({ const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest); core14.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); if (!finalizeResponse.ok) { + if (finalizeResponse.message) { + throw new FinalizeCacheError(finalizeResponse.message); + } throw new Error(`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`); } cacheId = parseInt(finalizeResponse.entryId); @@ -73373,6 +73410,8 @@ var require_cache3 = __commonJS({ throw error2; } else if (typedError.name === ReserveCacheError2.name) { core14.info(`Failed to save: ${typedError.message}`); + } else if (typedError.name === FinalizeCacheError.name) { + core14.warning(typedError.message); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { core14.error(`Failed to save: ${typedError.message}`); @@ -77685,7 +77724,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); } @@ -94795,7 +94834,7 @@ var require_commonjs16 = __commonJS({ var TYPEMASK = 1023; var entToType = (s) => s.isFile() ? IFREG : s.isDirectory() ? IFDIR : s.isSymbolicLink() ? IFLNK : s.isCharacterDevice() ? IFCHR : s.isBlockDevice() ? IFBLK : s.isSocket() ? IFSOCK : s.isFIFO() ? IFIFO : UNKNOWN; var normalizeCache = /* @__PURE__ */ new Map(); - var normalize3 = (s) => { + var normalize2 = (s) => { const c = normalizeCache.get(s); if (c) return c; @@ -94808,7 +94847,7 @@ var require_commonjs16 = __commonJS({ const c = normalizeNocaseCache.get(s); if (c) return c; - const n = normalize3(s.toLowerCase()); + const n = normalize2(s.toLowerCase()); normalizeNocaseCache.set(s, n); return n; }; @@ -94977,7 +95016,7 @@ var require_commonjs16 = __commonJS({ */ constructor(name, type2 = UNKNOWN, root, roots, nocase, children, opts) { this.name = name; - this.#matchName = nocase ? normalizeNocase(name) : normalize3(name); + this.#matchName = nocase ? normalizeNocase(name) : normalize2(name); this.#type = type2 & TYPEMASK; this.nocase = nocase; this.roots = roots; @@ -95070,7 +95109,7 @@ var require_commonjs16 = __commonJS({ return this.parent || this; } const children = this.children(); - const name = this.nocase ? normalizeNocase(pathPart) : normalize3(pathPart); + const name = this.nocase ? normalizeNocase(pathPart) : normalize2(pathPart); for (const p of children) { if (p.#matchName === name) { return p; @@ -95315,7 +95354,7 @@ var require_commonjs16 = __commonJS({ * directly. */ isNamed(n) { - return !this.nocase ? this.#matchName === normalize3(n) : this.#matchName === normalizeNocase(n); + return !this.nocase ? this.#matchName === normalize2(n) : this.#matchName === normalizeNocase(n); } /** * Return the Path object corresponding to the target of a symbolic link. @@ -95454,7 +95493,7 @@ var require_commonjs16 = __commonJS({ #readdirMaybePromoteChild(e, c) { for (let p = c.provisional; p < c.length; p++) { const pchild = c[p]; - const name = this.nocase ? normalizeNocase(e.name) : normalize3(e.name); + const name = this.nocase ? normalizeNocase(e.name) : normalize2(e.name); if (name !== pchild.#matchName) { continue; } @@ -103285,7 +103324,7 @@ var require_tr46 = __commonJS({ TRANSITIONAL: 0, NONTRANSITIONAL: 1 }; - function normalize3(str2) { + function normalize2(str2) { return str2.split("\0").map(function(s) { return s.normalize("NFC"); }).join("\0"); @@ -103365,7 +103404,7 @@ var require_tr46 = __commonJS({ processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL; } var error2 = false; - if (normalize3(label) !== label || label[3] === "-" && label[4] === "-" || label[0] === "-" || label[label.length - 1] === "-" || label.indexOf(".") !== -1 || label.search(combiningMarksRegex) === 0) { + if (normalize2(label) !== label || label[3] === "-" && label[4] === "-" || label[0] === "-" || label[label.length - 1] === "-" || label.indexOf(".") !== -1 || label.search(combiningMarksRegex) === 0) { error2 = true; } var len = countSymbols(label); @@ -103383,7 +103422,7 @@ var require_tr46 = __commonJS({ } function processing(domain_name, useSTD3, processing_option) { var result = mapChars(domain_name, useSTD3, processing_option); - result.string = normalize3(result.string); + result.string = normalize2(result.string); var labels = result.string.split("."); for (var i = 0; i < labels.length; ++i) { try { @@ -117486,7 +117525,6 @@ function wrapCliConfigurationError(cliError) { // src/config-utils.ts var fs3 = __toESM(require("fs")); var path3 = __toESM(require("path")); -var semver4 = __toESM(require_semver2()); // src/analyses.ts var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { @@ -117499,8 +117537,17 @@ var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); // src/caching-utils.ts var core6 = __toESM(require_core()); +// src/config/db-config.ts +var semver2 = __toESM(require_semver2()); +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}$`); +})(); + // src/feature-flags.ts -var semver3 = __toESM(require_semver2()); +var semver4 = __toESM(require_semver2()); // src/overlay-database-utils.ts var fs2 = __toESM(require("fs")); @@ -117685,7 +117732,7 @@ function withGroup(groupName, f) { } // src/overlay-database-utils.ts -var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; +var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.4"; 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) { @@ -117746,13 +117793,13 @@ function computeChangedFiles(baseFileOids, overlayFileOids) { } // src/tools-features.ts -var semver2 = __toESM(require_semver2()); +var semver3 = __toESM(require_semver2()); function isSupportedToolsFeature(versionInfo, feature) { return !!versionInfo.features && versionInfo.features[feature]; } var SafeArtifactUploadVersion = "2.20.3"; function isSafeArtifactUpload(codeQlVersion) { - return !codeQlVersion ? true : semver2.gte(codeQlVersion, SafeArtifactUploadVersion); + return !codeQlVersion ? true : semver3.gte(codeQlVersion, SafeArtifactUploadVersion); } // src/feature-flags.ts @@ -117796,6 +117843,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", @@ -117907,11 +117960,21 @@ var featureConfig = { minimumVersion: void 0, toolsFeature: "pythonDefaultIsToNotExtractStdlib" /* PythonDefaultIsToNotExtractStdlib */ }, + ["use_repository_properties" /* UseRepositoryProperties */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_USE_REPOSITORY_PROPERTIES", + minimumVersion: void 0 + }, ["qa_telemetry_enabled" /* QaTelemetryEnabled */]: { defaultValue: false, 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" } }; @@ -117943,12 +118006,6 @@ var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { 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 path3.join(tempDir, "config"); } @@ -117960,7 +118017,18 @@ async function getConfig(tempDir, logger) { const configString = fs3.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; } function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { const augmentedConfig = cloneObject(cliConfig); @@ -118206,13 +118274,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); diff --git a/lib/analyze-action.js b/lib/analyze-action.js index ce00934a08..c7e6b7b1a1 100644 --- a/lib/analyze-action.js +++ b/lib/analyze-action.js @@ -27722,7 +27722,7 @@ var require_pattern = __commonJS({ const absolute = []; const relative2 = []; for (const pattern of patterns) { - if (isAbsolute3(pattern)) { + if (isAbsolute2(pattern)) { absolute.push(pattern); } else { relative2.push(pattern); @@ -27731,10 +27731,10 @@ var require_pattern = __commonJS({ return [absolute, relative2]; } exports2.partitionAbsoluteAndRelative = partitionAbsoluteAndRelative; - function isAbsolute3(pattern) { + function isAbsolute2(pattern) { return path20.isAbsolute(pattern); } - exports2.isAbsolute = isAbsolute3; + exports2.isAbsolute = isAbsolute2; } }); @@ -32287,7 +32287,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.3", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -32296,7 +32296,7 @@ var require_package = __commonJS({ lint: "eslint --report-unused-disable-directives --max-warnings=0 .", "lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif", "lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix", - test: "npm run transpile && ava src/**.test.ts --serial --verbose", + test: "npm run transpile && ava src/ --serial --verbose", "test-debug": "npm run test -- --timeout=20m", transpile: "tsc --build --verbose" }, @@ -32312,7 +32312,7 @@ var require_package = __commonJS({ dependencies: { "@actions/artifact": "^2.3.1", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^4.0.5", + "@actions/cache": "^4.1.0", "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", @@ -32335,15 +32335,15 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^12.0.0" + uuid: "^13.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", - "@eslint/compat": "^1.3.2", + "@eslint/compat": "^1.4.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.35.0", + "@eslint/js": "^9.36.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", - "@octokit/types": "^14.1.0", + "@octokit/types": "^15.0.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", @@ -32352,10 +32352,10 @@ var require_package = __commonJS({ "@types/node-forge": "^1.3.14", "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.43.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", - esbuild: "^0.25.9", + esbuild: "^0.25.10", eslint: "^8.57.1", "eslint-import-resolver-typescript": "^3.8.7", "eslint-plugin-filenames": "^1.3.2", @@ -32385,7 +32385,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -73130,7 +73131,7 @@ var require_package2 = __commonJS({ "node_modules/@actions/cache/package.json"(exports2, module2) { module2.exports = { name: "@actions/cache", - version: "4.0.5", + version: "4.1.0", preview: true, description: "Actions cache lib", keywords: [ @@ -77939,11 +77940,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 9 /*ScalarType.STRING*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, signedUploadUrl: "" }; + const message = { ok: false, signedUploadUrl: "", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -77962,6 +77970,10 @@ var require_cache2 = __commonJS({ 2: message.signedUploadUrl = reader.string(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -77978,6 +77990,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.signedUploadUrl !== "") writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.signedUploadUrl); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -78083,11 +78097,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 3 /*ScalarType.INT64*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, entryId: "0" }; + const message = { ok: false, entryId: "0", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -78106,6 +78127,10 @@ var require_cache2 = __commonJS({ 2: message.entryId = reader.int64().toString(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -78122,6 +78147,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.entryId !== "0") writer.tag(2, runtime_1.WireType.Varint).int64(message.entryId); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -78885,7 +78912,7 @@ var require_cache3 = __commonJS({ }); }; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.ReserveCacheError = exports2.ValidationError = void 0; + exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; var core15 = __importStar4(require_core()); var path20 = __importStar4(require("path")); var utils = __importStar4(require_cacheUtils()); @@ -78893,7 +78920,6 @@ var require_cache3 = __commonJS({ var cacheTwirpClient = __importStar4(require_cacheTwirpClient()); var config_1 = require_config(); var tar_1 = require_tar(); - var constants_1 = require_constants10(); var http_client_1 = require_lib(); var ValidationError = class _ValidationError extends Error { constructor(message) { @@ -78911,6 +78937,14 @@ var require_cache3 = __commonJS({ } }; exports2.ReserveCacheError = ReserveCacheError2; + var FinalizeCacheError = class _FinalizeCacheError extends Error { + constructor(message) { + super(message); + this.name = "FinalizeCacheError"; + Object.setPrototypeOf(this, _FinalizeCacheError.prototype); + } + }; + exports2.FinalizeCacheError = FinalizeCacheError; function checkPaths(paths) { if (!paths || paths.length === 0) { throw new ValidationError(`Path Validation Error: At least one directory or file path is required`); @@ -79182,9 +79216,6 @@ var require_cache3 = __commonJS({ } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); core15.debug(`File Size: ${archiveFileSize}`); - if (archiveFileSize > constants_1.CacheFileSizeLimit && !(0, config_1.isGhes)()) { - throw new Error(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`); - } options.archiveSizeBytes = archiveFileSize; core15.debug("Reserving Cache"); const version = utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive); @@ -79196,7 +79227,10 @@ var require_cache3 = __commonJS({ try { const response = yield twirpClient.CreateCacheEntry(request); if (!response.ok) { - throw new Error("Response was not ok"); + if (response.message) { + core15.warning(`Cache reservation failed: ${response.message}`); + } + throw new Error(response.message || "Response was not ok"); } signedUploadUrl = response.signedUploadUrl; } catch (error2) { @@ -79213,6 +79247,9 @@ var require_cache3 = __commonJS({ const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest); core15.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); if (!finalizeResponse.ok) { + if (finalizeResponse.message) { + throw new FinalizeCacheError(finalizeResponse.message); + } throw new Error(`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`); } cacheId = parseInt(finalizeResponse.entryId); @@ -79222,6 +79259,8 @@ var require_cache3 = __commonJS({ throw error2; } else if (typedError.name === ReserveCacheError2.name) { core15.info(`Failed to save: ${typedError.message}`); + } else if (typedError.name === FinalizeCacheError.name) { + core15.warning(typedError.message); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { core15.error(`Failed to save: ${typedError.message}`); @@ -89753,7 +89792,7 @@ async function tryGetFolderBytes(cacheDir, logger, quiet = false) { } } var hadTimeout = false; -async function withTimeout(timeoutMs, promise, onTimeout) { +async function waitForResultWithTimeLimit(timeoutMs, promise, onTimeout) { let finished2 = false; const mainTask = async () => { const result = await promise; @@ -90197,6 +90236,14 @@ function getApiDetails() { function getApiClient() { return createApiClientWithDetails(getApiDetails()); } +function getAuthorizationHeaderFor(logger, apiDetails, url2) { + if (url2.startsWith(`${apiDetails.url}/`) || apiDetails.apiURL && url2.startsWith(`${apiDetails.apiURL}/`)) { + logger.debug(`Providing an authorization token.`); + return `token ${apiDetails.auth}`; + } + logger.debug(`Not using an authorization token.`); + return void 0; +} var cachedGitHubVersion = void 0; async function getGitHubVersionFromApi(apiClient, apiDetails) { if (parseGitHubUrl(apiDetails.url) === GITHUB_DOTCOM_URL) { @@ -90554,7 +90601,6 @@ function wrapCliConfigurationError(cliError) { // src/config-utils.ts var fs9 = __toESM(require("fs")); var path10 = __toESM(require("path")); -var semver4 = __toESM(require_semver2()); // src/caching-utils.ts var core6 = __toESM(require_core()); @@ -90568,6 +90614,15 @@ function shouldStoreCache(kind) { return kind === "full" /* Full */ || kind === "store" /* Store */; } +// src/config/db-config.ts +var semver2 = __toESM(require_semver2()); +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}$`); +})(); + // src/diff-informed-analysis-utils.ts var fs8 = __toESM(require("fs")); var path9 = __toESM(require("path")); @@ -90575,11 +90630,11 @@ var path9 = __toESM(require("path")); // src/feature-flags.ts var fs7 = __toESM(require("fs")); var path8 = __toESM(require("path")); -var semver3 = __toESM(require_semver2()); +var semver4 = __toESM(require_semver2()); // src/defaults.json -var bundleVersion = "codeql-bundle-v2.23.0"; -var cliVersion = "2.23.0"; +var bundleVersion = "codeql-bundle-v2.23.1"; +var cliVersion = "2.23.1"; // src/overlay-database-utils.ts var crypto = __toESM(require("crypto")); @@ -90810,7 +90865,7 @@ function formatDuration(durationMs) { } // src/overlay-database-utils.ts -var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; +var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.4"; 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) { @@ -90871,7 +90926,7 @@ function computeChangedFiles(baseFileOids, overlayFileOids) { } var CACHE_VERSION = 1; var CACHE_PREFIX = "codeql-overlay-base-database"; -var MAX_CACHE_OPERATION_MS = 12e4; +var MAX_CACHE_OPERATION_MS = 6e5; function checkOverlayBaseDatabase(config, logger, warningPrefix) { const baseDatabaseOidsFilePath = getBaseDatabaseOidsFilePath(config); if (!fs6.existsSync(baseDatabaseOidsFilePath)) { @@ -90939,7 +90994,7 @@ async function uploadOverlayBaseDatabaseToCache(codeql, config, logger) { `Uploading overlay-base database to Actions cache with key ${cacheSaveKey}` ); try { - const cacheId = await withTimeout( + const cacheId = await waitForResultWithTimeLimit( MAX_CACHE_OPERATION_MS, actionsCache.saveCache([dbLocation], cacheSaveKey), () => { @@ -90981,7 +91036,7 @@ function createCacheKeyHash(components) { } // src/tools-features.ts -var semver2 = __toESM(require_semver2()); +var semver3 = __toESM(require_semver2()); function isSupportedToolsFeature(versionInfo, feature) { return !!versionInfo.features && versionInfo.features[feature]; } @@ -91030,6 +91085,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", @@ -91141,11 +91202,21 @@ var featureConfig = { minimumVersion: void 0, toolsFeature: "pythonDefaultIsToNotExtractStdlib" /* PythonDefaultIsToNotExtractStdlib */ }, + ["use_repository_properties" /* UseRepositoryProperties */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_USE_REPOSITORY_PROPERTIES", + minimumVersion: void 0 + }, ["qa_telemetry_enabled" /* QaTelemetryEnabled */]: { defaultValue: false, 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"; @@ -91254,7 +91325,7 @@ var GitHubFeatureFlags = class { DEFAULT_VERSION_FEATURE_FLAG_PREFIX.length, f.length - DEFAULT_VERSION_FEATURE_FLAG_SUFFIX.length ).replace(/_/g, "."); - if (!semver3.valid(version)) { + if (!semver4.valid(version)) { this.logger.warning( `Ignoring feature flag ${f} as it does not specify a valid CodeQL version.` ); @@ -91486,7 +91557,7 @@ async function uploadTrapCaches(codeql, config, logger) { process.env.GITHUB_SHA || "unknown" ); logger.info(`Uploading TRAP cache to Actions cache with key ${key}`); - await withTimeout( + await waitForResultWithTimeLimit( MAX_CACHE_OPERATION_MS2, actionsCache2.saveCache([cacheDir], key), () => { @@ -91603,12 +91674,6 @@ var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { 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"); } @@ -91620,7 +91685,18 @@ async function getConfig(tempDir, logger) { const configString = fs9.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; } function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { const augmentedConfig = cloneObject(cliConfig); @@ -91660,7 +91736,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/stringify.js +// node_modules/uuid/dist-node/stringify.js var byteToHex = []; for (let i = 0; i < 256; ++i) { byteToHex.push((i + 256).toString(16).slice(1)); @@ -91669,7 +91745,7 @@ 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/rng.js +// node_modules/uuid/dist-node/rng.js var import_node_crypto = require("node:crypto"); var rnds8Pool = new Uint8Array(256); var poolPtr = rnds8Pool.length; @@ -91681,11 +91757,11 @@ function rng() { return rnds8Pool.slice(poolPtr, poolPtr += 16); } -// node_modules/uuid/dist/native.js +// node_modules/uuid/dist-node/native.js var import_node_crypto2 = require("node:crypto"); var native_default = { randomUUID: import_node_crypto2.randomUUID }; -// node_modules/uuid/dist/v4.js +// node_modules/uuid/dist-node/v4.js function _v4(options, buf, offset) { options = options || {}; const rnds = options.random ?? options.rng?.() ?? rng(); @@ -92028,7 +92104,10 @@ function sanitizeUrlForStatusReport(url2) { // src/setup-codeql.ts var CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; +var CODEQL_NIGHTLIES_REPOSITORY_OWNER = "dsp-testing"; +var CODEQL_NIGHTLIES_REPOSITORY_NAME = "codeql-cli-nightlies"; var CODEQL_BUNDLE_VERSION_ALIAS = ["linked", "latest"]; +var CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"]; function getCodeQLBundleExtension(compressionMethod) { switch (compressionMethod) { case "gzip": @@ -92171,7 +92250,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { return void 0; } async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, logger) { - if (toolsInput && !CODEQL_BUNDLE_VERSION_ALIAS.includes(toolsInput) && !toolsInput.startsWith("http")) { + if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); if (compressionMethod2 === void 0) { @@ -92200,6 +92279,12 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian let cliVersion2; let tagName; let url2; + if (toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { + logger.info( + `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + ); + toolsInput = await getNightlyToolsUrl(logger); + } if (forceShippedTools) { cliVersion2 = cliVersion; tagName = bundleVersion; @@ -92352,11 +92437,12 @@ var downloadCodeQL = async function(codeqlURL, compressionMethod, maybeBundleVer let authorization = void 0; if (searchParams.has("token")) { logger.debug("CodeQL tools URL contains an authorization token."); - } else if (codeqlURL.startsWith(`${apiDetails.url}/`) || apiDetails.apiURL && codeqlURL.startsWith(`${apiDetails.apiURL}/`)) { - logger.debug("Providing an authorization token to download CodeQL tools."); - authorization = `token ${apiDetails.auth}`; } else { - logger.debug("Downloading CodeQL tools without an authorization token."); + authorization = getAuthorizationHeaderFor( + logger, + apiDetails, + codeqlURL + ); } const toolcacheInfo = getToolcacheDestinationInfo( maybeBundleVersion, @@ -92483,6 +92569,34 @@ async function useZstdBundle(cliVersion2, tarSupportsZstd) { function getTempExtractionDir(tempDir) { return path12.join(tempDir, v4_default()); } +async function getNightlyToolsUrl(logger) { + const zstdAvailability = await isZstdAvailable(logger); + const compressionMethod = await useZstdBundle( + CODEQL_VERSION_ZSTD_BUNDLE, + zstdAvailability.available + ) ? "zstd" : "gzip"; + try { + const release3 = await getApiClient().rest.repos.listReleases({ + owner: CODEQL_NIGHTLIES_REPOSITORY_OWNER, + repo: CODEQL_NIGHTLIES_REPOSITORY_NAME, + per_page: 1, + page: 1, + prerelease: true + }); + const latestRelease = release3.data[0]; + if (!latestRelease) { + throw new Error("Could not find the latest nightly release."); + } + return `https://github.com/${CODEQL_NIGHTLIES_REPOSITORY_OWNER}/${CODEQL_NIGHTLIES_REPOSITORY_NAME}/releases/download/${latestRelease.tag_name}/${getCodeQLBundleName(compressionMethod)}`; + } catch (e) { + throw new Error( + `Failed to retrieve the latest nightly release: ${wrapError(e)}` + ); + } +} +function isReservedToolsValue(tools) { + return CODEQL_BUNDLE_VERSION_ALIAS.includes(tools) || CODEQL_NIGHTLY_TOOLS_INPUTS.includes(tools); +} // src/tracer-config.ts var fs13 = __toESM(require("fs")); @@ -92769,13 +92883,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); @@ -93221,7 +93338,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) { @@ -93244,7 +93361,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}...` ); @@ -93262,17 +93379,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}-`; } @@ -96054,7 +96174,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 38c842dce4..f6a3cdd902 100644 --- a/lib/autobuild-action.js +++ b/lib/autobuild-action.js @@ -26438,7 +26438,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.3", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -26447,7 +26447,7 @@ var require_package = __commonJS({ lint: "eslint --report-unused-disable-directives --max-warnings=0 .", "lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif", "lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix", - test: "npm run transpile && ava src/**.test.ts --serial --verbose", + test: "npm run transpile && ava src/ --serial --verbose", "test-debug": "npm run test -- --timeout=20m", transpile: "tsc --build --verbose" }, @@ -26463,7 +26463,7 @@ var require_package = __commonJS({ dependencies: { "@actions/artifact": "^2.3.1", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^4.0.5", + "@actions/cache": "^4.1.0", "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", @@ -26486,15 +26486,15 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^12.0.0" + uuid: "^13.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", - "@eslint/compat": "^1.3.2", + "@eslint/compat": "^1.4.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.35.0", + "@eslint/js": "^9.36.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", - "@octokit/types": "^14.1.0", + "@octokit/types": "^15.0.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", @@ -26503,10 +26503,10 @@ var require_package = __commonJS({ "@types/node-forge": "^1.3.14", "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.43.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", - esbuild: "^0.25.9", + esbuild: "^0.25.10", eslint: "^8.57.1", "eslint-import-resolver-typescript": "^3.8.7", "eslint-plugin-filenames": "^1.3.2", @@ -26536,7 +26536,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -67281,7 +67282,7 @@ var require_package2 = __commonJS({ "node_modules/@actions/cache/package.json"(exports2, module2) { module2.exports = { name: "@actions/cache", - version: "4.0.5", + version: "4.1.0", preview: true, description: "Actions cache lib", keywords: [ @@ -72090,11 +72091,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 9 /*ScalarType.STRING*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, signedUploadUrl: "" }; + const message = { ok: false, signedUploadUrl: "", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -72113,6 +72121,10 @@ var require_cache2 = __commonJS({ 2: message.signedUploadUrl = reader.string(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -72129,6 +72141,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.signedUploadUrl !== "") writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.signedUploadUrl); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -72234,11 +72248,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 3 /*ScalarType.INT64*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, entryId: "0" }; + const message = { ok: false, entryId: "0", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -72257,6 +72278,10 @@ var require_cache2 = __commonJS({ 2: message.entryId = reader.int64().toString(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -72273,6 +72298,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.entryId !== "0") writer.tag(2, runtime_1.WireType.Varint).int64(message.entryId); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -73036,7 +73063,7 @@ var require_cache3 = __commonJS({ }); }; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.ReserveCacheError = exports2.ValidationError = void 0; + exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; var core14 = __importStar4(require_core()); var path7 = __importStar4(require("path")); var utils = __importStar4(require_cacheUtils()); @@ -73044,7 +73071,6 @@ var require_cache3 = __commonJS({ var cacheTwirpClient = __importStar4(require_cacheTwirpClient()); var config_1 = require_config(); var tar_1 = require_tar(); - var constants_1 = require_constants7(); var http_client_1 = require_lib(); var ValidationError = class _ValidationError extends Error { constructor(message) { @@ -73062,6 +73088,14 @@ var require_cache3 = __commonJS({ } }; exports2.ReserveCacheError = ReserveCacheError; + var FinalizeCacheError = class _FinalizeCacheError extends Error { + constructor(message) { + super(message); + this.name = "FinalizeCacheError"; + Object.setPrototypeOf(this, _FinalizeCacheError.prototype); + } + }; + exports2.FinalizeCacheError = FinalizeCacheError; function checkPaths(paths) { if (!paths || paths.length === 0) { throw new ValidationError(`Path Validation Error: At least one directory or file path is required`); @@ -73333,9 +73367,6 @@ var require_cache3 = __commonJS({ } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); core14.debug(`File Size: ${archiveFileSize}`); - if (archiveFileSize > constants_1.CacheFileSizeLimit && !(0, config_1.isGhes)()) { - throw new Error(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`); - } options.archiveSizeBytes = archiveFileSize; core14.debug("Reserving Cache"); const version = utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive); @@ -73347,7 +73378,10 @@ var require_cache3 = __commonJS({ try { const response = yield twirpClient.CreateCacheEntry(request); if (!response.ok) { - throw new Error("Response was not ok"); + if (response.message) { + core14.warning(`Cache reservation failed: ${response.message}`); + } + throw new Error(response.message || "Response was not ok"); } signedUploadUrl = response.signedUploadUrl; } catch (error2) { @@ -73364,6 +73398,9 @@ var require_cache3 = __commonJS({ const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest); core14.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); if (!finalizeResponse.ok) { + if (finalizeResponse.message) { + throw new FinalizeCacheError(finalizeResponse.message); + } throw new Error(`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`); } cacheId = parseInt(finalizeResponse.entryId); @@ -73373,6 +73410,8 @@ var require_cache3 = __commonJS({ throw error2; } else if (typedError.name === ReserveCacheError.name) { core14.info(`Failed to save: ${typedError.message}`); + } else if (typedError.name === FinalizeCacheError.name) { + core14.warning(typedError.message); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { core14.error(`Failed to save: ${typedError.message}`); @@ -78228,7 +78267,6 @@ function wrapCliConfigurationError(cliError) { // src/config-utils.ts var fs4 = __toESM(require("fs")); var path4 = __toESM(require("path")); -var semver4 = __toESM(require_semver2()); // src/analyses.ts var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { @@ -78241,14 +78279,23 @@ var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); // src/caching-utils.ts var core6 = __toESM(require_core()); +// src/config/db-config.ts +var semver2 = __toESM(require_semver2()); +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}$`); +})(); + // src/feature-flags.ts var fs3 = __toESM(require("fs")); var path3 = __toESM(require("path")); -var semver3 = __toESM(require_semver2()); +var semver4 = __toESM(require_semver2()); // src/defaults.json -var bundleVersion = "codeql-bundle-v2.23.0"; -var cliVersion = "2.23.0"; +var bundleVersion = "codeql-bundle-v2.23.1"; +var cliVersion = "2.23.1"; // src/overlay-database-utils.ts var fs2 = __toESM(require("fs")); @@ -78425,7 +78472,7 @@ function getActionsLogger() { } // src/overlay-database-utils.ts -var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; +var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.4"; 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) { @@ -78486,7 +78533,7 @@ function computeChangedFiles(baseFileOids, overlayFileOids) { } // src/tools-features.ts -var semver2 = __toESM(require_semver2()); +var semver3 = __toESM(require_semver2()); function isSupportedToolsFeature(versionInfo, feature) { return !!versionInfo.features && versionInfo.features[feature]; } @@ -78534,6 +78581,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", @@ -78645,11 +78698,21 @@ var featureConfig = { minimumVersion: void 0, toolsFeature: "pythonDefaultIsToNotExtractStdlib" /* PythonDefaultIsToNotExtractStdlib */ }, + ["use_repository_properties" /* UseRepositoryProperties */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_USE_REPOSITORY_PROPERTIES", + minimumVersion: void 0 + }, ["qa_telemetry_enabled" /* QaTelemetryEnabled */]: { defaultValue: false, 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"; @@ -78758,7 +78821,7 @@ var GitHubFeatureFlags = class { DEFAULT_VERSION_FEATURE_FLAG_PREFIX.length, f.length - DEFAULT_VERSION_FEATURE_FLAG_SUFFIX.length ).replace(/_/g, "."); - if (!semver3.valid(version)) { + if (!semver4.valid(version)) { this.logger.warning( `Ignoring feature flag ${f} as it does not specify a valid CodeQL version.` ); @@ -78945,12 +79008,6 @@ var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { 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 path4.join(tempDir, "config"); } @@ -78962,7 +79019,18 @@ async function getConfig(tempDir, logger) { const configString = fs4.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; } function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { const augmentedConfig = cloneObject(cliConfig); @@ -79241,13 +79309,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); diff --git a/lib/defaults.json b/lib/defaults.json index 712efc19fe..dbc0d5e258 100644 --- a/lib/defaults.json +++ b/lib/defaults.json @@ -1,6 +1,6 @@ { - "bundleVersion": "codeql-bundle-v2.23.0", - "cliVersion": "2.23.0", - "priorBundleVersion": "codeql-bundle-v2.22.4", - "priorCliVersion": "2.22.4" + "bundleVersion": "codeql-bundle-v2.23.1", + "cliVersion": "2.23.1", + "priorBundleVersion": "codeql-bundle-v2.23.0", + "priorCliVersion": "2.23.0" } diff --git a/lib/init-action-post.js b/lib/init-action-post.js index 1cb50a92d3..65dadeb7de 100644 --- a/lib/init-action-post.js +++ b/lib/init-action-post.js @@ -27722,7 +27722,7 @@ var require_pattern = __commonJS({ const absolute = []; const relative2 = []; for (const pattern of patterns) { - if (isAbsolute3(pattern)) { + if (isAbsolute2(pattern)) { absolute.push(pattern); } else { relative2.push(pattern); @@ -27731,10 +27731,10 @@ var require_pattern = __commonJS({ return [absolute, relative2]; } exports2.partitionAbsoluteAndRelative = partitionAbsoluteAndRelative; - function isAbsolute3(pattern) { + function isAbsolute2(pattern) { return path19.isAbsolute(pattern); } - exports2.isAbsolute = isAbsolute3; + exports2.isAbsolute = isAbsolute2; } }); @@ -32287,7 +32287,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.3", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -32296,7 +32296,7 @@ var require_package = __commonJS({ lint: "eslint --report-unused-disable-directives --max-warnings=0 .", "lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif", "lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix", - test: "npm run transpile && ava src/**.test.ts --serial --verbose", + test: "npm run transpile && ava src/ --serial --verbose", "test-debug": "npm run test -- --timeout=20m", transpile: "tsc --build --verbose" }, @@ -32312,7 +32312,7 @@ var require_package = __commonJS({ dependencies: { "@actions/artifact": "^2.3.1", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^4.0.5", + "@actions/cache": "^4.1.0", "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", @@ -32335,15 +32335,15 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^12.0.0" + uuid: "^13.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", - "@eslint/compat": "^1.3.2", + "@eslint/compat": "^1.4.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.35.0", + "@eslint/js": "^9.36.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", - "@octokit/types": "^14.1.0", + "@octokit/types": "^15.0.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", @@ -32352,10 +32352,10 @@ var require_package = __commonJS({ "@types/node-forge": "^1.3.14", "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.43.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", - esbuild: "^0.25.9", + esbuild: "^0.25.10", eslint: "^8.57.1", "eslint-import-resolver-typescript": "^3.8.7", "eslint-plugin-filenames": "^1.3.2", @@ -32385,7 +32385,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -73130,7 +73131,7 @@ var require_package2 = __commonJS({ "node_modules/@actions/cache/package.json"(exports2, module2) { module2.exports = { name: "@actions/cache", - version: "4.0.5", + version: "4.1.0", preview: true, description: "Actions cache lib", keywords: [ @@ -77939,11 +77940,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 9 /*ScalarType.STRING*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, signedUploadUrl: "" }; + const message = { ok: false, signedUploadUrl: "", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -77962,6 +77970,10 @@ var require_cache2 = __commonJS({ 2: message.signedUploadUrl = reader.string(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -77978,6 +77990,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.signedUploadUrl !== "") writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.signedUploadUrl); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -78083,11 +78097,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 3 /*ScalarType.INT64*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, entryId: "0" }; + const message = { ok: false, entryId: "0", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -78106,6 +78127,10 @@ var require_cache2 = __commonJS({ 2: message.entryId = reader.int64().toString(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -78122,6 +78147,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.entryId !== "0") writer.tag(2, runtime_1.WireType.Varint).int64(message.entryId); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -78885,7 +78912,7 @@ var require_cache3 = __commonJS({ }); }; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.ReserveCacheError = exports2.ValidationError = void 0; + exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; var core18 = __importStar4(require_core()); var path19 = __importStar4(require("path")); var utils = __importStar4(require_cacheUtils()); @@ -78893,7 +78920,6 @@ var require_cache3 = __commonJS({ var cacheTwirpClient = __importStar4(require_cacheTwirpClient()); var config_1 = require_config(); var tar_1 = require_tar(); - var constants_1 = require_constants10(); var http_client_1 = require_lib(); var ValidationError = class _ValidationError extends Error { constructor(message) { @@ -78911,6 +78937,14 @@ var require_cache3 = __commonJS({ } }; exports2.ReserveCacheError = ReserveCacheError2; + var FinalizeCacheError = class _FinalizeCacheError extends Error { + constructor(message) { + super(message); + this.name = "FinalizeCacheError"; + Object.setPrototypeOf(this, _FinalizeCacheError.prototype); + } + }; + exports2.FinalizeCacheError = FinalizeCacheError; function checkPaths(paths) { if (!paths || paths.length === 0) { throw new ValidationError(`Path Validation Error: At least one directory or file path is required`); @@ -79182,9 +79216,6 @@ var require_cache3 = __commonJS({ } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); core18.debug(`File Size: ${archiveFileSize}`); - if (archiveFileSize > constants_1.CacheFileSizeLimit && !(0, config_1.isGhes)()) { - throw new Error(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`); - } options.archiveSizeBytes = archiveFileSize; core18.debug("Reserving Cache"); const version = utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive); @@ -79196,7 +79227,10 @@ var require_cache3 = __commonJS({ try { const response = yield twirpClient.CreateCacheEntry(request); if (!response.ok) { - throw new Error("Response was not ok"); + if (response.message) { + core18.warning(`Cache reservation failed: ${response.message}`); + } + throw new Error(response.message || "Response was not ok"); } signedUploadUrl = response.signedUploadUrl; } catch (error2) { @@ -79213,6 +79247,9 @@ var require_cache3 = __commonJS({ const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest); core18.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); if (!finalizeResponse.ok) { + if (finalizeResponse.message) { + throw new FinalizeCacheError(finalizeResponse.message); + } throw new Error(`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`); } cacheId = parseInt(finalizeResponse.entryId); @@ -79222,6 +79259,8 @@ var require_cache3 = __commonJS({ throw error2; } else if (typedError.name === ReserveCacheError2.name) { core18.info(`Failed to save: ${typedError.message}`); + } else if (typedError.name === FinalizeCacheError.name) { + core18.warning(typedError.message); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { core18.error(`Failed to save: ${typedError.message}`); @@ -83534,7 +83573,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); } @@ -100644,7 +100683,7 @@ var require_commonjs16 = __commonJS({ var TYPEMASK = 1023; var entToType = (s) => s.isFile() ? IFREG : s.isDirectory() ? IFDIR : s.isSymbolicLink() ? IFLNK : s.isCharacterDevice() ? IFCHR : s.isBlockDevice() ? IFBLK : s.isSocket() ? IFSOCK : s.isFIFO() ? IFIFO : UNKNOWN; var normalizeCache = /* @__PURE__ */ new Map(); - var normalize4 = (s) => { + var normalize3 = (s) => { const c = normalizeCache.get(s); if (c) return c; @@ -100657,7 +100696,7 @@ var require_commonjs16 = __commonJS({ const c = normalizeNocaseCache.get(s); if (c) return c; - const n = normalize4(s.toLowerCase()); + const n = normalize3(s.toLowerCase()); normalizeNocaseCache.set(s, n); return n; }; @@ -100826,7 +100865,7 @@ var require_commonjs16 = __commonJS({ */ constructor(name, type2 = UNKNOWN, root, roots, nocase, children, opts) { this.name = name; - this.#matchName = nocase ? normalizeNocase(name) : normalize4(name); + this.#matchName = nocase ? normalizeNocase(name) : normalize3(name); this.#type = type2 & TYPEMASK; this.nocase = nocase; this.roots = roots; @@ -100919,7 +100958,7 @@ var require_commonjs16 = __commonJS({ return this.parent || this; } const children = this.children(); - const name = this.nocase ? normalizeNocase(pathPart) : normalize4(pathPart); + const name = this.nocase ? normalizeNocase(pathPart) : normalize3(pathPart); for (const p of children) { if (p.#matchName === name) { return p; @@ -101164,7 +101203,7 @@ var require_commonjs16 = __commonJS({ * directly. */ isNamed(n) { - return !this.nocase ? this.#matchName === normalize4(n) : this.#matchName === normalizeNocase(n); + return !this.nocase ? this.#matchName === normalize3(n) : this.#matchName === normalizeNocase(n); } /** * Return the Path object corresponding to the target of a symbolic link. @@ -101303,7 +101342,7 @@ var require_commonjs16 = __commonJS({ #readdirMaybePromoteChild(e, c) { for (let p = c.provisional; p < c.length; p++) { const pchild = c[p]; - const name = this.nocase ? normalizeNocase(e.name) : normalize4(e.name); + const name = this.nocase ? normalizeNocase(e.name) : normalize3(e.name); if (name !== pchild.#matchName) { continue; } @@ -109134,7 +109173,7 @@ var require_tr46 = __commonJS({ TRANSITIONAL: 0, NONTRANSITIONAL: 1 }; - function normalize4(str2) { + function normalize3(str2) { return str2.split("\0").map(function(s) { return s.normalize("NFC"); }).join("\0"); @@ -109214,7 +109253,7 @@ var require_tr46 = __commonJS({ processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL; } var error2 = false; - if (normalize4(label) !== label || label[3] === "-" && label[4] === "-" || label[0] === "-" || label[label.length - 1] === "-" || label.indexOf(".") !== -1 || label.search(combiningMarksRegex) === 0) { + if (normalize3(label) !== label || label[3] === "-" && label[4] === "-" || label[0] === "-" || label[label.length - 1] === "-" || label.indexOf(".") !== -1 || label.search(combiningMarksRegex) === 0) { error2 = true; } var len = countSymbols(label); @@ -109232,7 +109271,7 @@ var require_tr46 = __commonJS({ } function processing(domain_name, useSTD3, processing_option) { var result = mapChars(domain_name, useSTD3, processing_option); - result.string = normalize4(result.string); + result.string = normalize3(result.string); var labels = result.string.split("."); for (var i = 0; i < labels.length; ++i) { try { @@ -128416,6 +128455,14 @@ function getApiDetails() { function getApiClient() { return createApiClientWithDetails(getApiDetails()); } +function getAuthorizationHeaderFor(logger, apiDetails, url2) { + if (url2.startsWith(`${apiDetails.url}/`) || apiDetails.apiURL && url2.startsWith(`${apiDetails.apiURL}/`)) { + logger.debug(`Providing an authorization token.`); + return `token ${apiDetails.auth}`; + } + logger.debug(`Not using an authorization token.`); + return void 0; +} var cachedGitHubVersion = void 0; async function getGitHubVersionFromApi(apiClient, apiDetails) { if (parseGitHubUrl(apiDetails.url) === GITHUB_DOTCOM_URL) { @@ -128745,7 +128792,6 @@ function wrapCliConfigurationError(cliError) { // src/config-utils.ts var fs9 = __toESM(require("fs")); var path10 = __toESM(require("path")); -var semver4 = __toESM(require_semver2()); // src/analyses.ts var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { @@ -128774,6 +128820,15 @@ var CodeQuality = { // src/caching-utils.ts var core6 = __toESM(require_core()); +// src/config/db-config.ts +var semver2 = __toESM(require_semver2()); +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}$`); +})(); + // src/diff-informed-analysis-utils.ts var fs8 = __toESM(require("fs")); var path9 = __toESM(require("path")); @@ -128781,11 +128836,11 @@ var path9 = __toESM(require("path")); // src/feature-flags.ts var fs7 = __toESM(require("fs")); var path8 = __toESM(require("path")); -var semver3 = __toESM(require_semver2()); +var semver4 = __toESM(require_semver2()); // src/defaults.json -var bundleVersion = "codeql-bundle-v2.23.0"; -var cliVersion = "2.23.0"; +var bundleVersion = "codeql-bundle-v2.23.1"; +var cliVersion = "2.23.1"; // src/overlay-database-utils.ts var fs6 = __toESM(require("fs")); @@ -129015,7 +129070,7 @@ function formatDuration(durationMs) { } // src/overlay-database-utils.ts -var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; +var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.4"; 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) { @@ -129076,13 +129131,13 @@ function computeChangedFiles(baseFileOids, overlayFileOids) { } // src/tools-features.ts -var semver2 = __toESM(require_semver2()); +var semver3 = __toESM(require_semver2()); function isSupportedToolsFeature(versionInfo, feature) { return !!versionInfo.features && versionInfo.features[feature]; } var SafeArtifactUploadVersion = "2.20.3"; function isSafeArtifactUpload(codeQlVersion) { - return !codeQlVersion ? true : semver2.gte(codeQlVersion, SafeArtifactUploadVersion); + return !codeQlVersion ? true : semver3.gte(codeQlVersion, SafeArtifactUploadVersion); } // src/feature-flags.ts @@ -129129,6 +129184,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", @@ -129240,11 +129301,21 @@ var featureConfig = { minimumVersion: void 0, toolsFeature: "pythonDefaultIsToNotExtractStdlib" /* PythonDefaultIsToNotExtractStdlib */ }, + ["use_repository_properties" /* UseRepositoryProperties */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_USE_REPOSITORY_PROPERTIES", + minimumVersion: void 0 + }, ["qa_telemetry_enabled" /* QaTelemetryEnabled */]: { defaultValue: false, 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"; @@ -129353,7 +129424,7 @@ var GitHubFeatureFlags = class { DEFAULT_VERSION_FEATURE_FLAG_PREFIX.length, f.length - DEFAULT_VERSION_FEATURE_FLAG_SUFFIX.length ).replace(/_/g, "."); - if (!semver3.valid(version)) { + if (!semver4.valid(version)) { this.logger.warning( `Ignoring feature flag ${f} as it does not specify a valid CodeQL version.` ); @@ -129558,12 +129629,6 @@ var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { 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"); } @@ -129575,7 +129640,18 @@ async function getConfig(tempDir, logger) { const configString = fs9.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; } function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { const augmentedConfig = cloneObject(cliConfig); @@ -129603,7 +129679,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/stringify.js +// node_modules/uuid/dist-node/stringify.js var byteToHex = []; for (let i = 0; i < 256; ++i) { byteToHex.push((i + 256).toString(16).slice(1)); @@ -129612,7 +129688,7 @@ 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/rng.js +// node_modules/uuid/dist-node/rng.js var import_node_crypto = require("node:crypto"); var rnds8Pool = new Uint8Array(256); var poolPtr = rnds8Pool.length; @@ -129624,11 +129700,11 @@ function rng() { return rnds8Pool.slice(poolPtr, poolPtr += 16); } -// node_modules/uuid/dist/native.js +// node_modules/uuid/dist-node/native.js var import_node_crypto2 = require("node:crypto"); var native_default = { randomUUID: import_node_crypto2.randomUUID }; -// node_modules/uuid/dist/v4.js +// node_modules/uuid/dist-node/v4.js function _v4(options, buf, offset) { options = options || {}; const rnds = options.random ?? options.rng?.() ?? rng(); @@ -129971,7 +130047,10 @@ function sanitizeUrlForStatusReport(url2) { // src/setup-codeql.ts var CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; +var CODEQL_NIGHTLIES_REPOSITORY_OWNER = "dsp-testing"; +var CODEQL_NIGHTLIES_REPOSITORY_NAME = "codeql-cli-nightlies"; var CODEQL_BUNDLE_VERSION_ALIAS = ["linked", "latest"]; +var CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"]; function getCodeQLBundleExtension(compressionMethod) { switch (compressionMethod) { case "gzip": @@ -130114,7 +130193,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { return void 0; } async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, logger) { - if (toolsInput && !CODEQL_BUNDLE_VERSION_ALIAS.includes(toolsInput) && !toolsInput.startsWith("http")) { + if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); if (compressionMethod2 === void 0) { @@ -130143,6 +130222,12 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian let cliVersion2; let tagName; let url2; + if (toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { + logger.info( + `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + ); + toolsInput = await getNightlyToolsUrl(logger); + } if (forceShippedTools) { cliVersion2 = cliVersion; tagName = bundleVersion; @@ -130295,11 +130380,12 @@ var downloadCodeQL = async function(codeqlURL, compressionMethod, maybeBundleVer let authorization = void 0; if (searchParams.has("token")) { logger.debug("CodeQL tools URL contains an authorization token."); - } else if (codeqlURL.startsWith(`${apiDetails.url}/`) || apiDetails.apiURL && codeqlURL.startsWith(`${apiDetails.apiURL}/`)) { - logger.debug("Providing an authorization token to download CodeQL tools."); - authorization = `token ${apiDetails.auth}`; } else { - logger.debug("Downloading CodeQL tools without an authorization token."); + authorization = getAuthorizationHeaderFor( + logger, + apiDetails, + codeqlURL + ); } const toolcacheInfo = getToolcacheDestinationInfo( maybeBundleVersion, @@ -130426,6 +130512,34 @@ async function useZstdBundle(cliVersion2, tarSupportsZstd) { function getTempExtractionDir(tempDir) { return path12.join(tempDir, v4_default()); } +async function getNightlyToolsUrl(logger) { + const zstdAvailability = await isZstdAvailable(logger); + const compressionMethod = await useZstdBundle( + CODEQL_VERSION_ZSTD_BUNDLE, + zstdAvailability.available + ) ? "zstd" : "gzip"; + try { + const release3 = await getApiClient().rest.repos.listReleases({ + owner: CODEQL_NIGHTLIES_REPOSITORY_OWNER, + repo: CODEQL_NIGHTLIES_REPOSITORY_NAME, + per_page: 1, + page: 1, + prerelease: true + }); + const latestRelease = release3.data[0]; + if (!latestRelease) { + throw new Error("Could not find the latest nightly release."); + } + return `https://github.com/${CODEQL_NIGHTLIES_REPOSITORY_OWNER}/${CODEQL_NIGHTLIES_REPOSITORY_NAME}/releases/download/${latestRelease.tag_name}/${getCodeQLBundleName(compressionMethod)}`; + } catch (e) { + throw new Error( + `Failed to retrieve the latest nightly release: ${wrapError(e)}` + ); + } +} +function isReservedToolsValue(tools) { + return CODEQL_BUNDLE_VERSION_ALIAS.includes(tools) || CODEQL_NIGHTLY_TOOLS_INPUTS.includes(tools); +} // src/tracer-config.ts async function shouldEnableIndirectTracing(codeql, config) { @@ -130679,13 +130793,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); @@ -133274,7 +133391,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"]; diff --git a/lib/init-action.js b/lib/init-action.js index 804f24af12..e8cd76dc98 100644 --- a/lib/init-action.js +++ b/lib/init-action.js @@ -999,14 +999,14 @@ var require_util = __commonJS({ } const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80; let origin = url.origin != null ? url.origin : `${url.protocol}//${url.hostname}:${port}`; - let path19 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`; + let path20 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`; if (origin.endsWith("/")) { origin = origin.substring(0, origin.length - 1); } - if (path19 && !path19.startsWith("/")) { - path19 = `/${path19}`; + if (path20 && !path20.startsWith("/")) { + path20 = `/${path20}`; } - url = new URL(origin + path19); + url = new URL(origin + path20); } return url; } @@ -2620,20 +2620,20 @@ var require_parseParams = __commonJS({ var require_basename = __commonJS({ "node_modules/@fastify/busboy/lib/utils/basename.js"(exports2, module2) { "use strict"; - module2.exports = function basename(path19) { - if (typeof path19 !== "string") { + module2.exports = function basename(path20) { + if (typeof path20 !== "string") { return ""; } - for (var i = path19.length - 1; i >= 0; --i) { - switch (path19.charCodeAt(i)) { + for (var i = path20.length - 1; i >= 0; --i) { + switch (path20.charCodeAt(i)) { case 47: // '/' case 92: - path19 = path19.slice(i + 1); - return path19 === ".." || path19 === "." ? "" : path19; + path20 = path20.slice(i + 1); + return path20 === ".." || path20 === "." ? "" : path20; } } - return path19 === ".." || path19 === "." ? "" : path19; + return path20 === ".." || path20 === "." ? "" : path20; }; } }); @@ -5663,7 +5663,7 @@ var require_request = __commonJS({ } var Request = class _Request { constructor(origin, { - path: path19, + path: path20, method, body, headers, @@ -5677,11 +5677,11 @@ var require_request = __commonJS({ throwOnError, expectContinue }, handler) { - if (typeof path19 !== "string") { + if (typeof path20 !== "string") { throw new InvalidArgumentError("path must be a string"); - } else if (path19[0] !== "/" && !(path19.startsWith("http://") || path19.startsWith("https://")) && method !== "CONNECT") { + } else if (path20[0] !== "/" && !(path20.startsWith("http://") || path20.startsWith("https://")) && method !== "CONNECT") { throw new InvalidArgumentError("path must be an absolute URL or start with a slash"); - } else if (invalidPathRegex.exec(path19) !== null) { + } else if (invalidPathRegex.exec(path20) !== null) { throw new InvalidArgumentError("invalid request path"); } if (typeof method !== "string") { @@ -5744,7 +5744,7 @@ var require_request = __commonJS({ this.completed = false; this.aborted = false; this.upgrade = upgrade || null; - this.path = query ? util.buildURL(path19, query) : path19; + this.path = query ? util.buildURL(path20, query) : path20; this.origin = origin; this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent; this.blocking = blocking == null ? false : blocking; @@ -6752,9 +6752,9 @@ var require_RedirectHandler = __commonJS({ return this.handler.onHeaders(statusCode, headers, resume, statusText); } const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin))); - const path19 = search ? `${pathname}${search}` : pathname; + const path20 = search ? `${pathname}${search}` : pathname; this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin); - this.opts.path = path19; + this.opts.path = path20; this.opts.origin = origin; this.opts.maxRedirections = 0; this.opts.query = null; @@ -7994,7 +7994,7 @@ var require_client = __commonJS({ writeH2(client, client[kHTTP2Session], request); return; } - const { body, method, path: path19, host, upgrade, headers, blocking, reset } = request; + const { body, method, path: path20, host, upgrade, headers, blocking, reset } = request; const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH"; if (body && typeof body.read === "function") { body.read(0); @@ -8044,7 +8044,7 @@ var require_client = __commonJS({ if (blocking) { socket[kBlocking] = true; } - let header = `${method} ${path19} HTTP/1.1\r + let header = `${method} ${path20} HTTP/1.1\r `; if (typeof host === "string") { header += `host: ${host}\r @@ -8107,7 +8107,7 @@ upgrade: ${upgrade}\r return true; } function writeH2(client, session, request) { - const { body, method, path: path19, host, upgrade, expectContinue, signal, headers: reqHeaders } = request; + const { body, method, path: path20, host, upgrade, expectContinue, signal, headers: reqHeaders } = request; let headers; if (typeof reqHeaders === "string") headers = Request[kHTTP2CopyHeaders](reqHeaders.trim()); else headers = reqHeaders; @@ -8150,7 +8150,7 @@ upgrade: ${upgrade}\r }); return true; } - headers[HTTP2_HEADER_PATH] = path19; + headers[HTTP2_HEADER_PATH] = path20; headers[HTTP2_HEADER_SCHEME] = "https"; const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH"; if (body && typeof body.read === "function") { @@ -10390,20 +10390,20 @@ var require_mock_utils = __commonJS({ } return true; } - function safeUrl(path19) { - if (typeof path19 !== "string") { - return path19; + function safeUrl(path20) { + if (typeof path20 !== "string") { + return path20; } - const pathSegments = path19.split("?"); + const pathSegments = path20.split("?"); if (pathSegments.length !== 2) { - return path19; + return path20; } const qp = new URLSearchParams(pathSegments.pop()); qp.sort(); return [...pathSegments, qp.toString()].join("?"); } - function matchKey(mockDispatch2, { path: path19, method, body, headers }) { - const pathMatch = matchValue(mockDispatch2.path, path19); + function matchKey(mockDispatch2, { path: path20, method, body, headers }) { + const pathMatch = matchValue(mockDispatch2.path, path20); const methodMatch = matchValue(mockDispatch2.method, method); const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true; const headersMatch = matchHeaders(mockDispatch2, headers); @@ -10421,7 +10421,7 @@ var require_mock_utils = __commonJS({ function getMockDispatch(mockDispatches, key) { const basePath = key.query ? buildURL(key.path, key.query) : key.path; const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath; - let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path19 }) => matchValue(safeUrl(path19), resolvedPath)); + let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path20 }) => matchValue(safeUrl(path20), resolvedPath)); if (matchedMockDispatches.length === 0) { throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`); } @@ -10458,9 +10458,9 @@ var require_mock_utils = __commonJS({ } } function buildKey(opts) { - const { path: path19, method, body, headers, query } = opts; + const { path: path20, method, body, headers, query } = opts; return { - path: path19, + path: path20, method, body, headers, @@ -10909,10 +10909,10 @@ var require_pending_interceptors_formatter = __commonJS({ } format(pendingInterceptors) { const withPrettyHeaders = pendingInterceptors.map( - ({ method, path: path19, data: { statusCode }, persist, times, timesInvoked, origin }) => ({ + ({ method, path: path20, data: { statusCode }, persist, times, timesInvoked, origin }) => ({ Method: method, Origin: origin, - Path: path19, + Path: path20, "Status code": statusCode, Persistent: persist ? "\u2705" : "\u274C", Invocations: timesInvoked, @@ -15532,8 +15532,8 @@ var require_util6 = __commonJS({ } } } - function validateCookiePath(path19) { - for (const char of path19) { + function validateCookiePath(path20) { + for (const char of path20) { const code = char.charCodeAt(0); if (code < 33 || char === ";") { throw new Error("Invalid cookie path"); @@ -17213,11 +17213,11 @@ var require_undici = __commonJS({ if (typeof opts.path !== "string") { throw new InvalidArgumentError("invalid opts.path"); } - let path19 = opts.path; + let path20 = opts.path; if (!opts.path.startsWith("/")) { - path19 = `/${path19}`; + path20 = `/${path20}`; } - url = new URL(util.parseOrigin(url).origin + path19); + url = new URL(util.parseOrigin(url).origin + path20); } else { if (!opts) { opts = typeof url === "object" ? url : {}; @@ -18440,7 +18440,7 @@ var require_path_utils = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.toPlatformPath = exports2.toWin32Path = exports2.toPosixPath = void 0; - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); function toPosixPath(pth) { return pth.replace(/[\\]/g, "/"); } @@ -18450,7 +18450,7 @@ var require_path_utils = __commonJS({ } exports2.toWin32Path = toWin32Path; function toPlatformPath(pth) { - return pth.replace(/[/\\]/g, path19.sep); + return pth.replace(/[/\\]/g, path20.sep); } exports2.toPlatformPath = toPlatformPath; } @@ -18514,7 +18514,7 @@ var require_io_util = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.getCmdPath = exports2.tryGetExecutablePath = exports2.isRooted = exports2.isDirectory = exports2.exists = exports2.READONLY = exports2.UV_FS_O_EXLOCK = exports2.IS_WINDOWS = exports2.unlink = exports2.symlink = exports2.stat = exports2.rmdir = exports2.rm = exports2.rename = exports2.readlink = exports2.readdir = exports2.open = exports2.mkdir = exports2.lstat = exports2.copyFile = exports2.chmod = void 0; var fs18 = __importStar4(require("fs")); - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); _a = fs18.promises, exports2.chmod = _a.chmod, exports2.copyFile = _a.copyFile, exports2.lstat = _a.lstat, exports2.mkdir = _a.mkdir, exports2.open = _a.open, exports2.readdir = _a.readdir, exports2.readlink = _a.readlink, exports2.rename = _a.rename, exports2.rm = _a.rm, exports2.rmdir = _a.rmdir, exports2.stat = _a.stat, exports2.symlink = _a.symlink, exports2.unlink = _a.unlink; exports2.IS_WINDOWS = process.platform === "win32"; exports2.UV_FS_O_EXLOCK = 268435456; @@ -18563,7 +18563,7 @@ var require_io_util = __commonJS({ } if (stats && stats.isFile()) { if (exports2.IS_WINDOWS) { - const upperExt = path19.extname(filePath).toUpperCase(); + const upperExt = path20.extname(filePath).toUpperCase(); if (extensions.some((validExt) => validExt.toUpperCase() === upperExt)) { return filePath; } @@ -18587,11 +18587,11 @@ var require_io_util = __commonJS({ if (stats && stats.isFile()) { if (exports2.IS_WINDOWS) { try { - const directory = path19.dirname(filePath); - const upperName = path19.basename(filePath).toUpperCase(); + const directory = path20.dirname(filePath); + const upperName = path20.basename(filePath).toUpperCase(); for (const actualName of yield exports2.readdir(directory)) { if (upperName === actualName.toUpperCase()) { - filePath = path19.join(directory, actualName); + filePath = path20.join(directory, actualName); break; } } @@ -18686,7 +18686,7 @@ var require_io = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.findInPath = exports2.which = exports2.mkdirP = exports2.rmRF = exports2.mv = exports2.cp = void 0; var assert_1 = require("assert"); - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var ioUtil = __importStar4(require_io_util()); function cp(source, dest, options = {}) { return __awaiter4(this, void 0, void 0, function* () { @@ -18695,7 +18695,7 @@ var require_io = __commonJS({ if (destStat && destStat.isFile() && !force) { return; } - const newDest = destStat && destStat.isDirectory() && copySourceDirectory ? path19.join(dest, path19.basename(source)) : dest; + const newDest = destStat && destStat.isDirectory() && copySourceDirectory ? path20.join(dest, path20.basename(source)) : dest; if (!(yield ioUtil.exists(source))) { throw new Error(`no such file or directory: ${source}`); } @@ -18707,7 +18707,7 @@ var require_io = __commonJS({ yield cpDirRecursive(source, newDest, 0, force); } } else { - if (path19.relative(source, newDest) === "") { + if (path20.relative(source, newDest) === "") { throw new Error(`'${newDest}' and '${source}' are the same file`); } yield copyFile(source, newDest, force); @@ -18720,7 +18720,7 @@ var require_io = __commonJS({ if (yield ioUtil.exists(dest)) { let destExists = true; if (yield ioUtil.isDirectory(dest)) { - dest = path19.join(dest, path19.basename(source)); + dest = path20.join(dest, path20.basename(source)); destExists = yield ioUtil.exists(dest); } if (destExists) { @@ -18731,7 +18731,7 @@ var require_io = __commonJS({ } } } - yield mkdirP(path19.dirname(dest)); + yield mkdirP(path20.dirname(dest)); yield ioUtil.rename(source, dest); }); } @@ -18794,7 +18794,7 @@ var require_io = __commonJS({ } const extensions = []; if (ioUtil.IS_WINDOWS && process.env["PATHEXT"]) { - for (const extension of process.env["PATHEXT"].split(path19.delimiter)) { + for (const extension of process.env["PATHEXT"].split(path20.delimiter)) { if (extension) { extensions.push(extension); } @@ -18807,12 +18807,12 @@ var require_io = __commonJS({ } return []; } - if (tool.includes(path19.sep)) { + if (tool.includes(path20.sep)) { return []; } const directories = []; if (process.env.PATH) { - for (const p of process.env.PATH.split(path19.delimiter)) { + for (const p of process.env.PATH.split(path20.delimiter)) { if (p) { directories.push(p); } @@ -18820,7 +18820,7 @@ var require_io = __commonJS({ } const matches = []; for (const directory of directories) { - const filePath = yield ioUtil.tryGetExecutablePath(path19.join(directory, tool), extensions); + const filePath = yield ioUtil.tryGetExecutablePath(path20.join(directory, tool), extensions); if (filePath) { matches.push(filePath); } @@ -18936,7 +18936,7 @@ var require_toolrunner = __commonJS({ var os5 = __importStar4(require("os")); var events = __importStar4(require("events")); var child = __importStar4(require("child_process")); - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var io7 = __importStar4(require_io()); var ioUtil = __importStar4(require_io_util()); var timers_1 = require("timers"); @@ -19151,7 +19151,7 @@ var require_toolrunner = __commonJS({ exec() { return __awaiter4(this, void 0, void 0, function* () { if (!ioUtil.isRooted(this.toolPath) && (this.toolPath.includes("/") || IS_WINDOWS && this.toolPath.includes("\\"))) { - this.toolPath = path19.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath); + this.toolPath = path20.resolve(process.cwd(), this.options.cwd || process.cwd(), this.toolPath); } this.toolPath = yield io7.which(this.toolPath, true); return new Promise((resolve9, reject) => __awaiter4(this, void 0, void 0, function* () { @@ -19651,7 +19651,7 @@ var require_core = __commonJS({ var file_command_1 = require_file_command(); var utils_1 = require_utils(); var os5 = __importStar4(require("os")); - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var oidc_utils_1 = require_oidc_utils(); var ExitCode; (function(ExitCode2) { @@ -19679,7 +19679,7 @@ var require_core = __commonJS({ } else { (0, command_1.issueCommand)("add-path", {}, inputPath); } - process.env["PATH"] = `${inputPath}${path19.delimiter}${process.env["PATH"]}`; + process.env["PATH"] = `${inputPath}${path20.delimiter}${process.env["PATH"]}`; } exports2.addPath = addPath2; function getInput2(name, options) { @@ -21743,8 +21743,8 @@ var require_context = __commonJS({ if ((0, fs_1.existsSync)(process.env.GITHUB_EVENT_PATH)) { this.payload = JSON.parse((0, fs_1.readFileSync)(process.env.GITHUB_EVENT_PATH, { encoding: "utf8" })); } else { - const path19 = process.env.GITHUB_EVENT_PATH; - process.stdout.write(`GITHUB_EVENT_PATH ${path19} does not exist${os_1.EOL}`); + const path20 = process.env.GITHUB_EVENT_PATH; + process.stdout.write(`GITHUB_EVENT_PATH ${path20} does not exist${os_1.EOL}`); } } this.eventName = process.env.GITHUB_EVENT_NAME; @@ -26505,7 +26505,7 @@ var require_path = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.convertPosixPathToPattern = exports2.convertWindowsPathToPattern = exports2.convertPathToPattern = exports2.escapePosixPath = exports2.escapeWindowsPath = exports2.escape = exports2.removeLeadingDotSegment = exports2.makeAbsolute = exports2.unixify = void 0; var os5 = require("os"); - var path19 = require("path"); + var path20 = require("path"); var IS_WINDOWS_PLATFORM = os5.platform() === "win32"; var LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; var POSIX_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\()|\\(?![!()*+?@[\]{|}]))/g; @@ -26517,7 +26517,7 @@ var require_path = __commonJS({ } exports2.unixify = unixify; function makeAbsolute(cwd, filepath) { - return path19.resolve(cwd, filepath); + return path20.resolve(cwd, filepath); } exports2.makeAbsolute = makeAbsolute; function removeLeadingDotSegment(entry) { @@ -27814,7 +27814,7 @@ var require_braces = __commonJS({ var require_constants8 = __commonJS({ "node_modules/picomatch/lib/constants.js"(exports2, module2) { "use strict"; - var path19 = require("path"); + var path20 = require("path"); var WIN_SLASH = "\\\\/"; var WIN_NO_SLASH = `[^${WIN_SLASH}]`; var DOT_LITERAL = "\\."; @@ -27984,7 +27984,7 @@ var require_constants8 = __commonJS({ /* | */ CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ - SEP: path19.sep, + SEP: path20.sep, /** * Create EXTGLOB_CHARS */ @@ -28011,7 +28011,7 @@ var require_constants8 = __commonJS({ var require_utils6 = __commonJS({ "node_modules/picomatch/lib/utils.js"(exports2) { "use strict"; - var path19 = require("path"); + var path20 = require("path"); var win32 = process.platform === "win32"; var { REGEX_BACKSLASH, @@ -28040,7 +28040,7 @@ var require_utils6 = __commonJS({ if (options && typeof options.windows === "boolean") { return options.windows; } - return win32 === true || path19.sep === "\\"; + return win32 === true || path20.sep === "\\"; }; exports2.escapeLast = (input, char, lastIdx) => { const idx = input.lastIndexOf(char, lastIdx); @@ -29175,7 +29175,7 @@ var require_parse4 = __commonJS({ var require_picomatch = __commonJS({ "node_modules/picomatch/lib/picomatch.js"(exports2, module2) { "use strict"; - var path19 = require("path"); + var path20 = require("path"); var scan = require_scan(); var parse = require_parse4(); var utils = require_utils6(); @@ -29260,7 +29260,7 @@ var require_picomatch = __commonJS({ }; picomatch.matchBase = (input, glob2, options, posix = utils.isWindows(options)) => { const regex = glob2 instanceof RegExp ? glob2 : picomatch.makeRe(glob2, options); - return regex.test(path19.basename(input)); + return regex.test(path20.basename(input)); }; picomatch.isMatch = (str2, patterns, options) => picomatch(patterns, options)(str2); picomatch.parse = (pattern, options) => { @@ -29487,7 +29487,7 @@ var require_pattern = __commonJS({ "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.isAbsolute = exports2.partitionAbsoluteAndRelative = exports2.removeDuplicateSlashes = exports2.matchAny = exports2.convertPatternsToRe = exports2.makeRe = exports2.getPatternParts = exports2.expandBraceExpansion = exports2.expandPatternsWithBraceExpansion = exports2.isAffectDepthOfReadingPattern = exports2.endsWithSlashGlobStar = exports2.hasGlobStar = exports2.getBaseDirectory = exports2.isPatternRelatedToParentDirectory = exports2.getPatternsOutsideCurrentDirectory = exports2.getPatternsInsideCurrentDirectory = exports2.getPositivePatterns = exports2.getNegativePatterns = exports2.isPositivePattern = exports2.isNegativePattern = exports2.convertToNegativePattern = exports2.convertToPositivePattern = exports2.isDynamicPattern = exports2.isStaticPattern = void 0; - var path19 = require("path"); + var path20 = require("path"); var globParent = require_glob_parent(); var micromatch = require_micromatch(); var GLOBSTAR = "**"; @@ -29582,7 +29582,7 @@ var require_pattern = __commonJS({ } exports2.endsWithSlashGlobStar = endsWithSlashGlobStar; function isAffectDepthOfReadingPattern(pattern) { - const basename = path19.basename(pattern); + const basename = path20.basename(pattern); return endsWithSlashGlobStar(pattern) || isStaticPattern(basename); } exports2.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern; @@ -29640,7 +29640,7 @@ var require_pattern = __commonJS({ } exports2.partitionAbsoluteAndRelative = partitionAbsoluteAndRelative; function isAbsolute3(pattern) { - return path19.isAbsolute(pattern); + return path20.isAbsolute(pattern); } exports2.isAbsolute = isAbsolute3; } @@ -29817,8 +29817,8 @@ var require_utils7 = __commonJS({ exports2.errno = errno; var fs18 = require_fs(); exports2.fs = fs18; - var path19 = require_path(); - exports2.path = path19; + var path20 = require_path(); + exports2.path = path20; var pattern = require_pattern(); exports2.pattern = pattern; var stream2 = require_stream(); @@ -29930,8 +29930,8 @@ var require_async = __commonJS({ "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.read = void 0; - function read(path19, settings, callback) { - settings.fs.lstat(path19, (lstatError, lstat) => { + function read(path20, settings, callback) { + settings.fs.lstat(path20, (lstatError, lstat) => { if (lstatError !== null) { callFailureCallback(callback, lstatError); return; @@ -29940,7 +29940,7 @@ var require_async = __commonJS({ callSuccessCallback(callback, lstat); return; } - settings.fs.stat(path19, (statError, stat) => { + settings.fs.stat(path20, (statError, stat) => { if (statError !== null) { if (settings.throwErrorOnBrokenSymbolicLink) { callFailureCallback(callback, statError); @@ -29972,13 +29972,13 @@ var require_sync = __commonJS({ "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.read = void 0; - function read(path19, settings) { - const lstat = settings.fs.lstatSync(path19); + function read(path20, settings) { + const lstat = settings.fs.lstatSync(path20); if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { return lstat; } try { - const stat = settings.fs.statSync(path19); + const stat = settings.fs.statSync(path20); if (settings.markSymbolicLink) { stat.isSymbolicLink = () => true; } @@ -30049,17 +30049,17 @@ var require_out = __commonJS({ var sync = require_sync(); var settings_1 = require_settings(); exports2.Settings = settings_1.default; - function stat(path19, optionsOrSettingsOrCallback, callback) { + function stat(path20, optionsOrSettingsOrCallback, callback) { if (typeof optionsOrSettingsOrCallback === "function") { - async.read(path19, getSettings(), optionsOrSettingsOrCallback); + async.read(path20, getSettings(), optionsOrSettingsOrCallback); return; } - async.read(path19, getSettings(optionsOrSettingsOrCallback), callback); + async.read(path20, getSettings(optionsOrSettingsOrCallback), callback); } exports2.stat = stat; - function statSync2(path19, optionsOrSettings) { + function statSync2(path20, optionsOrSettings) { const settings = getSettings(optionsOrSettings); - return sync.read(path19, settings); + return sync.read(path20, settings); } exports2.statSync = statSync2; function getSettings(settingsOrOptions = {}) { @@ -30275,16 +30275,16 @@ var require_async2 = __commonJS({ return; } const tasks = names.map((name) => { - const path19 = common2.joinPathSegments(directory, name, settings.pathSegmentSeparator); + const path20 = common2.joinPathSegments(directory, name, settings.pathSegmentSeparator); return (done) => { - fsStat.stat(path19, settings.fsStatSettings, (error2, stats) => { + fsStat.stat(path20, settings.fsStatSettings, (error2, stats) => { if (error2 !== null) { done(error2); return; } const entry = { name, - path: path19, + path: path20, dirent: utils.fs.createDirentFromStats(name, stats) }; if (settings.stats) { @@ -30402,7 +30402,7 @@ var require_settings2 = __commonJS({ "node_modules/@nodelib/fs.scandir/out/settings.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - var path19 = require("path"); + var path20 = require("path"); var fsStat = require_out(); var fs18 = require_fs4(); var Settings = class { @@ -30410,7 +30410,7 @@ var require_settings2 = __commonJS({ this._options = _options; this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false); this.fs = fs18.createFileSystemAdapter(this._options.fs); - this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path19.sep); + this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path20.sep); this.stats = this._getValue(this._options.stats, false); this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); this.fsStatSettings = new fsStat.Settings({ @@ -30437,17 +30437,17 @@ var require_out2 = __commonJS({ var sync = require_sync2(); var settings_1 = require_settings2(); exports2.Settings = settings_1.default; - function scandir(path19, optionsOrSettingsOrCallback, callback) { + function scandir(path20, optionsOrSettingsOrCallback, callback) { if (typeof optionsOrSettingsOrCallback === "function") { - async.read(path19, getSettings(), optionsOrSettingsOrCallback); + async.read(path20, getSettings(), optionsOrSettingsOrCallback); return; } - async.read(path19, getSettings(optionsOrSettingsOrCallback), callback); + async.read(path20, getSettings(optionsOrSettingsOrCallback), callback); } exports2.scandir = scandir; - function scandirSync(path19, optionsOrSettings) { + function scandirSync(path20, optionsOrSettings) { const settings = getSettings(optionsOrSettings); - return sync.read(path19, settings); + return sync.read(path20, settings); } exports2.scandirSync = scandirSync; function getSettings(settingsOrOptions = {}) { @@ -30974,7 +30974,7 @@ var require_settings3 = __commonJS({ "node_modules/@nodelib/fs.walk/out/settings.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - var path19 = require("path"); + var path20 = require("path"); var fsScandir = require_out2(); var Settings = class { constructor(_options = {}) { @@ -30984,7 +30984,7 @@ var require_settings3 = __commonJS({ this.deepFilter = this._getValue(this._options.deepFilter, null); this.entryFilter = this._getValue(this._options.entryFilter, null); this.errorFilter = this._getValue(this._options.errorFilter, null); - this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path19.sep); + this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path20.sep); this.fsScandirSettings = new fsScandir.Settings({ followSymbolicLinks: this._options.followSymbolicLinks, fs: this._options.fs, @@ -31046,7 +31046,7 @@ var require_reader2 = __commonJS({ "node_modules/fast-glob/out/readers/reader.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - var path19 = require("path"); + var path20 = require("path"); var fsStat = require_out(); var utils = require_utils7(); var Reader = class { @@ -31059,7 +31059,7 @@ var require_reader2 = __commonJS({ }); } _getFullEntryPath(filepath) { - return path19.resolve(this._settings.cwd, filepath); + return path20.resolve(this._settings.cwd, filepath); } _makeEntry(stats, pattern) { const entry = { @@ -31475,7 +31475,7 @@ var require_provider = __commonJS({ "node_modules/fast-glob/out/providers/provider.js"(exports2) { "use strict"; Object.defineProperty(exports2, "__esModule", { value: true }); - var path19 = require("path"); + var path20 = require("path"); var deep_1 = require_deep(); var entry_1 = require_entry(); var error_1 = require_error(); @@ -31489,7 +31489,7 @@ var require_provider = __commonJS({ this.entryTransformer = new entry_2.default(this._settings); } _getRootDirectory(task) { - return path19.resolve(this._settings.cwd, task.base); + return path20.resolve(this._settings.cwd, task.base); } _getReaderOptions(task) { const basePath = task.base === "." ? "" : task.base; @@ -32122,7 +32122,7 @@ var require_ignore = __commonJS({ // path matching. // - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE` // @returns {TestResult} true if a file is ignored - test(path19, checkUnignored, mode) { + test(path20, checkUnignored, mode) { let ignored = false; let unignored = false; let matchedRule; @@ -32131,7 +32131,7 @@ var require_ignore = __commonJS({ if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) { return; } - const matched = rule[mode].test(path19); + const matched = rule[mode].test(path20); if (!matched) { return; } @@ -32152,17 +32152,17 @@ var require_ignore = __commonJS({ var throwError2 = (message, Ctor) => { throw new Ctor(message); }; - var checkPath = (path19, originalPath, doThrow) => { - if (!isString(path19)) { + var checkPath = (path20, originalPath, doThrow) => { + if (!isString(path20)) { return doThrow( `path must be a string, but got \`${originalPath}\``, TypeError ); } - if (!path19) { + if (!path20) { return doThrow(`path must not be empty`, TypeError); } - if (checkPath.isNotRelative(path19)) { + if (checkPath.isNotRelative(path20)) { const r = "`path.relative()`d"; return doThrow( `path should be a ${r} string, but got "${originalPath}"`, @@ -32171,7 +32171,7 @@ var require_ignore = __commonJS({ } return true; }; - var isNotRelative = (path19) => REGEX_TEST_INVALID_PATH.test(path19); + var isNotRelative = (path20) => REGEX_TEST_INVALID_PATH.test(path20); checkPath.isNotRelative = isNotRelative; checkPath.convert = (p) => p; var Ignore = class { @@ -32201,19 +32201,19 @@ var require_ignore = __commonJS({ } // @returns {TestResult} _test(originalPath, cache, checkUnignored, slices) { - const path19 = originalPath && checkPath.convert(originalPath); + const path20 = originalPath && checkPath.convert(originalPath); checkPath( - path19, + path20, originalPath, this._strictPathCheck ? throwError2 : RETURN_FALSE ); - return this._t(path19, cache, checkUnignored, slices); + return this._t(path20, cache, checkUnignored, slices); } - checkIgnore(path19) { - if (!REGEX_TEST_TRAILING_SLASH.test(path19)) { - return this.test(path19); + checkIgnore(path20) { + if (!REGEX_TEST_TRAILING_SLASH.test(path20)) { + return this.test(path20); } - const slices = path19.split(SLASH).filter(Boolean); + const slices = path20.split(SLASH).filter(Boolean); slices.pop(); if (slices.length) { const parent = this._t( @@ -32226,18 +32226,18 @@ var require_ignore = __commonJS({ return parent; } } - return this._rules.test(path19, false, MODE_CHECK_IGNORE); + return this._rules.test(path20, false, MODE_CHECK_IGNORE); } - _t(path19, cache, checkUnignored, slices) { - if (path19 in cache) { - return cache[path19]; + _t(path20, cache, checkUnignored, slices) { + if (path20 in cache) { + return cache[path20]; } if (!slices) { - slices = path19.split(SLASH).filter(Boolean); + slices = path20.split(SLASH).filter(Boolean); } slices.pop(); if (!slices.length) { - return cache[path19] = this._rules.test(path19, checkUnignored, MODE_IGNORE); + return cache[path20] = this._rules.test(path20, checkUnignored, MODE_IGNORE); } const parent = this._t( slices.join(SLASH) + SLASH, @@ -32245,29 +32245,29 @@ var require_ignore = __commonJS({ checkUnignored, slices ); - return cache[path19] = parent.ignored ? parent : this._rules.test(path19, checkUnignored, MODE_IGNORE); + return cache[path20] = parent.ignored ? parent : this._rules.test(path20, checkUnignored, MODE_IGNORE); } - ignores(path19) { - return this._test(path19, this._ignoreCache, false).ignored; + ignores(path20) { + return this._test(path20, this._ignoreCache, false).ignored; } createFilter() { - return (path19) => !this.ignores(path19); + return (path20) => !this.ignores(path20); } filter(paths) { return makeArray(paths).filter(this.createFilter()); } // @returns {TestResult} - test(path19) { - return this._test(path19, this._testCache, true); + test(path20) { + return this._test(path20, this._testCache, true); } }; var factory = (options) => new Ignore(options); - var isPathValid = (path19) => checkPath(path19 && checkPath.convert(path19), path19, RETURN_FALSE); + var isPathValid = (path20) => checkPath(path20 && checkPath.convert(path20), path20, RETURN_FALSE); var setupWindows = () => { const makePosix = (str2) => /^\\\\\?\\/.test(str2) || /["<>|\u0000-\u001F]+/u.test(str2) ? str2 : str2.replace(/\\/g, "/"); checkPath.convert = makePosix; const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i; - checkPath.isNotRelative = (path19) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path19) || isNotRelative(path19); + checkPath.isNotRelative = (path20) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path20) || isNotRelative(path20); }; if ( // Detect `process` so that it can run in browsers. @@ -32287,7 +32287,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.3", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -32296,7 +32296,7 @@ var require_package = __commonJS({ lint: "eslint --report-unused-disable-directives --max-warnings=0 .", "lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif", "lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix", - test: "npm run transpile && ava src/**.test.ts --serial --verbose", + test: "npm run transpile && ava src/ --serial --verbose", "test-debug": "npm run test -- --timeout=20m", transpile: "tsc --build --verbose" }, @@ -32312,7 +32312,7 @@ var require_package = __commonJS({ dependencies: { "@actions/artifact": "^2.3.1", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^4.0.5", + "@actions/cache": "^4.1.0", "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", @@ -32335,15 +32335,15 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^12.0.0" + uuid: "^13.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", - "@eslint/compat": "^1.3.2", + "@eslint/compat": "^1.4.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.35.0", + "@eslint/js": "^9.36.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", - "@octokit/types": "^14.1.0", + "@octokit/types": "^15.0.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", @@ -32352,10 +32352,10 @@ var require_package = __commonJS({ "@types/node-forge": "^1.3.14", "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.43.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", - esbuild: "^0.25.9", + esbuild: "^0.25.10", eslint: "^8.57.1", "eslint-import-resolver-typescript": "^3.8.7", "eslint-plugin-filenames": "^1.3.2", @@ -32385,7 +32385,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -34049,7 +34050,7 @@ var require_internal_path_helper = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.safeTrimTrailingSeparator = exports2.normalizeSeparators = exports2.hasRoot = exports2.hasAbsoluteRoot = exports2.ensureAbsoluteRoot = exports2.dirname = void 0; - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var assert_1 = __importDefault4(require("assert")); var IS_WINDOWS = process.platform === "win32"; function dirname3(p) { @@ -34057,7 +34058,7 @@ var require_internal_path_helper = __commonJS({ if (IS_WINDOWS && /^\\\\[^\\]+(\\[^\\]+)?$/.test(p)) { return p; } - let result = path19.dirname(p); + let result = path20.dirname(p); if (IS_WINDOWS && /^\\\\[^\\]+\\[^\\]+\\$/.test(result)) { result = safeTrimTrailingSeparator(result); } @@ -34095,7 +34096,7 @@ var require_internal_path_helper = __commonJS({ assert_1.default(hasAbsoluteRoot(root), `ensureAbsoluteRoot parameter 'root' must have an absolute root`); if (root.endsWith("/") || IS_WINDOWS && root.endsWith("\\")) { } else { - root += path19.sep; + root += path20.sep; } return root + itemPath; } @@ -34133,10 +34134,10 @@ var require_internal_path_helper = __commonJS({ return ""; } p = normalizeSeparators(p); - if (!p.endsWith(path19.sep)) { + if (!p.endsWith(path20.sep)) { return p; } - if (p === path19.sep) { + if (p === path20.sep) { return p; } if (IS_WINDOWS && /^[A-Z]:\\$/i.test(p)) { @@ -34469,7 +34470,7 @@ var require_minimatch = __commonJS({ "node_modules/minimatch/minimatch.js"(exports2, module2) { module2.exports = minimatch; minimatch.Minimatch = Minimatch; - var path19 = (function() { + var path20 = (function() { try { return require("path"); } catch (e) { @@ -34477,7 +34478,7 @@ var require_minimatch = __commonJS({ })() || { sep: "/" }; - minimatch.sep = path19.sep; + minimatch.sep = path20.sep; var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}; var expand = require_brace_expansion(); var plTypes = { @@ -34566,8 +34567,8 @@ var require_minimatch = __commonJS({ assertValidPattern(pattern); if (!options) options = {}; pattern = pattern.trim(); - if (!options.allowWindowsEscape && path19.sep !== "/") { - pattern = pattern.split(path19.sep).join("/"); + if (!options.allowWindowsEscape && path20.sep !== "/") { + pattern = pattern.split(path20.sep).join("/"); } this.options = options; this.set = []; @@ -34936,8 +34937,8 @@ var require_minimatch = __commonJS({ if (this.empty) return f === ""; if (f === "/" && partial) return true; var options = this.options; - if (path19.sep !== "/") { - f = f.split(path19.sep).join("/"); + if (path20.sep !== "/") { + f = f.split(path20.sep).join("/"); } f = f.split(slashSplit); this.debug(this.pattern, "split", f); @@ -35069,7 +35070,7 @@ var require_internal_path = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Path = void 0; - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var pathHelper = __importStar4(require_internal_path_helper()); var assert_1 = __importDefault4(require("assert")); var IS_WINDOWS = process.platform === "win32"; @@ -35084,12 +35085,12 @@ var require_internal_path = __commonJS({ assert_1.default(itemPath, `Parameter 'itemPath' must not be empty`); itemPath = pathHelper.safeTrimTrailingSeparator(itemPath); if (!pathHelper.hasRoot(itemPath)) { - this.segments = itemPath.split(path19.sep); + this.segments = itemPath.split(path20.sep); } else { let remaining = itemPath; let dir = pathHelper.dirname(remaining); while (dir !== remaining) { - const basename = path19.basename(remaining); + const basename = path20.basename(remaining); this.segments.unshift(basename); remaining = dir; dir = pathHelper.dirname(remaining); @@ -35107,7 +35108,7 @@ var require_internal_path = __commonJS({ assert_1.default(segment === pathHelper.dirname(segment), `Parameter 'itemPath' root segment contains information for multiple segments`); this.segments.push(segment); } else { - assert_1.default(!segment.includes(path19.sep), `Parameter 'itemPath' contains unexpected path separators`); + assert_1.default(!segment.includes(path20.sep), `Parameter 'itemPath' contains unexpected path separators`); this.segments.push(segment); } } @@ -35118,12 +35119,12 @@ var require_internal_path = __commonJS({ */ toString() { let result = this.segments[0]; - let skipSlash = result.endsWith(path19.sep) || IS_WINDOWS && /^[A-Z]:$/i.test(result); + let skipSlash = result.endsWith(path20.sep) || IS_WINDOWS && /^[A-Z]:$/i.test(result); for (let i = 1; i < this.segments.length; i++) { if (skipSlash) { skipSlash = false; } else { - result += path19.sep; + result += path20.sep; } result += this.segments[i]; } @@ -35167,7 +35168,7 @@ var require_internal_pattern = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Pattern = void 0; var os5 = __importStar4(require("os")); - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var pathHelper = __importStar4(require_internal_path_helper()); var assert_1 = __importDefault4(require("assert")); var minimatch_1 = require_minimatch(); @@ -35196,7 +35197,7 @@ var require_internal_pattern = __commonJS({ } pattern = _Pattern.fixupPattern(pattern, homedir2); this.segments = new internal_path_1.Path(pattern).segments; - this.trailingSeparator = pathHelper.normalizeSeparators(pattern).endsWith(path19.sep); + this.trailingSeparator = pathHelper.normalizeSeparators(pattern).endsWith(path20.sep); pattern = pathHelper.safeTrimTrailingSeparator(pattern); let foundGlob = false; const searchSegments = this.segments.map((x) => _Pattern.getLiteral(x)).filter((x) => !foundGlob && !(foundGlob = x === "")); @@ -35220,8 +35221,8 @@ var require_internal_pattern = __commonJS({ match(itemPath) { if (this.segments[this.segments.length - 1] === "**") { itemPath = pathHelper.normalizeSeparators(itemPath); - if (!itemPath.endsWith(path19.sep) && this.isImplicitPattern === false) { - itemPath = `${itemPath}${path19.sep}`; + if (!itemPath.endsWith(path20.sep) && this.isImplicitPattern === false) { + itemPath = `${itemPath}${path20.sep}`; } } else { itemPath = pathHelper.safeTrimTrailingSeparator(itemPath); @@ -35256,9 +35257,9 @@ var require_internal_pattern = __commonJS({ assert_1.default(literalSegments.every((x, i) => (x !== "." || i === 0) && x !== ".."), `Invalid pattern '${pattern}'. Relative pathing '.' and '..' is not allowed.`); assert_1.default(!pathHelper.hasRoot(pattern) || literalSegments[0], `Invalid pattern '${pattern}'. Root segment must not contain globs.`); pattern = pathHelper.normalizeSeparators(pattern); - if (pattern === "." || pattern.startsWith(`.${path19.sep}`)) { + if (pattern === "." || pattern.startsWith(`.${path20.sep}`)) { pattern = _Pattern.globEscape(process.cwd()) + pattern.substr(1); - } else if (pattern === "~" || pattern.startsWith(`~${path19.sep}`)) { + } else if (pattern === "~" || pattern.startsWith(`~${path20.sep}`)) { homedir2 = homedir2 || os5.homedir(); assert_1.default(homedir2, "Unable to determine HOME directory"); assert_1.default(pathHelper.hasAbsoluteRoot(homedir2), `Expected HOME directory to be a rooted path. Actual '${homedir2}'`); @@ -35342,8 +35343,8 @@ var require_internal_search_state = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.SearchState = void 0; var SearchState = class { - constructor(path19, level) { - this.path = path19; + constructor(path20, level) { + this.path = path20; this.level = level; } }; @@ -35465,7 +35466,7 @@ var require_internal_globber = __commonJS({ var core14 = __importStar4(require_core()); var fs18 = __importStar4(require("fs")); var globOptionsHelper = __importStar4(require_internal_glob_options_helper()); - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var patternHelper = __importStar4(require_internal_pattern_helper()); var internal_match_kind_1 = require_internal_match_kind(); var internal_pattern_1 = require_internal_pattern(); @@ -35546,7 +35547,7 @@ var require_internal_globber = __commonJS({ continue; } const childLevel = item.level + 1; - const childItems = (yield __await4(fs18.promises.readdir(item.path))).map((x) => new internal_search_state_1.SearchState(path19.join(item.path, x), childLevel)); + const childItems = (yield __await4(fs18.promises.readdir(item.path))).map((x) => new internal_search_state_1.SearchState(path20.join(item.path, x), childLevel)); stack.push(...childItems.reverse()); } else if (match & internal_match_kind_1.MatchKind.File) { yield yield __await4(item.path); @@ -36931,7 +36932,7 @@ var require_cacheUtils = __commonJS({ var io7 = __importStar4(require_io()); var crypto2 = __importStar4(require("crypto")); var fs18 = __importStar4(require("fs")); - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var semver9 = __importStar4(require_semver3()); var util = __importStar4(require("util")); var constants_1 = require_constants10(); @@ -36951,9 +36952,9 @@ var require_cacheUtils = __commonJS({ baseLocation = "/home"; } } - tempDirectory = path19.join(baseLocation, "actions", "temp"); + tempDirectory = path20.join(baseLocation, "actions", "temp"); } - const dest = path19.join(tempDirectory, crypto2.randomUUID()); + const dest = path20.join(tempDirectory, crypto2.randomUUID()); yield io7.mkdirP(dest); return dest; }); @@ -36977,7 +36978,7 @@ var require_cacheUtils = __commonJS({ _c = _g.value; _e = false; const file = _c; - const relativeFile = path19.relative(workspace, file).replace(new RegExp(`\\${path19.sep}`, "g"), "/"); + const relativeFile = path20.relative(workspace, file).replace(new RegExp(`\\${path20.sep}`, "g"), "/"); core14.debug(`Matched: ${relativeFile}`); if (relativeFile === "") { paths.push("."); @@ -44883,15 +44884,15 @@ var require_urlHelpers = __commonJS({ let isAbsolutePath = false; let requestUrl = replaceAll(baseUri, urlReplacements); if (operationSpec.path) { - let path19 = replaceAll(operationSpec.path, urlReplacements); - if (operationSpec.path === "/{nextLink}" && path19.startsWith("/")) { - path19 = path19.substring(1); + let path20 = replaceAll(operationSpec.path, urlReplacements); + if (operationSpec.path === "/{nextLink}" && path20.startsWith("/")) { + path20 = path20.substring(1); } - if (isAbsoluteUrl(path19)) { - requestUrl = path19; + if (isAbsoluteUrl(path20)) { + requestUrl = path20; isAbsolutePath = true; } else { - requestUrl = appendPath(requestUrl, path19); + requestUrl = appendPath(requestUrl, path20); } } const { queryParams, sequenceParams } = calculateQueryParameters(operationSpec, operationArguments, fallbackObject); @@ -44939,9 +44940,9 @@ var require_urlHelpers = __commonJS({ } const searchStart = pathToAppend.indexOf("?"); if (searchStart !== -1) { - const path19 = pathToAppend.substring(0, searchStart); + const path20 = pathToAppend.substring(0, searchStart); const search = pathToAppend.substring(searchStart + 1); - newPath = newPath + path19; + newPath = newPath + path20; if (search) { parsedUrl.search = parsedUrl.search ? `${parsedUrl.search}&${search}` : search; } @@ -49090,10 +49091,10 @@ var require_dist7 = __commonJS({ ]; function escapeURLPath(url2) { const urlParsed = new URL(url2); - let path19 = urlParsed.pathname; - path19 = path19 || "/"; - path19 = escape(path19); - urlParsed.pathname = path19; + let path20 = urlParsed.pathname; + path20 = path20 || "/"; + path20 = escape(path20); + urlParsed.pathname = path20; return urlParsed.toString(); } function getProxyUriFromDevConnString(connectionString) { @@ -49178,9 +49179,9 @@ var require_dist7 = __commonJS({ } function appendToURLPath(url2, name) { const urlParsed = new URL(url2); - let path19 = urlParsed.pathname; - path19 = path19 ? path19.endsWith("/") ? `${path19}${name}` : `${path19}/${name}` : name; - urlParsed.pathname = path19; + let path20 = urlParsed.pathname; + path20 = path20 ? path20.endsWith("/") ? `${path20}${name}` : `${path20}/${name}` : name; + urlParsed.pathname = path20; return urlParsed.toString(); } function setURLParameter(url2, name, value) { @@ -50261,9 +50262,9 @@ var require_dist7 = __commonJS({ * @param request - */ getCanonicalizedResourceString(request) { - const path19 = getURLPath(request.url) || "/"; + const path20 = getURLPath(request.url) || "/"; let canonicalizedResourceString = ""; - canonicalizedResourceString += `/${this.factory.accountName}${path19}`; + canonicalizedResourceString += `/${this.factory.accountName}${path20}`; const queries = getURLQueries(request.url); const lowercaseQueries = {}; if (queries) { @@ -50556,9 +50557,9 @@ ${key}:${decodeURIComponent(lowercaseQueries[key])}`; return canonicalizedHeadersStringToSign; } function getCanonicalizedResourceString(request) { - const path19 = getURLPath(request.url) || "/"; + const path20 = getURLPath(request.url) || "/"; let canonicalizedResourceString = ""; - canonicalizedResourceString += `/${options.accountName}${path19}`; + canonicalizedResourceString += `/${options.accountName}${path20}`; const queries = getURLQueries(request.url); const lowercaseQueries = {}; if (queries) { @@ -69860,8 +69861,8 @@ ${key}:${decodeURIComponent(lowercaseQueries[key])}`; if (this.operationCount >= BATCH_MAX_REQUEST) { throw new RangeError(`Cannot exceed ${BATCH_MAX_REQUEST} sub requests in a single batch`); } - const path19 = getURLPath(subRequest.url); - if (!path19 || path19 === "") { + const path20 = getURLPath(subRequest.url); + if (!path20 || path20 === "") { throw new RangeError(`Invalid url for sub request: '${subRequest.url}'`); } } @@ -69921,8 +69922,8 @@ ${key}:${decodeURIComponent(lowercaseQueries[key])}`; pipeline = newPipeline(credentialOrPipeline, options); } const storageClientContext = new StorageContextClient(url2, getCoreClientOptions(pipeline)); - const path19 = getURLPath(url2); - if (path19 && path19 !== "/") { + const path20 = getURLPath(url2); + if (path20 && path20 !== "/") { this.serviceOrContainerContext = storageClientContext.container; } else { this.serviceOrContainerContext = storageClientContext.service; @@ -73130,7 +73131,7 @@ var require_package2 = __commonJS({ "node_modules/@actions/cache/package.json"(exports2, module2) { module2.exports = { name: "@actions/cache", - version: "4.0.5", + version: "4.1.0", preview: true, description: "Actions cache lib", keywords: [ @@ -77939,11 +77940,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 9 /*ScalarType.STRING*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, signedUploadUrl: "" }; + const message = { ok: false, signedUploadUrl: "", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -77962,6 +77970,10 @@ var require_cache2 = __commonJS({ 2: message.signedUploadUrl = reader.string(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -77978,6 +77990,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.signedUploadUrl !== "") writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.signedUploadUrl); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -78083,11 +78097,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 3 /*ScalarType.INT64*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, entryId: "0" }; + const message = { ok: false, entryId: "0", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -78106,6 +78127,10 @@ var require_cache2 = __commonJS({ 2: message.entryId = reader.int64().toString(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -78122,6 +78147,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.entryId !== "0") writer.tag(2, runtime_1.WireType.Varint).int64(message.entryId); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -78646,7 +78673,7 @@ var require_tar = __commonJS({ var exec_1 = require_exec(); var io7 = __importStar4(require_io()); var fs_1 = require("fs"); - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var utils = __importStar4(require_cacheUtils()); var constants_1 = require_constants10(); var IS_WINDOWS = process.platform === "win32"; @@ -78692,13 +78719,13 @@ var require_tar = __commonJS({ const BSD_TAR_ZSTD = tarPath.type === constants_1.ArchiveToolType.BSD && compressionMethod !== constants_1.CompressionMethod.Gzip && IS_WINDOWS; switch (type2) { case "create": - args.push("--posix", "-cf", BSD_TAR_ZSTD ? tarFile : cacheFileName.replace(new RegExp(`\\${path19.sep}`, "g"), "/"), "--exclude", BSD_TAR_ZSTD ? tarFile : cacheFileName.replace(new RegExp(`\\${path19.sep}`, "g"), "/"), "-P", "-C", workingDirectory.replace(new RegExp(`\\${path19.sep}`, "g"), "/"), "--files-from", constants_1.ManifestFilename); + args.push("--posix", "-cf", BSD_TAR_ZSTD ? tarFile : cacheFileName.replace(new RegExp(`\\${path20.sep}`, "g"), "/"), "--exclude", BSD_TAR_ZSTD ? tarFile : cacheFileName.replace(new RegExp(`\\${path20.sep}`, "g"), "/"), "-P", "-C", workingDirectory.replace(new RegExp(`\\${path20.sep}`, "g"), "/"), "--files-from", constants_1.ManifestFilename); break; case "extract": - args.push("-xf", BSD_TAR_ZSTD ? tarFile : archivePath.replace(new RegExp(`\\${path19.sep}`, "g"), "/"), "-P", "-C", workingDirectory.replace(new RegExp(`\\${path19.sep}`, "g"), "/")); + args.push("-xf", BSD_TAR_ZSTD ? tarFile : archivePath.replace(new RegExp(`\\${path20.sep}`, "g"), "/"), "-P", "-C", workingDirectory.replace(new RegExp(`\\${path20.sep}`, "g"), "/")); break; case "list": - args.push("-tf", BSD_TAR_ZSTD ? tarFile : archivePath.replace(new RegExp(`\\${path19.sep}`, "g"), "/"), "-P"); + args.push("-tf", BSD_TAR_ZSTD ? tarFile : archivePath.replace(new RegExp(`\\${path20.sep}`, "g"), "/"), "-P"); break; } if (tarPath.type === constants_1.ArchiveToolType.GNU) { @@ -78744,7 +78771,7 @@ var require_tar = __commonJS({ return BSD_TAR_ZSTD ? [ "zstd -d --long=30 --force -o", constants_1.TarFilename, - archivePath.replace(new RegExp(`\\${path19.sep}`, "g"), "/") + archivePath.replace(new RegExp(`\\${path20.sep}`, "g"), "/") ] : [ "--use-compress-program", IS_WINDOWS ? '"zstd -d --long=30"' : "unzstd --long=30" @@ -78753,7 +78780,7 @@ var require_tar = __commonJS({ return BSD_TAR_ZSTD ? [ "zstd -d --force -o", constants_1.TarFilename, - archivePath.replace(new RegExp(`\\${path19.sep}`, "g"), "/") + archivePath.replace(new RegExp(`\\${path20.sep}`, "g"), "/") ] : ["--use-compress-program", IS_WINDOWS ? '"zstd -d"' : "unzstd"]; default: return ["-z"]; @@ -78768,7 +78795,7 @@ var require_tar = __commonJS({ case constants_1.CompressionMethod.Zstd: return BSD_TAR_ZSTD ? [ "zstd -T0 --long=30 --force -o", - cacheFileName.replace(new RegExp(`\\${path19.sep}`, "g"), "/"), + cacheFileName.replace(new RegExp(`\\${path20.sep}`, "g"), "/"), constants_1.TarFilename ] : [ "--use-compress-program", @@ -78777,7 +78804,7 @@ var require_tar = __commonJS({ case constants_1.CompressionMethod.ZstdWithoutLong: return BSD_TAR_ZSTD ? [ "zstd -T0 --force -o", - cacheFileName.replace(new RegExp(`\\${path19.sep}`, "g"), "/"), + cacheFileName.replace(new RegExp(`\\${path20.sep}`, "g"), "/"), constants_1.TarFilename ] : ["--use-compress-program", IS_WINDOWS ? '"zstd -T0"' : "zstdmt"]; default: @@ -78817,7 +78844,7 @@ var require_tar = __commonJS({ exports2.extractTar = extractTar2; function createTar(archiveFolder, sourceDirectories, compressionMethod) { return __awaiter4(this, void 0, void 0, function* () { - (0, fs_1.writeFileSync)(path19.join(archiveFolder, constants_1.ManifestFilename), sourceDirectories.join("\n")); + (0, fs_1.writeFileSync)(path20.join(archiveFolder, constants_1.ManifestFilename), sourceDirectories.join("\n")); const commands = yield getCommands(compressionMethod, "create"); yield execCommands(commands, archiveFolder); }); @@ -78885,15 +78912,14 @@ var require_cache3 = __commonJS({ }); }; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.ReserveCacheError = exports2.ValidationError = void 0; + exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; var core14 = __importStar4(require_core()); - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var utils = __importStar4(require_cacheUtils()); var cacheHttpClient = __importStar4(require_cacheHttpClient()); var cacheTwirpClient = __importStar4(require_cacheTwirpClient()); var config_1 = require_config(); var tar_1 = require_tar(); - var constants_1 = require_constants10(); var http_client_1 = require_lib(); var ValidationError = class _ValidationError extends Error { constructor(message) { @@ -78911,6 +78937,14 @@ var require_cache3 = __commonJS({ } }; exports2.ReserveCacheError = ReserveCacheError2; + var FinalizeCacheError = class _FinalizeCacheError extends Error { + constructor(message) { + super(message); + this.name = "FinalizeCacheError"; + Object.setPrototypeOf(this, _FinalizeCacheError.prototype); + } + }; + exports2.FinalizeCacheError = FinalizeCacheError; function checkPaths(paths) { if (!paths || paths.length === 0) { throw new ValidationError(`Path Validation Error: At least one directory or file path is required`); @@ -78977,7 +79011,7 @@ var require_cache3 = __commonJS({ core14.info("Lookup only - skipping download"); return cacheEntry.cacheKey; } - archivePath = path19.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); + archivePath = path20.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); core14.debug(`Archive Path: ${archivePath}`); yield cacheHttpClient.downloadCache(cacheEntry.archiveLocation, archivePath, options); if (core14.isDebug()) { @@ -79046,7 +79080,7 @@ var require_cache3 = __commonJS({ core14.info("Lookup only - skipping download"); return response.matchedKey; } - archivePath = path19.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); + archivePath = path20.join(yield utils.createTempDirectory(), utils.getCacheFileName(compressionMethod)); core14.debug(`Archive path: ${archivePath}`); core14.debug(`Starting download of archive to: ${archivePath}`); yield cacheHttpClient.downloadCache(response.signedDownloadUrl, archivePath, options); @@ -79109,7 +79143,7 @@ var require_cache3 = __commonJS({ throw new Error(`Path Validation Error: Path(s) specified in the action for caching do(es) not exist, hence no cache is being saved.`); } const archiveFolder = yield utils.createTempDirectory(); - const archivePath = path19.join(archiveFolder, utils.getCacheFileName(compressionMethod)); + const archivePath = path20.join(archiveFolder, utils.getCacheFileName(compressionMethod)); core14.debug(`Archive Path: ${archivePath}`); try { yield (0, tar_1.createTar)(archiveFolder, cachePaths, compressionMethod); @@ -79173,7 +79207,7 @@ var require_cache3 = __commonJS({ throw new Error(`Path Validation Error: Path(s) specified in the action for caching do(es) not exist, hence no cache is being saved.`); } const archiveFolder = yield utils.createTempDirectory(); - const archivePath = path19.join(archiveFolder, utils.getCacheFileName(compressionMethod)); + const archivePath = path20.join(archiveFolder, utils.getCacheFileName(compressionMethod)); core14.debug(`Archive Path: ${archivePath}`); try { yield (0, tar_1.createTar)(archiveFolder, cachePaths, compressionMethod); @@ -79182,9 +79216,6 @@ var require_cache3 = __commonJS({ } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); core14.debug(`File Size: ${archiveFileSize}`); - if (archiveFileSize > constants_1.CacheFileSizeLimit && !(0, config_1.isGhes)()) { - throw new Error(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`); - } options.archiveSizeBytes = archiveFileSize; core14.debug("Reserving Cache"); const version = utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive); @@ -79196,7 +79227,10 @@ var require_cache3 = __commonJS({ try { const response = yield twirpClient.CreateCacheEntry(request); if (!response.ok) { - throw new Error("Response was not ok"); + if (response.message) { + core14.warning(`Cache reservation failed: ${response.message}`); + } + throw new Error(response.message || "Response was not ok"); } signedUploadUrl = response.signedUploadUrl; } catch (error2) { @@ -79213,6 +79247,9 @@ var require_cache3 = __commonJS({ const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest); core14.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); if (!finalizeResponse.ok) { + if (finalizeResponse.message) { + throw new FinalizeCacheError(finalizeResponse.message); + } throw new Error(`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`); } cacheId = parseInt(finalizeResponse.entryId); @@ -79222,6 +79259,8 @@ var require_cache3 = __commonJS({ throw error2; } else if (typedError.name === ReserveCacheError2.name) { core14.info(`Failed to save: ${typedError.message}`); + } else if (typedError.name === FinalizeCacheError.name) { + core14.warning(typedError.message); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { core14.error(`Failed to save: ${typedError.message}`); @@ -79348,7 +79387,7 @@ var require_internal_path_helper2 = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.safeTrimTrailingSeparator = exports2.normalizeSeparators = exports2.hasRoot = exports2.hasAbsoluteRoot = exports2.ensureAbsoluteRoot = exports2.dirname = void 0; - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var assert_1 = __importDefault4(require("assert")); var IS_WINDOWS = process.platform === "win32"; function dirname3(p) { @@ -79356,7 +79395,7 @@ var require_internal_path_helper2 = __commonJS({ if (IS_WINDOWS && /^\\\\[^\\]+(\\[^\\]+)?$/.test(p)) { return p; } - let result = path19.dirname(p); + let result = path20.dirname(p); if (IS_WINDOWS && /^\\\\[^\\]+\\[^\\]+\\$/.test(result)) { result = safeTrimTrailingSeparator(result); } @@ -79394,7 +79433,7 @@ var require_internal_path_helper2 = __commonJS({ (0, assert_1.default)(hasAbsoluteRoot(root), `ensureAbsoluteRoot parameter 'root' must have an absolute root`); if (root.endsWith("/") || IS_WINDOWS && root.endsWith("\\")) { } else { - root += path19.sep; + root += path20.sep; } return root + itemPath; } @@ -79432,10 +79471,10 @@ var require_internal_path_helper2 = __commonJS({ return ""; } p = normalizeSeparators(p); - if (!p.endsWith(path19.sep)) { + if (!p.endsWith(path20.sep)) { return p; } - if (p === path19.sep) { + if (p === path20.sep) { return p; } if (IS_WINDOWS && /^[A-Z]:\\$/i.test(p)) { @@ -79586,7 +79625,7 @@ var require_internal_path2 = __commonJS({ }; Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Path = void 0; - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var pathHelper = __importStar4(require_internal_path_helper2()); var assert_1 = __importDefault4(require("assert")); var IS_WINDOWS = process.platform === "win32"; @@ -79601,12 +79640,12 @@ var require_internal_path2 = __commonJS({ (0, assert_1.default)(itemPath, `Parameter 'itemPath' must not be empty`); itemPath = pathHelper.safeTrimTrailingSeparator(itemPath); if (!pathHelper.hasRoot(itemPath)) { - this.segments = itemPath.split(path19.sep); + this.segments = itemPath.split(path20.sep); } else { let remaining = itemPath; let dir = pathHelper.dirname(remaining); while (dir !== remaining) { - const basename = path19.basename(remaining); + const basename = path20.basename(remaining); this.segments.unshift(basename); remaining = dir; dir = pathHelper.dirname(remaining); @@ -79624,7 +79663,7 @@ var require_internal_path2 = __commonJS({ (0, assert_1.default)(segment === pathHelper.dirname(segment), `Parameter 'itemPath' root segment contains information for multiple segments`); this.segments.push(segment); } else { - (0, assert_1.default)(!segment.includes(path19.sep), `Parameter 'itemPath' contains unexpected path separators`); + (0, assert_1.default)(!segment.includes(path20.sep), `Parameter 'itemPath' contains unexpected path separators`); this.segments.push(segment); } } @@ -79635,12 +79674,12 @@ var require_internal_path2 = __commonJS({ */ toString() { let result = this.segments[0]; - let skipSlash = result.endsWith(path19.sep) || IS_WINDOWS && /^[A-Z]:$/i.test(result); + let skipSlash = result.endsWith(path20.sep) || IS_WINDOWS && /^[A-Z]:$/i.test(result); for (let i = 1; i < this.segments.length; i++) { if (skipSlash) { skipSlash = false; } else { - result += path19.sep; + result += path20.sep; } result += this.segments[i]; } @@ -79688,7 +79727,7 @@ var require_internal_pattern2 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.Pattern = void 0; var os5 = __importStar4(require("os")); - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var pathHelper = __importStar4(require_internal_path_helper2()); var assert_1 = __importDefault4(require("assert")); var minimatch_1 = require_minimatch(); @@ -79717,7 +79756,7 @@ var require_internal_pattern2 = __commonJS({ } pattern = _Pattern.fixupPattern(pattern, homedir2); this.segments = new internal_path_1.Path(pattern).segments; - this.trailingSeparator = pathHelper.normalizeSeparators(pattern).endsWith(path19.sep); + this.trailingSeparator = pathHelper.normalizeSeparators(pattern).endsWith(path20.sep); pattern = pathHelper.safeTrimTrailingSeparator(pattern); let foundGlob = false; const searchSegments = this.segments.map((x) => _Pattern.getLiteral(x)).filter((x) => !foundGlob && !(foundGlob = x === "")); @@ -79741,8 +79780,8 @@ var require_internal_pattern2 = __commonJS({ match(itemPath) { if (this.segments[this.segments.length - 1] === "**") { itemPath = pathHelper.normalizeSeparators(itemPath); - if (!itemPath.endsWith(path19.sep) && this.isImplicitPattern === false) { - itemPath = `${itemPath}${path19.sep}`; + if (!itemPath.endsWith(path20.sep) && this.isImplicitPattern === false) { + itemPath = `${itemPath}${path20.sep}`; } } else { itemPath = pathHelper.safeTrimTrailingSeparator(itemPath); @@ -79777,9 +79816,9 @@ var require_internal_pattern2 = __commonJS({ (0, assert_1.default)(literalSegments.every((x, i) => (x !== "." || i === 0) && x !== ".."), `Invalid pattern '${pattern}'. Relative pathing '.' and '..' is not allowed.`); (0, assert_1.default)(!pathHelper.hasRoot(pattern) || literalSegments[0], `Invalid pattern '${pattern}'. Root segment must not contain globs.`); pattern = pathHelper.normalizeSeparators(pattern); - if (pattern === "." || pattern.startsWith(`.${path19.sep}`)) { + if (pattern === "." || pattern.startsWith(`.${path20.sep}`)) { pattern = _Pattern.globEscape(process.cwd()) + pattern.substr(1); - } else if (pattern === "~" || pattern.startsWith(`~${path19.sep}`)) { + } else if (pattern === "~" || pattern.startsWith(`~${path20.sep}`)) { homedir2 = homedir2 || os5.homedir(); (0, assert_1.default)(homedir2, "Unable to determine HOME directory"); (0, assert_1.default)(pathHelper.hasAbsoluteRoot(homedir2), `Expected HOME directory to be a rooted path. Actual '${homedir2}'`); @@ -79863,8 +79902,8 @@ var require_internal_search_state2 = __commonJS({ Object.defineProperty(exports2, "__esModule", { value: true }); exports2.SearchState = void 0; var SearchState = class { - constructor(path19, level) { - this.path = path19; + constructor(path20, level) { + this.path = path20; this.level = level; } }; @@ -79990,7 +80029,7 @@ var require_internal_globber2 = __commonJS({ var core14 = __importStar4(require_core()); var fs18 = __importStar4(require("fs")); var globOptionsHelper = __importStar4(require_internal_glob_options_helper2()); - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var patternHelper = __importStar4(require_internal_pattern_helper2()); var internal_match_kind_1 = require_internal_match_kind2(); var internal_pattern_1 = require_internal_pattern2(); @@ -80066,7 +80105,7 @@ var require_internal_globber2 = __commonJS({ if (!stats) { continue; } - if (options.excludeHiddenFiles && path19.basename(item.path).match(/^\./)) { + if (options.excludeHiddenFiles && path20.basename(item.path).match(/^\./)) { continue; } if (stats.isDirectory()) { @@ -80076,7 +80115,7 @@ var require_internal_globber2 = __commonJS({ continue; } const childLevel = item.level + 1; - const childItems = (yield __await4(fs18.promises.readdir(item.path))).map((x) => new internal_search_state_1.SearchState(path19.join(item.path, x), childLevel)); + const childItems = (yield __await4(fs18.promises.readdir(item.path))).map((x) => new internal_search_state_1.SearchState(path20.join(item.path, x), childLevel)); stack.push(...childItems.reverse()); } else if (match & internal_match_kind_1.MatchKind.File) { yield yield __await4(item.path); @@ -80228,7 +80267,7 @@ var require_internal_hash_files = __commonJS({ var fs18 = __importStar4(require("fs")); var stream2 = __importStar4(require("stream")); var util = __importStar4(require("util")); - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); function hashFiles2(globber, currentWorkspace, verbose = false) { var _a, e_1, _b, _c; var _d; @@ -80244,7 +80283,7 @@ var require_internal_hash_files = __commonJS({ _e = false; const file = _c; writeDelegate(file); - if (!file.startsWith(`${githubWorkspace}${path19.sep}`)) { + if (!file.startsWith(`${githubWorkspace}${path20.sep}`)) { writeDelegate(`Ignore '${file}' since it is not under GITHUB_WORKSPACE.`); continue; } @@ -80650,7 +80689,7 @@ var require_tool_cache = __commonJS({ var fs18 = __importStar4(require("fs")); var mm = __importStar4(require_manifest()); var os5 = __importStar4(require("os")); - var path19 = __importStar4(require("path")); + var path20 = __importStar4(require("path")); var httpm = __importStar4(require_lib()); var semver9 = __importStar4(require_semver2()); var stream2 = __importStar4(require("stream")); @@ -80671,8 +80710,8 @@ 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(), crypto2.randomUUID()); - yield io7.mkdirP(path19.dirname(dest)); + dest = dest || path20.join(_getTempDirectory(), crypto2.randomUUID()); + yield io7.mkdirP(path20.dirname(dest)); core14.debug(`Downloading ${url}`); core14.debug(`Destination ${dest}`); const maxAttempts = 3; @@ -80759,7 +80798,7 @@ var require_tool_cache = __commonJS({ process.chdir(originalCwd); } } else { - const escapedScript = path19.join(__dirname, "..", "scripts", "Invoke-7zdec.ps1").replace(/'/g, "''").replace(/"|\n|\r/g, ""); + const escapedScript = path20.join(__dirname, "..", "scripts", "Invoke-7zdec.ps1").replace(/'/g, "''").replace(/"|\n|\r/g, ""); const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ""); const escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ""); const command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`; @@ -80935,7 +80974,7 @@ var require_tool_cache = __commonJS({ } const destPath = yield _createToolPath(tool, version, arch2); for (const itemName of fs18.readdirSync(sourceDir)) { - const s = path19.join(sourceDir, itemName); + const s = path20.join(sourceDir, itemName); yield io7.cp(s, destPath, { recursive: true }); } _completeToolPath(tool, version, arch2); @@ -80953,7 +80992,7 @@ var require_tool_cache = __commonJS({ throw new Error("sourceFile is not a file"); } const destFolder = yield _createToolPath(tool, version, arch2); - const destPath = path19.join(destFolder, targetFile); + const destPath = path20.join(destFolder, targetFile); core14.debug(`destination file ${destPath}`); yield io7.cp(sourceFile, destPath); _completeToolPath(tool, version, arch2); @@ -80977,7 +81016,7 @@ var require_tool_cache = __commonJS({ let toolPath = ""; if (versionSpec) { versionSpec = semver9.clean(versionSpec) || ""; - const cachePath = path19.join(_getCacheDirectory(), toolName, versionSpec, arch2); + const cachePath = path20.join(_getCacheDirectory(), toolName, versionSpec, arch2); core14.debug(`checking cache: ${cachePath}`); if (fs18.existsSync(cachePath) && fs18.existsSync(`${cachePath}.complete`)) { core14.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch2}`); @@ -80992,12 +81031,12 @@ var require_tool_cache = __commonJS({ function findAllVersions2(toolName, arch2) { const versions = []; arch2 = arch2 || os5.arch(); - const toolPath = path19.join(_getCacheDirectory(), toolName); + const toolPath = path20.join(_getCacheDirectory(), toolName); if (fs18.existsSync(toolPath)) { const children = fs18.readdirSync(toolPath); for (const child of children) { if (isExplicitVersion(child)) { - const fullPath = path19.join(toolPath, child, arch2 || ""); + const fullPath = path20.join(toolPath, child, arch2 || ""); if (fs18.existsSync(fullPath) && fs18.existsSync(`${fullPath}.complete`)) { versions.push(child); } @@ -81052,7 +81091,7 @@ var require_tool_cache = __commonJS({ function _createExtractFolder(dest) { return __awaiter4(this, void 0, void 0, function* () { if (!dest) { - dest = path19.join(_getTempDirectory(), crypto2.randomUUID()); + dest = path20.join(_getTempDirectory(), crypto2.randomUUID()); } yield io7.mkdirP(dest); return dest; @@ -81060,7 +81099,7 @@ var require_tool_cache = __commonJS({ } function _createToolPath(tool, version, arch2) { return __awaiter4(this, void 0, void 0, function* () { - const folderPath = path19.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch2 || ""); + const folderPath = path20.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch2 || ""); core14.debug(`destination ${folderPath}`); const markerPath = `${folderPath}.complete`; yield io7.rmRF(folderPath); @@ -81070,7 +81109,7 @@ var require_tool_cache = __commonJS({ }); } function _completeToolPath(tool, version, arch2) { - const folderPath = path19.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch2 || ""); + const folderPath = path20.join(_getCacheDirectory(), tool, semver9.clean(version) || version, arch2 || ""); const markerPath = `${folderPath}.complete`; fs18.writeFileSync(markerPath, ""); core14.debug("finished caching tool"); @@ -81681,12 +81720,12 @@ var require_follow_redirects = __commonJS({ // src/init-action.ts var fs17 = __toESM(require("fs")); -var path18 = __toESM(require("path")); +var path19 = __toESM(require("path")); var core13 = __toESM(require_core()); var io6 = __toESM(require_io()); var semver8 = __toESM(require_semver2()); -// node_modules/uuid/dist/stringify.js +// node_modules/uuid/dist-node/stringify.js var byteToHex = []; for (let i = 0; i < 256; ++i) { byteToHex.push((i + 256).toString(16).slice(1)); @@ -81695,7 +81734,7 @@ 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/rng.js +// node_modules/uuid/dist-node/rng.js var import_node_crypto = require("node:crypto"); var rnds8Pool = new Uint8Array(256); var poolPtr = rnds8Pool.length; @@ -81707,11 +81746,11 @@ function rng() { return rnds8Pool.slice(poolPtr, poolPtr += 16); } -// node_modules/uuid/dist/native.js +// node_modules/uuid/dist-node/native.js var import_node_crypto2 = require("node:crypto"); var native_default = { randomUUID: import_node_crypto2.randomUUID }; -// node_modules/uuid/dist/v4.js +// node_modules/uuid/dist-node/v4.js function _v4(options, buf, offset) { options = options || {}; const rnds = options.random ?? options.rng?.() ?? rng(); @@ -82137,12 +82176,12 @@ var import_fast_glob = __toESM(require_out4(), 1); var import_ignore = __toESM(require_ignore(), 1); // node_modules/slash/index.js -function slash(path19) { - const isExtendedLengthPath = path19.startsWith("\\\\?\\"); +function slash(path20) { + const isExtendedLengthPath = path20.startsWith("\\\\?\\"); if (isExtendedLengthPath) { - return path19; + return path20; } - return path19.replace(/\\/g, "/"); + return path20.replace(/\\/g, "/"); } // node_modules/globby/utilities.js @@ -82230,8 +82269,8 @@ var assertPatternsInput = (patterns) => { } }; var normalizePathForDirectoryGlob = (filePath, cwd) => { - const path19 = isNegativePattern(filePath) ? filePath.slice(1) : filePath; - return import_node_path3.default.isAbsolute(path19) ? path19 : import_node_path3.default.join(cwd, path19); + const path20 = isNegativePattern(filePath) ? filePath.slice(1) : filePath; + return import_node_path3.default.isAbsolute(path20) ? path20 : import_node_path3.default.join(cwd, path20); }; var getDirectoryGlob = ({ directoryPath, files, extensions }) => { const extensionGlob = extensions?.length > 0 ? `.${extensions.length > 1 ? `{${extensions.join(",")}}` : extensions[0]}` : ""; @@ -85618,7 +85657,7 @@ async function tryGetFolderBytes(cacheDir, logger, quiet = false) { } } var hadTimeout = false; -async function withTimeout(timeoutMs, promise, onTimeout) { +async function waitForResultWithTimeLimit(timeoutMs, promise, onTimeout) { let finished2 = false; const mainTask = async () => { const result = await promise; @@ -86052,6 +86091,14 @@ function getApiClient() { function getApiClientWithExternalAuth(apiDetails) { return createApiClientWithDetails(apiDetails, { allowExternal: true }); } +function getAuthorizationHeaderFor(logger, apiDetails, url) { + if (url.startsWith(`${apiDetails.url}/`) || apiDetails.apiURL && url.startsWith(`${apiDetails.apiURL}/`)) { + logger.debug(`Providing an authorization token.`); + return `token ${apiDetails.auth}`; + } + logger.debug(`Not using an authorization token.`); + return void 0; +} var cachedGitHubVersion = void 0; async function getGitHubVersionFromApi(apiClient, apiDetails) { if (parseGitHubUrl(apiDetails.url) === GITHUB_DOTCOM_URL) { @@ -86127,6 +86174,12 @@ function computeAutomationID(analysis_key, environment) { } return automationID; } +async function getRepositoryProperties(repositoryNwo) { + return getApiClient().request("GET /repos/:owner/:repo/properties/values", { + owner: repositoryNwo.owner, + repo: repositoryNwo.repo + }); +} // src/caching-utils.ts var core6 = __toESM(require_core()); @@ -86171,9 +86224,8 @@ function getDependencyCachingEnabled() { // src/config-utils.ts var fs9 = __toESM(require("fs")); -var path10 = __toESM(require("path")); +var path11 = __toESM(require("path")); var import_perf_hooks = require("perf_hooks"); -var semver4 = __toESM(require_semver2()); // src/analyses.ts var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { @@ -86200,19 +86252,323 @@ async function parseAnalysisKinds(input) { } var codeQualityQueries = ["code-quality"]; +// src/config/db-config.ts +var path7 = __toESM(require("path")); +var semver2 = __toESM(require_semver2()); + +// src/error-messages.ts +var PACKS_PROPERTY = "packs"; +function getConfigFileOutsideWorkspaceErrorMessage(configFile) { + return `The configuration file "${configFile}" is outside of the workspace`; +} +function getConfigFileDoesNotExistErrorMessage(configFile) { + return `The configuration file "${configFile}" does not exist`; +} +function getConfigFileRepoFormatInvalidMessage(configFile) { + let error2 = `The configuration file "${configFile}" is not a supported remote file reference.`; + error2 += " Expected format //@"; + return error2; +} +function getConfigFileFormatInvalidMessage(configFile) { + return `The configuration file "${configFile}" could not be read`; +} +function getConfigFileDirectoryGivenMessage(configFile) { + return `The configuration file "${configFile}" looks like a directory, not a file`; +} +function getEmptyCombinesError() { + return `A '+' was used to specify that you want to add extra arguments to the configuration, but no extra arguments were specified. Please either remove the '+' or specify some extra arguments.`; +} +function getConfigFilePropertyError(configFile, property, error2) { + if (configFile === void 0) { + return `The workflow property "${property}" is invalid: ${error2}`; + } else { + return `The configuration file "${configFile}" is invalid: property "${property}" ${error2}`; + } +} +function getRepoPropertyError(propertyName, error2) { + return `The repository property "${propertyName}" is invalid: ${error2}`; +} +function getPacksStrInvalid(packStr, configFile) { + return configFile ? getConfigFilePropertyError( + configFile, + PACKS_PROPERTY, + `"${packStr}" is not a valid pack` + ) : `"${packStr}" is not a valid pack`; +} +function getNoLanguagesError() { + return "Did not detect any languages to analyze. Please update input in workflow or check that GitHub detects the correct languages in your repository."; +} +function getUnknownLanguagesError(languages) { + return `Did not recognize the following languages: ${languages.join(", ")}`; +} + +// src/feature-flags/properties.ts +var RepositoryPropertyName = /* @__PURE__ */ ((RepositoryPropertyName2) => { + RepositoryPropertyName2["EXTRA_QUERIES"] = "github-codeql-extra-queries"; + return RepositoryPropertyName2; +})(RepositoryPropertyName || {}); +async function loadPropertiesFromApi(gitHubVersion, logger, repositoryNwo) { + if (gitHubVersion.type === 1 /* GHES */) { + return {}; + } + try { + const response = await getRepositoryProperties(repositoryNwo); + const remoteProperties = response.data; + if (!Array.isArray(remoteProperties)) { + throw new Error( + `Expected repository properties API to return an array, but got: ${JSON.stringify(response.data)}` + ); + } + logger.debug( + `Retrieved ${remoteProperties.length} repository properties: ${remoteProperties.map((p) => p.property_name).join(", ")}` + ); + const knownProperties = new Set(Object.values(RepositoryPropertyName)); + const properties = {}; + for (const property of remoteProperties) { + if (property.property_name === void 0) { + throw new Error( + `Expected property object to have a 'property_name', but got: ${JSON.stringify(property)}` + ); + } + if (knownProperties.has(property.property_name)) { + properties[property.property_name] = property.value; + } + } + logger.debug("Loaded the following values for the repository properties:"); + for (const [property, value] of Object.entries(properties).sort( + ([nameA], [nameB]) => nameA.localeCompare(nameB) + )) { + logger.debug(` ${property}: ${value}`); + } + return properties; + } catch (e) { + throw new Error( + `Encountered an error while trying to determine repository properties: ${e}` + ); + } +} + +// src/config/db-config.ts +function shouldCombine(inputValue) { + return !!inputValue?.trim().startsWith("+"); +} +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 parsePacksSpecification(packStr) { + if (typeof packStr !== "string") { + throw new ConfigurationError(getPacksStrInvalid(packStr)); + } + packStr = packStr.trim(); + const atIndex = packStr.indexOf("@"); + const colonIndex = packStr.indexOf(":", atIndex); + const packStart = 0; + const versionStart = atIndex + 1 || void 0; + const pathStart = colonIndex + 1 || void 0; + const packEnd = Math.min( + atIndex > 0 ? atIndex : Infinity, + colonIndex > 0 ? colonIndex : Infinity, + packStr.length + ); + const versionEnd = versionStart ? Math.min(colonIndex > 0 ? colonIndex : Infinity, packStr.length) : void 0; + const pathEnd = pathStart ? packStr.length : void 0; + const packName = packStr.slice(packStart, packEnd).trim(); + const version = versionStart ? packStr.slice(versionStart, versionEnd).trim() : void 0; + const packPath = pathStart ? packStr.slice(pathStart, pathEnd).trim() : void 0; + if (!PACK_IDENTIFIER_PATTERN.test(packName)) { + throw new ConfigurationError(getPacksStrInvalid(packStr)); + } + if (version) { + try { + new semver2.Range(version); + } catch { + throw new ConfigurationError(getPacksStrInvalid(packStr)); + } + } + if (packPath && (path7.isAbsolute(packPath) || // Permit using "/" instead of "\" on Windows + // Use `x.split(y).join(z)` as a polyfill for `x.replaceAll(y, z)` since + // if we used a regex we'd need to escape the path separator on Windows + // which seems more awkward. + path7.normalize(packPath).split(path7.sep).join("/") !== packPath.split(path7.sep).join("/"))) { + throw new ConfigurationError(getPacksStrInvalid(packStr)); + } + if (!packPath && pathStart) { + throw new ConfigurationError(getPacksStrInvalid(packStr)); + } + return { + name: packName, + version, + path: packPath + }; +} +function validatePackSpecification(pack) { + return prettyPrintPack(parsePacksSpecification(pack)); +} +function parsePacksFromInput(rawPacksInput, languages, packsInputCombines) { + if (!rawPacksInput?.trim()) { + return void 0; + } + if (languages.length > 1) { + throw new ConfigurationError( + "Cannot specify a 'packs' input in a multi-language analysis. Use a codeql-config.yml file instead and specify packs by language." + ); + } else if (languages.length === 0) { + throw new ConfigurationError( + "No languages specified. Cannot process the packs input." + ); + } + rawPacksInput = rawPacksInput.trim(); + if (packsInputCombines) { + rawPacksInput = rawPacksInput.trim().substring(1).trim(); + if (!rawPacksInput) { + throw new ConfigurationError( + getConfigFilePropertyError( + void 0, + "packs", + "A '+' was used in the 'packs' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs." + ) + ); + } + } + return { + [languages[0]]: rawPacksInput.split(",").reduce((packs, pack) => { + packs.push(validatePackSpecification(pack)); + return packs; + }, []) + }; +} +async function calculateAugmentation(rawPacksInput, rawQueriesInput, repositoryProperties, languages) { + const packsInputCombines = shouldCombine(rawPacksInput); + const packsInput = parsePacksFromInput( + rawPacksInput, + languages, + packsInputCombines + ); + const queriesInputCombines = shouldCombine(rawQueriesInput); + const queriesInput = parseQueriesFromInput( + rawQueriesInput, + queriesInputCombines + ); + const repoExtraQueries = repositoryProperties["github-codeql-extra-queries" /* EXTRA_QUERIES */]; + const repoExtraQueriesCombines = shouldCombine(repoExtraQueries); + const repoPropertyQueries = { + combines: repoExtraQueriesCombines, + input: parseQueriesFromInput( + repoExtraQueries, + repoExtraQueriesCombines, + new ConfigurationError( + getRepoPropertyError( + "github-codeql-extra-queries" /* EXTRA_QUERIES */, + getEmptyCombinesError() + ) + ) + ) + }; + return { + packsInputCombines, + packsInput: packsInput?.[languages[0]], + queriesInput, + queriesInputCombines, + repoPropertyQueries + }; +} +function parseQueriesFromInput(rawQueriesInput, queriesInputCombines, errorToThrow) { + if (!rawQueriesInput) { + return void 0; + } + const trimmedInput = queriesInputCombines ? rawQueriesInput.trim().slice(1).trim() : rawQueriesInput?.trim() ?? ""; + if (queriesInputCombines && trimmedInput.length === 0) { + if (errorToThrow) { + throw errorToThrow; + } + throw new ConfigurationError( + getConfigFilePropertyError( + void 0, + "queries", + "A '+' was used in the 'queries' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs." + ) + ); + } + return trimmedInput.split(",").map((query) => ({ uses: query.trim() })); +} +function combineQueries(logger, config, augmentationProperties) { + const result = []; + if (augmentationProperties.repoPropertyQueries && augmentationProperties.repoPropertyQueries.input) { + logger.info( + `Found query configuration in the repository properties (${"github-codeql-extra-queries" /* EXTRA_QUERIES */}): ${augmentationProperties.repoPropertyQueries.input.map((q) => q.uses).join(", ")}` + ); + if (!augmentationProperties.repoPropertyQueries.combines) { + logger.info( + `The queries configured in the repository properties don't allow combining with other query settings. Any queries configured elsewhere will be ignored.` + ); + return augmentationProperties.repoPropertyQueries.input; + } else { + result.push(...augmentationProperties.repoPropertyQueries.input); + } + } + if (augmentationProperties.queriesInput) { + if (!augmentationProperties.queriesInputCombines) { + return result.concat(augmentationProperties.queriesInput); + } else { + result.push(...augmentationProperties.queriesInput); + } + } + if (config.queries) { + result.push(...config.queries); + } + return result; +} +function generateCodeScanningConfig(logger, originalUserInput, augmentationProperties) { + const augmentedConfig = cloneObject(originalUserInput); + augmentedConfig.queries = combineQueries( + logger, + augmentedConfig, + augmentationProperties + ); + logger.debug( + `Combined queries: ${augmentedConfig.queries?.map((q) => q.uses).join(",")}` + ); + 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; + } + return augmentedConfig; +} + // src/feature-flags.ts var fs7 = __toESM(require("fs")); -var path8 = __toESM(require("path")); -var semver3 = __toESM(require_semver2()); +var path9 = __toESM(require("path")); +var semver4 = __toESM(require_semver2()); // src/defaults.json -var bundleVersion = "codeql-bundle-v2.23.0"; -var cliVersion = "2.23.0"; +var bundleVersion = "codeql-bundle-v2.23.1"; +var cliVersion = "2.23.1"; // src/overlay-database-utils.ts var crypto = __toESM(require("crypto")); var fs6 = __toESM(require("fs")); -var path7 = __toESM(require("path")); +var path8 = __toESM(require("path")); var actionsCache = __toESM(require_cache3()); // src/git-utils.ts @@ -86316,8 +86672,8 @@ var getFileOidsUnderPath = async function(basePath) { const match = line.match(regex); if (match) { const oid = match[1]; - const path19 = decodeGitFilePath(match[2]); - fileOidMap[path19] = oid; + const path20 = decodeGitFilePath(match[2]); + fileOidMap[path20] = oid; } else { throw new Error(`Unexpected "git ls-files" output: ${line}`); } @@ -86416,7 +86772,7 @@ function formatDuration(durationMs) { } // src/overlay-database-utils.ts -var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; +var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.4"; 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) { @@ -86441,7 +86797,7 @@ async function readBaseDatabaseOidsFile(config, logger) { } } function getBaseDatabaseOidsFilePath(config) { - return path7.join(config.dbLocation, "base-database-oids.json"); + return path8.join(config.dbLocation, "base-database-oids.json"); } async function writeOverlayChangesFile(config, sourceRoot, logger) { const baseFileOids = await readBaseDatabaseOidsFile(config, logger); @@ -86451,7 +86807,7 @@ async function writeOverlayChangesFile(config, sourceRoot, logger) { `Found ${changedFiles.length} changed file(s) under ${sourceRoot}.` ); const changedFilesJson = JSON.stringify({ changes: changedFiles }); - const overlayChangesFile = path7.join( + const overlayChangesFile = path8.join( getTemporaryDirectory(), "overlay-changes.json" ); @@ -86477,7 +86833,7 @@ function computeChangedFiles(baseFileOids, overlayFileOids) { } var CACHE_VERSION = 1; var CACHE_PREFIX = "codeql-overlay-base-database"; -var MAX_CACHE_OPERATION_MS = 12e4; +var MAX_CACHE_OPERATION_MS = 6e5; function checkOverlayBaseDatabase(config, logger, warningPrefix) { const baseDatabaseOidsFilePath = getBaseDatabaseOidsFilePath(config); if (!fs6.existsSync(baseDatabaseOidsFilePath)) { @@ -86520,9 +86876,39 @@ async function downloadOverlayBaseDatabaseFromCache(codeql, config, logger) { let databaseDownloadDurationMs = 0; try { const databaseDownloadStart = performance.now(); - const foundKey = await withTimeout( + const foundKey = await waitForResultWithTimeLimit( + // This ten-minute limit for the cache restore operation is mainly to + // guard against the possibility that the cache service is unresponsive + // and hangs outside the data download. + // + // Data download (which is normally the most time-consuming part of the + // restore operation) should not run long enough to hit this limit. Even + // for an extremely large 10GB database, at a download speed of 40MB/s + // (see below), the download should complete within five minutes. If we + // do hit this limit, there are likely more serious problems other than + // mere slow download speed. + // + // This is important because we don't want any ongoing file operations + // on the database directory when we do hit this limit. Hitting this + // time limit takes us to a fallback path where we re-initialize the + // database from scratch at dbLocation, and having the cache restore + // operation continue to write into dbLocation in the background would + // really mess things up. We want to hit this limit only in the case + // of a hung cache service, not just slow download speed. MAX_CACHE_OPERATION_MS, - actionsCache.restoreCache([dbLocation], cacheRestoreKeyPrefix), + actionsCache.restoreCache( + [dbLocation], + cacheRestoreKeyPrefix, + void 0, + { + // Azure SDK download (which is the default) uses 128MB segments; see + // https://github.com/actions/toolkit/blob/main/packages/cache/README.md. + // Setting segmentTimeoutInMs to 3000 translates to segment download + // speed of about 40 MB/s, which should be achievable unless the + // download is unreliable (in which case we do want to abort). + segmentTimeoutInMs: 3e3 + } + ), () => { logger.info("Timed out downloading overlay-base database from cache"); } @@ -86580,7 +86966,7 @@ function createCacheKeyHash(components) { } // src/tools-features.ts -var semver2 = __toESM(require_semver2()); +var semver3 = __toESM(require_semver2()); function isSupportedToolsFeature(versionInfo, feature) { return !!versionInfo.features && versionInfo.features[feature]; } @@ -86629,6 +87015,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", @@ -86740,11 +87132,21 @@ var featureConfig = { minimumVersion: void 0, toolsFeature: "pythonDefaultIsToNotExtractStdlib" /* PythonDefaultIsToNotExtractStdlib */ }, + ["use_repository_properties" /* UseRepositoryProperties */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_USE_REPOSITORY_PROPERTIES", + minimumVersion: void 0 + }, ["qa_telemetry_enabled" /* QaTelemetryEnabled */]: { defaultValue: false, 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"; @@ -86754,7 +87156,7 @@ var Features = class { this.gitHubFeatureFlags = new GitHubFeatureFlags( gitHubVersion, repositoryNwo, - path8.join(tempDir, FEATURE_FLAGS_FILE_NAME), + path9.join(tempDir, FEATURE_FLAGS_FILE_NAME), logger ); } @@ -86853,7 +87255,7 @@ var GitHubFeatureFlags = class { DEFAULT_VERSION_FEATURE_FLAG_PREFIX.length, f.length - DEFAULT_VERSION_FEATURE_FLAG_SUFFIX.length ).replace(/_/g, "."); - if (!semver3.valid(version)) { + if (!semver4.valid(version)) { this.logger.warning( `Ignoring feature flag ${f} as it does not specify a valid CodeQL version.` ); @@ -87050,7 +87452,7 @@ var KnownLanguage = /* @__PURE__ */ ((KnownLanguage2) => { // src/trap-caching.ts var fs8 = __toESM(require("fs")); -var path9 = __toESM(require("path")); +var path10 = __toESM(require("path")); var actionsCache2 = __toESM(require_cache3()); var CACHE_VERSION2 = 1; var CODEQL_TRAP_CACHE_PREFIX = "codeql-trap"; @@ -87066,12 +87468,12 @@ async function downloadTrapCaches(codeql, languages, logger) { `Found ${languagesSupportingCaching.length} languages that support TRAP caching` ); if (languagesSupportingCaching.length === 0) return result; - const cachesDir = path9.join( + const cachesDir = path10.join( getTemporaryDirectory(), "trapCaches" ); for (const language of languagesSupportingCaching) { - const cacheDir = path9.join(cachesDir, language); + const cacheDir = path10.join(cachesDir, language); fs8.mkdirSync(cacheDir, { recursive: true }); result[language] = cacheDir; } @@ -87084,7 +87486,7 @@ async function downloadTrapCaches(codeql, languages, logger) { let baseSha = "unknown"; const eventPath = process.env.GITHUB_EVENT_PATH; if (getWorkflowEventName() === "pull_request" && eventPath !== void 0) { - const event = JSON.parse(fs8.readFileSync(path9.resolve(eventPath), "utf-8")); + const event = JSON.parse(fs8.readFileSync(path10.resolve(eventPath), "utf-8")); baseSha = event.pull_request?.base?.sha || baseSha; } for (const language of languages) { @@ -87094,7 +87496,7 @@ async function downloadTrapCaches(codeql, languages, logger) { logger.info( `Looking in Actions cache for TRAP cache with key ${preferredKey}` ); - const found = await withTimeout( + const found = await waitForResultWithTimeLimit( MAX_CACHE_OPERATION_MS2, actionsCache2.restoreCache([cacheDir], preferredKey, [ // Fall back to any cache with the right key prefix @@ -87158,49 +87560,22 @@ async function cachePrefix(codeql, language) { } // src/config-utils.ts -var PACKS_PROPERTY = "packs"; -function getPacksStrInvalid(packStr, configFile) { - return configFile ? getConfigFilePropertyError( - configFile, - PACKS_PROPERTY, - `"${packStr}" is not a valid pack` - ) : `"${packStr}" is not a valid pack`; -} -function getConfigFileOutsideWorkspaceErrorMessage(configFile) { - return `The configuration file "${configFile}" is outside of the workspace`; -} -function getConfigFileDoesNotExistErrorMessage(configFile) { - return `The configuration file "${configFile}" does not exist`; -} -function getConfigFileRepoFormatInvalidMessage(configFile) { - let error2 = `The configuration file "${configFile}" is not a supported remote file reference.`; - error2 += " Expected format //@"; - return error2; -} -function getConfigFileFormatInvalidMessage(configFile) { - return `The configuration file "${configFile}" could not be read`; -} -function getConfigFileDirectoryGivenMessage(configFile) { - return `The configuration file "${configFile}" looks like a directory, not a file`; -} -function getConfigFilePropertyError(configFile, property, error2) { - if (configFile === void 0) { - return `The workflow property "${property}" is invalid: ${error2}`; - } else { - return `The configuration file "${configFile}" is invalid: property "${property}" ${error2}`; +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(", ")}` + ); } -} -function getNoLanguagesError() { - return "Did not detect any languages to analyze. Please update input in workflow or check that GitHub detects the correct languages in your repository."; -} -function getUnknownLanguagesError(languages) { - return `Did not recognize the following languages: ${languages.join(", ")}`; -} -async function getSupportedLanguageMap(codeql) { - const resolveResult = await codeql.betterResolveLanguages(); const supportedLanguages = {}; for (const extractor of Object.keys(resolveResult.extractors)) { - if (KnownLanguage[extractor] !== void 0) { + if (resolveSupportedLanguagesUsingCli || KnownLanguage[extractor] !== void 0) { supportedLanguages[extractor] = extractor; } } @@ -87213,7 +87588,7 @@ async function getSupportedLanguageMap(codeql) { } var baseWorkflowsPath = ".github/workflows"; function hasActionsWorkflows(sourceRoot) { - const workflowsPath = path10.resolve(sourceRoot, baseWorkflowsPath); + const workflowsPath = path11.resolve(sourceRoot, baseWorkflowsPath); const stats = fs9.lstatSync(workflowsPath, { throwIfNoEntry: false }); return stats !== void 0 && stats.isDirectory() && fs9.readdirSync(workflowsPath).length > 0; } @@ -87236,14 +87611,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) { @@ -87256,7 +87631,9 @@ async function getLanguages(codeql, languagesInput, repository, sourceRoot, logg } const languages = Array.from(languagesSet); if (!autodetected && unknownLanguages.length > 0) { - throw new ConfigurationError(getUnknownLanguagesError(unknownLanguages)); + throw new ConfigurationError( + getUnknownLanguagesError(unknownLanguages) + ); } if (languages.length === 0) { throw new ConfigurationError(getNoLanguagesError()); @@ -87300,6 +87677,7 @@ async function initActionState({ sourceRoot, githubVersion, features, + repositoryProperties, logger }, userConfig) { const analysisKinds = await parseAnalysisKinds(analysisKindsInput); @@ -87311,6 +87689,7 @@ async function initActionState({ languagesInput, repository, sourceRoot, + features, logger ); const buildMode = await parseBuildModeInput( @@ -87322,8 +87701,18 @@ async function initActionState({ const augmentationProperties = await calculateAugmentation( packsInput, queriesInput, + repositoryProperties, languages ); + if (analysisKinds.length === 1 && analysisKinds.includes("code-quality" /* CodeQuality */) && augmentationProperties.repoPropertyQueries.input) { + logger.info( + `Ignoring queries configured in the repository properties, because query customisations are not supported for Code Quality analyses.` + ); + augmentationProperties.repoPropertyQueries = { + combines: false, + input: void 0 + }; + } const { trapCaches, trapCacheDownloadTime } = await downloadCacheWithTime( trapCachingEnabled, codeql, @@ -87331,10 +87720,12 @@ async function initActionState({ logger ); const computedConfig = generateCodeScanningConfig( + logger, userConfig, augmentationProperties ); return { + version: getActionVersion(), analysisKinds, languages, buildMode, @@ -87352,7 +87743,8 @@ async function initActionState({ dependencyCachingEnabled: getCachingKind(dependencyCachingEnabled), extraQueryExclusions: [], overlayDatabaseMode: "none" /* None */, - useOverlayDatabaseCaching: false + useOverlayDatabaseCaching: false, + repositoryProperties }; } async function downloadCacheWithTime(trapCachingEnabled, codeQL, languages, logger) { @@ -87368,8 +87760,8 @@ async function downloadCacheWithTime(trapCachingEnabled, codeQL, languages, logg async function loadUserConfig(configFile, workspacePath, apiDetails, tempDir) { if (isLocal(configFile)) { if (configFile !== userConfigFromActionPath(tempDir)) { - configFile = path10.resolve(workspacePath, configFile); - if (!(configFile + path10.sep).startsWith(workspacePath + path10.sep)) { + configFile = path11.resolve(workspacePath, configFile); + if (!(configFile + path11.sep).startsWith(workspacePath + path11.sep)) { throw new ConfigurationError( getConfigFileOutsideWorkspaceErrorMessage(configFile) ); @@ -87380,41 +87772,6 @@ async function loadUserConfig(configFile, workspacePath, apiDetails, tempDir) { return await getRemoteConfig(configFile, apiDetails); } } -async function calculateAugmentation(rawPacksInput, rawQueriesInput, languages) { - const packsInputCombines = shouldCombine(rawPacksInput); - const packsInput = parsePacksFromInput( - rawPacksInput, - languages, - packsInputCombines - ); - const queriesInputCombines = shouldCombine(rawQueriesInput); - const queriesInput = parseQueriesFromInput( - rawQueriesInput, - queriesInputCombines - ); - return { - packsInputCombines, - packsInput: packsInput?.[languages[0]], - queriesInput, - queriesInputCombines - }; -} -function parseQueriesFromInput(rawQueriesInput, queriesInputCombines) { - if (!rawQueriesInput) { - return void 0; - } - const trimmedInput = queriesInputCombines ? rawQueriesInput.trim().slice(1).trim() : rawQueriesInput?.trim() ?? ""; - if (queriesInputCombines && trimmedInput.length === 0) { - throw new ConfigurationError( - getConfigFilePropertyError( - void 0, - "queries", - "A '+' was used in the 'queries' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs." - ) - ); - } - return trimmedInput.split(",").map((query) => ({ uses: query.trim() })); -} var OVERLAY_ANALYSIS_FEATURES = { actions: "overlay_analysis_actions" /* OverlayAnalysisActions */, cpp: "overlay_analysis_cpp" /* OverlayAnalysisCpp */, @@ -87526,102 +87883,11 @@ async function getOverlayDatabaseMode(codeql, repository, features, languages, s useOverlayDatabaseCaching }; } -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 parsePacksFromInput(rawPacksInput, languages, packsInputCombines) { - if (!rawPacksInput?.trim()) { - return void 0; - } - if (languages.length > 1) { - throw new ConfigurationError( - "Cannot specify a 'packs' input in a multi-language analysis. Use a codeql-config.yml file instead and specify packs by language." - ); - } else if (languages.length === 0) { - throw new ConfigurationError( - "No languages specified. Cannot process the packs input." - ); - } - rawPacksInput = rawPacksInput.trim(); - if (packsInputCombines) { - rawPacksInput = rawPacksInput.trim().substring(1).trim(); - if (!rawPacksInput) { - throw new ConfigurationError( - getConfigFilePropertyError( - void 0, - "packs", - "A '+' was used in the 'packs' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs." - ) - ); - } - } - return { - [languages[0]]: rawPacksInput.split(",").reduce((packs, pack) => { - packs.push(validatePackSpecification(pack)); - return packs; - }, []) - }; -} -function parsePacksSpecification(packStr) { - if (typeof packStr !== "string") { - throw new ConfigurationError(getPacksStrInvalid(packStr)); - } - packStr = packStr.trim(); - const atIndex = packStr.indexOf("@"); - const colonIndex = packStr.indexOf(":", atIndex); - const packStart = 0; - const versionStart = atIndex + 1 || void 0; - const pathStart = colonIndex + 1 || void 0; - const packEnd = Math.min( - atIndex > 0 ? atIndex : Infinity, - colonIndex > 0 ? colonIndex : Infinity, - packStr.length - ); - const versionEnd = versionStart ? Math.min(colonIndex > 0 ? colonIndex : Infinity, packStr.length) : void 0; - const pathEnd = pathStart ? packStr.length : void 0; - const packName = packStr.slice(packStart, packEnd).trim(); - const version = versionStart ? packStr.slice(versionStart, versionEnd).trim() : void 0; - const packPath = pathStart ? packStr.slice(pathStart, pathEnd).trim() : void 0; - if (!PACK_IDENTIFIER_PATTERN.test(packName)) { - throw new ConfigurationError(getPacksStrInvalid(packStr)); - } - if (version) { - try { - new semver4.Range(version); - } catch { - throw new ConfigurationError(getPacksStrInvalid(packStr)); - } - } - if (packPath && (path10.isAbsolute(packPath) || // Permit using "/" instead of "\" on Windows - // Use `x.split(y).join(z)` as a polyfill for `x.replaceAll(y, z)` since - // if we used a regex we'd need to escape the path separator on Windows - // which seems more awkward. - path10.normalize(packPath).split(path10.sep).join("/") !== packPath.split(path10.sep).join("/"))) { - throw new ConfigurationError(getPacksStrInvalid(packStr)); - } - if (!packPath && pathStart) { - throw new ConfigurationError(getPacksStrInvalid(packStr)); - } - return { - name: packName, - version, - path: packPath - }; -} -function validatePackSpecification(pack) { - return prettyPrintPack(parsePacksSpecification(pack)); -} -function shouldCombine(inputValue) { - return !!inputValue?.trim().startsWith("+"); -} function dbLocationOrDefault(dbLocation, tempDir) { - return dbLocation || path10.resolve(tempDir, "codeql_databases"); + return dbLocation || path11.resolve(tempDir, "codeql_databases"); } function userConfigFromActionPath(tempDir) { - return path10.resolve(tempDir, "user-config-from-action.yml"); + return path11.resolve(tempDir, "user-config-from-action.yml"); } function hasQueryCustomisation(userConfig) { return isDefined(userConfig["disable-default-queries"]) || isDefined(userConfig.queries) || isDefined(userConfig["query-filters"]); @@ -87686,7 +87952,6 @@ async function initConfig(inputs) { exclude: { tags: "exclude-from-incremental" } }); } - await saveConfig(config, logger); return config; } function parseRegistries(registriesInput) { @@ -87742,19 +88007,21 @@ async function getRemoteConfig(configFile, apiDetails) { getConfigFileDirectoryGivenMessage(configFile) ); } else { - throw new ConfigurationError(getConfigFileFormatInvalidMessage(configFile)); + throw new ConfigurationError( + getConfigFileFormatInvalidMessage(configFile) + ); } return load( Buffer.from(fileContents, "base64").toString("binary") ); } function getPathToParsedConfigFile(tempDir) { - return path10.join(tempDir, "config"); + return path11.join(tempDir, "config"); } async function saveConfig(config, logger) { const configString = JSON.stringify(config); const configFile = getPathToParsedConfigFile(config.tempDir); - fs9.mkdirSync(path10.dirname(configFile), { recursive: true }); + fs9.mkdirSync(path11.dirname(configFile), { recursive: true }); fs9.writeFileSync(configFile, configString, "utf8"); logger.debug("Saved config:"); logger.debug(configString); @@ -87765,7 +88032,7 @@ async function generateRegistries(registriesInput, tempDir, logger) { let qlconfigFile; if (registries) { const qlconfig = createRegistriesBlock(registries); - qlconfigFile = path10.join(tempDir, "qlconfig.yml"); + qlconfigFile = path11.join(tempDir, "qlconfig.yml"); const qlconfigContents = dump(qlconfig); fs9.writeFileSync(qlconfigFile, qlconfigContents, "utf8"); logger.debug("Generated qlconfig.yml:"); @@ -87842,41 +88109,6 @@ async function parseBuildModeInput(input, languages, features, logger) { } return input; } -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; - } - return augmentedConfig; -} function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { const augmentedConfig = cloneObject(cliConfig); if (extraQueryExclusions.length === 0) { @@ -87950,7 +88182,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]; @@ -87967,8 +88199,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( ", " @@ -87988,17 +88222,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}-`; } @@ -88071,13 +88308,13 @@ function flushDiagnostics(config) { // src/init.ts var fs15 = __toESM(require("fs")); -var path16 = __toESM(require("path")); +var path17 = __toESM(require("path")); var toolrunner4 = __toESM(require_toolrunner()); var io5 = __toESM(require_io()); // src/codeql.ts var fs14 = __toESM(require("fs")); -var path15 = __toESM(require("path")); +var path16 = __toESM(require("path")); var core10 = __toESM(require_core()); var toolrunner3 = __toESM(require_toolrunner()); @@ -88320,7 +88557,7 @@ function wrapCliConfigurationError(cliError) { // src/setup-codeql.ts var fs12 = __toESM(require("fs")); -var path13 = __toESM(require("path")); +var path14 = __toESM(require("path")); var toolcache3 = __toESM(require_tool_cache()); var import_fast_deep_equal = __toESM(require_fast_deep_equal()); var semver7 = __toESM(require_semver2()); @@ -88486,7 +88723,7 @@ function inferCompressionMethod(tarPath) { // src/tools-download.ts var fs11 = __toESM(require("fs")); var os3 = __toESM(require("os")); -var path12 = __toESM(require("path")); +var path13 = __toESM(require("path")); var import_perf_hooks2 = require("perf_hooks"); var core9 = __toESM(require_core()); var import_http_client = __toESM(require_lib()); @@ -88619,7 +88856,7 @@ async function downloadAndExtractZstdWithStreaming(codeqlURL, dest, authorizatio await extractTarZst(response, dest, tarVersion, logger); } function getToolcacheDirectory(version) { - return path12.join( + return path13.join( getRequiredEnvParam("RUNNER_TOOL_CACHE"), TOOLCACHE_TOOL_NAME, semver6.clean(version) || version, @@ -88639,7 +88876,10 @@ function sanitizeUrlForStatusReport(url) { // src/setup-codeql.ts var CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; +var CODEQL_NIGHTLIES_REPOSITORY_OWNER = "dsp-testing"; +var CODEQL_NIGHTLIES_REPOSITORY_NAME = "codeql-cli-nightlies"; var CODEQL_BUNDLE_VERSION_ALIAS = ["linked", "latest"]; +var CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"]; function getCodeQLBundleExtension(compressionMethod) { switch (compressionMethod) { case "gzip": @@ -88759,7 +88999,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { const candidates = toolcache3.findAllVersions("CodeQL").filter(isGoodVersion).map((version) => ({ folder: toolcache3.find("CodeQL", version), version - })).filter(({ folder }) => fs12.existsSync(path13.join(folder, "pinned-version"))); + })).filter(({ folder }) => fs12.existsSync(path14.join(folder, "pinned-version"))); if (candidates.length === 1) { const candidate = candidates[0]; logger.debug( @@ -88782,7 +89022,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { return void 0; } async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, logger) { - if (toolsInput && !CODEQL_BUNDLE_VERSION_ALIAS.includes(toolsInput) && !toolsInput.startsWith("http")) { + if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); if (compressionMethod2 === void 0) { @@ -88811,6 +89051,12 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian let cliVersion2; let tagName; let url; + if (toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { + logger.info( + `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + ); + toolsInput = await getNightlyToolsUrl(logger); + } if (forceShippedTools) { cliVersion2 = cliVersion; tagName = bundleVersion; @@ -88963,11 +89209,12 @@ var downloadCodeQL = async function(codeqlURL, compressionMethod, maybeBundleVer let authorization = void 0; if (searchParams.has("token")) { logger.debug("CodeQL tools URL contains an authorization token."); - } else if (codeqlURL.startsWith(`${apiDetails.url}/`) || apiDetails.apiURL && codeqlURL.startsWith(`${apiDetails.apiURL}/`)) { - logger.debug("Providing an authorization token to download CodeQL tools."); - authorization = `token ${apiDetails.auth}`; } else { - logger.debug("Downloading CodeQL tools without an authorization token."); + authorization = getAuthorizationHeaderFor( + logger, + apiDetails, + codeqlURL + ); } const toolcacheInfo = getToolcacheDestinationInfo( maybeBundleVersion, @@ -89092,12 +89339,40 @@ async function useZstdBundle(cliVersion2, tarSupportsZstd) { ); } function getTempExtractionDir(tempDir) { - return path13.join(tempDir, v4_default()); + return path14.join(tempDir, v4_default()); +} +async function getNightlyToolsUrl(logger) { + const zstdAvailability = await isZstdAvailable(logger); + const compressionMethod = await useZstdBundle( + CODEQL_VERSION_ZSTD_BUNDLE, + zstdAvailability.available + ) ? "zstd" : "gzip"; + try { + const release3 = await getApiClient().rest.repos.listReleases({ + owner: CODEQL_NIGHTLIES_REPOSITORY_OWNER, + repo: CODEQL_NIGHTLIES_REPOSITORY_NAME, + per_page: 1, + page: 1, + prerelease: true + }); + const latestRelease = release3.data[0]; + if (!latestRelease) { + throw new Error("Could not find the latest nightly release."); + } + return `https://github.com/${CODEQL_NIGHTLIES_REPOSITORY_OWNER}/${CODEQL_NIGHTLIES_REPOSITORY_NAME}/releases/download/${latestRelease.tag_name}/${getCodeQLBundleName(compressionMethod)}`; + } catch (e) { + throw new Error( + `Failed to retrieve the latest nightly release: ${wrapError(e)}` + ); + } +} +function isReservedToolsValue(tools) { + return CODEQL_BUNDLE_VERSION_ALIAS.includes(tools) || CODEQL_NIGHTLY_TOOLS_INPUTS.includes(tools); } // src/tracer-config.ts var fs13 = __toESM(require("fs")); -var path14 = __toESM(require("path")); +var path15 = __toESM(require("path")); async function shouldEnableIndirectTracing(codeql, config) { if (config.buildMode === "none" /* None */) { return false; @@ -89110,7 +89385,7 @@ async function shouldEnableIndirectTracing(codeql, config) { async function getTracerConfigForCluster(config) { const tracingEnvVariables = JSON.parse( fs13.readFileSync( - path14.resolve( + path15.resolve( config.dbLocation, "temp/tracingEnvironment/start-tracing.json" ), @@ -89157,7 +89432,7 @@ async function setupCodeQL(toolsInput, apiDetails, tempDir, variant, defaultCliV toolsDownloadStatusReport )}` ); - let codeqlCmd = path15.join(codeqlFolder, "codeql", "codeql"); + let codeqlCmd = path16.join(codeqlFolder, "codeql", "codeql"); if (process.platform === "win32") { codeqlCmd += ".exe"; } else if (process.platform !== "linux" && process.platform !== "darwin") { @@ -89212,7 +89487,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { }, async isTracedLanguage(language) { const extractorPath = await this.resolveExtractor(language); - const tracingConfigPath = path15.join( + const tracingConfigPath = path16.join( extractorPath, "tools", "tracing-config.lua" @@ -89288,7 +89563,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { }, async runAutobuild(config, language) { applyAutobuildAzurePipelinesTimeoutFix(); - const autobuildCmd = path15.join( + const autobuildCmd = path16.join( await this.resolveExtractor(language), "tools", process.platform === "win32" ? "autobuild.cmd" : "autobuild.sh" @@ -89363,13 +89638,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); @@ -89698,7 +89976,7 @@ async function getTrapCachingExtractorConfigArgsForLang(config, language) { ]; } function getGeneratedCodeScanningConfigPath(config) { - return path15.resolve(config.tempDir, "user-config.yaml"); + return path16.resolve(config.tempDir, "user-config.yaml"); } function getExtractionVerbosityArguments(enableDebugLogging) { return enableDebugLogging ? [`--verbosity=${EXTRACTION_DEBUG_MODE_VERBOSITY}`] : []; @@ -89787,9 +90065,9 @@ async function checkPacksForOverlayCompatibility(codeql, config, logger) { } function checkPackForOverlayCompatibility(packDir, codeQlOverlayVersion, logger) { try { - let qlpackPath = path16.join(packDir, "qlpack.yml"); + let qlpackPath = path17.join(packDir, "qlpack.yml"); if (!fs15.existsSync(qlpackPath)) { - qlpackPath = path16.join(packDir, "codeql-pack.yml"); + qlpackPath = path17.join(packDir, "codeql-pack.yml"); } const qlpackContents = load( fs15.readFileSync(qlpackPath, "utf8") @@ -89797,7 +90075,7 @@ function checkPackForOverlayCompatibility(packDir, codeQlOverlayVersion, logger) if (!qlpackContents.buildMetadata) { return true; } - const packInfoPath = path16.join(packDir, ".packinfo"); + const packInfoPath = path17.join(packDir, ".packinfo"); if (!fs15.existsSync(packInfoPath)) { logger.warning( `The query pack at ${packDir} does not have a .packinfo file, so it cannot support overlay analysis. Recompiling the query pack with the latest CodeQL CLI should solve this problem.` @@ -89830,7 +90108,7 @@ function checkPackForOverlayCompatibility(packDir, codeQlOverlayVersion, logger) } async function checkInstallPython311(languages, codeql) { if (languages.includes("python" /* python */) && process.platform === "win32" && !(await codeql.getVersion()).features?.supportsPython312) { - const script = path16.resolve( + const script = path17.resolve( __dirname, "../python-setup", "check_python12.ps1" @@ -90095,7 +90373,7 @@ async function createInitWithConfigStatusReport(config, initStatusReport, config // src/workflow.ts var fs16 = __toESM(require("fs")); -var path17 = __toESM(require("path")); +var path18 = __toESM(require("path")); var import_zlib = __toESM(require("zlib")); var core12 = __toESM(require_core()); function toCodedErrors(errors) { @@ -90109,7 +90387,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(); @@ -90163,6 +90442,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); @@ -90233,7 +90528,7 @@ async function getWorkflow(logger) { } async function getWorkflowAbsolutePath(logger) { const relativePath = await getWorkflowRelativePath(); - const absolutePath = path17.join( + const absolutePath = path18.join( getRequiredEnvParam("GITHUB_WORKSPACE"), relativePath ); @@ -90324,12 +90619,16 @@ async function run() { getTemporaryDirectory(), logger ); + const enableRepoProps = await features.getValue( + "use_repository_properties" /* UseRepositoryProperties */ + ); + const repositoryProperties = enableRepoProps ? await loadPropertiesFromApi(gitHubVersion, logger, repositoryNwo) : {}; const jobRunUuid = v4_default(); logger.info(`Job run UUID is ${jobRunUuid}.`); core13.exportVariable("JOB_RUN_UUID" /* JOB_RUN_UUID */, jobRunUuid); core13.exportVariable("CODEQL_ACTION_INIT_HAS_RUN" /* INIT_ACTION_HAS_RUN */, "true"); const configFile = getOptionalInput("config-file"); - const sourceRoot = path18.resolve( + const sourceRoot = path19.resolve( getRequiredEnvParam("GITHUB_WORKSPACE"), getOptionalInput("source-root") || "" ); @@ -90423,6 +90722,7 @@ async function run() { githubVersion: gitHubVersion, apiDetails, features, + repositoryProperties, logger }); await checkInstallPython311(config.languages, codeql); @@ -90506,14 +90806,14 @@ async function run() { )) { try { logger.debug(`Applying static binary workaround for Go`); - const tempBinPath = path18.resolve( + const tempBinPath = path19.resolve( getTemporaryDirectory(), "codeql-action-go-tracing", "bin" ); fs17.mkdirSync(tempBinPath, { recursive: true }); core13.addPath(tempBinPath); - const goWrapperPath = path18.resolve(tempBinPath, "go"); + const goWrapperPath = path19.resolve(tempBinPath, "go"); fs17.writeFileSync( goWrapperPath, `#!/bin/bash @@ -90584,8 +90884,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 { @@ -90618,6 +90926,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.dependencyCachingEnabled && 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, @@ -90683,6 +91001,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 edc2cc242a..f63ac24681 100644 --- a/lib/resolve-environment-action.js +++ b/lib/resolve-environment-action.js @@ -26438,7 +26438,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.3", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -26447,7 +26447,7 @@ var require_package = __commonJS({ lint: "eslint --report-unused-disable-directives --max-warnings=0 .", "lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif", "lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix", - test: "npm run transpile && ava src/**.test.ts --serial --verbose", + test: "npm run transpile && ava src/ --serial --verbose", "test-debug": "npm run test -- --timeout=20m", transpile: "tsc --build --verbose" }, @@ -26463,7 +26463,7 @@ var require_package = __commonJS({ dependencies: { "@actions/artifact": "^2.3.1", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^4.0.5", + "@actions/cache": "^4.1.0", "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", @@ -26486,15 +26486,15 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^12.0.0" + uuid: "^13.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", - "@eslint/compat": "^1.3.2", + "@eslint/compat": "^1.4.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.35.0", + "@eslint/js": "^9.36.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", - "@octokit/types": "^14.1.0", + "@octokit/types": "^15.0.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", @@ -26503,10 +26503,10 @@ var require_package = __commonJS({ "@types/node-forge": "^1.3.14", "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.43.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", - esbuild: "^0.25.9", + esbuild: "^0.25.10", eslint: "^8.57.1", "eslint-import-resolver-typescript": "^3.8.7", "eslint-plugin-filenames": "^1.3.2", @@ -26536,7 +26536,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -67281,7 +67282,7 @@ var require_package2 = __commonJS({ "node_modules/@actions/cache/package.json"(exports2, module2) { module2.exports = { name: "@actions/cache", - version: "4.0.5", + version: "4.1.0", preview: true, description: "Actions cache lib", keywords: [ @@ -72090,11 +72091,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 9 /*ScalarType.STRING*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, signedUploadUrl: "" }; + const message = { ok: false, signedUploadUrl: "", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -72113,6 +72121,10 @@ var require_cache2 = __commonJS({ 2: message.signedUploadUrl = reader.string(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -72129,6 +72141,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.signedUploadUrl !== "") writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.signedUploadUrl); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -72234,11 +72248,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 3 /*ScalarType.INT64*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, entryId: "0" }; + const message = { ok: false, entryId: "0", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -72257,6 +72278,10 @@ var require_cache2 = __commonJS({ 2: message.entryId = reader.int64().toString(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -72273,6 +72298,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.entryId !== "0") writer.tag(2, runtime_1.WireType.Varint).int64(message.entryId); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -73036,7 +73063,7 @@ var require_cache3 = __commonJS({ }); }; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.ReserveCacheError = exports2.ValidationError = void 0; + exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; var core13 = __importStar4(require_core()); var path5 = __importStar4(require("path")); var utils = __importStar4(require_cacheUtils()); @@ -73044,7 +73071,6 @@ var require_cache3 = __commonJS({ var cacheTwirpClient = __importStar4(require_cacheTwirpClient()); var config_1 = require_config(); var tar_1 = require_tar(); - var constants_1 = require_constants7(); var http_client_1 = require_lib(); var ValidationError = class _ValidationError extends Error { constructor(message) { @@ -73062,6 +73088,14 @@ var require_cache3 = __commonJS({ } }; exports2.ReserveCacheError = ReserveCacheError; + var FinalizeCacheError = class _FinalizeCacheError extends Error { + constructor(message) { + super(message); + this.name = "FinalizeCacheError"; + Object.setPrototypeOf(this, _FinalizeCacheError.prototype); + } + }; + exports2.FinalizeCacheError = FinalizeCacheError; function checkPaths(paths) { if (!paths || paths.length === 0) { throw new ValidationError(`Path Validation Error: At least one directory or file path is required`); @@ -73333,9 +73367,6 @@ var require_cache3 = __commonJS({ } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); core13.debug(`File Size: ${archiveFileSize}`); - if (archiveFileSize > constants_1.CacheFileSizeLimit && !(0, config_1.isGhes)()) { - throw new Error(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`); - } options.archiveSizeBytes = archiveFileSize; core13.debug("Reserving Cache"); const version = utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive); @@ -73347,7 +73378,10 @@ var require_cache3 = __commonJS({ try { const response = yield twirpClient.CreateCacheEntry(request); if (!response.ok) { - throw new Error("Response was not ok"); + if (response.message) { + core13.warning(`Cache reservation failed: ${response.message}`); + } + throw new Error(response.message || "Response was not ok"); } signedUploadUrl = response.signedUploadUrl; } catch (error2) { @@ -73364,6 +73398,9 @@ var require_cache3 = __commonJS({ const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest); core13.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); if (!finalizeResponse.ok) { + if (finalizeResponse.message) { + throw new FinalizeCacheError(finalizeResponse.message); + } throw new Error(`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`); } cacheId = parseInt(finalizeResponse.entryId); @@ -73373,6 +73410,8 @@ var require_cache3 = __commonJS({ throw error2; } else if (typedError.name === ReserveCacheError.name) { core13.info(`Failed to save: ${typedError.message}`); + } else if (typedError.name === FinalizeCacheError.name) { + core13.warning(typedError.message); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { core13.error(`Failed to save: ${typedError.message}`); @@ -78227,7 +78266,6 @@ function wrapCliConfigurationError(cliError) { // src/config-utils.ts var fs3 = __toESM(require("fs")); var path3 = __toESM(require("path")); -var semver4 = __toESM(require_semver2()); // src/analyses.ts var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { @@ -78240,8 +78278,17 @@ var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); // src/caching-utils.ts var core6 = __toESM(require_core()); +// src/config/db-config.ts +var semver2 = __toESM(require_semver2()); +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}$`); +})(); + // src/feature-flags.ts -var semver3 = __toESM(require_semver2()); +var semver4 = __toESM(require_semver2()); // src/overlay-database-utils.ts var fs2 = __toESM(require("fs")); @@ -78418,7 +78465,7 @@ function getActionsLogger() { } // src/overlay-database-utils.ts -var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; +var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.4"; 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) { @@ -78479,7 +78526,7 @@ function computeChangedFiles(baseFileOids, overlayFileOids) { } // src/tools-features.ts -var semver2 = __toESM(require_semver2()); +var semver3 = __toESM(require_semver2()); function isSupportedToolsFeature(versionInfo, feature) { return !!versionInfo.features && versionInfo.features[feature]; } @@ -78525,6 +78572,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", @@ -78636,11 +78689,21 @@ var featureConfig = { minimumVersion: void 0, toolsFeature: "pythonDefaultIsToNotExtractStdlib" /* PythonDefaultIsToNotExtractStdlib */ }, + ["use_repository_properties" /* UseRepositoryProperties */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_USE_REPOSITORY_PROPERTIES", + minimumVersion: void 0 + }, ["qa_telemetry_enabled" /* QaTelemetryEnabled */]: { defaultValue: false, 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" } }; @@ -78672,12 +78735,6 @@ var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { 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 path3.join(tempDir, "config"); } @@ -78689,7 +78746,18 @@ async function getConfig(tempDir, logger) { const configString = fs3.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; } function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { const augmentedConfig = cloneObject(cliConfig); @@ -78941,13 +79009,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); diff --git a/lib/start-proxy-action-post.js b/lib/start-proxy-action-post.js index f4ae973df6..8507bab0e0 100644 --- a/lib/start-proxy-action-post.js +++ b/lib/start-proxy-action-post.js @@ -26438,7 +26438,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.3", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -26447,7 +26447,7 @@ var require_package = __commonJS({ lint: "eslint --report-unused-disable-directives --max-warnings=0 .", "lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif", "lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix", - test: "npm run transpile && ava src/**.test.ts --serial --verbose", + test: "npm run transpile && ava src/ --serial --verbose", "test-debug": "npm run test -- --timeout=20m", transpile: "tsc --build --verbose" }, @@ -26463,7 +26463,7 @@ var require_package = __commonJS({ dependencies: { "@actions/artifact": "^2.3.1", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^4.0.5", + "@actions/cache": "^4.1.0", "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", @@ -26486,15 +26486,15 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^12.0.0" + uuid: "^13.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", - "@eslint/compat": "^1.3.2", + "@eslint/compat": "^1.4.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.35.0", + "@eslint/js": "^9.36.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", - "@octokit/types": "^14.1.0", + "@octokit/types": "^15.0.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", @@ -26503,10 +26503,10 @@ var require_package = __commonJS({ "@types/node-forge": "^1.3.14", "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.43.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", - esbuild: "^0.25.9", + esbuild: "^0.25.10", eslint: "^8.57.1", "eslint-import-resolver-typescript": "^3.8.7", "eslint-plugin-filenames": "^1.3.2", @@ -26536,7 +26536,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -67281,7 +67282,7 @@ var require_package2 = __commonJS({ "node_modules/@actions/cache/package.json"(exports2, module2) { module2.exports = { name: "@actions/cache", - version: "4.0.5", + version: "4.1.0", preview: true, description: "Actions cache lib", keywords: [ @@ -72090,11 +72091,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 9 /*ScalarType.STRING*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, signedUploadUrl: "" }; + const message = { ok: false, signedUploadUrl: "", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -72113,6 +72121,10 @@ var require_cache2 = __commonJS({ 2: message.signedUploadUrl = reader.string(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -72129,6 +72141,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.signedUploadUrl !== "") writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.signedUploadUrl); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -72234,11 +72248,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 3 /*ScalarType.INT64*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, entryId: "0" }; + const message = { ok: false, entryId: "0", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -72257,6 +72278,10 @@ var require_cache2 = __commonJS({ 2: message.entryId = reader.int64().toString(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -72273,6 +72298,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.entryId !== "0") writer.tag(2, runtime_1.WireType.Varint).int64(message.entryId); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -73036,7 +73063,7 @@ var require_cache3 = __commonJS({ }); }; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.ReserveCacheError = exports2.ValidationError = void 0; + exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; var core14 = __importStar4(require_core()); var path2 = __importStar4(require("path")); var utils = __importStar4(require_cacheUtils()); @@ -73044,7 +73071,6 @@ var require_cache3 = __commonJS({ var cacheTwirpClient = __importStar4(require_cacheTwirpClient()); var config_1 = require_config(); var tar_1 = require_tar(); - var constants_1 = require_constants7(); var http_client_1 = require_lib(); var ValidationError = class _ValidationError extends Error { constructor(message) { @@ -73062,6 +73088,14 @@ var require_cache3 = __commonJS({ } }; exports2.ReserveCacheError = ReserveCacheError2; + var FinalizeCacheError = class _FinalizeCacheError extends Error { + constructor(message) { + super(message); + this.name = "FinalizeCacheError"; + Object.setPrototypeOf(this, _FinalizeCacheError.prototype); + } + }; + exports2.FinalizeCacheError = FinalizeCacheError; function checkPaths(paths) { if (!paths || paths.length === 0) { throw new ValidationError(`Path Validation Error: At least one directory or file path is required`); @@ -73333,9 +73367,6 @@ var require_cache3 = __commonJS({ } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); core14.debug(`File Size: ${archiveFileSize}`); - if (archiveFileSize > constants_1.CacheFileSizeLimit && !(0, config_1.isGhes)()) { - throw new Error(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`); - } options.archiveSizeBytes = archiveFileSize; core14.debug("Reserving Cache"); const version = utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive); @@ -73347,7 +73378,10 @@ var require_cache3 = __commonJS({ try { const response = yield twirpClient.CreateCacheEntry(request); if (!response.ok) { - throw new Error("Response was not ok"); + if (response.message) { + core14.warning(`Cache reservation failed: ${response.message}`); + } + throw new Error(response.message || "Response was not ok"); } signedUploadUrl = response.signedUploadUrl; } catch (error2) { @@ -73364,6 +73398,9 @@ var require_cache3 = __commonJS({ const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest); core14.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); if (!finalizeResponse.ok) { + if (finalizeResponse.message) { + throw new FinalizeCacheError(finalizeResponse.message); + } throw new Error(`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`); } cacheId = parseInt(finalizeResponse.entryId); @@ -73373,6 +73410,8 @@ var require_cache3 = __commonJS({ throw error2; } else if (typedError.name === ReserveCacheError2.name) { core14.info(`Failed to save: ${typedError.message}`); + } else if (typedError.name === FinalizeCacheError.name) { + core14.warning(typedError.message); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { core14.error(`Failed to save: ${typedError.message}`); @@ -76345,7 +76384,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); } @@ -93455,7 +93494,7 @@ var require_commonjs16 = __commonJS({ var TYPEMASK = 1023; var entToType = (s) => s.isFile() ? IFREG : s.isDirectory() ? IFDIR : s.isSymbolicLink() ? IFLNK : s.isCharacterDevice() ? IFCHR : s.isBlockDevice() ? IFBLK : s.isSocket() ? IFSOCK : s.isFIFO() ? IFIFO : UNKNOWN; var normalizeCache = /* @__PURE__ */ new Map(); - var normalize2 = (s) => { + var normalize = (s) => { const c = normalizeCache.get(s); if (c) return c; @@ -93468,7 +93507,7 @@ var require_commonjs16 = __commonJS({ const c = normalizeNocaseCache.get(s); if (c) return c; - const n = normalize2(s.toLowerCase()); + const n = normalize(s.toLowerCase()); normalizeNocaseCache.set(s, n); return n; }; @@ -93637,7 +93676,7 @@ var require_commonjs16 = __commonJS({ */ constructor(name, type2 = UNKNOWN, root, roots, nocase, children, opts) { this.name = name; - this.#matchName = nocase ? normalizeNocase(name) : normalize2(name); + this.#matchName = nocase ? normalizeNocase(name) : normalize(name); this.#type = type2 & TYPEMASK; this.nocase = nocase; this.roots = roots; @@ -93730,7 +93769,7 @@ var require_commonjs16 = __commonJS({ return this.parent || this; } const children = this.children(); - const name = this.nocase ? normalizeNocase(pathPart) : normalize2(pathPart); + const name = this.nocase ? normalizeNocase(pathPart) : normalize(pathPart); for (const p of children) { if (p.#matchName === name) { return p; @@ -93975,7 +94014,7 @@ var require_commonjs16 = __commonJS({ * directly. */ isNamed(n) { - return !this.nocase ? this.#matchName === normalize2(n) : this.#matchName === normalizeNocase(n); + return !this.nocase ? this.#matchName === normalize(n) : this.#matchName === normalizeNocase(n); } /** * Return the Path object corresponding to the target of a symbolic link. @@ -94114,7 +94153,7 @@ var require_commonjs16 = __commonJS({ #readdirMaybePromoteChild(e, c) { for (let p = c.provisional; p < c.length; p++) { const pchild = c[p]; - const name = this.nocase ? normalizeNocase(e.name) : normalize2(e.name); + const name = this.nocase ? normalizeNocase(e.name) : normalize(e.name); if (name !== pchild.#matchName) { continue; } @@ -101945,7 +101984,7 @@ var require_tr46 = __commonJS({ TRANSITIONAL: 0, NONTRANSITIONAL: 1 }; - function normalize2(str2) { + function normalize(str2) { return str2.split("\0").map(function(s) { return s.normalize("NFC"); }).join("\0"); @@ -102025,7 +102064,7 @@ var require_tr46 = __commonJS({ processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL; } var error2 = false; - if (normalize2(label) !== label || label[3] === "-" && label[4] === "-" || label[0] === "-" || label[label.length - 1] === "-" || label.indexOf(".") !== -1 || label.search(combiningMarksRegex) === 0) { + if (normalize(label) !== label || label[3] === "-" && label[4] === "-" || label[0] === "-" || label[label.length - 1] === "-" || label.indexOf(".") !== -1 || label.search(combiningMarksRegex) === 0) { error2 = true; } var len = countSymbols(label); @@ -102043,7 +102082,7 @@ var require_tr46 = __commonJS({ } function processing(domain_name, useSTD3, processing_option) { var result = mapChars(domain_name, useSTD3, processing_option); - result.string = normalize2(result.string); + result.string = normalize(result.string); var labels = result.string.split("."); for (var i = 0; i < labels.length; ++i) { try { @@ -117126,7 +117165,6 @@ async function getGitHubVersion() { // src/config-utils.ts var fs = __toESM(require("fs")); var path = __toESM(require("path")); -var semver4 = __toESM(require_semver2()); // src/analyses.ts var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { @@ -117139,8 +117177,17 @@ var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); // src/caching-utils.ts var core6 = __toESM(require_core()); +// src/config/db-config.ts +var semver2 = __toESM(require_semver2()); +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}$`); +})(); + // src/feature-flags.ts -var semver3 = __toESM(require_semver2()); +var semver4 = __toESM(require_semver2()); // src/overlay-database-utils.ts var actionsCache = __toESM(require_cache3()); @@ -117157,12 +117204,12 @@ function getActionsLogger() { } // src/overlay-database-utils.ts -var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; +var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.4"; 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 -var semver2 = __toESM(require_semver2()); +var semver3 = __toESM(require_semver2()); // src/feature-flags.ts var featureConfig = { @@ -117205,6 +117252,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", @@ -117316,11 +117369,21 @@ var featureConfig = { minimumVersion: void 0, toolsFeature: "pythonDefaultIsToNotExtractStdlib" /* PythonDefaultIsToNotExtractStdlib */ }, + ["use_repository_properties" /* UseRepositoryProperties */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_USE_REPOSITORY_PROPERTIES", + minimumVersion: void 0 + }, ["qa_telemetry_enabled" /* QaTelemetryEnabled */]: { defaultValue: false, 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" } }; @@ -117352,12 +117415,6 @@ var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { 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 path.join(tempDir, "config"); } @@ -117369,7 +117426,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 ad4e5c882c..32691c1cca 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.3", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -44975,7 +44975,7 @@ var require_package = __commonJS({ lint: "eslint --report-unused-disable-directives --max-warnings=0 .", "lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif", "lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix", - test: "npm run transpile && ava src/**.test.ts --serial --verbose", + test: "npm run transpile && ava src/ --serial --verbose", "test-debug": "npm run test -- --timeout=20m", transpile: "tsc --build --verbose" }, @@ -44991,7 +44991,7 @@ var require_package = __commonJS({ dependencies: { "@actions/artifact": "^2.3.1", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^4.0.5", + "@actions/cache": "^4.1.0", "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", @@ -45014,15 +45014,15 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^12.0.0" + uuid: "^13.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", - "@eslint/compat": "^1.3.2", + "@eslint/compat": "^1.4.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.35.0", + "@eslint/js": "^9.36.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", - "@octokit/types": "^14.1.0", + "@octokit/types": "^15.0.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", @@ -45031,10 +45031,10 @@ var require_package = __commonJS({ "@types/node-forge": "^1.3.14", "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.43.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", - esbuild: "^0.25.9", + esbuild: "^0.25.10", eslint: "^8.57.1", "eslint-import-resolver-typescript": "^3.8.7", "eslint-plugin-filenames": "^1.3.2", @@ -45064,16 +45064,1587 @@ 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; + }; + } +}); + // 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()); @@ -47759,6 +49330,13 @@ function isDefined(value) { // 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; @@ -47767,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( @@ -47775,14 +49356,53 @@ var persistInputs = function() { core4.saveState(persistedInputsKey, JSON.stringify(inputEnvironmentVariables)); }; -// src/logging.ts +// src/api-client.ts var core5 = __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()); +} +function getAuthorizationHeaderFor(logger, apiDetails, url) { + if (url.startsWith(`${apiDetails.url}/`) || apiDetails.apiURL && url.startsWith(`${apiDetails.apiURL}/`)) { + logger.debug(`Providing an authorization token.`); + return `token ${apiDetails.auth}`; + } + logger.debug(`Not using an authorization token.`); + return void 0; +} + +// src/logging.ts +var core6 = __toESM(require_core()); function getActionsLogger() { - return core5; + return core6; } // src/start-proxy.ts -var core6 = __toESM(require_core()); +var core7 = __toESM(require_core()); + +// src/defaults.json +var bundleVersion = "codeql-bundle-v2.23.1"; +var cliVersion = "2.23.1"; // src/languages.ts var KnownLanguage = /* @__PURE__ */ ((KnownLanguage2) => { @@ -47800,6 +49420,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 */, @@ -47860,10 +49483,10 @@ 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( @@ -47892,11 +49515,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 = [ @@ -47948,7 +49613,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"), @@ -47968,7 +49633,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) { @@ -47989,7 +49654,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; @@ -48008,31 +49673,42 @@ 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 apiDetails = getApiDetails(); + const authorization = getAuthorizationHeaderFor( + logger, + apiDetails, + proxyInfo.url + ); + const temp = await toolcache.downloadTool( + proxyInfo.url, + void 0, + authorization, + { + accept: "application/octet-stream" + } + ); 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 d816e145f8..78ccf503c9 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -29019,7 +29019,7 @@ var require_pattern = __commonJS({ const absolute = []; const relative2 = []; for (const pattern of patterns) { - if (isAbsolute3(pattern)) { + if (isAbsolute2(pattern)) { absolute.push(pattern); } else { relative2.push(pattern); @@ -29028,10 +29028,10 @@ var require_pattern = __commonJS({ return [absolute, relative2]; } exports2.partitionAbsoluteAndRelative = partitionAbsoluteAndRelative; - function isAbsolute3(pattern) { + function isAbsolute2(pattern) { return path15.isAbsolute(pattern); } - exports2.isAbsolute = isAbsolute3; + exports2.isAbsolute = isAbsolute2; } }); @@ -33584,7 +33584,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.3", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -33593,7 +33593,7 @@ var require_package = __commonJS({ lint: "eslint --report-unused-disable-directives --max-warnings=0 .", "lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif", "lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix", - test: "npm run transpile && ava src/**.test.ts --serial --verbose", + test: "npm run transpile && ava src/ --serial --verbose", "test-debug": "npm run test -- --timeout=20m", transpile: "tsc --build --verbose" }, @@ -33609,7 +33609,7 @@ var require_package = __commonJS({ dependencies: { "@actions/artifact": "^2.3.1", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^4.0.5", + "@actions/cache": "^4.1.0", "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", @@ -33632,15 +33632,15 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^12.0.0" + uuid: "^13.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", - "@eslint/compat": "^1.3.2", + "@eslint/compat": "^1.4.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.35.0", + "@eslint/js": "^9.36.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", - "@octokit/types": "^14.1.0", + "@octokit/types": "^15.0.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", @@ -33649,10 +33649,10 @@ var require_package = __commonJS({ "@types/node-forge": "^1.3.14", "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.43.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", - esbuild: "^0.25.9", + esbuild: "^0.25.10", eslint: "^8.57.1", "eslint-import-resolver-typescript": "^3.8.7", "eslint-plugin-filenames": "^1.3.2", @@ -33682,7 +33682,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -74427,7 +74428,7 @@ var require_package2 = __commonJS({ "node_modules/@actions/cache/package.json"(exports2, module2) { module2.exports = { name: "@actions/cache", - version: "4.0.5", + version: "4.1.0", preview: true, description: "Actions cache lib", keywords: [ @@ -79236,11 +79237,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 9 /*ScalarType.STRING*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, signedUploadUrl: "" }; + const message = { ok: false, signedUploadUrl: "", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -79259,6 +79267,10 @@ var require_cache2 = __commonJS({ 2: message.signedUploadUrl = reader.string(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -79275,6 +79287,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.signedUploadUrl !== "") writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.signedUploadUrl); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -79380,11 +79394,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 3 /*ScalarType.INT64*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, entryId: "0" }; + const message = { ok: false, entryId: "0", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -79403,6 +79424,10 @@ var require_cache2 = __commonJS({ 2: message.entryId = reader.int64().toString(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -79419,6 +79444,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.entryId !== "0") writer.tag(2, runtime_1.WireType.Varint).int64(message.entryId); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -80182,7 +80209,7 @@ var require_cache3 = __commonJS({ }); }; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.ReserveCacheError = exports2.ValidationError = void 0; + exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; var core12 = __importStar4(require_core()); var path15 = __importStar4(require("path")); var utils = __importStar4(require_cacheUtils()); @@ -80190,7 +80217,6 @@ var require_cache3 = __commonJS({ var cacheTwirpClient = __importStar4(require_cacheTwirpClient()); var config_1 = require_config(); var tar_1 = require_tar(); - var constants_1 = require_constants10(); var http_client_1 = require_lib(); var ValidationError = class _ValidationError extends Error { constructor(message) { @@ -80208,6 +80234,14 @@ var require_cache3 = __commonJS({ } }; exports2.ReserveCacheError = ReserveCacheError; + var FinalizeCacheError = class _FinalizeCacheError extends Error { + constructor(message) { + super(message); + this.name = "FinalizeCacheError"; + Object.setPrototypeOf(this, _FinalizeCacheError.prototype); + } + }; + exports2.FinalizeCacheError = FinalizeCacheError; function checkPaths(paths) { if (!paths || paths.length === 0) { throw new ValidationError(`Path Validation Error: At least one directory or file path is required`); @@ -80479,9 +80513,6 @@ var require_cache3 = __commonJS({ } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); core12.debug(`File Size: ${archiveFileSize}`); - if (archiveFileSize > constants_1.CacheFileSizeLimit && !(0, config_1.isGhes)()) { - throw new Error(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`); - } options.archiveSizeBytes = archiveFileSize; core12.debug("Reserving Cache"); const version = utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive); @@ -80493,7 +80524,10 @@ var require_cache3 = __commonJS({ try { const response = yield twirpClient.CreateCacheEntry(request); if (!response.ok) { - throw new Error("Response was not ok"); + if (response.message) { + core12.warning(`Cache reservation failed: ${response.message}`); + } + throw new Error(response.message || "Response was not ok"); } signedUploadUrl = response.signedUploadUrl; } catch (error2) { @@ -80510,6 +80544,9 @@ var require_cache3 = __commonJS({ const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest); core12.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); if (!finalizeResponse.ok) { + if (finalizeResponse.message) { + throw new FinalizeCacheError(finalizeResponse.message); + } throw new Error(`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`); } cacheId = parseInt(finalizeResponse.entryId); @@ -80519,6 +80556,8 @@ var require_cache3 = __commonJS({ throw error2; } else if (typedError.name === ReserveCacheError.name) { core12.info(`Failed to save: ${typedError.message}`); + } else if (typedError.name === FinalizeCacheError.name) { + core12.warning(typedError.message); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { core12.error(`Failed to save: ${typedError.message}`); @@ -88543,6 +88582,14 @@ function getApiDetails() { function getApiClient() { return createApiClientWithDetails(getApiDetails()); } +function getAuthorizationHeaderFor(logger, apiDetails, url2) { + if (url2.startsWith(`${apiDetails.url}/`) || apiDetails.apiURL && url2.startsWith(`${apiDetails.apiURL}/`)) { + logger.debug(`Providing an authorization token.`); + return `token ${apiDetails.auth}`; + } + logger.debug(`Not using an authorization token.`); + return void 0; +} var cachedGitHubVersion = void 0; async function getGitHubVersionFromApi(apiClient, apiDetails) { if (parseGitHubUrl(apiDetails.url) === GITHUB_DOTCOM_URL) { @@ -88872,7 +88919,6 @@ function wrapCliConfigurationError(cliError) { // src/config-utils.ts var fs7 = __toESM(require("fs")); var path9 = __toESM(require("path")); -var semver4 = __toESM(require_semver2()); // src/analyses.ts var AnalysisKind = /* @__PURE__ */ ((AnalysisKind2) => { @@ -88885,16 +88931,25 @@ var supportedAnalysisKinds = new Set(Object.values(AnalysisKind)); // src/caching-utils.ts var core6 = __toESM(require_core()); +// src/config/db-config.ts +var semver2 = __toESM(require_semver2()); +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}$`); +})(); + // src/diff-informed-analysis-utils.ts var fs6 = __toESM(require("fs")); var path8 = __toESM(require("path")); // src/feature-flags.ts -var semver3 = __toESM(require_semver2()); +var semver4 = __toESM(require_semver2()); // src/defaults.json -var bundleVersion = "codeql-bundle-v2.23.0"; -var cliVersion = "2.23.0"; +var bundleVersion = "codeql-bundle-v2.23.1"; +var cliVersion = "2.23.1"; // src/overlay-database-utils.ts var fs5 = __toESM(require("fs")); @@ -89113,7 +89168,7 @@ function formatDuration(durationMs) { } // src/overlay-database-utils.ts -var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; +var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.4"; 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) { @@ -89174,7 +89229,7 @@ function computeChangedFiles(baseFileOids, overlayFileOids) { } // src/tools-features.ts -var semver2 = __toESM(require_semver2()); +var semver3 = __toESM(require_semver2()); function isSupportedToolsFeature(versionInfo, feature) { return !!versionInfo.features && versionInfo.features[feature]; } @@ -89221,6 +89276,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", @@ -89332,11 +89393,21 @@ var featureConfig = { minimumVersion: void 0, toolsFeature: "pythonDefaultIsToNotExtractStdlib" /* PythonDefaultIsToNotExtractStdlib */ }, + ["use_repository_properties" /* UseRepositoryProperties */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_USE_REPOSITORY_PROPERTIES", + minimumVersion: void 0 + }, ["qa_telemetry_enabled" /* QaTelemetryEnabled */]: { defaultValue: false, 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" } }; @@ -89386,12 +89457,6 @@ var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { 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 path9.join(tempDir, "config"); } @@ -89403,7 +89468,18 @@ async function getConfig(tempDir, logger) { const configString = fs7.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; } function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { const augmentedConfig = cloneObject(cliConfig); @@ -89431,7 +89507,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/stringify.js +// node_modules/uuid/dist-node/stringify.js var byteToHex = []; for (let i = 0; i < 256; ++i) { byteToHex.push((i + 256).toString(16).slice(1)); @@ -89440,7 +89516,7 @@ 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/rng.js +// node_modules/uuid/dist-node/rng.js var import_node_crypto = require("node:crypto"); var rnds8Pool = new Uint8Array(256); var poolPtr = rnds8Pool.length; @@ -89452,11 +89528,11 @@ function rng() { return rnds8Pool.slice(poolPtr, poolPtr += 16); } -// node_modules/uuid/dist/native.js +// node_modules/uuid/dist-node/native.js var import_node_crypto2 = require("node:crypto"); var native_default = { randomUUID: import_node_crypto2.randomUUID }; -// node_modules/uuid/dist/v4.js +// node_modules/uuid/dist-node/v4.js function _v4(options, buf, offset) { options = options || {}; const rnds = options.random ?? options.rng?.() ?? rng(); @@ -89799,7 +89875,10 @@ function sanitizeUrlForStatusReport(url2) { // src/setup-codeql.ts var CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; +var CODEQL_NIGHTLIES_REPOSITORY_OWNER = "dsp-testing"; +var CODEQL_NIGHTLIES_REPOSITORY_NAME = "codeql-cli-nightlies"; var CODEQL_BUNDLE_VERSION_ALIAS = ["linked", "latest"]; +var CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"]; function getCodeQLBundleExtension(compressionMethod) { switch (compressionMethod) { case "gzip": @@ -89942,7 +90021,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { return void 0; } async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, logger) { - if (toolsInput && !CODEQL_BUNDLE_VERSION_ALIAS.includes(toolsInput) && !toolsInput.startsWith("http")) { + if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); if (compressionMethod2 === void 0) { @@ -89971,6 +90050,12 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian let cliVersion2; let tagName; let url2; + if (toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { + logger.info( + `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + ); + toolsInput = await getNightlyToolsUrl(logger); + } if (forceShippedTools) { cliVersion2 = cliVersion; tagName = bundleVersion; @@ -90123,11 +90208,12 @@ var downloadCodeQL = async function(codeqlURL, compressionMethod, maybeBundleVer let authorization = void 0; if (searchParams.has("token")) { logger.debug("CodeQL tools URL contains an authorization token."); - } else if (codeqlURL.startsWith(`${apiDetails.url}/`) || apiDetails.apiURL && codeqlURL.startsWith(`${apiDetails.apiURL}/`)) { - logger.debug("Providing an authorization token to download CodeQL tools."); - authorization = `token ${apiDetails.auth}`; } else { - logger.debug("Downloading CodeQL tools without an authorization token."); + authorization = getAuthorizationHeaderFor( + logger, + apiDetails, + codeqlURL + ); } const toolcacheInfo = getToolcacheDestinationInfo( maybeBundleVersion, @@ -90254,6 +90340,34 @@ async function useZstdBundle(cliVersion2, tarSupportsZstd) { function getTempExtractionDir(tempDir) { return path11.join(tempDir, v4_default()); } +async function getNightlyToolsUrl(logger) { + const zstdAvailability = await isZstdAvailable(logger); + const compressionMethod = await useZstdBundle( + CODEQL_VERSION_ZSTD_BUNDLE, + zstdAvailability.available + ) ? "zstd" : "gzip"; + try { + const release = await getApiClient().rest.repos.listReleases({ + owner: CODEQL_NIGHTLIES_REPOSITORY_OWNER, + repo: CODEQL_NIGHTLIES_REPOSITORY_NAME, + per_page: 1, + page: 1, + prerelease: true + }); + const latestRelease = release.data[0]; + if (!latestRelease) { + throw new Error("Could not find the latest nightly release."); + } + return `https://github.com/${CODEQL_NIGHTLIES_REPOSITORY_OWNER}/${CODEQL_NIGHTLIES_REPOSITORY_NAME}/releases/download/${latestRelease.tag_name}/${getCodeQLBundleName(compressionMethod)}`; + } catch (e) { + throw new Error( + `Failed to retrieve the latest nightly release: ${wrapError(e)}` + ); + } +} +function isReservedToolsValue(tools) { + return CODEQL_BUNDLE_VERSION_ALIAS.includes(tools) || CODEQL_NIGHTLY_TOOLS_INPUTS.includes(tools); +} // src/tracer-config.ts async function shouldEnableIndirectTracing(codeql, config) { @@ -90507,13 +90621,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); diff --git a/lib/upload-sarif-action-post.js b/lib/upload-sarif-action-post.js index 76753057d2..95ddd53074 100644 --- a/lib/upload-sarif-action-post.js +++ b/lib/upload-sarif-action-post.js @@ -26438,7 +26438,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.3", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -26447,7 +26447,7 @@ var require_package = __commonJS({ lint: "eslint --report-unused-disable-directives --max-warnings=0 .", "lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif", "lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix", - test: "npm run transpile && ava src/**.test.ts --serial --verbose", + test: "npm run transpile && ava src/ --serial --verbose", "test-debug": "npm run test -- --timeout=20m", transpile: "tsc --build --verbose" }, @@ -26463,7 +26463,7 @@ var require_package = __commonJS({ dependencies: { "@actions/artifact": "^2.3.1", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^4.0.5", + "@actions/cache": "^4.1.0", "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", @@ -26486,15 +26486,15 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^12.0.0" + uuid: "^13.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", - "@eslint/compat": "^1.3.2", + "@eslint/compat": "^1.4.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.35.0", + "@eslint/js": "^9.36.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", - "@octokit/types": "^14.1.0", + "@octokit/types": "^15.0.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", @@ -26503,10 +26503,10 @@ var require_package = __commonJS({ "@types/node-forge": "^1.3.14", "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.43.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", - esbuild: "^0.25.9", + esbuild: "^0.25.10", eslint: "^8.57.1", "eslint-import-resolver-typescript": "^3.8.7", "eslint-plugin-filenames": "^1.3.2", @@ -26536,7 +26536,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -70467,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); } @@ -109983,7 +109984,7 @@ var require_package3 = __commonJS({ "node_modules/@actions/cache/package.json"(exports2, module2) { module2.exports = { name: "@actions/cache", - version: "4.0.5", + version: "4.1.0", preview: true, description: "Actions cache lib", keywords: [ @@ -110566,11 +110567,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 9 /*ScalarType.STRING*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, signedUploadUrl: "" }; + const message = { ok: false, signedUploadUrl: "", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -110589,6 +110597,10 @@ var require_cache2 = __commonJS({ 2: message.signedUploadUrl = reader.string(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -110605,6 +110617,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.signedUploadUrl !== "") writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.signedUploadUrl); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -110710,11 +110724,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 3 /*ScalarType.INT64*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, entryId: "0" }; + const message = { ok: false, entryId: "0", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -110733,6 +110754,10 @@ var require_cache2 = __commonJS({ 2: message.entryId = reader.int64().toString(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -110749,6 +110774,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.entryId !== "0") writer.tag(2, runtime_1.WireType.Varint).int64(message.entryId); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -111512,7 +111539,7 @@ var require_cache3 = __commonJS({ }); }; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.ReserveCacheError = exports2.ValidationError = void 0; + exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; var core14 = __importStar4(require_core()); var path2 = __importStar4(require("path")); var utils = __importStar4(require_cacheUtils()); @@ -111520,7 +111547,6 @@ var require_cache3 = __commonJS({ var cacheTwirpClient = __importStar4(require_cacheTwirpClient()); var config_1 = require_config2(); var tar_1 = require_tar2(); - var constants_1 = require_constants10(); var http_client_1 = require_lib(); var ValidationError = class _ValidationError extends Error { constructor(message) { @@ -111538,6 +111564,14 @@ var require_cache3 = __commonJS({ } }; exports2.ReserveCacheError = ReserveCacheError2; + var FinalizeCacheError = class _FinalizeCacheError extends Error { + constructor(message) { + super(message); + this.name = "FinalizeCacheError"; + Object.setPrototypeOf(this, _FinalizeCacheError.prototype); + } + }; + exports2.FinalizeCacheError = FinalizeCacheError; function checkPaths(paths) { if (!paths || paths.length === 0) { throw new ValidationError(`Path Validation Error: At least one directory or file path is required`); @@ -111809,9 +111843,6 @@ var require_cache3 = __commonJS({ } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); core14.debug(`File Size: ${archiveFileSize}`); - if (archiveFileSize > constants_1.CacheFileSizeLimit && !(0, config_1.isGhes)()) { - throw new Error(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`); - } options.archiveSizeBytes = archiveFileSize; core14.debug("Reserving Cache"); const version = utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive); @@ -111823,7 +111854,10 @@ var require_cache3 = __commonJS({ try { const response = yield twirpClient.CreateCacheEntry(request); if (!response.ok) { - throw new Error("Response was not ok"); + if (response.message) { + core14.warning(`Cache reservation failed: ${response.message}`); + } + throw new Error(response.message || "Response was not ok"); } signedUploadUrl = response.signedUploadUrl; } catch (error2) { @@ -111840,6 +111874,9 @@ var require_cache3 = __commonJS({ const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest); core14.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); if (!finalizeResponse.ok) { + if (finalizeResponse.message) { + throw new FinalizeCacheError(finalizeResponse.message); + } throw new Error(`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`); } cacheId = parseInt(finalizeResponse.entryId); @@ -111849,6 +111886,8 @@ var require_cache3 = __commonJS({ throw error2; } else if (typedError.name === ReserveCacheError2.name) { core14.info(`Failed to save: ${typedError.message}`); + } else if (typedError.name === FinalizeCacheError.name) { + core14.warning(typedError.message); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { core14.error(`Failed to save: ${typedError.message}`); @@ -117286,14 +117325,20 @@ var cliErrorsConfig = { } }; -// src/config-utils.ts -var semver4 = __toESM(require_semver2()); - // src/caching-utils.ts var core6 = __toESM(require_core()); +// src/config/db-config.ts +var semver2 = __toESM(require_semver2()); +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}$`); +})(); + // src/feature-flags.ts -var semver3 = __toESM(require_semver2()); +var semver4 = __toESM(require_semver2()); // src/overlay-database-utils.ts var actionsCache = __toESM(require_cache3()); @@ -117318,15 +117363,15 @@ function withGroup(groupName, f) { } // src/overlay-database-utils.ts -var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; +var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.4"; 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 -var semver2 = __toESM(require_semver2()); +var semver3 = __toESM(require_semver2()); var SafeArtifactUploadVersion = "2.20.3"; function isSafeArtifactUpload(codeQlVersion) { - return !codeQlVersion ? true : semver2.gte(codeQlVersion, SafeArtifactUploadVersion); + return !codeQlVersion ? true : semver3.gte(codeQlVersion, SafeArtifactUploadVersion); } // src/feature-flags.ts @@ -117370,6 +117415,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", @@ -117481,11 +117532,21 @@ var featureConfig = { minimumVersion: void 0, toolsFeature: "pythonDefaultIsToNotExtractStdlib" /* PythonDefaultIsToNotExtractStdlib */ }, + ["use_repository_properties" /* UseRepositoryProperties */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_USE_REPOSITORY_PROPERTIES", + minimumVersion: void 0 + }, ["qa_telemetry_enabled" /* QaTelemetryEnabled */]: { defaultValue: false, 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" } }; @@ -117517,12 +117578,6 @@ var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { 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}$`); -})(); // src/setup-codeql.ts var toolcache3 = __toESM(require_tool_cache()); diff --git a/lib/upload-sarif-action.js b/lib/upload-sarif-action.js index 3335f82c2c..88e26e3ca8 100644 --- a/lib/upload-sarif-action.js +++ b/lib/upload-sarif-action.js @@ -27722,7 +27722,7 @@ var require_pattern = __commonJS({ const absolute = []; const relative2 = []; for (const pattern of patterns) { - if (isAbsolute3(pattern)) { + if (isAbsolute2(pattern)) { absolute.push(pattern); } else { relative2.push(pattern); @@ -27731,10 +27731,10 @@ var require_pattern = __commonJS({ return [absolute, relative2]; } exports2.partitionAbsoluteAndRelative = partitionAbsoluteAndRelative; - function isAbsolute3(pattern) { + function isAbsolute2(pattern) { return path16.isAbsolute(pattern); } - exports2.isAbsolute = isAbsolute3; + exports2.isAbsolute = isAbsolute2; } }); @@ -32287,7 +32287,7 @@ var require_package = __commonJS({ "package.json"(exports2, module2) { module2.exports = { name: "codeql", - version: "3.30.3", + version: "3.30.4", private: true, description: "CodeQL action", scripts: { @@ -32296,7 +32296,7 @@ var require_package = __commonJS({ lint: "eslint --report-unused-disable-directives --max-warnings=0 .", "lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif", "lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix", - test: "npm run transpile && ava src/**.test.ts --serial --verbose", + test: "npm run transpile && ava src/ --serial --verbose", "test-debug": "npm run test -- --timeout=20m", transpile: "tsc --build --verbose" }, @@ -32312,7 +32312,7 @@ var require_package = __commonJS({ dependencies: { "@actions/artifact": "^2.3.1", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^4.0.5", + "@actions/cache": "^4.1.0", "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", @@ -32335,15 +32335,15 @@ var require_package = __commonJS({ "node-forge": "^1.3.1", octokit: "^5.0.3", semver: "^7.7.2", - uuid: "^12.0.0" + uuid: "^13.0.0" }, devDependencies: { "@ava/typescript": "6.0.0", - "@eslint/compat": "^1.3.2", + "@eslint/compat": "^1.4.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.35.0", + "@eslint/js": "^9.36.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", - "@octokit/types": "^14.1.0", + "@octokit/types": "^15.0.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", @@ -32352,10 +32352,10 @@ var require_package = __commonJS({ "@types/node-forge": "^1.3.14", "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.43.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.41.0", ava: "^6.4.1", - esbuild: "^0.25.9", + esbuild: "^0.25.10", eslint: "^8.57.1", "eslint-import-resolver-typescript": "^3.8.7", "eslint-plugin-filenames": "^1.3.2", @@ -32385,7 +32385,8 @@ var require_package = __commonJS({ }, "eslint-plugin-jsx-a11y": { semver: ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } }; } @@ -73130,7 +73131,7 @@ var require_package2 = __commonJS({ "node_modules/@actions/cache/package.json"(exports2, module2) { module2.exports = { name: "@actions/cache", - version: "4.0.5", + version: "4.1.0", preview: true, description: "Actions cache lib", keywords: [ @@ -77939,11 +77940,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 9 /*ScalarType.STRING*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, signedUploadUrl: "" }; + const message = { ok: false, signedUploadUrl: "", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -77962,6 +77970,10 @@ var require_cache2 = __commonJS({ 2: message.signedUploadUrl = reader.string(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -77978,6 +77990,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.signedUploadUrl !== "") writer.tag(2, runtime_1.WireType.LengthDelimited).string(message.signedUploadUrl); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -78083,11 +78097,18 @@ var require_cache2 = __commonJS({ kind: "scalar", T: 3 /*ScalarType.INT64*/ + }, + { + no: 3, + name: "message", + kind: "scalar", + T: 9 + /*ScalarType.STRING*/ } ]); } create(value) { - const message = { ok: false, entryId: "0" }; + const message = { ok: false, entryId: "0", message: "" }; globalThis.Object.defineProperty(message, runtime_4.MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== void 0) (0, runtime_3.reflectionMergePartial)(this, message, value); @@ -78106,6 +78127,10 @@ var require_cache2 = __commonJS({ 2: message.entryId = reader.int64().toString(); break; + case /* string message */ + 3: + message.message = reader.string(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -78122,6 +78147,8 @@ var require_cache2 = __commonJS({ writer.tag(1, runtime_1.WireType.Varint).bool(message.ok); if (message.entryId !== "0") writer.tag(2, runtime_1.WireType.Varint).int64(message.entryId); + if (message.message !== "") + writer.tag(3, runtime_1.WireType.LengthDelimited).string(message.message); let u = options.writeUnknownFields; if (u !== false) (u == true ? runtime_2.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -78885,7 +78912,7 @@ var require_cache3 = __commonJS({ }); }; Object.defineProperty(exports2, "__esModule", { value: true }); - exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.ReserveCacheError = exports2.ValidationError = void 0; + exports2.saveCache = exports2.restoreCache = exports2.isFeatureAvailable = exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0; var core14 = __importStar4(require_core()); var path16 = __importStar4(require("path")); var utils = __importStar4(require_cacheUtils()); @@ -78893,7 +78920,6 @@ var require_cache3 = __commonJS({ var cacheTwirpClient = __importStar4(require_cacheTwirpClient()); var config_1 = require_config(); var tar_1 = require_tar(); - var constants_1 = require_constants10(); var http_client_1 = require_lib(); var ValidationError = class _ValidationError extends Error { constructor(message) { @@ -78911,6 +78937,14 @@ var require_cache3 = __commonJS({ } }; exports2.ReserveCacheError = ReserveCacheError; + var FinalizeCacheError = class _FinalizeCacheError extends Error { + constructor(message) { + super(message); + this.name = "FinalizeCacheError"; + Object.setPrototypeOf(this, _FinalizeCacheError.prototype); + } + }; + exports2.FinalizeCacheError = FinalizeCacheError; function checkPaths(paths) { if (!paths || paths.length === 0) { throw new ValidationError(`Path Validation Error: At least one directory or file path is required`); @@ -79182,9 +79216,6 @@ var require_cache3 = __commonJS({ } const archiveFileSize = utils.getArchiveFileSizeInBytes(archivePath); core14.debug(`File Size: ${archiveFileSize}`); - if (archiveFileSize > constants_1.CacheFileSizeLimit && !(0, config_1.isGhes)()) { - throw new Error(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 10GB limit, not saving cache.`); - } options.archiveSizeBytes = archiveFileSize; core14.debug("Reserving Cache"); const version = utils.getCacheVersion(paths, compressionMethod, enableCrossOsArchive); @@ -79196,7 +79227,10 @@ var require_cache3 = __commonJS({ try { const response = yield twirpClient.CreateCacheEntry(request); if (!response.ok) { - throw new Error("Response was not ok"); + if (response.message) { + core14.warning(`Cache reservation failed: ${response.message}`); + } + throw new Error(response.message || "Response was not ok"); } signedUploadUrl = response.signedUploadUrl; } catch (error2) { @@ -79213,6 +79247,9 @@ var require_cache3 = __commonJS({ const finalizeResponse = yield twirpClient.FinalizeCacheEntryUpload(finalizeRequest); core14.debug(`FinalizeCacheEntryUploadResponse: ${finalizeResponse.ok}`); if (!finalizeResponse.ok) { + if (finalizeResponse.message) { + throw new FinalizeCacheError(finalizeResponse.message); + } throw new Error(`Unable to finalize cache with key ${key}, another job may be finalizing this cache.`); } cacheId = parseInt(finalizeResponse.entryId); @@ -79222,6 +79259,8 @@ var require_cache3 = __commonJS({ throw error2; } else if (typedError.name === ReserveCacheError.name) { core14.info(`Failed to save: ${typedError.message}`); + } else if (typedError.name === FinalizeCacheError.name) { + core14.warning(typedError.message); } else { if (typedError instanceof http_client_1.HttpClientError && typeof typedError.statusCode === "number" && typedError.statusCode >= 500) { core14.error(`Failed to save: ${typedError.message}`); @@ -88795,6 +88834,14 @@ function getApiDetails() { function getApiClient() { return createApiClientWithDetails(getApiDetails()); } +function getAuthorizationHeaderFor(logger, apiDetails, url2) { + if (url2.startsWith(`${apiDetails.url}/`) || apiDetails.apiURL && url2.startsWith(`${apiDetails.apiURL}/`)) { + logger.debug(`Providing an authorization token.`); + return `token ${apiDetails.auth}`; + } + logger.debug(`Not using an authorization token.`); + return void 0; +} var cachedGitHubVersion = void 0; async function getGitHubVersionFromApi(apiClient, apiDetails) { if (parseGitHubUrl(apiDetails.url) === GITHUB_DOTCOM_URL) { @@ -88884,8 +88931,8 @@ var path8 = __toESM(require("path")); var semver3 = __toESM(require_semver2()); // src/defaults.json -var bundleVersion = "codeql-bundle-v2.23.0"; -var cliVersion = "2.23.0"; +var bundleVersion = "codeql-bundle-v2.23.1"; +var cliVersion = "2.23.1"; // src/overlay-database-utils.ts var fs5 = __toESM(require("fs")); @@ -89107,7 +89154,7 @@ function formatDuration(durationMs) { } // src/overlay-database-utils.ts -var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; +var CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.4"; 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) { @@ -89217,6 +89264,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", @@ -89328,11 +89381,21 @@ var featureConfig = { minimumVersion: void 0, toolsFeature: "pythonDefaultIsToNotExtractStdlib" /* PythonDefaultIsToNotExtractStdlib */ }, + ["use_repository_properties" /* UseRepositoryProperties */]: { + defaultValue: false, + envVar: "CODEQL_ACTION_USE_REPOSITORY_PROPERTIES", + minimumVersion: void 0 + }, ["qa_telemetry_enabled" /* QaTelemetryEnabled */]: { defaultValue: false, 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"; @@ -89607,11 +89670,19 @@ 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/config/db-config.ts +var semver4 = __toESM(require_semver2()); +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}$`); +})(); + // src/diff-informed-analysis-utils.ts var fs7 = __toESM(require("fs")); var path9 = __toESM(require("path")); @@ -89660,12 +89731,6 @@ var OVERLAY_ANALYSIS_CODE_SCANNING_FEATURES = { 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"); } @@ -89677,7 +89742,18 @@ async function getConfig(tempDir, logger) { const configString = fs8.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; } function appendExtraQueryExclusions(extraQueryExclusions, cliConfig) { const augmentedConfig = cloneObject(cliConfig); @@ -90132,7 +90208,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/stringify.js +// node_modules/uuid/dist-node/stringify.js var byteToHex = []; for (let i = 0; i < 256; ++i) { byteToHex.push((i + 256).toString(16).slice(1)); @@ -90141,7 +90217,7 @@ 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/rng.js +// node_modules/uuid/dist-node/rng.js var import_node_crypto = require("node:crypto"); var rnds8Pool = new Uint8Array(256); var poolPtr = rnds8Pool.length; @@ -90153,11 +90229,11 @@ function rng() { return rnds8Pool.slice(poolPtr, poolPtr += 16); } -// node_modules/uuid/dist/native.js +// node_modules/uuid/dist-node/native.js var import_node_crypto2 = require("node:crypto"); var native_default = { randomUUID: import_node_crypto2.randomUUID }; -// node_modules/uuid/dist/v4.js +// node_modules/uuid/dist-node/v4.js function _v4(options, buf, offset) { options = options || {}; const rnds = options.random ?? options.rng?.() ?? rng(); @@ -90500,7 +90576,10 @@ function sanitizeUrlForStatusReport(url2) { // src/setup-codeql.ts var CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; +var CODEQL_NIGHTLIES_REPOSITORY_OWNER = "dsp-testing"; +var CODEQL_NIGHTLIES_REPOSITORY_NAME = "codeql-cli-nightlies"; var CODEQL_BUNDLE_VERSION_ALIAS = ["linked", "latest"]; +var CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"]; function getCodeQLBundleExtension(compressionMethod) { switch (compressionMethod) { case "gzip": @@ -90643,7 +90722,7 @@ async function findOverridingToolsInCache(humanReadableVersion, logger) { return void 0; } async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, variant, tarSupportsZstd, logger) { - if (toolsInput && !CODEQL_BUNDLE_VERSION_ALIAS.includes(toolsInput) && !toolsInput.startsWith("http")) { + if (toolsInput && !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http")) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); const compressionMethod2 = inferCompressionMethod(toolsInput); if (compressionMethod2 === void 0) { @@ -90672,6 +90751,12 @@ async function getCodeQLSource(toolsInput, defaultCliVersion, apiDetails, varian let cliVersion2; let tagName; let url2; + if (toolsInput !== void 0 && CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput)) { + logger.info( + `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.` + ); + toolsInput = await getNightlyToolsUrl(logger); + } if (forceShippedTools) { cliVersion2 = cliVersion; tagName = bundleVersion; @@ -90824,11 +90909,12 @@ var downloadCodeQL = async function(codeqlURL, compressionMethod, maybeBundleVer let authorization = void 0; if (searchParams.has("token")) { logger.debug("CodeQL tools URL contains an authorization token."); - } else if (codeqlURL.startsWith(`${apiDetails.url}/`) || apiDetails.apiURL && codeqlURL.startsWith(`${apiDetails.apiURL}/`)) { - logger.debug("Providing an authorization token to download CodeQL tools."); - authorization = `token ${apiDetails.auth}`; } else { - logger.debug("Downloading CodeQL tools without an authorization token."); + authorization = getAuthorizationHeaderFor( + logger, + apiDetails, + codeqlURL + ); } const toolcacheInfo = getToolcacheDestinationInfo( maybeBundleVersion, @@ -90955,6 +91041,34 @@ async function useZstdBundle(cliVersion2, tarSupportsZstd) { function getTempExtractionDir(tempDir) { return path12.join(tempDir, v4_default()); } +async function getNightlyToolsUrl(logger) { + const zstdAvailability = await isZstdAvailable(logger); + const compressionMethod = await useZstdBundle( + CODEQL_VERSION_ZSTD_BUNDLE, + zstdAvailability.available + ) ? "zstd" : "gzip"; + try { + const release3 = await getApiClient().rest.repos.listReleases({ + owner: CODEQL_NIGHTLIES_REPOSITORY_OWNER, + repo: CODEQL_NIGHTLIES_REPOSITORY_NAME, + per_page: 1, + page: 1, + prerelease: true + }); + const latestRelease = release3.data[0]; + if (!latestRelease) { + throw new Error("Could not find the latest nightly release."); + } + return `https://github.com/${CODEQL_NIGHTLIES_REPOSITORY_OWNER}/${CODEQL_NIGHTLIES_REPOSITORY_NAME}/releases/download/${latestRelease.tag_name}/${getCodeQLBundleName(compressionMethod)}`; + } catch (e) { + throw new Error( + `Failed to retrieve the latest nightly release: ${wrapError(e)}` + ); + } +} +function isReservedToolsValue(tools) { + return CODEQL_BUNDLE_VERSION_ALIAS.includes(tools) || CODEQL_NIGHTLY_TOOLS_INPUTS.includes(tools); +} // src/tracer-config.ts async function shouldEnableIndirectTracing(codeql, config) { @@ -91208,13 +91322,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); @@ -92959,23 +93076,6 @@ function findSarifFilesInDir(sarifPath, isSarif) { walkSarifFiles(sarifPath); return sarifFiles; } -function getSarifFilePaths(sarifPath, isSarif) { - if (!fs14.existsSync(sarifPath)) { - throw new ConfigurationError(`Path does not exist: ${sarifPath}`); - } - let sarifFiles; - if (fs14.lstatSync(sarifPath).isDirectory()) { - sarifFiles = findSarifFilesInDir(sarifPath, isSarif); - if (sarifFiles.length === 0) { - throw new ConfigurationError( - `No SARIF files found to upload in "${sarifPath}".` - ); - } - } else { - sarifFiles = [sarifPath]; - } - return sarifFiles; -} function countResultsInSarif(sarif) { let numResults = 0; const parsedSarif = JSON.parse(sarif); @@ -93071,20 +93171,6 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo } return payloadObj; } -async function uploadFiles(inputSarifPath, checkoutPath, category, features, logger, uploadTarget) { - const sarifPaths = getSarifFilePaths( - inputSarifPath, - uploadTarget.sarifPredicate - ); - return uploadSpecifiedFiles( - sarifPaths, - checkoutPath, - category, - features, - logger, - uploadTarget - ); -} async function uploadSpecifiedFiles(sarifPaths, checkoutPath, category, features, logger, uploadTarget) { logger.startGroup(`Uploading ${uploadTarget.name} results`); logger.info(`Processing sarif files: ${JSON.stringify(sarifPaths)}`); @@ -93332,6 +93418,30 @@ function filterAlertsByDiffRange(logger, sarif) { } // src/upload-sarif-action.ts +async function findAndUpload(logger, features, sarifPath, pathStats, checkoutPath, analysis, category) { + let sarifFiles; + if (pathStats.isDirectory()) { + sarifFiles = findSarifFilesInDir( + sarifPath, + analysis.sarifPredicate + ); + } else if (pathStats.isFile() && analysis.sarifPredicate(sarifPath)) { + sarifFiles = [sarifPath]; + } else { + return void 0; + } + if (sarifFiles.length !== 0) { + return await uploadSpecifiedFiles( + sarifFiles, + checkoutPath, + category, + features, + logger, + analysis + ); + } + return void 0; +} async function sendSuccessStatusReport(startedAt, uploadStats, logger) { const statusReportBase = await createStatusReportBase( "upload-sarif" /* UploadSarif */, @@ -93378,41 +93488,59 @@ async function run() { const sarifPath = getRequiredInput("sarif_file"); const checkoutPath = getRequiredInput("checkout_path"); const category = getOptionalInput("category"); - const uploadResult = await uploadFiles( + const pathStats = fs15.lstatSync(sarifPath, { throwIfNoEntry: false }); + if (pathStats === void 0) { + throw new ConfigurationError(`Path does not exist: ${sarifPath}.`); + } + const sarifIds = []; + const uploadResult = await findAndUpload( + logger, + features, sarifPath, + pathStats, checkoutPath, - category, - features, + CodeScanning, + category + ); + if (uploadResult !== void 0) { + core13.setOutput("sarif-id", uploadResult.sarifID); + sarifIds.push({ + analysis: "code-scanning" /* CodeScanning */, + id: uploadResult.sarifID + }); + } + const qualityUploadResult = await findAndUpload( logger, - CodeScanning + features, + sarifPath, + pathStats, + checkoutPath, + CodeQuality, + fixCodeQualityCategory(logger, category) ); - core13.setOutput("sarif-id", uploadResult.sarifID); - if (fs15.lstatSync(sarifPath).isDirectory()) { - const qualitySarifFiles = findSarifFilesInDir( - sarifPath, - CodeQuality.sarifPredicate - ); - if (qualitySarifFiles.length !== 0) { - await uploadSpecifiedFiles( - qualitySarifFiles, - checkoutPath, - fixCodeQualityCategory(logger, category), - features, - logger, - CodeQuality - ); - } + if (qualityUploadResult !== void 0) { + sarifIds.push({ + analysis: "code-quality" /* CodeQuality */, + id: qualityUploadResult.sarifID + }); } + core13.setOutput("sarif-ids", JSON.stringify(sarifIds)); if (isInTestMode()) { core13.debug("In test mode. Waiting for processing is disabled."); } else if (getRequiredInput("wait-for-processing") === "true") { - await waitForProcessing( - getRepositoryNwo(), - uploadResult.sarifID, - logger - ); + if (uploadResult !== void 0) { + await waitForProcessing( + getRepositoryNwo(), + uploadResult.sarifID, + logger + ); + } } - await sendSuccessStatusReport(startedAt, uploadResult.statusReport, logger); + await sendSuccessStatusReport( + startedAt, + uploadResult?.statusReport || {}, + logger + ); } catch (unwrappedError) { const error2 = isThirdPartyAnalysis("upload-sarif" /* UploadSarif */) && unwrappedError instanceof InvalidSarifUploadError ? new ConfigurationError(unwrappedError.message) : wrapError(unwrappedError); const message = error2.message; diff --git a/package-lock.json b/package-lock.json index 12ab1133b1..2974494647 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,17 @@ { "name": "codeql", - "version": "3.30.3", + "version": "3.30.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeql", - "version": "3.30.3", + "version": "3.30.4", "license": "MIT", "dependencies": { "@actions/artifact": "^2.3.1", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^4.0.5", + "@actions/cache": "^4.1.0", "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", @@ -34,15 +34,15 @@ "node-forge": "^1.3.1", "octokit": "^5.0.3", "semver": "^7.7.2", - "uuid": "^12.0.0" + "uuid": "^13.0.0" }, "devDependencies": { "@ava/typescript": "6.0.0", - "@eslint/compat": "^1.3.2", + "@eslint/compat": "^1.4.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.35.0", + "@eslint/js": "^9.36.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", - "@octokit/types": "^14.1.0", + "@octokit/types": "^15.0.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", @@ -51,10 +51,10 @@ "@types/node-forge": "^1.3.14", "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.43.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.41.0", "ava": "^6.4.1", - "esbuild": "^0.25.9", + "esbuild": "^0.25.10", "eslint": "^8.57.1", "eslint-import-resolver-typescript": "^3.8.7", "eslint-plugin-filenames": "^1.3.2", @@ -284,9 +284,9 @@ "integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==" }, "node_modules/@actions/cache": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-4.0.5.tgz", - "integrity": "sha512-RjLz1/vvntOfp3FpkY3wB0MjVRbLq7bfQEuQG9UUTKwdtcYmFrKVmuD+9B6ADbzbkSfHM+dM4sMjdr3R4XIkFg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@actions/cache/-/cache-4.1.0.tgz", + "integrity": "sha512-z3Opg+P4Y7baq+g1dODXgdtsvPLSewr3ZKpp3U0HQR1A/vWCoJFS52XSezjdngo4SIOdR5oHtyK3a3Arar+X9A==", "license": "MIT", "dependencies": { "@actions/core": "^1.11.1", @@ -780,9 +780,9 @@ "license": "0BSD" }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", - "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", + "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", "cpu": [ "ppc64" ], @@ -797,9 +797,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", - "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", + "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", "cpu": [ "arm" ], @@ -814,9 +814,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", - "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", + "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", "cpu": [ "arm64" ], @@ -831,9 +831,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", - "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", + "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", "cpu": [ "x64" ], @@ -848,9 +848,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", - "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", + "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", "cpu": [ "arm64" ], @@ -865,9 +865,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", - "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", + "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", "cpu": [ "x64" ], @@ -882,9 +882,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", - "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", + "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", "cpu": [ "arm64" ], @@ -899,9 +899,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", - "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", + "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", "cpu": [ "x64" ], @@ -916,9 +916,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", - "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", + "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", "cpu": [ "arm" ], @@ -933,9 +933,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", - "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", + "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", "cpu": [ "arm64" ], @@ -950,9 +950,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", - "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", + "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", "cpu": [ "ia32" ], @@ -967,9 +967,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", - "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", + "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", "cpu": [ "loong64" ], @@ -984,9 +984,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", - "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", + "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", "cpu": [ "mips64el" ], @@ -1001,9 +1001,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", - "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", + "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", "cpu": [ "ppc64" ], @@ -1018,9 +1018,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", - "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", + "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", "cpu": [ "riscv64" ], @@ -1035,9 +1035,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", - "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", + "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", "cpu": [ "s390x" ], @@ -1052,9 +1052,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", - "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", + "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", "cpu": [ "x64" ], @@ -1069,9 +1069,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", - "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", + "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", "cpu": [ "arm64" ], @@ -1086,9 +1086,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", - "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", + "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", "cpu": [ "x64" ], @@ -1103,9 +1103,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", - "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", + "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", "cpu": [ "arm64" ], @@ -1120,9 +1120,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", - "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", + "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", "cpu": [ "x64" ], @@ -1137,9 +1137,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", - "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", + "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", "cpu": [ "arm64" ], @@ -1154,9 +1154,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", - "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", + "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", "cpu": [ "x64" ], @@ -1171,9 +1171,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", - "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", + "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", "cpu": [ "arm64" ], @@ -1188,9 +1188,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", - "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", + "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", "cpu": [ "ia32" ], @@ -1205,9 +1205,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", - "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", + "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", "cpu": [ "x64" ], @@ -1248,11 +1248,14 @@ } }, "node_modules/@eslint/compat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.3.2.tgz", - "integrity": "sha512-jRNwzTbd6p2Rw4sZ1CgWRS8YMtqG15YyZf7zvb6gY2rB2u6n+2Z+ELW0GtL0fQgyl0pr4Y/BzBfng/BdsereRA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.4.0.tgz", + "integrity": "sha512-DEzm5dKeDBPm3r08Ixli/0cmxr8LkRdwxMRUIJBlSCpAwSrvFEJpVBzV+66JhDxiaqKxnRzCXhtiMiczF7Hglg==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -1265,6 +1268,19 @@ } } }, + "node_modules/@eslint/core": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", + "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", @@ -1330,9 +1346,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.35.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.35.0.tgz", - "integrity": "sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==", + "version": "9.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.36.0.tgz", + "integrity": "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==", "dev": true, "license": "MIT", "engines": { @@ -1655,6 +1671,12 @@ "node": ">= 20" } }, + "node_modules/@octokit/app/node_modules/@octokit/openapi-types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz", + "integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==", + "license": "MIT" + }, "node_modules/@octokit/app/node_modules/@octokit/plugin-paginate-rest": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-13.0.1.tgz", @@ -1669,6 +1691,15 @@ "@octokit/core": ">=6" } }, + "node_modules/@octokit/app/node_modules/@octokit/types": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz", + "integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^25.1.0" + } + }, "node_modules/@octokit/app/node_modules/before-after-hook": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", @@ -1697,6 +1728,21 @@ "node": ">= 20" } }, + "node_modules/@octokit/auth-app/node_modules/@octokit/openapi-types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz", + "integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==", + "license": "MIT" + }, + "node_modules/@octokit/auth-app/node_modules/@octokit/types": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz", + "integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^25.1.0" + } + }, "node_modules/@octokit/auth-app/node_modules/universal-user-agent": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", @@ -1717,6 +1763,21 @@ "node": ">= 20" } }, + "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/openapi-types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz", + "integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==", + "license": "MIT" + }, + "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/types": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz", + "integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^25.1.0" + } + }, "node_modules/@octokit/auth-oauth-app/node_modules/universal-user-agent": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", @@ -1736,6 +1797,21 @@ "node": ">= 20" } }, + "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/openapi-types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz", + "integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==", + "license": "MIT" + }, + "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/types": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz", + "integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^25.1.0" + } + }, "node_modules/@octokit/auth-oauth-device/node_modules/universal-user-agent": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", @@ -1756,6 +1832,21 @@ "node": ">= 20" } }, + "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/openapi-types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz", + "integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==", + "license": "MIT" + }, + "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/types": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz", + "integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^25.1.0" + } + }, "node_modules/@octokit/auth-oauth-user/node_modules/universal-user-agent": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", @@ -1781,6 +1872,21 @@ "node": ">= 20" } }, + "node_modules/@octokit/auth-unauthenticated/node_modules/@octokit/openapi-types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz", + "integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==", + "license": "MIT" + }, + "node_modules/@octokit/auth-unauthenticated/node_modules/@octokit/types": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz", + "integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^25.1.0" + } + }, "node_modules/@octokit/core": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz", @@ -1862,6 +1968,21 @@ "node": ">= 20" } }, + "node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz", + "integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==", + "license": "MIT" + }, + "node_modules/@octokit/endpoint/node_modules/@octokit/types": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz", + "integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^25.1.0" + } + }, "node_modules/@octokit/endpoint/node_modules/universal-user-agent": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", @@ -1988,6 +2109,21 @@ "node": ">= 20" } }, + "node_modules/@octokit/oauth-app/node_modules/@octokit/openapi-types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz", + "integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==", + "license": "MIT" + }, + "node_modules/@octokit/oauth-app/node_modules/@octokit/types": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz", + "integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^25.1.0" + } + }, "node_modules/@octokit/oauth-app/node_modules/before-after-hook": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", @@ -2020,10 +2156,27 @@ "node": ">= 20" } }, - "node_modules/@octokit/openapi-types": { + "node_modules/@octokit/oauth-methods/node_modules/@octokit/openapi-types": { "version": "25.1.0", "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz", - "integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==" + "integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==", + "license": "MIT" + }, + "node_modules/@octokit/oauth-methods/node_modules/@octokit/types": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz", + "integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^25.1.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-26.0.0.tgz", + "integrity": "sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA==", + "dev": true, + "license": "MIT" }, "node_modules/@octokit/openapi-webhooks-types": { "version": "11.0.0", @@ -2156,17 +2309,49 @@ "node": ">= 20" } }, + "node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz", + "integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==", + "license": "MIT" + }, + "node_modules/@octokit/request-error/node_modules/@octokit/types": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz", + "integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^25.1.0" + } + }, + "node_modules/@octokit/request/node_modules/@octokit/openapi-types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz", + "integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==", + "license": "MIT" + }, + "node_modules/@octokit/request/node_modules/@octokit/types": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz", + "integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^25.1.0" + } + }, "node_modules/@octokit/request/node_modules/universal-user-agent": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==" }, "node_modules/@octokit/types": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz", - "integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-15.0.0.tgz", + "integrity": "sha512-8o6yDfmoGJUIeR9OfYU0/TUJTnMPG2r68+1yEdUeG2Fdqpj8Qetg0ziKIgcBm0RW/j29H41WP37CYCEhp6GoHQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^25.1.0" + "@octokit/openapi-types": "^26.0.0" } }, "node_modules/@octokit/webhooks": { @@ -2462,6 +2647,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/json5": { "version": "0.0.29", "dev": true, @@ -2520,17 +2712,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.43.0.tgz", - "integrity": "sha512-8tg+gt7ENL7KewsKMKDHXR1vm8tt9eMxjJBYINf6swonlWgkYn5NwyIgXpbbDxTNU5DgpDFfj95prcTq2clIQQ==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.44.1.tgz", + "integrity": "sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.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", + "@typescript-eslint/scope-manager": "8.44.1", + "@typescript-eslint/type-utils": "8.44.1", + "@typescript-eslint/utils": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -2544,20 +2736,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.43.0", + "@typescript-eslint/parser": "^8.44.1", "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.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.43.0.tgz", - "integrity": "sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.1.tgz", + "integrity": "sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.43.0", - "@typescript-eslint/visitor-keys": "8.43.0" + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2568,9 +2760,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.43.0.tgz", - "integrity": "sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.1.tgz", + "integrity": "sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==", "dev": true, "license": "MIT", "engines": { @@ -2582,16 +2774,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "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==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.1.tgz", + "integrity": "sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==", "dev": true, "license": "MIT", "dependencies": { - "@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", + "@typescript-eslint/project-service": "8.44.1", + "@typescript-eslint/tsconfig-utils": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2611,16 +2803,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.43.0.tgz", - "integrity": "sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.1.tgz", + "integrity": "sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.43.0", - "@typescript-eslint/types": "8.43.0", - "@typescript-eslint/typescript-estree": "8.43.0" + "@typescript-eslint/scope-manager": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2635,13 +2827,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "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==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.1.tgz", + "integrity": "sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/types": "8.44.1", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -2714,16 +2906,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.43.0.tgz", - "integrity": "sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.44.1.tgz", + "integrity": "sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==", "dev": true, "license": "MIT", "dependencies": { - "@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", + "@typescript-eslint/scope-manager": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1", "debug": "^4.3.4" }, "engines": { @@ -2739,14 +2931,14 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.43.0.tgz", - "integrity": "sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.1.tgz", + "integrity": "sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.43.0", - "@typescript-eslint/visitor-keys": "8.43.0" + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2757,9 +2949,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.43.0.tgz", - "integrity": "sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.1.tgz", + "integrity": "sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==", "dev": true, "license": "MIT", "engines": { @@ -2771,16 +2963,16 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "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==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.1.tgz", + "integrity": "sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==", "dev": true, "license": "MIT", "dependencies": { - "@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", + "@typescript-eslint/project-service": "8.44.1", + "@typescript-eslint/tsconfig-utils": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2800,13 +2992,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "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==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.1.tgz", + "integrity": "sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/types": "8.44.1", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -2870,14 +3062,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "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==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.44.1.tgz", + "integrity": "sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.43.0", - "@typescript-eslint/types": "^8.43.0", + "@typescript-eslint/tsconfig-utils": "^8.44.1", + "@typescript-eslint/types": "^8.44.1", "debug": "^4.3.4" }, "engines": { @@ -2892,9 +3084,9 @@ } }, "node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.43.0.tgz", - "integrity": "sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.1.tgz", + "integrity": "sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==", "dev": true, "license": "MIT", "engines": { @@ -2924,9 +3116,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "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==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.44.1.tgz", + "integrity": "sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==", "dev": true, "license": "MIT", "engines": { @@ -2941,15 +3133,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.43.0.tgz", - "integrity": "sha512-qaH1uLBpBuBBuRf8c1mLJ6swOfzCXryhKND04Igr4pckzSEW9JX5Aw9AgW00kwfjWJF0kk0ps9ExKTfvXfw4Qg==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.44.1.tgz", + "integrity": "sha512-KdEerZqHWXsRNKjF9NYswNISnFzXfXNDfPxoTh7tqohU/PRIbwTmsjGK6V9/RTYWau7NZvfo52lgVk+sJh0K3g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.43.0", - "@typescript-eslint/typescript-estree": "8.43.0", - "@typescript-eslint/utils": "8.43.0", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1", + "@typescript-eslint/utils": "8.44.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -2966,14 +3158,14 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.43.0.tgz", - "integrity": "sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.1.tgz", + "integrity": "sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.43.0", - "@typescript-eslint/visitor-keys": "8.43.0" + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2984,9 +3176,9 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.43.0.tgz", - "integrity": "sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.1.tgz", + "integrity": "sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==", "dev": true, "license": "MIT", "engines": { @@ -2998,16 +3190,16 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "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==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.1.tgz", + "integrity": "sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==", "dev": true, "license": "MIT", "dependencies": { - "@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", + "@typescript-eslint/project-service": "8.44.1", + "@typescript-eslint/tsconfig-utils": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -3027,16 +3219,16 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.43.0.tgz", - "integrity": "sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.1.tgz", + "integrity": "sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.43.0", - "@typescript-eslint/types": "8.43.0", - "@typescript-eslint/typescript-estree": "8.43.0" + "@typescript-eslint/scope-manager": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3051,13 +3243,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "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==", + "version": "8.44.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.1.tgz", + "integrity": "sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/types": "8.44.1", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -3164,9 +3356,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": { @@ -4867,9 +5059,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", - "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", + "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -4880,32 +5072,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.9", - "@esbuild/android-arm": "0.25.9", - "@esbuild/android-arm64": "0.25.9", - "@esbuild/android-x64": "0.25.9", - "@esbuild/darwin-arm64": "0.25.9", - "@esbuild/darwin-x64": "0.25.9", - "@esbuild/freebsd-arm64": "0.25.9", - "@esbuild/freebsd-x64": "0.25.9", - "@esbuild/linux-arm": "0.25.9", - "@esbuild/linux-arm64": "0.25.9", - "@esbuild/linux-ia32": "0.25.9", - "@esbuild/linux-loong64": "0.25.9", - "@esbuild/linux-mips64el": "0.25.9", - "@esbuild/linux-ppc64": "0.25.9", - "@esbuild/linux-riscv64": "0.25.9", - "@esbuild/linux-s390x": "0.25.9", - "@esbuild/linux-x64": "0.25.9", - "@esbuild/netbsd-arm64": "0.25.9", - "@esbuild/netbsd-x64": "0.25.9", - "@esbuild/openbsd-arm64": "0.25.9", - "@esbuild/openbsd-x64": "0.25.9", - "@esbuild/openharmony-arm64": "0.25.9", - "@esbuild/sunos-x64": "0.25.9", - "@esbuild/win32-arm64": "0.25.9", - "@esbuild/win32-ia32": "0.25.9", - "@esbuild/win32-x64": "0.25.9" + "@esbuild/aix-ppc64": "0.25.10", + "@esbuild/android-arm": "0.25.10", + "@esbuild/android-arm64": "0.25.10", + "@esbuild/android-x64": "0.25.10", + "@esbuild/darwin-arm64": "0.25.10", + "@esbuild/darwin-x64": "0.25.10", + "@esbuild/freebsd-arm64": "0.25.10", + "@esbuild/freebsd-x64": "0.25.10", + "@esbuild/linux-arm": "0.25.10", + "@esbuild/linux-arm64": "0.25.10", + "@esbuild/linux-ia32": "0.25.10", + "@esbuild/linux-loong64": "0.25.10", + "@esbuild/linux-mips64el": "0.25.10", + "@esbuild/linux-ppc64": "0.25.10", + "@esbuild/linux-riscv64": "0.25.10", + "@esbuild/linux-s390x": "0.25.10", + "@esbuild/linux-x64": "0.25.10", + "@esbuild/netbsd-arm64": "0.25.10", + "@esbuild/netbsd-x64": "0.25.10", + "@esbuild/openbsd-arm64": "0.25.10", + "@esbuild/openbsd-x64": "0.25.10", + "@esbuild/openharmony-arm64": "0.25.10", + "@esbuild/sunos-x64": "0.25.10", + "@esbuild/win32-arm64": "0.25.10", + "@esbuild/win32-ia32": "0.25.10", + "@esbuild/win32-x64": "0.25.10" } }, "node_modules/escalade": { @@ -7405,6 +7597,12 @@ "node": ">= 20" } }, + "node_modules/octokit/node_modules/@octokit/openapi-types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz", + "integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==", + "license": "MIT" + }, "node_modules/octokit/node_modules/@octokit/plugin-paginate-graphql": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-graphql/-/plugin-paginate-graphql-6.0.0.tgz", @@ -7475,6 +7673,15 @@ "@octokit/core": "^7.0.0" } }, + "node_modules/octokit/node_modules/@octokit/types": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz", + "integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^25.1.0" + } + }, "node_modules/octokit/node_modules/before-after-hook": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", @@ -7792,9 +7999,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" @@ -9076,16 +9283,16 @@ "license": "MIT" }, "node_modules/uuid": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-12.0.0.tgz", - "integrity": "sha512-USe1zesMYh4fjCA8ZH5+X5WIVD0J4V1Jksm1bFTVBX2F/cwSXt0RO5w/3UXbdLKmZX65MiWV+hwhSS8p6oBTGA==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz", + "integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], "license": "MIT", "bin": { - "uuid": "dist/bin/uuid" + "uuid": "dist-node/bin/uuid" } }, "node_modules/webidl-conversions": { diff --git a/package.json b/package.json index dacadc7321..96fe4d3aa1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeql", - "version": "3.30.3", + "version": "3.30.4", "private": true, "description": "CodeQL action", "scripts": { @@ -9,7 +9,7 @@ "lint": "eslint --report-unused-disable-directives --max-warnings=0 .", "lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif", "lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix", - "test": "npm run transpile && ava src/**.test.ts --serial --verbose", + "test": "npm run transpile && ava src/ --serial --verbose", "test-debug": "npm run test -- --timeout=20m", "transpile": "tsc --build --verbose" }, @@ -25,7 +25,7 @@ "dependencies": { "@actions/artifact": "^2.3.1", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", - "@actions/cache": "^4.0.5", + "@actions/cache": "^4.1.0", "@actions/core": "^1.11.1", "@actions/exec": "^1.1.1", "@actions/github": "^6.0.0", @@ -48,15 +48,15 @@ "node-forge": "^1.3.1", "octokit": "^5.0.3", "semver": "^7.7.2", - "uuid": "^12.0.0" + "uuid": "^13.0.0" }, "devDependencies": { "@ava/typescript": "6.0.0", - "@eslint/compat": "^1.3.2", + "@eslint/compat": "^1.4.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.35.0", + "@eslint/js": "^9.36.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", - "@octokit/types": "^14.1.0", + "@octokit/types": "^15.0.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", "@types/follow-redirects": "^1.14.4", @@ -65,10 +65,10 @@ "@types/node-forge": "^1.3.14", "@types/semver": "^7.7.1", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.43.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", "@typescript-eslint/parser": "^8.41.0", "ava": "^6.4.1", - "esbuild": "^0.25.9", + "esbuild": "^0.25.10", "eslint": "^8.57.1", "eslint-import-resolver-typescript": "^3.8.7", "eslint-plugin-filenames": "^1.3.2", @@ -98,6 +98,7 @@ }, "eslint-plugin-jsx-a11y": { "semver": ">=6.3.1" - } + }, + "brace-expansion@2.0.1": "2.0.2" } } diff --git a/pr-checks/.gitignore b/pr-checks/.gitignore index 0a764a4de3..979f35ea98 100644 --- a/pr-checks/.gitignore +++ b/pr-checks/.gitignore @@ -1 +1,3 @@ env +__pycache__/ +*.pyc diff --git a/pr-checks/__init__.py b/pr-checks/__init__.py new file mode 100644 index 0000000000..e69de29bb2 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/bundle-toolcache.yml b/pr-checks/checks/bundle-toolcache.yml index d384cefee5..d3a15fcb41 100644 --- a/pr-checks/checks/bundle-toolcache.yml +++ b/pr-checks/checks/bundle-toolcache.yml @@ -8,7 +8,7 @@ operatingSystems: - windows steps: - name: Remove CodeQL from toolcache - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | const fs = require('fs'); @@ -18,7 +18,7 @@ steps: - name: Install @actions/tool-cache run: npm install @actions/tool-cache - name: Check toolcache does not contain CodeQL - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | const toolcache = require('@actions/tool-cache'); @@ -37,7 +37,7 @@ steps: output: ${{ runner.temp }}/results upload-database: false - name: Check CodeQL is installed within the toolcache - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | const toolcache = require('@actions/tool-cache'); diff --git a/pr-checks/checks/bundle-zstd.yml b/pr-checks/checks/bundle-zstd.yml index de83d8e923..2ec8b3b8d2 100644 --- a/pr-checks/checks/bundle-zstd.yml +++ b/pr-checks/checks/bundle-zstd.yml @@ -8,7 +8,7 @@ operatingSystems: - windows steps: - name: Remove CodeQL from toolcache - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | const fs = require('fs'); @@ -33,7 +33,7 @@ steps: path: ${{ runner.temp }}/results/javascript.sarif retention-days: 7 - name: Check diagnostic with expected tools URL appears in SARIF - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: SARIF_PATH: ${{ runner.temp }}/results/javascript.sarif with: diff --git a/pr-checks/checks/config-export.yml b/pr-checks/checks/config-export.yml index ce94482567..c51ad04e26 100644 --- a/pr-checks/checks/config-export.yml +++ b/pr-checks/checks/config-export.yml @@ -18,7 +18,7 @@ steps: path: "${{ runner.temp }}/results/javascript.sarif" retention-days: 7 - name: Check config properties appear in SARIF - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: SARIF_PATH: "${{ runner.temp }}/results/javascript.sarif" with: 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..eb247f7caf 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: | @@ -32,7 +31,7 @@ steps: path: "${{ runner.temp }}/results/javascript.sarif" retention-days: 7 - name: Check diagnostics appear in SARIF - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: SARIF_PATH: "${{ runner.temp }}/results/javascript.sarif" with: 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..39ec0096ab 100644 --- a/pr-checks/checks/go-indirect-tracing-workaround-diagnostic.yml +++ b/pr-checks/checks/go-indirect-tracing-workaround-diagnostic.yml @@ -12,18 +12,17 @@ steps: languages: go tools: ${{ steps.prepare-test.outputs.tools-url }} # Deliberately change Go after the `init` step - - uses: actions/setup-go@v5 + - uses: actions/setup-go@v6 with: go-version: "1.20" - name: Build code - shell: bash run: go build main.go - uses: ./../action/analyze with: output: "${{ runner.temp }}/results" upload-database: false - name: Check diagnostic appears in SARIF - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: SARIF_PATH: "${{ runner.temp }}/results/go.sarif" 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..0078a2e450 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,14 +17,13 @@ steps: languages: go tools: ${{ steps.prepare-test.outputs.tools-url }} - name: Build code - shell: bash run: go build main.go - uses: ./../action/analyze with: output: "${{ runner.temp }}/results" upload-database: false - name: Check diagnostic appears in SARIF - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: SARIF_PATH: "${{ runner.temp }}/results/go.sarif" 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 9eb578171e..b8420ad209 100644 --- a/pr-checks/checks/quality-queries.yml +++ b/pr-checks/checks/quality-queries.yml @@ -54,7 +54,7 @@ steps: 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 + uses: actions/github-script@v8 env: SARIF_PATH: "${{ runner.temp }}/results/javascript.sarif" EXPECT_PRESENT: "false" @@ -62,7 +62,7 @@ steps: script: ${{ env.CHECK_SCRIPT }} - name: Check quality query appears in quality SARIF if: contains(matrix.analysis-kinds, 'code-quality') - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: SARIF_PATH: "${{ runner.temp }}/results/javascript.quality.sarif" EXPECT_PRESENT: "true" 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..2be248a5f2 100644 --- a/pr-checks/checks/rubocop-multi-language.yml +++ b/pr-checks/checks/rubocop-multi-language.yml @@ -5,17 +5,14 @@ operatingSystems: ["ubuntu"] versions: ["default"] steps: - name: Set up Ruby - uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0 + uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a # v1.263.0 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..1e41e5dd3d 100644 --- a/pr-checks/checks/test-local-codeql.yml +++ b/pr-checks/checks/test-local-codeql.yml @@ -1,15 +1,12 @@ name: "Local CodeQL bundle" description: "Tests using a CodeQL bundle from a local file rather than a URL" -versions: ["nightly-latest"] +versions: ["linked"] operatingSystems: ["ubuntu"] installGo: true steps: - - name: Fetch a CodeQL bundle - shell: bash - env: - CODEQL_URL: ${{ steps.prepare-test.outputs.tools-url }} + - name: Fetch latest CodeQL bundle run: | - wget "$CODEQL_URL" + wget https://github.com/github/codeql-action/releases/latest/download/codeql-bundle-linux64.tar.zst - id: init uses: ./../action/init with: @@ -17,6 +14,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 02d2cc5636..cc4786735b 100644 --- a/pr-checks/checks/upload-quality-sarif.yml +++ b/pr-checks/checks/upload-quality-sarif.yml @@ -6,11 +6,9 @@ steps: - uses: ./../action/init with: 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 }} - analysis-kinds: code-scanning,code-quality + languages: csharp,java,javascript,python + analysis-kinds: code-quality - name: Build code - shell: bash run: ./build.sh # Generate some SARIF we can upload with the upload-sarif step - uses: ./../action/analyze @@ -19,6 +17,10 @@ steps: sha: '5e235361806c361d4d3f8859e3c897658025a9a2' upload: never - uses: ./../action/upload-sarif + id: upload-sarif with: ref: 'refs/heads/main' sha: '5e235361806c361d4d3f8859e3c897658025a9a2' + - name: "Check output from `upload-sarif` step" + if: fromJSON(steps.upload-sarif.outputs.sarif-ids)[0].analysis != 'code-quality' + run: exit 1 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/readme.md b/pr-checks/readme.md index 618a67503d..283ed35993 100644 --- a/pr-checks/readme.md +++ b/pr-checks/readme.md @@ -9,6 +9,6 @@ to one of the files in this directory. 1. Install https://github.com/casey/just by whichever way you prefer. 2. Run `just update-pr-checks` in your terminal. -### If you don't want to intall `just` +### If you don't want to install `just` Manually run each step in the `justfile`. diff --git a/pr-checks/sync.py b/pr-checks/sync.py index 6d23cafab5..550953980a 100755 --- a/pr-checks/sync.py +++ b/pr-checks/sync.py @@ -1,9 +1,8 @@ #!/usr/bin/env python import ruamel.yaml -from ruamel.yaml.scalarstring import FoldedScalarString, SingleQuotedScalarString +from ruamel.yaml.scalarstring import SingleQuotedScalarString import pathlib -import textwrap import os # The default set of CodeQL Bundle versions to use for the PR checks. @@ -18,6 +17,8 @@ "stable-v2.20.7", # The last CodeQL release in the 2.21 series. "stable-v2.21.4", + # The last CodeQL release in the 2.22 series. + "stable-v2.22.4", # The default version of CodeQL for Dotcom, as determined by feature flags. "default", # The version of CodeQL shipped with the Action in `defaults.json`. During the release process @@ -127,7 +128,7 @@ def writeHeader(checkStream): steps.extend([ { 'name': 'Install Node.js', - 'uses': 'actions/setup-node@v4', + 'uses': 'actions/setup-node@v5', 'with': { 'node-version': '20.x', 'cache': 'npm', @@ -165,7 +166,7 @@ def writeHeader(checkStream): steps.append({ 'name': 'Install Go', - 'uses': 'actions/setup-go@v5', + 'uses': 'actions/setup-go@v6', 'with': { 'go-version': '${{ inputs.go-version || \'' + baseGoVersionExpr + '\' }}', # to avoid potentially misleading autobuilder results where we expect it to download @@ -210,6 +211,7 @@ def writeHeader(checkStream): } }, 'name': checkSpecification['name'], + 'if': 'github.triggering_actor != \'dependabot[bot]\'', 'permissions': { 'contents': 'read', 'security-events': 'read' @@ -240,7 +242,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']}", @@ -263,13 +265,29 @@ def writeHeader(checkStream): 'inputs': workflowInputs } }, + 'defaults': { + 'run': { + 'shell': 'bash', + }, + }, + 'concurrency': { + # Cancel in-progress workflows in the same 'group' for pull_request events, + # but not other event types. This should have the effect that workflows on PRs + # get cancelled if there is a newer workflow in the same concurrency group. + # For other events, the new workflows should wait until earlier ones have finished. + # This should help reduce the number of concurrent workflows on the repo, and + # consequently the number of concurrent API requests. + 'cancel-in-progress': "${{ github.event_name == 'pull_request' }}", + # The group is determined by the workflow name + the ref + 'group': "${{ github.workflow }}-${{ github.ref }}" + }, '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) @@ -323,7 +341,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/pr-checks/sync_back.py b/pr-checks/sync_back.py new file mode 100755 index 0000000000..1474b455e6 --- /dev/null +++ b/pr-checks/sync_back.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python3 +""" +Sync-back script to automatically update action versions in source templates +from the generated workflow files after Dependabot updates. + +This script scans the generated workflow files (.github/workflows/__*.yml) to find +all external action versions used, then updates: +1. Hardcoded action versions in pr-checks/sync.py +2. Action version references in template files in pr-checks/checks/ + +The script automatically detects all actions used in generated workflows and +preserves version comments (e.g., # v1.2.3) when syncing versions. + +This ensures that when Dependabot updates action versions in generated workflows, +those changes are properly synced back to the source templates. Regular workflow +files are updated directly by Dependabot and don't need sync-back. +""" + +import os +import re +import glob +import argparse +import sys +from pathlib import Path +from typing import Dict, List + + +def scan_generated_workflows(workflow_dir: str) -> Dict[str, str]: + """ + Scan generated workflow files to extract the latest action versions. + + Args: + workflow_dir: Path to .github/workflows directory + + Returns: + Dictionary mapping action names to their latest versions (including comments) + """ + action_versions = {} + generated_files = glob.glob(os.path.join(workflow_dir, "__*.yml")) + + for file_path in generated_files: + with open(file_path, 'r') as f: + content = f.read() + + # Find all action uses in the file, including potential comments + # This pattern captures: action_name@version_with_possible_comment + pattern = r'uses:\s+([^/\s]+/[^@\s]+)@([^@\n]+)' + matches = re.findall(pattern, content) + + for action_name, version_with_comment in matches: + # Only track non-local actions (those with / but not starting with ./) + if not action_name.startswith('./'): + # Assume that version numbers are consistent (this should be the case on a Dependabot update PR) + action_versions[action_name] = version_with_comment.rstrip() + + return action_versions + + +def update_sync_py(sync_py_path: str, action_versions: Dict[str, str]) -> bool: + """ + Update hardcoded action versions in pr-checks/sync.py + + Args: + sync_py_path: Path to sync.py file + action_versions: Dictionary of action names to versions (may include comments) + + Returns: + True if file was modified, False otherwise + """ + if not os.path.exists(sync_py_path): + raise FileNotFoundError(f"Could not find {sync_py_path}") + + with open(sync_py_path, 'r') as f: + content = f.read() + + original_content = content + + # Update hardcoded action versions + for action_name, version_with_comment in action_versions.items(): + # Extract just the version part (before any comment) for sync.py + version = version_with_comment.split('#')[0].strip() if '#' in version_with_comment else version_with_comment.strip() + + # Look for patterns like 'uses': 'actions/setup-node@v4' + # Note that this will break if we store an Action uses reference in a + # variable - that's a risk we're happy to take since in that case the + # PR checks will just fail. + pattern = rf"('uses':\s*'){re.escape(action_name)}@(?:[^']+)(')" + replacement = rf"\1{action_name}@{version}\2" + content = re.sub(pattern, replacement, content) + + if content != original_content: + with open(sync_py_path, 'w') as f: + f.write(content) + print(f"Updated {sync_py_path}") + return True + else: + print(f"No changes needed in {sync_py_path}") + return False + + +def update_template_files(checks_dir: str, action_versions: Dict[str, str]) -> List[str]: + """ + Update action versions in template files in pr-checks/checks/ + + Args: + checks_dir: Path to pr-checks/checks directory + action_versions: Dictionary of action names to versions (may include comments) + + Returns: + List of files that were modified + """ + modified_files = [] + template_files = glob.glob(os.path.join(checks_dir, "*.yml")) + + for file_path in template_files: + with open(file_path, 'r') as f: + content = f.read() + + original_content = content + + # Update action versions + for action_name, version_with_comment in action_versions.items(): + # Look for patterns like 'uses: actions/setup-node@v4' or 'uses: actions/setup-node@sha # comment' + pattern = rf"(uses:\s+{re.escape(action_name)})@(?:[^@\n]+)" + replacement = rf"\1@{version_with_comment}" + content = re.sub(pattern, replacement, content) + + if content != original_content: + with open(file_path, 'w') as f: + f.write(content) + modified_files.append(file_path) + print(f"Updated {file_path}") + + return modified_files + + +def main(): + parser = argparse.ArgumentParser(description="Sync action versions from generated workflows back to templates") + parser.add_argument("--verbose", "-v", action="store_true", help="Enable verbose output") + args = parser.parse_args() + + # Get the repository root (assuming script is in pr-checks/) + script_dir = Path(__file__).parent + repo_root = script_dir.parent + + workflow_dir = repo_root / ".github" / "workflows" + checks_dir = script_dir / "checks" + sync_py_path = script_dir / "sync.py" + + print("Scanning generated workflows for latest action versions...") + action_versions = scan_generated_workflows(str(workflow_dir)) + + if args.verbose: + print("Found action versions:") + for action, version in action_versions.items(): + print(f" {action}@{version}") + + if not action_versions: + print("No action versions found in generated workflows") + return 1 + + # Update files + print("\nUpdating source files...") + modified_files = [] + + # Update sync.py + if update_sync_py(str(sync_py_path), action_versions): + modified_files.append(str(sync_py_path)) + + # Update template files + template_modified = update_template_files(str(checks_dir), action_versions) + modified_files.extend(template_modified) + + if modified_files: + print(f"\nSync completed. Modified {len(modified_files)} files:") + for file_path in modified_files: + print(f" {file_path}") + else: + print("\nNo files needed updating - all action versions are already in sync") + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/pr-checks/test_sync_back.py b/pr-checks/test_sync_back.py new file mode 100644 index 0000000000..de2e42d733 --- /dev/null +++ b/pr-checks/test_sync_back.py @@ -0,0 +1,237 @@ +#!/usr/bin/env python3 +""" +Tests for the sync_back.py script +""" + +import os +import shutil +import tempfile +import unittest + +import sync_back + + +class TestSyncBack(unittest.TestCase): + + def setUp(self): + """Set up temporary directories and files for testing""" + self.test_dir = tempfile.mkdtemp() + self.workflow_dir = os.path.join(self.test_dir, ".github", "workflows") + self.checks_dir = os.path.join(self.test_dir, "pr-checks", "checks") + os.makedirs(self.workflow_dir) + os.makedirs(self.checks_dir) + + # Create sync.py file + self.sync_py_path = os.path.join(self.test_dir, "pr-checks", "sync.py") + + def tearDown(self): + """Clean up temporary directories""" + shutil.rmtree(self.test_dir) + + def test_scan_generated_workflows_basic(self): + """Test basic workflow scanning functionality""" + # Create a test generated workflow file + workflow_content = """ +name: Test Workflow +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v5 + - uses: actions/setup-go@v6 + """ + + with open(os.path.join(self.workflow_dir, "__test.yml"), 'w') as f: + f.write(workflow_content) + + result = sync_back.scan_generated_workflows(self.workflow_dir) + + self.assertEqual(result['actions/checkout'], 'v4') + self.assertEqual(result['actions/setup-node'], 'v5') + self.assertEqual(result['actions/setup-go'], 'v6') + + def test_scan_generated_workflows_with_comments(self): + """Test scanning workflows with version comments""" + workflow_content = """ +name: Test Workflow +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0 + - uses: actions/setup-python@v6 # Latest Python + """ + + with open(os.path.join(self.workflow_dir, "__test.yml"), 'w') as f: + f.write(workflow_content) + + result = sync_back.scan_generated_workflows(self.workflow_dir) + + self.assertEqual(result['actions/checkout'], 'v4') + self.assertEqual(result['ruby/setup-ruby'], '44511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0') + self.assertEqual(result['actions/setup-python'], 'v6 # Latest Python') + + def test_scan_generated_workflows_ignores_local_actions(self): + """Test that local actions (starting with ./) are ignored""" + workflow_content = """ +name: Test Workflow +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/local-action + - uses: ./another-local-action@v1 + """ + + with open(os.path.join(self.workflow_dir, "__test.yml"), 'w') as f: + f.write(workflow_content) + + result = sync_back.scan_generated_workflows(self.workflow_dir) + + self.assertEqual(result['actions/checkout'], 'v4') + self.assertNotIn('./.github/actions/local-action', result) + self.assertNotIn('./another-local-action', result) + + + def test_update_sync_py(self): + """Test updating sync.py file""" + sync_py_content = """ +steps = [ + { + 'uses': 'actions/setup-node@v4', + 'with': {'node-version': '16'} + }, + { + 'uses': 'actions/setup-go@v5', + 'with': {'go-version': '1.19'} + } +] + """ + + with open(self.sync_py_path, 'w') as f: + f.write(sync_py_content) + + action_versions = { + 'actions/setup-node': 'v5', + 'actions/setup-go': 'v6' + } + + result = sync_back.update_sync_py(self.sync_py_path, action_versions) + self.assertTrue(result) + + with open(self.sync_py_path, 'r') as f: + updated_content = f.read() + + self.assertIn("'uses': 'actions/setup-node@v5'", updated_content) + self.assertIn("'uses': 'actions/setup-go@v6'", updated_content) + + def test_update_sync_py_with_comments(self): + """Test updating sync.py file when versions have comments""" + sync_py_content = """ +steps = [ + { + 'uses': 'actions/setup-node@v4', + 'with': {'node-version': '16'} + } +] + """ + + with open(self.sync_py_path, 'w') as f: + f.write(sync_py_content) + + action_versions = { + 'actions/setup-node': 'v5 # Latest version' + } + + result = sync_back.update_sync_py(self.sync_py_path, action_versions) + self.assertTrue(result) + + with open(self.sync_py_path, 'r') as f: + updated_content = f.read() + + # sync.py should get the version without comment + self.assertIn("'uses': 'actions/setup-node@v5'", updated_content) + self.assertNotIn("# Latest version", updated_content) + + def test_update_template_files(self): + """Test updating template files""" + template_content = """ +name: Test Template +steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v4 + with: + node-version: 16 + """ + + template_path = os.path.join(self.checks_dir, "test.yml") + with open(template_path, 'w') as f: + f.write(template_content) + + action_versions = { + 'actions/checkout': 'v4', + 'actions/setup-node': 'v5 # Latest' + } + + result = sync_back.update_template_files(self.checks_dir, action_versions) + self.assertEqual(len(result), 1) + self.assertIn(template_path, result) + + with open(template_path, 'r') as f: + updated_content = f.read() + + self.assertIn("uses: actions/checkout@v4", updated_content) + self.assertIn("uses: actions/setup-node@v5 # Latest", updated_content) + + def test_update_template_files_preserves_comments(self): + """Test that updating template files preserves version comments""" + template_content = """ +name: Test Template +steps: + - uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb # v1.256.0 + """ + + template_path = os.path.join(self.checks_dir, "test.yml") + with open(template_path, 'w') as f: + f.write(template_content) + + action_versions = { + 'ruby/setup-ruby': '55511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0' + } + + result = sync_back.update_template_files(self.checks_dir, action_versions) + self.assertEqual(len(result), 1) + + with open(template_path, 'r') as f: + updated_content = f.read() + + self.assertIn("uses: ruby/setup-ruby@55511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0", updated_content) + + def test_no_changes_needed(self): + """Test that functions return False/empty when no changes are needed""" + # Test sync.py with no changes needed + sync_py_content = """ +steps = [ + { + 'uses': 'actions/setup-node@v5', + 'with': {'node-version': '16'} + } +] + """ + + with open(self.sync_py_path, 'w') as f: + f.write(sync_py_content) + + action_versions = { + 'actions/setup-node': 'v5' + } + + result = sync_back.update_sync_py(self.sync_py_path, action_versions) + self.assertFalse(result) + + +if __name__ == '__main__': + unittest.main() diff --git a/src/analyze-action.ts b/src/analyze-action.ts index f93072d723..31251be488 100644 --- a/src/analyze-action.ts +++ b/src/analyze-action.ts @@ -29,7 +29,7 @@ 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"; @@ -384,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/api-client.ts b/src/api-client.ts index 207b3c86af..86134b7f89 100644 --- a/src/api-client.ts +++ b/src/api-client.ts @@ -4,7 +4,8 @@ import * as retry from "@octokit/plugin-retry"; import consoleLogLevel from "console-log-level"; import { getActionVersion, getRequiredInput } from "./actions-util"; -import { getRepositoryNwo } from "./repository"; +import { Logger } from "./logging"; +import { getRepositoryNwo, RepositoryNwo } from "./repository"; import { ConfigurationError, getRequiredEnvParam, @@ -54,7 +55,7 @@ function createApiClientWithDetails( ); } -export function getApiDetails() { +export function getApiDetails(): GitHubApiDetails { return { auth: getRequiredInput("token"), url: getRequiredEnvParam("GITHUB_SERVER_URL"), @@ -72,6 +73,36 @@ export function getApiClientWithExternalAuth( return createApiClientWithDetails(apiDetails, { allowExternal: true }); } +/** + * Gets a value for the `Authorization` header for a request to `url`; or `undefined` if the + * `Authorization` header should not be set for `url`. + * + * @param logger The logger to use for debugging messages. + * @param apiDetails Details of the GitHub API we are using. + * @param url The URL for which we want to add an `Authorization` header. + * + * @returns The value for the `Authorization` header or `undefined` if it shouldn't be populated. + */ +export function getAuthorizationHeaderFor( + logger: Logger, + apiDetails: GitHubApiDetails, + url: string, +): string | undefined { + // We only want to provide an authorization header if we are downloading + // from the same GitHub instance the Action is running on. + // This avoids leaking Enterprise tokens to dotcom. + if ( + url.startsWith(`${apiDetails.url}/`) || + (apiDetails.apiURL && url.startsWith(`${apiDetails.apiURL}/`)) + ) { + logger.debug(`Providing an authorization token.`); + return `token ${apiDetails.auth}`; + } + + logger.debug(`Not using an authorization token.`); + return undefined; +} + let cachedGitHubVersion: GitHubVersion | undefined = undefined; export async function getGitHubVersionFromApi( @@ -240,6 +271,14 @@ export async function deleteActionsCache(id: number) { }); } +/** Retrieve all custom repository properties. */ +export async function getRepositoryProperties(repositoryNwo: RepositoryNwo) { + return getApiClient().request("GET /repos/:owner/:repo/properties/values", { + owner: repositoryNwo.owner, + repo: repositoryNwo.repo, + }); +} + export function wrapApiConfigurationError(e: unknown) { if (isHTTPError(e)) { if ( diff --git a/src/codeql.test.ts b/src/codeql.test.ts index 36775f6530..a5422b1e38 100644 --- a/src/codeql.test.ts +++ b/src/codeql.test.ts @@ -496,6 +496,8 @@ const injectedConfigMacro = test.macro({ expectedConfig: any, ) => { await util.withTmpDir(async (tempDir) => { + sinon.stub(actionsUtil, "isDefaultSetup").resolves(false); + const runnerConstructorStub = stubToolRunnerConstructor(); const codeqlObject = await stubCodeql(); @@ -505,6 +507,7 @@ const injectedConfigMacro = test.macro({ tempDir, }; thisStubConfig.computedConfig = generateCodeScanningConfig( + getRunnerLogger(true), thisStubConfig.originalUserInput, augmentationProperties, ); @@ -659,15 +662,15 @@ test( }, { queries: [ - { - uses: "zzz", - }, { uses: "xxx", }, { uses: "yyy", }, + { + uses: "zzz", + }, ], }, ); @@ -713,6 +716,84 @@ test( {}, ); +test( + "repo property queries have the highest precedence", + injectedConfigMacro, + { + ...defaultAugmentationProperties, + queriesInputCombines: true, + queriesInput: [{ uses: "xxx" }, { uses: "yyy" }], + repoPropertyQueries: { + combines: false, + input: [{ uses: "zzz" }, { uses: "aaa" }], + }, + }, + { + originalUserInput: { + queries: [{ uses: "uu" }, { uses: "vv" }], + }, + }, + { + queries: [{ uses: "zzz" }, { uses: "aaa" }], + }, +); + +test( + "repo property queries combines with queries input", + injectedConfigMacro, + { + ...defaultAugmentationProperties, + queriesInputCombines: false, + queriesInput: [{ uses: "xxx" }, { uses: "yyy" }], + repoPropertyQueries: { + combines: true, + input: [{ uses: "zzz" }, { uses: "aaa" }], + }, + }, + { + originalUserInput: { + queries: [{ uses: "uu" }, { uses: "vv" }], + }, + }, + { + queries: [ + { uses: "zzz" }, + { uses: "aaa" }, + { uses: "xxx" }, + { uses: "yyy" }, + ], + }, +); + +test( + "repo property queries combines everything else", + injectedConfigMacro, + { + ...defaultAugmentationProperties, + queriesInputCombines: true, + queriesInput: [{ uses: "xxx" }, { uses: "yyy" }], + repoPropertyQueries: { + combines: true, + input: [{ uses: "zzz" }, { uses: "aaa" }], + }, + }, + { + originalUserInput: { + queries: [{ uses: "uu" }, { uses: "vv" }], + }, + }, + { + queries: [ + { uses: "zzz" }, + { uses: "aaa" }, + { uses: "xxx" }, + { uses: "yyy" }, + { uses: "uu" }, + { uses: "vv" }, + ], + }, +); + test("passes a code scanning config AND qlconfig to the CLI", async (t: ExecutionContext) => { await util.withTmpDir(async (tempDir) => { const runnerConstructorStub = stubToolRunnerConstructor(); diff --git a/src/codeql.ts b/src/codeql.ts index 35c3cc625f..16b105a3df 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -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' */ @@ -736,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); diff --git a/src/config-utils.test.ts b/src/config-utils.test.ts index 3bb9e1e116..566a719ca0 100644 --- a/src/config-utils.test.ts +++ b/src/config-utils.test.ts @@ -12,6 +12,7 @@ import * as api from "./api-client"; import { CachingKind } from "./caching-utils"; import { createStubCodeQL } from "./codeql"; import * as configUtils from "./config-utils"; +import * as errorMessages from "./error-messages"; import { Feature } from "./feature-flags"; import * as gitUtils from "./git-utils"; import { KnownLanguage, Language } from "./languages"; @@ -28,11 +29,11 @@ import { getRecordingLogger, LoggedMessage, mockCodeQLVersion, + createTestConfig, } from "./testing-utils"; import { GitHubVariant, GitHubVersion, - prettyPrintPack, ConfigurationError, withTmpDir, BuildMode, @@ -82,11 +83,11 @@ function createTestInitConfigInputs( externalRepoAuth: "token", url: "https://github.example.com", apiURL: undefined, - registriesAuthTokens: undefined, }, features: createFeatures([]), + repositoryProperties: {}, logger: getRunnerLogger(true), - }, + } satisfies configUtils.InitConfigInputs, overrides, ); } @@ -199,6 +200,7 @@ test("load code quality config", async (t) => { // And the config we expect it to result in const expectedConfig: configUtils.Config = { + version: actionsUtil.getActionVersion(), analysisKinds: [AnalysisKind.CodeQuality], languages: [KnownLanguage.actions], buildMode: undefined, @@ -222,13 +224,71 @@ test("load code quality config", async (t) => { extraQueryExclusions: [], overlayDatabaseMode: OverlayDatabaseMode.None, useOverlayDatabaseCaching: false, + repositoryProperties: {}, }; t.deepEqual(config, expectedConfig); }); }); -test("loading config saves config", async (t) => { +test("initActionState doesn't throw if there are queries configured in the repository properties", async (t) => { + return await withTmpDir(async (tempDir) => { + const logger = getRunnerLogger(true); + const languages = "javascript"; + + const codeql = createStubCodeQL({ + async betterResolveLanguages() { + return { + extractors: { + javascript: [{ extractor_root: "" }], + }, + }; + }, + }); + + // This should be ignored and no error should be thrown. + const repositoryProperties = { + "github-codeql-extra-queries": "+foo", + }; + + // Expected configuration for a CQ-only analysis. + const computedConfig: configUtils.UserConfig = { + "disable-default-queries": true, + queries: [{ uses: "code-quality" }], + "query-filters": [], + }; + + const expectedConfig = createTestConfig({ + analysisKinds: [AnalysisKind.CodeQuality], + languages: [KnownLanguage.javascript], + codeQLCmd: codeql.getPath(), + computedConfig, + dbLocation: path.resolve(tempDir, "codeql_databases"), + debugArtifactName: "", + debugDatabaseName: "", + tempDir, + repositoryProperties, + }); + + await t.notThrowsAsync(async () => { + const config = await configUtils.initConfig( + createTestInitConfigInputs({ + analysisKindsInput: "code-quality", + languagesInput: languages, + repository: { owner: "github", repo: "example" }, + tempDir, + codeql, + repositoryProperties, + logger, + }), + ); + + t.deepEqual(config, expectedConfig); + }); + }); +}); + +test("loading a saved config produces the same config", async (t) => { return await withTmpDir(async (tempDir) => { const logger = getRunnerLogger(true); @@ -258,6 +318,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))); @@ -273,6 +334,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 { @@ -288,7 +400,7 @@ test("load input outside of workspace", async (t) => { t.deepEqual( err, new ConfigurationError( - configUtils.getConfigFileOutsideWorkspaceErrorMessage( + errorMessages.getConfigFileOutsideWorkspaceErrorMessage( path.join(tempDir, "../input"), ), ), @@ -315,7 +427,7 @@ test("load non-local input with invalid repo syntax", async (t) => { t.deepEqual( err, new ConfigurationError( - configUtils.getConfigFileRepoFormatInvalidMessage( + errorMessages.getConfigFileRepoFormatInvalidMessage( "octo-org/codeql-config@main", ), ), @@ -344,7 +456,7 @@ test("load non-existent input", async (t) => { t.deepEqual( err, new ConfigurationError( - configUtils.getConfigFileDoesNotExistErrorMessage( + errorMessages.getConfigFileDoesNotExistErrorMessage( path.join(tempDir, "input"), ), ), @@ -389,6 +501,7 @@ test("load non-empty input", async (t) => { // 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, @@ -407,6 +520,7 @@ test("load non-empty input", async (t) => { extraQueryExclusions: [], overlayDatabaseMode: OverlayDatabaseMode.None, useOverlayDatabaseCaching: false, + repositoryProperties: {}, }; const languagesInput = "javascript"; @@ -550,7 +664,7 @@ test("Remote config handles the case where a directory is provided", async (t) = t.deepEqual( err, new ConfigurationError( - configUtils.getConfigFileDirectoryGivenMessage(repoReference), + errorMessages.getConfigFileDirectoryGivenMessage(repoReference), ), ); } @@ -578,7 +692,7 @@ test("Invalid format of remote config handled correctly", async (t) => { t.deepEqual( err, new ConfigurationError( - configUtils.getConfigFileFormatInvalidMessage(repoReference), + errorMessages.getConfigFileFormatInvalidMessage(repoReference), ), ); } @@ -606,7 +720,7 @@ test("No detected languages", async (t) => { } catch (err) { t.deepEqual( err, - new ConfigurationError(configUtils.getNoLanguagesError()), + new ConfigurationError(errorMessages.getNoLanguagesError()), ); } }); @@ -629,344 +743,15 @@ test("Unknown languages", async (t) => { t.deepEqual( err, new ConfigurationError( - configUtils.getUnknownLanguagesError(["rubbish", "english"]), + errorMessages.getUnknownLanguagesError(["rubbish", "english"]), ), ); } }); }); -/** - * Test macro for ensuring the packs block is valid - */ -const parsePacksMacro = test.macro({ - exec: ( - t: ExecutionContext, - packsInput: string, - languages: Language[], - expected: configUtils.Packs | undefined, - ) => - t.deepEqual( - configUtils.parsePacksFromInput(packsInput, languages, false), - expected, - ), - - title: (providedTitle = "") => `Parse Packs: ${providedTitle}`, -}); - -/** - * Test macro for testing when the packs block is invalid - */ -const parsePacksErrorMacro = test.macro({ - exec: ( - t: ExecutionContext, - packsInput: string, - languages: Language[], - expected: RegExp, - ) => - t.throws( - () => configUtils.parsePacksFromInput(packsInput, languages, false), - { - message: expected, - }, - ), - title: (providedTitle = "") => `Parse Packs Error: ${providedTitle}`, -}); - -/** - * Test macro for testing when the packs block is invalid - */ -const invalidPackNameMacro = test.macro({ - exec: (t: ExecutionContext, name: string) => - parsePacksErrorMacro.exec( - t, - name, - [KnownLanguage.cpp], - new RegExp(`^"${name}" is not a valid pack$`), - ), - title: (_providedTitle: string | undefined, arg: string | undefined) => - `Invalid pack string: ${arg}`, -}); - -test("no packs", parsePacksMacro, "", [], undefined); -test("two packs", parsePacksMacro, "a/b,c/d@1.2.3", [KnownLanguage.cpp], { - [KnownLanguage.cpp]: ["a/b", "c/d@1.2.3"], -}); -test( - "two packs with spaces", - parsePacksMacro, - " a/b , c/d@1.2.3 ", - [KnownLanguage.cpp], - { - [KnownLanguage.cpp]: ["a/b", "c/d@1.2.3"], - }, -); -test( - "two packs with language", - parsePacksErrorMacro, - "a/b,c/d@1.2.3", - [KnownLanguage.cpp, KnownLanguage.java], - new RegExp( - "Cannot specify a 'packs' input in a multi-language analysis. " + - "Use a codeql-config.yml file instead and specify packs by language.", - ), -); - -test( - "packs with other valid names", - parsePacksMacro, - [ - // ranges are ok - "c/d@1.0", - "c/d@~1.0.0", - "c/d@~1.0.0:a/b", - "c/d@~1.0.0+abc:a/b", - "c/d@~1.0.0-abc:a/b", - "c/d:a/b", - // whitespace is removed - " c/d @ ~1.0.0 : b.qls ", - // and it is retained within a path - " c/d @ ~1.0.0 : b/a path with/spaces.qls ", - // this is valid. the path is '@'. It will probably fail when passed to the CLI - "c/d@1.2.3:@", - // this is valid, too. It will fail if it doesn't match a path - // (globbing is not done) - "c/d@1.2.3:+*)_(", - ].join(","), - [KnownLanguage.cpp], - { - [KnownLanguage.cpp]: [ - "c/d@1.0", - "c/d@~1.0.0", - "c/d@~1.0.0:a/b", - "c/d@~1.0.0+abc:a/b", - "c/d@~1.0.0-abc:a/b", - "c/d:a/b", - "c/d@~1.0.0:b.qls", - "c/d@~1.0.0:b/a path with/spaces.qls", - "c/d@1.2.3:@", - "c/d@1.2.3:+*)_(", - ], - }, -); - -test(invalidPackNameMacro, "c"); // all packs require at least a scope and a name -test(invalidPackNameMacro, "c-/d"); -test(invalidPackNameMacro, "-c/d"); -test(invalidPackNameMacro, "c/d_d"); -test(invalidPackNameMacro, "c/d@@"); -test(invalidPackNameMacro, "c/d@1.0.0:"); -test(invalidPackNameMacro, "c/d:"); -test(invalidPackNameMacro, "c/d:/a"); -test(invalidPackNameMacro, "@1.0.0:a"); -test(invalidPackNameMacro, "c/d@../a"); -test(invalidPackNameMacro, "c/d@b/../a"); -test(invalidPackNameMacro, "c/d:z@1"); - -/** - * Test macro for pretty printing pack specs - */ -const packSpecPrettyPrintingMacro = test.macro({ - exec: (t: ExecutionContext, packStr: string, packObj: configUtils.Pack) => { - const parsed = configUtils.parsePacksSpecification(packStr); - t.deepEqual(parsed, packObj, "parsed pack spec is correct"); - const stringified = prettyPrintPack(packObj); - t.deepEqual( - stringified, - packStr.trim(), - "pretty-printed pack spec is correct", - ); - - t.deepEqual( - configUtils.validatePackSpecification(packStr), - packStr.trim(), - "pack spec is valid", - ); - }, - title: ( - _providedTitle: string | undefined, - packStr: string, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - _packObj: configUtils.Pack, - ) => `Prettyprint pack spec: '${packStr}'`, -}); - -test(packSpecPrettyPrintingMacro, "a/b", { - name: "a/b", - version: undefined, - path: undefined, -}); -test(packSpecPrettyPrintingMacro, "a/b@~1.2.3", { - name: "a/b", - version: "~1.2.3", - path: undefined, -}); -test(packSpecPrettyPrintingMacro, "a/b@~1.2.3:abc/def", { - name: "a/b", - version: "~1.2.3", - path: "abc/def", -}); -test(packSpecPrettyPrintingMacro, "a/b:abc/def", { - name: "a/b", - version: undefined, - path: "abc/def", -}); -test(packSpecPrettyPrintingMacro, " a/b:abc/def ", { - name: "a/b", - version: undefined, - path: "abc/def", -}); - const mockLogger = getRunnerLogger(true); -const calculateAugmentationMacro = test.macro({ - exec: async ( - t: ExecutionContext, - _title: string, - rawPacksInput: string | undefined, - rawQueriesInput: string | undefined, - languages: Language[], - expectedAugmentationProperties: configUtils.AugmentationProperties, - ) => { - const actualAugmentationProperties = - await configUtils.calculateAugmentation( - rawPacksInput, - rawQueriesInput, - languages, - ); - t.deepEqual(actualAugmentationProperties, expectedAugmentationProperties); - }, - title: (_, title) => `Calculate Augmentation: ${title}`, -}); - -test( - calculateAugmentationMacro, - "All empty", - undefined, - undefined, - [KnownLanguage.javascript], - { - ...configUtils.defaultAugmentationProperties, - }, -); - -test( - calculateAugmentationMacro, - "With queries", - undefined, - " a, b , c, d", - [KnownLanguage.javascript], - { - ...configUtils.defaultAugmentationProperties, - queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }], - }, -); - -test( - calculateAugmentationMacro, - "With queries combining", - undefined, - " + a, b , c, d ", - [KnownLanguage.javascript], - { - ...configUtils.defaultAugmentationProperties, - queriesInputCombines: true, - queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }], - }, -); - -test( - calculateAugmentationMacro, - "With packs", - " codeql/a , codeql/b , codeql/c , codeql/d ", - undefined, - [KnownLanguage.javascript], - { - ...configUtils.defaultAugmentationProperties, - packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"], - }, -); - -test( - calculateAugmentationMacro, - "With packs combining", - " + codeql/a, codeql/b, codeql/c, codeql/d", - undefined, - [KnownLanguage.javascript], - { - ...configUtils.defaultAugmentationProperties, - packsInputCombines: true, - packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"], - }, -); - -const calculateAugmentationErrorMacro = test.macro({ - exec: async ( - t: ExecutionContext, - _title: string, - rawPacksInput: string | undefined, - rawQueriesInput: string | undefined, - languages: Language[], - expectedError: RegExp | string, - ) => { - await t.throwsAsync( - () => - configUtils.calculateAugmentation( - rawPacksInput, - rawQueriesInput, - languages, - ), - { message: expectedError }, - ); - }, - title: (_, title) => `Calculate Augmentation Error: ${title}`, -}); - -test( - calculateAugmentationErrorMacro, - "Plus (+) with nothing else (queries)", - undefined, - " + ", - [KnownLanguage.javascript], - /The workflow property "queries" is invalid/, -); - -test( - calculateAugmentationErrorMacro, - "Plus (+) with nothing else (packs)", - " + ", - undefined, - [KnownLanguage.javascript], - /The workflow property "packs" is invalid/, -); - -test( - calculateAugmentationErrorMacro, - "Packs input with multiple languages", - " + a/b, c/d ", - undefined, - [KnownLanguage.javascript, KnownLanguage.java], - /Cannot specify a 'packs' input in a multi-language analysis/, -); - -test( - calculateAugmentationErrorMacro, - "Packs input with no languages", - " + a/b, c/d ", - undefined, - [], - /No languages specified/, -); - -test( - calculateAugmentationErrorMacro, - "Invalid packs", - " a-pack-without-a-scope ", - undefined, - [KnownLanguage.javascript], - /"a-pack-without-a-scope" is not a valid pack/, -); - test("no generateRegistries when registries is undefined", async (t) => { return await withTmpDir(async (tmpDir) => { const registriesInput = undefined; @@ -1038,26 +823,33 @@ const mockRepositoryNwo = parseRepositoryNwo("owner/repo"); expectedLanguages: ["javascript", "csharp", "cpp"], expectedApiCall: true, }, + { + name: "unsupported languages from github api", + languagesInput: "", + languagesInRepository: ["html"], + expectedApiCall: true, + expectedError: errorMessages.getNoLanguagesError(), + }, { name: "no languages", languagesInput: "", languagesInRepository: [], expectedApiCall: true, - expectedError: configUtils.getNoLanguagesError(), + expectedError: errorMessages.getNoLanguagesError(), }, { name: "unrecognized languages from input", languagesInput: "a, b, c, javascript", languagesInRepository: [], expectedApiCall: false, - expectedError: configUtils.getUnknownLanguagesError(["a", "b"]), + expectedError: errorMessages.getUnknownLanguagesError(["a", "b"]), }, { name: "extractors that aren't languages aren't included (specified)", languagesInput: "html", languagesInRepository: [], expectedApiCall: false, - expectedError: configUtils.getUnknownLanguagesError(["html"]), + expectedError: errorMessages.getUnknownLanguagesError(["html"]), }, { name: "extractors that aren't languages aren't included (autodetected)", @@ -1067,57 +859,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 [ diff --git a/src/config-utils.ts b/src/config-utils.ts index 92d36920c8..fe4b392ab2 100644 --- a/src/config-utils.ts +++ b/src/config-utils.ts @@ -3,9 +3,8 @@ import * as path from "path"; import { performance } from "perf_hooks"; import * as yaml from "js-yaml"; -import * as semver from "semver"; -import { isAnalyzingPullRequest } from "./actions-util"; +import { getActionVersion, isAnalyzingPullRequest } from "./actions-util"; import { AnalysisConfig, AnalysisKind, @@ -17,8 +16,16 @@ import { import * as api from "./api-client"; import { CachingKind, getCachingKind } from "./caching-utils"; import { type CodeQL } from "./codeql"; +import { + calculateAugmentation, + ExcludeQueryFilter, + generateCodeScanningConfig, + UserConfig, +} from "./config/db-config"; import { shouldPerformDiffInformedAnalysis } from "./diff-informed-analysis-utils"; +import * as errorMessages from "./error-messages"; import { Feature, FeatureEnablement } from "./feature-flags"; +import { RepositoryProperties } from "./feature-flags/properties"; import { getGitRoot, isAnalyzingDefaultBranch } from "./git-utils"; import { KnownLanguage, Language } from "./languages"; import { Logger } from "./logging"; @@ -30,7 +37,6 @@ import { RepositoryNwo } from "./repository"; import { downloadTrapCaches } from "./trap-caching"; import { GitHubVersion, - prettyPrintPack, ConfigurationError, BuildMode, codeQlVersionAtLeast, @@ -38,34 +44,7 @@ import { isDefined, } from "./util"; -// Property names from the user-supplied config file. - -const PACKS_PROPERTY = "packs"; - -/** - * Format of the config file supplied by the user. - */ -export interface UserConfig { - name?: string; - "disable-default-queries"?: boolean; - queries?: Array<{ - name?: string; - uses: string; - }>; - "paths-ignore"?: string[]; - paths?: string[]; - - // If this is a multi-language analysis, then the packages must be split by - // language. If this is a single language analysis, then no split by - // language is necessary. - packs?: Record | string[]; - - // Set of query filters to include and exclude extra queries based on - // codeql query suite `include` and `exclude` properties - "query-filters"?: QueryFilter[]; -} - -export type QueryFilter = ExcludeQueryFilter | IncludeQueryFilter; +export * from "./config/db-config"; export type RegistryConfigWithCredentials = RegistryConfigNoCredentials & { // Token to use when downloading packs from this registry. @@ -90,18 +69,14 @@ export interface RegistryConfigNoCredentials { kind?: "github" | "docker"; } -interface ExcludeQueryFilter { - exclude: Record; -} - -interface IncludeQueryFilter { - include: Record; -} - /** * 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. */ @@ -193,135 +168,40 @@ export interface Config { * `OverlayBase`. */ useOverlayDatabaseCaching: boolean; -} - -/** - * Describes how to augment the user config with inputs from the action. - * - * When running a CodeQL analysis, the user can supply a config file. When - * running a CodeQL analysis from a GitHub action, the user can supply a - * config file _and_ a set of inputs. - * - * The inputs from the action are used to augment the user config before - * passing the user config to the CodeQL CLI invocation. - */ -export interface AugmentationProperties { - /** - * Whether or not the queries input combines with the queries in the config. - */ - queriesInputCombines: boolean; - - /** - * The queries input from the `with` block of the action declaration - */ - queriesInput?: Array<{ uses: string }>; /** - * Whether or not the packs input combines with the packs in the config. + * A partial mapping from repository properties that affect us to their values. */ - packsInputCombines: boolean; - - /** - * The packs input from the `with` block of the action declaration - */ - packsInput?: string[]; -} - -/** - * The default, empty augmentation properties. This is most useful - * for tests. - */ -export const defaultAugmentationProperties: AugmentationProperties = { - queriesInputCombines: false, - packsInputCombines: false, - packsInput: undefined, - queriesInput: undefined, -}; -export type Packs = Partial>; - -export interface Pack { - name: string; - version?: string; - path?: string; -} - -export function getPacksStrInvalid( - packStr: string, - configFile?: string, -): string { - return configFile - ? getConfigFilePropertyError( - configFile, - PACKS_PROPERTY, - `"${packStr}" is not a valid pack`, - ) - : `"${packStr}" is not a valid pack`; -} - -export function getConfigFileOutsideWorkspaceErrorMessage( - configFile: string, -): string { - return `The configuration file "${configFile}" is outside of the workspace`; -} - -export function getConfigFileDoesNotExistErrorMessage( - configFile: string, -): string { - return `The configuration file "${configFile}" does not exist`; -} - -export function getConfigFileRepoFormatInvalidMessage( - configFile: string, -): string { - let error = `The configuration file "${configFile}" is not a supported remote file reference.`; - error += " Expected format //@"; - - return error; -} - -export function getConfigFileFormatInvalidMessage(configFile: string): string { - return `The configuration file "${configFile}" could not be read`; -} - -export function getConfigFileDirectoryGivenMessage(configFile: string): string { - return `The configuration file "${configFile}" looks like a directory, not a file`; -} - -function getConfigFilePropertyError( - configFile: string | undefined, - property: string, - error: string, -): string { - if (configFile === undefined) { - return `The workflow property "${property}" is invalid: ${error}`; - } else { - return `The configuration file "${configFile}" is invalid: property "${property}" ${error}`; - } -} - -export function getNoLanguagesError(): string { - return ( - "Did not detect any languages to analyze. " + - "Please update input in workflow or check that GitHub detects the correct languages in your repository." - ); -} - -export function getUnknownLanguagesError(languages: string[]): string { - return `Did not recognize the following languages: ${languages.join(", ")}`; + repositoryProperties: RepositoryProperties; } 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; } } @@ -403,6 +283,7 @@ export async function getLanguages( languagesInput: string | undefined, repository: RepositoryNwo, sourceRoot: string, + features: FeatureEnablement, logger: Logger, ): Promise { // Obtain languages without filtering them. @@ -413,7 +294,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[] = []; @@ -430,13 +311,15 @@ export async function getLanguages( const languages = Array.from(languagesSet); if (!autodetected && unknownLanguages.length > 0) { - throw new ConfigurationError(getUnknownLanguagesError(unknownLanguages)); + throw new ConfigurationError( + errorMessages.getUnknownLanguagesError(unknownLanguages), + ); } // If the languages parameter was not given and no languages were // detected then fail here as this is a workflow configuration error. if (languages.length === 0) { - throw new ConfigurationError(getNoLanguagesError()); + throw new ConfigurationError(errorMessages.getNoLanguagesError()); } if (autodetected) { @@ -512,6 +395,7 @@ export interface InitConfigInputs { githubVersion: GitHubVersion; apiDetails: api.GitHubApiCombinedDetails; features: FeatureEnablement; + repositoryProperties: RepositoryProperties; logger: Logger; } @@ -539,6 +423,7 @@ export async function initActionState( sourceRoot, githubVersion, features, + repositoryProperties, logger, }: InitConfigInputs, userConfig: UserConfig, @@ -560,6 +445,7 @@ export async function initActionState( languagesInput, repository, sourceRoot, + features, logger, ); @@ -573,9 +459,28 @@ export async function initActionState( const augmentationProperties = await calculateAugmentation( packsInput, queriesInput, + repositoryProperties, languages, ); + // If `code-quality` is the only enabled analysis kind, we don't support query customisation. + // It would be a problem if queries that are configured in repository properties cause `code-quality`-only + // analyses to break. We therefore ignore query customisations that are configured in repository properties + // if `code-quality` is the only enabled analysis kind. + if ( + analysisKinds.length === 1 && + analysisKinds.includes(AnalysisKind.CodeQuality) && + augmentationProperties.repoPropertyQueries.input + ) { + logger.info( + `Ignoring queries configured in the repository properties, because query customisations are not supported for Code Quality analyses.`, + ); + augmentationProperties.repoPropertyQueries = { + combines: false, + input: undefined, + }; + } + const { trapCaches, trapCacheDownloadTime } = await downloadCacheWithTime( trapCachingEnabled, codeql, @@ -586,11 +491,13 @@ export async function initActionState( // 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( + logger, userConfig, augmentationProperties, ); return { + version: getActionVersion(), analysisKinds, languages, buildMode, @@ -609,6 +516,7 @@ export async function initActionState( extraQueryExclusions: [], overlayDatabaseMode: OverlayDatabaseMode.None, useOverlayDatabaseCaching: false, + repositoryProperties, }; } @@ -644,7 +552,7 @@ async function loadUserConfig( // Error if the config file is now outside of the workspace if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) { throw new ConfigurationError( - getConfigFileOutsideWorkspaceErrorMessage(configFile), + errorMessages.getConfigFileOutsideWorkspaceErrorMessage(configFile), ); } } @@ -654,73 +562,6 @@ async function loadUserConfig( } } -/** - * Calculates how the codeql config file needs to be augmented before passing - * it to the CLI. The reason this is necessary is the codeql-action can be called - * with extra inputs from the workflow. These inputs are not part of the config - * and the CLI does not know about these inputs so we need to inject them into - * the config file sent to the CLI. - * - * @param rawPacksInput The packs input from the action configuration. - * @param rawQueriesInput The queries input from the action configuration. - * @param languages The languages that the config file is for. If the packs input - * is non-empty, then there must be exactly one language. Otherwise, an - * error is thrown. - * - * @returns The properties that need to be augmented in the config file. - * - * @throws An error if the packs input is non-empty and the languages input does - * not have exactly one language. - */ -// exported for testing. -export async function calculateAugmentation( - rawPacksInput: string | undefined, - rawQueriesInput: string | undefined, - languages: Language[], -): Promise { - const packsInputCombines = shouldCombine(rawPacksInput); - const packsInput = parsePacksFromInput( - rawPacksInput, - languages, - packsInputCombines, - ); - const queriesInputCombines = shouldCombine(rawQueriesInput); - const queriesInput = parseQueriesFromInput( - rawQueriesInput, - queriesInputCombines, - ); - - return { - packsInputCombines, - packsInput: packsInput?.[languages[0]], - queriesInput, - queriesInputCombines, - }; -} - -function parseQueriesFromInput( - rawQueriesInput: string | undefined, - queriesInputCombines: boolean, -) { - if (!rawQueriesInput) { - return undefined; - } - - const trimmedInput = queriesInputCombines - ? rawQueriesInput.trim().slice(1).trim() - : (rawQueriesInput?.trim() ?? ""); - if (queriesInputCombines && trimmedInput.length === 0) { - throw new ConfigurationError( - getConfigFilePropertyError( - undefined, - "queries", - "A '+' was used in the 'queries' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs.", - ), - ); - } - return trimmedInput.split(",").map((query) => ({ uses: query.trim() })); -} - const OVERLAY_ANALYSIS_FEATURES: Record = { actions: Feature.OverlayAnalysisActions, cpp: Feature.OverlayAnalysisCpp, @@ -916,161 +757,6 @@ export async function getOverlayDatabaseMode( }; } -/** - * Pack names must be in the form of `scope/name`, with only alpha-numeric characters, - * and `-` allowed as long as not the first or last char. - **/ -const PACK_IDENTIFIER_PATTERN = (function () { - const alphaNumeric = "[a-z0-9]"; - const alphaNumericDash = "[a-z0-9-]"; - const component = `${alphaNumeric}(${alphaNumericDash}*${alphaNumeric})?`; - return new RegExp(`^${component}/${component}$`); -})(); - -// Exported for testing -export function parsePacksFromInput( - rawPacksInput: string | undefined, - languages: Language[], - packsInputCombines: boolean, -): Packs | undefined { - if (!rawPacksInput?.trim()) { - return undefined; - } - - if (languages.length > 1) { - throw new ConfigurationError( - "Cannot specify a 'packs' input in a multi-language analysis. Use a codeql-config.yml file instead and specify packs by language.", - ); - } else if (languages.length === 0) { - throw new ConfigurationError( - "No languages specified. Cannot process the packs input.", - ); - } - - rawPacksInput = rawPacksInput.trim(); - if (packsInputCombines) { - rawPacksInput = rawPacksInput.trim().substring(1).trim(); - if (!rawPacksInput) { - throw new ConfigurationError( - getConfigFilePropertyError( - undefined, - "packs", - "A '+' was used in the 'packs' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs.", - ), - ); - } - } - - return { - [languages[0]]: rawPacksInput.split(",").reduce((packs, pack) => { - packs.push(validatePackSpecification(pack)); - return packs; - }, [] as string[]), - }; -} - -/** - * Validates that this package specification is syntactically correct. - * It may not point to any real package, but after this function returns - * without throwing, we are guaranteed that the package specification - * is roughly correct. - * - * The CLI itself will do a more thorough validation of the package - * specification. - * - * A package specification looks like this: - * - * `scope/name@version:path` - * - * Version and path are optional. - * - * @param packStr the package specification to verify. - * @param configFile Config file to use for error reporting - */ -export function parsePacksSpecification(packStr: string): Pack { - if (typeof packStr !== "string") { - throw new ConfigurationError(getPacksStrInvalid(packStr)); - } - - packStr = packStr.trim(); - const atIndex = packStr.indexOf("@"); - const colonIndex = packStr.indexOf(":", atIndex); - const packStart = 0; - const versionStart = atIndex + 1 || undefined; - const pathStart = colonIndex + 1 || undefined; - const packEnd = Math.min( - atIndex > 0 ? atIndex : Infinity, - colonIndex > 0 ? colonIndex : Infinity, - packStr.length, - ); - const versionEnd = versionStart - ? Math.min(colonIndex > 0 ? colonIndex : Infinity, packStr.length) - : undefined; - const pathEnd = pathStart ? packStr.length : undefined; - - const packName = packStr.slice(packStart, packEnd).trim(); - const version = versionStart - ? packStr.slice(versionStart, versionEnd).trim() - : undefined; - const packPath = pathStart - ? packStr.slice(pathStart, pathEnd).trim() - : undefined; - - if (!PACK_IDENTIFIER_PATTERN.test(packName)) { - throw new ConfigurationError(getPacksStrInvalid(packStr)); - } - if (version) { - try { - new semver.Range(version); - } catch { - // The range string is invalid. OK to ignore the caught error - throw new ConfigurationError(getPacksStrInvalid(packStr)); - } - } - - if ( - packPath && - (path.isAbsolute(packPath) || - // Permit using "/" instead of "\" on Windows - // Use `x.split(y).join(z)` as a polyfill for `x.replaceAll(y, z)` since - // if we used a regex we'd need to escape the path separator on Windows - // which seems more awkward. - path.normalize(packPath).split(path.sep).join("/") !== - packPath.split(path.sep).join("/")) - ) { - throw new ConfigurationError(getPacksStrInvalid(packStr)); - } - - if (!packPath && pathStart) { - // 0 length path - throw new ConfigurationError(getPacksStrInvalid(packStr)); - } - - return { - name: packName, - version, - path: packPath, - }; -} - -export function validatePackSpecification(pack: string) { - return prettyPrintPack(parsePacksSpecification(pack)); -} - -/** - * The convention in this action is that an input value that is prefixed with a '+' will - * be combined with the corresponding value in the config file. - * - * Without a '+', an input value will override the corresponding value in the config file. - * - * @param inputValue The input value to process. - * @returns true if the input value should replace the corresponding value in the config file, - * false if it should be appended. - */ -function shouldCombine(inputValue?: string): boolean { - return !!inputValue?.trim().startsWith("+"); -} - function dbLocationOrDefault( dbLocation: string | undefined, tempDir: string, @@ -1184,9 +870,6 @@ export async function initConfig(inputs: InitConfigInputs): Promise { exclude: { tags: "exclude-from-incremental" }, }); } - - // Save the config so we can easily access it again in the future - await saveConfig(config, logger); return config; } @@ -1226,7 +909,7 @@ function getLocalConfig(configFile: string): UserConfig { // Error if the file does not exist if (!fs.existsSync(configFile)) { throw new ConfigurationError( - getConfigFileDoesNotExistErrorMessage(configFile), + errorMessages.getConfigFileDoesNotExistErrorMessage(configFile), ); } @@ -1245,7 +928,7 @@ async function getRemoteConfig( // 5 = 4 groups + the whole expression if (pieces === null || pieces.groups === undefined || pieces.length < 5) { throw new ConfigurationError( - getConfigFileRepoFormatInvalidMessage(configFile), + errorMessages.getConfigFileRepoFormatInvalidMessage(configFile), ); } @@ -1263,10 +946,12 @@ async function getRemoteConfig( fileContents = response.data.content; } else if (Array.isArray(response.data)) { throw new ConfigurationError( - getConfigFileDirectoryGivenMessage(configFile), + errorMessages.getConfigFileDirectoryGivenMessage(configFile), ); } else { - throw new ConfigurationError(getConfigFileFormatInvalidMessage(configFile)); + throw new ConfigurationError( + errorMessages.getConfigFileFormatInvalidMessage(configFile), + ); } return yaml.load( @@ -1284,7 +969,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 }); @@ -1308,7 +993,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; } /** @@ -1463,56 +1162,6 @@ export async function parseBuildModeInput( return input as BuildMode; } -export function generateCodeScanningConfig( - originalUserInput: UserConfig, - augmentationProperties: AugmentationProperties, -): UserConfig { - // make a copy so we can modify it - const augmentedConfig = cloneObject(originalUserInput); - - // Inject the queries from the input - 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; - } - - // Inject the packs from the input - if (augmentationProperties.packsInput) { - if (augmentationProperties.packsInputCombines) { - // At this point, we already know that this is a single-language analysis - if (Array.isArray(augmentedConfig.packs)) { - augmentedConfig.packs = (augmentedConfig.packs || []).concat( - augmentationProperties.packsInput, - ); - } else if (!augmentedConfig.packs) { - augmentedConfig.packs = augmentationProperties.packsInput; - } else { - // At this point, we know there is only one language. - // If there were more than one language, an error would already have been thrown. - const language = Object.keys(augmentedConfig.packs)[0]; - augmentedConfig.packs[language] = augmentedConfig.packs[ - language - ].concat(augmentationProperties.packsInput); - } - } else { - augmentedConfig.packs = augmentationProperties.packsInput; - } - } - if (Array.isArray(augmentedConfig.packs) && !augmentedConfig.packs.length) { - delete augmentedConfig.packs; - } - - return augmentedConfig; -} - /** * Appends `extraQueryExclusions` to `cliConfig`'s `query-filters`. * diff --git a/src/config/db-config.test.ts b/src/config/db-config.test.ts new file mode 100644 index 0000000000..b22503475d --- /dev/null +++ b/src/config/db-config.test.ts @@ -0,0 +1,394 @@ +import test, { ExecutionContext } from "ava"; + +import { RepositoryProperties } from "../feature-flags/properties"; +import { KnownLanguage, Language } from "../languages"; +import { prettyPrintPack } from "../util"; + +import * as dbConfig from "./db-config"; + +/** + * Test macro for ensuring the packs block is valid + */ +const parsePacksMacro = test.macro({ + exec: ( + t: ExecutionContext, + packsInput: string, + languages: Language[], + expected: dbConfig.Packs | undefined, + ) => + t.deepEqual( + dbConfig.parsePacksFromInput(packsInput, languages, false), + expected, + ), + + title: (providedTitle = "") => `Parse Packs: ${providedTitle}`, +}); + +/** + * Test macro for testing when the packs block is invalid + */ +const parsePacksErrorMacro = test.macro({ + exec: ( + t: ExecutionContext, + packsInput: string, + languages: Language[], + expected: RegExp, + ) => + t.throws(() => dbConfig.parsePacksFromInput(packsInput, languages, false), { + message: expected, + }), + title: (providedTitle = "") => `Parse Packs Error: ${providedTitle}`, +}); + +/** + * Test macro for testing when the packs block is invalid + */ +const invalidPackNameMacro = test.macro({ + exec: (t: ExecutionContext, name: string) => + parsePacksErrorMacro.exec( + t, + name, + [KnownLanguage.cpp], + new RegExp(`^"${name}" is not a valid pack$`), + ), + title: (_providedTitle: string | undefined, arg: string | undefined) => + `Invalid pack string: ${arg}`, +}); + +test("no packs", parsePacksMacro, "", [], undefined); +test("two packs", parsePacksMacro, "a/b,c/d@1.2.3", [KnownLanguage.cpp], { + [KnownLanguage.cpp]: ["a/b", "c/d@1.2.3"], +}); +test( + "two packs with spaces", + parsePacksMacro, + " a/b , c/d@1.2.3 ", + [KnownLanguage.cpp], + { + [KnownLanguage.cpp]: ["a/b", "c/d@1.2.3"], + }, +); +test( + "two packs with language", + parsePacksErrorMacro, + "a/b,c/d@1.2.3", + [KnownLanguage.cpp, KnownLanguage.java], + new RegExp( + "Cannot specify a 'packs' input in a multi-language analysis. " + + "Use a codeql-config.yml file instead and specify packs by language.", + ), +); + +test( + "packs with other valid names", + parsePacksMacro, + [ + // ranges are ok + "c/d@1.0", + "c/d@~1.0.0", + "c/d@~1.0.0:a/b", + "c/d@~1.0.0+abc:a/b", + "c/d@~1.0.0-abc:a/b", + "c/d:a/b", + // whitespace is removed + " c/d @ ~1.0.0 : b.qls ", + // and it is retained within a path + " c/d @ ~1.0.0 : b/a path with/spaces.qls ", + // this is valid. the path is '@'. It will probably fail when passed to the CLI + "c/d@1.2.3:@", + // this is valid, too. It will fail if it doesn't match a path + // (globbing is not done) + "c/d@1.2.3:+*)_(", + ].join(","), + [KnownLanguage.cpp], + { + [KnownLanguage.cpp]: [ + "c/d@1.0", + "c/d@~1.0.0", + "c/d@~1.0.0:a/b", + "c/d@~1.0.0+abc:a/b", + "c/d@~1.0.0-abc:a/b", + "c/d:a/b", + "c/d@~1.0.0:b.qls", + "c/d@~1.0.0:b/a path with/spaces.qls", + "c/d@1.2.3:@", + "c/d@1.2.3:+*)_(", + ], + }, +); + +test(invalidPackNameMacro, "c"); // all packs require at least a scope and a name +test(invalidPackNameMacro, "c-/d"); +test(invalidPackNameMacro, "-c/d"); +test(invalidPackNameMacro, "c/d_d"); +test(invalidPackNameMacro, "c/d@@"); +test(invalidPackNameMacro, "c/d@1.0.0:"); +test(invalidPackNameMacro, "c/d:"); +test(invalidPackNameMacro, "c/d:/a"); +test(invalidPackNameMacro, "@1.0.0:a"); +test(invalidPackNameMacro, "c/d@../a"); +test(invalidPackNameMacro, "c/d@b/../a"); +test(invalidPackNameMacro, "c/d:z@1"); + +/** + * Test macro for pretty printing pack specs + */ +const packSpecPrettyPrintingMacro = test.macro({ + exec: (t: ExecutionContext, packStr: string, packObj: dbConfig.Pack) => { + const parsed = dbConfig.parsePacksSpecification(packStr); + t.deepEqual(parsed, packObj, "parsed pack spec is correct"); + const stringified = prettyPrintPack(packObj); + t.deepEqual( + stringified, + packStr.trim(), + "pretty-printed pack spec is correct", + ); + + t.deepEqual( + dbConfig.validatePackSpecification(packStr), + packStr.trim(), + "pack spec is valid", + ); + }, + title: ( + _providedTitle: string | undefined, + packStr: string, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _packObj: dbConfig.Pack, + ) => `Prettyprint pack spec: '${packStr}'`, +}); + +test(packSpecPrettyPrintingMacro, "a/b", { + name: "a/b", + version: undefined, + path: undefined, +}); +test(packSpecPrettyPrintingMacro, "a/b@~1.2.3", { + name: "a/b", + version: "~1.2.3", + path: undefined, +}); +test(packSpecPrettyPrintingMacro, "a/b@~1.2.3:abc/def", { + name: "a/b", + version: "~1.2.3", + path: "abc/def", +}); +test(packSpecPrettyPrintingMacro, "a/b:abc/def", { + name: "a/b", + version: undefined, + path: "abc/def", +}); +test(packSpecPrettyPrintingMacro, " a/b:abc/def ", { + name: "a/b", + version: undefined, + path: "abc/def", +}); + +const calculateAugmentationMacro = test.macro({ + exec: async ( + t: ExecutionContext, + _title: string, + rawPacksInput: string | undefined, + rawQueriesInput: string | undefined, + languages: Language[], + repositoryProperties: RepositoryProperties, + expectedAugmentationProperties: dbConfig.AugmentationProperties, + ) => { + const actualAugmentationProperties = await dbConfig.calculateAugmentation( + rawPacksInput, + rawQueriesInput, + repositoryProperties, + languages, + ); + t.deepEqual(actualAugmentationProperties, expectedAugmentationProperties); + }, + title: (_, title) => `Calculate Augmentation: ${title}`, +}); + +test( + calculateAugmentationMacro, + "All empty", + undefined, + undefined, + [KnownLanguage.javascript], + {}, + { + ...dbConfig.defaultAugmentationProperties, + }, +); + +test( + calculateAugmentationMacro, + "With queries", + undefined, + " a, b , c, d", + [KnownLanguage.javascript], + {}, + { + ...dbConfig.defaultAugmentationProperties, + queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }], + }, +); + +test( + calculateAugmentationMacro, + "With queries combining", + undefined, + " + a, b , c, d ", + [KnownLanguage.javascript], + {}, + { + ...dbConfig.defaultAugmentationProperties, + queriesInputCombines: true, + queriesInput: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }], + }, +); + +test( + calculateAugmentationMacro, + "With packs", + " codeql/a , codeql/b , codeql/c , codeql/d ", + undefined, + [KnownLanguage.javascript], + {}, + { + ...dbConfig.defaultAugmentationProperties, + packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"], + }, +); + +test( + calculateAugmentationMacro, + "With packs combining", + " + codeql/a, codeql/b, codeql/c, codeql/d", + undefined, + [KnownLanguage.javascript], + {}, + { + ...dbConfig.defaultAugmentationProperties, + packsInputCombines: true, + packsInput: ["codeql/a", "codeql/b", "codeql/c", "codeql/d"], + }, +); + +test( + calculateAugmentationMacro, + "With repo property queries", + undefined, + undefined, + [KnownLanguage.javascript], + { + "github-codeql-extra-queries": "a, b, c, d", + }, + { + ...dbConfig.defaultAugmentationProperties, + repoPropertyQueries: { + combines: false, + input: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }], + }, + }, +); + +test( + calculateAugmentationMacro, + "With repo property queries combining", + undefined, + undefined, + [KnownLanguage.javascript], + { + "github-codeql-extra-queries": "+ a, b, c, d", + }, + { + ...dbConfig.defaultAugmentationProperties, + repoPropertyQueries: { + combines: true, + input: [{ uses: "a" }, { uses: "b" }, { uses: "c" }, { uses: "d" }], + }, + }, +); + +const calculateAugmentationErrorMacro = test.macro({ + exec: async ( + t: ExecutionContext, + _title: string, + rawPacksInput: string | undefined, + rawQueriesInput: string | undefined, + languages: Language[], + repositoryProperties: RepositoryProperties, + expectedError: RegExp | string, + ) => { + await t.throwsAsync( + () => + dbConfig.calculateAugmentation( + rawPacksInput, + rawQueriesInput, + repositoryProperties, + languages, + ), + { message: expectedError }, + ); + }, + title: (_, title) => `Calculate Augmentation Error: ${title}`, +}); + +test( + calculateAugmentationErrorMacro, + "Plus (+) with nothing else (queries)", + undefined, + " + ", + [KnownLanguage.javascript], + {}, + /The workflow property "queries" is invalid/, +); + +test( + calculateAugmentationErrorMacro, + "Plus (+) with nothing else (packs)", + " + ", + undefined, + [KnownLanguage.javascript], + {}, + /The workflow property "packs" is invalid/, +); + +test( + calculateAugmentationErrorMacro, + "Plus (+) with nothing else (repo property queries)", + undefined, + undefined, + [KnownLanguage.javascript], + { + "github-codeql-extra-queries": " + ", + }, + /The repository property "github-codeql-extra-queries" is invalid/, +); + +test( + calculateAugmentationErrorMacro, + "Packs input with multiple languages", + " + a/b, c/d ", + undefined, + [KnownLanguage.javascript, KnownLanguage.java], + {}, + /Cannot specify a 'packs' input in a multi-language analysis/, +); + +test( + calculateAugmentationErrorMacro, + "Packs input with no languages", + " + a/b, c/d ", + undefined, + [], + {}, + /No languages specified/, +); + +test( + calculateAugmentationErrorMacro, + "Invalid packs", + " a-pack-without-a-scope ", + undefined, + [KnownLanguage.javascript], + {}, + /"a-pack-without-a-scope" is not a valid pack/, +); diff --git a/src/config/db-config.ts b/src/config/db-config.ts new file mode 100644 index 0000000000..2639493543 --- /dev/null +++ b/src/config/db-config.ts @@ -0,0 +1,476 @@ +import * as path from "path"; + +import * as semver from "semver"; + +import * as errorMessages from "../error-messages"; +import { + RepositoryProperties, + RepositoryPropertyName, +} from "../feature-flags/properties"; +import { Language } from "../languages"; +import { Logger } from "../logging"; +import { cloneObject, ConfigurationError, prettyPrintPack } from "../util"; + +export interface ExcludeQueryFilter { + exclude: Record; +} + +export interface IncludeQueryFilter { + include: Record; +} + +export type QueryFilter = ExcludeQueryFilter | IncludeQueryFilter; + +export interface QuerySpec { + name?: string; + uses: string; +} + +/** + * Format of the config file supplied by the user. + */ +export interface UserConfig { + name?: string; + "disable-default-queries"?: boolean; + queries?: QuerySpec[]; + "paths-ignore"?: string[]; + paths?: string[]; + + // If this is a multi-language analysis, then the packages must be split by + // language. If this is a single language analysis, then no split by + // language is necessary. + packs?: Record | string[]; + + // Set of query filters to include and exclude extra queries based on + // codeql query suite `include` and `exclude` properties + "query-filters"?: QueryFilter[]; +} + +/** + * Represents additional configuration data from a source other than + * a configuration file. + */ +interface Augmentation { + /** Whether or not the `input` combines with data in the base config. */ + combines: boolean; + /** The additional input data. */ + input?: T; +} + +/** + * Describes how to augment the user config with inputs from the action. + * + * When running a CodeQL analysis, the user can supply a config file. When + * running a CodeQL analysis from a GitHub action, the user can supply a + * config file _and_ a set of inputs. + * + * The inputs from the action are used to augment the user config before + * passing the user config to the CodeQL CLI invocation. + */ +export interface AugmentationProperties { + /** + * Whether or not the queries input combines with the queries in the config. + */ + queriesInputCombines: boolean; + + /** + * The queries input from the `with` block of the action declaration + */ + queriesInput?: QuerySpec[]; + + /** + * Whether or not the packs input combines with the packs in the config. + */ + packsInputCombines: boolean; + + /** + * The packs input from the `with` block of the action declaration + */ + packsInput?: string[]; + + /** + * Extra queries from the corresponding repository property. + */ + repoPropertyQueries: Augmentation; +} + +/** + * The default, empty augmentation properties. This is most useful + * for tests. + */ +export const defaultAugmentationProperties: AugmentationProperties = { + queriesInputCombines: false, + packsInputCombines: false, + packsInput: undefined, + queriesInput: undefined, + repoPropertyQueries: { + combines: false, + input: undefined, + }, +}; + +/** + * The convention in this action is that an input value that is prefixed with a '+' will + * be combined with the corresponding value in the config file. + * + * Without a '+', an input value will override the corresponding value in the config file. + * + * @param inputValue The input value to process. + * @returns true if the input value should replace the corresponding value in the config file, + * false if it should be appended. + */ +function shouldCombine(inputValue?: string): boolean { + return !!inputValue?.trim().startsWith("+"); +} + +export type Packs = Partial>; + +export interface Pack { + name: string; + version?: string; + path?: string; +} + +/** + * Pack names must be in the form of `scope/name`, with only alpha-numeric characters, + * and `-` allowed as long as not the first or last char. + **/ +const PACK_IDENTIFIER_PATTERN = (function () { + const alphaNumeric = "[a-z0-9]"; + const alphaNumericDash = "[a-z0-9-]"; + const component = `${alphaNumeric}(${alphaNumericDash}*${alphaNumeric})?`; + return new RegExp(`^${component}/${component}$`); +})(); + +/** + * Validates that this package specification is syntactically correct. + * It may not point to any real package, but after this function returns + * without throwing, we are guaranteed that the package specification + * is roughly correct. + * + * The CLI itself will do a more thorough validation of the package + * specification. + * + * A package specification looks like this: + * + * `scope/name@version:path` + * + * Version and path are optional. + * + * @param packStr the package specification to verify. + * @param configFile Config file to use for error reporting + */ +export function parsePacksSpecification(packStr: string): Pack { + if (typeof packStr !== "string") { + throw new ConfigurationError(errorMessages.getPacksStrInvalid(packStr)); + } + + packStr = packStr.trim(); + const atIndex = packStr.indexOf("@"); + const colonIndex = packStr.indexOf(":", atIndex); + const packStart = 0; + const versionStart = atIndex + 1 || undefined; + const pathStart = colonIndex + 1 || undefined; + const packEnd = Math.min( + atIndex > 0 ? atIndex : Infinity, + colonIndex > 0 ? colonIndex : Infinity, + packStr.length, + ); + const versionEnd = versionStart + ? Math.min(colonIndex > 0 ? colonIndex : Infinity, packStr.length) + : undefined; + const pathEnd = pathStart ? packStr.length : undefined; + + const packName = packStr.slice(packStart, packEnd).trim(); + const version = versionStart + ? packStr.slice(versionStart, versionEnd).trim() + : undefined; + const packPath = pathStart + ? packStr.slice(pathStart, pathEnd).trim() + : undefined; + + if (!PACK_IDENTIFIER_PATTERN.test(packName)) { + throw new ConfigurationError(errorMessages.getPacksStrInvalid(packStr)); + } + if (version) { + try { + new semver.Range(version); + } catch { + // The range string is invalid. OK to ignore the caught error + throw new ConfigurationError(errorMessages.getPacksStrInvalid(packStr)); + } + } + + if ( + packPath && + (path.isAbsolute(packPath) || + // Permit using "/" instead of "\" on Windows + // Use `x.split(y).join(z)` as a polyfill for `x.replaceAll(y, z)` since + // if we used a regex we'd need to escape the path separator on Windows + // which seems more awkward. + path.normalize(packPath).split(path.sep).join("/") !== + packPath.split(path.sep).join("/")) + ) { + throw new ConfigurationError(errorMessages.getPacksStrInvalid(packStr)); + } + + if (!packPath && pathStart) { + // 0 length path + throw new ConfigurationError(errorMessages.getPacksStrInvalid(packStr)); + } + + return { + name: packName, + version, + path: packPath, + }; +} + +export function validatePackSpecification(pack: string) { + return prettyPrintPack(parsePacksSpecification(pack)); +} + +// Exported for testing +export function parsePacksFromInput( + rawPacksInput: string | undefined, + languages: Language[], + packsInputCombines: boolean, +): Packs | undefined { + if (!rawPacksInput?.trim()) { + return undefined; + } + + if (languages.length > 1) { + throw new ConfigurationError( + "Cannot specify a 'packs' input in a multi-language analysis. Use a codeql-config.yml file instead and specify packs by language.", + ); + } else if (languages.length === 0) { + throw new ConfigurationError( + "No languages specified. Cannot process the packs input.", + ); + } + + rawPacksInput = rawPacksInput.trim(); + if (packsInputCombines) { + rawPacksInput = rawPacksInput.trim().substring(1).trim(); + if (!rawPacksInput) { + throw new ConfigurationError( + errorMessages.getConfigFilePropertyError( + undefined, + "packs", + "A '+' was used in the 'packs' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs.", + ), + ); + } + } + + return { + [languages[0]]: rawPacksInput.split(",").reduce((packs, pack) => { + packs.push(validatePackSpecification(pack)); + return packs; + }, [] as string[]), + }; +} + +/** + * Calculates how the codeql config file needs to be augmented before passing + * it to the CLI. The reason this is necessary is the codeql-action can be called + * with extra inputs from the workflow. These inputs are not part of the config + * and the CLI does not know about these inputs so we need to inject them into + * the config file sent to the CLI. + * + * @param rawPacksInput The packs input from the action configuration. + * @param rawQueriesInput The queries input from the action configuration. + * @param repositoryProperties The dictionary of repository properties. + * @param languages The languages that the config file is for. If the packs input + * is non-empty, then there must be exactly one language. Otherwise, an + * error is thrown. + * + * @returns The properties that need to be augmented in the config file. + * + * @throws An error if the packs input is non-empty and the languages input does + * not have exactly one language. + */ +export async function calculateAugmentation( + rawPacksInput: string | undefined, + rawQueriesInput: string | undefined, + repositoryProperties: RepositoryProperties, + languages: Language[], +): Promise { + const packsInputCombines = shouldCombine(rawPacksInput); + const packsInput = parsePacksFromInput( + rawPacksInput, + languages, + packsInputCombines, + ); + const queriesInputCombines = shouldCombine(rawQueriesInput); + const queriesInput = parseQueriesFromInput( + rawQueriesInput, + queriesInputCombines, + ); + + const repoExtraQueries = + repositoryProperties[RepositoryPropertyName.EXTRA_QUERIES]; + const repoExtraQueriesCombines = shouldCombine(repoExtraQueries); + const repoPropertyQueries = { + combines: repoExtraQueriesCombines, + input: parseQueriesFromInput( + repoExtraQueries, + repoExtraQueriesCombines, + new ConfigurationError( + errorMessages.getRepoPropertyError( + RepositoryPropertyName.EXTRA_QUERIES, + errorMessages.getEmptyCombinesError(), + ), + ), + ), + }; + + return { + packsInputCombines, + packsInput: packsInput?.[languages[0]], + queriesInput, + queriesInputCombines, + repoPropertyQueries, + }; +} + +function parseQueriesFromInput( + rawQueriesInput: string | undefined, + queriesInputCombines: boolean, + errorToThrow?: ConfigurationError, +) { + if (!rawQueriesInput) { + return undefined; + } + + const trimmedInput = queriesInputCombines + ? rawQueriesInput.trim().slice(1).trim() + : (rawQueriesInput?.trim() ?? ""); + if (queriesInputCombines && trimmedInput.length === 0) { + if (errorToThrow) { + throw errorToThrow; + } + throw new ConfigurationError( + errorMessages.getConfigFilePropertyError( + undefined, + "queries", + "A '+' was used in the 'queries' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs.", + ), + ); + } + return trimmedInput.split(",").map((query) => ({ uses: query.trim() })); +} + +/** + * Combines queries from various configuration sources. + * + * @param logger The logger to use. + * @param config The loaded configuration file (either `config-file` or `config` input). + * @param augmentationProperties Additional configuration data from other sources. + * @returns Returns `augmentedConfig` with `queries` set to the computed array of queries. + */ +function combineQueries( + logger: Logger, + config: UserConfig, + augmentationProperties: AugmentationProperties, +): QuerySpec[] { + const result: QuerySpec[] = []; + + // Query settings obtained from the repository properties have the highest precedence. + if ( + augmentationProperties.repoPropertyQueries && + augmentationProperties.repoPropertyQueries.input + ) { + logger.info( + `Found query configuration in the repository properties (${RepositoryPropertyName.EXTRA_QUERIES}): ` + + `${augmentationProperties.repoPropertyQueries.input.map((q) => q.uses).join(", ")}`, + ); + + // If there are queries configured as a repository property, these may be organisational + // settings. If they don't allow combining with other query configurations, return just the + // ones configured in the repository properties. + if (!augmentationProperties.repoPropertyQueries.combines) { + logger.info( + `The queries configured in the repository properties don't allow combining with other query settings. ` + + `Any queries configured elsewhere will be ignored.`, + ); + return augmentationProperties.repoPropertyQueries.input; + } else { + // Otherwise, add them to the query array and continue. + result.push(...augmentationProperties.repoPropertyQueries.input); + } + } + + // If there is a `queries` input to the Action, it has the next highest precedence. + if (augmentationProperties.queriesInput) { + // If there is a `queries` input and `queriesInputCombines` is `false`, then we don't + // combine it with the queries configured in the configuration file (if any). That is the + // original behaviour of this property. However, we DO combine it with any queries that + // we obtained from the repository properties, since that may be enforced by the organisation. + if (!augmentationProperties.queriesInputCombines) { + return result.concat(augmentationProperties.queriesInput); + } else { + // If they combine, add them to the query array and continue. + result.push(...augmentationProperties.queriesInput); + } + } + + // If we get to this point, we either don't have any extra configuration inputs or all of them + // allow themselves to be combined with the settings from the configuration file. + if (config.queries) { + result.push(...config.queries); + } + + return result; +} + +export function generateCodeScanningConfig( + logger: Logger, + originalUserInput: UserConfig, + augmentationProperties: AugmentationProperties, +): UserConfig { + // make a copy so we can modify it + const augmentedConfig = cloneObject(originalUserInput); + + // Inject the queries from the input + augmentedConfig.queries = combineQueries( + logger, + augmentedConfig, + augmentationProperties, + ); + logger.debug( + `Combined queries: ${augmentedConfig.queries?.map((q) => q.uses).join(",")}`, + ); + if (augmentedConfig.queries?.length === 0) { + delete augmentedConfig.queries; + } + + // Inject the packs from the input + if (augmentationProperties.packsInput) { + if (augmentationProperties.packsInputCombines) { + // At this point, we already know that this is a single-language analysis + if (Array.isArray(augmentedConfig.packs)) { + augmentedConfig.packs = (augmentedConfig.packs || []).concat( + augmentationProperties.packsInput, + ); + } else if (!augmentedConfig.packs) { + augmentedConfig.packs = augmentationProperties.packsInput; + } else { + // At this point, we know there is only one language. + // If there were more than one language, an error would already have been thrown. + const language = Object.keys(augmentedConfig.packs)[0]; + augmentedConfig.packs[language] = augmentedConfig.packs[ + language + ].concat(augmentationProperties.packsInput); + } + } else { + augmentedConfig.packs = augmentationProperties.packsInput; + } + } + if (Array.isArray(augmentedConfig.packs) && !augmentedConfig.packs.length) { + delete augmentedConfig.packs; + } + + return augmentedConfig; +} diff --git a/src/defaults.json b/src/defaults.json index 712efc19fe..dbc0d5e258 100644 --- a/src/defaults.json +++ b/src/defaults.json @@ -1,6 +1,6 @@ { - "bundleVersion": "codeql-bundle-v2.23.0", - "cliVersion": "2.23.0", - "priorBundleVersion": "codeql-bundle-v2.22.4", - "priorCliVersion": "2.22.4" + "bundleVersion": "codeql-bundle-v2.23.1", + "cliVersion": "2.23.1", + "priorBundleVersion": "codeql-bundle-v2.23.0", + "priorCliVersion": "2.23.0" } 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 e78c367244..e1daeedc2d 100644 --- a/src/environment.ts +++ b/src/environment.ts @@ -115,6 +115,9 @@ 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. */ diff --git a/src/error-messages.ts b/src/error-messages.ts new file mode 100644 index 0000000000..eb49266771 --- /dev/null +++ b/src/error-messages.ts @@ -0,0 +1,79 @@ +import { RepositoryPropertyName } from "./feature-flags/properties"; + +const PACKS_PROPERTY = "packs"; + +export function getConfigFileOutsideWorkspaceErrorMessage( + configFile: string, +): string { + return `The configuration file "${configFile}" is outside of the workspace`; +} + +export function getConfigFileDoesNotExistErrorMessage( + configFile: string, +): string { + return `The configuration file "${configFile}" does not exist`; +} + +export function getConfigFileRepoFormatInvalidMessage( + configFile: string, +): string { + let error = `The configuration file "${configFile}" is not a supported remote file reference.`; + error += " Expected format //@"; + + return error; +} + +export function getConfigFileFormatInvalidMessage(configFile: string): string { + return `The configuration file "${configFile}" could not be read`; +} + +export function getConfigFileDirectoryGivenMessage(configFile: string): string { + return `The configuration file "${configFile}" looks like a directory, not a file`; +} + +export function getEmptyCombinesError(): string { + return `A '+' was used to specify that you want to add extra arguments to the configuration, but no extra arguments were specified. Please either remove the '+' or specify some extra arguments.`; +} + +export function getConfigFilePropertyError( + configFile: string | undefined, + property: string, + error: string, +): string { + if (configFile === undefined) { + return `The workflow property "${property}" is invalid: ${error}`; + } else { + return `The configuration file "${configFile}" is invalid: property "${property}" ${error}`; + } +} + +export function getRepoPropertyError( + propertyName: RepositoryPropertyName, + error: string, +): string { + return `The repository property "${propertyName}" is invalid: ${error}`; +} + +export function getPacksStrInvalid( + packStr: string, + configFile?: string, +): string { + return configFile + ? getConfigFilePropertyError( + configFile, + PACKS_PROPERTY, + `"${packStr}" is not a valid pack`, + ) + : `"${packStr}" is not a valid pack`; +} + +export function getNoLanguagesError(): string { + return ( + "Did not detect any languages to analyze. " + + "Please update input in workflow or check that GitHub detects the correct languages in your repository." + ); +} + +export function getUnknownLanguagesError(languages: string[]): string { + return `Did not recognize the following languages: ${languages.join(", ")}`; +} diff --git a/src/feature-flags.ts b/src/feature-flags.ts index d9f1a1cc3a..2938f5108c 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", @@ -72,7 +73,9 @@ export enum Feature { OverlayAnalysisRust = "overlay_analysis_rust", OverlayAnalysisSwift = "overlay_analysis_swift", PythonDefaultIsToNotExtractStdlib = "python_default_is_to_not_extract_stdlib", + UseRepositoryProperties = "use_repository_properties", QaTelemetryEnabled = "qa_telemetry_enabled", + ResolveSupportedLanguagesUsingCli = "resolve_supported_languages_using_cli", } export const featureConfig: Record< @@ -145,6 +148,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", @@ -256,12 +265,22 @@ export const featureConfig: Record< minimumVersion: undefined, toolsFeature: ToolsFeature.PythonDefaultIsToNotExtractStdlib, }, + [Feature.UseRepositoryProperties]: { + defaultValue: false, + envVar: "CODEQL_ACTION_USE_REPOSITORY_PROPERTIES", + minimumVersion: undefined, + }, [Feature.QaTelemetryEnabled]: { defaultValue: false, envVar: "CODEQL_ACTION_QA_TELEMETRY", legacyApi: true, minimumVersion: undefined, }, + [Feature.JavaMinimizeDependencyJars]: { + defaultValue: false, + envVar: "CODEQL_ACTION_JAVA_MINIMIZE_DEPENDENCY_JARS", + minimumVersion: "2.23.0", + }, }; /** diff --git a/src/feature-flags/properties.test.ts b/src/feature-flags/properties.test.ts new file mode 100644 index 0000000000..dd0c72a21e --- /dev/null +++ b/src/feature-flags/properties.test.ts @@ -0,0 +1,97 @@ +import test from "ava"; +import * as sinon from "sinon"; + +import * as api from "../api-client"; +import { getRunnerLogger } from "../logging"; +import { parseRepositoryNwo } from "../repository"; +import { setupTests } from "../testing-utils"; +import * as util from "../util"; + +import * as properties from "./properties"; + +setupTests(test); + +test("loadPropertiesFromApi throws if response data is not an array", async (t) => { + sinon.stub(api, "getRepositoryProperties").resolves({ + headers: {}, + status: 200, + url: "", + data: {}, + }); + const logger = getRunnerLogger(true); + const mockRepositoryNwo = parseRepositoryNwo("owner/repo"); + await t.throwsAsync( + properties.loadPropertiesFromApi( + { + type: util.GitHubVariant.DOTCOM, + }, + logger, + mockRepositoryNwo, + ), + ); +}); + +test("loadPropertiesFromApi throws if response data contains unexpected objects", async (t) => { + sinon.stub(api, "getRepositoryProperties").resolves({ + headers: {}, + status: 200, + url: "", + data: [{}], + }); + const logger = getRunnerLogger(true); + const mockRepositoryNwo = parseRepositoryNwo("owner/repo"); + await t.throwsAsync( + properties.loadPropertiesFromApi( + { + type: util.GitHubVariant.DOTCOM, + }, + logger, + mockRepositoryNwo, + ), + ); +}); + +test("loadPropertiesFromApi returns empty object if on GHES", async (t) => { + sinon.stub(api, "getRepositoryProperties").resolves({ + headers: {}, + status: 200, + url: "", + data: [ + { property_name: "github-codeql-extra-queries", value: "+queries" }, + { property_name: "unknown-property", value: "something" }, + ] satisfies properties.RepositoryProperty[], + }); + const logger = getRunnerLogger(true); + const mockRepositoryNwo = parseRepositoryNwo("owner/repo"); + const response = await properties.loadPropertiesFromApi( + { + type: util.GitHubVariant.GHES, + version: "", + }, + logger, + mockRepositoryNwo, + ); + t.deepEqual(response, {}); +}); + +test("loadPropertiesFromApi loads known properties", async (t) => { + sinon.stub(api, "getRepositoryProperties").resolves({ + headers: {}, + status: 200, + url: "", + data: [ + { property_name: "github-codeql-extra-queries", value: "+queries" }, + { property_name: "unknown-property", value: "something" }, + ] satisfies properties.RepositoryProperty[], + }); + const logger = getRunnerLogger(true); + const mockRepositoryNwo = parseRepositoryNwo("owner/repo"); + const response = await properties.loadPropertiesFromApi( + { + type: util.GitHubVariant.DOTCOM, + }, + logger, + mockRepositoryNwo, + ); + t.deepEqual(response, { "github-codeql-extra-queries": "+queries" }); +}); diff --git a/src/feature-flags/properties.ts b/src/feature-flags/properties.ts new file mode 100644 index 0000000000..0104cddd91 --- /dev/null +++ b/src/feature-flags/properties.ts @@ -0,0 +1,94 @@ +import { getRepositoryProperties } from "../api-client"; +import { Logger } from "../logging"; +import { RepositoryNwo } from "../repository"; +import { GitHubVariant, GitHubVersion } from "../util"; + +/** + * Enumerates repository property names that have some meaning to us. + */ +export enum RepositoryPropertyName { + EXTRA_QUERIES = "github-codeql-extra-queries", +} + +/** + * A repository property has a name and a value. + */ +export interface RepositoryProperty { + property_name: string; + value: string; +} + +/** + * The API returns a list of `RepositoryProperty` objects. + */ +type GitHubPropertiesResponse = RepositoryProperty[]; + +/** + * A partial mapping from `RepositoryPropertyName` to values. + */ +export type RepositoryProperties = Partial< + Record +>; + +/** + * Retrieves all known repository properties from the API. + * + * @param logger The logger to use. + * @param repositoryNwo Information about the repository for which to load properties. + * @returns Returns a partial mapping from `RepositoryPropertyName` to values. + */ +export async function loadPropertiesFromApi( + gitHubVersion: GitHubVersion, + logger: Logger, + repositoryNwo: RepositoryNwo, +): Promise { + // TODO: To be safe for now; later we should replace this with a version check once we know + // which version of GHES we expect this to be supported by. + if (gitHubVersion.type === GitHubVariant.GHES) { + return {}; + } + + try { + const response = await getRepositoryProperties(repositoryNwo); + const remoteProperties = response.data as GitHubPropertiesResponse; + + if (!Array.isArray(remoteProperties)) { + throw new Error( + `Expected repository properties API to return an array, but got: ${JSON.stringify(response.data)}`, + ); + } + + logger.debug( + `Retrieved ${remoteProperties.length} repository properties: ${remoteProperties.map((p) => p.property_name).join(", ")}`, + ); + + const knownProperties = new Set(Object.values(RepositoryPropertyName)); + const properties: RepositoryProperties = {}; + for (const property of remoteProperties) { + if (property.property_name === undefined) { + throw new Error( + `Expected property object to have a 'property_name', but got: ${JSON.stringify(property)}`, + ); + } + + if ( + knownProperties.has(property.property_name as RepositoryPropertyName) + ) { + properties[property.property_name] = property.value; + } + } + + logger.debug("Loaded the following values for the repository properties:"); + for (const [property, value] of Object.entries(properties).sort( + ([nameA], [nameB]) => nameA.localeCompare(nameB), + )) { + logger.debug(` ${property}: ${value}`); + } + + return properties; + } catch (e) { + throw new Error( + `Encountered an error while trying to determine repository properties: ${e}`, + ); + } +} diff --git a/src/init-action.ts b/src/init-action.ts index 8c9e2f36b8..2b4dba3fcf 100644 --- a/src/init-action.ts +++ b/src/init-action.ts @@ -32,6 +32,7 @@ import { } from "./diagnostics"; import { EnvVar } from "./environment"; import { Feature, Features } from "./feature-flags"; +import { loadPropertiesFromApi } from "./feature-flags/properties"; import { checkInstallPython311, checkPacksForOverlayCompatibility, @@ -78,6 +79,7 @@ import { wrapError, checkActionVersion, getErrorMessage, + BuildMode, } from "./util"; import { validateWorkflow } from "./workflow"; @@ -195,6 +197,14 @@ async function run() { logger, ); + // Fetch the values of known repository properties that affect us. + const enableRepoProps = await features.getValue( + Feature.UseRepositoryProperties, + ); + const repositoryProperties = enableRepoProps + ? await loadPropertiesFromApi(gitHubVersion, logger, repositoryNwo) + : {}; + const jobRunUuid = uuidV4(); logger.info(`Job run UUID is ${jobRunUuid}.`); core.exportVariable(EnvVar.JOB_RUN_UUID, jobRunUuid); @@ -316,6 +326,7 @@ async function run() { githubVersion: gitHubVersion, apiDetails, features, + repositoryProperties, logger, }); @@ -546,8 +557,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. @@ -597,6 +616,28 @@ 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. We also only do this if + // dependency caching is enabled, since the option is intended to reduce the size of + // dependency caches, but the jar-rewriting does have a performance cost that we'd like to avoid + // when caching is not being used. + 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.dependencyCachingEnabled && + 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"), @@ -680,6 +721,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.ts b/src/overlay-database-utils.ts index ea43abcaa3..1de76fef77 100644 --- a/src/overlay-database-utils.ts +++ b/src/overlay-database-utils.ts @@ -10,7 +10,11 @@ import { type CodeQL } from "./codeql"; import { type Config } from "./config-utils"; import { getCommitOid, getFileOidsUnderPath } from "./git-utils"; import { Logger, withGroupAsync } from "./logging"; -import { isInTestMode, tryGetFolderBytes, withTimeout } from "./util"; +import { + isInTestMode, + tryGetFolderBytes, + waitForResultWithTimeLimit, +} from "./util"; export enum OverlayDatabaseMode { Overlay = "overlay", @@ -18,7 +22,7 @@ export enum OverlayDatabaseMode { None = "none", } -export const CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.3"; +export const CODEQL_OVERLAY_MINIMUM_VERSION = "2.22.4"; /** * The maximum (uncompressed) size of the overlay base database that we will @@ -154,7 +158,12 @@ function computeChangedFiles( // Constants for database caching const CACHE_VERSION = 1; const CACHE_PREFIX = "codeql-overlay-base-database"; -const MAX_CACHE_OPERATION_MS = 120_000; // Two minutes + +// The purpose of this ten-minute limit is to guard against the possibility +// that the cache service is unresponsive, which would otherwise cause the +// entire action to hang. Normally we expect cache operations to complete +// within two minutes. +const MAX_CACHE_OPERATION_MS = 600_000; /** * Checks that the overlay-base database is valid by checking for the @@ -268,7 +277,7 @@ export async function uploadOverlayBaseDatabaseToCache( ); try { - const cacheId = await withTimeout( + const cacheId = await waitForResultWithTimeLimit( MAX_CACHE_OPERATION_MS, actionsCache.saveCache([dbLocation], cacheSaveKey), () => {}, @@ -346,9 +355,39 @@ export async function downloadOverlayBaseDatabaseFromCache( let databaseDownloadDurationMs = 0; try { const databaseDownloadStart = performance.now(); - const foundKey = await withTimeout( + const foundKey = await waitForResultWithTimeLimit( + // This ten-minute limit for the cache restore operation is mainly to + // guard against the possibility that the cache service is unresponsive + // and hangs outside the data download. + // + // Data download (which is normally the most time-consuming part of the + // restore operation) should not run long enough to hit this limit. Even + // for an extremely large 10GB database, at a download speed of 40MB/s + // (see below), the download should complete within five minutes. If we + // do hit this limit, there are likely more serious problems other than + // mere slow download speed. + // + // This is important because we don't want any ongoing file operations + // on the database directory when we do hit this limit. Hitting this + // time limit takes us to a fallback path where we re-initialize the + // database from scratch at dbLocation, and having the cache restore + // operation continue to write into dbLocation in the background would + // really mess things up. We want to hit this limit only in the case + // of a hung cache service, not just slow download speed. MAX_CACHE_OPERATION_MS, - actionsCache.restoreCache([dbLocation], cacheRestoreKeyPrefix), + actionsCache.restoreCache( + [dbLocation], + cacheRestoreKeyPrefix, + undefined, + { + // Azure SDK download (which is the default) uses 128MB segments; see + // https://github.com/actions/toolkit/blob/main/packages/cache/README.md. + // Setting segmentTimeoutInMs to 3000 translates to segment download + // speed of about 40 MB/s, which should be achievable unless the + // download is unreliable (in which case we do want to abort). + segmentTimeoutInMs: 3000, + }, + ), () => { logger.info("Timed out downloading overlay-base database from cache"); }, diff --git a/src/setup-codeql.ts b/src/setup-codeql.ts index e64a032c97..e147a31129 100644 --- a/src/setup-codeql.ts +++ b/src/setup-codeql.ts @@ -33,8 +33,11 @@ export enum ToolsSource { } export const CODEQL_DEFAULT_ACTION_REPOSITORY = "github/codeql-action"; +const CODEQL_NIGHTLIES_REPOSITORY_OWNER = "dsp-testing"; +const CODEQL_NIGHTLIES_REPOSITORY_NAME = "codeql-cli-nightlies"; const CODEQL_BUNDLE_VERSION_ALIAS: string[] = ["linked", "latest"]; +const CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"]; function getCodeQLBundleExtension( compressionMethod: tar.CompressionMethod, @@ -276,7 +279,7 @@ export async function getCodeQLSource( ): Promise { if ( toolsInput && - !CODEQL_BUNDLE_VERSION_ALIAS.includes(toolsInput) && + !isReservedToolsValue(toolsInput) && !toolsInput.startsWith("http") ) { logger.info(`Using CodeQL CLI from local path ${toolsInput}`); @@ -331,6 +334,16 @@ export async function getCodeQLSource( */ let url: string | undefined; + if ( + toolsInput !== undefined && + CODEQL_NIGHTLY_TOOLS_INPUTS.includes(toolsInput) + ) { + logger.info( + `Using the latest CodeQL CLI nightly, as requested by 'tools: ${toolsInput}'.`, + ); + toolsInput = await getNightlyToolsUrl(logger); + } + if (forceShippedTools) { cliVersion = defaults.cliVersion; tagName = defaults.bundleVersion; @@ -554,21 +567,17 @@ export const downloadCodeQL = async function ( const headers: OutgoingHttpHeaders = { accept: "application/octet-stream", }; - // We only want to provide an authorization header if we are downloading - // from the same GitHub instance the Action is running on. - // This avoids leaking Enterprise tokens to dotcom. - // We also don't want to send an authorization header if there's already a token provided in the URL. let authorization: string | undefined = undefined; + + // We don't want to send an authorization header if there's already a token provided in the URL. if (searchParams.has("token")) { logger.debug("CodeQL tools URL contains an authorization token."); - } else if ( - codeqlURL.startsWith(`${apiDetails.url}/`) || - (apiDetails.apiURL && codeqlURL.startsWith(`${apiDetails.apiURL}/`)) - ) { - logger.debug("Providing an authorization token to download CodeQL tools."); - authorization = `token ${apiDetails.auth}`; } else { - logger.debug("Downloading CodeQL tools without an authorization token."); + authorization = api.getAuthorizationHeaderFor( + logger, + apiDetails, + codeqlURL, + ); } const toolcacheInfo = getToolcacheDestinationInfo( @@ -771,3 +780,46 @@ async function useZstdBundle( function getTempExtractionDir(tempDir: string) { return path.join(tempDir, uuidV4()); } + +/** + * Get the URL of the latest nightly CodeQL bundle. + */ +async function getNightlyToolsUrl(logger: Logger) { + const zstdAvailability = await tar.isZstdAvailable(logger); + // The nightly is guaranteed to have a zstd bundle + const compressionMethod = (await useZstdBundle( + CODEQL_VERSION_ZSTD_BUNDLE, + zstdAvailability.available, + )) + ? "zstd" + : "gzip"; + + try { + // Since nightlies are prereleases, we can't just download the latest release + // on the repository. So instead we need to find the latest pre-release + // version and construct the download URL from that. + const release = await api.getApiClient().rest.repos.listReleases({ + owner: CODEQL_NIGHTLIES_REPOSITORY_OWNER, + repo: CODEQL_NIGHTLIES_REPOSITORY_NAME, + per_page: 1, + page: 1, + prerelease: true, + }); + const latestRelease = release.data[0]; + if (!latestRelease) { + throw new Error("Could not find the latest nightly release."); + } + return `https://github.com/${CODEQL_NIGHTLIES_REPOSITORY_OWNER}/${CODEQL_NIGHTLIES_REPOSITORY_NAME}/releases/download/${latestRelease.tag_name}/${getCodeQLBundleName(compressionMethod)}`; + } catch (e) { + throw new Error( + `Failed to retrieve the latest nightly release: ${util.wrapError(e)}`, + ); + } +} + +function isReservedToolsValue(tools: string): boolean { + return ( + CODEQL_BUNDLE_VERSION_ALIAS.includes(tools) || + CODEQL_NIGHTLY_TOOLS_INPUTS.includes(tools) + ); +} diff --git a/src/start-proxy-action.ts b/src/start-proxy-action.ts index 1efedb7d5c..9592b904bb 100644 --- a/src/start-proxy-action.ts +++ b/src/start-proxy-action.ts @@ -6,14 +6,16 @@ import * as toolcache from "@actions/tool-cache"; import { pki } from "node-forge"; import * as actionsUtil from "./actions-util"; +import { getApiDetails, getAuthorizationHeaderFor } from "./api-client"; 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 +121,7 @@ async function runWrapper() { }; // Start the Proxy - const proxyBin = await getProxyBinaryPath(); + const proxyBin = await getProxyBinaryPath(logger); await startProxy(proxyBin, proxyConfig, proxyLogFilePath, logger); } @@ -184,26 +186,32 @@ 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 apiDetails = getApiDetails(); + const authorization = getAuthorizationHeaderFor( + logger, + apiDetails, + proxyInfo.url, + ); + const temp = await toolcache.downloadTool( + proxyInfo.url, + undefined, + authorization, + { + accept: "application/octet-stream", + }, + ); 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 3e2748aaf9..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"; @@ -197,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 18e8faa158..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, isDefined } 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; @@ -166,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/testing-utils.ts b/src/testing-utils.ts index a12c995851..ea3929131c 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,6 +357,7 @@ export function createTestConfig(overrides: Partial): Config { return Object.assign( {}, { + version: getActionVersion(), analysisKinds: [AnalysisKind.CodeScanning], languages: [], buildMode: undefined, @@ -376,6 +378,7 @@ export function createTestConfig(overrides: Partial): Config { extraQueryExclusions: [], overlayDatabaseMode: OverlayDatabaseMode.None, useOverlayDatabaseCaching: false, + repositoryProperties: {}, } 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/trap-caching.ts b/src/trap-caching.ts index 4e9a21634c..13b0450f1a 100644 --- a/src/trap-caching.ts +++ b/src/trap-caching.ts @@ -16,7 +16,7 @@ import { getErrorMessage, isHTTPError, tryGetFolderBytes, - withTimeout, + waitForResultWithTimeLimit, } from "./util"; // This constant should be bumped if we make a breaking change @@ -96,7 +96,7 @@ export async function downloadTrapCaches( logger.info( `Looking in Actions cache for TRAP cache with key ${preferredKey}`, ); - const found = await withTimeout( + const found = await waitForResultWithTimeLimit( MAX_CACHE_OPERATION_MS, actionsCache.restoreCache([cacheDir], preferredKey, [ // Fall back to any cache with the right key prefix @@ -156,7 +156,7 @@ export async function uploadTrapCaches( process.env.GITHUB_SHA || "unknown", ); logger.info(`Uploading TRAP cache to Actions cache with key ${key}`); - await withTimeout( + await waitForResultWithTimeLimit( MAX_CACHE_OPERATION_MS, actionsCache.saveCache([cacheDir], key), () => { diff --git a/src/upload-sarif-action.ts b/src/upload-sarif-action.ts index a193e242a6..aa1a5a4443 100644 --- a/src/upload-sarif-action.ts +++ b/src/upload-sarif-action.ts @@ -32,6 +32,55 @@ interface UploadSarifStatusReport extends StatusReportBase, upload_lib.UploadStatusReport {} +/** + * Searches for SARIF files for the given `analysis` in the given `sarifPath`. + * If any are found, then they are uploaded to the appropriate endpoint for the given `analysis`. + * + * @param logger The logger to use. + * @param features Information about FFs. + * @param sarifPath The path to a SARIF file or directory containing SARIF files. + * @param pathStats Information about `sarifPath`. + * @param checkoutPath The checkout path. + * @param analysis The configuration of the analysis we should upload SARIF files for. + * @param category The SARIF category to use for the upload. + * @returns The result of uploading the SARIF file(s) or `undefined` if there are none. + */ +async function findAndUpload( + logger: Logger, + features: Features, + sarifPath: string, + pathStats: fs.Stats, + checkoutPath: string, + analysis: analyses.AnalysisConfig, + category?: string, +): Promise { + let sarifFiles: string[] | undefined; + + if (pathStats.isDirectory()) { + sarifFiles = upload_lib.findSarifFilesInDir( + sarifPath, + analysis.sarifPredicate, + ); + } else if (pathStats.isFile() && analysis.sarifPredicate(sarifPath)) { + sarifFiles = [sarifPath]; + } else { + return undefined; + } + + if (sarifFiles.length !== 0) { + return await upload_lib.uploadSpecifiedFiles( + sarifFiles, + checkoutPath, + category, + features, + logger, + analysis, + ); + } + + return undefined; +} + async function sendSuccessStatusReport( startedAt: Date, uploadStats: upload_lib.UploadStatusReport, @@ -86,54 +135,71 @@ async function run() { } try { + // `sarifPath` can either be a path to a single file, or a path to a directory. const sarifPath = actionsUtil.getRequiredInput("sarif_file"); const checkoutPath = actionsUtil.getRequiredInput("checkout_path"); const category = actionsUtil.getOptionalInput("category"); + const pathStats = fs.lstatSync(sarifPath, { throwIfNoEntry: false }); - const uploadResult = await upload_lib.uploadFiles( + if (pathStats === undefined) { + throw new ConfigurationError(`Path does not exist: ${sarifPath}.`); + } + + const sarifIds: Array<{ analysis: string; id: string }> = []; + const uploadResult = await findAndUpload( + logger, + features, sarifPath, + pathStats, checkoutPath, - category, - features, - logger, analyses.CodeScanning, + category, ); - core.setOutput("sarif-id", uploadResult.sarifID); + if (uploadResult !== undefined) { + core.setOutput("sarif-id", uploadResult.sarifID); + sarifIds.push({ + analysis: analyses.AnalysisKind.CodeScanning, + id: uploadResult.sarifID, + }); + } // If there are `.quality.sarif` files in `sarifPath`, then upload those to the code quality service. - // Code quality can currently only be enabled on top of security, so we'd currently always expect to - // have a directory for the results here. - if (fs.lstatSync(sarifPath).isDirectory()) { - const qualitySarifFiles = upload_lib.findSarifFilesInDir( - sarifPath, - analyses.CodeQuality.sarifPredicate, - ); - - if (qualitySarifFiles.length !== 0) { - await upload_lib.uploadSpecifiedFiles( - qualitySarifFiles, - checkoutPath, - actionsUtil.fixCodeQualityCategory(logger, category), - features, - logger, - analyses.CodeQuality, - ); - } + const qualityUploadResult = await findAndUpload( + logger, + features, + sarifPath, + pathStats, + checkoutPath, + analyses.CodeQuality, + actionsUtil.fixCodeQualityCategory(logger, category), + ); + if (qualityUploadResult !== undefined) { + sarifIds.push({ + analysis: analyses.AnalysisKind.CodeQuality, + id: qualityUploadResult.sarifID, + }); } + core.setOutput("sarif-ids", JSON.stringify(sarifIds)); // We don't upload results in test mode, so don't wait for processing if (isInTestMode()) { core.debug("In test mode. Waiting for processing is disabled."); } else if (actionsUtil.getRequiredInput("wait-for-processing") === "true") { - await upload_lib.waitForProcessing( - getRepositoryNwo(), - uploadResult.sarifID, - logger, - ); + if (uploadResult !== undefined) { + await upload_lib.waitForProcessing( + getRepositoryNwo(), + uploadResult.sarifID, + logger, + ); + } // The code quality service does not currently have an endpoint to wait for SARIF processing, // so we can't wait for that here. } - await sendSuccessStatusReport(startedAt, uploadResult.statusReport, logger); + await sendSuccessStatusReport( + startedAt, + uploadResult?.statusReport || {}, + logger, + ); } catch (unwrappedError) { const error = isThirdPartyAnalysis(ActionName.UploadSarif) && diff --git a/src/util.test.ts b/src/util.test.ts index b884e8c0a2..88da235254 100644 --- a/src/util.test.ts +++ b/src/util.test.ts @@ -297,7 +297,7 @@ test("listFolder", async (t) => { const longTime = 999_999; const shortTime = 10; -test("withTimeout on long task", async (t) => { +test("waitForResultWithTimeLimit on long task", async (t) => { let longTaskTimedOut = false; const longTask = new Promise((resolve) => { const timer = setTimeout(() => { @@ -305,35 +305,43 @@ test("withTimeout on long task", async (t) => { }, longTime); t.teardown(() => clearTimeout(timer)); }); - const result = await util.withTimeout(shortTime, longTask, () => { - longTaskTimedOut = true; - }); + const result = await util.waitForResultWithTimeLimit( + shortTime, + longTask, + () => { + longTaskTimedOut = true; + }, + ); t.deepEqual(longTaskTimedOut, true); t.deepEqual(result, undefined); }); -test("withTimeout on short task", async (t) => { +test("waitForResultWithTimeLimit on short task", async (t) => { let shortTaskTimedOut = false; const shortTask = new Promise((resolve) => { setTimeout(() => { resolve(99); }, shortTime); }); - const result = await util.withTimeout(longTime, shortTask, () => { - shortTaskTimedOut = true; - }); + const result = await util.waitForResultWithTimeLimit( + longTime, + shortTask, + () => { + shortTaskTimedOut = true; + }, + ); t.deepEqual(shortTaskTimedOut, false); t.deepEqual(result, 99); }); -test("withTimeout doesn't call callback if promise resolves", async (t) => { +test("waitForResultWithTimeLimit doesn't call callback if promise resolves", async (t) => { let shortTaskTimedOut = false; const shortTask = new Promise((resolve) => { setTimeout(() => { resolve(99); }, shortTime); }); - const result = await util.withTimeout(100, shortTask, () => { + const result = await util.waitForResultWithTimeLimit(100, shortTask, () => { shortTaskTimedOut = true; }); await new Promise((r) => setTimeout(r, 200)); diff --git a/src/util.ts b/src/util.ts index 5ef037636f..db7ba6cfda 100644 --- a/src/util.ts +++ b/src/util.ts @@ -864,7 +864,7 @@ let hadTimeout = false; * @param onTimeout A callback to call if the promise times out. * @returns The result of the promise, or undefined if the promise times out. */ -export async function withTimeout( +export async function waitForResultWithTimeLimit( timeoutMs: number, promise: Promise, onTimeout: () => void, @@ -894,7 +894,7 @@ export async function withTimeout( * Check if the global hadTimeout variable has been set, and if so then * exit the process to ensure any background tasks that are still running * are killed. This should be called at the end of execution if the - * `withTimeout` function has been used. + * `waitForResultWithTimeLimit` function has been used. */ export async function checkForTimeout() { if (hadTimeout === true) { 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/upload-sarif/action.yml b/upload-sarif/action.yml index f4fd30f0c6..cd61886c69 100644 --- a/upload-sarif/action.yml +++ b/upload-sarif/action.yml @@ -14,7 +14,7 @@ inputs: required: false default: ${{ github.workspace }} ref: - description: "The ref where results will be uploaded. If not provided, the Action will use the GITHUB_REF environment variable. If provided, the sha input must be provided as well. This input is ignored for pull requests from forks." + description: "The ref where results will be uploaded. If not provided, the Action will use the GITHUB_REF environment variable. If provided, the sha input must be provided as well. This input is ignored for pull requests from forks. Expected format: refs/heads/, refs/tags/, refs/pull//merge, or refs/pull//head." required: false sha: description: "The sha of the HEAD of the ref where results will be uploaded. If not provided, the Action will use the GITHUB_SHA environment variable. If provided, the ref input must be provided as well. This input is ignored for pull requests from forks." @@ -34,7 +34,12 @@ inputs: default: "true" outputs: sarif-id: - description: The ID of the uploaded SARIF file. + description: The ID of the uploaded Code Scanning SARIF file, if any. + sarif-ids: + description: | + A stringified JSON object containing the SARIF ID for each kind of analysis. For example: + + { "code-scanning": "some-id", "code-quality": "some-other-id" } runs: using: node20 main: '../lib/upload-sarif-action.js'