mirror of
https://github.com/github/codeql-action
synced 2026-10-11 10:04:20 +03:00
Compare commits
158
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4e9b269fe | ||
|
|
6e7fe2e990 | ||
|
|
fa56eef12f | ||
|
|
71f2680f85 | ||
|
|
3b399fec34 | ||
|
|
5532d8e11e | ||
|
|
68f5b579fa | ||
|
|
45cda5b577 | ||
|
|
e57c0e65dd | ||
|
|
1ced68ed2f | ||
|
|
13b1321685 | ||
|
|
cc826bb8e3 | ||
|
|
40d76bc727 | ||
|
|
bd97dda6bf | ||
|
|
d6196d8703 | ||
|
|
3acc10a2ce | ||
|
|
2a935ca93d | ||
|
|
5aa5056e2d | ||
|
|
ea60dc6408 | ||
|
|
ce3f825b1d | ||
|
|
24c54180a6 | ||
|
|
69e87c56c1 | ||
|
|
23b682830b | ||
|
|
38fee79b02 | ||
|
|
ebd711ff66 | ||
|
|
75ea4cb2e4 | ||
|
|
59ff83ecef | ||
|
|
1728f0c676 | ||
|
|
63c5299790 | ||
|
|
e0b52dbdc5 | ||
|
|
39f1b3fa8d | ||
|
|
6b99698c8c | ||
|
|
d5b1e793ce | ||
|
|
63d3d632fc | ||
|
|
7377a10091 | ||
|
|
c1a30cda11 | ||
|
|
d208ec71e3 | ||
|
|
a71b0c6684 | ||
|
|
0a44f18dc2 | ||
|
|
0f3412f832 | ||
|
|
a2374c3d1c | ||
|
|
4c932d9948 | ||
|
|
1b38bb12c6 | ||
|
|
f5b4c32a4e | ||
|
|
b813f91953 | ||
|
|
4c98a0bfb7 | ||
|
|
36f377b9f2 | ||
|
|
f455295c9b | ||
|
|
7265309f7a | ||
|
|
d1ca36fda6 | ||
|
|
2c8d410c03 | ||
|
|
118af5959a | ||
|
|
61c3b54338 | ||
|
|
12db63b222 | ||
|
|
55e4091e2b | ||
|
|
8e6b600bd0 | ||
|
|
9d3242ebc0 | ||
|
|
e0b8480262 | ||
|
|
6cb83faca6 | ||
|
|
a4a04dc476 | ||
|
|
966f3c3593 | ||
|
|
711f3bffae | ||
|
|
ac4b9b891d | ||
|
|
c1e7769cf5 | ||
|
|
1767808e11 | ||
|
|
aeafd00d94 | ||
|
|
363d874905 | ||
|
|
fa90489493 | ||
|
|
d8251b8572 | ||
|
|
b6d38e563b | ||
|
|
b948c4d91e | ||
|
|
894842692f | ||
|
|
62b0dd96ff | ||
|
|
c275b4a69e | ||
|
|
4d9cd8c21b | ||
|
|
412197a0f3 | ||
|
|
0cd78b35d9 | ||
|
|
c26ee0ca71 | ||
|
|
6ce88f6aaf | ||
|
|
1f8080af29 | ||
|
|
56b0d5f02c | ||
|
|
b804ae96cc | ||
|
|
a47cc9ff16 | ||
|
|
27c60c532d | ||
|
|
c535168544 | ||
|
|
488027b53c | ||
|
|
dc1f3ac122 | ||
|
|
05d2a1a6fb | ||
|
|
f6a7f00613 | ||
|
|
113b18e688 | ||
|
|
e869836b5a | ||
|
|
1c0814d7d2 | ||
|
|
ce28f3e445 | ||
|
|
f24d88130e | ||
|
|
f45aab1a23 | ||
|
|
d036b81d95 | ||
|
|
f306a93590 | ||
|
|
ffc4a0cd10 | ||
|
|
d06baaa128 | ||
|
|
a6cd2a544a | ||
|
|
1bb99cb5c7 | ||
|
|
725421c272 | ||
|
|
70897a78fe | ||
|
|
a4fbe39872 | ||
|
|
a98f604084 | ||
|
|
2da0d298e0 | ||
|
|
87a1923fea | ||
|
|
222d54a705 | ||
|
|
cbe61e2f00 | ||
|
|
f1b8b0f7b3 | ||
|
|
99522b4961 | ||
|
|
7816c33354 | ||
|
|
d8b6f2a09b | ||
|
|
1609a51ab7 | ||
|
|
5e3132db95 | ||
|
|
b5a476b47f | ||
|
|
61817fadad | ||
|
|
cd1a7c16f0 | ||
|
|
8e838ff396 | ||
|
|
10e476ce02 | ||
|
|
fc2d2f7d2d | ||
|
|
62a2268b34 | ||
|
|
97a91d9861 | ||
|
|
85c0c095cb | ||
|
|
503e2f62a9 | ||
|
|
260cb2adcf | ||
|
|
31252c2639 | ||
|
|
1991d2001e | ||
|
|
0af3281195 | ||
|
|
8dfe937b99 | ||
|
|
8102666a8c | ||
|
|
7b6a151fb5 | ||
|
|
29b01b6799 | ||
|
|
fa2bea7c7a | ||
|
|
9fb2fa5f46 | ||
|
|
054b25e1c2 | ||
|
|
fa8392b7e5 | ||
|
|
38c1d74ffa | ||
|
|
19aa55de51 | ||
|
|
a7334dd080 | ||
|
|
aa2cb993a1 | ||
|
|
9c970806c4 | ||
|
|
415d925fee | ||
|
|
b5f938c947 | ||
|
|
73dc34459c | ||
|
|
266e866100 | ||
|
|
b435ce4361 | ||
|
|
477ba697e3 | ||
|
|
6aa6d5553a | ||
|
|
f42df5b5c1 | ||
|
|
fa4712895b | ||
|
|
660f7c5f24 | ||
|
|
fe0a932a6a | ||
|
|
8e36092a16 | ||
|
|
2294a7a8b1 | ||
|
|
c0369726ee | ||
|
|
a5c2338ec0 | ||
|
|
f042742baf |
No files matched your search
@@ -92,8 +92,7 @@ runs:
|
||||
Please do the following:
|
||||
|
||||
- [ ] Approve running the full set of PR checks.
|
||||
- [ ] Approve and merge the PR. When merging the PR, make sure "Create a merge commit" is
|
||||
selected rather than "Squash and merge" or "Rebase and merge".
|
||||
- [ ] Approve and merge the PR. When merging the PR, make sure "Create a merge commit" is selected rather than "Squash and merge" or "Rebase and merge".
|
||||
EOF
|
||||
)
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@ updates:
|
||||
interval: weekly
|
||||
cooldown:
|
||||
default-days: 7
|
||||
exclude:
|
||||
- "@actions/*"
|
||||
labels:
|
||||
- Rebuild
|
||||
# Ignore incompatible dependency updates
|
||||
@@ -33,8 +31,6 @@ updates:
|
||||
interval: weekly
|
||||
cooldown:
|
||||
default-days: 7
|
||||
exclude:
|
||||
- "actions/*"
|
||||
labels:
|
||||
- Rebuild
|
||||
groups:
|
||||
|
||||
Generated
+2
@@ -51,6 +51,8 @@ jobs:
|
||||
with:
|
||||
node-version: 20.x
|
||||
cache: npm
|
||||
- name: Install newer npm
|
||||
run: npm install -g npm@11.19.1
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Prepare test
|
||||
|
||||
@@ -124,4 +124,5 @@ jobs:
|
||||
env:
|
||||
CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS: false
|
||||
CODEQL_ACTION_SUBLANGUAGE_FILE_COVERAGE: true
|
||||
CODEQL_ACTION_PER_LANGUAGE_BUNDLES: false
|
||||
CODEQL_ACTION_TEST_MODE: true
|
||||
+4
-3
@@ -116,13 +116,14 @@ jobs:
|
||||
version: ${{ matrix.version }}
|
||||
use-all-platform-bundle: 'false'
|
||||
setup-kotlin: 'true'
|
||||
- name: Install Python 3.13 for older CLI versions
|
||||
# We need Python 3.13 for older CLI versions because they are not compatible with Python 3.14 or newer.
|
||||
- name: Install Python 3.13.15 for older CLI versions
|
||||
# Older CLI versions don't work with Python 3.13.16 or newer because their Python extractor
|
||||
# imports `importlib._bootstrap._ERR_MSG`, which those Python versions no longer define.
|
||||
# See https://github.com/github/codeql-action/pull/3212
|
||||
if: matrix.version != 'nightly-latest' && matrix.version != 'linked'
|
||||
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||
with:
|
||||
python-version: '3.13'
|
||||
python-version: '3.13.15'
|
||||
|
||||
- name: Use Xcode 16
|
||||
# Only the older CodeQL CLI versions need Xcode 16, and these run on macOS 15.
|
||||
|
||||
@@ -84,6 +84,8 @@ jobs:
|
||||
with:
|
||||
node-version: 20.x
|
||||
cache: npm
|
||||
- name: Install newer npm
|
||||
run: npm install -g npm@11.19.1
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Prepare test
|
||||
|
||||
@@ -84,6 +84,8 @@ jobs:
|
||||
with:
|
||||
node-version: 20.x
|
||||
cache: npm
|
||||
- name: Install newer npm
|
||||
run: npm install -g npm@11.19.1
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Prepare test
|
||||
|
||||
+2
@@ -84,6 +84,8 @@ jobs:
|
||||
with:
|
||||
node-version: 20.x
|
||||
cache: npm
|
||||
- name: Install newer npm
|
||||
run: npm install -g npm@11.19.1
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Prepare test
|
||||
|
||||
+2
@@ -84,6 +84,8 @@ jobs:
|
||||
with:
|
||||
node-version: 20.x
|
||||
cache: npm
|
||||
- name: Install newer npm
|
||||
run: npm install -g npm@11.19.1
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Prepare test
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ jobs:
|
||||
use-all-platform-bundle: 'false'
|
||||
setup-kotlin: 'true'
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
|
||||
uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 # v1.327.0
|
||||
with:
|
||||
ruby-version: 2.6
|
||||
- name: Install Code Scanning integration
|
||||
|
||||
@@ -47,6 +47,12 @@ jobs:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: "npm"
|
||||
|
||||
# Install a new enough version of `npm` to understand `min-release-age`
|
||||
# that is still compatible with Node 20.
|
||||
- name: Install newer npm
|
||||
if: matrix.node-version == 20
|
||||
run: npm install -g npm@11.19.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
# Use the system Bash shell to ensure we can run commands like `npm ci`
|
||||
@@ -95,6 +101,14 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Check for incorrect addresses in package-lock.json
|
||||
run: |
|
||||
if git grep -nE '(pkgs\.visualstudio\.com|pkgs\.dev\.azure\.com|packagefeedproxy\.microsoft\.io)' -- \
|
||||
'package-lock.json'; then
|
||||
echo "::error::package-lock.json contains internal package feed URLs. Replace them with public registry URLs."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
@@ -114,9 +128,9 @@ jobs:
|
||||
working-directory: pr-checks
|
||||
run: npx tsx --test
|
||||
|
||||
- name: Run `pr-checks/changenotes.mts` to ensure that all unreleased change notes are valid
|
||||
- name: Run `pr-checks/changenotes.ts` to ensure that all unreleased change notes are valid
|
||||
if: ${{ !cancelled() && steps.install-deps.outcome == 'success' }}
|
||||
run: npx tsx pr-checks/changenotes.mts validate
|
||||
run: npx tsx pr-checks/changenotes.ts validate
|
||||
|
||||
- name: Verify all Actions use the same Node version
|
||||
id: head-version
|
||||
|
||||
@@ -28,7 +28,7 @@ defaults:
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
name: "Prepare release"
|
||||
name: "Release info"
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'github/codeql-action'
|
||||
|
||||
|
||||
@@ -54,32 +54,27 @@ jobs:
|
||||
run: |
|
||||
git fetch origin "$BASE_BRANCH"
|
||||
|
||||
# Allow merge conflicts in `lib`, since rebuilding should resolve them.
|
||||
git merge "origin/$BASE_BRANCH"
|
||||
MERGE_RESULT=$?
|
||||
|
||||
if [ "$MERGE_RESULT" -eq 0 ]; then
|
||||
# Allow merge conflicts in `lib`, since rebuilding should resolve them. Conflicts leave the
|
||||
# merge in progress, so check for `MERGE_HEAD` to tell them apart from failures that don't.
|
||||
if git merge "origin/$BASE_BRANCH"; then
|
||||
echo "Merge succeeded cleanly."
|
||||
elif [ "$MERGE_RESULT" -eq 1 ]; then
|
||||
echo "Merge conflicts detected (exit code $MERGE_RESULT), continuing."
|
||||
else
|
||||
echo "git merge failed with unexpected exit code $MERGE_RESULT."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$MERGE_RESULT" -ne 0 ]; then
|
||||
elif git rev-parse --verify MERGE_HEAD >/dev/null 2>&1; then
|
||||
echo "Merge conflicts detected, continuing."
|
||||
echo "merge-in-progress=true" >> $GITHUB_OUTPUT
|
||||
|
||||
# Check for merge conflicts outside of `lib`. Disable git diff's trailing whitespace check
|
||||
# since `node_modules/@types/semver/README.md` fails it.
|
||||
if git -c core.whitespace=-trailing-space diff --check | grep --invert-match '^lib/'; then
|
||||
# Check for merge conflicts outside of `lib`.
|
||||
CONFLICTS_OUTSIDE_LIB=$(git diff --name-only --diff-filter=U | grep --invert-match '^lib/' || true)
|
||||
if [ -n "$CONFLICTS_OUTSIDE_LIB" ]; then
|
||||
echo "Merge conflicts were detected outside of the lib directory. Please resolve them manually."
|
||||
git -c core.whitespace=-trailing-space diff --check | grep --invert-match '^lib/' || true
|
||||
echo "$CONFLICTS_OUTSIDE_LIB"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "No merge conflicts found outside the lib directory. We should be able to resolve all of" \
|
||||
"these by rebuilding the Action."
|
||||
else
|
||||
echo "git merge failed for a reason other than merge conflicts."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Compile TypeScript
|
||||
|
||||
@@ -10,8 +10,7 @@ on:
|
||||
required: true
|
||||
# Only for dry-runs of changes to the workflow.
|
||||
push:
|
||||
# Don't run dry-run on release branches, to avoid an issue where the
|
||||
# "new" tag determined by the "Prepare release" job already exists.
|
||||
# Don't run dry-run on release branches, since that's unnecessary.
|
||||
branches-ignore:
|
||||
- releases/v*
|
||||
paths:
|
||||
@@ -24,7 +23,7 @@ defaults:
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
name: "Prepare release"
|
||||
name: "Prepare"
|
||||
if: github.repository == 'github/codeql-action'
|
||||
|
||||
permissions:
|
||||
@@ -107,8 +106,10 @@ jobs:
|
||||
# We usually expect to checkout `inputs.rollback-tag` (required for `workflow_dispatch`),
|
||||
# but use `v0.0.0` for testing.
|
||||
ROLLBACK_TAG: ${{ inputs.rollback-tag || 'v0.0.0' }}
|
||||
RELEASE_TAG: ${{ needs.prepare.outputs.version }}
|
||||
MAJOR_VERSION_TAG: ${{ needs.prepare.outputs.major_version }}
|
||||
# Use `needs.prepare.outputs.version` for actual runs and `v0.0.1` for testing.
|
||||
RELEASE_TAG: ${{ case(github.event_name == 'workflow_dispatch', needs.prepare.outputs.version, 'v0.0.1') }}
|
||||
# Use `needs.prepare.outputs.major_version` for actual runs and `v0` for testing.
|
||||
MAJOR_VERSION_TAG: ${{ case(github.event_name == 'workflow_dispatch', needs.prepare.outputs.major_version, 'v0') }}
|
||||
run: |
|
||||
git checkout "refs/tags/${ROLLBACK_TAG}"
|
||||
git tag --annotate "${RELEASE_TAG}" --message "${RELEASE_TAG}"
|
||||
@@ -184,4 +185,3 @@ jobs:
|
||||
# Setting this to `true` for non-workflow_dispatch events will
|
||||
# still push the `branch`, but won't create a corresponding PR
|
||||
dry-run: "${{ github.event_name != 'workflow_dispatch' }}"
|
||||
|
||||
@@ -16,15 +16,15 @@ defaults:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
|
||||
prepare:
|
||||
name: "Prepare release"
|
||||
name: "Prepare"
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
uses: ./.github/workflows/prepare-release.yml
|
||||
|
||||
update:
|
||||
name: "Update release branch"
|
||||
timeout-minutes: 45
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
@@ -77,6 +77,7 @@ jobs:
|
||||
--conductor ${GITHUB_ACTOR}
|
||||
|
||||
backport:
|
||||
name: "Create backport"
|
||||
timeout-minutes: 45
|
||||
runs-on: ubuntu-latest
|
||||
environment: Automation
|
||||
|
||||
Vendored
+5
-1
@@ -7,6 +7,10 @@
|
||||
// transpiled JavaScript
|
||||
"build": true,
|
||||
"lib": true,
|
||||
|
||||
// exclude "tests" by default because it causes VSCode to start language-specific extensions
|
||||
// that are not typically needed during development (or indeed may not work correctly)
|
||||
"tests": true
|
||||
},
|
||||
"search.exclude": {
|
||||
"**/node_modules": true,
|
||||
@@ -18,7 +22,7 @@
|
||||
"git.ignoreLimitWarning": true,
|
||||
// Use the vendored TypeScript version to have a consistent development experience across
|
||||
// machines.
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"js/ts.tsdk.path": "node_modules/typescript/lib",
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
|
||||
@@ -2,6 +2,16 @@
|
||||
|
||||
See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs.
|
||||
|
||||
## [UNRELEASED]
|
||||
|
||||
No user facing changes.
|
||||
|
||||
## 4.38.3 - 08 Oct 2026
|
||||
|
||||
- _Upcoming breaking change_: CodeQL version 2.21.2 and earlier were discontinued on 24 September 2026 alongside GitHub Enterprise Server 3.17, and will be unsupported by the next minor release of the CodeQL Action. Added a deprecation warning for customers using these versions of CodeQL. [#4188](https://github.com/github/codeql-action/pull/4188)
|
||||
- Update default CodeQL bundle version to [2.27.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.2). [#4203](https://github.com/github/codeql-action/pull/4203)
|
||||
- Fixed a bug where the decision of whether to use a per-language bundle did not account for custom configurations that reference queries outside of compiled CodeQL packs. This issue was caught during internal testing and did not affect any customer repositories. We will resume the roll out of per-language bundles in the coming weeks. [#4184](https://github.com/github/codeql-action/pull/4184)
|
||||
|
||||
## 4.38.2 - 24 Sept 2026
|
||||
|
||||
- Update default CodeQL bundle version to [2.27.1](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.1). [#4160](https://github.com/github/codeql-action/pull/4160)
|
||||
|
||||
@@ -53,6 +53,7 @@ Here are a few things you can do that will increase the likelihood of your pull
|
||||
- Write tests.
|
||||
- Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests.
|
||||
- Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
|
||||
- For user-facing changes, add a change-note file. See [unreleased-change-notes/README.md](unreleased-change-notes/README.md).
|
||||
|
||||
## Releasing (write access required)
|
||||
|
||||
|
||||
@@ -72,12 +72,11 @@ 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.36.2` | `2.25.6` | Enterprise Server 3.22 | |
|
||||
| `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 | |
|
||||
|
||||
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).
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import pkg from "./package.json" with { type: "json" };
|
||||
|
||||
globalThis.__CODEQL_ACTION_VERSION__ = pkg.version;
|
||||
globalThis.__CODEQL_ACTION_TEST_ENV__ = "unit-test";
|
||||
@@ -78,7 +78,7 @@ const UPLOAD_LIB_SRC = "./src/upload-lib";
|
||||
*
|
||||
* The virtual module additionally re-exports `upload-lib` under the `uploadLib` namespace so that
|
||||
* external consumers can access it via the small `lib/upload-lib.js` stub emitted below.
|
||||
*
|
||||
*
|
||||
* A tiny stub file is emitted for each Action entrypoint, and one for `upload-lib`. Each stub
|
||||
* imports the shared bundle and calls/re-exports from the respective entry point.
|
||||
*
|
||||
@@ -212,6 +212,7 @@ const context = await esbuild.context({
|
||||
target: ["node20"],
|
||||
define: {
|
||||
__CODEQL_ACTION_VERSION__: JSON.stringify(pkg.version),
|
||||
__CODEQL_ACTION_TEST_ENV__: JSON.stringify(""),
|
||||
},
|
||||
metafile: true,
|
||||
});
|
||||
|
||||
+22
-2
@@ -140,6 +140,17 @@ export default [
|
||||
"no-async-foreach/no-async-foreach": "error",
|
||||
"no-sequences": "error",
|
||||
"no-shadow": "off",
|
||||
|
||||
// A basic check that we don't use `exportVariable` from `@actions/core`.
|
||||
"no-restricted-syntax": [
|
||||
"error",
|
||||
{
|
||||
selector: "MemberExpression[property.name='exportVariable']",
|
||||
message:
|
||||
"Use the `export` method of an `Env` instance or `exportEnvVar` from `environment.ts` instead.",
|
||||
},
|
||||
],
|
||||
|
||||
// This is overly restrictive with unsetting `EnvVar`s
|
||||
"@typescript-eslint/no-dynamic-delete": "off",
|
||||
"@typescript-eslint/no-shadow": "error",
|
||||
@@ -158,7 +169,16 @@ export default [
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["**/*.ts", "**/*.js", "**/*.mts"],
|
||||
files: ["src/environment.ts"],
|
||||
|
||||
// We allow `exportVariable` from `@actions/core` to be used in this file
|
||||
// since it defines the wrapper around it that other modules use.
|
||||
rules: {
|
||||
"no-restricted-syntax": "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["**/*.ts", "**/*.js"],
|
||||
|
||||
rules: {
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
@@ -180,7 +200,7 @@ export default [
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["pr-checks/**/*.ts", "pr-checks/**/*.mts"],
|
||||
files: ["pr-checks/**/*.ts"],
|
||||
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"bundleVersion": "codeql-bundle-v2.27.1",
|
||||
"cliVersion": "2.27.1",
|
||||
"priorBundleVersion": "codeql-bundle-v2.27.0",
|
||||
"priorCliVersion": "2.27.0"
|
||||
"bundleVersion": "codeql-bundle-v2.27.2",
|
||||
"cliVersion": "2.27.2",
|
||||
"priorBundleVersion": "codeql-bundle-v2.27.1",
|
||||
"priorCliVersion": "2.27.1"
|
||||
}
|
||||
Generated
+35567
-11438
File diff suppressed because it is too large.
Load diff
Generated
+239
-183
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "codeql",
|
||||
"version": "4.38.2",
|
||||
"version": "4.38.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "codeql",
|
||||
"version": "4.38.2",
|
||||
"version": "4.38.4",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"pr-checks"
|
||||
@@ -58,14 +58,14 @@
|
||||
"eslint-import-resolver-typescript": "^4.4.5",
|
||||
"eslint-plugin-github": "^6.1.2",
|
||||
"eslint-plugin-import-x": "^4.17.1",
|
||||
"eslint-plugin-jsdoc": "^64.5.2",
|
||||
"eslint-plugin-jsdoc": "^65.0.1",
|
||||
"eslint-plugin-no-async-foreach": "^0.1.1",
|
||||
"glob": "^13.0.6",
|
||||
"globals": "^17.12.0",
|
||||
"nock": "^14.0.17",
|
||||
"sinon": "^22.1.0",
|
||||
"typescript": "^6.0.3",
|
||||
"typescript-eslint": "^8.70.0"
|
||||
"typescript-eslint": "^8.70.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@aashutoshrathi/word-wrap": {
|
||||
@@ -374,9 +374,9 @@
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@actions/artifact/node_modules/brace-expansion": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz",
|
||||
"integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==",
|
||||
"version": "2.1.7",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.7.tgz",
|
||||
"integrity": "sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
@@ -665,9 +665,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/core-client": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.10.1.tgz",
|
||||
"integrity": "sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w==",
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.11.1.tgz",
|
||||
"integrity": "sha512-2QygG2F76ZpMP2eMztiJvAiFMu71M9rDeU7vO/QKg5Css7MgM4frUOslFjhVjRhbGaCNPtz/S8M6y46/fFKVuQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "^2.1.2",
|
||||
@@ -679,45 +679,47 @@
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
"node": ">=22.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/core-client/node_modules/@azure/abort-controller": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
|
||||
"integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.2.0.tgz",
|
||||
"integrity": "sha512-fNAjWnA/nZ2jz31kxR/AqRaUT8ewHBw/WuBIosK0moMy1C9e5ValbDfFdIxJzVOOYaYkV/b2F1S4H/aHiqfVQg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
"node": ">=22.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/core-http-compat": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.3.1.tgz",
|
||||
"integrity": "sha512-az9BkXND3/d5VgdRRQVkiJb2gOmDU8Qcq4GvjtBmDICNiQ9udFmDk4ZpSB5Qq1OmtDJGlQAfBaS4palFsazQ5g==",
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.5.0.tgz",
|
||||
"integrity": "sha512-BoSmXPx2er1Ai+wKlDvj29jIQespCNBwEmKyZVHO2kEFsWbGjAjwMCGzug3DJM5/QYIV3vej0S1zcU5bq9fa8w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "^2.1.2",
|
||||
"@azure/core-client": "^1.10.0",
|
||||
"@azure/core-rest-pipeline": "^1.22.0"
|
||||
"@azure/abort-controller": "^2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
"node": ">=22.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@azure/core-client": "^1.10.0",
|
||||
"@azure/core-rest-pipeline": "^1.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/core-http-compat/node_modules/@azure/abort-controller": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
|
||||
"integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.2.0.tgz",
|
||||
"integrity": "sha512-fNAjWnA/nZ2jz31kxR/AqRaUT8ewHBw/WuBIosK0moMy1C9e5ValbDfFdIxJzVOOYaYkV/b2F1S4H/aHiqfVQg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
"node": ">=22.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/core-lro": {
|
||||
@@ -760,9 +762,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/core-rest-pipeline": {
|
||||
"version": "1.22.2",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.22.2.tgz",
|
||||
"integrity": "sha512-MzHym+wOi8CLUlKCQu12de0nwcq9k9Kuv43j4Wa++CsCpJwps2eeBQwD2Bu8snkxTtDKDx4GwjuR9E8yC8LNrg==",
|
||||
"version": "1.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.25.0.tgz",
|
||||
"integrity": "sha512-bMs8ekJLjX8wPV+9IPBges1SLPyuDtE9g5gLDWOpxzKcoOFQnpLGkbcT1tdw3FaAmDS1gnPmMmJ6y/T5B96kIA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "^2.1.2",
|
||||
@@ -770,11 +772,11 @@
|
||||
"@azure/core-tracing": "^1.3.0",
|
||||
"@azure/core-util": "^1.13.0",
|
||||
"@azure/logger": "^1.3.0",
|
||||
"@typespec/ts-http-runtime": "^0.3.0",
|
||||
"@typespec/ts-http-runtime": "^0.3.4",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
"node": ">=22.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/core-rest-pipeline/node_modules/@azure/abort-controller": {
|
||||
@@ -854,9 +856,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/storage-blob": {
|
||||
"version": "12.29.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.29.1.tgz",
|
||||
"integrity": "sha512-7ktyY0rfTM0vo7HvtK6E3UvYnI9qfd6Oz6z/+92VhGRveWng3kJwMKeUpqmW/NmwcDNbxHpSlldG+vsUnRFnBg==",
|
||||
"version": "12.34.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.34.0.tgz",
|
||||
"integrity": "sha512-cXDTCAMwDx8Ng9yUe82kOOd2kPnZ8AQqe4FkLMcpaQ3Mvr3/PXVdvRhyP0FtY5/U5Oh6JGk3EcEibaFOymRLFw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "^2.1.2",
|
||||
@@ -870,12 +872,13 @@
|
||||
"@azure/core-util": "^1.11.0",
|
||||
"@azure/core-xml": "^1.4.5",
|
||||
"@azure/logger": "^1.1.4",
|
||||
"@azure/storage-common": "^12.1.1",
|
||||
"@azure/storage-common": "^12.5.0",
|
||||
"apache-arrow": "^21.1.0",
|
||||
"events": "^3.0.0",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
"node": ">=22.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/storage-blob/node_modules/@azure/abort-controller": {
|
||||
@@ -891,15 +894,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/storage-common": {
|
||||
"version": "12.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure/storage-common/-/storage-common-12.1.1.tgz",
|
||||
"integrity": "sha512-eIOH1pqFwI6UmVNnDQvmFeSg0XppuzDLFeUNO/Xht7ODAzRLgGDh7h550pSxoA+lPDxBl1+D2m/KG3jWzCUjTg==",
|
||||
"version": "12.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/storage-common/-/storage-common-12.5.0.tgz",
|
||||
"integrity": "sha512-bttzuhQiCIwrkzjPDA+AtAR7dg19L/CC6ztcqJ5LfvWpXuys9mHp0UQ0udYnoUvv9SCT9KTR5kqFvFr0e6k0lQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@azure/abort-controller": "^2.1.2",
|
||||
"@azure/core-auth": "^1.9.0",
|
||||
"@azure/core-http-compat": "^2.2.0",
|
||||
"@azure/core-rest-pipeline": "^1.19.1",
|
||||
"@azure/core-http-compat": "^2.4.0",
|
||||
"@azure/core-rest-pipeline": "^1.24.0",
|
||||
"@azure/core-tracing": "^1.2.0",
|
||||
"@azure/core-util": "^1.11.0",
|
||||
"@azure/logger": "^1.1.4",
|
||||
@@ -907,19 +910,19 @@
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
"node": ">=22.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/storage-common/node_modules/@azure/abort-controller": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
|
||||
"integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.2.0.tgz",
|
||||
"integrity": "sha512-fNAjWnA/nZ2jz31kxR/AqRaUT8ewHBw/WuBIosK0moMy1C9e5ValbDfFdIxJzVOOYaYkV/b2F1S4H/aHiqfVQg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
"node": ">=22.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/core": {
|
||||
@@ -957,17 +960,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@es-joy/jsdoccomment": {
|
||||
"version": "0.97.0",
|
||||
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.97.0.tgz",
|
||||
"integrity": "sha512-EP8uoFfh6+GsdGCduYtmWAW0h7AO+Ayik9Vh5YbA2r/3N6lmJKkCNZX+q3QBXC1K6ixjQ/9igF2b7WVvLm063g==",
|
||||
"version": "0.98.0",
|
||||
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.98.0.tgz",
|
||||
"integrity": "sha512-QS+b7I2aaSM+gZfDz1b9E4B367JJ2qTjFXRKF289iKkh9sYdZ21Q5MiF/Duzouy3J0C4VhM3I/8f2F4+zT8gYQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.9",
|
||||
"@typescript-eslint/types": "^8.69.0",
|
||||
"comment-parser": "1.4.8",
|
||||
"@typescript-eslint/types": "^8.70.0",
|
||||
"comment-parser": "1.4.9",
|
||||
"esquery": "^1.7.0",
|
||||
"jsdoc-type-pratt-parser": "~9.2.1"
|
||||
"jsdoc-type-pratt-parser": "~9.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^22.22.2 || >=24.15.0"
|
||||
@@ -2593,7 +2596,7 @@
|
||||
},
|
||||
"node_modules/@types/debug": {
|
||||
"version": "4.1.13",
|
||||
"resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/debug/-/debug-4.1.13.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz",
|
||||
"integrity": "sha1-ItHMnVQtNZPK6nZPl0MGqzYobuc=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -2636,7 +2639,7 @@
|
||||
},
|
||||
"node_modules/@types/mdast": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/mdast/-/mdast-4.0.4.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
|
||||
"integrity": "sha1-fM9y7dLxqn3TQ34YDGQ3NYWATdY=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -2645,7 +2648,7 @@
|
||||
},
|
||||
"node_modules/@types/ms": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/ms/-/ms-2.1.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
|
||||
"integrity": "sha1-BSqmekjszEMJ1/AZG35BQ0uQu3g=",
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -2710,22 +2713,22 @@
|
||||
},
|
||||
"node_modules/@types/unist": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/unist/-/unist-3.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
|
||||
"integrity": "sha1-rKqw+RnOaczmKcLU7S60rcG2wgw=",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "8.70.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.70.0.tgz",
|
||||
"integrity": "sha512-/v8HZt6RlyIZxB3ntehELOcUcfxKPVGWXnQdJuHRmzrqgF8nQypcC/oxGW+Ot4VGKDq81XugPKxx0n5PBtf9PA==",
|
||||
"version": "8.70.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.70.1.tgz",
|
||||
"integrity": "sha512-nDNrUQ/4ruSNYbu749TRY7cfrzPtoLHEXSNBI8aaNY32LlZCajixqRf3FqcKC4p5Cam4VOHYx/t+i5+nKXvrqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.12.2",
|
||||
"@typescript-eslint/scope-manager": "8.70.0",
|
||||
"@typescript-eslint/type-utils": "8.70.0",
|
||||
"@typescript-eslint/utils": "8.70.0",
|
||||
"@typescript-eslint/visitor-keys": "8.70.0",
|
||||
"@typescript-eslint/scope-manager": "8.70.1",
|
||||
"@typescript-eslint/type-utils": "8.70.1",
|
||||
"@typescript-eslint/utils": "8.70.1",
|
||||
"@typescript-eslint/visitor-keys": "8.70.1",
|
||||
"ignore": "^7.0.5",
|
||||
"natural-compare": "^1.4.0",
|
||||
"ts-api-utils": "^2.5.0"
|
||||
@@ -2738,7 +2741,7 @@
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@typescript-eslint/parser": "^8.70.0",
|
||||
"@typescript-eslint/parser": "^8.70.1",
|
||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||
"typescript": ">=4.8.4 <6.1.0"
|
||||
}
|
||||
@@ -2754,16 +2757,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "8.70.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.70.0.tgz",
|
||||
"integrity": "sha512-zYvrmj9Yxd63UGaXw+kdt6A0F0s0qveJyuatIM77bYC2DE4pgmg7a50u8LR7PRtXd0x+h+Tl3eXabGm06SWd3Q==",
|
||||
"version": "8.70.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.70.1.tgz",
|
||||
"integrity": "sha512-nO974WLllwhSFWQXnMLj6nDGa8f0khKEz1JzpPJ1u7Vm/4X1X6ZHajpoknU4bb41vJyMB0HHVyS2GqdhWfIXZw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.70.0",
|
||||
"@typescript-eslint/types": "8.70.0",
|
||||
"@typescript-eslint/typescript-estree": "8.70.0",
|
||||
"@typescript-eslint/visitor-keys": "8.70.0",
|
||||
"@typescript-eslint/scope-manager": "8.70.1",
|
||||
"@typescript-eslint/types": "8.70.1",
|
||||
"@typescript-eslint/typescript-estree": "8.70.1",
|
||||
"@typescript-eslint/visitor-keys": "8.70.1",
|
||||
"debug": "^4.4.3"
|
||||
},
|
||||
"engines": {
|
||||
@@ -2797,14 +2800,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/project-service": {
|
||||
"version": "8.70.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.70.0.tgz",
|
||||
"integrity": "sha512-hFHbTNqhU9G+2eKFXCBVb1tjFT/LceiJ4+HfLO4pTpDI0KHi6iajpcFFkaSQ9gXmCh7n82A0PthaayEdN6mspQ==",
|
||||
"version": "8.70.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.70.1.tgz",
|
||||
"integrity": "sha512-62xOgboPfwc3/IgPSX/W6oQR3ZbF04194FPGUGH8HL8iLFHbt/456/8Ph1wLNUgVF+s94FlHoipBsz+v7+LMnA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/tsconfig-utils": "^8.70.0",
|
||||
"@typescript-eslint/types": "^8.70.0",
|
||||
"@typescript-eslint/tsconfig-utils": "^8.70.1",
|
||||
"@typescript-eslint/types": "^8.70.1",
|
||||
"debug": "^4.4.3"
|
||||
},
|
||||
"engines": {
|
||||
@@ -2837,14 +2840,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "8.70.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.70.0.tgz",
|
||||
"integrity": "sha512-8nP3Kwh5hlgZ4FicGvmznAmJe8UL4sdU8tLukrPaMuQmDuk4Y8xYfzu/aYZW4xT2JCgc7H/TpDI5cGlxcWJSqQ==",
|
||||
"version": "8.70.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.70.1.tgz",
|
||||
"integrity": "sha512-Pa0EeSeAusQc1WbjQMac+YfenewYTBu0KjgYvkUKwhXaHUKbFog23Dm/rp0DX/6tyYOQ3Xl1a+3EcFNZynGHCw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.70.0",
|
||||
"@typescript-eslint/visitor-keys": "8.70.0"
|
||||
"@typescript-eslint/types": "8.70.1",
|
||||
"@typescript-eslint/visitor-keys": "8.70.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
@@ -2855,9 +2858,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/tsconfig-utils": {
|
||||
"version": "8.70.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.70.0.tgz",
|
||||
"integrity": "sha512-adnkeeNq9Sq1sUf4+FRVc0KdgYghzsgFpZSQVZVvY0LCuUuN0FnQgyGzCJeC4fW1cdXseBAjU2EOqUIjbNcZUw==",
|
||||
"version": "8.70.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.70.1.tgz",
|
||||
"integrity": "sha512-jumze1fPI+sDOaM2TWGQdn39PDxTr7TZGeuyLkAbNyx2vtMT3uRnVKChN0hfht5V2TugphJzF6bYXvBcE09qqg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -2872,15 +2875,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils": {
|
||||
"version": "8.70.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.70.0.tgz",
|
||||
"integrity": "sha512-NUMKIhYVaVIVLnRL9CRt+VVcuLgSHUCpXn4/+K8wql+vdInUzvx8BjUO1oJ7cG9shjFJKtF8F8Hh2kCh3/KBVw==",
|
||||
"version": "8.70.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.70.1.tgz",
|
||||
"integrity": "sha512-7zKTnyvaVWqzLZHPFQtX1hVHqgkMC+WebPWakNCSyrQVbIP1AM0L0TlBZtACldIRb6PptI8Odk+jyZ5kP3B1VA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.70.0",
|
||||
"@typescript-eslint/typescript-estree": "8.70.0",
|
||||
"@typescript-eslint/utils": "8.70.0",
|
||||
"@typescript-eslint/types": "8.70.1",
|
||||
"@typescript-eslint/typescript-estree": "8.70.1",
|
||||
"@typescript-eslint/utils": "8.70.1",
|
||||
"debug": "^4.4.3",
|
||||
"ts-api-utils": "^2.5.0"
|
||||
},
|
||||
@@ -2915,9 +2918,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "8.70.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.70.0.tgz",
|
||||
"integrity": "sha512-asTOIYhDg4zdzOScCyaytrsV3cR6B4ecPQlXw/dJIm7J/MZTtCtfVII9JD8Geh4jTCrK/Xe6cg5UevoleMcoJQ==",
|
||||
"version": "8.70.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.70.1.tgz",
|
||||
"integrity": "sha512-Dm1ypdhhrGCTyyehxElhgJ6kgk8MVCv5qXdoOVqPr1uqk42jX8KjrZqhROvdShczA8qrDoYiOWn1ykWlx2k81Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -2929,16 +2932,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "8.70.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.70.0.tgz",
|
||||
"integrity": "sha512-d9NmHMPEKQ7QCLLm1jI3zmoQBwT5KwFYjXBJ9ymZfKCUU+5rmTRykKAFvH5Qn/ZCds3CEAFS9OC9M/jkl0X2bA==",
|
||||
"version": "8.70.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.70.1.tgz",
|
||||
"integrity": "sha512-TU8PwyGN0PQJUcE96mw8eCQ44SmxGdQlJmlWakHaHQ15eIuuvye5yNtmh/i6oS88jzXVQB71xdNkbkB/fMwL0g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/project-service": "8.70.0",
|
||||
"@typescript-eslint/tsconfig-utils": "8.70.0",
|
||||
"@typescript-eslint/types": "8.70.0",
|
||||
"@typescript-eslint/visitor-keys": "8.70.0",
|
||||
"@typescript-eslint/project-service": "8.70.1",
|
||||
"@typescript-eslint/tsconfig-utils": "8.70.1",
|
||||
"@typescript-eslint/types": "8.70.1",
|
||||
"@typescript-eslint/visitor-keys": "8.70.1",
|
||||
"debug": "^4.4.3",
|
||||
"minimatch": "^10.2.2",
|
||||
"semver": "^7.7.3",
|
||||
@@ -2967,9 +2970,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
|
||||
"version": "5.0.9",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
|
||||
"integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
|
||||
"version": "5.0.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
|
||||
"integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -3014,16 +3017,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "8.70.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.70.0.tgz",
|
||||
"integrity": "sha512-oZmtKJz/4fufZ2p3+Cn3ijEojcdfR+1zYDH2xKYrEly0dR/Q/1xUPRCOlKGxod78nWlU2UnDe09GZ3TaknBFGA==",
|
||||
"version": "8.70.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.70.1.tgz",
|
||||
"integrity": "sha512-Esgul8MsnKnRLdYU2Eb2cRV9bS5HJYtKj1ByJnOzzG2M58DGdSUQ1jUuILxipqcpB2h9WLrbD5GijIWUjX/Tqw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.9.1",
|
||||
"@typescript-eslint/scope-manager": "8.70.0",
|
||||
"@typescript-eslint/types": "8.70.0",
|
||||
"@typescript-eslint/typescript-estree": "8.70.0"
|
||||
"@typescript-eslint/scope-manager": "8.70.1",
|
||||
"@typescript-eslint/types": "8.70.1",
|
||||
"@typescript-eslint/typescript-estree": "8.70.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
@@ -3038,13 +3041,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "8.70.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.70.0.tgz",
|
||||
"integrity": "sha512-BoC8PiO4Hkdo0TVJh9Ntxr5MxPDI7/oFsrygN5ADelFSeXG/qgNuucIGA+L5Z6JpPTE/uRfcTWtscjbUaufepQ==",
|
||||
"version": "8.70.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.70.1.tgz",
|
||||
"integrity": "sha512-Vwj9lUIW5Xq3wQ9w6gv3R86g1hMK8f2zNOdGTAgeXUMMXFK78G9ruCjjqutHMNJc0+CH7LYRnHeUB9IT8wFmcw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.70.0",
|
||||
"@typescript-eslint/types": "8.70.1",
|
||||
"eslint-visitor-keys": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -3069,9 +3072,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typespec/ts-http-runtime": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.2.tgz",
|
||||
"integrity": "sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==",
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.9.tgz",
|
||||
"integrity": "sha512-edSdeAqkdxBVzA1yL1LrLCml1YjyCVvPMtMqJpbF+6K609tHe8V6sQUzFQSGcYNhcuhOceZtjvN32+mpIth30A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"http-proxy-agent": "^7.0.0",
|
||||
@@ -3079,7 +3082,7 @@
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
"node": ">=22.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ungap/structured-clone": {
|
||||
@@ -3497,6 +3500,36 @@
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/apache-arrow": {
|
||||
"version": "21.2.0",
|
||||
"resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-21.2.0.tgz",
|
||||
"integrity": "sha512-Hxe6Agq26gQOM954qpzYSllJBPJl+e16U5CkfuMUhLrNba+5nKkttIVlflaovN6oaTratqMGAO8H5u/aNhmHWQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/node": "^25.2.0",
|
||||
"flatbuffers": "^25.1.24",
|
||||
"json-with-bigint": "^3.5.3",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"bin": {
|
||||
"arrow2csv": "bin/arrow2csv.js"
|
||||
}
|
||||
},
|
||||
"node_modules/apache-arrow/node_modules/@types/node": {
|
||||
"version": "25.9.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.8.tgz",
|
||||
"integrity": "sha512-VfMrScDmMhUJQmd5hArdQnFvK0OIeD36uN2Va1FcpYaLB/BgkgM8Ulc50XtYISPMz7APJ30+N0T5EM0jlcdfRw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": ">=7.24.0 <7.24.7"
|
||||
}
|
||||
},
|
||||
"node_modules/apache-arrow/node_modules/undici-types": {
|
||||
"version": "7.24.6",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
||||
"integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/archiver": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/archiver/-/archiver-8.0.0.tgz",
|
||||
@@ -4001,9 +4034,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.18",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
|
||||
"integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
|
||||
"version": "1.1.21",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz",
|
||||
"integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
@@ -4216,7 +4249,7 @@
|
||||
},
|
||||
"node_modules/character-entities": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/character-entities/-/character-entities-2.0.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
|
||||
"integrity": "sha1-LQnC5yzZUjB2zLIRV9/2atQ/zCI=",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
@@ -4377,9 +4410,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/comment-parser": {
|
||||
"version": "1.4.8",
|
||||
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.8.tgz",
|
||||
"integrity": "sha512-rKZTGo4fzKYna8UcL0isTg5wkBNla7bxTypLwZQXjIdi++IdP1OJ41rI5Mti3/jltkPujbu4i9LIARYA+zpotQ==",
|
||||
"version": "1.4.9",
|
||||
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.9.tgz",
|
||||
"integrity": "sha512-+2AvZKjJaNq9GQljm3tr0utwrig5BL+jgJGvz5rDpGKNIp+ojcRXWUwBbh/sGIi1QCprR6PsKFakub+w1v+4hQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -4611,7 +4644,7 @@
|
||||
},
|
||||
"node_modules/decode-named-character-reference": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz",
|
||||
"integrity": "sha1-PkBgN2CHTC5YZ2kbWZ1zp9oltT8=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -4667,7 +4700,7 @@
|
||||
},
|
||||
"node_modules/dequal": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/dequal/-/dequal-2.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||
"integrity": "sha1-JkQhTxmX057Q7g7OcjNUkKesZ74=",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -4686,7 +4719,7 @@
|
||||
},
|
||||
"node_modules/devlop": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/devlop/-/devlop-1.1.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
|
||||
"integrity": "sha1-TbfCyk3G4Og0wwvnDJS7yXbccBg=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -5311,9 +5344,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-import-x/node_modules/brace-expansion": {
|
||||
"version": "5.0.9",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
|
||||
"integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
|
||||
"version": "5.0.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
|
||||
"integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -5348,17 +5381,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-jsdoc": {
|
||||
"version": "64.5.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-64.5.2.tgz",
|
||||
"integrity": "sha512-GirLf/jpVQ/HSLVT98ztIrJ8GUlWWrrwExkofqzeIjjOxlqFtyqnpkRs30FLwEKh0xHEpgy35CU0qFn0I/Mh9w==",
|
||||
"version": "65.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-65.0.1.tgz",
|
||||
"integrity": "sha512-7IvB+ZS71WCw5tGKh6f6D5k55qtXKdrGTnIpQTBKWdpyZ5IfhGHfh0i6ArWlCJ4JEtz22YRk5Bqu1MvbOlpMKQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@es-joy/jsdoccomment": "~0.97.0",
|
||||
"@es-joy/jsdoccomment": "~0.98.0",
|
||||
"@es-joy/resolve.exports": "1.2.0",
|
||||
"@typescript-eslint/utils": "^8.69.0",
|
||||
"@typescript-eslint/utils": "^8.70.1",
|
||||
"are-docs-informative": "^0.1.1",
|
||||
"comment-parser": "1.4.8",
|
||||
"comment-parser": "1.4.9",
|
||||
"debug": "^4.4.3",
|
||||
"escape-string-regexp": "^5.0.0",
|
||||
"espree": "^11.2.0",
|
||||
@@ -5960,6 +5993,12 @@
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/flatbuffers": {
|
||||
"version": "25.9.23",
|
||||
"resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz",
|
||||
"integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/flatted": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
|
||||
@@ -6227,9 +6266,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/glob/node_modules/brace-expansion": {
|
||||
"version": "5.0.9",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
|
||||
"integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
|
||||
"version": "5.0.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
|
||||
"integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^4.0.2"
|
||||
@@ -7129,9 +7168,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jsdoc-type-pratt-parser": {
|
||||
"version": "9.2.1",
|
||||
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-9.2.1.tgz",
|
||||
"integrity": "sha512-V4Ww4EHnTcTLSOMoB0FsF72JhQvcAsriCm/LWnxJeGWoxIjEL2l9na11abQok5SYShq8m0Gl02el/xAbTCulvQ==",
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-9.2.2.tgz",
|
||||
"integrity": "sha512-eFY7Rlscvv/BpY6UsVsjKwMhu1tJO/F4U/vC9g3yeRy/JqszuO1UP6Vdq+85G+3FP6fEw/sWR8a5ftPFY86csw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -7143,9 +7182,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jsdoc-type-pratt-parser/node_modules/@types/node": {
|
||||
"version": "26.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.5.0.tgz",
|
||||
"integrity": "sha512-dVSGpriSoCgz8WnDNTuSSuSv1PC/ALXihO4ulRZt7Md8k9mlbdin3lGOcDE8SnWOgf513ByWlXd7BK4azmyg/A==",
|
||||
"version": "26.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.2.tgz",
|
||||
"integrity": "sha512-X1P21scMv4zGKLYqjdGjaKa7COa0RKVYYZZN/NfvLQ1JegxFhdhpZG/Lyn8AXx6CDUavKAd11v6BvfpkDByK8g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -7480,7 +7519,7 @@
|
||||
},
|
||||
"node_modules/mdast-util-to-string": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
|
||||
"integrity": "sha1-elEhR1VWoE5+3etnsmSq550xKBQ=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -7519,7 +7558,7 @@
|
||||
},
|
||||
"node_modules/micromark": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark/-/micromark-4.0.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz",
|
||||
"integrity": "sha1-kTlaPhiEoZjmIRbjPJxWjjmTb9s=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7554,7 +7593,7 @@
|
||||
},
|
||||
"node_modules/micromark-core-commonmark": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz",
|
||||
"integrity": "sha1-xpFjDkhQIaaM8o28Kyyifr9njNQ=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7588,7 +7627,7 @@
|
||||
},
|
||||
"node_modules/micromark-factory-destination": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
|
||||
"integrity": "sha1-j++OD3CB8EdPvdkt61DJkKAmRjk=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7609,7 +7648,7 @@
|
||||
},
|
||||
"node_modules/micromark-factory-label": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz",
|
||||
"integrity": "sha1-UmfvqX8eUlTvx/ILRZo4yyEFi6E=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7631,7 +7670,7 @@
|
||||
},
|
||||
"node_modules/micromark-factory-space": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
|
||||
"integrity": "sha1-NtAhLpYrKzEh+FJfx6PHwCnzNPw=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7651,7 +7690,7 @@
|
||||
},
|
||||
"node_modules/micromark-factory-title": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz",
|
||||
"integrity": "sha1-I35KpdWKlYY/AQMtnumwkPHebpQ=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7673,7 +7712,7 @@
|
||||
},
|
||||
"node_modules/micromark-factory-whitespace": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz",
|
||||
"integrity": "sha1-BrJrKYPE0nv8xlezPiUTTUhosLE=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7695,7 +7734,7 @@
|
||||
},
|
||||
"node_modules/micromark-util-character": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
|
||||
"integrity": "sha1-L5h4MaQNTFEKwmHomFLE6XA8zaY=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7715,7 +7754,7 @@
|
||||
},
|
||||
"node_modules/micromark-util-chunked": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz",
|
||||
"integrity": "sha1-R/vNk0caP8yrhs/wOEf8NVLbEFE=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7734,7 +7773,7 @@
|
||||
},
|
||||
"node_modules/micromark-util-classify-character": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz",
|
||||
"integrity": "sha1-05n6+cRcoUyLS+mLHqSBvO2Htik=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7755,7 +7794,7 @@
|
||||
},
|
||||
"node_modules/micromark-util-combine-extensions": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz",
|
||||
"integrity": "sha1-Kg9JCrCL/1zC/V7sbdDKBPibMKk=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7775,7 +7814,7 @@
|
||||
},
|
||||
"node_modules/micromark-util-decode-numeric-character-reference": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz",
|
||||
"integrity": "sha1-/PFbZgl5OI5vEYzba/fXnXPSb+U=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7794,7 +7833,7 @@
|
||||
},
|
||||
"node_modules/micromark-util-decode-string": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz",
|
||||
"integrity": "sha1-bLmVguXScehO/KjmGoB5lNcWHrI=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7816,7 +7855,7 @@
|
||||
},
|
||||
"node_modules/micromark-util-encode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
|
||||
"integrity": "sha1-DVHRwJVVHPqsNoMmljz1XxX1QLg=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7832,7 +7871,7 @@
|
||||
},
|
||||
"node_modules/micromark-util-html-tag-name": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
|
||||
"integrity": "sha1-5AQDCWSBmGtBwQZif5j3LU0QuCU=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7848,7 +7887,7 @@
|
||||
},
|
||||
"node_modules/micromark-util-normalize-identifier": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz",
|
||||
"integrity": "sha1-ww13sugyrPZSb4vxqke8nJQ4wW0=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7867,7 +7906,7 @@
|
||||
},
|
||||
"node_modules/micromark-util-resolve-all": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz",
|
||||
"integrity": "sha1-4aLWLN0jcjCirhGDkCexk4HjHos=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7886,7 +7925,7 @@
|
||||
},
|
||||
"node_modules/micromark-util-sanitize-uri": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
|
||||
"integrity": "sha1-q4l4m4GKWHUrc9a1UjhiG3+qj9c=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7907,7 +7946,7 @@
|
||||
},
|
||||
"node_modules/micromark-util-subtokenize": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz",
|
||||
"integrity": "sha1-2K3lug8xl6HPaimZ+7/mNXoaGe4=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7929,7 +7968,7 @@
|
||||
},
|
||||
"node_modules/micromark-util-symbol": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
|
||||
"integrity": "sha1-5dpJTo6ysHGg0I+zT2zv7GwKGbg=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -7945,7 +7984,7 @@
|
||||
},
|
||||
"node_modules/micromark-util-types": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
|
||||
"integrity": "sha1-8AIl9fWg68MlT5bDa2YFxLOTkI4=",
|
||||
"funding": [
|
||||
{
|
||||
@@ -8727,9 +8766,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/readdir-glob/node_modules/brace-expansion": {
|
||||
"version": "5.0.9",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
|
||||
"integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
|
||||
"version": "5.0.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
|
||||
"integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^4.0.2"
|
||||
@@ -9805,9 +9844,9 @@
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/tsx": {
|
||||
"version": "4.23.13",
|
||||
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.13.tgz",
|
||||
"integrity": "sha512-BL5MGkRln6aDYhb0xbQlEAGw743BaZYWdbWtdJOBriYJboKgUUYCadFp2/FpBBZquBC/ezNBn7wMMPx7FDZUDw==",
|
||||
"version": "4.23.15",
|
||||
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.15.tgz",
|
||||
"integrity": "sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -9957,16 +9996,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript-eslint": {
|
||||
"version": "8.70.0",
|
||||
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.70.0.tgz",
|
||||
"integrity": "sha512-P/W5cz70/cQAuKfY3xwQMWWTV7BvJ0mAQmi+9mBcsVPaBUpd6Ohpa+fECv9rBFrQcig86jAiNBFNWUqnTjr4pw==",
|
||||
"version": "8.70.1",
|
||||
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.70.1.tgz",
|
||||
"integrity": "sha512-AcWG7KDjZ2THNXsgwttMaGmzVi0VFRlFYfqFHYQRbDpF3owuYbuiL8c7UUrd2k8s3PoSfIQrWfrGXfcElrWLYA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "8.70.0",
|
||||
"@typescript-eslint/parser": "8.70.0",
|
||||
"@typescript-eslint/typescript-estree": "8.70.0",
|
||||
"@typescript-eslint/utils": "8.70.0"
|
||||
"@typescript-eslint/eslint-plugin": "8.70.1",
|
||||
"@typescript-eslint/parser": "8.70.1",
|
||||
"@typescript-eslint/typescript-estree": "8.70.1",
|
||||
"@typescript-eslint/utils": "8.70.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
@@ -10030,7 +10069,7 @@
|
||||
},
|
||||
"node_modules/unist-util-stringify-position": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz",
|
||||
"integrity": "sha1-RJxuIaiA4IVb9aq63rOnQDFKusI=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -10469,9 +10508,26 @@
|
||||
"yaml": "^2.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.19.43",
|
||||
"tsx": "^4.23.13"
|
||||
"@types/node": "^24.19.0",
|
||||
"tsx": "^4.23.15"
|
||||
}
|
||||
},
|
||||
"pr-checks/node_modules/@types/node": {
|
||||
"version": "24.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.19.0.tgz",
|
||||
"integrity": "sha512-zY+5tKxXdhGh1PYI0ac+7juvEu4OI6vWtVVoj5i2m42jxAY1U+zHGt6QCyOFwykdP62sM3MJ9stoYYUw5aCWew==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": ">=7.24.0 <7.24.7"
|
||||
}
|
||||
},
|
||||
"pr-checks/node_modules/undici-types": {
|
||||
"version": "7.24.6",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
||||
"integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "codeql",
|
||||
"version": "4.38.2",
|
||||
"version": "4.38.4",
|
||||
"private": true,
|
||||
"description": "CodeQL action",
|
||||
"scripts": {
|
||||
@@ -44,8 +44,8 @@
|
||||
"long": "^5.3.2",
|
||||
"node-forge": "^1.4.0",
|
||||
"semver": "^7.8.5",
|
||||
"uuid": "^14.0.2",
|
||||
"undici": "^6.28.0"
|
||||
"undici": "^6.28.0",
|
||||
"uuid": "^14.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ava/typescript": "6.0.0",
|
||||
@@ -66,14 +66,14 @@
|
||||
"eslint-import-resolver-typescript": "^4.4.5",
|
||||
"eslint-plugin-github": "^6.1.2",
|
||||
"eslint-plugin-import-x": "^4.17.1",
|
||||
"eslint-plugin-jsdoc": "^64.5.2",
|
||||
"eslint-plugin-jsdoc": "^65.0.1",
|
||||
"eslint-plugin-no-async-foreach": "^0.1.1",
|
||||
"glob": "^13.0.6",
|
||||
"globals": "^17.12.0",
|
||||
"nock": "^14.0.17",
|
||||
"sinon": "^22.1.0",
|
||||
"typescript": "^6.0.3",
|
||||
"typescript-eslint": "^8.70.0"
|
||||
"typescript-eslint": "^8.70.1"
|
||||
},
|
||||
"overrides": {
|
||||
"@actions/tool-cache": {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
24
|
||||
@@ -122,6 +122,6 @@ function main() {
|
||||
}
|
||||
|
||||
// Only call `main` if this script was run directly.
|
||||
if (require.main === module) {
|
||||
if (import.meta.main) {
|
||||
process.exit(main());
|
||||
}
|
||||
@@ -43,6 +43,6 @@ async function main() {
|
||||
}
|
||||
|
||||
// Only call `main` if this script was run directly.
|
||||
if (require.main === module) {
|
||||
if (import.meta.main) {
|
||||
void main();
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
isValidChangenoteFile,
|
||||
isValidChangenoteFilename,
|
||||
VALID_CHANGE_NOTE_CATEGORIES,
|
||||
} from "./validate.mjs";
|
||||
} from "./validate";
|
||||
|
||||
await describe("isValidChangenoteContent", async () => {
|
||||
await it("recognizes an unordered Markdown list", () => {
|
||||
@@ -154,26 +154,6 @@ await describe("isValidChangenoteFile", async () => {
|
||||
assert.equal(isValidChangenoteFile("non-existent-file.md"), false);
|
||||
});
|
||||
|
||||
await it("rejects invalid filename", async () => {
|
||||
await withTmpFile(
|
||||
"fix-bug.md",
|
||||
"---\ncategory: fix\n---\n- Fixed a bug\n",
|
||||
(filePath) => {
|
||||
assert.equal(isValidChangenoteFile(filePath), false);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
await it("rejects missing frontmatter", async () => {
|
||||
await withTmpFile(
|
||||
"2026-01-01-fix-bug.md",
|
||||
"- Fixed a bug\n",
|
||||
(filePath) => {
|
||||
assert.equal(isValidChangenoteFile(filePath), false);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
await it("rejects invalid Markdown", async () => {
|
||||
await withTmpFile(
|
||||
"2026-01-01-fix-bug.md",
|
||||
@@ -1,5 +1,4 @@
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
|
||||
import { matter } from "lite-matter";
|
||||
import type { List, ListItem } from "mdast";
|
||||
@@ -95,21 +94,7 @@ export function isValidChangenoteFile(filename: string): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { data: frontmatter, content } = matter(fileData);
|
||||
|
||||
if (!isValidChangenoteFilename(path.basename(filename))) {
|
||||
isValid = false;
|
||||
console.error(
|
||||
`${filename}: invalid filename; must match pattern YYYY-MM-DD-id.md`,
|
||||
);
|
||||
}
|
||||
if (!hasValidChangenoteCategory(frontmatter)) {
|
||||
isValid = false;
|
||||
const categories = Object.keys(VALID_CHANGE_NOTE_CATEGORIES).join(", ");
|
||||
console.error(
|
||||
`${filename}: invalid category; must be one of: ${categories}`,
|
||||
);
|
||||
}
|
||||
const { content } = matter(fileData);
|
||||
if (!isValidChangenoteContent(content)) {
|
||||
isValid = false;
|
||||
console.error(
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
renderChangelog,
|
||||
withChangelog,
|
||||
} from "./changelog";
|
||||
import { isValidChangenoteFile } from "./changelog/validate.mjs";
|
||||
import { isValidChangenoteFile } from "./changelog/validate";
|
||||
import { CHANGENOTES_DIR } from "./config";
|
||||
|
||||
/**
|
||||
@@ -28,12 +28,12 @@ interface ChangenoteFile {
|
||||
|
||||
/**
|
||||
* Returns the absolute file paths of all files in
|
||||
* {@link CHANGENOTES_DIR} (except ".gitkeep").
|
||||
* {@link CHANGENOTES_DIR} (except ".gitkeep" and "README.md").
|
||||
* */
|
||||
function listUnreleasedChangenoteDir(): string[] {
|
||||
return fs
|
||||
.readdirSync(CHANGENOTES_DIR)
|
||||
.filter((name) => name !== ".gitkeep")
|
||||
.filter((name) => ![".gitkeep", "README.md"].includes(name))
|
||||
.map((name) => path.join(CHANGENOTES_DIR, name));
|
||||
}
|
||||
|
||||
@@ -82,9 +82,9 @@ function main(): ExitCode {
|
||||
|
||||
function usage(): ExitCode {
|
||||
const message =
|
||||
"Usage: changenotes.mts assemble\n" +
|
||||
" changenotes.mts validate\n" +
|
||||
" changenotes.mts help";
|
||||
"Usage: changenotes.ts assemble\n" +
|
||||
" changenotes.ts validate\n" +
|
||||
" changenotes.ts help";
|
||||
console.log(message);
|
||||
return ExitCode.Success;
|
||||
}
|
||||
@@ -218,6 +218,6 @@ async function run(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
if (import.meta.main) {
|
||||
void run();
|
||||
}
|
||||
@@ -11,6 +11,10 @@ installDotNet: true
|
||||
env:
|
||||
CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS: false
|
||||
CODEQL_ACTION_SUBLANGUAGE_FILE_COVERAGE: true
|
||||
# To balance speed and coverage, we analyze only a single language (JavaScript), but use the
|
||||
# combined bundle so we can test that baseline information is reported for each language in the
|
||||
# multi-language source directory.
|
||||
CODEQL_ACTION_PER_LANGUAGE_BUNDLES: false
|
||||
steps:
|
||||
- uses: ./../action/init
|
||||
id: init
|
||||
|
||||
@@ -20,13 +20,14 @@ env:
|
||||
installGo: true
|
||||
installDotNet: true
|
||||
steps:
|
||||
- name: Install Python 3.13 for older CLI versions
|
||||
# We need Python 3.13 for older CLI versions because they are not compatible with Python 3.14 or newer.
|
||||
- name: Install Python 3.13.15 for older CLI versions
|
||||
# Older CLI versions don't work with Python 3.13.16 or newer because their Python extractor
|
||||
# imports `importlib._bootstrap._ERR_MSG`, which those Python versions no longer define.
|
||||
# See https://github.com/github/codeql-action/pull/3212
|
||||
if: matrix.version != 'nightly-latest' && matrix.version != 'linked'
|
||||
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||
with:
|
||||
python-version: "3.13"
|
||||
python-version: "3.13.15"
|
||||
|
||||
- name: Use Xcode 16
|
||||
# Only the older CodeQL CLI versions need Xcode 16, and these run on macOS 15.
|
||||
|
||||
@@ -5,7 +5,7 @@ versions:
|
||||
- default
|
||||
steps:
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@984c0c890880bbf811283d6f09c4607c62d210a4 # v1.323.0
|
||||
uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 # v1.327.0
|
||||
with:
|
||||
ruby-version: 2.6
|
||||
- name: Install Code Scanning integration
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
// For backwards-compatibility.
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
/** The oldest supported major version of the CodeQL Action. */
|
||||
export const OLDEST_SUPPORTED_MAJOR_VERSION = 3;
|
||||
|
||||
@@ -5,6 +5,8 @@ contains:
|
||||
- "test-setup-python-scripts"
|
||||
- "update"
|
||||
- "Update"
|
||||
# Matrix-ed job; the name starts with this
|
||||
- "Create backport"
|
||||
is:
|
||||
- "Agent"
|
||||
- "check-expected-release-files"
|
||||
@@ -15,4 +17,6 @@ is:
|
||||
- "Label PR with size"
|
||||
- "Post repo size comment"
|
||||
- "Prepare"
|
||||
- "Release info"
|
||||
- "Upload results"
|
||||
- "Update release branch"
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"description": "Dependencies for codeql-action scripts",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@actions/core": "^2.0.3",
|
||||
"@actions/github": "^8.0.1",
|
||||
@@ -13,7 +14,7 @@
|
||||
"yaml": "^2.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.19.43",
|
||||
"tsx": "^4.23.13"
|
||||
"@types/node": "^24.19.0",
|
||||
"tsx": "^4.23.15"
|
||||
}
|
||||
}
|
||||
@@ -77,6 +77,6 @@ function main() {
|
||||
}
|
||||
|
||||
// Only call `main` if this script was run directly.
|
||||
if (require.main === module) {
|
||||
if (import.meta.main) {
|
||||
process.exit(main());
|
||||
}
|
||||
@@ -116,6 +116,6 @@ async function main() {
|
||||
}
|
||||
|
||||
// Only call `main` if this script was run directly.
|
||||
if (require.main === module) {
|
||||
if (import.meta.main) {
|
||||
void main();
|
||||
}
|
||||
@@ -79,6 +79,6 @@ function main() {
|
||||
}
|
||||
|
||||
// Only call `main` if this script was run directly.
|
||||
if (require.main === module) {
|
||||
if (import.meta.main) {
|
||||
process.exit(main());
|
||||
}
|
||||
@@ -21,10 +21,11 @@ import * as fs from "fs";
|
||||
import { parseArgs } from "node:util";
|
||||
import * as path from "path";
|
||||
|
||||
const THIS_DIR = __dirname;
|
||||
const CHECKS_DIR = path.join(THIS_DIR, "checks");
|
||||
const WORKFLOW_DIR = path.join(THIS_DIR, "..", ".github", "workflows");
|
||||
const SYNC_TS_PATH = path.join(THIS_DIR, "sync.ts");
|
||||
import { PR_CHECKS_DIR, REPO_ROOT } from "./config";
|
||||
|
||||
const CHECKS_DIR = path.join(PR_CHECKS_DIR, "checks");
|
||||
const WORKFLOW_DIR = path.join(REPO_ROOT, ".github", "workflows");
|
||||
const SYNC_TS_PATH = path.join(PR_CHECKS_DIR, "sync.ts");
|
||||
|
||||
/**
|
||||
* Scan generated workflow files to extract the latest action versions.
|
||||
@@ -232,6 +233,6 @@ function main(): number {
|
||||
}
|
||||
|
||||
// Only call `main` if this script was run directly.
|
||||
if (require.main === module) {
|
||||
if (import.meta.main) {
|
||||
process.exit(main());
|
||||
}
|
||||
@@ -342,6 +342,6 @@ async function main(): Promise<void> {
|
||||
}
|
||||
|
||||
// Only call `main` if this script was run directly.
|
||||
if (require.main === module) {
|
||||
if (import.meta.main) {
|
||||
void main();
|
||||
}
|
||||
+10
-3
@@ -7,6 +7,8 @@ import * as yaml from "yaml";
|
||||
|
||||
import { BuiltInLanguage } from "../src/languages";
|
||||
|
||||
import { PR_CHECKS_DIR, REPO_ROOT } from "./config";
|
||||
|
||||
/**
|
||||
* Returns a `uses` value for `action` pinned to a commit SHA, with the
|
||||
* human-readable version recorded in a trailing comment.
|
||||
@@ -221,6 +223,12 @@ const languageSetups: LanguageSetups = {
|
||||
cache: "npm",
|
||||
},
|
||||
},
|
||||
// Install a new enough version of `npm` to understand `min-release-age`
|
||||
// that is still compatible with Node 20.
|
||||
{
|
||||
name: "Install newer npm",
|
||||
run: "npm install -g npm@11.19.1",
|
||||
},
|
||||
{
|
||||
name: "Install dependencies",
|
||||
run: "npm ci",
|
||||
@@ -306,9 +314,8 @@ const languageSetups: LanguageSetups = {
|
||||
// See https://github.com/github/codeql-action/pull/3423
|
||||
const YQ_VERSION = "v4.50.1";
|
||||
|
||||
const THIS_DIR = __dirname;
|
||||
const CHECKS_DIR = path.join(THIS_DIR, "checks");
|
||||
const OUTPUT_DIR = path.join(THIS_DIR, "..", ".github", "workflows");
|
||||
const CHECKS_DIR = path.join(PR_CHECKS_DIR, "checks");
|
||||
const OUTPUT_DIR = path.join(REPO_ROOT, ".github", "workflows");
|
||||
|
||||
/**
|
||||
* Loads and parses a YAML file.
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
"sourceMap": false,
|
||||
"noEmit": true
|
||||
},
|
||||
"include": ["./**/*.ts", "./**/*.mts", "../src/**/*.ts"],
|
||||
"include": ["./**/*.ts", "../src/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
@@ -238,6 +238,6 @@ function main() {
|
||||
}
|
||||
|
||||
// Only call `main` if this script was run directly.
|
||||
if (require.main === module) {
|
||||
if (import.meta.main) {
|
||||
main();
|
||||
}
|
||||
@@ -835,6 +835,6 @@ async function main(): Promise<void> {
|
||||
}
|
||||
|
||||
// Only call `main` if this script was run directly.
|
||||
if (require.main === module) {
|
||||
if (import.meta.main) {
|
||||
void main();
|
||||
}
|
||||
@@ -23,7 +23,8 @@ predicate isSafeForDefaultSetup(string envVar) {
|
||||
"GITHUB_BASE_REF", "GITHUB_EVENT_NAME", "GITHUB_JOB", "GITHUB_RUN_ATTEMPT", "GITHUB_RUN_ID",
|
||||
"GITHUB_SHA", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "GITHUB_TOKEN", "GITHUB_WORKFLOW",
|
||||
"GITHUB_WORKSPACE", "GOFLAGS", "ImageVersion", "JAVA_TOOL_OPTIONS", "RUNNER_ARCH",
|
||||
"RUNNER_ENVIRONMENT", "RUNNER_NAME", "RUNNER_OS", "RUNNER_TEMP", "RUNNER_TOOL_CACHE"
|
||||
"RUNNER_ENVIRONMENT", "RUNNER_NAME", "RUNNER_OS", "RUNNER_TEMP", "RUNNER_TOOL_CACHE",
|
||||
"NODE_ENV"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
+7
-10
@@ -21,19 +21,16 @@ inputs:
|
||||
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`.
|
||||
A comma-separated list of CodeQL languages that the installed CodeQL CLI will be used to
|
||||
analyze. 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.
|
||||
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`.
|
||||
[Internal] A comma-separated list of analysis kinds that the installed CodeQL CLI will be used
|
||||
for. If specified, the Action may use this list to select a CodeQL CLI version that is best
|
||||
suited to those analysis kinds.
|
||||
|
||||
Available options are the same as for the `analysis-kinds` input on the `init` Action.
|
||||
default: 'code-scanning'
|
||||
|
||||
+76
-1
@@ -19,6 +19,10 @@ export interface BaseState {
|
||||
name: ActionName;
|
||||
/** When the Action was started. */
|
||||
startedAt: Date;
|
||||
/** The platform the Action is running on. */
|
||||
platform: NodeJS.Platform;
|
||||
/** The architecture of the host. */
|
||||
arch: NodeJS.Architecture;
|
||||
}
|
||||
|
||||
/** Describes different state features that an Action may have. */
|
||||
@@ -52,6 +56,29 @@ export interface FeatureState {
|
||||
/** Identifies a type of state an Action may have. */
|
||||
export type StateFeature = keyof FeatureState;
|
||||
|
||||
/**
|
||||
* The `Env` feature implies the availability of the `ReadOnlyEnv` feature.
|
||||
*
|
||||
* If `T` is `Env`, this returns `Env | ReadOnlyEnv`.
|
||||
* Otherwise, it is the identity and returns T.
|
||||
*/
|
||||
type ImpliedFeatures<T extends StateFeature> = T extends "Env"
|
||||
? "Env" | "ReadOnlyEnv"
|
||||
: T;
|
||||
|
||||
/**
|
||||
* Given an object type `Obj`, this tries to lookup a corresponding `StateFeature`
|
||||
* to which the object type belongs in `FeatureState`. Resolves to `never` if there
|
||||
* is no match.
|
||||
*/
|
||||
type FeatureNameFor<Obj extends object> = {
|
||||
[K in StateFeature]: [Obj] extends [FeatureState[K]]
|
||||
? [FeatureState[K]] extends [Obj]
|
||||
? K
|
||||
: never
|
||||
: never;
|
||||
}[StateFeature];
|
||||
|
||||
/** Constructs the intersection of all state types identifies by `Fs`. */
|
||||
export type FieldsOf<Fs extends readonly StateFeature[]> = Fs extends []
|
||||
? Record<never, never>
|
||||
@@ -62,8 +89,54 @@ export type FieldsOf<Fs extends readonly StateFeature[]> = Fs extends []
|
||||
? FeatureState[Head] & FieldsOf<Tail>
|
||||
: never;
|
||||
|
||||
/**
|
||||
* Symbol used for a field in `ActionState` that carries the type array of state features.
|
||||
* This is a Symbol so that it doesn't clash with any property names we might want to have.
|
||||
*/
|
||||
const stateFeatures = Symbol();
|
||||
|
||||
/** Describes the state of an Action that has access to the state corresponding to `Fs`. */
|
||||
export type ActionState<Fs extends readonly StateFeature[]> = FieldsOf<Fs>;
|
||||
export type ActionState<Fs extends readonly StateFeature[]> = FieldsOf<Fs> & {
|
||||
/**
|
||||
* When given a chance, TypeScript will simplify an `ActionState<Fs>` type as much as possible,
|
||||
* which results in a concrete object type that doesn't mention `Fs`.
|
||||
*
|
||||
* That causes problems for functions which accept `ActionState<Fs>` values, but need to know the
|
||||
* feature keys `Fs`. This property here explicitly captures `Fs` in the concrete object type
|
||||
* that results from simplifying `ActionState<Fs>`.
|
||||
*
|
||||
* This is a function rather than a field, because we want to be able to provide values of type
|
||||
* `ActionState<Fs>` to functions expecting `ActionState<As>` where `As` is a subset of `Fs`.
|
||||
*
|
||||
* Since function types are contravariant in the types of their parameters, using a function
|
||||
* type here allows that to happen.
|
||||
*
|
||||
* Because the field is optional, we don't have to explicitly provide a value
|
||||
* for it anywhere while the type is still inferred.
|
||||
*
|
||||
* `Fs[number]` returns the union of all features in `Fs`. We wrap it in `ImpliedFeatures`
|
||||
* so that `Env` is expanded into `Env | ReadOnlyEnv`, allowing functions that expect the
|
||||
* `ReadOnlyEnv` feature to be provided with an `ActionState` that has the `Env` feature
|
||||
* without requiring this to be made explicit.
|
||||
*/
|
||||
readonly [stateFeatures]?: (ts: ImpliedFeatures<Fs[number]>) => void;
|
||||
};
|
||||
|
||||
/** Extends `state` with an `extra` feature. */
|
||||
export function extendActionState<
|
||||
// In first position, so that it can be explicitly provided if `FeatureNameFor`
|
||||
// should not work on `extra`.
|
||||
F extends StateFeature,
|
||||
Fs extends readonly StateFeature[],
|
||||
E extends FeatureState[F],
|
||||
>(
|
||||
state: ActionState<Fs>,
|
||||
extra: E,
|
||||
): ActionState<[...Fs, FeatureNameFor<E> & F]> {
|
||||
return { ...state, ...extra } as unknown as ActionState<
|
||||
[...Fs, FeatureNameFor<E> & F]
|
||||
>;
|
||||
}
|
||||
|
||||
/** The type of an Action's main entry point. This is a function that is provided
|
||||
* with a basic `ActionState` object with features that are always available.
|
||||
@@ -98,6 +171,8 @@ export async function runInActions(action: Action) {
|
||||
const actionState = {
|
||||
name: action.name,
|
||||
startedAt,
|
||||
platform: process.platform,
|
||||
arch: process.arch,
|
||||
logger,
|
||||
env,
|
||||
actions: actionsEnv,
|
||||
|
||||
+16
-8
@@ -14,6 +14,7 @@ import {
|
||||
getCodeQLDatabasePath,
|
||||
ConfigurationError,
|
||||
getEnv,
|
||||
getErrorMessage,
|
||||
} from "./util";
|
||||
|
||||
/**
|
||||
@@ -29,7 +30,6 @@ declare const __CODEQL_ACTION_VERSION__: string;
|
||||
export interface ActionsEnv {
|
||||
getRequiredInput: (name: string) => string;
|
||||
getOptionalInput: (name: string) => string | undefined;
|
||||
exportVariable: (name: string, value: string) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,6 @@ export function getActionsEnv(): ActionsEnv {
|
||||
return {
|
||||
getRequiredInput,
|
||||
getOptionalInput,
|
||||
exportVariable: core.exportVariable,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -412,14 +411,23 @@ export const persistInputs = function (env: Env = getEnv()) {
|
||||
/**
|
||||
* Restores all inputs to the action from the persisted state.
|
||||
*/
|
||||
export const restoreInputs = function () {
|
||||
const persistedInputs = core.getState(persistedInputsKey);
|
||||
if (persistedInputs) {
|
||||
for (const [name, value] of JSON.parse(persistedInputs)) {
|
||||
process.env[name] = value;
|
||||
export function restoreInputs(logger: Logger) {
|
||||
try {
|
||||
const persistedInputsValue = core.getState(persistedInputsKey);
|
||||
if (persistedInputsValue) {
|
||||
const persistedInputs = JSON.parse(persistedInputsValue);
|
||||
|
||||
for (const [name, value] of persistedInputs) {
|
||||
process.env[name] = value;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error(`Unable to restore inputs: ${getErrorMessage(err)}`);
|
||||
throw new Error(
|
||||
"Failed to restore inputs from the state set by this action's main execution.",
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export interface PullRequestBranches {
|
||||
base: string;
|
||||
|
||||
@@ -25,8 +25,8 @@ export async function runWrapper() {
|
||||
// possible, and only use safe functions outside.
|
||||
|
||||
try {
|
||||
actionsUtil.restoreInputs();
|
||||
const logger = getActionsLogger();
|
||||
actionsUtil.restoreInputs(logger);
|
||||
const gitHubVersion = await getGitHubVersion();
|
||||
checkGitHubVersionInRange(gitHubVersion, logger);
|
||||
|
||||
|
||||
@@ -214,9 +214,10 @@ async function runAutobuildIfLegacyGoWorkflow(config: Config, logger: Logger) {
|
||||
|
||||
async function run({
|
||||
startedAt,
|
||||
env,
|
||||
logger,
|
||||
actions,
|
||||
}: ActionState<["Base", "Logger", "Actions"]>) {
|
||||
}: ActionState<["Base", "Env", "Logger", "Actions"]>) {
|
||||
// To capture errors appropriately, keep as much code within the try-catch as
|
||||
// possible, and only use safe functions outside.
|
||||
|
||||
@@ -287,7 +288,7 @@ async function run({
|
||||
|
||||
const apiDetails = getApiDetails();
|
||||
const outputDir = actionsUtil.getRequiredInput("output");
|
||||
core.exportVariable(EnvVar.SARIF_RESULTS_OUTPUT_DIR, outputDir);
|
||||
env.export(EnvVar.SARIF_RESULTS_OUTPUT_DIR, outputDir);
|
||||
const threads = util.getThreadsFlag(
|
||||
actionsUtil.getOptionalInput("threads") || process.env["CODEQL_THREADS"],
|
||||
logger,
|
||||
@@ -456,7 +457,7 @@ async function run({
|
||||
`expect-error input was set to true but no error was thrown.`,
|
||||
);
|
||||
}
|
||||
core.exportVariable(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY, "true");
|
||||
env.export(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY, "true");
|
||||
} catch (unwrappedError) {
|
||||
const error = util.wrapError(unwrappedError);
|
||||
if (
|
||||
|
||||
+1
-1
@@ -7,12 +7,12 @@ import * as sinon from "sinon";
|
||||
import { CodeQuality, CodeScanning, RiskAssessment } from "./analyses";
|
||||
import {
|
||||
runQueries,
|
||||
defaultSuites,
|
||||
resolveQuerySuiteAlias,
|
||||
addSarifExtension,
|
||||
diffRangeExtensionPackContents,
|
||||
} from "./analyze";
|
||||
import { createStubCodeQL } from "./codeql";
|
||||
import { defaultSuites } from "./config/db-config";
|
||||
import { Feature } from "./feature-flags";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
|
||||
+1
-9
@@ -9,6 +9,7 @@ import { getTemporaryDirectory } from "./actions-util";
|
||||
import * as analyses from "./analyses";
|
||||
import { setupCppAutobuild } from "./autobuild";
|
||||
import { type CodeQL } from "./codeql";
|
||||
import { defaultSuites } from "./config/db-config";
|
||||
import * as configUtils from "./config-utils";
|
||||
import {
|
||||
getCsharpTempDependencyDir,
|
||||
@@ -357,15 +358,6 @@ dataExtensions:
|
||||
return diffRangeDir;
|
||||
}
|
||||
|
||||
// A set of default query suite names that are understood by the CLI.
|
||||
export const defaultSuites: Set<string> = new Set([
|
||||
"security-experimental",
|
||||
"security-extended",
|
||||
"security-and-quality",
|
||||
"code-quality",
|
||||
"code-scanning",
|
||||
]);
|
||||
|
||||
/**
|
||||
* If `maybeSuite` is the name of a default query suite, it is resolved into the corresponding
|
||||
* query suite name for the given `language`. Otherwise, `maybeSuite` is returned as is.
|
||||
|
||||
+99
-87
@@ -111,103 +111,115 @@ test.serial("getGitHubVersion for GHEC-DR", async (t) => {
|
||||
t.deepEqual({ type: util.GitHubVariant.GHEC_DR }, gheDotcom);
|
||||
});
|
||||
|
||||
test.serial(
|
||||
"wrapApiConfigurationError correctly wraps specific configuration errors",
|
||||
(t) => {
|
||||
test("wrapApiConfigurationError doesn't wrap errors it isn't supposed to", (t) => {
|
||||
const unwrappedErrors = [
|
||||
// We don't reclassify arbitrary errors
|
||||
const arbitraryError = new Error("arbitrary error");
|
||||
let res = api.wrapApiConfigurationError(arbitraryError);
|
||||
t.is(res, arbitraryError);
|
||||
new Error("arbitrary error"),
|
||||
// Same goes for arbitrary strings
|
||||
"arbitrary error",
|
||||
// If an HTTP error doesn't contain a specific error message, we don't wrap it.
|
||||
new util.HTTPError("arbitrary HTTP error", 456),
|
||||
];
|
||||
|
||||
// Same goes for arbitrary errors
|
||||
const configError = new util.ConfigurationError("arbitrary error");
|
||||
res = api.wrapApiConfigurationError(configError);
|
||||
t.is(res, configError);
|
||||
|
||||
// If an HTTP error doesn't contain a specific error message, we don't
|
||||
// wrap is an an API error.
|
||||
const httpError = new util.HTTPError("arbitrary HTTP error", 456);
|
||||
res = api.wrapApiConfigurationError(httpError);
|
||||
t.is(res, httpError);
|
||||
|
||||
// For other HTTP errors, we wrap them as Configuration errors if they contain
|
||||
// specific error messages.
|
||||
const httpNotFoundError = new util.HTTPError("commit not found", 404);
|
||||
res = api.wrapApiConfigurationError(httpNotFoundError);
|
||||
t.deepEqual(res, new util.ConfigurationError("commit not found"));
|
||||
|
||||
const refNotFoundError = new util.HTTPError(
|
||||
"ref 'refs/heads/jitsi' not found in this repository - https://docs.github.com/rest",
|
||||
404,
|
||||
);
|
||||
res = api.wrapApiConfigurationError(refNotFoundError);
|
||||
t.deepEqual(
|
||||
for (const unwrappedError of unwrappedErrors) {
|
||||
const res = api.wrapApiConfigurationError(unwrappedError);
|
||||
t.is(
|
||||
res,
|
||||
new util.ConfigurationError(
|
||||
"ref 'refs/heads/jitsi' not found in this repository - https://docs.github.com/rest",
|
||||
),
|
||||
unwrappedError,
|
||||
`${util.getErrorMessage(unwrappedError)} should not be wrapped by wrapApiConfigurationError`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const apiRateLimitError = new util.HTTPError(
|
||||
"API rate limit exceeded for installation",
|
||||
403,
|
||||
);
|
||||
res = api.wrapApiConfigurationError(apiRateLimitError);
|
||||
t.deepEqual(
|
||||
res,
|
||||
new util.ConfigurationError("API rate limit exceeded for installation"),
|
||||
);
|
||||
test("wrapApiConfigurationError correctly wraps specific configuration errors", (t) => {
|
||||
// For other HTTP errors, we wrap them as Configuration errors if they contain
|
||||
// specific error messages.
|
||||
const httpNotFoundError = new util.HTTPError("commit not found", 404);
|
||||
const refNotFoundError = new util.HTTPError(
|
||||
"ref 'refs/heads/jitsi' not found in this repository - https://docs.github.com/rest",
|
||||
404,
|
||||
);
|
||||
const apiRateLimitError = new util.HTTPError(
|
||||
"API rate limit exceeded for installation",
|
||||
403,
|
||||
);
|
||||
const resourceNotAccessibleError = new util.HTTPError(
|
||||
"Resource not accessible by integration",
|
||||
403,
|
||||
);
|
||||
const errorsToWrap = [
|
||||
httpNotFoundError,
|
||||
refNotFoundError,
|
||||
apiRateLimitError,
|
||||
resourceNotAccessibleError,
|
||||
];
|
||||
|
||||
const tokenSuggestionMessage =
|
||||
"Please check that your token is valid and has the required permissions: contents: read, security-events: write";
|
||||
const badCredentialsError = new util.HTTPError("Bad credentials", 401);
|
||||
res = api.wrapApiConfigurationError(badCredentialsError);
|
||||
for (const errorToWrap of errorsToWrap) {
|
||||
const res = api.wrapApiConfigurationError(errorToWrap);
|
||||
t.deepEqual(res, new util.ConfigurationError(errorToWrap.message));
|
||||
}
|
||||
});
|
||||
|
||||
test("wrapApiConfigurationError wraps token errors", async (t) => {
|
||||
const tokenSuggestionMessage =
|
||||
"Please check that your token is valid and has the required permissions: contents: read, security-events: write";
|
||||
const badCredentialsError = new util.HTTPError("Bad credentials", 401);
|
||||
const notFoundError = new util.HTTPError("Not Found", 404);
|
||||
const errorsToWrap = [badCredentialsError, notFoundError];
|
||||
|
||||
for (const errorToWrap of errorsToWrap) {
|
||||
const res = api.wrapApiConfigurationError(errorToWrap);
|
||||
t.deepEqual(res, new util.ConfigurationError(tokenSuggestionMessage));
|
||||
}
|
||||
});
|
||||
|
||||
const notFoundError = new util.HTTPError("Not Found", 404);
|
||||
res = api.wrapApiConfigurationError(notFoundError);
|
||||
t.deepEqual(res, new util.ConfigurationError(tokenSuggestionMessage));
|
||||
test("wrapApiConfigurationError wraps enablement errors", async (t) => {
|
||||
// Enablement errors.
|
||||
const enablementErrorMessages = [
|
||||
"Code Security must be enabled for this repository to use code scanning",
|
||||
"Advanced Security must be enabled for this repository to use code scanning",
|
||||
"Code Scanning is not enabled for this repository. Please enable code scanning in the repository settings.",
|
||||
"Code quality is not enabled for this repository. Please enable code quality in the repository settings.",
|
||||
];
|
||||
const transforms = [
|
||||
(msg: string) => msg,
|
||||
(msg: string) => msg.toLowerCase(),
|
||||
(msg: string) => msg.toLocaleUpperCase(),
|
||||
];
|
||||
|
||||
const resourceNotAccessibleError = new util.HTTPError(
|
||||
"Resource not accessible by integration",
|
||||
403,
|
||||
);
|
||||
res = api.wrapApiConfigurationError(resourceNotAccessibleError);
|
||||
t.deepEqual(
|
||||
res,
|
||||
new util.ConfigurationError("Resource not accessible by integration"),
|
||||
);
|
||||
|
||||
// Enablement errors.
|
||||
const enablementErrorMessages = [
|
||||
"Code Security must be enabled for this repository to use code scanning",
|
||||
"Advanced Security must be enabled for this repository to use code scanning",
|
||||
"Code Scanning is not enabled for this repository. Please enable code scanning in the repository settings.",
|
||||
"Code quality is not enabled for this repository. Please enable code quality in the repository settings.",
|
||||
];
|
||||
const transforms = [
|
||||
(msg: string) => msg,
|
||||
(msg: string) => msg.toLowerCase(),
|
||||
(msg: string) => msg.toLocaleUpperCase(),
|
||||
];
|
||||
|
||||
for (const enablementErrorMessage of enablementErrorMessages) {
|
||||
for (const transform of transforms) {
|
||||
const enablementError = new util.HTTPError(
|
||||
transform(enablementErrorMessage),
|
||||
403,
|
||||
);
|
||||
res = api.wrapApiConfigurationError(enablementError);
|
||||
t.deepEqual(
|
||||
res,
|
||||
new util.ConfigurationError(
|
||||
api.getFeatureEnablementError(enablementError.message),
|
||||
),
|
||||
);
|
||||
}
|
||||
for (const enablementErrorMessage of enablementErrorMessages) {
|
||||
for (const transform of transforms) {
|
||||
const enablementError = new util.HTTPError(
|
||||
transform(enablementErrorMessage),
|
||||
403,
|
||||
);
|
||||
const res = api.wrapApiConfigurationError(enablementError);
|
||||
t.deepEqual(
|
||||
res,
|
||||
new util.ConfigurationError(
|
||||
api.getFeatureEnablementError(enablementError.message),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("wrapApiConfigurationError doesn't double-wrap errors", async (t) => {
|
||||
// This test checks that errors don't get wrapped a second time if `wrapApiConfigurationError`
|
||||
// is called on an error that was already wrapped by a previous call to `wrapApiConfigurationError`.
|
||||
// Start by calling `wrapApiConfigurationError` on an unwrapped error that should be wrapped:
|
||||
const unwrappedError = new util.HTTPError("commit not found", 404);
|
||||
const wrappedError = api.wrapApiConfigurationError(unwrappedError);
|
||||
|
||||
// Sanity-check that it was wrapped, as expected.
|
||||
t.deepEqual(
|
||||
wrappedError,
|
||||
new util.ConfigurationError(unwrappedError.message),
|
||||
);
|
||||
|
||||
// The result of the second call should be exactly `wrappedError`:
|
||||
t.is(api.wrapApiConfigurationError(wrappedError), wrappedError);
|
||||
});
|
||||
|
||||
test("getRegistryProxy - returns undefined if the proxy is not configured", async (t) => {
|
||||
const target = callee(api.getRegistryProxy).withArgs();
|
||||
|
||||
+36
-21
@@ -17,6 +17,7 @@ import {
|
||||
ReadOnlyEnv,
|
||||
RegistryProxyVars,
|
||||
getEnv,
|
||||
exportEnvVar,
|
||||
} from "./environment";
|
||||
import { Logger } from "./logging";
|
||||
import { getRepositoryNwo, RepositoryNwo } from "./repository";
|
||||
@@ -219,25 +220,31 @@ export async function getGitHubVersionFromApi(
|
||||
return { type: GitHubVariant.DOTCOM };
|
||||
}
|
||||
|
||||
// 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();
|
||||
try {
|
||||
// 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();
|
||||
|
||||
// This happens on dotcom, although we expect to have already returned in that
|
||||
// case. This can also serve as a fallback in cases we haven't foreseen.
|
||||
if (response.headers[GITHUB_ENTERPRISE_VERSION_HEADER] === undefined) {
|
||||
return { type: GitHubVariant.DOTCOM };
|
||||
// This happens on dotcom, although we expect to have already returned in that
|
||||
// case. This can also serve as a fallback in cases we haven't foreseen.
|
||||
if (response.headers[GITHUB_ENTERPRISE_VERSION_HEADER] === undefined) {
|
||||
return { type: GitHubVariant.DOTCOM };
|
||||
}
|
||||
|
||||
if (response.headers[GITHUB_ENTERPRISE_VERSION_HEADER] === "ghe.com") {
|
||||
return { type: GitHubVariant.GHEC_DR };
|
||||
}
|
||||
|
||||
const version = response.headers[
|
||||
GITHUB_ENTERPRISE_VERSION_HEADER
|
||||
] as string;
|
||||
return { type: GitHubVariant.GHES, version };
|
||||
} catch (err) {
|
||||
throw wrapApiConfigurationError(err);
|
||||
}
|
||||
|
||||
if (response.headers[GITHUB_ENTERPRISE_VERSION_HEADER] === "ghe.com") {
|
||||
return { type: GitHubVariant.GHEC_DR };
|
||||
}
|
||||
|
||||
const version = response.headers[GITHUB_ENTERPRISE_VERSION_HEADER] as string;
|
||||
return { type: GitHubVariant.GHES, version };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -249,9 +256,10 @@ export async function getGitHubVersionFromApi(
|
||||
*/
|
||||
export async function getGitHubVersion(): Promise<GitHubVersion> {
|
||||
if (cachedGitHubVersion === undefined) {
|
||||
const apiDetails = getApiDetails();
|
||||
cachedGitHubVersion = await getGitHubVersionFromApi(
|
||||
getApiClient(),
|
||||
getApiDetails(),
|
||||
createApiClientWithDetails(apiDetails),
|
||||
apiDetails,
|
||||
);
|
||||
}
|
||||
return cachedGitHubVersion;
|
||||
@@ -309,7 +317,7 @@ export async function getAnalysisKey(): Promise<string> {
|
||||
const jobName = getRequiredEnvParam("GITHUB_JOB");
|
||||
|
||||
analysisKey = `${workflowPath}:${jobName}`;
|
||||
core.exportVariable(EnvVar.ANALYSIS_KEY, analysisKey);
|
||||
exportEnvVar(EnvVar.ANALYSIS_KEY, analysisKey);
|
||||
return analysisKey;
|
||||
}
|
||||
|
||||
@@ -414,7 +422,14 @@ export function getFeatureEnablementError(message: string): string {
|
||||
return `Please verify that the necessary features are enabled: ${message}`;
|
||||
}
|
||||
|
||||
export function wrapApiConfigurationError(e: unknown) {
|
||||
/**
|
||||
* Decides whether `e` is a known error returned by the GitHub API that we should
|
||||
* classify as a `ConfigurationError`.
|
||||
*
|
||||
* @param e The error to classify.
|
||||
* @returns Either `e` or a corresponding `ConfigurationError`.
|
||||
*/
|
||||
export function wrapApiConfigurationError<T>(e: T): T | ConfigurationError {
|
||||
const httpError = asHTTPError(e);
|
||||
if (httpError !== undefined) {
|
||||
if (
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"maximumVersion":"3.23","minimumVersion":"3.17"}
|
||||
{"maximumVersion":"3.23","minimumVersion":"3.18"}
|
||||
@@ -68,7 +68,11 @@ async function sendCompletedStatusReport(
|
||||
}
|
||||
}
|
||||
|
||||
async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) {
|
||||
async function run({
|
||||
startedAt,
|
||||
env,
|
||||
logger,
|
||||
}: ActionState<["Base", "Env", "Logger"]>) {
|
||||
// To capture errors appropriately, keep as much code within the try-catch as
|
||||
// possible, and only use safe functions outside.
|
||||
|
||||
@@ -135,7 +139,7 @@ async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) {
|
||||
return;
|
||||
}
|
||||
|
||||
core.exportVariable(EnvVar.AUTOBUILD_DID_COMPLETE_SUCCESSFULLY, "true");
|
||||
env.export(EnvVar.AUTOBUILD_DID_COMPLETE_SUCCESSFULLY, "true");
|
||||
|
||||
await sendCompletedStatusReport(config, logger, startedAt, languages ?? []);
|
||||
}
|
||||
|
||||
+5
-7
@@ -1,11 +1,9 @@
|
||||
import * as core from "@actions/core";
|
||||
|
||||
import { getTemporaryDirectory, getWorkflowEventName } from "./actions-util";
|
||||
import { getGitHubVersion } from "./api-client";
|
||||
import { CodeQL, getCodeQL } from "./codeql";
|
||||
import * as configUtils from "./config-utils";
|
||||
import { DocUrl } from "./doc-url";
|
||||
import { ActionsEnvVars, EnvVar } from "./environment";
|
||||
import { ActionsEnvVars, EnvVar, exportEnvVar } from "./environment";
|
||||
import { Feature, featureConfig, initFeatures } from "./feature-flags";
|
||||
import { BuiltInLanguage, Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
@@ -136,16 +134,16 @@ export async function setupCppAutobuild(codeql: CodeQL, logger: Logger) {
|
||||
: ""
|
||||
}`,
|
||||
);
|
||||
core.exportVariable(envVar, "false");
|
||||
exportEnvVar(envVar, "false");
|
||||
} else {
|
||||
logger.info(
|
||||
`Enabling ${featureName}. This can be disabled by setting the ${envVar} environment variable to 'false'. See ${DocUrl.DEFINE_ENV_VARIABLES} for more information.`,
|
||||
);
|
||||
core.exportVariable(envVar, "true");
|
||||
exportEnvVar(envVar, "true");
|
||||
}
|
||||
} else {
|
||||
logger.info(`Disabling ${featureName}.`);
|
||||
core.exportVariable(envVar, "false");
|
||||
exportEnvVar(envVar, "false");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +163,7 @@ export async function runAutobuild(
|
||||
await codeQL.runAutobuild(config, language);
|
||||
}
|
||||
if (language === BuiltInLanguage.go) {
|
||||
core.exportVariable(EnvVar.DID_AUTOBUILD_GOLANG, "true");
|
||||
exportEnvVar(EnvVar.DID_AUTOBUILD_GOLANG, "true");
|
||||
}
|
||||
logger.endGroup();
|
||||
}
|
||||
@@ -1,7 +1,26 @@
|
||||
import test from "ava";
|
||||
|
||||
import { getCodeQLBundleFromUrl } from "./codeql-bundle";
|
||||
import { getCodeQLBundleFromUrl, getCodeQLBundleName } from "./codeql-bundle";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import { BundlePlatform } from "./platform";
|
||||
|
||||
test("getCodeQLBundleName returns a per-language bundle name only when a language is specified", (t) => {
|
||||
t.is(
|
||||
getCodeQLBundleName("zstd", BundlePlatform.Linux64, BuiltInLanguage.java),
|
||||
"codeql-bundle-java-linux64.tar.zst",
|
||||
);
|
||||
t.is(
|
||||
getCodeQLBundleName("zstd", BundlePlatform.Linux64),
|
||||
"codeql-bundle-linux64.tar.zst",
|
||||
);
|
||||
});
|
||||
|
||||
test("getCodeQLBundleName names the Swift bundle for macOS", (t) => {
|
||||
t.is(
|
||||
getCodeQLBundleName("zstd", BundlePlatform.Osx64, BuiltInLanguage.swift),
|
||||
"codeql-bundle-swift-osx64.tar.zst",
|
||||
);
|
||||
});
|
||||
|
||||
for (const [assetName, language] of [
|
||||
["codeql-bundle-java-linux64.tar.zst", BuiltInLanguage.java],
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { BuiltInLanguage, parseBuiltInLanguage } from "./languages";
|
||||
import { BundlePlatform } from "./platform";
|
||||
import type { CompressionMethod } from "./tar";
|
||||
|
||||
/** Describes the contents and location of a downloadable CodeQL bundle. */
|
||||
export type CodeQLBundle =
|
||||
@@ -11,6 +13,42 @@ export type CodeQLBundle =
|
||||
combinedBundleURL?: string;
|
||||
};
|
||||
|
||||
/** A resolved download, including its bundle identity and version. */
|
||||
export interface CodeQLDownloadSource {
|
||||
/** Distinguishes downloads from local archives and cached installations. */
|
||||
sourceType: "download";
|
||||
/** The bundle to download. */
|
||||
bundle: CodeQLBundle;
|
||||
/** The compression format of the bundle archive. */
|
||||
compressionMethod: CompressionMethod;
|
||||
/** Bundle version of the tools, if known. */
|
||||
bundleVersion?: string;
|
||||
/** Requested CLI version, if known. */
|
||||
cliVersion?: string;
|
||||
/** Resolved version for telemetry, independent of whether the bundle can be cached. */
|
||||
toolsVersion: string;
|
||||
}
|
||||
|
||||
/** Returns the exact bundle asset name for a platform and optional language. */
|
||||
export function getCodeQLBundleName(
|
||||
compressionMethod: CompressionMethod,
|
||||
platform: BundlePlatform | undefined,
|
||||
language?: BuiltInLanguage,
|
||||
): string {
|
||||
const extensions: Record<CompressionMethod, string> = {
|
||||
gzip: ".tar.gz",
|
||||
zstd: ".tar.zst",
|
||||
};
|
||||
const extension = extensions[compressionMethod];
|
||||
if (platform === undefined) {
|
||||
return `codeql-bundle${extension}`;
|
||||
}
|
||||
if (language !== undefined) {
|
||||
return `codeql-bundle-${language}-${platform}${extension}`;
|
||||
}
|
||||
return `codeql-bundle-${platform}${extension}`;
|
||||
}
|
||||
|
||||
const PER_LANGUAGE_BUNDLE_NAME =
|
||||
/^codeql-bundle-(.+)-(?:linux64|osx64|win64)\.tar\.(?:gz|zst)$/;
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ async function installIntoToolcache({
|
||||
? { enabledVersions: [{ cliVersion, tagName }] }
|
||||
: SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
createFeatures([]),
|
||||
getRunnerLogger(true),
|
||||
@@ -172,6 +173,7 @@ test.serial(
|
||||
util.GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
@@ -207,6 +209,7 @@ test.serial(
|
||||
util.GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
@@ -246,6 +249,7 @@ test.serial(
|
||||
util.GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
@@ -355,6 +359,7 @@ for (const {
|
||||
util.GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
@@ -397,6 +402,7 @@ for (const toolcacheVersion of [
|
||||
util.GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
@@ -441,6 +447,7 @@ test.serial(
|
||||
],
|
||||
},
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
@@ -487,6 +494,7 @@ test.serial(
|
||||
],
|
||||
},
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
@@ -526,6 +534,7 @@ test.serial(
|
||||
util.GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
@@ -567,6 +576,7 @@ test.serial(
|
||||
util.GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
|
||||
+17
-6
@@ -17,7 +17,7 @@ import type { VersionInfo } from "./cli/types";
|
||||
import { CliError, wrapCliConfigurationError } from "./cli-errors";
|
||||
import { appendExtraQueryExclusions, type Config } from "./config-utils";
|
||||
import { DocUrl } from "./doc-url";
|
||||
import { EnvVar, getEnv } from "./environment";
|
||||
import { EnvVar, getEnv, exportEnvVar } from "./environment";
|
||||
import {
|
||||
CodeQLDefaultVersionInfo,
|
||||
Feature,
|
||||
@@ -258,17 +258,17 @@ 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.20.7";
|
||||
const CODEQL_NEXT_MINIMUM_VERSION = "2.21.3";
|
||||
|
||||
/**
|
||||
* This is the version of GHES that was most recently deprecated.
|
||||
*/
|
||||
const GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.16";
|
||||
const GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.17";
|
||||
|
||||
/**
|
||||
* This is the deprecation date for the version of GHES that was most recently deprecated.
|
||||
*/
|
||||
const GHES_MOST_RECENT_DEPRECATION_DATE = "2026-07-01";
|
||||
const GHES_MOST_RECENT_DEPRECATION_DATE = "2026-09-24";
|
||||
|
||||
/** The CLI verbosity level to use for extraction in debug mode. */
|
||||
const EXTRACTION_DEBUG_MODE_VERBOSITY = "progress++";
|
||||
@@ -302,6 +302,9 @@ export function isDiskConfigurationError(e: unknown): boolean {
|
||||
* @param variant
|
||||
* @param defaultCliVersion
|
||||
* @param rawLanguages Raw set of languages.
|
||||
* @param otherLanguagePacksReason Why the CodeQL CLI may need packs for languages other than
|
||||
* `rawLanguages`, or `undefined` if it won't. If defined, the combined bundle is used. See
|
||||
* `PerLanguageBundleOptions.otherLanguagePacksReason`.
|
||||
* @param useOverlayAwareDefaultCliVersion Whether to select an overlay-aware default CLI version.
|
||||
* @param features Information about the features that are enabled.
|
||||
* @param logger
|
||||
@@ -316,6 +319,7 @@ export async function setupCodeQL(
|
||||
variant: util.GitHubVariant,
|
||||
defaultCliVersion: CodeQLDefaultVersionInfo,
|
||||
rawLanguages: string[] | undefined,
|
||||
otherLanguagePacksReason: string | undefined,
|
||||
useOverlayAwareDefaultCliVersion: boolean,
|
||||
features: FeatureEnablement,
|
||||
logger: Logger,
|
||||
@@ -339,6 +343,7 @@ export async function setupCodeQL(
|
||||
variant,
|
||||
defaultCliVersion,
|
||||
rawLanguages,
|
||||
otherLanguagePacksReason,
|
||||
useOverlayAwareDefaultCliVersion,
|
||||
features,
|
||||
logger,
|
||||
@@ -952,7 +957,13 @@ async function getCodeQLForCmd(
|
||||
},
|
||||
},
|
||||
).exec();
|
||||
return JSON.parse(extractorPath) as string;
|
||||
try {
|
||||
return JSON.parse(extractorPath) as string;
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Failed to parse extractor path for '${language}' from CLI: ${getErrorMessage(err)}\nOutput was: ${extractorPath}`,
|
||||
);
|
||||
}
|
||||
},
|
||||
async resolveQueriesStartingPacks(queries: string[]): Promise<string[]> {
|
||||
const codeqlArgs = [
|
||||
@@ -1043,7 +1054,7 @@ async function getCodeQLForCmd(
|
||||
}' by 'github/codeql-action/*@v${getActionVersion()}' in your code scanning workflow to ` +
|
||||
"continue using this version of the CodeQL Action.",
|
||||
);
|
||||
core.exportVariable(EnvVar.SUPPRESS_DEPRECATED_SOON_WARNING, "true");
|
||||
exportEnvVar(EnvVar.SUPPRESS_DEPRECATED_SOON_WARNING, "true");
|
||||
}
|
||||
return codeql;
|
||||
}
|
||||
|
||||
+59
-33
@@ -473,6 +473,12 @@ const simpleConfigFileContents = `
|
||||
queries:
|
||||
- uses: ./foo_file`;
|
||||
|
||||
/** The configuration in `simpleConfigFileContents`. */
|
||||
const simpleConfigInput: UserConfig = {
|
||||
name: "my config",
|
||||
queries: [{ uses: "./foo_file" }],
|
||||
};
|
||||
|
||||
/** A less minimal configuration file. */
|
||||
const otherConfigFileContents = `
|
||||
name: my config
|
||||
@@ -558,16 +564,14 @@ test.serial(
|
||||
tempDir,
|
||||
);
|
||||
|
||||
const configInput = `
|
||||
name: my config
|
||||
queries:
|
||||
- uses: ./foo
|
||||
packs:
|
||||
javascript:
|
||||
- a/b@1.2.3
|
||||
python:
|
||||
- c/d@1.2.3
|
||||
`;
|
||||
const configInput: UserConfig = {
|
||||
name: "my config",
|
||||
queries: [{ uses: "./foo" }],
|
||||
packs: {
|
||||
javascript: ["a/b@1.2.3"],
|
||||
python: ["c/d@1.2.3"],
|
||||
},
|
||||
};
|
||||
|
||||
fs.mkdirSync(path.join(tempDir, "foo"));
|
||||
|
||||
@@ -598,7 +602,16 @@ test.serial(
|
||||
}),
|
||||
);
|
||||
|
||||
t.deepEqual(config.originalUserInput, yaml.load(configInput));
|
||||
// Compare with a separate object rather than `configInput` itself, so that the test catches
|
||||
// changes made to the input in place.
|
||||
t.deepEqual(config.originalUserInput, {
|
||||
name: "my config",
|
||||
queries: [{ uses: "./foo" }],
|
||||
packs: {
|
||||
javascript: ["a/b@1.2.3"],
|
||||
python: ["c/d@1.2.3"],
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
@@ -2413,7 +2426,7 @@ test("determineUserConfig - loads config input", async (t) => {
|
||||
const expectedConfigPath = configUtils.userConfigFromActionPath(tmpDir);
|
||||
|
||||
const inputs = createTestInitConfigInputs({
|
||||
configInput: simpleConfigFileContents,
|
||||
configInput: simpleConfigInput,
|
||||
configFile: undefined,
|
||||
workspacePath: tmpDir,
|
||||
});
|
||||
@@ -2423,17 +2436,15 @@ test("determineUserConfig - loads config input", async (t) => {
|
||||
|
||||
await target
|
||||
// The input source and path of the generated config file should have been logged.
|
||||
.logs(
|
||||
t,
|
||||
"Using config from action input:",
|
||||
`Using configuration file: ${expectedConfigPath}`,
|
||||
)
|
||||
// The message about no configuration input and
|
||||
// the warning about both inputs should not have been logged.
|
||||
.logs(t, `Using config from action input: ${expectedConfigPath}`)
|
||||
// The message about no configuration input and the warning about both inputs should not have
|
||||
// been logged. The generated config file isn't loaded, since the `config` input has already
|
||||
// been parsed.
|
||||
.notLogs(
|
||||
t,
|
||||
"No configuration file was provided",
|
||||
"Both a config file and config input were provided. Ignoring config file.",
|
||||
`Using configuration file: ${expectedConfigPath}`,
|
||||
)
|
||||
// The loaded configuration should match `simpleConfigFileContents`.
|
||||
.passes(t.deepEqual, {
|
||||
@@ -2452,7 +2463,7 @@ test("determineUserConfig - ignores config file input when both specified", asyn
|
||||
const expectedConfigPath = configUtils.userConfigFromActionPath(tmpDir);
|
||||
|
||||
const inputs = createTestInitConfigInputs({
|
||||
configInput: simpleConfigFileContents,
|
||||
configInput: simpleConfigInput,
|
||||
configFile: configFilePath,
|
||||
workspacePath: tmpDir,
|
||||
});
|
||||
@@ -2466,10 +2477,14 @@ test("determineUserConfig - ignores config file input when both specified", asyn
|
||||
.logs(
|
||||
t,
|
||||
`Using config from action input: ${expectedConfigPath}`,
|
||||
`Using configuration file: ${expectedConfigPath}`,
|
||||
"Both a config file and config input were provided. Ignoring config file.",
|
||||
)
|
||||
.notLogs(t, "No configuration file was provided")
|
||||
// The generated config file isn't loaded, since the `config` input has already been parsed.
|
||||
.notLogs(
|
||||
t,
|
||||
"No configuration file was provided",
|
||||
`Using configuration file: ${expectedConfigPath}`,
|
||||
)
|
||||
// The loaded configuration should match `simpleConfigFileContents`.
|
||||
.passes(t.deepEqual, {
|
||||
name: "my config",
|
||||
@@ -2482,11 +2497,14 @@ test("determineUserConfig - ignores config file input when both specified", asyn
|
||||
});
|
||||
|
||||
/** A `config` input that we might get from Default Setup. */
|
||||
const defaultSetupConfigInput = `
|
||||
threat-models: [local, remote]
|
||||
default-setup:
|
||||
org:
|
||||
model-packs: [foo, bar]`;
|
||||
const defaultSetupConfigInput: UserConfig = {
|
||||
"threat-models": ["local", "remote"],
|
||||
"default-setup": {
|
||||
org: {
|
||||
"model-packs": ["foo", "bar"],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
test("determineUserConfig - merges configs if FF is enabled in Default Setup", async (t) => {
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
@@ -2555,7 +2573,7 @@ test("determineUserConfig - ignores config file input in Default Setup if FF is
|
||||
.withArgs(
|
||||
tmpDir,
|
||||
createTestInitConfigInputs({
|
||||
configInput: simpleConfigFileContents,
|
||||
configInput: simpleConfigInput,
|
||||
configFile: configFilePath,
|
||||
workspacePath: tmpDir,
|
||||
}),
|
||||
@@ -2565,10 +2583,14 @@ test("determineUserConfig - ignores config file input in Default Setup if FF is
|
||||
.logs(
|
||||
t,
|
||||
`Using config from action input: ${expectedConfigPath}`,
|
||||
`Using configuration file: ${expectedConfigPath}`,
|
||||
"Both a config file and config input were provided. Ignoring config file.",
|
||||
)
|
||||
.notLogs(t, "No configuration file was provided")
|
||||
// The generated config file isn't loaded, since the `config` input has already been parsed.
|
||||
.notLogs(
|
||||
t,
|
||||
"No configuration file was provided",
|
||||
`Using configuration file: ${expectedConfigPath}`,
|
||||
)
|
||||
.passes(t.deepEqual, {
|
||||
name: "my config",
|
||||
queries: [{ uses: "./foo_file" }],
|
||||
@@ -2587,7 +2609,7 @@ test("determineUserConfig - ignores config file input outside Default Setup if F
|
||||
.withArgs(
|
||||
tmpDir,
|
||||
createTestInitConfigInputs({
|
||||
configInput: simpleConfigFileContents,
|
||||
configInput: simpleConfigInput,
|
||||
configFile: configFilePath,
|
||||
workspacePath: tmpDir,
|
||||
}),
|
||||
@@ -2597,10 +2619,14 @@ test("determineUserConfig - ignores config file input outside Default Setup if F
|
||||
.logs(
|
||||
t,
|
||||
`Using config from action input: ${expectedConfigPath}`,
|
||||
`Using configuration file: ${expectedConfigPath}`,
|
||||
"Both a config file and config input were provided. Ignoring config file.",
|
||||
)
|
||||
.notLogs(t, "No configuration file was provided")
|
||||
// The generated config file isn't loaded, since the `config` input has already been parsed.
|
||||
.notLogs(
|
||||
t,
|
||||
"No configuration file was provided",
|
||||
`Using configuration file: ${expectedConfigPath}`,
|
||||
)
|
||||
.passes(t.deepEqual, {
|
||||
name: "my config",
|
||||
queries: [{ uses: "./foo_file" }],
|
||||
|
||||
+16
-20
@@ -2,7 +2,6 @@ import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import { performance } from "perf_hooks";
|
||||
|
||||
import * as core from "@actions/core";
|
||||
import * as yaml from "js-yaml";
|
||||
|
||||
import { ActionState } from "./action-common";
|
||||
@@ -46,7 +45,7 @@ import {
|
||||
makeTelemetryDiagnostic,
|
||||
} from "./diagnostics";
|
||||
import { prepareDiffInformedAnalysis } from "./diff-informed-analysis-utils";
|
||||
import { EnvVar } from "./environment";
|
||||
import { EnvVar, exportEnvVar } from "./environment";
|
||||
import * as errorMessages from "./error-messages";
|
||||
import { Feature, FeatureEnablement, FeatureWithoutCLI } from "./feature-flags";
|
||||
import {
|
||||
@@ -337,7 +336,8 @@ export interface InitConfigInputs {
|
||||
packsInput: string | undefined;
|
||||
configFile: string | undefined;
|
||||
dbLocation: string | undefined;
|
||||
configInput: string | undefined;
|
||||
/** The configuration from the `config` input. */
|
||||
configInput: UserConfig | undefined;
|
||||
buildModeInput: string | undefined;
|
||||
ramInput: string | undefined;
|
||||
dependencyCachingEnabled: string | undefined;
|
||||
@@ -964,10 +964,10 @@ async function setCppTrapCachingEnvironmentVariables(
|
||||
);
|
||||
} else if (config.trapCaches[BuiltInLanguage.cpp]) {
|
||||
logger.info("Enabling TRAP caching for C/C++.");
|
||||
core.exportVariable(envVar, "true");
|
||||
exportEnvVar(envVar, "true");
|
||||
} else {
|
||||
logger.debug(`Disabling TRAP caching for C/C++.`);
|
||||
core.exportVariable(envVar, "false");
|
||||
exportEnvVar(envVar, "false");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1057,17 +1057,13 @@ export async function determineUserConfig(
|
||||
tempDir: string,
|
||||
inputs: InitConfigInputs,
|
||||
): Promise<UserConfig> {
|
||||
const validateConfig = await action.features.getValue(
|
||||
Feature.ValidateDbConfig,
|
||||
);
|
||||
|
||||
// We have the following cases:
|
||||
// 1. A `config` or `config-file` input is provided, but not both: use the provided one.
|
||||
// 2. Both are provided and we are in an advanced workflow: ignore the `config-file` input.
|
||||
// 3. Both are provided and we are in Default Setup: the `config` input uses a limited
|
||||
// set of options, which are supported by `mergeDefaultSetupAndUserConfigs`,
|
||||
// and we merge the two configs.
|
||||
if (inputs.configInput) {
|
||||
if (inputs.configInput !== undefined) {
|
||||
const computedConfigPath = userConfigFromActionPath(tempDir);
|
||||
|
||||
// Get a function which enables us to determine whether the FF that allows us to
|
||||
@@ -1084,12 +1080,6 @@ export async function determineUserConfig(
|
||||
) {
|
||||
// If the FF is enabled and we are in Default Setup, combine the supported
|
||||
// configuration file properties and write the result to disk.
|
||||
const fromConfigInput = parseUserConfig(
|
||||
action.logger,
|
||||
"`config` input",
|
||||
inputs.configInput,
|
||||
validateConfig,
|
||||
);
|
||||
const fromConfigFile = await loadUserConfig(
|
||||
action,
|
||||
inputs.configFile,
|
||||
@@ -1102,7 +1092,7 @@ export async function determineUserConfig(
|
||||
// the CLI or other CodeQL Action steps.
|
||||
const mergedConfig = mergeDefaultSetupAndUserConfigs(
|
||||
action.logger,
|
||||
fromConfigInput,
|
||||
inputs.configInput,
|
||||
fromConfigFile,
|
||||
);
|
||||
fs.writeFileSync(computedConfigPath, yaml.dump(mergedConfig));
|
||||
@@ -1122,12 +1112,13 @@ export async function determineUserConfig(
|
||||
);
|
||||
}
|
||||
|
||||
// Write the `config` input straight to disk.
|
||||
fs.writeFileSync(computedConfigPath, inputs.configInput);
|
||||
// Write the `config` input to disk without merging it with a configuration file.
|
||||
fs.writeFileSync(computedConfigPath, yaml.dump(inputs.configInput));
|
||||
inputs.configFile = computedConfigPath;
|
||||
action.logger.debug(
|
||||
`Using config from action input: ${inputs.configFile}`,
|
||||
);
|
||||
return inputs.configInput;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1425,7 +1416,12 @@ export async function getConfig(
|
||||
}
|
||||
if (config.version !== getActionVersion()) {
|
||||
throw new ConfigurationError(
|
||||
`Loaded a configuration file for version '${config.version}', but running version '${getActionVersion()}'`,
|
||||
[
|
||||
`Loaded a configuration file for version '${config.version}', but running version '${getActionVersion()}'.`,
|
||||
"All steps in a workflow that use `github/codeql-action` must use the same version to work correctly.",
|
||||
"If you are using Dependabot to manage dependency updates, you can configure a dependency group to update all `github/codeql-action` steps at the same time.",
|
||||
"For more information, see https://docs.github.com/en/code-security/reference/supply-chain-security/dependabot-options-reference#groups--",
|
||||
].join(" "),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -625,3 +625,73 @@ test("mergeDefaultSetupAndUserConfigs - warns about invalid keys from Default Se
|
||||
`Invalid keys in Default Setup configuration: ${expectedInvalidKeys}`,
|
||||
]);
|
||||
});
|
||||
|
||||
/** Parses `contents` as a configuration without validating it. */
|
||||
function parseUnvalidatedConfig(contents: string): dbConfig.UserConfig {
|
||||
return dbConfig.parseUserConfig(
|
||||
getRunnerLogger(true),
|
||||
"test",
|
||||
contents,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
test("matchesDefaultSetupConfigSchema - returns true for configurations that only use Default Setup properties", (t) => {
|
||||
for (const contents of [
|
||||
[
|
||||
"default-setup:",
|
||||
" org:",
|
||||
" model-packs: [ github/immutable-actions-list@0.0.1 ]",
|
||||
"threat-models: [ ]",
|
||||
].join("\n"),
|
||||
"threat-models: [ local ]",
|
||||
"{}",
|
||||
]) {
|
||||
t.true(
|
||||
dbConfig.matchesDefaultSetupConfigSchema(
|
||||
parseUnvalidatedConfig(contents),
|
||||
),
|
||||
contents,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("matchesDefaultSetupConfigSchema - returns false for configurations that use other properties", (t) => {
|
||||
for (const contents of [
|
||||
"queries: [ { uses: ./queries/show_ifs.ql } ]",
|
||||
"paths-ignore: [ tests ]",
|
||||
"default-setup: { org: { model-packs: [], queries: [] } }",
|
||||
]) {
|
||||
t.false(
|
||||
dbConfig.matchesDefaultSetupConfigSchema(
|
||||
parseUnvalidatedConfig(contents),
|
||||
),
|
||||
contents,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("matchesDefaultSetupConfigSchema - returns false for invalid Default Setup properties", (t) => {
|
||||
for (const contents of [
|
||||
"threat-models: local",
|
||||
"default-setup: { org: { model-packs: [ 1 ] } }",
|
||||
]) {
|
||||
t.false(
|
||||
dbConfig.matchesDefaultSetupConfigSchema(
|
||||
parseUnvalidatedConfig(contents),
|
||||
),
|
||||
contents,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("matchesDefaultSetupConfigSchema - returns false for configurations that aren't mappings", (t) => {
|
||||
for (const contents of ["- threat-models", "local", "null"]) {
|
||||
t.false(
|
||||
dbConfig.matchesDefaultSetupConfigSchema(
|
||||
parseUnvalidatedConfig(contents),
|
||||
),
|
||||
contents,
|
||||
);
|
||||
}
|
||||
});
|
||||
+79
-49
@@ -33,6 +33,15 @@ export interface QuerySpec {
|
||||
uses: string;
|
||||
}
|
||||
|
||||
// A set of default query suite names that are understood by the CLI.
|
||||
export const defaultSuites: Set<string> = new Set([
|
||||
"security-experimental",
|
||||
"security-extended",
|
||||
"security-and-quality",
|
||||
"code-quality",
|
||||
"code-scanning",
|
||||
]);
|
||||
|
||||
const ORG_SCHEMA = {
|
||||
/** An array of model pack names. */
|
||||
"model-packs": json.optional(json.array(json.string)),
|
||||
@@ -77,7 +86,11 @@ export interface UserConfig {
|
||||
"default-setup"?: DefaultSetupConfig;
|
||||
}
|
||||
|
||||
/** A subset of the `UserConfig` schema that is used by Default Setup. */
|
||||
/**
|
||||
* A subset of the `UserConfig` schema that is known to be used by Default Setup. None of these
|
||||
* properties may add queries, since a per-language CodeQL bundle can be used with a `config` input
|
||||
* that only sets them.
|
||||
*/
|
||||
const DEFAULT_SETUP_CONFIG_SCHEMA = {
|
||||
"threat-models": json.optional(json.array(json.string)),
|
||||
"default-setup": json.optional<DefaultSetupConfig>(
|
||||
@@ -85,6 +98,24 @@ const DEFAULT_SETUP_CONFIG_SCHEMA = {
|
||||
),
|
||||
} as const satisfies json.Schema;
|
||||
|
||||
/**
|
||||
* Returns whether `config` matches what we expect Default Setup to send in the `config` input: a
|
||||
* mapping that only sets properties in `DEFAULT_SETUP_CONFIG_SCHEMA`, with values of the expected
|
||||
* types.
|
||||
*/
|
||||
export function matchesDefaultSetupConfigSchema(config: UserConfig): boolean {
|
||||
// Unless validation is enabled, `parseUserConfig` doesn't check that the YAML is a mapping.
|
||||
if (!json.isObject(config)) {
|
||||
return false;
|
||||
}
|
||||
const result = json.checkSchema(
|
||||
DEFAULT_SETUP_CONFIG_SCHEMA,
|
||||
config as json.UnvalidatedObject<any>,
|
||||
);
|
||||
// `valid` doesn't account for unknown properties.
|
||||
return result.valid && result.unknownKeys.length === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges supported properties from two configuration files. This is intended only for
|
||||
* use with merging the `config` input provided by Default Setup with a potentially
|
||||
@@ -437,63 +468,60 @@ export async function calculateAugmentation(
|
||||
languages,
|
||||
packsInputCombines,
|
||||
);
|
||||
const queriesInputCombines = shouldCombine(rawQueriesInput);
|
||||
const queriesInput = parseQueriesFromInput(
|
||||
rawQueriesInput,
|
||||
queriesInputCombines,
|
||||
const queries = parseQueriesFromInput(rawQueriesInput);
|
||||
const repoPropertyQueries = parseQueriesFromInput(
|
||||
repositoryProperties[RepositoryPropertyName.EXTRA_QUERIES],
|
||||
RepositoryPropertyName.EXTRA_QUERIES,
|
||||
);
|
||||
|
||||
const repoExtraQueries =
|
||||
repositoryProperties[RepositoryPropertyName.EXTRA_QUERIES];
|
||||
const repoExtraQueriesCombines = shouldCombine(repoExtraQueries);
|
||||
const repoPropertyQueries = {
|
||||
combines: repoExtraQueriesCombines,
|
||||
input: parseQueriesFromInput(
|
||||
repoExtraQueries,
|
||||
repoExtraQueriesCombines,
|
||||
new ConfigurationError(
|
||||
errorMessages.getRepoPropertyError(
|
||||
RepositoryPropertyName.EXTRA_QUERIES,
|
||||
errorMessages.getEmptyCombinesError(),
|
||||
),
|
||||
),
|
||||
),
|
||||
};
|
||||
|
||||
return {
|
||||
packsInputCombines,
|
||||
packsInput: packsInput?.[languages[0]],
|
||||
queriesInput,
|
||||
queriesInputCombines,
|
||||
queriesInput: queries.input,
|
||||
queriesInputCombines: queries.combines,
|
||||
repoPropertyQueries,
|
||||
};
|
||||
}
|
||||
|
||||
function parseQueriesFromInput(
|
||||
rawQueriesInput: string | undefined,
|
||||
queriesInputCombines: boolean,
|
||||
errorToThrow?: ConfigurationError,
|
||||
) {
|
||||
if (!rawQueriesInput) {
|
||||
return undefined;
|
||||
/**
|
||||
* Parses a comma-separated list of queries, which may have a '+' prefix. Entries aren't validated,
|
||||
* so an empty entry becomes `{ uses: "" }`.
|
||||
*
|
||||
* @param value The list of queries.
|
||||
* @param repositoryProperty The repository property that `value` comes from, if any. Error messages
|
||||
* refer to this property, or to the `queries` input if no property is given.
|
||||
* @returns An `Augmentation` containing the parsed queries and whether `value` has a '+' prefix.
|
||||
* The queries are `undefined` if `value` is unset or empty.
|
||||
* @throws A `ConfigurationError` if `value` is a '+' with no queries after it.
|
||||
*/
|
||||
export function parseQueriesFromInput(
|
||||
value: string | undefined,
|
||||
repositoryProperty?: RepositoryPropertyName,
|
||||
): Augmentation<QuerySpec[]> {
|
||||
if (!value) {
|
||||
return { combines: false, input: undefined };
|
||||
}
|
||||
|
||||
const trimmedInput = queriesInputCombines
|
||||
? rawQueriesInput.trim().slice(1).trim()
|
||||
: (rawQueriesInput?.trim() ?? "");
|
||||
if (queriesInputCombines && trimmedInput.length === 0) {
|
||||
if (errorToThrow) {
|
||||
throw errorToThrow;
|
||||
}
|
||||
const combines = shouldCombine(value);
|
||||
const trimmedInput = combines ? value.trim().slice(1).trim() : value.trim();
|
||||
if (combines && trimmedInput.length === 0) {
|
||||
throw new ConfigurationError(
|
||||
errorMessages.getConfigFilePropertyError(
|
||||
undefined,
|
||||
"queries",
|
||||
"A '+' was used in the 'queries' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs.",
|
||||
),
|
||||
repositoryProperty !== undefined
|
||||
? errorMessages.getRepoPropertyError(
|
||||
repositoryProperty,
|
||||
errorMessages.getEmptyCombinesError(),
|
||||
)
|
||||
: errorMessages.getConfigFilePropertyError(
|
||||
undefined,
|
||||
"queries",
|
||||
"A '+' was used in the 'queries' input to specify that you wished to add some packs to your CodeQL analysis. However, no packs were specified. Please either remove the '+' or specify some packs.",
|
||||
),
|
||||
);
|
||||
}
|
||||
return trimmedInput.split(",").map((query) => ({ uses: query.trim() }));
|
||||
return {
|
||||
combines,
|
||||
input: trimmedInput.split(",").map((query) => ({ uses: query.trim() })),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -610,11 +638,13 @@ export function generateCodeScanningConfig(
|
||||
* Attempts to parse `contents` into a `UserConfig` value.
|
||||
*
|
||||
* @param logger The logger to use.
|
||||
* @param pathInput The path to the file where `contents` was obtained from, for use in error messages.
|
||||
* @param contents The string contents of a YAML file to try and parse as a `UserConfig`.
|
||||
* @param validateConfig Whether to validate the configuration file against the schema.
|
||||
* @returns The `UserConfig` corresponding to `contents`, if parsing was successful.
|
||||
* @throws A `ConfigurationError` if parsing failed.
|
||||
* @param pathInput Where `contents` came from, such as the path to a file, for use in error messages.
|
||||
* @param contents The YAML to try and parse as a `UserConfig`.
|
||||
* @param validateConfig Whether to validate the configuration against the schema.
|
||||
* @returns The `UserConfig` corresponding to `contents`, if parsing was successful. Unless
|
||||
* `validateConfig` is set, the result might not be a mapping.
|
||||
* @throws A `ConfigurationError` if `contents` isn't valid YAML or, when `validateConfig` is set,
|
||||
* isn't a valid configuration.
|
||||
*/
|
||||
export function parseUserConfig(
|
||||
logger: Logger,
|
||||
|
||||
@@ -11,7 +11,7 @@ import { dbIsFinalized } from "./analyze";
|
||||
import { scanArtifactsForTokens } from "./artifact-scanner";
|
||||
import { type CodeQL } from "./codeql";
|
||||
import { Config } from "./config-utils";
|
||||
import { EnvVar } from "./environment";
|
||||
import { EnvVar, exportEnvVar } from "./environment";
|
||||
import * as json from "./json";
|
||||
import { Language } from "./languages";
|
||||
import { Logger, withGroup } from "./logging";
|
||||
@@ -330,7 +330,7 @@ export async function uploadArtifacts(
|
||||
// some issues early.
|
||||
if (isInTestMode()) {
|
||||
await scanArtifactsForTokens(toUpload, logger);
|
||||
core.exportVariable("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true");
|
||||
exportEnvVar("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true");
|
||||
}
|
||||
|
||||
const suffix = getArtifactSuffix(getOptionalInput("matrix"));
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"bundleVersion": "codeql-bundle-v2.27.1",
|
||||
"cliVersion": "2.27.1",
|
||||
"priorBundleVersion": "codeql-bundle-v2.27.0",
|
||||
"priorCliVersion": "2.27.0"
|
||||
"bundleVersion": "codeql-bundle-v2.27.2",
|
||||
"cliVersion": "2.27.2",
|
||||
"priorBundleVersion": "codeql-bundle-v2.27.1",
|
||||
"priorCliVersion": "2.27.1"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import test from "ava";
|
||||
|
||||
import { Env, ReadOnlyEnv } from "./environment";
|
||||
import { getTestEnv, setupTests } from "./testing-utils";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
test("isTestingEnv() is true", (t) => {
|
||||
t.true(new ReadOnlyEnv(process.env).isTestingEnv());
|
||||
t.true(new Env(process.env).isTestingEnv());
|
||||
t.true(getTestEnv().isTestingEnv());
|
||||
});
|
||||
+91
-1
@@ -1,3 +1,10 @@
|
||||
import * as core from "@actions/core";
|
||||
|
||||
/**
|
||||
* This constant is set in `ava.setup.mjs` for tests.
|
||||
*/
|
||||
declare const __CODEQL_ACTION_TEST_ENV__: string | undefined;
|
||||
|
||||
/**
|
||||
* Environment variables used by Default Setup to communicate the private registry proxy configuration.
|
||||
*/
|
||||
@@ -211,8 +218,20 @@ export enum ActionsEnvVars {
|
||||
RUNNER_TOOL_CACHE = "RUNNER_TOOL_CACHE",
|
||||
}
|
||||
|
||||
/** Environment variables which are not specific to CodeQL. */
|
||||
export enum SystemEnvVar {
|
||||
/**
|
||||
* Used by Node and related tools to indicate what kind of environment we are running in.
|
||||
*/
|
||||
NODE_ENV = "NODE_ENV",
|
||||
}
|
||||
|
||||
/** A type representing all known environment variables. */
|
||||
export type KnownEnvVar = EnvVar | ActionsEnvVars | RegistryProxyVars;
|
||||
export type KnownEnvVar =
|
||||
| EnvVar
|
||||
| ActionsEnvVars
|
||||
| RegistryProxyVars
|
||||
| SystemEnvVar;
|
||||
|
||||
/**
|
||||
* Gets an environment variable, but throws an error if it is not set.
|
||||
@@ -289,6 +308,26 @@ export class ReadOnlyEnv<T extends string | undefined = string | undefined> {
|
||||
public entries(): Array<[string, T]> {
|
||||
return Object.entries(this.vars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether we should skip uploads of
|
||||
* all kinds (SARIF results, status reports, DBs, ...).
|
||||
*
|
||||
* This is not guaranteed to be set in all test environments.
|
||||
*/
|
||||
public isSkippingUploadsInTests(): boolean {
|
||||
return this.getOptional(EnvVar.TEST_MODE) === "true";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicative of whether we are in a testing environment
|
||||
* by testing whether the value of the `NODE_ENV` variable is "test".
|
||||
* This is expected to be the case if e.g. `ava` is running the tests
|
||||
* or if this instance was constructed by `getTestEnv`.
|
||||
*/
|
||||
public isTestingEnv(): boolean {
|
||||
return __CODEQL_ACTION_TEST_ENV__ === "unit-test";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,6 +346,26 @@ export class Env<
|
||||
this.changed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around `core.exportVariable` which does not call `core.exportVariable`
|
||||
* when running unit tests. This is important, because otherwise `core.exportVariable`
|
||||
* sets environment variables for other steps in a workflow when we run unit tests in CI.
|
||||
*
|
||||
* @param name The name of the environment variable to set and export.
|
||||
* @param val The value to set and export for the environment variable.
|
||||
*/
|
||||
public export(name: string, val: T): void {
|
||||
// Setting the environment variable for this instance is always OK, including
|
||||
// in tests, since we use fresh `Env` instances whenever needed. This allows
|
||||
// tests to pass that rely on that part of the `core.exportVariable` behaviour.
|
||||
this.set(name, val);
|
||||
|
||||
// Call `core.exportVariable` whenever we are not in a test environment.
|
||||
if (!this.isTestingEnv()) {
|
||||
core.exportVariable(name, val);
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets a value indicating whether `set` was called at least once. */
|
||||
public hasChanged(): boolean {
|
||||
return this.changed;
|
||||
@@ -317,3 +376,34 @@ export class Env<
|
||||
export function getEnv(env: NodeJS.ProcessEnv = process.env): Env {
|
||||
return new Env(env);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether we are in test mode. This is used by CodeQL Action PR checks.
|
||||
*
|
||||
* In test mode, we skip several uploads (SARIF results, status reports, DBs, ...).
|
||||
*
|
||||
* @deprecated
|
||||
* The purpose of this function is ambiguous. Use `isSkippingUploadsInTests` on
|
||||
* a `ReadOnlyEnv` instance instead for equivalent behaviour. Use `isTestingEnv`
|
||||
* to determine if we are running in a unit test.
|
||||
*/
|
||||
export function isInTestMode(): boolean {
|
||||
return getEnv().isSkippingUploadsInTests();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around `core.exportVariable` which does not call `core.exportVariable`
|
||||
* when running unit tests. This is important, because otherwise `core.exportVariable`
|
||||
* sets environment variables for other steps in a workflow when we run unit tests in CI.
|
||||
*
|
||||
* @deprecated Use `export` on an `Env` instance instead.
|
||||
*/
|
||||
export function exportEnvVar(name: string, val: any): void {
|
||||
const env = getEnv();
|
||||
|
||||
if (typeof val === "string") {
|
||||
env.export(name, val);
|
||||
} else {
|
||||
env.export(name, JSON.stringify(val));
|
||||
}
|
||||
}
|
||||
@@ -168,7 +168,7 @@ export enum Feature {
|
||||
* Controls whether we may download a bundle containing only the single language being analysed,
|
||||
* rather than the combined bundle that contains every language.
|
||||
*/
|
||||
PerLanguageBundles = "per_language_bundles",
|
||||
PerLanguageBundles = "per_language_bundles_v2",
|
||||
QaTelemetryEnabled = "qa_telemetry_enabled",
|
||||
/** Routes (some) API requests through the registry proxy. */
|
||||
ProxyApiRequests = "proxy_api_requests",
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
getTemporaryDirectory,
|
||||
printDebugLogs,
|
||||
} from "./actions-util";
|
||||
import { getGitHubVersion } from "./api-client";
|
||||
import { getGitHubVersion, wrapApiConfigurationError } from "./api-client";
|
||||
import { CachingKind } from "./caching-utils";
|
||||
import { getCodeQL } from "./codeql";
|
||||
import { type Config, getConfig } from "./config-utils";
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
DependencyCachingUsageReport,
|
||||
getDependencyCacheUsage,
|
||||
} from "./dependency-caching";
|
||||
import { EnvVar, getEnv } from "./environment";
|
||||
import { EnvVar, getEnv, exportEnvVar } from "./environment";
|
||||
import { initFeatures } from "./feature-flags";
|
||||
import * as gitUtils from "./git-utils";
|
||||
import * as initActionPostHelper from "./init-action-post-helper";
|
||||
@@ -62,9 +62,11 @@ async function run(startedAt: Date) {
|
||||
const jobStatus = getOptionalInput("job-status");
|
||||
|
||||
// Restore inputs from `init` Action.
|
||||
restoreInputs();
|
||||
restoreInputs(logger);
|
||||
|
||||
const gitHubVersion = await getGitHubVersion();
|
||||
config = await getConfig(getTemporaryDirectory(), logger);
|
||||
|
||||
const gitHubVersion = config?.gitHubVersion ?? (await getGitHubVersion());
|
||||
checkGitHubVersionInRange(gitHubVersion, logger);
|
||||
|
||||
const repositoryNwo = getRepositoryNwo();
|
||||
@@ -75,7 +77,6 @@ async function run(startedAt: Date) {
|
||||
logger,
|
||||
);
|
||||
|
||||
config = await getConfig(getTemporaryDirectory(), logger);
|
||||
if (config === undefined) {
|
||||
logger.warning(
|
||||
"Debugging artifacts are unavailable since the 'init' Action failed before it could produce any.",
|
||||
@@ -107,7 +108,7 @@ async function run(startedAt: Date) {
|
||||
}
|
||||
}
|
||||
} catch (unwrappedError) {
|
||||
const error = wrapError(unwrappedError);
|
||||
const error = wrapApiConfigurationError(wrapError(unwrappedError));
|
||||
core.setFailed(error.message);
|
||||
|
||||
const statusReportBase = await createStatusReportBase(
|
||||
@@ -165,7 +166,7 @@ function getFinalJobStatus(config: Config | undefined): JobStatus {
|
||||
let jobStatus: JobStatus;
|
||||
|
||||
if (process.env[EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY] === "true") {
|
||||
core.exportVariable(EnvVar.JOB_STATUS, JobStatus.SuccessStatus);
|
||||
exportEnvVar(EnvVar.JOB_STATUS, JobStatus.SuccessStatus);
|
||||
jobStatus = JobStatus.SuccessStatus;
|
||||
} else if (config !== undefined) {
|
||||
// - We have computed a CodeQL config
|
||||
@@ -190,7 +191,7 @@ function getFinalJobStatus(config: Config | undefined): JobStatus {
|
||||
|
||||
// This shouldn't be necessary, but in the odd case that we run more than one
|
||||
// `init` post step, ensure the job status is consistent between them.
|
||||
core.exportVariable(EnvVar.JOB_STATUS, jobStatus);
|
||||
exportEnvVar(EnvVar.JOB_STATUS, jobStatus);
|
||||
return jobStatus;
|
||||
}
|
||||
|
||||
|
||||
+55
-22
@@ -5,7 +5,12 @@ import * as core from "@actions/core";
|
||||
import * as io from "@actions/io";
|
||||
import * as semver from "semver";
|
||||
|
||||
import { Action, ActionState, runInActions } from "./action-common";
|
||||
import {
|
||||
Action,
|
||||
ActionState,
|
||||
extendActionState,
|
||||
runInActions,
|
||||
} from "./action-common";
|
||||
import {
|
||||
FileCmdNotFoundError,
|
||||
getActionVersion,
|
||||
@@ -23,6 +28,7 @@ import {
|
||||
shouldRestoreCache,
|
||||
} from "./caching-utils";
|
||||
import { CodeQL } from "./codeql";
|
||||
import { parseUserConfig } from "./config/db-config";
|
||||
import { getConfigFileInput } from "./config/file";
|
||||
import { ComputedInput, getToolsInput } from "./config/inputs";
|
||||
import * as configUtils from "./config-utils";
|
||||
@@ -40,7 +46,10 @@ import {
|
||||
} from "./diagnostics";
|
||||
import { ActionsEnvVars, EnvVar } from "./environment";
|
||||
import { Feature, FeatureEnablement, initFeatures } from "./feature-flags";
|
||||
import { loadRepositoryProperties } from "./feature-flags/properties";
|
||||
import {
|
||||
loadRepositoryProperties,
|
||||
RepositoryPropertyName,
|
||||
} from "./feature-flags/properties";
|
||||
import {
|
||||
checkInstallPython311,
|
||||
checkPacksForOverlayCompatibility,
|
||||
@@ -58,6 +67,7 @@ import {
|
||||
OverlayBaseDatabaseDownloadStats,
|
||||
} from "./overlay/caching";
|
||||
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
|
||||
import { getOtherLanguagePacksReason } from "./per-language-bundles";
|
||||
import { getRepositoryNwo } from "./repository";
|
||||
import { ToolsSource } from "./setup-codeql";
|
||||
import {
|
||||
@@ -88,7 +98,6 @@ import {
|
||||
checkActionVersion,
|
||||
getErrorMessage,
|
||||
BuildMode,
|
||||
getOptionalEnvVar,
|
||||
} from "./util";
|
||||
import { checkWorkflow } from "./workflow";
|
||||
|
||||
@@ -248,7 +257,7 @@ async function run(
|
||||
);
|
||||
const repositoryProperties = repositoryPropertiesResult.orElse({});
|
||||
|
||||
core.exportVariable(EnvVar.INIT_ACTION_HAS_RUN, "true");
|
||||
actionState.env.export(EnvVar.INIT_ACTION_HAS_RUN, "true");
|
||||
|
||||
// path.resolve() respects the intended semantics of source-root. If
|
||||
// source-root is relative, it is relative to the GITHUB_WORKSPACE. If
|
||||
@@ -273,7 +282,9 @@ async function run(
|
||||
}
|
||||
|
||||
// Compute the value of the `config-file` input.
|
||||
const actionStateWithFeatures = { ...actionState, features };
|
||||
const actionStateWithFeatures = extendActionState(actionState, {
|
||||
features,
|
||||
});
|
||||
configFile = await getConfigFileInput(
|
||||
actionStateWithFeatures,
|
||||
repositoryProperties,
|
||||
@@ -302,6 +313,24 @@ async function run(
|
||||
const rawLanguages = configUtils.getRawLanguagesNoAutodetect(
|
||||
getOptionalInput("languages"),
|
||||
);
|
||||
const rawConfigInput = getOptionalInput("config");
|
||||
const configInput =
|
||||
rawConfigInput === undefined
|
||||
? undefined
|
||||
: parseUserConfig(
|
||||
logger,
|
||||
"`config` input",
|
||||
rawConfigInput,
|
||||
await features.getValue(Feature.ValidateDbConfig),
|
||||
);
|
||||
const queriesInput = getOptionalInput("queries");
|
||||
const otherLanguagePacksReason = getOtherLanguagePacksReason({
|
||||
configFile,
|
||||
configInput,
|
||||
queriesInput,
|
||||
extraQueriesProperty:
|
||||
repositoryProperties[RepositoryPropertyName.EXTRA_QUERIES],
|
||||
});
|
||||
const useOverlayAwareDefaultCliVersion =
|
||||
analysisKinds?.length === 1 &&
|
||||
analysisKinds[0] === AnalysisKind.CodeScanning;
|
||||
@@ -312,6 +341,7 @@ async function run(
|
||||
gitHubVersion.type,
|
||||
codeQLDefaultVersionInfo,
|
||||
rawLanguages,
|
||||
otherLanguagePacksReason,
|
||||
useOverlayAwareDefaultCliVersion,
|
||||
features,
|
||||
logger,
|
||||
@@ -345,7 +375,7 @@ async function run(
|
||||
);
|
||||
}
|
||||
if (semver.lt(actualVer, publicPreview)) {
|
||||
core.exportVariable(EnvVar.EXPERIMENTAL_FEATURES, "true");
|
||||
actionState.env.export(EnvVar.EXPERIMENTAL_FEATURES, "true");
|
||||
logger.info("Experimental Rust analysis enabled");
|
||||
}
|
||||
}
|
||||
@@ -362,13 +392,13 @@ async function run(
|
||||
config = await initConfig(actionStateWithFeatures, {
|
||||
analysisKinds,
|
||||
languagesInput: getOptionalInput("languages"),
|
||||
queriesInput: getOptionalInput("queries"),
|
||||
queriesInput,
|
||||
packsInput: getOptionalInput("packs"),
|
||||
buildModeInput: getOptionalInput("build-mode"),
|
||||
ramInput: getOptionalInput("ram"),
|
||||
configFile,
|
||||
dbLocation: getOptionalInput("db-location"),
|
||||
configInput: getOptionalInput("config"),
|
||||
configInput,
|
||||
dependencyCachingEnabled: getDependencyCachingEnabled(),
|
||||
// Debug mode is enabled if:
|
||||
// - The `init` Action is passed `debug: true`.
|
||||
@@ -493,9 +523,9 @@ async function run(
|
||||
}
|
||||
|
||||
// Forward Go flags
|
||||
const goFlags = process.env["GOFLAGS"];
|
||||
const goFlags = actionState.env.getOptional("GOFLAGS");
|
||||
if (goFlags) {
|
||||
core.exportVariable("GOFLAGS", goFlags);
|
||||
actionState.env.export("GOFLAGS", goFlags);
|
||||
core.warning(
|
||||
"Passing the GOFLAGS env parameter to the init action is deprecated. Please move this to the analyze action.",
|
||||
);
|
||||
@@ -541,7 +571,7 @@ async function run(
|
||||
|
||||
// Store the original location of our wrapper script somewhere where we can
|
||||
// later retrieve it from and cross-check that it hasn't been changed.
|
||||
core.exportVariable(EnvVar.GO_BINARY_LOCATION, goWrapperPath);
|
||||
actionState.env.export(EnvVar.GO_BINARY_LOCATION, goWrapperPath);
|
||||
} catch (e) {
|
||||
logger.warning(
|
||||
`Analyzing Go on Linux, but failed to install wrapper script. Tracing custom builds may fail: ${e}`,
|
||||
@@ -550,7 +580,7 @@ async function run(
|
||||
} else {
|
||||
// Store the location of the original Go binary, so we can check that no setup tasks were performed after the
|
||||
// `init` Action ran.
|
||||
core.exportVariable(EnvVar.GO_BINARY_LOCATION, goBinaryPath);
|
||||
actionState.env.export(EnvVar.GO_BINARY_LOCATION, goBinaryPath);
|
||||
}
|
||||
} catch (e) {
|
||||
logger.warning(
|
||||
@@ -585,12 +615,12 @@ async function run(
|
||||
// threads it would ask extractors to use. See help text for the "--ram" and "--threads"
|
||||
// options at https://codeql.github.com/docs/codeql-cli/manual/database-trace-command/
|
||||
// for details.
|
||||
core.exportVariable(
|
||||
actionState.env.export(
|
||||
"CODEQL_RAM",
|
||||
process.env["CODEQL_RAM"] ||
|
||||
getCodeQLMemoryLimit(getOptionalInput("ram"), logger).toString(),
|
||||
);
|
||||
core.exportVariable(
|
||||
actionState.env.export(
|
||||
"CODEQL_THREADS",
|
||||
process.env["CODEQL_THREADS"] ||
|
||||
getThreadsFlagValue(getOptionalInput("threads"), logger).toString(),
|
||||
@@ -598,12 +628,15 @@ async function run(
|
||||
|
||||
// Disable Kotlin extractor if feature flag set
|
||||
if (await features.getValue(Feature.DisableKotlinAnalysisEnabled)) {
|
||||
core.exportVariable("CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN", "true");
|
||||
actionState.env.export(
|
||||
"CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN",
|
||||
"true",
|
||||
);
|
||||
}
|
||||
|
||||
// Emergency override to force the CodeQL CLI back to the JGit-based Git backend.
|
||||
if (await features.getValue(Feature.ForceJGit)) {
|
||||
core.exportVariable("CODEQL_GIT_BACKEND", "jgit");
|
||||
actionState.env.export("CODEQL_GIT_BACKEND", "jgit");
|
||||
}
|
||||
|
||||
const kotlinLimitVar =
|
||||
@@ -612,7 +645,7 @@ async function run(
|
||||
(await codeQlVersionAtLeast(codeql, "2.20.3")) &&
|
||||
!(await codeQlVersionAtLeast(codeql, "2.20.4"))
|
||||
) {
|
||||
core.exportVariable(kotlinLimitVar, "2.1.20");
|
||||
actionState.env.export(kotlinLimitVar, "2.1.20");
|
||||
}
|
||||
|
||||
// Restore dependency cache(s), if they exist.
|
||||
@@ -661,7 +694,7 @@ async function run(
|
||||
config.buildMode === BuildMode.None &&
|
||||
config.languages.includes(BuiltInLanguage.java)
|
||||
) {
|
||||
core.exportVariable(
|
||||
actionState.env.export(
|
||||
EnvVar.JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS,
|
||||
"true",
|
||||
);
|
||||
@@ -716,10 +749,10 @@ async function run(
|
||||
);
|
||||
}
|
||||
|
||||
const tracerConfig = await getCombinedTracerConfig(codeql, config);
|
||||
const tracerConfig = await getCombinedTracerConfig(logger, codeql, config);
|
||||
if (tracerConfig !== undefined) {
|
||||
for (const [key, value] of Object.entries(tracerConfig.env)) {
|
||||
core.exportVariable(key, value);
|
||||
actionState.env.export(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -727,10 +760,10 @@ async function run(
|
||||
if (await features.getValue(Feature.JavaNetworkDebugging)) {
|
||||
// Get the existing value of `JAVA_TOOL_OPTIONS`, if any.
|
||||
const existingJavaToolOptions =
|
||||
getOptionalEnvVar(JavaEnvVars.JAVA_TOOL_OPTIONS) || "";
|
||||
actionState.env.getOptional(JavaEnvVars.JAVA_TOOL_OPTIONS) ?? "";
|
||||
|
||||
// Add the network debugging options.
|
||||
core.exportVariable(
|
||||
actionState.env.export(
|
||||
JavaEnvVars.JAVA_TOOL_OPTIONS,
|
||||
`${existingJavaToolOptions} -Djavax.net.debug=all`,
|
||||
);
|
||||
|
||||
+16
-17
@@ -1,14 +1,13 @@
|
||||
import * as fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
import * as core from "@actions/core";
|
||||
import * as github from "@actions/github";
|
||||
import test, { ExecutionContext } from "ava";
|
||||
import * as sinon from "sinon";
|
||||
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import { createStubCodeQL } from "./codeql";
|
||||
import { ActionsEnvVars } from "./environment";
|
||||
import * as environment from "./environment";
|
||||
import { Feature } from "./feature-flags";
|
||||
import {
|
||||
checkPacksForOverlayCompatibility,
|
||||
@@ -85,7 +84,7 @@ for (const { runnerEnv, ErrorConstructor, message } of [
|
||||
`cleanupDatabaseClusterDirectory throws a ${ErrorConstructor.name} when cleanup fails on ${runnerEnv} runner`,
|
||||
async (t) => {
|
||||
await withTmpDir(async (tmpDir: string) => {
|
||||
process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = runnerEnv;
|
||||
process.env[environment.ActionsEnvVars.RUNNER_ENVIRONMENT] = runnerEnv;
|
||||
|
||||
const dbLocation = path.resolve(tmpDir, "dbs");
|
||||
fs.mkdirSync(dbLocation, { recursive: true });
|
||||
@@ -546,7 +545,7 @@ test.serial(
|
||||
test.serial(
|
||||
"file coverage deprecation warning for org-owned repo with default setup recommends repo property",
|
||||
(t) => {
|
||||
const exportVariableStub = sinon.stub(core, "exportVariable");
|
||||
const exportEnvVarStub = sinon.stub(environment, "exportEnvVar");
|
||||
sinon.stub(actionsUtil, "isDefaultSetup").returns(true);
|
||||
github.context.payload = {
|
||||
repository: {
|
||||
@@ -566,14 +565,14 @@ test.serial(
|
||||
'with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to ' +
|
||||
"`true` in the repository's settings.",
|
||||
);
|
||||
t.true(exportVariableStub.calledOnce);
|
||||
t.true(exportEnvVarStub.calledOnce);
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"file coverage deprecation warning for org-owned repo with advanced setup recommends env var and repo property",
|
||||
(t) => {
|
||||
const exportVariableStub = sinon.stub(core, "exportVariable");
|
||||
const exportEnvVarStub = sinon.stub(environment, "exportEnvVar");
|
||||
sinon.stub(actionsUtil, "isDefaultSetup").returns(false);
|
||||
github.context.payload = {
|
||||
repository: {
|
||||
@@ -594,14 +593,14 @@ test.serial(
|
||||
'with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to ' +
|
||||
"`true` in the repository's settings.",
|
||||
);
|
||||
t.true(exportVariableStub.calledOnce);
|
||||
t.true(exportEnvVarStub.calledOnce);
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"file coverage deprecation warning for user-owned repo with default setup recommends advanced setup",
|
||||
(t) => {
|
||||
const exportVariableStub = sinon.stub(core, "exportVariable");
|
||||
const exportEnvVarStub = sinon.stub(environment, "exportEnvVar");
|
||||
sinon.stub(actionsUtil, "isDefaultSetup").returns(true);
|
||||
github.context.payload = {
|
||||
repository: {
|
||||
@@ -620,14 +619,14 @@ test.serial(
|
||||
"To opt out of this change, switch to an advanced setup workflow and " +
|
||||
"set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.",
|
||||
);
|
||||
t.true(exportVariableStub.calledOnce);
|
||||
t.true(exportEnvVarStub.calledOnce);
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"file coverage deprecation warning for user-owned repo with advanced setup recommends env var",
|
||||
(t) => {
|
||||
const exportVariableStub = sinon.stub(core, "exportVariable");
|
||||
const exportEnvVarStub = sinon.stub(environment, "exportEnvVar");
|
||||
sinon.stub(actionsUtil, "isDefaultSetup").returns(false);
|
||||
github.context.payload = {
|
||||
repository: {
|
||||
@@ -645,14 +644,14 @@ test.serial(
|
||||
"to improve analysis performance. File coverage information will still be computed on non-PR analyses.\n\n" +
|
||||
"To opt out of this change, set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.",
|
||||
);
|
||||
t.true(exportVariableStub.calledOnce);
|
||||
t.true(exportEnvVarStub.calledOnce);
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"file coverage deprecation warning for unknown owner type with default setup recommends advanced setup",
|
||||
(t) => {
|
||||
const exportVariableStub = sinon.stub(core, "exportVariable");
|
||||
const exportEnvVarStub = sinon.stub(environment, "exportEnvVar");
|
||||
sinon.stub(actionsUtil, "isDefaultSetup").returns(true);
|
||||
github.context.payload = { repository: undefined };
|
||||
const messages: LoggedMessage[] = [];
|
||||
@@ -666,14 +665,14 @@ test.serial(
|
||||
"To opt out of this change, switch to an advanced setup workflow and " +
|
||||
"set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.",
|
||||
);
|
||||
t.true(exportVariableStub.calledOnce);
|
||||
t.true(exportEnvVarStub.calledOnce);
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"file coverage deprecation warning for unknown owner type with advanced setup recommends env var",
|
||||
(t) => {
|
||||
const exportVariableStub = sinon.stub(core, "exportVariable");
|
||||
const exportEnvVarStub = sinon.stub(environment, "exportEnvVar");
|
||||
sinon.stub(actionsUtil, "isDefaultSetup").returns(false);
|
||||
github.context.payload = { repository: undefined };
|
||||
const messages: LoggedMessage[] = [];
|
||||
@@ -686,7 +685,7 @@ test.serial(
|
||||
"to improve analysis performance. File coverage information will still be computed on non-PR analyses.\n\n" +
|
||||
"To opt out of this change, set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.",
|
||||
);
|
||||
t.true(exportVariableStub.calledOnce);
|
||||
t.true(exportEnvVarStub.calledOnce);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -695,10 +694,10 @@ test.serial(
|
||||
(t) => {
|
||||
process.env["CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION"] =
|
||||
"true";
|
||||
const exportVariableStub = sinon.stub(core, "exportVariable");
|
||||
const exportEnvVarStub = sinon.stub(environment, "exportEnvVar");
|
||||
const messages: LoggedMessage[] = [];
|
||||
logFileCoverageOnPrsDeprecationWarning(getRecordingLogger(messages));
|
||||
t.is(messages.length, 0);
|
||||
t.true(exportVariableStub.notCalled);
|
||||
t.true(exportEnvVarStub.notCalled);
|
||||
},
|
||||
);
|
||||
+4
-3
@@ -1,7 +1,6 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
import * as core from "@actions/core";
|
||||
import * as toolrunner from "@actions/exec/lib/toolrunner";
|
||||
import * as github from "@actions/github";
|
||||
import * as io from "@actions/io";
|
||||
@@ -17,7 +16,7 @@ import {
|
||||
import { GitHubApiDetails } from "./api-client";
|
||||
import { CodeQL, setupCodeQL } from "./codeql";
|
||||
import * as configUtils from "./config-utils";
|
||||
import { EnvVar } from "./environment";
|
||||
import { EnvVar, exportEnvVar } from "./environment";
|
||||
import {
|
||||
CodeQLDefaultVersionInfo,
|
||||
Feature,
|
||||
@@ -40,6 +39,7 @@ export async function initCodeQL(
|
||||
variant: util.GitHubVariant,
|
||||
defaultCliVersion: CodeQLDefaultVersionInfo,
|
||||
rawLanguages: string[] | undefined,
|
||||
otherLanguagePacksReason: string | undefined,
|
||||
useOverlayAwareDefaultCliVersion: boolean,
|
||||
features: FeatureEnablement,
|
||||
logger: Logger,
|
||||
@@ -58,6 +58,7 @@ export async function initCodeQL(
|
||||
variant,
|
||||
defaultCliVersion,
|
||||
rawLanguages,
|
||||
otherLanguagePacksReason,
|
||||
useOverlayAwareDefaultCliVersion,
|
||||
features,
|
||||
logger,
|
||||
@@ -409,5 +410,5 @@ export function logFileCoverageOnPrsDeprecationWarning(logger: Logger): void {
|
||||
}
|
||||
|
||||
logger.warning(message);
|
||||
core.exportVariable(EnvVar.DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION, "true");
|
||||
exportEnvVar(EnvVar.DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION, "true");
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import * as sinon from "sinon";
|
||||
import * as actionsUtil from "../actions-util";
|
||||
import * as apiClient from "../api-client";
|
||||
import type { ResolveDatabaseOutput } from "../codeql";
|
||||
import * as environment from "../environment";
|
||||
import * as gitUtils from "../git-utils";
|
||||
import { BuiltInLanguage } from "../languages";
|
||||
import { getRunnerLogger } from "../logging";
|
||||
@@ -82,7 +83,7 @@ const testDownloadOverlayBaseDatabaseFromCache = makeMacro({
|
||||
|
||||
sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/");
|
||||
|
||||
sinon.stub(utils, "isInTestMode").returns(testCase.isInTestMode);
|
||||
sinon.stub(environment, "isInTestMode").returns(testCase.isInTestMode);
|
||||
|
||||
if (testCase.restoreCacheResult instanceof Error) {
|
||||
sinon
|
||||
|
||||
@@ -4,9 +4,11 @@ import { ActionsEnvVars } from "./environment";
|
||||
import { Feature } from "./feature-flags";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import {
|
||||
getOtherLanguagePacksReason,
|
||||
getPerLanguageBundleLanguage,
|
||||
MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION,
|
||||
PerLanguageBundleOptions,
|
||||
QueryConfigInputs,
|
||||
} from "./per-language-bundles";
|
||||
import { BundlePlatform } from "./platform";
|
||||
import {
|
||||
@@ -16,11 +18,12 @@ import {
|
||||
initAllState,
|
||||
LoggedMessage,
|
||||
} from "./testing-utils";
|
||||
import { GitHubVariant } from "./util";
|
||||
import { ConfigurationError, GitHubVariant } from "./util";
|
||||
|
||||
/** Options for which we would use a per-language bundle. */
|
||||
const ELIGIBLE_OPTIONS: PerLanguageBundleOptions = {
|
||||
rawLanguages: ["java"],
|
||||
otherLanguagePacksReason: undefined,
|
||||
// Any version at least as new as the minimum will do.
|
||||
cliVersion: MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION,
|
||||
compressionMethod: "zstd",
|
||||
@@ -81,6 +84,23 @@ test("getPerLanguageBundleLanguage requires a known language", async (t) => {
|
||||
t.is(await checkEligibility({ rawLanguages: ["cobol"] }), undefined);
|
||||
});
|
||||
|
||||
test("getPerLanguageBundleLanguage explains why the CodeQL CLI may need packs for other languages before checking the languages", async (t) => {
|
||||
// Without a language, the explanation would otherwise suggest requesting a single language.
|
||||
for (const rawLanguages of [["java"], undefined]) {
|
||||
const messages: LoggedMessage[] = [];
|
||||
const language = await checkEligibility(
|
||||
{ rawLanguages, otherLanguagePacksReason: "an example reason" },
|
||||
{ logger: getRecordingLogger(messages, { logToConsole: false }) },
|
||||
);
|
||||
|
||||
t.is(language, undefined);
|
||||
t.deepEqual(
|
||||
messages.map((message) => message.message),
|
||||
["Not using a per-language CodeQL bundle since an example reason."],
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("getPerLanguageBundleLanguage requires a zstd bundle", async (t) => {
|
||||
t.is(await checkEligibility({ compressionMethod: "gzip" }), undefined);
|
||||
});
|
||||
@@ -142,9 +162,7 @@ test("getPerLanguageBundleLanguage explains a disabled feature before checking e
|
||||
t.is(language, undefined);
|
||||
t.deepEqual(
|
||||
messages.map((message) => message.message),
|
||||
[
|
||||
"Not using a per-language CodeQL bundle since the per_language_bundles feature is disabled.",
|
||||
],
|
||||
["Not using a per-language CodeQL bundle since the feature is disabled."],
|
||||
);
|
||||
});
|
||||
|
||||
@@ -155,6 +173,7 @@ test("getPerLanguageBundleLanguage skips only the release version check for the
|
||||
for (const overrides of [
|
||||
{ rawLanguages: undefined },
|
||||
{ rawLanguages: ["java", "python"] },
|
||||
{ otherLanguagePacksReason: "an example reason" },
|
||||
{ compressionMethod: "gzip" as const },
|
||||
{ platform: BundlePlatform.Osx64 },
|
||||
{ variant: GitHubVariant.GHES },
|
||||
@@ -173,3 +192,106 @@ test("getPerLanguageBundleLanguage skips only the release version check for the
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
||||
/** Query configuration inputs that configure nothing. */
|
||||
const NO_QUERY_CONFIG: QueryConfigInputs = {
|
||||
configFile: undefined,
|
||||
configInput: undefined,
|
||||
queriesInput: undefined,
|
||||
extraQueriesProperty: undefined,
|
||||
};
|
||||
|
||||
test("getOtherLanguagePacksReason returns undefined when no queries are configured", (t) => {
|
||||
t.is(getOtherLanguagePacksReason(NO_QUERY_CONFIG), undefined);
|
||||
});
|
||||
|
||||
test("getOtherLanguagePacksReason returns undefined for built-in query suites", (t) => {
|
||||
for (const queries of [
|
||||
"security-extended",
|
||||
"+security-and-quality",
|
||||
" security-extended , code-quality ",
|
||||
]) {
|
||||
t.is(
|
||||
getOtherLanguagePacksReason({
|
||||
...NO_QUERY_CONFIG,
|
||||
queriesInput: queries,
|
||||
extraQueriesProperty: queries,
|
||||
}),
|
||||
undefined,
|
||||
queries,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("getOtherLanguagePacksReason returns undefined for a config input that only uses default setup properties", (t) => {
|
||||
t.is(
|
||||
getOtherLanguagePacksReason({
|
||||
...NO_QUERY_CONFIG,
|
||||
// The configuration from the `config` input that default setup passes.
|
||||
configInput: {
|
||||
"default-setup": {
|
||||
org: { "model-packs": ["github/immutable-actions-list@0.0.1"] },
|
||||
},
|
||||
"threat-models": [],
|
||||
},
|
||||
}),
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
||||
test("getOtherLanguagePacksReason explains a configuration file", (t) => {
|
||||
t.is(
|
||||
getOtherLanguagePacksReason({
|
||||
...NO_QUERY_CONFIG,
|
||||
configFile: "./.github/codeql/codeql-config.yml",
|
||||
}),
|
||||
"the configuration file './.github/codeql/codeql-config.yml' may use queries that need " +
|
||||
"library packs for other languages",
|
||||
);
|
||||
});
|
||||
|
||||
test("getOtherLanguagePacksReason explains a config input that uses other properties", (t) => {
|
||||
t.is(
|
||||
getOtherLanguagePacksReason({
|
||||
...NO_QUERY_CONFIG,
|
||||
configInput: { queries: [{ uses: "./queries/show_ifs.ql" }] },
|
||||
}),
|
||||
"the 'config' input may use queries that need library packs for other languages",
|
||||
);
|
||||
});
|
||||
|
||||
test("getOtherLanguagePacksReason explains the first query in the queries input that isn't a built-in query suite", (t) => {
|
||||
t.is(
|
||||
getOtherLanguagePacksReason({
|
||||
...NO_QUERY_CONFIG,
|
||||
queriesInput:
|
||||
"+security-extended, ./queries/show_ifs.ql, octo-org/queries@main",
|
||||
}),
|
||||
"the query './queries/show_ifs.ql' from the 'queries' input may need library packs for " +
|
||||
"other languages",
|
||||
);
|
||||
});
|
||||
|
||||
test("getOtherLanguagePacksReason explains a query in the extra queries repository property that isn't a built-in query suite", (t) => {
|
||||
t.is(
|
||||
getOtherLanguagePacksReason({
|
||||
...NO_QUERY_CONFIG,
|
||||
extraQueriesProperty: "+octo-org/queries/show_ifs.ql@main",
|
||||
}),
|
||||
"the query 'octo-org/queries/show_ifs.ql@main' from the 'github-codeql-extra-queries' " +
|
||||
"repository property may need library packs for other languages",
|
||||
);
|
||||
});
|
||||
|
||||
test("getOtherLanguagePacksReason throws a ConfigurationError for a '+' with no queries after it", (t) => {
|
||||
// Loading the configuration would throw the same errors.
|
||||
for (const inputs of [
|
||||
{ queriesInput: "+" },
|
||||
{ extraQueriesProperty: " + " },
|
||||
]) {
|
||||
t.throws(
|
||||
() => getOtherLanguagePacksReason({ ...NO_QUERY_CONFIG, ...inputs }),
|
||||
{ instanceOf: ConfigurationError },
|
||||
);
|
||||
}
|
||||
});
|
||||
+115
-1
@@ -2,7 +2,15 @@ import * as semver from "semver";
|
||||
|
||||
import { ActionState } from "./action-common";
|
||||
import { isGitHubHostedRunner } from "./actions-util";
|
||||
import {
|
||||
defaultSuites,
|
||||
matchesDefaultSetupConfigSchema,
|
||||
parseQueriesFromInput,
|
||||
QuerySpec,
|
||||
UserConfig,
|
||||
} from "./config/db-config";
|
||||
import { Feature } from "./feature-flags";
|
||||
import { RepositoryPropertyName } from "./feature-flags/properties";
|
||||
import { BuiltInLanguage, parseBuiltInLanguage } from "./languages";
|
||||
import { BundlePlatform } from "./platform";
|
||||
import * as tar from "./tar";
|
||||
@@ -31,10 +39,95 @@ const PER_LANGUAGE_BUNDLE_LANGUAGES: Readonly<
|
||||
[BundlePlatform.Win64]: new Set(),
|
||||
};
|
||||
|
||||
/** Query configuration that is known before CodeQL is set up. */
|
||||
export interface QueryConfigInputs {
|
||||
/** The configuration file from the `config-file` input or repository property. */
|
||||
configFile: string | undefined;
|
||||
/** The configuration from the `config` input. */
|
||||
configInput: UserConfig | undefined;
|
||||
/** The `queries` input. */
|
||||
queriesInput: string | undefined;
|
||||
/** The `github-codeql-extra-queries` repository property. */
|
||||
extraQueriesProperty: string | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Explains why the configured queries may need library packs for languages other than the one
|
||||
* being analyzed, which a per-language bundle doesn't contain. Returns `undefined` if the only
|
||||
* queries that these inputs add are built-in query suites. The `packs` input doesn't matter, since
|
||||
* query packs are downloaded together with their dependencies.
|
||||
*
|
||||
* Any configuration file is assumed to configure such queries, since reading it may need file or API
|
||||
* access. So is the `config` input, unless it only sets the properties that default setup is known
|
||||
* to set (see `matchesDefaultSetupConfigSchema`).
|
||||
*
|
||||
* @throws A `ConfigurationError` if the `queries` input or the `github-codeql-extra-queries`
|
||||
* repository property is a '+' with no queries after it, unless an input that's checked earlier
|
||||
* already gives a reason.
|
||||
*/
|
||||
export function getOtherLanguagePacksReason(
|
||||
inputs: QueryConfigInputs,
|
||||
): string | undefined {
|
||||
if (inputs.configFile !== undefined) {
|
||||
return (
|
||||
`the configuration file '${inputs.configFile}' may use queries that need library packs ` +
|
||||
"for other languages"
|
||||
);
|
||||
}
|
||||
|
||||
// The `config` input can configure queries in the same way as a configuration file. The
|
||||
// properties that default setup is known to set, listed in `DEFAULT_SETUP_CONFIG_SCHEMA` in
|
||||
// `config/db-config.ts`, don't add queries.
|
||||
if (
|
||||
inputs.configInput !== undefined &&
|
||||
!matchesDefaultSetupConfigSchema(inputs.configInput)
|
||||
) {
|
||||
return "the 'config' input may use queries that need library packs for other languages";
|
||||
}
|
||||
|
||||
// We can't tell which language a local query or a query from another repository is for without
|
||||
// loading it, and CodeQL resolves the library packs for every configured query, including those
|
||||
// for languages that aren't being analyzed.
|
||||
const query = findNonBuiltInQuery(
|
||||
parseQueriesFromInput(inputs.queriesInput).input,
|
||||
);
|
||||
if (query !== undefined) {
|
||||
return `the query '${query}' from the 'queries' input may need library packs for other languages`;
|
||||
}
|
||||
const extraQuery = findNonBuiltInQuery(
|
||||
parseQueriesFromInput(
|
||||
inputs.extraQueriesProperty,
|
||||
RepositoryPropertyName.EXTRA_QUERIES,
|
||||
).input,
|
||||
);
|
||||
if (extraQuery !== undefined) {
|
||||
return (
|
||||
`the query '${extraQuery}' from the '${RepositoryPropertyName.EXTRA_QUERIES}' repository ` +
|
||||
"property may need library packs for other languages"
|
||||
);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Returns the `uses` value of the first of `queries` that isn't a built-in query suite. */
|
||||
function findNonBuiltInQuery(
|
||||
queries: QuerySpec[] | undefined,
|
||||
): string | undefined {
|
||||
return queries?.find((query) => !defaultSuites.has(query.uses))?.uses;
|
||||
}
|
||||
|
||||
/** Inputs that determine whether we may download a per-language bundle. */
|
||||
export interface PerLanguageBundleOptions {
|
||||
/** Explicit input only: autodetection needs a CLI instance. */
|
||||
rawLanguages: string[] | undefined;
|
||||
/**
|
||||
* Why the CodeQL CLI may need packs for other languages, for example because of the configured
|
||||
* queries, or `undefined` if it won't. If defined, the combined bundle is used, and this reason is
|
||||
* logged to complete the sentence "Not using a per-language CodeQL bundle since ...". See
|
||||
* `getOtherLanguagePacksReason`.
|
||||
*/
|
||||
otherLanguagePacksReason: string | undefined;
|
||||
/** Requested CLI version, if known. Ignored when requesting the latest nightly. */
|
||||
cliVersion: string | undefined;
|
||||
compressionMethod: tar.CompressionMethod;
|
||||
@@ -56,6 +149,7 @@ export async function getPerLanguageBundleLanguage(
|
||||
): Promise<BuiltInLanguage | undefined> {
|
||||
const {
|
||||
rawLanguages,
|
||||
otherLanguagePacksReason,
|
||||
cliVersion,
|
||||
compressionMethod,
|
||||
platform,
|
||||
@@ -69,7 +163,14 @@ export async function getPerLanguageBundleLanguage(
|
||||
};
|
||||
|
||||
if (!(await features.getValue(Feature.PerLanguageBundles))) {
|
||||
return explain(`the ${Feature.PerLanguageBundles} feature is disabled`);
|
||||
return explain("the feature is disabled");
|
||||
}
|
||||
|
||||
// A defined reason means the CodeQL CLI may need packs for other languages, for example because
|
||||
// of the configured queries. That applies whichever languages were requested, so check it first
|
||||
// to avoid suggesting that requesting a single language would be enough.
|
||||
if (otherLanguagePacksReason !== undefined) {
|
||||
return explain(otherLanguagePacksReason);
|
||||
}
|
||||
|
||||
if (rawLanguages?.length !== 1) {
|
||||
@@ -131,3 +232,16 @@ export async function getPerLanguageBundleLanguage(
|
||||
|
||||
return language;
|
||||
}
|
||||
|
||||
/** Explains why an eligible per-language bundle is being replaced by a combined bundle. */
|
||||
export function logPerLanguageBundleFallback(
|
||||
{ logger }: ActionState<["Logger"]>,
|
||||
language: BuiltInLanguage,
|
||||
location: string,
|
||||
): void {
|
||||
logger.warning(
|
||||
`No per-language CodeQL bundle for '${language}' was found at ${location}, so ` +
|
||||
"falling back to the bundle that contains all languages. This analysis will still " +
|
||||
"produce correct results, but will take longer to set up.",
|
||||
);
|
||||
}
|
||||
+8
-1
@@ -1,6 +1,7 @@
|
||||
import * as fs from "fs";
|
||||
|
||||
import { Logger } from "../logging";
|
||||
import { getErrorMessage } from "../util";
|
||||
|
||||
import * as sarif from "sarif";
|
||||
|
||||
@@ -48,7 +49,13 @@ export function getToolNames(sarifFile: Partial<sarif.Log>): string[] {
|
||||
* @returns The resulting JSON value, cast to a SARIF `Log`.
|
||||
*/
|
||||
export function readSarifFile(sarifFilePath: string): Partial<sarif.Log> {
|
||||
return JSON.parse(fs.readFileSync(sarifFilePath, "utf8")) as sarif.Log;
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(sarifFilePath, "utf8")) as sarif.Log;
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Parsing SARIF file at '${sarifFilePath}' failed: ${getErrorMessage(err)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Takes a list of paths to sarif files and combines them together,
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import * as core from "@actions/core";
|
||||
|
||||
import { Action, ActionState, runInActions } from "./action-common";
|
||||
import {
|
||||
Action,
|
||||
ActionState,
|
||||
extendActionState,
|
||||
runInActions,
|
||||
} from "./action-common";
|
||||
import {
|
||||
getActionVersion,
|
||||
getOptionalInput,
|
||||
@@ -131,7 +136,9 @@ async function run(
|
||||
);
|
||||
const repositoryProperties = repositoryPropertiesResult.orElse({});
|
||||
|
||||
const actionStateWithFeatures = { ...actionState, features };
|
||||
const actionStateWithFeatures = extendActionState(actionState, {
|
||||
features,
|
||||
});
|
||||
|
||||
const statusReportBase = await createStatusReportBase(
|
||||
ActionName.SetupCodeQL,
|
||||
@@ -165,6 +172,12 @@ async function run(
|
||||
gitHubVersion.type,
|
||||
codeQLDefaultVersionInfo,
|
||||
rawLanguages,
|
||||
// CodeQL resolves the dependencies of queries that aren't in compiled packs from the bundle,
|
||||
// so the queries that the workflow runs with this CLI may need library packs for languages
|
||||
// other than those in the `languages` input. That input therefore only informs the choice of
|
||||
// CLI version.
|
||||
"the 'setup-codeql' Action can't tell whether the queries that the workflow runs will need " +
|
||||
"library packs for other languages",
|
||||
analysisKinds.length === 1 &&
|
||||
analysisKinds[0] === AnalysisKind.CodeScanning,
|
||||
features,
|
||||
@@ -178,7 +191,7 @@ async function run(
|
||||
core.setOutput("codeql-path", codeql.getPath());
|
||||
core.setOutput("codeql-version", (await codeql.getVersion()).version);
|
||||
|
||||
core.exportVariable(EnvVar.SETUP_CODEQL_ACTION_HAS_RUN, "true");
|
||||
actionState.env.export(EnvVar.SETUP_CODEQL_ACTION_HAS_RUN, "true");
|
||||
} catch (unwrappedError) {
|
||||
const error = wrapError(unwrappedError);
|
||||
core.setFailed(error.message);
|
||||
|
||||
+71
-44
@@ -157,6 +157,7 @@ test.serial(
|
||||
url,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -242,6 +243,7 @@ for (const {
|
||||
"linked",
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -275,6 +277,7 @@ test.serial(
|
||||
"latest",
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -320,6 +323,7 @@ test.serial(
|
||||
GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
logger,
|
||||
@@ -377,6 +381,7 @@ test.serial(
|
||||
GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
logger,
|
||||
@@ -425,6 +430,7 @@ test.serial(
|
||||
"nightly",
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -435,7 +441,7 @@ test.serial(
|
||||
|
||||
// Check that the `CodeQLToolsSource` object matches our expectations.
|
||||
const expectedVersion = `0.0.0-${expectedDate}`;
|
||||
const expectedURL = `https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/${expectedTag}/${setupCodeql.getCodeQLBundleName("zstd")}`;
|
||||
const expectedURL = `https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/${expectedTag}/codeql-bundle-linux64.tar.zst`;
|
||||
t.deepEqual(source, {
|
||||
bundle: { kind: "combined", url: expectedURL },
|
||||
bundleVersion: expectedDate,
|
||||
@@ -452,6 +458,7 @@ test.serial(
|
||||
GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
["javascript"],
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
logger,
|
||||
@@ -495,6 +502,7 @@ test.serial(
|
||||
undefined,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -505,7 +513,7 @@ test.serial(
|
||||
|
||||
// Check that the `CodeQLToolsSource` object matches our expectations.
|
||||
const expectedVersion = `0.0.0-${expectedDate}`;
|
||||
const expectedURL = `https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/${expectedTag}/${setupCodeql.getCodeQLBundleName("zstd")}`;
|
||||
const expectedURL = `https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/${expectedTag}/codeql-bundle-linux64.tar.zst`;
|
||||
t.deepEqual(source, {
|
||||
bundle: { kind: "combined", url: expectedURL },
|
||||
bundleVersion: expectedDate,
|
||||
@@ -550,6 +558,7 @@ for (const bundlePath of [
|
||||
GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
createFeatures([]),
|
||||
getRecordingLogger(messages),
|
||||
@@ -603,6 +612,7 @@ test.serial(
|
||||
GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
createFeatures([Feature.CleanupToolcacheBundles]),
|
||||
getRunnerLogger(true),
|
||||
@@ -636,6 +646,7 @@ for (const toolsInput of ["nightly", "nightly-latest"]) {
|
||||
toolsInput,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
["java"],
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -671,12 +682,23 @@ test.serial(
|
||||
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
for (const { languages, features } of [
|
||||
for (const { languages, otherLanguagePacksReason, features } of [
|
||||
// The per-language feature is disabled.
|
||||
{ languages: ["java"], features: createFeatures([]) },
|
||||
{
|
||||
languages: ["java"],
|
||||
otherLanguagePacksReason: undefined,
|
||||
features: createFeatures([]),
|
||||
},
|
||||
// More than one language requires a combined bundle.
|
||||
{
|
||||
languages: ["java", "python"],
|
||||
otherLanguagePacksReason: undefined,
|
||||
features: createFeatures([Feature.PerLanguageBundles]),
|
||||
},
|
||||
// The configured queries may need library packs for other languages.
|
||||
{
|
||||
languages: ["java"],
|
||||
otherLanguagePacksReason: "an example reason",
|
||||
features: createFeatures([Feature.PerLanguageBundles]),
|
||||
},
|
||||
]) {
|
||||
@@ -684,6 +706,7 @@ test.serial(
|
||||
"nightly",
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
languages,
|
||||
otherLanguagePacksReason,
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -718,6 +741,7 @@ for (const perLanguageBundles of [false, true]) {
|
||||
undefined, // toolsInput: the nightly is selected by ForceNightly
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
["java"],
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -777,6 +801,7 @@ for (const date of ["20200101", "30260213"]) {
|
||||
url,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
["java"],
|
||||
undefined, // otherLanguagePacksReason
|
||||
false,
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -804,6 +829,7 @@ for (const date of ["20200101", "30260213"]) {
|
||||
GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
["java"],
|
||||
undefined, // otherLanguagePacksReason
|
||||
false,
|
||||
features,
|
||||
logger,
|
||||
@@ -834,6 +860,7 @@ test.serial(
|
||||
"toolcache",
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
["java"],
|
||||
undefined, // otherLanguagePacksReason
|
||||
false,
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -875,6 +902,7 @@ test.serial(
|
||||
"toolcache",
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -944,6 +972,7 @@ const toolcacheInputFallbackMacro = makeMacro({
|
||||
"toolcache",
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -1081,6 +1110,7 @@ test.serial(
|
||||
undefined,
|
||||
overlayMatchEnabledVersions,
|
||||
["javascript"],
|
||||
undefined, // otherLanguagePacksReason
|
||||
true,
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -1119,6 +1149,7 @@ test.serial(
|
||||
undefined,
|
||||
overlayMatchEnabledVersions,
|
||||
["javascript"],
|
||||
undefined, // otherLanguagePacksReason
|
||||
false,
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -1143,30 +1174,6 @@ const PER_LANGUAGE_CLI_VERSION = {
|
||||
],
|
||||
};
|
||||
|
||||
test.serial(
|
||||
"getCodeQLBundleName returns a per-language bundle name only when a language is specified",
|
||||
(t) => {
|
||||
sinon.stub(process, "platform").value("linux");
|
||||
sinon.stub(process, "arch").value("x64");
|
||||
t.is(
|
||||
setupCodeql.getCodeQLBundleName("zstd", BuiltInLanguage.java),
|
||||
"codeql-bundle-java-linux64.tar.zst",
|
||||
);
|
||||
t.is(
|
||||
setupCodeql.getCodeQLBundleName("zstd"),
|
||||
"codeql-bundle-linux64.tar.zst",
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test.serial("getCodeQLBundleName names the Swift bundle for macOS", (t) => {
|
||||
sinon.stub(process, "platform").value("darwin");
|
||||
t.is(
|
||||
setupCodeql.getCodeQLBundleName("zstd", BuiltInLanguage.swift),
|
||||
"codeql-bundle-swift-osx64.tar.zst",
|
||||
);
|
||||
});
|
||||
|
||||
test.serial(
|
||||
"getCodeQLSource downloads the per-language bundle for a single explicit language",
|
||||
async (t) => {
|
||||
@@ -1180,6 +1187,7 @@ test.serial(
|
||||
undefined,
|
||||
PER_LANGUAGE_CLI_VERSION,
|
||||
["java-kotlin"],
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
@@ -1209,7 +1217,7 @@ test.serial(
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"getCodeQLSource downloads the combined bundle when the feature is disabled",
|
||||
"getCodeQLSource downloads the combined bundle when per-language selection is ineligible",
|
||||
async (t) => {
|
||||
sinon.stub(process, "platform").value("linux");
|
||||
sinon.stub(process, "arch").value("x64");
|
||||
@@ -1217,22 +1225,33 @@ test.serial(
|
||||
|
||||
await withTmpDir(async (tmpDir) => {
|
||||
setupActionsVars(tmpDir, tmpDir);
|
||||
const source = await setupCodeql.getCodeQLSource(
|
||||
undefined,
|
||||
PER_LANGUAGE_CLI_VERSION,
|
||||
["java"],
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
true, // tarSupportsZstd
|
||||
createFeatures([]),
|
||||
getRunnerLogger(true),
|
||||
);
|
||||
for (const { otherLanguagePacksReason, features } of [
|
||||
// The per-language feature is disabled.
|
||||
{ otherLanguagePacksReason: undefined, features: createFeatures([]) },
|
||||
// The configured queries may need library packs for other languages.
|
||||
{
|
||||
otherLanguagePacksReason: "an example reason",
|
||||
features: createFeatures([Feature.PerLanguageBundles]),
|
||||
},
|
||||
]) {
|
||||
const source = await setupCodeql.getCodeQLSource(
|
||||
undefined,
|
||||
PER_LANGUAGE_CLI_VERSION,
|
||||
["java"],
|
||||
otherLanguagePacksReason,
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
SAMPLE_DOTCOM_API_DETAILS,
|
||||
GitHubVariant.DOTCOM,
|
||||
true, // tarSupportsZstd
|
||||
features,
|
||||
getRunnerLogger(true),
|
||||
);
|
||||
|
||||
t.is(source.sourceType, "download");
|
||||
if (source.sourceType === "download") {
|
||||
t.true(source.bundle.url.endsWith("/codeql-bundle-linux64.tar.zst"));
|
||||
t.is(source.bundle.kind, "combined");
|
||||
t.is(source.sourceType, "download");
|
||||
if (source.sourceType === "download") {
|
||||
t.true(source.bundle.url.endsWith("/codeql-bundle-linux64.tar.zst"));
|
||||
t.is(source.bundle.kind, "combined");
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -1292,6 +1311,7 @@ for (const fallback of [false, true]) {
|
||||
GitHubVariant.DOTCOM,
|
||||
PER_LANGUAGE_CLI_VERSION,
|
||||
["java"],
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
createFeatures([Feature.PerLanguageBundles]),
|
||||
getRunnerLogger(true),
|
||||
@@ -1387,6 +1407,7 @@ for (const bundle of ["per-language", "combined", "fallback"] as const) {
|
||||
GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
bundle === "combined" ? ["javascript", "python"] : ["javascript"],
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
logger,
|
||||
@@ -1467,6 +1488,7 @@ for (const bundle of ["per-language", "combined", "fallback"] as const) {
|
||||
GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
["javascript"],
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
features,
|
||||
logger,
|
||||
@@ -1502,6 +1524,7 @@ for (const asset of [
|
||||
GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
createFeatures([]),
|
||||
getRecordingLogger(messages),
|
||||
@@ -1556,6 +1579,7 @@ for (const error of [
|
||||
GitHubVariant.DOTCOM,
|
||||
PER_LANGUAGE_CLI_VERSION,
|
||||
["java"],
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
createFeatures([Feature.PerLanguageBundles]),
|
||||
getRunnerLogger(true),
|
||||
@@ -1591,6 +1615,7 @@ test.serial(
|
||||
GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
createFeatures([]),
|
||||
getRunnerLogger(true),
|
||||
@@ -2263,6 +2288,7 @@ test.serial(
|
||||
GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
createFeatures([]),
|
||||
getRunnerLogger(true),
|
||||
@@ -2302,6 +2328,7 @@ test.serial(
|
||||
GitHubVariant.DOTCOM,
|
||||
SAMPLE_DEFAULT_CLI_VERSION,
|
||||
undefined, // rawLanguages
|
||||
undefined, // otherLanguagePacksReason
|
||||
false, // useOverlayAwareDefaultCliVersion
|
||||
createFeatures([Feature.CleanupToolcacheBundles]),
|
||||
getRunnerLogger(true),
|
||||
|
||||
+36
-66
@@ -3,7 +3,6 @@ import { OutgoingHttpHeaders } from "http";
|
||||
import * as path from "path";
|
||||
import { performance } from "perf_hooks";
|
||||
|
||||
import * as core from "@actions/core";
|
||||
import * as toolcache from "@actions/tool-cache";
|
||||
import { default as deepEqual } from "fast-deep-equal";
|
||||
import * as semver from "semver";
|
||||
@@ -17,14 +16,19 @@ import {
|
||||
isRunningLocalAction,
|
||||
} from "./actions-util";
|
||||
import * as api from "./api-client";
|
||||
import { CodeQLBundle, getCodeQLBundleFromUrl } from "./codeql-bundle";
|
||||
import {
|
||||
CodeQLBundle,
|
||||
CodeQLDownloadSource,
|
||||
getCodeQLBundleFromUrl,
|
||||
getCodeQLBundleName,
|
||||
} from "./codeql-bundle";
|
||||
import * as defaults from "./defaults.json";
|
||||
import {
|
||||
addNoLanguageDiagnostic,
|
||||
makeDiagnostic,
|
||||
makeTelemetryDiagnostic,
|
||||
} from "./diagnostics";
|
||||
import { EnvVar, getEnv } from "./environment";
|
||||
import { EnvVar, exportEnvVar, getEnv } from "./environment";
|
||||
import {
|
||||
CODEQL_VERSION_ZSTD_BUNDLE,
|
||||
CodeQLDefaultVersionInfo,
|
||||
@@ -35,7 +39,10 @@ import {
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { getCodeQlVersionsForOverlayBaseDatabases } from "./overlay/caching";
|
||||
import { getPerLanguageBundleLanguage } from "./per-language-bundles";
|
||||
import {
|
||||
getPerLanguageBundleLanguage,
|
||||
logPerLanguageBundleFallback,
|
||||
} from "./per-language-bundles";
|
||||
import { getBundlePlatform } from "./platform";
|
||||
import * as tar from "./tar";
|
||||
import {
|
||||
@@ -49,6 +56,8 @@ import {
|
||||
import * as util from "./util";
|
||||
import { isGoodVersion } from "./util";
|
||||
|
||||
export type { CodeQLDownloadSource } from "./codeql-bundle";
|
||||
|
||||
export enum ToolsSource {
|
||||
Unknown = "UNKNOWN",
|
||||
Local = "LOCAL",
|
||||
@@ -64,41 +73,6 @@ const CODEQL_BUNDLE_VERSION_ALIAS: string[] = ["linked", "latest"];
|
||||
const CODEQL_NIGHTLY_TOOLS_INPUTS = ["nightly", "nightly-latest"];
|
||||
const CODEQL_TOOLCACHE_INPUT = "toolcache";
|
||||
|
||||
function getCodeQLBundleExtension(
|
||||
compressionMethod: tar.CompressionMethod,
|
||||
): string {
|
||||
switch (compressionMethod) {
|
||||
case "gzip":
|
||||
return ".tar.gz";
|
||||
case "zstd":
|
||||
return ".tar.zst";
|
||||
default:
|
||||
util.assertNever(compressionMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the CodeQL bundle asset to download.
|
||||
*
|
||||
* @param compressionMethod The compression method of the bundle.
|
||||
* @param language Optional language for a per-language bundle. If omitted, returns a combined bundle name.
|
||||
*/
|
||||
export function getCodeQLBundleName(
|
||||
compressionMethod: tar.CompressionMethod,
|
||||
language?: BuiltInLanguage,
|
||||
): string {
|
||||
const extension = getCodeQLBundleExtension(compressionMethod);
|
||||
const platform = getBundlePlatform();
|
||||
|
||||
if (platform === undefined) {
|
||||
return `codeql-bundle${extension}`;
|
||||
}
|
||||
if (language !== undefined) {
|
||||
return `codeql-bundle-${language}-${platform}${extension}`;
|
||||
}
|
||||
return `codeql-bundle-${platform}${extension}`;
|
||||
}
|
||||
|
||||
export function getCodeQLActionRepository(logger: Logger): string {
|
||||
if (isRunningLocalAction()) {
|
||||
// This handles the case where the Action does not come from an Action repository,
|
||||
@@ -223,22 +197,6 @@ export function convertToSemVer(version: string, logger: Logger): string {
|
||||
return s;
|
||||
}
|
||||
|
||||
/** A resolved download, including its bundle identity and version. */
|
||||
export interface CodeQLDownloadSource {
|
||||
/** Distinguishes downloads from local archives and cached installations. */
|
||||
sourceType: "download";
|
||||
/** The bundle to download. */
|
||||
bundle: CodeQLBundle;
|
||||
/** The compression format of the bundle archive. */
|
||||
compressionMethod: tar.CompressionMethod;
|
||||
/** Bundle version of the tools, if known. */
|
||||
bundleVersion?: string;
|
||||
/** Requested CLI version, if known. */
|
||||
cliVersion?: string;
|
||||
/** Resolved version for telemetry, independent of whether the bundle can be cached. */
|
||||
toolsVersion: string;
|
||||
}
|
||||
|
||||
export type CodeQLToolsSource =
|
||||
| {
|
||||
codeqlTarPath: string;
|
||||
@@ -418,6 +376,9 @@ async function resolveDefaultCliVersion(
|
||||
* @param toolsInput The argument provided for the `tools` input, if any.
|
||||
* @param defaultCliVersion The default CLI version that's linked to the CodeQL Action.
|
||||
* @param rawLanguages Raw set of languages.
|
||||
* @param otherLanguagePacksReason Why the CodeQL CLI may need packs for languages other than
|
||||
* `rawLanguages`, or `undefined` if it won't. If defined, the combined bundle is used. See
|
||||
* `PerLanguageBundleOptions.otherLanguagePacksReason`.
|
||||
* @param useOverlayAwareDefaultCliVersion Whether to select an overlay-aware default CLI version.
|
||||
* @param apiDetails Information about the GitHub API.
|
||||
* @param variant The GitHub variant we are running on.
|
||||
@@ -431,6 +392,7 @@ export async function getCodeQLSource(
|
||||
toolsInput: string | undefined,
|
||||
defaultCliVersion: CodeQLDefaultVersionInfo,
|
||||
rawLanguages: string[] | undefined,
|
||||
otherLanguagePacksReason: string | undefined,
|
||||
useOverlayAwareDefaultCliVersion: boolean,
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
variant: util.GitHubVariant,
|
||||
@@ -519,6 +481,7 @@ export async function getCodeQLSource(
|
||||
bundle = await getLatestNightlyBundle(
|
||||
{ env: getEnv(), features, logger },
|
||||
rawLanguages,
|
||||
otherLanguagePacksReason,
|
||||
variant,
|
||||
);
|
||||
toolsInput = bundle.url;
|
||||
@@ -757,13 +720,15 @@ export async function getCodeQLSource(
|
||||
? "zstd"
|
||||
: "gzip";
|
||||
|
||||
const platform = getBundlePlatform();
|
||||
const perLanguageBundleLanguage = await getPerLanguageBundleLanguage(
|
||||
{ env: getEnv(), features, logger },
|
||||
{
|
||||
rawLanguages,
|
||||
otherLanguagePacksReason,
|
||||
cliVersion,
|
||||
compressionMethod,
|
||||
platform: getBundlePlatform(),
|
||||
platform,
|
||||
variant,
|
||||
},
|
||||
);
|
||||
@@ -773,7 +738,7 @@ export async function getCodeQLSource(
|
||||
getCodeQLBundleDownloadURL(
|
||||
bundleTagName,
|
||||
apiDetails,
|
||||
getCodeQLBundleName(compressionMethod, language),
|
||||
getCodeQLBundleName(compressionMethod, platform, language),
|
||||
logger,
|
||||
);
|
||||
|
||||
@@ -1041,6 +1006,7 @@ export async function setupCodeQLBundle(
|
||||
variant: util.GitHubVariant,
|
||||
defaultCliVersion: CodeQLDefaultVersionInfo,
|
||||
rawLanguages: string[] | undefined,
|
||||
otherLanguagePacksReason: string | undefined,
|
||||
useOverlayAwareDefaultCliVersion: boolean,
|
||||
features: FeatureEnablement,
|
||||
logger: Logger,
|
||||
@@ -1056,6 +1022,7 @@ export async function setupCodeQLBundle(
|
||||
toolsInput,
|
||||
defaultCliVersion,
|
||||
rawLanguages,
|
||||
otherLanguagePacksReason,
|
||||
useOverlayAwareDefaultCliVersion,
|
||||
apiDetails,
|
||||
variant,
|
||||
@@ -1103,7 +1070,7 @@ export async function setupCodeQLBundle(
|
||||
|
||||
// Record that this job now has a copy of the CodeQL tools, so that a later step doesn't delete
|
||||
// the toolcache out from under the path we are about to return.
|
||||
core.exportVariable(EnvVar.HAS_SET_UP_CODEQL, "true");
|
||||
exportEnvVar(EnvVar.HAS_SET_UP_CODEQL, "true");
|
||||
|
||||
return {
|
||||
codeqlFolder,
|
||||
@@ -1153,11 +1120,7 @@ export async function downloadCodeQLBundle(
|
||||
) {
|
||||
throw e;
|
||||
}
|
||||
logger.warning(
|
||||
`No per-language CodeQL bundle for '${bundle.language}' was found at ${bundle.url}, so ` +
|
||||
"falling back to the bundle that contains all languages. This analysis will still " +
|
||||
"produce correct results, but will take longer to set up.",
|
||||
);
|
||||
logPerLanguageBundleFallback(action, bundle.language, bundle.url);
|
||||
|
||||
const result = await downloadCodeQL(
|
||||
{
|
||||
@@ -1203,6 +1166,7 @@ function getTempExtractionDir(tempDir: string) {
|
||||
async function getLatestNightlyBundle(
|
||||
action: ActionState<["Logger", "ReadOnlyEnv", "FeatureFlags"]>,
|
||||
rawLanguages: string[] | undefined,
|
||||
otherLanguagePacksReason: string | undefined,
|
||||
variant: util.GitHubVariant,
|
||||
): Promise<CodeQLBundle> {
|
||||
const { logger } = action;
|
||||
@@ -1215,11 +1179,13 @@ async function getLatestNightlyBundle(
|
||||
? "zstd"
|
||||
: "gzip";
|
||||
|
||||
const platform = getBundlePlatform();
|
||||
const language = await getPerLanguageBundleLanguage(action, {
|
||||
rawLanguages,
|
||||
otherLanguagePacksReason,
|
||||
cliVersion: undefined,
|
||||
compressionMethod,
|
||||
platform: getBundlePlatform(),
|
||||
platform,
|
||||
variant,
|
||||
isLatestNightly: true,
|
||||
});
|
||||
@@ -1241,14 +1207,18 @@ async function getLatestNightlyBundle(
|
||||
}
|
||||
const assetUrl = (name: string) =>
|
||||
`https://github.com/${CODEQL_NIGHTLIES_REPOSITORY_OWNER}/${CODEQL_NIGHTLIES_REPOSITORY_NAME}/releases/download/${latestRelease.tag_name}/${name}`;
|
||||
const url = assetUrl(getCodeQLBundleName(compressionMethod, language));
|
||||
const url = assetUrl(
|
||||
getCodeQLBundleName(compressionMethod, platform, language),
|
||||
);
|
||||
return language === undefined
|
||||
? { kind: "combined", url }
|
||||
: {
|
||||
kind: "per-language",
|
||||
url,
|
||||
language,
|
||||
combinedBundleURL: assetUrl(getCodeQLBundleName(compressionMethod)),
|
||||
combinedBundleURL: assetUrl(
|
||||
getCodeQLBundleName(compressionMethod, platform),
|
||||
),
|
||||
};
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
|
||||
@@ -20,7 +20,7 @@ export async function runWrapper() {
|
||||
|
||||
try {
|
||||
// Restore inputs from `start-proxy` Action.
|
||||
actionsUtil.restoreInputs();
|
||||
actionsUtil.restoreInputs(logger);
|
||||
|
||||
// Kill the running proxy
|
||||
const pid = core.getState("proxy-process-pid");
|
||||
@@ -38,12 +38,6 @@ export async function runWrapper() {
|
||||
logger.info(
|
||||
"Debug mode is on. Uploading proxy log as Actions debugging artifact...",
|
||||
);
|
||||
if (config?.gitHubVersion.type === undefined) {
|
||||
logger.warning(
|
||||
`Did not upload debug artifacts because cannot determine the GitHub variant running.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
const gitHubVersion = await getGitHubVersion();
|
||||
checkGitHubVersionInRange(gitHubVersion, logger);
|
||||
|
||||
|
||||
@@ -3,7 +3,12 @@ import * as path from "path";
|
||||
|
||||
import * as core from "@actions/core";
|
||||
|
||||
import { Action, ActionState, runInActions } from "./action-common";
|
||||
import {
|
||||
Action,
|
||||
ActionState,
|
||||
extendActionState,
|
||||
runInActions,
|
||||
} from "./action-common";
|
||||
import * as actionsUtil from "./actions-util";
|
||||
import { getGitHubVersion } from "./api-client";
|
||||
import { FeatureEnablement, initFeatures } from "./feature-flags";
|
||||
@@ -98,7 +103,8 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) {
|
||||
};
|
||||
|
||||
// Start the Proxy
|
||||
const proxyBin = await getProxyBinaryPath(logger, features);
|
||||
const actionWithFeatures = extendActionState(action, { features });
|
||||
const proxyBin = await getProxyBinaryPath(actionWithFeatures);
|
||||
const proxyInfo = await startProxy(
|
||||
proxyBin,
|
||||
proxyConfig,
|
||||
|
||||
+83
-25
@@ -5,6 +5,7 @@ import * as toolcache from "@actions/tool-cache";
|
||||
import test, { ExecutionContext } from "ava";
|
||||
import sinon from "sinon";
|
||||
|
||||
import { ActionState } from "./action-common";
|
||||
import * as apiClient from "./api-client";
|
||||
import * as defaults from "./defaults.json";
|
||||
import { setUpFeatureFlagTests } from "./feature-flags/testing-util";
|
||||
@@ -12,12 +13,14 @@ import { UnvalidatedObject, validateSchema } from "./json";
|
||||
import { makeFromSchema } from "./json/testing-util";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import { getRunnerLogger, Logger } from "./logging";
|
||||
import { BundlePlatform, getBundlePlatform } from "./platform";
|
||||
import * as startProxyExports from "./start-proxy";
|
||||
import * as statusReport from "./status-report";
|
||||
import {
|
||||
assertNotLogged,
|
||||
checkExpectedLogMessages,
|
||||
createFeatures,
|
||||
initAllState,
|
||||
makeMacro,
|
||||
makeTestToken,
|
||||
RecordingLogger,
|
||||
@@ -685,6 +688,12 @@ test("getCredentials always returns ALWAYS_ENABLED_REGISTRY_TYPE credentials for
|
||||
}
|
||||
});
|
||||
|
||||
test("getProxyPackage - includes platform in name", (t) => {
|
||||
for (const platform of Object.values(BundlePlatform)) {
|
||||
t.true(startProxyExports.getProxyPackage(platform).includes(platform));
|
||||
}
|
||||
});
|
||||
|
||||
function mockGetApiClient(endpoints: any) {
|
||||
return (
|
||||
sinon
|
||||
@@ -721,6 +730,44 @@ function mockOfflineFeatures(tempDir: string, logger: Logger) {
|
||||
return setUpFeatureFlagTests(tempDir, logger, gitHubVersion);
|
||||
}
|
||||
|
||||
/** Gets the `BundlePlatform` based on the `action` state, but defaults to `Linux64` if undefined. */
|
||||
function getTestPlatform(action: ActionState<["Base"]>) {
|
||||
return (
|
||||
getBundlePlatform(action.platform, action.arch) ?? BundlePlatform.Linux64
|
||||
);
|
||||
}
|
||||
|
||||
test.serial(
|
||||
"getDownloadUrl logs unknown platforms/arch and defaults to linux64",
|
||||
async (t) => {
|
||||
const logger = new RecordingLogger();
|
||||
mockGetReleaseByTag();
|
||||
|
||||
await withTmpDir(async (tempDir) => {
|
||||
const features = mockOfflineFeatures(tempDir, logger);
|
||||
const state = initAllState({
|
||||
platform: "android",
|
||||
arch: "ppc",
|
||||
logger,
|
||||
features,
|
||||
});
|
||||
const info = await startProxyExports.getDownloadUrl(state);
|
||||
|
||||
t.is(info.version, startProxyExports.UPDATEJOB_PROXY_VERSION);
|
||||
t.is(
|
||||
info.url,
|
||||
startProxyExports.getFallbackUrl(
|
||||
startProxyExports.getProxyPackage(BundlePlatform.Linux64),
|
||||
),
|
||||
);
|
||||
|
||||
t.true(
|
||||
logger.hasMessage(`Unsupported platform android on architecture ppc`),
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
test.serial(
|
||||
"getDownloadUrl returns fallback when `getReleaseByVersion` rejects",
|
||||
async (t) => {
|
||||
@@ -729,15 +776,15 @@ test.serial(
|
||||
|
||||
await withTmpDir(async (tempDir) => {
|
||||
const features = mockOfflineFeatures(tempDir, logger);
|
||||
const info = await startProxyExports.getDownloadUrl(
|
||||
getRunnerLogger(true),
|
||||
features,
|
||||
);
|
||||
const state = initAllState({ logger, features });
|
||||
const info = await startProxyExports.getDownloadUrl(state);
|
||||
|
||||
t.is(info.version, startProxyExports.UPDATEJOB_PROXY_VERSION);
|
||||
t.is(
|
||||
info.url,
|
||||
startProxyExports.getFallbackUrl(startProxyExports.getProxyPackage()),
|
||||
startProxyExports.getFallbackUrl(
|
||||
startProxyExports.getProxyPackage(getTestPlatform(state)),
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
@@ -751,18 +798,18 @@ test.serial(
|
||||
|
||||
await withTmpDir(async (tempDir) => {
|
||||
const features = mockOfflineFeatures(tempDir, logger);
|
||||
const state = initAllState({ logger, features });
|
||||
|
||||
for (const assets of testAssets) {
|
||||
const stub = mockGetReleaseByTag(assets);
|
||||
const info = await startProxyExports.getDownloadUrl(
|
||||
getRunnerLogger(true),
|
||||
features,
|
||||
);
|
||||
const info = await startProxyExports.getDownloadUrl(state);
|
||||
|
||||
t.is(info.version, startProxyExports.UPDATEJOB_PROXY_VERSION);
|
||||
t.is(
|
||||
info.url,
|
||||
startProxyExports.getFallbackUrl(startProxyExports.getProxyPackage()),
|
||||
startProxyExports.getFallbackUrl(
|
||||
startProxyExports.getProxyPackage(getTestPlatform(state)),
|
||||
),
|
||||
);
|
||||
|
||||
stub.restore();
|
||||
@@ -773,18 +820,19 @@ test.serial(
|
||||
|
||||
test.serial("getDownloadUrl returns matching release asset", async (t) => {
|
||||
const logger = new RecordingLogger();
|
||||
const state = initAllState({ logger });
|
||||
const assets = [
|
||||
{ name: "foo", url: "other-url" },
|
||||
{ name: startProxyExports.getProxyPackage(), url: "url-we-want" },
|
||||
{
|
||||
name: startProxyExports.getProxyPackage(getTestPlatform(state)),
|
||||
url: "url-we-want",
|
||||
},
|
||||
];
|
||||
mockGetReleaseByTag(assets);
|
||||
|
||||
await withTmpDir(async (tempDir) => {
|
||||
const features = mockOfflineFeatures(tempDir, logger);
|
||||
const info = await startProxyExports.getDownloadUrl(
|
||||
getRunnerLogger(true),
|
||||
features,
|
||||
);
|
||||
const info = await startProxyExports.getDownloadUrl({ ...state, features });
|
||||
|
||||
t.is(info.version, defaults.cliVersion);
|
||||
t.is(info.url, "url-we-want");
|
||||
@@ -918,7 +966,9 @@ test.serial(
|
||||
sinon.stub(toolcache, "find").returns(toolcachePath);
|
||||
|
||||
const features = mockOfflineFeatures(tempDir, logger);
|
||||
const path = await startProxyExports.getProxyBinaryPath(logger, features);
|
||||
const path = await startProxyExports.getProxyBinaryPath(
|
||||
initAllState({ logger, features }),
|
||||
);
|
||||
|
||||
t.assert(path);
|
||||
t.is(
|
||||
@@ -933,9 +983,13 @@ test.serial(
|
||||
"getProxyBinaryPath - downloads proxy if not in cache",
|
||||
async (t) => {
|
||||
const logger = new RecordingLogger();
|
||||
const state = initAllState({ logger });
|
||||
const downloadUrl = "url-we-want";
|
||||
mockGetReleaseByTag([
|
||||
{ name: startProxyExports.getProxyPackage(), url: downloadUrl },
|
||||
{
|
||||
name: startProxyExports.getProxyPackage(getTestPlatform(state)),
|
||||
url: downloadUrl,
|
||||
},
|
||||
]);
|
||||
|
||||
const toolcachePath = "/path/to/proxy/dir";
|
||||
@@ -958,10 +1012,10 @@ test.serial(
|
||||
.resolves(extractedPath);
|
||||
const cacheDir = sinon.stub(toolcache, "cacheDir").resolves(toolcachePath);
|
||||
|
||||
const path = await startProxyExports.getProxyBinaryPath(
|
||||
logger,
|
||||
createFeatures([]),
|
||||
);
|
||||
const path = await startProxyExports.getProxyBinaryPath({
|
||||
...state,
|
||||
features: createFeatures([]),
|
||||
});
|
||||
|
||||
t.assert(find.calledOnce);
|
||||
t.assert(getApiDetails.calledOnce);
|
||||
@@ -976,7 +1030,7 @@ test.serial(
|
||||
);
|
||||
|
||||
checkExpectedLogMessages(t, logger.messages, [
|
||||
`Found '${startProxyExports.getProxyPackage()}' in release '${defaults.bundleVersion}' at '${downloadUrl}'`,
|
||||
`Found '${startProxyExports.getProxyPackage(getTestPlatform(state))}' in release '${defaults.bundleVersion}' at '${downloadUrl}'`,
|
||||
]);
|
||||
},
|
||||
);
|
||||
@@ -985,6 +1039,7 @@ test.serial(
|
||||
"getProxyBinaryPath - downloads proxy based on features if not in cache",
|
||||
async (t) => {
|
||||
const logger = new RecordingLogger();
|
||||
const state = initAllState({ logger });
|
||||
const expectedTag = "codeql-bundle-v2.20.1";
|
||||
const expectedParams = {
|
||||
owner: "github",
|
||||
@@ -994,7 +1049,7 @@ test.serial(
|
||||
const downloadUrl = "url-we-want";
|
||||
const assets = [
|
||||
{
|
||||
name: startProxyExports.getProxyPackage(),
|
||||
name: startProxyExports.getProxyPackage(getTestPlatform(state)),
|
||||
url: downloadUrl,
|
||||
},
|
||||
];
|
||||
@@ -1045,7 +1100,10 @@ test.serial(
|
||||
.resolves({
|
||||
enabledVersions: [{ cliVersion: "2.20.1", tagName: expectedTag }],
|
||||
});
|
||||
const path = await startProxyExports.getProxyBinaryPath(logger, features);
|
||||
const path = await startProxyExports.getProxyBinaryPath({
|
||||
...state,
|
||||
features,
|
||||
});
|
||||
|
||||
t.assert(getDefaultCliVersion.calledOnce);
|
||||
sinon.assert.calledOnceWithMatch(
|
||||
@@ -1067,7 +1125,7 @@ test.serial(
|
||||
});
|
||||
|
||||
checkExpectedLogMessages(t, logger.messages, [
|
||||
`Found '${startProxyExports.getProxyPackage()}' in release '${expectedTag}' at '${downloadUrl}'`,
|
||||
`Found '${startProxyExports.getProxyPackage(getTestPlatform(state))}' in release '${expectedTag}' at '${downloadUrl}'`,
|
||||
]);
|
||||
},
|
||||
);
|
||||
+27
-21
@@ -3,6 +3,7 @@ import * as path from "path";
|
||||
import * as core from "@actions/core";
|
||||
import * as toolcache from "@actions/tool-cache";
|
||||
|
||||
import { ActionState } from "./action-common";
|
||||
import {
|
||||
getApiClient,
|
||||
getApiDetails,
|
||||
@@ -20,6 +21,7 @@ import {
|
||||
import * as json from "./json";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { BundlePlatform, getBundlePlatform } from "./platform";
|
||||
import {
|
||||
Address,
|
||||
Registry,
|
||||
@@ -370,14 +372,10 @@ export function getCredentials(
|
||||
|
||||
/**
|
||||
* Gets the name of the proxy release asset for the current platform.
|
||||
*
|
||||
* @param platform The platform to get the asset name for.
|
||||
*/
|
||||
export function getProxyPackage(): string {
|
||||
const platform =
|
||||
process.platform === "win32"
|
||||
? "win64"
|
||||
: process.platform === "darwin"
|
||||
? "osx64"
|
||||
: "linux64";
|
||||
export function getProxyPackage(platform: BundlePlatform): string {
|
||||
return `${UPDATEJOB_PROXY}-${platform}.tar.gz`;
|
||||
}
|
||||
|
||||
@@ -417,25 +415,33 @@ async function getCliVersionFromFeatures(
|
||||
* Determines the URL of the proxy release asset that we should download if its not
|
||||
* already in the toolcache, and its version.
|
||||
*
|
||||
* @param logger The logger to use.
|
||||
* @param features Information about enabled features.
|
||||
* @param action The action state.
|
||||
* @returns Returns the download URL and version of the proxy package we plan to use.
|
||||
*/
|
||||
export async function getDownloadUrl(
|
||||
logger: Logger,
|
||||
features: FeatureEnablement,
|
||||
action: ActionState<["Base", "Logger", "FeatureFlags"]>,
|
||||
): Promise<{ url: string; version: string }> {
|
||||
const proxyPackage = getProxyPackage();
|
||||
// Default to linux64 if we don't recognise the platform+arch pair.
|
||||
// This maintains the behaviour we had before switching to `getBundlePlatform` here.
|
||||
let platform = getBundlePlatform(action.platform, action.arch);
|
||||
if (platform === undefined) {
|
||||
action.logger.warning(
|
||||
`Unsupported platform ${action.platform} on architecture ${action.arch}, defaulting to ${BundlePlatform.Linux64}`,
|
||||
);
|
||||
platform = BundlePlatform.Linux64;
|
||||
}
|
||||
|
||||
const proxyPackage = getProxyPackage(platform);
|
||||
|
||||
try {
|
||||
const useFeaturesToDetermineCLI = await features.getValue(
|
||||
const useFeaturesToDetermineCLI = await action.features.getValue(
|
||||
Feature.StartProxyUseFeaturesRelease,
|
||||
);
|
||||
|
||||
// Retrieve information about the CLI version we should use. This will be either the linked
|
||||
// version, or the one enabled by FFs.
|
||||
const versionInfo = useFeaturesToDetermineCLI
|
||||
? (await getCliVersionFromFeatures(features)).enabledVersions[0]
|
||||
? (await getCliVersionFromFeatures(action.features)).enabledVersions[0]
|
||||
: {
|
||||
cliVersion: defaults.cliVersion,
|
||||
tagName: defaults.bundleVersion,
|
||||
@@ -447,7 +453,7 @@ export async function getDownloadUrl(
|
||||
// Search the release's assets to find the one we are looking for.
|
||||
for (const asset of cliRelease.data.assets) {
|
||||
if (asset.name === proxyPackage) {
|
||||
logger.info(
|
||||
action.logger.info(
|
||||
`Found '${proxyPackage}' in release '${versionInfo.tagName}' at '${asset.url}'`,
|
||||
);
|
||||
return {
|
||||
@@ -460,13 +466,13 @@ export async function getDownloadUrl(
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
logger.warning(
|
||||
action.logger.warning(
|
||||
`Failed to retrieve information about the linked release: ${getErrorMessage(ex)}`,
|
||||
);
|
||||
}
|
||||
|
||||
// Fallback to the hard-coded URL.
|
||||
logger.info(
|
||||
action.logger.info(
|
||||
`Did not find '${proxyPackage}' in the linked release, falling back to hard-coded version.`,
|
||||
);
|
||||
return {
|
||||
@@ -559,15 +565,15 @@ export function getProxyFilename() {
|
||||
* runner's tool cache. Otherwise, it downloads and extracts the proxy binary,
|
||||
* and stores it in the tool cache.
|
||||
*
|
||||
* @param logger The logger to use.
|
||||
* @param action The action state.
|
||||
* @returns The path to the proxy binary.
|
||||
*/
|
||||
export async function getProxyBinaryPath(
|
||||
logger: Logger,
|
||||
features: FeatureEnablement,
|
||||
action: ActionState<["Base", "Logger", "FeatureFlags"]>,
|
||||
): Promise<string> {
|
||||
const logger = action.logger;
|
||||
const proxyFileName = getProxyFilename();
|
||||
const proxyInfo = await getDownloadUrl(logger, features);
|
||||
const proxyInfo = await getDownloadUrl(action);
|
||||
|
||||
let proxyBin = toolcache.find(proxyFileName, proxyInfo.version);
|
||||
if (!proxyBin) {
|
||||
|
||||
+13
-9
@@ -23,7 +23,13 @@ import type { ComputedInput, InputName } from "./config/inputs";
|
||||
import { parseRegistriesWithoutCredentials } from "./config/pack-registries";
|
||||
import type { DependencyCacheRestoreStatusReport } from "./dependency-caching";
|
||||
import { DocUrl } from "./doc-url";
|
||||
import { EnvVar, getEnv, ReadOnlyEnv, RegistryProxyVars } from "./environment";
|
||||
import {
|
||||
EnvVar,
|
||||
getEnv,
|
||||
ReadOnlyEnv,
|
||||
RegistryProxyVars,
|
||||
exportEnvVar,
|
||||
} from "./environment";
|
||||
import { getRef } from "./git-utils";
|
||||
import * as json from "./json";
|
||||
import type { Logger } from "./logging";
|
||||
@@ -71,9 +77,7 @@ export function getDisplayActionName(actionName: ActionName): string {
|
||||
* environment and returns it.
|
||||
* If a new UUID is generated, it is also exported as an environment variable.
|
||||
*/
|
||||
export function getJobUUID(
|
||||
action: ActionState<["Logger", "ReadOnlyEnv", "Actions"]>,
|
||||
) {
|
||||
export function getJobUUID(action: ActionState<["Logger", "Env", "Actions"]>) {
|
||||
// Check if we already have a UUID for the analysis and return it if so.
|
||||
const existingJobRunUuid = action.env.getOptional(EnvVar.JOB_RUN_UUID);
|
||||
|
||||
@@ -86,7 +90,7 @@ export function getJobUUID(
|
||||
const jobRunUuid = uuid.v4();
|
||||
action.logger.info(`Job run UUID is ${jobRunUuid}.`);
|
||||
|
||||
action.actions.exportVariable(EnvVar.JOB_RUN_UUID, jobRunUuid);
|
||||
action.env.export(EnvVar.JOB_RUN_UUID, jobRunUuid);
|
||||
return jobRunUuid;
|
||||
}
|
||||
|
||||
@@ -268,12 +272,12 @@ export function getJobStatusDisplayName(status: JobStatus): string {
|
||||
*/
|
||||
function setJobStatusIfUnsuccessful(actionStatus: ActionStatus) {
|
||||
if (actionStatus === "user-error") {
|
||||
core.exportVariable(
|
||||
exportEnvVar(
|
||||
EnvVar.JOB_STATUS,
|
||||
process.env[EnvVar.JOB_STATUS] ?? JobStatus.ConfigErrorStatus,
|
||||
);
|
||||
} else if (actionStatus === "failure" || actionStatus === "aborted") {
|
||||
core.exportVariable(
|
||||
exportEnvVar(
|
||||
EnvVar.JOB_STATUS,
|
||||
process.env[EnvVar.JOB_STATUS] ?? JobStatus.FailureStatus,
|
||||
);
|
||||
@@ -376,7 +380,7 @@ export async function createStatusReportBase(
|
||||
let workflowStartedAt = process.env[EnvVar.WORKFLOW_STARTED_AT];
|
||||
if (workflowStartedAt === undefined) {
|
||||
workflowStartedAt = actionStartedAt.toISOString();
|
||||
core.exportVariable(EnvVar.WORKFLOW_STARTED_AT, workflowStartedAt);
|
||||
exportEnvVar(EnvVar.WORKFLOW_STARTED_AT, workflowStartedAt);
|
||||
}
|
||||
const runnerOs = getRequiredEnvParam("RUNNER_OS");
|
||||
const codeQlCliVersion = getCachedCodeQlVersion(
|
||||
@@ -388,7 +392,7 @@ export async function createStatusReportBase(
|
||||
// re-export the testing environment variable so that it is available to subsequent steps,
|
||||
// even if it was only set for this step
|
||||
if (testingEnvironment) {
|
||||
core.exportVariable(EnvVar.TESTING_ENVIRONMENT, testingEnvironment);
|
||||
exportEnvVar(EnvVar.TESTING_ENVIRONMENT, testingEnvironment);
|
||||
}
|
||||
const isSteadyStateDefaultSetupRun =
|
||||
process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true";
|
||||
|
||||
@@ -202,10 +202,6 @@ class TestActionsEnv implements ActionsEnv {
|
||||
public getOptionalInput(_name: string): string | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public exportVariable(name: string, value: string): void {
|
||||
this.env.set(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,6 +230,8 @@ export function initAllState(
|
||||
return {
|
||||
name: ActionName.Init,
|
||||
startedAt: new Date(),
|
||||
platform: process.platform,
|
||||
arch: process.arch,
|
||||
logger: new RecordingLogger(),
|
||||
env,
|
||||
actions: getTestActionsEnv(env),
|
||||
|
||||
@@ -7,7 +7,12 @@ import * as sinon from "sinon";
|
||||
import { CodeQL, getCodeQLForTesting } from "./codeql";
|
||||
import * as configUtils from "./config-utils";
|
||||
import { BuiltInLanguage } from "./languages";
|
||||
import { createTestConfig, makeVersionInfo, setupTests } from "./testing-utils";
|
||||
import {
|
||||
createTestConfig,
|
||||
makeVersionInfo,
|
||||
RecordingLogger,
|
||||
setupTests,
|
||||
} from "./testing-utils";
|
||||
import { ToolsFeature } from "./tools-features";
|
||||
import { getCombinedTracerConfig } from "./tracer-config";
|
||||
import * as util from "./util";
|
||||
@@ -42,18 +47,20 @@ async function stubCodeql(
|
||||
}
|
||||
|
||||
test("getCombinedTracerConfig - return undefined when no languages are traced languages", async (t) => {
|
||||
const logger = new RecordingLogger();
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
const config = getTestConfig(tmpDir);
|
||||
// No traced languages
|
||||
config.languages = [BuiltInLanguage.javascript, BuiltInLanguage.python];
|
||||
t.deepEqual(
|
||||
await getCombinedTracerConfig(await stubCodeql(), config),
|
||||
await getCombinedTracerConfig(logger, await stubCodeql(), config),
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test("getCombinedTracerConfig", async (t) => {
|
||||
const logger = new RecordingLogger();
|
||||
await util.withTmpDir(async (tmpDir) => {
|
||||
const config = getTestConfig(tmpDir);
|
||||
|
||||
@@ -82,7 +89,11 @@ test("getCombinedTracerConfig", async (t) => {
|
||||
);
|
||||
fs.writeFileSync(startTracingJson, JSON.stringify(startTracingEnv));
|
||||
|
||||
const result = await getCombinedTracerConfig(await stubCodeql(), config);
|
||||
const result = await getCombinedTracerConfig(
|
||||
logger,
|
||||
await stubCodeql(),
|
||||
config,
|
||||
);
|
||||
t.notDeepEqual(result, undefined);
|
||||
|
||||
t.false(Object.prototype.hasOwnProperty.call(result?.env, "CODEQL_RUNNER"));
|
||||
|
||||
+18
-13
@@ -4,7 +4,7 @@ import * as path from "path";
|
||||
import { type CodeQL } from "./codeql";
|
||||
import { type Config } from "./config-utils";
|
||||
import { Logger } from "./logging";
|
||||
import { asyncSome, BuildMode } from "./util";
|
||||
import { asyncSome, BuildMode, getErrorMessage } from "./util";
|
||||
|
||||
export type TracerConfig = {
|
||||
env: { [key: string]: string };
|
||||
@@ -77,23 +77,28 @@ export async function endTracingForCluster(
|
||||
}
|
||||
|
||||
async function getTracerConfigForCluster(
|
||||
logger: Logger,
|
||||
config: Config,
|
||||
): Promise<TracerConfig> {
|
||||
const tracingEnvVariables = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.resolve(
|
||||
config.dbLocation,
|
||||
"temp/tracingEnvironment/start-tracing.json",
|
||||
),
|
||||
"utf8",
|
||||
),
|
||||
const filePath = path.resolve(
|
||||
config.dbLocation,
|
||||
"temp/tracingEnvironment/start-tracing.json",
|
||||
);
|
||||
return {
|
||||
env: tracingEnvVariables,
|
||||
};
|
||||
try {
|
||||
const tracingEnvVariables = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
||||
return {
|
||||
env: tracingEnvVariables,
|
||||
};
|
||||
} catch (err) {
|
||||
logger.error(
|
||||
`Failed to parse tracing environment from '${filePath}': ${getErrorMessage(err)}`,
|
||||
);
|
||||
throw new Error(`Failed to parse tracing environment from '${filePath}'.`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getCombinedTracerConfig(
|
||||
logger: Logger,
|
||||
codeql: CodeQL,
|
||||
config: Config,
|
||||
): Promise<TracerConfig | undefined> {
|
||||
@@ -101,5 +106,5 @@ export async function getCombinedTracerConfig(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return await getTracerConfigForCluster(config);
|
||||
return await getTracerConfigForCluster(logger, config);
|
||||
}
|
||||
+4
-3
@@ -14,7 +14,7 @@ import { getGitHubVersion, wrapApiConfigurationError } from "./api-client";
|
||||
import { CodeQL, getCodeQL } from "./codeql";
|
||||
import { getConfig } from "./config-utils";
|
||||
import { readDiffRangesJsonFile } from "./diff-informed-analysis-utils";
|
||||
import { EnvVar } from "./environment";
|
||||
import { EnvVar, exportEnvVar } from "./environment";
|
||||
import { FeatureEnablement } from "./feature-flags";
|
||||
import * as fingerprints from "./fingerprints";
|
||||
import * as gitUtils from "./git-utils";
|
||||
@@ -126,7 +126,7 @@ async function combineSarifFilesUsingCLI(
|
||||
logger.warning(
|
||||
`Uploading multiple SARIF runs with the same category is deprecated ${deprecationWarningMessage}. Please update your workflow to upload a single run per category. ${deprecationMoreInformationMessage}`,
|
||||
);
|
||||
core.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true");
|
||||
exportEnvVar("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true");
|
||||
}
|
||||
|
||||
// If not, use the naive method of combining the files.
|
||||
@@ -166,6 +166,7 @@ async function combineSarifFilesUsingCLI(
|
||||
gitHubVersion.type,
|
||||
codeQLDefaultVersionInfo,
|
||||
undefined, // rawLanguages: upload-lib does not run analysis
|
||||
undefined, // otherLanguagePacksReason: upload-lib does not run analysis
|
||||
false, // useOverlayAwareDefaultCliVersion: upload-lib does not run analysis
|
||||
features,
|
||||
logger,
|
||||
@@ -1031,7 +1032,7 @@ export function validateUniqueCategory(
|
||||
`Category: (${id ? id : "none"}) Tool: (${tool ? tool : "none"})`,
|
||||
);
|
||||
}
|
||||
core.exportVariable(sentinelEnvVar, sentinelEnvVar);
|
||||
exportEnvVar(sentinelEnvVar, sentinelEnvVar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,10 @@ export async function runWrapper() {
|
||||
// possible, and only use safe functions outside.
|
||||
|
||||
try {
|
||||
// Restore inputs from `upload-sarif` Action.
|
||||
actionsUtil.restoreInputs();
|
||||
const logger = getActionsLogger();
|
||||
|
||||
// Restore inputs from `upload-sarif` Action.
|
||||
actionsUtil.restoreInputs(logger);
|
||||
const gitHubVersion = await getGitHubVersion();
|
||||
checkGitHubVersionInRange(gitHubVersion, logger);
|
||||
|
||||
|
||||
+32
-21
@@ -14,13 +14,23 @@ import * as apiCompatibility from "./api-compatibility.json";
|
||||
import type { CodeQL } from "./codeql";
|
||||
import type { Pack } from "./config/db-config";
|
||||
import type { Config } from "./config-utils";
|
||||
import { EnvVar, getRequiredEnvParam } from "./environment";
|
||||
import {
|
||||
EnvVar,
|
||||
getRequiredEnvParam,
|
||||
isInTestMode,
|
||||
exportEnvVar,
|
||||
} from "./environment";
|
||||
import * as json from "./json";
|
||||
import { Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
|
||||
// Re-export for backwards compatibility to avoid updating a lot of imports elsewhere.
|
||||
export { getRequiredEnvParam, getOptionalEnvVar, getEnv } from "./environment";
|
||||
export {
|
||||
getRequiredEnvParam,
|
||||
getOptionalEnvVar,
|
||||
getEnv,
|
||||
isInTestMode,
|
||||
} from "./environment";
|
||||
|
||||
/**
|
||||
* The name of the file containing the base database OIDs, as stored in the
|
||||
@@ -542,7 +552,7 @@ export function checkGitHubVersionInRange(
|
||||
);
|
||||
}
|
||||
hasBeenWarnedAboutVersion = true;
|
||||
core.exportVariable(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true);
|
||||
exportEnvVar(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true);
|
||||
}
|
||||
|
||||
export enum DisallowedAPIVersionReason {
|
||||
@@ -586,11 +596,11 @@ export function assertNever(value: never): never {
|
||||
* knowing what version of CodeQL we're running.
|
||||
*/
|
||||
export function initializeEnvironment(version: string) {
|
||||
core.exportVariable(EnvVar.FEATURE_MULTI_LANGUAGE, "false");
|
||||
core.exportVariable(EnvVar.FEATURE_SANDWICH, "false");
|
||||
core.exportVariable(EnvVar.FEATURE_SARIF_COMBINE, "true");
|
||||
core.exportVariable(EnvVar.FEATURE_WILL_UPLOAD, "true");
|
||||
core.exportVariable(EnvVar.VERSION, version);
|
||||
exportEnvVar(EnvVar.FEATURE_MULTI_LANGUAGE, "false");
|
||||
exportEnvVar(EnvVar.FEATURE_SANDWICH, "false");
|
||||
exportEnvVar(EnvVar.FEATURE_SARIF_COMBINE, "true");
|
||||
exportEnvVar(EnvVar.FEATURE_WILL_UPLOAD, "true");
|
||||
exportEnvVar(EnvVar.VERSION, version);
|
||||
}
|
||||
|
||||
export class HTTPError extends Error {
|
||||
@@ -711,15 +721,6 @@ export function isGoodVersion(versionSpec: string) {
|
||||
return !BROKEN_VERSIONS.includes(versionSpec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether we are in test mode. This is used by CodeQL Action PR checks.
|
||||
*
|
||||
* In test mode, we skip several uploads (SARIF results, status reports, DBs, ...).
|
||||
*/
|
||||
export function isInTestMode(): boolean {
|
||||
return process.env[EnvVar.TEST_MODE] === "true";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether we specifically want to skip uploading SARIF files.
|
||||
*/
|
||||
@@ -894,7 +895,13 @@ export function parseMatrixInput(
|
||||
if (matrixInput === undefined || matrixInput === "null") {
|
||||
return undefined;
|
||||
}
|
||||
return JSON.parse(matrixInput) as { [key: string]: string };
|
||||
try {
|
||||
return JSON.parse(matrixInput) as { [key: string]: string };
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Failed to parse matrix input '${matrixInput}': ${getErrorMessage(err)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function wrapError(error: unknown): Error {
|
||||
@@ -942,7 +949,7 @@ export async function checkDiskUsage(
|
||||
} else {
|
||||
logger.debug(message);
|
||||
}
|
||||
core.exportVariable(EnvVar.HAS_WARNED_ABOUT_DISK_SPACE, "true");
|
||||
exportEnvVar(EnvVar.HAS_WARNED_ABOUT_DISK_SPACE, "true");
|
||||
}
|
||||
return {
|
||||
numAvailableBytes: diskUsage.bavail * blockSizeInBytes,
|
||||
@@ -991,7 +998,7 @@ export function checkActionVersion(
|
||||
"https://github.blog/changelog/2025-10-28-upcoming-deprecation-of-codeql-action-v3/",
|
||||
);
|
||||
// set LOG_VERSION_DEPRECATION env var to prevent the warning from being logged multiple times
|
||||
core.exportVariable(EnvVar.LOG_VERSION_DEPRECATION, "true");
|
||||
exportEnvVar(EnvVar.LOG_VERSION_DEPRECATION, "true");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1037,7 +1044,11 @@ export enum BuildMode {
|
||||
}
|
||||
|
||||
export function cloneObject<T>(obj: T): T {
|
||||
return JSON.parse(JSON.stringify(obj)) as T;
|
||||
try {
|
||||
return JSON.parse(JSON.stringify(obj)) as T;
|
||||
} catch (err) {
|
||||
throw new Error(`Cloning object failed: ${getErrorMessage(err)}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function cleanUpPath(file: string, name: string, logger: Logger) {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
## Change notes
|
||||
|
||||
Change-notes are Markdown files used to document user-facing changes. When making a change that affects users, create a Markdown file here that describes the change. During the next release, the change-note files in `unreleased-change-notes/` will automatically be added to `CHANGELOG.md`.
|
||||
|
||||
### Change-note file format
|
||||
|
||||
Change-note files must follow a certain format so that they can be automatically validated and processed. Failure to follow the format will result in a failed PR check.
|
||||
|
||||
You may validate your change-note file locally by running `npx tsx pr-checks/changenotes.ts validate`. This command will scan all change-note files in `unreleased-change-notes/` and report any errors.
|
||||
|
||||
|
||||
#### Body
|
||||
|
||||
The body of the change-note file must:
|
||||
|
||||
- Be written in valid [GitHub-Flavored Markdown](https://github.github.com/gfm/).
|
||||
- Be structured as a single unordered Markdown list with hyphen (`-`) bullets. Each list item should describe a single change. If there are multiple changes, use multiple list items.
|
||||
|
||||
### Example change-note file
|
||||
|
||||
```
|
||||
- Fixed a bug where a network error while streaming the download of the CodeQL bundle could terminate the `init` Action instead of falling back to downloading the bundle before extracting it. [#4061](https://github.com/github/codeql-action/pull/4061)
|
||||
- Fix incorrect minimum required Git version for [improved incremental analysis](https://github.com/github/roadmap/issues/1158): it should have been 2.36.0, not 2.11.0. [#3781](https://github.com/github/codeql-action/pull/3781)
|
||||
```
|
||||
Reference in new issue
Block a user