mirror of
https://github.com/github/codeql-action.git
synced 2026-05-24 16:14:33 +00:00
Compare commits
249 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ba697a3ec | |||
| 74374a3893 | |||
| 3e85884434 | |||
| 5aed9f7d64 | |||
| f9feddd874 | |||
| 15f19e1870 | |||
| 51cc08af6f | |||
| 71b697dd8b | |||
| f5808271b0 | |||
| da26a016ee | |||
| 4536424fcf | |||
| d98bedfdea | |||
| 952a538c24 | |||
| 04d4fd51e9 | |||
| c05837d3e8 | |||
| c8a3492b26 | |||
| e94195c896 | |||
| 05e8f288eb | |||
| b71f5aebfc | |||
| 2365a46087 | |||
| cf51dca1af | |||
| b30a935ea5 | |||
| 5b815f25ca | |||
| 93c8a9ed99 | |||
| 2a02de1a14 | |||
| 67f403822c | |||
| bbef5ff663 | |||
| 7187b6ecc7 | |||
| f1ce9f4421 | |||
| 06c7e6fdd5 | |||
| 9e0d7b8d25 | |||
| 6d7d59927c | |||
| 51f7e38c69 | |||
| b43bb7bd69 | |||
| 064674dfa3 | |||
| ab5047bf8f | |||
| 2320f9d058 | |||
| 46959216a2 | |||
| 9e1f914560 | |||
| db84cb5ccb | |||
| d4b485515e | |||
| 931147e852 | |||
| 127de8117f | |||
| 7fde13f26a | |||
| dfa61e7305 | |||
| 52aafec073 | |||
| 0d08c01f78 | |||
| 1b65777c19 | |||
| 14085a675c | |||
| a32db48565 | |||
| aa005faaad | |||
| fcdf5dd4cf | |||
| e8d3fa290e | |||
| eb17ca4f4d | |||
| a41c444cd9 | |||
| d7e50c23fe | |||
| bb30f3132d | |||
| 336884853e | |||
| 2f137c9dc6 | |||
| 4795ef8153 | |||
| f0489abddd | |||
| 2e202367c7 | |||
| 9d7243005b | |||
| 237b03b3c3 | |||
| d4eab006fa | |||
| ea37b337cd | |||
| ba0a2f91b7 | |||
| 4041a11865 | |||
| 2a6fe1608c | |||
| 3c8c0ae6cb | |||
| 93d215d874 | |||
| 3d6ea97f26 | |||
| 7d25a3e590 | |||
| 4dc72761a6 | |||
| 9c3aedb4cd | |||
| a66f7bbb5a | |||
| b986640672 | |||
| a333d64ec4 | |||
| 97fb30df6b | |||
| d122da3c9f | |||
| de3e561d12 | |||
| c559992c9e | |||
| 6a4e35fad9 | |||
| 8d217609b0 | |||
| 257b3d3fc8 | |||
| 201a96b541 | |||
| 312a2fee96 | |||
| 2ca0fbdca8 | |||
| 12c1d88854 | |||
| 70419e3273 | |||
| b62aaa99a5 | |||
| 2f2dbd2e78 | |||
| b4ea7aa65a | |||
| 87ac48dae6 | |||
| 42d7f62579 | |||
| 540699dcca | |||
| 9a85234875 | |||
| 2a950b930c | |||
| 4f815a68d3 | |||
| 0aedbb71d8 | |||
| 868e2ea564 | |||
| 792c223bc1 | |||
| efc9b0a9e3 | |||
| 272ada693f | |||
| 610a6682b6 | |||
| 1627096569 | |||
| 68bde559de | |||
| 9739ad2d18 | |||
| b81d0d250f | |||
| a16cb53dd8 | |||
| 803d9e8c3c | |||
| 0c80cee806 | |||
| d032ee8c47 | |||
| 0fd9c7d135 | |||
| 922d6fb888 | |||
| df77e87896 | |||
| 6e3f985e4f | |||
| e7a347dfb1 | |||
| 17eabb2500 | |||
| aaef09c48d | |||
| ae1b9155d3 | |||
| 9f82f88f07 | |||
| 7525c68ea1 | |||
| 01bc9be56a | |||
| 9d6b456c59 | |||
| e259d26055 | |||
| 817b68489e | |||
| 1b5632783c | |||
| 1848b73afa | |||
| d1e9792bc8 | |||
| 2c9cd77837 | |||
| b967fdfbdc | |||
| 55d6319f96 | |||
| b0942116d7 | |||
| bc0b696b41 | |||
| a796e3e4ed | |||
| f9bb0e001c | |||
| 4b7faf0b3d | |||
| 09a1d9ec2a | |||
| f64a4491cf | |||
| 7fc86e0c37 | |||
| 5997e25ad9 | |||
| 7587714d0a | |||
| 8ab64a211d | |||
| a723e99345 | |||
| fbba1e03be | |||
| 933238e8d5 | |||
| e46ed2cbd0 | |||
| b73d1d1634 | |||
| 24e0bb00a9 | |||
| ec298daba7 | |||
| f8b93c30a6 | |||
| 8c6e48dbe0 | |||
| 80a72986d3 | |||
| e9e36aec74 | |||
| 719098349e | |||
| 2bb209555a | |||
| 4ed52dcbfa | |||
| 3cc8dd3e59 | |||
| 7851e55dc3 | |||
| 262a15f6cf | |||
| a6109b1c07 | |||
| 022ff3c73f | |||
| 0a4d574ac4 | |||
| d1edf2e4de | |||
| facd53f789 | |||
| b77983290b | |||
| fcf29e3d86 | |||
| 1fed3e9ba8 | |||
| 549683cee5 | |||
| 7a6ed56219 | |||
| 91fbc51606 | |||
| 35715ef8fe | |||
| bac7fdaf42 | |||
| 1517969c90 | |||
| f073360456 | |||
| 5145c112e7 | |||
| 7108503ac6 | |||
| 4fe9b1e243 | |||
| 56733fb5ae | |||
| 0a636086c9 | |||
| 97be3af35a | |||
| de303a9db5 | |||
| 7a818e6977 | |||
| 30e0f4391d | |||
| 7c5585e5cf | |||
| 245f6828c4 | |||
| c109008fac | |||
| e73c940c9b | |||
| cdb655d6d4 | |||
| 6153577cab | |||
| 8f02cfa11d | |||
| 0ed734b61b | |||
| efdcb31f11 | |||
| 4d2c7c6e10 | |||
| 70b2658d23 | |||
| 530fcb3bbf | |||
| 2acf81942b | |||
| d2a54a4507 | |||
| bc4097bbe1 | |||
| c8e26e209a | |||
| 0752451507 | |||
| 243c274daf | |||
| 5ded561dcd | |||
| 19b3a84f58 | |||
| faca00d3ae | |||
| 858a6149c1 | |||
| 5d1c58464f | |||
| c60c75576d | |||
| 59aede2113 | |||
| 6c35f8607b | |||
| c486cacf49 | |||
| 365478cc5b | |||
| f0e6490756 | |||
| 860353f245 | |||
| 4fb8483ef0 | |||
| c2574efbee | |||
| 4cbe7bef85 | |||
| f6a5638305 | |||
| 1279e8d41c | |||
| af1f613989 | |||
| 5026833be5 | |||
| 201ddc275d | |||
| 1dcdb940d5 | |||
| 0b7b740d4c | |||
| 0ac85966ba | |||
| 5019ed041c | |||
| d64d81d41f | |||
| 6777c894e9 | |||
| 79f9c0517c | |||
| 3b3a77544b | |||
| 9f95de42d6 | |||
| e2d518d895 | |||
| 9df9e9176e | |||
| 6847a42aa8 | |||
| f820c80d4d | |||
| ca7d6d3b79 | |||
| 8d9c36a0ce | |||
| f8b62132ab | |||
| 90d7616015 | |||
| 1aef4ed505 | |||
| cb52ba6486 | |||
| 7c9e131894 | |||
| 130ab2d721 | |||
| 8cf2dc52f9 | |||
| 97bcdd8c1e | |||
| e6c21da23c | |||
| bad0a744dd | |||
| 4ea3a4b4af |
@@ -1,5 +1,5 @@
|
||||
name: "CodeQL config"
|
||||
queries:
|
||||
queries:
|
||||
- name: Run custom queries
|
||||
uses: ./queries
|
||||
# Run all extra query suites, both because we want to
|
||||
@@ -13,3 +13,5 @@ queries:
|
||||
paths-ignore:
|
||||
- lib
|
||||
- tests
|
||||
- "**/*.test.ts"
|
||||
- "**/testing-util.ts"
|
||||
|
||||
@@ -16,12 +16,23 @@ No user facing changes.
|
||||
"""
|
||||
|
||||
# NB: This exact commit message is used to find commits for reverting during backports.
|
||||
# Changing it requires a transition period where both old and new versions are supported.
|
||||
# Changing it requires a transition period where both old and new versions are supported.
|
||||
BACKPORT_COMMIT_MESSAGE = 'Update version and changelog for v'
|
||||
|
||||
# Name of the remote
|
||||
ORIGIN = 'origin'
|
||||
|
||||
# Environment variables to check for a GitHub API token.
|
||||
TOKEN_ENVIRONMENT_VARIABLES = ('GH_TOKEN', 'GITHUB_TOKEN')
|
||||
|
||||
# Gets a GitHub API token from one of the supported environment variables.
|
||||
def get_github_token():
|
||||
for variable_name in TOKEN_ENVIRONMENT_VARIABLES:
|
||||
token = os.environ.get(variable_name, '').strip()
|
||||
if token:
|
||||
return token
|
||||
raise Exception('Missing GitHub token. Set GITHUB_TOKEN or GH_TOKEN.')
|
||||
|
||||
# Runs git with the given args and returns the stdout.
|
||||
# Raises an error if git does not exit successfully (unless passed
|
||||
# allow_non_zero_exit_code=True).
|
||||
@@ -270,12 +281,6 @@ def update_changelog(version):
|
||||
def main():
|
||||
parser = argparse.ArgumentParser('update-release-branch.py')
|
||||
|
||||
parser.add_argument(
|
||||
'--github-token',
|
||||
type=str,
|
||||
required=True,
|
||||
help='GitHub token, typically from GitHub Actions.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--repository-nwo',
|
||||
type=str,
|
||||
@@ -313,7 +318,7 @@ def main():
|
||||
target_branch = args.target_branch
|
||||
is_primary_release = args.is_primary_release
|
||||
|
||||
repo = Github(args.github_token).get_repo(args.repository_nwo)
|
||||
repo = Github(get_github_token()).get_repo(args.repository_nwo)
|
||||
|
||||
# the target branch will be of the form releases/vN, where N is the major version number
|
||||
target_branch_major_version = target_branch.strip('releases/v')
|
||||
|
||||
+4
-4
@@ -49,10 +49,6 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.17.6
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.18.4
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.19.4
|
||||
- os: ubuntu-latest
|
||||
@@ -61,6 +57,10 @@ jobs:
|
||||
version: stable-v2.21.4
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.22.4
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.23.9
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.24.3
|
||||
- os: ubuntu-latest
|
||||
version: default
|
||||
- os: ubuntu-latest
|
||||
|
||||
+4
-4
@@ -49,10 +49,6 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.17.6
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.18.4
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.19.4
|
||||
- os: ubuntu-latest
|
||||
@@ -61,6 +57,10 @@ jobs:
|
||||
version: stable-v2.21.4
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.22.4
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.23.9
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.24.3
|
||||
- os: ubuntu-latest
|
||||
version: default
|
||||
- os: ubuntu-latest
|
||||
|
||||
+4
-4
@@ -49,10 +49,6 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.17.6
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.18.4
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.19.4
|
||||
- os: ubuntu-latest
|
||||
@@ -61,6 +57,10 @@ jobs:
|
||||
version: stable-v2.21.4
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.22.4
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.23.9
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.24.3
|
||||
- os: ubuntu-latest
|
||||
version: default
|
||||
- os: ubuntu-latest
|
||||
|
||||
+15
-15
@@ -59,41 +59,41 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.17.6
|
||||
- os: macos-latest
|
||||
version: stable-v2.17.6
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.18.4
|
||||
- os: macos-latest
|
||||
version: stable-v2.18.4
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.19.4
|
||||
- os: macos-latest
|
||||
- os: macos-latest-xlarge
|
||||
version: stable-v2.19.4
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.20.7
|
||||
- os: macos-latest
|
||||
- os: macos-latest-xlarge
|
||||
version: stable-v2.20.7
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.21.4
|
||||
- os: macos-latest
|
||||
- os: macos-latest-xlarge
|
||||
version: stable-v2.21.4
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.22.4
|
||||
- os: macos-latest
|
||||
- os: macos-latest-xlarge
|
||||
version: stable-v2.22.4
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.23.9
|
||||
- os: macos-latest-xlarge
|
||||
version: stable-v2.23.9
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.24.3
|
||||
- os: macos-latest-xlarge
|
||||
version: stable-v2.24.3
|
||||
- os: ubuntu-latest
|
||||
version: default
|
||||
- os: macos-latest
|
||||
- os: macos-latest-xlarge
|
||||
version: default
|
||||
- os: ubuntu-latest
|
||||
version: linked
|
||||
- os: macos-latest
|
||||
- os: macos-latest-xlarge
|
||||
version: linked
|
||||
- os: ubuntu-latest
|
||||
version: nightly-latest
|
||||
- os: macos-latest
|
||||
- os: macos-latest-xlarge
|
||||
version: nightly-latest
|
||||
name: Multi-language repository
|
||||
if: github.triggering_actor != 'dependabot[bot]'
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ jobs:
|
||||
use-all-platform-bundle: 'false'
|
||||
setup-kotlin: 'true'
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0
|
||||
uses: ruby/setup-ruby@c4e5b1316158f92e3d49443a9d58b31d25ac0f8f # v1.306.0
|
||||
with:
|
||||
ruby-version: 2.6
|
||||
- name: Install Code Scanning integration
|
||||
|
||||
Generated
+1
-1
@@ -40,7 +40,7 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.19.3
|
||||
version: stable-v2.19.4
|
||||
- os: ubuntu-latest
|
||||
version: stable-v2.22.1
|
||||
- os: ubuntu-latest
|
||||
|
||||
Generated
+1
-1
@@ -39,7 +39,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: macos-latest
|
||||
- os: macos-latest-xlarge
|
||||
version: nightly-latest
|
||||
name: Swift analysis using autobuild
|
||||
if: github.triggering_actor != 'dependabot[bot]'
|
||||
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-22.04,ubuntu-24.04,windows-2022,windows-2025,macos-14,macos-15]
|
||||
os: [ubuntu-22.04,ubuntu-24.04,windows-2022,windows-2025,macos-14-xlarge,macos-15-xlarge]
|
||||
tools: ${{ fromJson(needs.check-codeql-versions.outputs.versions) }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
|
||||
@@ -6,13 +6,6 @@ env:
|
||||
# Diff informed queries add an additional query filter which is not yet
|
||||
# taken into account by these tests.
|
||||
CODEQL_ACTION_DIFF_INFORMED_QUERIES: false
|
||||
# Specify overlay enablement manually to ensure stability around the exclude-from-incremental
|
||||
# query filter. Here we only enable for the default code scanning suite.
|
||||
CODEQL_ACTION_OVERLAY_ANALYSIS: true
|
||||
CODEQL_ACTION_OVERLAY_ANALYSIS_JAVASCRIPT: false
|
||||
CODEQL_ACTION_OVERLAY_ANALYSIS_CODE_SCANNING_JAVASCRIPT: true
|
||||
CODEQL_ACTION_OVERLAY_ANALYSIS_STATUS_CHECK: false
|
||||
CODEQL_ACTION_OVERLAY_ANALYSIS_SKIP_RESOURCE_CHECKS: true
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -79,33 +72,13 @@ jobs:
|
||||
with:
|
||||
version: ${{ matrix.version }}
|
||||
|
||||
# On PRs, overlay analysis may change the config that is passed to the CLI.
|
||||
# Therefore, we have two variants of the following test, one for PRs and one for other events.
|
||||
- name: Empty file (non-PR)
|
||||
if: github.event_name != 'pull_request'
|
||||
- name: Empty file
|
||||
uses: ./../action/.github/actions/check-codescanning-config
|
||||
with:
|
||||
expected-config-file-contents: "{}"
|
||||
languages: javascript
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
|
||||
- name: Empty file (PR)
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: ./../action/.github/actions/check-codescanning-config
|
||||
with:
|
||||
expected-config-file-contents: |
|
||||
{
|
||||
"query-filters": [
|
||||
{
|
||||
"exclude": {
|
||||
"tags": "exclude-from-incremental"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
languages: javascript
|
||||
tools: ${{ steps.prepare-test.outputs.tools-url }}
|
||||
|
||||
- name: Packs from input
|
||||
if: success() || failure()
|
||||
uses: ./../action/.github/actions/check-codescanning-config
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
# Workflow runs on main, on a release branch, and that were triggered as part of a merge group have
|
||||
# already passed CI before being merged. Therefore if they fail, we should make sure that there
|
||||
# wasn't a transient failure by rerunning the failed jobs once before investigating further.
|
||||
name: Deflake
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
types: [completed]
|
||||
# Exclude workflows that have significant side effects, like publishing releases. It's OK to
|
||||
# retry CodeQL analysis.
|
||||
workflows:
|
||||
- Check Expected Release Files
|
||||
- Code-Scanning config CLI tests
|
||||
- CodeQL action
|
||||
- Manual Check - go
|
||||
- "PR Check - All-platform bundle"
|
||||
- "PR Check - Analysis kinds"
|
||||
- "PR Check - Analyze: 'ref' and 'sha' from inputs"
|
||||
- "PR Check - autobuild-action"
|
||||
- "PR Check - Autobuild direct tracing (custom working directory)"
|
||||
- "PR Check - Autobuild working directory"
|
||||
- "PR Check - Build mode autobuild"
|
||||
- "PR Check - Build mode manual"
|
||||
- "PR Check - Build mode none"
|
||||
- "PR Check - Build mode rollback"
|
||||
- "PR Check - Bundle: Caching checks"
|
||||
- "PR Check - Bundle: From nightly"
|
||||
- "PR Check - Bundle: From toolcache"
|
||||
- "PR Check - Bundle: Zstandard checks"
|
||||
- "PR Check - C/C\\+\\+: autoinstalling dependencies (Linux)"
|
||||
- "PR Check - C/C\\+\\+: autoinstalling dependencies is skipped (macOS)"
|
||||
- "PR Check - C/C\\+\\+: disabling autoinstalling dependencies (Linux)"
|
||||
- "PR Check - Clean up database cluster directory"
|
||||
- "PR Check - CodeQL Bundle All"
|
||||
- "PR Check - Config export"
|
||||
- "PR Check - Config input"
|
||||
- "PR Check - Custom source root"
|
||||
- "PR Check - Debug artifact upload"
|
||||
- "PR Check - Debug artifacts after failure"
|
||||
- "PR Check - Diagnostic export"
|
||||
- "PR Check - Export file baseline information"
|
||||
- "PR Check - Extractor ram and threads options test"
|
||||
- "PR Check - Go: Custom queries"
|
||||
- "PR Check - Go: diagnostic when Go is changed after init step"
|
||||
- "PR Check - Go: diagnostic when `file` is not installed"
|
||||
- "PR Check - Go: tracing with autobuilder step"
|
||||
- "PR Check - Go: tracing with custom build steps"
|
||||
- "PR Check - Go: tracing with legacy workflow"
|
||||
- "PR Check - Go: workaround for indirect tracing"
|
||||
- "PR Check - Job run UUID added to SARIF"
|
||||
- "PR Check - Language aliases"
|
||||
- "PR Check - Local CodeQL bundle"
|
||||
- "PR Check - Multi-language repository"
|
||||
- "PR Check - Overlay database init fallback"
|
||||
- "PR Check - Packaging: Action input"
|
||||
- "PR Check - Packaging: Config and input"
|
||||
- "PR Check - Packaging: Config and input passed to the CLI"
|
||||
- "PR Check - Packaging: Config file"
|
||||
- "PR Check - Packaging: Download using registries"
|
||||
- "PR Check - Proxy test"
|
||||
- "PR Check - Remote config file"
|
||||
- "PR Check - Resolve environment"
|
||||
- "PR Check - RuboCop multi-language"
|
||||
- "PR Check - Ruby analysis"
|
||||
- "PR Check - Rust analysis"
|
||||
- "PR Check - Split workflow"
|
||||
- "PR Check - Start proxy"
|
||||
- "PR Check - Submit SARIF after failure"
|
||||
- "PR Check - Swift analysis using a custom build command"
|
||||
- "PR Check - Swift analysis using autobuild"
|
||||
- "PR Check - Test different uses of `upload-sarif`"
|
||||
- "PR Check - Test unsetting environment variables"
|
||||
- "PR Check - Upload-sarif: ref and sha from inputs"
|
||||
- "PR Check - Use a custom `checkout_path`"
|
||||
- PR Checks
|
||||
- Query filters tests
|
||||
- Test that the workaround for python 3.12 on windows works
|
||||
|
||||
jobs:
|
||||
rerun-on-failure:
|
||||
name: Rerun failed jobs
|
||||
if: >-
|
||||
github.event.workflow_run.conclusion == 'failure' &&
|
||||
github.event.workflow_run.run_attempt == 1 &&
|
||||
(
|
||||
github.event.workflow_run.head_branch == 'main' ||
|
||||
startsWith(github.event.workflow_run.head_branch, 'releases/') ||
|
||||
github.event.workflow_run.event == 'merge_group'
|
||||
)
|
||||
runs-on: ubuntu-slim
|
||||
permissions:
|
||||
actions: write
|
||||
steps:
|
||||
- name: Rerun failed jobs in ${{ github.event.workflow_run.name }}
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
RUN_ID: ${{ github.event.workflow_run.id }}
|
||||
RUN_NAME: ${{ github.event.workflow_run.name }}
|
||||
RUN_URL: ${{ github.event.workflow_run.html_url }}
|
||||
run: |
|
||||
echo "Rerunning failed jobs for workflow run ${RUN_ID}"
|
||||
gh run rerun "${RUN_ID}" --failed
|
||||
echo "### Reran failed jobs :recycle:" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "Workflow: [${RUN_NAME}](${RUN_URL})" >> "$GITHUB_STEP_SUMMARY"
|
||||
@@ -131,7 +131,7 @@ jobs:
|
||||
echo "::endgroup::"
|
||||
|
||||
- name: Generate token
|
||||
uses: actions/create-github-app-token@v3.1.1
|
||||
uses: actions/create-github-app-token@v3.2.0
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ vars.AUTOMATION_APP_ID }}
|
||||
|
||||
@@ -136,7 +136,7 @@ jobs:
|
||||
|
||||
- name: Generate token
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
uses: actions/create-github-app-token@v3.1.1
|
||||
uses: actions/create-github-app-token@v3.2.0
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ vars.AUTOMATION_APP_ID }}
|
||||
|
||||
@@ -63,13 +63,10 @@ jobs:
|
||||
with:
|
||||
tools: https://github.com/github/codeql-action/releases/download/${{ github.event.release.tag_name }}/codeql-bundle-linux64.tar.gz
|
||||
|
||||
- name: Update language aliases
|
||||
- name: Update built-in languages
|
||||
run: npx tsx pr-checks/update-builtin-languages.ts "$CODEQL_PATH"
|
||||
env:
|
||||
CODEQL_PATH: ${{ steps.setup-codeql.outputs.codeql-path }}
|
||||
run: |
|
||||
"$CODEQL_PATH" resolve languages --format=betterjson --extractor-include-aliases \
|
||||
| jq -S '.aliases // {}' \
|
||||
> src/known-language-aliases.json
|
||||
|
||||
- name: Bump Action minor version if new CodeQL minor version series
|
||||
id: bump-action-version
|
||||
|
||||
@@ -64,11 +64,12 @@ jobs:
|
||||
|
||||
- name: Update current release branch
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
echo SOURCE_BRANCH=${REF_NAME}
|
||||
echo TARGET_BRANCH=releases/${MAJOR_VERSION}
|
||||
python .github/update-release-branch.py \
|
||||
--github-token ${{ secrets.GITHUB_TOKEN }} \
|
||||
--repository-nwo ${{ github.repository }} \
|
||||
--source-branch '${{ env.REF_NAME }}' \
|
||||
--target-branch 'releases/${{ env.MAJOR_VERSION }}' \
|
||||
@@ -93,7 +94,7 @@ jobs:
|
||||
pull-requests: write # needed to create pull request
|
||||
steps:
|
||||
- name: Generate token
|
||||
uses: actions/create-github-app-token@v3.1.1
|
||||
uses: actions/create-github-app-token@v3.2.0
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ vars.AUTOMATION_APP_ID }}
|
||||
@@ -107,11 +108,12 @@ jobs:
|
||||
- uses: ./.github/actions/release-initialise
|
||||
|
||||
- name: Update older release branch
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
echo SOURCE_BRANCH=${SOURCE_BRANCH}
|
||||
echo TARGET_BRANCH=${TARGET_BRANCH}
|
||||
python .github/update-release-branch.py \
|
||||
--github-token ${{ secrets.GITHUB_TOKEN }} \
|
||||
--repository-nwo ${{ github.repository }} \
|
||||
--source-branch ${SOURCE_BRANCH} \
|
||||
--target-branch ${TARGET_BRANCH} \
|
||||
|
||||
@@ -9,7 +9,7 @@ on:
|
||||
- main
|
||||
paths:
|
||||
- .github/workflows/update-supported-enterprise-server-versions.yml
|
||||
- .github/workflows/update-supported-enterprise-server-versions/update.py
|
||||
- pr-checks/update-ghes-versions.ts
|
||||
|
||||
jobs:
|
||||
update-supported-enterprise-server-versions:
|
||||
@@ -22,12 +22,18 @@ jobs:
|
||||
pull-requests: write # needed to create pull request
|
||||
|
||||
steps:
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.13"
|
||||
- name: Checkout CodeQL Action
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Checkout Enterprise Releases
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
@@ -35,18 +41,18 @@ jobs:
|
||||
token: ${{ secrets.ENTERPRISE_RELEASE_TOKEN }}
|
||||
path: ${{ github.workspace }}/enterprise-releases/
|
||||
sparse-checkout: releases.json
|
||||
|
||||
- name: Update Supported Enterprise Server Versions
|
||||
working-directory: pr-checks
|
||||
run: |
|
||||
cd ./.github/workflows/update-supported-enterprise-server-versions/
|
||||
python3 -m pip install pipenv
|
||||
pipenv install
|
||||
pipenv run ./update.py
|
||||
npx tsx update-ghes-versions.ts
|
||||
rm --recursive "$ENTERPRISE_RELEASES_PATH"
|
||||
npm ci
|
||||
npm run build
|
||||
env:
|
||||
ENTERPRISE_RELEASES_PATH: ${{ github.workspace }}/enterprise-releases/
|
||||
|
||||
- name: Rebuild
|
||||
run: npm run build
|
||||
|
||||
- name: Update git config
|
||||
run: |
|
||||
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[packages]
|
||||
semver = "*"
|
||||
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "e3ba923dcb4888e05de5448c18a732bf40197e80fabfa051a61c01b22c504879"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"semver": {
|
||||
"hashes": [
|
||||
"sha256:ced8b23dceb22134307c1b8abfa523da14198793d9787ac838e70e29e77458d4",
|
||||
"sha256:fa0fe2722ee1c3f57eac478820c3a5ae2f624af8264cbdf9000c980ff7f75e3f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.13.0"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import pathlib
|
||||
|
||||
import semver
|
||||
|
||||
_API_COMPATIBILITY_PATH = pathlib.Path(__file__).absolute().parents[3] / "src" / "api-compatibility.json"
|
||||
_ENTERPRISE_RELEASES_PATH = pathlib.Path(os.environ["ENTERPRISE_RELEASES_PATH"])
|
||||
_RELEASE_FILE_PATH = _ENTERPRISE_RELEASES_PATH / "releases.json"
|
||||
_FIRST_SUPPORTED_RELEASE = semver.VersionInfo.parse("2.22.0") # Versions older than this did not include Code Scanning.
|
||||
|
||||
def main():
|
||||
api_compatibility_data = json.loads(_API_COMPATIBILITY_PATH.read_text())
|
||||
|
||||
releases = json.loads(_RELEASE_FILE_PATH.read_text())
|
||||
|
||||
# Remove GHES version using a previous version numbering scheme.
|
||||
if "11.10" in releases:
|
||||
del releases["11.10"]
|
||||
|
||||
oldest_supported_release = None
|
||||
newest_supported_release = semver.VersionInfo.parse(api_compatibility_data["maximumVersion"] + ".0")
|
||||
|
||||
for release_version_string, release_data in releases.items():
|
||||
release_version = semver.VersionInfo.parse(release_version_string + ".0")
|
||||
if release_version < _FIRST_SUPPORTED_RELEASE:
|
||||
continue
|
||||
|
||||
if release_version > newest_supported_release:
|
||||
feature_freeze_date = datetime.date.fromisoformat(release_data["feature_freeze"])
|
||||
if feature_freeze_date < datetime.date.today() + datetime.timedelta(weeks=2):
|
||||
newest_supported_release = release_version
|
||||
|
||||
if oldest_supported_release is None or release_version < oldest_supported_release:
|
||||
end_of_life_date = datetime.date.fromisoformat(release_data["end"])
|
||||
# The GHES version is not actually end of life until the end of the day specified by
|
||||
# `end_of_life_date`. Wait an extra week to be safe.
|
||||
is_end_of_life = datetime.date.today() > end_of_life_date + datetime.timedelta(weeks=1)
|
||||
if not is_end_of_life:
|
||||
oldest_supported_release = release_version
|
||||
|
||||
api_compatibility_data = {
|
||||
"minimumVersion": f"{oldest_supported_release.major}.{oldest_supported_release.minor}",
|
||||
"maximumVersion": f"{newest_supported_release.major}.{newest_supported_release.minor}",
|
||||
}
|
||||
_API_COMPATIBILITY_PATH.write_text(json.dumps(api_compatibility_data, sort_keys=True) + "\n")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Vendored
+1
-1
@@ -19,7 +19,7 @@
|
||||
"scope": "javascript, typescript",
|
||||
"prefix": "testMacro",
|
||||
"body": [
|
||||
"const ${1:nameMacro} = test.macro({",
|
||||
"const ${1:nameMacro} = makeMacro({",
|
||||
" exec: async (t: ExecutionContext<unknown>) => {},",
|
||||
"",
|
||||
" title: (providedTitle = \"\") => `${2:common title} - \\${providedTitle}`,",
|
||||
|
||||
@@ -2,6 +2,30 @@
|
||||
|
||||
See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs.
|
||||
|
||||
## [UNRELEASED]
|
||||
|
||||
- _Breaking change_: Bump the minimum required CodeQL bundle version to 2.19.4. [#3894](https://github.com/github/codeql-action/pull/3894)
|
||||
- Add support for SHA-256 Git object IDs. [#3893](https://github.com/github/codeql-action/pull/3893)
|
||||
|
||||
## 4.35.5 - 15 May 2026
|
||||
|
||||
- We have improved how the JavaScript bundles for the CodeQL Action are generated to avoid duplication across bundles and reduce the size of the repository by around 70%. This should have no effect on the runtime behaviour of the CodeQL Action. [#3899](https://github.com/github/codeql-action/pull/3899)
|
||||
- For performance and accuracy reasons, [improved incremental analysis](https://github.com/github/roadmap/issues/1158) will now only be enabled on a pull request when diff-informed analysis is also enabled for that run. If diff-informed analysis is unavailable (for example, because the PR diff ranges could not be computed), the action will fall back to a full analysis. [#3791](https://github.com/github/codeql-action/pull/3791)
|
||||
- If multiple inputs are provided for the GitHub-internal `analysis-kinds` input, only `code-scanning` will be enabled. The `analysis-kinds` input is experimental, for GitHub-internal use only, and may change without notice at any time. [#3892](https://github.com/github/codeql-action/pull/3892)
|
||||
- Added an experimental change which, when running a Code Scanning analysis for a PR with [improved incremental analysis](https://github.com/github/roadmap/issues/1158) enabled, prefers CodeQL CLI versions that have a cached overlay-base database for the configured languages. This speeds up analysis for a repository when there is not yet a cached overlay-base database for the latest CLI version. We expect to roll this change out to everyone in May. [#3880](https://github.com/github/codeql-action/pull/3880)
|
||||
|
||||
## 4.35.4 - 07 May 2026
|
||||
|
||||
- Update default CodeQL bundle version to [2.25.4](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.4). [#3881](https://github.com/github/codeql-action/pull/3881)
|
||||
|
||||
## 4.35.3 - 01 May 2026
|
||||
|
||||
- _Upcoming breaking change_: Add a deprecation warning for customers using CodeQL version 2.19.3 and earlier. These versions of CodeQL were discontinued on 9 April 2026 alongside GitHub Enterprise Server 3.15, and will be unsupported by the next minor release of the CodeQL Action. [#3837](https://github.com/github/codeql-action/pull/3837)
|
||||
- Configurations for private registries that use Cloudsmith or GCP OIDC are now accepted. [#3850](https://github.com/github/codeql-action/pull/3850)
|
||||
- Best-effort connection tests for private registries now use `GET` requests instead of `HEAD` for better compatibility with various registry implementations. For NuGet feeds, the test is now always performed against the service index. [#3853](https://github.com/github/codeql-action/pull/3853)
|
||||
- Fixed a bug where two diagnostics produced within the same millisecond could overwrite each other on disk, causing one of them to be lost. [#3852](https://github.com/github/codeql-action/pull/3852)
|
||||
- Update default CodeQL bundle version to [2.25.3](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.3). [#3865](https://github.com/github/codeql-action/pull/3865)
|
||||
|
||||
## 4.35.2 - 15 Apr 2026
|
||||
|
||||
- The undocumented TRAP cache cleanup feature that could be enabled using the `CODEQL_ACTION_CLEANUP_TRAP_CACHES` environment variable is deprecated and will be removed in May 2026. If you are affected by this, we recommend disabling TRAP caching by passing the `trap-caching: false` input to the `init` Action. [#3795](https://github.com/github/codeql-action/pull/3795)
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ Once the mergeback and backport pull request have been merged, the release is co
|
||||
|
||||
Since the `codeql-action` runs most of its testing through individual Actions workflows, there are over two hundred required jobs that need to pass in order for a PR to turn green. It would be too tedious to maintain that list manually. You can regenerate the set of required checks automatically by running the [sync-checks.ts](pr-checks/sync-checks.ts) script:
|
||||
|
||||
- At a minimum, you must provide an argument for the `--token` input. For example, `--token "$(gh auth token)"` to use the same token that `gh` uses. If no token is provided or the token has insufficient permissions, the script will fail.
|
||||
- At a minimum, you must provide a token with permissions to update branch protection rules. For example, `gh auth token | pr-checks/sync-checks.ts --token-stdin` uses the same token that `gh` uses. You can also set the `GH_TOKEN` or `GITHUB_TOKEN` environment variable. If no token is provided or the token has insufficient permissions, the script will fail.
|
||||
- By default, the script performs a dry run and outputs information about the changes it would make to the branch protection rules. To actually apply the changes, specify the `--apply` flag.
|
||||
- If you run the script without any other arguments, it will retrieve the set of workflows that ran for the latest commit on `main`.
|
||||
- You can specify a different git ref with the `--ref` input. You will likely want to use this if you have a PR that removes or adds PR checks. For example, `--ref "some/branch/name"` to use the HEAD of the `some/branch/name` branch.
|
||||
|
||||
@@ -72,13 +72,12 @@ We typically release new minor versions of the CodeQL Action and Bundle when a n
|
||||
|
||||
| Minimum CodeQL Action | Minimum CodeQL Bundle Version | GitHub Environment | Notes |
|
||||
|-----------------------|-------------------------------|--------------------|-------|
|
||||
| `v4.33.0` | `2.24.3` | Enterprise Server 3.21 | |
|
||||
| `v4.31.10` | `2.23.9` | Enterprise Server 3.20 | |
|
||||
| `v3.29.11` | `2.22.4` | Enterprise Server 3.19 | |
|
||||
| `v3.28.21` | `2.21.3` | Enterprise Server 3.18 | |
|
||||
| `v3.28.12` | `2.20.7` | Enterprise Server 3.17 | |
|
||||
| `v3.28.6` | `2.20.3` | Enterprise Server 3.16 | |
|
||||
| `v3.28.6` | `2.20.3` | Enterprise Server 3.15 | |
|
||||
| `v3.28.6` | `2.20.3` | Enterprise Server 3.14 | |
|
||||
|
||||
See the full list of GHES release and deprecation dates at [GitHub Enterprise Server releases](https://docs.github.com/en/enterprise-server/admin/all-releases#releases-of-github-enterprise-server).
|
||||
|
||||
|
||||
+2
-2
@@ -95,5 +95,5 @@ outputs:
|
||||
description: The ID of the uploaded SARIF file.
|
||||
runs:
|
||||
using: node24
|
||||
main: "../lib/analyze-action.js"
|
||||
post: "../lib/analyze-action-post.js"
|
||||
main: "../lib/analyze-entry.js"
|
||||
post: "../lib/analyze-post-entry.js"
|
||||
|
||||
@@ -16,4 +16,4 @@ inputs:
|
||||
required: false
|
||||
runs:
|
||||
using: node24
|
||||
main: '../lib/autobuild-action.js'
|
||||
main: '../lib/autobuild-entry.js'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { copyFile, rm, writeFile } from "node:fs/promises";
|
||||
import { dirname, join } from "node:path";
|
||||
import { copyFile, readFile, rm, writeFile } from "node:fs/promises";
|
||||
import { basename, dirname, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import * as esbuild from "esbuild";
|
||||
@@ -62,18 +62,123 @@ const onEndPlugin = {
|
||||
},
|
||||
};
|
||||
|
||||
/** The name of the virtual `entry-points` module. */
|
||||
const SHARED_ENTRYPOINT = "entry-points";
|
||||
|
||||
/**
|
||||
* This plugin finds all source files that contain Action entry points.
|
||||
* It then generates the virtual `entry-points` module which imports all identified files,
|
||||
* and re-exports their `runWrapper` functions with suitable aliases.
|
||||
* A tiny stub file is emitted for each Action entrypoint. Each stub imports the shared bundle
|
||||
* and calls the respective entry point.
|
||||
*
|
||||
* @type {esbuild.Plugin}
|
||||
*/
|
||||
const entryPointsPlugin = {
|
||||
name: "entry-points",
|
||||
setup(build) {
|
||||
const namespace = "actions";
|
||||
const actions = [];
|
||||
|
||||
const toPascal = (s) =>
|
||||
s.replace(/(^|-)([a-z0-9])/gi, (_, __, c) => c.toUpperCase());
|
||||
|
||||
// Find the source files containing Action entry points.
|
||||
build.onStart(() => {
|
||||
const actionFiles = globSync("src/*-action{,-post}.ts");
|
||||
for (const actionFile of actionFiles) {
|
||||
const match = basename(actionFile).match(/(.*)-action(-post)?/);
|
||||
|
||||
if (match.length < 2) {
|
||||
throw new Error(`'${actionFile}' didn't match expected pattern.`);
|
||||
}
|
||||
|
||||
const actionName = match[1];
|
||||
const isPost = match[2] !== undefined;
|
||||
|
||||
actions.push({
|
||||
path: actionFile,
|
||||
name: actionName,
|
||||
isPost,
|
||||
pascalCaseName: `${toPascal(actionName)}${isPost ? "Post" : ""}Action`,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Resolve the virtual `entry-points` file and set the corresponding namespace.
|
||||
// Ideally, we'd `RegExp.escape` the entrypoint here, but that API isn't supported in Node 20.
|
||||
// Since we're dealing with a hardcoded string, this isn't too much of a problem.
|
||||
build.onResolve({ filter: new RegExp(`^${SHARED_ENTRYPOINT}$`) }, () => {
|
||||
return { path: SHARED_ENTRYPOINT, namespace };
|
||||
});
|
||||
|
||||
// Generate the virtual `entry-points` file based on the Actions we discovered.
|
||||
// Restrict using the namespace. The path filter does not need to discriminate any further.
|
||||
build.onLoad({ filter: /.*/, namespace }, async () => {
|
||||
const wrapperTemplatePath = "entry-wrapper.js.tpl";
|
||||
const wrapperTemplate = await readFile(
|
||||
join(SRC_DIR, wrapperTemplatePath),
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
const actionsSorted = actions.sort((a, b) =>
|
||||
a.name.localeCompare(b.name),
|
||||
);
|
||||
const imports = actionsSorted
|
||||
.map(
|
||||
(action) =>
|
||||
`import * as ${action.pascalCaseName} from "./src/${basename(action.path)}";`,
|
||||
)
|
||||
.join("\n");
|
||||
const wrappers = actionsSorted
|
||||
.map((action) =>
|
||||
wrapperTemplate.replaceAll("__ACTION__", action.pascalCaseName),
|
||||
)
|
||||
.join("\n\n");
|
||||
|
||||
return {
|
||||
contents: `"use strict";\n${imports}\n\n${wrappers}\n`,
|
||||
resolveDir: ".",
|
||||
loader: "ts",
|
||||
};
|
||||
});
|
||||
|
||||
// Emit entry point stubs for each Action using the entry template.
|
||||
build.onEnd(async (result) => {
|
||||
// Read the entry point template.
|
||||
const templatePath = "action-entry.js.tpl";
|
||||
const template = await readFile(join(SRC_DIR, templatePath), "utf-8");
|
||||
|
||||
const makeHeader = (sourceFile) =>
|
||||
`// Automatically generated from '${templatePath}' for 'src/${basename(sourceFile)}'.\n\n`;
|
||||
|
||||
// Write entry point stubs for each Action.
|
||||
for (const action of actions) {
|
||||
await writeFile(
|
||||
join(
|
||||
OUT_DIR,
|
||||
`${action.name}${action.isPost ? "-post" : ""}-entry.js`,
|
||||
),
|
||||
makeHeader(action.path) +
|
||||
template.replaceAll("__ACTION__", action.pascalCaseName),
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
const context = await esbuild.context({
|
||||
// Include upload-lib.ts as an entry point for use in testing environments.
|
||||
entryPoints: globSync([
|
||||
`${SRC_DIR}/*-action.ts`,
|
||||
`${SRC_DIR}/*-action-post.ts`,
|
||||
"src/upload-lib.ts",
|
||||
]),
|
||||
entryPoints: [
|
||||
{ in: SHARED_ENTRYPOINT, out: SHARED_ENTRYPOINT },
|
||||
join(SRC_DIR, "upload-lib.ts"),
|
||||
],
|
||||
bundle: true,
|
||||
format: "cjs",
|
||||
outdir: OUT_DIR,
|
||||
platform: "node",
|
||||
plugins: [cleanPlugin, copyDefaultsPlugin, onEndPlugin],
|
||||
external: ["./entry-points"],
|
||||
plugins: [cleanPlugin, copyDefaultsPlugin, entryPointsPlugin, onEndPlugin],
|
||||
target: ["node20"],
|
||||
define: {
|
||||
__CODEQL_ACTION_VERSION__: JSON.stringify(pkg.version),
|
||||
|
||||
+2
-2
@@ -171,5 +171,5 @@ outputs:
|
||||
description: The version of the CodeQL binary used for analysis
|
||||
runs:
|
||||
using: node24
|
||||
main: '../lib/init-action.js'
|
||||
post: '../lib/init-action-post.js'
|
||||
main: '../lib/init-entry.js'
|
||||
post: '../lib/init-post-entry.js'
|
||||
|
||||
Generated
-163813
File diff suppressed because one or more lines are too long
Generated
-113732
File diff suppressed because one or more lines are too long
Generated
+6
@@ -0,0 +1,6 @@
|
||||
// Automatically generated from 'action-entry.js.tpl' for 'src/analyze-action.ts'.
|
||||
|
||||
"use strict";
|
||||
|
||||
const import_entry_points = require("./entry-points");
|
||||
void (0, import_entry_points.runAnalyzeAction)();
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
// Automatically generated from 'action-entry.js.tpl' for 'src/analyze-action-post.ts'.
|
||||
|
||||
"use strict";
|
||||
|
||||
const import_entry_points = require("./entry-points");
|
||||
void (0, import_entry_points.runAnalyzePostAction)();
|
||||
Generated
-106115
File diff suppressed because one or more lines are too long
Generated
+6
@@ -0,0 +1,6 @@
|
||||
// Automatically generated from 'action-entry.js.tpl' for 'src/autobuild-action.ts'.
|
||||
|
||||
"use strict";
|
||||
|
||||
const import_entry_points = require("./entry-points");
|
||||
void (0, import_entry_points.runAutobuildAction)();
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"bundleVersion": "codeql-bundle-v2.25.2",
|
||||
"cliVersion": "2.25.2",
|
||||
"priorBundleVersion": "codeql-bundle-v2.25.1",
|
||||
"priorCliVersion": "2.25.1"
|
||||
"bundleVersion": "codeql-bundle-v2.25.4",
|
||||
"cliVersion": "2.25.4",
|
||||
"priorBundleVersion": "codeql-bundle-v2.25.3",
|
||||
"priorCliVersion": "2.25.3"
|
||||
}
|
||||
|
||||
+71255
-81219
File diff suppressed because one or more lines are too long
Generated
-110707
File diff suppressed because one or more lines are too long
Generated
+6
@@ -0,0 +1,6 @@
|
||||
// Automatically generated from 'action-entry.js.tpl' for 'src/init-action.ts'.
|
||||
|
||||
"use strict";
|
||||
|
||||
const import_entry_points = require("./entry-points");
|
||||
void (0, import_entry_points.runInitAction)();
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
// Automatically generated from 'action-entry.js.tpl' for 'src/init-action-post.ts'.
|
||||
|
||||
"use strict";
|
||||
|
||||
const import_entry_points = require("./entry-points");
|
||||
void (0, import_entry_points.runInitPostAction)();
|
||||
Generated
-105674
File diff suppressed because one or more lines are too long
Generated
+6
@@ -0,0 +1,6 @@
|
||||
// Automatically generated from 'action-entry.js.tpl' for 'src/resolve-environment-action.ts'.
|
||||
|
||||
"use strict";
|
||||
|
||||
const import_entry_points = require("./entry-points");
|
||||
void (0, import_entry_points.runResolveEnvironmentAction)();
|
||||
Generated
-107188
File diff suppressed because one or more lines are too long
Generated
+6
@@ -0,0 +1,6 @@
|
||||
// Automatically generated from 'action-entry.js.tpl' for 'src/setup-codeql-action.ts'.
|
||||
|
||||
"use strict";
|
||||
|
||||
const import_entry_points = require("./entry-points");
|
||||
void (0, import_entry_points.runSetupCodeqlAction)();
|
||||
Generated
-162625
File diff suppressed because one or more lines are too long
Generated
-122903
File diff suppressed because one or more lines are too long
Generated
+6
@@ -0,0 +1,6 @@
|
||||
// Automatically generated from 'action-entry.js.tpl' for 'src/start-proxy-action.ts'.
|
||||
|
||||
"use strict";
|
||||
|
||||
const import_entry_points = require("./entry-points");
|
||||
void (0, import_entry_points.runStartProxyAction)();
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
// Automatically generated from 'action-entry.js.tpl' for 'src/start-proxy-action-post.ts'.
|
||||
|
||||
"use strict";
|
||||
|
||||
const import_entry_points = require("./entry-points");
|
||||
void (0, import_entry_points.runStartProxyPostAction)();
|
||||
Generated
+2375
-19989
File diff suppressed because one or more lines are too long
Generated
-162650
File diff suppressed because one or more lines are too long
Generated
-112078
File diff suppressed because one or more lines are too long
Generated
+6
@@ -0,0 +1,6 @@
|
||||
// Automatically generated from 'action-entry.js.tpl' for 'src/upload-sarif-action.ts'.
|
||||
|
||||
"use strict";
|
||||
|
||||
const import_entry_points = require("./entry-points");
|
||||
void (0, import_entry_points.runUploadSarifAction)();
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
// Automatically generated from 'action-entry.js.tpl' for 'src/upload-sarif-action-post.ts'.
|
||||
|
||||
"use strict";
|
||||
|
||||
const import_entry_points = require("./entry-points");
|
||||
void (0, import_entry_points.runUploadSarifPostAction)();
|
||||
Generated
+251
-271
File diff suppressed because it is too large
Load Diff
+17
-16
@@ -1,18 +1,19 @@
|
||||
{
|
||||
"name": "codeql",
|
||||
"version": "4.35.2",
|
||||
"version": "4.36.0",
|
||||
"private": true,
|
||||
"description": "CodeQL action",
|
||||
"scripts": {
|
||||
"_build_comment": "echo 'Run the full build so we typecheck the project and can reuse the transpiled files in npm test'",
|
||||
"build": "./scripts/check-node-modules.sh && npm run transpile && node build.mjs && npx tsx ./pr-checks/bundle-metadata.ts",
|
||||
"build": "./scripts/check-node-modules.sh && npm run transpile && node build.mjs",
|
||||
"lint": "eslint --report-unused-disable-directives --max-warnings=0 .",
|
||||
"lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif",
|
||||
"lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix",
|
||||
"ava": "npm run transpile && ava --verbose",
|
||||
"test": "npm run ava -- src/",
|
||||
"test-debug": "npm run test -- --timeout=20m",
|
||||
"transpile": "tsc --build --verbose"
|
||||
"transpile": "tsc --build --verbose tsconfig.json",
|
||||
"update-pr-checks": "./pr-checks/sync.sh"
|
||||
},
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
@@ -32,7 +33,7 @@
|
||||
"@octokit/plugin-retry": "^8.1.0",
|
||||
"archiver": "^7.0.1",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"follow-redirects": "^1.15.11",
|
||||
"follow-redirects": "^1.16.0",
|
||||
"get-folder-size": "^5.0.0",
|
||||
"https-proxy-agent": "^7.0.6",
|
||||
"js-yaml": "^4.1.1",
|
||||
@@ -40,35 +41,35 @@
|
||||
"long": "^5.3.2",
|
||||
"node-forge": "^1.4.0",
|
||||
"semver": "^7.7.4",
|
||||
"uuid": "^13.0.0"
|
||||
"uuid": "^14.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ava/typescript": "6.0.0",
|
||||
"@eslint/compat": "^2.0.4",
|
||||
"@ava/typescript": "7.0.0",
|
||||
"@eslint/compat": "^2.0.5",
|
||||
"@microsoft/eslint-formatter-sarif": "^3.1.0",
|
||||
"@octokit/types": "^16.0.0",
|
||||
"@types/archiver": "^7.0.0",
|
||||
"@types/follow-redirects": "^1.14.4",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/node": "^20.19.9",
|
||||
"@types/node": "^20.19.39",
|
||||
"@types/node-forge": "^1.3.14",
|
||||
"@types/sarif": "^2.1.7",
|
||||
"@types/semver": "^7.7.1",
|
||||
"@types/sinon": "^21.0.1",
|
||||
"ava": "^7.0.0",
|
||||
"esbuild": "^0.28.0",
|
||||
"eslint": "^9.39.2",
|
||||
"eslint-import-resolver-typescript": "^3.8.7",
|
||||
"eslint": "^9.39.4",
|
||||
"eslint-import-resolver-typescript": "^4.4.4",
|
||||
"eslint-plugin-github": "^6.0.0",
|
||||
"eslint-plugin-import-x": "^4.16.2",
|
||||
"eslint-plugin-jsdoc": "^62.9.0",
|
||||
"eslint-plugin-no-async-foreach": "^0.1.1",
|
||||
"glob": "^11.1.0",
|
||||
"globals": "^17.4.0",
|
||||
"globals": "^17.6.0",
|
||||
"nock": "^14.0.12",
|
||||
"sinon": "^21.0.3",
|
||||
"typescript": "^6.0.2",
|
||||
"typescript-eslint": "^8.58.0"
|
||||
"sinon": "^22.0.0",
|
||||
"typescript": "^6.0.3",
|
||||
"typescript-eslint": "^8.59.2"
|
||||
},
|
||||
"overrides": {
|
||||
"@actions/tool-cache": {
|
||||
@@ -89,7 +90,7 @@
|
||||
"eslint-plugin-jsx-a11y": {
|
||||
"semver": ">=6.3.1"
|
||||
},
|
||||
"brace-expansion@2.0.1": "2.0.2",
|
||||
"glob": "^11.1.0"
|
||||
"glob": "^11.1.0",
|
||||
"undici": "^6.24.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@ name: "Multi-language repository"
|
||||
description: "An end-to-end integration test of a multi-language repository using automatic language detection"
|
||||
operatingSystems:
|
||||
- ubuntu
|
||||
- macos
|
||||
- os: macos
|
||||
runner-image: macos-latest-xlarge
|
||||
env:
|
||||
CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI: true
|
||||
installGo: true
|
||||
|
||||
@@ -5,7 +5,7 @@ versions:
|
||||
- default
|
||||
steps:
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0
|
||||
uses: ruby/setup-ruby@c4e5b1316158f92e3d49443a9d58b31d25ac0f8f # v1.306.0
|
||||
with:
|
||||
ruby-version: 2.6
|
||||
- name: Install Code Scanning integration
|
||||
|
||||
@@ -2,7 +2,7 @@ name: "Rust analysis"
|
||||
description: "Tests creation of a Rust database"
|
||||
versions:
|
||||
# experimental rust support introduced, requires action to set `CODEQL_ENABLE_EXPERIMENTAL_FEATURES`
|
||||
- stable-v2.19.3
|
||||
- stable-v2.19.4
|
||||
# first public preview version
|
||||
- stable-v2.22.1
|
||||
- linked
|
||||
|
||||
@@ -3,7 +3,8 @@ description: "Tests creation of a Swift database using autobuild"
|
||||
versions:
|
||||
- nightly-latest
|
||||
operatingSystems:
|
||||
- macos
|
||||
- os: macos
|
||||
runner-image: macos-latest-xlarge
|
||||
steps:
|
||||
- uses: ./../action/init
|
||||
id: init
|
||||
|
||||
@@ -11,3 +11,19 @@ export const PR_CHECK_EXCLUDED_FILE = path.join(PR_CHECKS_DIR, "excluded.yml");
|
||||
|
||||
/** The path to the esbuild metadata file. */
|
||||
export const BUNDLE_METADATA_FILE = path.join(PR_CHECKS_DIR, "..", "meta.json");
|
||||
|
||||
/** The `src` directory. */
|
||||
const SOURCE_ROOT = path.join(PR_CHECKS_DIR, "..", "src");
|
||||
|
||||
/** The path to the built-in languages file. */
|
||||
export const BUILTIN_LANGUAGES_FILE = path.join(
|
||||
SOURCE_ROOT,
|
||||
"languages",
|
||||
"builtin.json",
|
||||
);
|
||||
|
||||
/** Path to the api-compatibility.json file. */
|
||||
export const API_COMPATIBILITY_FILE = path.join(
|
||||
SOURCE_ROOT,
|
||||
"api-compatibility.json",
|
||||
);
|
||||
|
||||
@@ -7,10 +7,11 @@
|
||||
"@octokit/core": "^7.0.6",
|
||||
"@octokit/plugin-paginate-rest": ">=9.2.2",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^17.0.0",
|
||||
"yaml": "^2.8.3"
|
||||
"semver": "^7.8.0",
|
||||
"yaml": "^2.8.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.19.9",
|
||||
"@types/node": "^20.19.39",
|
||||
"tsx": "^4.21.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,13 @@ Tests for the sync-checks.ts script
|
||||
import * as assert from "node:assert/strict";
|
||||
import { describe, it } from "node:test";
|
||||
|
||||
import { CheckInfo, Exclusions, Options, removeExcluded } from "./sync-checks";
|
||||
import {
|
||||
CheckInfo,
|
||||
Exclusions,
|
||||
Options,
|
||||
removeExcluded,
|
||||
resolveToken,
|
||||
} from "./sync-checks";
|
||||
|
||||
const defaultOptions: Options = {
|
||||
apply: false,
|
||||
@@ -58,3 +64,46 @@ describe("removeExcluded", async () => {
|
||||
assert.deepEqual(retained, expectedExactMatches);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveToken", async () => {
|
||||
await it("reads the token from standard input", async () => {
|
||||
const token = await resolveToken(
|
||||
{ tokenStdin: true },
|
||||
{ env: {}, readStdin: async () => " stdin-token\n" },
|
||||
);
|
||||
assert.equal(token, "stdin-token");
|
||||
});
|
||||
|
||||
await it("reads the token from the GH_TOKEN environment variable", async () => {
|
||||
const token = await resolveToken(
|
||||
{},
|
||||
{ env: { GH_TOKEN: "env-token" }, readStdin: async () => "" },
|
||||
);
|
||||
assert.equal(token, "env-token");
|
||||
});
|
||||
|
||||
await it("reads the token from the GITHUB_TOKEN environment variable", async () => {
|
||||
const token = await resolveToken(
|
||||
{},
|
||||
{ env: { GITHUB_TOKEN: "env-token" }, readStdin: async () => "" },
|
||||
);
|
||||
assert.equal(token, "env-token");
|
||||
});
|
||||
|
||||
await it("rejects an empty standard input token", async () => {
|
||||
await assert.rejects(
|
||||
resolveToken(
|
||||
{ tokenStdin: true },
|
||||
{ env: {}, readStdin: async () => "\n" },
|
||||
),
|
||||
/No token received on standard input/,
|
||||
);
|
||||
});
|
||||
|
||||
await it("rejects missing token sources", async () => {
|
||||
await assert.rejects(
|
||||
resolveToken({}, { env: {}, readStdin: async () => "" }),
|
||||
/Missing authentication token/,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,8 +15,8 @@ import {
|
||||
|
||||
/** Represents the command-line options. */
|
||||
export interface Options {
|
||||
/** The token to use to authenticate to the GitHub API. */
|
||||
token?: string;
|
||||
/** Whether to read the GitHub API token from standard input. */
|
||||
tokenStdin?: boolean;
|
||||
/** The git ref to use the checks for. */
|
||||
ref?: string;
|
||||
/** Whether to actually apply the changes or not. */
|
||||
@@ -31,6 +31,65 @@ const codeqlActionRepo = {
|
||||
repo: "codeql-action",
|
||||
};
|
||||
|
||||
/** Environment variables to check for a GitHub API token. */
|
||||
const TOKEN_ENVIRONMENT_VARIABLES = ["GH_TOKEN", "GITHUB_TOKEN"];
|
||||
|
||||
/** Represents the sources from which we can retrieve the GitHub API token. */
|
||||
interface TokenSource {
|
||||
/** Environment variables to inspect. */
|
||||
env: NodeJS.ProcessEnv;
|
||||
/** Reads a token from standard input. */
|
||||
readStdin: () => Promise<string>;
|
||||
}
|
||||
|
||||
/** Reads the GitHub API token from standard input. */
|
||||
async function readTokenFromStdin(): Promise<string> {
|
||||
let token = "";
|
||||
process.stdin.setEncoding("utf8");
|
||||
for await (const chunk of process.stdin) {
|
||||
token += chunk;
|
||||
}
|
||||
return token.trim();
|
||||
}
|
||||
|
||||
/** Gets a GitHub API token from one of the supported environment variables. */
|
||||
function getTokenFromEnvironment(env: NodeJS.ProcessEnv): string | undefined {
|
||||
for (const variableName of TOKEN_ENVIRONMENT_VARIABLES) {
|
||||
const token = env[variableName]?.trim();
|
||||
if (token) {
|
||||
return token;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Gets the token to use to authenticate to the GitHub API. */
|
||||
export async function resolveToken(
|
||||
options: Pick<Options, "tokenStdin">,
|
||||
tokenSource: TokenSource = {
|
||||
env: process.env,
|
||||
readStdin: readTokenFromStdin,
|
||||
},
|
||||
): Promise<string> {
|
||||
if (options.tokenStdin) {
|
||||
const token = (await tokenSource.readStdin()).trim();
|
||||
if (token.length === 0) {
|
||||
throw new Error("No token received on standard input.");
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
const environmentToken = getTokenFromEnvironment(tokenSource.env);
|
||||
if (environmentToken !== undefined) {
|
||||
return environmentToken;
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
"Missing authentication token. Set GH_TOKEN/GITHUB_TOKEN or pipe a token " +
|
||||
"to --token-stdin.",
|
||||
);
|
||||
}
|
||||
|
||||
/** Represents a configuration of which checks should not be set up as required checks. */
|
||||
export interface Exclusions {
|
||||
/** A list of strings that, if contained in a check name, are excluded. */
|
||||
@@ -205,9 +264,10 @@ async function updateBranch(
|
||||
async function main(): Promise<void> {
|
||||
const { values: options } = parseArgs({
|
||||
options: {
|
||||
// The token to use to authenticate to the API.
|
||||
token: {
|
||||
type: "string",
|
||||
// Read the token to use to authenticate to the API from standard input.
|
||||
"token-stdin": {
|
||||
type: "boolean",
|
||||
default: false,
|
||||
},
|
||||
// The git ref for which to retrieve the check runs.
|
||||
ref: {
|
||||
@@ -228,16 +288,16 @@ async function main(): Promise<void> {
|
||||
strict: true,
|
||||
});
|
||||
|
||||
if (options.token === undefined) {
|
||||
throw new Error("Missing --token");
|
||||
}
|
||||
const token = await resolveToken({
|
||||
tokenStdin: options["token-stdin"],
|
||||
});
|
||||
|
||||
console.info(
|
||||
`Oldest supported major version is: ${OLDEST_SUPPORTED_MAJOR_VERSION}`,
|
||||
);
|
||||
|
||||
// Initialise the API client.
|
||||
const client = getApiClient(options.token);
|
||||
const client = getApiClient(token);
|
||||
|
||||
// Find the check runs for the specified `ref` that we will later set as the required checks
|
||||
// for the main and release branches.
|
||||
|
||||
+47
-16
@@ -5,7 +5,7 @@ import * as path from "path";
|
||||
|
||||
import * as yaml from "yaml";
|
||||
|
||||
import { KnownLanguage } from "../src/languages";
|
||||
import { BuiltInLanguage } from "../src/languages";
|
||||
|
||||
/** Known workflow input names. */
|
||||
enum KnownInputName {
|
||||
@@ -28,6 +28,24 @@ interface WorkflowInput {
|
||||
/** A partial mapping from known input names to input definitions. */
|
||||
type WorkflowInputs = Partial<Record<KnownInputName, WorkflowInput>>;
|
||||
|
||||
/** An operating system identifier. */
|
||||
type OperatingSystemIdentifier = "ubuntu" | "macos" | "windows";
|
||||
|
||||
/**
|
||||
* Represents an operating system matrix entry for a generated PR check workflow.
|
||||
*
|
||||
* Either a string containing the OS identifier or an object containing the OS identifier and an
|
||||
* optional runner image label.
|
||||
*/
|
||||
type OperatingSystem =
|
||||
| OperatingSystemIdentifier
|
||||
| {
|
||||
/** OS identifier. */
|
||||
os: OperatingSystemIdentifier;
|
||||
/** Optional runner image label. */
|
||||
"runner-image"?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents PR check specifications.
|
||||
*/
|
||||
@@ -36,8 +54,8 @@ interface Specification extends JobSpecification {
|
||||
inputs?: Record<string, WorkflowInput>;
|
||||
/** CodeQL bundle versions to test against. Defaults to `DEFAULT_TEST_VERSIONS`. */
|
||||
versions?: string[];
|
||||
/** Operating system prefixes used to select runner images (e.g. `["ubuntu", "macos"]`). */
|
||||
operatingSystems?: string[];
|
||||
/** Operating system prefixes, either as strings or with explicit runner image labels. */
|
||||
operatingSystems?: OperatingSystem[];
|
||||
/** Per-OS version overrides. If specified for an OS, only those versions are tested on that OS. */
|
||||
osCodeQlVersions?: Record<string, string[]>;
|
||||
/** Whether to use the all-platform CodeQL bundle. */
|
||||
@@ -91,16 +109,12 @@ interface LanguageSetup {
|
||||
steps: Step[];
|
||||
}
|
||||
|
||||
/** Describes partial mappings from known languages to their specific setup information. */
|
||||
type LanguageSetups = Partial<Record<KnownLanguage, LanguageSetup>>;
|
||||
/** Describes partial mappings from built-in languages to their specific setup information. */
|
||||
type LanguageSetups = Partial<Record<BuiltInLanguage, LanguageSetup>>;
|
||||
|
||||
// The default set of CodeQL Bundle versions to use for the PR checks.
|
||||
const defaultTestVersions = [
|
||||
// The oldest supported CodeQL version. If bumping, update `CODEQL_MINIMUM_VERSION` in `codeql.ts`
|
||||
"stable-v2.17.6",
|
||||
// The last CodeQL release in the 2.18 series.
|
||||
"stable-v2.18.4",
|
||||
// The last CodeQL release in the 2.19 series.
|
||||
"stable-v2.19.4",
|
||||
// The last CodeQL release in the 2.20 series.
|
||||
"stable-v2.20.7",
|
||||
@@ -108,6 +122,10 @@ const defaultTestVersions = [
|
||||
"stable-v2.21.4",
|
||||
// The last CodeQL release in the 2.22 series.
|
||||
"stable-v2.22.4",
|
||||
// The last CodeQL release in the 2.23 series.
|
||||
"stable-v2.23.9",
|
||||
// The last CodeQL release in the 2.24 series.
|
||||
"stable-v2.24.3",
|
||||
// The default version of CodeQL for Dotcom, as determined by feature flags.
|
||||
"default",
|
||||
// The version of CodeQL shipped with the Action in `defaults.json`. During the release process
|
||||
@@ -125,7 +143,7 @@ const defaultLanguageVersions = {
|
||||
java: "17",
|
||||
python: "3.13",
|
||||
csharp: "9.x",
|
||||
} as const satisfies Partial<Record<KnownLanguage, string>>;
|
||||
} as const satisfies Partial<Record<BuiltInLanguage, string>>;
|
||||
|
||||
/** A mapping from known input names to their specifications. */
|
||||
const inputSpecs: WorkflowInputs = {
|
||||
@@ -311,10 +329,19 @@ function generateJobMatrix(
|
||||
);
|
||||
}
|
||||
|
||||
const runnerImages = ["ubuntu-latest", "macos-latest", "windows-latest"];
|
||||
const defaultRunnerImages = [
|
||||
"ubuntu-latest",
|
||||
"macos-latest",
|
||||
"windows-latest",
|
||||
];
|
||||
const operatingSystems = checkSpecification.operatingSystems ?? ["ubuntu"];
|
||||
|
||||
for (const operatingSystem of operatingSystems) {
|
||||
for (const operatingSystemConfig of operatingSystems) {
|
||||
const operatingSystem =
|
||||
typeof operatingSystemConfig === "string"
|
||||
? operatingSystemConfig
|
||||
: operatingSystemConfig.os;
|
||||
|
||||
// If osCodeQlVersions is set for this OS, only include the specified CodeQL versions.
|
||||
const allowedVersions =
|
||||
checkSpecification.osCodeQlVersions?.[operatingSystem];
|
||||
@@ -322,9 +349,13 @@ function generateJobMatrix(
|
||||
continue;
|
||||
}
|
||||
|
||||
const runnerImagesForOs = runnerImages.filter((image) =>
|
||||
image.startsWith(operatingSystem),
|
||||
);
|
||||
const runnerImagesForOs =
|
||||
typeof operatingSystemConfig === "string" ||
|
||||
operatingSystemConfig["runner-image"] === undefined
|
||||
? defaultRunnerImages.filter((image) =>
|
||||
image.startsWith(operatingSystem),
|
||||
)
|
||||
: [operatingSystemConfig["runner-image"]];
|
||||
|
||||
for (const runnerImage of runnerImagesForOs) {
|
||||
matrix.push({
|
||||
@@ -364,7 +395,7 @@ function getSetupSteps(checkSpecification: JobSpecification): {
|
||||
const inputs: Array<Set<KnownInputName>> = [];
|
||||
const steps: Step[] = [];
|
||||
|
||||
for (const language of Object.values(KnownLanguage).sort()) {
|
||||
for (const language of Object.values(BuiltInLanguage).sort()) {
|
||||
const setupSpec = languageSetups[language];
|
||||
|
||||
if (
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env npx tsx
|
||||
|
||||
/*
|
||||
* Updates src/languages/builtin.json by querying the CodeQL CLI for:
|
||||
* - Languages that have default queries (via codeql-extractor.yml)
|
||||
* - Language aliases (via `codeql resolve languages --format=betterjson --extractor-include-aliases`)
|
||||
*
|
||||
* Usage:
|
||||
* npx tsx pr-checks/update-builtin-languages.ts [path-to-codeql]
|
||||
*
|
||||
* If no path is given, falls back to "codeql".
|
||||
*/
|
||||
|
||||
import { execFileSync } from "node:child_process";
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
|
||||
import * as yaml from "yaml";
|
||||
|
||||
import { EnvVar } from "../src/environment";
|
||||
|
||||
import { BUILTIN_LANGUAGES_FILE } from "./config";
|
||||
|
||||
/** Resolve all known language extractor directories. */
|
||||
function resolveLanguages(codeqlPath: string): Record<string, string[]> {
|
||||
return JSON.parse(
|
||||
execFileSync(codeqlPath, ["resolve", "languages", "--format=json"], {
|
||||
encoding: "utf8",
|
||||
env: {
|
||||
...process.env,
|
||||
[EnvVar.EXPERIMENTAL_FEATURES]: "true", // include experimental languages
|
||||
},
|
||||
}),
|
||||
) as Record<string, string[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sorted list of languages whose extractors ship default queries.
|
||||
*
|
||||
* @param extractorDirs - Map from language to list of extractor directories
|
||||
*/
|
||||
function findLanguagesWithDefaultQueries(
|
||||
extractorDirs: Record<string, string[]>,
|
||||
): string[] {
|
||||
const languages: string[] = [];
|
||||
|
||||
for (const [language, dirs] of Object.entries(extractorDirs)) {
|
||||
if (dirs.length !== 1) {
|
||||
throw new Error(
|
||||
`Expected exactly one extractor directory for language '${language}', but found ${dirs.length}: ${dirs.join(
|
||||
", ",
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
|
||||
const extractorYmlPath = path.join(dirs[0], "codeql-extractor.yml");
|
||||
|
||||
if (!fs.existsSync(extractorYmlPath)) {
|
||||
throw new Error(
|
||||
`Extractor YAML not found for language '${language}' at expected path: ${extractorYmlPath}`,
|
||||
);
|
||||
}
|
||||
|
||||
const extractorYml = yaml.parse(fs.readFileSync(extractorYmlPath, "utf8"));
|
||||
const defaultQueries: unknown[] | undefined = extractorYml.default_queries;
|
||||
|
||||
if (Array.isArray(defaultQueries) && defaultQueries.length > 0) {
|
||||
console.log(
|
||||
` ✅ ${language}: included (default queries: ${JSON.stringify(defaultQueries)})`,
|
||||
);
|
||||
languages.push(language);
|
||||
} else {
|
||||
console.log(` ❌ ${language}: excluded (no default queries)`);
|
||||
}
|
||||
}
|
||||
|
||||
return languages.sort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve language aliases from the CodeQL CLI, keeping only those whose
|
||||
* target is in the given set of included languages.
|
||||
*/
|
||||
function resolveAliases(
|
||||
codeqlPath: string,
|
||||
includedLanguages: Set<string>,
|
||||
): Record<string, string> {
|
||||
const betterjsonOutput = JSON.parse(
|
||||
execFileSync(
|
||||
codeqlPath,
|
||||
[
|
||||
"resolve",
|
||||
"languages",
|
||||
"--format=betterjson",
|
||||
"--extractor-include-aliases",
|
||||
],
|
||||
{ encoding: "utf8" },
|
||||
),
|
||||
);
|
||||
|
||||
return Object.fromEntries(
|
||||
Object.entries((betterjsonOutput.aliases ?? {}) as Record<string, string>)
|
||||
.filter(([, target]) => includedLanguages.has(target))
|
||||
.sort(([a], [b]) => a.localeCompare(b)),
|
||||
);
|
||||
}
|
||||
|
||||
/** Write the built-in languages data to disk. */
|
||||
function writeBuiltinLanguages(
|
||||
languages: string[],
|
||||
aliases: Record<string, string>,
|
||||
): void {
|
||||
const content = `${JSON.stringify({ languages, aliases }, null, 2)}\n`;
|
||||
fs.mkdirSync(path.dirname(BUILTIN_LANGUAGES_FILE), { recursive: true });
|
||||
fs.writeFileSync(BUILTIN_LANGUAGES_FILE, content);
|
||||
|
||||
console.log(`\nWrote ${BUILTIN_LANGUAGES_FILE}`);
|
||||
console.log(` Languages: ${languages.join(", ")}`);
|
||||
console.log(` Aliases: ${Object.keys(aliases).join(", ")}`);
|
||||
}
|
||||
|
||||
function main(): void {
|
||||
const codeqlPath = process.argv[2] || "codeql";
|
||||
|
||||
const extractorDirs = resolveLanguages(codeqlPath);
|
||||
const languages = findLanguagesWithDefaultQueries(extractorDirs);
|
||||
const aliases = resolveAliases(codeqlPath, new Set(languages));
|
||||
writeBuiltinLanguages(languages, aliases);
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,204 @@
|
||||
#!/usr/bin/env npx tsx
|
||||
|
||||
/*
|
||||
* Tests for the update-ghes-versions.ts script
|
||||
*/
|
||||
|
||||
import * as assert from "node:assert/strict";
|
||||
import { describe, it } from "node:test";
|
||||
|
||||
import {
|
||||
addWeeks,
|
||||
determineSupportedRange,
|
||||
type EnterpriseReleases,
|
||||
parseEnterpriseVersion,
|
||||
printEnterpriseVersion,
|
||||
} from "./update-ghes-versions";
|
||||
|
||||
describe("parseEnterpriseVersion", async () => {
|
||||
await it("parses a two-component version string", () => {
|
||||
const ver = parseEnterpriseVersion("3.10");
|
||||
assert.notEqual(ver, null);
|
||||
assert.equal(ver!.major, 3);
|
||||
assert.equal(ver!.minor, 10);
|
||||
assert.equal(ver!.patch, 0);
|
||||
});
|
||||
|
||||
await it("parses a three-component version string", () => {
|
||||
const ver = parseEnterpriseVersion("3.10.2");
|
||||
assert.notEqual(ver, null);
|
||||
assert.equal(ver!.major, 3);
|
||||
assert.equal(ver!.minor, 10);
|
||||
assert.equal(ver!.patch, 2);
|
||||
});
|
||||
|
||||
await it("returns null for invalid input", () => {
|
||||
assert.equal(parseEnterpriseVersion("not-a-version"), null);
|
||||
});
|
||||
});
|
||||
|
||||
describe("printEnterpriseVersion", async () => {
|
||||
await it("prints only major.minor when patch is 0", () => {
|
||||
const ver = parseEnterpriseVersion("3.10")!;
|
||||
assert.equal(printEnterpriseVersion(ver), "3.10");
|
||||
});
|
||||
|
||||
await it("includes patch when non-zero", () => {
|
||||
const ver = parseEnterpriseVersion("3.10.2")!;
|
||||
assert.equal(printEnterpriseVersion(ver), "3.10.2");
|
||||
});
|
||||
});
|
||||
|
||||
describe("addWeeks", async () => {
|
||||
await it("adds weeks to a date", () => {
|
||||
const date = new Date("2025-01-01T00:00:00Z");
|
||||
const result = addWeeks(date, 2);
|
||||
assert.equal(result.toISOString(), "2025-01-15T00:00:00.000Z");
|
||||
});
|
||||
|
||||
await it("does not mutate the original date", () => {
|
||||
const date = new Date("2025-01-01T00:00:00Z");
|
||||
addWeeks(date, 2);
|
||||
assert.equal(date.toISOString(), "2025-01-01T00:00:00.000Z");
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Helper to build a release entry with a feature freeze and end-of-life date.
|
||||
* Dates are ISO date strings (e.g. "2025-06-01").
|
||||
*/
|
||||
function release(featureFreeze: string, end: string) {
|
||||
return { feature_freeze: featureFreeze, end };
|
||||
}
|
||||
|
||||
describe("determineSupportedRange", async () => {
|
||||
// A fixed "today" for deterministic tests.
|
||||
const today = new Date("2025-06-15");
|
||||
|
||||
const farPastEnd = "2020-01-01";
|
||||
const farFutureEnd = "2099-12-31";
|
||||
const farPastFreeze = "2020-01-01";
|
||||
const farFutureFreeze = "2099-12-31";
|
||||
|
||||
await it("returns the only supported release as both min and max", () => {
|
||||
const releases: EnterpriseReleases = {
|
||||
"3.10": release(farPastFreeze, farFutureEnd),
|
||||
};
|
||||
const result = determineSupportedRange(
|
||||
today,
|
||||
{ minimumVersion: "3.10", maximumVersion: "3.10" },
|
||||
releases,
|
||||
);
|
||||
assert.equal(result.minimumVersion, "3.10");
|
||||
assert.equal(result.maximumVersion, "3.10");
|
||||
});
|
||||
|
||||
await it("determines the range from multiple supported releases", () => {
|
||||
const releases: EnterpriseReleases = {
|
||||
"3.10": release(farPastFreeze, farFutureEnd),
|
||||
"3.11": release(farPastFreeze, farFutureEnd),
|
||||
"3.12": release(farPastFreeze, farFutureEnd),
|
||||
};
|
||||
const result = determineSupportedRange(
|
||||
today,
|
||||
{ minimumVersion: "3.10", maximumVersion: "3.12" },
|
||||
releases,
|
||||
);
|
||||
assert.equal(result.minimumVersion, "3.10");
|
||||
assert.equal(result.maximumVersion, "3.12");
|
||||
});
|
||||
|
||||
await it("drops an end-of-life release from the minimum", () => {
|
||||
const releases: EnterpriseReleases = {
|
||||
// 3.10 has been end of life for a long time.
|
||||
"3.10": release(farPastFreeze, farPastEnd),
|
||||
"3.11": release(farPastFreeze, farFutureEnd),
|
||||
"3.12": release(farPastFreeze, farFutureEnd),
|
||||
};
|
||||
const result = determineSupportedRange(
|
||||
today,
|
||||
{ minimumVersion: "3.10", maximumVersion: "3.12" },
|
||||
releases,
|
||||
);
|
||||
assert.equal(result.minimumVersion, "3.11");
|
||||
assert.equal(result.maximumVersion, "3.12");
|
||||
});
|
||||
|
||||
await it("bumps the maximum when a newer release's feature freeze has passed", () => {
|
||||
const releases: EnterpriseReleases = {
|
||||
"3.10": release(farPastFreeze, farFutureEnd),
|
||||
"3.11": release(farPastFreeze, farFutureEnd),
|
||||
// 3.12 has a feature freeze far in the past, so it should be picked up.
|
||||
"3.12": release(farPastFreeze, farFutureEnd),
|
||||
};
|
||||
const result = determineSupportedRange(
|
||||
today,
|
||||
// The stored maximum is 3.11, but 3.12 should be picked up.
|
||||
{ minimumVersion: "3.10", maximumVersion: "3.11" },
|
||||
releases,
|
||||
);
|
||||
assert.equal(result.minimumVersion, "3.10");
|
||||
assert.equal(result.maximumVersion, "3.12");
|
||||
});
|
||||
|
||||
await it("does not bump the maximum when feature freeze is far in the future", () => {
|
||||
const releases: EnterpriseReleases = {
|
||||
"3.10": release(farPastFreeze, farFutureEnd),
|
||||
"3.11": release(farPastFreeze, farFutureEnd),
|
||||
// 3.12 has a feature freeze far in the future, so it should NOT be picked up.
|
||||
"3.12": release(farFutureFreeze, farFutureEnd),
|
||||
};
|
||||
const result = determineSupportedRange(
|
||||
today,
|
||||
{ minimumVersion: "3.10", maximumVersion: "3.11" },
|
||||
releases,
|
||||
);
|
||||
assert.equal(result.minimumVersion, "3.10");
|
||||
assert.equal(result.maximumVersion, "3.11");
|
||||
});
|
||||
|
||||
await it("ignores releases older than the first supported release (2.22)", () => {
|
||||
const releases: EnterpriseReleases = {
|
||||
"2.21": release(farPastFreeze, farFutureEnd),
|
||||
"3.10": release(farPastFreeze, farFutureEnd),
|
||||
"3.11": release(farPastFreeze, farFutureEnd),
|
||||
};
|
||||
const result = determineSupportedRange(
|
||||
today,
|
||||
{ minimumVersion: "3.10", maximumVersion: "3.11" },
|
||||
releases,
|
||||
);
|
||||
// 2.21 is older than 2.22, so it should be ignored — 3.10 remains the minimum.
|
||||
assert.equal(result.minimumVersion, "3.10");
|
||||
assert.equal(result.maximumVersion, "3.11");
|
||||
});
|
||||
|
||||
await it("throws when no supported releases remain", () => {
|
||||
const releases: EnterpriseReleases = {
|
||||
// All releases are end of life.
|
||||
"3.10": release(farPastFreeze, farPastEnd),
|
||||
"3.11": release(farPastFreeze, farPastEnd),
|
||||
};
|
||||
assert.throws(
|
||||
() =>
|
||||
determineSupportedRange(
|
||||
today,
|
||||
{ minimumVersion: "3.10", maximumVersion: "3.11" },
|
||||
releases,
|
||||
),
|
||||
/Could not determine oldest supported release/,
|
||||
);
|
||||
});
|
||||
|
||||
await it("throws when maximumVersion is not a valid version", () => {
|
||||
assert.throws(
|
||||
() =>
|
||||
determineSupportedRange(
|
||||
today,
|
||||
{ minimumVersion: "3.10", maximumVersion: "invalid" },
|
||||
{},
|
||||
),
|
||||
/is not a valid semantic version/,
|
||||
);
|
||||
});
|
||||
});
|
||||
Executable
+243
@@ -0,0 +1,243 @@
|
||||
#!/usr/bin/env npx tsx
|
||||
|
||||
/**
|
||||
* Updates src/api-compatibility.json with the current range of supported
|
||||
* GitHub Enterprise Server versions by reading the releases.json file from
|
||||
* an `enterprise-releases` checkout.
|
||||
*/
|
||||
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
|
||||
import { type SemVer } from "semver";
|
||||
import * as semver from "semver";
|
||||
|
||||
import * as json from "../src/json";
|
||||
|
||||
import { API_COMPATIBILITY_FILE } from "./config";
|
||||
|
||||
/** The first GHES version that included Code Scanning. */
|
||||
const FIRST_SUPPORTED_RELEASE: SemVer = new semver.SemVer("2.22.0");
|
||||
|
||||
/** Environment variables specific to this script. */
|
||||
export enum EnvVar {
|
||||
ENTERPRISE_RELEASES_PATH = "ENTERPRISE_RELEASES_PATH",
|
||||
}
|
||||
|
||||
/**
|
||||
* The semver specification requires three numeric components, but GHES release families
|
||||
* only have two. This function uses `semver.coerce` to first coerce the version string
|
||||
* into an acceptable input for `semver.parse`. E.g. `3.10` becomes `3.10.0`.
|
||||
*/
|
||||
export function parseEnterpriseVersion(val: string): SemVer | null {
|
||||
return semver.parse(semver.coerce(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mirroring `parseEnterpriseVersion`, this function returns only the major and minor
|
||||
* version components from `ver`.
|
||||
*/
|
||||
export function printEnterpriseVersion(ver: SemVer) {
|
||||
if (ver.patch === 0) {
|
||||
return `${ver.major}.${ver.minor}`;
|
||||
}
|
||||
return ver.toString();
|
||||
}
|
||||
|
||||
/** The JSON schema for `API_COMPATIBILITY_FILE`. */
|
||||
const apiCompatibilitySchema = {
|
||||
minimumVersion: json.string,
|
||||
maximumVersion: json.string,
|
||||
} as const satisfies json.Schema;
|
||||
|
||||
/** The type representing the expected contents of `API_COMPATIBILITY_FILE`. */
|
||||
type ApiCompatibility = json.FromSchema<typeof apiCompatibilitySchema>;
|
||||
|
||||
/** Reads the current contents of the `API_COMPATIBILITY_FILE` file. */
|
||||
export function readApiCompatibility(): ApiCompatibility {
|
||||
const apiCompatibilityData: unknown = JSON.parse(
|
||||
fs.readFileSync(API_COMPATIBILITY_FILE, "utf8"),
|
||||
);
|
||||
|
||||
if (!json.isObject(apiCompatibilityData)) {
|
||||
throw new Error(
|
||||
`Expected '${API_COMPATIBILITY_FILE}' to contain an object.`,
|
||||
);
|
||||
}
|
||||
if (!json.validateSchema(apiCompatibilitySchema, apiCompatibilityData)) {
|
||||
throw new Error(
|
||||
`The contents of '${API_COMPATIBILITY_FILE}' do not match the expected JSON schema.`,
|
||||
);
|
||||
}
|
||||
|
||||
return apiCompatibilityData;
|
||||
}
|
||||
|
||||
/** The JSON schema for entries in the `releases.json` file. */
|
||||
const releaseDataSchema = {
|
||||
feature_freeze: json.string,
|
||||
end: json.string,
|
||||
} as const satisfies json.Schema;
|
||||
|
||||
/** The type representing entries in the `releases.json` file. */
|
||||
export type ReleaseData = json.FromSchema<typeof releaseDataSchema>;
|
||||
|
||||
/** A mapping from GHES releases to release information. */
|
||||
export type EnterpriseReleases = Record<string, ReleaseData>;
|
||||
|
||||
/** Reads information about GHES releases. */
|
||||
export function readEnterpriseReleases(
|
||||
enterpriseReleasesPath: string,
|
||||
): EnterpriseReleases {
|
||||
const releaseFilePath = path.join(enterpriseReleasesPath, "releases.json");
|
||||
const releases: unknown = JSON.parse(
|
||||
fs.readFileSync(releaseFilePath, "utf8"),
|
||||
);
|
||||
|
||||
if (!json.isObject(releases)) {
|
||||
throw new Error(`Expected '${releaseFilePath}' to contain an object.`);
|
||||
}
|
||||
|
||||
// Remove GHES version using a previous version numbering scheme.
|
||||
delete releases["11.10"];
|
||||
|
||||
// Validate that the object satisfies the schema.
|
||||
for (const [, releaseData] of Object.entries(releases)) {
|
||||
if (!json.isObject(releaseData)) {
|
||||
throw new Error(
|
||||
`Expected release data to be an object, but it is ${typeof releaseData}.`,
|
||||
);
|
||||
}
|
||||
if (!json.validateSchema(releaseDataSchema, releaseData)) {
|
||||
throw new Error("Expected release data to satisfy schema.");
|
||||
}
|
||||
}
|
||||
|
||||
return releases;
|
||||
}
|
||||
|
||||
/** Adds `weeks`-many weeks to the UTC date of `date`. */
|
||||
export function addWeeks(date: Date, weeks: number): Date {
|
||||
const result = new Date(date);
|
||||
result.setUTCDate(date.getUTCDate() + weeks * 7);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Determines the current range of GHES versions we should support. */
|
||||
export function determineSupportedRange(
|
||||
today: Date,
|
||||
apiCompatibilityData: ApiCompatibility,
|
||||
releases: EnterpriseReleases,
|
||||
): ApiCompatibility {
|
||||
// We only care about the UTC date component.
|
||||
today.setUTCHours(0, 0, 0, 0);
|
||||
|
||||
// Our goal is to identify the oldest and newest GHES release we should support.
|
||||
// We begin with `oldestSupportRelease = undefined` so that we determine the
|
||||
// minimum from scratch and don't stick to `apiCompatibilityData.minimumVersion`
|
||||
// when it is no longer supported.
|
||||
// For `newestSupportedRelease`, we assume that `apiCompatibilityData.maximumVersion`
|
||||
// is guaranteed to not be outdated.
|
||||
let oldestSupportedRelease: SemVer | undefined;
|
||||
let newestSupportedRelease = parseEnterpriseVersion(
|
||||
apiCompatibilityData.maximumVersion,
|
||||
);
|
||||
|
||||
if (newestSupportedRelease === null) {
|
||||
throw new Error(
|
||||
`${apiCompatibilityData.maximumVersion} is not a valid semantic version.`,
|
||||
);
|
||||
}
|
||||
|
||||
// NOTE: We deliberately omit including any data from `releases` in the error messages below.
|
||||
|
||||
for (const [releaseVersionString, releaseData] of Object.entries(releases)) {
|
||||
const releaseVersion = parseEnterpriseVersion(releaseVersionString);
|
||||
|
||||
if (releaseVersion === null) {
|
||||
throw new Error("Invalid enterprise release version.");
|
||||
}
|
||||
|
||||
// Ignore GHES releases older than `FIRST_SUPPORTED_RELEASE`.
|
||||
if (semver.compare(releaseVersion, FIRST_SUPPORTED_RELEASE) < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set `newestSupportedRelease` to a GHES release if it has a greater version
|
||||
// than the current `newestSupportedRelease` and the feature freeze has
|
||||
// already happened or will be in the next two weeks.
|
||||
if (semver.compare(releaseVersion, newestSupportedRelease) > 0) {
|
||||
const featureFreezeDate = new Date(releaseData.feature_freeze);
|
||||
if (featureFreezeDate < addWeeks(today, 2)) {
|
||||
newestSupportedRelease = releaseVersion;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
oldestSupportedRelease === undefined ||
|
||||
semver.compare(releaseVersion, oldestSupportedRelease) < 0
|
||||
) {
|
||||
const endOfLifeDate = new Date(releaseData.end);
|
||||
// The GHES version is not actually end of life until the end of the day
|
||||
// specified by `endOfLifeDate`. Wait an extra week to be safe.
|
||||
const isEndOfLife = today > addWeeks(endOfLifeDate, 1);
|
||||
if (!isEndOfLife) {
|
||||
oldestSupportedRelease = releaseVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!oldestSupportedRelease) {
|
||||
throw new Error("Could not determine oldest supported release.");
|
||||
}
|
||||
|
||||
return {
|
||||
maximumVersion: printEnterpriseVersion(newestSupportedRelease),
|
||||
minimumVersion: printEnterpriseVersion(oldestSupportedRelease),
|
||||
};
|
||||
}
|
||||
|
||||
function main() {
|
||||
const enterpriseReleasesPath = process.env[EnvVar.ENTERPRISE_RELEASES_PATH];
|
||||
if (!enterpriseReleasesPath) {
|
||||
throw new Error(
|
||||
`${EnvVar.ENTERPRISE_RELEASES_PATH} environment variable must be set`,
|
||||
);
|
||||
}
|
||||
|
||||
// Get the version compatibility data stored in the repo.
|
||||
const apiCompatibilityData = readApiCompatibility();
|
||||
|
||||
// Get the GHES release information.
|
||||
const releases = readEnterpriseReleases(enterpriseReleasesPath);
|
||||
|
||||
// Determine the supported range.
|
||||
const newCompatibilityData: ApiCompatibility = determineSupportedRange(
|
||||
new Date(),
|
||||
apiCompatibilityData,
|
||||
releases,
|
||||
);
|
||||
|
||||
// If the version range has changed, write the updates to `API_COMPATIBILITY_FILE`.
|
||||
if (
|
||||
newCompatibilityData.minimumVersion !==
|
||||
apiCompatibilityData.minimumVersion ||
|
||||
newCompatibilityData.maximumVersion !== apiCompatibilityData.maximumVersion
|
||||
) {
|
||||
const data = JSON.stringify(newCompatibilityData);
|
||||
fs.writeFileSync(API_COMPATIBILITY_FILE, `${data}\n`);
|
||||
|
||||
console.log(
|
||||
`Updated '${path.basename(API_COMPATIBILITY_FILE)}': ${newCompatibilityData.minimumVersion} - ${newCompatibilityData.maximumVersion}`,
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
`No changes, not writing to '${path.basename(API_COMPATIBILITY_FILE)}'.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Only call `main` if this script was run directly.
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
@@ -22,4 +22,4 @@ outputs:
|
||||
description: The inferred build environment configuration.
|
||||
runs:
|
||||
using: node24
|
||||
main: '../lib/resolve-environment-action.js'
|
||||
main: '../lib/resolve-environment-entry.js'
|
||||
|
||||
+20
-1
@@ -19,6 +19,25 @@ inputs:
|
||||
If not specified, the Action will check in several places until it finds
|
||||
the CodeQL tools.
|
||||
required: false
|
||||
languages:
|
||||
description: >-
|
||||
A comma-separated list of CodeQL languages that will be analyzed in subsequent
|
||||
`github/codeql-action/init` and `github/codeql-action/analyze` invocations. If specified, the
|
||||
Action may use this list to select a CodeQL CLI version that is best suited to analyzing those
|
||||
languages, for example by preferring a version that has a cached overlay-base database for the
|
||||
specified languages. This input is not remembered and must also be passed to
|
||||
`github/codeql-action/init`.
|
||||
required: false
|
||||
analysis-kinds:
|
||||
description: >-
|
||||
[Internal] A comma-separated list of analysis kinds that subsequent
|
||||
`github/codeql-action/init` invocations will enable. If specified, the Action may use this
|
||||
list to select a CodeQL CLI version that is best suited to those analysis kinds. This input is
|
||||
not remembered and must also be passed to `github/codeql-action/init`.
|
||||
|
||||
Available options are the same as for the `analysis-kinds` input on the `init` Action.
|
||||
default: 'code-scanning'
|
||||
required: true
|
||||
token:
|
||||
description: GitHub token to use for authenticating with this instance of GitHub.
|
||||
default: ${{ github.token }}
|
||||
@@ -36,4 +55,4 @@ outputs:
|
||||
description: The version of the CodeQL binary that was installed.
|
||||
runs:
|
||||
using: node24
|
||||
main: '../lib/setup-codeql-action.js'
|
||||
main: '../lib/setup-codeql-entry.js'
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
"use strict";
|
||||
|
||||
const import_entry_points = require("./entry-points");
|
||||
void (0, import_entry_points.run__ACTION__)();
|
||||
+54
-9
@@ -16,7 +16,7 @@ import {
|
||||
} from "./analyses";
|
||||
import { EnvVar } from "./environment";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { setupTests } from "./testing-utils";
|
||||
import { createFeatures, RecordingLogger, setupTests } from "./testing-utils";
|
||||
import { AssessmentPayload } from "./upload-lib/types";
|
||||
import { ConfigurationError } from "./util";
|
||||
|
||||
@@ -53,24 +53,56 @@ test("Parsing analysis kinds requires at least one analysis kind", async (t) =>
|
||||
test.serial(
|
||||
"getAnalysisKinds - returns expected analysis kinds for `analysis-kinds` input",
|
||||
async (t) => {
|
||||
process.env[EnvVar.TEST_MODE] = "true";
|
||||
const features = createFeatures([]);
|
||||
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
||||
requiredInputStub
|
||||
.withArgs("analysis-kinds")
|
||||
.returns("code-scanning,code-quality");
|
||||
const result = await getAnalysisKinds(getRunnerLogger(true), true);
|
||||
const result = await getAnalysisKinds(
|
||||
getRunnerLogger(true),
|
||||
features,
|
||||
true,
|
||||
);
|
||||
t.assert(result.includes(AnalysisKind.CodeScanning));
|
||||
t.assert(result.includes(AnalysisKind.CodeQuality));
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"getAnalysisKinds - only use `code-scanning` for multiple analysis kinds outside of test mode",
|
||||
async (t) => {
|
||||
process.env[EnvVar.TEST_MODE] = "false";
|
||||
const features = createFeatures([]);
|
||||
const logger = new RecordingLogger();
|
||||
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
||||
requiredInputStub
|
||||
.withArgs("analysis-kinds")
|
||||
.returns("code-scanning,code-quality");
|
||||
const result = await getAnalysisKinds(logger, features, true);
|
||||
t.deepEqual(result, [AnalysisKind.CodeScanning]);
|
||||
t.assert(
|
||||
logger.hasMessage(
|
||||
"Continuing with only `analysis-kinds: code-scanning`.",
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"getAnalysisKinds - includes `code-quality` when deprecated `quality-queries` input is used",
|
||||
async (t) => {
|
||||
process.env[EnvVar.TEST_MODE] = "true";
|
||||
const features = createFeatures([]);
|
||||
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
||||
requiredInputStub.withArgs("analysis-kinds").returns("code-scanning");
|
||||
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
|
||||
optionalInputStub.withArgs("quality-queries").returns("code-quality");
|
||||
const result = await getAnalysisKinds(getRunnerLogger(true), true);
|
||||
const result = await getAnalysisKinds(
|
||||
getRunnerLogger(true),
|
||||
features,
|
||||
true,
|
||||
);
|
||||
t.assert(result.includes(AnalysisKind.CodeScanning));
|
||||
t.assert(result.includes(AnalysisKind.CodeQuality));
|
||||
},
|
||||
@@ -79,9 +111,12 @@ test.serial(
|
||||
test.serial(
|
||||
"getAnalysisKinds - throws if `analysis-kinds` input is invalid",
|
||||
async (t) => {
|
||||
const features = createFeatures([]);
|
||||
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
||||
requiredInputStub.withArgs("analysis-kinds").returns("no-such-thing");
|
||||
await t.throwsAsync(getAnalysisKinds(getRunnerLogger(true), true));
|
||||
await t.throwsAsync(
|
||||
getAnalysisKinds(getRunnerLogger(true), features, true),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -98,11 +133,17 @@ for (let i = 0; i < analysisKinds.length; i++) {
|
||||
test.serial(
|
||||
`getAnalysisKinds - allows ${analysisKind} with ${otherAnalysis}`,
|
||||
async (t) => {
|
||||
process.env[EnvVar.TEST_MODE] = "true";
|
||||
const features = createFeatures([]);
|
||||
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
||||
requiredInputStub
|
||||
.withArgs("analysis-kinds")
|
||||
.returns([analysisKind, otherAnalysis].join(","));
|
||||
const result = await getAnalysisKinds(getRunnerLogger(true), true);
|
||||
const result = await getAnalysisKinds(
|
||||
getRunnerLogger(true),
|
||||
features,
|
||||
true,
|
||||
);
|
||||
t.is(result.length, 2);
|
||||
},
|
||||
);
|
||||
@@ -110,14 +151,18 @@ for (let i = 0; i < analysisKinds.length; i++) {
|
||||
test.serial(
|
||||
`getAnalysisKinds - throws if ${analysisKind} is enabled with ${otherAnalysis}`,
|
||||
async (t) => {
|
||||
const features = createFeatures([]);
|
||||
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
||||
requiredInputStub
|
||||
.withArgs("analysis-kinds")
|
||||
.returns([analysisKind, otherAnalysis].join(","));
|
||||
await t.throwsAsync(getAnalysisKinds(getRunnerLogger(true), true), {
|
||||
instanceOf: ConfigurationError,
|
||||
message: `${analysisKind} and ${otherAnalysis} cannot be enabled at the same time`,
|
||||
});
|
||||
await t.throwsAsync(
|
||||
getAnalysisKinds(getRunnerLogger(true), features, true),
|
||||
{
|
||||
instanceOf: ConfigurationError,
|
||||
message: `${analysisKind} and ${otherAnalysis} cannot be enabled at the same time`,
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
+22
-1
@@ -4,13 +4,14 @@ import {
|
||||
getRequiredInput,
|
||||
} from "./actions-util";
|
||||
import { EnvVar } from "./environment";
|
||||
import { Feature, FeatureEnablement } from "./feature-flags";
|
||||
import { Logger } from "./logging";
|
||||
import {
|
||||
AssessmentPayload,
|
||||
BasePayload,
|
||||
UploadPayload,
|
||||
} from "./upload-lib/types";
|
||||
import { ConfigurationError, getRequiredEnvParam } from "./util";
|
||||
import { ConfigurationError, getRequiredEnvParam, isInTestMode } from "./util";
|
||||
|
||||
export enum AnalysisKind {
|
||||
CodeScanning = "code-scanning",
|
||||
@@ -77,6 +78,7 @@ let cachedAnalysisKinds: AnalysisKind[] | undefined;
|
||||
*/
|
||||
export async function getAnalysisKinds(
|
||||
logger: Logger,
|
||||
features: FeatureEnablement,
|
||||
skipCache: boolean = false,
|
||||
): Promise<AnalysisKind[]> {
|
||||
if (!skipCache && cachedAnalysisKinds !== undefined) {
|
||||
@@ -120,6 +122,25 @@ export async function getAnalysisKinds(
|
||||
}
|
||||
}
|
||||
|
||||
// Log an error if we have multiple inputs for `analysis-kinds` outside of test mode,
|
||||
// and enable only `code-scanning`.
|
||||
if (
|
||||
!isInTestMode() &&
|
||||
analysisKinds.length > 1 &&
|
||||
!(await features.getValue(Feature.AllowMultipleAnalysisKinds))
|
||||
) {
|
||||
logger.error(
|
||||
"The `analysis-kinds` input is experimental and for GitHub-internal use only. " +
|
||||
"Its behaviour may change at any time or be removed entirely. " +
|
||||
"Specifying multiple values as input is no longer supported. " +
|
||||
"Continuing with only `analysis-kinds: code-scanning`.",
|
||||
);
|
||||
|
||||
// Only enable Code Scanning.
|
||||
cachedAnalysisKinds = [AnalysisKind.CodeScanning];
|
||||
return cachedAnalysisKinds;
|
||||
}
|
||||
|
||||
// Cache the analysis kinds and return them.
|
||||
cachedAnalysisKinds = analysisKinds;
|
||||
return cachedAnalysisKinds;
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
import test from "ava";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import * as analyze from "./analyze";
|
||||
import * as api from "./api-client";
|
||||
import * as configUtils from "./config-utils";
|
||||
import * as gitUtils from "./git-utils";
|
||||
import * as statusReport from "./status-report";
|
||||
import {
|
||||
setupTests,
|
||||
setupActionsVars,
|
||||
mockFeatureFlagApiEndpoint,
|
||||
} from "./testing-utils";
|
||||
import * as util from "./util";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
// This test needs to be in its own file so that ava would run it in its own
|
||||
// nodejs process. The code being tested is in analyze-action.ts, which runs
|
||||
// immediately on load. So the file needs to be loaded during part of the test,
|
||||
// and that can happen only once per nodejs process. If multiple such tests are
|
||||
// in the same test file, ava would run them in the same nodejs process, and all
|
||||
// but the first test would fail.
|
||||
|
||||
test("analyze action with RAM & threads from environment variables", async (t) => {
|
||||
// This test frequently times out on Windows with the default timeout, so we bump
|
||||
// it a bit to 20s.
|
||||
t.timeout(1000 * 20);
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
sinon
|
||||
.stub(statusReport, "createStatusReportBase")
|
||||
.resolves({} as statusReport.StatusReportBase);
|
||||
sinon.stub(statusReport, "sendStatusReport").resolves();
|
||||
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
|
||||
|
||||
const gitHubVersion: util.GitHubVersion = {
|
||||
type: util.GitHubVariant.DOTCOM,
|
||||
};
|
||||
sinon.stub(configUtils, "getConfig").resolves({
|
||||
gitHubVersion,
|
||||
augmentationProperties: {},
|
||||
languages: [],
|
||||
packs: [],
|
||||
trapCaches: {},
|
||||
} as unknown as configUtils.Config);
|
||||
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
||||
requiredInputStub.withArgs("token").returns("fake-token");
|
||||
requiredInputStub.withArgs("upload-database").returns("false");
|
||||
requiredInputStub.withArgs("output").returns("out");
|
||||
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
|
||||
optionalInputStub.withArgs("expect-error").returns("false");
|
||||
sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion);
|
||||
mockFeatureFlagApiEndpoint(200, {});
|
||||
|
||||
// When there are no action inputs for RAM and threads, the action uses
|
||||
// environment variables (passed down from the init action) to set RAM and
|
||||
// threads usage.
|
||||
process.env["CODEQL_THREADS"] = "-1";
|
||||
process.env["CODEQL_RAM"] = "4992";
|
||||
|
||||
const runFinalizeStub = sinon.stub(analyze, "runFinalize");
|
||||
const runQueriesStub = sinon.stub(analyze, "runQueries");
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const analyzeAction = require("./analyze-action");
|
||||
|
||||
// When analyze-action.ts loads, it runs an async function from the top
|
||||
// level but does not wait for it to finish. To ensure that calls to
|
||||
// runFinalize and runQueries are correctly captured by spies, we explicitly
|
||||
// wait for the action promise to complete before starting verification.
|
||||
await analyzeAction.runPromise;
|
||||
|
||||
t.assert(
|
||||
runFinalizeStub.calledOnceWith(
|
||||
sinon.match.any,
|
||||
sinon.match.any,
|
||||
"--threads=-1",
|
||||
"--ram=4992",
|
||||
),
|
||||
);
|
||||
t.assert(
|
||||
runQueriesStub.calledOnceWith(
|
||||
sinon.match.any,
|
||||
"--ram=4992",
|
||||
"--threads=-1",
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,88 +0,0 @@
|
||||
import test from "ava";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import * as analyze from "./analyze";
|
||||
import * as api from "./api-client";
|
||||
import * as configUtils from "./config-utils";
|
||||
import * as gitUtils from "./git-utils";
|
||||
import * as statusReport from "./status-report";
|
||||
import {
|
||||
setupTests,
|
||||
setupActionsVars,
|
||||
mockFeatureFlagApiEndpoint,
|
||||
} from "./testing-utils";
|
||||
import * as util from "./util";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
// This test needs to be in its own file so that ava would run it in its own
|
||||
// nodejs process. The code being tested is in analyze-action.ts, which runs
|
||||
// immediately on load. So the file needs to be loaded during part of the test,
|
||||
// and that can happen only once per nodejs process. If multiple such tests are
|
||||
// in the same test file, ava would run them in the same nodejs process, and all
|
||||
// but the first test would fail.
|
||||
|
||||
test("analyze action with RAM & threads from action inputs", async (t) => {
|
||||
t.timeout(1000 * 20);
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
sinon
|
||||
.stub(statusReport, "createStatusReportBase")
|
||||
.resolves({} as statusReport.StatusReportBase);
|
||||
sinon.stub(statusReport, "sendStatusReport").resolves();
|
||||
const gitHubVersion: util.GitHubVersion = {
|
||||
type: util.GitHubVariant.DOTCOM,
|
||||
};
|
||||
sinon.stub(configUtils, "getConfig").resolves({
|
||||
gitHubVersion,
|
||||
augmentationProperties: {},
|
||||
languages: [],
|
||||
packs: [],
|
||||
trapCaches: {},
|
||||
} as unknown as configUtils.Config);
|
||||
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
||||
requiredInputStub.withArgs("token").returns("fake-token");
|
||||
requiredInputStub.withArgs("upload-database").returns("false");
|
||||
requiredInputStub.withArgs("output").returns("out");
|
||||
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
|
||||
optionalInputStub.withArgs("expect-error").returns("false");
|
||||
sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion);
|
||||
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
|
||||
mockFeatureFlagApiEndpoint(200, {});
|
||||
|
||||
process.env["CODEQL_THREADS"] = "1";
|
||||
process.env["CODEQL_RAM"] = "4992";
|
||||
|
||||
// Action inputs have precedence over environment variables.
|
||||
optionalInputStub.withArgs("threads").returns("-1");
|
||||
optionalInputStub.withArgs("ram").returns("3012");
|
||||
|
||||
const runFinalizeStub = sinon.stub(analyze, "runFinalize");
|
||||
const runQueriesStub = sinon.stub(analyze, "runQueries");
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const analyzeAction = require("./analyze-action");
|
||||
|
||||
// When analyze-action.ts loads, it runs an async function from the top
|
||||
// level but does not wait for it to finish. To ensure that calls to
|
||||
// runFinalize and runQueries are correctly captured by spies, we explicitly
|
||||
// wait for the action promise to complete before starting verification.
|
||||
await analyzeAction.runPromise;
|
||||
|
||||
t.assert(
|
||||
runFinalizeStub.calledOnceWith(
|
||||
sinon.match.any,
|
||||
sinon.match.any,
|
||||
"--threads=-1",
|
||||
"--ram=3012",
|
||||
),
|
||||
);
|
||||
t.assert(
|
||||
runQueriesStub.calledOnceWith(
|
||||
sinon.match.any,
|
||||
"--ram=3012",
|
||||
"--threads=-1",
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -20,7 +20,7 @@ import { EnvVar } from "./environment";
|
||||
import { getActionsLogger } from "./logging";
|
||||
import { checkGitHubVersionInRange, getErrorMessage } from "./util";
|
||||
|
||||
async function runWrapper() {
|
||||
export async function runWrapper() {
|
||||
// To capture errors appropriately, keep as much code within the try-catch as
|
||||
// possible, and only use safe functions outside.
|
||||
|
||||
@@ -72,5 +72,3 @@ async function runWrapper() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void runWrapper();
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
import test from "ava";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import * as analyze from "./analyze";
|
||||
import { runWrapper } from "./analyze-action";
|
||||
import * as api from "./api-client";
|
||||
import * as configUtils from "./config-utils";
|
||||
import * as gitUtils from "./git-utils";
|
||||
import * as statusReport from "./status-report";
|
||||
import {
|
||||
setupTests,
|
||||
setupActionsVars,
|
||||
mockFeatureFlagApiEndpoint,
|
||||
} from "./testing-utils";
|
||||
import * as util from "./util";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
test.serial(
|
||||
"analyze action with RAM & threads from environment variables",
|
||||
async (t) => {
|
||||
// This test frequently times out on Windows with the default timeout, so we bump
|
||||
// it a bit to 20s.
|
||||
t.timeout(1000 * 20);
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
sinon
|
||||
.stub(statusReport, "createStatusReportBase")
|
||||
.resolves({} as statusReport.StatusReportBase);
|
||||
sinon.stub(statusReport, "sendStatusReport").resolves();
|
||||
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
|
||||
|
||||
const gitHubVersion: util.GitHubVersion = {
|
||||
type: util.GitHubVariant.DOTCOM,
|
||||
};
|
||||
sinon.stub(configUtils, "getConfig").resolves({
|
||||
gitHubVersion,
|
||||
augmentationProperties: {},
|
||||
languages: [],
|
||||
packs: [],
|
||||
trapCaches: {},
|
||||
} as unknown as configUtils.Config);
|
||||
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
||||
requiredInputStub.withArgs("token").returns("fake-token");
|
||||
requiredInputStub.withArgs("upload-database").returns("false");
|
||||
requiredInputStub.withArgs("output").returns("out");
|
||||
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
|
||||
optionalInputStub.withArgs("expect-error").returns("false");
|
||||
sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion);
|
||||
mockFeatureFlagApiEndpoint(200, {});
|
||||
|
||||
// When there are no action inputs for RAM and threads, the action uses
|
||||
// environment variables (passed down from the init action) to set RAM and
|
||||
// threads usage.
|
||||
process.env["CODEQL_THREADS"] = "-1";
|
||||
process.env["CODEQL_RAM"] = "4992";
|
||||
|
||||
const runFinalizeStub = sinon.stub(analyze, "runFinalize");
|
||||
const runQueriesStub = sinon.stub(analyze, "runQueries");
|
||||
|
||||
await runWrapper();
|
||||
|
||||
t.assert(
|
||||
runFinalizeStub.calledOnceWith(
|
||||
sinon.match.any,
|
||||
sinon.match.any,
|
||||
"--threads=-1",
|
||||
"--ram=4992",
|
||||
),
|
||||
);
|
||||
t.assert(
|
||||
runQueriesStub.calledOnceWith(
|
||||
sinon.match.any,
|
||||
"--ram=4992",
|
||||
"--threads=-1",
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"analyze action with RAM & threads from action inputs",
|
||||
async (t) => {
|
||||
t.timeout(1000 * 20);
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
sinon
|
||||
.stub(statusReport, "createStatusReportBase")
|
||||
.resolves({} as statusReport.StatusReportBase);
|
||||
sinon.stub(statusReport, "sendStatusReport").resolves();
|
||||
const gitHubVersion: util.GitHubVersion = {
|
||||
type: util.GitHubVariant.DOTCOM,
|
||||
};
|
||||
sinon.stub(configUtils, "getConfig").resolves({
|
||||
gitHubVersion,
|
||||
augmentationProperties: {},
|
||||
languages: [],
|
||||
packs: [],
|
||||
trapCaches: {},
|
||||
} as unknown as configUtils.Config);
|
||||
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
|
||||
requiredInputStub.withArgs("token").returns("fake-token");
|
||||
requiredInputStub.withArgs("upload-database").returns("false");
|
||||
requiredInputStub.withArgs("output").returns("out");
|
||||
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
|
||||
optionalInputStub.withArgs("expect-error").returns("false");
|
||||
sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion);
|
||||
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
|
||||
mockFeatureFlagApiEndpoint(200, {});
|
||||
|
||||
process.env["CODEQL_THREADS"] = "1";
|
||||
process.env["CODEQL_RAM"] = "4992";
|
||||
|
||||
// Action inputs have precedence over environment variables.
|
||||
optionalInputStub.withArgs("threads").returns("-1");
|
||||
optionalInputStub.withArgs("ram").returns("3012");
|
||||
|
||||
const runFinalizeStub = sinon.stub(analyze, "runFinalize");
|
||||
const runQueriesStub = sinon.stub(analyze, "runQueries");
|
||||
|
||||
await runWrapper();
|
||||
|
||||
t.assert(
|
||||
runFinalizeStub.calledOnceWith(
|
||||
sinon.match.any,
|
||||
sinon.match.any,
|
||||
"--threads=-1",
|
||||
"--ram=3012",
|
||||
),
|
||||
);
|
||||
t.assert(
|
||||
runQueriesStub.calledOnceWith(
|
||||
sinon.match.any,
|
||||
"--ram=3012",
|
||||
"--threads=-1",
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
+13
-14
@@ -30,7 +30,7 @@ import {
|
||||
} from "./dependency-caching";
|
||||
import { EnvVar } from "./environment";
|
||||
import { initFeatures } from "./feature-flags";
|
||||
import { KnownLanguage } from "./languages";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import { getActionsLogger, Logger } from "./logging";
|
||||
import { cleanupAndUploadOverlayBaseDatabaseToCache } from "./overlay/caching";
|
||||
import { getRepositoryNwo } from "./repository";
|
||||
@@ -135,9 +135,13 @@ function hasBadExpectErrorInput(): boolean {
|
||||
function doesGoExtractionOutputExist(config: Config): boolean {
|
||||
const golangDbDirectory = util.getCodeQLDatabasePath(
|
||||
config,
|
||||
KnownLanguage.go,
|
||||
BuiltInLanguage.go,
|
||||
);
|
||||
const trapDirectory = path.join(
|
||||
golangDbDirectory,
|
||||
"trap",
|
||||
BuiltInLanguage.go,
|
||||
);
|
||||
const trapDirectory = path.join(golangDbDirectory, "trap", KnownLanguage.go);
|
||||
return (
|
||||
fs.existsSync(trapDirectory) &&
|
||||
fs
|
||||
@@ -169,7 +173,7 @@ function doesGoExtractionOutputExist(config: Config): boolean {
|
||||
* whether any extraction output already exists for Go.
|
||||
*/
|
||||
async function runAutobuildIfLegacyGoWorkflow(config: Config, logger: Logger) {
|
||||
if (!config.languages.includes(KnownLanguage.go)) {
|
||||
if (!config.languages.includes(BuiltInLanguage.go)) {
|
||||
return;
|
||||
}
|
||||
if (config.buildMode) {
|
||||
@@ -182,7 +186,7 @@ async function runAutobuildIfLegacyGoWorkflow(config: Config, logger: Logger) {
|
||||
logger.debug("Won't run Go autobuild since it has already been run.");
|
||||
return;
|
||||
}
|
||||
if (dbIsFinalized(config, KnownLanguage.go, logger)) {
|
||||
if (dbIsFinalized(config, BuiltInLanguage.go, logger)) {
|
||||
logger.debug(
|
||||
"Won't run Go autobuild since there is already a finalized database for Go.",
|
||||
);
|
||||
@@ -205,7 +209,7 @@ async function runAutobuildIfLegacyGoWorkflow(config: Config, logger: Logger) {
|
||||
logger.debug(
|
||||
"Running Go autobuild because extraction output (TRAP files) for Go code has not been found.",
|
||||
);
|
||||
await runAutobuild(config, KnownLanguage.go, logger);
|
||||
await runAutobuild(config, BuiltInLanguage.go, logger);
|
||||
}
|
||||
|
||||
async function run(startedAt: Date) {
|
||||
@@ -519,14 +523,11 @@ async function run(startedAt: Date) {
|
||||
}
|
||||
}
|
||||
|
||||
// Module-level startedAt so it can be accessed by runWrapper for error reporting
|
||||
const startedAt = new Date();
|
||||
export const runPromise = run(startedAt);
|
||||
|
||||
async function runWrapper() {
|
||||
export async function runWrapper() {
|
||||
const startedAt = new Date();
|
||||
const logger = getActionsLogger();
|
||||
try {
|
||||
await runPromise;
|
||||
await run(startedAt);
|
||||
} catch (error) {
|
||||
core.setFailed(`analyze action failed: ${util.getErrorMessage(error)}`);
|
||||
await sendUnhandledErrorStatusReport(
|
||||
@@ -538,5 +539,3 @@ async function runWrapper() {
|
||||
}
|
||||
await util.checkForTimeout();
|
||||
}
|
||||
|
||||
void runWrapper();
|
||||
|
||||
+6
-6
@@ -14,7 +14,7 @@ import {
|
||||
} from "./analyze";
|
||||
import { createStubCodeQL } from "./codeql";
|
||||
import { Feature } from "./feature-flags";
|
||||
import { KnownLanguage } from "./languages";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import {
|
||||
setupTests,
|
||||
@@ -41,7 +41,7 @@ test.serial("status report fields", async (t) => {
|
||||
const threadsFlag = "";
|
||||
sinon.stub(uploadLib, "validateSarifFileSchema");
|
||||
|
||||
for (const language of Object.values(KnownLanguage)) {
|
||||
for (const language of Object.values(BuiltInLanguage)) {
|
||||
const codeql = createStubCodeQL({
|
||||
databaseRunQueries: async () => {},
|
||||
databaseInterpretResults: async (
|
||||
@@ -130,13 +130,13 @@ test.serial("status report fields", async (t) => {
|
||||
test("resolveQuerySuiteAlias", (t) => {
|
||||
// default query suite names should resolve to something language-specific ending in `.qls`.
|
||||
for (const suite of defaultSuites) {
|
||||
const resolved = resolveQuerySuiteAlias(KnownLanguage.go, suite);
|
||||
const resolved = resolveQuerySuiteAlias(BuiltInLanguage.go, suite);
|
||||
t.assert(
|
||||
path.extname(resolved) === ".qls",
|
||||
"Resolved default suite doesn't end in .qls",
|
||||
);
|
||||
t.assert(
|
||||
resolved.indexOf(KnownLanguage.go) >= 0,
|
||||
resolved.indexOf(BuiltInLanguage.go) >= 0,
|
||||
"Resolved default suite doesn't contain language name",
|
||||
);
|
||||
}
|
||||
@@ -145,12 +145,12 @@ test("resolveQuerySuiteAlias", (t) => {
|
||||
const names = ["foo", "bar", "codeql/go-queries@1.0"];
|
||||
|
||||
for (const name of names) {
|
||||
t.deepEqual(resolveQuerySuiteAlias(KnownLanguage.go, name), name);
|
||||
t.deepEqual(resolveQuerySuiteAlias(BuiltInLanguage.go, name), name);
|
||||
}
|
||||
});
|
||||
|
||||
test("addSarifExtension", (t) => {
|
||||
for (const language of Object.values(KnownLanguage)) {
|
||||
for (const language of Object.values(BuiltInLanguage)) {
|
||||
t.deepEqual(addSarifExtension(CodeScanning, language), `${language}.sarif`);
|
||||
t.deepEqual(
|
||||
addSarifExtension(CodeQuality, language),
|
||||
|
||||
+15
-27
@@ -21,7 +21,7 @@ import {
|
||||
} from "./diff-informed-analysis-utils";
|
||||
import { EnvVar } from "./environment";
|
||||
import { FeatureEnablement, Feature } from "./feature-flags";
|
||||
import { KnownLanguage, Language } from "./languages";
|
||||
import { BuiltInLanguage, Language } from "./languages";
|
||||
import { Logger, withGroupAsync } from "./logging";
|
||||
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
|
||||
import type * as sarif from "./sarif";
|
||||
@@ -41,7 +41,7 @@ export class CodeQLAnalysisError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
type KnownLanguageKey = keyof typeof KnownLanguage;
|
||||
type BuiltInLanguageKey = keyof typeof BuiltInLanguage;
|
||||
|
||||
type RunQueriesDurationStatusReport = {
|
||||
/**
|
||||
@@ -50,12 +50,12 @@ type RunQueriesDurationStatusReport = {
|
||||
* The "builtin" designation is now outdated with the move to CLI config parsing: this is the time
|
||||
* taken to run _all_ the queries.
|
||||
*/
|
||||
[L in KnownLanguageKey as `analyze_builtin_queries_${L}_duration_ms`]?: number;
|
||||
[L in BuiltInLanguageKey as `analyze_builtin_queries_${L}_duration_ms`]?: number;
|
||||
};
|
||||
|
||||
type InterpretResultsDurationStatusReport = {
|
||||
/** Time taken in ms to interpret results for the language (or undefined if this language was not analyzed). */
|
||||
[L in KnownLanguageKey as `interpret_results_${L}_duration_ms`]?: number;
|
||||
[L in BuiltInLanguageKey as `interpret_results_${L}_duration_ms`]?: number;
|
||||
};
|
||||
|
||||
export interface QueriesStatusReport
|
||||
@@ -115,12 +115,12 @@ export async function runExtraction(
|
||||
|
||||
if (await shouldExtractLanguage(codeql, config, language)) {
|
||||
logger.startGroup(`Extracting ${language}`);
|
||||
if (language === KnownLanguage.python) {
|
||||
if (language === BuiltInLanguage.python) {
|
||||
await setupPythonExtractor(logger);
|
||||
}
|
||||
if (config.buildMode) {
|
||||
if (
|
||||
language === KnownLanguage.cpp &&
|
||||
language === BuiltInLanguage.cpp &&
|
||||
config.buildMode === BuildMode.Autobuild
|
||||
) {
|
||||
await setupCppAutobuild(codeql, logger);
|
||||
@@ -131,14 +131,14 @@ export async function runExtraction(
|
||||
// a stable path that caches can be restored into and that we can cache at the
|
||||
// end of the workflow (i.e. that does not get removed when the scratch directory is).
|
||||
if (
|
||||
language === KnownLanguage.java &&
|
||||
language === BuiltInLanguage.java &&
|
||||
config.buildMode === BuildMode.None
|
||||
) {
|
||||
process.env["CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS_DEPENDENCY_DIR"] =
|
||||
getJavaTempDependencyDir();
|
||||
}
|
||||
if (
|
||||
language === KnownLanguage.csharp &&
|
||||
language === BuiltInLanguage.csharp &&
|
||||
config.buildMode === BuildMode.None &&
|
||||
(await features.getValue(Feature.CsharpCacheBuildModeNone))
|
||||
) {
|
||||
@@ -251,16 +251,9 @@ export async function setupDiffInformedQueryRun(
|
||||
diffRanges,
|
||||
checkoutPath,
|
||||
);
|
||||
if (packDir === undefined) {
|
||||
logger.warning(
|
||||
"Cannot create diff range extension pack for diff-informed queries; " +
|
||||
"reverting to performing full analysis.",
|
||||
);
|
||||
} else {
|
||||
logger.info(
|
||||
`Successfully created diff range extension pack at ${packDir}.`,
|
||||
);
|
||||
}
|
||||
logger.info(
|
||||
`Successfully created diff range extension pack at ${packDir}.`,
|
||||
);
|
||||
return packDir;
|
||||
},
|
||||
);
|
||||
@@ -314,18 +307,13 @@ extensions:
|
||||
* @param ranges The file line ranges, as returned by
|
||||
* `getPullRequestEditedDiffRanges`.
|
||||
* @param checkoutPath The path at which the repository was checked out.
|
||||
* @returns The absolute path of the directory containing the extension pack, or
|
||||
* `undefined` if no extension pack was created.
|
||||
* @returns The absolute path of the directory containing the extension pack.
|
||||
*/
|
||||
function writeDiffRangeDataExtensionPack(
|
||||
logger: Logger,
|
||||
ranges: DiffThunkRange[] | undefined,
|
||||
ranges: DiffThunkRange[],
|
||||
checkoutPath: string,
|
||||
): string | undefined {
|
||||
if (ranges === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
): string {
|
||||
if (ranges.length === 0) {
|
||||
// An empty diff range means that there are no added or modified lines in
|
||||
// the pull request. But the `restrictAlertsTo` extensible predicate
|
||||
@@ -698,7 +686,7 @@ export async function warnIfGoInstalledAfterInit(
|
||||
|
||||
addDiagnostic(
|
||||
config,
|
||||
KnownLanguage.go,
|
||||
BuiltInLanguage.go,
|
||||
makeDiagnostic(
|
||||
"go/workflow/go-installed-after-codeql-init",
|
||||
"Go was installed after the `codeql-action/init` Action was run",
|
||||
|
||||
+22
-5
@@ -128,6 +128,8 @@ export async function getGitHubVersionFromApi(
|
||||
|
||||
// Doesn't strictly have to be the meta endpoint as we're only
|
||||
// using the response headers which are available on every request.
|
||||
//
|
||||
// See https://docs.github.com/en/rest/meta/meta#get-github-meta-information.
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
const response = await apiClient.rest.meta.get();
|
||||
|
||||
@@ -164,6 +166,9 @@ export async function getGitHubVersion(): Promise<GitHubVersion> {
|
||||
|
||||
/**
|
||||
* Get the path of the currently executing workflow relative to the repository root.
|
||||
*
|
||||
* See https://docs.github.com/en/rest/actions/workflow-runs#get-a-workflow-run
|
||||
* and https://docs.github.com/en/rest/actions/workflows#get-a-workflow.
|
||||
*/
|
||||
export async function getWorkflowRelativePath(): Promise<string> {
|
||||
const repo_nwo = getRepositoryNwo();
|
||||
@@ -252,9 +257,13 @@ export interface ActionsCacheItem {
|
||||
size_in_bytes?: number;
|
||||
}
|
||||
|
||||
/** List all Actions cache entries matching the provided key and ref. */
|
||||
/**
|
||||
* List all Actions cache entries starting with the provided key prefix and matching the provided ref.
|
||||
*
|
||||
* See https://docs.github.com/en/rest/actions/cache#list-github-actions-caches-for-a-repository.
|
||||
*/
|
||||
export async function listActionsCaches(
|
||||
key: string,
|
||||
keyPrefix: string,
|
||||
ref?: string,
|
||||
): Promise<ActionsCacheItem[]> {
|
||||
const repositoryNwo = getRepositoryNwo();
|
||||
@@ -264,13 +273,17 @@ export async function listActionsCaches(
|
||||
{
|
||||
owner: repositoryNwo.owner,
|
||||
repo: repositoryNwo.repo,
|
||||
key,
|
||||
key: keyPrefix,
|
||||
ref,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** Delete an Actions cache item by its ID. */
|
||||
/**
|
||||
* Delete an Actions cache item by its ID.
|
||||
*
|
||||
* See https://docs.github.com/en/rest/actions/cache#delete-a-github-actions-cache-for-a-repository-using-a-cache-id.
|
||||
*/
|
||||
export async function deleteActionsCache(id: number) {
|
||||
const repositoryNwo = getRepositoryNwo();
|
||||
|
||||
@@ -281,7 +294,11 @@ export async function deleteActionsCache(id: number) {
|
||||
});
|
||||
}
|
||||
|
||||
/** Retrieve all custom repository properties. */
|
||||
/**
|
||||
* Retrieve all custom repository properties.
|
||||
*
|
||||
* See https://docs.github.com/en/rest/repos/custom-properties#get-all-custom-property-values-for-a-repository.
|
||||
*/
|
||||
export async function getRepositoryProperties(repositoryNwo: RepositoryNwo) {
|
||||
return getApiClient().request("GET /repos/:owner/:repo/properties/values", {
|
||||
owner: repositoryNwo.owner,
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"maximumVersion": "3.21", "minimumVersion": "3.14"}
|
||||
{"maximumVersion": "3.21", "minimumVersion": "3.16"}
|
||||
|
||||
@@ -141,9 +141,9 @@ test("scanArtifactsForTokens handles files without tokens", async (t) => {
|
||||
}
|
||||
});
|
||||
|
||||
// `scanArchiveFile` does not support Windows, so we skip this test there.
|
||||
if (os.platform() !== "win32") {
|
||||
test("scanArtifactsForTokens finds token in debug artifacts", async (t) => {
|
||||
t.timeout(15000); // 15 seconds
|
||||
const messages: LoggedMessage[] = [];
|
||||
const logger = getRecordingLogger(messages, { logToConsole: false });
|
||||
// The zip here is a regression test based on
|
||||
|
||||
@@ -156,6 +156,10 @@ async function scanArchiveFile(
|
||||
);
|
||||
}
|
||||
|
||||
if (process.platform === "win32") {
|
||||
throw new Error("Scanning archives is not supported on Windows.");
|
||||
}
|
||||
|
||||
const result: ScanResult = {
|
||||
scannedFiles: 0,
|
||||
findings: [],
|
||||
|
||||
@@ -142,7 +142,7 @@ async function run(startedAt: Date) {
|
||||
await sendCompletedStatusReport(config, logger, startedAt, languages ?? []);
|
||||
}
|
||||
|
||||
async function runWrapper() {
|
||||
export async function runWrapper() {
|
||||
const startedAt = new Date();
|
||||
const logger = getActionsLogger();
|
||||
try {
|
||||
@@ -157,5 +157,3 @@ async function runWrapper() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void runWrapper();
|
||||
|
||||
+5
-5
@@ -7,7 +7,7 @@ import * as configUtils from "./config-utils";
|
||||
import { DocUrl } from "./doc-url";
|
||||
import { EnvVar } from "./environment";
|
||||
import { Feature, featureConfig, initFeatures } from "./feature-flags";
|
||||
import { KnownLanguage, Language } from "./languages";
|
||||
import { BuiltInLanguage, Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { getRepositoryNwo } from "./repository";
|
||||
import { asyncFilter, BuildMode } from "./util";
|
||||
@@ -72,7 +72,7 @@ export async function determineAutobuildLanguages(
|
||||
* version of the CodeQL Action.
|
||||
*/
|
||||
const autobuildLanguagesWithoutGo = autobuildLanguages.filter(
|
||||
(l) => l !== KnownLanguage.go,
|
||||
(l) => l !== BuiltInLanguage.go,
|
||||
);
|
||||
|
||||
const languages: Language[] = [];
|
||||
@@ -84,7 +84,7 @@ export async function determineAutobuildLanguages(
|
||||
// If Go is requested, run the Go autobuilder last to ensure it doesn't
|
||||
// interfere with the other autobuilder.
|
||||
if (autobuildLanguages.length !== autobuildLanguagesWithoutGo.length) {
|
||||
languages.push(KnownLanguage.go);
|
||||
languages.push(BuiltInLanguage.go);
|
||||
}
|
||||
|
||||
logger.debug(`Will autobuild ${languages.join(" and ")}.`);
|
||||
@@ -156,7 +156,7 @@ export async function runAutobuild(
|
||||
) {
|
||||
logger.startGroup(`Attempting to automatically build ${language} code`);
|
||||
const codeQL = await getCodeQL(config.codeQLCmd);
|
||||
if (language === KnownLanguage.cpp) {
|
||||
if (language === BuiltInLanguage.cpp) {
|
||||
await setupCppAutobuild(codeQL, logger);
|
||||
}
|
||||
if (config.buildMode) {
|
||||
@@ -164,7 +164,7 @@ export async function runAutobuild(
|
||||
} else {
|
||||
await codeQL.runAutobuild(config, language);
|
||||
}
|
||||
if (language === KnownLanguage.go) {
|
||||
if (language === BuiltInLanguage.go) {
|
||||
core.exportVariable(EnvVar.DID_AUTOBUILD_GOLANG, "true");
|
||||
}
|
||||
logger.endGroup();
|
||||
|
||||
+65
-43
@@ -21,7 +21,7 @@ import {
|
||||
import type { Config } from "./config-utils";
|
||||
import * as defaults from "./defaults.json";
|
||||
import { DocUrl } from "./doc-url";
|
||||
import { KnownLanguage } from "./languages";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { ToolsSource } from "./setup-codeql";
|
||||
import {
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
mockBundleDownloadApi,
|
||||
makeVersionInfo,
|
||||
createTestConfig,
|
||||
makeMacro,
|
||||
} from "./testing-utils";
|
||||
import { ToolsDownloadStatusReport } from "./tools-download";
|
||||
import * as util from "./util";
|
||||
@@ -46,7 +47,7 @@ test.beforeEach(() => {
|
||||
initializeEnvironment("1.2.3");
|
||||
|
||||
stubConfig = createTestConfig({
|
||||
languages: [KnownLanguage.cpp],
|
||||
languages: [BuiltInLanguage.cpp],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -70,8 +71,10 @@ async function installIntoToolcache({
|
||||
tmpDir,
|
||||
util.GitHubVariant.GHES,
|
||||
cliVersion !== undefined
|
||||
? { cliVersion, tagName }
|
||||
? { enabledVersions: [{ cliVersion, tagName }] }
|
||||
: SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
createFeatures([]),
|
||||
getRunnerLogger(true),
|
||||
false,
|
||||
@@ -115,7 +118,7 @@ async function stubCodeql(): Promise<codeql.CodeQL> {
|
||||
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.17.6"));
|
||||
sinon
|
||||
.stub(codeqlObject, "isTracedLanguage")
|
||||
.withArgs(KnownLanguage.cpp)
|
||||
.withArgs(BuiltInLanguage.cpp)
|
||||
.resolves(true);
|
||||
return codeqlObject;
|
||||
}
|
||||
@@ -143,6 +146,8 @@ test.serial(
|
||||
tmpDir,
|
||||
util.GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
false,
|
||||
@@ -175,6 +180,8 @@ test.serial(
|
||||
tmpDir,
|
||||
util.GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
false,
|
||||
@@ -214,6 +221,8 @@ test.serial(
|
||||
tmpDir,
|
||||
util.GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
false,
|
||||
@@ -264,6 +273,8 @@ for (const {
|
||||
tmpDir,
|
||||
util.GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
false,
|
||||
@@ -284,11 +295,11 @@ for (const {
|
||||
for (const toolcacheVersion of [
|
||||
// Test that we use the tools from the toolcache when `SAMPLE_DEFAULT_CLI_VERSION` is requested
|
||||
// and `SAMPLE_DEFAULT_CLI_VERSION-` is in the toolcache.
|
||||
SAMPLE_DEFAULT_CLI_VERSION.cliVersion,
|
||||
`${SAMPLE_DEFAULT_CLI_VERSION.cliVersion}-20230101`,
|
||||
SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion,
|
||||
`${SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion}-20230101`,
|
||||
]) {
|
||||
test.serial(
|
||||
`uses tools from toolcache when ${SAMPLE_DEFAULT_CLI_VERSION.cliVersion} is requested and ` +
|
||||
`uses tools from toolcache when ${SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion} is requested and ` +
|
||||
`${toolcacheVersion} is installed`,
|
||||
async (t) => {
|
||||
const features = createFeatures([]);
|
||||
@@ -308,11 +319,16 @@ for (const toolcacheVersion of [
|
||||
tmpDir,
|
||||
util.GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
false,
|
||||
);
|
||||
t.is(result.toolsVersion, SAMPLE_DEFAULT_CLI_VERSION.cliVersion);
|
||||
t.is(
|
||||
result.toolsVersion,
|
||||
SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion,
|
||||
);
|
||||
t.is(result.toolsSource, ToolsSource.Toolcache);
|
||||
t.is(result.toolsDownloadStatusReport?.combinedDurationMs, undefined);
|
||||
t.is(result.toolsDownloadStatusReport?.downloadDurationMs, undefined);
|
||||
@@ -342,9 +358,15 @@ test.serial(
|
||||
tmpDir,
|
||||
util.GitHubVariant.GHES,
|
||||
{
|
||||
cliVersion: defaults.cliVersion,
|
||||
tagName: defaults.bundleVersion,
|
||||
enabledVersions: [
|
||||
{
|
||||
cliVersion: defaults.cliVersion,
|
||||
tagName: defaults.bundleVersion,
|
||||
},
|
||||
],
|
||||
},
|
||||
undefined, // rawLanguages
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
false,
|
||||
@@ -384,9 +406,15 @@ test.serial(
|
||||
tmpDir,
|
||||
util.GitHubVariant.GHES,
|
||||
{
|
||||
cliVersion: defaults.cliVersion,
|
||||
tagName: defaults.bundleVersion,
|
||||
enabledVersions: [
|
||||
{
|
||||
cliVersion: defaults.cliVersion,
|
||||
tagName: defaults.bundleVersion,
|
||||
},
|
||||
],
|
||||
},
|
||||
undefined, // rawLanguages
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
false,
|
||||
@@ -426,6 +454,8 @@ test.serial(
|
||||
tmpDir,
|
||||
util.GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
false,
|
||||
@@ -467,6 +497,8 @@ test.serial(
|
||||
tmpDir,
|
||||
util.GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
false,
|
||||
@@ -540,7 +572,7 @@ test.serial("getExtraOptions throws for bad content", (t) => {
|
||||
});
|
||||
|
||||
// Test macro for ensuring different variants of injected augmented configurations
|
||||
const injectedConfigMacro = test.macro({
|
||||
const injectedConfigMacro = makeMacro({
|
||||
exec: async (
|
||||
t: ExecutionContext<unknown>,
|
||||
augmentationProperties: AugmentationProperties,
|
||||
@@ -590,9 +622,8 @@ const injectedConfigMacro = test.macro({
|
||||
`databaseInitCluster() injected config: ${providedTitle}`,
|
||||
});
|
||||
|
||||
test.serial(
|
||||
injectedConfigMacro.serial(
|
||||
"basic",
|
||||
injectedConfigMacro,
|
||||
{
|
||||
...defaultAugmentationProperties,
|
||||
},
|
||||
@@ -600,9 +631,8 @@ test.serial(
|
||||
{},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
injectedConfigMacro.serial(
|
||||
"injected packs from input",
|
||||
injectedConfigMacro,
|
||||
{
|
||||
...defaultAugmentationProperties,
|
||||
packsInput: ["xxx", "yyy"],
|
||||
@@ -613,9 +643,8 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
injectedConfigMacro.serial(
|
||||
"injected packs from input with existing packs combines",
|
||||
injectedConfigMacro,
|
||||
{
|
||||
...defaultAugmentationProperties,
|
||||
packsInputCombines: true,
|
||||
@@ -635,9 +664,8 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
injectedConfigMacro.serial(
|
||||
"injected packs from input with existing packs overrides",
|
||||
injectedConfigMacro,
|
||||
{
|
||||
...defaultAugmentationProperties,
|
||||
packsInput: ["xxx", "yyy"],
|
||||
@@ -655,9 +683,8 @@ test.serial(
|
||||
);
|
||||
|
||||
// similar, but with queries
|
||||
test.serial(
|
||||
injectedConfigMacro.serial(
|
||||
"injected queries from input",
|
||||
injectedConfigMacro,
|
||||
{
|
||||
...defaultAugmentationProperties,
|
||||
queriesInput: [{ uses: "xxx" }, { uses: "yyy" }],
|
||||
@@ -675,9 +702,8 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
injectedConfigMacro.serial(
|
||||
"injected queries from input overrides",
|
||||
injectedConfigMacro,
|
||||
{
|
||||
...defaultAugmentationProperties,
|
||||
queriesInput: [{ uses: "xxx" }, { uses: "yyy" }],
|
||||
@@ -699,9 +725,8 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
injectedConfigMacro.serial(
|
||||
"injected queries from input combines",
|
||||
injectedConfigMacro,
|
||||
{
|
||||
...defaultAugmentationProperties,
|
||||
queriesInputCombines: true,
|
||||
@@ -727,9 +752,8 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
injectedConfigMacro.serial(
|
||||
"injected queries from input combines 2",
|
||||
injectedConfigMacro,
|
||||
{
|
||||
...defaultAugmentationProperties,
|
||||
queriesInputCombines: true,
|
||||
@@ -749,9 +773,8 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
injectedConfigMacro.serial(
|
||||
"injected queries and packs, but empty",
|
||||
injectedConfigMacro,
|
||||
{
|
||||
...defaultAugmentationProperties,
|
||||
queriesInputCombines: true,
|
||||
@@ -768,9 +791,8 @@ test.serial(
|
||||
{},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
injectedConfigMacro.serial(
|
||||
"repo property queries have the highest precedence",
|
||||
injectedConfigMacro,
|
||||
{
|
||||
...defaultAugmentationProperties,
|
||||
queriesInputCombines: true,
|
||||
@@ -790,9 +812,8 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
injectedConfigMacro.serial(
|
||||
"repo property queries combines with queries input",
|
||||
injectedConfigMacro,
|
||||
{
|
||||
...defaultAugmentationProperties,
|
||||
queriesInputCombines: false,
|
||||
@@ -817,9 +838,8 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
injectedConfigMacro.serial(
|
||||
"repo property queries combines everything else",
|
||||
injectedConfigMacro,
|
||||
{
|
||||
...defaultAugmentationProperties,
|
||||
queriesInputCombines: true,
|
||||
@@ -956,7 +976,8 @@ test.serial("runTool summarizes autobuilder errors", async (t) => {
|
||||
sinon.stub(io, "which").resolves("");
|
||||
|
||||
await t.throwsAsync(
|
||||
async () => await codeqlObject.runAutobuild(stubConfig, KnownLanguage.java),
|
||||
async () =>
|
||||
await codeqlObject.runAutobuild(stubConfig, BuiltInLanguage.java),
|
||||
{
|
||||
instanceOf: util.ConfigurationError,
|
||||
message:
|
||||
@@ -982,7 +1003,8 @@ test.serial("runTool truncates long autobuilder errors", async (t) => {
|
||||
sinon.stub(io, "which").resolves("");
|
||||
|
||||
await t.throwsAsync(
|
||||
async () => await codeqlObject.runAutobuild(stubConfig, KnownLanguage.java),
|
||||
async () =>
|
||||
await codeqlObject.runAutobuild(stubConfig, BuiltInLanguage.java),
|
||||
{
|
||||
instanceOf: util.ConfigurationError,
|
||||
message:
|
||||
@@ -1050,7 +1072,7 @@ test.serial(
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"Avoids duplicating --overwrite flag if specified in CODEQL_ACTION_EXTRA_OPTIONS",
|
||||
"Avoids duplicating --force-overwrite flag if specified in CODEQL_ACTION_EXTRA_OPTIONS",
|
||||
async (t) => {
|
||||
const runnerConstructorStub = stubToolRunnerConstructor();
|
||||
const codeqlObject = await stubCodeql();
|
||||
@@ -1058,7 +1080,7 @@ test.serial(
|
||||
sinon.stub(io, "which").resolves("");
|
||||
|
||||
process.env["CODEQL_ACTION_EXTRA_OPTIONS"] =
|
||||
'{ "database": { "init": ["--overwrite"] } }';
|
||||
'{ "database": { "init": ["--force-overwrite"] } }';
|
||||
|
||||
await codeqlObject.databaseInitCluster(
|
||||
stubConfig,
|
||||
@@ -1071,9 +1093,9 @@ test.serial(
|
||||
t.true(runnerConstructorStub.calledOnce);
|
||||
const args = runnerConstructorStub.firstCall.args[1] as string[];
|
||||
t.is(
|
||||
args.filter((option: string) => option === "--overwrite").length,
|
||||
args.filter((option: string) => option === "--force-overwrite").length,
|
||||
1,
|
||||
"--overwrite should only be passed once",
|
||||
"--force-overwrite should only be passed once",
|
||||
);
|
||||
|
||||
// Clean up
|
||||
|
||||
+22
-21
@@ -277,22 +277,22 @@ let cachedCodeQL: CodeQL | undefined = undefined;
|
||||
* The version flags below can be used to conditionally enable certain features
|
||||
* on versions newer than this.
|
||||
*/
|
||||
const CODEQL_MINIMUM_VERSION = "2.17.6";
|
||||
const CODEQL_MINIMUM_VERSION = "2.19.4";
|
||||
|
||||
/**
|
||||
* This version will shortly become the oldest version of CodeQL that the Action will run with.
|
||||
*/
|
||||
const CODEQL_NEXT_MINIMUM_VERSION = "2.17.6";
|
||||
const CODEQL_NEXT_MINIMUM_VERSION = "2.19.4";
|
||||
|
||||
/**
|
||||
* This is the version of GHES that was most recently deprecated.
|
||||
*/
|
||||
const GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.13";
|
||||
const GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15";
|
||||
|
||||
/**
|
||||
* This is the deprecation date for the version of GHES that was most recently deprecated.
|
||||
*/
|
||||
const GHES_MOST_RECENT_DEPRECATION_DATE = "2025-06-19";
|
||||
const GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09";
|
||||
|
||||
/** The CLI verbosity level to use for extraction in debug mode. */
|
||||
const EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++";
|
||||
@@ -305,6 +305,8 @@ const EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++";
|
||||
* @param tempDir
|
||||
* @param variant
|
||||
* @param defaultCliVersion
|
||||
* @param rawLanguages Raw set of languages.
|
||||
* @param useOverlayAwareDefaultCliVersion Whether to select an overlay-aware default CLI version.
|
||||
* @param features Information about the features that are enabled.
|
||||
* @param logger
|
||||
* @param checkVersion Whether to check that CodeQL CLI meets the minimum
|
||||
@@ -317,6 +319,8 @@ export async function setupCodeQL(
|
||||
tempDir: string,
|
||||
variant: util.GitHubVariant,
|
||||
defaultCliVersion: CodeQLDefaultVersionInfo,
|
||||
rawLanguages: string[] | undefined,
|
||||
useOverlayAwareDefaultCliVersion: boolean,
|
||||
features: FeatureEnablement,
|
||||
logger: Logger,
|
||||
checkVersion: boolean,
|
||||
@@ -340,6 +344,8 @@ export async function setupCodeQL(
|
||||
tempDir,
|
||||
variant,
|
||||
defaultCliVersion,
|
||||
rawLanguages,
|
||||
useOverlayAwareDefaultCliVersion,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
@@ -586,13 +592,6 @@ async function getCodeQLForCmd(
|
||||
extraArgs.push(`--qlconfig-file=${qlconfigFile}`);
|
||||
}
|
||||
|
||||
const overwriteFlag = isSupportedToolsFeature(
|
||||
await this.getVersion(),
|
||||
ToolsFeature.ForceOverwrite,
|
||||
)
|
||||
? "--force-overwrite"
|
||||
: "--overwrite";
|
||||
|
||||
const overlayDatabaseMode = config.overlayDatabaseMode;
|
||||
if (overlayDatabaseMode === OverlayDatabaseMode.Overlay) {
|
||||
const overlayChangesFile = await writeOverlayChangesFile(
|
||||
@@ -619,7 +618,7 @@ async function getCodeQLForCmd(
|
||||
"init",
|
||||
...(overlayDatabaseMode === OverlayDatabaseMode.Overlay
|
||||
? []
|
||||
: [overwriteFlag]),
|
||||
: ["--force-overwrite"]),
|
||||
"--db-cluster",
|
||||
config.dbLocation,
|
||||
`--source-root=${sourceRoot}`,
|
||||
@@ -630,7 +629,14 @@ async function getCodeQLForCmd(
|
||||
// Some user configs specify `--no-calculate-baseline` as an additional
|
||||
// argument to `codeql database init`. Therefore ignore the baseline file
|
||||
// options here to avoid specifying the same argument twice and erroring.
|
||||
ignoringOptions: ["--overwrite", ...baselineFilesOptions],
|
||||
//
|
||||
// Ignore `--overwrite` to avoid passing both `--force-overwrite` and `--overwrite` if
|
||||
// the user has configured `--overwrite`.
|
||||
ignoringOptions: [
|
||||
"--force-overwrite",
|
||||
"--overwrite",
|
||||
...baselineFilesOptions,
|
||||
],
|
||||
}),
|
||||
],
|
||||
{ stdin: externalRepositoryToken },
|
||||
@@ -847,7 +853,7 @@ async function getCodeQLForCmd(
|
||||
"--sarif-group-rules-by-pack",
|
||||
"--sarif-include-query-help=always",
|
||||
"--sublanguage-file-coverage",
|
||||
...(await getJobRunUuidSarifOptions(this)),
|
||||
...(await getJobRunUuidSarifOptions()),
|
||||
...getExtraOptionsFromEnv(["database", "interpret-results"]),
|
||||
];
|
||||
if (sarifRunPropertyFlag !== undefined) {
|
||||
@@ -1277,13 +1283,8 @@ function applyAutobuildAzurePipelinesTimeoutFix() {
|
||||
].join(" ");
|
||||
}
|
||||
|
||||
async function getJobRunUuidSarifOptions(codeql: CodeQL) {
|
||||
async function getJobRunUuidSarifOptions() {
|
||||
const jobRunUuid = process.env[EnvVar.JOB_RUN_UUID];
|
||||
|
||||
return jobRunUuid &&
|
||||
(await codeql.supportsFeature(
|
||||
ToolsFeature.DatabaseInterpretResultsSupportsSarifRunProperty,
|
||||
))
|
||||
? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`]
|
||||
: [];
|
||||
return jobRunUuid ? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`] : [];
|
||||
}
|
||||
|
||||
+213
-185
@@ -18,9 +18,10 @@ import { Feature } from "./feature-flags";
|
||||
import { RepositoryProperties } from "./feature-flags/properties";
|
||||
import * as gitUtils from "./git-utils";
|
||||
import { GitVersionInfo } from "./git-utils";
|
||||
import { KnownLanguage, Language } from "./languages";
|
||||
import { BuiltInLanguage, Language } from "./languages";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { CODEQL_OVERLAY_MINIMUM_VERSION } from "./overlay";
|
||||
import * as overlayDiagnostics from "./overlay/diagnostics";
|
||||
import { OverlayDisabledReason } from "./overlay/diagnostics";
|
||||
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
|
||||
import * as overlayStatus from "./overlay/status";
|
||||
@@ -34,6 +35,7 @@ import {
|
||||
LoggedMessage,
|
||||
mockCodeQLVersion,
|
||||
createTestConfig,
|
||||
makeMacro,
|
||||
} from "./testing-utils";
|
||||
import {
|
||||
GitHubVariant,
|
||||
@@ -215,7 +217,7 @@ test.serial("load code quality config", async (t) => {
|
||||
// And the config we expect it to result in
|
||||
const expectedConfig = createTestConfig({
|
||||
analysisKinds: [AnalysisKind.CodeQuality],
|
||||
languages: [KnownLanguage.actions],
|
||||
languages: [BuiltInLanguage.actions],
|
||||
// This gets set because we only have `AnalysisKind.CodeQuality`
|
||||
computedConfig: {
|
||||
"disable-default-queries": true,
|
||||
@@ -268,7 +270,7 @@ test.serial(
|
||||
|
||||
const expectedConfig = createTestConfig({
|
||||
analysisKinds: [AnalysisKind.CodeQuality],
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
codeQLCmd: codeql.getPath(),
|
||||
computedConfig,
|
||||
dbLocation: path.resolve(tempDir, "codeql_databases"),
|
||||
@@ -518,7 +520,7 @@ test.serial("load non-empty input", async (t) => {
|
||||
|
||||
// And the config we expect it to parse to
|
||||
const expectedConfig = createTestConfig({
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
buildMode: BuildMode.None,
|
||||
originalUserInput: userConfig,
|
||||
computedConfig: userConfig,
|
||||
@@ -892,10 +894,10 @@ const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
|
||||
betterResolveLanguages: (options) =>
|
||||
Promise.resolve({
|
||||
aliases: {
|
||||
"c#": KnownLanguage.csharp,
|
||||
c: KnownLanguage.cpp,
|
||||
kotlin: KnownLanguage.java,
|
||||
typescript: KnownLanguage.javascript,
|
||||
"c#": BuiltInLanguage.csharp,
|
||||
c: BuiltInLanguage.cpp,
|
||||
kotlin: BuiltInLanguage.java,
|
||||
typescript: BuiltInLanguage.javascript,
|
||||
},
|
||||
extractors: {
|
||||
cpp: [stubExtractorEntry],
|
||||
@@ -944,12 +946,12 @@ const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
|
||||
for (const { displayName, language, feature } of [
|
||||
{
|
||||
displayName: "Java",
|
||||
language: KnownLanguage.java,
|
||||
language: BuiltInLanguage.java,
|
||||
feature: Feature.DisableJavaBuildlessEnabled,
|
||||
},
|
||||
{
|
||||
displayName: "C#",
|
||||
language: KnownLanguage.csharp,
|
||||
language: BuiltInLanguage.csharp,
|
||||
feature: Feature.DisableCsharpBuildless,
|
||||
},
|
||||
]) {
|
||||
@@ -969,7 +971,7 @@ for (const { displayName, language, feature } of [
|
||||
const messages: LoggedMessage[] = [];
|
||||
const buildMode = await configUtils.parseBuildModeInput(
|
||||
"none",
|
||||
[KnownLanguage.python],
|
||||
[BuiltInLanguage.python],
|
||||
createFeatures([feature]),
|
||||
getRecordingLogger(messages),
|
||||
);
|
||||
@@ -1019,7 +1021,7 @@ const defaultOverlayDatabaseModeTestSetup: OverlayDatabaseModeTestSetup = {
|
||||
isPullRequest: false,
|
||||
isDefaultBranch: false,
|
||||
buildMode: BuildMode.None,
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
codeqlVersion: CODEQL_OVERLAY_MINIMUM_VERSION,
|
||||
gitRoot: "/some/git/root",
|
||||
gitVersion: new GitVersionInfo("2.39.0", "2.39.0"),
|
||||
@@ -1034,10 +1036,9 @@ const defaultOverlayDatabaseModeTestSetup: OverlayDatabaseModeTestSetup = {
|
||||
repositoryProperties: {},
|
||||
};
|
||||
|
||||
const checkOverlayEnablementMacro = test.macro({
|
||||
const checkOverlayEnablementMacro = makeMacro({
|
||||
exec: async (
|
||||
t: ExecutionContext,
|
||||
_title: string,
|
||||
setupOverrides: Partial<OverlayDatabaseModeTestSetup>,
|
||||
expected:
|
||||
| {
|
||||
@@ -1091,7 +1092,7 @@ const checkOverlayEnablementMacro = test.macro({
|
||||
sinon
|
||||
.stub(codeql, "isTracedLanguage")
|
||||
.callsFake(async (lang: Language) => {
|
||||
return [KnownLanguage.java].includes(lang as KnownLanguage);
|
||||
return lang === BuiltInLanguage.java;
|
||||
});
|
||||
|
||||
// Mock git root detection
|
||||
@@ -1131,11 +1132,10 @@ const checkOverlayEnablementMacro = test.macro({
|
||||
}
|
||||
});
|
||||
},
|
||||
title: (_, title) => `checkOverlayEnablement: ${title}`,
|
||||
title: (title) => `checkOverlayEnablement: ${title}`,
|
||||
});
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Environment variable override - Overlay",
|
||||
{
|
||||
overlayDatabaseEnvVar: "overlay",
|
||||
@@ -1146,8 +1146,7 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Environment variable override - OverlayBase",
|
||||
{
|
||||
overlayDatabaseEnvVar: "overlay-base",
|
||||
@@ -1158,8 +1157,7 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Environment variable override - None",
|
||||
{
|
||||
overlayDatabaseEnvVar: "none",
|
||||
@@ -1169,8 +1167,7 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Ignore invalid environment variable",
|
||||
{
|
||||
overlayDatabaseEnvVar: "invalid-mode",
|
||||
@@ -1180,11 +1177,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Ignore feature flag when analyzing non-default branch",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript],
|
||||
},
|
||||
{
|
||||
@@ -1192,11 +1188,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay-base database on default branch when feature enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript],
|
||||
isDefaultBranch: true,
|
||||
},
|
||||
@@ -1206,15 +1201,14 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay-base database on default branch when feature enabled with custom analysis",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript],
|
||||
codeScanningConfig: {
|
||||
packs: ["some-custom-pack@1.0.0"],
|
||||
} as UserConfig,
|
||||
},
|
||||
isDefaultBranch: true,
|
||||
},
|
||||
{
|
||||
@@ -1223,11 +1217,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay-base database on default branch when code-scanning feature enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1240,11 +1233,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay-base database on default branch if runner disk space is too low",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1260,11 +1252,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay-base database on default branch if we can't determine runner disk space",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1277,11 +1268,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay-base database on default branch if runner disk space is too low and skip resource checks flag is enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1299,11 +1289,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay-base database on default branch if runner disk space is below v2 limit and v2 resource checks enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1320,11 +1309,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay-base database on default branch if runner disk space is between v2 and v1 limits and v2 resource checks enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1342,11 +1330,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay-base database on default branch if runner disk space is between v2 and v1 limits and v2 resource checks not enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1362,11 +1349,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay-base database on default branch if memory flag is too low",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1379,11 +1365,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay-base database on default branch if memory flag is too low but CodeQL >= 2.24.3",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1398,11 +1383,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay-base database on default branch if memory flag is too low and skip resource checks flag is enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1417,11 +1401,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay-base database on default branch when cached status indicates previous failure",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisJavascript,
|
||||
@@ -1435,11 +1418,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay analysis on PR when cached status indicates previous failure",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisJavascript,
|
||||
@@ -1453,18 +1435,17 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay-base database on default branch when code-scanning feature enabled with disable-default-queries",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
],
|
||||
codeScanningConfig: {
|
||||
"disable-default-queries": true,
|
||||
} as UserConfig,
|
||||
},
|
||||
isDefaultBranch: true,
|
||||
},
|
||||
{
|
||||
@@ -1472,18 +1453,17 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay-base database on default branch when code-scanning feature enabled with packs",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
],
|
||||
codeScanningConfig: {
|
||||
packs: ["some-custom-pack@1.0.0"],
|
||||
} as UserConfig,
|
||||
},
|
||||
isDefaultBranch: true,
|
||||
},
|
||||
{
|
||||
@@ -1491,18 +1471,17 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay-base database on default branch when code-scanning feature enabled with queries",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
],
|
||||
codeScanningConfig: {
|
||||
queries: [{ uses: "some-query.ql" }],
|
||||
} as UserConfig,
|
||||
},
|
||||
isDefaultBranch: true,
|
||||
},
|
||||
{
|
||||
@@ -1510,18 +1489,17 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay-base database on default branch when code-scanning feature enabled with query-filters",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
],
|
||||
codeScanningConfig: {
|
||||
"query-filters": [{ include: { "security-severity": "high" } }],
|
||||
} as UserConfig,
|
||||
},
|
||||
isDefaultBranch: true,
|
||||
},
|
||||
{
|
||||
@@ -1529,11 +1507,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay-base database on default branch when only language-specific feature enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysisJavascript],
|
||||
isDefaultBranch: true,
|
||||
},
|
||||
@@ -1542,11 +1519,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay-base database on default branch when only code-scanning feature enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysisCodeScanningJavascript],
|
||||
isDefaultBranch: true,
|
||||
},
|
||||
@@ -1555,11 +1531,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay-base database on default branch when language-specific feature disabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysis],
|
||||
isDefaultBranch: true,
|
||||
},
|
||||
@@ -1568,11 +1543,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay analysis on PR when feature enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript],
|
||||
isPullRequest: true,
|
||||
},
|
||||
@@ -1582,15 +1556,14 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay analysis on PR when feature enabled with custom analysis",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript],
|
||||
codeScanningConfig: {
|
||||
packs: ["some-custom-pack@1.0.0"],
|
||||
} as UserConfig,
|
||||
},
|
||||
isPullRequest: true,
|
||||
},
|
||||
{
|
||||
@@ -1599,11 +1572,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay analysis on PR when code-scanning feature enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1616,11 +1588,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay analysis on PR if runner disk space is too low",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1636,11 +1607,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay analysis on PR if runner disk space is too low and skip resource checks flag is enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1658,11 +1628,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay analysis on PR if we can't determine runner disk space",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1675,11 +1644,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay analysis on PR if memory flag is too low",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1692,11 +1660,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay analysis on PR if memory flag is too low but CodeQL >= 2.24.3",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1711,11 +1678,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay analysis on PR if memory flag is too low and skip resource checks flag is enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
@@ -1730,18 +1696,17 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay analysis on PR when code-scanning feature enabled with disable-default-queries",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
],
|
||||
codeScanningConfig: {
|
||||
"disable-default-queries": true,
|
||||
} as UserConfig,
|
||||
},
|
||||
isPullRequest: true,
|
||||
},
|
||||
{
|
||||
@@ -1749,18 +1714,17 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay analysis on PR when code-scanning feature enabled with packs",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
],
|
||||
codeScanningConfig: {
|
||||
packs: ["some-custom-pack@1.0.0"],
|
||||
} as UserConfig,
|
||||
},
|
||||
isPullRequest: true,
|
||||
},
|
||||
{
|
||||
@@ -1768,18 +1732,17 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay analysis on PR when code-scanning feature enabled with queries",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
],
|
||||
codeScanningConfig: {
|
||||
queries: [{ uses: "some-query.ql" }],
|
||||
} as UserConfig,
|
||||
},
|
||||
isPullRequest: true,
|
||||
},
|
||||
{
|
||||
@@ -1787,18 +1750,17 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay analysis on PR when code-scanning feature enabled with query-filters",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [
|
||||
Feature.OverlayAnalysis,
|
||||
Feature.OverlayAnalysisCodeScanningJavascript,
|
||||
],
|
||||
codeScanningConfig: {
|
||||
"query-filters": [{ include: { "security-severity": "high" } }],
|
||||
} as UserConfig,
|
||||
},
|
||||
isPullRequest: true,
|
||||
},
|
||||
{
|
||||
@@ -1806,11 +1768,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay analysis on PR when only language-specific feature enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysisJavascript],
|
||||
isPullRequest: true,
|
||||
},
|
||||
@@ -1819,11 +1780,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay analysis on PR when only code-scanning feature enabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysisCodeScanningJavascript],
|
||||
isPullRequest: true,
|
||||
},
|
||||
@@ -1832,11 +1792,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay analysis on PR when language-specific feature disabled",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysis],
|
||||
isPullRequest: true,
|
||||
},
|
||||
@@ -1845,8 +1804,7 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay PR analysis by env",
|
||||
{
|
||||
overlayDatabaseEnvVar: "overlay",
|
||||
@@ -1857,8 +1815,7 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay PR analysis by env on a runner with low disk space",
|
||||
{
|
||||
overlayDatabaseEnvVar: "overlay",
|
||||
@@ -1870,11 +1827,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay PR analysis by feature flag",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript],
|
||||
isPullRequest: true,
|
||||
},
|
||||
@@ -1884,34 +1840,31 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Fallback due to autobuild with traced language",
|
||||
{
|
||||
overlayDatabaseEnvVar: "overlay",
|
||||
buildMode: BuildMode.Autobuild,
|
||||
languages: [KnownLanguage.java],
|
||||
languages: [BuiltInLanguage.java],
|
||||
},
|
||||
{
|
||||
disabledReason: OverlayDisabledReason.IncompatibleBuildMode,
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Fallback due to no build mode with traced language",
|
||||
{
|
||||
overlayDatabaseEnvVar: "overlay",
|
||||
buildMode: undefined,
|
||||
languages: [KnownLanguage.java],
|
||||
languages: [BuiltInLanguage.java],
|
||||
},
|
||||
{
|
||||
disabledReason: OverlayDisabledReason.IncompatibleBuildMode,
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Fallback due to old CodeQL version",
|
||||
{
|
||||
overlayDatabaseEnvVar: "overlay",
|
||||
@@ -1922,8 +1875,7 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Fallback due to missing git root",
|
||||
{
|
||||
overlayDatabaseEnvVar: "overlay",
|
||||
@@ -1934,8 +1886,7 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Fallback due to old git version with submodules",
|
||||
{
|
||||
overlayDatabaseEnvVar: "overlay",
|
||||
@@ -1947,8 +1898,7 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Fallback when git version cannot be determined and repo has submodules",
|
||||
{
|
||||
overlayDatabaseEnvVar: "overlay",
|
||||
@@ -1960,8 +1910,7 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay enabled when git version cannot be determined and repo has no submodules",
|
||||
{
|
||||
overlayDatabaseEnvVar: "overlay",
|
||||
@@ -1974,11 +1923,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay when disabled via repository property",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript],
|
||||
isPullRequest: true,
|
||||
repositoryProperties: {
|
||||
@@ -1990,11 +1938,10 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Overlay not disabled when repository property is false",
|
||||
{
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
features: [Feature.OverlayAnalysis, Feature.OverlayAnalysisJavascript],
|
||||
isPullRequest: true,
|
||||
repositoryProperties: {
|
||||
@@ -2007,8 +1954,7 @@ test.serial(
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"Environment variable override takes precedence over repository property",
|
||||
{
|
||||
overlayDatabaseEnvVar: "overlay",
|
||||
@@ -2023,9 +1969,8 @@ test.serial(
|
||||
);
|
||||
|
||||
// Exercise language-specific overlay analysis features code paths
|
||||
for (const language in KnownLanguage) {
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
for (const language in BuiltInLanguage) {
|
||||
checkOverlayEnablementMacro.serial(
|
||||
`Check default overlay analysis feature for ${language}`,
|
||||
{
|
||||
languages: [language],
|
||||
@@ -2042,11 +1987,10 @@ for (const language in KnownLanguage) {
|
||||
// overlay analysis enabled, even when the base overlay feature flag is on.
|
||||
// Using swift here as it doesn't currently have overlay support — update this if
|
||||
// swift gains overlay support.
|
||||
test.serial(
|
||||
checkOverlayEnablementMacro,
|
||||
checkOverlayEnablementMacro.serial(
|
||||
"No overlay analysis for language without per-language overlay feature flag",
|
||||
{
|
||||
languages: [KnownLanguage.swift],
|
||||
languages: [BuiltInLanguage.swift],
|
||||
features: [Feature.OverlayAnalysis],
|
||||
isPullRequest: true,
|
||||
},
|
||||
@@ -2200,3 +2144,87 @@ test.serial(
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test("applyIncrementalAnalysisSettings: no-op when mode is not Overlay and diff ranges are unavailable", async (t) => {
|
||||
const config = createTestConfig({});
|
||||
config.overlayDatabaseMode = OverlayDatabaseMode.None;
|
||||
const codeql = createStubCodeQL({});
|
||||
const logger = getRunnerLogger(true);
|
||||
|
||||
await configUtils.applyIncrementalAnalysisSettings(
|
||||
config,
|
||||
false,
|
||||
codeql,
|
||||
logger,
|
||||
);
|
||||
|
||||
t.is(config.overlayDatabaseMode, OverlayDatabaseMode.None);
|
||||
t.deepEqual(config.extraQueryExclusions, []);
|
||||
});
|
||||
|
||||
test("applyIncrementalAnalysisSettings: keeps overlay mode and adds exclusions when diff ranges are available", async (t) => {
|
||||
const config = createTestConfig({
|
||||
overlayDatabaseMode: OverlayDatabaseMode.Overlay,
|
||||
});
|
||||
const codeql = createStubCodeQL({});
|
||||
const logger = getRunnerLogger(true);
|
||||
|
||||
await configUtils.applyIncrementalAnalysisSettings(
|
||||
config,
|
||||
true,
|
||||
codeql,
|
||||
logger,
|
||||
);
|
||||
|
||||
t.is(config.overlayDatabaseMode, OverlayDatabaseMode.Overlay);
|
||||
t.deepEqual(config.extraQueryExclusions, [
|
||||
{ exclude: { tags: "exclude-from-incremental" } },
|
||||
]);
|
||||
});
|
||||
|
||||
test("applyIncrementalAnalysisSettings: disables overlay analysis when diff ranges are unavailable", async (t) => {
|
||||
const config = createTestConfig({
|
||||
overlayDatabaseMode: OverlayDatabaseMode.Overlay,
|
||||
});
|
||||
config.useOverlayDatabaseCaching = true;
|
||||
const codeql = createStubCodeQL({});
|
||||
const logger = getRunnerLogger(true);
|
||||
const addDiagnosticsStub = sinon
|
||||
.stub(overlayDiagnostics, "addOverlayDisablementDiagnostics")
|
||||
.resolves();
|
||||
|
||||
await configUtils.applyIncrementalAnalysisSettings(
|
||||
config,
|
||||
false,
|
||||
codeql,
|
||||
logger,
|
||||
);
|
||||
|
||||
t.is(config.overlayDatabaseMode, OverlayDatabaseMode.None);
|
||||
t.is(config.useOverlayDatabaseCaching, false);
|
||||
t.deepEqual(config.extraQueryExclusions, []);
|
||||
t.true(addDiagnosticsStub.calledOnce);
|
||||
t.is(
|
||||
addDiagnosticsStub.firstCall.args[2],
|
||||
OverlayDisabledReason.DiffInformedAnalysisNotEnabled,
|
||||
);
|
||||
});
|
||||
|
||||
test("applyIncrementalAnalysisSettings: adds exclusions for diff-informed-only runs", async (t) => {
|
||||
const config = createTestConfig({});
|
||||
config.overlayDatabaseMode = OverlayDatabaseMode.None;
|
||||
const codeql = createStubCodeQL({});
|
||||
const logger = getRunnerLogger(true);
|
||||
|
||||
await configUtils.applyIncrementalAnalysisSettings(
|
||||
config,
|
||||
true,
|
||||
codeql,
|
||||
logger,
|
||||
);
|
||||
|
||||
t.is(config.overlayDatabaseMode, OverlayDatabaseMode.None);
|
||||
t.deepEqual(config.extraQueryExclusions, [
|
||||
{ exclude: { tags: "exclude-from-incremental" } },
|
||||
]);
|
||||
});
|
||||
|
||||
+64
-21
@@ -31,7 +31,7 @@ import {
|
||||
addNoLanguageDiagnostic,
|
||||
makeTelemetryDiagnostic,
|
||||
} from "./diagnostics";
|
||||
import { shouldPerformDiffInformedAnalysis } from "./diff-informed-analysis-utils";
|
||||
import { prepareDiffInformedAnalysis } from "./diff-informed-analysis-utils";
|
||||
import { EnvVar } from "./environment";
|
||||
import * as errorMessages from "./error-messages";
|
||||
import { Feature, FeatureEnablement } from "./feature-flags";
|
||||
@@ -48,7 +48,7 @@ import {
|
||||
hasSubmodules,
|
||||
isAnalyzingDefaultBranch,
|
||||
} from "./git-utils";
|
||||
import { KnownLanguage, Language } from "./languages";
|
||||
import { BuiltInLanguage, Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { CODEQL_OVERLAY_MINIMUM_VERSION } from "./overlay";
|
||||
import {
|
||||
@@ -274,10 +274,10 @@ async function getSupportedLanguageMap(
|
||||
for (const extractor of Object.keys(resolveResult.extractors)) {
|
||||
// If the CLI supports resolving languages with default queries, use these
|
||||
// as the set of supported languages. Otherwise, require the language to be
|
||||
// a known language.
|
||||
// a built-in language.
|
||||
if (
|
||||
resolveSupportedLanguagesUsingCli ||
|
||||
KnownLanguage[extractor] !== undefined
|
||||
BuiltInLanguage[extractor] !== undefined
|
||||
) {
|
||||
supportedLanguages[extractor] = extractor;
|
||||
}
|
||||
@@ -407,6 +407,7 @@ export async function getLanguages(
|
||||
return languages;
|
||||
}
|
||||
|
||||
/** Splits the `languages` input into a list of raw languages without checking if they are supported by CodeQL. */
|
||||
export function getRawLanguagesNoAutodetect(
|
||||
languagesInput: string | undefined,
|
||||
): string[] {
|
||||
@@ -947,7 +948,7 @@ async function validateOverlayDatabaseMode(
|
||||
await Promise.all(
|
||||
languages.map(
|
||||
async (l) =>
|
||||
l !== KnownLanguage.go && // Workaround to allow overlay analysis for Go with any build
|
||||
l !== BuiltInLanguage.go && // Workaround to allow overlay analysis for Go with any build
|
||||
// mode, since it does not yet support BMN. The Go autobuilder and/or extractor will
|
||||
// ensure that overlay-base databases are only created for supported Go build setups,
|
||||
// and that we'll fall back to full databases in other cases.
|
||||
@@ -1036,13 +1037,13 @@ async function setCppTrapCachingEnvironmentVariables(
|
||||
config: Config,
|
||||
logger: Logger,
|
||||
): Promise<void> {
|
||||
if (config.languages.includes(KnownLanguage.cpp)) {
|
||||
if (config.languages.includes(BuiltInLanguage.cpp)) {
|
||||
const envVar = "CODEQL_EXTRACTOR_CPP_TRAP_CACHING";
|
||||
if (process.env[envVar]) {
|
||||
logger.info(
|
||||
`Environment variable ${envVar} already set, leaving it unchanged.`,
|
||||
);
|
||||
} else if (config.trapCaches[KnownLanguage.cpp]) {
|
||||
} else if (config.trapCaches[BuiltInLanguage.cpp]) {
|
||||
logger.info("Enabling TRAP caching for C/C++.");
|
||||
core.exportVariable(envVar, "true");
|
||||
} else {
|
||||
@@ -1076,6 +1077,48 @@ function hasQueryCustomisation(userConfig: UserConfig): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize the incremental-analysis configuration for this run.
|
||||
*
|
||||
* Overlay analysis has only been validated in combination with diff-informed
|
||||
* analysis, so if `Overlay` mode was selected for a pull request but the diff
|
||||
* ranges could not be computed, fall back to a full non-overlay analysis.
|
||||
*
|
||||
* Query exclusions for incremental-only queries are then applied whenever the
|
||||
* diff ranges are available — which, after the fallback above, is exactly the
|
||||
* set of runs where any kind of incremental analysis (overlay or
|
||||
* diff-informed) is in effect.
|
||||
*/
|
||||
export async function applyIncrementalAnalysisSettings(
|
||||
config: Config,
|
||||
hasDiffRanges: boolean,
|
||||
codeql: CodeQL,
|
||||
logger: Logger,
|
||||
): Promise<void> {
|
||||
if (
|
||||
config.overlayDatabaseMode === OverlayDatabaseMode.Overlay &&
|
||||
!hasDiffRanges
|
||||
) {
|
||||
logger.info(
|
||||
`Reverting overlay database mode to ${OverlayDatabaseMode.None} ` +
|
||||
"because the PR diff ranges could not be computed.",
|
||||
);
|
||||
config.overlayDatabaseMode = OverlayDatabaseMode.None;
|
||||
config.useOverlayDatabaseCaching = false;
|
||||
await addOverlayDisablementDiagnostics(
|
||||
config,
|
||||
codeql,
|
||||
OverlayDisabledReason.DiffInformedAnalysisNotEnabled,
|
||||
);
|
||||
}
|
||||
|
||||
if (hasDiffRanges) {
|
||||
config.extraQueryExclusions.push({
|
||||
exclude: { tags: "exclude-from-incremental" },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and return the config.
|
||||
*
|
||||
@@ -1230,18 +1273,18 @@ export async function initConfig(
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
config.overlayDatabaseMode === OverlayDatabaseMode.Overlay ||
|
||||
(await shouldPerformDiffInformedAnalysis(
|
||||
inputs.codeql,
|
||||
inputs.features,
|
||||
logger,
|
||||
))
|
||||
) {
|
||||
config.extraQueryExclusions.push({
|
||||
exclude: { tags: "exclude-from-incremental" },
|
||||
});
|
||||
}
|
||||
const hasDiffRanges = await prepareDiffInformedAnalysis(
|
||||
inputs.codeql,
|
||||
inputs.features,
|
||||
logger,
|
||||
);
|
||||
|
||||
await applyIncrementalAnalysisSettings(
|
||||
config,
|
||||
hasDiffRanges,
|
||||
inputs.codeql,
|
||||
logger,
|
||||
);
|
||||
|
||||
if (await isTrapCachingEnabled(features, config.overlayDatabaseMode)) {
|
||||
const { trapCaches, trapCacheDownloadTime } = await downloadCacheWithTime(
|
||||
@@ -1539,7 +1582,7 @@ export async function parseBuildModeInput(
|
||||
}
|
||||
|
||||
if (
|
||||
languages.includes(KnownLanguage.csharp) &&
|
||||
languages.includes(BuiltInLanguage.csharp) &&
|
||||
(await features.getValue(Feature.DisableCsharpBuildless))
|
||||
) {
|
||||
logger.warning(
|
||||
@@ -1549,7 +1592,7 @@ export async function parseBuildModeInput(
|
||||
}
|
||||
|
||||
if (
|
||||
languages.includes(KnownLanguage.java) &&
|
||||
languages.includes(BuiltInLanguage.java) &&
|
||||
(await features.getValue(Feature.DisableJavaBuildlessEnabled))
|
||||
) {
|
||||
logger.warning(
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import test, { ExecutionContext } from "ava";
|
||||
|
||||
import { RepositoryProperties } from "../feature-flags/properties";
|
||||
import { KnownLanguage, Language } from "../languages";
|
||||
import { BuiltInLanguage, Language } from "../languages";
|
||||
import { getRunnerLogger } from "../logging";
|
||||
import {
|
||||
checkExpectedLogMessages,
|
||||
getRecordingLogger,
|
||||
LoggedMessage,
|
||||
makeMacro,
|
||||
} from "../testing-utils";
|
||||
import { ConfigurationError, prettyPrintPack } from "../util";
|
||||
|
||||
@@ -15,7 +16,7 @@ import * as dbConfig from "./db-config";
|
||||
/**
|
||||
* Test macro for ensuring the packs block is valid
|
||||
*/
|
||||
const parsePacksMacro = test.macro({
|
||||
const parsePacksMacro = makeMacro({
|
||||
exec: (
|
||||
t: ExecutionContext<unknown>,
|
||||
packsInput: string,
|
||||
@@ -33,7 +34,7 @@ const parsePacksMacro = test.macro({
|
||||
/**
|
||||
* Test macro for testing when the packs block is invalid
|
||||
*/
|
||||
const parsePacksErrorMacro = test.macro({
|
||||
const parsePacksErrorMacro = makeMacro({
|
||||
exec: (
|
||||
t: ExecutionContext<unknown>,
|
||||
packsInput: string,
|
||||
@@ -49,45 +50,42 @@ const parsePacksErrorMacro = test.macro({
|
||||
/**
|
||||
* Test macro for testing when the packs block is invalid
|
||||
*/
|
||||
const invalidPackNameMacro = test.macro({
|
||||
exec: (t: ExecutionContext, name: string) =>
|
||||
parsePacksErrorMacro.exec(
|
||||
const invalidPackNameMacro = makeMacro({
|
||||
exec: (t: ExecutionContext, arg: string) =>
|
||||
parsePacksErrorMacro.fn(
|
||||
t,
|
||||
name,
|
||||
[KnownLanguage.cpp],
|
||||
new RegExp(`^"${name}" is not a valid pack$`),
|
||||
arg,
|
||||
[BuiltInLanguage.cpp],
|
||||
new RegExp(`^"${arg}" is not a valid pack$`),
|
||||
),
|
||||
title: (_providedTitle: string | undefined, arg: string | undefined) =>
|
||||
`Invalid pack string: ${arg}`,
|
||||
});
|
||||
|
||||
test("no packs", parsePacksMacro, "", [], undefined);
|
||||
test("two packs", parsePacksMacro, "a/b,c/d@1.2.3", [KnownLanguage.cpp], {
|
||||
[KnownLanguage.cpp]: ["a/b", "c/d@1.2.3"],
|
||||
parsePacksMacro("no packs", "", [], undefined);
|
||||
parsePacksMacro("two packs", "a/b,c/d@1.2.3", [BuiltInLanguage.cpp], {
|
||||
[BuiltInLanguage.cpp]: ["a/b", "c/d@1.2.3"],
|
||||
});
|
||||
test(
|
||||
parsePacksMacro(
|
||||
"two packs with spaces",
|
||||
parsePacksMacro,
|
||||
" a/b , c/d@1.2.3 ",
|
||||
[KnownLanguage.cpp],
|
||||
[BuiltInLanguage.cpp],
|
||||
{
|
||||
[KnownLanguage.cpp]: ["a/b", "c/d@1.2.3"],
|
||||
[BuiltInLanguage.cpp]: ["a/b", "c/d@1.2.3"],
|
||||
},
|
||||
);
|
||||
test(
|
||||
parsePacksErrorMacro(
|
||||
"two packs with language",
|
||||
parsePacksErrorMacro,
|
||||
"a/b,c/d@1.2.3",
|
||||
[KnownLanguage.cpp, KnownLanguage.java],
|
||||
[BuiltInLanguage.cpp, BuiltInLanguage.java],
|
||||
new RegExp(
|
||||
"Cannot specify a 'packs' input in a multi-language analysis. " +
|
||||
"Use a codeql-config.yml file instead and specify packs by language.",
|
||||
),
|
||||
);
|
||||
|
||||
test(
|
||||
parsePacksMacro(
|
||||
"packs with other valid names",
|
||||
parsePacksMacro,
|
||||
[
|
||||
// ranges are ok
|
||||
"c/d@1.0",
|
||||
@@ -106,9 +104,9 @@ test(
|
||||
// (globbing is not done)
|
||||
"c/d@1.2.3:+*)_(",
|
||||
].join(","),
|
||||
[KnownLanguage.cpp],
|
||||
[BuiltInLanguage.cpp],
|
||||
{
|
||||
[KnownLanguage.cpp]: [
|
||||
[BuiltInLanguage.cpp]: [
|
||||
"c/d@1.0",
|
||||
"c/d@~1.0.0",
|
||||
"c/d@~1.0.0:a/b",
|
||||
@@ -123,23 +121,23 @@ test(
|
||||
},
|
||||
);
|
||||
|
||||
test(invalidPackNameMacro, "c"); // all packs require at least a scope and a name
|
||||
test(invalidPackNameMacro, "c-/d");
|
||||
test(invalidPackNameMacro, "-c/d");
|
||||
test(invalidPackNameMacro, "c/d_d");
|
||||
test(invalidPackNameMacro, "c/d@@");
|
||||
test(invalidPackNameMacro, "c/d@1.0.0:");
|
||||
test(invalidPackNameMacro, "c/d:");
|
||||
test(invalidPackNameMacro, "c/d:/a");
|
||||
test(invalidPackNameMacro, "@1.0.0:a");
|
||||
test(invalidPackNameMacro, "c/d@../a");
|
||||
test(invalidPackNameMacro, "c/d@b/../a");
|
||||
test(invalidPackNameMacro, "c/d:z@1");
|
||||
invalidPackNameMacro.test("c"); // all packs require at least a scope and a name
|
||||
invalidPackNameMacro.test("c-/d");
|
||||
invalidPackNameMacro.test("-c/d");
|
||||
invalidPackNameMacro.test("c/d_d");
|
||||
invalidPackNameMacro.test("c/d@@");
|
||||
invalidPackNameMacro.test("c/d@1.0.0:");
|
||||
invalidPackNameMacro.test("c/d:");
|
||||
invalidPackNameMacro.test("c/d:/a");
|
||||
invalidPackNameMacro.test("@1.0.0:a");
|
||||
invalidPackNameMacro.test("c/d@../a");
|
||||
invalidPackNameMacro.test("c/d@b/../a");
|
||||
invalidPackNameMacro.test("c/d:z@1");
|
||||
|
||||
/**
|
||||
* Test macro for pretty printing pack specs
|
||||
*/
|
||||
const packSpecPrettyPrintingMacro = test.macro({
|
||||
const packSpecPrettyPrintingMacro = makeMacro({
|
||||
exec: (t: ExecutionContext, packStr: string, packObj: dbConfig.Pack) => {
|
||||
const parsed = dbConfig.parsePacksSpecification(packStr);
|
||||
t.deepEqual(parsed, packObj, "parsed pack spec is correct");
|
||||
@@ -163,36 +161,35 @@ const packSpecPrettyPrintingMacro = test.macro({
|
||||
) => `Prettyprint pack spec: '${packStr}'`,
|
||||
});
|
||||
|
||||
test(packSpecPrettyPrintingMacro, "a/b", {
|
||||
packSpecPrettyPrintingMacro.test("a/b", {
|
||||
name: "a/b",
|
||||
version: undefined,
|
||||
path: undefined,
|
||||
});
|
||||
test(packSpecPrettyPrintingMacro, "a/b@~1.2.3", {
|
||||
packSpecPrettyPrintingMacro.test("a/b@~1.2.3", {
|
||||
name: "a/b",
|
||||
version: "~1.2.3",
|
||||
path: undefined,
|
||||
});
|
||||
test(packSpecPrettyPrintingMacro, "a/b@~1.2.3:abc/def", {
|
||||
packSpecPrettyPrintingMacro.test("a/b@~1.2.3:abc/def", {
|
||||
name: "a/b",
|
||||
version: "~1.2.3",
|
||||
path: "abc/def",
|
||||
});
|
||||
test(packSpecPrettyPrintingMacro, "a/b:abc/def", {
|
||||
packSpecPrettyPrintingMacro.test("a/b:abc/def", {
|
||||
name: "a/b",
|
||||
version: undefined,
|
||||
path: "abc/def",
|
||||
});
|
||||
test(packSpecPrettyPrintingMacro, " a/b:abc/def ", {
|
||||
packSpecPrettyPrintingMacro.test(" a/b:abc/def ", {
|
||||
name: "a/b",
|
||||
version: undefined,
|
||||
path: "abc/def",
|
||||
});
|
||||
|
||||
const calculateAugmentationMacro = test.macro({
|
||||
const calculateAugmentationMacro = makeMacro({
|
||||
exec: async (
|
||||
t: ExecutionContext,
|
||||
_title: string,
|
||||
rawPacksInput: string | undefined,
|
||||
rawQueriesInput: string | undefined,
|
||||
languages: Language[],
|
||||
@@ -207,27 +204,25 @@ const calculateAugmentationMacro = test.macro({
|
||||
);
|
||||
t.deepEqual(actualAugmentationProperties, expectedAugmentationProperties);
|
||||
},
|
||||
title: (_, title) => `Calculate Augmentation: ${title}`,
|
||||
title: (title) => `Calculate Augmentation: ${title}`,
|
||||
});
|
||||
|
||||
test(
|
||||
calculateAugmentationMacro,
|
||||
calculateAugmentationMacro(
|
||||
"All empty",
|
||||
undefined,
|
||||
undefined,
|
||||
[KnownLanguage.javascript],
|
||||
[BuiltInLanguage.javascript],
|
||||
{},
|
||||
{
|
||||
...dbConfig.defaultAugmentationProperties,
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
calculateAugmentationMacro,
|
||||
calculateAugmentationMacro(
|
||||
"With queries",
|
||||
undefined,
|
||||
" a, b , c, d",
|
||||
[KnownLanguage.javascript],
|
||||
[BuiltInLanguage.javascript],
|
||||
{},
|
||||
{
|
||||
...dbConfig.defaultAugmentationProperties,
|
||||
@@ -235,12 +230,11 @@ test(
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
calculateAugmentationMacro,
|
||||
calculateAugmentationMacro(
|
||||
"With queries combining",
|
||||
undefined,
|
||||
" + a, b , c, d ",
|
||||
[KnownLanguage.javascript],
|
||||
[BuiltInLanguage.javascript],
|
||||
{},
|
||||
{
|
||||
...dbConfig.defaultAugmentationProperties,
|
||||
@@ -249,12 +243,11 @@ test(
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
calculateAugmentationMacro,
|
||||
calculateAugmentationMacro(
|
||||
"With packs",
|
||||
" codeql/a , codeql/b , codeql/c , codeql/d ",
|
||||
undefined,
|
||||
[KnownLanguage.javascript],
|
||||
[BuiltInLanguage.javascript],
|
||||
{},
|
||||
{
|
||||
...dbConfig.defaultAugmentationProperties,
|
||||
@@ -262,12 +255,11 @@ test(
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
calculateAugmentationMacro,
|
||||
calculateAugmentationMacro(
|
||||
"With packs combining",
|
||||
" + codeql/a, codeql/b, codeql/c, codeql/d",
|
||||
undefined,
|
||||
[KnownLanguage.javascript],
|
||||
[BuiltInLanguage.javascript],
|
||||
{},
|
||||
{
|
||||
...dbConfig.defaultAugmentationProperties,
|
||||
@@ -276,12 +268,11 @@ test(
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
calculateAugmentationMacro,
|
||||
calculateAugmentationMacro(
|
||||
"With repo property queries",
|
||||
undefined,
|
||||
undefined,
|
||||
[KnownLanguage.javascript],
|
||||
[BuiltInLanguage.javascript],
|
||||
{
|
||||
"github-codeql-extra-queries": "a, b, c, d",
|
||||
},
|
||||
@@ -294,12 +285,11 @@ test(
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
calculateAugmentationMacro,
|
||||
calculateAugmentationMacro(
|
||||
"With repo property queries combining",
|
||||
undefined,
|
||||
undefined,
|
||||
[KnownLanguage.javascript],
|
||||
[BuiltInLanguage.javascript],
|
||||
{
|
||||
"github-codeql-extra-queries": "+ a, b, c, d",
|
||||
},
|
||||
@@ -312,10 +302,9 @@ test(
|
||||
},
|
||||
);
|
||||
|
||||
const calculateAugmentationErrorMacro = test.macro({
|
||||
const calculateAugmentationErrorMacro = makeMacro({
|
||||
exec: async (
|
||||
t: ExecutionContext,
|
||||
_title: string,
|
||||
rawPacksInput: string | undefined,
|
||||
rawQueriesInput: string | undefined,
|
||||
languages: Language[],
|
||||
@@ -333,53 +322,48 @@ const calculateAugmentationErrorMacro = test.macro({
|
||||
{ message: expectedError },
|
||||
);
|
||||
},
|
||||
title: (_, title) => `Calculate Augmentation Error: ${title}`,
|
||||
title: (title) => `Calculate Augmentation Error: ${title}`,
|
||||
});
|
||||
|
||||
test(
|
||||
calculateAugmentationErrorMacro,
|
||||
calculateAugmentationErrorMacro(
|
||||
"Plus (+) with nothing else (queries)",
|
||||
undefined,
|
||||
" + ",
|
||||
[KnownLanguage.javascript],
|
||||
[BuiltInLanguage.javascript],
|
||||
{},
|
||||
/The workflow property "queries" is invalid/,
|
||||
);
|
||||
|
||||
test(
|
||||
calculateAugmentationErrorMacro,
|
||||
calculateAugmentationErrorMacro(
|
||||
"Plus (+) with nothing else (packs)",
|
||||
" + ",
|
||||
undefined,
|
||||
[KnownLanguage.javascript],
|
||||
[BuiltInLanguage.javascript],
|
||||
{},
|
||||
/The workflow property "packs" is invalid/,
|
||||
);
|
||||
|
||||
test(
|
||||
calculateAugmentationErrorMacro,
|
||||
calculateAugmentationErrorMacro(
|
||||
"Plus (+) with nothing else (repo property queries)",
|
||||
undefined,
|
||||
undefined,
|
||||
[KnownLanguage.javascript],
|
||||
[BuiltInLanguage.javascript],
|
||||
{
|
||||
"github-codeql-extra-queries": " + ",
|
||||
},
|
||||
/The repository property "github-codeql-extra-queries" is invalid/,
|
||||
);
|
||||
|
||||
test(
|
||||
calculateAugmentationErrorMacro,
|
||||
calculateAugmentationErrorMacro(
|
||||
"Packs input with multiple languages",
|
||||
" + a/b, c/d ",
|
||||
undefined,
|
||||
[KnownLanguage.javascript, KnownLanguage.java],
|
||||
[BuiltInLanguage.javascript, BuiltInLanguage.java],
|
||||
{},
|
||||
/Cannot specify a 'packs' input in a multi-language analysis/,
|
||||
);
|
||||
|
||||
test(
|
||||
calculateAugmentationErrorMacro,
|
||||
calculateAugmentationErrorMacro(
|
||||
"Packs input with no languages",
|
||||
" + a/b, c/d ",
|
||||
undefined,
|
||||
@@ -388,12 +372,11 @@ test(
|
||||
/No languages specified/,
|
||||
);
|
||||
|
||||
test(
|
||||
calculateAugmentationErrorMacro,
|
||||
calculateAugmentationErrorMacro(
|
||||
"Invalid packs",
|
||||
" a-pack-without-a-scope ",
|
||||
undefined,
|
||||
[KnownLanguage.javascript],
|
||||
[BuiltInLanguage.javascript],
|
||||
{},
|
||||
/"a-pack-without-a-scope" is not a valid pack/,
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ import { createStubCodeQL } from "./codeql";
|
||||
import { Config } from "./config-utils";
|
||||
import { cleanupAndUploadDatabases } from "./database-upload";
|
||||
import * as gitUtils from "./git-utils";
|
||||
import { KnownLanguage } from "./languages";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import { RepositoryNwo } from "./repository";
|
||||
import {
|
||||
checkExpectedLogMessages,
|
||||
@@ -45,7 +45,7 @@ const testApiDetails: GitHubApiDetails = {
|
||||
|
||||
function getTestConfig(tmpDir: string): Config {
|
||||
return createTestConfig({
|
||||
languages: [KnownLanguage.javascript],
|
||||
languages: [BuiltInLanguage.javascript],
|
||||
dbLocation: tmpDir,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ export function getArtifactSuffix(matrix: string | undefined): string {
|
||||
try {
|
||||
const matrixObject = JSON.parse(matrix);
|
||||
if (json.isObject(matrixObject)) {
|
||||
for (const matrixKey of Object.keys(matrixObject as object).sort())
|
||||
for (const matrixKey of Object.keys(matrixObject).sort())
|
||||
suffix += `-${matrixObject[matrixKey]}`;
|
||||
} else {
|
||||
core.warning("User-specified `matrix` input is not an object.");
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"bundleVersion": "codeql-bundle-v2.25.2",
|
||||
"cliVersion": "2.25.2",
|
||||
"priorBundleVersion": "codeql-bundle-v2.25.1",
|
||||
"priorCliVersion": "2.25.1"
|
||||
"bundleVersion": "codeql-bundle-v2.25.4",
|
||||
"cliVersion": "2.25.4",
|
||||
"priorBundleVersion": "codeql-bundle-v2.25.3",
|
||||
"priorCliVersion": "2.25.3"
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
CacheStoreResult,
|
||||
} from "./dependency-caching";
|
||||
import { Feature } from "./feature-flags";
|
||||
import { KnownLanguage } from "./languages";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import {
|
||||
setupTests,
|
||||
createFeatures,
|
||||
@@ -179,7 +179,7 @@ test("checkHashPatterns - logs when no patterns match", async (t) => {
|
||||
const result = await checkHashPatterns(
|
||||
codeql,
|
||||
features,
|
||||
KnownLanguage.csharp,
|
||||
BuiltInLanguage.csharp,
|
||||
config,
|
||||
"download",
|
||||
getRecordingLogger(messages),
|
||||
@@ -208,7 +208,7 @@ test("checkHashPatterns - returns patterns when patterns match", async (t) => {
|
||||
const result = await checkHashPatterns(
|
||||
codeql,
|
||||
features,
|
||||
KnownLanguage.csharp,
|
||||
BuiltInLanguage.csharp,
|
||||
config,
|
||||
"upload",
|
||||
getRecordingLogger(messages),
|
||||
@@ -270,7 +270,7 @@ test.serial(
|
||||
const keyWithFeature = await cacheKey(
|
||||
codeql,
|
||||
createFeatures([Feature.CsharpNewCacheKey]),
|
||||
KnownLanguage.csharp,
|
||||
BuiltInLanguage.csharp,
|
||||
// Patterns don't matter here because we have stubbed `hashFiles` to always return a specific hash above.
|
||||
[],
|
||||
);
|
||||
@@ -288,12 +288,12 @@ test.serial(
|
||||
const result = await downloadDependencyCaches(
|
||||
codeql,
|
||||
createFeatures([]),
|
||||
[KnownLanguage.csharp],
|
||||
[BuiltInLanguage.csharp],
|
||||
logger,
|
||||
);
|
||||
const statusReport = result.statusReport;
|
||||
t.is(statusReport.length, 1);
|
||||
t.is(statusReport[0].language, KnownLanguage.csharp);
|
||||
t.is(statusReport[0].language, BuiltInLanguage.csharp);
|
||||
t.is(statusReport[0].hit_kind, CacheHitKind.Miss);
|
||||
t.deepEqual(result.restoredKeys, []);
|
||||
t.assert(restoreCacheStub.calledOnce);
|
||||
@@ -316,7 +316,7 @@ test.serial(
|
||||
const keyWithFeature = await cacheKey(
|
||||
codeql,
|
||||
features,
|
||||
KnownLanguage.csharp,
|
||||
BuiltInLanguage.csharp,
|
||||
// Patterns don't matter here because we have stubbed `hashFiles` to always return a specific hash above.
|
||||
[],
|
||||
);
|
||||
@@ -334,14 +334,14 @@ test.serial(
|
||||
const result = await downloadDependencyCaches(
|
||||
codeql,
|
||||
features,
|
||||
[KnownLanguage.csharp],
|
||||
[BuiltInLanguage.csharp],
|
||||
logger,
|
||||
);
|
||||
|
||||
// Check that the status report for telemetry indicates that one cache was restored with an exact match.
|
||||
const statusReport = result.statusReport;
|
||||
t.is(statusReport.length, 1);
|
||||
t.is(statusReport[0].language, KnownLanguage.csharp);
|
||||
t.is(statusReport[0].language, BuiltInLanguage.csharp);
|
||||
t.is(statusReport[0].hit_kind, CacheHitKind.Exact);
|
||||
|
||||
// Check that the restored key has been returned.
|
||||
@@ -380,7 +380,7 @@ test.serial(
|
||||
const keyWithFeature = await cacheKey(
|
||||
codeql,
|
||||
features,
|
||||
KnownLanguage.csharp,
|
||||
BuiltInLanguage.csharp,
|
||||
// Patterns don't matter here because we have stubbed `hashFiles` to always return a specific hash above.
|
||||
[],
|
||||
);
|
||||
@@ -398,14 +398,14 @@ test.serial(
|
||||
const result = await downloadDependencyCaches(
|
||||
codeql,
|
||||
features,
|
||||
[KnownLanguage.csharp],
|
||||
[BuiltInLanguage.csharp],
|
||||
logger,
|
||||
);
|
||||
|
||||
// Check that the status report for telemetry indicates that one cache was restored with a partial match.
|
||||
const statusReport = result.statusReport;
|
||||
t.is(statusReport.length, 1);
|
||||
t.is(statusReport[0].language, KnownLanguage.csharp);
|
||||
t.is(statusReport[0].language, BuiltInLanguage.csharp);
|
||||
t.is(statusReport[0].hit_kind, CacheHitKind.Partial);
|
||||
|
||||
// Check that the restored key has been returned.
|
||||
@@ -426,7 +426,7 @@ test("uploadDependencyCaches - skips upload for a language with no cache config"
|
||||
const logger = getRecordingLogger(messages);
|
||||
const features = createFeatures([]);
|
||||
const config = createTestConfig({
|
||||
languages: [KnownLanguage.actions],
|
||||
languages: [BuiltInLanguage.actions],
|
||||
});
|
||||
|
||||
const result = await uploadDependencyCaches(codeql, features, config, logger);
|
||||
@@ -444,7 +444,7 @@ test.serial(
|
||||
const logger = getRecordingLogger(messages);
|
||||
const features = createFeatures([]);
|
||||
const config = createTestConfig({
|
||||
languages: [KnownLanguage.go],
|
||||
languages: [BuiltInLanguage.go],
|
||||
});
|
||||
|
||||
const makePatternCheckStub = sinon.stub(internal, "makePatternCheck");
|
||||
@@ -457,7 +457,7 @@ test.serial(
|
||||
logger,
|
||||
);
|
||||
t.is(result.length, 1);
|
||||
t.is(result[0].language, KnownLanguage.go);
|
||||
t.is(result[0].language, BuiltInLanguage.go);
|
||||
t.is(result[0].result, CacheStoreResult.NoHash);
|
||||
},
|
||||
);
|
||||
@@ -483,12 +483,12 @@ test.serial(
|
||||
const primaryCacheKey = await cacheKey(
|
||||
codeql,
|
||||
features,
|
||||
KnownLanguage.csharp,
|
||||
BuiltInLanguage.csharp,
|
||||
CSHARP_BASE_PATTERNS,
|
||||
);
|
||||
|
||||
const config = createTestConfig({
|
||||
languages: [KnownLanguage.csharp],
|
||||
languages: [BuiltInLanguage.csharp],
|
||||
dependencyCachingRestoredKeys: [primaryCacheKey],
|
||||
});
|
||||
|
||||
@@ -499,7 +499,7 @@ test.serial(
|
||||
logger,
|
||||
);
|
||||
t.is(result.length, 1);
|
||||
t.is(result[0].language, KnownLanguage.csharp);
|
||||
t.is(result[0].language, BuiltInLanguage.csharp);
|
||||
t.is(result[0].result, CacheStoreResult.Duplicate);
|
||||
},
|
||||
);
|
||||
@@ -525,7 +525,7 @@ test.serial(
|
||||
sinon.stub(cachingUtils, "getTotalCacheSize").resolves(0);
|
||||
|
||||
const config = createTestConfig({
|
||||
languages: [KnownLanguage.csharp],
|
||||
languages: [BuiltInLanguage.csharp],
|
||||
});
|
||||
|
||||
const result = await uploadDependencyCaches(
|
||||
@@ -535,7 +535,7 @@ test.serial(
|
||||
logger,
|
||||
);
|
||||
t.is(result.length, 1);
|
||||
t.is(result[0].language, KnownLanguage.csharp);
|
||||
t.is(result[0].language, BuiltInLanguage.csharp);
|
||||
t.is(result[0].result, CacheStoreResult.Empty);
|
||||
|
||||
checkExpectedLogMessages(t, messages, [
|
||||
@@ -566,7 +566,7 @@ test.serial(
|
||||
sinon.stub(actionsCache, "saveCache").resolves();
|
||||
|
||||
const config = createTestConfig({
|
||||
languages: [KnownLanguage.csharp],
|
||||
languages: [BuiltInLanguage.csharp],
|
||||
});
|
||||
|
||||
const result = await uploadDependencyCaches(
|
||||
@@ -576,7 +576,7 @@ test.serial(
|
||||
logger,
|
||||
);
|
||||
t.is(result.length, 1);
|
||||
t.is(result[0].language, KnownLanguage.csharp);
|
||||
t.is(result[0].language, BuiltInLanguage.csharp);
|
||||
t.is(result[0].result, CacheStoreResult.Stored);
|
||||
t.is(result[0].upload_size_bytes, 1024);
|
||||
|
||||
@@ -608,7 +608,7 @@ test.serial(
|
||||
.throws(new actionsCache.ReserveCacheError("Already in use"));
|
||||
|
||||
const config = createTestConfig({
|
||||
languages: [KnownLanguage.csharp],
|
||||
languages: [BuiltInLanguage.csharp],
|
||||
});
|
||||
|
||||
await t.notThrowsAsync(async () => {
|
||||
@@ -619,7 +619,7 @@ test.serial(
|
||||
logger,
|
||||
);
|
||||
t.is(result.length, 1);
|
||||
t.is(result[0].language, KnownLanguage.csharp);
|
||||
t.is(result[0].language, BuiltInLanguage.csharp);
|
||||
t.is(result[0].result, CacheStoreResult.Duplicate);
|
||||
|
||||
checkExpectedLogMessages(t, messages, ["Not uploading cache for"]);
|
||||
@@ -647,7 +647,7 @@ test.serial("uploadDependencyCaches - throws other exceptions", async (t) => {
|
||||
sinon.stub(actionsCache, "saveCache").throws();
|
||||
|
||||
const config = createTestConfig({
|
||||
languages: [KnownLanguage.csharp],
|
||||
languages: [BuiltInLanguage.csharp],
|
||||
});
|
||||
|
||||
await t.throwsAsync(async () => {
|
||||
@@ -659,7 +659,7 @@ test("getFeaturePrefix - returns empty string if no features are enabled", async
|
||||
const codeql = createStubCodeQL({});
|
||||
const features = createFeatures([]);
|
||||
|
||||
for (const knownLanguage of Object.values(KnownLanguage)) {
|
||||
for (const knownLanguage of Object.values(BuiltInLanguage)) {
|
||||
const result = await getFeaturePrefix(codeql, features, knownLanguage);
|
||||
t.deepEqual(result, "", `Expected no feature prefix for ${knownLanguage}`);
|
||||
}
|
||||
@@ -669,7 +669,11 @@ test("getFeaturePrefix - C# - returns prefix if CsharpNewCacheKey is enabled", a
|
||||
const codeql = createStubCodeQL({});
|
||||
const features = createFeatures([Feature.CsharpNewCacheKey]);
|
||||
|
||||
const result = await getFeaturePrefix(codeql, features, KnownLanguage.csharp);
|
||||
const result = await getFeaturePrefix(
|
||||
codeql,
|
||||
features,
|
||||
BuiltInLanguage.csharp,
|
||||
);
|
||||
t.notDeepEqual(result, "");
|
||||
t.assert(result.endsWith("-"));
|
||||
// Check the length of the prefix, which should correspond to `cacheKeyHashLength` + 1 for the trailing `-`.
|
||||
@@ -680,9 +684,9 @@ test("getFeaturePrefix - non-C# - returns '' if CsharpNewCacheKey is enabled", a
|
||||
const codeql = createStubCodeQL({});
|
||||
const features = createFeatures([Feature.CsharpNewCacheKey]);
|
||||
|
||||
for (const knownLanguage of Object.values(KnownLanguage)) {
|
||||
for (const knownLanguage of Object.values(BuiltInLanguage)) {
|
||||
// Skip C# since we expect a result for it, which is tested in the previous test.
|
||||
if (knownLanguage === KnownLanguage.csharp) {
|
||||
if (knownLanguage === BuiltInLanguage.csharp) {
|
||||
continue;
|
||||
}
|
||||
const result = await getFeaturePrefix(codeql, features, knownLanguage);
|
||||
@@ -694,7 +698,11 @@ test("getFeaturePrefix - C# - returns prefix if CsharpCacheBuildModeNone is enab
|
||||
const codeql = createStubCodeQL({});
|
||||
const features = createFeatures([Feature.CsharpCacheBuildModeNone]);
|
||||
|
||||
const result = await getFeaturePrefix(codeql, features, KnownLanguage.csharp);
|
||||
const result = await getFeaturePrefix(
|
||||
codeql,
|
||||
features,
|
||||
BuiltInLanguage.csharp,
|
||||
);
|
||||
t.notDeepEqual(result, "");
|
||||
t.assert(result.endsWith("-"));
|
||||
// Check the length of the prefix, which should correspond to `cacheKeyHashLength` + 1 for the trailing `-`.
|
||||
@@ -705,9 +713,9 @@ test("getFeaturePrefix - non-C# - returns '' if CsharpCacheBuildModeNone is enab
|
||||
const codeql = createStubCodeQL({});
|
||||
const features = createFeatures([Feature.CsharpCacheBuildModeNone]);
|
||||
|
||||
for (const knownLanguage of Object.values(KnownLanguage)) {
|
||||
for (const knownLanguage of Object.values(BuiltInLanguage)) {
|
||||
// Skip C# since we expect a result for it, which is tested in the previous test.
|
||||
if (knownLanguage === KnownLanguage.csharp) {
|
||||
if (knownLanguage === BuiltInLanguage.csharp) {
|
||||
continue;
|
||||
}
|
||||
const result = await getFeaturePrefix(codeql, features, knownLanguage);
|
||||
|
||||
@@ -11,7 +11,7 @@ import { CodeQL } from "./codeql";
|
||||
import { Config } from "./config-utils";
|
||||
import { EnvVar } from "./environment";
|
||||
import { Feature, FeatureEnablement } from "./feature-flags";
|
||||
import { KnownLanguage, Language } from "./languages";
|
||||
import { BuiltInLanguage, Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { getErrorMessage, getRequiredEnvParam } from "./util";
|
||||
|
||||
@@ -541,7 +541,7 @@ export async function getFeaturePrefix(
|
||||
}
|
||||
};
|
||||
|
||||
if (language === KnownLanguage.csharp) {
|
||||
if (language === BuiltInLanguage.csharp) {
|
||||
await addFeatureIfEnabled(Feature.CsharpNewCacheKey);
|
||||
await addFeatureIfEnabled(Feature.CsharpCacheBuildModeNone);
|
||||
}
|
||||
|
||||
+17
-2
@@ -72,6 +72,13 @@ let unwrittenDiagnostics: UnwrittenDiagnostic[] = [];
|
||||
*/
|
||||
let unwrittenDefaultLanguageDiagnostics: DiagnosticMessage[] = [];
|
||||
|
||||
/**
|
||||
* Counter used to generate a unique suffix for each diagnostic filename, so that
|
||||
* two diagnostics produced within the same millisecond do not overwrite each
|
||||
* other on disk.
|
||||
*/
|
||||
let diagnosticCounter = 0;
|
||||
|
||||
/**
|
||||
* Constructs a new diagnostic message with the specified id and name, as well as optional additional data.
|
||||
*
|
||||
@@ -167,10 +174,18 @@ function writeDiagnostic(
|
||||
// Create the directory if it doesn't exist yet.
|
||||
mkdirSync(diagnosticsPath, { recursive: true });
|
||||
|
||||
// Include a monotonically increasing suffix to avoid filename collisions
|
||||
// between diagnostics produced within the same millisecond.
|
||||
const uniqueSuffix = (diagnosticCounter++).toString();
|
||||
// We should only need to remove colons, but to be defensive, only allow a restricted set of
|
||||
// characters.
|
||||
const sanitizedTimestamp = diagnostic.timestamp.replace(
|
||||
/[^a-zA-Z0-9.-]/g,
|
||||
"",
|
||||
);
|
||||
const jsonPath = path.resolve(
|
||||
diagnosticsPath,
|
||||
// Remove colons from the timestamp as these are not allowed in Windows filenames.
|
||||
`codeql-action-${diagnostic.timestamp.replaceAll(":", "")}.json`,
|
||||
`codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json`,
|
||||
);
|
||||
|
||||
writeFileSync(jsonPath, JSON.stringify(diagnostic));
|
||||
|
||||
@@ -5,17 +5,20 @@ import * as actionsUtil from "./actions-util";
|
||||
import type { PullRequestBranches } from "./actions-util";
|
||||
import * as apiClient from "./api-client";
|
||||
import {
|
||||
shouldPerformDiffInformedAnalysis,
|
||||
getDiffInformedAnalysisBranches,
|
||||
prepareDiffInformedAnalysis,
|
||||
exportedForTesting,
|
||||
} from "./diff-informed-analysis-utils";
|
||||
import { Feature, initFeatures } from "./feature-flags";
|
||||
import { Feature, FeatureEnablement, initFeatures } from "./feature-flags";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { parseRepositoryNwo } from "./repository";
|
||||
import {
|
||||
setupTests,
|
||||
createFeatures,
|
||||
mockCodeQLVersion,
|
||||
mockFeatureFlagApiEndpoint,
|
||||
setupActionsVars,
|
||||
makeMacro,
|
||||
} from "./testing-utils";
|
||||
import { GitHubVariant, withTmpDir } from "./util";
|
||||
import type { GitHubVersion } from "./util";
|
||||
@@ -42,10 +45,9 @@ const defaultTestCase: DiffInformedAnalysisTestCase = {
|
||||
codeQLVersion: "2.21.0",
|
||||
};
|
||||
|
||||
const testShouldPerformDiffInformedAnalysis = test.macro({
|
||||
const testShouldPerformDiffInformedAnalysis = makeMacro({
|
||||
exec: async (
|
||||
t: ExecutionContext,
|
||||
_title: string,
|
||||
partialTestCase: Partial<DiffInformedAnalysisTestCase>,
|
||||
expectedResult: boolean,
|
||||
) => {
|
||||
@@ -73,39 +75,34 @@ const testShouldPerformDiffInformedAnalysis = test.macro({
|
||||
[Feature.DiffInformedQueries]: testCase.featureEnabled,
|
||||
});
|
||||
|
||||
const getGitHubVersionStub = sinon
|
||||
sinon
|
||||
.stub(apiClient, "getGitHubVersion")
|
||||
.resolves(testCase.gitHubVersion);
|
||||
const getPullRequestBranchesStub = sinon
|
||||
sinon
|
||||
.stub(actionsUtil, "getPullRequestBranches")
|
||||
.returns(testCase.pullRequestBranches);
|
||||
|
||||
const result = await shouldPerformDiffInformedAnalysis(
|
||||
const branches = await getDiffInformedAnalysisBranches(
|
||||
codeql,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
|
||||
t.is(result, expectedResult);
|
||||
t.is(branches !== undefined, expectedResult);
|
||||
|
||||
delete process.env.CODEQL_ACTION_DIFF_INFORMED_QUERIES;
|
||||
|
||||
getGitHubVersionStub.restore();
|
||||
getPullRequestBranchesStub.restore();
|
||||
});
|
||||
},
|
||||
title: (_, title) => `shouldPerformDiffInformedAnalysis: ${title}`,
|
||||
title: (title) => `getDiffInformedAnalysisBranches: ${title}`,
|
||||
});
|
||||
|
||||
test.serial(
|
||||
testShouldPerformDiffInformedAnalysis,
|
||||
testShouldPerformDiffInformedAnalysis.serial(
|
||||
"returns true in the default test case",
|
||||
{},
|
||||
true,
|
||||
);
|
||||
|
||||
test.serial(
|
||||
testShouldPerformDiffInformedAnalysis,
|
||||
testShouldPerformDiffInformedAnalysis.serial(
|
||||
"returns false when feature flag is disabled from the API",
|
||||
{
|
||||
featureEnabled: false,
|
||||
@@ -113,8 +110,7 @@ test.serial(
|
||||
false,
|
||||
);
|
||||
|
||||
test.serial(
|
||||
testShouldPerformDiffInformedAnalysis,
|
||||
testShouldPerformDiffInformedAnalysis.serial(
|
||||
"returns false when CODEQL_ACTION_DIFF_INFORMED_QUERIES is set to false",
|
||||
{
|
||||
featureEnabled: true,
|
||||
@@ -123,8 +119,7 @@ test.serial(
|
||||
false,
|
||||
);
|
||||
|
||||
test.serial(
|
||||
testShouldPerformDiffInformedAnalysis,
|
||||
testShouldPerformDiffInformedAnalysis.serial(
|
||||
"returns true when CODEQL_ACTION_DIFF_INFORMED_QUERIES is set to true",
|
||||
{
|
||||
featureEnabled: false,
|
||||
@@ -133,8 +128,7 @@ test.serial(
|
||||
true,
|
||||
);
|
||||
|
||||
test.serial(
|
||||
testShouldPerformDiffInformedAnalysis,
|
||||
testShouldPerformDiffInformedAnalysis.serial(
|
||||
"returns false for CodeQL version 2.20.0",
|
||||
{
|
||||
codeQLVersion: "2.20.0",
|
||||
@@ -142,8 +136,7 @@ test.serial(
|
||||
false,
|
||||
);
|
||||
|
||||
test.serial(
|
||||
testShouldPerformDiffInformedAnalysis,
|
||||
testShouldPerformDiffInformedAnalysis.serial(
|
||||
"returns false for invalid GHES version",
|
||||
{
|
||||
gitHubVersion: {
|
||||
@@ -154,8 +147,7 @@ test.serial(
|
||||
false,
|
||||
);
|
||||
|
||||
test.serial(
|
||||
testShouldPerformDiffInformedAnalysis,
|
||||
testShouldPerformDiffInformedAnalysis.serial(
|
||||
"returns false for GHES version 3.18.5",
|
||||
{
|
||||
gitHubVersion: {
|
||||
@@ -166,8 +158,7 @@ test.serial(
|
||||
false,
|
||||
);
|
||||
|
||||
test.serial(
|
||||
testShouldPerformDiffInformedAnalysis,
|
||||
testShouldPerformDiffInformedAnalysis.serial(
|
||||
"returns true for GHES version 3.19.0",
|
||||
{
|
||||
gitHubVersion: {
|
||||
@@ -178,8 +169,7 @@ test.serial(
|
||||
true,
|
||||
);
|
||||
|
||||
test.serial(
|
||||
testShouldPerformDiffInformedAnalysis,
|
||||
testShouldPerformDiffInformedAnalysis.serial(
|
||||
"returns false when not a pull request",
|
||||
{
|
||||
pullRequestBranches: undefined,
|
||||
@@ -187,6 +177,135 @@ test.serial(
|
||||
false,
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"prepareDiffInformedAnalysis: returns false when not a pull request",
|
||||
async (t) => {
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
const logger = getRunnerLogger(true);
|
||||
const codeql = mockCodeQLVersion("2.21.0");
|
||||
const features = createFeatures([Feature.DiffInformedQueries]);
|
||||
|
||||
sinon.stub(actionsUtil, "getPullRequestBranches").returns(undefined);
|
||||
sinon
|
||||
.stub(apiClient, "getGitHubVersion")
|
||||
.resolves({ type: GitHubVariant.DOTCOM });
|
||||
|
||||
const result = await prepareDiffInformedAnalysis(
|
||||
codeql,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
|
||||
t.false(result);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"prepareDiffInformedAnalysis: returns false when applicability check throws",
|
||||
async (t) => {
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
const logger = getRunnerLogger(true);
|
||||
const codeql = mockCodeQLVersion("2.21.0");
|
||||
// A features implementation whose getValue rejects, simulating an
|
||||
// unexpected failure when determining whether diff-informed analysis
|
||||
// should run.
|
||||
const features: FeatureEnablement = {
|
||||
getEnabledDefaultCliVersions: async () => {
|
||||
throw new Error("not implemented");
|
||||
},
|
||||
getValue: async () => {
|
||||
throw new Error("feature flag lookup failed");
|
||||
},
|
||||
};
|
||||
|
||||
const result = await prepareDiffInformedAnalysis(
|
||||
codeql,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
|
||||
t.false(result);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"prepareDiffInformedAnalysis: returns true when the diff is fetched successfully",
|
||||
async (t) => {
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
const logger = getRunnerLogger(true);
|
||||
const codeql = mockCodeQLVersion("2.21.0");
|
||||
const features = createFeatures([Feature.DiffInformedQueries]);
|
||||
|
||||
sinon
|
||||
.stub(actionsUtil, "getPullRequestBranches")
|
||||
.returns({ base: "main", head: "feature" });
|
||||
sinon
|
||||
.stub(apiClient, "getGitHubVersion")
|
||||
.resolves({ type: GitHubVariant.DOTCOM });
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
sinon.stub(apiClient, "getApiClient").returns({
|
||||
rest: {
|
||||
repos: {
|
||||
compareCommitsWithBasehead: sinon
|
||||
.stub()
|
||||
.resolves({ data: { files: [] } }),
|
||||
},
|
||||
},
|
||||
} as any);
|
||||
|
||||
const result = await prepareDiffInformedAnalysis(
|
||||
codeql,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
|
||||
t.true(result);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"prepareDiffInformedAnalysis: returns false when the diff API call fails",
|
||||
async (t) => {
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
const logger = getRunnerLogger(true);
|
||||
const codeql = mockCodeQLVersion("2.21.0");
|
||||
const features = createFeatures([Feature.DiffInformedQueries]);
|
||||
|
||||
sinon
|
||||
.stub(actionsUtil, "getPullRequestBranches")
|
||||
.returns({ base: "main", head: "feature" });
|
||||
sinon
|
||||
.stub(apiClient, "getGitHubVersion")
|
||||
.resolves({ type: GitHubVariant.DOTCOM });
|
||||
const notFoundError: any = new Error("Not Found");
|
||||
notFoundError.status = 404;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
sinon.stub(apiClient, "getApiClient").returns({
|
||||
rest: {
|
||||
repos: {
|
||||
compareCommitsWithBasehead: sinon.stub().rejects(notFoundError),
|
||||
},
|
||||
},
|
||||
} as any);
|
||||
|
||||
const result = await prepareDiffInformedAnalysis(
|
||||
codeql,
|
||||
features,
|
||||
logger,
|
||||
);
|
||||
|
||||
t.false(result);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
function runGetDiffRanges(changes: number, patch: string[] | undefined): any {
|
||||
return exportedForTesting.getDiffRanges(
|
||||
{
|
||||
|
||||
@@ -5,9 +5,9 @@ import type { PullRequestBranches } from "./actions-util";
|
||||
import { getApiClient, getGitHubVersion } from "./api-client";
|
||||
import type { CodeQL } from "./codeql";
|
||||
import { Feature, FeatureEnablement } from "./feature-flags";
|
||||
import { Logger } from "./logging";
|
||||
import { Logger, withGroupAsync } from "./logging";
|
||||
import { getRepositoryNwoFromEnv } from "./repository";
|
||||
import { GitHubVariant, satisfiesGHESVersion } from "./util";
|
||||
import { getErrorMessage, GitHubVariant, satisfiesGHESVersion } from "./util";
|
||||
|
||||
/**
|
||||
* This interface is an abbreviated version of the file diff object returned by
|
||||
@@ -21,20 +21,6 @@ interface FileDiff {
|
||||
patch?: string | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the action should perform diff-informed analysis.
|
||||
*/
|
||||
export async function shouldPerformDiffInformedAnalysis(
|
||||
codeql: CodeQL,
|
||||
features: FeatureEnablement,
|
||||
logger: Logger,
|
||||
): Promise<boolean> {
|
||||
return (
|
||||
(await getDiffInformedAnalysisBranches(codeql, features, logger)) !==
|
||||
undefined
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the branches to use for diff-informed analysis.
|
||||
*
|
||||
@@ -69,6 +55,46 @@ export async function getDiffInformedAnalysisBranches(
|
||||
return branches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the diff ranges needed for diff-informed analysis for the current
|
||||
* run.
|
||||
*
|
||||
* @returns `true` if the diff ranges were successfully computed and persisted
|
||||
* and are therefore available for use, `false` otherwise.
|
||||
*/
|
||||
export async function prepareDiffInformedAnalysis(
|
||||
codeql: CodeQL,
|
||||
features: FeatureEnablement,
|
||||
logger: Logger,
|
||||
): Promise<boolean> {
|
||||
let branches: PullRequestBranches | undefined;
|
||||
try {
|
||||
branches = await getDiffInformedAnalysisBranches(codeql, features, logger);
|
||||
} catch (e) {
|
||||
// If we cannot determine whether diff-informed analysis applies (for
|
||||
// example, because a feature-flag lookup failed), treat it as not
|
||||
// applicable rather than triggering the overlay fallback.
|
||||
logger.warning(
|
||||
`Failed to determine branch information for diff-informed analysis: ${getErrorMessage(e)}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (!branches) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return await withGroupAsync("Computing PR diff ranges", async () => {
|
||||
try {
|
||||
return await computeAndPersistDiffRanges(branches, logger);
|
||||
} catch (e) {
|
||||
logger.warning(
|
||||
`Failed to compute diff-informed analysis ranges: ${getErrorMessage(e)}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export interface DiffThunkRange {
|
||||
/** Relative path from the repository root, using forward slashes as separators. */
|
||||
path: string;
|
||||
@@ -151,6 +177,33 @@ export async function getPullRequestEditedDiffRanges(
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute and persist the diff ranges for a pull request. This fetches the
|
||||
* diff from the GitHub API and writes it to the diff ranges JSON file so that
|
||||
* CodeQL can use it for diff-informed analysis.
|
||||
*
|
||||
* @param branches The base and head branches of the pull request, as returned
|
||||
* by `getDiffInformedAnalysisBranches`.
|
||||
* @param logger
|
||||
* @returns `true` if the diff ranges were successfully computed and persisted,
|
||||
* otherwise `false`.
|
||||
*/
|
||||
export async function computeAndPersistDiffRanges(
|
||||
branches: PullRequestBranches,
|
||||
logger: Logger,
|
||||
): Promise<boolean> {
|
||||
const ranges = await getPullRequestEditedDiffRanges(branches, logger);
|
||||
if (ranges === undefined) {
|
||||
return false;
|
||||
}
|
||||
writeDiffRangesJsonFile(logger, ranges);
|
||||
const distinctFiles = new Set(ranges.map((r) => r.path)).size;
|
||||
logger.info(
|
||||
`Persisted ${ranges.length} diff range(s) across ${distinctFiles} file(s).`,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
async function getFileDiffsWithBasehead(
|
||||
branches: PullRequestBranches,
|
||||
logger: Logger,
|
||||
|
||||
@@ -8,6 +8,7 @@ export enum DocUrl {
|
||||
CODEQL_BUILD_MODES = "https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages#codeql-build-modes",
|
||||
DEFINE_ENV_VARIABLES = "https://docs.github.com/en/actions/learn-github-actions/variables#defining-environment-variables-for-a-single-workflow",
|
||||
DELETE_ACTIONS_CACHE_ENTRIES = "https://docs.github.com/en/actions/how-tos/manage-workflow-runs/manage-caches#deleting-cache-entries",
|
||||
PRIVATE_REGISTRY_LOGS = "https://docs.github.com/en/code-security/reference/code-scanning/code-scanning-logs#diagnostic-information-for-private-package-registries",
|
||||
SCANNING_ON_PUSH = "https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning#scanning-on-push",
|
||||
SPECIFY_BUILD_STEPS_MANUALLY = "https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages#about-specifying-build-steps-manually",
|
||||
SYSTEM_REQUIREMENTS = "https://codeql.github.com/docs/codeql-overview/system-requirements/",
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export async function run__ACTION__() {
|
||||
return await __ACTION__.runWrapper();
|
||||
}
|
||||
+27
-12
@@ -451,12 +451,16 @@ test.serial(`selects CLI from defaults.json on GHES`, async (t) => {
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
const features = setUpFeatureFlagTests(tmpDir);
|
||||
|
||||
const defaultCliVersion = await features.getDefaultCliVersion(
|
||||
const defaultCliVersion = await features.getEnabledDefaultCliVersions(
|
||||
GitHubVariant.GHES,
|
||||
);
|
||||
t.deepEqual(defaultCliVersion, {
|
||||
cliVersion: defaults.cliVersion,
|
||||
tagName: defaults.bundleVersion,
|
||||
enabledVersions: [
|
||||
{
|
||||
cliVersion: defaults.cliVersion,
|
||||
tagName: defaults.bundleVersion,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -482,10 +486,13 @@ for (const variant of [GitHubVariant.DOTCOM, GitHubVariant.GHEC_DR]) {
|
||||
false;
|
||||
mockFeatureFlagApiEndpoint(200, expectedFeatureEnablement);
|
||||
|
||||
const defaultCliVersion = await features.getDefaultCliVersion(variant);
|
||||
const defaultCliVersion =
|
||||
await features.getEnabledDefaultCliVersions(variant);
|
||||
t.deepEqual(defaultCliVersion, {
|
||||
cliVersion: "2.20.1",
|
||||
tagName: "codeql-bundle-v2.20.1",
|
||||
enabledVersions: [
|
||||
{ cliVersion: "2.20.1", tagName: "codeql-bundle-v2.20.1" },
|
||||
{ cliVersion: "2.20.0", tagName: "codeql-bundle-v2.20.0" },
|
||||
],
|
||||
toolsFeatureFlagsValid: true,
|
||||
});
|
||||
});
|
||||
@@ -500,10 +507,15 @@ for (const variant of [GitHubVariant.DOTCOM, GitHubVariant.GHEC_DR]) {
|
||||
const expectedFeatureEnablement = initializeFeatures(true);
|
||||
mockFeatureFlagApiEndpoint(200, expectedFeatureEnablement);
|
||||
|
||||
const defaultCliVersion = await features.getDefaultCliVersion(variant);
|
||||
const defaultCliVersion =
|
||||
await features.getEnabledDefaultCliVersions(variant);
|
||||
t.deepEqual(defaultCliVersion, {
|
||||
cliVersion: defaults.cliVersion,
|
||||
tagName: defaults.bundleVersion,
|
||||
enabledVersions: [
|
||||
{
|
||||
cliVersion: defaults.cliVersion,
|
||||
tagName: defaults.bundleVersion,
|
||||
},
|
||||
],
|
||||
toolsFeatureFlagsValid: false,
|
||||
});
|
||||
});
|
||||
@@ -529,10 +541,13 @@ for (const variant of [GitHubVariant.DOTCOM, GitHubVariant.GHEC_DR]) {
|
||||
] = true;
|
||||
mockFeatureFlagApiEndpoint(200, expectedFeatureEnablement);
|
||||
|
||||
const defaultCliVersion = await features.getDefaultCliVersion(variant);
|
||||
const defaultCliVersion =
|
||||
await features.getEnabledDefaultCliVersions(variant);
|
||||
t.deepEqual(defaultCliVersion, {
|
||||
cliVersion: "2.20.1",
|
||||
tagName: "codeql-bundle-v2.20.1",
|
||||
enabledVersions: [
|
||||
{ cliVersion: "2.20.1", tagName: "codeql-bundle-v2.20.1" },
|
||||
{ cliVersion: "2.20.0", tagName: "codeql-bundle-v2.20.0" },
|
||||
],
|
||||
toolsFeatureFlagsValid: true,
|
||||
});
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user