Compare commits

...

48 Commits

Author SHA1 Message Date
github-actions[bot] ba68d8d47d Rebuild 2026-05-19 18:15:19 +00:00
github-actions[bot] c518671741 Update changelog and version after v4.36.0 2026-05-19 18:15:08 +00:00
Henry Mercer 3b0e64cb09 Merge pull request #3914 from github/henrymercer/auto-rebuild-release-prs
Release process: Automatically rebuild PRs
2026-05-19 18:00:31 +00:00
Henry Mercer eb9a790d15 Apply suggestion from @henrymercer 2026-05-18 19:39:41 +01:00
Henry Mercer b8baf41834 Remove comments about npm cache 2026-05-18 19:31:53 +01:00
Henry Mercer 5e9ae56429 Add specific instruction about "Rebuild" commit 2026-05-18 19:28:49 +01:00
Henry Mercer 8442bc0af9 Release process: Automatically rebuild PRs 2026-05-18 19:06:49 +01:00
Henry Mercer 26a1e570a6 Merge pull request #3913 from github/henrymercer/downgrade-ava
Downgrade ava to version 6.4.1
2026-05-18 18:00:26 +00:00
Henry Mercer 9665bc2f5a Downgrade ava to version 6.4.1
Since we run CI on Node 20 as well as Node 24
2026-05-18 18:07:08 +01:00
Henry Mercer c8a3492b26 Merge pull request #3894 from github/henrymercer/require-codeql-2.19.4
Bump minimum CodeQL CLI version to 2.19.4
2026-05-18 14:55:40 +00:00
Henry Mercer e94195c896 Move changelog note to right place 2026-05-18 14:27:03 +01:00
Henry Mercer 05e8f288eb Merge branch 'main' into henrymercer/require-codeql-2.19.4 2026-05-15 18:13:43 +01:00
Michael B. Gale b71f5aebfc Merge pull request #3898 from github/dependabot/npm_and_yarn/sinon-22.0.0
Bump sinon from 21.1.2 to 22.0.0
2026-05-15 14:58:30 +00:00
Henry Mercer 2365a46087 Merge pull request #3908 from github/henrymercer/token-stdin
Update scripts to read tokens more securely
2026-05-15 14:54:00 +00:00
Henry Mercer cf51dca1af Merge pull request #3893 from github/henrymercer/sha256
Add support for SHA-256 Git object IDs
2026-05-15 14:53:55 +00:00
Michael B. Gale b30a935ea5 Merge branch 'main' into dependabot/npm_and_yarn/sinon-22.0.0 2026-05-15 15:42:13 +01:00
Henry Mercer 5b815f25ca Merge branch 'main' into henrymercer/sha256 2026-05-15 14:58:14 +01:00
Henry Mercer 93c8a9ed99 Update update-release-branch.py to take token from stdin 2026-05-15 14:53:43 +01:00
Henry Mercer 2a02de1a14 Read token from stdin in sync-checks.ts
Also allow specifying the token using an environment variable.
2026-05-15 14:53:43 +01:00
Henry Mercer 67f403822c Merge pull request #3903 from github/henrymercer/macos-larger-runners
PR checks: Run slowest macOS checks on larger runners
2026-05-15 13:32:01 +00:00
Michael B. Gale bbef5ff663 Merge pull request #3904 from github/mbg/esbuild/split-follow-up
Address review comments for #3899
2026-05-15 12:48:02 +00:00
Michael B. Gale 7187b6ecc7 Merge pull request #3906 from github/mergeback/v4.35.5-to-main-9e0d7b8d
Mergeback v4.35.5 refs/heads/releases/v4 into main
2026-05-15 11:50:42 +00:00
github-actions[bot] f1ce9f4421 Rebuild 2026-05-15 11:30:22 +00:00
github-actions[bot] 06c7e6fdd5 Update changelog and version after v4.35.5 2026-05-15 11:24:05 +00:00
Henry Mercer b43bb7bd69 Merge branch 'main' into henrymercer/sha256 2026-05-15 11:41:47 +01:00
Michael B. Gale 064674dfa3 Fix typo
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-15 11:35:47 +01:00
Michael B. Gale ab5047bf8f Add missing semicolons 2026-05-15 11:27:58 +01:00
Michael B. Gale 2320f9d058 "action" to "Action" in build.mjs 2026-05-15 11:26:51 +01:00
Michael B. Gale 46959216a2 Rename analyze-action-env.test.ts to analyze-action.test.ts 2026-05-15 11:25:12 +01:00
Michael B. Gale 9e1f914560 Merge analyze-action-input test into analyze-action-env file
The tests still can't run in parallel so I had to change `test` to `test.serial`, which caused a bunch of formatting changes.
2026-05-15 11:24:28 +01:00
Michael B. Gale db84cb5ccb Remove outdated comments for analyze-action tests 2026-05-15 11:22:17 +01:00
Henry Mercer 931147e852 Improve OS types and docs 2026-05-15 11:10:02 +01:00
Henry Mercer 1b65777c19 Address review comments 2026-05-14 18:13:20 +01:00
Henry Mercer a32db48565 Move checks back to default runners
These jobs are not rate-limiting so we don't need to run them on larger runners.
2026-05-14 17:57:11 +01:00
Henry Mercer aa005faaad PR checks: Run slowest macOS checks on larger runners 2026-05-14 17:29:44 +01:00
Henry Mercer fcdf5dd4cf Add PR checks shortcut to package.json 2026-05-14 17:22:02 +01:00
Henry Mercer e8d3fa290e Merge branch 'main' into henrymercer/sha256 2026-05-14 17:10:41 +01:00
dependabot[bot] d4eab006fa Bump sinon from 21.1.2 to 22.0.0
Bumps [sinon](https://github.com/sinonjs/sinon) from 21.1.2 to 22.0.0.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v21.1.2...v22.0.0)

---
updated-dependencies:
- dependency-name: sinon
  dependency-version: 22.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-14 10:34:00 +00:00
Henry Mercer 3c8c0ae6cb Remove unnecessary sinon restore calls 2026-05-13 18:53:33 +01:00
Henry Mercer 93d215d874 Merge branch 'main' into henrymercer/sha256 2026-05-13 18:44:38 +01:00
Henry Mercer 9c3aedb4cd Update PR check testing matrix 2026-05-13 14:25:03 +01:00
Henry Mercer a66f7bbb5a Merge branch 'main' into henrymercer/sha256 2026-05-13 10:51:44 +01:00
Henry Mercer b986640672 Add note about CODEQL_VERSION_ZSTD_BUNDLE 2026-05-12 19:26:23 +01:00
Henry Mercer a333d64ec4 Remove DatabaseInterpretResultsSupportsSarifRunProperty tools feature
This feature has been supported since CodeQL CLI v2.19.0
2026-05-12 19:26:21 +01:00
Henry Mercer 97fb30df6b Remove ForceOverwrite tools feature
This feature has been supported since CodeQL CLI v2.18.0, which is below the new minimum version.
2026-05-12 19:26:20 +01:00
Henry Mercer d122da3c9f Bump minimum CodeQL CLI version to 2.19.4 2026-05-12 19:26:20 +01:00
Henry Mercer de3e561d12 Improve regex clarity 2026-05-12 19:06:04 +01:00
Henry Mercer 6a4e35fad9 Add support for SHA-256 Git object IDs 2026-05-12 18:24:21 +01:00
40 changed files with 841 additions and 748 deletions
@@ -41,7 +41,38 @@ runs:
git add .
git commit -m "Update changelog and version after ${VERSION}"
git push origin "${NEW_BRANCH}"
# Update the build artifacts with the new version number
- name: Rebuild the Action
shell: bash
run: |
set -exu
npm ci
npm run build
- name: Check for rebuild changes
id: rebuild_changes
shell: bash
run: |
set -exu
git add --all
if git diff --cached --quiet; then
echo "has_changes=false" >> "${GITHUB_OUTPUT}"
else
echo "has_changes=true" >> "${GITHUB_OUTPUT}"
fi
- name: Commit rebuild
if: steps.rebuild_changes.outputs.has_changes == 'true'
shell: bash
run: |
set -exu
git commit -m "Rebuild"
- name: Push mergeback branch
shell: bash
env:
NEW_BRANCH: "${{ inputs.branch }}"
run: git push origin "${NEW_BRANCH}"
- name: Create PR
shell: bash
@@ -60,8 +91,6 @@ runs:
Please do the following:
- [ ] Remove and re-add the "Rebuild" label to the PR to trigger just this workflow.
- [ ] Wait for the "Rebuild" workflow to push a commit updating the distribution files.
- [ ] Mark the PR as ready for review to trigger 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".
@@ -74,7 +103,6 @@ runs:
--head "${NEW_BRANCH}" \
--base "${BASE_BRANCH}" \
--title "${pr_title}" \
--label "Rebuild" \
--body "${pr_body}" \
--assignee "${GITHUB_ACTOR}" \
--draft
@@ -18,7 +18,7 @@ runs:
- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: 20
node-version: 24
cache: 'npm'
- name: Set up Python
+56 -20
View File
@@ -16,12 +16,27 @@ No user facing changes.
"""
# NB: This exact commit message is used to find commits for reverting during backports.
# Changing it requires a transition period where both old and new versions are supported.
# Changing it requires a transition period where both old and new versions are supported.
BACKPORT_COMMIT_MESSAGE = 'Update version and changelog for v'
# Commit message used for rebuild commits, both those produced by this script and those produced
# by the `Rebuild Action` workflow (`.github/workflows/rebuild.yml`).
REBUILD_COMMIT_MESSAGE = 'Rebuild'
# Name of the remote
ORIGIN = 'origin'
# Environment variables to check for a GitHub API token.
TOKEN_ENVIRONMENT_VARIABLES = ('GH_TOKEN', 'GITHUB_TOKEN')
# Gets a GitHub API token from one of the supported environment variables.
def get_github_token():
for variable_name in TOKEN_ENVIRONMENT_VARIABLES:
token = os.environ.get(variable_name, '').strip()
if token:
return token
raise Exception('Missing GitHub token. Set GITHUB_TOKEN or GH_TOKEN.')
# Runs git with the given args and returns the stdout.
# Raises an error if git does not exit successfully (unless passed
# allow_non_zero_exit_code=True).
@@ -32,6 +47,28 @@ def run_git(*args, allow_non_zero_exit_code=False):
raise Exception(f'Call to {" ".join(cmd)} exited with code {p.returncode} stderr: {p.stderr.decode("ascii")}.')
return p.stdout.decode('ascii')
# Runs the given command, streaming output to the console.
# Raises an error if the command does not exit successfully.
def run_command(*args):
cmd = list(args)
print(f'Running `{" ".join(cmd)}`.')
subprocess.run(cmd, check=True)
# Rebuilds the action and commits any changes.
def rebuild_action():
# For backports, the only source-level change vs the source branch is the new version number,
# so we just need to refresh the version embedded in `lib/`.
run_command('npm', 'ci')
run_command('npm', 'run', 'build')
run_git('add', '--all')
# `git diff --cached --quiet` exits 0 if there are no staged changes, 1 if there are.
if subprocess.run(['git', 'diff', '--cached', '--quiet']).returncode == 0:
print('Rebuild produced no changes; skipping Rebuild commit.')
else:
run_git('commit', '-m', REBUILD_COMMIT_MESSAGE)
print('Created Rebuild commit.')
# Returns true if the given branch exists on the origin remote
def branch_exists_on_remote(branch_name):
return run_git('ls-remote', '--heads', ORIGIN, branch_name).strip() != ''
@@ -87,9 +124,11 @@ def open_pr(
body.append('Please do the following:')
if len(conflicted_files) > 0:
body.append(' - [ ] Ensure `package.json` file contains the correct version.')
body.append(' - [ ] Add commits to this branch to resolve the merge conflicts ' +
body.append(' - [ ] Add a commit to this branch to resolve the merge conflicts ' +
'in the following files:')
body.extend([f' - [ ] `{file}`' for file in conflicted_files])
body.extend([f' - `{file}`' for file in conflicted_files])
body.append(' - [ ] Rebuild the Action locally (`npm run build`) and push any changes to the ' +
f'built output in `lib` as a separate commit named exactly `{REBUILD_COMMIT_MESSAGE}`.')
body.append(' - [ ] Ensure another maintainer has reviewed the additional commits you added to this ' +
'branch to resolve the merge conflicts.')
body.append(' - [ ] Ensure the CHANGELOG displays the correct version and date.')
@@ -97,10 +136,6 @@ def open_pr(
body.append(f' - [ ] Check that there are not any unexpected commits being merged into the `{target_branch}` branch.')
body.append(' - [ ] Ensure the docs team is aware of any documentation changes that need to be released.')
if not is_primary_release:
body.append(' - [ ] Remove and re-add the "Rebuild" label to the PR to trigger just this workflow.')
body.append(' - [ ] Wait for the "Rebuild" workflow to push a commit updating the distribution files.')
body.append(' - [ ] Mark the PR as ready for review to trigger the full set of PR checks.')
body.append(' - [ ] Approve and merge this PR. Make sure `Create a merge commit` is selected rather than `Squash and merge` or `Rebase and merge`.')
@@ -109,13 +144,11 @@ def open_pr(
body.append(' - [ ] Merge all backport PRs to older release branches, that will automatically be created once this PR is merged.')
title = f'Merge {source_branch} into {target_branch}'
labels = ['Rebuild'] if not is_primary_release else []
# Create the pull request
# PR checks won't be triggered on PRs created by Actions. Therefore mark the PR as draft so that
# a maintainer can take the PR out of draft, thereby triggering the PR checks.
pr = repo.create_pull(title=title, body='\n'.join(body), head=new_branch_name, base=target_branch, draft=True)
pr.add_to_labels(*labels)
print(f'Created PR #{str(pr.number)}')
# Assign the conductor
@@ -270,12 +303,6 @@ def update_changelog(version):
def main():
parser = argparse.ArgumentParser('update-release-branch.py')
parser.add_argument(
'--github-token',
type=str,
required=True,
help='GitHub token, typically from GitHub Actions.'
)
parser.add_argument(
'--repository-nwo',
type=str,
@@ -313,7 +340,7 @@ def main():
target_branch = args.target_branch
is_primary_release = args.is_primary_release
repo = Github(args.github_token).get_repo(args.repository_nwo)
repo = Github(get_github_token()).get_repo(args.repository_nwo)
# the target branch will be of the form releases/vN, where N is the major version number
target_branch_major_version = target_branch.strip('releases/v')
@@ -380,8 +407,9 @@ def main():
# releases.
run_git('revert', vOlder_update_commits[0], '--no-edit')
# Also revert the "Rebuild" commit created by Actions.
rebuild_commit = run_git('log', '--grep', '^Rebuild$', '--format=%H').split()[0]
# Also revert the "Rebuild" commit, whether created by this script or by the
# `Rebuild Action` workflow.
rebuild_commit = run_git('log', '--grep', f'^{REBUILD_COMMIT_MESSAGE}$', '--format=%H').split()[0]
print(f' Reverting {rebuild_commit}')
run_git('revert', rebuild_commit, '--no-edit')
@@ -396,9 +424,10 @@ def main():
run_git('add', '.')
run_git('commit', '--no-edit')
# Migrate the package version number from a vLatest version number to a vOlder version number
# Migrate the package version number from a vLatest version number to a vOlder version number.
# `package-lock.json` is updated as part of the subsequent rebuild step (see `rebuild_action`).
print(f'Setting version number to {version} in package.json')
replace_version_package_json(get_current_version(), version) # We rely on the `Rebuild` workflow to update package-lock.json
replace_version_package_json(get_current_version(), version)
run_git('add', 'package.json')
# Migrate the changelog notes from vLatest version numbers to vOlder version numbers
@@ -421,6 +450,13 @@ def main():
run_git('add', 'CHANGELOG.md')
run_git('commit', '-m', f'Update changelog for v{version}')
if not is_primary_release:
if len(conflicted_files) == 0:
print('Rebuilding the Action.')
rebuild_action()
else:
print(f'Skipping automatic rebuild because the merge produced conflicts in {conflicted_files}.')
run_git('push', ORIGIN, new_branch_name)
# Open a PR to update the branch
+4 -4
View File
@@ -49,10 +49,6 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: stable-v2.17.6
- os: ubuntu-latest
version: stable-v2.18.4
- os: ubuntu-latest
version: stable-v2.19.4
- os: ubuntu-latest
@@ -61,6 +57,10 @@ jobs:
version: stable-v2.21.4
- os: ubuntu-latest
version: stable-v2.22.4
- os: ubuntu-latest
version: stable-v2.23.9
- os: ubuntu-latest
version: stable-v2.24.3
- os: ubuntu-latest
version: default
- os: ubuntu-latest
+4 -4
View File
@@ -49,10 +49,6 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: stable-v2.17.6
- os: ubuntu-latest
version: stable-v2.18.4
- os: ubuntu-latest
version: stable-v2.19.4
- os: ubuntu-latest
@@ -61,6 +57,10 @@ jobs:
version: stable-v2.21.4
- os: ubuntu-latest
version: stable-v2.22.4
- os: ubuntu-latest
version: stable-v2.23.9
- os: ubuntu-latest
version: stable-v2.24.3
- os: ubuntu-latest
version: default
- os: ubuntu-latest
+4 -4
View File
@@ -49,10 +49,6 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: stable-v2.17.6
- os: ubuntu-latest
version: stable-v2.18.4
- os: ubuntu-latest
version: stable-v2.19.4
- os: ubuntu-latest
@@ -61,6 +57,10 @@ jobs:
version: stable-v2.21.4
- os: ubuntu-latest
version: stable-v2.22.4
- os: ubuntu-latest
version: stable-v2.23.9
- os: ubuntu-latest
version: stable-v2.24.3
- os: ubuntu-latest
version: default
- os: ubuntu-latest
+15 -15
View File
@@ -59,41 +59,41 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: stable-v2.17.6
- os: macos-latest
version: stable-v2.17.6
- os: ubuntu-latest
version: stable-v2.18.4
- os: macos-latest
version: stable-v2.18.4
- os: ubuntu-latest
version: stable-v2.19.4
- os: macos-latest
- os: macos-latest-xlarge
version: stable-v2.19.4
- os: ubuntu-latest
version: stable-v2.20.7
- os: macos-latest
- os: macos-latest-xlarge
version: stable-v2.20.7
- os: ubuntu-latest
version: stable-v2.21.4
- os: macos-latest
- os: macos-latest-xlarge
version: stable-v2.21.4
- os: ubuntu-latest
version: stable-v2.22.4
- os: macos-latest
- os: macos-latest-xlarge
version: stable-v2.22.4
- os: ubuntu-latest
version: stable-v2.23.9
- os: macos-latest-xlarge
version: stable-v2.23.9
- os: ubuntu-latest
version: stable-v2.24.3
- os: macos-latest-xlarge
version: stable-v2.24.3
- os: ubuntu-latest
version: default
- os: macos-latest
- os: macos-latest-xlarge
version: default
- os: ubuntu-latest
version: linked
- os: macos-latest
- os: macos-latest-xlarge
version: linked
- os: ubuntu-latest
version: nightly-latest
- os: macos-latest
- os: macos-latest-xlarge
version: nightly-latest
name: Multi-language repository
if: github.triggering_actor != 'dependabot[bot]'
+1 -1
View File
@@ -40,7 +40,7 @@ jobs:
matrix:
include:
- os: ubuntu-latest
version: stable-v2.19.3
version: stable-v2.19.4
- os: ubuntu-latest
version: stable-v2.22.1
- os: ubuntu-latest
+1 -1
View File
@@ -39,7 +39,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: macos-latest
- os: macos-latest-xlarge
version: nightly-latest
name: Swift analysis using autobuild
if: github.triggering_actor != 'dependabot[bot]'
+1 -1
View File
@@ -77,7 +77,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04,ubuntu-24.04,windows-2022,windows-2025,macos-14,macos-15]
os: [ubuntu-22.04,ubuntu-24.04,windows-2022,windows-2025,macos-14-xlarge,macos-15-xlarge]
tools: ${{ fromJson(needs.check-codeql-versions.outputs.versions) }}
runs-on: ${{ matrix.os }}
@@ -48,6 +48,9 @@ jobs:
with:
fetch-depth: 0 # ensure we have all tags and can push commits
- uses: actions/setup-node@v6
with:
node-version: 24
cache: 'npm'
- uses: actions/setup-python@v6
with:
python-version: '3.12'
+4 -2
View File
@@ -64,11 +64,12 @@ jobs:
- name: Update current release branch
if: github.event_name == 'workflow_dispatch'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo SOURCE_BRANCH=${REF_NAME}
echo TARGET_BRANCH=releases/${MAJOR_VERSION}
python .github/update-release-branch.py \
--github-token ${{ secrets.GITHUB_TOKEN }} \
--repository-nwo ${{ github.repository }} \
--source-branch '${{ env.REF_NAME }}' \
--target-branch 'releases/${{ env.MAJOR_VERSION }}' \
@@ -107,11 +108,12 @@ jobs:
- uses: ./.github/actions/release-initialise
- name: Update older release branch
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo SOURCE_BRANCH=${SOURCE_BRANCH}
echo TARGET_BRANCH=${TARGET_BRANCH}
python .github/update-release-branch.py \
--github-token ${{ secrets.GITHUB_TOKEN }} \
--repository-nwo ${{ github.repository }} \
--source-branch ${SOURCE_BRANCH} \
--target-branch ${TARGET_BRANCH} \
+9
View File
@@ -2,6 +2,14 @@
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.
## v4.36.0 - 19 May 2026
This release rolls back 4.35.5 due to issues with that release. It is identical to 0.0.0.
## 4.35.5 - 15 May 2026
- We have improved how the JavaScript bundles for the CodeQL Action are generated to avoid duplication across bundles and reduce the size of the repository by around 70%. This should have no effect on the runtime behaviour of the CodeQL Action. [#3899](https://github.com/github/codeql-action/pull/3899)
@@ -1208,3 +1216,4 @@ No user facing changes.
- Add this changelog file. [#507](https://github.com/github/codeql-action/pull/507)
- Improve grouping of analysis logs. Add a new log group containing a summary of metrics and diagnostics, if they were produced by CodeQL builtin queries. [#515](https://github.com/github/codeql-action/pull/515)
- Add metrics and diagnostics summaries from custom query suites to the analysis summary log group. [#532](https://github.com/github/codeql-action/pull/532)
+1 -1
View File
@@ -71,7 +71,7 @@ Once the mergeback and backport pull request have been merged, the release is co
Since the `codeql-action` runs most of its testing through individual Actions workflows, there are over two hundred required jobs that need to pass in order for a PR to turn green. It would be too tedious to maintain that list manually. You can regenerate the set of required checks automatically by running the [sync-checks.ts](pr-checks/sync-checks.ts) script:
- At a minimum, you must provide an argument for the `--token` input. For example, `--token "$(gh auth token)"` to use the same token that `gh` uses. If no token is provided or the token has insufficient permissions, the script will fail.
- At a minimum, you must provide a token with permissions to update branch protection rules. For example, `gh auth token | pr-checks/sync-checks.ts --token-stdin` uses the same token that `gh` uses. You can also set the `GH_TOKEN` or `GITHUB_TOKEN` environment variable. If no token is provided or the token has insufficient permissions, the script will fail.
- By default, the script performs a dry run and outputs information about the changes it would make to the branch protection rules. To actually apply the changes, specify the `--apply` flag.
- If you run the script without any other arguments, it will retrieve the set of workflows that ran for the latest commit on `main`.
- You can specify a different git ref with the `--ref` input. You will likely want to use this if you have a PR that removes or adds PR checks. For example, `--ref "some/branch/name"` to use the HEAD of the `some/branch/name` branch.
-2
View File
@@ -78,8 +78,6 @@ We typically release new minor versions of the CodeQL Action and Bundle when a n
| `v3.28.21` | `2.21.3` | Enterprise Server 3.18 | |
| `v3.28.12` | `2.20.7` | Enterprise Server 3.17 | |
| `v3.28.6` | `2.20.3` | Enterprise Server 3.16 | |
| `v3.28.6` | `2.20.3` | Enterprise Server 3.15 | |
| `v3.28.6` | `2.20.3` | Enterprise Server 3.14 | |
See the full list of GHES release and deprecation dates at [GitHub Enterprise Server releases](https://docs.github.com/en/enterprise-server/admin/all-releases#releases-of-github-enterprise-server).
+7 -7
View File
@@ -66,8 +66,8 @@ const onEndPlugin = {
const SHARED_ENTRYPOINT = "entry-points";
/**
* This plugin finds all source files that contain action entry points.
* It then generates the virtual `entry-points` module which imports all identifies files,
* This plugin finds all source files that contain Action entry points.
* It then generates the virtual `entry-points` module which imports all identified files,
* and re-exports their `runWrapper` functions with suitable aliases.
* A tiny stub file is emitted for each Action entrypoint. Each stub imports the shared bundle
* and calls the respective entry point.
@@ -83,7 +83,7 @@ const entryPointsPlugin = {
const toPascal = (s) =>
s.replace(/(^|-)([a-z0-9])/gi, (_, __, c) => c.toUpperCase());
// Find the source files containing action entry points.
// Find the source files containing Action entry points.
build.onStart(() => {
const actionFiles = globSync("src/*-action{,-post}.ts");
for (const actionFile of actionFiles) {
@@ -112,7 +112,7 @@ const entryPointsPlugin = {
return { path: SHARED_ENTRYPOINT, namespace };
});
// Generate the virtual `entry-points` file based on the actions we discovered.
// Generate the virtual `entry-points` file based on the Actions we discovered.
// Restrict using the namespace. The path filter does not need to discriminate any further.
build.onLoad({ filter: /.*/, namespace }, async () => {
const wrapperTemplatePath = "entry-wrapper.js.tpl";
@@ -127,7 +127,7 @@ const entryPointsPlugin = {
const imports = actionsSorted
.map(
(action) =>
`import * as ${action.pascalCaseName} from "./src/${basename(action.path)}"`,
`import * as ${action.pascalCaseName} from "./src/${basename(action.path)}";`,
)
.join("\n");
const wrappers = actionsSorted
@@ -143,7 +143,7 @@ const entryPointsPlugin = {
};
});
// Emit entry point stubs for each action using the entry template.
// Emit entry point stubs for each Action using the entry template.
build.onEnd(async (result) => {
// Read the entry point template.
const templatePath = "action-entry.js.tpl";
@@ -152,7 +152,7 @@ const entryPointsPlugin = {
const makeHeader = (sourceFile) =>
`// Automatically generated from '${templatePath}' for 'src/${basename(sourceFile)}'.\n\n`;
// Write entry point stubs for each action.
// Write entry point stubs for each Action.
for (const action of actions) {
await writeFile(
join(
+16 -15
View File
@@ -148304,7 +148304,7 @@ function getDiffRangesJsonFilePath() {
return path2.join(getTemporaryDirectory(), PR_DIFF_RANGE_JSON_FILENAME);
}
function getActionVersion() {
return "4.35.5";
return "4.36.1";
}
function getWorkflowEventName() {
return getRequiredEnvParam("GITHUB_EVENT_NAME");
@@ -148973,7 +148973,7 @@ var determineBaseBranchHeadCommitOid = async function(checkoutPathOverride) {
}
}
}
if (commitOid === mergeSha && headOid.length === 40 && baseOid.length === 40) {
if (commitOid === mergeSha && (headOid.length === 40 || headOid.length === 64) && (baseOid.length === 40 || baseOid.length === 64)) {
return baseOid;
}
return void 0;
@@ -149039,7 +149039,7 @@ var getFileOidsUnderPath = async function(basePath) {
"Cannot list Git OIDs of tracked files."
);
const fileOidMap = {};
const regex = /^[0-9]+ ([0-9a-f]{40}) [0-9]+\t(.+)$/;
const regex = /^[0-9]+ ([0-9a-f]{40}|[0-9a-f]{64}) [0-9]+\t(.+)$/;
for (const line of stdout.split("\n")) {
if (line) {
const match = line.match(regex);
@@ -153719,7 +153719,7 @@ async function getCombinedTracerConfig(codeql, config) {
// src/codeql.ts
var cachedCodeQL = void 0;
var CODEQL_MINIMUM_VERSION = "2.17.6";
var CODEQL_MINIMUM_VERSION = "2.19.4";
var CODEQL_NEXT_MINIMUM_VERSION = "2.19.4";
var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15";
var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09";
@@ -153846,10 +153846,6 @@ async function getCodeQLForCmd(cmd, checkVersion) {
if (qlconfigFile !== void 0) {
extraArgs.push(`--qlconfig-file=${qlconfigFile}`);
}
const overwriteFlag = isSupportedToolsFeature(
await this.getVersion(),
"forceOverwrite" /* ForceOverwrite */
) ? "--force-overwrite" : "--overwrite";
const overlayDatabaseMode = config.overlayDatabaseMode;
if (overlayDatabaseMode === "overlay" /* Overlay */) {
const overlayChangesFile = await writeOverlayChangesFile(
@@ -153870,7 +153866,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
[
"database",
"init",
...overlayDatabaseMode === "overlay" /* Overlay */ ? [] : [overwriteFlag],
...overlayDatabaseMode === "overlay" /* Overlay */ ? [] : ["--force-overwrite"],
"--db-cluster",
config.dbLocation,
`--source-root=${sourceRoot}`,
@@ -153881,7 +153877,14 @@ async function getCodeQLForCmd(cmd, checkVersion) {
// Some user configs specify `--no-calculate-baseline` as an additional
// argument to `codeql database init`. Therefore ignore the baseline file
// options here to avoid specifying the same argument twice and erroring.
ignoringOptions: ["--overwrite", ...baselineFilesOptions]
//
// Ignore `--overwrite` to avoid passing both `--force-overwrite` and `--overwrite` if
// the user has configured `--overwrite`.
ignoringOptions: [
"--force-overwrite",
"--overwrite",
...baselineFilesOptions
]
})
],
{ stdin: externalRepositoryToken }
@@ -154046,7 +154049,7 @@ ${output}`
"--sarif-group-rules-by-pack",
"--sarif-include-query-help=always",
"--sublanguage-file-coverage",
...await getJobRunUuidSarifOptions(this),
...await getJobRunUuidSarifOptions(),
...getExtraOptionsFromEnv(["database", "interpret-results"])
];
if (sarifRunPropertyFlag !== void 0) {
@@ -154327,11 +154330,9 @@ function applyAutobuildAzurePipelinesTimeoutFix() {
"-Dmaven.wagon.http.pool=false"
].join(" ");
}
async function getJobRunUuidSarifOptions(codeql) {
async function getJobRunUuidSarifOptions() {
const jobRunUuid = process.env["JOB_RUN_UUID" /* JOB_RUN_UUID */];
return jobRunUuid && await codeql.supportsFeature(
"databaseInterpretResultsSupportsSarifRunProperty" /* DatabaseInterpretResultsSupportsSarifRunProperty */
) ? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`] : [];
return jobRunUuid ? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`] : [];
}
// src/autobuild.ts
+16 -15
View File
@@ -88509,7 +88509,7 @@ function getDiffRangesJsonFilePath() {
return path2.join(getTemporaryDirectory(), PR_DIFF_RANGE_JSON_FILENAME);
}
function getActionVersion() {
return "4.35.5";
return "4.36.1";
}
function getWorkflowEventName() {
return getRequiredEnvParam("GITHUB_EVENT_NAME");
@@ -89032,7 +89032,7 @@ var determineBaseBranchHeadCommitOid = async function(checkoutPathOverride) {
}
}
}
if (commitOid === mergeSha && headOid.length === 40 && baseOid.length === 40) {
if (commitOid === mergeSha && (headOid.length === 40 || headOid.length === 64) && (baseOid.length === 40 || baseOid.length === 64)) {
return baseOid;
}
return void 0;
@@ -89098,7 +89098,7 @@ var getFileOidsUnderPath = async function(basePath) {
"Cannot list Git OIDs of tracked files."
);
const fileOidMap = {};
const regex = /^[0-9]+ ([0-9a-f]{40}) [0-9]+\t(.+)$/;
const regex = /^[0-9]+ ([0-9a-f]{40}|[0-9a-f]{64}) [0-9]+\t(.+)$/;
for (const line of stdout.split("\n")) {
if (line) {
const match = line.match(regex);
@@ -91212,7 +91212,7 @@ async function shouldEnableIndirectTracing(codeql, config) {
// src/codeql.ts
var cachedCodeQL = void 0;
var CODEQL_MINIMUM_VERSION = "2.17.6";
var CODEQL_MINIMUM_VERSION = "2.19.4";
var CODEQL_NEXT_MINIMUM_VERSION = "2.19.4";
var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15";
var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09";
@@ -91339,10 +91339,6 @@ async function getCodeQLForCmd(cmd, checkVersion) {
if (qlconfigFile !== void 0) {
extraArgs.push(`--qlconfig-file=${qlconfigFile}`);
}
const overwriteFlag = isSupportedToolsFeature(
await this.getVersion(),
"forceOverwrite" /* ForceOverwrite */
) ? "--force-overwrite" : "--overwrite";
const overlayDatabaseMode = config.overlayDatabaseMode;
if (overlayDatabaseMode === "overlay" /* Overlay */) {
const overlayChangesFile = await writeOverlayChangesFile(
@@ -91363,7 +91359,7 @@ async function getCodeQLForCmd(cmd, checkVersion) {
[
"database",
"init",
...overlayDatabaseMode === "overlay" /* Overlay */ ? [] : [overwriteFlag],
...overlayDatabaseMode === "overlay" /* Overlay */ ? [] : ["--force-overwrite"],
"--db-cluster",
config.dbLocation,
`--source-root=${sourceRoot}`,
@@ -91374,7 +91370,14 @@ async function getCodeQLForCmd(cmd, checkVersion) {
// Some user configs specify `--no-calculate-baseline` as an additional
// argument to `codeql database init`. Therefore ignore the baseline file
// options here to avoid specifying the same argument twice and erroring.
ignoringOptions: ["--overwrite", ...baselineFilesOptions]
//
// Ignore `--overwrite` to avoid passing both `--force-overwrite` and `--overwrite` if
// the user has configured `--overwrite`.
ignoringOptions: [
"--force-overwrite",
"--overwrite",
...baselineFilesOptions
]
})
],
{ stdin: externalRepositoryToken }
@@ -91539,7 +91542,7 @@ ${output}`
"--sarif-group-rules-by-pack",
"--sarif-include-query-help=always",
"--sublanguage-file-coverage",
...await getJobRunUuidSarifOptions(this),
...await getJobRunUuidSarifOptions(),
...getExtraOptionsFromEnv(["database", "interpret-results"])
];
if (sarifRunPropertyFlag !== void 0) {
@@ -91820,11 +91823,9 @@ function applyAutobuildAzurePipelinesTimeoutFix() {
"-Dmaven.wagon.http.pool=false"
].join(" ");
}
async function getJobRunUuidSarifOptions(codeql) {
async function getJobRunUuidSarifOptions() {
const jobRunUuid = process.env["JOB_RUN_UUID" /* JOB_RUN_UUID */];
return jobRunUuid && await codeql.supportsFeature(
"databaseInterpretResultsSupportsSarifRunProperty" /* DatabaseInterpretResultsSupportsSarifRunProperty */
) ? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`] : [];
return jobRunUuid ? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`] : [];
}
// src/fingerprints.ts
+207 -309
View File
@@ -1,12 +1,12 @@
{
"name": "codeql",
"version": "4.35.5",
"version": "4.36.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "codeql",
"version": "4.35.5",
"version": "4.36.1",
"license": "MIT",
"workspaces": [
"pr-checks"
@@ -36,7 +36,7 @@
"uuid": "^14.0.0"
},
"devDependencies": {
"@ava/typescript": "7.0.0",
"@ava/typescript": "6.0.0",
"@eslint/compat": "^2.0.5",
"@microsoft/eslint-formatter-sarif": "^3.1.0",
"@octokit/types": "^16.0.0",
@@ -48,7 +48,7 @@
"@types/sarif": "^2.1.7",
"@types/semver": "^7.7.1",
"@types/sinon": "^21.0.1",
"ava": "^7.0.0",
"ava": "^6.4.1",
"esbuild": "^0.28.0",
"eslint": "^9.39.4",
"eslint-import-resolver-typescript": "^4.4.4",
@@ -59,7 +59,7 @@
"glob": "^11.1.0",
"globals": "^17.6.0",
"nock": "^14.0.12",
"sinon": "^21.1.2",
"sinon": "^22.0.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.59.2"
}
@@ -450,17 +450,17 @@
}
},
"node_modules/@ava/typescript": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@ava/typescript/-/typescript-7.0.0.tgz",
"integrity": "sha512-0ktzq4/9ya2QoAuVWzl3McpLV9W//Tj+oMonQ4ucgm5l6tQ46aaju/rJL9kzeY5MkG6wzXvFt/MmaLqf9uNC9w==",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@ava/typescript/-/typescript-6.0.0.tgz",
"integrity": "sha512-+8oDYc4J5cCaWZh1VUbyc+cegGplJO9FqHpqR4LVAVx8fRLVRaYlC4yyA6cqHJ1vWP23Ff/ECS5U68Zz6OLZlg==",
"dev": true,
"license": "MIT",
"dependencies": {
"escape-string-regexp": "^5.0.0",
"execa": "^9.6.1"
"execa": "^9.6.0"
},
"engines": {
"node": "^22.20 || ^24.12 || >=25"
"node": "^20.8 || ^22 || >=24"
}
},
"node_modules/@ava/typescript/node_modules/escape-string-regexp": {
@@ -2379,9 +2379,9 @@
}
},
"node_modules/@sinonjs/fake-timers": {
"version": "15.3.2",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz",
"integrity": "sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==",
"version": "15.4.0",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz",
"integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -3172,9 +3172,9 @@
]
},
"node_modules/@vercel/nft": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-1.3.2.tgz",
"integrity": "sha512-HC8venRc4Ya7vNeBsJneKHHMDDWpQie7VaKhAIOst3MKO+DES+Y/SbzSp8mFkD7OzwAE2HhHkeSuSmwS20mz3A==",
"version": "0.29.4",
"resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.29.4.tgz",
"integrity": "sha512-6lLqMNX3TuycBPABycx7A9F1bHQR7kiQln6abjFbPrf5C/05qHM9M5E4PeTE59c7z8g6vHnx1Ioihb2AQl7BTA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3185,7 +3185,7 @@
"async-sema": "^3.1.1",
"bindings": "^1.4.0",
"estree-walker": "2.0.2",
"glob": "^13.0.0",
"glob": "^10.4.5",
"graceful-fs": "^4.2.9",
"node-gyp-build": "^4.2.2",
"picomatch": "^4.0.2",
@@ -3195,7 +3195,7 @@
"nft": "out/cli.js"
},
"engines": {
"node": ">=20"
"node": ">=18"
}
},
"node_modules/abbrev": {
@@ -3561,57 +3561,58 @@
"license": "MIT"
},
"node_modules/ava": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/ava/-/ava-7.0.0.tgz",
"integrity": "sha512-4sRJO/gehlfAgSbuH02mClDDiyymnuFmirE3KqPXl2pic1FaFTZaAACKqr85WT4o08iLjViMR9gmMkxzbZ3AgA==",
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/ava/-/ava-6.4.1.tgz",
"integrity": "sha512-vxmPbi1gZx9zhAjHBgw81w/iEDKcrokeRk/fqDTyA2DQygZ0o+dUGRHFOtX8RA5N0heGJTTsIk7+xYxitDb61Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vercel/nft": "^1.3.2",
"acorn": "^8.16.0",
"acorn-walk": "^8.3.5",
"ansi-styles": "^6.2.3",
"@vercel/nft": "^0.29.4",
"acorn": "^8.15.0",
"acorn-walk": "^8.3.4",
"ansi-styles": "^6.2.1",
"arrgv": "^1.0.2",
"arrify": "^3.0.0",
"callsites": "^4.2.0",
"cbor": "^10.0.11",
"chalk": "^5.6.2",
"cbor": "^10.0.9",
"chalk": "^5.4.1",
"chunkd": "^2.0.1",
"ci-info": "^4.4.0",
"ci-info": "^4.3.0",
"ci-parallel-vars": "^1.0.1",
"cli-truncate": "^5.1.1",
"cli-truncate": "^4.0.0",
"code-excerpt": "^4.0.0",
"common-path-prefix": "^3.0.0",
"concordance": "^5.0.4",
"currently-unhandled": "^0.4.1",
"debug": "^4.4.3",
"debug": "^4.4.1",
"emittery": "^1.2.0",
"figures": "^6.1.0",
"globby": "^16.1.1",
"globby": "^14.1.0",
"ignore-by-default": "^2.1.0",
"indent-string": "^5.0.0",
"is-plain-object": "^5.0.0",
"is-promise": "^4.0.0",
"matcher": "^6.0.0",
"memoize": "^10.2.0",
"matcher": "^5.0.0",
"memoize": "^10.1.0",
"ms": "^2.1.3",
"p-map": "^7.0.4",
"p-map": "^7.0.3",
"package-config": "^5.0.0",
"picomatch": "^4.0.3",
"plur": "^6.0.0",
"pretty-ms": "^9.3.0",
"picomatch": "^4.0.2",
"plur": "^5.1.0",
"pretty-ms": "^9.2.0",
"resolve-cwd": "^3.0.0",
"stack-utils": "^2.0.6",
"strip-ansi": "^7.1.0",
"supertap": "^3.0.1",
"temp-dir": "^3.0.0",
"write-file-atomic": "^7.0.0",
"yargs": "^18.0.0"
"write-file-atomic": "^6.0.0",
"yargs": "^17.7.2"
},
"bin": {
"ava": "entrypoints/cli.mjs"
},
"engines": {
"node": "^20.19 || ^22.20 || ^24.12 || >=25"
"node": "^18.18 || ^20.8 || ^22 || ^23 || >=24"
},
"peerDependencies": {
"@ava/typescript": "*"
@@ -3622,6 +3623,19 @@
}
}
},
"node_modules/ava/node_modules/ansi-regex": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/ava/node_modules/callsites": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-4.2.0.tgz",
@@ -3652,6 +3666,22 @@
}
}
},
"node_modules/ava/node_modules/strip-ansi": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.2.2"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/available-typed-arrays": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
@@ -4016,17 +4046,17 @@
"dev": true
},
"node_modules/cli-truncate": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz",
"integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz",
"integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==",
"dev": true,
"license": "MIT",
"dependencies": {
"slice-ansi": "^8.0.0",
"string-width": "^8.2.0"
"slice-ansi": "^5.0.0",
"string-width": "^7.0.0"
},
"engines": {
"node": ">=20"
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -4045,18 +4075,26 @@
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/cli-truncate/node_modules/emoji-regex": {
"version": "10.6.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
"integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
"dev": true,
"license": "MIT"
},
"node_modules/cli-truncate/node_modules/string-width": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz",
"integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"get-east-asian-width": "^1.5.0",
"strip-ansi": "^7.1.2"
"emoji-regex": "^10.3.0",
"get-east-asian-width": "^1.0.0",
"strip-ansi": "^7.1.0"
},
"engines": {
"node": ">=20"
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -4079,72 +4117,18 @@
}
},
"node_modules/cliui": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz",
"integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==",
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dev": true,
"license": "ISC",
"dependencies": {
"string-width": "^7.2.0",
"strip-ansi": "^7.1.0",
"wrap-ansi": "^9.0.0"
},
"engines": {
"node": ">=20"
}
},
"node_modules/cliui/node_modules/ansi-regex": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/cliui/node_modules/emoji-regex": {
"version": "10.6.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
"integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
"dev": true,
"license": "MIT"
},
"node_modules/cliui/node_modules/string-width": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^10.3.0",
"get-east-asian-width": "^1.0.0",
"strip-ansi": "^7.1.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/cliui/node_modules/strip-ansi": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.2.2"
"string-width": "^4.2.0",
"strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/code-excerpt": {
@@ -4458,9 +4442,9 @@
}
},
"node_modules/diff": {
"version": "8.0.4",
"resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz",
"integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-9.0.0.tgz",
"integrity": "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
@@ -5939,9 +5923,9 @@
}
},
"node_modules/get-east-asian-width": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz",
"integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
"integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6151,21 +6135,34 @@
}
},
"node_modules/globby": {
"version": "16.1.1",
"resolved": "https://registry.npmjs.org/globby/-/globby-16.1.1.tgz",
"integrity": "sha512-dW7vl+yiAJSp6aCekaVnVJxurRv7DCOLyXqEG3RYMYUg7AuJ2jCqPkZTA8ooqC2vtnkaMcV5WfFBMuEnTu1OQg==",
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz",
"integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@sindresorhus/merge-streams": "^4.0.0",
"@sindresorhus/merge-streams": "^2.1.0",
"fast-glob": "^3.3.3",
"ignore": "^7.0.5",
"is-path-inside": "^4.0.0",
"ignore": "^7.0.3",
"path-type": "^6.0.0",
"slash": "^5.1.0",
"unicorn-magic": "^0.4.0"
"unicorn-magic": "^0.3.0"
},
"engines": {
"node": ">=20"
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/globby/node_modules/@sindresorhus/merge-streams": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz",
"integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -6181,32 +6178,6 @@
"node": ">= 4"
}
},
"node_modules/globby/node_modules/is-path-inside": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz",
"integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/globby/node_modules/unicorn-magic": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz",
"integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -6471,16 +6442,13 @@
}
},
"node_modules/irregular-plurals": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-4.2.0.tgz",
"integrity": "sha512-bW9UXHL7bnUcNtTo+9ccSngbxc+V40H32IgvdVin0Xs8gbo+AVYD5g/72ce/54Kjfhq66vcZr8H8TKEvsifeOw==",
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz",
"integrity": "sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18.20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
"node": ">=8"
}
},
"node_modules/is-array-buffer": {
@@ -7251,16 +7219,16 @@
}
},
"node_modules/matcher": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/matcher/-/matcher-6.0.0.tgz",
"integrity": "sha512-TzDerdcNtI79w7Av4GT57bLdElPA/VAkjqdMZv8yhuc8geU2z0ljW9anXbX/55aHEMTpYypZb1lxsA/46r9oOQ==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/matcher/-/matcher-5.0.0.tgz",
"integrity": "sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==",
"dev": true,
"license": "MIT",
"dependencies": {
"escape-string-regexp": "^5.0.0"
},
"engines": {
"node": ">=20"
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -7881,6 +7849,19 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/path-type": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz",
"integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -7902,16 +7883,16 @@
}
},
"node_modules/plur": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/plur/-/plur-6.0.0.tgz",
"integrity": "sha512-Y9wXQivjRX0REtwpA9+n0bYYypWESn3cWtW2vazymw711qn+AQXxzZjRqhANYGBLIMC1UzVdpwe/1hHQwHfwng==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/plur/-/plur-5.1.0.tgz",
"integrity": "sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==",
"dev": true,
"license": "MIT",
"dependencies": {
"irregular-plurals": "^4.2.0"
"irregular-plurals": "^3.3.0"
},
"engines": {
"node": ">=20"
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -8128,6 +8109,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/requireindex": {
"version": "1.1.0",
"dev": true,
@@ -8511,16 +8502,16 @@
}
},
"node_modules/sinon": {
"version": "21.1.2",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-21.1.2.tgz",
"integrity": "sha512-FS6mN+/bx7e2ajpXkEmOcWB6xBzWiuNoAQT18/+a20SS4U7FSYl8Ms7N6VTUxN/1JAjkx7aXp+THMC8xdpp0gA==",
"version": "22.0.0",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-22.0.0.tgz",
"integrity": "sha512-sq/6DpdXOrLyfbKlXLg/Usc7xu8YXPeLkOFZRvA3bNUSA2lhbrZ06yuXbH1fkzBPCbz9O10+7hznzUsjaYNm0Q==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@sinonjs/commons": "^3.0.1",
"@sinonjs/fake-timers": "^15.3.2",
"@sinonjs/fake-timers": "^15.4.0",
"@sinonjs/samsam": "^10.0.2",
"diff": "^8.0.4"
"diff": "^9.0.0"
},
"funding": {
"type": "opencollective",
@@ -8541,33 +8532,30 @@
}
},
"node_modules/slice-ansi": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz",
"integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz",
"integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^6.2.3",
"is-fullwidth-code-point": "^5.1.0"
"ansi-styles": "^6.0.0",
"is-fullwidth-code-point": "^4.0.0"
},
"engines": {
"node": ">=20"
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
}
},
"node_modules/slice-ansi/node_modules/is-fullwidth-code-point": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz",
"integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz",
"integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"get-east-asian-width": "^1.3.1"
},
"engines": {
"node": ">=18"
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -8962,9 +8950,9 @@
}
},
"node_modules/tar": {
"version": "7.5.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.11.tgz",
"integrity": "sha512-ChjMH33/KetonMTAtpYdgUFr0tbz69Fp2v7zWxQfYZX4g5ZN2nOBXm1R2xyA+lMIKrLKIoKAwFj93jE/avX9cQ==",
"version": "7.5.15",
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.15.tgz",
"integrity": "sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
@@ -10104,18 +10092,18 @@
}
},
"node_modules/wrap-ansi": {
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
"integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^6.2.1",
"string-width": "^7.0.0",
"strip-ansi": "^7.1.0"
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=18"
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
@@ -10154,58 +10142,20 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/wrap-ansi/node_modules/ansi-regex": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/wrap-ansi/node_modules/emoji-regex": {
"version": "10.6.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
"integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
"dev": true,
"license": "MIT"
},
"node_modules/wrap-ansi/node_modules/string-width": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
"node_modules/wrap-ansi/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^10.3.0",
"get-east-asian-width": "^1.0.0",
"strip-ansi": "^7.1.0"
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=18"
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/wrap-ansi/node_modules/strip-ansi": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.2.2"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/wrappy": {
@@ -10213,16 +10163,17 @@
"license": "ISC"
},
"node_modules/write-file-atomic": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-7.0.1.tgz",
"integrity": "sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==",
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-6.0.0.tgz",
"integrity": "sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ==",
"dev": true,
"license": "ISC",
"dependencies": {
"imurmurhash": "^0.1.4",
"signal-exit": "^4.0.1"
},
"engines": {
"node": "^20.17.0 || >=22.9.0"
"node": "^18.17.0 || >=20.5.0"
}
},
"node_modules/xml-naming": {
@@ -10276,85 +10227,32 @@
}
},
"node_modules/yargs": {
"version": "18.0.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz",
"integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==",
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dev": true,
"license": "MIT",
"dependencies": {
"cliui": "^9.0.1",
"cliui": "^8.0.1",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"string-width": "^7.2.0",
"require-directory": "^2.1.1",
"string-width": "^4.2.3",
"y18n": "^5.0.5",
"yargs-parser": "^22.0.0"
"yargs-parser": "^21.1.1"
},
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=23"
"node": ">=12"
}
},
"node_modules/yargs-parser": {
"version": "22.0.0",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz",
"integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==",
"version": "21.1.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"dev": true,
"license": "ISC",
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=23"
}
},
"node_modules/yargs/node_modules/ansi-regex": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/yargs/node_modules/emoji-regex": {
"version": "10.6.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
"integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
"dev": true,
"license": "MIT"
},
"node_modules/yargs/node_modules/string-width": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^10.3.0",
"get-east-asian-width": "^1.0.0",
"strip-ansi": "^7.1.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/yargs/node_modules/strip-ansi": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.2.2"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/yocto-queue": {
+6 -5
View File
@@ -1,6 +1,6 @@
{
"name": "codeql",
"version": "4.35.5",
"version": "4.36.1",
"private": true,
"description": "CodeQL action",
"scripts": {
@@ -12,7 +12,8 @@
"ava": "npm run transpile && ava --verbose",
"test": "npm run ava -- src/",
"test-debug": "npm run test -- --timeout=20m",
"transpile": "tsc --build --verbose tsconfig.json"
"transpile": "tsc --build --verbose tsconfig.json",
"update-pr-checks": "./pr-checks/sync.sh"
},
"license": "MIT",
"workspaces": [
@@ -43,7 +44,7 @@
"uuid": "^14.0.0"
},
"devDependencies": {
"@ava/typescript": "7.0.0",
"@ava/typescript": "6.0.0",
"@eslint/compat": "^2.0.5",
"@microsoft/eslint-formatter-sarif": "^3.1.0",
"@octokit/types": "^16.0.0",
@@ -55,7 +56,7 @@
"@types/sarif": "^2.1.7",
"@types/semver": "^7.7.1",
"@types/sinon": "^21.0.1",
"ava": "^7.0.0",
"ava": "^6.4.1",
"esbuild": "^0.28.0",
"eslint": "^9.39.4",
"eslint-import-resolver-typescript": "^4.4.4",
@@ -66,7 +67,7 @@
"glob": "^11.1.0",
"globals": "^17.6.0",
"nock": "^14.0.12",
"sinon": "^21.1.2",
"sinon": "^22.0.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.59.2"
},
@@ -2,7 +2,8 @@ name: "Multi-language repository"
description: "An end-to-end integration test of a multi-language repository using automatic language detection"
operatingSystems:
- ubuntu
- macos
- os: macos
runner-image: macos-latest-xlarge
env:
CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI: true
installGo: true
+1 -1
View File
@@ -2,7 +2,7 @@ name: "Rust analysis"
description: "Tests creation of a Rust database"
versions:
# experimental rust support introduced, requires action to set `CODEQL_ENABLE_EXPERIMENTAL_FEATURES`
- stable-v2.19.3
- stable-v2.19.4
# first public preview version
- stable-v2.22.1
- linked
+2 -1
View File
@@ -3,7 +3,8 @@ description: "Tests creation of a Swift database using autobuild"
versions:
- nightly-latest
operatingSystems:
- macos
- os: macos
runner-image: macos-latest-xlarge
steps:
- uses: ./../action/init
id: init
+50 -1
View File
@@ -7,7 +7,13 @@ Tests for the sync-checks.ts script
import * as assert from "node:assert/strict";
import { describe, it } from "node:test";
import { CheckInfo, Exclusions, Options, removeExcluded } from "./sync-checks";
import {
CheckInfo,
Exclusions,
Options,
removeExcluded,
resolveToken,
} from "./sync-checks";
const defaultOptions: Options = {
apply: false,
@@ -58,3 +64,46 @@ describe("removeExcluded", async () => {
assert.deepEqual(retained, expectedExactMatches);
});
});
describe("resolveToken", async () => {
await it("reads the token from standard input", async () => {
const token = await resolveToken(
{ tokenStdin: true },
{ env: {}, readStdin: async () => " stdin-token\n" },
);
assert.equal(token, "stdin-token");
});
await it("reads the token from the GH_TOKEN environment variable", async () => {
const token = await resolveToken(
{},
{ env: { GH_TOKEN: "env-token" }, readStdin: async () => "" },
);
assert.equal(token, "env-token");
});
await it("reads the token from the GITHUB_TOKEN environment variable", async () => {
const token = await resolveToken(
{},
{ env: { GITHUB_TOKEN: "env-token" }, readStdin: async () => "" },
);
assert.equal(token, "env-token");
});
await it("rejects an empty standard input token", async () => {
await assert.rejects(
resolveToken(
{ tokenStdin: true },
{ env: {}, readStdin: async () => "\n" },
),
/No token received on standard input/,
);
});
await it("rejects missing token sources", async () => {
await assert.rejects(
resolveToken({}, { env: {}, readStdin: async () => "" }),
/Missing authentication token/,
);
});
});
+69 -9
View File
@@ -15,8 +15,8 @@ import {
/** Represents the command-line options. */
export interface Options {
/** The token to use to authenticate to the GitHub API. */
token?: string;
/** Whether to read the GitHub API token from standard input. */
tokenStdin?: boolean;
/** The git ref to use the checks for. */
ref?: string;
/** Whether to actually apply the changes or not. */
@@ -31,6 +31,65 @@ const codeqlActionRepo = {
repo: "codeql-action",
};
/** Environment variables to check for a GitHub API token. */
const TOKEN_ENVIRONMENT_VARIABLES = ["GH_TOKEN", "GITHUB_TOKEN"];
/** Represents the sources from which we can retrieve the GitHub API token. */
interface TokenSource {
/** Environment variables to inspect. */
env: NodeJS.ProcessEnv;
/** Reads a token from standard input. */
readStdin: () => Promise<string>;
}
/** Reads the GitHub API token from standard input. */
async function readTokenFromStdin(): Promise<string> {
let token = "";
process.stdin.setEncoding("utf8");
for await (const chunk of process.stdin) {
token += chunk;
}
return token.trim();
}
/** Gets a GitHub API token from one of the supported environment variables. */
function getTokenFromEnvironment(env: NodeJS.ProcessEnv): string | undefined {
for (const variableName of TOKEN_ENVIRONMENT_VARIABLES) {
const token = env[variableName]?.trim();
if (token) {
return token;
}
}
return undefined;
}
/** Gets the token to use to authenticate to the GitHub API. */
export async function resolveToken(
options: Pick<Options, "tokenStdin">,
tokenSource: TokenSource = {
env: process.env,
readStdin: readTokenFromStdin,
},
): Promise<string> {
if (options.tokenStdin) {
const token = (await tokenSource.readStdin()).trim();
if (token.length === 0) {
throw new Error("No token received on standard input.");
}
return token;
}
const environmentToken = getTokenFromEnvironment(tokenSource.env);
if (environmentToken !== undefined) {
return environmentToken;
}
throw new Error(
"Missing authentication token. Set GH_TOKEN/GITHUB_TOKEN or pipe a token " +
"to --token-stdin.",
);
}
/** Represents a configuration of which checks should not be set up as required checks. */
export interface Exclusions {
/** A list of strings that, if contained in a check name, are excluded. */
@@ -205,9 +264,10 @@ async function updateBranch(
async function main(): Promise<void> {
const { values: options } = parseArgs({
options: {
// The token to use to authenticate to the API.
token: {
type: "string",
// Read the token to use to authenticate to the API from standard input.
"token-stdin": {
type: "boolean",
default: false,
},
// The git ref for which to retrieve the check runs.
ref: {
@@ -228,16 +288,16 @@ async function main(): Promise<void> {
strict: true,
});
if (options.token === undefined) {
throw new Error("Missing --token");
}
const token = await resolveToken({
tokenStdin: options["token-stdin"],
});
console.info(
`Oldest supported major version is: ${OLDEST_SUPPORTED_MAJOR_VERSION}`,
);
// Initialise the API client.
const client = getApiClient(options.token);
const client = getApiClient(token);
// Find the check runs for the specified `ref` that we will later set as the required checks
// for the main and release branches.
+42 -11
View File
@@ -28,6 +28,24 @@ interface WorkflowInput {
/** A partial mapping from known input names to input definitions. */
type WorkflowInputs = Partial<Record<KnownInputName, WorkflowInput>>;
/** An operating system identifier. */
type OperatingSystemIdentifier = "ubuntu" | "macos" | "windows";
/**
* Represents an operating system matrix entry for a generated PR check workflow.
*
* Either a string containing the OS identifier or an object containing the OS identifier and an
* optional runner image label.
*/
type OperatingSystem =
| OperatingSystemIdentifier
| {
/** OS identifier. */
os: OperatingSystemIdentifier;
/** Optional runner image label. */
"runner-image"?: string;
};
/**
* Represents PR check specifications.
*/
@@ -36,8 +54,8 @@ interface Specification extends JobSpecification {
inputs?: Record<string, WorkflowInput>;
/** CodeQL bundle versions to test against. Defaults to `DEFAULT_TEST_VERSIONS`. */
versions?: string[];
/** Operating system prefixes used to select runner images (e.g. `["ubuntu", "macos"]`). */
operatingSystems?: string[];
/** Operating system prefixes, either as strings or with explicit runner image labels. */
operatingSystems?: OperatingSystem[];
/** Per-OS version overrides. If specified for an OS, only those versions are tested on that OS. */
osCodeQlVersions?: Record<string, string[]>;
/** Whether to use the all-platform CodeQL bundle. */
@@ -97,10 +115,6 @@ type LanguageSetups = Partial<Record<BuiltInLanguage, LanguageSetup>>;
// The default set of CodeQL Bundle versions to use for the PR checks.
const defaultTestVersions = [
// The oldest supported CodeQL version. If bumping, update `CODEQL_MINIMUM_VERSION` in `codeql.ts`
"stable-v2.17.6",
// The last CodeQL release in the 2.18 series.
"stable-v2.18.4",
// The last CodeQL release in the 2.19 series.
"stable-v2.19.4",
// The last CodeQL release in the 2.20 series.
"stable-v2.20.7",
@@ -108,6 +122,10 @@ const defaultTestVersions = [
"stable-v2.21.4",
// The last CodeQL release in the 2.22 series.
"stable-v2.22.4",
// The last CodeQL release in the 2.23 series.
"stable-v2.23.9",
// The last CodeQL release in the 2.24 series.
"stable-v2.24.3",
// The default version of CodeQL for Dotcom, as determined by feature flags.
"default",
// The version of CodeQL shipped with the Action in `defaults.json`. During the release process
@@ -311,10 +329,19 @@ function generateJobMatrix(
);
}
const runnerImages = ["ubuntu-latest", "macos-latest", "windows-latest"];
const defaultRunnerImages = [
"ubuntu-latest",
"macos-latest",
"windows-latest",
];
const operatingSystems = checkSpecification.operatingSystems ?? ["ubuntu"];
for (const operatingSystem of operatingSystems) {
for (const operatingSystemConfig of operatingSystems) {
const operatingSystem =
typeof operatingSystemConfig === "string"
? operatingSystemConfig
: operatingSystemConfig.os;
// If osCodeQlVersions is set for this OS, only include the specified CodeQL versions.
const allowedVersions =
checkSpecification.osCodeQlVersions?.[operatingSystem];
@@ -322,9 +349,13 @@ function generateJobMatrix(
continue;
}
const runnerImagesForOs = runnerImages.filter((image) =>
image.startsWith(operatingSystem),
);
const runnerImagesForOs =
typeof operatingSystemConfig === "string" ||
operatingSystemConfig["runner-image"] === undefined
? defaultRunnerImages.filter((image) =>
image.startsWith(operatingSystem),
)
: [operatingSystemConfig["runner-image"]];
for (const runnerImage of runnerImagesForOs) {
matrix.push({
-85
View File
@@ -1,85 +0,0 @@
import test from "ava";
import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import * as analyze from "./analyze";
import { runWrapper } from "./analyze-action";
import * as api from "./api-client";
import * as configUtils from "./config-utils";
import * as gitUtils from "./git-utils";
import * as statusReport from "./status-report";
import {
setupTests,
setupActionsVars,
mockFeatureFlagApiEndpoint,
} from "./testing-utils";
import * as util from "./util";
setupTests(test);
// This test needs to be in its own file so that ava would run it in its own
// nodejs process. The code being tested is in analyze-action.ts, which runs
// immediately on load. So the file needs to be loaded during part of the test,
// and that can happen only once per nodejs process. If multiple such tests are
// in the same test file, ava would run them in the same nodejs process, and all
// but the first test would fail.
test("analyze action with RAM & threads from environment variables", async (t) => {
// This test frequently times out on Windows with the default timeout, so we bump
// it a bit to 20s.
t.timeout(1000 * 20);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
sinon
.stub(statusReport, "createStatusReportBase")
.resolves({} as statusReport.StatusReportBase);
sinon.stub(statusReport, "sendStatusReport").resolves();
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
const gitHubVersion: util.GitHubVersion = {
type: util.GitHubVariant.DOTCOM,
};
sinon.stub(configUtils, "getConfig").resolves({
gitHubVersion,
augmentationProperties: {},
languages: [],
packs: [],
trapCaches: {},
} as unknown as configUtils.Config);
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
requiredInputStub.withArgs("token").returns("fake-token");
requiredInputStub.withArgs("upload-database").returns("false");
requiredInputStub.withArgs("output").returns("out");
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
optionalInputStub.withArgs("expect-error").returns("false");
sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion);
mockFeatureFlagApiEndpoint(200, {});
// When there are no action inputs for RAM and threads, the action uses
// environment variables (passed down from the init action) to set RAM and
// threads usage.
process.env["CODEQL_THREADS"] = "-1";
process.env["CODEQL_RAM"] = "4992";
const runFinalizeStub = sinon.stub(analyze, "runFinalize");
const runQueriesStub = sinon.stub(analyze, "runQueries");
await runWrapper();
t.assert(
runFinalizeStub.calledOnceWith(
sinon.match.any,
sinon.match.any,
"--threads=-1",
"--ram=4992",
),
);
t.assert(
runQueriesStub.calledOnceWith(
sinon.match.any,
"--ram=4992",
"--threads=-1",
),
);
});
});
-83
View File
@@ -1,83 +0,0 @@
import test from "ava";
import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import * as analyze from "./analyze";
import { runWrapper } from "./analyze-action";
import * as api from "./api-client";
import * as configUtils from "./config-utils";
import * as gitUtils from "./git-utils";
import * as statusReport from "./status-report";
import {
setupTests,
setupActionsVars,
mockFeatureFlagApiEndpoint,
} from "./testing-utils";
import * as util from "./util";
setupTests(test);
// This test needs to be in its own file so that ava would run it in its own
// nodejs process. The code being tested is in analyze-action.ts, which runs
// immediately on load. So the file needs to be loaded during part of the test,
// and that can happen only once per nodejs process. If multiple such tests are
// in the same test file, ava would run them in the same nodejs process, and all
// but the first test would fail.
test("analyze action with RAM & threads from action inputs", async (t) => {
t.timeout(1000 * 20);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
sinon
.stub(statusReport, "createStatusReportBase")
.resolves({} as statusReport.StatusReportBase);
sinon.stub(statusReport, "sendStatusReport").resolves();
const gitHubVersion: util.GitHubVersion = {
type: util.GitHubVariant.DOTCOM,
};
sinon.stub(configUtils, "getConfig").resolves({
gitHubVersion,
augmentationProperties: {},
languages: [],
packs: [],
trapCaches: {},
} as unknown as configUtils.Config);
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
requiredInputStub.withArgs("token").returns("fake-token");
requiredInputStub.withArgs("upload-database").returns("false");
requiredInputStub.withArgs("output").returns("out");
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
optionalInputStub.withArgs("expect-error").returns("false");
sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion);
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
mockFeatureFlagApiEndpoint(200, {});
process.env["CODEQL_THREADS"] = "1";
process.env["CODEQL_RAM"] = "4992";
// Action inputs have precedence over environment variables.
optionalInputStub.withArgs("threads").returns("-1");
optionalInputStub.withArgs("ram").returns("3012");
const runFinalizeStub = sinon.stub(analyze, "runFinalize");
const runQueriesStub = sinon.stub(analyze, "runQueries");
await runWrapper();
t.assert(
runFinalizeStub.calledOnceWith(
sinon.match.any,
sinon.match.any,
"--threads=-1",
"--ram=3012",
),
);
t.assert(
runQueriesStub.calledOnceWith(
sinon.match.any,
"--ram=3012",
"--threads=-1",
),
);
});
});
+142
View File
@@ -0,0 +1,142 @@
import test from "ava";
import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import * as analyze from "./analyze";
import { runWrapper } from "./analyze-action";
import * as api from "./api-client";
import * as configUtils from "./config-utils";
import * as gitUtils from "./git-utils";
import * as statusReport from "./status-report";
import {
setupTests,
setupActionsVars,
mockFeatureFlagApiEndpoint,
} from "./testing-utils";
import * as util from "./util";
setupTests(test);
test.serial(
"analyze action with RAM & threads from environment variables",
async (t) => {
// This test frequently times out on Windows with the default timeout, so we bump
// it a bit to 20s.
t.timeout(1000 * 20);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
sinon
.stub(statusReport, "createStatusReportBase")
.resolves({} as statusReport.StatusReportBase);
sinon.stub(statusReport, "sendStatusReport").resolves();
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
const gitHubVersion: util.GitHubVersion = {
type: util.GitHubVariant.DOTCOM,
};
sinon.stub(configUtils, "getConfig").resolves({
gitHubVersion,
augmentationProperties: {},
languages: [],
packs: [],
trapCaches: {},
} as unknown as configUtils.Config);
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
requiredInputStub.withArgs("token").returns("fake-token");
requiredInputStub.withArgs("upload-database").returns("false");
requiredInputStub.withArgs("output").returns("out");
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
optionalInputStub.withArgs("expect-error").returns("false");
sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion);
mockFeatureFlagApiEndpoint(200, {});
// When there are no action inputs for RAM and threads, the action uses
// environment variables (passed down from the init action) to set RAM and
// threads usage.
process.env["CODEQL_THREADS"] = "-1";
process.env["CODEQL_RAM"] = "4992";
const runFinalizeStub = sinon.stub(analyze, "runFinalize");
const runQueriesStub = sinon.stub(analyze, "runQueries");
await runWrapper();
t.assert(
runFinalizeStub.calledOnceWith(
sinon.match.any,
sinon.match.any,
"--threads=-1",
"--ram=4992",
),
);
t.assert(
runQueriesStub.calledOnceWith(
sinon.match.any,
"--ram=4992",
"--threads=-1",
),
);
});
},
);
test.serial(
"analyze action with RAM & threads from action inputs",
async (t) => {
t.timeout(1000 * 20);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
sinon
.stub(statusReport, "createStatusReportBase")
.resolves({} as statusReport.StatusReportBase);
sinon.stub(statusReport, "sendStatusReport").resolves();
const gitHubVersion: util.GitHubVersion = {
type: util.GitHubVariant.DOTCOM,
};
sinon.stub(configUtils, "getConfig").resolves({
gitHubVersion,
augmentationProperties: {},
languages: [],
packs: [],
trapCaches: {},
} as unknown as configUtils.Config);
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
requiredInputStub.withArgs("token").returns("fake-token");
requiredInputStub.withArgs("upload-database").returns("false");
requiredInputStub.withArgs("output").returns("out");
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
optionalInputStub.withArgs("expect-error").returns("false");
sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion);
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
mockFeatureFlagApiEndpoint(200, {});
process.env["CODEQL_THREADS"] = "1";
process.env["CODEQL_RAM"] = "4992";
// Action inputs have precedence over environment variables.
optionalInputStub.withArgs("threads").returns("-1");
optionalInputStub.withArgs("ram").returns("3012");
const runFinalizeStub = sinon.stub(analyze, "runFinalize");
const runQueriesStub = sinon.stub(analyze, "runQueries");
await runWrapper();
t.assert(
runFinalizeStub.calledOnceWith(
sinon.match.any,
sinon.match.any,
"--threads=-1",
"--ram=3012",
),
);
t.assert(
runQueriesStub.calledOnceWith(
sinon.match.any,
"--ram=3012",
"--threads=-1",
),
);
});
},
);
+4 -4
View File
@@ -1072,7 +1072,7 @@ test.serial(
);
test.serial(
"Avoids duplicating --overwrite flag if specified in CODEQL_ACTION_EXTRA_OPTIONS",
"Avoids duplicating --force-overwrite flag if specified in CODEQL_ACTION_EXTRA_OPTIONS",
async (t) => {
const runnerConstructorStub = stubToolRunnerConstructor();
const codeqlObject = await stubCodeql();
@@ -1080,7 +1080,7 @@ test.serial(
sinon.stub(io, "which").resolves("");
process.env["CODEQL_ACTION_EXTRA_OPTIONS"] =
'{ "database": { "init": ["--overwrite"] } }';
'{ "database": { "init": ["--force-overwrite"] } }';
await codeqlObject.databaseInitCluster(
stubConfig,
@@ -1093,9 +1093,9 @@ test.serial(
t.true(runnerConstructorStub.calledOnce);
const args = runnerConstructorStub.firstCall.args[1] as string[];
t.is(
args.filter((option: string) => option === "--overwrite").length,
args.filter((option: string) => option === "--force-overwrite").length,
1,
"--overwrite should only be passed once",
"--force-overwrite should only be passed once",
);
// Clean up
+13 -18
View File
@@ -277,7 +277,7 @@ let cachedCodeQL: CodeQL | undefined = undefined;
* The version flags below can be used to conditionally enable certain features
* on versions newer than this.
*/
const CODEQL_MINIMUM_VERSION = "2.17.6";
const CODEQL_MINIMUM_VERSION = "2.19.4";
/**
* This version will shortly become the oldest version of CodeQL that the Action will run with.
@@ -592,13 +592,6 @@ async function getCodeQLForCmd(
extraArgs.push(`--qlconfig-file=${qlconfigFile}`);
}
const overwriteFlag = isSupportedToolsFeature(
await this.getVersion(),
ToolsFeature.ForceOverwrite,
)
? "--force-overwrite"
: "--overwrite";
const overlayDatabaseMode = config.overlayDatabaseMode;
if (overlayDatabaseMode === OverlayDatabaseMode.Overlay) {
const overlayChangesFile = await writeOverlayChangesFile(
@@ -625,7 +618,7 @@ async function getCodeQLForCmd(
"init",
...(overlayDatabaseMode === OverlayDatabaseMode.Overlay
? []
: [overwriteFlag]),
: ["--force-overwrite"]),
"--db-cluster",
config.dbLocation,
`--source-root=${sourceRoot}`,
@@ -636,7 +629,14 @@ async function getCodeQLForCmd(
// Some user configs specify `--no-calculate-baseline` as an additional
// argument to `codeql database init`. Therefore ignore the baseline file
// options here to avoid specifying the same argument twice and erroring.
ignoringOptions: ["--overwrite", ...baselineFilesOptions],
//
// Ignore `--overwrite` to avoid passing both `--force-overwrite` and `--overwrite` if
// the user has configured `--overwrite`.
ignoringOptions: [
"--force-overwrite",
"--overwrite",
...baselineFilesOptions,
],
}),
],
{ stdin: externalRepositoryToken },
@@ -853,7 +853,7 @@ async function getCodeQLForCmd(
"--sarif-group-rules-by-pack",
"--sarif-include-query-help=always",
"--sublanguage-file-coverage",
...(await getJobRunUuidSarifOptions(this)),
...(await getJobRunUuidSarifOptions()),
...getExtraOptionsFromEnv(["database", "interpret-results"]),
];
if (sarifRunPropertyFlag !== undefined) {
@@ -1283,13 +1283,8 @@ function applyAutobuildAzurePipelinesTimeoutFix() {
].join(" ");
}
async function getJobRunUuidSarifOptions(codeql: CodeQL) {
async function getJobRunUuidSarifOptions() {
const jobRunUuid = process.env[EnvVar.JOB_RUN_UUID];
return jobRunUuid &&
(await codeql.supportsFeature(
ToolsFeature.DatabaseInterpretResultsSupportsSarifRunProperty,
))
? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`]
: [];
return jobRunUuid ? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`] : [];
}
+2 -5
View File
@@ -75,10 +75,10 @@ const testShouldPerformDiffInformedAnalysis = makeMacro({
[Feature.DiffInformedQueries]: testCase.featureEnabled,
});
const getGitHubVersionStub = sinon
sinon
.stub(apiClient, "getGitHubVersion")
.resolves(testCase.gitHubVersion);
const getPullRequestBranchesStub = sinon
sinon
.stub(actionsUtil, "getPullRequestBranches")
.returns(testCase.pullRequestBranches);
@@ -91,9 +91,6 @@ const testShouldPerformDiffInformedAnalysis = makeMacro({
t.is(branches !== undefined, expectedResult);
delete process.env.CODEQL_ACTION_DIFF_INFORMED_QUERIES;
getGitHubVersionStub.restore();
getPullRequestBranchesStub.restore();
});
},
title: (title) => `getDiffInformedAnalysisBranches: ${title}`,
+3
View File
@@ -26,6 +26,9 @@ const DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled";
/**
* The first version of the CodeQL Bundle that shipped with zstd-compressed bundles.
*
* This is now below the minimum version of CodeQL, but we keep this around because we currently set
* up CodeQL before checking that the version is new enough.
*/
export const CODEQL_VERSION_ZSTD_BUNDLE = "2.19.0";
+77 -14
View File
@@ -33,7 +33,6 @@ test.serial(
const actualRef = await gitUtils.getRef();
t.deepEqual(actualRef, expectedRef);
callback.restore();
});
},
);
@@ -54,7 +53,6 @@ test.serial(
const actualRef = await gitUtils.getRef();
t.deepEqual(actualRef, expectedRef);
callback.restore();
});
},
);
@@ -73,7 +71,6 @@ test.serial(
const actualRef = await gitUtils.getRef();
t.deepEqual(actualRef, "refs/pull/1/head");
callback.restore();
});
},
);
@@ -100,8 +97,6 @@ test.serial(
const actualRef = await gitUtils.getRef();
t.deepEqual(actualRef, "refs/pull/2/merge");
callback.restore();
getAdditionalInputStub.restore();
});
},
);
@@ -161,7 +156,6 @@ test.serial(
"Both 'ref' and 'sha' are required if one of them is provided.",
},
);
getAdditionalInputStub.restore();
});
},
);
@@ -188,7 +182,6 @@ test.serial(
"Both 'ref' and 'sha' are required if one of them is provided.",
},
);
getAdditionalInputStub.restore();
});
},
);
@@ -242,7 +235,6 @@ test.serial("isAnalyzingDefaultBranch()", async (t) => {
process.env["GITHUB_EVENT_NAME"] = "schedule";
process.env["GITHUB_REF"] = "refs/heads/main";
t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(), false);
getAdditionalInputStub.restore();
});
});
@@ -254,8 +246,6 @@ test.serial("determineBaseBranchHeadCommitOid non-pullrequest", async (t) => {
const result = await gitUtils.determineBaseBranchHeadCommitOid(__dirname);
t.deepEqual(result, undefined);
t.deepEqual(0, infoStub.callCount);
infoStub.restore();
});
test.serial(
@@ -276,8 +266,6 @@ test.serial(
"git call failed. Will calculate the base branch SHA on the server. Error: " +
"The checkout path provided to the action does not appear to be a git repository.",
);
infoStub.restore();
},
);
@@ -301,10 +289,27 @@ test.serial("determineBaseBranchHeadCommitOid other error", async (t) => {
"The checkout path provided to the action does not appear to be a git repository.",
),
);
infoStub.restore();
});
test.serial(
"determineBaseBranchHeadCommitOid accepts SHA-256 OIDs",
async (t) => {
const mergeSha = "a".repeat(64);
const baseOid = "b".repeat(64);
const headOid = "c".repeat(64);
process.env["GITHUB_EVENT_NAME"] = "pull_request";
process.env["GITHUB_SHA"] = mergeSha;
sinon
.stub(gitUtils as any, "runGitCommand")
.resolves(`commit ${mergeSha}\nparent ${baseOid}\nparent ${headOid}\n`);
const result = await gitUtils.determineBaseBranchHeadCommitOid(__dirname);
t.deepEqual(result, baseOid);
},
);
test.serial("decodeGitFilePath unquoted strings", async (t) => {
t.deepEqual(gitUtils.decodeGitFilePath("foo"), "foo");
t.deepEqual(gitUtils.decodeGitFilePath("foo bar"), "foo bar");
@@ -436,6 +441,64 @@ test.serial("getFileOidsUnderPath handles quoted paths", async (t) => {
});
});
test.serial("getFileOidsUnderPath handles SHA-256 OIDs", async (t) => {
await withTmpDir(async (tmpDir) => {
const sha256OidA =
"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2c0d4b7e8f9a1234567890ab";
const sha256OidB =
"aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899";
sinon
.stub(gitUtils as any, "runGitCommand")
.callsFake(async (_cwd: any, args: any) => {
if (args[0] === "rev-parse") {
return `${tmpDir}\n`;
}
return (
`100644 ${sha256OidA} 0\tlib/sha256-file-a.js\n` +
`100644 ${sha256OidB} 0\tsrc/sha256-file-b.ts`
);
});
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
t.deepEqual(result, {
"lib/sha256-file-a.js": sha256OidA,
"src/sha256-file-b.ts": sha256OidB,
});
});
});
test.serial(
"getFileOidsUnderPath rejects OIDs of unsupported length",
async (t) => {
await withTmpDir(async (tmpDir) => {
// 50-char OID: not a valid SHA-1 (40) or SHA-256 (64) length. The regex
// must not accept this even though every character is a valid hex digit.
const invalidLine =
"100644 30d998ded095371488be3a729eb61d86ed721a1830d998ded0 0\tlib/bad.js";
sinon
.stub(gitUtils as any, "runGitCommand")
.callsFake(async (_cwd: any, args: any) => {
if (args[0] === "rev-parse") {
return `${tmpDir}\n`;
}
return invalidLine;
});
await t.throwsAsync(
async () => {
await gitUtils.getFileOidsUnderPath("/fake/path");
},
{
instanceOf: Error,
message: `Unexpected "git ls-files" output: ${invalidLine}`,
},
);
});
},
);
test.serial("getFileOidsUnderPath handles empty output", async (t) => {
await withTmpDir(async (tmpDir) => {
sinon
+6 -4
View File
@@ -163,11 +163,12 @@ export const determineBaseBranchHeadCommitOid = async function (
}
}
// Let's confirm our assumptions: We had a merge commit and the parsed parent data looks correct
// Let's confirm our assumptions: We had a merge commit and the parsed parent
// data looks correct. OIDs are either 40 (SHA-1) or 64 (SHA-256) hex characters.
if (
commitOid === mergeSha &&
headOid.length === 40 &&
baseOid.length === 40
(headOid.length === 40 || headOid.length === 64) &&
(baseOid.length === 40 || baseOid.length === 64)
) {
return baseOid;
}
@@ -296,7 +297,8 @@ export const getFileOidsUnderPath = async function (
// 100644 4c51bc1d9e86cd86e01b0f340cb8ce095c33b283 0\tsrc/git-utils.test.ts
// 100644 6b792ea543ce75d7a8a03df591e3c85311ecb64f 0\tsrc/git-utils.ts
// The fields are: <mode> <oid> <stage>\t<path>
const regex = /^[0-9]+ ([0-9a-f]{40}) [0-9]+\t(.+)$/;
// The OID is either 40 (SHA-1) or 64 (SHA-256) hex characters.
const regex = /^[0-9]+ ([0-9a-f]{40}|[0-9a-f]{64}) [0-9]+\t(.+)$/;
for (const line of stdout.split("\n")) {
if (line) {
const match = line.match(regex);
+16 -35
View File
@@ -80,65 +80,46 @@ const testDownloadOverlayBaseDatabaseFromCache = makeMacro({
await fs.promises.writeFile(baseDatabaseOidsFile, JSON.stringify({}));
}
const stubs: sinon.SinonStub[] = [];
sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/");
const getAutomationIDStub = sinon
.stub(apiClient, "getAutomationID")
.resolves("test-automation-id/");
stubs.push(getAutomationIDStub);
const isInTestModeStub = sinon
.stub(utils, "isInTestMode")
.returns(testCase.isInTestMode);
stubs.push(isInTestModeStub);
sinon.stub(utils, "isInTestMode").returns(testCase.isInTestMode);
if (testCase.restoreCacheResult instanceof Error) {
const restoreCacheStub = sinon
sinon
.stub(actionsCache, "restoreCache")
.rejects(testCase.restoreCacheResult);
stubs.push(restoreCacheStub);
} else {
const restoreCacheStub = sinon
sinon
.stub(actionsCache, "restoreCache")
.resolves(testCase.restoreCacheResult);
stubs.push(restoreCacheStub);
}
const tryGetFolderBytesStub = sinon
sinon
.stub(utils, "tryGetFolderBytes")
.resolves(testCase.tryGetFolderBytesSucceeds ? 1024 * 1024 : undefined);
stubs.push(tryGetFolderBytesStub);
const codeql = mockCodeQLVersion(testCase.codeQLVersion);
if (testCase.resolveDatabaseOutput instanceof Error) {
const resolveDatabaseStub = sinon
sinon
.stub(codeql, "resolveDatabase")
.rejects(testCase.resolveDatabaseOutput);
stubs.push(resolveDatabaseStub);
} else {
const resolveDatabaseStub = sinon
sinon
.stub(codeql, "resolveDatabase")
.resolves(testCase.resolveDatabaseOutput);
stubs.push(resolveDatabaseStub);
}
try {
const result = await downloadOverlayBaseDatabaseFromCache(
codeql,
config,
logger,
);
const result = await downloadOverlayBaseDatabaseFromCache(
codeql,
config,
logger,
);
if (expectDownloadSuccess) {
t.truthy(result);
} else {
t.is(result, undefined);
}
} finally {
for (const stub of stubs) {
stub.restore();
}
if (expectDownloadSuccess) {
t.truthy(result);
} else {
t.is(result, undefined);
}
});
},
+16 -56
View File
@@ -50,31 +50,21 @@ test.serial(
"modified.js": "ddd444", // Changed OID
"added.js": "eee555", // New file
};
const getFileOidsStubForOverlay = sinon
.stub(gitUtils, "getFileOidsUnderPath")
.resolves(currentOids);
sinon.stub(gitUtils, "getFileOidsUnderPath").resolves(currentOids);
// Write the overlay changes file, which uses the mocked overlay OIDs
// and the base database OIDs file
const diffRangeFilePath = path.join(tempDir, "pr-diff-range.json");
const getTempDirStub = sinon
.stub(actionsUtil, "getTemporaryDirectory")
.returns(tempDir);
const getDiffRangesStub = sinon
sinon.stub(actionsUtil, "getTemporaryDirectory").returns(tempDir);
sinon
.stub(actionsUtil, "getDiffRangesJsonFilePath")
.returns(diffRangeFilePath);
const getGitRootStub = sinon
.stub(gitUtils, "getGitRoot")
.resolves(sourceRoot);
sinon.stub(gitUtils, "getGitRoot").resolves(sourceRoot);
const changesFilePath = await writeOverlayChangesFile(
config,
sourceRoot,
logger,
);
getFileOidsStubForOverlay.restore();
getTempDirStub.restore();
getDiffRangesStub.restore();
getGitRootStub.restore();
const fileContent = await fs.promises.readFile(changesFilePath, "utf-8");
const parsedContent = JSON.parse(fileContent) as { changes: string[] };
@@ -128,20 +118,14 @@ test.serial(
"modified.js": "ddd444", // Changed OID
"reverted.js": "eee555", // Same OID as base -- not detected by OID comparison
};
const getFileOidsStubForOverlay = sinon
.stub(gitUtils, "getFileOidsUnderPath")
.resolves(currentOids);
sinon.stub(gitUtils, "getFileOidsUnderPath").resolves(currentOids);
const diffRangeFilePath = path.join(tempDir, "pr-diff-range.json");
const getTempDirStub = sinon
.stub(actionsUtil, "getTemporaryDirectory")
.returns(tempDir);
const getDiffRangesStub = sinon
sinon.stub(actionsUtil, "getTemporaryDirectory").returns(tempDir);
sinon
.stub(actionsUtil, "getDiffRangesJsonFilePath")
.returns(diffRangeFilePath);
const getGitRootStub = sinon
.stub(gitUtils, "getGitRoot")
.resolves(sourceRoot);
sinon.stub(gitUtils, "getGitRoot").resolves(sourceRoot);
// Write a pr-diff-range.json file with diff ranges including
// "reverted.js" (unchanged OIDs) and "modified.js" (already in OID changes)
@@ -159,10 +143,6 @@ test.serial(
sourceRoot,
logger,
);
getFileOidsStubForOverlay.restore();
getTempDirStub.restore();
getDiffRangesStub.restore();
getGitRootStub.restore();
const fileContent = await fs.promises.readFile(changesFilePath, "utf-8");
const parsedContent = JSON.parse(fileContent) as { changes: string[] };
@@ -208,20 +188,14 @@ test.serial(
"unchanged.js": "aaa111",
"modified.js": "ddd444",
};
const getFileOidsStubForOverlay = sinon
.stub(gitUtils, "getFileOidsUnderPath")
.resolves(currentOids);
sinon.stub(gitUtils, "getFileOidsUnderPath").resolves(currentOids);
const diffRangeFilePath = path.join(tempDir, "pr-diff-range.json");
const getTempDirStub = sinon
.stub(actionsUtil, "getTemporaryDirectory")
.returns(tempDir);
const getDiffRangesStub = sinon
sinon.stub(actionsUtil, "getTemporaryDirectory").returns(tempDir);
sinon
.stub(actionsUtil, "getDiffRangesJsonFilePath")
.returns(diffRangeFilePath);
const getGitRootStub = sinon
.stub(gitUtils, "getGitRoot")
.resolves(sourceRoot);
sinon.stub(gitUtils, "getGitRoot").resolves(sourceRoot);
// No pr-diff-range.json file exists - should work the same as before
const changesFilePath = await writeOverlayChangesFile(
@@ -229,10 +203,6 @@ test.serial(
sourceRoot,
logger,
);
getFileOidsStubForOverlay.restore();
getTempDirStub.restore();
getDiffRangesStub.restore();
getGitRootStub.restore();
const fileContent = await fs.promises.readFile(changesFilePath, "utf-8");
const parsedContent = JSON.parse(fileContent) as { changes: string[] };
@@ -281,21 +251,15 @@ test.serial(
"app.js": "aaa111",
"lib/util.js": "bbb222",
};
const getFileOidsStubForOverlay = sinon
.stub(gitUtils, "getFileOidsUnderPath")
.resolves(currentOids);
sinon.stub(gitUtils, "getFileOidsUnderPath").resolves(currentOids);
const diffRangeFilePath = path.join(tempDir, "pr-diff-range.json");
const getTempDirStub = sinon
.stub(actionsUtil, "getTemporaryDirectory")
.returns(tempDir);
const getDiffRangesStub = sinon
sinon.stub(actionsUtil, "getTemporaryDirectory").returns(tempDir);
sinon
.stub(actionsUtil, "getDiffRangesJsonFilePath")
.returns(diffRangeFilePath);
// getGitRoot returns the repo root (parent of sourceRoot)
const getGitRootStub = sinon
.stub(gitUtils, "getGitRoot")
.resolves(repoRoot);
sinon.stub(gitUtils, "getGitRoot").resolves(repoRoot);
// Diff ranges use repo-root-relative paths (as returned by the GitHub compare API)
await fs.promises.writeFile(
@@ -312,10 +276,6 @@ test.serial(
sourceRoot,
logger,
);
getFileOidsStubForOverlay.restore();
getTempDirStub.restore();
getDiffRangesStub.restore();
getGitRootStub.restore();
const fileContent = await fs.promises.readFile(changesFilePath, "utf-8");
const parsedContent = JSON.parse(fileContent) as { changes: string[] };
+7 -3
View File
@@ -6,9 +6,13 @@ import { ToolsFeature, isSupportedToolsFeature } from "./tools-features";
test("isSupportedToolsFeature", async (t) => {
const versionInfo = makeVersionInfo("1.0.0");
t.false(isSupportedToolsFeature(versionInfo, ToolsFeature.ForceOverwrite));
t.false(
isSupportedToolsFeature(versionInfo, ToolsFeature.BundleSupportsOverlay),
);
versionInfo.features = { forceOverwrite: true };
versionInfo.features = { bundleSupportsOverlay: true };
t.true(isSupportedToolsFeature(versionInfo, ToolsFeature.ForceOverwrite));
t.true(
isSupportedToolsFeature(versionInfo, ToolsFeature.BundleSupportsOverlay),
);
});
-2
View File
@@ -6,8 +6,6 @@ export enum ToolsFeature {
BuiltinExtractorsSpecifyDefaultQueries = "builtinExtractorsSpecifyDefaultQueries",
BundleSupportsIncludeOption = "bundleSupportsIncludeOption",
BundleSupportsOverlay = "bundleSupportsOverlay",
DatabaseInterpretResultsSupportsSarifRunProperty = "databaseInterpretResultsSupportsSarifRunProperty",
ForceOverwrite = "forceOverwrite",
IndirectTracingSupportsStaticBinaries = "indirectTracingSupportsStaticBinaries",
SuppressesMissingFileBaselineWarning = "suppressesMissingFileBaselineWarning",
}
+1 -4
View File
@@ -418,9 +418,7 @@ for (const [
`checkActionVersion ${reportErrorDescription} for ${versionsDescription}`,
async (t) => {
const warningSpy = sinon.spy(core, "warning");
const versionStub = sinon
.stub(api, "getGitHubVersion")
.resolves(githubVersion);
sinon.stub(api, "getGitHubVersion").resolves(githubVersion);
// call checkActionVersion twice and assert below that warning is reported only once
util.checkActionVersion(version, await api.getGitHubVersion());
@@ -437,7 +435,6 @@ for (const [
} else {
t.false(warningSpy.called);
}
versionStub.restore();
},
);
}