mirror of
https://github.com/github/codeql-action.git
synced 2026-08-06 05:07:52 -05:00
Compare commits
162 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ff3337ee1b | |||
| 484236cda4 | |||
| f837e8e761 | |||
| ef21864950 | |||
| 4789c1331c | |||
| 59ebabde5d | |||
| 3224214d91 | |||
| e09fbf5b4a | |||
| e9ff99b027 | |||
| 8b9e982393 | |||
| 8d1e008ecb | |||
| 579411fb6c | |||
| e4818d46c4 | |||
| 4778dfbd93 | |||
| 0a3f985290 | |||
| 04f1897968 | |||
| 6ac6037211 | |||
| 959cbb7472 | |||
| 10ca836463 | |||
| d58039a1e3 | |||
| 37a4496237 | |||
| b7028afcb4 | |||
| f629dada4c | |||
| ccee4c68ff | |||
| 899bf9c076 | |||
| dd7c3ef80e | |||
| b7b875efff | |||
| 53ab991fbe | |||
| 54d25f56dd | |||
| d827cf3d65 | |||
| 9438015b82 | |||
| 5aced81848 | |||
| 118e294bb9 | |||
| dc9c1c1a51 | |||
| a409f43c7a | |||
| e67ad6aaed | |||
| 896079047b | |||
| e58b8d6a61 | |||
| 01330498de | |||
| a669cc5936 | |||
| 6fec2ab57a | |||
| aab7a26877 | |||
| 2b971a70bb | |||
| 4e81e2933a | |||
| bf944d782b | |||
| 566a5e6727 | |||
| 10c89976dc | |||
| 8121f62c54 | |||
| 104319fe98 | |||
| aba18b82f7 | |||
| 4a5ad5af18 | |||
| 19f867a052 | |||
| 5e452f0d9d | |||
| 8bebf77dbd | |||
| fb74504ab5 | |||
| c51babb6c6 | |||
| 79166d0788 | |||
| 44ef9d902a | |||
| 384a214d60 | |||
| 697ed97fa5 | |||
| 2207a72006 | |||
| 4623c8edb6 | |||
| 9085295c40 | |||
| 3b0a2f607d | |||
| 5566638d56 | |||
| 27c1438455 | |||
| 1e8d3b8fca | |||
| 7fc528c3c6 | |||
| 2cbc140ac5 | |||
| 1653364141 | |||
| 61cc378b7f | |||
| 7aa5026a55 | |||
| c80f00a5c9 | |||
| 62b14cbbad | |||
| 794a4b543a | |||
| ee6ba9c213 | |||
| 81f99a8582 | |||
| 4b18b7bc24 | |||
| 4acf201e5b | |||
| 1e5919b22d | |||
| 375dacad24 | |||
| e0ff272230 | |||
| aa0e650c6a | |||
| 98b2ddc7f9 | |||
| 0d9b15ca93 | |||
| b1c26c4c53 | |||
| 21044b004d | |||
| 0828b04e3a | |||
| b2a92eb56d | |||
| 075b74d36e | |||
| 9af9a11da8 | |||
| a631f4b016 | |||
| 77cda4d75d | |||
| 3d90c4f911 | |||
| 1384ce4ab3 | |||
| 6c5cad784c | |||
| 58b2ab08a8 | |||
| e0dec83cfc | |||
| 00a3c456fb | |||
| e628ee0ae1 | |||
| 605b23d10b | |||
| 160613c380 | |||
| caf1c5057b | |||
| c62445de22 | |||
| 7fc3c603aa | |||
| 24fd4c0f4e | |||
| d0517be03a | |||
| 37b4358e44 | |||
| 122b180b66 | |||
| 8337c2be0f | |||
| 5296a763b1 | |||
| 3afc2b194c | |||
| 3cf2a1ba2e | |||
| 4d4e25083a | |||
| 9de6c31571 | |||
| 44ae944a29 | |||
| e2338066a1 | |||
| 8f05fcd048 | |||
| 9dac9f748a | |||
| c6e756bb39 | |||
| 8d8b898c0f | |||
| 312e093a18 | |||
| aef0440821 | |||
| 9f2aa7ec75 | |||
| 7e73dedacc | |||
| 102e01da36 | |||
| eb19ecbad1 | |||
| f0a052e8b4 | |||
| ead8da6199 | |||
| c61f4c61f8 | |||
| ad7ca9bf21 | |||
| f79028af27 | |||
| 909c8687d5 | |||
| 5b7c9daecd | |||
| ce90479412 | |||
| bff0be7364 | |||
| daf4614f68 | |||
| e2d523ca5e | |||
| 996d04b1e5 | |||
| 79f8286c68 | |||
| d52e657b2e | |||
| 187515b328 | |||
| bc341c5dd1 | |||
| 39fe7aa8a1 | |||
| c719ec0b33 | |||
| 09bfd560f6 | |||
| 33b2045510 | |||
| 93c6b70dc3 | |||
| def4f60c6c | |||
| 34d91a9ce7 | |||
| c49c05b5df | |||
| 2ccaddd459 | |||
| 5dcca8a6e4 | |||
| b6e17a6616 | |||
| e9e73b0cb9 | |||
| bab5a146ac | |||
| 6013661451 | |||
| 26df9a9a4f | |||
| 4ee97e5e55 | |||
| cfce1c4e19 | |||
| da75623c67 | |||
| c29fca48a1 |
+9
-12
@@ -1,20 +1,17 @@
|
|||||||
version: 2
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
- package-ecosystem: "npm"
|
- package-ecosystem: npm
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: weekly
|
||||||
day: "thursday" # Gives us a working day to merge this before our typical release
|
|
||||||
labels:
|
labels:
|
||||||
- "Update dependencies"
|
- Update dependencies
|
||||||
ignore:
|
ignore:
|
||||||
- dependency-name: "*"
|
- dependency-name: "*"
|
||||||
update-types: ["version-update:semver-minor", "version-update:semver-patch"]
|
update-types:
|
||||||
- package-ecosystem: "npm"
|
- version-update:semver-minor
|
||||||
directory: "/runner"
|
- version-update:semver-patch
|
||||||
|
- package-ecosystem: github-actions
|
||||||
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: weekly
|
||||||
day: "thursday" # Gives us a working day to merge this before our typical release
|
|
||||||
ignore:
|
|
||||||
- dependency-name: "*"
|
|
||||||
update-types: ["version-update:semver-minor", "version-update:semver-patch"]
|
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
name: "Set up Swift"
|
||||||
|
description: Performs necessary steps to set up appropriate Swift version.
|
||||||
|
inputs:
|
||||||
|
codeql-path:
|
||||||
|
required: true
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Get Swift version
|
||||||
|
id: get_swift_version
|
||||||
|
# We don't support Swift on Windows or prior versions of CLI.
|
||||||
|
if: "(runner.os != 'Windows') && (matrix.version == 'cached' || matrix.version == 'latest' || matrix.version == 'nightly-latest')"
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
CODEQL_PATH: ${{inputs.codeql-path}}
|
||||||
|
run: |
|
||||||
|
if [ $RUNNER_OS = "macOS" ]; then
|
||||||
|
PLATFORM="osx64"
|
||||||
|
else # We do not run this step on Windows.
|
||||||
|
PLATFORM="linux64"
|
||||||
|
fi
|
||||||
|
SWIFT_EXTRACTOR_DIR="$("$CODEQL_PATH" resolve languages --format json | jq -r '.swift[0]')"
|
||||||
|
VERSION="$("$SWIFT_EXTRACTOR_DIR/tools/$PLATFORM/extractor" --version | awk '/version/ { print $3 }')"
|
||||||
|
# Specify 5.7.0, otherwise setup Action will default to latest minor version.
|
||||||
|
if [ $VERSION = "5.7" ]; then
|
||||||
|
VERSION="5.7.0"
|
||||||
|
fi
|
||||||
|
echo "version=$VERSION" | tee -a $GITHUB_OUTPUT
|
||||||
|
- uses: swift-actions/setup-swift@194625b58a582570f61cc707c3b558086c26b723
|
||||||
|
if: "(runner.os != 'Windows') && (matrix.version == 'cached' || matrix.version == 'latest' || matrix.version == 'nightly-latest')"
|
||||||
|
with:
|
||||||
|
swift-version: "${{steps.get_swift_version.outputs.version}}"
|
||||||
+5
-2
@@ -43,12 +43,15 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
version: ${{ matrix.version }}
|
version: ${{ matrix.version }}
|
||||||
- uses: ./../action/init
|
- uses: ./../action/init
|
||||||
|
id: init
|
||||||
with:
|
with:
|
||||||
languages: javascript
|
languages: javascript
|
||||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
env:
|
env:
|
||||||
CODEQL_FILE_BASELINE_INFORMATION: true
|
CODEQL_FILE_BASELINE_INFORMATION: true
|
||||||
CODEQL_ENABLE_EXPERIMENTAL_FEATURES_SWIFT: true
|
- uses: ./../action/.github/setup-swift
|
||||||
|
with:
|
||||||
|
codeql-path: ${{steps.init.outputs.codeql-path}}
|
||||||
- name: Build code
|
- name: Build code
|
||||||
shell: bash
|
shell: bash
|
||||||
run: ./build.sh
|
run: ./build.sh
|
||||||
@@ -57,7 +60,6 @@ jobs:
|
|||||||
output: ${{ runner.temp }}/results
|
output: ${{ runner.temp }}/results
|
||||||
env:
|
env:
|
||||||
CODEQL_FILE_BASELINE_INFORMATION: true
|
CODEQL_FILE_BASELINE_INFORMATION: true
|
||||||
CODEQL_ENABLE_EXPERIMENTAL_FEATURES_SWIFT: true
|
|
||||||
- name: Upload SARIF
|
- name: Upload SARIF
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
@@ -82,4 +84,5 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
env:
|
env:
|
||||||
|
CODEQL_ENABLE_EXPERIMENTAL_FEATURES_SWIFT: true # Remove when Swift is GA.
|
||||||
CODEQL_ACTION_TEST_MODE: true
|
CODEQL_ACTION_TEST_MODE: true
|
||||||
|
|||||||
+2
-3
@@ -87,8 +87,7 @@ jobs:
|
|||||||
- name: Check sarif
|
- name: Check sarif
|
||||||
uses: ./../action/.github/check-sarif
|
uses: ./../action/.github/check-sarif
|
||||||
# Running on Windows requires CodeQL CLI 2.9.0+.
|
# Running on Windows requires CodeQL CLI 2.9.0+.
|
||||||
if: "!(matrix.version == 'stable-20220120' && (matrix.os == 'windows-latest'\
|
if: "!(matrix.version == 'stable-20220120' && runner.os == 'Windows')"
|
||||||
\ || matrix.os == 'windows-2019'))"
|
|
||||||
with:
|
with:
|
||||||
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
sarif-file: ${{ runner.temp }}/results/javascript.sarif
|
||||||
queries-run: js/ml-powered/nosql-injection,js/ml-powered/path-injection,js/ml-powered/sql-injection,js/ml-powered/xss
|
queries-run: js/ml-powered/nosql-injection,js/ml-powered/path-injection,js/ml-powered/sql-injection,js/ml-powered/xss
|
||||||
@@ -98,7 +97,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
# Running on Windows requires CodeQL CLI 2.9.0+.
|
# Running on Windows requires CodeQL CLI 2.9.0+.
|
||||||
SHOULD_RUN_ML_POWERED_QUERIES: ${{ !(matrix.version == 'stable-20220120' &&
|
SHOULD_RUN_ML_POWERED_QUERIES: ${{ !(matrix.version == 'stable-20220120' &&
|
||||||
(matrix.os == 'windows-latest' || matrix.os == 'windows-2019')) }}
|
runner.os == 'Windows') }}
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
echo "Expecting ML-powered queries to be run: ${SHOULD_RUN_ML_POWERED_QUERIES}"
|
echo "Expecting ML-powered queries to be run: ${SHOULD_RUN_ML_POWERED_QUERIES}"
|
||||||
|
|||||||
+33
-1
@@ -66,15 +66,24 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: ^1.13.1
|
go-version: ^1.13.1
|
||||||
- uses: ./../action/init
|
- uses: ./../action/init
|
||||||
|
id: init
|
||||||
with:
|
with:
|
||||||
db-location: ${{ runner.temp }}/customDbLocation
|
db-location: ${{ runner.temp }}/customDbLocation
|
||||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
|
||||||
|
- uses: ./../action/.github/setup-swift
|
||||||
|
with:
|
||||||
|
codeql-path: ${{steps.init.outputs.codeql-path}}
|
||||||
|
|
||||||
- name: Build code
|
- name: Build code
|
||||||
shell: bash
|
shell: bash
|
||||||
run: ./build.sh
|
run: ./build.sh
|
||||||
|
|
||||||
- uses: ./../action/analyze
|
- uses: ./../action/analyze
|
||||||
id: analysis
|
id: analysis
|
||||||
- shell: bash
|
|
||||||
|
- name: Check language autodetect for all languages excluding Ruby, Swift
|
||||||
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
CPP_DB=${{ fromJson(steps.analysis.outputs.db-locations).cpp }}
|
CPP_DB=${{ fromJson(steps.analysis.outputs.db-locations).cpp }}
|
||||||
if [[ ! -d $CPP_DB ]] || [[ ! $CPP_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
|
if [[ ! -d $CPP_DB ]] || [[ ! $CPP_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
|
||||||
@@ -106,5 +115,28 @@ jobs:
|
|||||||
echo "Did not create a database for Python, or created it in the wrong location."
|
echo "Did not create a database for Python, or created it in the wrong location."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
- name: Check language autodetect for Ruby
|
||||||
|
if: (matrix.version == 'cached' || matrix.version == 'latest' || matrix.version
|
||||||
|
== 'nightly-latest')
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
RUBY_DB=${{ fromJson(steps.analysis.outputs.db-locations).ruby }}
|
||||||
|
if [[ ! -d $RUBY_DB ]] || [[ ! $RUBY_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
|
||||||
|
echo "Did not create a database for Ruby, or created it in the wrong location."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check language autodetect for Swift
|
||||||
|
if: (matrix.version == 'cached' || matrix.version == 'latest' || matrix.version
|
||||||
|
== 'nightly-latest')
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
SWIFT_DB=${{ fromJson(steps.analysis.outputs.db-locations).swift }}
|
||||||
|
if [[ ! -d $SWIFT_DB ]] || [[ ! $SWIFT_DB == ${{ runner.temp }}/customDbLocation/* ]]; then
|
||||||
|
echo "Did not create a database for Swift, or created it in the wrong location."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
env:
|
env:
|
||||||
|
CODEQL_ENABLE_EXPERIMENTAL_FEATURES_SWIFT: 'true' # Remove when Swift is GA.
|
||||||
CODEQL_ACTION_TEST_MODE: true
|
CODEQL_ACTION_TEST_MODE: true
|
||||||
|
|||||||
Generated
-66
@@ -1,66 +0,0 @@
|
|||||||
# Warning: This file is generated automatically, and should not be modified.
|
|
||||||
# Instead, please modify the template in the pr-checks directory and run:
|
|
||||||
# pip install ruamel.yaml && python3 sync.py
|
|
||||||
# to regenerate this file.
|
|
||||||
|
|
||||||
name: PR Check - Ruby analysis using autodetect
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
GO111MODULE: auto
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- releases/v1
|
|
||||||
- releases/v2
|
|
||||||
pull_request:
|
|
||||||
types:
|
|
||||||
- opened
|
|
||||||
- synchronize
|
|
||||||
- reopened
|
|
||||||
- ready_for_review
|
|
||||||
workflow_dispatch: {}
|
|
||||||
jobs:
|
|
||||||
ruby-autodetect:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- os: ubuntu-latest
|
|
||||||
version: latest
|
|
||||||
- os: macos-latest
|
|
||||||
version: latest
|
|
||||||
- os: ubuntu-latest
|
|
||||||
version: cached
|
|
||||||
- os: macos-latest
|
|
||||||
version: cached
|
|
||||||
- os: ubuntu-latest
|
|
||||||
version: nightly-latest
|
|
||||||
- os: macos-latest
|
|
||||||
version: nightly-latest
|
|
||||||
name: Ruby analysis using autodetect
|
|
||||||
timeout-minutes: 45
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- name: Check out repository
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Prepare test
|
|
||||||
id: prepare-test
|
|
||||||
uses: ./.github/prepare-test
|
|
||||||
with:
|
|
||||||
version: ${{ matrix.version }}
|
|
||||||
- uses: ./../action/init
|
|
||||||
with:
|
|
||||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
|
||||||
- uses: ./../action/analyze
|
|
||||||
id: analysis
|
|
||||||
- name: Check database
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
RUBY_DB="${{ fromJson(steps.analysis.outputs.db-locations).ruby }}"
|
|
||||||
if [[ ! -d "$RUBY_DB" ]]; then
|
|
||||||
echo "Did not create a database for Ruby."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
env:
|
|
||||||
CODEQL_ENABLE_EXPERIMENTAL_FEATURES: 'true'
|
|
||||||
CODEQL_ACTION_TEST_MODE: true
|
|
||||||
Generated
-1
@@ -63,5 +63,4 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
env:
|
env:
|
||||||
CODEQL_ENABLE_EXPERIMENTAL_FEATURES: 'true'
|
|
||||||
CODEQL_ACTION_TEST_MODE: true
|
CODEQL_ACTION_TEST_MODE: true
|
||||||
|
|||||||
+72
@@ -0,0 +1,72 @@
|
|||||||
|
# Warning: This file is generated automatically, and should not be modified.
|
||||||
|
# Instead, please modify the template in the pr-checks directory and run:
|
||||||
|
# pip install ruamel.yaml && python3 sync.py
|
||||||
|
# to regenerate this file.
|
||||||
|
|
||||||
|
name: PR Check - Submit SARIF after failure
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GO111MODULE: auto
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- releases/v1
|
||||||
|
- releases/v2
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- synchronize
|
||||||
|
- reopened
|
||||||
|
- ready_for_review
|
||||||
|
workflow_dispatch: {}
|
||||||
|
jobs:
|
||||||
|
submit-sarif-failure:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
version: latest
|
||||||
|
- os: ubuntu-latest
|
||||||
|
version: cached
|
||||||
|
- os: ubuntu-latest
|
||||||
|
version: nightly-latest
|
||||||
|
name: Submit SARIF after failure
|
||||||
|
timeout-minutes: 45
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Prepare test
|
||||||
|
id: prepare-test
|
||||||
|
uses: ./.github/prepare-test
|
||||||
|
with:
|
||||||
|
version: ${{ matrix.version }}
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: ./init
|
||||||
|
with:
|
||||||
|
languages: javascript
|
||||||
|
- name: Fail
|
||||||
|
# We want this job to pass if the Action correctly uploads the SARIF file for
|
||||||
|
# the failed run.
|
||||||
|
# Setting this step to continue on error means that it is marked as completing
|
||||||
|
# successfully, so will not fail the job.
|
||||||
|
continue-on-error: true
|
||||||
|
run: exit 1
|
||||||
|
- uses: ./analyze
|
||||||
|
# In a real workflow, this step wouldn't run. Since we used `continue-on-error`
|
||||||
|
# above, we manually disable it with an `if` condition.
|
||||||
|
if: false
|
||||||
|
with:
|
||||||
|
category: /test-codeql-version:${{ matrix.version }}
|
||||||
|
env:
|
||||||
|
# Internal-only environment variable used to indicate that the post-init Action
|
||||||
|
# should expect to upload a SARIF file for the failed run.
|
||||||
|
CODEQL_ACTION_EXPECT_UPLOAD_FAILED_SARIF: true
|
||||||
|
# Make sure the uploading SARIF files feature is enabled.
|
||||||
|
CODEQL_ACTION_UPLOAD_FAILED_SARIF: true
|
||||||
|
# Upload the failed SARIF file as an integration test of the API endpoint.
|
||||||
|
CODEQL_ACTION_TEST_MODE: false
|
||||||
|
# Mark telemetry for this workflow so it can be treated separately.
|
||||||
|
CODEQL_ACTION_TESTING_ENVIRONMENT: codeql-action-pr-checks
|
||||||
|
|
||||||
Generated
+8
-1
@@ -43,9 +43,16 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
version: ${{ matrix.version }}
|
version: ${{ matrix.version }}
|
||||||
- uses: ./../action/init
|
- uses: ./../action/init
|
||||||
|
id: init
|
||||||
with:
|
with:
|
||||||
languages: swift
|
languages: swift
|
||||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
- uses: ./../action/.github/setup-swift
|
||||||
|
with:
|
||||||
|
codeql-path: ${{steps.init.outputs.codeql-path}}
|
||||||
|
- name: Check working directory
|
||||||
|
shell: bash
|
||||||
|
run: pwd
|
||||||
- uses: ./../action/autobuild
|
- uses: ./../action/autobuild
|
||||||
- uses: ./../action/analyze
|
- uses: ./../action/analyze
|
||||||
id: analysis
|
id: analysis
|
||||||
@@ -58,5 +65,5 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
env:
|
env:
|
||||||
CODEQL_ENABLE_EXPERIMENTAL_FEATURES_SWIFT: 'true'
|
CODEQL_ENABLE_EXPERIMENTAL_FEATURES_SWIFT: 'true' # Remove when Swift is GA.
|
||||||
CODEQL_ACTION_TEST_MODE: true
|
CODEQL_ACTION_TEST_MODE: true
|
||||||
|
|||||||
+8
-1
@@ -49,9 +49,16 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
version: ${{ matrix.version }}
|
version: ${{ matrix.version }}
|
||||||
- uses: ./../action/init
|
- uses: ./../action/init
|
||||||
|
id: init
|
||||||
with:
|
with:
|
||||||
languages: swift
|
languages: swift
|
||||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||||
|
- uses: ./../action/.github/setup-swift
|
||||||
|
with:
|
||||||
|
codeql-path: ${{steps.init.outputs.codeql-path}}
|
||||||
|
- name: Check working directory
|
||||||
|
shell: bash
|
||||||
|
run: pwd
|
||||||
- name: Build code
|
- name: Build code
|
||||||
shell: bash
|
shell: bash
|
||||||
run: ./build.sh
|
run: ./build.sh
|
||||||
@@ -66,6 +73,6 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
env:
|
env:
|
||||||
CODEQL_ENABLE_EXPERIMENTAL_FEATURES_SWIFT: 'true'
|
CODEQL_ENABLE_EXPERIMENTAL_FEATURES_SWIFT: 'true' # Remove when Swift is GA.
|
||||||
DOTNET_GENERATE_ASPNET_CERTIFICATE: 'false'
|
DOTNET_GENERATE_ASPNET_CERTIFICATE: 'false'
|
||||||
CODEQL_ACTION_TEST_MODE: true
|
CODEQL_ACTION_TEST_MODE: true
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ on:
|
|||||||
# Run checks on reopened draft PRs to support triggering PR checks on draft PRs that were opened
|
# Run checks on reopened draft PRs to support triggering PR checks on draft PRs that were opened
|
||||||
# by other workflows.
|
# by other workflows.
|
||||||
types: [opened, synchronize, reopened, ready_for_review]
|
types: [opened, synchronize, reopened, ready_for_review]
|
||||||
|
schedule:
|
||||||
|
# Weekly on Sunday.
|
||||||
|
- cron: '30 1 * * 0'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CODEQL_ACTION_TESTING_ENVIRONMENT: codeql-action-pr-checks
|
CODEQL_ACTION_TESTING_ENVIRONMENT: codeql-action-pr-checks
|
||||||
@@ -54,7 +57,7 @@ jobs:
|
|||||||
# be the same as `tools: null`. This allows us to make the job for each of the bundles a
|
# be the same as `tools: null`. This allows us to make the job for each of the bundles a
|
||||||
# required status check.
|
# required status check.
|
||||||
#
|
#
|
||||||
# If we're running on push, then we can skip running with `tools: latest` when it would be
|
# If we're running on push or schedule, then we can skip running with `tools: latest` when it would be
|
||||||
# the same as running with `tools: null`.
|
# the same as running with `tools: null`.
|
||||||
if [[ "$GITHUB_EVENT_NAME" != "pull_request" && "$CODEQL_VERSION_DEFAULT" == "$CODEQL_VERSION_LATEST" ]]; then
|
if [[ "$GITHUB_EVENT_NAME" != "pull_request" && "$CODEQL_VERSION_DEFAULT" == "$CODEQL_VERSION_LATEST" ]]; then
|
||||||
VERSIONS_JSON='[null]'
|
VERSIONS_JSON='[null]'
|
||||||
@@ -78,8 +81,10 @@ jobs:
|
|||||||
security-events: write
|
security-events: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- name: Checkout
|
||||||
- uses: ./init
|
uses: actions/checkout@v3
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: ./init
|
||||||
id: init
|
id: init
|
||||||
with:
|
with:
|
||||||
languages: javascript
|
languages: javascript
|
||||||
@@ -88,4 +93,5 @@ jobs:
|
|||||||
# confirm steps.init.outputs.codeql-path points to the codeql binary
|
# confirm steps.init.outputs.codeql-path points to the codeql binary
|
||||||
- name: Print CodeQL Version
|
- name: Print CodeQL Version
|
||||||
run: ${{steps.init.outputs.codeql-path}} version --format=json
|
run: ${{steps.init.outputs.codeql-path}} version --format=json
|
||||||
- uses: ./analyze
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: ./analyze
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v3
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: 3.8
|
python-version: 3.8
|
||||||
|
|
||||||
|
|||||||
@@ -28,17 +28,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-20.04, ubuntu-22.04, macos-latest]
|
os: [ubuntu-20.04, ubuntu-22.04, macos-latest]
|
||||||
python_deps_type: [pipenv, poetry, requirements, setup_py]
|
python_deps_type: [pipenv, poetry, requirements, setup_py]
|
||||||
python_version: [2, 3]
|
python_version: [3]
|
||||||
exclude:
|
|
||||||
# Python2 and poetry are not supported. See https://github.com/actions/setup-python/issues/374
|
|
||||||
- python_version: 2
|
|
||||||
python_deps_type: poetry
|
|
||||||
# Python2 and pipenv are not supported since pipenv v2021.11.5
|
|
||||||
- python_version: 2
|
|
||||||
python_deps_type: pipenv
|
|
||||||
# Python2 is not available on ubuntu-22.04 by default -- see https://github.com/github/codeql-action/pull/1257
|
|
||||||
- python_version: 2
|
|
||||||
os: ubuntu-22.04
|
|
||||||
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@@ -138,14 +128,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python_deps_type: [pipenv, poetry, requirements, setup_py]
|
python_deps_type: [pipenv, poetry, requirements, setup_py]
|
||||||
python_version: [2, 3]
|
python_version: [3]
|
||||||
exclude:
|
|
||||||
# Python2 and poetry are not supported. See https://github.com/actions/setup-python/issues/374
|
|
||||||
- python_version: 2
|
|
||||||
python_deps_type: poetry
|
|
||||||
# Python2 and pipenv are not supported since pipenv v2021.11.5
|
|
||||||
- python_version: 2
|
|
||||||
python_deps_type: pipenv
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
CODEQL_ACTION_TEST_MODE: true
|
CODEQL_ACTION_TEST_MODE: true
|
||||||
@@ -156,7 +139,7 @@ jobs:
|
|||||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- uses: actions/setup-python@v3
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python_version }}
|
python-version: ${{ matrix.python_version }}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ fi
|
|||||||
|
|
||||||
if [ "$#" -eq 1 ]; then
|
if [ "$#" -eq 1 ]; then
|
||||||
# If we were passed an argument, use that as the SHA
|
# If we were passed an argument, use that as the SHA
|
||||||
GITHUB_SHA="$0"
|
GITHUB_SHA="$1"
|
||||||
elif [ "$#" -gt 1 ]; then
|
elif [ "$#" -gt 1 ]; then
|
||||||
echo "Usage: $0 [SHA]"
|
echo "Usage: $0 [SHA]"
|
||||||
echo "Update the required checks based on the SHA, or main."
|
echo "Update the required checks based on the SHA, or main."
|
||||||
@@ -23,7 +23,7 @@ fi
|
|||||||
echo "Getting checks for $GITHUB_SHA"
|
echo "Getting checks for $GITHUB_SHA"
|
||||||
|
|
||||||
# Ignore any checks with "https://", CodeQL, LGTM, and Update checks.
|
# Ignore any checks with "https://", CodeQL, LGTM, and Update checks.
|
||||||
CHECKS="$(gh api repos/github/codeql-action/commits/"${GITHUB_SHA}"/check-runs --paginate | jq --slurp --compact-output --raw-output '[.[].check_runs | .[].name | select(contains("https://") or . == "CodeQL" or . == "LGTM.com" or contains("Update") or contains("update") or contains("test-setup-python-scripts") | not)] | unique | sort')"
|
CHECKS="$(gh api repos/github/codeql-action/commits/"${GITHUB_SHA}"/check-runs --paginate | jq --slurp --compact-output --raw-output '[.[].check_runs | .[].name | select(contains("https://") or . == "CodeQL" or . == "LGTM.com" or . == "check-expected-release-files" or contains("Update") or contains("update") or contains("test-setup-python-scripts") | not)] | unique | sort')"
|
||||||
|
|
||||||
echo "$CHECKS" | jq
|
echo "$CHECKS" | jq
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v3
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: 3.8
|
python-version: 3.8
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v3
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: "3.7"
|
python-version: "3.7"
|
||||||
- name: Checkout CodeQL Action
|
- name: Checkout CodeQL Action
|
||||||
@@ -35,7 +35,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
ENTERPRISE_RELEASES_PATH: ${{ github.workspace }}/enterprise-releases/
|
ENTERPRISE_RELEASES_PATH: ${{ github.workspace }}/enterprise-releases/
|
||||||
- name: Commit Changes
|
- name: Commit Changes
|
||||||
uses: peter-evans/create-pull-request@c7f493a8000b8aeb17a1332e326ba76b57cb83eb # v3.4.1
|
uses: peter-evans/create-pull-request@2b011faafdcbc9ceb11414d64d0573f37c774b04 # v4.2.3
|
||||||
with:
|
with:
|
||||||
commit-message: Update supported GitHub Enterprise Server versions.
|
commit-message: Update supported GitHub Enterprise Server versions.
|
||||||
title: Update supported GitHub Enterprise Server versions.
|
title: Update supported GitHub Enterprise Server versions.
|
||||||
|
|||||||
@@ -4,6 +4,25 @@
|
|||||||
|
|
||||||
No user facing changes.
|
No user facing changes.
|
||||||
|
|
||||||
|
## 2.1.37 - 14 Dec 2022
|
||||||
|
|
||||||
|
- Update default CodeQL bundle version to 2.11.6. [#1433](https://github.com/github/codeql-action/pull/1433)
|
||||||
|
|
||||||
|
## 2.1.36 - 08 Dec 2022
|
||||||
|
|
||||||
|
- Update default CodeQL bundle version to 2.11.5. [#1412](https://github.com/github/codeql-action/pull/1412)
|
||||||
|
- Add a step that tries to upload a SARIF file for the workflow run when that workflow run fails. This will help better surface failed code scanning workflow runs. [#1393](https://github.com/github/codeql-action/pull/1393)
|
||||||
|
- Python automatic dependency installation will no longer consider dependecy code installed in venv as user-written, for projects using Poetry that specify `virtualenvs.in-project = true` in their `poetry.toml`. [#1419](https://github.com/github/codeql-action/pull/1419).
|
||||||
|
|
||||||
|
## 2.1.35 - 01 Dec 2022
|
||||||
|
|
||||||
|
No user facing changes.
|
||||||
|
|
||||||
|
## 2.1.34 - 25 Nov 2022
|
||||||
|
|
||||||
|
- Update default CodeQL bundle version to 2.11.4. [#1391](https://github.com/github/codeql-action/pull/1391)
|
||||||
|
- Fixed a bug where some the `init` action and the `analyze` action would have different sets of experimental feature flags enabled. [#1384](https://github.com/github/codeql-action/pull/1384)
|
||||||
|
|
||||||
## 2.1.33 - 16 Nov 2022
|
## 2.1.33 - 16 Nov 2022
|
||||||
|
|
||||||
- Go is now analyzed in the same way as other compiled languages such as C/C++, C#, and Java. This completes the rollout of the feature described in [CodeQL Action version 2.1.27](#2127---06-oct-2022). [#1322](https://github.com/github/codeql-action/pull/1322)
|
- Go is now analyzed in the same way as other compiled languages such as C/C++, C#, and Java. This completes the rollout of the feature described in [CodeQL Action version 2.1.27](#2127---06-oct-2022). [#1322](https://github.com/github/codeql-action/pull/1322)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ inputs:
|
|||||||
upload:
|
upload:
|
||||||
description: Upload the SARIF file to Code Scanning
|
description: Upload the SARIF file to Code Scanning
|
||||||
required: false
|
required: false
|
||||||
|
# If changing this, make sure to update workflow.ts accordingly.
|
||||||
default: "true"
|
default: "true"
|
||||||
cleanup-level:
|
cleanup-level:
|
||||||
description: "Level of cleanup to perform on CodeQL databases at the end of the analyze step. This should either be 'none' to skip cleanup, or be a valid argument for the --mode flag of the CodeQL CLI command 'codeql database cleanup' as documented at https://codeql.github.com/docs/codeql-cli/manual/database-cleanup"
|
description: "Level of cleanup to perform on CodeQL databases at the end of the analyze step. This should either be 'none' to skip cleanup, or be a valid argument for the --mode flag of the CodeQL CLI command 'codeql database cleanup' as documented at https://codeql.github.com/docs/codeql-cli/manual/database-cleanup"
|
||||||
@@ -44,6 +45,7 @@ inputs:
|
|||||||
checkout_path:
|
checkout_path:
|
||||||
description: "The path at which the analyzed repository was checked out. Used to relativize any absolute paths in the uploaded SARIF file."
|
description: "The path at which the analyzed repository was checked out. Used to relativize any absolute paths in the uploaded SARIF file."
|
||||||
required: false
|
required: false
|
||||||
|
# If changing this, make sure to update workflow.ts accordingly.
|
||||||
default: ${{ github.workspace }}
|
default: ${{ github.workspace }}
|
||||||
ref:
|
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 not available in 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 not available in pull requests from forks."
|
||||||
|
|||||||
Generated
+7
-226
@@ -19,17 +19,17 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.printDebugLogs = exports.isAnalyzingDefaultBranch = exports.getRelativeScriptPath = exports.isRunningLocalAction = exports.workflowEventName = exports.sendStatusReport = exports.createStatusReportBase = exports.getActionsStatus = exports.getRef = exports.computeAutomationID = exports.getAutomationID = exports.getAnalysisKey = exports.getWorkflowRunID = exports.getWorkflow = exports.formatWorkflowCause = exports.formatWorkflowErrors = exports.validateWorkflow = exports.getWorkflowErrors = exports.WorkflowErrors = exports.patternIsSuperset = exports.determineMergeBaseCommitOid = exports.getCommitOid = exports.getTemporaryDirectory = exports.getOptionalInput = exports.getRequiredInput = void 0;
|
exports.printDebugLogs = exports.isAnalyzingDefaultBranch = exports.getRelativeScriptPath = exports.isRunningLocalAction = exports.workflowEventName = exports.sendStatusReport = exports.createStatusReportBase = exports.getActionsStatus = exports.getRef = exports.computeAutomationID = exports.getAutomationID = exports.getAnalysisKey = exports.determineMergeBaseCommitOid = exports.getCommitOid = exports.getTemporaryDirectory = exports.getOptionalInput = exports.getRequiredInput = void 0;
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const os = __importStar(require("os"));
|
const os = __importStar(require("os"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
const core = __importStar(require("@actions/core"));
|
const core = __importStar(require("@actions/core"));
|
||||||
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||||
const safeWhich = __importStar(require("@chrisgavin/safe-which"));
|
const safeWhich = __importStar(require("@chrisgavin/safe-which"));
|
||||||
const yaml = __importStar(require("js-yaml"));
|
|
||||||
const api = __importStar(require("./api-client"));
|
const api = __importStar(require("./api-client"));
|
||||||
const sharedEnv = __importStar(require("./shared-environment"));
|
const sharedEnv = __importStar(require("./shared-environment"));
|
||||||
const util_1 = require("./util");
|
const util_1 = require("./util");
|
||||||
|
const workflow_1 = require("./workflow");
|
||||||
// eslint-disable-next-line import/no-commonjs
|
// eslint-disable-next-line import/no-commonjs
|
||||||
const pkg = require("../package.json");
|
const pkg = require("../package.json");
|
||||||
/**
|
/**
|
||||||
@@ -145,225 +145,6 @@ const determineMergeBaseCommitOid = async function () {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
exports.determineMergeBaseCommitOid = determineMergeBaseCommitOid;
|
exports.determineMergeBaseCommitOid = determineMergeBaseCommitOid;
|
||||||
function isObject(o) {
|
|
||||||
return o !== null && typeof o === "object";
|
|
||||||
}
|
|
||||||
const GLOB_PATTERN = new RegExp("(\\*\\*?)");
|
|
||||||
function escapeRegExp(string) {
|
|
||||||
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
|
||||||
}
|
|
||||||
function patternToRegExp(value) {
|
|
||||||
return new RegExp(`^${value
|
|
||||||
.toString()
|
|
||||||
.split(GLOB_PATTERN)
|
|
||||||
.reduce(function (arr, cur) {
|
|
||||||
if (cur === "**") {
|
|
||||||
arr.push(".*?");
|
|
||||||
}
|
|
||||||
else if (cur === "*") {
|
|
||||||
arr.push("[^/]*?");
|
|
||||||
}
|
|
||||||
else if (cur) {
|
|
||||||
arr.push(escapeRegExp(cur));
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
}, [])
|
|
||||||
.join("")}$`);
|
|
||||||
}
|
|
||||||
// this function should return true if patternA is a superset of patternB
|
|
||||||
// e.g: * is a superset of main-* but main-* is not a superset of *.
|
|
||||||
function patternIsSuperset(patternA, patternB) {
|
|
||||||
return patternToRegExp(patternA).test(patternB);
|
|
||||||
}
|
|
||||||
exports.patternIsSuperset = patternIsSuperset;
|
|
||||||
function branchesToArray(branches) {
|
|
||||||
if (typeof branches === "string") {
|
|
||||||
return [branches];
|
|
||||||
}
|
|
||||||
if (Array.isArray(branches)) {
|
|
||||||
if (branches.length === 0) {
|
|
||||||
return "**";
|
|
||||||
}
|
|
||||||
return branches;
|
|
||||||
}
|
|
||||||
return "**";
|
|
||||||
}
|
|
||||||
function toCodedErrors(errors) {
|
|
||||||
return Object.entries(errors).reduce((acc, [key, value]) => {
|
|
||||||
acc[key] = { message: value, code: key };
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
// code to send back via status report
|
|
||||||
// message to add as a warning annotation to the run
|
|
||||||
exports.WorkflowErrors = toCodedErrors({
|
|
||||||
MismatchedBranches: `Please make sure that every branch in on.pull_request is also in on.push so that Code Scanning can compare pull requests against the state of the base branch.`,
|
|
||||||
MissingPushHook: `Please specify an on.push hook so that Code Scanning can compare pull requests against the state of the base branch.`,
|
|
||||||
PathsSpecified: `Using on.push.paths can prevent Code Scanning annotating new alerts in your pull requests.`,
|
|
||||||
PathsIgnoreSpecified: `Using on.push.paths-ignore can prevent Code Scanning annotating new alerts in your pull requests.`,
|
|
||||||
CheckoutWrongHead: `git checkout HEAD^2 is no longer necessary. Please remove this step as Code Scanning recommends analyzing the merge commit for best results.`,
|
|
||||||
});
|
|
||||||
function getWorkflowErrors(doc) {
|
|
||||||
var _a, _b, _c, _d, _e;
|
|
||||||
const errors = [];
|
|
||||||
const jobName = process.env.GITHUB_JOB;
|
|
||||||
if (jobName) {
|
|
||||||
const job = (_a = doc === null || doc === void 0 ? void 0 : doc.jobs) === null || _a === void 0 ? void 0 : _a[jobName];
|
|
||||||
const steps = job === null || job === void 0 ? void 0 : job.steps;
|
|
||||||
if (Array.isArray(steps)) {
|
|
||||||
for (const step of steps) {
|
|
||||||
// this was advice that we used to give in the README
|
|
||||||
// we actually want to run the analysis on the merge commit
|
|
||||||
// to produce results that are more inline with expectations
|
|
||||||
// (i.e: this is what will happen if you merge this PR)
|
|
||||||
// and avoid some race conditions
|
|
||||||
if ((step === null || step === void 0 ? void 0 : step.run) === "git checkout HEAD^2") {
|
|
||||||
errors.push(exports.WorkflowErrors.CheckoutWrongHead);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let missingPush = false;
|
|
||||||
if (doc.on === undefined) {
|
|
||||||
// this is not a valid config
|
|
||||||
}
|
|
||||||
else if (typeof doc.on === "string") {
|
|
||||||
if (doc.on === "pull_request") {
|
|
||||||
missingPush = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Array.isArray(doc.on)) {
|
|
||||||
const hasPush = doc.on.includes("push");
|
|
||||||
const hasPullRequest = doc.on.includes("pull_request");
|
|
||||||
if (hasPullRequest && !hasPush) {
|
|
||||||
missingPush = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (isObject(doc.on)) {
|
|
||||||
const hasPush = Object.prototype.hasOwnProperty.call(doc.on, "push");
|
|
||||||
const hasPullRequest = Object.prototype.hasOwnProperty.call(doc.on, "pull_request");
|
|
||||||
if (!hasPush && hasPullRequest) {
|
|
||||||
missingPush = true;
|
|
||||||
}
|
|
||||||
if (hasPush && hasPullRequest) {
|
|
||||||
const paths = (_b = doc.on.push) === null || _b === void 0 ? void 0 : _b.paths;
|
|
||||||
// if you specify paths or paths-ignore you can end up with commits that have no baseline
|
|
||||||
// if they didn't change any files
|
|
||||||
// currently we cannot go back through the history and find the most recent baseline
|
|
||||||
if (Array.isArray(paths) && paths.length > 0) {
|
|
||||||
errors.push(exports.WorkflowErrors.PathsSpecified);
|
|
||||||
}
|
|
||||||
const pathsIgnore = (_c = doc.on.push) === null || _c === void 0 ? void 0 : _c["paths-ignore"];
|
|
||||||
if (Array.isArray(pathsIgnore) && pathsIgnore.length > 0) {
|
|
||||||
errors.push(exports.WorkflowErrors.PathsIgnoreSpecified);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if doc.on.pull_request is null that means 'all branches'
|
|
||||||
// if doc.on.pull_request is undefined that means 'off'
|
|
||||||
// we only want to check for mismatched branches if pull_request is on.
|
|
||||||
if (doc.on.pull_request !== undefined) {
|
|
||||||
const push = branchesToArray((_d = doc.on.push) === null || _d === void 0 ? void 0 : _d.branches);
|
|
||||||
if (push !== "**") {
|
|
||||||
const pull_request = branchesToArray((_e = doc.on.pull_request) === null || _e === void 0 ? void 0 : _e.branches);
|
|
||||||
if (pull_request !== "**") {
|
|
||||||
const difference = pull_request.filter((value) => !push.some((o) => patternIsSuperset(o, value)));
|
|
||||||
if (difference.length > 0) {
|
|
||||||
// there are branches in pull_request that may not have a baseline
|
|
||||||
// because we are not building them on push
|
|
||||||
errors.push(exports.WorkflowErrors.MismatchedBranches);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (push.length > 0) {
|
|
||||||
// push is set up to run on a subset of branches
|
|
||||||
// and you could open a PR against a branch with no baseline
|
|
||||||
errors.push(exports.WorkflowErrors.MismatchedBranches);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (missingPush) {
|
|
||||||
errors.push(exports.WorkflowErrors.MissingPushHook);
|
|
||||||
}
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
exports.getWorkflowErrors = getWorkflowErrors;
|
|
||||||
async function validateWorkflow() {
|
|
||||||
let workflow;
|
|
||||||
try {
|
|
||||||
workflow = await getWorkflow();
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return `error: getWorkflow() failed: ${String(e)}`;
|
|
||||||
}
|
|
||||||
let workflowErrors;
|
|
||||||
try {
|
|
||||||
workflowErrors = getWorkflowErrors(workflow);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return `error: getWorkflowErrors() failed: ${String(e)}`;
|
|
||||||
}
|
|
||||||
if (workflowErrors.length > 0) {
|
|
||||||
let message;
|
|
||||||
try {
|
|
||||||
message = formatWorkflowErrors(workflowErrors);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return `error: formatWorkflowErrors() failed: ${String(e)}`;
|
|
||||||
}
|
|
||||||
core.warning(message);
|
|
||||||
}
|
|
||||||
return formatWorkflowCause(workflowErrors);
|
|
||||||
}
|
|
||||||
exports.validateWorkflow = validateWorkflow;
|
|
||||||
function formatWorkflowErrors(errors) {
|
|
||||||
const issuesWere = errors.length === 1 ? "issue was" : "issues were";
|
|
||||||
const errorsList = errors.map((e) => e.message).join(" ");
|
|
||||||
return `${errors.length} ${issuesWere} detected with this workflow: ${errorsList}`;
|
|
||||||
}
|
|
||||||
exports.formatWorkflowErrors = formatWorkflowErrors;
|
|
||||||
function formatWorkflowCause(errors) {
|
|
||||||
if (errors.length === 0) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return errors.map((e) => e.code).join(",");
|
|
||||||
}
|
|
||||||
exports.formatWorkflowCause = formatWorkflowCause;
|
|
||||||
async function getWorkflow() {
|
|
||||||
const relativePath = await getWorkflowPath();
|
|
||||||
const absolutePath = path.join((0, util_1.getRequiredEnvParam)("GITHUB_WORKSPACE"), relativePath);
|
|
||||||
return yaml.load(fs.readFileSync(absolutePath, "utf-8"));
|
|
||||||
}
|
|
||||||
exports.getWorkflow = getWorkflow;
|
|
||||||
/**
|
|
||||||
* Get the path of the currently executing workflow.
|
|
||||||
*/
|
|
||||||
async function getWorkflowPath() {
|
|
||||||
const repo_nwo = (0, util_1.getRequiredEnvParam)("GITHUB_REPOSITORY").split("/");
|
|
||||||
const owner = repo_nwo[0];
|
|
||||||
const repo = repo_nwo[1];
|
|
||||||
const run_id = Number((0, util_1.getRequiredEnvParam)("GITHUB_RUN_ID"));
|
|
||||||
const apiClient = api.getApiClient();
|
|
||||||
const runsResponse = await apiClient.request("GET /repos/:owner/:repo/actions/runs/:run_id?exclude_pull_requests=true", {
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
run_id,
|
|
||||||
});
|
|
||||||
const workflowUrl = runsResponse.data.workflow_url;
|
|
||||||
const workflowResponse = await apiClient.request(`GET ${workflowUrl}`);
|
|
||||||
return workflowResponse.data.path;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Get the workflow run ID.
|
|
||||||
*/
|
|
||||||
function getWorkflowRunID() {
|
|
||||||
const workflowRunID = parseInt((0, util_1.getRequiredEnvParam)("GITHUB_RUN_ID"), 10);
|
|
||||||
if (Number.isNaN(workflowRunID)) {
|
|
||||||
throw new Error("GITHUB_RUN_ID must define a non NaN workflow run ID");
|
|
||||||
}
|
|
||||||
return workflowRunID;
|
|
||||||
}
|
|
||||||
exports.getWorkflowRunID = getWorkflowRunID;
|
|
||||||
/**
|
/**
|
||||||
* Get the analysis key parameter for the current job.
|
* Get the analysis key parameter for the current job.
|
||||||
*
|
*
|
||||||
@@ -377,7 +158,7 @@ async function getAnalysisKey() {
|
|||||||
if (analysisKey !== undefined) {
|
if (analysisKey !== undefined) {
|
||||||
return analysisKey;
|
return analysisKey;
|
||||||
}
|
}
|
||||||
const workflowPath = await getWorkflowPath();
|
const workflowPath = await (0, workflow_1.getWorkflowPath)();
|
||||||
const jobName = (0, util_1.getRequiredEnvParam)("GITHUB_JOB");
|
const jobName = (0, util_1.getRequiredEnvParam)("GITHUB_JOB");
|
||||||
analysisKey = `${workflowPath}:${jobName}`;
|
analysisKey = `${workflowPath}:${jobName}`;
|
||||||
core.exportVariable(analysisKeyEnvVar, analysisKey);
|
core.exportVariable(analysisKeyEnvVar, analysisKey);
|
||||||
@@ -392,10 +173,10 @@ async function getAutomationID() {
|
|||||||
exports.getAutomationID = getAutomationID;
|
exports.getAutomationID = getAutomationID;
|
||||||
function computeAutomationID(analysis_key, environment) {
|
function computeAutomationID(analysis_key, environment) {
|
||||||
let automationID = `${analysis_key}/`;
|
let automationID = `${analysis_key}/`;
|
||||||
// the id has to be deterministic so we sort the fields
|
const matrix = (0, util_1.parseMatrixInput)(environment);
|
||||||
if (environment !== undefined && environment !== "null") {
|
if (matrix !== undefined) {
|
||||||
const environmentObject = JSON.parse(environment);
|
// the id has to be deterministic so we sort the fields
|
||||||
for (const entry of Object.entries(environmentObject).sort()) {
|
for (const entry of Object.entries(matrix).sort()) {
|
||||||
if (typeof entry[1] === "string") {
|
if (typeof entry[1] === "string") {
|
||||||
automationID += `${entry[0]}:${entry[1]}/`;
|
automationID += `${entry[0]}:${entry[1]}/`;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Generated
+24
-331
@@ -25,14 +25,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
const ava_1 = __importDefault(require("ava"));
|
const ava_1 = __importDefault(require("ava"));
|
||||||
const yaml = __importStar(require("js-yaml"));
|
|
||||||
const sinon = __importStar(require("sinon"));
|
const sinon = __importStar(require("sinon"));
|
||||||
const actionsutil = __importStar(require("./actions-util"));
|
const actionsutil = __importStar(require("./actions-util"));
|
||||||
const testing_utils_1 = require("./testing-utils");
|
const testing_utils_1 = require("./testing-utils");
|
||||||
const util_1 = require("./util");
|
const util_1 = require("./util");
|
||||||
function errorCodes(actual, expected) {
|
|
||||||
return [actual.map(({ code }) => code), expected.map(({ code }) => code)];
|
|
||||||
}
|
|
||||||
(0, testing_utils_1.setupTests)(ava_1.default);
|
(0, testing_utils_1.setupTests)(ava_1.default);
|
||||||
(0, ava_1.default)("getRef() throws on the empty string", async (t) => {
|
(0, ava_1.default)("getRef() throws on the empty string", async (t) => {
|
||||||
process.env["GITHUB_REF"] = "";
|
process.env["GITHUB_REF"] = "";
|
||||||
@@ -98,6 +94,30 @@ function errorCodes(actual, expected) {
|
|||||||
getAdditionalInputStub.restore();
|
getAdditionalInputStub.restore();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
(0, ava_1.default)("getRef() returns CODE_SCANNING_REF as a fallback for GITHUB_REF", async (t) => {
|
||||||
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
|
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
|
||||||
|
const expectedRef = "refs/pull/1/HEAD";
|
||||||
|
const currentSha = "a".repeat(40);
|
||||||
|
process.env["CODE_SCANNING_REF"] = expectedRef;
|
||||||
|
process.env["GITHUB_REF"] = "";
|
||||||
|
process.env["GITHUB_SHA"] = currentSha;
|
||||||
|
const actualRef = await actionsutil.getRef();
|
||||||
|
t.deepEqual(actualRef, expectedRef);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getRef() returns GITHUB_REF over CODE_SCANNING_REF if both are provided", async (t) => {
|
||||||
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
|
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
|
||||||
|
const expectedRef = "refs/pull/1/merge";
|
||||||
|
const currentSha = "a".repeat(40);
|
||||||
|
process.env["CODE_SCANNING_REF"] = "refs/pull/1/HEAD";
|
||||||
|
process.env["GITHUB_REF"] = expectedRef;
|
||||||
|
process.env["GITHUB_SHA"] = currentSha;
|
||||||
|
const actualRef = await actionsutil.getRef();
|
||||||
|
t.deepEqual(actualRef, expectedRef);
|
||||||
|
});
|
||||||
|
});
|
||||||
(0, ava_1.default)("getRef() throws an error if only `ref` is provided as an input", async (t) => {
|
(0, ava_1.default)("getRef() throws an error if only `ref` is provided as an input", async (t) => {
|
||||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
|
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
|
||||||
@@ -143,333 +163,6 @@ function errorCodes(actual, expected) {
|
|||||||
actualAutomationID = actionsutil.computeAutomationID(".github/workflows/codeql-analysis.yml:analyze", undefined);
|
actualAutomationID = actionsutil.computeAutomationID(".github/workflows/codeql-analysis.yml:analyze", undefined);
|
||||||
t.deepEqual(actualAutomationID, ".github/workflows/codeql-analysis.yml:analyze/");
|
t.deepEqual(actualAutomationID, ".github/workflows/codeql-analysis.yml:analyze/");
|
||||||
});
|
});
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on is empty", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors({ on: {} });
|
|
||||||
t.deepEqual(...errorCodes(errors, []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.push is an array missing pull_request", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors({ on: ["push"] });
|
|
||||||
t.deepEqual(...errorCodes(errors, []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.push is an array missing push", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors({ on: ["pull_request"] });
|
|
||||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.MissingPushHook]));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.push is valid", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors({
|
|
||||||
on: ["push", "pull_request"],
|
|
||||||
});
|
|
||||||
t.deepEqual(...errorCodes(errors, []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.push is a valid superset", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors({
|
|
||||||
on: ["push", "pull_request", "schedule"],
|
|
||||||
});
|
|
||||||
t.deepEqual(...errorCodes(errors, []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.push should not have a path", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors({
|
|
||||||
on: {
|
|
||||||
push: { branches: ["main"], paths: ["test/*"] },
|
|
||||||
pull_request: { branches: ["main"] },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.PathsSpecified]));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.push is a correct object", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors({
|
|
||||||
on: { push: { branches: ["main"] }, pull_request: { branches: ["main"] } },
|
|
||||||
});
|
|
||||||
t.deepEqual(...errorCodes(errors, []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.pull_requests is a string", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors({
|
|
||||||
on: { push: { branches: ["main"] }, pull_request: { branches: "*" } },
|
|
||||||
});
|
|
||||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.MismatchedBranches]));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.pull_requests is a string and correct", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors({
|
|
||||||
on: { push: { branches: "*" }, pull_request: { branches: "*" } },
|
|
||||||
});
|
|
||||||
t.deepEqual(...errorCodes(errors, []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.push is correct with empty objects", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors(yaml.load(`
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
`));
|
|
||||||
t.deepEqual(...errorCodes(errors, []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.push is mismatched", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors({
|
|
||||||
on: {
|
|
||||||
push: { branches: ["main"] },
|
|
||||||
pull_request: { branches: ["feature"] },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.MismatchedBranches]));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.push is not mismatched", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors({
|
|
||||||
on: {
|
|
||||||
push: { branches: ["main", "feature"] },
|
|
||||||
pull_request: { branches: ["main"] },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
t.deepEqual(...errorCodes(errors, []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.push is mismatched for pull_request", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors({
|
|
||||||
on: {
|
|
||||||
push: { branches: ["main"] },
|
|
||||||
pull_request: { branches: ["main", "feature"] },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.MismatchedBranches]));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() for a range of malformed workflows", (t) => {
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
|
||||||
on: {
|
|
||||||
push: 1,
|
|
||||||
pull_request: 1,
|
|
||||||
},
|
|
||||||
}), []));
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
|
||||||
on: 1,
|
|
||||||
}), []));
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
|
||||||
on: 1,
|
|
||||||
jobs: 1,
|
|
||||||
}), []));
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
|
||||||
on: 1,
|
|
||||||
jobs: [1],
|
|
||||||
}), []));
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
|
||||||
on: 1,
|
|
||||||
jobs: { 1: 1 },
|
|
||||||
}), []));
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
|
||||||
on: 1,
|
|
||||||
jobs: { test: 1 },
|
|
||||||
}), []));
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
|
||||||
on: 1,
|
|
||||||
jobs: { test: [1] },
|
|
||||||
}), []));
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
|
||||||
on: 1,
|
|
||||||
jobs: { test: { steps: 1 } },
|
|
||||||
}), []));
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
|
||||||
on: 1,
|
|
||||||
jobs: { test: { steps: [{ notrun: "git checkout HEAD^2" }] } },
|
|
||||||
}), []));
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
|
||||||
on: 1,
|
|
||||||
jobs: { test: [undefined] },
|
|
||||||
}), []));
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors(1), []));
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors({
|
|
||||||
on: {
|
|
||||||
push: {
|
|
||||||
branches: 1,
|
|
||||||
},
|
|
||||||
pull_request: {
|
|
||||||
branches: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}), []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.pull_request for every branch but push specifies branches", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors(yaml.load(`
|
|
||||||
name: "CodeQL"
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: ["main"]
|
|
||||||
pull_request:
|
|
||||||
`));
|
|
||||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.MismatchedBranches]));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.pull_request for wildcard branches", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors({
|
|
||||||
on: {
|
|
||||||
push: { branches: ["feature/*"] },
|
|
||||||
pull_request: { branches: "feature/moose" },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
t.deepEqual(...errorCodes(errors, []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.pull_request for mismatched wildcard branches", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors({
|
|
||||||
on: {
|
|
||||||
push: { branches: ["feature/moose"] },
|
|
||||||
pull_request: { branches: "feature/*" },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.MismatchedBranches]));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when HEAD^2 is checked out", (t) => {
|
|
||||||
process.env.GITHUB_JOB = "test";
|
|
||||||
const errors = actionsutil.getWorkflowErrors({
|
|
||||||
on: ["push", "pull_request"],
|
|
||||||
jobs: { test: { steps: [{ run: "git checkout HEAD^2" }] } },
|
|
||||||
});
|
|
||||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.CheckoutWrongHead]));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("formatWorkflowErrors() when there is one error", (t) => {
|
|
||||||
const message = actionsutil.formatWorkflowErrors([
|
|
||||||
actionsutil.WorkflowErrors.CheckoutWrongHead,
|
|
||||||
]);
|
|
||||||
t.true(message.startsWith("1 issue was detected with this workflow:"));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("formatWorkflowErrors() when there are multiple errors", (t) => {
|
|
||||||
const message = actionsutil.formatWorkflowErrors([
|
|
||||||
actionsutil.WorkflowErrors.CheckoutWrongHead,
|
|
||||||
actionsutil.WorkflowErrors.PathsSpecified,
|
|
||||||
]);
|
|
||||||
t.true(message.startsWith("2 issues were detected with this workflow:"));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("formatWorkflowCause() with no errors", (t) => {
|
|
||||||
const message = actionsutil.formatWorkflowCause([]);
|
|
||||||
t.deepEqual(message, undefined);
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("formatWorkflowCause()", (t) => {
|
|
||||||
const message = actionsutil.formatWorkflowCause([
|
|
||||||
actionsutil.WorkflowErrors.CheckoutWrongHead,
|
|
||||||
actionsutil.WorkflowErrors.PathsSpecified,
|
|
||||||
]);
|
|
||||||
t.deepEqual(message, "CheckoutWrongHead,PathsSpecified");
|
|
||||||
t.deepEqual(actionsutil.formatWorkflowCause([]), undefined);
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("patternIsSuperset()", (t) => {
|
|
||||||
t.false(actionsutil.patternIsSuperset("main-*", "main"));
|
|
||||||
t.true(actionsutil.patternIsSuperset("*", "*"));
|
|
||||||
t.true(actionsutil.patternIsSuperset("*", "main-*"));
|
|
||||||
t.false(actionsutil.patternIsSuperset("main-*", "*"));
|
|
||||||
t.false(actionsutil.patternIsSuperset("main-*", "main"));
|
|
||||||
t.true(actionsutil.patternIsSuperset("main", "main"));
|
|
||||||
t.false(actionsutil.patternIsSuperset("*", "feature/*"));
|
|
||||||
t.true(actionsutil.patternIsSuperset("**", "feature/*"));
|
|
||||||
t.false(actionsutil.patternIsSuperset("feature-*", "**"));
|
|
||||||
t.false(actionsutil.patternIsSuperset("a/**/c", "a/**/d"));
|
|
||||||
t.false(actionsutil.patternIsSuperset("a/**/c", "a/**"));
|
|
||||||
t.true(actionsutil.patternIsSuperset("a/**", "a/**/c"));
|
|
||||||
t.true(actionsutil.patternIsSuperset("a/**/c", "a/main-**/c"));
|
|
||||||
t.false(actionsutil.patternIsSuperset("a/**/b/**/c", "a/**/d/**/c"));
|
|
||||||
t.true(actionsutil.patternIsSuperset("a/**/b/**/c", "a/**/b/c/**/c"));
|
|
||||||
t.true(actionsutil.patternIsSuperset("a/**/b/**/c", "a/**/b/d/**/c"));
|
|
||||||
t.false(actionsutil.patternIsSuperset("a/**/c/d/**/c", "a/**/b/**/c"));
|
|
||||||
t.false(actionsutil.patternIsSuperset("a/main-**/c", "a/**/c"));
|
|
||||||
t.true(actionsutil.patternIsSuperset("/robin/*/release/*", "/robin/moose/release/goose"));
|
|
||||||
t.false(actionsutil.patternIsSuperset("/robin/moose/release/goose", "/robin/*/release/*"));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when branches contain dots", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors(yaml.load(`
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [4.1, master]
|
|
||||||
pull_request:
|
|
||||||
# The branches below must be a subset of the branches above
|
|
||||||
branches: [4.1, master]
|
|
||||||
`));
|
|
||||||
t.deepEqual(...errorCodes(errors, []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on.push has a trailing comma", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors(yaml.load(`
|
|
||||||
name: "CodeQL"
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [master, ]
|
|
||||||
pull_request:
|
|
||||||
# The branches below must be a subset of the branches above
|
|
||||||
branches: [master]
|
|
||||||
`));
|
|
||||||
t.deepEqual(...errorCodes(errors, []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() should only report the current job's CheckoutWrongHead", (t) => {
|
|
||||||
process.env.GITHUB_JOB = "test";
|
|
||||||
const errors = actionsutil.getWorkflowErrors(yaml.load(`
|
|
||||||
name: "CodeQL"
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [master]
|
|
||||||
pull_request:
|
|
||||||
# The branches below must be a subset of the branches above
|
|
||||||
branches: [master]
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
steps:
|
|
||||||
- run: "git checkout HEAD^2"
|
|
||||||
|
|
||||||
test2:
|
|
||||||
steps:
|
|
||||||
- run: "git checkout HEAD^2"
|
|
||||||
|
|
||||||
test3:
|
|
||||||
steps: []
|
|
||||||
`));
|
|
||||||
t.deepEqual(...errorCodes(errors, [actionsutil.WorkflowErrors.CheckoutWrongHead]));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() should not report a different job's CheckoutWrongHead", (t) => {
|
|
||||||
process.env.GITHUB_JOB = "test3";
|
|
||||||
const errors = actionsutil.getWorkflowErrors(yaml.load(`
|
|
||||||
name: "CodeQL"
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [master]
|
|
||||||
pull_request:
|
|
||||||
# The branches below must be a subset of the branches above
|
|
||||||
branches: [master]
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
steps:
|
|
||||||
- run: "git checkout HEAD^2"
|
|
||||||
|
|
||||||
test2:
|
|
||||||
steps:
|
|
||||||
- run: "git checkout HEAD^2"
|
|
||||||
|
|
||||||
test3:
|
|
||||||
steps: []
|
|
||||||
`));
|
|
||||||
t.deepEqual(...errorCodes(errors, []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() when on is missing", (t) => {
|
|
||||||
const errors = actionsutil.getWorkflowErrors(yaml.load(`
|
|
||||||
name: "CodeQL"
|
|
||||||
`));
|
|
||||||
t.deepEqual(...errorCodes(errors, []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() with a different on setup", (t) => {
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors(yaml.load(`
|
|
||||||
name: "CodeQL"
|
|
||||||
on: "workflow_dispatch"
|
|
||||||
`)), []));
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors(yaml.load(`
|
|
||||||
name: "CodeQL"
|
|
||||||
on: [workflow_dispatch]
|
|
||||||
`)), []));
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors(yaml.load(`
|
|
||||||
name: "CodeQL"
|
|
||||||
on:
|
|
||||||
workflow_dispatch: {}
|
|
||||||
`)), []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("getWorkflowErrors() should not report an error if PRs are totally unconfigured", (t) => {
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors(yaml.load(`
|
|
||||||
name: "CodeQL"
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [master]
|
|
||||||
`)), []));
|
|
||||||
t.deepEqual(...errorCodes(actionsutil.getWorkflowErrors(yaml.load(`
|
|
||||||
name: "CodeQL"
|
|
||||||
on: ["push"]
|
|
||||||
`)), []));
|
|
||||||
});
|
|
||||||
(0, ava_1.default)("initializeEnvironment", (t) => {
|
(0, ava_1.default)("initializeEnvironment", (t) => {
|
||||||
(0, util_1.initializeEnvironment)("1.2.3");
|
(0, util_1.initializeEnvironment)("1.2.3");
|
||||||
t.deepEqual(process.env.CODEQL_ACTION_VERSION, "1.2.3");
|
t.deepEqual(process.env.CODEQL_ACTION_VERSION, "1.2.3");
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Generated
+1
@@ -45,6 +45,7 @@ const util = __importStar(require("./util"));
|
|||||||
.stub(actionsUtil, "createStatusReportBase")
|
.stub(actionsUtil, "createStatusReportBase")
|
||||||
.resolves({});
|
.resolves({});
|
||||||
sinon.stub(actionsUtil, "sendStatusReport").resolves(true);
|
sinon.stub(actionsUtil, "sendStatusReport").resolves(true);
|
||||||
|
sinon.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
|
||||||
const gitHubVersion = {
|
const gitHubVersion = {
|
||||||
type: util.GitHubVariant.DOTCOM,
|
type: util.GitHubVariant.DOTCOM,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"analyze-action-env.test.js","sourceRoot":"","sources":["../src/analyze-action-env.test.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"analyze-action-env.test.js","sourceRoot":"","sources":["../src/analyze-action-env.test.ts"],"names":[],"mappings":"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"}
|
||||||
Generated
+1
@@ -61,6 +61,7 @@ const util = __importStar(require("./util"));
|
|||||||
optionalInputStub.withArgs("cleanup-level").returns("none");
|
optionalInputStub.withArgs("cleanup-level").returns("none");
|
||||||
optionalInputStub.withArgs("expect-error").returns("false");
|
optionalInputStub.withArgs("expect-error").returns("false");
|
||||||
sinon.stub(util, "getGitHubVersion").resolves(gitHubVersion);
|
sinon.stub(util, "getGitHubVersion").resolves(gitHubVersion);
|
||||||
|
sinon.stub(actionsUtil, "isAnalyzingDefaultBranch").resolves(true);
|
||||||
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
|
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
|
||||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, {});
|
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, {});
|
||||||
process.env["CODEQL_THREADS"] = "1";
|
process.env["CODEQL_THREADS"] = "1";
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"analyze-action-input.test.js","sourceRoot":"","sources":["../src/analyze-action-input.test.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"analyze-action-input.test.js","sourceRoot":"","sources":["../src/analyze-action-input.test.ts"],"names":[],"mappings":"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"}
|
||||||
Generated
+10
-4
@@ -39,6 +39,7 @@ const feature_flags_1 = require("./feature-flags");
|
|||||||
const languages_1 = require("./languages");
|
const languages_1 = require("./languages");
|
||||||
const logging_1 = require("./logging");
|
const logging_1 = require("./logging");
|
||||||
const repository_1 = require("./repository");
|
const repository_1 = require("./repository");
|
||||||
|
const shared_environment_1 = require("./shared-environment");
|
||||||
const trap_caching_1 = require("./trap-caching");
|
const trap_caching_1 = require("./trap-caching");
|
||||||
const upload_lib = __importStar(require("./upload-lib"));
|
const upload_lib = __importStar(require("./upload-lib"));
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
@@ -103,6 +104,8 @@ function doesGoExtractionOutputExist(config) {
|
|||||||
* - We detect whether an autobuild step is present by checking the
|
* - We detect whether an autobuild step is present by checking the
|
||||||
* `util.DID_AUTOBUILD_GO_ENV_VAR_NAME` environment variable, which is set
|
* `util.DID_AUTOBUILD_GO_ENV_VAR_NAME` environment variable, which is set
|
||||||
* when the autobuilder is invoked.
|
* when the autobuilder is invoked.
|
||||||
|
* - We detect whether the Go database has already been finalized in case it
|
||||||
|
* has been manually set in a prior Action step.
|
||||||
* - We approximate whether manual build steps are present by looking at
|
* - We approximate whether manual build steps are present by looking at
|
||||||
* whether any extraction output already exists for Go.
|
* whether any extraction output already exists for Go.
|
||||||
*/
|
*/
|
||||||
@@ -114,6 +117,10 @@ async function runAutobuildIfLegacyGoWorkflow(config, logger) {
|
|||||||
logger.debug("Won't run Go autobuild since it has already been run.");
|
logger.debug("Won't run Go autobuild since it has already been run.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ((0, analyze_1.dbIsFinalized)(config, languages_1.Language.go, logger)) {
|
||||||
|
logger.debug("Won't run Go autobuild since there is already a finalized database for Go.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
// This captures whether a user has added manual build steps for Go
|
// This captures whether a user has added manual build steps for Go
|
||||||
if (doesGoExtractionOutputExist(config)) {
|
if (doesGoExtractionOutputExist(config)) {
|
||||||
logger.debug("Won't run Go autobuild since at least one file of Go code has already been extracted.");
|
logger.debug("Won't run Go autobuild since at least one file of Go code has already been extracted.");
|
||||||
@@ -155,7 +162,7 @@ async function run() {
|
|||||||
const memory = util.getMemoryFlag(actionsUtil.getOptionalInput("ram") || process.env["CODEQL_RAM"]);
|
const memory = util.getMemoryFlag(actionsUtil.getOptionalInput("ram") || process.env["CODEQL_RAM"]);
|
||||||
const repositoryNwo = (0, repository_1.parseRepositoryNwo)(util.getRequiredEnvParam("GITHUB_REPOSITORY"));
|
const repositoryNwo = (0, repository_1.parseRepositoryNwo)(util.getRequiredEnvParam("GITHUB_REPOSITORY"));
|
||||||
const gitHubVersion = await (0, api_client_1.getGitHubVersion)();
|
const gitHubVersion = await (0, api_client_1.getGitHubVersion)();
|
||||||
const features = new feature_flags_1.Features(gitHubVersion, repositoryNwo, logger);
|
const features = new feature_flags_1.Features(gitHubVersion, repositoryNwo, actionsUtil.getTemporaryDirectory(), logger);
|
||||||
await runAutobuildIfLegacyGoWorkflow(config, logger);
|
await runAutobuildIfLegacyGoWorkflow(config, logger);
|
||||||
dbCreationTimings = await (0, analyze_1.runFinalize)(outputDir, threads, memory, config, logger);
|
dbCreationTimings = await (0, analyze_1.runFinalize)(outputDir, threads, memory, config, logger);
|
||||||
if (actionsUtil.getRequiredInput("skip-queries") !== "true") {
|
if (actionsUtil.getRequiredInput("skip-queries") !== "true") {
|
||||||
@@ -170,7 +177,7 @@ async function run() {
|
|||||||
}
|
}
|
||||||
core.setOutput("db-locations", dbLocations);
|
core.setOutput("db-locations", dbLocations);
|
||||||
if (runStats && actionsUtil.getRequiredInput("upload") === "true") {
|
if (runStats && actionsUtil.getRequiredInput("upload") === "true") {
|
||||||
uploadResult = await upload_lib.uploadFromActions(outputDir, config.gitHubVersion, logger);
|
uploadResult = await upload_lib.uploadFromActions(outputDir, actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getOptionalInput("category"), logger);
|
||||||
core.setOutput("sarif-id", uploadResult.sarifID);
|
core.setOutput("sarif-id", uploadResult.sarifID);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -195,6 +202,7 @@ async function run() {
|
|||||||
if (actionsUtil.getOptionalInput("expect-error") === "true") {
|
if (actionsUtil.getOptionalInput("expect-error") === "true") {
|
||||||
core.setFailed(`expect-error input was set to true but no error was thrown.`);
|
core.setFailed(`expect-error input was set to true but no error was thrown.`);
|
||||||
}
|
}
|
||||||
|
core.exportVariable(shared_environment_1.CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY, "true");
|
||||||
}
|
}
|
||||||
catch (origError) {
|
catch (origError) {
|
||||||
const error = origError instanceof Error ? origError : new Error(String(origError));
|
const error = origError instanceof Error ? origError : new Error(String(origError));
|
||||||
@@ -202,7 +210,6 @@ async function run() {
|
|||||||
hasBadExpectErrorInput()) {
|
hasBadExpectErrorInput()) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
}
|
}
|
||||||
console.log(error);
|
|
||||||
if (error instanceof analyze_1.CodeQLAnalysisError) {
|
if (error instanceof analyze_1.CodeQLAnalysisError) {
|
||||||
const stats = { ...error.queriesStatusReport };
|
const stats = { ...error.queriesStatusReport };
|
||||||
await sendStatusReport(startedAt, config, stats, error, trapCacheUploadTime, dbCreationTimings, didUploadTrapCaches, logger);
|
await sendStatusReport(startedAt, config, stats, error, trapCacheUploadTime, dbCreationTimings, didUploadTrapCaches, logger);
|
||||||
@@ -232,7 +239,6 @@ async function runWrapper() {
|
|||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
core.setFailed(`analyze action failed: ${error}`);
|
core.setFailed(`analyze action failed: ${error}`);
|
||||||
console.log(error);
|
|
||||||
}
|
}
|
||||||
await (0, util_1.checkForTimeout)();
|
await (0, util_1.checkForTimeout)();
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Generated
+1
-1
@@ -207,7 +207,7 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag,
|
|||||||
return statusReport;
|
return statusReport;
|
||||||
async function runInterpretResults(language, queries, sarifFile, enableDebugLogging) {
|
async function runInterpretResults(language, queries, sarifFile, enableDebugLogging) {
|
||||||
const databasePath = util.getCodeQLDatabasePath(config, language);
|
const databasePath = util.getCodeQLDatabasePath(config, language);
|
||||||
return await codeql.databaseInterpretResults(databasePath, queries, sarifFile, addSnippetsFlag, threadsFlag, enableDebugLogging ? "-vv" : "-v", automationDetailsId, featureEnablement);
|
return await codeql.databaseInterpretResults(databasePath, queries, sarifFile, addSnippetsFlag, threadsFlag, enableDebugLogging ? "-vv" : "-v", automationDetailsId);
|
||||||
}
|
}
|
||||||
async function runPrintLinesOfCode(language) {
|
async function runPrintLinesOfCode(language) {
|
||||||
const databasePath = util.getCodeQLDatabasePath(config, language);
|
const databasePath = util.getCodeQLDatabasePath(config, language);
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
{ "maximumVersion": "3.7", "minimumVersion": "3.3" }
|
{ "maximumVersion": "3.8", "minimumVersion": "3.3" }
|
||||||
|
|||||||
Generated
+34
-22
@@ -29,14 +29,12 @@ const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
|||||||
const toolcache = __importStar(require("@actions/tool-cache"));
|
const toolcache = __importStar(require("@actions/tool-cache"));
|
||||||
const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
|
const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
|
||||||
const yaml = __importStar(require("js-yaml"));
|
const yaml = __importStar(require("js-yaml"));
|
||||||
const query_string_1 = __importDefault(require("query-string"));
|
|
||||||
const semver = __importStar(require("semver"));
|
const semver = __importStar(require("semver"));
|
||||||
const uuid_1 = require("uuid");
|
const uuid_1 = require("uuid");
|
||||||
const actions_util_1 = require("./actions-util");
|
const actions_util_1 = require("./actions-util");
|
||||||
const api = __importStar(require("./api-client"));
|
const api = __importStar(require("./api-client"));
|
||||||
const defaults = __importStar(require("./defaults.json")); // Referenced from codeql-action-sync-tool!
|
const defaults = __importStar(require("./defaults.json")); // Referenced from codeql-action-sync-tool!
|
||||||
const error_matcher_1 = require("./error-matcher");
|
const error_matcher_1 = require("./error-matcher");
|
||||||
const feature_flags_1 = require("./feature-flags");
|
|
||||||
const languages_1 = require("./languages");
|
const languages_1 = require("./languages");
|
||||||
const toolrunner_error_catcher_1 = require("./toolrunner-error-catcher");
|
const toolrunner_error_catcher_1 = require("./toolrunner-error-catcher");
|
||||||
const trap_caching_1 = require("./trap-caching");
|
const trap_caching_1 = require("./trap-caching");
|
||||||
@@ -77,6 +75,7 @@ const CODEQL_VERSION_LUA_TRACER_CONFIG = "2.10.0";
|
|||||||
exports.CODEQL_VERSION_CONFIG_FILES = "2.10.1";
|
exports.CODEQL_VERSION_CONFIG_FILES = "2.10.1";
|
||||||
const CODEQL_VERSION_LUA_TRACING_GO_WINDOWS_FIXED = "2.10.4";
|
const CODEQL_VERSION_LUA_TRACING_GO_WINDOWS_FIXED = "2.10.4";
|
||||||
exports.CODEQL_VERSION_GHES_PACK_DOWNLOAD = "2.10.4";
|
exports.CODEQL_VERSION_GHES_PACK_DOWNLOAD = "2.10.4";
|
||||||
|
const CODEQL_VERSION_FILE_BASELINE_INFORMATION = "2.11.3";
|
||||||
/**
|
/**
|
||||||
* This variable controls using the new style of tracing from the CodeQL
|
* This variable controls using the new style of tracing from the CodeQL
|
||||||
* CLI. In particular, with versions above this we will use both indirect
|
* CLI. In particular, with versions above this we will use both indirect
|
||||||
@@ -120,20 +119,14 @@ function getCodeQLBundleName() {
|
|||||||
return `codeql-bundle-${platform}.tar.gz`;
|
return `codeql-bundle-${platform}.tar.gz`;
|
||||||
}
|
}
|
||||||
function getCodeQLActionRepository(logger) {
|
function getCodeQLActionRepository(logger) {
|
||||||
if (process.env["GITHUB_ACTION_REPOSITORY"] !== undefined) {
|
|
||||||
return process.env["GITHUB_ACTION_REPOSITORY"];
|
|
||||||
}
|
|
||||||
// The Actions Runner used with GitHub Enterprise Server 2.22 did not set the GITHUB_ACTION_REPOSITORY variable.
|
|
||||||
// This fallback logic can be removed after the end-of-support for 2.22 on 2021-09-23.
|
|
||||||
if ((0, actions_util_1.isRunningLocalAction)()) {
|
if ((0, actions_util_1.isRunningLocalAction)()) {
|
||||||
// This handles the case where the Action does not come from an Action repository,
|
// This handles the case where the Action does not come from an Action repository,
|
||||||
// e.g. our integration tests which use the Action code from the current checkout.
|
// e.g. our integration tests which use the Action code from the current checkout.
|
||||||
|
// In these cases, the GITHUB_ACTION_REPOSITORY environment variable is not set.
|
||||||
logger.info("The CodeQL Action is checked out locally. Using the default CodeQL Action repository.");
|
logger.info("The CodeQL Action is checked out locally. Using the default CodeQL Action repository.");
|
||||||
return exports.CODEQL_DEFAULT_ACTION_REPOSITORY;
|
return exports.CODEQL_DEFAULT_ACTION_REPOSITORY;
|
||||||
}
|
}
|
||||||
logger.info("GITHUB_ACTION_REPOSITORY environment variable was not set. Falling back to legacy method of finding the GitHub Action.");
|
return util.getRequiredEnvParam("GITHUB_ACTION_REPOSITORY");
|
||||||
const relativeScriptPathParts = (0, actions_util_1.getRelativeScriptPath)().split(path.sep);
|
|
||||||
return `${relativeScriptPathParts[0]}/${relativeScriptPathParts[1]}`;
|
|
||||||
}
|
}
|
||||||
exports.getCodeQLActionRepository = getCodeQLActionRepository;
|
exports.getCodeQLActionRepository = getCodeQLActionRepository;
|
||||||
async function getCodeQLBundleDownloadURL(apiDetails, variant, logger) {
|
async function getCodeQLBundleDownloadURL(apiDetails, variant, logger) {
|
||||||
@@ -216,7 +209,7 @@ async function getCodeQLBundleDownloadURL(apiDetails, variant, logger) {
|
|||||||
* version requirement. Must be set to true outside tests.
|
* version requirement. Must be set to true outside tests.
|
||||||
* @returns a { CodeQL, toolsVersion } object.
|
* @returns a { CodeQL, toolsVersion } object.
|
||||||
*/
|
*/
|
||||||
async function setupCodeQL(codeqlURL, apiDetails, tempDir, variant, features, logger, checkVersion) {
|
async function setupCodeQL(codeqlURL, apiDetails, tempDir, variant, bypassToolcache, logger, checkVersion) {
|
||||||
try {
|
try {
|
||||||
const forceLatestReason =
|
const forceLatestReason =
|
||||||
// We use the special value of 'latest' to prioritize the version in the
|
// We use the special value of 'latest' to prioritize the version in the
|
||||||
@@ -227,8 +220,7 @@ async function setupCodeQL(codeqlURL, apiDetails, tempDir, variant, features, lo
|
|||||||
// the toolcache when the appropriate feature is enabled. This
|
// the toolcache when the appropriate feature is enabled. This
|
||||||
// allows us to quickly rollback a broken bundle that has made its way
|
// allows us to quickly rollback a broken bundle that has made its way
|
||||||
// into the toolcache.
|
// into the toolcache.
|
||||||
codeqlURL === undefined &&
|
codeqlURL === undefined && bypassToolcache
|
||||||
(await features.getValue(feature_flags_1.Feature.BypassToolcacheEnabled))
|
|
||||||
? "a specific version of CodeQL was not requested and the bypass toolcache feature is enabled"
|
? "a specific version of CodeQL was not requested and the bypass toolcache feature is enabled"
|
||||||
: undefined;
|
: undefined;
|
||||||
const forceLatest = forceLatestReason !== undefined;
|
const forceLatest = forceLatestReason !== undefined;
|
||||||
@@ -269,7 +261,7 @@ async function setupCodeQL(codeqlURL, apiDetails, tempDir, variant, features, lo
|
|||||||
codeqlURL = await getCodeQLBundleDownloadURL(apiDetails, variant, logger);
|
codeqlURL = await getCodeQLBundleDownloadURL(apiDetails, variant, logger);
|
||||||
}
|
}
|
||||||
const parsedCodeQLURL = new URL(codeqlURL);
|
const parsedCodeQLURL = new URL(codeqlURL);
|
||||||
const parsedQueryString = query_string_1.default.parse(parsedCodeQLURL.search);
|
const searchParams = new URLSearchParams(parsedCodeQLURL.search);
|
||||||
const headers = {
|
const headers = {
|
||||||
accept: "application/octet-stream",
|
accept: "application/octet-stream",
|
||||||
};
|
};
|
||||||
@@ -278,7 +270,7 @@ async function setupCodeQL(codeqlURL, apiDetails, tempDir, variant, features, lo
|
|||||||
// This avoids leaking Enterprise tokens to dotcom.
|
// 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.
|
// We also don't want to send an authorization header if there's already a token provided in the URL.
|
||||||
if (codeqlURL.startsWith(`${apiDetails.url}/`) &&
|
if (codeqlURL.startsWith(`${apiDetails.url}/`) &&
|
||||||
parsedQueryString["token"] === undefined) {
|
!searchParams.has("token")) {
|
||||||
logger.debug("Downloading CodeQL bundle with token.");
|
logger.debug("Downloading CodeQL bundle with token.");
|
||||||
headers.authorization = `token ${apiDetails.auth}`;
|
headers.authorization = `token ${apiDetails.auth}`;
|
||||||
}
|
}
|
||||||
@@ -378,6 +370,7 @@ function setCodeQL(partialCodeql) {
|
|||||||
databaseRunQueries: resolveFunction(partialCodeql, "databaseRunQueries"),
|
databaseRunQueries: resolveFunction(partialCodeql, "databaseRunQueries"),
|
||||||
databaseInterpretResults: resolveFunction(partialCodeql, "databaseInterpretResults"),
|
databaseInterpretResults: resolveFunction(partialCodeql, "databaseInterpretResults"),
|
||||||
databasePrintBaseline: resolveFunction(partialCodeql, "databasePrintBaseline"),
|
databasePrintBaseline: resolveFunction(partialCodeql, "databasePrintBaseline"),
|
||||||
|
diagnosticsExport: resolveFunction(partialCodeql, "diagnosticsExport"),
|
||||||
};
|
};
|
||||||
return cachedCodeQL;
|
return cachedCodeQL;
|
||||||
}
|
}
|
||||||
@@ -673,9 +666,9 @@ async function getCodeQLForCmd(cmd, checkVersion) {
|
|||||||
if (querySuitePath) {
|
if (querySuitePath) {
|
||||||
codeqlArgs.push(querySuitePath);
|
codeqlArgs.push(querySuitePath);
|
||||||
}
|
}
|
||||||
await runTool(cmd, codeqlArgs);
|
await (0, toolrunner_error_catcher_1.toolrunnerErrorCatcher)(cmd, codeqlArgs, error_matcher_1.errorMatchers);
|
||||||
},
|
},
|
||||||
async databaseInterpretResults(databasePath, querySuitePaths, sarifFile, addSnippetsFlag, threadsFlag, verbosityFlag, automationDetailsId, featureEnablement) {
|
async databaseInterpretResults(databasePath, querySuitePaths, sarifFile, addSnippetsFlag, threadsFlag, verbosityFlag, automationDetailsId) {
|
||||||
const codeqlArgs = [
|
const codeqlArgs = [
|
||||||
"database",
|
"database",
|
||||||
"interpret-results",
|
"interpret-results",
|
||||||
@@ -694,7 +687,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
|
|||||||
if (automationDetailsId !== undefined) {
|
if (automationDetailsId !== undefined) {
|
||||||
codeqlArgs.push("--sarif-category", automationDetailsId);
|
codeqlArgs.push("--sarif-category", automationDetailsId);
|
||||||
}
|
}
|
||||||
if (await featureEnablement.getValue(feature_flags_1.Feature.FileBaselineInformationEnabled, this)) {
|
if (await util.codeQlVersionAbove(this, CODEQL_VERSION_FILE_BASELINE_INFORMATION)) {
|
||||||
codeqlArgs.push("--sarif-add-baseline-file-info");
|
codeqlArgs.push("--sarif-add-baseline-file-info");
|
||||||
}
|
}
|
||||||
codeqlArgs.push(databasePath);
|
codeqlArgs.push(databasePath);
|
||||||
@@ -702,7 +695,8 @@ async function getCodeQLForCmd(cmd, checkVersion) {
|
|||||||
codeqlArgs.push(...querySuitePaths);
|
codeqlArgs.push(...querySuitePaths);
|
||||||
}
|
}
|
||||||
// capture stdout, which contains analysis summaries
|
// capture stdout, which contains analysis summaries
|
||||||
return await runTool(cmd, codeqlArgs);
|
const returnState = await (0, toolrunner_error_catcher_1.toolrunnerErrorCatcher)(cmd, codeqlArgs, error_matcher_1.errorMatchers);
|
||||||
|
return returnState.stdout;
|
||||||
},
|
},
|
||||||
async databasePrintBaseline(databasePath) {
|
async databasePrintBaseline(databasePath) {
|
||||||
const codeqlArgs = [
|
const codeqlArgs = [
|
||||||
@@ -778,6 +772,19 @@ async function getCodeQLForCmd(cmd, checkVersion) {
|
|||||||
];
|
];
|
||||||
await new toolrunner.ToolRunner(cmd, args).exec();
|
await new toolrunner.ToolRunner(cmd, args).exec();
|
||||||
},
|
},
|
||||||
|
async diagnosticsExport(sarifFile, automationDetailsId) {
|
||||||
|
const args = [
|
||||||
|
"diagnostics",
|
||||||
|
"export",
|
||||||
|
"--format=sarif-latest",
|
||||||
|
`--output=${sarifFile}`,
|
||||||
|
...getExtraOptionsFromEnv(["diagnostics", "export"]),
|
||||||
|
];
|
||||||
|
if (automationDetailsId !== undefined) {
|
||||||
|
args.push("--sarif-category", automationDetailsId);
|
||||||
|
}
|
||||||
|
await new toolrunner.ToolRunner(cmd, args).exec();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
// To ensure that status reports include the CodeQL CLI version wherever
|
// To ensure that status reports include the CodeQL CLI version wherever
|
||||||
// possible, we want to call getVersion(), which populates the version value
|
// possible, we want to call getVersion(), which populates the version value
|
||||||
@@ -853,11 +860,16 @@ async function runTool(cmd, args = []) {
|
|||||||
const exitCode = await new toolrunner.ToolRunner(cmd, args, {
|
const exitCode = await new toolrunner.ToolRunner(cmd, args, {
|
||||||
listeners: {
|
listeners: {
|
||||||
stdout: (data) => {
|
stdout: (data) => {
|
||||||
output += data.toString();
|
output += data.toString("utf8");
|
||||||
},
|
},
|
||||||
stderr: (data) => {
|
stderr: (data) => {
|
||||||
const toRead = Math.min(maxErrorSize - error.length, data.length);
|
let readStartIndex = 0;
|
||||||
error += data.toString("utf8", 0, toRead);
|
// If the error is too large, then we only take the last 20,000 characters
|
||||||
|
if (data.length - maxErrorSize > 0) {
|
||||||
|
// Eg: if we have 20,000 the start index should be 2.
|
||||||
|
readStartIndex = data.length - maxErrorSize + 1;
|
||||||
|
}
|
||||||
|
error += data.toString("utf8", readStartIndex);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ignoreReturnCode: true,
|
ignoreReturnCode: true,
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
Generated
+27
-19
@@ -27,11 +27,13 @@ const fs = __importStar(require("fs"));
|
|||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
const toolrunner = __importStar(require("@actions/exec/lib/toolrunner"));
|
||||||
const toolcache = __importStar(require("@actions/tool-cache"));
|
const toolcache = __importStar(require("@actions/tool-cache"));
|
||||||
|
const safeWhich = __importStar(require("@chrisgavin/safe-which"));
|
||||||
const ava_1 = __importDefault(require("ava"));
|
const ava_1 = __importDefault(require("ava"));
|
||||||
const del_1 = __importDefault(require("del"));
|
const del_1 = __importDefault(require("del"));
|
||||||
const yaml = __importStar(require("js-yaml"));
|
const yaml = __importStar(require("js-yaml"));
|
||||||
const nock_1 = __importDefault(require("nock"));
|
const nock_1 = __importDefault(require("nock"));
|
||||||
const sinon = __importStar(require("sinon"));
|
const sinon = __importStar(require("sinon"));
|
||||||
|
const actionsUtil = __importStar(require("./actions-util"));
|
||||||
const codeql = __importStar(require("./codeql"));
|
const codeql = __importStar(require("./codeql"));
|
||||||
const defaults = __importStar(require("./defaults.json"));
|
const defaults = __importStar(require("./defaults.json"));
|
||||||
const feature_flags_1 = require("./feature-flags");
|
const feature_flags_1 = require("./feature-flags");
|
||||||
@@ -81,7 +83,7 @@ ava_1.default.beforeEach(() => {
|
|||||||
trapCacheDownloadTime: 0,
|
trapCacheDownloadTime: 0,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
async function mockApiAndSetupCodeQL({ apiDetails, featureEnablement, isPinned, tmpDir, toolsInput, version, }) {
|
async function mockApiAndSetupCodeQL({ apiDetails, bypassToolcache, isPinned, tmpDir, toolsInput, version, }) {
|
||||||
var _a;
|
var _a;
|
||||||
const platform = process.platform === "win32"
|
const platform = process.platform === "win32"
|
||||||
? "win64"
|
? "win64"
|
||||||
@@ -95,7 +97,7 @@ async function mockApiAndSetupCodeQL({ apiDetails, featureEnablement, isPinned,
|
|||||||
(0, nock_1.default)(baseUrl)
|
(0, nock_1.default)(baseUrl)
|
||||||
.get(relativeUrl)
|
.get(relativeUrl)
|
||||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle${isPinned ? "-pinned" : ""}.tar.gz`));
|
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle${isPinned ? "-pinned" : ""}.tar.gz`));
|
||||||
return await codeql.setupCodeQL(toolsInput ? toolsInput.input : `${baseUrl}${relativeUrl}`, apiDetails !== null && apiDetails !== void 0 ? apiDetails : sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, featureEnablement !== null && featureEnablement !== void 0 ? featureEnablement : (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true), false);
|
return await codeql.setupCodeQL(toolsInput ? toolsInput.input : `${baseUrl}${relativeUrl}`, apiDetails !== null && apiDetails !== void 0 ? apiDetails : sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, !!bypassToolcache, (0, logging_1.getRunnerLogger)(true), false);
|
||||||
}
|
}
|
||||||
(0, ava_1.default)("download codeql bundle cache", async (t) => {
|
(0, ava_1.default)("download codeql bundle cache", async (t) => {
|
||||||
await util.withTmpDir(async (tmpDir) => {
|
await util.withTmpDir(async (tmpDir) => {
|
||||||
@@ -138,7 +140,7 @@ async function mockApiAndSetupCodeQL({ apiDetails, featureEnablement, isPinned,
|
|||||||
});
|
});
|
||||||
t.assert(toolcache.find("CodeQL", "0.0.0-20200601"));
|
t.assert(toolcache.find("CodeQL", "0.0.0-20200601"));
|
||||||
t.deepEqual(pinnedCodeQLConfig.toolsVersion, "20200601");
|
t.deepEqual(pinnedCodeQLConfig.toolsVersion, "20200601");
|
||||||
const codeQLConfig = await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true), false);
|
const codeQLConfig = await codeql.setupCodeQL(undefined, sampleApiDetails, tmpDir, util.GitHubVariant.DOTCOM, false, (0, logging_1.getRunnerLogger)(true), false);
|
||||||
t.deepEqual(codeQLConfig.toolsVersion, "0.0.0-20200601");
|
t.deepEqual(codeQLConfig.toolsVersion, "0.0.0-20200601");
|
||||||
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
||||||
t.is(cachedVersions.length, 1);
|
t.is(cachedVersions.length, 1);
|
||||||
@@ -208,7 +210,7 @@ for (const [isFeatureEnabled, toolsInput, shouldToolcacheBeBypassed,] of TOOLCAC
|
|||||||
await mockApiAndSetupCodeQL({
|
await mockApiAndSetupCodeQL({
|
||||||
version: defaults.bundleVersion,
|
version: defaults.bundleVersion,
|
||||||
apiDetails: sampleApiDetails,
|
apiDetails: sampleApiDetails,
|
||||||
featureEnablement: (0, testing_utils_1.createFeatures)(isFeatureEnabled ? [feature_flags_1.Feature.BypassToolcacheEnabled] : []),
|
bypassToolcache: isFeatureEnabled,
|
||||||
toolsInput: { input: toolsInput },
|
toolsInput: { input: toolsInput },
|
||||||
tmpDir,
|
tmpDir,
|
||||||
});
|
});
|
||||||
@@ -240,7 +242,7 @@ for (const [isFeatureEnabled, toolsInput, shouldToolcacheBeBypassed,] of TOOLCAC
|
|||||||
(0, nock_1.default)("https://example.githubenterprise.com")
|
(0, nock_1.default)("https://example.githubenterprise.com")
|
||||||
.get(`/github/codeql-action/releases/download/${defaults.bundleVersion}/${codeQLBundleName}`)
|
.get(`/github/codeql-action/releases/download/${defaults.bundleVersion}/${codeQLBundleName}`)
|
||||||
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle-pinned.tar.gz`));
|
.replyWithFile(200, path.join(__dirname, `/../src/testdata/codeql-bundle-pinned.tar.gz`));
|
||||||
await codeql.setupCodeQL(undefined, sampleGHAEApiDetails, tmpDir, util.GitHubVariant.GHAE, (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true), false);
|
await codeql.setupCodeQL(undefined, sampleGHAEApiDetails, tmpDir, util.GitHubVariant.GHAE, false, (0, logging_1.getRunnerLogger)(true), false);
|
||||||
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
const cachedVersions = toolcache.findAllVersions("CodeQL");
|
||||||
t.is(cachedVersions.length, 1);
|
t.is(cachedVersions.length, 1);
|
||||||
});
|
});
|
||||||
@@ -297,6 +299,8 @@ for (const [isFeatureEnabled, toolsInput, shouldToolcacheBeBypassed,] of TOOLCAC
|
|||||||
process.env["RUNNER_TEMP"] = path.dirname(__dirname);
|
process.env["RUNNER_TEMP"] = path.dirname(__dirname);
|
||||||
const repoLocalRunner = codeql.getCodeQLActionRepository(logger);
|
const repoLocalRunner = codeql.getCodeQLActionRepository(logger);
|
||||||
t.deepEqual(repoLocalRunner, "github/codeql-action");
|
t.deepEqual(repoLocalRunner, "github/codeql-action");
|
||||||
|
// isRunningLocalAction() === false
|
||||||
|
sinon.stub(actionsUtil, "isRunningLocalAction").returns(false);
|
||||||
process.env["GITHUB_ACTION_REPOSITORY"] = "xxx/yyy";
|
process.env["GITHUB_ACTION_REPOSITORY"] = "xxx/yyy";
|
||||||
const repoEnv = codeql.getCodeQLActionRepository(logger);
|
const repoEnv = codeql.getCodeQLActionRepository(logger);
|
||||||
t.deepEqual(repoEnv, "xxx/yyy");
|
t.deepEqual(repoEnv, "xxx/yyy");
|
||||||
@@ -305,14 +309,18 @@ for (const [isFeatureEnabled, toolsInput, shouldToolcacheBeBypassed,] of TOOLCAC
|
|||||||
const runnerConstructorStub = stubToolRunnerConstructor();
|
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
sinon.stub(codeqlObject, "getVersion").resolves("2.7.0");
|
sinon.stub(codeqlObject, "getVersion").resolves("2.7.0");
|
||||||
await codeqlObject.databaseInterpretResults("", [], "", "", "", "-v", "", (0, testing_utils_1.createFeatures)([]));
|
// safeWhich throws because of the test CodeQL object.
|
||||||
|
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||||
|
await codeqlObject.databaseInterpretResults("", [], "", "", "", "-v", "");
|
||||||
t.false(runnerConstructorStub.firstCall.args[1].includes("--sarif-add-query-help"), "--sarif-add-query-help should be absent, but it is present");
|
t.false(runnerConstructorStub.firstCall.args[1].includes("--sarif-add-query-help"), "--sarif-add-query-help should be absent, but it is present");
|
||||||
});
|
});
|
||||||
(0, ava_1.default)("databaseInterpretResults() sets --sarif-add-query-help for 2.7.1", async (t) => {
|
(0, ava_1.default)("databaseInterpretResults() sets --sarif-add-query-help for 2.7.1", async (t) => {
|
||||||
const runnerConstructorStub = stubToolRunnerConstructor();
|
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
sinon.stub(codeqlObject, "getVersion").resolves("2.7.1");
|
sinon.stub(codeqlObject, "getVersion").resolves("2.7.1");
|
||||||
await codeqlObject.databaseInterpretResults("", [], "", "", "", "-v", "", (0, testing_utils_1.createFeatures)([]));
|
// safeWhich throws because of the test CodeQL object.
|
||||||
|
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||||
|
await codeqlObject.databaseInterpretResults("", [], "", "", "", "-v", "");
|
||||||
t.true(runnerConstructorStub.firstCall.args[1].includes("--sarif-add-query-help"), "--sarif-add-query-help should be present, but it is absent");
|
t.true(runnerConstructorStub.firstCall.args[1].includes("--sarif-add-query-help"), "--sarif-add-query-help should be present, but it is absent");
|
||||||
});
|
});
|
||||||
(0, ava_1.default)("databaseInitCluster() without injected codescanning config", async (t) => {
|
(0, ava_1.default)("databaseInitCluster() without injected codescanning config", async (t) => {
|
||||||
@@ -320,6 +328,8 @@ for (const [isFeatureEnabled, toolsInput, shouldToolcacheBeBypassed,] of TOOLCAC
|
|||||||
const runnerConstructorStub = stubToolRunnerConstructor();
|
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
sinon.stub(codeqlObject, "getVersion").resolves("2.8.1");
|
sinon.stub(codeqlObject, "getVersion").resolves("2.8.1");
|
||||||
|
// safeWhich throws because of the test CodeQL object.
|
||||||
|
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||||
const thisStubConfig = {
|
const thisStubConfig = {
|
||||||
...stubConfig,
|
...stubConfig,
|
||||||
tempDir,
|
tempDir,
|
||||||
@@ -561,24 +571,22 @@ const injectedConfigMacro = ava_1.default.macro({
|
|||||||
process.env["CODEQL_PASS_CONFIG_TO_CLI"] = origCODEQL_PASS_CONFIG_TO_CLI;
|
process.env["CODEQL_PASS_CONFIG_TO_CLI"] = origCODEQL_PASS_CONFIG_TO_CLI;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
(0, ava_1.default)("databaseInterpretResults() sets --sarif-add-baseline-file-info when feature enabled", async (t) => {
|
(0, ava_1.default)("databaseInterpretResults() sets --sarif-add-baseline-file-info for 2.11.3", async (t) => {
|
||||||
const runnerConstructorStub = stubToolRunnerConstructor();
|
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
// We need to set a CodeQL version such that running `databaseInterpretResults` does not crash.
|
sinon.stub(codeqlObject, "getVersion").resolves("2.11.3");
|
||||||
// The version of CodeQL is checked separately to determine feature enablement, and does not
|
// safeWhich throws because of the test CodeQL object.
|
||||||
// otherwise impact this test, so set it to 0.0.0.
|
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||||
sinon.stub(codeqlObject, "getVersion").resolves("0.0.0");
|
await codeqlObject.databaseInterpretResults("", [], "", "", "", "-v", "");
|
||||||
await codeqlObject.databaseInterpretResults("", [], "", "", "", "-v", "", (0, testing_utils_1.createFeatures)([feature_flags_1.Feature.FileBaselineInformationEnabled]));
|
|
||||||
t.true(runnerConstructorStub.firstCall.args[1].includes("--sarif-add-baseline-file-info"), "--sarif-add-baseline-file-info should be present, but it is absent");
|
t.true(runnerConstructorStub.firstCall.args[1].includes("--sarif-add-baseline-file-info"), "--sarif-add-baseline-file-info should be present, but it is absent");
|
||||||
});
|
});
|
||||||
(0, ava_1.default)("databaseInterpretResults() does not set --sarif-add-baseline-file-info if feature disabled", async (t) => {
|
(0, ava_1.default)("databaseInterpretResults() does not set --sarif-add-baseline-file-info for 2.11.2", async (t) => {
|
||||||
const runnerConstructorStub = stubToolRunnerConstructor();
|
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||||
const codeqlObject = await codeql.getCodeQLForTesting();
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
// We need to set a CodeQL version such that running `databaseInterpretResults` does not crash.
|
sinon.stub(codeqlObject, "getVersion").resolves("2.11.2");
|
||||||
// The version of CodeQL is checked upstream to determine feature enablement, so it does not
|
// safeWhich throws because of the test CodeQL object.
|
||||||
// affect this test.
|
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||||
sinon.stub(codeqlObject, "getVersion").resolves("0.0.0");
|
await codeqlObject.databaseInterpretResults("", [], "", "", "", "-v", "");
|
||||||
await codeqlObject.databaseInterpretResults("", [], "", "", "", "-v", "", (0, testing_utils_1.createFeatures)([]));
|
|
||||||
t.false(runnerConstructorStub.firstCall.args[1].includes("--sarif-add-baseline-file-info"), "--sarif-add-baseline-file-info must be absent, but it is present");
|
t.false(runnerConstructorStub.firstCall.args[1].includes("--sarif-add-baseline-file-info"), "--sarif-add-baseline-file-info must be absent, but it is present");
|
||||||
});
|
});
|
||||||
function stubToolRunnerConstructor() {
|
function stubToolRunnerConstructor() {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Generated
+45
-13
@@ -19,7 +19,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.downloadPacks = exports.getConfig = exports.getPathToParsedConfigFile = exports.initConfig = exports.parsePacks = exports.validatePackSpecification = exports.prettyPrintPack = exports.parsePacksSpecification = exports.parsePacksFromConfig = exports.calculateAugmentation = exports.getDefaultConfig = exports.getUnknownLanguagesError = exports.getNoLanguagesError = exports.getConfigFileDirectoryGivenMessage = exports.getConfigFileFormatInvalidMessage = exports.getConfigFileRepoFormatInvalidMessage = exports.getConfigFileDoesNotExistErrorMessage = exports.getConfigFileOutsideWorkspaceErrorMessage = exports.getLocalPathDoesNotExist = exports.getLocalPathOutsideOfRepository = exports.getPacksStrInvalid = exports.getPacksInvalid = exports.getPacksInvalidSplit = exports.getPathsInvalid = exports.getPathsIgnoreInvalid = exports.getQueryUsesInvalid = exports.getQueriesMissingUses = exports.getQueriesInvalid = exports.getDisableDefaultQueriesInvalid = exports.getNameInvalid = exports.validateAndSanitisePath = exports.defaultAugmentationProperties = void 0;
|
exports.downloadPacks = exports.getConfig = exports.getPathToParsedConfigFile = exports.initConfig = exports.parsePacks = exports.validatePackSpecification = exports.prettyPrintPack = exports.parsePacksSpecification = exports.parsePacksFromConfig = exports.calculateAugmentation = exports.getDefaultConfig = exports.getRawLanguages = exports.getLanguages = exports.getLanguagesInRepo = exports.getUnknownLanguagesError = exports.getNoLanguagesError = exports.getConfigFileDirectoryGivenMessage = exports.getConfigFileFormatInvalidMessage = exports.getConfigFileRepoFormatInvalidMessage = exports.getConfigFileDoesNotExistErrorMessage = exports.getConfigFileOutsideWorkspaceErrorMessage = exports.getLocalPathDoesNotExist = exports.getLocalPathOutsideOfRepository = exports.getPacksStrInvalid = exports.getPacksInvalid = exports.getPacksInvalidSplit = exports.getPathsInvalid = exports.getPathsIgnoreInvalid = exports.getQueryUsesInvalid = exports.getQueriesMissingUses = exports.getQueriesInvalid = exports.getDisableDefaultQueriesInvalid = exports.getNameInvalid = exports.validateAndSanitisePath = exports.defaultAugmentationProperties = void 0;
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
// We need to import `performance` on Node 12
|
// We need to import `performance` on Node 12
|
||||||
@@ -385,7 +385,8 @@ function getUnknownLanguagesError(languages) {
|
|||||||
}
|
}
|
||||||
exports.getUnknownLanguagesError = getUnknownLanguagesError;
|
exports.getUnknownLanguagesError = getUnknownLanguagesError;
|
||||||
/**
|
/**
|
||||||
* Gets the set of languages in the current repository
|
* Gets the set of languages in the current repository that are
|
||||||
|
* scannable by CodeQL.
|
||||||
*/
|
*/
|
||||||
async function getLanguagesInRepo(repository, logger) {
|
async function getLanguagesInRepo(repository, logger) {
|
||||||
logger.debug(`GitHub repo ${repository.owner} ${repository.repo}`);
|
logger.debug(`GitHub repo ${repository.owner} ${repository.repo}`);
|
||||||
@@ -407,6 +408,7 @@ async function getLanguagesInRepo(repository, logger) {
|
|||||||
}
|
}
|
||||||
return [...languages];
|
return [...languages];
|
||||||
}
|
}
|
||||||
|
exports.getLanguagesInRepo = getLanguagesInRepo;
|
||||||
/**
|
/**
|
||||||
* Get the languages to analyse.
|
* Get the languages to analyse.
|
||||||
*
|
*
|
||||||
@@ -418,18 +420,16 @@ async function getLanguagesInRepo(repository, logger) {
|
|||||||
* then throw an error.
|
* then throw an error.
|
||||||
*/
|
*/
|
||||||
async function getLanguages(codeQL, languagesInput, repository, logger) {
|
async function getLanguages(codeQL, languagesInput, repository, logger) {
|
||||||
// Obtain from action input 'languages' if set
|
// Obtain languages without filtering them.
|
||||||
let languages = (languagesInput || "")
|
const { rawLanguages, autodetected } = await getRawLanguages(languagesInput, repository, logger);
|
||||||
.split(",")
|
let languages = rawLanguages.map(languages_1.resolveAlias);
|
||||||
.map((x) => x.trim())
|
if (autodetected) {
|
||||||
.filter((x) => x.length > 0);
|
|
||||||
logger.info(`Languages from configuration: ${JSON.stringify(languages)}`);
|
|
||||||
if (languages.length === 0) {
|
|
||||||
// Obtain languages as all languages in the repo that can be analysed
|
|
||||||
languages = await getLanguagesInRepo(repository, logger);
|
|
||||||
const availableLanguages = await codeQL.resolveLanguages();
|
const availableLanguages = await codeQL.resolveLanguages();
|
||||||
languages = languages.filter((value) => value in availableLanguages);
|
languages = languages.filter((value) => value in availableLanguages);
|
||||||
logger.info(`Automatically detected languages: ${JSON.stringify(languages)}`);
|
logger.info(`Automatically detected languages: ${languages.join(", ")}`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logger.info(`Languages from configuration: ${languages.join(", ")}`);
|
||||||
}
|
}
|
||||||
// If the languages parameter was not given and no languages were
|
// If the languages parameter was not given and no languages were
|
||||||
// detected then fail here as this is a workflow configuration error.
|
// detected then fail here as this is a workflow configuration error.
|
||||||
@@ -440,19 +440,51 @@ async function getLanguages(codeQL, languagesInput, repository, logger) {
|
|||||||
const parsedLanguages = [];
|
const parsedLanguages = [];
|
||||||
const unknownLanguages = [];
|
const unknownLanguages = [];
|
||||||
for (const language of languages) {
|
for (const language of languages) {
|
||||||
|
// We know this is not an alias since we resolved it above.
|
||||||
const parsedLanguage = (0, languages_1.parseLanguage)(language);
|
const parsedLanguage = (0, languages_1.parseLanguage)(language);
|
||||||
if (parsedLanguage === undefined) {
|
if (parsedLanguage === undefined) {
|
||||||
unknownLanguages.push(language);
|
unknownLanguages.push(language);
|
||||||
}
|
}
|
||||||
else if (parsedLanguages.indexOf(parsedLanguage) === -1) {
|
else if (!parsedLanguages.includes(parsedLanguage)) {
|
||||||
parsedLanguages.push(parsedLanguage);
|
parsedLanguages.push(parsedLanguage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Any unknown languages here would have come directly from the input
|
||||||
|
// since we filter unknown languages coming from the GitHub API.
|
||||||
if (unknownLanguages.length > 0) {
|
if (unknownLanguages.length > 0) {
|
||||||
throw new Error(getUnknownLanguagesError(unknownLanguages));
|
throw new Error(getUnknownLanguagesError(unknownLanguages));
|
||||||
}
|
}
|
||||||
return parsedLanguages;
|
return parsedLanguages;
|
||||||
}
|
}
|
||||||
|
exports.getLanguages = getLanguages;
|
||||||
|
/**
|
||||||
|
* Gets the set of languages in the current repository without checking to
|
||||||
|
* see if these languages are actually supported by CodeQL.
|
||||||
|
*
|
||||||
|
* @param languagesInput The languages from the workflow input
|
||||||
|
* @param repository the owner/name of the repository
|
||||||
|
* @param logger a logger
|
||||||
|
* @returns A tuple containing a list of languages in this repository that might be
|
||||||
|
* analyzable and whether or not this list was determined automatically.
|
||||||
|
*/
|
||||||
|
async function getRawLanguages(languagesInput, repository, logger) {
|
||||||
|
// Obtain from action input 'languages' if set
|
||||||
|
let rawLanguages = (languagesInput || "")
|
||||||
|
.split(",")
|
||||||
|
.map((x) => x.trim().toLowerCase())
|
||||||
|
.filter((x) => x.length > 0);
|
||||||
|
let autodetected;
|
||||||
|
if (rawLanguages.length) {
|
||||||
|
autodetected = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
autodetected = true;
|
||||||
|
// Obtain all languages in the repo that can be analysed
|
||||||
|
rawLanguages = (await getLanguagesInRepo(repository, logger));
|
||||||
|
}
|
||||||
|
return { rawLanguages, autodetected };
|
||||||
|
}
|
||||||
|
exports.getRawLanguages = getRawLanguages;
|
||||||
async function addQueriesAndPacksFromWorkflow(codeQL, queriesInput, languages, resultMap, packs, tempDir, workspacePath, apiDetails, featureEnablement, logger) {
|
async function addQueriesAndPacksFromWorkflow(codeQL, queriesInput, languages, resultMap, packs, tempDir, workspacePath, apiDetails, featureEnablement, logger) {
|
||||||
let injectedMlQueries = false;
|
let injectedMlQueries = false;
|
||||||
queriesInput = queriesInput.trim();
|
queriesInput = queriesInput.trim();
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Generated
+84
-5
@@ -34,6 +34,7 @@ const configUtils = __importStar(require("./config-utils"));
|
|||||||
const feature_flags_1 = require("./feature-flags");
|
const feature_flags_1 = require("./feature-flags");
|
||||||
const languages_1 = require("./languages");
|
const languages_1 = require("./languages");
|
||||||
const logging_1 = require("./logging");
|
const logging_1 = require("./logging");
|
||||||
|
const repository_1 = require("./repository");
|
||||||
const testing_utils_1 = require("./testing-utils");
|
const testing_utils_1 = require("./testing-utils");
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
(0, testing_utils_1.setupTests)(ava_1.default);
|
(0, testing_utils_1.setupTests)(ava_1.default);
|
||||||
@@ -933,11 +934,7 @@ function parseInputAndConfigMacro(t, packsFromConfig, packsFromInput, languages,
|
|||||||
languages, "/a/b", mockLogger), expected);
|
languages, "/a/b", mockLogger), expected);
|
||||||
}
|
}
|
||||||
parseInputAndConfigMacro.title = (providedTitle) => `Parse Packs input and config: ${providedTitle}`;
|
parseInputAndConfigMacro.title = (providedTitle) => `Parse Packs input and config: ${providedTitle}`;
|
||||||
const mockLogger = {
|
const mockLogger = (0, logging_1.getRunnerLogger)(true);
|
||||||
info: (message) => {
|
|
||||||
console.log(message);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
function parseInputAndConfigErrorMacro(t, packsFromConfig, packsFromInput, languages, packsFromInputOverride, expected) {
|
function parseInputAndConfigErrorMacro(t, packsFromConfig, packsFromInput, languages, packsFromInputOverride, expected) {
|
||||||
t.throws(() => {
|
t.throws(() => {
|
||||||
configUtils.parsePacks(packsFromConfig, packsFromInput, packsFromInputOverride, languages, "/a/b", mockLogger);
|
configUtils.parsePacks(packsFromConfig, packsFromInput, packsFromInputOverride, languages, "/a/b", mockLogger);
|
||||||
@@ -1237,4 +1234,86 @@ const calculateAugmentationErrorMacro = ava_1.default.macro({
|
|||||||
}, { instanceOf: Error }, "Invalid 'registries' input. Must be an array of objects with 'url' and 'packages' properties.");
|
}, { instanceOf: Error }, "Invalid 'registries' input. Must be an array of objects with 'url' and 'packages' properties.");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// getLanguages
|
||||||
|
const mockRepositoryNwo = (0, repository_1.parseRepositoryNwo)("owner/repo");
|
||||||
|
// eslint-disable-next-line github/array-foreach
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name: "languages from input",
|
||||||
|
codeqlResolvedLanguages: ["javascript", "java", "python"],
|
||||||
|
languagesInput: "jAvAscript, \n jaVa",
|
||||||
|
languagesInRepository: ["SwiFt", "other"],
|
||||||
|
expectedLanguages: ["javascript", "java"],
|
||||||
|
expectedApiCall: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "languages from github api",
|
||||||
|
codeqlResolvedLanguages: ["javascript", "java", "python"],
|
||||||
|
languagesInput: "",
|
||||||
|
languagesInRepository: [" jAvAscript\n \t", " jaVa", "SwiFt", "other"],
|
||||||
|
expectedLanguages: ["javascript", "java"],
|
||||||
|
expectedApiCall: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "aliases from input",
|
||||||
|
codeqlResolvedLanguages: ["javascript", "csharp", "cpp", "java", "python"],
|
||||||
|
languagesInput: " typEscript\n \t, C#, c , KoTlin",
|
||||||
|
languagesInRepository: ["SwiFt", "other"],
|
||||||
|
expectedLanguages: ["javascript", "csharp", "cpp", "java"],
|
||||||
|
expectedApiCall: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "duplicate languages from input",
|
||||||
|
codeqlResolvedLanguages: ["javascript", "java", "python"],
|
||||||
|
languagesInput: "jAvAscript, \n jaVa, kotlin, typescript",
|
||||||
|
languagesInRepository: ["SwiFt", "other"],
|
||||||
|
expectedLanguages: ["javascript", "java"],
|
||||||
|
expectedApiCall: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "aliases from github api",
|
||||||
|
codeqlResolvedLanguages: ["javascript", "csharp", "cpp", "java", "python"],
|
||||||
|
languagesInput: "",
|
||||||
|
languagesInRepository: [" typEscript\n \t", " C#", "c", "other"],
|
||||||
|
expectedLanguages: ["javascript", "csharp", "cpp"],
|
||||||
|
expectedApiCall: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no languages",
|
||||||
|
codeqlResolvedLanguages: ["javascript", "java", "python"],
|
||||||
|
languagesInput: "",
|
||||||
|
languagesInRepository: [],
|
||||||
|
expectedApiCall: true,
|
||||||
|
expectedError: configUtils.getNoLanguagesError(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unrecognized languages from input",
|
||||||
|
codeqlResolvedLanguages: ["javascript", "java", "python"],
|
||||||
|
languagesInput: "a, b, c, javascript",
|
||||||
|
languagesInRepository: [],
|
||||||
|
expectedApiCall: false,
|
||||||
|
expectedError: configUtils.getUnknownLanguagesError(["a", "b"]),
|
||||||
|
},
|
||||||
|
].forEach((args) => {
|
||||||
|
(0, ava_1.default)(`getLanguages: ${args.name}`, async (t) => {
|
||||||
|
const mockRequest = (0, testing_utils_1.mockLanguagesInRepo)(args.languagesInRepository);
|
||||||
|
const languages = args.codeqlResolvedLanguages.reduce((acc, lang) => ({
|
||||||
|
...acc,
|
||||||
|
[lang]: true,
|
||||||
|
}), {});
|
||||||
|
const codeQL = (0, codeql_1.setCodeQL)({
|
||||||
|
resolveLanguages: () => Promise.resolve(languages),
|
||||||
|
});
|
||||||
|
if (args.expectedLanguages) {
|
||||||
|
// happy path
|
||||||
|
const actualLanguages = await configUtils.getLanguages(codeQL, args.languagesInput, mockRepositoryNwo, 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);
|
||||||
|
});
|
||||||
|
});
|
||||||
//# sourceMappingURL=config-utils.test.js.map
|
//# sourceMappingURL=config-utils.test.js.map
|
||||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"bundleVersion": "codeql-bundle-20221105"
|
"bundleVersion": "codeql-bundle-20221211"
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+4
@@ -12,6 +12,10 @@ exports.namedMatchersForTesting = {
|
|||||||
message: "No code found during the build. Please see:\n" +
|
message: "No code found during the build. Please see:\n" +
|
||||||
"https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/troubleshooting-code-scanning#no-code-found-during-the-build",
|
"https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/troubleshooting-code-scanning#no-code-found-during-the-build",
|
||||||
},
|
},
|
||||||
|
fatalError: {
|
||||||
|
outputRegex: new RegExp("A fatal error occurred"),
|
||||||
|
message: "A fatal error occurred.",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
// we collapse the matches into an array for use in execErrorCatcher
|
// we collapse the matches into an array for use in execErrorCatcher
|
||||||
exports.errorMatchers = Object.values(exports.namedMatchersForTesting);
|
exports.errorMatchers = Object.values(exports.namedMatchersForTesting);
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"error-matcher.js","sourceRoot":"","sources":["../src/error-matcher.ts"],"names":[],"mappings":";;;AAQA,qCAAqC;AACxB,QAAA,uBAAuB,GAAoC;IACtE;;MAEE;IACF,iBAAiB,EAAE;QACjB,QAAQ,EAAE,EAAE;QACZ,WAAW,EAAE,IAAI,MAAM,CAAC,2CAA2C,CAAC;QACpE,OAAO,EACL,+CAA+C;YAC/C,yJAAyJ;KAC5J;CACF,CAAC;AAEF,oEAAoE;AACvD,QAAA,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,+BAAuB,CAAC,CAAC"}
|
{"version":3,"file":"error-matcher.js","sourceRoot":"","sources":["../src/error-matcher.ts"],"names":[],"mappings":";;;AAQA,qCAAqC;AACxB,QAAA,uBAAuB,GAAoC;IACtE;;MAEE;IACF,iBAAiB,EAAE;QACjB,QAAQ,EAAE,EAAE;QACZ,WAAW,EAAE,IAAI,MAAM,CAAC,2CAA2C,CAAC;QACpE,OAAO,EACL,+CAA+C;YAC/C,yJAAyJ;KAC5J;IACD,UAAU,EAAE;QACV,WAAW,EAAE,IAAI,MAAM,CAAC,wBAAwB,CAAC;QACjD,OAAO,EAAE,yBAAyB;KACnC;CACF,CAAC;AAEF,oEAAoE;AACvD,QAAA,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,+BAAuB,CAAC,CAAC"}
|
||||||
Generated
+3
@@ -16,6 +16,9 @@ NB We test the regexes for all the matchers against example log output snippets.
|
|||||||
2020-09-07T17:39:53.9251124Z [2020-09-07 17:39:53] [ERROR] Spawned process exited abnormally (code 255; tried to run: [/opt/hostedtoolcache/CodeQL/0.0.0-20200630/x64/codeql/javascript/tools/autobuild.sh])
|
2020-09-07T17:39:53.9251124Z [2020-09-07 17:39:53] [ERROR] Spawned process exited abnormally (code 255; tried to run: [/opt/hostedtoolcache/CodeQL/0.0.0-20200630/x64/codeql/javascript/tools/autobuild.sh])
|
||||||
`));
|
`));
|
||||||
});
|
});
|
||||||
|
(0, ava_1.default)("fatalError matches against example log output", async (t) => {
|
||||||
|
t.assert(testErrorMatcher("fatalError", "A fatal error occurred: Could not process query metadata for test-query.ql"));
|
||||||
|
});
|
||||||
function testErrorMatcher(matcherName, logSample) {
|
function testErrorMatcher(matcherName, logSample) {
|
||||||
if (!(matcherName in error_matcher_1.namedMatchersForTesting)) {
|
if (!(matcherName in error_matcher_1.namedMatchersForTesting)) {
|
||||||
throw new Error(`Unknown matcher ${matcherName}`);
|
throw new Error(`Unknown matcher ${matcherName}`);
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"error-matcher.test.js","sourceRoot":"","sources":["../src/error-matcher.test.ts"],"names":[],"mappings":";;;;;AAAA,8CAAuB;AAEvB,mDAA0D;AAE1D;;EAEE;AAEF,IAAA,aAAI,EAAC,6DAA6D,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC9E,CAAC,CAAC,MAAM,CACN,gBAAgB,CACd,mBAAmB,EACnB;;;;;GAKH,CACE,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,SAAS,gBAAgB,CAAC,WAAmB,EAAE,SAAiB;IAC9D,IAAI,CAAC,CAAC,WAAW,IAAI,uCAAuB,CAAC,EAAE;QAC7C,MAAM,IAAI,KAAK,CAAC,mBAAmB,WAAW,EAAE,CAAC,CAAC;KACnD;IACD,MAAM,KAAK,GAAG,uCAAuB,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC;IAC/D,IAAI,KAAK,KAAK,SAAS,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,uBAAuB,WAAW,kBAAkB,CAAC,CAAC;KACvE;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC"}
|
{"version":3,"file":"error-matcher.test.js","sourceRoot":"","sources":["../src/error-matcher.test.ts"],"names":[],"mappings":";;;;;AAAA,8CAAuB;AAEvB,mDAA0D;AAE1D;;EAEE;AAEF,IAAA,aAAI,EAAC,6DAA6D,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAC9E,CAAC,CAAC,MAAM,CACN,gBAAgB,CACd,mBAAmB,EACnB;;;;;GAKH,CACE,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,+CAA+C,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAChE,CAAC,CAAC,MAAM,CACN,gBAAgB,CACd,YAAY,EACZ,4EAA4E,CAC7E,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,SAAS,gBAAgB,CAAC,WAAmB,EAAE,SAAiB;IAC9D,IAAI,CAAC,CAAC,WAAW,IAAI,uCAAuB,CAAC,EAAE;QAC7C,MAAM,IAAI,KAAK,CAAC,mBAAmB,WAAW,EAAE,CAAC,CAAC;KACnD;IACD,MAAM,KAAK,GAAG,uCAAuB,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC;IAC/D,IAAI,KAAK,KAAK,SAAS,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,uBAAuB,WAAW,kBAAkB,CAAC,CAAC;KACvE;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC"}
|
||||||
Generated
+65
-14
@@ -19,21 +19,32 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.Features = exports.featureConfig = exports.Feature = void 0;
|
exports.Features = exports.FEATURE_FLAGS_FILE_NAME = exports.featureConfig = exports.Feature = void 0;
|
||||||
|
const fs = __importStar(require("fs"));
|
||||||
|
const path = __importStar(require("path"));
|
||||||
const api_client_1 = require("./api-client");
|
const api_client_1 = require("./api-client");
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
var Feature;
|
var Feature;
|
||||||
(function (Feature) {
|
(function (Feature) {
|
||||||
Feature["BypassToolcacheEnabled"] = "bypass_toolcache_enabled";
|
Feature["BypassToolcacheEnabled"] = "bypass_toolcache_enabled";
|
||||||
|
Feature["BypassToolcacheKotlinSwiftEnabled"] = "bypass_toolcache_kotlin_swift_enabled";
|
||||||
Feature["CliConfigFileEnabled"] = "cli_config_file_enabled";
|
Feature["CliConfigFileEnabled"] = "cli_config_file_enabled";
|
||||||
Feature["DisableKotlinAnalysisEnabled"] = "disable_kotlin_analysis_enabled";
|
Feature["DisableKotlinAnalysisEnabled"] = "disable_kotlin_analysis_enabled";
|
||||||
Feature["FileBaselineInformationEnabled"] = "file_baseline_information_enabled";
|
|
||||||
Feature["MlPoweredQueriesEnabled"] = "ml_powered_queries_enabled";
|
Feature["MlPoweredQueriesEnabled"] = "ml_powered_queries_enabled";
|
||||||
Feature["TrapCachingEnabled"] = "trap_caching_enabled";
|
Feature["TrapCachingEnabled"] = "trap_caching_enabled";
|
||||||
|
Feature["UploadFailedSarifEnabled"] = "upload_failed_sarif_enabled";
|
||||||
})(Feature = exports.Feature || (exports.Feature = {}));
|
})(Feature = exports.Feature || (exports.Feature = {}));
|
||||||
exports.featureConfig = {
|
exports.featureConfig = {
|
||||||
[Feature.BypassToolcacheEnabled]: {
|
[Feature.BypassToolcacheEnabled]: {
|
||||||
envVar: "CODEQL_BYPASS_TOOLCACHE",
|
envVar: "CODEQL_BYPASS_TOOLCACHE",
|
||||||
|
// Cannot specify a minimum version because this flag is checked before we have
|
||||||
|
// access to the CodeQL instance.
|
||||||
|
minimumVersion: undefined,
|
||||||
|
},
|
||||||
|
[Feature.BypassToolcacheKotlinSwiftEnabled]: {
|
||||||
|
envVar: "CODEQL_BYPASS_TOOLCACHE_KOTLIN_SWIFT",
|
||||||
|
// Cannot specify a minimum version because this flag is checked before we have
|
||||||
|
// access to the CodeQL instance.
|
||||||
minimumVersion: undefined,
|
minimumVersion: undefined,
|
||||||
},
|
},
|
||||||
[Feature.DisableKotlinAnalysisEnabled]: {
|
[Feature.DisableKotlinAnalysisEnabled]: {
|
||||||
@@ -44,10 +55,6 @@ exports.featureConfig = {
|
|||||||
envVar: "CODEQL_PASS_CONFIG_TO_CLI",
|
envVar: "CODEQL_PASS_CONFIG_TO_CLI",
|
||||||
minimumVersion: "2.11.1",
|
minimumVersion: "2.11.1",
|
||||||
},
|
},
|
||||||
[Feature.FileBaselineInformationEnabled]: {
|
|
||||||
envVar: "CODEQL_FILE_BASELINE_INFORMATION",
|
|
||||||
minimumVersion: "2.11.3",
|
|
||||||
},
|
|
||||||
[Feature.MlPoweredQueriesEnabled]: {
|
[Feature.MlPoweredQueriesEnabled]: {
|
||||||
envVar: "CODEQL_ML_POWERED_QUERIES",
|
envVar: "CODEQL_ML_POWERED_QUERIES",
|
||||||
minimumVersion: "2.7.5",
|
minimumVersion: "2.7.5",
|
||||||
@@ -56,15 +63,20 @@ exports.featureConfig = {
|
|||||||
envVar: "CODEQL_TRAP_CACHING",
|
envVar: "CODEQL_TRAP_CACHING",
|
||||||
minimumVersion: undefined,
|
minimumVersion: undefined,
|
||||||
},
|
},
|
||||||
|
[Feature.UploadFailedSarifEnabled]: {
|
||||||
|
envVar: "CODEQL_ACTION_UPLOAD_FAILED_SARIF",
|
||||||
|
minimumVersion: "2.11.3",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
exports.FEATURE_FLAGS_FILE_NAME = "cached-feature-flags.json";
|
||||||
/**
|
/**
|
||||||
* Determines the enablement status of a number of features.
|
* Determines the enablement status of a number of features.
|
||||||
* If feature enablement is not able to be determined locally, a request to the
|
* If feature enablement is not able to be determined locally, a request to the
|
||||||
* GitHub API is made to determine the enablement status.
|
* GitHub API is made to determine the enablement status.
|
||||||
*/
|
*/
|
||||||
class Features {
|
class Features {
|
||||||
constructor(gitHubVersion, repositoryNwo, logger) {
|
constructor(gitHubVersion, repositoryNwo, tempDir, logger) {
|
||||||
this.gitHubFeatureFlags = new GitHubFeatureFlags(gitHubVersion, repositoryNwo, logger);
|
this.gitHubFeatureFlags = new GitHubFeatureFlags(gitHubVersion, repositoryNwo, path.join(tempDir, exports.FEATURE_FLAGS_FILE_NAME), logger);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -108,14 +120,15 @@ class Features {
|
|||||||
}
|
}
|
||||||
exports.Features = Features;
|
exports.Features = Features;
|
||||||
class GitHubFeatureFlags {
|
class GitHubFeatureFlags {
|
||||||
constructor(gitHubVersion, repositoryNwo, logger) {
|
constructor(gitHubVersion, repositoryNwo, featureFlagsFile, logger) {
|
||||||
this.gitHubVersion = gitHubVersion;
|
this.gitHubVersion = gitHubVersion;
|
||||||
this.repositoryNwo = repositoryNwo;
|
this.repositoryNwo = repositoryNwo;
|
||||||
|
this.featureFlagsFile = featureFlagsFile;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
/**/
|
/**/
|
||||||
}
|
}
|
||||||
async getValue(feature) {
|
async getValue(feature) {
|
||||||
const response = await this.getApiResponse();
|
const response = await this.getAllFeatures();
|
||||||
if (response === undefined) {
|
if (response === undefined) {
|
||||||
this.logger.debug(`No feature flags API response for ${feature}, considering it disabled.`);
|
this.logger.debug(`No feature flags API response for ${feature}, considering it disabled.`);
|
||||||
return false;
|
return false;
|
||||||
@@ -127,10 +140,48 @@ class GitHubFeatureFlags {
|
|||||||
}
|
}
|
||||||
return !!featureEnablement;
|
return !!featureEnablement;
|
||||||
}
|
}
|
||||||
async getApiResponse() {
|
async getAllFeatures() {
|
||||||
const apiResponse = this.cachedApiResponse || (await this.loadApiResponse());
|
// if we have an in memory cache, use that
|
||||||
this.cachedApiResponse = apiResponse;
|
if (this.cachedApiResponse !== undefined) {
|
||||||
return apiResponse;
|
return this.cachedApiResponse;
|
||||||
|
}
|
||||||
|
// if a previous step has written a feature flags file to disk, use that
|
||||||
|
const fileFlags = await this.readLocalFlags();
|
||||||
|
if (fileFlags !== undefined) {
|
||||||
|
this.cachedApiResponse = fileFlags;
|
||||||
|
return fileFlags;
|
||||||
|
}
|
||||||
|
// if not, request flags from the server
|
||||||
|
let remoteFlags = await this.loadApiResponse();
|
||||||
|
if (remoteFlags === undefined) {
|
||||||
|
remoteFlags = {};
|
||||||
|
}
|
||||||
|
// cache the response in memory
|
||||||
|
this.cachedApiResponse = remoteFlags;
|
||||||
|
// and cache them to disk so future workflow steps can use them
|
||||||
|
await this.writeLocalFlags(remoteFlags);
|
||||||
|
return remoteFlags;
|
||||||
|
}
|
||||||
|
async readLocalFlags() {
|
||||||
|
try {
|
||||||
|
if (fs.existsSync(this.featureFlagsFile)) {
|
||||||
|
this.logger.debug(`Loading feature flags from ${this.featureFlagsFile}`);
|
||||||
|
return JSON.parse(fs.readFileSync(this.featureFlagsFile, "utf8"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
this.logger.warning(`Error reading cached feature flags file ${this.featureFlagsFile}: ${e}. Requesting from GitHub instead.`);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
async writeLocalFlags(flags) {
|
||||||
|
try {
|
||||||
|
this.logger.debug(`Writing feature flags to ${this.featureFlagsFile}`);
|
||||||
|
fs.writeFileSync(this.featureFlagsFile, JSON.stringify(flags));
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
this.logger.warning(`Error writing cached feature flags file ${this.featureFlagsFile}: ${e}.`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
async loadApiResponse() {
|
async loadApiResponse() {
|
||||||
// Do nothing when not running against github.com
|
// Do nothing when not running against github.com
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"feature-flags.js","sourceRoot":"","sources":["../src/feature-flags.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"feature-flags.js","sourceRoot":"","sources":["../src/feature-flags.ts"],"names":[],"mappings":"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"}
|
||||||
Generated
+63
-11
@@ -1,8 +1,29 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const fs = __importStar(require("fs"));
|
||||||
|
const path = __importStar(require("path"));
|
||||||
const ava_1 = __importDefault(require("ava"));
|
const ava_1 = __importDefault(require("ava"));
|
||||||
const feature_flags_1 = require("./feature-flags");
|
const feature_flags_1 = require("./feature-flags");
|
||||||
const logging_1 = require("./logging");
|
const logging_1 = require("./logging");
|
||||||
@@ -25,7 +46,7 @@ for (const variant of ALL_FEATURES_DISABLED_VARIANTS) {
|
|||||||
(0, ava_1.default)(`All features are disabled if running against ${variant.description}`, async (t) => {
|
(0, ava_1.default)(`All features are disabled if running against ${variant.description}`, async (t) => {
|
||||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
const loggedMessages = [];
|
const loggedMessages = [];
|
||||||
const featureEnablement = setUpTests(tmpDir, (0, testing_utils_1.getRecordingLogger)(loggedMessages), variant.gitHubVersion);
|
const featureEnablement = setUpFeatureFlagTests(tmpDir, (0, testing_utils_1.getRecordingLogger)(loggedMessages), variant.gitHubVersion);
|
||||||
for (const feature of Object.values(feature_flags_1.Feature)) {
|
for (const feature of Object.values(feature_flags_1.Feature)) {
|
||||||
t.false(await featureEnablement.getValue(feature, includeCodeQlIfRequired(feature)));
|
t.false(await featureEnablement.getValue(feature, includeCodeQlIfRequired(feature)));
|
||||||
}
|
}
|
||||||
@@ -38,7 +59,7 @@ for (const variant of ALL_FEATURES_DISABLED_VARIANTS) {
|
|||||||
(0, ava_1.default)("API response missing", async (t) => {
|
(0, ava_1.default)("API response missing", async (t) => {
|
||||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
const loggedMessages = [];
|
const loggedMessages = [];
|
||||||
const featureEnablement = setUpTests(tmpDir, (0, testing_utils_1.getRecordingLogger)(loggedMessages));
|
const featureEnablement = setUpFeatureFlagTests(tmpDir, (0, testing_utils_1.getRecordingLogger)(loggedMessages));
|
||||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(403, {});
|
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(403, {});
|
||||||
for (const feature of Object.values(feature_flags_1.Feature)) {
|
for (const feature of Object.values(feature_flags_1.Feature)) {
|
||||||
t.assert((await featureEnablement.getValue(feature, includeCodeQlIfRequired(feature))) === false);
|
t.assert((await featureEnablement.getValue(feature, includeCodeQlIfRequired(feature))) === false);
|
||||||
@@ -49,7 +70,7 @@ for (const variant of ALL_FEATURES_DISABLED_VARIANTS) {
|
|||||||
(0, ava_1.default)("Features are disabled if they're not returned in API response", async (t) => {
|
(0, ava_1.default)("Features are disabled if they're not returned in API response", async (t) => {
|
||||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
const loggedMessages = [];
|
const loggedMessages = [];
|
||||||
const featureEnablement = setUpTests(tmpDir, (0, testing_utils_1.getRecordingLogger)(loggedMessages));
|
const featureEnablement = setUpFeatureFlagTests(tmpDir, (0, testing_utils_1.getRecordingLogger)(loggedMessages));
|
||||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, {});
|
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, {});
|
||||||
for (const feature of Object.values(feature_flags_1.Feature)) {
|
for (const feature of Object.values(feature_flags_1.Feature)) {
|
||||||
t.assert((await featureEnablement.getValue(feature, includeCodeQlIfRequired(feature))) === false);
|
t.assert((await featureEnablement.getValue(feature, includeCodeQlIfRequired(feature))) === false);
|
||||||
@@ -59,7 +80,7 @@ for (const variant of ALL_FEATURES_DISABLED_VARIANTS) {
|
|||||||
});
|
});
|
||||||
(0, ava_1.default)("Feature flags exception is propagated if the API request errors", async (t) => {
|
(0, ava_1.default)("Feature flags exception is propagated if the API request errors", async (t) => {
|
||||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
const featureEnablement = setUpTests(tmpDir);
|
const featureEnablement = setUpFeatureFlagTests(tmpDir);
|
||||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(500, {});
|
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(500, {});
|
||||||
await t.throwsAsync(async () => featureEnablement.getValue(feature_flags_1.Feature.MlPoweredQueriesEnabled, includeCodeQlIfRequired(feature_flags_1.Feature.MlPoweredQueriesEnabled)), {
|
await t.throwsAsync(async () => featureEnablement.getValue(feature_flags_1.Feature.MlPoweredQueriesEnabled, includeCodeQlIfRequired(feature_flags_1.Feature.MlPoweredQueriesEnabled)), {
|
||||||
message: "Encountered an error while trying to determine feature enablement: Error: some error message",
|
message: "Encountered an error while trying to determine feature enablement: Error: some error message",
|
||||||
@@ -69,7 +90,7 @@ for (const variant of ALL_FEATURES_DISABLED_VARIANTS) {
|
|||||||
for (const feature of Object.keys(feature_flags_1.featureConfig)) {
|
for (const feature of Object.keys(feature_flags_1.featureConfig)) {
|
||||||
(0, ava_1.default)(`Only feature '${feature}' is enabled if enabled in the API response. Other features disabled`, async (t) => {
|
(0, ava_1.default)(`Only feature '${feature}' is enabled if enabled in the API response. Other features disabled`, async (t) => {
|
||||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
const featureEnablement = setUpTests(tmpDir);
|
const featureEnablement = setUpFeatureFlagTests(tmpDir);
|
||||||
// set all features to false except the one we're testing
|
// set all features to false except the one we're testing
|
||||||
const expectedFeatureEnablement = {};
|
const expectedFeatureEnablement = {};
|
||||||
for (const f of Object.keys(feature_flags_1.featureConfig)) {
|
for (const f of Object.keys(feature_flags_1.featureConfig)) {
|
||||||
@@ -87,7 +108,7 @@ for (const feature of Object.keys(feature_flags_1.featureConfig)) {
|
|||||||
});
|
});
|
||||||
(0, ava_1.default)(`Only feature '${feature}' is enabled if the associated environment variable is true. Others disabled.`, async (t) => {
|
(0, ava_1.default)(`Only feature '${feature}' is enabled if the associated environment variable is true. Others disabled.`, async (t) => {
|
||||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
const featureEnablement = setUpTests(tmpDir);
|
const featureEnablement = setUpFeatureFlagTests(tmpDir);
|
||||||
const expectedFeatureEnablement = initializeFeatures(false);
|
const expectedFeatureEnablement = initializeFeatures(false);
|
||||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, expectedFeatureEnablement);
|
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, expectedFeatureEnablement);
|
||||||
// feature should be disabled initially
|
// feature should be disabled initially
|
||||||
@@ -99,7 +120,7 @@ for (const feature of Object.keys(feature_flags_1.featureConfig)) {
|
|||||||
});
|
});
|
||||||
(0, ava_1.default)(`Feature '${feature}' is disabled if the associated environment variable is false, even if enabled in API`, async (t) => {
|
(0, ava_1.default)(`Feature '${feature}' is disabled if the associated environment variable is false, even if enabled in API`, async (t) => {
|
||||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
const featureEnablement = setUpTests(tmpDir);
|
const featureEnablement = setUpFeatureFlagTests(tmpDir);
|
||||||
const expectedFeatureEnablement = initializeFeatures(true);
|
const expectedFeatureEnablement = initializeFeatures(true);
|
||||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, expectedFeatureEnablement);
|
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, expectedFeatureEnablement);
|
||||||
// feature should be enabled initially
|
// feature should be enabled initially
|
||||||
@@ -112,7 +133,7 @@ for (const feature of Object.keys(feature_flags_1.featureConfig)) {
|
|||||||
if (feature_flags_1.featureConfig[feature].minimumVersion !== undefined) {
|
if (feature_flags_1.featureConfig[feature].minimumVersion !== undefined) {
|
||||||
(0, ava_1.default)(`Getting feature '${feature} should throw if no codeql is provided`, async (t) => {
|
(0, ava_1.default)(`Getting feature '${feature} should throw if no codeql is provided`, async (t) => {
|
||||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
const featureEnablement = setUpTests(tmpDir);
|
const featureEnablement = setUpFeatureFlagTests(tmpDir);
|
||||||
const expectedFeatureEnablement = initializeFeatures(true);
|
const expectedFeatureEnablement = initializeFeatures(true);
|
||||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, expectedFeatureEnablement);
|
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, expectedFeatureEnablement);
|
||||||
await t.throwsAsync(async () => featureEnablement.getValue(feature), {
|
await t.throwsAsync(async () => featureEnablement.getValue(feature), {
|
||||||
@@ -124,7 +145,7 @@ for (const feature of Object.keys(feature_flags_1.featureConfig)) {
|
|||||||
if (feature_flags_1.featureConfig[feature].minimumVersion !== undefined) {
|
if (feature_flags_1.featureConfig[feature].minimumVersion !== undefined) {
|
||||||
(0, ava_1.default)(`Feature '${feature}' is disabled if the minimum CLI version is below ${feature_flags_1.featureConfig[feature].minimumVersion}`, async (t) => {
|
(0, ava_1.default)(`Feature '${feature}' is disabled if the minimum CLI version is below ${feature_flags_1.featureConfig[feature].minimumVersion}`, async (t) => {
|
||||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
const featureEnablement = setUpTests(tmpDir);
|
const featureEnablement = setUpFeatureFlagTests(tmpDir);
|
||||||
const expectedFeatureEnablement = initializeFeatures(true);
|
const expectedFeatureEnablement = initializeFeatures(true);
|
||||||
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, expectedFeatureEnablement);
|
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, expectedFeatureEnablement);
|
||||||
// feature should be disabled when an old CLI version is set
|
// feature should be disabled when an old CLI version is set
|
||||||
@@ -156,6 +177,37 @@ for (const feature of Object.keys(feature_flags_1.featureConfig)) {
|
|||||||
// An even less likely scenario is that we no longer have any features.
|
// An even less likely scenario is that we no longer have any features.
|
||||||
t.assert(Object.values(feature_flags_1.featureConfig).length > 0, "There should be at least one feature");
|
t.assert(Object.values(feature_flags_1.featureConfig).length > 0, "There should be at least one feature");
|
||||||
});
|
});
|
||||||
|
(0, ava_1.default)("Feature flags are saved to disk", async (t) => {
|
||||||
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
|
const featureEnablement = setUpFeatureFlagTests(tmpDir);
|
||||||
|
const expectedFeatureEnablement = initializeFeatures(true);
|
||||||
|
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, expectedFeatureEnablement);
|
||||||
|
const cachedFeatureFlags = path.join(tmpDir, feature_flags_1.FEATURE_FLAGS_FILE_NAME);
|
||||||
|
t.false(fs.existsSync(cachedFeatureFlags), "Feature flag cached file should not exist before getting feature flags");
|
||||||
|
t.true(await featureEnablement.getValue(feature_flags_1.Feature.CliConfigFileEnabled, includeCodeQlIfRequired(feature_flags_1.Feature.CliConfigFileEnabled)), "Feature flag should be enabled initially");
|
||||||
|
t.true(fs.existsSync(cachedFeatureFlags), "Feature flag cached file should exist after getting feature flags");
|
||||||
|
const actualFeatureEnablement = JSON.parse(fs.readFileSync(cachedFeatureFlags, "utf8"));
|
||||||
|
t.deepEqual(actualFeatureEnablement, expectedFeatureEnablement);
|
||||||
|
// now test that we actually use the feature flag cache instead of the server
|
||||||
|
actualFeatureEnablement[feature_flags_1.Feature.CliConfigFileEnabled] = false;
|
||||||
|
fs.writeFileSync(cachedFeatureFlags, JSON.stringify(actualFeatureEnablement));
|
||||||
|
// delete the in memory cache so that we are forced to use the cached file
|
||||||
|
featureEnablement.gitHubFeatureFlags.cachedApiResponse = undefined;
|
||||||
|
t.false(await featureEnablement.getValue(feature_flags_1.Feature.CliConfigFileEnabled, includeCodeQlIfRequired(feature_flags_1.Feature.CliConfigFileEnabled)), "Feature flag should be enabled after reading from cached file");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("Environment variable can override feature flag cache", async (t) => {
|
||||||
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
|
const featureEnablement = setUpFeatureFlagTests(tmpDir);
|
||||||
|
const expectedFeatureEnablement = initializeFeatures(true);
|
||||||
|
(0, testing_utils_1.mockFeatureFlagApiEndpoint)(200, expectedFeatureEnablement);
|
||||||
|
const cachedFeatureFlags = path.join(tmpDir, feature_flags_1.FEATURE_FLAGS_FILE_NAME);
|
||||||
|
t.true(await featureEnablement.getValue(feature_flags_1.Feature.CliConfigFileEnabled, includeCodeQlIfRequired(feature_flags_1.Feature.CliConfigFileEnabled)), "Feature flag should be enabled initially");
|
||||||
|
t.true(fs.existsSync(cachedFeatureFlags), "Feature flag cached file should exist after getting feature flags");
|
||||||
|
process.env.CODEQL_PASS_CONFIG_TO_CLI = "false";
|
||||||
|
t.false(await featureEnablement.getValue(feature_flags_1.Feature.CliConfigFileEnabled, includeCodeQlIfRequired(feature_flags_1.Feature.CliConfigFileEnabled)), "Feature flag should be disabled after setting env var");
|
||||||
|
});
|
||||||
|
});
|
||||||
function assertAllFeaturesUndefinedInApi(t, loggedMessages) {
|
function assertAllFeaturesUndefinedInApi(t, loggedMessages) {
|
||||||
for (const feature of Object.keys(feature_flags_1.featureConfig)) {
|
for (const feature of Object.keys(feature_flags_1.featureConfig)) {
|
||||||
t.assert(loggedMessages.find((v) => v.type === "debug" &&
|
t.assert(loggedMessages.find((v) => v.type === "debug" &&
|
||||||
@@ -169,9 +221,9 @@ function initializeFeatures(initialValue) {
|
|||||||
return features;
|
return features;
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
function setUpTests(tmpDir, logger = (0, logging_1.getRunnerLogger)(true), gitHubVersion = { type: util_1.GitHubVariant.DOTCOM }) {
|
function setUpFeatureFlagTests(tmpDir, logger = (0, logging_1.getRunnerLogger)(true), gitHubVersion = { type: util_1.GitHubVariant.DOTCOM }) {
|
||||||
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
|
(0, testing_utils_1.setupActionsVars)(tmpDir, tmpDir);
|
||||||
return new feature_flags_1.Features(gitHubVersion, testRepositoryNwo, logger);
|
return new feature_flags_1.Features(gitHubVersion, testRepositoryNwo, tmpDir, logger);
|
||||||
}
|
}
|
||||||
function includeCodeQlIfRequired(feature) {
|
function includeCodeQlIfRequired(feature) {
|
||||||
return feature_flags_1.featureConfig[feature].minimumVersion !== undefined
|
return feature_flags_1.featureConfig[feature].minimumVersion !== undefined
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Generated
+75
-5
@@ -19,24 +19,94 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.run = void 0;
|
exports.run = exports.tryUploadSarifIfRunFailed = void 0;
|
||||||
const core = __importStar(require("@actions/core"));
|
const core = __importStar(require("@actions/core"));
|
||||||
const actionsUtil = __importStar(require("./actions-util"));
|
const actionsUtil = __importStar(require("./actions-util"));
|
||||||
|
const codeql_1 = require("./codeql");
|
||||||
const config_utils_1 = require("./config-utils");
|
const config_utils_1 = require("./config-utils");
|
||||||
const logging_1 = require("./logging");
|
const feature_flags_1 = require("./feature-flags");
|
||||||
async function run(uploadDatabaseBundleDebugArtifact, uploadLogsDebugArtifact, printDebugLogs) {
|
const shared_environment_1 = require("./shared-environment");
|
||||||
const logger = (0, logging_1.getActionsLogger)();
|
const uploadLib = __importStar(require("./upload-lib"));
|
||||||
|
const util_1 = require("./util");
|
||||||
|
const workflow_1 = require("./workflow");
|
||||||
|
function createFailedUploadFailedSarifResult(error) {
|
||||||
|
return {
|
||||||
|
upload_failed_run_error: error instanceof Error ? error.message : String(error),
|
||||||
|
upload_failed_run_stack_trace: error instanceof Error ? error.stack : undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Upload a failed SARIF file if we can verify that SARIF upload is enabled and determine the SARIF
|
||||||
|
* category for the workflow.
|
||||||
|
*/
|
||||||
|
async function maybeUploadFailedSarif(config, repositoryNwo, featureEnablement, logger) {
|
||||||
|
var _a;
|
||||||
|
if (!config.codeQLCmd) {
|
||||||
|
return { upload_failed_run_skipped_because: "CodeQL command not found" };
|
||||||
|
}
|
||||||
|
const codeql = await (0, codeql_1.getCodeQL)(config.codeQLCmd);
|
||||||
|
if (!(await featureEnablement.getValue(feature_flags_1.Feature.UploadFailedSarifEnabled, codeql))) {
|
||||||
|
return { upload_failed_run_skipped_because: "Feature disabled" };
|
||||||
|
}
|
||||||
|
const workflow = await (0, workflow_1.getWorkflow)();
|
||||||
|
const jobName = (0, util_1.getRequiredEnvParam)("GITHUB_JOB");
|
||||||
|
const matrix = (0, util_1.parseMatrixInput)(actionsUtil.getRequiredInput("matrix"));
|
||||||
|
if ((0, workflow_1.getUploadInputOrThrow)(workflow, jobName, matrix) !== "true" ||
|
||||||
|
(0, util_1.isInTestMode)()) {
|
||||||
|
return { upload_failed_run_skipped_because: "SARIF upload is disabled" };
|
||||||
|
}
|
||||||
|
const category = (0, workflow_1.getCategoryInputOrThrow)(workflow, jobName, matrix);
|
||||||
|
const checkoutPath = (0, workflow_1.getCheckoutPathInputOrThrow)(workflow, jobName, matrix);
|
||||||
|
const sarifFile = "../codeql-failed-run.sarif";
|
||||||
|
await codeql.diagnosticsExport(sarifFile, category);
|
||||||
|
core.info(`Uploading failed SARIF file ${sarifFile}`);
|
||||||
|
const uploadResult = await uploadLib.uploadFromActions(sarifFile, checkoutPath, category, logger);
|
||||||
|
await uploadLib.waitForProcessing(repositoryNwo, uploadResult.sarifID, logger, { isUnsuccessfulExecution: true });
|
||||||
|
return (_a = uploadResult === null || uploadResult === void 0 ? void 0 : uploadResult.statusReport) !== null && _a !== void 0 ? _a : {};
|
||||||
|
}
|
||||||
|
async function tryUploadSarifIfRunFailed(config, repositoryNwo, featureEnablement, logger) {
|
||||||
|
if (process.env[shared_environment_1.CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY] !== "true") {
|
||||||
|
try {
|
||||||
|
return await maybeUploadFailedSarif(config, repositoryNwo, featureEnablement, logger);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
logger.debug(`Failed to upload a SARIF file for this failed CodeQL code scanning run. ${e}`);
|
||||||
|
return createFailedUploadFailedSarifResult(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return {
|
||||||
|
upload_failed_run_skipped_because: "Analyze Action completed successfully",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.tryUploadSarifIfRunFailed = tryUploadSarifIfRunFailed;
|
||||||
|
async function run(uploadDatabaseBundleDebugArtifact, uploadLogsDebugArtifact, printDebugLogs, repositoryNwo, featureEnablement, logger) {
|
||||||
const config = await (0, config_utils_1.getConfig)(actionsUtil.getTemporaryDirectory(), logger);
|
const config = await (0, config_utils_1.getConfig)(actionsUtil.getTemporaryDirectory(), logger);
|
||||||
if (config === undefined) {
|
if (config === undefined) {
|
||||||
logger.warning("Debugging artifacts are unavailable since the 'init' Action failed before it could produce any.");
|
logger.warning("Debugging artifacts are unavailable since the 'init' Action failed before it could produce any.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const uploadFailedSarifResult = await tryUploadSarifIfRunFailed(config, repositoryNwo, featureEnablement, logger);
|
||||||
|
if (uploadFailedSarifResult.upload_failed_run_skipped_because) {
|
||||||
|
logger.debug("Won't upload a failed SARIF file for this CodeQL code scanning run because: " +
|
||||||
|
`${uploadFailedSarifResult.upload_failed_run_skipped_because}.`);
|
||||||
|
}
|
||||||
|
// Throw an error if in integration tests, we expected to upload a SARIF file for a failed run
|
||||||
|
// but we didn't upload anything.
|
||||||
|
if (process.env["CODEQL_ACTION_EXPECT_UPLOAD_FAILED_SARIF"] === "true" &&
|
||||||
|
!uploadFailedSarifResult.raw_upload_size_bytes) {
|
||||||
|
throw new Error("Expected to upload a failed SARIF file for this CodeQL code scanning run, " +
|
||||||
|
`but the result was instead ${uploadFailedSarifResult}.`);
|
||||||
}
|
}
|
||||||
// Upload appropriate Actions artifacts for debugging
|
// Upload appropriate Actions artifacts for debugging
|
||||||
if (config === null || config === void 0 ? void 0 : config.debugMode) {
|
if (config.debugMode) {
|
||||||
core.info("Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts...");
|
core.info("Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts...");
|
||||||
await uploadDatabaseBundleDebugArtifact(config, logger);
|
await uploadDatabaseBundleDebugArtifact(config, logger);
|
||||||
await uploadLogsDebugArtifact(config);
|
await uploadLogsDebugArtifact(config);
|
||||||
await printDebugLogs(config);
|
await printDebugLogs(config);
|
||||||
}
|
}
|
||||||
|
return uploadFailedSarifResult;
|
||||||
}
|
}
|
||||||
exports.run = run;
|
exports.run = run;
|
||||||
//# sourceMappingURL=init-action-post-helper.js.map
|
//# sourceMappingURL=init-action-post-helper.js.map
|
||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"init-action-post-helper.js","sourceRoot":"","sources":["../src/init-action-post-helper.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,oDAAsC;AAEtC,4DAA8C;AAC9C,iDAA2C;AAC3C,uCAA6C;AAEtC,KAAK,UAAU,GAAG,CACvB,iCAA2C,EAC3C,uBAAiC,EACjC,cAAwB;IAExB,MAAM,MAAM,GAAG,IAAA,0BAAgB,GAAE,CAAC;IAElC,MAAM,MAAM,GAAG,MAAM,IAAA,wBAAS,EAAC,WAAW,CAAC,qBAAqB,EAAE,EAAE,MAAM,CAAC,CAAC;IAC5E,IAAI,MAAM,KAAK,SAAS,EAAE;QACxB,MAAM,CAAC,OAAO,CACZ,iGAAiG,CAClG,CAAC;KACH;IAED,qDAAqD;IACrD,IAAI,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,SAAS,EAAE;QACrB,IAAI,CAAC,IAAI,CACP,mGAAmG,CACpG,CAAC;QACF,MAAM,iCAAiC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACxD,MAAM,uBAAuB,CAAC,MAAM,CAAC,CAAC;QAEtC,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;KAC9B;AACH,CAAC;AAxBD,kBAwBC"}
|
{"version":3,"file":"init-action-post-helper.js","sourceRoot":"","sources":["../src/init-action-post-helper.ts"],"names":[],"mappings":"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"}
|
||||||
Generated
+194
-2
@@ -24,13 +24,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const ava_1 = __importDefault(require("ava"));
|
const ava_1 = __importDefault(require("ava"));
|
||||||
const sinon = __importStar(require("sinon"));
|
const sinon = __importStar(require("sinon"));
|
||||||
|
const actionsUtil = __importStar(require("./actions-util"));
|
||||||
|
const codeql = __importStar(require("./codeql"));
|
||||||
const configUtils = __importStar(require("./config-utils"));
|
const configUtils = __importStar(require("./config-utils"));
|
||||||
|
const feature_flags_1 = require("./feature-flags");
|
||||||
const initActionPostHelper = __importStar(require("./init-action-post-helper"));
|
const initActionPostHelper = __importStar(require("./init-action-post-helper"));
|
||||||
|
const logging_1 = require("./logging");
|
||||||
|
const repository_1 = require("./repository");
|
||||||
const testing_utils_1 = require("./testing-utils");
|
const testing_utils_1 = require("./testing-utils");
|
||||||
|
const uploadLib = __importStar(require("./upload-lib"));
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
|
const workflow = __importStar(require("./workflow"));
|
||||||
(0, testing_utils_1.setupTests)(ava_1.default);
|
(0, testing_utils_1.setupTests)(ava_1.default);
|
||||||
(0, ava_1.default)("post: init action with debug mode off", async (t) => {
|
(0, ava_1.default)("post: init action with debug mode off", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
|
process.env["GITHUB_REPOSITORY"] = "github/codeql-action-fake-repository";
|
||||||
process.env["RUNNER_TEMP"] = tmpDir;
|
process.env["RUNNER_TEMP"] = tmpDir;
|
||||||
const gitHubVersion = {
|
const gitHubVersion = {
|
||||||
type: util.GitHubVariant.DOTCOM,
|
type: util.GitHubVariant.DOTCOM,
|
||||||
@@ -44,7 +52,7 @@ const util = __importStar(require("./util"));
|
|||||||
const uploadDatabaseBundleSpy = sinon.spy();
|
const uploadDatabaseBundleSpy = sinon.spy();
|
||||||
const uploadLogsSpy = sinon.spy();
|
const uploadLogsSpy = sinon.spy();
|
||||||
const printDebugLogsSpy = sinon.spy();
|
const printDebugLogsSpy = sinon.spy();
|
||||||
await initActionPostHelper.run(uploadDatabaseBundleSpy, uploadLogsSpy, printDebugLogsSpy);
|
await initActionPostHelper.run(uploadDatabaseBundleSpy, uploadLogsSpy, printDebugLogsSpy, (0, repository_1.parseRepositoryNwo)("github/codeql-action"), (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
|
||||||
t.assert(uploadDatabaseBundleSpy.notCalled);
|
t.assert(uploadDatabaseBundleSpy.notCalled);
|
||||||
t.assert(uploadLogsSpy.notCalled);
|
t.assert(uploadLogsSpy.notCalled);
|
||||||
t.assert(printDebugLogsSpy.notCalled);
|
t.assert(printDebugLogsSpy.notCalled);
|
||||||
@@ -52,6 +60,7 @@ const util = __importStar(require("./util"));
|
|||||||
});
|
});
|
||||||
(0, ava_1.default)("post: init action with debug mode on", async (t) => {
|
(0, ava_1.default)("post: init action with debug mode on", async (t) => {
|
||||||
return await util.withTmpDir(async (tmpDir) => {
|
return await util.withTmpDir(async (tmpDir) => {
|
||||||
|
process.env["GITHUB_REPOSITORY"] = "github/codeql-action-fake-repository";
|
||||||
process.env["RUNNER_TEMP"] = tmpDir;
|
process.env["RUNNER_TEMP"] = tmpDir;
|
||||||
const gitHubVersion = {
|
const gitHubVersion = {
|
||||||
type: util.GitHubVariant.DOTCOM,
|
type: util.GitHubVariant.DOTCOM,
|
||||||
@@ -65,10 +74,193 @@ const util = __importStar(require("./util"));
|
|||||||
const uploadDatabaseBundleSpy = sinon.spy();
|
const uploadDatabaseBundleSpy = sinon.spy();
|
||||||
const uploadLogsSpy = sinon.spy();
|
const uploadLogsSpy = sinon.spy();
|
||||||
const printDebugLogsSpy = sinon.spy();
|
const printDebugLogsSpy = sinon.spy();
|
||||||
await initActionPostHelper.run(uploadDatabaseBundleSpy, uploadLogsSpy, printDebugLogsSpy);
|
await initActionPostHelper.run(uploadDatabaseBundleSpy, uploadLogsSpy, printDebugLogsSpy, (0, repository_1.parseRepositoryNwo)("github/codeql-action"), (0, testing_utils_1.createFeatures)([]), (0, logging_1.getRunnerLogger)(true));
|
||||||
t.assert(uploadDatabaseBundleSpy.called);
|
t.assert(uploadDatabaseBundleSpy.called);
|
||||||
t.assert(uploadLogsSpy.called);
|
t.assert(uploadLogsSpy.called);
|
||||||
t.assert(printDebugLogsSpy.called);
|
t.assert(printDebugLogsSpy.called);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
(0, ava_1.default)("uploads failed SARIF run for typical workflow", async (t) => {
|
||||||
|
const actionsWorkflow = createTestWorkflow([
|
||||||
|
{
|
||||||
|
name: "Checkout repository",
|
||||||
|
uses: "actions/checkout@v3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Initialize CodeQL",
|
||||||
|
uses: "github/codeql-action/init@v2",
|
||||||
|
with: {
|
||||||
|
languages: "javascript",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Perform CodeQL Analysis",
|
||||||
|
uses: "github/codeql-action/analyze@v2",
|
||||||
|
with: {
|
||||||
|
category: "my-category",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
await testFailedSarifUpload(t, actionsWorkflow, { category: "my-category" });
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("doesn't upload failed SARIF for workflow with upload: false", async (t) => {
|
||||||
|
const actionsWorkflow = createTestWorkflow([
|
||||||
|
{
|
||||||
|
name: "Checkout repository",
|
||||||
|
uses: "actions/checkout@v3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Initialize CodeQL",
|
||||||
|
uses: "github/codeql-action/init@v2",
|
||||||
|
with: {
|
||||||
|
languages: "javascript",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Perform CodeQL Analysis",
|
||||||
|
uses: "github/codeql-action/analyze@v2",
|
||||||
|
with: {
|
||||||
|
category: "my-category",
|
||||||
|
upload: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const result = await testFailedSarifUpload(t, actionsWorkflow, {
|
||||||
|
expectUpload: false,
|
||||||
|
});
|
||||||
|
t.is(result.upload_failed_run_skipped_because, "SARIF upload is disabled");
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("uploading failed SARIF run succeeds when workflow uses an input with a matrix var", async (t) => {
|
||||||
|
const actionsWorkflow = createTestWorkflow([
|
||||||
|
{
|
||||||
|
name: "Checkout repository",
|
||||||
|
uses: "actions/checkout@v3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Initialize CodeQL",
|
||||||
|
uses: "github/codeql-action/init@v2",
|
||||||
|
with: {
|
||||||
|
languages: "javascript",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Perform CodeQL Analysis",
|
||||||
|
uses: "github/codeql-action/analyze@v2",
|
||||||
|
with: {
|
||||||
|
category: "/language:${{ matrix.language }}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
await testFailedSarifUpload(t, actionsWorkflow, {
|
||||||
|
category: "/language:csharp",
|
||||||
|
matrix: { language: "csharp" },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("uploading failed SARIF run fails when workflow uses a complex upload input", async (t) => {
|
||||||
|
const actionsWorkflow = createTestWorkflow([
|
||||||
|
{
|
||||||
|
name: "Checkout repository",
|
||||||
|
uses: "actions/checkout@v3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Initialize CodeQL",
|
||||||
|
uses: "github/codeql-action/init@v2",
|
||||||
|
with: {
|
||||||
|
languages: "javascript",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Perform CodeQL Analysis",
|
||||||
|
uses: "github/codeql-action/analyze@v2",
|
||||||
|
with: {
|
||||||
|
upload: "${{ matrix.language != 'csharp' }}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const result = await testFailedSarifUpload(t, actionsWorkflow, {
|
||||||
|
expectUpload: false,
|
||||||
|
});
|
||||||
|
t.is(result.upload_failed_run_error, "Could not get upload input to github/codeql-action/analyze since it contained an " +
|
||||||
|
"unrecognized dynamic value.");
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("uploading failed SARIF run fails when workflow does not reference github/codeql-action", async (t) => {
|
||||||
|
const actionsWorkflow = createTestWorkflow([
|
||||||
|
{
|
||||||
|
name: "Checkout repository",
|
||||||
|
uses: "actions/checkout@v3",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const result = await testFailedSarifUpload(t, actionsWorkflow, {
|
||||||
|
expectUpload: false,
|
||||||
|
});
|
||||||
|
t.is(result.upload_failed_run_error, "Could not get upload input to github/codeql-action/analyze since the analyze job does not " +
|
||||||
|
"call github/codeql-action/analyze.");
|
||||||
|
t.truthy(result.upload_failed_run_stack_trace);
|
||||||
|
});
|
||||||
|
function createTestWorkflow(steps) {
|
||||||
|
return {
|
||||||
|
name: "CodeQL",
|
||||||
|
on: {
|
||||||
|
push: {
|
||||||
|
branches: ["main"],
|
||||||
|
},
|
||||||
|
pull_request: {
|
||||||
|
branches: ["main"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
jobs: {
|
||||||
|
analyze: {
|
||||||
|
name: "CodeQL Analysis",
|
||||||
|
"runs-on": "ubuntu-latest",
|
||||||
|
steps,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async function testFailedSarifUpload(t, actionsWorkflow, { category, expectUpload = true, matrix = {}, } = {}) {
|
||||||
|
const config = {
|
||||||
|
codeQLCmd: "codeql",
|
||||||
|
debugMode: true,
|
||||||
|
languages: [],
|
||||||
|
packs: [],
|
||||||
|
};
|
||||||
|
process.env["GITHUB_JOB"] = "analyze";
|
||||||
|
process.env["GITHUB_REPOSITORY"] = "github/codeql-action-fake-repository";
|
||||||
|
process.env["GITHUB_WORKSPACE"] =
|
||||||
|
"/home/runner/work/codeql-action/codeql-action";
|
||||||
|
sinon
|
||||||
|
.stub(actionsUtil, "getRequiredInput")
|
||||||
|
.withArgs("matrix")
|
||||||
|
.returns(JSON.stringify(matrix));
|
||||||
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
|
sinon.stub(codeql, "getCodeQL").resolves(codeqlObject);
|
||||||
|
const diagnosticsExportStub = sinon.stub(codeqlObject, "diagnosticsExport");
|
||||||
|
sinon.stub(workflow, "getWorkflow").resolves(actionsWorkflow);
|
||||||
|
const uploadFromActions = sinon.stub(uploadLib, "uploadFromActions");
|
||||||
|
uploadFromActions.resolves({
|
||||||
|
sarifID: "42",
|
||||||
|
statusReport: { raw_upload_size_bytes: 20, zipped_upload_size_bytes: 10 },
|
||||||
|
});
|
||||||
|
const waitForProcessing = sinon.stub(uploadLib, "waitForProcessing");
|
||||||
|
const result = await initActionPostHelper.tryUploadSarifIfRunFailed(config, (0, repository_1.parseRepositoryNwo)("github/codeql-action"), (0, testing_utils_1.createFeatures)([feature_flags_1.Feature.UploadFailedSarifEnabled]), (0, logging_1.getRunnerLogger)(true));
|
||||||
|
if (expectUpload) {
|
||||||
|
t.deepEqual(result, {
|
||||||
|
raw_upload_size_bytes: 20,
|
||||||
|
zipped_upload_size_bytes: 10,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (expectUpload) {
|
||||||
|
t.true(diagnosticsExportStub.calledOnceWith(sinon.match.string, category), `Actual args were: ${diagnosticsExportStub.args}`);
|
||||||
|
t.true(uploadFromActions.calledOnceWith(sinon.match.string, sinon.match.string, category, sinon.match.any), `Actual args were: ${uploadFromActions.args}`);
|
||||||
|
t.true(waitForProcessing.calledOnceWith(sinon.match.any, "42", sinon.match.any, {
|
||||||
|
isUnsuccessfulExecution: true,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
t.true(diagnosticsExportStub.notCalled);
|
||||||
|
t.true(uploadFromActions.notCalled);
|
||||||
|
t.true(waitForProcessing.notCalled);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
//# sourceMappingURL=init-action-post-helper.test.js.map
|
//# sourceMappingURL=init-action-post-helper.test.js.map
|
||||||
File diff suppressed because one or more lines are too long
Generated
+25
-5
@@ -25,17 +25,37 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const core = __importStar(require("@actions/core"));
|
const core = __importStar(require("@actions/core"));
|
||||||
const actionsUtil = __importStar(require("./actions-util"));
|
const actions_util_1 = require("./actions-util");
|
||||||
|
const api_client_1 = require("./api-client");
|
||||||
const debugArtifacts = __importStar(require("./debug-artifacts"));
|
const debugArtifacts = __importStar(require("./debug-artifacts"));
|
||||||
|
const feature_flags_1 = require("./feature-flags");
|
||||||
const initActionPostHelper = __importStar(require("./init-action-post-helper"));
|
const initActionPostHelper = __importStar(require("./init-action-post-helper"));
|
||||||
|
const logging_1 = require("./logging");
|
||||||
|
const repository_1 = require("./repository");
|
||||||
|
const util_1 = require("./util");
|
||||||
async function runWrapper() {
|
async function runWrapper() {
|
||||||
|
const startedAt = new Date();
|
||||||
|
let uploadFailedSarifResult;
|
||||||
try {
|
try {
|
||||||
await initActionPostHelper.run(debugArtifacts.uploadDatabaseBundleDebugArtifact, debugArtifacts.uploadLogsDebugArtifact, actionsUtil.printDebugLogs);
|
const logger = (0, logging_1.getActionsLogger)();
|
||||||
|
const gitHubVersion = await (0, api_client_1.getGitHubVersion)();
|
||||||
|
(0, util_1.checkGitHubVersionInRange)(gitHubVersion, logger);
|
||||||
|
const repositoryNwo = (0, repository_1.parseRepositoryNwo)((0, util_1.getRequiredEnvParam)("GITHUB_REPOSITORY"));
|
||||||
|
const features = new feature_flags_1.Features(gitHubVersion, repositoryNwo, (0, actions_util_1.getTemporaryDirectory)(), logger);
|
||||||
|
uploadFailedSarifResult = await initActionPostHelper.run(debugArtifacts.uploadDatabaseBundleDebugArtifact, debugArtifacts.uploadLogsDebugArtifact, actions_util_1.printDebugLogs, repositoryNwo, features, logger);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (e) {
|
||||||
core.setFailed(`init post-action step failed: ${error}`);
|
core.setFailed(e instanceof Error ? e.message : String(e));
|
||||||
console.log(error);
|
console.log(e);
|
||||||
|
await (0, actions_util_1.sendStatusReport)(await (0, actions_util_1.createStatusReportBase)("init-post", (0, actions_util_1.getActionsStatus)(e), startedAt, String(e), e instanceof Error ? e.stack : undefined));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
const statusReportBase = await (0, actions_util_1.createStatusReportBase)("init-post", "success", startedAt);
|
||||||
|
const statusReport = {
|
||||||
|
...statusReportBase,
|
||||||
|
...uploadFailedSarifResult,
|
||||||
|
};
|
||||||
|
await (0, actions_util_1.sendStatusReport)(statusReport);
|
||||||
}
|
}
|
||||||
void runWrapper();
|
void runWrapper();
|
||||||
//# sourceMappingURL=init-action-post.js.map
|
//# sourceMappingURL=init-action-post.js.map
|
||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"init-action-post.js","sourceRoot":"","sources":["../src/init-action-post.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;;;;;;AAEH,oDAAsC;AAEtC,4DAA8C;AAC9C,kEAAoD;AACpD,gFAAkE;AAElE,KAAK,UAAU,UAAU;IACvB,IAAI;QACF,MAAM,oBAAoB,CAAC,GAAG,CAC5B,cAAc,CAAC,iCAAiC,EAChD,cAAc,CAAC,uBAAuB,EACtC,WAAW,CAAC,cAAc,CAC3B,CAAC;KACH;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,CAAC,SAAS,CAAC,iCAAiC,KAAK,EAAE,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACpB;AACH,CAAC;AAED,KAAK,UAAU,EAAE,CAAC"}
|
{"version":3,"file":"init-action-post.js","sourceRoot":"","sources":["../src/init-action-post.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;;;;;;AAEH,oDAAsC;AAEtC,iDAOwB;AACxB,6CAAgD;AAChD,kEAAoD;AACpD,mDAA2C;AAC3C,gFAAkE;AAClE,uCAA6C;AAC7C,6CAAkD;AAClD,iCAAwE;AAMxE,KAAK,UAAU,UAAU;IACvB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,IAAI,uBAES,CAAC;IACd,IAAI;QACF,MAAM,MAAM,GAAG,IAAA,0BAAgB,GAAE,CAAC;QAClC,MAAM,aAAa,GAAG,MAAM,IAAA,6BAAgB,GAAE,CAAC;QAC/C,IAAA,gCAAyB,EAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAEjD,MAAM,aAAa,GAAG,IAAA,+BAAkB,EACtC,IAAA,0BAAmB,EAAC,mBAAmB,CAAC,CACzC,CAAC;QACF,MAAM,QAAQ,GAAG,IAAI,wBAAQ,CAC3B,aAAa,EACb,aAAa,EACb,IAAA,oCAAqB,GAAE,EACvB,MAAM,CACP,CAAC;QAEF,uBAAuB,GAAG,MAAM,oBAAoB,CAAC,GAAG,CACtD,cAAc,CAAC,iCAAiC,EAChD,cAAc,CAAC,uBAAuB,EACtC,6BAAc,EACd,aAAa,EACb,QAAQ,EACR,MAAM,CACP,CAAC;KACH;IAAC,OAAO,CAAC,EAAE;QACV,IAAI,CAAC,SAAS,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3D,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACf,MAAM,IAAA,+BAAgB,EACpB,MAAM,IAAA,qCAAsB,EAC1B,WAAW,EACX,IAAA,+BAAgB,EAAC,CAAC,CAAC,EACnB,SAAS,EACT,MAAM,CAAC,CAAC,CAAC,EACT,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CACzC,CACF,CAAC;QACF,OAAO;KACR;IACD,MAAM,gBAAgB,GAAG,MAAM,IAAA,qCAAsB,EACnD,WAAW,EACX,SAAS,EACT,SAAS,CACV,CAAC;IACF,MAAM,YAAY,GAAyB;QACzC,GAAG,gBAAgB;QACnB,GAAG,uBAAuB;KAC3B,CAAC;IACF,MAAM,IAAA,+BAAgB,EAAC,YAAY,CAAC,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,EAAE,CAAC"}
|
||||||
Generated
+4
-3
@@ -31,6 +31,7 @@ const logging_1 = require("./logging");
|
|||||||
const repository_1 = require("./repository");
|
const repository_1 = require("./repository");
|
||||||
const trap_caching_1 = require("./trap-caching");
|
const trap_caching_1 = require("./trap-caching");
|
||||||
const util_1 = require("./util");
|
const util_1 = require("./util");
|
||||||
|
const workflow_1 = require("./workflow");
|
||||||
// eslint-disable-next-line import/no-commonjs
|
// eslint-disable-next-line import/no-commonjs
|
||||||
const pkg = require("../package.json");
|
const pkg = require("../package.json");
|
||||||
async function sendSuccessStatusReport(startedAt, config, toolsVersion, logger) {
|
async function sendSuccessStatusReport(startedAt, config, toolsVersion, logger) {
|
||||||
@@ -88,13 +89,13 @@ async function run() {
|
|||||||
const gitHubVersion = await (0, api_client_1.getGitHubVersion)();
|
const gitHubVersion = await (0, api_client_1.getGitHubVersion)();
|
||||||
(0, util_1.checkGitHubVersionInRange)(gitHubVersion, logger);
|
(0, util_1.checkGitHubVersionInRange)(gitHubVersion, logger);
|
||||||
const repositoryNwo = (0, repository_1.parseRepositoryNwo)((0, util_1.getRequiredEnvParam)("GITHUB_REPOSITORY"));
|
const repositoryNwo = (0, repository_1.parseRepositoryNwo)((0, util_1.getRequiredEnvParam)("GITHUB_REPOSITORY"));
|
||||||
const features = new feature_flags_1.Features(gitHubVersion, repositoryNwo, logger);
|
const features = new feature_flags_1.Features(gitHubVersion, repositoryNwo, (0, actions_util_1.getTemporaryDirectory)(), logger);
|
||||||
try {
|
try {
|
||||||
const workflowErrors = await (0, actions_util_1.validateWorkflow)();
|
const workflowErrors = await (0, workflow_1.validateWorkflow)();
|
||||||
if (!(await (0, actions_util_1.sendStatusReport)(await (0, actions_util_1.createStatusReportBase)("init", "starting", startedAt, workflowErrors)))) {
|
if (!(await (0, actions_util_1.sendStatusReport)(await (0, actions_util_1.createStatusReportBase)("init", "starting", startedAt, workflowErrors)))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const initCodeQLResult = await (0, init_1.initCodeQL)((0, actions_util_1.getOptionalInput)("tools"), apiDetails, (0, actions_util_1.getTemporaryDirectory)(), gitHubVersion.type, features, logger);
|
const initCodeQLResult = await (0, init_1.initCodeQL)((0, actions_util_1.getOptionalInput)("tools"), apiDetails, (0, actions_util_1.getTemporaryDirectory)(), gitHubVersion.type, await (0, util_1.shouldBypassToolcache)(features, (0, actions_util_1.getOptionalInput)("tools"), (0, actions_util_1.getOptionalInput)("languages"), repositoryNwo, logger), logger);
|
||||||
codeql = initCodeQLResult.codeql;
|
codeql = initCodeQLResult.codeql;
|
||||||
toolsVersion = initCodeQLResult.toolsVersion;
|
toolsVersion = initCodeQLResult.toolsVersion;
|
||||||
await (0, util_1.enrichEnvironment)(codeql);
|
await (0, util_1.enrichEnvironment)(codeql);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Generated
+2
-2
@@ -30,9 +30,9 @@ const configUtils = __importStar(require("./config-utils"));
|
|||||||
const tracer_config_1 = require("./tracer-config");
|
const tracer_config_1 = require("./tracer-config");
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
const util_1 = require("./util");
|
const util_1 = require("./util");
|
||||||
async function initCodeQL(codeqlURL, apiDetails, tempDir, variant, featureEnablement, logger) {
|
async function initCodeQL(codeqlURL, apiDetails, tempDir, variant, bypassToolcache, logger) {
|
||||||
logger.startGroup("Setup CodeQL tools");
|
logger.startGroup("Setup CodeQL tools");
|
||||||
const { codeql, toolsVersion } = await (0, codeql_1.setupCodeQL)(codeqlURL, apiDetails, tempDir, variant, featureEnablement, logger, true);
|
const { codeql, toolsVersion } = await (0, codeql_1.setupCodeQL)(codeqlURL, apiDetails, tempDir, variant, bypassToolcache, logger, true);
|
||||||
await codeql.printVersion();
|
await codeql.printVersion();
|
||||||
logger.endGroup();
|
logger.endGroup();
|
||||||
return { codeql, toolsVersion };
|
return { codeql, toolsVersion };
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
|
||||||
Generated
+22
-7
@@ -1,6 +1,6 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.isScannedLanguage = exports.isTracedLanguage = exports.parseLanguage = exports.Language = void 0;
|
exports.isScannedLanguage = exports.isTracedLanguage = exports.parseLanguage = exports.resolveAlias = exports.KOTLIN_SWIFT_BYPASS = exports.LANGUAGE_ALIASES = exports.Language = void 0;
|
||||||
// All the languages supported by CodeQL
|
// All the languages supported by CodeQL
|
||||||
var Language;
|
var Language;
|
||||||
(function (Language) {
|
(function (Language) {
|
||||||
@@ -14,24 +14,39 @@ var Language;
|
|||||||
Language["swift"] = "swift";
|
Language["swift"] = "swift";
|
||||||
})(Language = exports.Language || (exports.Language = {}));
|
})(Language = exports.Language || (exports.Language = {}));
|
||||||
// Additional names for languages
|
// Additional names for languages
|
||||||
const LANGUAGE_ALIASES = {
|
exports.LANGUAGE_ALIASES = {
|
||||||
c: Language.cpp,
|
c: Language.cpp,
|
||||||
"c++": Language.cpp,
|
"c++": Language.cpp,
|
||||||
"c#": Language.csharp,
|
"c#": Language.csharp,
|
||||||
kotlin: Language.java,
|
kotlin: Language.java,
|
||||||
typescript: Language.javascript,
|
typescript: Language.javascript,
|
||||||
};
|
};
|
||||||
// Translate from user input or GitHub's API names for languages to CodeQL's names for languages
|
exports.KOTLIN_SWIFT_BYPASS = ["kotlin", "swift"];
|
||||||
|
function resolveAlias(lang) {
|
||||||
|
return exports.LANGUAGE_ALIASES[lang] || lang;
|
||||||
|
}
|
||||||
|
exports.resolveAlias = resolveAlias;
|
||||||
|
/**
|
||||||
|
* Translate from user input or GitHub's API names for languages to CodeQL's
|
||||||
|
* names for languages. This does not translate a language alias to the actual
|
||||||
|
* language used by CodeQL.
|
||||||
|
*
|
||||||
|
* @param language The language to translate.
|
||||||
|
* @returns A language supported by CodeQL, an alias for a language, or
|
||||||
|
* `undefined` if the input language cannot be parsed into a langauge supported
|
||||||
|
* by CodeQL.
|
||||||
|
*/
|
||||||
function parseLanguage(language) {
|
function parseLanguage(language) {
|
||||||
// Normalise to lower case
|
// Normalise to lower case
|
||||||
language = language.toLowerCase();
|
language = language.trim().toLowerCase();
|
||||||
// See if it's an exact match
|
// See if it's an exact match
|
||||||
if (language in Language) {
|
if (language in Language) {
|
||||||
return language;
|
return language;
|
||||||
}
|
}
|
||||||
// Check language aliases
|
// Check language aliases, but return the original language name,
|
||||||
if (language in LANGUAGE_ALIASES) {
|
// the alias will be resolved later.
|
||||||
return LANGUAGE_ALIASES[language];
|
if (language in exports.LANGUAGE_ALIASES) {
|
||||||
|
return language;
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"languages.js","sourceRoot":"","sources":["../src/languages.ts"],"names":[],"mappings":";;;AAAA,wCAAwC;AACxC,IAAY,QASX;AATD,WAAY,QAAQ;IAClB,6BAAiB,CAAA;IACjB,uBAAW,CAAA;IACX,qBAAS,CAAA;IACT,yBAAa,CAAA;IACb,qCAAyB,CAAA;IACzB,6BAAiB,CAAA;IACjB,yBAAa,CAAA;IACb,2BAAe,CAAA;AACjB,CAAC,EATW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QASnB;AAED,iCAAiC;AACjC,MAAM,gBAAgB,GAAiC;IACrD,CAAC,EAAE,QAAQ,CAAC,GAAG;IACf,KAAK,EAAE,QAAQ,CAAC,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAC,MAAM;IACrB,MAAM,EAAE,QAAQ,CAAC,IAAI;IACrB,UAAU,EAAE,QAAQ,CAAC,UAAU;CAChC,CAAC;AAEF,gGAAgG;AAChG,SAAgB,aAAa,CAAC,QAAgB;IAC5C,0BAA0B;IAC1B,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IAElC,6BAA6B;IAC7B,IAAI,QAAQ,IAAI,QAAQ,EAAE;QACxB,OAAO,QAAoB,CAAC;KAC7B;IAED,yBAAyB;IACzB,IAAI,QAAQ,IAAI,gBAAgB,EAAE;QAChC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,CAAC;KACnC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAfD,sCAeC;AAED,SAAgB,gBAAgB,CAAC,QAAkB;IACjD,OAAO;QACL,QAAQ,CAAC,GAAG;QACZ,QAAQ,CAAC,MAAM;QACf,QAAQ,CAAC,EAAE;QACX,QAAQ,CAAC,IAAI;QACb,QAAQ,CAAC,KAAK;KACf,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACvB,CAAC;AARD,4CAQC;AAED,SAAgB,iBAAiB,CAAC,QAAkB;IAClD,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAFD,8CAEC"}
|
{"version":3,"file":"languages.js","sourceRoot":"","sources":["../src/languages.ts"],"names":[],"mappings":";;;AAAA,wCAAwC;AACxC,IAAY,QASX;AATD,WAAY,QAAQ;IAClB,6BAAiB,CAAA;IACjB,uBAAW,CAAA;IACX,qBAAS,CAAA;IACT,yBAAa,CAAA;IACb,qCAAyB,CAAA;IACzB,6BAAiB,CAAA;IACjB,yBAAa,CAAA;IACb,2BAAe,CAAA;AACjB,CAAC,EATW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QASnB;AAED,iCAAiC;AACpB,QAAA,gBAAgB,GAAiC;IAC5D,CAAC,EAAE,QAAQ,CAAC,GAAG;IACf,KAAK,EAAE,QAAQ,CAAC,GAAG;IACnB,IAAI,EAAE,QAAQ,CAAC,MAAM;IACrB,MAAM,EAAE,QAAQ,CAAC,IAAI;IACrB,UAAU,EAAE,QAAQ,CAAC,UAAU;CAChC,CAAC;AAIW,QAAA,mBAAmB,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAEvD,SAAgB,YAAY,CAAC,IAAqB;IAChD,OAAO,wBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;AACxC,CAAC;AAFD,oCAEC;AAED;;;;;;;;;GASG;AACH,SAAgB,aAAa,CAAC,QAAgB;IAC5C,0BAA0B;IAC1B,QAAQ,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAEzC,6BAA6B;IAC7B,IAAI,QAAQ,IAAI,QAAQ,EAAE;QACxB,OAAO,QAAoB,CAAC;KAC7B;IAED,iEAAiE;IACjE,oCAAoC;IACpC,IAAI,QAAQ,IAAI,wBAAgB,EAAE;QAChC,OAAO,QAAQ,CAAC;KACjB;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAhBD,sCAgBC;AAED,SAAgB,gBAAgB,CAAC,QAAkB;IACjD,OAAO;QACL,QAAQ,CAAC,GAAG;QACZ,QAAQ,CAAC,MAAM;QACf,QAAQ,CAAC,EAAE;QACX,QAAQ,CAAC,IAAI;QACb,QAAQ,CAAC,KAAK;KACf,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACvB,CAAC;AARD,4CAQC;AAED,SAAgB,iBAAiB,CAAC,QAAkB;IAClD,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;AACrC,CAAC;AAFD,8CAEC"}
|
||||||
Generated
+8
-5
@@ -16,11 +16,14 @@ const testing_utils_1 = require("./testing-utils");
|
|||||||
t.deepEqual((0, languages_1.parseLanguage)("javascript"), languages_1.Language.javascript);
|
t.deepEqual((0, languages_1.parseLanguage)("javascript"), languages_1.Language.javascript);
|
||||||
t.deepEqual((0, languages_1.parseLanguage)("python"), languages_1.Language.python);
|
t.deepEqual((0, languages_1.parseLanguage)("python"), languages_1.Language.python);
|
||||||
// Aliases
|
// Aliases
|
||||||
t.deepEqual((0, languages_1.parseLanguage)("c"), languages_1.Language.cpp);
|
t.deepEqual((0, languages_1.parseLanguage)("c"), "c");
|
||||||
t.deepEqual((0, languages_1.parseLanguage)("c++"), languages_1.Language.cpp);
|
t.deepEqual((0, languages_1.parseLanguage)("c++"), "c++");
|
||||||
t.deepEqual((0, languages_1.parseLanguage)("c#"), languages_1.Language.csharp);
|
t.deepEqual((0, languages_1.parseLanguage)("c#"), "c#");
|
||||||
t.deepEqual((0, languages_1.parseLanguage)("kotlin"), languages_1.Language.java);
|
t.deepEqual((0, languages_1.parseLanguage)("kotlin"), "kotlin");
|
||||||
t.deepEqual((0, languages_1.parseLanguage)("typescript"), languages_1.Language.javascript);
|
t.deepEqual((0, languages_1.parseLanguage)("typescript"), "typescript");
|
||||||
|
// spaces and case-insensitivity
|
||||||
|
t.deepEqual((0, languages_1.parseLanguage)(" \t\nCsHaRp\t\t"), languages_1.Language.csharp);
|
||||||
|
t.deepEqual((0, languages_1.parseLanguage)(" \t\nkOtLin\t\t"), "kotlin");
|
||||||
// Not matches
|
// Not matches
|
||||||
t.deepEqual((0, languages_1.parseLanguage)("foo"), undefined);
|
t.deepEqual((0, languages_1.parseLanguage)("foo"), undefined);
|
||||||
t.deepEqual((0, languages_1.parseLanguage)(" "), undefined);
|
t.deepEqual((0, languages_1.parseLanguage)(" "), undefined);
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"languages.test.js","sourceRoot":"","sources":["../src/languages.test.ts"],"names":[],"mappings":";;;;;AAAA,8CAAuB;AAEvB,2CAKqB;AACrB,mDAA6C;AAE7C,IAAA,0BAAU,EAAC,aAAI,CAAC,CAAC;AAEjB,IAAA,aAAI,EAAC,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAChC,gBAAgB;IAChB,CAAC,CAAC,SAAS,CAAC,IAAA,yBAAa,EAAC,QAAQ,CAAC,EAAE,oBAAQ,CAAC,MAAM,CAAC,CAAC;IACtD,CAAC,CAAC,SAAS,CAAC,IAAA,yBAAa,EAAC,KAAK,CAAC,EAAE,oBAAQ,CAAC,GAAG,CAAC,CAAC;IAChD,CAAC,CAAC,SAAS,CAAC,IAAA,yBAAa,EAAC,IAAI,CAAC,EAAE,oBAAQ,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC,CAAC,SAAS,CAAC,IAAA,yBAAa,EAAC,MAAM,CAAC,EAAE,oBAAQ,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC,CAAC,SAAS,CAAC,IAAA,yBAAa,EAAC,YAAY,CAAC,EAAE,oBAAQ,CAAC,UAAU,CAAC,CAAC;IAC9D,CAAC,CAAC,SAAS,CAAC,IAAA,yBAAa,EAAC,QAAQ,CAAC,EAAE,oBAAQ,CAAC,MAAM,CAAC,CAAC;IAEtD,UAAU;IACV,CAAC,CAAC,SAAS,CAAC,IAAA,yBAAa,EAAC,GAAG,CAAC,EAAE,oBAAQ,CAAC,GAAG,CAAC,CAAC;IAC9C,CAAC,CAAC,SAAS,CAAC,IAAA,yBAAa,EAAC,KAAK,CAAC,EAAE,oBAAQ,CAAC,GAAG,CAAC,CAAC;IAChD,CAAC,CAAC,SAAS,CAAC,IAAA,yBAAa,EAAC,IAAI,CAAC,EAAE,oBAAQ,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC,CAAC,SAAS,CAAC,IAAA,yBAAa,EAAC,QAAQ,CAAC,EAAE,oBAAQ,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC,CAAC,SAAS,CAAC,IAAA,yBAAa,EAAC,YAAY,CAAC,EAAE,oBAAQ,CAAC,UAAU,CAAC,CAAC;IAE9D,cAAc;IACd,CAAC,CAAC,SAAS,CAAC,IAAA,yBAAa,EAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;IAC7C,CAAC,CAAC,SAAS,CAAC,IAAA,yBAAa,EAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;IAC3C,CAAC,CAAC,SAAS,CAAC,IAAA,yBAAa,EAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;AAC5C,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACnC,CAAC,CAAC,IAAI,CAAC,IAAA,4BAAgB,EAAC,oBAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,IAAI,CAAC,IAAA,4BAAgB,EAAC,oBAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,IAAI,CAAC,IAAA,4BAAgB,EAAC,oBAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,IAAI,CAAC,IAAA,4BAAgB,EAAC,oBAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC,IAAI,CAAC,IAAA,4BAAgB,EAAC,oBAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAEzC,CAAC,CAAC,KAAK,CAAC,IAAA,4BAAgB,EAAC,oBAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,KAAK,CAAC,IAAA,4BAAgB,EAAC,oBAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,KAAK,CAAC,IAAA,4BAAgB,EAAC,oBAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,mBAAmB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IACpC,CAAC,CAAC,KAAK,CAAC,IAAA,6BAAiB,EAAC,oBAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,KAAK,CAAC,IAAA,6BAAiB,EAAC,oBAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,KAAK,CAAC,IAAA,6BAAiB,EAAC,oBAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IACxC,CAAC,CAAC,KAAK,CAAC,IAAA,6BAAiB,EAAC,oBAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,KAAK,CAAC,IAAA,6BAAiB,EAAC,oBAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAE3C,CAAC,CAAC,IAAI,CAAC,IAAA,6BAAiB,EAAC,oBAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,IAAI,CAAC,IAAA,6BAAiB,EAAC,oBAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,IAAI,CAAC,IAAA,6BAAiB,EAAC,oBAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC"}
|
{"version":3,"file":"languages.test.js","sourceRoot":"","sources":["../src/languages.test.ts"],"names":[],"mappings":"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"}
|
||||||
Generated
+15
-8
@@ -1,14 +1,21 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.CODEQL_ACTION_TEST_MODE = exports.CODEQL_ACTION_TESTING_ENVIRONMENT = exports.CODEQL_WORKFLOW_STARTED_AT = exports.ODASA_TRACER_CONFIGURATION = void 0;
|
exports.ODASA_TRACER_CONFIGURATION = exports.CODEQL_WORKFLOW_STARTED_AT = exports.CODEQL_ACTION_TEST_MODE = exports.CODEQL_ACTION_TESTING_ENVIRONMENT = exports.CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY = void 0;
|
||||||
exports.ODASA_TRACER_CONFIGURATION = "ODASA_TRACER_CONFIGURATION";
|
/**
|
||||||
// The time at which the first action (normally init) started executing.
|
* This environment variable is set to true when the `analyze` Action
|
||||||
// If a workflow invokes a different action without first invoking the init
|
* completes successfully.
|
||||||
// action (i.e. the upload action is being used by a third-party integrator)
|
*/
|
||||||
// then this variable will be assigned the start time of the action invoked
|
exports.CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY = "CODEQL_ACTION_ANALYZE_DID_COMPLETE_SUCCESSFULLY";
|
||||||
// rather that the init action.
|
|
||||||
exports.CODEQL_WORKFLOW_STARTED_AT = "CODEQL_WORKFLOW_STARTED_AT";
|
|
||||||
exports.CODEQL_ACTION_TESTING_ENVIRONMENT = "CODEQL_ACTION_TESTING_ENVIRONMENT";
|
exports.CODEQL_ACTION_TESTING_ENVIRONMENT = "CODEQL_ACTION_TESTING_ENVIRONMENT";
|
||||||
/** Used to disable uploading SARIF results or status reports to the GitHub API */
|
/** Used to disable uploading SARIF results or status reports to the GitHub API */
|
||||||
exports.CODEQL_ACTION_TEST_MODE = "CODEQL_ACTION_TEST_MODE";
|
exports.CODEQL_ACTION_TEST_MODE = "CODEQL_ACTION_TEST_MODE";
|
||||||
|
/**
|
||||||
|
* The time at which the first action (normally init) started executing.
|
||||||
|
* If a workflow invokes a different action without first invoking the init
|
||||||
|
* action (i.e. the upload action is being used by a third-party integrator)
|
||||||
|
* then this variable will be assigned the start time of the action invoked
|
||||||
|
* rather that the init action.
|
||||||
|
*/
|
||||||
|
exports.CODEQL_WORKFLOW_STARTED_AT = "CODEQL_WORKFLOW_STARTED_AT";
|
||||||
|
exports.ODASA_TRACER_CONFIGURATION = "ODASA_TRACER_CONFIGURATION";
|
||||||
//# sourceMappingURL=shared-environment.js.map
|
//# sourceMappingURL=shared-environment.js.map
|
||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"shared-environment.js","sourceRoot":"","sources":["../src/shared-environment.ts"],"names":[],"mappings":";;;AAAa,QAAA,0BAA0B,GAAG,4BAA4B,CAAC;AACvE,wEAAwE;AACxE,2EAA2E;AAC3E,4EAA4E;AAC5E,2EAA2E;AAC3E,+BAA+B;AAClB,QAAA,0BAA0B,GAAG,4BAA4B,CAAC;AAE1D,QAAA,iCAAiC,GAC5C,mCAAmC,CAAC;AAEtC,kFAAkF;AACrE,QAAA,uBAAuB,GAAG,yBAAyB,CAAC"}
|
{"version":3,"file":"shared-environment.js","sourceRoot":"","sources":["../src/shared-environment.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACU,QAAA,+CAA+C,GAC1D,iDAAiD,CAAC;AAEvC,QAAA,iCAAiC,GAC5C,mCAAmC,CAAC;AAEtC,kFAAkF;AACrE,QAAA,uBAAuB,GAAG,yBAAyB,CAAC;AAEjE;;;;;;GAMG;AACU,QAAA,0BAA0B,GAAG,4BAA4B,CAAC;AAE1D,QAAA,0BAA0B,GAAG,4BAA4B,CAAC"}
|
||||||
Generated
+20
-1
@@ -19,7 +19,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.createFeatures = exports.mockCodeQLVersion = exports.mockFeatureFlagApiEndpoint = exports.getRecordingLogger = exports.setupActionsVars = exports.setupTests = void 0;
|
exports.createFeatures = exports.mockCodeQLVersion = exports.mockLanguagesInRepo = exports.mockFeatureFlagApiEndpoint = exports.getRecordingLogger = exports.setupActionsVars = exports.setupTests = void 0;
|
||||||
const github = __importStar(require("@actions/github"));
|
const github = __importStar(require("@actions/github"));
|
||||||
const sinon = __importStar(require("sinon"));
|
const sinon = __importStar(require("sinon"));
|
||||||
const apiClient = __importStar(require("./api-client"));
|
const apiClient = __importStar(require("./api-client"));
|
||||||
@@ -144,6 +144,25 @@ function mockFeatureFlagApiEndpoint(responseStatusCode, response) {
|
|||||||
sinon.stub(apiClient, "getApiClient").value(() => client);
|
sinon.stub(apiClient, "getApiClient").value(() => client);
|
||||||
}
|
}
|
||||||
exports.mockFeatureFlagApiEndpoint = mockFeatureFlagApiEndpoint;
|
exports.mockFeatureFlagApiEndpoint = mockFeatureFlagApiEndpoint;
|
||||||
|
function mockLanguagesInRepo(languages) {
|
||||||
|
const mockClient = sinon.stub(apiClient, "getApiClient");
|
||||||
|
const listLanguages = sinon.stub().resolves({
|
||||||
|
status: 200,
|
||||||
|
data: languages.reduce((acc, lang) => {
|
||||||
|
acc[lang] = 1;
|
||||||
|
return acc;
|
||||||
|
}, {}),
|
||||||
|
headers: {},
|
||||||
|
url: "GET /repos/:owner/:repo/languages",
|
||||||
|
});
|
||||||
|
mockClient.returns({
|
||||||
|
repos: {
|
||||||
|
listLanguages,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return listLanguages;
|
||||||
|
}
|
||||||
|
exports.mockLanguagesInRepo = mockLanguagesInRepo;
|
||||||
function mockCodeQLVersion(version) {
|
function mockCodeQLVersion(version) {
|
||||||
return {
|
return {
|
||||||
async getVersion() {
|
async getVersion() {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"testing-utils.js","sourceRoot":"","sources":["../src/testing-utils.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"testing-utils.js","sourceRoot":"","sources":["../src/testing-utils.ts"],"names":[],"mappings":"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"}
|
||||||
Generated
+18
-22
@@ -31,7 +31,7 @@ const safeWhich = __importStar(require("@chrisgavin/safe-which"));
|
|||||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
* @param args optional arguments for tool. Escaping is handled by the lib.
|
||||||
* @param matchers defines specific codes and/or regexes that should lead to return of a custom error
|
* @param matchers defines specific codes and/or regexes that should lead to return of a custom error
|
||||||
* @param options optional exec options. See ExecOptions
|
* @param options optional exec options. See ExecOptions
|
||||||
* @returns Promise<number> exit code
|
* @returns ReturnState exit code and stdout output, if applicable
|
||||||
*/
|
*/
|
||||||
async function toolrunnerErrorCatcher(commandLine, args, matchers, options) {
|
async function toolrunnerErrorCatcher(commandLine, args, matchers, options) {
|
||||||
var _a, _b;
|
var _a, _b;
|
||||||
@@ -54,40 +54,36 @@ async function toolrunnerErrorCatcher(commandLine, args, matchers, options) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
// we capture the original return code or error so that if no match is found we can duplicate the behavior
|
// we capture the original return code or error so that if no match is found we can duplicate the behavior
|
||||||
let returnState;
|
let exitCode;
|
||||||
try {
|
try {
|
||||||
returnState = await new toolrunner.ToolRunner(await safeWhich.safeWhich(commandLine), args, {
|
exitCode = await new toolrunner.ToolRunner(await safeWhich.safeWhich(commandLine), args, {
|
||||||
...options,
|
...options,
|
||||||
listeners,
|
listeners,
|
||||||
ignoreReturnCode: true, // so we can check for specific codes using the matchers
|
ignoreReturnCode: true, // so we can check for specific codes using the matchers
|
||||||
}).exec();
|
}).exec();
|
||||||
}
|
// if there is a zero return code then we do not apply the matchers
|
||||||
catch (e) {
|
if (exitCode === 0)
|
||||||
returnState = e instanceof Error ? e : new Error(String(e));
|
return { exitCode, stdout };
|
||||||
}
|
if (matchers) {
|
||||||
// if there is a zero return code then we do not apply the matchers
|
for (const matcher of matchers) {
|
||||||
if (returnState === 0)
|
if (matcher.exitCode === exitCode ||
|
||||||
return returnState;
|
((_a = matcher.outputRegex) === null || _a === void 0 ? void 0 : _a.test(stderr)) ||
|
||||||
if (matchers) {
|
((_b = matcher.outputRegex) === null || _b === void 0 ? void 0 : _b.test(stdout))) {
|
||||||
for (const matcher of matchers) {
|
throw new Error(matcher.message);
|
||||||
if (matcher.exitCode === returnState ||
|
}
|
||||||
((_a = matcher.outputRegex) === null || _a === void 0 ? void 0 : _a.test(stderr)) ||
|
|
||||||
((_b = matcher.outputRegex) === null || _b === void 0 ? void 0 : _b.test(stdout))) {
|
|
||||||
throw new Error(matcher.message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (typeof returnState === "number") {
|
|
||||||
// only if we were instructed to ignore the return code do we ever return it non-zero
|
// only if we were instructed to ignore the return code do we ever return it non-zero
|
||||||
if (options === null || options === void 0 ? void 0 : options.ignoreReturnCode) {
|
if (options === null || options === void 0 ? void 0 : options.ignoreReturnCode) {
|
||||||
return returnState;
|
return { exitCode, stdout };
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new Error(`The process '${commandLine}' failed with exit code ${returnState}`);
|
throw new Error(`The process '${commandLine}' failed with exit code ${exitCode}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
catch (e) {
|
||||||
throw returnState;
|
const error = e instanceof Error ? e : new Error(String(e));
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.toolrunnerErrorCatcher = toolrunnerErrorCatcher;
|
exports.toolrunnerErrorCatcher = toolrunnerErrorCatcher;
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"toolrunner-error-catcher.js","sourceRoot":"","sources":["../src/toolrunner-error-catcher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AACA,yEAA2D;AAC3D,kEAAoD;AAIpD;;;;;;;;;;GAUG;AACI,KAAK,UAAU,sBAAsB,CAC1C,WAAmB,EACnB,IAAe,EACf,QAAyB,EACzB,OAAwB;;IAExB,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,MAAM,SAAS,GAAG;QAChB,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;;YACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,0CAAE,MAAM,MAAK,SAAS,EAAE;gBAC5C,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAChC;QACH,CAAC;QACD,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;;YACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,0CAAE,MAAM,MAAK,SAAS,EAAE;gBAC5C,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAChC;QACH,CAAC;KACF,CAAC;IAEF,0GAA0G;IAC1G,IAAI,WAA2B,CAAC;IAChC,IAAI;QACF,WAAW,GAAG,MAAM,IAAI,UAAU,CAAC,UAAU,CAC3C,MAAM,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,EACtC,IAAI,EACJ;YACE,GAAG,OAAO;YACV,SAAS;YACT,gBAAgB,EAAE,IAAI,EAAE,wDAAwD;SACjF,CACF,CAAC,IAAI,EAAE,CAAC;KACV;IAAC,OAAO,CAAC,EAAE;QACV,WAAW,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;KAC7D;IAED,mEAAmE;IACnE,IAAI,WAAW,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC;IAE1C,IAAI,QAAQ,EAAE;QACZ,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;YAC9B,IACE,OAAO,CAAC,QAAQ,KAAK,WAAW;iBAChC,MAAA,OAAO,CAAC,WAAW,0CAAE,IAAI,CAAC,MAAM,CAAC,CAAA;iBACjC,MAAA,OAAO,CAAC,WAAW,0CAAE,IAAI,CAAC,MAAM,CAAC,CAAA,EACjC;gBACA,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;aAClC;SACF;KACF;IAED,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE;QACnC,qFAAqF;QACrF,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,gBAAgB,EAAE;YAC7B,OAAO,WAAW,CAAC;SACpB;aAAM;YACL,MAAM,IAAI,KAAK,CACb,gBAAgB,WAAW,2BAA2B,WAAW,EAAE,CACpE,CAAC;SACH;KACF;SAAM;QACL,MAAM,WAAW,CAAC;KACnB;AACH,CAAC;AAnED,wDAmEC"}
|
{"version":3,"file":"toolrunner-error-catcher.js","sourceRoot":"","sources":["../src/toolrunner-error-catcher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AACA,yEAA2D;AAC3D,kEAAoD;AASpD;;;;;;;;;;GAUG;AACI,KAAK,UAAU,sBAAsB,CAC1C,WAAmB,EACnB,IAAe,EACf,QAAyB,EACzB,OAAwB;;IAExB,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,MAAM,SAAS,GAAG;QAChB,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;;YACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,0CAAE,MAAM,MAAK,SAAS,EAAE;gBAC5C,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAChC;QACH,CAAC;QACD,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;;YACvB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,0CAAE,MAAM,MAAK,SAAS,EAAE;gBAC5C,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aAChC;QACH,CAAC;KACF,CAAC;IAEF,0GAA0G;IAC1G,IAAI,QAAgB,CAAC;IACrB,IAAI;QACF,QAAQ,GAAG,MAAM,IAAI,UAAU,CAAC,UAAU,CACxC,MAAM,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,EACtC,IAAI,EACJ;YACE,GAAG,OAAO;YACV,SAAS;YACT,gBAAgB,EAAE,IAAI,EAAE,wDAAwD;SACjF,CACF,CAAC,IAAI,EAAE,CAAC;QAET,mEAAmE;QACnE,IAAI,QAAQ,KAAK,CAAC;YAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAEhD,IAAI,QAAQ,EAAE;YACZ,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;gBAC9B,IACE,OAAO,CAAC,QAAQ,KAAK,QAAQ;qBAC7B,MAAA,OAAO,CAAC,WAAW,0CAAE,IAAI,CAAC,MAAM,CAAC,CAAA;qBACjC,MAAA,OAAO,CAAC,WAAW,0CAAE,IAAI,CAAC,MAAM,CAAC,CAAA,EACjC;oBACA,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;iBAClC;aACF;SACF;QAED,qFAAqF;QACrF,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,gBAAgB,EAAE;YAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;SAC7B;aAAM;YACL,MAAM,IAAI,KAAK,CACb,gBAAgB,WAAW,2BAA2B,QAAQ,EAAE,CACjE,CAAC;SACH;KACF;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,KAAK,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,KAAK,CAAC;KACb;AACH,CAAC;AAhED,wDAgEC"}
|
||||||
Generated
+8
-5
@@ -33,7 +33,8 @@ const toolrunner_error_catcher_1 = require("./toolrunner-error-catcher");
|
|||||||
{ exitCode: 123, outputRegex: new RegExp("foo bar"), message: "error!!!" },
|
{ exitCode: 123, outputRegex: new RegExp("foo bar"), message: "error!!!" },
|
||||||
];
|
];
|
||||||
t.deepEqual(await exec.exec("node", testArgs), 0);
|
t.deepEqual(await exec.exec("node", testArgs), 0);
|
||||||
t.deepEqual(await (0, toolrunner_error_catcher_1.toolrunnerErrorCatcher)("node", testArgs, matchers), 0);
|
const returnState = await (0, toolrunner_error_catcher_1.toolrunnerErrorCatcher)("node", testArgs, matchers);
|
||||||
|
t.deepEqual(returnState.exitCode, 0);
|
||||||
});
|
});
|
||||||
(0, ava_1.default)("regex matchers are applied to stdout for non-zero exit code", async (t) => {
|
(0, ava_1.default)("regex matchers are applied to stdout for non-zero exit code", async (t) => {
|
||||||
const testArgs = buildDummyArgs("foo bar\\nblort qux", "", "", 1);
|
const testArgs = buildDummyArgs("foo bar\\nblort qux", "", "", 1);
|
||||||
@@ -116,9 +117,10 @@ const toolrunner_error_catcher_1 = require("./toolrunner-error-catcher");
|
|||||||
(0, ava_1.default)("execErrorCatcher respects the ignoreReturnValue option", async (t) => {
|
(0, ava_1.default)("execErrorCatcher respects the ignoreReturnValue option", async (t) => {
|
||||||
const testArgs = buildDummyArgs("standard output", "error output", "", 199);
|
const testArgs = buildDummyArgs("standard output", "error output", "", 199);
|
||||||
await t.throwsAsync((0, toolrunner_error_catcher_1.toolrunnerErrorCatcher)("node", testArgs, [], { ignoreReturnCode: false }), { instanceOf: Error });
|
await t.throwsAsync((0, toolrunner_error_catcher_1.toolrunnerErrorCatcher)("node", testArgs, [], { ignoreReturnCode: false }), { instanceOf: Error });
|
||||||
t.deepEqual(await (0, toolrunner_error_catcher_1.toolrunnerErrorCatcher)("node", testArgs, [], {
|
const returnState = await (0, toolrunner_error_catcher_1.toolrunnerErrorCatcher)("node", testArgs, [], {
|
||||||
ignoreReturnCode: true,
|
ignoreReturnCode: true,
|
||||||
}), 199);
|
});
|
||||||
|
t.deepEqual(returnState.exitCode, 199);
|
||||||
});
|
});
|
||||||
(0, ava_1.default)("execErrorCatcher preserves behavior of provided listeners", async (t) => {
|
(0, ava_1.default)("execErrorCatcher preserves behavior of provided listeners", async (t) => {
|
||||||
const stdoutExpected = "standard output";
|
const stdoutExpected = "standard output";
|
||||||
@@ -134,9 +136,10 @@ const toolrunner_error_catcher_1 = require("./toolrunner-error-catcher");
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
const testArgs = buildDummyArgs(stdoutExpected, stderrExpected, "", 0);
|
const testArgs = buildDummyArgs(stdoutExpected, stderrExpected, "", 0);
|
||||||
t.deepEqual(await (0, toolrunner_error_catcher_1.toolrunnerErrorCatcher)("node", testArgs, [], {
|
const returnState = await (0, toolrunner_error_catcher_1.toolrunnerErrorCatcher)("node", testArgs, [], {
|
||||||
listeners,
|
listeners,
|
||||||
}), 0);
|
});
|
||||||
|
t.deepEqual(returnState.exitCode, 0);
|
||||||
t.deepEqual(stdoutActual, `${stdoutExpected}\n`);
|
t.deepEqual(stdoutActual, `${stdoutExpected}\n`);
|
||||||
t.deepEqual(stderrActual, `${stderrExpected}\n`);
|
t.deepEqual(stderrActual, `${stderrExpected}\n`);
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Generated
+103
-64
@@ -30,13 +30,13 @@ const zlib_1 = __importDefault(require("zlib"));
|
|||||||
const core = __importStar(require("@actions/core"));
|
const core = __importStar(require("@actions/core"));
|
||||||
const file_url_1 = __importDefault(require("file-url"));
|
const file_url_1 = __importDefault(require("file-url"));
|
||||||
const jsonschema = __importStar(require("jsonschema"));
|
const jsonschema = __importStar(require("jsonschema"));
|
||||||
const semver = __importStar(require("semver"));
|
|
||||||
const actionsUtil = __importStar(require("./actions-util"));
|
const actionsUtil = __importStar(require("./actions-util"));
|
||||||
const api = __importStar(require("./api-client"));
|
const api = __importStar(require("./api-client"));
|
||||||
const fingerprints = __importStar(require("./fingerprints"));
|
const fingerprints = __importStar(require("./fingerprints"));
|
||||||
const repository_1 = require("./repository");
|
const repository_1 = require("./repository");
|
||||||
const sharedEnv = __importStar(require("./shared-environment"));
|
const sharedEnv = __importStar(require("./shared-environment"));
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
|
const workflow = __importStar(require("./workflow"));
|
||||||
// Takes a list of paths to sarif files and combines them together,
|
// Takes a list of paths to sarif files and combines them together,
|
||||||
// returning the contents of the combined sarif file.
|
// returning the contents of the combined sarif file.
|
||||||
function combineSarifFiles(sarifFiles) {
|
function combineSarifFiles(sarifFiles) {
|
||||||
@@ -128,9 +128,8 @@ function findSarifFilesInDir(sarifPath) {
|
|||||||
exports.findSarifFilesInDir = findSarifFilesInDir;
|
exports.findSarifFilesInDir = findSarifFilesInDir;
|
||||||
// Uploads a single sarif file or a directory of sarif files
|
// Uploads a single sarif file or a directory of sarif files
|
||||||
// depending on what the path happens to refer to.
|
// depending on what the path happens to refer to.
|
||||||
// Returns true iff the upload occurred and succeeded
|
async function uploadFromActions(sarifPath, checkoutPath, category, logger) {
|
||||||
async function uploadFromActions(sarifPath, gitHubVersion, logger) {
|
return await uploadFiles(getSarifFilePaths(sarifPath), (0, repository_1.parseRepositoryNwo)(util.getRequiredEnvParam("GITHUB_REPOSITORY")), await actionsUtil.getCommitOid(checkoutPath), await actionsUtil.getRef(), await actionsUtil.getAnalysisKey(), category, util.getRequiredEnvParam("GITHUB_WORKFLOW"), workflow.getWorkflowRunID(), checkoutPath, actionsUtil.getRequiredInput("matrix"), logger);
|
||||||
return await uploadFiles(getSarifFilePaths(sarifPath), (0, repository_1.parseRepositoryNwo)(util.getRequiredEnvParam("GITHUB_REPOSITORY")), await actionsUtil.getCommitOid(actionsUtil.getRequiredInput("checkout_path")), await actionsUtil.getRef(), await actionsUtil.getAnalysisKey(), actionsUtil.getOptionalInput("category"), util.getRequiredEnvParam("GITHUB_WORKFLOW"), actionsUtil.getWorkflowRunID(), actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getRequiredInput("matrix"), gitHubVersion, logger);
|
|
||||||
}
|
}
|
||||||
exports.uploadFromActions = uploadFromActions;
|
exports.uploadFromActions = uploadFromActions;
|
||||||
function getSarifFilePaths(sarifPath) {
|
function getSarifFilePaths(sarifPath) {
|
||||||
@@ -193,7 +192,7 @@ function validateSarifFileSchema(sarifFilePath, logger) {
|
|||||||
exports.validateSarifFileSchema = validateSarifFileSchema;
|
exports.validateSarifFileSchema = validateSarifFileSchema;
|
||||||
// buildPayload constructs a map ready to be uploaded to the API from the given
|
// buildPayload constructs a map ready to be uploaded to the API from the given
|
||||||
// parameters, respecting the current mode and target GitHub instance version.
|
// parameters, respecting the current mode and target GitHub instance version.
|
||||||
function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, workflowRunID, checkoutURI, environment, toolNames, gitHubVersion, mergeBaseCommitOid) {
|
function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, workflowRunID, checkoutURI, environment, toolNames, mergeBaseCommitOid) {
|
||||||
const payloadObj = {
|
const payloadObj = {
|
||||||
commit_oid: commitOid,
|
commit_oid: commitOid,
|
||||||
ref,
|
ref,
|
||||||
@@ -208,26 +207,22 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo
|
|||||||
base_ref: undefined,
|
base_ref: undefined,
|
||||||
base_sha: undefined,
|
base_sha: undefined,
|
||||||
};
|
};
|
||||||
// This behaviour can be made the default when support for GHES 3.0 is discontinued.
|
if (actionsUtil.workflowEventName() === "pull_request") {
|
||||||
if (gitHubVersion.type !== util.GitHubVariant.GHES ||
|
if (commitOid === util.getRequiredEnvParam("GITHUB_SHA") &&
|
||||||
semver.satisfies(gitHubVersion.version, `>=3.1`)) {
|
mergeBaseCommitOid) {
|
||||||
if (actionsUtil.workflowEventName() === "pull_request") {
|
// We're uploading results for the merge commit
|
||||||
if (commitOid === util.getRequiredEnvParam("GITHUB_SHA") &&
|
// and were able to determine the merge base.
|
||||||
mergeBaseCommitOid) {
|
// So we use that as the most accurate base.
|
||||||
// We're uploading results for the merge commit
|
payloadObj.base_ref = `refs/heads/${util.getRequiredEnvParam("GITHUB_BASE_REF")}`;
|
||||||
// and were able to determine the merge base.
|
payloadObj.base_sha = mergeBaseCommitOid;
|
||||||
// So we use that as the most accurate base.
|
}
|
||||||
payloadObj.base_ref = `refs/heads/${util.getRequiredEnvParam("GITHUB_BASE_REF")}`;
|
else if (process.env.GITHUB_EVENT_PATH) {
|
||||||
payloadObj.base_sha = mergeBaseCommitOid;
|
// Either we're not uploading results for the merge commit
|
||||||
}
|
// or we could not determine the merge base.
|
||||||
else if (process.env.GITHUB_EVENT_PATH) {
|
// Using the PR base is the only option here
|
||||||
// Either we're not uploading results for the merge commit
|
const githubEvent = JSON.parse(fs.readFileSync(process.env.GITHUB_EVENT_PATH, "utf8"));
|
||||||
// or we could not determine the merge base.
|
payloadObj.base_ref = `refs/heads/${githubEvent.pull_request.base.ref}`;
|
||||||
// Using the PR base is the only option here
|
payloadObj.base_sha = githubEvent.pull_request.base.sha;
|
||||||
const githubEvent = JSON.parse(fs.readFileSync(process.env.GITHUB_EVENT_PATH, "utf8"));
|
|
||||||
payloadObj.base_ref = `refs/heads/${githubEvent.pull_request.base.ref}`;
|
|
||||||
payloadObj.base_sha = githubEvent.pull_request.base.sha;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return payloadObj;
|
return payloadObj;
|
||||||
@@ -235,7 +230,7 @@ function buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, wo
|
|||||||
exports.buildPayload = buildPayload;
|
exports.buildPayload = buildPayload;
|
||||||
// Uploads the given set of sarif files.
|
// Uploads the given set of sarif files.
|
||||||
// Returns true iff the upload occurred and succeeded
|
// Returns true iff the upload occurred and succeeded
|
||||||
async function uploadFiles(sarifFiles, repositoryNwo, commitOid, ref, analysisKey, category, analysisName, workflowRunID, sourceRoot, environment, gitHubVersion, logger) {
|
async function uploadFiles(sarifFiles, repositoryNwo, commitOid, ref, analysisKey, category, analysisName, workflowRunID, sourceRoot, environment, logger) {
|
||||||
logger.startGroup("Uploading results");
|
logger.startGroup("Uploading results");
|
||||||
logger.info(`Processing sarif files: ${JSON.stringify(sarifFiles)}`);
|
logger.info(`Processing sarif files: ${JSON.stringify(sarifFiles)}`);
|
||||||
// Validate that the files we were asked to upload are all valid SARIF files
|
// Validate that the files we were asked to upload are all valid SARIF files
|
||||||
@@ -252,7 +247,7 @@ async function uploadFiles(sarifFiles, repositoryNwo, commitOid, ref, analysisKe
|
|||||||
const sarifPayload = JSON.stringify(sarif);
|
const sarifPayload = JSON.stringify(sarif);
|
||||||
const zippedSarif = zlib_1.default.gzipSync(sarifPayload).toString("base64");
|
const zippedSarif = zlib_1.default.gzipSync(sarifPayload).toString("base64");
|
||||||
const checkoutURI = (0, file_url_1.default)(sourceRoot);
|
const checkoutURI = (0, file_url_1.default)(sourceRoot);
|
||||||
const payload = buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, workflowRunID, checkoutURI, environment, toolNames, gitHubVersion, await actionsUtil.determineMergeBaseCommitOid());
|
const payload = buildPayload(commitOid, ref, analysisKey, analysisName, zippedSarif, workflowRunID, checkoutURI, environment, toolNames, await actionsUtil.determineMergeBaseCommitOid());
|
||||||
// Log some useful debug info about the info
|
// Log some useful debug info about the info
|
||||||
const rawUploadSizeBytes = sarifPayload.length;
|
const rawUploadSizeBytes = sarifPayload.length;
|
||||||
logger.debug(`Raw upload size: ${rawUploadSizeBytes} bytes`);
|
logger.debug(`Raw upload size: ${rawUploadSizeBytes} bytes`);
|
||||||
@@ -274,48 +269,92 @@ async function uploadFiles(sarifFiles, repositoryNwo, commitOid, ref, analysisKe
|
|||||||
}
|
}
|
||||||
const STATUS_CHECK_FREQUENCY_MILLISECONDS = 5 * 1000;
|
const STATUS_CHECK_FREQUENCY_MILLISECONDS = 5 * 1000;
|
||||||
const STATUS_CHECK_TIMEOUT_MILLISECONDS = 2 * 60 * 1000;
|
const STATUS_CHECK_TIMEOUT_MILLISECONDS = 2 * 60 * 1000;
|
||||||
// Waits until either the analysis is successfully processed, a processing error is reported, or STATUS_CHECK_TIMEOUT_MILLISECONDS elapses.
|
/**
|
||||||
async function waitForProcessing(repositoryNwo, sarifID, logger) {
|
* Waits until either the analysis is successfully processed, a processing error
|
||||||
|
* is reported, or `STATUS_CHECK_TIMEOUT_MILLISECONDS` elapses.
|
||||||
|
*
|
||||||
|
* If `isUnsuccessfulExecution` is passed, will throw an error if the analysis
|
||||||
|
* processing does not produce a single error mentioning the unsuccessful
|
||||||
|
* execution.
|
||||||
|
*/
|
||||||
|
async function waitForProcessing(repositoryNwo, sarifID, logger, options = {
|
||||||
|
isUnsuccessfulExecution: false,
|
||||||
|
}) {
|
||||||
logger.startGroup("Waiting for processing to finish");
|
logger.startGroup("Waiting for processing to finish");
|
||||||
const client = api.getApiClient();
|
try {
|
||||||
const statusCheckingStarted = Date.now();
|
const client = api.getApiClient();
|
||||||
// eslint-disable-next-line no-constant-condition
|
const statusCheckingStarted = Date.now();
|
||||||
while (true) {
|
// eslint-disable-next-line no-constant-condition
|
||||||
if (Date.now() >
|
while (true) {
|
||||||
statusCheckingStarted + STATUS_CHECK_TIMEOUT_MILLISECONDS) {
|
if (Date.now() >
|
||||||
// If the analysis hasn't finished processing in the allotted time, we continue anyway rather than failing.
|
statusCheckingStarted + STATUS_CHECK_TIMEOUT_MILLISECONDS) {
|
||||||
// It's possible the analysis will eventually finish processing, but it's not worth spending more Actions time waiting.
|
// If the analysis hasn't finished processing in the allotted time, we continue anyway rather than failing.
|
||||||
logger.warning("Timed out waiting for analysis to finish processing. Continuing.");
|
// It's possible the analysis will eventually finish processing, but it's not worth spending more Actions time waiting.
|
||||||
break;
|
logger.warning("Timed out waiting for analysis to finish processing. Continuing.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let response = undefined;
|
||||||
|
try {
|
||||||
|
response = await client.request("GET /repos/:owner/:repo/code-scanning/sarifs/:sarif_id", {
|
||||||
|
owner: repositoryNwo.owner,
|
||||||
|
repo: repositoryNwo.repo,
|
||||||
|
sarif_id: sarifID,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
logger.warning(`An error occurred checking the status of the delivery. ${e} It should still be processed in the background, but errors that occur during processing may not be reported.`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const status = response.data.processing_status;
|
||||||
|
logger.info(`Analysis upload status is ${status}.`);
|
||||||
|
if (status === "pending") {
|
||||||
|
logger.debug("Analysis processing is still pending...");
|
||||||
|
}
|
||||||
|
else if (options.isUnsuccessfulExecution) {
|
||||||
|
// We expect a specific processing error for unsuccessful executions, so
|
||||||
|
// handle these separately.
|
||||||
|
handleProcessingResultForUnsuccessfulExecution(response, status, logger);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (status === "complete") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (status === "failed") {
|
||||||
|
throw new Error(`Code Scanning could not process the submitted SARIF file:\n${response.data.errors}`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
util.assertNever(status);
|
||||||
|
}
|
||||||
|
await util.delay(STATUS_CHECK_FREQUENCY_MILLISECONDS);
|
||||||
}
|
}
|
||||||
let response = undefined;
|
|
||||||
try {
|
|
||||||
response = await client.request("GET /repos/:owner/:repo/code-scanning/sarifs/:sarif_id", {
|
|
||||||
owner: repositoryNwo.owner,
|
|
||||||
repo: repositoryNwo.repo,
|
|
||||||
sarif_id: sarifID,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
logger.warning(`An error occurred checking the status of the delivery. ${e} It should still be processed in the background, but errors that occur during processing may not be reported.`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const status = response.data.processing_status;
|
|
||||||
logger.info(`Analysis upload status is ${status}.`);
|
|
||||||
if (status === "complete") {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (status === "pending") {
|
|
||||||
logger.debug("Analysis processing is still pending...");
|
|
||||||
}
|
|
||||||
else if (status === "failed") {
|
|
||||||
throw new Error(`Code Scanning could not process the submitted SARIF file:\n${response.data.errors}`);
|
|
||||||
}
|
|
||||||
await util.delay(STATUS_CHECK_FREQUENCY_MILLISECONDS);
|
|
||||||
}
|
}
|
||||||
logger.endGroup();
|
finally {
|
||||||
|
logger.endGroup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exports.waitForProcessing = waitForProcessing;
|
exports.waitForProcessing = waitForProcessing;
|
||||||
|
/**
|
||||||
|
* Checks the processing result for an unsuccessful execution. Throws if the
|
||||||
|
* result is not a failure with a single "unsuccessful execution" error.
|
||||||
|
*/
|
||||||
|
function handleProcessingResultForUnsuccessfulExecution(response, status, logger) {
|
||||||
|
if (status === "failed" &&
|
||||||
|
Array.isArray(response.data.errors) &&
|
||||||
|
response.data.errors.length === 1 &&
|
||||||
|
response.data.errors[0].toString().startsWith("unsuccessful execution")) {
|
||||||
|
logger.debug("Successfully uploaded a SARIF file for the unsuccessful execution. Received expected " +
|
||||||
|
'"unsuccessful execution" error, and no other errors.');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const shortMessage = "Failed to upload a SARIF file for the unsuccessful execution. Code scanning status " +
|
||||||
|
"information for the repository may be out of date as a result.";
|
||||||
|
const longMessage = shortMessage + status === "failed"
|
||||||
|
? ` Processing errors: ${response.data.errors}`
|
||||||
|
: ' Encountered no processing errors, but expected to receive an "unsuccessful execution" error.';
|
||||||
|
logger.debug(longMessage);
|
||||||
|
throw new Error(shortMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
function validateUniqueCategory(sarif) {
|
function validateUniqueCategory(sarif) {
|
||||||
var _a, _b, _c;
|
var _a, _b, _c;
|
||||||
// duplicate categories are allowed in the same sarif file
|
// duplicate categories are allowed in the same sarif file
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Generated
+13
-34
@@ -42,45 +42,24 @@ ava_1.default.beforeEach(() => {
|
|||||||
const inputFile = `${__dirname}/../src/testdata/invalid-sarif.sarif`;
|
const inputFile = `${__dirname}/../src/testdata/invalid-sarif.sarif`;
|
||||||
t.throws(() => uploadLib.validateSarifFileSchema(inputFile, (0, logging_1.getRunnerLogger)(true)));
|
t.throws(() => uploadLib.validateSarifFileSchema(inputFile, (0, logging_1.getRunnerLogger)(true)));
|
||||||
});
|
});
|
||||||
(0, ava_1.default)("validate correct payload used per version", async (t) => {
|
(0, ava_1.default)("validate correct payload used for push, PR merge commit, and PR head", async (t) => {
|
||||||
const newVersions = [
|
|
||||||
{ type: util_1.GitHubVariant.DOTCOM },
|
|
||||||
{ type: util_1.GitHubVariant.GHES, version: "3.1.0" },
|
|
||||||
];
|
|
||||||
const oldVersions = [
|
|
||||||
{ type: util_1.GitHubVariant.GHES, version: "2.22.1" },
|
|
||||||
{ type: util_1.GitHubVariant.GHES, version: "3.0.0" },
|
|
||||||
];
|
|
||||||
const allVersions = newVersions.concat(oldVersions);
|
|
||||||
process.env["GITHUB_EVENT_NAME"] = "push";
|
process.env["GITHUB_EVENT_NAME"] = "push";
|
||||||
for (const version of allVersions) {
|
const pushPayload = uploadLib.buildPayload("commit", "refs/heads/master", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], "mergeBaseCommit");
|
||||||
const payload = uploadLib.buildPayload("commit", "refs/heads/master", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], version, "mergeBaseCommit");
|
// Not triggered by a pull request
|
||||||
// Not triggered by a pull request
|
t.falsy(pushPayload.base_ref);
|
||||||
t.falsy(payload.base_ref);
|
t.falsy(pushPayload.base_sha);
|
||||||
t.falsy(payload.base_sha);
|
|
||||||
}
|
|
||||||
process.env["GITHUB_EVENT_NAME"] = "pull_request";
|
process.env["GITHUB_EVENT_NAME"] = "pull_request";
|
||||||
process.env["GITHUB_SHA"] = "commit";
|
process.env["GITHUB_SHA"] = "commit";
|
||||||
process.env["GITHUB_BASE_REF"] = "master";
|
process.env["GITHUB_BASE_REF"] = "master";
|
||||||
process.env["GITHUB_EVENT_PATH"] = `${__dirname}/../src/testdata/pull_request.json`;
|
process.env["GITHUB_EVENT_PATH"] = `${__dirname}/../src/testdata/pull_request.json`;
|
||||||
for (const version of newVersions) {
|
const prMergePayload = uploadLib.buildPayload("commit", "refs/pull/123/merge", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], "mergeBaseCommit");
|
||||||
const payload = uploadLib.buildPayload("commit", "refs/pull/123/merge", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], version, "mergeBaseCommit");
|
// Uploads for a merge commit use the merge base
|
||||||
// Uploads for a merge commit use the merge base
|
t.deepEqual(prMergePayload.base_ref, "refs/heads/master");
|
||||||
t.deepEqual(payload.base_ref, "refs/heads/master");
|
t.deepEqual(prMergePayload.base_sha, "mergeBaseCommit");
|
||||||
t.deepEqual(payload.base_sha, "mergeBaseCommit");
|
const prHeadPayload = uploadLib.buildPayload("headCommit", "refs/pull/123/head", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], "mergeBaseCommit");
|
||||||
}
|
// Uploads for the head use the PR base
|
||||||
for (const version of newVersions) {
|
t.deepEqual(prHeadPayload.base_ref, "refs/heads/master");
|
||||||
const payload = uploadLib.buildPayload("headCommit", "refs/pull/123/head", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], version, "mergeBaseCommit");
|
t.deepEqual(prHeadPayload.base_sha, "f95f852bd8fca8fcc58a9a2d6c842781e32a215e");
|
||||||
// Uploads for the head use the PR base
|
|
||||||
t.deepEqual(payload.base_ref, "refs/heads/master");
|
|
||||||
t.deepEqual(payload.base_sha, "f95f852bd8fca8fcc58a9a2d6c842781e32a215e");
|
|
||||||
}
|
|
||||||
for (const version of oldVersions) {
|
|
||||||
const payload = uploadLib.buildPayload("commit", "refs/pull/123/merge", "key", undefined, "", undefined, "/opt/src", undefined, ["CodeQL", "eslint"], version, "mergeBaseCommit");
|
|
||||||
// These older versions won't expect these values
|
|
||||||
t.falsy(payload.base_ref);
|
|
||||||
t.falsy(payload.base_sha);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
(0, ava_1.default)("finding SARIF files", async (t) => {
|
(0, ava_1.default)("finding SARIF files", async (t) => {
|
||||||
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
await (0, util_1.withTmpDir)(async (tmpDir) => {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Generated
+1
-3
@@ -21,7 +21,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
const core = __importStar(require("@actions/core"));
|
const core = __importStar(require("@actions/core"));
|
||||||
const actionsUtil = __importStar(require("./actions-util"));
|
const actionsUtil = __importStar(require("./actions-util"));
|
||||||
const api_client_1 = require("./api-client");
|
|
||||||
const logging_1 = require("./logging");
|
const logging_1 = require("./logging");
|
||||||
const repository_1 = require("./repository");
|
const repository_1 = require("./repository");
|
||||||
const upload_lib = __importStar(require("./upload-lib"));
|
const upload_lib = __importStar(require("./upload-lib"));
|
||||||
@@ -44,8 +43,7 @@ async function run() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const gitHubVersion = await (0, api_client_1.getGitHubVersion)();
|
const uploadResult = await upload_lib.uploadFromActions(actionsUtil.getRequiredInput("sarif_file"), actionsUtil.getRequiredInput("checkout_path"), actionsUtil.getOptionalInput("category"), (0, logging_1.getActionsLogger)());
|
||||||
const uploadResult = await upload_lib.uploadFromActions(actionsUtil.getRequiredInput("sarif_file"), gitHubVersion, (0, logging_1.getActionsLogger)());
|
|
||||||
core.setOutput("sarif-id", uploadResult.sarifID);
|
core.setOutput("sarif-id", uploadResult.sarifID);
|
||||||
// We don't upload results in test mode, so don't wait for processing
|
// We don't upload results in test mode, so don't wait for processing
|
||||||
if ((0, util_1.isInTestMode)()) {
|
if ((0, util_1.isInTestMode)()) {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"upload-sarif-action.js","sourceRoot":"","sources":["../src/upload-sarif-action.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"upload-sarif-action.js","sourceRoot":"","sources":["../src/upload-sarif-action.ts"],"names":[],"mappings":"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"}
|
||||||
Generated
+49
-2
@@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.isHostedRunner = exports.checkForTimeout = exports.withTimeout = exports.tryGetFolderBytes = exports.listFolder = exports.doesDirectoryExist = exports.logCodeScanningConfigInCli = exports.useCodeScanningConfigInCli = exports.isInTestMode = exports.checkActionVersion = exports.getMlPoweredJsQueriesStatus = exports.getMlPoweredJsQueriesPack = exports.ML_POWERED_JS_QUERIES_PACK_NAME = exports.isGoodVersion = exports.delay = exports.bundleDb = exports.codeQlVersionAbove = exports.getCachedCodeQlVersion = exports.cacheCodeQlVersion = exports.isHTTPError = exports.UserError = exports.HTTPError = exports.getRequiredEnvParam = exports.enrichEnvironment = exports.initializeEnvironment = exports.EnvVar = exports.assertNever = exports.apiVersionInRange = exports.DisallowedAPIVersionReason = exports.checkGitHubVersionInRange = exports.getGitHubVersion = exports.GitHubVariant = exports.parseGitHubUrl = exports.getCodeQLDatabasePath = exports.getThreadsFlag = exports.getThreadsFlagValue = exports.getAddSnippetsFlag = exports.getMemoryFlag = exports.getMemoryFlagValue = exports.withTmpDir = exports.getToolNames = exports.getExtraOptionsEnvParam = exports.DID_AUTOBUILD_GO_ENV_VAR_NAME = exports.DEFAULT_DEBUG_DATABASE_NAME = exports.DEFAULT_DEBUG_ARTIFACT_NAME = exports.GITHUB_DOTCOM_URL = void 0;
|
exports.parseMatrixInput = exports.shouldBypassToolcache = exports.isHostedRunner = exports.checkForTimeout = exports.withTimeout = exports.tryGetFolderBytes = exports.listFolder = exports.doesDirectoryExist = exports.logCodeScanningConfigInCli = exports.useCodeScanningConfigInCli = exports.isInTestMode = exports.checkActionVersion = exports.getMlPoweredJsQueriesStatus = exports.getMlPoweredJsQueriesPack = exports.ML_POWERED_JS_QUERIES_PACK_NAME = exports.isGoodVersion = exports.delay = exports.bundleDb = exports.codeQlVersionAbove = exports.getCachedCodeQlVersion = exports.cacheCodeQlVersion = exports.isHTTPError = exports.UserError = exports.HTTPError = exports.getRequiredEnvParam = exports.enrichEnvironment = exports.initializeEnvironment = exports.EnvVar = exports.assertNever = exports.apiVersionInRange = exports.DisallowedAPIVersionReason = exports.checkGitHubVersionInRange = exports.getGitHubVersion = exports.GitHubVariant = exports.parseGitHubUrl = exports.getCodeQLDatabasePath = exports.getThreadsFlag = exports.getThreadsFlagValue = exports.getAddSnippetsFlag = exports.getMemoryFlag = exports.getMemoryFlagValue = exports.withTmpDir = exports.getToolNames = exports.getExtraOptionsEnvParam = exports.DID_AUTOBUILD_GO_ENV_VAR_NAME = exports.DEFAULT_DEBUG_DATABASE_NAME = exports.DEFAULT_DEBUG_ARTIFACT_NAME = exports.GITHUB_DOTCOM_URL = void 0;
|
||||||
const fs = __importStar(require("fs"));
|
const fs = __importStar(require("fs"));
|
||||||
const os = __importStar(require("os"));
|
const os = __importStar(require("os"));
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
@@ -37,6 +37,7 @@ const apiCompatibility = __importStar(require("./api-compatibility.json"));
|
|||||||
const codeql_1 = require("./codeql");
|
const codeql_1 = require("./codeql");
|
||||||
const config_utils_1 = require("./config-utils");
|
const config_utils_1 = require("./config-utils");
|
||||||
const feature_flags_1 = require("./feature-flags");
|
const feature_flags_1 = require("./feature-flags");
|
||||||
|
const languages_1 = require("./languages");
|
||||||
const shared_environment_1 = require("./shared-environment");
|
const shared_environment_1 = require("./shared-environment");
|
||||||
/**
|
/**
|
||||||
* Specifies bundle versions that are known to be broken
|
* Specifies bundle versions that are known to be broken
|
||||||
@@ -545,7 +546,7 @@ async function checkActionVersion(version) {
|
|||||||
githubVersion.type === GitHubVariant.GHAE ||
|
githubVersion.type === GitHubVariant.GHAE ||
|
||||||
(githubVersion.type === GitHubVariant.GHES &&
|
(githubVersion.type === GitHubVariant.GHES &&
|
||||||
semver.satisfies((_a = semver.coerce(githubVersion.version)) !== null && _a !== void 0 ? _a : "0.0.0", ">=3.4"))) {
|
semver.satisfies((_a = semver.coerce(githubVersion.version)) !== null && _a !== void 0 ? _a : "0.0.0", ">=3.4"))) {
|
||||||
core.warning("CodeQL Action v1 will be deprecated on December 7th, 2022. Please upgrade to v2. For " +
|
core.warning("CodeQL Action v1 will be deprecated on January 18th, 2023. Please upgrade to v2. For " +
|
||||||
"more information, see " +
|
"more information, see " +
|
||||||
"https://github.blog/changelog/2022-04-27-code-scanning-deprecation-of-codeql-action-v1/");
|
"https://github.blog/changelog/2022-04-27-code-scanning-deprecation-of-codeql-action-v1/");
|
||||||
}
|
}
|
||||||
@@ -710,4 +711,50 @@ function isHostedRunner() {
|
|||||||
(_c = process.env["RUNNER_TOOL_CACHE"]) === null || _c === void 0 ? void 0 : _c.includes("hostedtoolcache")));
|
(_c = process.env["RUNNER_TOOL_CACHE"]) === null || _c === void 0 ? void 0 : _c.includes("hostedtoolcache")));
|
||||||
}
|
}
|
||||||
exports.isHostedRunner = isHostedRunner;
|
exports.isHostedRunner = isHostedRunner;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param featuresEnablement The features enabled for the current run
|
||||||
|
* @param languagesInput Languages input from the workflow
|
||||||
|
* @param repository The owner/name of the repository
|
||||||
|
* @param logger A logger
|
||||||
|
* @returns A boolean indicating whether or not the toolcache should be bypassed and the latest codeql should be downloaded.
|
||||||
|
*/
|
||||||
|
async function shouldBypassToolcache(featuresEnablement, codeqlUrl, languagesInput, repository, logger) {
|
||||||
|
// An explicit codeql url is specified, that means the toolcache will not be used.
|
||||||
|
if (codeqlUrl) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Check if the toolcache is disabled for all languages
|
||||||
|
if (await featuresEnablement.getValue(feature_flags_1.Feature.BypassToolcacheEnabled)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Check if the toolcache is disabled for kotlin and swift.
|
||||||
|
if (!(await featuresEnablement.getValue(feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Now check to see if kotlin or swift is one of the languages being analyzed.
|
||||||
|
const { rawLanguages, autodetected } = await (0, config_utils_1.getRawLanguages)(languagesInput, repository, logger);
|
||||||
|
let bypass = rawLanguages.some((lang) => languages_1.KOTLIN_SWIFT_BYPASS.includes(lang));
|
||||||
|
if (bypass) {
|
||||||
|
logger.info(`Bypassing toolcache for kotlin or swift. Languages: ${rawLanguages}`);
|
||||||
|
}
|
||||||
|
else if (!autodetected && rawLanguages.includes(languages_1.Language.java)) {
|
||||||
|
// special case: java was explicitly specified, but there might be
|
||||||
|
// some kotlin in the repository, so we need to make a request for that.
|
||||||
|
const langsInRepo = await (0, config_utils_1.getLanguagesInRepo)(repository, logger);
|
||||||
|
if (langsInRepo.includes("kotlin")) {
|
||||||
|
logger.info(`Bypassing toolcache for kotlin.`);
|
||||||
|
bypass = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bypass;
|
||||||
|
}
|
||||||
|
exports.shouldBypassToolcache = shouldBypassToolcache;
|
||||||
|
function parseMatrixInput(matrixInput) {
|
||||||
|
if (matrixInput === undefined || matrixInput === "null") {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return JSON.parse(matrixInput);
|
||||||
|
}
|
||||||
|
exports.parseMatrixInput = parseMatrixInput;
|
||||||
//# sourceMappingURL=util.js.map
|
//# sourceMappingURL=util.js.map
|
||||||
+1
-1
File diff suppressed because one or more lines are too long
Generated
+115
@@ -30,7 +30,9 @@ const github = __importStar(require("@actions/github"));
|
|||||||
const ava_1 = __importDefault(require("ava"));
|
const ava_1 = __importDefault(require("ava"));
|
||||||
const sinon = __importStar(require("sinon"));
|
const sinon = __importStar(require("sinon"));
|
||||||
const api = __importStar(require("./api-client"));
|
const api = __importStar(require("./api-client"));
|
||||||
|
const feature_flags_1 = require("./feature-flags");
|
||||||
const logging_1 = require("./logging");
|
const logging_1 = require("./logging");
|
||||||
|
const repository_1 = require("./repository");
|
||||||
const testing_utils_1 = require("./testing-utils");
|
const testing_utils_1 = require("./testing-utils");
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
(0, testing_utils_1.setupTests)(ava_1.default);
|
(0, testing_utils_1.setupTests)(ava_1.default);
|
||||||
@@ -363,4 +365,117 @@ const shortTime = 10;
|
|||||||
t.deepEqual(shortTaskTimedOut, false);
|
t.deepEqual(shortTaskTimedOut, false);
|
||||||
t.deepEqual(result, 99);
|
t.deepEqual(result, 99);
|
||||||
});
|
});
|
||||||
|
const mockRepositoryNwo = (0, repository_1.parseRepositoryNwo)("owner/repo");
|
||||||
|
// eslint-disable-next-line github/array-foreach
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name: "disabled",
|
||||||
|
features: [],
|
||||||
|
hasCustomCodeQL: false,
|
||||||
|
languagesInput: undefined,
|
||||||
|
languagesInRepository: [],
|
||||||
|
expected: false,
|
||||||
|
expectedApiCall: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "disabled even though swift kotlin bypassed",
|
||||||
|
features: [feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled],
|
||||||
|
hasCustomCodeQL: false,
|
||||||
|
languagesInput: undefined,
|
||||||
|
languagesInRepository: [],
|
||||||
|
expected: false,
|
||||||
|
expectedApiCall: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "disabled even though swift kotlin analyzed",
|
||||||
|
features: [],
|
||||||
|
hasCustomCodeQL: false,
|
||||||
|
languagesInput: " sWiFt , KoTlIn ",
|
||||||
|
languagesInRepository: [],
|
||||||
|
expected: false,
|
||||||
|
expectedApiCall: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "toolcache bypass all",
|
||||||
|
features: [feature_flags_1.Feature.BypassToolcacheEnabled],
|
||||||
|
hasCustomCodeQL: false,
|
||||||
|
languagesInput: undefined,
|
||||||
|
languagesInRepository: [],
|
||||||
|
expected: true,
|
||||||
|
expectedApiCall: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "custom CodeQL",
|
||||||
|
features: [],
|
||||||
|
hasCustomCodeQL: true,
|
||||||
|
languagesInput: undefined,
|
||||||
|
languagesInRepository: [],
|
||||||
|
expected: true,
|
||||||
|
expectedApiCall: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bypass swift",
|
||||||
|
features: [feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled],
|
||||||
|
hasCustomCodeQL: false,
|
||||||
|
languagesInput: " sWiFt ,other",
|
||||||
|
languagesInRepository: [],
|
||||||
|
expected: true,
|
||||||
|
expectedApiCall: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bypass kotlin",
|
||||||
|
features: [feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled],
|
||||||
|
hasCustomCodeQL: false,
|
||||||
|
languagesInput: "other, KoTlIn ",
|
||||||
|
languagesInRepository: [],
|
||||||
|
expected: true,
|
||||||
|
expectedApiCall: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bypass kotlin language from repository",
|
||||||
|
features: [feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled],
|
||||||
|
hasCustomCodeQL: false,
|
||||||
|
languagesInput: "",
|
||||||
|
languagesInRepository: ["KoTlIn", "other"],
|
||||||
|
expected: true,
|
||||||
|
expectedApiCall: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bypass swift language from repository",
|
||||||
|
features: [feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled],
|
||||||
|
hasCustomCodeQL: false,
|
||||||
|
languagesInput: "",
|
||||||
|
languagesInRepository: ["SwiFt", "other"],
|
||||||
|
expected: true,
|
||||||
|
expectedApiCall: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bypass java from input if there is kotlin in repository",
|
||||||
|
features: [feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled],
|
||||||
|
hasCustomCodeQL: false,
|
||||||
|
languagesInput: "java",
|
||||||
|
languagesInRepository: ["kotlin", "other"],
|
||||||
|
expected: true,
|
||||||
|
expectedApiCall: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "don't bypass java from input if there is no kotlin in repository",
|
||||||
|
features: [feature_flags_1.Feature.BypassToolcacheKotlinSwiftEnabled],
|
||||||
|
hasCustomCodeQL: false,
|
||||||
|
languagesInput: "java",
|
||||||
|
languagesInRepository: ["java", "other"],
|
||||||
|
expected: false,
|
||||||
|
expectedApiCall: true,
|
||||||
|
},
|
||||||
|
].forEach((args) => {
|
||||||
|
(0, ava_1.default)(`shouldBypassToolcache: ${args.name}`, async (t) => {
|
||||||
|
const mockRequest = (0, testing_utils_1.mockLanguagesInRepo)(args.languagesInRepository);
|
||||||
|
const mockLogger = (0, logging_1.getRunnerLogger)(true);
|
||||||
|
const featureEnablement = (0, testing_utils_1.createFeatures)(args.features);
|
||||||
|
const codeqlUrl = args.hasCustomCodeQL ? "custom-codeql-url" : undefined;
|
||||||
|
const actual = await util.shouldBypassToolcache(featureEnablement, codeqlUrl, args.languagesInput, mockRepositoryNwo, mockLogger);
|
||||||
|
t.deepEqual(actual, args.expected);
|
||||||
|
t.deepEqual(mockRequest.called, args.expectedApiCall);
|
||||||
|
});
|
||||||
|
});
|
||||||
//# sourceMappingURL=util.test.js.map
|
//# sourceMappingURL=util.test.js.map
|
||||||
File diff suppressed because one or more lines are too long
Generated
+362
@@ -0,0 +1,362 @@
|
|||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.getCheckoutPathInputOrThrow = exports.getUploadInputOrThrow = exports.getCategoryInputOrThrow = exports.getWorkflowRunID = exports.getWorkflowPath = exports.getWorkflow = exports.formatWorkflowCause = exports.formatWorkflowErrors = exports.validateWorkflow = exports.getWorkflowErrors = exports.WorkflowErrors = exports.patternIsSuperset = void 0;
|
||||||
|
const fs = __importStar(require("fs"));
|
||||||
|
const path = __importStar(require("path"));
|
||||||
|
const core = __importStar(require("@actions/core"));
|
||||||
|
const yaml = __importStar(require("js-yaml"));
|
||||||
|
const api = __importStar(require("./api-client"));
|
||||||
|
const util_1 = require("./util");
|
||||||
|
function isObject(o) {
|
||||||
|
return o !== null && typeof o === "object";
|
||||||
|
}
|
||||||
|
const GLOB_PATTERN = new RegExp("(\\*\\*?)");
|
||||||
|
function escapeRegExp(string) {
|
||||||
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
||||||
|
}
|
||||||
|
function patternToRegExp(value) {
|
||||||
|
return new RegExp(`^${value
|
||||||
|
.toString()
|
||||||
|
.split(GLOB_PATTERN)
|
||||||
|
.reduce(function (arr, cur) {
|
||||||
|
if (cur === "**") {
|
||||||
|
arr.push(".*?");
|
||||||
|
}
|
||||||
|
else if (cur === "*") {
|
||||||
|
arr.push("[^/]*?");
|
||||||
|
}
|
||||||
|
else if (cur) {
|
||||||
|
arr.push(escapeRegExp(cur));
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}, [])
|
||||||
|
.join("")}$`);
|
||||||
|
}
|
||||||
|
// this function should return true if patternA is a superset of patternB
|
||||||
|
// e.g: * is a superset of main-* but main-* is not a superset of *.
|
||||||
|
function patternIsSuperset(patternA, patternB) {
|
||||||
|
return patternToRegExp(patternA).test(patternB);
|
||||||
|
}
|
||||||
|
exports.patternIsSuperset = patternIsSuperset;
|
||||||
|
function branchesToArray(branches) {
|
||||||
|
if (typeof branches === "string") {
|
||||||
|
return [branches];
|
||||||
|
}
|
||||||
|
if (Array.isArray(branches)) {
|
||||||
|
if (branches.length === 0) {
|
||||||
|
return "**";
|
||||||
|
}
|
||||||
|
return branches;
|
||||||
|
}
|
||||||
|
return "**";
|
||||||
|
}
|
||||||
|
function toCodedErrors(errors) {
|
||||||
|
return Object.entries(errors).reduce((acc, [code, message]) => {
|
||||||
|
acc[code] = { message, code };
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
// code to send back via status report
|
||||||
|
// message to add as a warning annotation to the run
|
||||||
|
exports.WorkflowErrors = toCodedErrors({
|
||||||
|
MismatchedBranches: `Please make sure that every branch in on.pull_request is also in on.push so that Code Scanning can compare pull requests against the state of the base branch.`,
|
||||||
|
MissingPushHook: `Please specify an on.push hook so that Code Scanning can compare pull requests against the state of the base branch.`,
|
||||||
|
PathsSpecified: `Using on.push.paths can prevent Code Scanning annotating new alerts in your pull requests.`,
|
||||||
|
PathsIgnoreSpecified: `Using on.push.paths-ignore can prevent Code Scanning annotating new alerts in your pull requests.`,
|
||||||
|
CheckoutWrongHead: `git checkout HEAD^2 is no longer necessary. Please remove this step as Code Scanning recommends analyzing the merge commit for best results.`,
|
||||||
|
});
|
||||||
|
function getWorkflowErrors(doc) {
|
||||||
|
var _a, _b, _c, _d, _e;
|
||||||
|
const errors = [];
|
||||||
|
const jobName = process.env.GITHUB_JOB;
|
||||||
|
if (jobName) {
|
||||||
|
const job = (_a = doc === null || doc === void 0 ? void 0 : doc.jobs) === null || _a === void 0 ? void 0 : _a[jobName];
|
||||||
|
const steps = job === null || job === void 0 ? void 0 : job.steps;
|
||||||
|
if (Array.isArray(steps)) {
|
||||||
|
for (const step of steps) {
|
||||||
|
// this was advice that we used to give in the README
|
||||||
|
// we actually want to run the analysis on the merge commit
|
||||||
|
// to produce results that are more inline with expectations
|
||||||
|
// (i.e: this is what will happen if you merge this PR)
|
||||||
|
// and avoid some race conditions
|
||||||
|
if ((step === null || step === void 0 ? void 0 : step.run) === "git checkout HEAD^2") {
|
||||||
|
errors.push(exports.WorkflowErrors.CheckoutWrongHead);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let missingPush = false;
|
||||||
|
if (doc.on === undefined) {
|
||||||
|
// this is not a valid config
|
||||||
|
}
|
||||||
|
else if (typeof doc.on === "string") {
|
||||||
|
if (doc.on === "pull_request") {
|
||||||
|
missingPush = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Array.isArray(doc.on)) {
|
||||||
|
const hasPush = doc.on.includes("push");
|
||||||
|
const hasPullRequest = doc.on.includes("pull_request");
|
||||||
|
if (hasPullRequest && !hasPush) {
|
||||||
|
missingPush = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (isObject(doc.on)) {
|
||||||
|
const hasPush = Object.prototype.hasOwnProperty.call(doc.on, "push");
|
||||||
|
const hasPullRequest = Object.prototype.hasOwnProperty.call(doc.on, "pull_request");
|
||||||
|
if (!hasPush && hasPullRequest) {
|
||||||
|
missingPush = true;
|
||||||
|
}
|
||||||
|
if (hasPush && hasPullRequest) {
|
||||||
|
const paths = (_b = doc.on.push) === null || _b === void 0 ? void 0 : _b.paths;
|
||||||
|
// if you specify paths or paths-ignore you can end up with commits that have no baseline
|
||||||
|
// if they didn't change any files
|
||||||
|
// currently we cannot go back through the history and find the most recent baseline
|
||||||
|
if (Array.isArray(paths) && paths.length > 0) {
|
||||||
|
errors.push(exports.WorkflowErrors.PathsSpecified);
|
||||||
|
}
|
||||||
|
const pathsIgnore = (_c = doc.on.push) === null || _c === void 0 ? void 0 : _c["paths-ignore"];
|
||||||
|
if (Array.isArray(pathsIgnore) && pathsIgnore.length > 0) {
|
||||||
|
errors.push(exports.WorkflowErrors.PathsIgnoreSpecified);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if doc.on.pull_request is null that means 'all branches'
|
||||||
|
// if doc.on.pull_request is undefined that means 'off'
|
||||||
|
// we only want to check for mismatched branches if pull_request is on.
|
||||||
|
if (doc.on.pull_request !== undefined) {
|
||||||
|
const push = branchesToArray((_d = doc.on.push) === null || _d === void 0 ? void 0 : _d.branches);
|
||||||
|
if (push !== "**") {
|
||||||
|
const pull_request = branchesToArray((_e = doc.on.pull_request) === null || _e === void 0 ? void 0 : _e.branches);
|
||||||
|
if (pull_request !== "**") {
|
||||||
|
const difference = pull_request.filter((value) => !push.some((o) => patternIsSuperset(o, value)));
|
||||||
|
if (difference.length > 0) {
|
||||||
|
// there are branches in pull_request that may not have a baseline
|
||||||
|
// because we are not building them on push
|
||||||
|
errors.push(exports.WorkflowErrors.MismatchedBranches);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (push.length > 0) {
|
||||||
|
// push is set up to run on a subset of branches
|
||||||
|
// and you could open a PR against a branch with no baseline
|
||||||
|
errors.push(exports.WorkflowErrors.MismatchedBranches);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (missingPush) {
|
||||||
|
errors.push(exports.WorkflowErrors.MissingPushHook);
|
||||||
|
}
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
exports.getWorkflowErrors = getWorkflowErrors;
|
||||||
|
async function validateWorkflow() {
|
||||||
|
let workflow;
|
||||||
|
try {
|
||||||
|
workflow = await getWorkflow();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return `error: getWorkflow() failed: ${String(e)}`;
|
||||||
|
}
|
||||||
|
let workflowErrors;
|
||||||
|
try {
|
||||||
|
workflowErrors = getWorkflowErrors(workflow);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return `error: getWorkflowErrors() failed: ${String(e)}`;
|
||||||
|
}
|
||||||
|
if (workflowErrors.length > 0) {
|
||||||
|
let message;
|
||||||
|
try {
|
||||||
|
message = formatWorkflowErrors(workflowErrors);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
return `error: formatWorkflowErrors() failed: ${String(e)}`;
|
||||||
|
}
|
||||||
|
core.warning(message);
|
||||||
|
}
|
||||||
|
return formatWorkflowCause(workflowErrors);
|
||||||
|
}
|
||||||
|
exports.validateWorkflow = validateWorkflow;
|
||||||
|
function formatWorkflowErrors(errors) {
|
||||||
|
const issuesWere = errors.length === 1 ? "issue was" : "issues were";
|
||||||
|
const errorsList = errors.map((e) => e.message).join(" ");
|
||||||
|
return `${errors.length} ${issuesWere} detected with this workflow: ${errorsList}`;
|
||||||
|
}
|
||||||
|
exports.formatWorkflowErrors = formatWorkflowErrors;
|
||||||
|
function formatWorkflowCause(errors) {
|
||||||
|
if (errors.length === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return errors.map((e) => e.code).join(",");
|
||||||
|
}
|
||||||
|
exports.formatWorkflowCause = formatWorkflowCause;
|
||||||
|
async function getWorkflow() {
|
||||||
|
const relativePath = await getWorkflowPath();
|
||||||
|
const absolutePath = path.join((0, util_1.getRequiredEnvParam)("GITHUB_WORKSPACE"), relativePath);
|
||||||
|
try {
|
||||||
|
return yaml.load(fs.readFileSync(absolutePath, "utf-8"));
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
if (e instanceof Error && e["code"] === "ENOENT") {
|
||||||
|
throw new Error(`Unable to load code scanning workflow from ${absolutePath}. This can happen if the currently ` +
|
||||||
|
"running workflow checks out a branch that doesn't contain the corresponding workflow file.");
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.getWorkflow = getWorkflow;
|
||||||
|
/**
|
||||||
|
* Get the path of the currently executing workflow.
|
||||||
|
*/
|
||||||
|
async function getWorkflowPath() {
|
||||||
|
const repo_nwo = (0, util_1.getRequiredEnvParam)("GITHUB_REPOSITORY").split("/");
|
||||||
|
const owner = repo_nwo[0];
|
||||||
|
const repo = repo_nwo[1];
|
||||||
|
const run_id = Number((0, util_1.getRequiredEnvParam)("GITHUB_RUN_ID"));
|
||||||
|
const apiClient = api.getApiClient();
|
||||||
|
const runsResponse = await apiClient.request("GET /repos/:owner/:repo/actions/runs/:run_id?exclude_pull_requests=true", {
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
run_id,
|
||||||
|
});
|
||||||
|
const workflowUrl = runsResponse.data.workflow_url;
|
||||||
|
const workflowResponse = await apiClient.request(`GET ${workflowUrl}`);
|
||||||
|
return workflowResponse.data.path;
|
||||||
|
}
|
||||||
|
exports.getWorkflowPath = getWorkflowPath;
|
||||||
|
/**
|
||||||
|
* Get the workflow run ID.
|
||||||
|
*/
|
||||||
|
function getWorkflowRunID() {
|
||||||
|
const workflowRunID = parseInt((0, util_1.getRequiredEnvParam)("GITHUB_RUN_ID"), 10);
|
||||||
|
if (Number.isNaN(workflowRunID)) {
|
||||||
|
throw new Error("GITHUB_RUN_ID must define a non NaN workflow run ID");
|
||||||
|
}
|
||||||
|
return workflowRunID;
|
||||||
|
}
|
||||||
|
exports.getWorkflowRunID = getWorkflowRunID;
|
||||||
|
function getStepsCallingAction(job, actionName) {
|
||||||
|
if (job.uses) {
|
||||||
|
throw new Error(`Could not get steps calling ${actionName} since the job calls a reusable workflow.`);
|
||||||
|
}
|
||||||
|
const steps = job.steps;
|
||||||
|
if (!Array.isArray(steps)) {
|
||||||
|
throw new Error(`Could not get steps calling ${actionName} since job.steps was not an array.`);
|
||||||
|
}
|
||||||
|
return steps.filter((step) => { var _a; return (_a = step.uses) === null || _a === void 0 ? void 0 : _a.includes(actionName); });
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Makes a best effort attempt to retrieve the value of a particular input with which
|
||||||
|
* an Action in the workflow would be invoked.
|
||||||
|
*
|
||||||
|
* Typically you'll want to wrap this function in a try/catch block and handle the error.
|
||||||
|
*
|
||||||
|
* @returns the value of the input, or undefined if no such input is passed to the Action
|
||||||
|
* @throws an error if the value of the input could not be determined, or we could not
|
||||||
|
* determine that no such input is passed to the Action.
|
||||||
|
*/
|
||||||
|
function getInputOrThrow(workflow, jobName, actionName, inputName, matrixVars) {
|
||||||
|
var _a, _b;
|
||||||
|
const preamble = `Could not get ${inputName} input to ${actionName} since`;
|
||||||
|
if (!workflow.jobs) {
|
||||||
|
throw new Error(`${preamble} the workflow has no jobs.`);
|
||||||
|
}
|
||||||
|
if (!workflow.jobs[jobName]) {
|
||||||
|
throw new Error(`${preamble} the workflow has no job named ${jobName}.`);
|
||||||
|
}
|
||||||
|
const stepsCallingAction = getStepsCallingAction(workflow.jobs[jobName], actionName);
|
||||||
|
if (stepsCallingAction.length === 0) {
|
||||||
|
throw new Error(`${preamble} the ${jobName} job does not call ${actionName}.`);
|
||||||
|
}
|
||||||
|
else if (stepsCallingAction.length > 1) {
|
||||||
|
throw new Error(`${preamble} the ${jobName} job calls ${actionName} multiple times.`);
|
||||||
|
}
|
||||||
|
let input = (_b = (_a = stepsCallingAction[0].with) === null || _a === void 0 ? void 0 : _a[inputName]) === null || _b === void 0 ? void 0 : _b.toString();
|
||||||
|
if (input !== undefined && matrixVars !== undefined) {
|
||||||
|
// Normalize by removing whitespace
|
||||||
|
input = input.replace(/\${{\s+/, "${{").replace(/\s+}}/, "}}");
|
||||||
|
// Make a basic attempt to substitute matrix variables
|
||||||
|
for (const [key, value] of Object.entries(matrixVars)) {
|
||||||
|
input = input.replace(`\${{matrix.${key}}}`, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (input !== undefined && input.includes("${{")) {
|
||||||
|
throw new Error(`Could not get ${inputName} input to ${actionName} since it contained an unrecognized dynamic value.`);
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get the expected name of the analyze Action.
|
||||||
|
*
|
||||||
|
* This allows us to test workflow parsing functionality as a CodeQL Action PR check.
|
||||||
|
*/
|
||||||
|
function getAnalyzeActionName() {
|
||||||
|
if ((0, util_1.getRequiredEnvParam)("GITHUB_REPOSITORY") === "github/codeql-action") {
|
||||||
|
return "./analyze";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "github/codeql-action/analyze";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Makes a best effort attempt to retrieve the category input for the particular job,
|
||||||
|
* given a set of matrix variables.
|
||||||
|
*
|
||||||
|
* Typically you'll want to wrap this function in a try/catch block and handle the error.
|
||||||
|
*
|
||||||
|
* @returns the category input, or undefined if the category input is not defined
|
||||||
|
* @throws an error if the category input could not be determined
|
||||||
|
*/
|
||||||
|
function getCategoryInputOrThrow(workflow, jobName, matrixVars) {
|
||||||
|
return getInputOrThrow(workflow, jobName, getAnalyzeActionName(), "category", matrixVars);
|
||||||
|
}
|
||||||
|
exports.getCategoryInputOrThrow = getCategoryInputOrThrow;
|
||||||
|
/**
|
||||||
|
* Makes a best effort attempt to retrieve the upload input for the particular job,
|
||||||
|
* given a set of matrix variables.
|
||||||
|
*
|
||||||
|
* Typically you'll want to wrap this function in a try/catch block and handle the error.
|
||||||
|
*
|
||||||
|
* @returns the upload input
|
||||||
|
* @throws an error if the upload input could not be determined
|
||||||
|
*/
|
||||||
|
function getUploadInputOrThrow(workflow, jobName, matrixVars) {
|
||||||
|
return (getInputOrThrow(workflow, jobName, getAnalyzeActionName(), "upload", matrixVars) || "true" // if unspecified, upload defaults to true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
exports.getUploadInputOrThrow = getUploadInputOrThrow;
|
||||||
|
/**
|
||||||
|
* Makes a best effort attempt to retrieve the checkout_path input for the
|
||||||
|
* particular job, given a set of matrix variables.
|
||||||
|
*
|
||||||
|
* Typically you'll want to wrap this function in a try/catch block and handle the error.
|
||||||
|
*
|
||||||
|
* @returns the checkout_path input
|
||||||
|
* @throws an error if the checkout_path input could not be determined
|
||||||
|
*/
|
||||||
|
function getCheckoutPathInputOrThrow(workflow, jobName, matrixVars) {
|
||||||
|
return (getInputOrThrow(workflow, jobName, getAnalyzeActionName(), "checkout_path", matrixVars) || (0, util_1.getRequiredEnvParam)("GITHUB_WORKSPACE") // if unspecified, checkout_path defaults to ${{ github.workspace }}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
exports.getCheckoutPathInputOrThrow = getCheckoutPathInputOrThrow;
|
||||||
|
//# sourceMappingURL=workflow.js.map
|
||||||
File diff suppressed because one or more lines are too long
Generated
+463
@@ -0,0 +1,463 @@
|
|||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const ava_1 = __importDefault(require("ava"));
|
||||||
|
const yaml = __importStar(require("js-yaml"));
|
||||||
|
const testing_utils_1 = require("./testing-utils");
|
||||||
|
const workflow_1 = require("./workflow");
|
||||||
|
function errorCodes(actual, expected) {
|
||||||
|
return [actual.map(({ code }) => code), expected.map(({ code }) => code)];
|
||||||
|
}
|
||||||
|
(0, testing_utils_1.setupTests)(ava_1.default);
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on is empty", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({ on: {} });
|
||||||
|
t.deepEqual(...errorCodes(errors, []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.push is an array missing pull_request", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({ on: ["push"] });
|
||||||
|
t.deepEqual(...errorCodes(errors, []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.push is an array missing push", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({ on: ["pull_request"] });
|
||||||
|
t.deepEqual(...errorCodes(errors, [workflow_1.WorkflowErrors.MissingPushHook]));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.push is valid", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: ["push", "pull_request"],
|
||||||
|
});
|
||||||
|
t.deepEqual(...errorCodes(errors, []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.push is a valid superset", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: ["push", "pull_request", "schedule"],
|
||||||
|
});
|
||||||
|
t.deepEqual(...errorCodes(errors, []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.push should not have a path", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: {
|
||||||
|
push: { branches: ["main"], paths: ["test/*"] },
|
||||||
|
pull_request: { branches: ["main"] },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
t.deepEqual(...errorCodes(errors, [workflow_1.WorkflowErrors.PathsSpecified]));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.push is a correct object", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: { push: { branches: ["main"] }, pull_request: { branches: ["main"] } },
|
||||||
|
});
|
||||||
|
t.deepEqual(...errorCodes(errors, []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.pull_requests is a string", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: { push: { branches: ["main"] }, pull_request: { branches: "*" } },
|
||||||
|
});
|
||||||
|
t.deepEqual(...errorCodes(errors, [workflow_1.WorkflowErrors.MismatchedBranches]));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.pull_requests is a string and correct", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: { push: { branches: "*" }, pull_request: { branches: "*" } },
|
||||||
|
});
|
||||||
|
t.deepEqual(...errorCodes(errors, []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.push is correct with empty objects", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)(yaml.load(`
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
`));
|
||||||
|
t.deepEqual(...errorCodes(errors, []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.push is mismatched", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: {
|
||||||
|
push: { branches: ["main"] },
|
||||||
|
pull_request: { branches: ["feature"] },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
t.deepEqual(...errorCodes(errors, [workflow_1.WorkflowErrors.MismatchedBranches]));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.push is not mismatched", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: {
|
||||||
|
push: { branches: ["main", "feature"] },
|
||||||
|
pull_request: { branches: ["main"] },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
t.deepEqual(...errorCodes(errors, []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.push is mismatched for pull_request", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: {
|
||||||
|
push: { branches: ["main"] },
|
||||||
|
pull_request: { branches: ["main", "feature"] },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
t.deepEqual(...errorCodes(errors, [workflow_1.WorkflowErrors.MismatchedBranches]));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() for a range of malformed workflows", (t) => {
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: {
|
||||||
|
push: 1,
|
||||||
|
pull_request: 1,
|
||||||
|
},
|
||||||
|
}), []));
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: 1,
|
||||||
|
}), []));
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: 1,
|
||||||
|
jobs: 1,
|
||||||
|
}), []));
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: 1,
|
||||||
|
jobs: [1],
|
||||||
|
}), []));
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: 1,
|
||||||
|
jobs: { 1: 1 },
|
||||||
|
}), []));
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: 1,
|
||||||
|
jobs: { test: 1 },
|
||||||
|
}), []));
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: 1,
|
||||||
|
jobs: { test: [1] },
|
||||||
|
}), []));
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: 1,
|
||||||
|
jobs: { test: { steps: 1 } },
|
||||||
|
}), []));
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: 1,
|
||||||
|
jobs: { test: { steps: [{ notrun: "git checkout HEAD^2" }] } },
|
||||||
|
}), []));
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: 1,
|
||||||
|
jobs: { test: [undefined] },
|
||||||
|
}), []));
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)(1), []));
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: {
|
||||||
|
push: {
|
||||||
|
branches: 1,
|
||||||
|
},
|
||||||
|
pull_request: {
|
||||||
|
branches: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}), []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.pull_request for every branch but push specifies branches", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)(yaml.load(`
|
||||||
|
name: "CodeQL"
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ["main"]
|
||||||
|
pull_request:
|
||||||
|
`));
|
||||||
|
t.deepEqual(...errorCodes(errors, [workflow_1.WorkflowErrors.MismatchedBranches]));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.pull_request for wildcard branches", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: {
|
||||||
|
push: { branches: ["feature/*"] },
|
||||||
|
pull_request: { branches: "feature/moose" },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
t.deepEqual(...errorCodes(errors, []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.pull_request for mismatched wildcard branches", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: {
|
||||||
|
push: { branches: ["feature/moose"] },
|
||||||
|
pull_request: { branches: "feature/*" },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
t.deepEqual(...errorCodes(errors, [workflow_1.WorkflowErrors.MismatchedBranches]));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when HEAD^2 is checked out", (t) => {
|
||||||
|
process.env.GITHUB_JOB = "test";
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)({
|
||||||
|
on: ["push", "pull_request"],
|
||||||
|
jobs: { test: { steps: [{ run: "git checkout HEAD^2" }] } },
|
||||||
|
});
|
||||||
|
t.deepEqual(...errorCodes(errors, [workflow_1.WorkflowErrors.CheckoutWrongHead]));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("formatWorkflowErrors() when there is one error", (t) => {
|
||||||
|
const message = (0, workflow_1.formatWorkflowErrors)([workflow_1.WorkflowErrors.CheckoutWrongHead]);
|
||||||
|
t.true(message.startsWith("1 issue was detected with this workflow:"));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("formatWorkflowErrors() when there are multiple errors", (t) => {
|
||||||
|
const message = (0, workflow_1.formatWorkflowErrors)([
|
||||||
|
workflow_1.WorkflowErrors.CheckoutWrongHead,
|
||||||
|
workflow_1.WorkflowErrors.PathsSpecified,
|
||||||
|
]);
|
||||||
|
t.true(message.startsWith("2 issues were detected with this workflow:"));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("formatWorkflowCause() with no errors", (t) => {
|
||||||
|
const message = (0, workflow_1.formatWorkflowCause)([]);
|
||||||
|
t.deepEqual(message, undefined);
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("formatWorkflowCause()", (t) => {
|
||||||
|
const message = (0, workflow_1.formatWorkflowCause)([
|
||||||
|
workflow_1.WorkflowErrors.CheckoutWrongHead,
|
||||||
|
workflow_1.WorkflowErrors.PathsSpecified,
|
||||||
|
]);
|
||||||
|
t.deepEqual(message, "CheckoutWrongHead,PathsSpecified");
|
||||||
|
t.deepEqual((0, workflow_1.formatWorkflowCause)([]), undefined);
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("patternIsSuperset()", (t) => {
|
||||||
|
t.false((0, workflow_1.patternIsSuperset)("main-*", "main"));
|
||||||
|
t.true((0, workflow_1.patternIsSuperset)("*", "*"));
|
||||||
|
t.true((0, workflow_1.patternIsSuperset)("*", "main-*"));
|
||||||
|
t.false((0, workflow_1.patternIsSuperset)("main-*", "*"));
|
||||||
|
t.false((0, workflow_1.patternIsSuperset)("main-*", "main"));
|
||||||
|
t.true((0, workflow_1.patternIsSuperset)("main", "main"));
|
||||||
|
t.false((0, workflow_1.patternIsSuperset)("*", "feature/*"));
|
||||||
|
t.true((0, workflow_1.patternIsSuperset)("**", "feature/*"));
|
||||||
|
t.false((0, workflow_1.patternIsSuperset)("feature-*", "**"));
|
||||||
|
t.false((0, workflow_1.patternIsSuperset)("a/**/c", "a/**/d"));
|
||||||
|
t.false((0, workflow_1.patternIsSuperset)("a/**/c", "a/**"));
|
||||||
|
t.true((0, workflow_1.patternIsSuperset)("a/**", "a/**/c"));
|
||||||
|
t.true((0, workflow_1.patternIsSuperset)("a/**/c", "a/main-**/c"));
|
||||||
|
t.false((0, workflow_1.patternIsSuperset)("a/**/b/**/c", "a/**/d/**/c"));
|
||||||
|
t.true((0, workflow_1.patternIsSuperset)("a/**/b/**/c", "a/**/b/c/**/c"));
|
||||||
|
t.true((0, workflow_1.patternIsSuperset)("a/**/b/**/c", "a/**/b/d/**/c"));
|
||||||
|
t.false((0, workflow_1.patternIsSuperset)("a/**/c/d/**/c", "a/**/b/**/c"));
|
||||||
|
t.false((0, workflow_1.patternIsSuperset)("a/main-**/c", "a/**/c"));
|
||||||
|
t.true((0, workflow_1.patternIsSuperset)("/robin/*/release/*", "/robin/moose/release/goose"));
|
||||||
|
t.false((0, workflow_1.patternIsSuperset)("/robin/moose/release/goose", "/robin/*/release/*"));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when branches contain dots", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)(yaml.load(`
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [4.1, master]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [4.1, master]
|
||||||
|
`));
|
||||||
|
t.deepEqual(...errorCodes(errors, []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on.push has a trailing comma", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)(yaml.load(`
|
||||||
|
name: "CodeQL"
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master, ]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [master]
|
||||||
|
`));
|
||||||
|
t.deepEqual(...errorCodes(errors, []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() should only report the current job's CheckoutWrongHead", (t) => {
|
||||||
|
process.env.GITHUB_JOB = "test";
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)(yaml.load(`
|
||||||
|
name: "CodeQL"
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [master]
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
steps:
|
||||||
|
- run: "git checkout HEAD^2"
|
||||||
|
|
||||||
|
test2:
|
||||||
|
steps:
|
||||||
|
- run: "git checkout HEAD^2"
|
||||||
|
|
||||||
|
test3:
|
||||||
|
steps: []
|
||||||
|
`));
|
||||||
|
t.deepEqual(...errorCodes(errors, [workflow_1.WorkflowErrors.CheckoutWrongHead]));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() should not report a different job's CheckoutWrongHead", (t) => {
|
||||||
|
process.env.GITHUB_JOB = "test3";
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)(yaml.load(`
|
||||||
|
name: "CodeQL"
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [master]
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
steps:
|
||||||
|
- run: "git checkout HEAD^2"
|
||||||
|
|
||||||
|
test2:
|
||||||
|
steps:
|
||||||
|
- run: "git checkout HEAD^2"
|
||||||
|
|
||||||
|
test3:
|
||||||
|
steps: []
|
||||||
|
`));
|
||||||
|
t.deepEqual(...errorCodes(errors, []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() when on is missing", (t) => {
|
||||||
|
const errors = (0, workflow_1.getWorkflowErrors)(yaml.load(`
|
||||||
|
name: "CodeQL"
|
||||||
|
`));
|
||||||
|
t.deepEqual(...errorCodes(errors, []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() with a different on setup", (t) => {
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)(yaml.load(`
|
||||||
|
name: "CodeQL"
|
||||||
|
on: "workflow_dispatch"
|
||||||
|
`)), []));
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)(yaml.load(`
|
||||||
|
name: "CodeQL"
|
||||||
|
on: [workflow_dispatch]
|
||||||
|
`)), []));
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)(yaml.load(`
|
||||||
|
name: "CodeQL"
|
||||||
|
on:
|
||||||
|
workflow_dispatch: {}
|
||||||
|
`)), []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getWorkflowErrors() should not report an error if PRs are totally unconfigured", (t) => {
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)(yaml.load(`
|
||||||
|
name: "CodeQL"
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
`)), []));
|
||||||
|
t.deepEqual(...errorCodes((0, workflow_1.getWorkflowErrors)(yaml.load(`
|
||||||
|
name: "CodeQL"
|
||||||
|
on: ["push"]
|
||||||
|
`)), []));
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getCategoryInputOrThrow returns category for simple workflow with category", (t) => {
|
||||||
|
process.env["GITHUB_REPOSITORY"] = "github/codeql-action-fake-repository";
|
||||||
|
t.is((0, workflow_1.getCategoryInputOrThrow)(yaml.load(`
|
||||||
|
jobs:
|
||||||
|
analysis:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: github/codeql-action/init@v2
|
||||||
|
- uses: github/codeql-action/analyze@v2
|
||||||
|
with:
|
||||||
|
category: some-category
|
||||||
|
`), "analysis", {}), "some-category");
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getCategoryInputOrThrow returns undefined for simple workflow without category", (t) => {
|
||||||
|
process.env["GITHUB_REPOSITORY"] = "github/codeql-action-fake-repository";
|
||||||
|
t.is((0, workflow_1.getCategoryInputOrThrow)(yaml.load(`
|
||||||
|
jobs:
|
||||||
|
analysis:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: github/codeql-action/init@v2
|
||||||
|
- uses: github/codeql-action/analyze@v2
|
||||||
|
`), "analysis", {}), undefined);
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getCategoryInputOrThrow returns category for workflow with multiple jobs", (t) => {
|
||||||
|
process.env["GITHUB_REPOSITORY"] = "github/codeql-action-fake-repository";
|
||||||
|
t.is((0, workflow_1.getCategoryInputOrThrow)(yaml.load(`
|
||||||
|
jobs:
|
||||||
|
foo:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: github/codeql-action/init@v2
|
||||||
|
- runs: ./build foo
|
||||||
|
- uses: github/codeql-action/analyze@v2
|
||||||
|
with:
|
||||||
|
category: foo-category
|
||||||
|
bar:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: github/codeql-action/init@v2
|
||||||
|
- runs: ./build bar
|
||||||
|
- uses: github/codeql-action/analyze@v2
|
||||||
|
with:
|
||||||
|
category: bar-category
|
||||||
|
`), "bar", {}), "bar-category");
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getCategoryInputOrThrow finds category for workflow with language matrix", (t) => {
|
||||||
|
process.env["GITHUB_REPOSITORY"] = "github/codeql-action-fake-repository";
|
||||||
|
t.is((0, workflow_1.getCategoryInputOrThrow)(yaml.load(`
|
||||||
|
jobs:
|
||||||
|
analysis:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
language: [javascript, python]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: github/codeql-action/init@v2
|
||||||
|
with:
|
||||||
|
language: \${{ matrix.language }}
|
||||||
|
- uses: github/codeql-action/analyze@v2
|
||||||
|
with:
|
||||||
|
category: "/language:\${{ matrix.language }}"
|
||||||
|
`), "analysis", { language: "javascript" }), "/language:javascript");
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getCategoryInputOrThrow throws error for workflow with dynamic category", (t) => {
|
||||||
|
process.env["GITHUB_REPOSITORY"] = "github/codeql-action-fake-repository";
|
||||||
|
t.throws(() => (0, workflow_1.getCategoryInputOrThrow)(yaml.load(`
|
||||||
|
jobs:
|
||||||
|
analysis:
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: github/codeql-action/init@v2
|
||||||
|
- uses: github/codeql-action/analyze@v2
|
||||||
|
with:
|
||||||
|
category: "\${{ github.workflow }}"
|
||||||
|
`), "analysis", {}), {
|
||||||
|
message: "Could not get category input to github/codeql-action/analyze since it contained " +
|
||||||
|
"an unrecognized dynamic value.",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("getCategoryInputOrThrow throws error for workflow with multiple calls to analyze", (t) => {
|
||||||
|
process.env["GITHUB_REPOSITORY"] = "github/codeql-action-fake-repository";
|
||||||
|
t.throws(() => (0, workflow_1.getCategoryInputOrThrow)(yaml.load(`
|
||||||
|
jobs:
|
||||||
|
analysis:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: github/codeql-action/init@v2
|
||||||
|
- uses: github/codeql-action/analyze@v2
|
||||||
|
with:
|
||||||
|
category: some-category
|
||||||
|
- uses: github/codeql-action/analyze@v2
|
||||||
|
with:
|
||||||
|
category: another-category
|
||||||
|
`), "analysis", {}), {
|
||||||
|
message: "Could not get category input to github/codeql-action/analyze since the analysis job " +
|
||||||
|
"calls github/codeql-action/analyze multiple times.",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//# sourceMappingURL=workflow.test.js.map
|
||||||
File diff suppressed because one or more lines are too long
+1
-46
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "codeql",
|
"name": "codeql",
|
||||||
"version": "2.1.34",
|
"version": "2.1.38",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
@@ -1924,13 +1924,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/decode-uri-component": {
|
|
||||||
"version": "0.2.0",
|
|
||||||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/deep-is": {
|
"node_modules/deep-is": {
|
||||||
"version": "0.1.3",
|
"version": "0.1.3",
|
||||||
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
|
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
|
||||||
@@ -3046,13 +3039,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/filter-obj": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/find-up": {
|
"node_modules/find-up": {
|
||||||
"version": "6.2.0",
|
"version": "6.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-6.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-6.2.0.tgz",
|
||||||
@@ -4559,23 +4545,6 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/query-string": {
|
|
||||||
"version": "7.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-7.0.1.tgz",
|
|
||||||
"integrity": "sha512-uIw3iRvHnk9to1blJCG3BTc+Ro56CBowJXKmNNAm3RulvPBzWLRqKSiiDk+IplJhsydwtuNMHi8UGQFcCLVfkA==",
|
|
||||||
"dependencies": {
|
|
||||||
"decode-uri-component": "^0.2.0",
|
|
||||||
"filter-obj": "^1.1.0",
|
|
||||||
"split-on-first": "^1.0.0",
|
|
||||||
"strict-uri-encode": "^2.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/read-pkg-up": {
|
"node_modules/read-pkg-up": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
|
||||||
@@ -5041,13 +5010,6 @@
|
|||||||
"integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
|
"integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/split-on-first": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/sprintf-js": {
|
"node_modules/sprintf-js": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
@@ -5075,13 +5037,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/strict-uri-encode": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/string-width": {
|
"node_modules/string-width": {
|
||||||
"version": "4.2.3",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
|
|||||||
-94
@@ -1,94 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
var token = '%[a-f0-9]{2}';
|
|
||||||
var singleMatcher = new RegExp(token, 'gi');
|
|
||||||
var multiMatcher = new RegExp('(' + token + ')+', 'gi');
|
|
||||||
|
|
||||||
function decodeComponents(components, split) {
|
|
||||||
try {
|
|
||||||
// Try to decode the entire string first
|
|
||||||
return decodeURIComponent(components.join(''));
|
|
||||||
} catch (err) {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
if (components.length === 1) {
|
|
||||||
return components;
|
|
||||||
}
|
|
||||||
|
|
||||||
split = split || 1;
|
|
||||||
|
|
||||||
// Split the array in 2 parts
|
|
||||||
var left = components.slice(0, split);
|
|
||||||
var right = components.slice(split);
|
|
||||||
|
|
||||||
return Array.prototype.concat.call([], decodeComponents(left), decodeComponents(right));
|
|
||||||
}
|
|
||||||
|
|
||||||
function decode(input) {
|
|
||||||
try {
|
|
||||||
return decodeURIComponent(input);
|
|
||||||
} catch (err) {
|
|
||||||
var tokens = input.match(singleMatcher);
|
|
||||||
|
|
||||||
for (var i = 1; i < tokens.length; i++) {
|
|
||||||
input = decodeComponents(tokens, i).join('');
|
|
||||||
|
|
||||||
tokens = input.match(singleMatcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function customDecodeURIComponent(input) {
|
|
||||||
// Keep track of all the replacements and prefill the map with the `BOM`
|
|
||||||
var replaceMap = {
|
|
||||||
'%FE%FF': '\uFFFD\uFFFD',
|
|
||||||
'%FF%FE': '\uFFFD\uFFFD'
|
|
||||||
};
|
|
||||||
|
|
||||||
var match = multiMatcher.exec(input);
|
|
||||||
while (match) {
|
|
||||||
try {
|
|
||||||
// Decode as big chunks as possible
|
|
||||||
replaceMap[match[0]] = decodeURIComponent(match[0]);
|
|
||||||
} catch (err) {
|
|
||||||
var result = decode(match[0]);
|
|
||||||
|
|
||||||
if (result !== match[0]) {
|
|
||||||
replaceMap[match[0]] = result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match = multiMatcher.exec(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add `%C2` at the end of the map to make sure it does not replace the combinator before everything else
|
|
||||||
replaceMap['%C2'] = '\uFFFD';
|
|
||||||
|
|
||||||
var entries = Object.keys(replaceMap);
|
|
||||||
|
|
||||||
for (var i = 0; i < entries.length; i++) {
|
|
||||||
// Replace all decoded components
|
|
||||||
var key = entries[i];
|
|
||||||
input = input.replace(new RegExp(key, 'g'), replaceMap[key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = function (encodedURI) {
|
|
||||||
if (typeof encodedURI !== 'string') {
|
|
||||||
throw new TypeError('Expected `encodedURI` to be of type `string`, got `' + typeof encodedURI + '`');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
encodedURI = encodedURI.replace(/\+/g, ' ');
|
|
||||||
|
|
||||||
// Try the built in decoder first
|
|
||||||
return decodeURIComponent(encodedURI);
|
|
||||||
} catch (err) {
|
|
||||||
// Fallback to a more advanced decoder
|
|
||||||
return customDecodeURIComponent(encodedURI);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
-21
@@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) Sam Verschueren <sam.verschueren@gmail.com> (github.com/SamVerschueren)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
-37
@@ -1,37 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "decode-uri-component",
|
|
||||||
"version": "0.2.0",
|
|
||||||
"description": "A better decodeURIComponent",
|
|
||||||
"license": "MIT",
|
|
||||||
"repository": "SamVerschueren/decode-uri-component",
|
|
||||||
"author": {
|
|
||||||
"name": "Sam Verschueren",
|
|
||||||
"email": "sam.verschueren@gmail.com",
|
|
||||||
"url": "github.com/SamVerschueren"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"test": "xo && nyc ava",
|
|
||||||
"coveralls": "nyc report --reporter=text-lcov | coveralls"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"index.js"
|
|
||||||
],
|
|
||||||
"keywords": [
|
|
||||||
"decode",
|
|
||||||
"uri",
|
|
||||||
"component",
|
|
||||||
"decodeuricomponent",
|
|
||||||
"components",
|
|
||||||
"decoder",
|
|
||||||
"url"
|
|
||||||
],
|
|
||||||
"devDependencies": {
|
|
||||||
"ava": "^0.17.0",
|
|
||||||
"coveralls": "^2.13.1",
|
|
||||||
"nyc": "^10.3.2",
|
|
||||||
"xo": "^0.16.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-70
@@ -1,70 +0,0 @@
|
|||||||
# decode-uri-component
|
|
||||||
|
|
||||||
[](https://travis-ci.org/SamVerschueren/decode-uri-component) [](https://coveralls.io/github/SamVerschueren/decode-uri-component?branch=master)
|
|
||||||
|
|
||||||
> A better [decodeURIComponent](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent)
|
|
||||||
|
|
||||||
|
|
||||||
## Why?
|
|
||||||
|
|
||||||
- Decodes `+` to a space.
|
|
||||||
- Converts the [BOM](https://en.wikipedia.org/wiki/Byte_order_mark) to a [replacement character](https://en.wikipedia.org/wiki/Specials_(Unicode_block)#Replacement_character) `�`.
|
|
||||||
- Does not throw with invalid encoded input.
|
|
||||||
- Decodes as much of the string as possible.
|
|
||||||
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
```
|
|
||||||
$ npm install --save decode-uri-component
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
const decodeUriComponent = require('decode-uri-component');
|
|
||||||
|
|
||||||
decodeUriComponent('%25');
|
|
||||||
//=> '%'
|
|
||||||
|
|
||||||
decodeUriComponent('%');
|
|
||||||
//=> '%'
|
|
||||||
|
|
||||||
decodeUriComponent('st%C3%A5le');
|
|
||||||
//=> 'ståle'
|
|
||||||
|
|
||||||
decodeUriComponent('%st%C3%A5le%');
|
|
||||||
//=> '%ståle%'
|
|
||||||
|
|
||||||
decodeUriComponent('%%7Bst%C3%A5le%7D%');
|
|
||||||
//=> '%{ståle}%'
|
|
||||||
|
|
||||||
decodeUriComponent('%7B%ab%%7C%de%%7D');
|
|
||||||
//=> '{%ab%|%de%}'
|
|
||||||
|
|
||||||
decodeUriComponent('%FE%FF');
|
|
||||||
//=> '\uFFFD\uFFFD'
|
|
||||||
|
|
||||||
decodeUriComponent('%C2');
|
|
||||||
//=> '\uFFFD'
|
|
||||||
|
|
||||||
decodeUriComponent('%C2%B5');
|
|
||||||
//=> 'µ'
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### decodeUriComponent(encodedURI)
|
|
||||||
|
|
||||||
#### encodedURI
|
|
||||||
|
|
||||||
Type: `string`
|
|
||||||
|
|
||||||
An encoded component of a Uniform Resource Identifier.
|
|
||||||
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT © [Sam Verschueren](https://github.com/SamVerschueren)
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
module.exports = function (obj, predicate) {
|
|
||||||
var ret = {};
|
|
||||||
var keys = Object.keys(obj);
|
|
||||||
var isArr = Array.isArray(predicate);
|
|
||||||
|
|
||||||
for (var i = 0; i < keys.length; i++) {
|
|
||||||
var key = keys[i];
|
|
||||||
var val = obj[key];
|
|
||||||
|
|
||||||
if (isArr ? predicate.indexOf(key) !== -1 : predicate(key, val, obj)) {
|
|
||||||
ret[key] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
-21
@@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
-37
@@ -1,37 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "filter-obj",
|
|
||||||
"version": "1.1.0",
|
|
||||||
"description": "Filter object keys and values into a new object",
|
|
||||||
"license": "MIT",
|
|
||||||
"repository": "sindresorhus/filter-obj",
|
|
||||||
"author": {
|
|
||||||
"name": "Sindre Sorhus",
|
|
||||||
"email": "sindresorhus@gmail.com",
|
|
||||||
"url": "sindresorhus.com"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"test": "xo && node test.js"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"index.js"
|
|
||||||
],
|
|
||||||
"keywords": [
|
|
||||||
"filter",
|
|
||||||
"obj",
|
|
||||||
"object",
|
|
||||||
"key",
|
|
||||||
"keys",
|
|
||||||
"value",
|
|
||||||
"values",
|
|
||||||
"val",
|
|
||||||
"iterate",
|
|
||||||
"iterator"
|
|
||||||
],
|
|
||||||
"devDependencies": {
|
|
||||||
"ava": "0.0.4",
|
|
||||||
"xo": "*"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-41
@@ -1,41 +0,0 @@
|
|||||||
# filter-obj [](https://travis-ci.org/sindresorhus/filter-obj)
|
|
||||||
|
|
||||||
> Filter object keys and values into a new object
|
|
||||||
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
```
|
|
||||||
$ npm install --save filter-obj
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
var filterObj = require('filter-obj');
|
|
||||||
|
|
||||||
var obj = {
|
|
||||||
foo: true,
|
|
||||||
bar: false
|
|
||||||
};
|
|
||||||
|
|
||||||
var newObject = filterObj(obj, function (key, value, object) {
|
|
||||||
return value === true;
|
|
||||||
});
|
|
||||||
//=> {foo: true}
|
|
||||||
|
|
||||||
var newObject2 = filterObj(obj, ['bar']);
|
|
||||||
//=> {bar: true}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Related
|
|
||||||
|
|
||||||
- [map-obj](https://github.com/sindresorhus/map-obj) - Map object keys and values into a new object
|
|
||||||
- [object-assign](https://github.com/sindresorhus/object-assign) - Copy enumerable own properties from one or more source objects to a target object
|
|
||||||
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT © [Sindre Sorhus](http://sindresorhus.com)
|
|
||||||
-545
@@ -1,545 +0,0 @@
|
|||||||
export interface ParseOptions {
|
|
||||||
/**
|
|
||||||
Decode the keys and values. URI components are decoded with [`decode-uri-component`](https://github.com/SamVerschueren/decode-uri-component).
|
|
||||||
|
|
||||||
@default true
|
|
||||||
*/
|
|
||||||
readonly decode?: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
@default 'none'
|
|
||||||
|
|
||||||
- `bracket`: Parse arrays with bracket representation:
|
|
||||||
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo[]=1&foo[]=2&foo[]=3', {arrayFormat: 'bracket'});
|
|
||||||
//=> {foo: ['1', '2', '3']}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `index`: Parse arrays with index representation:
|
|
||||||
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo[0]=1&foo[1]=2&foo[3]=3', {arrayFormat: 'index'});
|
|
||||||
//=> {foo: ['1', '2', '3']}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `comma`: Parse arrays with elements separated by comma:
|
|
||||||
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo=1,2,3', {arrayFormat: 'comma'});
|
|
||||||
//=> {foo: ['1', '2', '3']}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `separator`: Parse arrays with elements separated by a custom character:
|
|
||||||
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo=1|2|3', {arrayFormat: 'separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> {foo: ['1', '2', '3']}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `bracket-separator`: Parse arrays (that are explicitly marked with brackets) with elements separated by a custom character:
|
|
||||||
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo[]', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> {foo: []}
|
|
||||||
|
|
||||||
queryString.parse('foo[]=', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> {foo: ['']}
|
|
||||||
|
|
||||||
queryString.parse('foo[]=1', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> {foo: ['1']}
|
|
||||||
|
|
||||||
queryString.parse('foo[]=1|2|3', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> {foo: ['1', '2', '3']}
|
|
||||||
|
|
||||||
queryString.parse('foo[]=1||3|||6', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> {foo: ['1', '', 3, '', '', '6']}
|
|
||||||
|
|
||||||
queryString.parse('foo[]=1|2|3&bar=fluffy&baz[]=4', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> {foo: ['1', '2', '3'], bar: 'fluffy', baz:['4']}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `none`: Parse arrays with elements using duplicate keys:
|
|
||||||
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo=1&foo=2&foo=3');
|
|
||||||
//=> {foo: ['1', '2', '3']}
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
readonly arrayFormat?: 'bracket' | 'index' | 'comma' | 'separator' | 'bracket-separator' | 'none';
|
|
||||||
|
|
||||||
/**
|
|
||||||
The character used to separate array elements when using `{arrayFormat: 'separator'}`.
|
|
||||||
|
|
||||||
@default ,
|
|
||||||
*/
|
|
||||||
readonly arrayFormatSeparator?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Supports both `Function` as a custom sorting function or `false` to disable sorting.
|
|
||||||
|
|
||||||
If omitted, keys are sorted using `Array#sort`, which means, converting them to strings and comparing strings in Unicode code point order.
|
|
||||||
|
|
||||||
@default true
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
const order = ['c', 'a', 'b'];
|
|
||||||
|
|
||||||
queryString.parse('?a=one&b=two&c=three', {
|
|
||||||
sort: (itemLeft, itemRight) => order.indexOf(itemLeft) - order.indexOf(itemRight)
|
|
||||||
});
|
|
||||||
//=> {c: 'three', a: 'one', b: 'two'}
|
|
||||||
```
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('?a=one&c=three&b=two', {sort: false});
|
|
||||||
//=> {a: 'one', c: 'three', b: 'two'}
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
readonly sort?: ((itemLeft: string, itemRight: string) => number) | false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Parse the value as a number type instead of string type if it's a number.
|
|
||||||
|
|
||||||
@default false
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo=1', {parseNumbers: true});
|
|
||||||
//=> {foo: 1}
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
readonly parseNumbers?: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Parse the value as a boolean type instead of string type if it's a boolean.
|
|
||||||
|
|
||||||
@default false
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo=true', {parseBooleans: true});
|
|
||||||
//=> {foo: true}
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
readonly parseBooleans?: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Parse the fragment identifier from the URL and add it to result object.
|
|
||||||
|
|
||||||
@default false
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parseUrl('https://foo.bar?foo=bar#xyz', {parseFragmentIdentifier: true});
|
|
||||||
//=> {url: 'https://foo.bar', query: {foo: 'bar'}, fragmentIdentifier: 'xyz'}
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
readonly parseFragmentIdentifier?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ParsedQuery<T = string> {
|
|
||||||
[key: string]: T | T[] | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Parse a query string into an object. Leading `?` or `#` are ignored, so you can pass `location.search` or `location.hash` directly.
|
|
||||||
|
|
||||||
The returned object is created with [`Object.create(null)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create) and thus does not have a `prototype`.
|
|
||||||
|
|
||||||
@param query - The query string to parse.
|
|
||||||
*/
|
|
||||||
export function parse(query: string, options: {parseBooleans: true, parseNumbers: true} & ParseOptions): ParsedQuery<string | boolean | number>;
|
|
||||||
export function parse(query: string, options: {parseBooleans: true} & ParseOptions): ParsedQuery<string | boolean>;
|
|
||||||
export function parse(query: string, options: {parseNumbers: true} & ParseOptions): ParsedQuery<string | number>;
|
|
||||||
export function parse(query: string, options?: ParseOptions): ParsedQuery;
|
|
||||||
|
|
||||||
export interface ParsedUrl {
|
|
||||||
readonly url: string;
|
|
||||||
readonly query: ParsedQuery;
|
|
||||||
|
|
||||||
/**
|
|
||||||
The fragment identifier of the URL.
|
|
||||||
|
|
||||||
Present when the `parseFragmentIdentifier` option is `true`.
|
|
||||||
*/
|
|
||||||
readonly fragmentIdentifier?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Extract the URL and the query string as an object.
|
|
||||||
|
|
||||||
If the `parseFragmentIdentifier` option is `true`, the object will also contain a `fragmentIdentifier` property.
|
|
||||||
|
|
||||||
@param url - The URL to parse.
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parseUrl('https://foo.bar?foo=bar');
|
|
||||||
//=> {url: 'https://foo.bar', query: {foo: 'bar'}}
|
|
||||||
|
|
||||||
queryString.parseUrl('https://foo.bar?foo=bar#xyz', {parseFragmentIdentifier: true});
|
|
||||||
//=> {url: 'https://foo.bar', query: {foo: 'bar'}, fragmentIdentifier: 'xyz'}
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
export function parseUrl(url: string, options?: ParseOptions): ParsedUrl;
|
|
||||||
|
|
||||||
export interface StringifyOptions {
|
|
||||||
/**
|
|
||||||
Strictly encode URI components with [`strict-uri-encode`](https://github.com/kevva/strict-uri-encode). It uses [`encodeURIComponent`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) if set to `false`. You probably [don't care](https://github.com/sindresorhus/query-string/issues/42) about this option.
|
|
||||||
|
|
||||||
@default true
|
|
||||||
*/
|
|
||||||
readonly strict?: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
[URL encode](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) the keys and values.
|
|
||||||
|
|
||||||
@default true
|
|
||||||
*/
|
|
||||||
readonly encode?: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
@default 'none'
|
|
||||||
|
|
||||||
- `bracket`: Serialize arrays using bracket representation:
|
|
||||||
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'bracket'});
|
|
||||||
//=> 'foo[]=1&foo[]=2&foo[]=3'
|
|
||||||
```
|
|
||||||
|
|
||||||
- `index`: Serialize arrays using index representation:
|
|
||||||
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'index'});
|
|
||||||
//=> 'foo[0]=1&foo[1]=2&foo[2]=3'
|
|
||||||
```
|
|
||||||
|
|
||||||
- `comma`: Serialize arrays by separating elements with comma:
|
|
||||||
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'comma'});
|
|
||||||
//=> 'foo=1,2,3'
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, null, '']}, {arrayFormat: 'comma'});
|
|
||||||
//=> 'foo=1,,'
|
|
||||||
// Note that typing information for null values is lost
|
|
||||||
// and `.parse('foo=1,,')` would return `{foo: [1, '', '']}`.
|
|
||||||
```
|
|
||||||
|
|
||||||
- `separator`: Serialize arrays by separating elements with character:
|
|
||||||
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> 'foo=1|2|3'
|
|
||||||
```
|
|
||||||
|
|
||||||
- `bracket-separator`: Serialize arrays by explicitly post-fixing array names with brackets and separating elements with a custom character:
|
|
||||||
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({foo: []}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> 'foo[]'
|
|
||||||
|
|
||||||
queryString.stringify({foo: ['']}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> 'foo[]='
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> 'foo[]=1'
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> 'foo[]=1|2|3'
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, '', 3, null, null, 6]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> 'foo[]=1||3|||6'
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, '', 3, null, null, 6]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|', skipNull: true});
|
|
||||||
//=> 'foo[]=1||3|6'
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, 2, 3], bar: 'fluffy', baz: [4]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> 'foo[]=1|2|3&bar=fluffy&baz[]=4'
|
|
||||||
```
|
|
||||||
|
|
||||||
- `none`: Serialize arrays by using duplicate keys:
|
|
||||||
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, 2, 3]});
|
|
||||||
//=> 'foo=1&foo=2&foo=3'
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
readonly arrayFormat?: 'bracket' | 'index' | 'comma' | 'separator' | 'bracket-separator' | 'none';
|
|
||||||
|
|
||||||
/**
|
|
||||||
The character used to separate array elements when using `{arrayFormat: 'separator'}`.
|
|
||||||
|
|
||||||
@default ,
|
|
||||||
*/
|
|
||||||
readonly arrayFormatSeparator?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Supports both `Function` as a custom sorting function or `false` to disable sorting.
|
|
||||||
|
|
||||||
If omitted, keys are sorted using `Array#sort`, which means, converting them to strings and comparing strings in Unicode code point order.
|
|
||||||
|
|
||||||
@default true
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
const order = ['c', 'a', 'b'];
|
|
||||||
|
|
||||||
queryString.stringify({a: 1, b: 2, c: 3}, {
|
|
||||||
sort: (itemLeft, itemRight) => order.indexOf(itemLeft) - order.indexOf(itemRight)
|
|
||||||
});
|
|
||||||
//=> 'c=3&a=1&b=2'
|
|
||||||
```
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({b: 1, c: 2, a: 3}, {sort: false});
|
|
||||||
//=> 'b=1&c=2&a=3'
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
readonly sort?: ((itemLeft: string, itemRight: string) => number) | false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Skip keys with `null` as the value.
|
|
||||||
|
|
||||||
Note that keys with `undefined` as the value are always skipped.
|
|
||||||
|
|
||||||
@default false
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({a: 1, b: undefined, c: null, d: 4}, {
|
|
||||||
skipNull: true
|
|
||||||
});
|
|
||||||
//=> 'a=1&d=4'
|
|
||||||
|
|
||||||
queryString.stringify({a: undefined, b: null}, {
|
|
||||||
skipNull: true
|
|
||||||
});
|
|
||||||
//=> ''
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
readonly skipNull?: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Skip keys with an empty string as the value.
|
|
||||||
|
|
||||||
@default false
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({a: 1, b: '', c: '', d: 4}, {
|
|
||||||
skipEmptyString: true
|
|
||||||
});
|
|
||||||
//=> 'a=1&d=4'
|
|
||||||
```
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
import queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({a: '', b: ''}, {
|
|
||||||
skipEmptyString: true
|
|
||||||
});
|
|
||||||
//=> ''
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
readonly skipEmptyString?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Stringifiable = string | boolean | number | null | undefined;
|
|
||||||
|
|
||||||
export type StringifiableRecord = Record<
|
|
||||||
string,
|
|
||||||
Stringifiable | readonly Stringifiable[]
|
|
||||||
>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Stringify an object into a query string and sort the keys.
|
|
||||||
*/
|
|
||||||
export function stringify(
|
|
||||||
// TODO: Use the below instead when the following TS issues are fixed:
|
|
||||||
// - https://github.com/microsoft/TypeScript/issues/15300
|
|
||||||
// - https://github.com/microsoft/TypeScript/issues/42021
|
|
||||||
// Context: https://github.com/sindresorhus/query-string/issues/298
|
|
||||||
// object: StringifiableRecord,
|
|
||||||
object: Record<string, any>,
|
|
||||||
options?: StringifyOptions
|
|
||||||
): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Extract a query string from a URL that can be passed into `.parse()`.
|
|
||||||
|
|
||||||
Note: This behaviour can be changed with the `skipNull` option.
|
|
||||||
*/
|
|
||||||
export function extract(url: string): string;
|
|
||||||
|
|
||||||
export interface UrlObject {
|
|
||||||
readonly url: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Overrides queries in the `url` property.
|
|
||||||
*/
|
|
||||||
readonly query?: StringifiableRecord;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Overrides the fragment identifier in the `url` property.
|
|
||||||
*/
|
|
||||||
readonly fragmentIdentifier?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Stringify an object into a URL with a query string and sorting the keys. The inverse of [`.parseUrl()`](https://github.com/sindresorhus/query-string#parseurlstring-options)
|
|
||||||
|
|
||||||
Query items in the `query` property overrides queries in the `url` property.
|
|
||||||
|
|
||||||
The `fragmentIdentifier` property overrides the fragment identifier in the `url` property.
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
queryString.stringifyUrl({url: 'https://foo.bar', query: {foo: 'bar'}});
|
|
||||||
//=> 'https://foo.bar?foo=bar'
|
|
||||||
|
|
||||||
queryString.stringifyUrl({url: 'https://foo.bar?foo=baz', query: {foo: 'bar'}});
|
|
||||||
//=> 'https://foo.bar?foo=bar'
|
|
||||||
|
|
||||||
queryString.stringifyUrl({
|
|
||||||
url: 'https://foo.bar',
|
|
||||||
query: {
|
|
||||||
top: 'foo'
|
|
||||||
},
|
|
||||||
fragmentIdentifier: 'bar'
|
|
||||||
});
|
|
||||||
//=> 'https://foo.bar?top=foo#bar'
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
export function stringifyUrl(
|
|
||||||
object: UrlObject,
|
|
||||||
options?: StringifyOptions
|
|
||||||
): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Pick query parameters from a URL.
|
|
||||||
|
|
||||||
@param url - The URL containing the query parameters to pick.
|
|
||||||
@param keys - The names of the query parameters to keep. All other query parameters will be removed from the URL.
|
|
||||||
@param filter - A filter predicate that will be provided the name of each query parameter and its value. The `parseNumbers` and `parseBooleans` options also affect `value`.
|
|
||||||
|
|
||||||
@returns The URL with the picked query parameters.
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
queryString.pick('https://foo.bar?foo=1&bar=2#hello', ['foo']);
|
|
||||||
//=> 'https://foo.bar?foo=1#hello'
|
|
||||||
|
|
||||||
queryString.pick('https://foo.bar?foo=1&bar=2#hello', (name, value) => value === 2, {parseNumbers: true});
|
|
||||||
//=> 'https://foo.bar?bar=2#hello'
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
export function pick(
|
|
||||||
url: string,
|
|
||||||
keys: readonly string[],
|
|
||||||
options?: ParseOptions & StringifyOptions
|
|
||||||
): string
|
|
||||||
export function pick(
|
|
||||||
url: string,
|
|
||||||
filter: (key: string, value: string | boolean | number) => boolean,
|
|
||||||
options?: {parseBooleans: true, parseNumbers: true} & ParseOptions & StringifyOptions
|
|
||||||
): string
|
|
||||||
export function pick(
|
|
||||||
url: string,
|
|
||||||
filter: (key: string, value: string | boolean) => boolean,
|
|
||||||
options?: {parseBooleans: true} & ParseOptions & StringifyOptions
|
|
||||||
): string
|
|
||||||
export function pick(
|
|
||||||
url: string,
|
|
||||||
filter: (key: string, value: string | number) => boolean,
|
|
||||||
options?: {parseNumbers: true} & ParseOptions & StringifyOptions
|
|
||||||
): string
|
|
||||||
|
|
||||||
/**
|
|
||||||
Exclude query parameters from a URL. Like `.pick()` but reversed.
|
|
||||||
|
|
||||||
@param url - The URL containing the query parameters to exclude.
|
|
||||||
@param keys - The names of the query parameters to remove. All other query parameters will remain in the URL.
|
|
||||||
@param filter - A filter predicate that will be provided the name of each query parameter and its value. The `parseNumbers` and `parseBooleans` options also affect `value`.
|
|
||||||
|
|
||||||
@returns The URL without the excluded the query parameters.
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
queryString.exclude('https://foo.bar?foo=1&bar=2#hello', ['foo']);
|
|
||||||
//=> 'https://foo.bar?bar=2#hello'
|
|
||||||
|
|
||||||
queryString.exclude('https://foo.bar?foo=1&bar=2#hello', (name, value) => value === 2, {parseNumbers: true});
|
|
||||||
//=> 'https://foo.bar?foo=1#hello'
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
export function exclude(
|
|
||||||
url: string,
|
|
||||||
keys: readonly string[],
|
|
||||||
options?: ParseOptions & StringifyOptions
|
|
||||||
): string
|
|
||||||
export function exclude(
|
|
||||||
url: string,
|
|
||||||
filter: (key: string, value: string | boolean | number) => boolean,
|
|
||||||
options?: {parseBooleans: true, parseNumbers: true} & ParseOptions & StringifyOptions
|
|
||||||
): string
|
|
||||||
export function exclude(
|
|
||||||
url: string,
|
|
||||||
filter: (key: string, value: string | boolean) => boolean,
|
|
||||||
options?: {parseBooleans: true} & ParseOptions & StringifyOptions
|
|
||||||
): string
|
|
||||||
export function exclude(
|
|
||||||
url: string,
|
|
||||||
filter: (key: string, value: string | number) => boolean,
|
|
||||||
options?: {parseNumbers: true} & ParseOptions & StringifyOptions
|
|
||||||
): string
|
|
||||||
-447
@@ -1,447 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
const strictUriEncode = require('strict-uri-encode');
|
|
||||||
const decodeComponent = require('decode-uri-component');
|
|
||||||
const splitOnFirst = require('split-on-first');
|
|
||||||
const filterObject = require('filter-obj');
|
|
||||||
|
|
||||||
const isNullOrUndefined = value => value === null || value === undefined;
|
|
||||||
|
|
||||||
const encodeFragmentIdentifier = Symbol('encodeFragmentIdentifier');
|
|
||||||
|
|
||||||
function encoderForArrayFormat(options) {
|
|
||||||
switch (options.arrayFormat) {
|
|
||||||
case 'index':
|
|
||||||
return key => (result, value) => {
|
|
||||||
const index = result.length;
|
|
||||||
|
|
||||||
if (
|
|
||||||
value === undefined ||
|
|
||||||
(options.skipNull && value === null) ||
|
|
||||||
(options.skipEmptyString && value === '')
|
|
||||||
) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value === null) {
|
|
||||||
return [...result, [encode(key, options), '[', index, ']'].join('')];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
...result,
|
|
||||||
[encode(key, options), '[', encode(index, options), ']=', encode(value, options)].join('')
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'bracket':
|
|
||||||
return key => (result, value) => {
|
|
||||||
if (
|
|
||||||
value === undefined ||
|
|
||||||
(options.skipNull && value === null) ||
|
|
||||||
(options.skipEmptyString && value === '')
|
|
||||||
) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value === null) {
|
|
||||||
return [...result, [encode(key, options), '[]'].join('')];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [...result, [encode(key, options), '[]=', encode(value, options)].join('')];
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'comma':
|
|
||||||
case 'separator':
|
|
||||||
case 'bracket-separator': {
|
|
||||||
const keyValueSep = options.arrayFormat === 'bracket-separator' ?
|
|
||||||
'[]=' :
|
|
||||||
'=';
|
|
||||||
|
|
||||||
return key => (result, value) => {
|
|
||||||
if (
|
|
||||||
value === undefined ||
|
|
||||||
(options.skipNull && value === null) ||
|
|
||||||
(options.skipEmptyString && value === '')
|
|
||||||
) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translate null to an empty string so that it doesn't serialize as 'null'
|
|
||||||
value = value === null ? '' : value;
|
|
||||||
|
|
||||||
if (result.length === 0) {
|
|
||||||
return [[encode(key, options), keyValueSep, encode(value, options)].join('')];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [[result, encode(value, options)].join(options.arrayFormatSeparator)];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return key => (result, value) => {
|
|
||||||
if (
|
|
||||||
value === undefined ||
|
|
||||||
(options.skipNull && value === null) ||
|
|
||||||
(options.skipEmptyString && value === '')
|
|
||||||
) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value === null) {
|
|
||||||
return [...result, encode(key, options)];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [...result, [encode(key, options), '=', encode(value, options)].join('')];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function parserForArrayFormat(options) {
|
|
||||||
let result;
|
|
||||||
|
|
||||||
switch (options.arrayFormat) {
|
|
||||||
case 'index':
|
|
||||||
return (key, value, accumulator) => {
|
|
||||||
result = /\[(\d*)\]$/.exec(key);
|
|
||||||
|
|
||||||
key = key.replace(/\[\d*\]$/, '');
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
accumulator[key] = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accumulator[key] === undefined) {
|
|
||||||
accumulator[key] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
accumulator[key][result[1]] = value;
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'bracket':
|
|
||||||
return (key, value, accumulator) => {
|
|
||||||
result = /(\[\])$/.exec(key);
|
|
||||||
key = key.replace(/\[\]$/, '');
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
accumulator[key] = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accumulator[key] === undefined) {
|
|
||||||
accumulator[key] = [value];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
accumulator[key] = [].concat(accumulator[key], value);
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'comma':
|
|
||||||
case 'separator':
|
|
||||||
return (key, value, accumulator) => {
|
|
||||||
const isArray = typeof value === 'string' && value.includes(options.arrayFormatSeparator);
|
|
||||||
const isEncodedArray = (typeof value === 'string' && !isArray && decode(value, options).includes(options.arrayFormatSeparator));
|
|
||||||
value = isEncodedArray ? decode(value, options) : value;
|
|
||||||
const newValue = isArray || isEncodedArray ? value.split(options.arrayFormatSeparator).map(item => decode(item, options)) : value === null ? value : decode(value, options);
|
|
||||||
accumulator[key] = newValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
case 'bracket-separator':
|
|
||||||
return (key, value, accumulator) => {
|
|
||||||
const isArray = /(\[\])$/.test(key);
|
|
||||||
key = key.replace(/\[\]$/, '');
|
|
||||||
|
|
||||||
if (!isArray) {
|
|
||||||
accumulator[key] = value ? decode(value, options) : value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const arrayValue = value === null ?
|
|
||||||
[] :
|
|
||||||
value.split(options.arrayFormatSeparator).map(item => decode(item, options));
|
|
||||||
|
|
||||||
if (accumulator[key] === undefined) {
|
|
||||||
accumulator[key] = arrayValue;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
accumulator[key] = [].concat(accumulator[key], arrayValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
default:
|
|
||||||
return (key, value, accumulator) => {
|
|
||||||
if (accumulator[key] === undefined) {
|
|
||||||
accumulator[key] = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
accumulator[key] = [].concat(accumulator[key], value);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateArrayFormatSeparator(value) {
|
|
||||||
if (typeof value !== 'string' || value.length !== 1) {
|
|
||||||
throw new TypeError('arrayFormatSeparator must be single character string');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function encode(value, options) {
|
|
||||||
if (options.encode) {
|
|
||||||
return options.strict ? strictUriEncode(value) : encodeURIComponent(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function decode(value, options) {
|
|
||||||
if (options.decode) {
|
|
||||||
return decodeComponent(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function keysSorter(input) {
|
|
||||||
if (Array.isArray(input)) {
|
|
||||||
return input.sort();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof input === 'object') {
|
|
||||||
return keysSorter(Object.keys(input))
|
|
||||||
.sort((a, b) => Number(a) - Number(b))
|
|
||||||
.map(key => input[key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeHash(input) {
|
|
||||||
const hashStart = input.indexOf('#');
|
|
||||||
if (hashStart !== -1) {
|
|
||||||
input = input.slice(0, hashStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getHash(url) {
|
|
||||||
let hash = '';
|
|
||||||
const hashStart = url.indexOf('#');
|
|
||||||
if (hashStart !== -1) {
|
|
||||||
hash = url.slice(hashStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
function extract(input) {
|
|
||||||
input = removeHash(input);
|
|
||||||
const queryStart = input.indexOf('?');
|
|
||||||
if (queryStart === -1) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return input.slice(queryStart + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseValue(value, options) {
|
|
||||||
if (options.parseNumbers && !Number.isNaN(Number(value)) && (typeof value === 'string' && value.trim() !== '')) {
|
|
||||||
value = Number(value);
|
|
||||||
} else if (options.parseBooleans && value !== null && (value.toLowerCase() === 'true' || value.toLowerCase() === 'false')) {
|
|
||||||
value = value.toLowerCase() === 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function parse(query, options) {
|
|
||||||
options = Object.assign({
|
|
||||||
decode: true,
|
|
||||||
sort: true,
|
|
||||||
arrayFormat: 'none',
|
|
||||||
arrayFormatSeparator: ',',
|
|
||||||
parseNumbers: false,
|
|
||||||
parseBooleans: false
|
|
||||||
}, options);
|
|
||||||
|
|
||||||
validateArrayFormatSeparator(options.arrayFormatSeparator);
|
|
||||||
|
|
||||||
const formatter = parserForArrayFormat(options);
|
|
||||||
|
|
||||||
// Create an object with no prototype
|
|
||||||
const ret = Object.create(null);
|
|
||||||
|
|
||||||
if (typeof query !== 'string') {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
query = query.trim().replace(/^[?#&]/, '');
|
|
||||||
|
|
||||||
if (!query) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const param of query.split('&')) {
|
|
||||||
if (param === '') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let [key, value] = splitOnFirst(options.decode ? param.replace(/\+/g, ' ') : param, '=');
|
|
||||||
|
|
||||||
// Missing `=` should be `null`:
|
|
||||||
// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
|
|
||||||
value = value === undefined ? null : ['comma', 'separator', 'bracket-separator'].includes(options.arrayFormat) ? value : decode(value, options);
|
|
||||||
formatter(decode(key, options), value, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const key of Object.keys(ret)) {
|
|
||||||
const value = ret[key];
|
|
||||||
if (typeof value === 'object' && value !== null) {
|
|
||||||
for (const k of Object.keys(value)) {
|
|
||||||
value[k] = parseValue(value[k], options);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ret[key] = parseValue(value, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.sort === false) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (options.sort === true ? Object.keys(ret).sort() : Object.keys(ret).sort(options.sort)).reduce((result, key) => {
|
|
||||||
const value = ret[key];
|
|
||||||
if (Boolean(value) && typeof value === 'object' && !Array.isArray(value)) {
|
|
||||||
// Sort object keys, not values
|
|
||||||
result[key] = keysSorter(value);
|
|
||||||
} else {
|
|
||||||
result[key] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}, Object.create(null));
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.extract = extract;
|
|
||||||
exports.parse = parse;
|
|
||||||
|
|
||||||
exports.stringify = (object, options) => {
|
|
||||||
if (!object) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
options = Object.assign({
|
|
||||||
encode: true,
|
|
||||||
strict: true,
|
|
||||||
arrayFormat: 'none',
|
|
||||||
arrayFormatSeparator: ','
|
|
||||||
}, options);
|
|
||||||
|
|
||||||
validateArrayFormatSeparator(options.arrayFormatSeparator);
|
|
||||||
|
|
||||||
const shouldFilter = key => (
|
|
||||||
(options.skipNull && isNullOrUndefined(object[key])) ||
|
|
||||||
(options.skipEmptyString && object[key] === '')
|
|
||||||
);
|
|
||||||
|
|
||||||
const formatter = encoderForArrayFormat(options);
|
|
||||||
|
|
||||||
const objectCopy = {};
|
|
||||||
|
|
||||||
for (const key of Object.keys(object)) {
|
|
||||||
if (!shouldFilter(key)) {
|
|
||||||
objectCopy[key] = object[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const keys = Object.keys(objectCopy);
|
|
||||||
|
|
||||||
if (options.sort !== false) {
|
|
||||||
keys.sort(options.sort);
|
|
||||||
}
|
|
||||||
|
|
||||||
return keys.map(key => {
|
|
||||||
const value = object[key];
|
|
||||||
|
|
||||||
if (value === undefined) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value === null) {
|
|
||||||
return encode(key, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
|
||||||
if (value.length === 0 && options.arrayFormat === 'bracket-separator') {
|
|
||||||
return encode(key, options) + '[]';
|
|
||||||
}
|
|
||||||
|
|
||||||
return value
|
|
||||||
.reduce(formatter(key), [])
|
|
||||||
.join('&');
|
|
||||||
}
|
|
||||||
|
|
||||||
return encode(key, options) + '=' + encode(value, options);
|
|
||||||
}).filter(x => x.length > 0).join('&');
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.parseUrl = (url, options) => {
|
|
||||||
options = Object.assign({
|
|
||||||
decode: true
|
|
||||||
}, options);
|
|
||||||
|
|
||||||
const [url_, hash] = splitOnFirst(url, '#');
|
|
||||||
|
|
||||||
return Object.assign(
|
|
||||||
{
|
|
||||||
url: url_.split('?')[0] || '',
|
|
||||||
query: parse(extract(url), options)
|
|
||||||
},
|
|
||||||
options && options.parseFragmentIdentifier && hash ? {fragmentIdentifier: decode(hash, options)} : {}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.stringifyUrl = (object, options) => {
|
|
||||||
options = Object.assign({
|
|
||||||
encode: true,
|
|
||||||
strict: true,
|
|
||||||
[encodeFragmentIdentifier]: true
|
|
||||||
}, options);
|
|
||||||
|
|
||||||
const url = removeHash(object.url).split('?')[0] || '';
|
|
||||||
const queryFromUrl = exports.extract(object.url);
|
|
||||||
const parsedQueryFromUrl = exports.parse(queryFromUrl, {sort: false});
|
|
||||||
|
|
||||||
const query = Object.assign(parsedQueryFromUrl, object.query);
|
|
||||||
let queryString = exports.stringify(query, options);
|
|
||||||
if (queryString) {
|
|
||||||
queryString = `?${queryString}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
let hash = getHash(object.url);
|
|
||||||
if (object.fragmentIdentifier) {
|
|
||||||
hash = `#${options[encodeFragmentIdentifier] ? encode(object.fragmentIdentifier, options) : object.fragmentIdentifier}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${url}${queryString}${hash}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.pick = (input, filter, options) => {
|
|
||||||
options = Object.assign({
|
|
||||||
parseFragmentIdentifier: true,
|
|
||||||
[encodeFragmentIdentifier]: false
|
|
||||||
}, options);
|
|
||||||
|
|
||||||
const {url, query, fragmentIdentifier} = exports.parseUrl(input, options);
|
|
||||||
return exports.stringifyUrl({
|
|
||||||
url,
|
|
||||||
query: filterObject(query, filter),
|
|
||||||
fragmentIdentifier
|
|
||||||
}, options);
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.exclude = (input, filter, options) => {
|
|
||||||
const exclusionFilter = Array.isArray(filter) ? key => !filter.includes(key) : (key, value) => !filter(key, value);
|
|
||||||
|
|
||||||
return exports.pick(input, exclusionFilter, options);
|
|
||||||
};
|
|
||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (http://sindresorhus.com)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
-54
@@ -1,54 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "query-string",
|
|
||||||
"version": "7.0.1",
|
|
||||||
"description": "Parse and stringify URL query strings",
|
|
||||||
"license": "MIT",
|
|
||||||
"repository": "sindresorhus/query-string",
|
|
||||||
"funding": "https://github.com/sponsors/sindresorhus",
|
|
||||||
"author": {
|
|
||||||
"name": "Sindre Sorhus",
|
|
||||||
"email": "sindresorhus@gmail.com",
|
|
||||||
"url": "https://sindresorhus.com"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"benchmark": "node benchmark.js",
|
|
||||||
"test": "xo && ava && tsd"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"index.js",
|
|
||||||
"index.d.ts"
|
|
||||||
],
|
|
||||||
"keywords": [
|
|
||||||
"browser",
|
|
||||||
"querystring",
|
|
||||||
"query",
|
|
||||||
"string",
|
|
||||||
"qs",
|
|
||||||
"param",
|
|
||||||
"parameter",
|
|
||||||
"url",
|
|
||||||
"parse",
|
|
||||||
"stringify",
|
|
||||||
"encode",
|
|
||||||
"decode",
|
|
||||||
"searchparams",
|
|
||||||
"filter"
|
|
||||||
],
|
|
||||||
"dependencies": {
|
|
||||||
"decode-uri-component": "^0.2.0",
|
|
||||||
"filter-obj": "^1.1.0",
|
|
||||||
"split-on-first": "^1.0.0",
|
|
||||||
"strict-uri-encode": "^2.0.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"ava": "^1.4.1",
|
|
||||||
"benchmark": "^2.1.4",
|
|
||||||
"deep-equal": "^1.0.1",
|
|
||||||
"fast-check": "^1.5.0",
|
|
||||||
"tsd": "^0.7.3",
|
|
||||||
"xo": "^0.24.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-633
@@ -1,633 +0,0 @@
|
|||||||
# query-string
|
|
||||||
|
|
||||||
> Parse and stringify URL [query strings](https://en.wikipedia.org/wiki/Query_string)
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<div align="center">
|
|
||||||
<p>
|
|
||||||
<p>
|
|
||||||
<sup>
|
|
||||||
<a href="https://github.com/sponsors/sindresorhus">My open source work is supported by the community</a>
|
|
||||||
</sup>
|
|
||||||
</p>
|
|
||||||
<sup>Special thanks to:</sup>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<a href="https://standardresume.co/tech">
|
|
||||||
<img src="https://sindresorhus.com/assets/thanks/standard-resume-logo.svg" width="180"/>
|
|
||||||
</a>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<a href="https://doppler.com/?utm_campaign=github_repo&utm_medium=referral&utm_content=query-string&utm_source=github">
|
|
||||||
<div>
|
|
||||||
<img src="https://dashboard.doppler.com/imgs/logo-long.svg" width="240" alt="Doppler">
|
|
||||||
</div>
|
|
||||||
<b>All your environment variables, in one place</b>
|
|
||||||
<div>
|
|
||||||
<span>Stop struggling with scattered API keys, hacking together home-brewed tools,</span>
|
|
||||||
<br>
|
|
||||||
<span>and avoiding access controls. Keep your team and servers in sync with Doppler.</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<br>
|
|
||||||
<a href="https://strapi.io/?ref=sindresorhus">
|
|
||||||
<div>
|
|
||||||
<img src="https://sindresorhus.com/assets/thanks/strapi-logo-white-bg.png" width="200" alt="Strapi">
|
|
||||||
</div>
|
|
||||||
<b>Strapi is the leading open-source headless CMS.</b>
|
|
||||||
<div>
|
|
||||||
<sup>It’s 100% JavaScript, fully customizable, and developer-first.</sup>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<br>
|
|
||||||
<a href="https://oss.capital">
|
|
||||||
<div>
|
|
||||||
<img src="https://sindresorhus.com/assets/thanks/oss-capital-logo-white-bg.svg" width="300" alt="OSS Capital">
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<sup><b>Founded in 2018, OSS Capital is the first and only venture capital platform focused<br>exclusively on supporting early-stage COSS (commercial open source) startup founders.</b></sup>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
```
|
|
||||||
$ npm install query-string
|
|
||||||
```
|
|
||||||
|
|
||||||
**Not `npm install querystring`!!!!!**
|
|
||||||
|
|
||||||
This module targets Node.js 6 or later and the latest version of Chrome, Firefox, and Safari.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
console.log(location.search);
|
|
||||||
//=> '?foo=bar'
|
|
||||||
|
|
||||||
const parsed = queryString.parse(location.search);
|
|
||||||
console.log(parsed);
|
|
||||||
//=> {foo: 'bar'}
|
|
||||||
|
|
||||||
console.log(location.hash);
|
|
||||||
//=> '#token=bada55cafe'
|
|
||||||
|
|
||||||
const parsedHash = queryString.parse(location.hash);
|
|
||||||
console.log(parsedHash);
|
|
||||||
//=> {token: 'bada55cafe'}
|
|
||||||
|
|
||||||
parsed.foo = 'unicorn';
|
|
||||||
parsed.ilike = 'pizza';
|
|
||||||
|
|
||||||
const stringified = queryString.stringify(parsed);
|
|
||||||
//=> 'foo=unicorn&ilike=pizza'
|
|
||||||
|
|
||||||
location.search = stringified;
|
|
||||||
// note that `location.search` automatically prepends a question mark
|
|
||||||
console.log(location.search);
|
|
||||||
//=> '?foo=unicorn&ilike=pizza'
|
|
||||||
```
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### .parse(string, options?)
|
|
||||||
|
|
||||||
Parse a query string into an object. Leading `?` or `#` are ignored, so you can pass `location.search` or `location.hash` directly.
|
|
||||||
|
|
||||||
The returned object is created with [`Object.create(null)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create) and thus does not have a `prototype`.
|
|
||||||
|
|
||||||
#### options
|
|
||||||
|
|
||||||
Type: `object`
|
|
||||||
|
|
||||||
##### decode
|
|
||||||
|
|
||||||
Type: `boolean`\
|
|
||||||
Default: `true`
|
|
||||||
|
|
||||||
Decode the keys and values. URL components are decoded with [`decode-uri-component`](https://github.com/SamVerschueren/decode-uri-component).
|
|
||||||
|
|
||||||
##### arrayFormat
|
|
||||||
|
|
||||||
Type: `string`\
|
|
||||||
Default: `'none'`
|
|
||||||
|
|
||||||
- `'bracket'`: Parse arrays with bracket representation:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo[]=1&foo[]=2&foo[]=3', {arrayFormat: 'bracket'});
|
|
||||||
//=> {foo: ['1', '2', '3']}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `'index'`: Parse arrays with index representation:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo[0]=1&foo[1]=2&foo[3]=3', {arrayFormat: 'index'});
|
|
||||||
//=> {foo: ['1', '2', '3']}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `'comma'`: Parse arrays with elements separated by comma:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo=1,2,3', {arrayFormat: 'comma'});
|
|
||||||
//=> {foo: ['1', '2', '3']}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `'separator'`: Parse arrays with elements separated by a custom character:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo=1|2|3', {arrayFormat: 'separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> {foo: ['1', '2', '3']}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `'bracket-separator'`: Parse arrays (that are explicitly marked with brackets) with elements separated by a custom character:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo[]', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> {foo: []}
|
|
||||||
|
|
||||||
queryString.parse('foo[]=', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> {foo: ['']}
|
|
||||||
|
|
||||||
queryString.parse('foo[]=1', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> {foo: ['1']}
|
|
||||||
|
|
||||||
queryString.parse('foo[]=1|2|3', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> {foo: ['1', '2', '3']}
|
|
||||||
|
|
||||||
queryString.parse('foo[]=1||3|||6', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> {foo: ['1', '', 3, '', '', '6']}
|
|
||||||
|
|
||||||
queryString.parse('foo[]=1|2|3&bar=fluffy&baz[]=4', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> {foo: ['1', '2', '3'], bar: 'fluffy', baz:['4']}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `'none'`: Parse arrays with elements using duplicate keys:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo=1&foo=2&foo=3');
|
|
||||||
//=> {foo: ['1', '2', '3']}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### arrayFormatSeparator
|
|
||||||
|
|
||||||
Type: `string`\
|
|
||||||
Default: `','`
|
|
||||||
|
|
||||||
The character used to separate array elements when using `{arrayFormat: 'separator'}`.
|
|
||||||
|
|
||||||
##### sort
|
|
||||||
|
|
||||||
Type: `Function | boolean`\
|
|
||||||
Default: `true`
|
|
||||||
|
|
||||||
Supports both `Function` as a custom sorting function or `false` to disable sorting.
|
|
||||||
|
|
||||||
##### parseNumbers
|
|
||||||
|
|
||||||
Type: `boolean`\
|
|
||||||
Default: `false`
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo=1', {parseNumbers: true});
|
|
||||||
//=> {foo: 1}
|
|
||||||
```
|
|
||||||
|
|
||||||
Parse the value as a number type instead of string type if it's a number.
|
|
||||||
|
|
||||||
##### parseBooleans
|
|
||||||
|
|
||||||
Type: `boolean`\
|
|
||||||
Default: `false`
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('foo=true', {parseBooleans: true});
|
|
||||||
//=> {foo: true}
|
|
||||||
```
|
|
||||||
|
|
||||||
Parse the value as a boolean type instead of string type if it's a boolean.
|
|
||||||
|
|
||||||
### .stringify(object, options?)
|
|
||||||
|
|
||||||
Stringify an object into a query string and sorting the keys.
|
|
||||||
|
|
||||||
#### options
|
|
||||||
|
|
||||||
Type: `object`
|
|
||||||
|
|
||||||
##### strict
|
|
||||||
|
|
||||||
Type: `boolean`\
|
|
||||||
Default: `true`
|
|
||||||
|
|
||||||
Strictly encode URI components with [strict-uri-encode](https://github.com/kevva/strict-uri-encode). It uses [encodeURIComponent](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) if set to false. You probably [don't care](https://github.com/sindresorhus/query-string/issues/42) about this option.
|
|
||||||
|
|
||||||
##### encode
|
|
||||||
|
|
||||||
Type: `boolean`\
|
|
||||||
Default: `true`
|
|
||||||
|
|
||||||
[URL encode](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) the keys and values.
|
|
||||||
|
|
||||||
##### arrayFormat
|
|
||||||
|
|
||||||
Type: `string`\
|
|
||||||
Default: `'none'`
|
|
||||||
|
|
||||||
- `'bracket'`: Serialize arrays using bracket representation:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'bracket'});
|
|
||||||
//=> 'foo[]=1&foo[]=2&foo[]=3'
|
|
||||||
```
|
|
||||||
|
|
||||||
- `'index'`: Serialize arrays using index representation:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'index'});
|
|
||||||
//=> 'foo[0]=1&foo[1]=2&foo[2]=3'
|
|
||||||
```
|
|
||||||
|
|
||||||
- `'comma'`: Serialize arrays by separating elements with comma:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'comma'});
|
|
||||||
//=> 'foo=1,2,3'
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, null, '']}, {arrayFormat: 'comma'});
|
|
||||||
//=> 'foo=1,,'
|
|
||||||
// Note that typing information for null values is lost
|
|
||||||
// and `.parse('foo=1,,')` would return `{foo: [1, '', '']}`.
|
|
||||||
```
|
|
||||||
|
|
||||||
- `'separator'`: Serialize arrays by separating elements with a custom character:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> 'foo=1|2|3'
|
|
||||||
```
|
|
||||||
|
|
||||||
- `'bracket-separator'`: Serialize arrays by explicitly post-fixing array names with brackets and separating elements with a custom character:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({foo: []}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> 'foo[]'
|
|
||||||
|
|
||||||
queryString.stringify({foo: ['']}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> 'foo[]='
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> 'foo[]=1'
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> 'foo[]=1|2|3'
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, '', 3, null, null, 6]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> 'foo[]=1||3|||6'
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, '', 3, null, null, 6]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|', skipNull: true});
|
|
||||||
//=> 'foo[]=1||3|6'
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, 2, 3], bar: 'fluffy', baz: [4]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
|
|
||||||
//=> 'foo[]=1|2|3&bar=fluffy&baz[]=4'
|
|
||||||
```
|
|
||||||
|
|
||||||
- `'none'`: Serialize arrays by using duplicate keys:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({foo: [1, 2, 3]});
|
|
||||||
//=> 'foo=1&foo=2&foo=3'
|
|
||||||
```
|
|
||||||
|
|
||||||
##### arrayFormatSeparator
|
|
||||||
|
|
||||||
Type: `string`\
|
|
||||||
Default: `','`
|
|
||||||
|
|
||||||
The character used to separate array elements when using `{arrayFormat: 'separator'}`.
|
|
||||||
|
|
||||||
##### sort
|
|
||||||
|
|
||||||
Type: `Function | boolean`
|
|
||||||
|
|
||||||
Supports both `Function` as a custom sorting function or `false` to disable sorting.
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
const order = ['c', 'a', 'b'];
|
|
||||||
|
|
||||||
queryString.stringify({a: 1, b: 2, c: 3}, {
|
|
||||||
sort: (a, b) => order.indexOf(a) - order.indexOf(b)
|
|
||||||
});
|
|
||||||
//=> 'c=3&a=1&b=2'
|
|
||||||
```
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({b: 1, c: 2, a: 3}, {sort: false});
|
|
||||||
//=> 'b=1&c=2&a=3'
|
|
||||||
```
|
|
||||||
|
|
||||||
If omitted, keys are sorted using `Array#sort()`, which means, converting them to strings and comparing strings in Unicode code point order.
|
|
||||||
|
|
||||||
##### skipNull
|
|
||||||
|
|
||||||
Skip keys with `null` as the value.
|
|
||||||
|
|
||||||
Note that keys with `undefined` as the value are always skipped.
|
|
||||||
|
|
||||||
Type: `boolean`\
|
|
||||||
Default: `false`
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({a: 1, b: undefined, c: null, d: 4}, {
|
|
||||||
skipNull: true
|
|
||||||
});
|
|
||||||
//=> 'a=1&d=4'
|
|
||||||
```
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({a: undefined, b: null}, {
|
|
||||||
skipNull: true
|
|
||||||
});
|
|
||||||
//=> ''
|
|
||||||
```
|
|
||||||
|
|
||||||
##### skipEmptyString
|
|
||||||
|
|
||||||
Skip keys with an empty string as the value.
|
|
||||||
|
|
||||||
Type: `boolean`\
|
|
||||||
Default: `false`
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({a: 1, b: '', c: '', d: 4}, {
|
|
||||||
skipEmptyString: true
|
|
||||||
});
|
|
||||||
//=> 'a=1&d=4'
|
|
||||||
```
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({a: '', b: ''}, {
|
|
||||||
skipEmptyString: true
|
|
||||||
});
|
|
||||||
//=> ''
|
|
||||||
```
|
|
||||||
|
|
||||||
### .extract(string)
|
|
||||||
|
|
||||||
Extract a query string from a URL that can be passed into `.parse()`.
|
|
||||||
|
|
||||||
Note: This behaviour can be changed with the `skipNull` option.
|
|
||||||
|
|
||||||
### .parseUrl(string, options?)
|
|
||||||
|
|
||||||
Extract the URL and the query string as an object.
|
|
||||||
|
|
||||||
Returns an object with a `url` and `query` property.
|
|
||||||
|
|
||||||
If the `parseFragmentIdentifier` option is `true`, the object will also contain a `fragmentIdentifier` property.
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parseUrl('https://foo.bar?foo=bar');
|
|
||||||
//=> {url: 'https://foo.bar', query: {foo: 'bar'}}
|
|
||||||
|
|
||||||
queryString.parseUrl('https://foo.bar?foo=bar#xyz', {parseFragmentIdentifier: true});
|
|
||||||
//=> {url: 'https://foo.bar', query: {foo: 'bar'}, fragmentIdentifier: 'xyz'}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### options
|
|
||||||
|
|
||||||
Type: `object`
|
|
||||||
|
|
||||||
The options are the same as for `.parse()`.
|
|
||||||
|
|
||||||
Extra options are as below.
|
|
||||||
|
|
||||||
##### parseFragmentIdentifier
|
|
||||||
|
|
||||||
Parse the fragment identifier from the URL.
|
|
||||||
|
|
||||||
Type: `boolean`\
|
|
||||||
Default: `false`
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parseUrl('https://foo.bar?foo=bar#xyz', {parseFragmentIdentifier: true});
|
|
||||||
//=> {url: 'https://foo.bar', query: {foo: 'bar'}, fragmentIdentifier: 'xyz'}
|
|
||||||
```
|
|
||||||
|
|
||||||
### .stringifyUrl(object, options?)
|
|
||||||
|
|
||||||
Stringify an object into a URL with a query string and sorting the keys. The inverse of [`.parseUrl()`](https://github.com/sindresorhus/query-string#parseurlstring-options)
|
|
||||||
|
|
||||||
The `options` are the same as for `.stringify()`.
|
|
||||||
|
|
||||||
Returns a string with the URL and a query string.
|
|
||||||
|
|
||||||
Query items in the `query` property overrides queries in the `url` property.
|
|
||||||
|
|
||||||
The `fragmentIdentifier` property overrides the fragment identifier in the `url` property.
|
|
||||||
|
|
||||||
```js
|
|
||||||
queryString.stringifyUrl({url: 'https://foo.bar', query: {foo: 'bar'}});
|
|
||||||
//=> 'https://foo.bar?foo=bar'
|
|
||||||
|
|
||||||
queryString.stringifyUrl({url: 'https://foo.bar?foo=baz', query: {foo: 'bar'}});
|
|
||||||
//=> 'https://foo.bar?foo=bar'
|
|
||||||
|
|
||||||
queryString.stringifyUrl({
|
|
||||||
url: 'https://foo.bar',
|
|
||||||
query: {
|
|
||||||
top: 'foo'
|
|
||||||
},
|
|
||||||
fragmentIdentifier: 'bar'
|
|
||||||
});
|
|
||||||
//=> 'https://foo.bar?top=foo#bar'
|
|
||||||
```
|
|
||||||
|
|
||||||
#### object
|
|
||||||
|
|
||||||
Type: `object`
|
|
||||||
|
|
||||||
##### url
|
|
||||||
|
|
||||||
Type: `string`
|
|
||||||
|
|
||||||
The URL to stringify.
|
|
||||||
|
|
||||||
##### query
|
|
||||||
|
|
||||||
Type: `object`
|
|
||||||
|
|
||||||
Query items to add to the URL.
|
|
||||||
|
|
||||||
### .pick(url, keys, options?)
|
|
||||||
### .pick(url, filter, options?)
|
|
||||||
|
|
||||||
Pick query parameters from a URL.
|
|
||||||
|
|
||||||
Returns a string with the new URL.
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.pick('https://foo.bar?foo=1&bar=2#hello', ['foo']);
|
|
||||||
//=> 'https://foo.bar?foo=1#hello'
|
|
||||||
|
|
||||||
queryString.pick('https://foo.bar?foo=1&bar=2#hello', (name, value) => value === 2, {parseNumbers: true});
|
|
||||||
//=> 'https://foo.bar?bar=2#hello'
|
|
||||||
```
|
|
||||||
|
|
||||||
### .exclude(url, keys, options?)
|
|
||||||
### .exclude(url, filter, options?)
|
|
||||||
|
|
||||||
Exclude query parameters from a URL.
|
|
||||||
|
|
||||||
Returns a string with the new URL.
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.exclude('https://foo.bar?foo=1&bar=2#hello', ['foo']);
|
|
||||||
//=> 'https://foo.bar?bar=2#hello'
|
|
||||||
|
|
||||||
queryString.exclude('https://foo.bar?foo=1&bar=2#hello', (name, value) => value === 2, {parseNumbers: true});
|
|
||||||
//=> 'https://foo.bar?foo=1#hello'
|
|
||||||
```
|
|
||||||
|
|
||||||
#### url
|
|
||||||
|
|
||||||
Type: `string`
|
|
||||||
|
|
||||||
The URL containing the query parameters to filter.
|
|
||||||
|
|
||||||
#### keys
|
|
||||||
|
|
||||||
Type: `string[]`
|
|
||||||
|
|
||||||
The names of the query parameters to filter based on the function used.
|
|
||||||
|
|
||||||
#### filter
|
|
||||||
|
|
||||||
Type: `(key, value) => boolean`
|
|
||||||
|
|
||||||
A filter predicate that will be provided the name of each query parameter and its value. The `parseNumbers` and `parseBooleans` options also affect `value`.
|
|
||||||
|
|
||||||
#### options
|
|
||||||
|
|
||||||
Type: `object`
|
|
||||||
|
|
||||||
[Parse options](#options) and [stringify options](#options-1).
|
|
||||||
|
|
||||||
## Nesting
|
|
||||||
|
|
||||||
This module intentionally doesn't support nesting as it's not spec'd and varies between implementations, which causes a lot of [edge cases](https://github.com/visionmedia/node-querystring/issues).
|
|
||||||
|
|
||||||
You're much better off just converting the object to a JSON string:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({
|
|
||||||
foo: 'bar',
|
|
||||||
nested: JSON.stringify({
|
|
||||||
unicorn: 'cake'
|
|
||||||
})
|
|
||||||
});
|
|
||||||
//=> 'foo=bar&nested=%7B%22unicorn%22%3A%22cake%22%7D'
|
|
||||||
```
|
|
||||||
|
|
||||||
However, there is support for multiple instances of the same key:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.parse('likes=cake&name=bob&likes=icecream');
|
|
||||||
//=> {likes: ['cake', 'icecream'], name: 'bob'}
|
|
||||||
|
|
||||||
queryString.stringify({color: ['taupe', 'chartreuse'], id: '515'});
|
|
||||||
//=> 'color=taupe&color=chartreuse&id=515'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Falsy values
|
|
||||||
|
|
||||||
Sometimes you want to unset a key, or maybe just make it present without assigning a value to it. Here is how falsy values are stringified:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const queryString = require('query-string');
|
|
||||||
|
|
||||||
queryString.stringify({foo: false});
|
|
||||||
//=> 'foo=false'
|
|
||||||
|
|
||||||
queryString.stringify({foo: null});
|
|
||||||
//=> 'foo'
|
|
||||||
|
|
||||||
queryString.stringify({foo: undefined});
|
|
||||||
//=> ''
|
|
||||||
```
|
|
||||||
|
|
||||||
## FAQ
|
|
||||||
|
|
||||||
### Why is it parsing `+` as a space?
|
|
||||||
|
|
||||||
See [this answer](https://github.com/sindresorhus/query-string/issues/305).
|
|
||||||
|
|
||||||
## query-string for enterprise
|
|
||||||
|
|
||||||
Available as part of the Tidelift Subscription.
|
|
||||||
|
|
||||||
The maintainers of query-string and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-query-string?utm_source=npm-query-string&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
/**
|
|
||||||
Split a string on the first occurrence of a given separator.
|
|
||||||
|
|
||||||
@param string - The string to split.
|
|
||||||
@param separator - The separator to split on.
|
|
||||||
|
|
||||||
@example
|
|
||||||
```
|
|
||||||
import splitOnFirst = require('split-on-first');
|
|
||||||
|
|
||||||
splitOnFirst('a-b-c', '-');
|
|
||||||
//=> ['a', 'b-c']
|
|
||||||
|
|
||||||
splitOnFirst('key:value:value2', ':');
|
|
||||||
//=> ['key', 'value:value2']
|
|
||||||
|
|
||||||
splitOnFirst('a---b---c', '---');
|
|
||||||
//=> ['a', 'b---c']
|
|
||||||
|
|
||||||
splitOnFirst('a-b-c', '+');
|
|
||||||
//=> ['a-b-c']
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
declare function splitOnFirst(
|
|
||||||
string: string,
|
|
||||||
separator: string
|
|
||||||
): [string, string?];
|
|
||||||
|
|
||||||
export = splitOnFirst;
|
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
module.exports = (string, separator) => {
|
|
||||||
if (!(typeof string === 'string' && typeof separator === 'string')) {
|
|
||||||
throw new TypeError('Expected the arguments to be of type `string`');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (separator === '') {
|
|
||||||
return [string];
|
|
||||||
}
|
|
||||||
|
|
||||||
const separatorIndex = string.indexOf(separator);
|
|
||||||
|
|
||||||
if (separatorIndex === -1) {
|
|
||||||
return [string];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
string.slice(0, separatorIndex),
|
|
||||||
string.slice(separatorIndex + separator.length)
|
|
||||||
];
|
|
||||||
};
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user