Compare commits

..

2 Commits

Author SHA1 Message Date
Henry Mercer
4d8b358273 Disable SIP disablement check 2025-10-28 12:27:34 +00:00
Henry Mercer
f336c09493 Add testing trigger 2025-10-28 12:26:18 +00:00
62 changed files with 73921 additions and 13713 deletions

View File

@@ -16,9 +16,9 @@ runs:
shell: bash shell: bash
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v6 uses: actions/setup-python@v5
with: with:
python-version: '3.12' python-version: 3.12
- name: Install dependencies - name: Install dependencies
run: | run: |

View File

@@ -79,7 +79,7 @@ jobs:
output: ${{ runner.temp }}/results output: ${{ runner.temp }}/results
upload-database: false upload-database: false
- name: Upload SARIF - name: Upload SARIF
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: ${{ matrix.os }}-zstd-bundle.sarif name: ${{ matrix.os }}-zstd-bundle.sarif
path: ${{ runner.temp }}/results/javascript.sarif path: ${{ runner.temp }}/results/javascript.sarif

View File

@@ -67,7 +67,7 @@ jobs:
output: ${{ runner.temp }}/results output: ${{ runner.temp }}/results
upload-database: false upload-database: false
- name: Upload SARIF - name: Upload SARIF
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: config-export-${{ matrix.os }}-${{ matrix.version }}.sarif.json name: config-export-${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: ${{ runner.temp }}/results/javascript.sarif path: ${{ runner.temp }}/results/javascript.sarif

View File

@@ -78,7 +78,7 @@ jobs:
output: ${{ runner.temp }}/results output: ${{ runner.temp }}/results
upload-database: false upload-database: false
- name: Upload SARIF - name: Upload SARIF
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: diagnostics-export-${{ matrix.os }}-${{ matrix.version }}.sarif.json name: diagnostics-export-${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: ${{ runner.temp }}/results/javascript.sarif path: ${{ runner.temp }}/results/javascript.sarif

View File

@@ -85,7 +85,7 @@ jobs:
with: with:
output: ${{ runner.temp }}/results output: ${{ runner.temp }}/results
- name: Upload SARIF - name: Upload SARIF
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: with-baseline-information-${{ matrix.os }}-${{ matrix.version }}.sarif.json name: with-baseline-information-${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: ${{ runner.temp }}/results/javascript.sarif path: ${{ runner.temp }}/results/javascript.sarif

View File

@@ -64,7 +64,7 @@ jobs:
with: with:
output: ${{ runner.temp }}/results output: ${{ runner.temp }}/results
- name: Upload SARIF - name: Upload SARIF
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: ${{ matrix.os }}-${{ matrix.version }}.sarif.json name: ${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: ${{ runner.temp }}/results/javascript.sarif path: ${{ runner.temp }}/results/javascript.sarif

View File

@@ -9,9 +9,6 @@ env:
GO111MODULE: auto GO111MODULE: auto
on: on:
push: push:
branches:
- main
- releases/v*
pull_request: pull_request:
types: types:
- opened - opened
@@ -56,42 +53,8 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- os: macos-latest
version: stable-v2.17.6
- os: ubuntu-latest
version: stable-v2.17.6
- os: macos-latest
version: stable-v2.18.4
- os: ubuntu-latest
version: stable-v2.18.4
- os: macos-latest
version: stable-v2.19.4
- os: ubuntu-latest
version: stable-v2.19.4
- os: macos-latest
version: stable-v2.20.7
- os: ubuntu-latest
version: stable-v2.20.7
- os: macos-latest
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
version: default
- os: macos-latest - os: macos-latest
version: linked version: linked
- os: ubuntu-latest
version: linked
- os: macos-latest
version: nightly-latest
- os: ubuntu-latest
version: nightly-latest
name: Multi-language repository name: Multi-language repository
if: github.triggering_actor != 'dependabot[bot]' if: github.triggering_actor != 'dependabot[bot]'
permissions: permissions:
@@ -185,6 +148,3 @@ jobs:
echo "Did not create a database for Swift, or created it in the wrong location." echo "Did not create a database for Swift, or created it in the wrong location."
exit 1 exit 1
fi fi
env:
CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI: true
CODEQL_ACTION_TEST_MODE: true

View File

@@ -83,7 +83,7 @@ jobs:
post-processed-sarif-path: ${{ runner.temp }}/post-processed post-processed-sarif-path: ${{ runner.temp }}/post-processed
- name: Upload security SARIF - name: Upload security SARIF
if: contains(matrix.analysis-kinds, 'code-scanning') if: contains(matrix.analysis-kinds, 'code-scanning')
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: | name: |
quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json
@@ -91,14 +91,14 @@ jobs:
retention-days: 7 retention-days: 7
- name: Upload quality SARIF - name: Upload quality SARIF
if: contains(matrix.analysis-kinds, 'code-quality') if: contains(matrix.analysis-kinds, 'code-quality')
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: | name: |
quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.quality.sarif.json quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.quality.sarif.json
path: ${{ runner.temp }}/results/javascript.quality.sarif path: ${{ runner.temp }}/results/javascript.quality.sarif
retention-days: 7 retention-days: 7
- name: Upload post-processed SARIF - name: Upload post-processed SARIF
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: | name: |
post-processed-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json post-processed-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json

View File

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

View File

@@ -15,7 +15,7 @@ defaults:
jobs: jobs:
check-expected-release-files: check-expected-release-files:
runs-on: ubuntu-slim runs-on: ubuntu-latest
permissions: permissions:
contents: read contents: read

View File

@@ -79,7 +79,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Download all artifacts - name: Download all artifacts
uses: actions/download-artifact@v6 uses: actions/download-artifact@v5
- name: Check expected artifacts exist - name: Check expected artifacts exist
run: | run: |
LANGUAGES="cpp csharp go java javascript python" LANGUAGES="cpp csharp go java javascript python"

View File

@@ -73,7 +73,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Download all artifacts - name: Download all artifacts
uses: actions/download-artifact@v6 uses: actions/download-artifact@v5
- name: Check expected artifacts exist - name: Check expected artifacts exist
run: | run: |
VERSIONS="stable-v2.20.3 default linked nightly-latest" VERSIONS="stable-v2.20.3 default linked nightly-latest"

View File

@@ -16,7 +16,7 @@ permissions:
jobs: jobs:
sizeup: sizeup:
name: Label PR with size name: Label PR with size
runs-on: ubuntu-slim runs-on: ubuntu-latest
steps: steps:
- name: Run sizeup - name: Run sizeup

View File

@@ -24,7 +24,7 @@ defaults:
jobs: jobs:
merge-back: merge-back:
runs-on: ubuntu-slim runs-on: ubuntu-latest
environment: Automation environment: Automation
if: github.repository == 'github/codeql-action' if: github.repository == 'github/codeql-action'
env: env:
@@ -48,9 +48,6 @@ jobs:
with: with:
fetch-depth: 0 # ensure we have all tags and can push commits fetch-depth: 0 # ensure we have all tags and can push commits
- uses: actions/setup-node@v6 - uses: actions/setup-node@v6
- uses: actions/setup-python@v6
with:
python-version: '3.12'
- name: Update git config - name: Update git config
run: | run: |

View File

@@ -29,7 +29,7 @@ defaults:
jobs: jobs:
prepare: prepare:
name: "Prepare release" name: "Prepare release"
runs-on: ubuntu-slim runs-on: ubuntu-latest
if: github.repository == 'github/codeql-action' if: github.repository == 'github/codeql-action'
permissions: permissions:

View File

@@ -10,7 +10,7 @@ defaults:
jobs: jobs:
publish: publish:
runs-on: ubuntu-slim runs-on: ubuntu-latest
permissions: permissions:
contents: read contents: read
id-token: write id-token: write

View File

@@ -20,7 +20,7 @@ defaults:
jobs: jobs:
update-bundle: update-bundle:
if: github.event.release.prerelease && startsWith(github.event.release.tag_name, 'codeql-bundle-') if: github.event.release.prerelease && startsWith(github.event.release.tag_name, 'codeql-bundle-')
runs-on: ubuntu-slim runs-on: ubuntu-latest
permissions: permissions:
contents: write # needed to push commits contents: write # needed to push commits
pull-requests: write # needed to create pull requests pull-requests: write # needed to create pull requests

View File

@@ -26,7 +26,7 @@ jobs:
update: update:
timeout-minutes: 45 timeout-minutes: 45
runs-on: ubuntu-slim runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' if: github.event_name == 'workflow_dispatch'
needs: [prepare] needs: [prepare]
env: env:
@@ -77,7 +77,7 @@ jobs:
backport: backport:
timeout-minutes: 45 timeout-minutes: 45
runs-on: ubuntu-slim runs-on: ubuntu-latest
environment: Automation environment: Automation
needs: [prepare] needs: [prepare]
if: ${{ (github.event_name == 'push') && needs.prepare.outputs.backport_target_branches != '[]' }} if: ${{ (github.event_name == 'push') && needs.prepare.outputs.backport_target_branches != '[]' }}

View File

@@ -9,7 +9,7 @@ jobs:
update-supported-enterprise-server-versions: update-supported-enterprise-server-versions:
name: Update Supported Enterprise Server Versions name: Update Supported Enterprise Server Versions
timeout-minutes: 45 timeout-minutes: 45
runs-on: ubuntu-slim runs-on: ubuntu-latest
if: github.repository == 'github/codeql-action' if: github.repository == 'github/codeql-action'
permissions: permissions:
contents: write # needed to push commits contents: write # needed to push commits

View File

@@ -2,14 +2,10 @@
See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs. See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs.
## 4.31.2 - 30 Oct 2025 ## [UNRELEASED]
No user facing changes. No user facing changes.
## 4.31.1 - 30 Oct 2025
- The `add-snippets` input has been removed from the `analyze` action. This input has been deprecated since CodeQL Action 3.26.4 in August 2024 when this removal was announced.
## 4.31.0 - 24 Oct 2025 ## 4.31.0 - 24 Oct 2025
- Bump minimum CodeQL bundle version to 2.17.6. [#3223](https://github.com/github/codeql-action/pull/3223) - Bump minimum CodeQL bundle version to 2.17.6. [#3223](https://github.com/github/codeql-action/pull/3223)

View File

@@ -32,10 +32,14 @@ inputs:
and 13GB for macOS). and 13GB for macOS).
required: false required: false
add-snippets: add-snippets:
description: Does not have any effect. description: Specify whether or not to add code snippets to the output sarif file.
required: false required: false
default: "false"
deprecationMessage: >- deprecationMessage: >-
The input "add-snippets" has been removed and no longer has any effect. The input "add-snippets" is deprecated and will be removed on the first release in August 2025.
When this input is set to true it is expected to add code snippets with an alert to the SARIF file.
However, since Code Scanning ignores code snippets provided as part of a SARIF file this is currently
a no operation. No alternative is available.
skip-queries: skip-queries:
description: If this option is set, the CodeQL database will be built but no queries will be run on it. Thus, no results will be produced. description: If this option is set, the CodeQL database will be built but no queries will be run on it. Thus, no results will be produced.
required: false required: false

File diff suppressed because one or more lines are too long

8737
lib/analyze-action.js generated

File diff suppressed because it is too large Load Diff

1137
lib/autobuild-action.js generated

File diff suppressed because it is too large Load Diff

16306
lib/init-action-post.js generated

File diff suppressed because one or more lines are too long

8697
lib/init-action.js generated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

1630
lib/start-proxy-action.js generated

File diff suppressed because it is too large Load Diff

8481
lib/upload-lib.js generated

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

704
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "codeql", "name": "codeql",
"version": "4.31.2", "version": "4.31.1",
"private": true, "private": true,
"description": "CodeQL action", "description": "CodeQL action",
"scripts": { "scripts": {
@@ -24,7 +24,7 @@
}, },
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/artifact": "^4.0.0", "@actions/artifact": "^2.3.1",
"@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2", "@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2",
"@actions/cache": "^4.1.0", "@actions/cache": "^4.1.0",
"@actions/core": "^1.11.1", "@actions/core": "^1.11.1",
@@ -38,6 +38,8 @@
"@octokit/request-error": "^7.0.1", "@octokit/request-error": "^7.0.1",
"@schemastore/package": "0.0.10", "@schemastore/package": "0.0.10",
"archiver": "^7.0.1", "archiver": "^7.0.1",
"console-log-level": "^1.4.1",
"del": "^8.0.0",
"fast-deep-equal": "^3.1.3", "fast-deep-equal": "^3.1.3",
"follow-redirects": "^1.15.11", "follow-redirects": "^1.15.11",
"get-folder-size": "^5.0.0", "get-folder-size": "^5.0.0",
@@ -55,15 +57,16 @@
"@eslint/eslintrc": "^3.3.1", "@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.38.0", "@eslint/js": "^9.38.0",
"@microsoft/eslint-formatter-sarif": "^3.1.0", "@microsoft/eslint-formatter-sarif": "^3.1.0",
"@octokit/types": "^15.0.1", "@octokit/types": "^15.0.0",
"@types/archiver": "^6.0.4", "@types/archiver": "^6.0.3",
"@types/console-log-level": "^1.4.5",
"@types/follow-redirects": "^1.14.4", "@types/follow-redirects": "^1.14.4",
"@types/js-yaml": "^4.0.9", "@types/js-yaml": "^4.0.9",
"@types/node": "20.19.9", "@types/node": "20.19.9",
"@types/node-forge": "^1.3.14", "@types/node-forge": "^1.3.14",
"@types/semver": "^7.7.1", "@types/semver": "^7.7.1",
"@types/sinon": "^17.0.4", "@types/sinon": "^17.0.4",
"@typescript-eslint/eslint-plugin": "^8.46.2", "@typescript-eslint/eslint-plugin": "^8.46.1",
"@typescript-eslint/parser": "^8.41.0", "@typescript-eslint/parser": "^8.41.0",
"ava": "^6.4.1", "ava": "^6.4.1",
"esbuild": "^0.25.11", "esbuild": "^0.25.11",

View File

@@ -27,7 +27,7 @@ steps:
output: ${{ runner.temp }}/results output: ${{ runner.temp }}/results
upload-database: false upload-database: false
- name: Upload SARIF - name: Upload SARIF
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: ${{ matrix.os }}-zstd-bundle.sarif name: ${{ matrix.os }}-zstd-bundle.sarif
path: ${{ runner.temp }}/results/javascript.sarif path: ${{ runner.temp }}/results/javascript.sarif

View File

@@ -12,7 +12,7 @@ steps:
output: "${{ runner.temp }}/results" output: "${{ runner.temp }}/results"
upload-database: false upload-database: false
- name: Upload SARIF - name: Upload SARIF
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: config-export-${{ matrix.os }}-${{ matrix.version }}.sarif.json name: config-export-${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: "${{ runner.temp }}/results/javascript.sarif" path: "${{ runner.temp }}/results/javascript.sarif"

View File

@@ -25,7 +25,7 @@ steps:
output: "${{ runner.temp }}/results" output: "${{ runner.temp }}/results"
upload-database: false upload-database: false
- name: Upload SARIF - name: Upload SARIF
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: diagnostics-export-${{ matrix.os }}-${{ matrix.version }}.sarif.json name: diagnostics-export-${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: "${{ runner.temp }}/results/javascript.sarif" path: "${{ runner.temp }}/results/javascript.sarif"

View File

@@ -17,7 +17,7 @@ steps:
with: with:
output: "${{ runner.temp }}/results" output: "${{ runner.temp }}/results"
- name: Upload SARIF - name: Upload SARIF
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: with-baseline-information-${{ matrix.os }}-${{ matrix.version }}.sarif.json name: with-baseline-information-${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: "${{ runner.temp }}/results/javascript.sarif" path: "${{ runner.temp }}/results/javascript.sarif"

View File

@@ -11,7 +11,7 @@ steps:
with: with:
output: "${{ runner.temp }}/results" output: "${{ runner.temp }}/results"
- name: Upload SARIF - name: Upload SARIF
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: ${{ matrix.os }}-${{ matrix.version }}.sarif.json name: ${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: "${{ runner.temp }}/results/javascript.sarif" path: "${{ runner.temp }}/results/javascript.sarif"

View File

@@ -39,7 +39,7 @@ steps:
post-processed-sarif-path: "${{ runner.temp }}/post-processed" post-processed-sarif-path: "${{ runner.temp }}/post-processed"
- name: Upload security SARIF - name: Upload security SARIF
if: contains(matrix.analysis-kinds, 'code-scanning') if: contains(matrix.analysis-kinds, 'code-scanning')
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: | name: |
quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json
@@ -47,14 +47,14 @@ steps:
retention-days: 7 retention-days: 7
- name: Upload quality SARIF - name: Upload quality SARIF
if: contains(matrix.analysis-kinds, 'code-quality') if: contains(matrix.analysis-kinds, 'code-quality')
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: | name: |
quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.quality.sarif.json quality-queries-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.quality.sarif.json
path: "${{ runner.temp }}/results/javascript.quality.sarif" path: "${{ runner.temp }}/results/javascript.quality.sarif"
retention-days: 7 retention-days: 7
- name: Upload post-processed SARIF - name: Upload post-processed SARIF
uses: actions/upload-artifact@v5 uses: actions/upload-artifact@v4
with: with:
name: | name: |
post-processed-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json post-processed-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}.sarif.json

View File

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

View File

@@ -9,15 +9,9 @@ if [ "$GITHUB_ACTIONS" = "true" ]; then
fi fi
# Check if npm install is likely needed before proceeding # Check if npm install is likely needed before proceeding
if [ ! -d node_modules ]; then if [ ! -d node_modules ] || [ package-lock.json -nt node_modules/.package-lock.json ]; then
echo "Running 'npm install' because 'node_modules' directory is missing." echo "Running 'npm install' because 'node_modules/.package-lock.json' appears to be outdated..."
npm install
elif [ package.json -nt package-lock.json ]; then
echo "Running 'npm install' because 'package-lock.json' appears to be outdated."
npm install
elif [ package-lock.json -nt node_modules/.package-lock.json ]; then
echo "Running 'npm install' because 'node_modules/.package-lock.json' appears to be outdated."
npm install npm install
else else
echo "Skipping 'npm install' because everything appears to be up-to-date." echo "Skipping 'npm install' because 'node_modules/.package-lock.json' appears to be up-to-date."
fi fi

View File

@@ -78,7 +78,7 @@ test("analyze action with RAM & threads from environment variables", async (t) =
t.deepEqual(runFinalizeStub.firstCall.args[1], "--threads=-1"); t.deepEqual(runFinalizeStub.firstCall.args[1], "--threads=-1");
t.deepEqual(runFinalizeStub.firstCall.args[2], "--ram=4992"); t.deepEqual(runFinalizeStub.firstCall.args[2], "--ram=4992");
t.assert(runQueriesStub.calledOnce); t.assert(runQueriesStub.calledOnce);
t.deepEqual(runQueriesStub.firstCall.args[2], "--threads=-1"); t.deepEqual(runQueriesStub.firstCall.args[3], "--threads=-1");
t.deepEqual(runQueriesStub.firstCall.args[1], "--ram=4992"); t.deepEqual(runQueriesStub.firstCall.args[1], "--ram=4992");
}); });
}); });

View File

@@ -76,7 +76,7 @@ test("analyze action with RAM & threads from action inputs", async (t) => {
t.deepEqual(runFinalizeStub.firstCall.args[1], "--threads=-1"); t.deepEqual(runFinalizeStub.firstCall.args[1], "--threads=-1");
t.deepEqual(runFinalizeStub.firstCall.args[2], "--ram=3012"); t.deepEqual(runFinalizeStub.firstCall.args[2], "--ram=3012");
t.assert(runQueriesStub.calledOnce); t.assert(runQueriesStub.calledOnce);
t.deepEqual(runQueriesStub.firstCall.args[2], "--threads=-1"); t.deepEqual(runQueriesStub.firstCall.args[3], "--threads=-1");
t.deepEqual(runQueriesStub.firstCall.args[1], "--ram=3012"); t.deepEqual(runQueriesStub.firstCall.args[1], "--ram=3012");
}); });
}); });

View File

@@ -324,16 +324,10 @@ async function run() {
); );
if (actionsUtil.getRequiredInput("skip-queries") !== "true") { if (actionsUtil.getRequiredInput("skip-queries") !== "true") {
// Warn if the removed `add-snippets` input is used.
if (actionsUtil.getOptionalInput("add-snippets") !== undefined) {
logger.warning(
"The `add-snippets` input has been removed and no longer has any effect.",
);
}
runStats = await runQueries( runStats = await runQueries(
outputDir, outputDir,
memory, memory,
util.getAddSnippetsFlag(actionsUtil.getRequiredInput("add-snippets")),
threads, threads,
diffRangePackDir, diffRangePackDir,
actionsUtil.getOptionalInput("category"), actionsUtil.getOptionalInput("category"),

View File

@@ -37,6 +37,7 @@ test("status report fields", async (t) => {
setupActionsVars(tmpDir, tmpDir); setupActionsVars(tmpDir, tmpDir);
const memoryFlag = ""; const memoryFlag = "";
const addSnippetsFlag = "";
const threadsFlag = ""; const threadsFlag = "";
sinon.stub(uploadLib, "validateSarifFileSchema"); sinon.stub(uploadLib, "validateSarifFileSchema");
@@ -102,6 +103,7 @@ test("status report fields", async (t) => {
const statusReport = await runQueries( const statusReport = await runQueries(
tmpDir, tmpDir,
memoryFlag, memoryFlag,
addSnippetsFlag,
threadsFlag, threadsFlag,
undefined, undefined,
undefined, undefined,

View File

@@ -3,6 +3,7 @@ import * as path from "path";
import { performance } from "perf_hooks"; import { performance } from "perf_hooks";
import * as io from "@actions/io"; import * as io from "@actions/io";
import * as del from "del";
import * as yaml from "js-yaml"; import * as yaml from "js-yaml";
import { getTemporaryDirectory, PullRequestBranches } from "./actions-util"; import { getTemporaryDirectory, PullRequestBranches } from "./actions-util";
@@ -436,6 +437,7 @@ export function addSarifExtension(
export async function runQueries( export async function runQueries(
sarifFolder: string, sarifFolder: string,
memoryFlag: string, memoryFlag: string,
addSnippetsFlag: string,
threadsFlag: string, threadsFlag: string,
diffRangePackDir: string | undefined, diffRangePackDir: string | undefined,
automationDetailsId: string | undefined, automationDetailsId: string | undefined,
@@ -625,6 +627,7 @@ export async function runQueries(
databasePath, databasePath,
queries, queries,
sarifFile, sarifFile,
addSnippetsFlag,
threadsFlag, threadsFlag,
enableDebugLogging ? "-vv" : "-v", enableDebugLogging ? "-vv" : "-v",
sarifRunPropertyFlag, sarifRunPropertyFlag,
@@ -668,7 +671,7 @@ export async function runFinalize(
logger: Logger, logger: Logger,
): Promise<DatabaseCreationTimings> { ): Promise<DatabaseCreationTimings> {
try { try {
await fs.promises.rm(outputDir, { force: true, recursive: true }); await del.deleteAsync(outputDir, { force: true });
} catch (error: any) { } catch (error: any) {
if (error?.code !== "ENOENT") { if (error?.code !== "ENOENT") {
throw error; throw error;

View File

@@ -169,32 +169,4 @@ test("wrapApiConfigurationError correctly wraps specific configuration errors",
res, res,
new util.ConfigurationError("Resource not accessible by integration"), new util.ConfigurationError("Resource not accessible by integration"),
); );
// Enablement errors.
const enablementErrorMessages = [
"Code Security must be enabled for this repository to use code scanning",
"Advanced Security must be enabled for this repository to use code scanning",
"Code Scanning is not enabled for this repository. Please enable code scanning in the repository settings.",
];
const transforms = [
(msg: string) => msg,
(msg: string) => msg.toLowerCase(),
(msg: string) => msg.toLocaleUpperCase(),
];
for (const enablementErrorMessage of enablementErrorMessages) {
for (const transform of transforms) {
const enablementError = new util.HTTPError(
transform(enablementErrorMessage),
403,
);
res = api.wrapApiConfigurationError(enablementError);
t.deepEqual(
res,
new util.ConfigurationError(
api.getFeatureEnablementError(enablementError.message),
),
);
}
}
}); });

View File

@@ -1,6 +1,7 @@
import * as core from "@actions/core"; import * as core from "@actions/core";
import * as githubUtils from "@actions/github/lib/utils"; import * as githubUtils from "@actions/github/lib/utils";
import * as retry from "@octokit/plugin-retry"; import * as retry from "@octokit/plugin-retry";
import consoleLogLevel from "console-log-level";
import { getActionVersion, getRequiredInput } from "./actions-util"; import { getActionVersion, getRequiredInput } from "./actions-util";
import { Logger } from "./logging"; import { Logger } from "./logging";
@@ -49,12 +50,7 @@ function createApiClientWithDetails(
githubUtils.getOctokitOptions(auth, { githubUtils.getOctokitOptions(auth, {
baseUrl: apiDetails.apiURL, baseUrl: apiDetails.apiURL,
userAgent: `CodeQL-Action/${getActionVersion()}`, userAgent: `CodeQL-Action/${getActionVersion()}`,
log: { log: consoleLogLevel({ level: "debug" }),
debug: core.debug,
info: core.info,
warn: core.warning,
error: core.error,
},
}), }),
); );
} }
@@ -283,20 +279,6 @@ export async function getRepositoryProperties(repositoryNwo: RepositoryNwo) {
}); });
} }
function isEnablementError(msg: string) {
return [
/Code Security must be enabled/i,
/Advanced Security must be enabled/i,
/Code Scanning is not enabled/i,
].some((pattern) => pattern.test(msg));
}
// TODO: Move to `error-messages.ts` after refactoring import order to avoid cycle
// since `error-messages.ts` currently depends on this file.
export function getFeatureEnablementError(message: string): string {
return `Please verify that the necessary features are enabled: ${message}`;
}
export function wrapApiConfigurationError(e: unknown) { export function wrapApiConfigurationError(e: unknown) {
const httpError = asHTTPError(e); const httpError = asHTTPError(e);
if (httpError !== undefined) { if (httpError !== undefined) {
@@ -318,11 +300,6 @@ export function wrapApiConfigurationError(e: unknown) {
"Please check that your token is valid and has the required permissions: contents: read, security-events: write", "Please check that your token is valid and has the required permissions: contents: read, security-events: write",
); );
} }
if (httpError.status === 403 && isEnablementError(httpError.message)) {
return new ConfigurationError(
getFeatureEnablementError(httpError.message),
);
}
if (httpError.status === 429) { if (httpError.status === 429) {
return new ConfigurationError("API rate limit exceeded"); return new ConfigurationError("API rate limit exceeded");
} }

View File

@@ -5,6 +5,7 @@ import * as toolrunner from "@actions/exec/lib/toolrunner";
import * as io from "@actions/io"; import * as io from "@actions/io";
import * as toolcache from "@actions/tool-cache"; import * as toolcache from "@actions/tool-cache";
import test, { ExecutionContext } from "ava"; import test, { ExecutionContext } from "ava";
import * as del from "del";
import * as yaml from "js-yaml"; import * as yaml from "js-yaml";
import nock from "nock"; import nock from "nock";
import * as sinon from "sinon"; import * as sinon from "sinon";
@@ -556,7 +557,7 @@ const injectedConfigMacro = test.macro({
const augmentedConfig = yaml.load(fs.readFileSync(configFile, "utf8")); const augmentedConfig = yaml.load(fs.readFileSync(configFile, "utf8"));
t.deepEqual(augmentedConfig, expectedConfig); t.deepEqual(augmentedConfig, expectedConfig);
await fs.promises.rm(configFile, { force: true }); await del.deleteAsync(configFile, { force: true });
}); });
}, },
@@ -1045,7 +1046,7 @@ test("Avoids duplicating --overwrite flag if specified in CODEQL_ACTION_EXTRA_OP
); );
t.truthy(configArg, "Should have injected a codescanning config"); t.truthy(configArg, "Should have injected a codescanning config");
const configFile = configArg!.split("=")[1]; const configFile = configArg!.split("=")[1];
await fs.promises.rm(configFile, { force: true }); await del.deleteAsync(configFile, { force: true });
}); });
export function stubToolRunnerConstructor( export function stubToolRunnerConstructor(

View File

@@ -167,6 +167,7 @@ export interface CodeQL {
databasePath: string, databasePath: string,
querySuitePaths: string[] | undefined, querySuitePaths: string[] | undefined,
sarifFile: string, sarifFile: string,
addSnippetsFlag: string,
threadsFlag: string, threadsFlag: string,
verbosityFlag: string | undefined, verbosityFlag: string | undefined,
sarifRunPropertyFlag: string | undefined, sarifRunPropertyFlag: string | undefined,
@@ -816,6 +817,7 @@ export async function getCodeQLForCmd(
databasePath: string, databasePath: string,
querySuitePaths: string[] | undefined, querySuitePaths: string[] | undefined,
sarifFile: string, sarifFile: string,
addSnippetsFlag: string,
threadsFlag: string, threadsFlag: string,
verbosityFlag: string, verbosityFlag: string,
sarifRunPropertyFlag: string | undefined, sarifRunPropertyFlag: string | undefined,
@@ -834,6 +836,7 @@ export async function getCodeQLForCmd(
"--format=sarif-latest", "--format=sarif-latest",
verbosityFlag, verbosityFlag,
`--output=${sarifFile}`, `--output=${sarifFile}`,
addSnippetsFlag,
"--print-diagnostics-summary", "--print-diagnostics-summary",
"--print-metrics-summary", "--print-metrics-summary",
"--sarif-add-baseline-file-info", "--sarif-add-baseline-file-info",

View File

@@ -5,6 +5,7 @@ import * as artifact from "@actions/artifact";
import * as artifactLegacy from "@actions/artifact-legacy"; import * as artifactLegacy from "@actions/artifact-legacy";
import * as core from "@actions/core"; import * as core from "@actions/core";
import archiver from "archiver"; import archiver from "archiver";
import * as del from "del";
import { getOptionalInput, getTemporaryDirectory } from "./actions-util"; import { getOptionalInput, getTemporaryDirectory } from "./actions-util";
import { dbIsFinalized } from "./analyze"; import { dbIsFinalized } from "./analyze";
@@ -344,7 +345,7 @@ async function createPartialDatabaseBundle(
); );
// See `bundleDb` for explanation behind deleting existing db bundle. // See `bundleDb` for explanation behind deleting existing db bundle.
if (fs.existsSync(databaseBundlePath)) { if (fs.existsSync(databaseBundlePath)) {
await fs.promises.rm(databaseBundlePath, { force: true }); await del.deleteAsync(databaseBundlePath, { force: true });
} }
const output = fs.createWriteStream(databaseBundlePath); const output = fs.createWriteStream(databaseBundlePath);
const zip = archiver("zip"); const zip = archiver("zip");

View File

@@ -137,10 +137,4 @@ export enum EnvVar {
* This setting is more specific than `CODEQL_ACTION_TEST_MODE`, which implies this option. * This setting is more specific than `CODEQL_ACTION_TEST_MODE`, which implies this option.
*/ */
SKIP_SARIF_UPLOAD = "CODEQL_ACTION_SKIP_SARIF_UPLOAD", SKIP_SARIF_UPLOAD = "CODEQL_ACTION_SKIP_SARIF_UPLOAD",
/**
* Whether to skip workflow validation. Intended for internal use, where we know that
* the workflow is valid and validation is not necessary.
*/
SKIP_WORKFLOW_VALIDATION = "CODEQL_ACTION_SKIP_WORKFLOW_VALIDATION",
} }

View File

@@ -86,7 +86,7 @@ import {
getErrorMessage, getErrorMessage,
BuildMode, BuildMode,
} from "./util"; } from "./util";
import { checkWorkflow } from "./workflow"; import { validateWorkflow } from "./workflow";
/** /**
* Sends a status report indicating that the `init` Action is starting. * Sends a status report indicating that the `init` Action is starting.
@@ -288,9 +288,16 @@ async function run() {
toolsSource = initCodeQLResult.toolsSource; toolsSource = initCodeQLResult.toolsSource;
zstdAvailability = initCodeQLResult.zstdAvailability; zstdAvailability = initCodeQLResult.zstdAvailability;
// Check the workflow for problems. If there are any problems, they are reported core.startGroup("Validating workflow");
// to the workflow log. No exceptions are thrown. const validateWorkflowResult = await validateWorkflow(codeql, logger);
await checkWorkflow(logger, codeql); if (validateWorkflowResult === undefined) {
logger.info("Detected no issues with the code scanning workflow.");
} else {
logger.warning(
`Unable to validate code scanning workflow: ${validateWorkflowResult}`,
);
}
core.endGroup();
// Set CODEQL_ENABLE_EXPERIMENTAL_FEATURES for Rust if between 2.19.3 (included) and 2.22.1 (excluded) // Set CODEQL_ENABLE_EXPERIMENTAL_FEATURES for Rust if between 2.19.3 (included) and 2.22.1 (excluded)
// We need to set this environment variable before initializing the config, otherwise Rust // We need to set this environment variable before initializing the config, otherwise Rust

View File

@@ -13,15 +13,7 @@ export interface Logger {
} }
export function getActionsLogger(): Logger { export function getActionsLogger(): Logger {
return { return core;
debug: core.debug,
info: core.info,
warning: core.warning,
error: core.error,
isDebug: core.isDebug,
startGroup: core.startGroup,
endGroup: core.endGroup,
};
} }
export function getRunnerLogger(debugMode: boolean): Logger { export function getRunnerLogger(debugMode: boolean): Logger {

View File

@@ -9,7 +9,7 @@ import * as semver from "semver";
import { CommandInvocationError } from "./actions-util"; import { CommandInvocationError } from "./actions-util";
import { Logger } from "./logging"; import { Logger } from "./logging";
import { assertNever, cleanUpPath, isBinaryAccessible } from "./util"; import { assertNever, cleanUpGlob, isBinaryAccessible } from "./util";
const MIN_REQUIRED_BSD_TAR_VERSION = "3.4.3"; const MIN_REQUIRED_BSD_TAR_VERSION = "3.4.3";
const MIN_REQUIRED_GNU_TAR_VERSION = "1.31"; const MIN_REQUIRED_GNU_TAR_VERSION = "1.31";
@@ -217,7 +217,7 @@ export async function extractTarZst(
}); });
}); });
} catch (e) { } catch (e) {
await cleanUpPath(dest, "extraction destination directory", logger); await cleanUpGlob(dest, "extraction destination directory", logger);
throw e; throw e;
} }
} }

View File

@@ -12,7 +12,7 @@ import * as semver from "semver";
import { formatDuration, Logger } from "./logging"; import { formatDuration, Logger } from "./logging";
import * as tar from "./tar"; import * as tar from "./tar";
import { cleanUpPath, getErrorMessage, getRequiredEnvParam } from "./util"; import { cleanUpGlob, getErrorMessage, getRequiredEnvParam } from "./util";
/** /**
* High watermark to use when streaming the download and extraction of the CodeQL tools. * High watermark to use when streaming the download and extraction of the CodeQL tools.
@@ -130,7 +130,7 @@ export async function downloadAndExtract(
// If we failed during processing, we want to clean up the destination directory // If we failed during processing, we want to clean up the destination directory
// before we try again. // before we try again.
await cleanUpPath(dest, "CodeQL bundle", logger); await cleanUpGlob(dest, "CodeQL bundle", logger);
} }
const toolsDownloadStart = performance.now(); const toolsDownloadStart = performance.now();
@@ -167,7 +167,7 @@ export async function downloadAndExtract(
)}).`, )}).`,
); );
} finally { } finally {
await cleanUpPath(archivedBundlePath, "CodeQL bundle archive", logger); await cleanUpGlob(archivedBundlePath, "CodeQL bundle archive", logger);
} }
return { return {

View File

@@ -101,6 +101,16 @@ test("getMemoryFlag() throws if the ram input is < 0 or NaN", async (t) => {
} }
}); });
test("getAddSnippetsFlag() should return the correct flag", (t) => {
t.deepEqual(util.getAddSnippetsFlag(true), "--sarif-add-snippets");
t.deepEqual(util.getAddSnippetsFlag("true"), "--sarif-add-snippets");
t.deepEqual(util.getAddSnippetsFlag(false), "--no-sarif-add-snippets");
t.deepEqual(util.getAddSnippetsFlag(undefined), "--no-sarif-add-snippets");
t.deepEqual(util.getAddSnippetsFlag("false"), "--no-sarif-add-snippets");
t.deepEqual(util.getAddSnippetsFlag("foo bar"), "--no-sarif-add-snippets");
});
test("getThreadsFlag() should return the correct --threads flag", (t) => { test("getThreadsFlag() should return the correct --threads flag", (t) => {
const numCpus = os.cpus().length; const numCpus = os.cpus().length;
@@ -524,12 +534,3 @@ test("getCgroupCpuCountFromCpus returns undefined if the CPU file exists but is
); );
}); });
}); });
test("checkDiskUsage succeeds and produces positive numbers", async (t) => {
process.env["GITHUB_WORKSPACE"] = os.tmpdir();
const diskUsage = await util.checkDiskUsage(getRunnerLogger(true));
if (t.truthy(diskUsage)) {
t.true(diskUsage.numAvailableBytes > 0);
t.true(diskUsage.numTotalBytes > 0);
}
});

View File

@@ -6,6 +6,7 @@ import * as path from "path";
import * as core from "@actions/core"; import * as core from "@actions/core";
import * as exec from "@actions/exec/lib/exec"; import * as exec from "@actions/exec/lib/exec";
import * as io from "@actions/io"; import * as io from "@actions/io";
import * as del from "del";
import getFolderSize from "get-folder-size"; import getFolderSize from "get-folder-size";
import * as yaml from "js-yaml"; import * as yaml from "js-yaml";
import * as semver from "semver"; import * as semver from "semver";
@@ -166,7 +167,7 @@ export async function withTmpDir<T>(
): Promise<T> { ): Promise<T> {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "codeql-action-")); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "codeql-action-"));
const result = await body(tmpDir); const result = await body(tmpDir);
await fs.promises.rm(tmpDir, { force: true, recursive: true }); await del.deleteAsync(tmpDir, { force: true });
return result; return result;
} }
@@ -342,6 +343,21 @@ export function getMemoryFlag(
return `--ram=${megabytes}`; return `--ram=${megabytes}`;
} }
/**
* Get the codeql flag to specify whether to add code snippets to the sarif file.
*
* @returns string
*/
export function getAddSnippetsFlag(
userInput: string | boolean | undefined,
): string {
if (typeof userInput === "string") {
// have to process specifically because any non-empty string is truthy
userInput = userInput.toLowerCase() === "true";
}
return userInput ? "--sarif-add-snippets" : "--no-sarif-add-snippets";
}
/** /**
* Get the value of the codeql `--threads` flag specified for the `threads` * Get the value of the codeql `--threads` flag specified for the `threads`
* input. If no value was specified, all available threads will be used. * input. If no value was specified, all available threads will be used.
@@ -740,7 +756,7 @@ export async function bundleDb(
// from somewhere else or someone trying to make the action upload a // from somewhere else or someone trying to make the action upload a
// non-database file. // non-database file.
if (fs.existsSync(databaseBundlePath)) { if (fs.existsSync(databaseBundlePath)) {
await fs.promises.rm(databaseBundlePath, { force: true }); await del.deleteAsync(databaseBundlePath, { force: true });
} }
await codeql.databaseBundle(databasePath, databaseBundlePath, dbName); await codeql.databaseBundle(databasePath, databaseBundlePath, dbName);
return databaseBundlePath; return databaseBundlePath;
@@ -1240,13 +1256,19 @@ export async function checkSipEnablement(
} }
} }
export async function cleanUpPath(file: string, name: string, logger: Logger) { export async function cleanUpGlob(glob: string, name: string, logger: Logger) {
logger.debug(`Cleaning up ${name}.`); logger.debug(`Cleaning up ${name}.`);
try { try {
await fs.promises.rm(file, { const deletedPaths = await del.deleteAsync(glob, { force: true });
force: true, if (deletedPaths.length === 0) {
recursive: true, logger.warning(
}); `Failed to clean up ${name}: no files found matching ${glob}.`,
);
} else if (deletedPaths.length === 1) {
logger.debug(`Cleaned up ${name}.`);
} else {
logger.debug(`Cleaned up ${name} (${deletedPaths.length} files).`);
}
} catch (e) { } catch (e) {
logger.warning(`Failed to clean up ${name}: ${e}.`); logger.warning(`Failed to clean up ${name}: ${e}.`);
} }

View File

@@ -2,17 +2,9 @@ import test, { ExecutionContext } from "ava";
import * as yaml from "js-yaml"; import * as yaml from "js-yaml";
import * as sinon from "sinon"; import * as sinon from "sinon";
import * as actionsUtil from "./actions-util"; import { getCodeQLForTesting } from "./codeql";
import { createStubCodeQL, getCodeQLForTesting } from "./codeql"; import { setupTests } from "./testing-utils";
import { EnvVar } from "./environment";
import { import {
checkExpectedLogMessages,
getRecordingLogger,
LoggedMessage,
setupTests,
} from "./testing-utils";
import {
checkWorkflow,
CodedError, CodedError,
formatWorkflowCause, formatWorkflowCause,
formatWorkflowErrors, formatWorkflowErrors,
@@ -21,7 +13,6 @@ import {
Workflow, Workflow,
WorkflowErrors, WorkflowErrors,
} from "./workflow"; } from "./workflow";
import * as workflow from "./workflow";
function errorCodes( function errorCodes(
actual: CodedError[], actual: CodedError[],
@@ -879,78 +870,3 @@ test("getCategoryInputOrThrow throws error for workflow with multiple calls to a
}, },
); );
}); });
test("checkWorkflow - validates workflow if `SKIP_WORKFLOW_VALIDATION` is not set", async (t) => {
const messages: LoggedMessage[] = [];
const codeql = createStubCodeQL({});
sinon.stub(actionsUtil, "isDynamicWorkflow").returns(false);
const validateWorkflow = sinon.stub(workflow.internal, "validateWorkflow");
validateWorkflow.resolves(undefined);
await checkWorkflow(getRecordingLogger(messages), codeql);
t.assert(
validateWorkflow.calledOnce,
"`checkWorkflow` unexpectedly did not call `validateWorkflow`",
);
checkExpectedLogMessages(t, messages, [
"Detected no issues with the code scanning workflow.",
]);
});
test("checkWorkflow - logs problems with workflow validation", async (t) => {
const messages: LoggedMessage[] = [];
const codeql = createStubCodeQL({});
sinon.stub(actionsUtil, "isDynamicWorkflow").returns(false);
const validateWorkflow = sinon.stub(workflow.internal, "validateWorkflow");
validateWorkflow.resolves("problem");
await checkWorkflow(getRecordingLogger(messages), codeql);
t.assert(
validateWorkflow.calledOnce,
"`checkWorkflow` unexpectedly did not call `validateWorkflow`",
);
checkExpectedLogMessages(t, messages, [
"Unable to validate code scanning workflow: problem",
]);
});
test("checkWorkflow - skips validation if `SKIP_WORKFLOW_VALIDATION` is `true`", async (t) => {
process.env[EnvVar.SKIP_WORKFLOW_VALIDATION] = "true";
const messages: LoggedMessage[] = [];
const codeql = createStubCodeQL({});
sinon.stub(actionsUtil, "isDynamicWorkflow").returns(false);
const validateWorkflow = sinon.stub(workflow.internal, "validateWorkflow");
await checkWorkflow(getRecordingLogger(messages), codeql);
t.assert(
validateWorkflow.notCalled,
"`checkWorkflow` called `validateWorkflow` unexpectedly",
);
t.is(messages.length, 0);
});
test("checkWorkflow - skips validation for `dynamic` workflows", async (t) => {
const messages: LoggedMessage[] = [];
const codeql = createStubCodeQL({});
const isDynamicWorkflow = sinon
.stub(actionsUtil, "isDynamicWorkflow")
.returns(true);
const validateWorkflow = sinon.stub(workflow.internal, "validateWorkflow");
await checkWorkflow(getRecordingLogger(messages), codeql);
t.assert(isDynamicWorkflow.calledOnce);
t.assert(
validateWorkflow.notCalled,
"`checkWorkflow` called `validateWorkflow` unexpectedly",
);
t.is(messages.length, 0);
});

View File

@@ -5,10 +5,8 @@ import zlib from "zlib";
import * as core from "@actions/core"; import * as core from "@actions/core";
import * as yaml from "js-yaml"; import * as yaml from "js-yaml";
import { isDynamicWorkflow } from "./actions-util";
import * as api from "./api-client"; import * as api from "./api-client";
import { CodeQL } from "./codeql"; import { CodeQL } from "./codeql";
import { EnvVar } from "./environment";
import { Logger } from "./logging"; import { Logger } from "./logging";
import { import {
getRequiredEnvParam, getRequiredEnvParam,
@@ -218,7 +216,7 @@ function hasWorkflowTrigger(triggerName: string, doc: Workflow): boolean {
return Object.prototype.hasOwnProperty.call(doc.on, triggerName); return Object.prototype.hasOwnProperty.call(doc.on, triggerName);
} }
async function validateWorkflow( export async function validateWorkflow(
codeql: CodeQL, codeql: CodeQL,
logger: Logger, logger: Logger,
): Promise<undefined | string> { ): Promise<undefined | string> {
@@ -464,36 +462,3 @@ export function getCheckoutPathInputOrThrow(
) || getRequiredEnvParam("GITHUB_WORKSPACE") // if unspecified, checkout_path defaults to ${{ github.workspace }} ) || getRequiredEnvParam("GITHUB_WORKSPACE") // if unspecified, checkout_path defaults to ${{ github.workspace }}
); );
} }
/**
* A wrapper around `validateWorkflow` which reports the outcome.
*
* @param logger The logger to use.
* @param codeql The CodeQL instance.
*/
export async function checkWorkflow(logger: Logger, codeql: CodeQL) {
// Check the workflow for problems, unless `SKIP_WORKFLOW_VALIDATION` is `true`
// or the workflow trigger is `dynamic`.
if (
!isDynamicWorkflow() &&
process.env[EnvVar.SKIP_WORKFLOW_VALIDATION] !== "true"
) {
core.startGroup("Validating workflow");
const validateWorkflowResult = await internal.validateWorkflow(
codeql,
logger,
);
if (validateWorkflowResult === undefined) {
logger.info("Detected no issues with the code scanning workflow.");
} else {
logger.debug(
`Unable to validate code scanning workflow: ${validateWorkflowResult}`,
);
}
core.endGroup();
}
}
export const internal = {
validateWorkflow,
};