Compare commits

...
Author SHA1 Message Date
Henry Mercer ce64ddcb0d Merge pull request #3826 from github/backport-v3.35.2-95e58e9a2
Merge releases/v4 into releases/v3
2026-04-15 12:51:20 +01:00
github-actions[bot] c186c7b484 Rebuild 2026-04-15 11:30:55 +00:00
github-actions[bot] 8bcc8f23a2 Update version and changelog for v3.35.2 2026-04-15 11:26:58 +00:00
github-actions[bot] 834786ac9b Merge remote-tracking branch 'origin/releases/v4' into backport-v3.35.2-95e58e9a2 2026-04-15 11:26:57 +00:00
github-actions[bot] 047c547345 Revert "Rebuild"
This reverts commit 646729a1e2.
2026-04-15 11:26:56 +00:00
github-actions[bot] 7ca215887b Revert "Update version and changelog for v3.35.1"
This reverts commit c983cb8e74.
2026-04-15 11:26:56 +00:00
Henry Mercer 95e58e9a2c Merge pull request #3824 from github/update-v4.35.2-d2e135a73
Merge main into releases/v4
2026-04-15 12:22:51 +01:00
github-actions[bot] 6f31bfe060 Update changelog for v4.35.2 2026-04-15 10:56:23 +00:00
Henry Mercer d2e135a73a Merge pull request #3823 from github/update-bundle/codeql-bundle-v2.25.2
Update default bundle to 2.25.2
2026-04-15 10:06:23 +00:00
github-actions[bot] 60abb65df0 Add changelog note 2026-04-15 09:39:31 +00:00
github-actions[bot] 5a0a562209 Update default bundle to codeql-bundle-v2.25.2 2026-04-15 09:39:24 +00:00
Henry Mercer 65216971a1 Merge pull request #3820 from github/dependabot/github_actions/dot-github/workflows/actions-minor-cc17fecf2b
Bump the actions-minor group across 1 directory with 2 updates
2026-04-13 18:04:26 +00:00
Henry Mercer 3c45af2dd2 Merge pull request #3821 from github/dependabot/npm_and_yarn/npm-minor-345b938e93
Bump the npm-minor group across 1 directory with 6 updates
2026-04-13 17:59:04 +00:00
github-actions[bot] f1c339364c Rebuild 2026-04-13 17:31:19 +00:00
github-actions[bot] 1024fc496c Rebuild 2026-04-13 17:30:13 +00:00
dependabot[bot] 9dd4cfed96 Bump the npm-minor group across 1 directory with 6 updates
Bumps the npm-minor group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@octokit/plugin-retry](https://github.com/octokit/plugin-retry.js) | `8.0.3` | `8.1.0` |
| [jsonschema](https://github.com/tdegrunt/jsonschema) | `1.4.1` | `1.5.0` |
| [@eslint/compat](https://github.com/eslint/rewrite/tree/HEAD/packages/compat) | `2.0.3` | `2.0.4` |
| [@types/sinon](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/sinon) | `21.0.0` | `21.0.1` |
| [esbuild](https://github.com/evanw/esbuild) | `0.27.4` | `0.28.0` |
| [nock](https://github.com/nock/nock) | `14.0.11` | `14.0.12` |



Updates `@octokit/plugin-retry` from 8.0.3 to 8.1.0
- [Release notes](https://github.com/octokit/plugin-retry.js/releases)
- [Commits](https://github.com/octokit/plugin-retry.js/compare/v8.0.3...v8.1.0)

Updates `jsonschema` from 1.4.1 to 1.5.0
- [Commits](https://github.com/tdegrunt/jsonschema/commits)

Updates `@eslint/compat` from 2.0.3 to 2.0.4
- [Release notes](https://github.com/eslint/rewrite/releases)
- [Changelog](https://github.com/eslint/rewrite/blob/main/packages/compat/CHANGELOG.md)
- [Commits](https://github.com/eslint/rewrite/commits/compat-v2.0.4/packages/compat)

Updates `@types/sinon` from 21.0.0 to 21.0.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/sinon)

Updates `esbuild` from 0.27.4 to 0.28.0
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.27.4...v0.28.0)

Updates `nock` from 14.0.11 to 14.0.12
- [Release notes](https://github.com/nock/nock/releases)
- [Changelog](https://github.com/nock/nock/blob/main/CHANGELOG.md)
- [Commits](https://github.com/nock/nock/compare/v14.0.11...v14.0.12)

---
updated-dependencies:
- dependency-name: "@octokit/plugin-retry"
  dependency-version: 8.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-minor
- dependency-name: jsonschema
  dependency-version: 1.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-minor
- dependency-name: "@eslint/compat"
  dependency-version: 2.0.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-minor
- dependency-name: "@types/sinon"
  dependency-version: 21.0.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-minor
- dependency-name: esbuild
  dependency-version: 0.28.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-minor
- dependency-name: nock
  dependency-version: 14.0.12
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-13 17:29:04 +00:00
dependabot[bot] c1403f094c Bump the actions-minor group across 1 directory with 2 updates
Bumps the actions-minor group with 2 updates in the /.github/workflows directory: [ruby/setup-ruby](https://github.com/ruby/setup-ruby) and [actions/create-github-app-token](https://github.com/actions/create-github-app-token).


Updates `ruby/setup-ruby` from 1.295.0 to 1.300.0
- [Release notes](https://github.com/ruby/setup-ruby/releases)
- [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb)
- [Commits](https://github.com/ruby/setup-ruby/compare/319994f95fa847cf3fb3cd3dbe89f6dcde9f178f...4c56a21280b36d862b5fc31348f463d60bdc55d5)

Updates `actions/create-github-app-token` from 3.0.0 to 3.1.1
- [Release notes](https://github.com/actions/create-github-app-token/releases)
- [Commits](https://github.com/actions/create-github-app-token/compare/v3.0.0...v3.1.1)

---
updated-dependencies:
- dependency-name: ruby/setup-ruby
  dependency-version: 1.300.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-minor
- dependency-name: actions/create-github-app-token
  dependency-version: 3.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-13 17:27:57 +00:00
Henry Mercer 8339b9254e Merge pull request #3819 from github/henrymercer/refactor-overlay-caching
Refactoring: Introduce `overlay/caching.ts`
2026-04-13 15:49:12 +00:00
Michael B. Gale ee09113642 Merge pull request #3810 from github/mbg/ts6/fix-pr-checks
Fix `pr-checks/tsconfig.json` for TS6
2026-04-10 18:02:01 +00:00
Michael B. Gale b669eab7e3 Explicitly add pr-checks to Dependabot config 2026-04-10 16:58:30 +01:00
Henry Mercer 4e8c9ce33c Refactoring: Introduce overlay/caching.ts 2026-04-10 14:55:12 +01:00
Michael B. Gale 1cf0431149 Set module option for pr-checks/tsconfig.json 2026-04-10 13:22:36 +01:00
Michael B. Gale a26cb68cc7 Merge pull request #3807 from github/mbg/start-proxy/fix-field-names
Fix OIDC credential property names
2026-04-10 09:18:24 +00:00
Henry Mercer 60991e61ac Merge pull request #3806 from github/henrymercer/store-language-aliases
Store language aliases from linked CLI
2026-04-10 09:16:45 +00:00
Michael B. Gale 7197c2b792 Add changelog entry 2026-04-09 19:01:45 +01:00
Henry Mercer 597e12aa85 Merge pull request #3801 from github/henrymercer/swift-incompatible-os
Mark Swift incompatible OS as configuration error
2026-04-09 17:30:06 +00:00
Michael B. Gale d277a56348 Fix OIDC credential property names 2026-04-09 17:48:52 +01:00
Henry Mercer 111a537cd9 Update start-proxy Action to use known language aliases 2026-04-09 17:10:15 +01:00
Henry Mercer 51d833290e Store language aliases from linked CLI 2026-04-09 17:10:15 +01:00
Henry Mercer 5a17511bf0 Throw error on Windows too 2026-04-09 16:52:50 +01:00
Henry Mercer 43d8420a42 Do not run Swift in debug artifacts after failure check 2026-04-09 15:18:51 +01:00
Henry Mercer 76a687e1d8 Merge pull request #3804 from github/dependabot/npm_and_yarn/npm-minor-e84c604a08
Bump eslint-plugin-jsdoc from 62.8.1 to 62.9.0 in the npm-minor group
2026-04-09 13:04:00 +00:00
dependabot[bot] 751f3e2f7c Bump eslint-plugin-jsdoc from 62.8.1 to 62.9.0 in the npm-minor group
Bumps the npm-minor group with 1 update: [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc).


Updates `eslint-plugin-jsdoc` from 62.8.1 to 62.9.0
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v62.8.1...v62.9.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-version: 62.9.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-08 17:53:21 +00:00
Henry Mercer 808513f048 Update language aliases test 2026-04-08 16:38:23 +01:00
Henry Mercer e452857e57 Throw error early rather than warning 2026-04-08 16:33:19 +01:00
Mario Campos b623f5fd57 Merge pull request #3799 from github/mario-campos/test-multiple-registries
Add tests for getCredentials with multiple goproxy_servers and maven_…
2026-04-07 14:52:14 +00:00
Mario CamposandMichael B. Gale 35a38985d3 Specify "Java" for a test case
Co-authored-by: Michael B. Gale <mbg@github.com>
2026-04-07 09:01:00 -05:00
Mario CamposandMichael B. Gale 14ed573199 Specify "Go" for a test case
Co-authored-by: Michael B. Gale <mbg@github.com>
2026-04-07 09:01:00 -05:00
Mario Campos 43d8864b35 Run npm run lint-fix to format the code 2026-04-07 09:01:00 -05:00
Mario Campos f8aff3ad8b Add tests for getCredentials with multiple goproxy_servers and maven_repositories 2026-04-07 09:01:00 -05:00
Henry Mercer e6c83948f5 Merge pull request #3802 from github/dependabot/npm_and_yarn/lodash-4.18.1
Bump lodash from 4.17.23 to 4.18.1
2026-04-07 10:12:08 +00:00
Henry Mercer 347f0c676d Merge pull request #3803 from github/dependabot/npm_and_yarn/npm-minor-113ae615b7
Bump eslint-plugin-jsdoc from 62.8.0 to 62.8.1 in the npm-minor group across 1 directory
2026-04-07 10:08:35 +00:00
dependabot[bot] 6eed62b035 Bump eslint-plugin-jsdoc in the npm-minor group across 1 directory
Bumps the npm-minor group with 1 update in the / directory: [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc).


Updates `eslint-plugin-jsdoc` from 62.8.0 to 62.8.1
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v62.8.0...v62.8.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-version: 62.8.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-07 09:36:59 +00:00
dependabot[bot] de1752b85d Bump lodash from 4.17.23 to 4.18.1
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.23 to 4.18.1.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.23...4.18.1)

---
updated-dependencies:
- dependency-name: lodash
  dependency-version: 4.18.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-07 09:36:15 +00:00
Henry Mercer 1065967b50 Merge pull request #3800 from github/henrymercer/typescript-6
Upgrade to TypeScript 6
2026-04-07 09:14:42 +00:00
Henry Mercer e25c0a535a Merge pull request #3795 from github/henrymercer/deprecate-trap-caching-cleanup
Deprecate TRAP cache cleanup
2026-04-07 09:14:31 +00:00
Henry Mercer 5f323cad05 Mark Swift incompatible OS as configuration error 2026-04-02 18:46:26 +01:00
Henry Mercer 212e28374b Upgrade to TypeScript 6
tsconfig changes:

- Specify `moduleResolution: bundler` since we use a bundler
- Specify `types: ["node"]` to speed up build
- Remove `alwaysStrict` as this is now deprecated
- Specify `skipLibCheck: true` to speed up build
- Specify Octokit types.d.ts path manually to address compiler not being able to find types with `moduleResolution: bundler`
2026-04-02 18:32:58 +01:00
Henry Mercer 36075a4980 Deprecate TRAP cache cleanup 2026-04-01 15:31:15 +01:00
Michael B. Gale 34950e1b11 Merge pull request #3792 from github/mario-campos/issue-1664
Extend start-proxy.yml to test multiple registry support
2026-04-01 13:59:59 +00:00
Henry Mercer 57ec7e1000 Merge pull request #3794 from github/henrymercer/cleanup
Python: Disable standard library extraction on GHES
2026-04-01 11:37:34 +00:00
Henry Mercer 311573e58e Add changelog note 2026-04-01 12:19:11 +01:00
Henry Mercer 1f4c852aeb Clean up Python extract stdlib feature flag 2026-04-01 12:08:06 +01:00
Michael B. Gale 2e3aaaefca Merge pull request #3787 from github/mbg/bundle/metadata
Generate and analyse esbuild bundle metadata
2026-04-01 10:29:27 +00:00
Mario Campos e2203c62cf Delete fromJSON() calls in test validation step 2026-03-31 13:19:33 -05:00
Mario Campos 7b0c5b1669 Keep validation steps named consistently 2026-03-31 12:49:07 -05:00
Mario Campos faf45e07f9 Use different maven URL for start-proxy.yml test 2026-03-31 12:44:43 -05:00
Mario Campos 8b5e60477c Use maven_repository, not maven-repository
The registry/language mapping table does not map the one with hyphens.
2026-03-31 11:36:17 -05:00
Mario Campos 99b8dd4d57 Run pr-checks/sync.sh to generate __start-proxy.yml. 2026-03-31 09:32:42 -05:00
Henry Mercer c618c9bddb Merge pull request #3789 from github/henrymercer/lower-minimum-git-if-no-submodules
Overlay: Only require Git 2.36.0 for repos that contain submodules
2026-03-31 10:10:05 +00:00
Mario Campos 9fd9b64766 Replace jq with Actions expression for proxy_urls validation
For the sake of consistency with the other pre-existing validation code.
2026-03-30 22:47:06 -05:00
Mario Campos 0c7c298b2a Extend start-proxy.yml to test multiple registry support 2026-03-30 18:35:04 -05:00
Henry Mercer a507a542a4 Test fallback when repo has no submodules 2026-03-30 15:58:58 +01:00
Henry Mercer be0a156326 Save a computation of the git root 2026-03-30 13:37:14 +01:00
Michael B. Gale f98bf5e347 Output relative to __dirname 2026-03-27 19:21:14 +00:00
Michael B. Gale 3db32b5d27 Fix outputs type 2026-03-27 19:13:22 +00:00
Michael B. Gale 4e0952a3c0 Output largest inputs 2026-03-27 19:13:02 +00:00
Henry Mercer 0592832ed8 Add changelog note 2026-03-27 18:58:05 +00:00
Henry Mercer 88a7e5118e Don't disable if we don't need the git version 2026-03-27 18:54:26 +00:00
Henry Mercer 6643a7d207 Only require Git 2.36.0 when repo contains submodules 2026-03-27 18:54:24 +00:00
Michael B. Gale 47f1709a3c Add basic metadata analysis script 2026-03-27 18:19:57 +00:00
Michael B. Gale b1981a5480 Move getApiClient out of sync-checks.ts 2026-03-27 18:13:48 +00:00
Henry Mercer a899987af2 Merge pull request #3786 from github/henrymercer/faster-interactive-jobs
Move time-sensitive Actions workflows to `ubuntu-latest`
2026-03-27 18:08:16 +00:00
Michael B. Gale 4ed3c0efe6 Generate esbuild metadata file 2026-03-27 17:54:29 +00:00
Henry Mercer 191d7c6f13 Merge pull request #3783 from github/mergeback/v4.35.1-to-main-c10b8064
Mergeback v4.35.1 refs/heads/releases/v4 into main
2026-03-27 17:11:42 +00:00
Henry Mercer aa69c483cd Merge pull request #3779 from github/henrymercer/remove-unused-dependency
Remove unused `@schemastore/package` dependency
2026-03-27 17:11:32 +00:00
Henry Mercer fe775da508 Merge pull request #3780 from github/dependabot/npm_and_yarn/brace-expansion-1.1.13
Bump brace-expansion from 1.1.12 to 1.1.13
2026-03-27 17:11:18 +00:00
Henry Mercer 5c8a8a642e Merge pull request #3784 from github/backport-v3.35.1-c10b8064d
Merge releases/v4 into releases/v3
2026-03-27 16:41:10 +00:00
Henry Mercer 353802f9f2 Move time-sensitive Actions workflows to ubuntu-latest
We originally moved these to `ubuntu-slim`, but there is a significant performance difference.  Since we often find ourselves waiting on these jobs, let's use the faster runners.
2026-03-27 16:22:19 +00:00
github-actions[bot] cc7db4a1f9 Rebuild 2026-03-27 16:20:01 +00:00
github-actions[bot] 646729a1e2 Rebuild 2026-03-27 16:19:35 +00:00
github-actions[bot] c983cb8e74 Update version and changelog for v3.35.1 2026-03-27 16:13:31 +00:00
github-actions[bot] 557b58c47c Merge remote-tracking branch 'origin/releases/v4' into backport-v3.35.1-c10b8064d 2026-03-27 16:13:29 +00:00
github-actions[bot] 8bb5bdb9fd Revert "Rebuild"
This reverts commit b1a5f00cf1.
2026-03-27 16:13:29 +00:00
github-actions[bot] 4d2fde9e07 Revert "Update version and changelog for v3.35.0"
This reverts commit 124f6eec3b.
2026-03-27 16:13:29 +00:00
github-actions[bot] 6010f9d8e2 Update changelog and version after v4.35.1 2026-03-27 16:10:47 +00:00
Henry Mercer c10b8064de Merge pull request #3782 from github/update-v4.35.1-d6d1743b8
Merge main into releases/v4
2026-03-27 16:07:37 +00:00
Óscar San José 13efb23391 Merge pull request #3778 from github/backport-v3.35.0-b8bb9f28b
Merge releases/v4 into releases/v3
2026-03-27 17:00:05 +01:00
github-actions[bot] c5ffd06837 Update changelog for v4.35.1 2026-03-27 15:39:16 +00:00
Henry Mercer d6d1743b8e Merge pull request #3781 from github/henrymercer/update-git-minimum-version
Update minimum Git version for overlay to 2.36.0
2026-03-27 14:59:36 +00:00
github-actions[bot] 999119ba45 Rebuild 2026-03-27 14:00:54 +00:00
Henry Mercer 65d2efa733 Add changelog note 2026-03-27 14:00:27 +00:00
Henry Mercer 2437b20ab3 Update minimum git version for overlay to 2.36.0 2026-03-27 14:00:17 +00:00
dependabot[bot] f13c600724 Bump brace-expansion from 1.1.12 to 1.1.13
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 1.1.12 to 1.1.13.
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v1.1.12...v1.1.13)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 1.1.13
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-27 13:58:43 +00:00
Henry Mercer 7dcea06663 Remove unused @schemastore/package dependency 2026-03-27 13:57:52 +00:00
Michael B. Gale ea5f71947c Merge pull request #3775 from github/dependabot/npm_and_yarn/node-forge-1.4.0
Bump node-forge from 1.3.3 to 1.4.0
2026-03-27 13:47:55 +00:00
Henry Mercer 45ceeea896 Merge pull request #3777 from github/mergeback/v4.35.0-to-main-b8bb9f28
Mergeback v4.35.0 refs/heads/releases/v4 into main
2026-03-27 13:36:14 +00:00
github-actions[bot] b1a5f00cf1 Rebuild 2026-03-27 12:23:35 +00:00
github-actions[bot] 24448c9843 Rebuild 2026-03-27 12:23:25 +00:00
github-actions[bot] 124f6eec3b Update version and changelog for v3.35.0 2026-03-27 12:18:22 +00:00
github-actions[bot] a88fb3cde0 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.35.0-b8bb9f28b 2026-03-27 12:18:20 +00:00
github-actions[bot] 57d591c67c Revert "Rebuild"
This reverts commit 97fd992228.
2026-03-27 12:18:20 +00:00
github-actions[bot] dba1849cf2 Revert "Update version and changelog for v3.34.1"
This reverts commit 95a562052b.
2026-03-27 12:18:20 +00:00
github-actions[bot] 7c51060631 Update changelog and version after v4.35.0 2026-03-27 12:14:07 +00:00
Óscar San José b8bb9f28b8 Merge pull request #3776 from github/update-v4.35.0-0078ad667
Merge main into releases/v4
2026-03-27 13:11:18 +01:00
github-actions[bot] e9cf68bb33 Update changelog for v4.35.0 2026-03-27 11:44:34 +00:00
github-actions[bot] 36791d8d66 Rebuild 2026-03-27 10:27:12 +00:00
dependabot[bot] 22eba96a28 Bump node-forge from 1.3.3 to 1.4.0
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.3.3 to 1.4.0.
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/v1.3.3...v1.4.0)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-version: 1.4.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-27 10:25:06 +00:00
Óscar San José 0078ad667e Merge pull request #3773 from github/update-bundle/codeql-bundle-v2.25.1
Update default bundle to 2.25.1
2026-03-27 10:02:52 +00:00
github-actions[bot] fa7a15b909 Add changelog note 2026-03-27 09:43:23 +00:00
github-actions[bot] 8c29faa7ab Update default bundle to codeql-bundle-v2.25.1 2026-03-27 09:43:12 +00:00
Henry Mercer f94817b9f0 Merge pull request #3772 from github/dependabot/npm_and_yarn/yaml-2.8.3
Bump yaml from 2.8.2 to 2.8.3
2026-03-26 19:43:58 +00:00
dependabot[bot] dd060970a5 Bump yaml from 2.8.2 to 2.8.3
Bumps [yaml](https://github.com/eemeli/yaml) from 2.8.2 to 2.8.3.
- [Release notes](https://github.com/eemeli/yaml/releases)
- [Commits](https://github.com/eemeli/yaml/compare/v2.8.2...v2.8.3)

---
updated-dependencies:
- dependency-name: yaml
  dependency-version: 2.8.3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-26 18:26:45 +00:00
Michael B. Gale 5cc552f43e Merge pull request #3768 from github/dependabot/npm_and_yarn/npm-minor-3536e7c6f0
Bump the npm-minor group with 5 updates
2026-03-26 17:46:04 +00:00
Michael B. Gale 6b1a9f2131 Merge branch 'main' into dependabot/npm_and_yarn/npm-minor-3536e7c6f0 2026-03-26 16:36:54 +00:00
Michael B. Gale 9d3ec5727a Merge pull request #3770 from github/dependabot/github_actions/dot-github/workflows/actions-minor-266139ee1d
Bump ruby/setup-ruby from 1.288.0 to 1.295.0 in /.github/workflows in the actions-minor group across 1 directory
2026-03-26 16:32:19 +00:00
Michael B. Gale 3ff82aacd0 Merge pull request #3575 from github/mbg/ts/sync-checks
Convert `release-branches.py` and `update-required-checks.sh` to TypeScript
2026-03-26 15:47:43 +00:00
Sam Robson 4bdd4e7526 Merge pull request #3554 from github/sam-robson/overlay-include-diff
feat: always include files from diff in overlay changed files
2026-03-26 10:57:24 +00:00
Sam Robson 23a0098b57 fix: improve error handling and logging for diff range path resolution 2026-03-25 19:53:21 +00:00
github-actions[bot] ea7b090925 Rebuild 2026-03-25 18:01:40 +00:00
dependabot[bot] a663d0174a Bump ruby/setup-ruby
Bumps the actions-minor group with 1 update in the /.github/workflows directory: [ruby/setup-ruby](https://github.com/ruby/setup-ruby).


Updates `ruby/setup-ruby` from 1.288.0 to 1.295.0
- [Release notes](https://github.com/ruby/setup-ruby/releases)
- [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb)
- [Commits](https://github.com/ruby/setup-ruby/compare/09a7688d3b55cf0e976497ff046b70949eeaccfd...319994f95fa847cf3fb3cd3dbe89f6dcde9f178f)

---
updated-dependencies:
- dependency-name: ruby/setup-ruby
  dependency-version: 1.295.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-25 17:59:44 +00:00
dependabot[bot] b659882aae Bump the npm-minor group with 5 updates
Bumps the npm-minor group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [esbuild](https://github.com/evanw/esbuild) | `0.27.3` | `0.27.4` |
| [eslint-plugin-import-x](https://github.com/un-ts/eslint-plugin-import-x) | `4.16.1` | `4.16.2` |
| [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) | `62.7.1` | `62.8.0` |
| [sinon](https://github.com/sinonjs/sinon) | `21.0.2` | `21.0.3` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.57.0` | `8.57.1` |


Updates `esbuild` from 0.27.3 to 0.27.4
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.27.3...v0.27.4)

Updates `eslint-plugin-import-x` from 4.16.1 to 4.16.2
- [Release notes](https://github.com/un-ts/eslint-plugin-import-x/releases)
- [Changelog](https://github.com/un-ts/eslint-plugin-import-x/blob/master/CHANGELOG.md)
- [Commits](https://github.com/un-ts/eslint-plugin-import-x/compare/v4.16.1...v4.16.2)

Updates `eslint-plugin-jsdoc` from 62.7.1 to 62.8.0
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v62.7.1...v62.8.0)

Updates `sinon` from 21.0.2 to 21.0.3
- [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.0.2...v21.0.3)

Updates `typescript-eslint` from 8.57.0 to 8.57.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.57.1/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: esbuild
  dependency-version: 0.27.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-minor
- dependency-name: eslint-plugin-import-x
  dependency-version: 4.16.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-minor
- dependency-name: eslint-plugin-jsdoc
  dependency-version: 62.8.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-minor
- dependency-name: sinon
  dependency-version: 21.0.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-minor
- dependency-name: typescript-eslint
  dependency-version: 8.57.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-25 17:53:49 +00:00
Sam Robson d5bb39fa0b refactor: single source of truth for getDiffRangesJsonFilePath and simplified getDiffRangeFilePaths 2026-03-25 15:51:51 +00:00
Sam Robson 521c3536d3 feat: always include files from diff in overlay changed files 2026-03-25 15:51:51 +00:00
Michael B. Gale 972365e142 Fix comment 2026-03-25 14:15:39 +00:00
Michael B. Gale 8a0b4f2746 fixup! Update CONTRIBUTING.md 2026-03-25 14:14:49 +00:00
Michael B. Gale a5418e172c Delete releases.ini 2026-03-25 13:49:47 +00:00
Michael B. Gale fae4c28b51 Update CONTRIBUTING.md 2026-03-25 13:48:55 +00:00
Michael B. Gale 661a8fbbe3 Default ref to main 2026-03-25 13:40:05 +00:00
Michael B. Gale e7c7b68c5f Remove update-required-checks.sh 2026-03-25 13:38:28 +00:00
Michael B. Gale fa568ebc69 Delete release-branches.py 2026-03-25 13:37:41 +00:00
Michael B. Gale 0da3139813 Rename to branchName 2026-03-25 13:35:02 +00:00
Michael B. Gale 0abe92ed20 Configure ESLint import/no-extraneous-dependencies rule for pr-checks 2026-03-25 13:17:37 +00:00
Michael B. Gale 07f235e5f2 Add --verbose option 2026-03-25 13:17:37 +00:00
Michael B. Gale 9fd40ff508 Tidy up pr-checks/package.json 2026-03-25 13:17:37 +00:00
Michael B. Gale 75ed461aaa Add excluded.yml path to config.ts 2026-03-25 13:16:35 +00:00
Michael B. Gale cfc18781e0 Rebuild 2026-03-25 13:16:34 +00:00
Michael B. Gale 9fe42f69b7 Add some unit tests for sync-checks.ts 2026-03-25 13:16:33 +00:00
Michael B. Gale c5a984e1aa Update CONTRIBUTING.md 2026-03-25 13:16:33 +00:00
Michael B. Gale 0543156694 Actually perform the update when necessary and requested 2026-03-25 13:16:33 +00:00
Michael B. Gale 4cec5d2830 Call updateBranch for main 2026-03-25 13:16:32 +00:00
Michael B. Gale 74dd691a45 Identify changes before applying them 2026-03-25 13:16:32 +00:00
Michael B. Gale a5244bf7dd Fetch release branches and identify major versions 2026-03-25 13:16:32 +00:00
Michael B. Gale 1bc611ed0c Fetch and filter check runs for ref 2026-03-25 13:16:32 +00:00
Michael B. Gale d2008eee7c Add type to represent exclusions.yml and loading helper 2026-03-25 13:16:32 +00:00
Michael B. Gale 9481177f3d Initialise API client 2026-03-25 13:16:31 +00:00
Michael B. Gale 9813849e61 Add initial TS implementation of update-required-checks.sh 2026-03-25 13:16:31 +00:00
Michael B. Gale 4867f5927a Add config file for excluded checks from update-required-checks.sh 2026-03-25 13:16:31 +00:00
Michael B. Gale 49af37b7ab Add tests for release-branches.ts 2026-03-25 13:16:31 +00:00
Michael B. Gale b72f4fec40 Validate inputs 2026-03-25 13:16:30 +00:00
Michael B. Gale 0d87a75829 Refactor backport computation into computeReleaseBranches 2026-03-25 13:16:30 +00:00
Michael B. Gale 3db9a05c73 Replace release-branches.py with TS version in release-branches action 2026-03-25 13:16:30 +00:00
Michael B. Gale aa2773169b Install node in release-initialise action 2026-03-25 13:16:30 +00:00
Michael B. Gale 054745baee Convert release-branches.py to TypeScript 2026-03-25 13:16:30 +00:00
Michael B. Gale 3d564d9359 Merge pull request #3579 from github/mbg/start-proxy/token-check-fixes
Fix warning for PAT-like token with username
2026-03-25 13:02:47 +00:00
Michael B. Gale 137e0dec2b Merge remote-tracking branch 'origin/main' into mbg/start-proxy/token-check-fixes 2026-03-25 12:39:48 +00:00
Michael B. Gale d128e5daa8 Fix test names 2026-03-25 12:39:42 +00:00
Henry Mercer eedab83377 Merge pull request #3767 from github/henrymercer/overlay-reduce-minimum-git-version
Reduce the minimum Git version required for overlay
2026-03-24 11:26:07 +00:00
Henry Mercer 8c023a6b07 Add changelog note 2026-03-23 18:40:55 +00:00
Henry Mercer 28f56f2bed Update minimum Git version required for overlay 2026-03-23 18:36:25 +00:00
Henry Mercer d48d054533 Use --stage instead of --format in git ls-files 2026-03-23 18:33:59 +00:00
Henry Mercer 72c0b0efb7 Merge pull request #3587 from github/dependabot/npm_and_yarn/fast-xml-parser-5.5.7
Bump fast-xml-parser from 5.5.6 to 5.5.7
2026-03-23 14:22:53 +00:00
Henry Mercer 05b1a5d28f Merge pull request #3764 from github/mergeback/v4.34.1-to-main-38697555
Mergeback v4.34.1 refs/heads/releases/v4 into main
2026-03-20 18:38:55 +00:00
Henry Mercer ebcb5b36de Merge pull request #3765 from github/backport-v3.34.1-386975555
Merge releases/v4 into releases/v3
2026-03-20 18:37:00 +00:00
github-actions[bot] 8dc2e5d9d2 Rebuild 2026-03-20 18:19:40 +00:00
github-actions[bot] 97fd992228 Rebuild 2026-03-20 18:19:37 +00:00
github-actions[bot] 95a562052b Update version and changelog for v3.34.1 2026-03-20 18:16:44 +00:00
github-actions[bot] ae8b37eb31 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.34.1-386975555 2026-03-20 18:16:42 +00:00
github-actions[bot] d75030c604 Revert "Rebuild"
This reverts commit c146cd2193.
2026-03-20 18:16:42 +00:00
github-actions[bot] a777590c0f Revert "Update version and changelog for v3.34.0"
This reverts commit 3fef31e9b5.
2026-03-20 18:16:41 +00:00
github-actions[bot] 8fd6c0e573 Update changelog and version after v4.34.1 2026-03-20 18:14:55 +00:00
Henry Mercer 3869755554 Merge pull request #3763 from github/update-v4.34.1-095e0fe50
Merge main into releases/v4
2026-03-20 18:10:50 +00:00
github-actions[bot] 20e68ac12b Update changelog for v4.34.1 2026-03-20 17:33:39 +00:00
Henry Mercer 095e0fe505 Merge pull request #3762 from github/henrymercer/downgrade-default-bundle
Downgrade default bundle to 2.24.3
2026-03-20 17:06:34 +00:00
Henry Mercer 47b94fe61c Add changelog note 2026-03-20 16:46:45 +00:00
Henry Mercer 51a1d6917f Downgrade default bundle to codeql-bundle-v2.24.3 2026-03-20 16:45:20 +00:00
Óscar San José 510cf736e3 Merge pull request #3589 from github/mergeback/v4.34.0-to-main-c6f93110
Mergeback v4.34.0 refs/heads/releases/v4 into main
2026-03-20 15:15:34 +00:00
Óscar San José dfad8f8ebc Merge pull request #3590 from github/backport-v3.34.0-c6f931105
Merge releases/v4 into releases/v3
2026-03-20 16:15:08 +01:00
github-actions[bot] 89f0c86efa Rebuild 2026-03-20 12:03:59 +00:00
github-actions[bot] c146cd2193 Rebuild 2026-03-20 12:03:47 +00:00
github-actions[bot] 3fef31e9b5 Update version and changelog for v3.34.0 2026-03-20 11:59:46 +00:00
github-actions[bot] 3d7478b23a Merge remote-tracking branch 'origin/releases/v4' into backport-v3.34.0-c6f931105 2026-03-20 11:59:44 +00:00
github-actions[bot] f874badee7 Revert "Rebuild"
This reverts commit 9ed0d758ce.
2026-03-20 11:59:44 +00:00
github-actions[bot] 1c3843e226 Revert "Update version and changelog for v3.33.0"
This reverts commit 2da877a512.
2026-03-20 11:59:44 +00:00
github-actions[bot] c3f90ba975 Update changelog and version after v4.34.0 2026-03-20 11:56:24 +00:00
Óscar San José c6f931105c Merge pull request #3588 from github/update-v4.34.0-30c555a52
Merge main into releases/v4
2026-03-20 12:53:53 +01:00
github-actions[bot] eeb9b3f424 Update changelog for v4.34.0 2026-03-20 10:35:57 +00:00
github-actions[bot] 64507ed148 Rebuild 2026-03-20 01:40:06 +00:00
dependabot[bot] 1a45a9b9d0 Bump fast-xml-parser from 5.5.6 to 5.5.7
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 5.5.6 to 5.5.7.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.5.6...v5.5.7)

---
updated-dependencies:
- dependency-name: fast-xml-parser
  dependency-version: 5.5.7
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-20 01:38:13 +00:00
Michael B. Gale f88d49ee5d Fix warning for PAT-like token with username 2026-03-16 19:34:33 +00:00
Michael B. Gale 28f515d9ad Add tests for the absence of the warning 2026-03-16 19:34:33 +00:00
Michael B. Gale de06821112 Add hasMessage to RecordingLogger 2026-03-16 19:34:33 +00:00
Michael B. Gale ddafddb826 Replace getRecordingLogger implementation with RecordingLogger 2026-03-16 19:34:32 +00:00
Michael B. Gale 740f177889 Add assertNotLogged test helper 2026-03-16 19:34:32 +00:00
Michael B. Gale 0393130759 Add "token without a username" test 2026-03-16 19:34:32 +00:00
Michael B. Gale f86097dfdb Add params for credentials and checkAccepted to testPATWarning 2026-03-16 19:34:32 +00:00
Michael B. Gale 6e67ef61f2 Refactor PAT test into a test.macro 2026-03-16 19:34:32 +00:00
Michael B. Gale 193dd19c2d Add snippet to scaffold test.macros 2026-03-16 19:34:32 +00:00
Michael B. Gale 603b797f8b Merge pull request #3577 from github/backport-v3.33.0-b1bff8193
Merge releases/v4 into releases/v3
2026-03-16 12:23:22 +00:00
github-actions[bot] 9ed0d758ce Rebuild 2026-03-16 11:10:08 +00:00
github-actions[bot] 2da877a512 Update version and changelog for v3.33.0 2026-03-16 09:08:36 +00:00
github-actions[bot] 4ccf9a5deb Merge remote-tracking branch 'origin/releases/v4' into backport-v3.33.0-b1bff8193 2026-03-16 09:08:34 +00:00
github-actions[bot] e50ab6dc1d Revert "Rebuild"
This reverts commit dabb34c95a.
2026-03-16 09:08:33 +00:00
github-actions[bot] ee6db5e4f5 Revert "Update version and changelog for v3.32.6"
This reverts commit c0e7770e36.
2026-03-16 09:08:33 +00:00
Óscar San José 820e3160e2 Merge pull request #3553 from github/backport-v3.32.6-0d579ffd0
Merge releases/v4 into releases/v3
2026-03-06 10:44:37 +01:00
github-actions[bot] dabb34c95a Rebuild 2026-03-05 19:44:24 +00:00
github-actions[bot] c0e7770e36 Update version and changelog for v3.32.6 2026-03-05 19:35:55 +00:00
github-actions[bot] dbc2ac9b7a Merge remote-tracking branch 'origin/releases/v4' into backport-v3.32.6-0d579ffd0 2026-03-05 19:35:54 +00:00
github-actions[bot] e61b8b4cf5 Revert "Rebuild"
This reverts commit b58ecf644d.
2026-03-05 19:35:53 +00:00
github-actions[bot] b7ebceaf1a Revert "Update version and changelog for v3.32.5"
This reverts commit e3632d0ee3.
2026-03-05 19:35:53 +00:00
Henry Mercer ae9ef3a1d2 Merge pull request #3533 from github/backport-v3.32.5-c793b717b
Merge releases/v4 into releases/v3
2026-03-02 12:01:34 +00:00
github-actions[bot] b58ecf644d Rebuild 2026-03-02 11:34:55 +00:00
github-actions[bot] e3632d0ee3 Update version and changelog for v3.32.5 2026-03-02 11:17:26 +00:00
github-actions[bot] cdcb071e67 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.32.5-c793b717b 2026-03-02 11:17:25 +00:00
github-actions[bot] 177cb24be1 Revert "Rebuild"
This reverts commit a3696cdbdf.
2026-03-02 11:17:24 +00:00
github-actions[bot] 2427cfc4a9 Revert "Update version and changelog for v3.32.4"
This reverts commit 147ec67ee5.
2026-03-02 11:17:23 +00:00
Michael B. Gale 45580472a5 Merge pull request #3496 from github/backport-v3.32.4-89a39a4e5 2026-02-20 15:34:23 +00:00
github-actions[bot] a3696cdbdf Rebuild 2026-02-20 14:52:56 +00:00
github-actions[bot] 147ec67ee5 Update version and changelog for v3.32.4 2026-02-20 14:21:14 +00:00
github-actions[bot] acb91bd91f Merge remote-tracking branch 'origin/releases/v4' into backport-v3.32.4-89a39a4e5 2026-02-20 14:21:13 +00:00
github-actions[bot] 88d9aba91d Revert "Rebuild"
This reverts commit 70a71a57dd.
2026-02-20 14:21:12 +00:00
github-actions[bot] 72edeaa05b Revert "Update version and changelog for v3.32.3"
This reverts commit 676a1ceb5c.
2026-02-20 14:21:12 +00:00
Henry Mercer f5c2471be7 Merge pull request #3481 from github/backport-v3.32.3-9e907b5e6
Merge releases/v4 into releases/v3
2026-02-13 12:21:24 +00:00
github-actions[bot] 70a71a57dd Rebuild 2026-02-13 12:01:04 +00:00
github-actions[bot] 676a1ceb5c Update version and changelog for v3.32.3 2026-02-13 11:55:54 +00:00
github-actions[bot] e127ec2647 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.32.3-9e907b5e6 2026-02-13 11:55:52 +00:00
github-actions[bot] f5e6f52190 Revert "Rebuild"
This reverts commit bb159524f9.
2026-02-13 11:55:52 +00:00
github-actions[bot] e2a90d3e23 Revert "Update version and changelog for v3.32.2"
This reverts commit 6b68dd5d27.
2026-02-13 11:55:52 +00:00
Henry Mercer b5ebac6f4c Merge pull request #3463 from github/backport-v3.32.2-45cbd0c69
Merge releases/v4 into releases/v3
2026-02-06 11:22:57 +00:00
github-actions[bot] bb159524f9 Rebuild 2026-02-06 11:00:51 +00:00
github-actions[bot] 6b68dd5d27 Update version and changelog for v3.32.2 2026-02-05 17:12:29 +00:00
github-actions[bot] 24e739f51f Merge remote-tracking branch 'origin/releases/v4' into backport-v3.32.2-45cbd0c69 2026-02-05 17:12:25 +00:00
github-actions[bot] e5a63de15c Revert "Rebuild"
This reverts commit fd13ffa22c.
2026-02-05 17:12:25 +00:00
github-actions[bot] c2d57b0fc7 Revert "Update version and changelog for v3.32.1"
This reverts commit ce04bc5815.
2026-02-05 17:12:24 +00:00
Henry Mercer 2588666de8 Merge pull request #3449 from github/backport-v3.32.1-6bc82e05f
Merge releases/v4 into releases/v3
2026-02-02 07:47:27 -08:00
github-actions[bot] fd13ffa22c Rebuild 2026-02-02 15:21:36 +00:00
github-actions[bot] ce04bc5815 Update version and changelog for v3.32.1 2026-02-02 15:14:15 +00:00
github-actions[bot] 27eb5f56eb Merge remote-tracking branch 'origin/releases/v4' into backport-v3.32.1-6bc82e05f 2026-02-02 15:14:12 +00:00
github-actions[bot] 44f67f0887 Revert "Rebuild"
This reverts commit f5ab452606.
2026-02-02 15:14:12 +00:00
github-actions[bot] 5d24c86a89 Revert "Update version and changelog for v3.32.0"
This reverts commit 56c8e1c8a8.
2026-02-02 15:14:12 +00:00
Henry Mercer 439137e1b5 Merge pull request #3430 from github/backport-v3.32.0-b20883b0c
Merge releases/v4 into releases/v3
2026-01-26 11:23:41 -08:00
github-actions[bot] f5ab452606 Rebuild 2026-01-26 18:54:38 +00:00
github-actions[bot] 56c8e1c8a8 Update version and changelog for v3.32.0 2026-01-26 18:41:33 +00:00
github-actions[bot] 4f5ca6f9a5 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.32.0-b20883b0c 2026-01-26 18:41:32 +00:00
github-actions[bot] 92f3a2822b Revert "Rebuild"
This reverts commit c9e0329cc4.
2026-01-26 18:41:32 +00:00
github-actions[bot] e9bf22fb0e Revert "Update version and changelog for v3.31.11"
This reverts commit 9ffacc75e8.
2026-01-26 18:41:32 +00:00
Michael B. Gale 38e701f46e Merge pull request #3419 from github/backport-v3.31.11-19b2f06db 2026-01-23 15:44:23 +00:00
github-actions[bot] c9e0329cc4 Rebuild 2026-01-23 15:14:24 +00:00
github-actions[bot] 9ffacc75e8 Update version and changelog for v3.31.11 2026-01-23 13:56:12 +00:00
github-actions[bot] 21961f3b6f Merge remote-tracking branch 'origin/releases/v4' into backport-v3.31.11-19b2f06db 2026-01-23 13:56:10 +00:00
github-actions[bot] 8233700206 Revert "Rebuild"
This reverts commit 6252d140cd.
2026-01-23 13:56:10 +00:00
github-actions[bot] 23e84a39f0 Revert "Update version and changelog for v3.31.10"
This reverts commit 84cf4b44bb.
2026-01-23 13:56:09 +00:00
Ian Lynagh 4bdb89f480 Merge pull request #3396 from github/backport-v3.31.10-cdefb33c0
Merge releases/v4 into releases/v3
2026-01-12 16:26:37 +00:00
Michael B. Gale ed629463c0 Set using: node20 for verify-debug-artifact-scan-completed on releases/v3 2026-01-12 15:44:23 +00:00
github-actions[bot] 6252d140cd Rebuild 2026-01-12 15:28:18 +00:00
github-actions[bot] 84cf4b44bb Update version and changelog for v3.31.10 2026-01-12 14:37:46 +00:00
github-actions[bot] 52cebb523a Merge remote-tracking branch 'origin/releases/v4' into backport-v3.31.10-cdefb33c0 2026-01-12 14:37:43 +00:00
github-actions[bot] fc6e643fe1 Revert "Rebuild"
This reverts commit 311b632b9d.
2026-01-12 14:37:43 +00:00
github-actions[bot] f8ee3fcc9a Revert "Update version and changelog for v3.31.9"
This reverts commit d300581d5e.
2026-01-12 14:37:43 +00:00
Henry Mercer 45c373516f Merge pull request #3373 from github/backport-v3.31.9-5d4e8d1ac
Merge releases/v4 into releases/v3
2025-12-16 19:21:59 +00:00
github-actions[bot] 311b632b9d Rebuild 2025-12-16 18:51:43 +00:00
github-actions[bot] d300581d5e Update version and changelog for v3.31.9 2025-12-16 18:34:57 +00:00
github-actions[bot] 7348876640 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.31.9-5d4e8d1ac 2025-12-16 18:34:56 +00:00
github-actions[bot] 4f34645a82 Revert "Rebuild"
This reverts commit 74951318a2.
2025-12-16 18:34:56 +00:00
github-actions[bot] e7c7a2d323 Revert "Update version and changelog for v3.31.8"
This reverts commit 5676d1f64a.
2025-12-16 18:34:56 +00:00
Óscar San José f47c8e6a9b Merge pull request #3357 from github/backport-v3.31.8-1b168cd39
Merge releases/v4 into releases/v3
2025-12-12 10:43:49 +01:00
github-actions[bot] 74951318a2 Rebuild 2025-12-12 08:53:47 +00:00
github-actions[bot] 5676d1f64a Update version and changelog for v3.31.8 2025-12-12 08:46:33 +00:00
github-actions[bot] c1bea80e56 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.31.8-1b168cd39 2025-12-12 08:46:32 +00:00
github-actions[bot] 2d9c0b97af Revert "Rebuild"
This reverts commit 817dbfb39b.
2025-12-12 08:46:32 +00:00
github-actions[bot] 827017f97b Revert "Update version and changelog for v3.31.7"
This reverts commit 793f7006bb.
2025-12-12 08:46:31 +00:00
Henry Mercer bffd034ab1 Merge pull request #3346 from github/backport-v3.31.7-cf1bb45a2
Merge releases/v4 into releases/v3
2025-12-09 13:26:37 +00:00
github-actions[bot] 817dbfb39b Rebuild 2025-12-05 20:45:51 +00:00
github-actions[bot] 793f7006bb Update version and changelog for v3.31.7 2025-12-05 17:21:20 +00:00
github-actions[bot] d2e9832330 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.31.7-cf1bb45a2 2025-12-05 17:21:19 +00:00
github-actions[bot] c2e4b7785f Revert "Rebuild"
This reverts commit 89cb79a131.
2025-12-05 17:21:18 +00:00
github-actions[bot] 66d7f51a10 Revert "Update version and changelog for v3.31.6"
This reverts commit dbf6819ebd.
2025-12-05 17:21:18 +00:00
Michael B. Gale 497990dfed Merge pull request #3338 from github/backport-v3.31.6-fe4161a26
Merge releases/v4 into releases/v3
2025-12-01 10:24:24 +00:00
github-actions[bot] 89cb79a131 Rebuild 2025-12-01 09:59:32 +00:00
github-actions[bot] dbf6819ebd Update version and changelog for v3.31.6 2025-12-01 09:52:51 +00:00
github-actions[bot] 5af51f4048 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.31.6-fe4161a26 2025-12-01 09:52:49 +00:00
github-actions[bot] e439418aab Revert "Rebuild"
This reverts commit c12d7c1f2d.
2025-12-01 09:52:49 +00:00
github-actions[bot] 249860e323 Revert "Update version and changelog for v3.31.5"
This reverts commit 2e2a1cf1ef.
2025-12-01 09:52:49 +00:00
Paolo Tranquilli d3ced5c96c Merge pull request #3324 from github/backport-v3.31.5-fdbfb4d27
Merge releases/v4 into releases/v3
2025-11-24 12:16:57 +01:00
github-actions[bot] c12d7c1f2d Rebuild 2025-11-24 10:56:57 +00:00
github-actions[bot] 2e2a1cf1ef Update version and changelog for v3.31.5 2025-11-24 09:33:54 +00:00
github-actions[bot] e2cca77d06 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.31.5-fdbfb4d27 2025-11-24 09:33:53 +00:00
github-actions[bot] 801a18bea6 Revert "Rebuild"
This reverts commit 9031cd9330.
2025-11-24 09:33:52 +00:00
github-actions[bot] 1c715a714c Revert "Update version and changelog for v3.31.4"
This reverts commit f58938aee2.
2025-11-24 09:33:52 +00:00
Henry Mercer c3d42c5d08 Merge pull request #3314 from github/backport-v3.31.4-e12f01789
Merge releases/v4 into releases/v3
2025-11-19 10:02:25 +00:00
github-actions[bot] 9031cd9330 Rebuild 2025-11-18 17:06:56 +00:00
github-actions[bot] f58938aee2 Update version and changelog for v3.31.4 2025-11-18 16:16:32 +00:00
github-actions[bot] 1f1c162805 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.31.4-e12f01789 2025-11-18 16:16:30 +00:00
github-actions[bot] 7ab96a0e6f Revert "Rebuild"
This reverts commit e5971bdba6.
2025-11-18 16:16:30 +00:00
github-actions[bot] e3cb86275a Revert "Update version and changelog for v3.31.3"
This reverts commit c5a9d29dc9.
2025-11-18 16:16:29 +00:00
Michael B. Gale f94c9befff Merge pull request #3295 from github/backport-v3.31.3-014f16e7a
Merge releases/v4 into releases/v3
2025-11-13 22:45:46 +00:00
github-actions[bot] e5971bdba6 Rebuild 2025-11-13 22:03:22 +00:00
github-actions[bot] c5a9d29dc9 Update version and changelog for v3.31.3 2025-11-13 21:57:42 +00:00
github-actions[bot] 9f1109665d Merge remote-tracking branch 'origin/releases/v4' into backport-v3.31.3-014f16e7a 2025-11-13 21:57:40 +00:00
github-actions[bot] f8f60f3a2b Revert "Rebuild"
This reverts commit c6eb09db21.
2025-11-13 21:57:40 +00:00
github-actions[bot] f4d10b9ef7 Revert "Update version and changelog for v3.31.2"
This reverts commit 09db9044dc.
2025-11-13 21:57:39 +00:00
Henry Mercer 5d5cd550d3 Merge pull request #3263 from github/backport-v3.31.2-0499de31b
Merge releases/v4 into releases/v3
2025-10-30 15:01:09 +00:00
github-actions[bot] c6eb09db21 Rebuild 2025-10-30 14:37:32 +00:00
github-actions[bot] 09db9044dc Update version and changelog for v3.31.2 2025-10-30 14:34:26 +00:00
github-actions[bot] d3cd47d8d6 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.31.2-0499de31b 2025-10-30 14:34:25 +00:00
github-actions[bot] 8e9caa5100 Revert "Rebuild"
This reverts commit c2805e0a04.
2025-10-30 14:34:25 +00:00
github-actions[bot] 23a6333b88 Revert "Update version and changelog for v3.31.1"
This reverts commit c0d3370b54.
2025-10-30 14:34:24 +00:00
Henry Mercer c503cb4fbb Merge pull request #3254 from github/backport-v3.31.1-5fe9434cd
Merge releases/v4 into releases/v3
2025-10-30 11:00:54 +00:00
github-actions[bot] c2805e0a04 Rebuild 2025-10-30 10:35:44 +00:00
github-actions[bot] c0d3370b54 Update version and changelog for v3.31.1 2025-10-30 10:31:02 +00:00
github-actions[bot] ddd0dc746a Merge remote-tracking branch 'origin/releases/v4' into backport-v3.31.1-5fe9434cd 2025-10-30 10:31:01 +00:00
github-actions[bot] 2f607936ce Revert "Rebuild"
This reverts commit 9e3918e481.
2025-10-30 10:31:00 +00:00
github-actions[bot] 37e7dfbaa0 Revert "Update version and changelog for v3.31.0"
This reverts commit 7dd1575dac.
2025-10-30 10:31:00 +00:00
Michael B. Gale d198d2fabf Merge pull request #3237 from github/backport-v3.31.0-4e94bd11f
Merge releases/v4 into releases/v3
2025-10-24 19:30:34 +01:00
github-actions[bot] 9e3918e481 Rebuild 2025-10-24 17:18:40 +00:00
github-actions[bot] 7dd1575dac Update version and changelog for v3.31.0 2025-10-24 17:11:07 +00:00
github-actions[bot] 28fc48d83c Merge remote-tracking branch 'origin/releases/v4' into backport-v3.31.0-4e94bd11f 2025-10-24 17:11:06 +00:00
github-actions[bot] 12c6008004 Revert "Rebuild"
This reverts commit 5f3f3164ad.
2025-10-24 17:11:05 +00:00
github-actions[bot] d3019effb0 Revert "Update version and changelog for v3.30.9"
This reverts commit ba42101490.
2025-10-24 17:11:05 +00:00
Henry Mercer 42213152a8 Merge pull request #3216 from github/backport-v3.30.9-16140ae1a
Merge releases/v4 into releases/v3
2025-10-17 17:09:13 +01:00
Henry Mercer e677e67801 Run setup-codeql on Node 20 for v3 2025-10-17 16:53:18 +01:00
github-actions[bot] 5f3f3164ad Rebuild 2025-10-17 15:34:40 +00:00
github-actions[bot] ba42101490 Update version and changelog for v3.30.9 2025-10-17 15:24:34 +00:00
github-actions[bot] f11af5849b Merge remote-tracking branch 'origin/releases/v4' into backport-v3.30.9-16140ae1a 2025-10-17 15:24:33 +00:00
github-actions[bot] ba5430dc86 Revert "Rebuild"
This reverts commit 948223fe01.
2025-10-17 15:24:33 +00:00
github-actions[bot] 13e883e119 Revert "Update version and changelog for v3.30.8"
This reverts commit a37add20d4.
2025-10-17 15:24:32 +00:00
Michael B. Gale 755f44910c Merge pull request #3201 from github/backport-v3.30.8-2a6736cca
Merge releases/v4 into releases/v3
2025-10-10 18:20:36 +01:00
github-actions[bot] 948223fe01 Rebuild 2025-10-10 16:56:34 +00:00
github-actions[bot] a37add20d4 Update version and changelog for v3.30.8 2025-10-10 16:50:13 +00:00
github-actions[bot] ab163cf08b Merge remote-tracking branch 'origin/releases/v4' into backport-v3.30.8-2a6736cca 2025-10-10 16:50:12 +00:00
github-actions[bot] 319796f085 Revert "Rebuild"
This reverts commit c551c50310.
2025-10-10 16:50:12 +00:00
github-actions[bot] bd1ac56295 Revert "Update version and changelog for v3.30.7"
This reverts commit b264e15259.
2025-10-10 16:50:12 +00:00
Mario Campos a8d1ac45b9 Merge pull request #3187 from github/backport-v3.30.7-e296a9355
Merge releases/v4 into releases/v3
2025-10-07 10:58:53 -05:00
github-actions[bot] c551c50310 Rebuild 2025-10-07 15:33:29 +00:00
Mario Campos 01f1a24033 Downgrade action.yml to use Node.js 20 instead of Node.js 24 for v3 2025-10-07 10:29:22 -05:00
github-actions[bot] b264e15259 Update version and changelog for v3.30.7 2025-10-07 15:23:05 +00:00
90 changed files with 16299 additions and 13337 deletions

No files matched your search

+1 -1
View File
@@ -16,5 +16,5 @@ inputs:
Comma separated list of query ids that should NOT be included in this SARIF file.
runs:
using: node24
using: node20
main: index.js
+2 -1
View File
@@ -22,7 +22,8 @@ runs:
MAJOR_VERSION: ${{ inputs.major_version }}
LATEST_TAG: ${{ inputs.latest_tag }}
run: |
python ${{ github.action_path }}/release-branches.py \
npm ci
npx tsx ./pr-checks/release-branches.ts \
--major-version "$MAJOR_VERSION" \
--latest-tag "$LATEST_TAG"
shell: bash
@@ -1,55 +0,0 @@
import argparse
import json
import os
import configparser
# Name of the remote
ORIGIN = 'origin'
script_dir = os.path.dirname(os.path.realpath(__file__))
grandparent_dir = os.path.dirname(os.path.dirname(script_dir))
config = configparser.ConfigParser()
with open(os.path.join(grandparent_dir, 'releases.ini')) as stream:
config.read_string('[default]\n' + stream.read())
OLDEST_SUPPORTED_MAJOR_VERSION = int(config['default']['OLDEST_SUPPORTED_MAJOR_VERSION'])
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--major-version", required=True, type=str, help="The major version of the release")
parser.add_argument("--latest-tag", required=True, type=str, help="The most recent tag published to the repository")
args = parser.parse_args()
major_version = args.major_version
latest_tag = args.latest_tag
print("major_version: " + major_version)
print("latest_tag: " + latest_tag)
# If this is a primary release, we backport to all supported branches,
# so we check whether the major_version taken from the package.json
# is greater than or equal to the latest tag pulled from the repo.
# For example...
# 'v1' >= 'v2' is False # we're operating from an older release branch and should not backport
# 'v2' >= 'v2' is True # the normal case where we're updating the current version
# 'v3' >= 'v2' is True # in this case we are making the first release of a new major version
consider_backports = ( major_version >= latest_tag.split(".")[0] )
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
f.write(f"backport_source_branch=releases/{major_version}\n")
backport_target_branches = []
if consider_backports:
for i in range(int(major_version.strip("v"))-1, 0, -1):
branch_name = f"releases/v{i}"
if i >= OLDEST_SUPPORTED_MAJOR_VERSION:
backport_target_branches.append(branch_name)
f.write("backport_target_branches="+json.dumps(backport_target_branches)+"\n")
if __name__ == "__main__":
main()
@@ -15,6 +15,12 @@ runs:
run: echo "$GITHUB_CONTEXT"
shell: bash
- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: 20
cache: 'npm'
- name: Set up Python
uses: actions/setup-python@v6
with:
@@ -1,6 +1,6 @@
name: Verify that the best-effort debug artifact scan completed
description: Verifies that the best-effort debug artifact scan completed successfully during tests
runs:
using: node24
using: node20
main: index.js
post: post.js
+3 -1
View File
@@ -1,7 +1,9 @@
version: 2
updates:
- package-ecosystem: npm
directory: "/"
directories:
- "/"
- "/pr-checks"
schedule:
interval: weekly
cooldown:
-1
View File
@@ -1 +0,0 @@
OLDEST_SUPPORTED_MAJOR_VERSION=3
+2 -2
View File
@@ -60,12 +60,12 @@ jobs:
setup-kotlin: 'true'
- uses: ./../action/init
with:
languages: C#,java-kotlin,swift,typescript
languages: C#,java-kotlin,typescript
tools: ${{ steps.prepare-test.outputs.tools-url }}
- name: 'Check languages'
run: |
expected_languages="csharp,java,swift,javascript"
expected_languages="csharp,java,javascript"
actual_languages=$(jq -r '.languages | join(",")' "$RUNNER_TEMP"/config)
if [ "$expected_languages" != "$actual_languages" ]; then
+1 -1
View File
@@ -59,7 +59,7 @@ jobs:
use-all-platform-bundle: 'false'
setup-kotlin: 'true'
- name: Set up Ruby
uses: ruby/setup-ruby@09a7688d3b55cf0e976497ff046b70949eeaccfd # v1.288.0
uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0
with:
ruby-version: 2.6
- name: Install Code Scanning integration
+18 -1
View File
@@ -71,7 +71,17 @@ jobs:
id: proxy
uses: ./../action/start-proxy
with:
registry_secrets: '[{ "type": "nuget_feed", "url": "https://api.nuget.org/v3/index.json" }]'
registry_secrets: |
[
{
"type": "maven_repository",
"url": "https://repo.maven.apache.org/maven2/"
},
{
"type": "maven_repository",
"url": "https://repo1.maven.org/maven2"
}
]
- name: Print proxy outputs
run: |
@@ -82,5 +92,12 @@ jobs:
- name: Fail if proxy outputs are not set
if: (!steps.proxy.outputs.proxy_host) || (!steps.proxy.outputs.proxy_port) || (!steps.proxy.outputs.proxy_ca_certificate) || (!steps.proxy.outputs.proxy_urls)
run: exit 1
- name: Fail if proxy_urls does not contain all registries
if: |
join(fromJSON(steps.proxy.outputs.proxy_urls)[*].type, ',') != 'maven_repository,maven_repository'
|| !contains(steps.proxy.outputs.proxy_urls, 'https://repo.maven.apache.org/maven2/')
|| !contains(steps.proxy.outputs.proxy_urls, 'https://repo1.maven.org/maven2')
run: exit 1
env:
CODEQL_ACTION_TEST_MODE: true
@@ -66,6 +66,7 @@ jobs:
uses: ./../action/.github/actions/verify-debug-artifact-scan-completed
- uses: ./../action/init
with:
languages: cpp,csharp,go,java,javascript,python
tools: ${{ steps.prepare-test.outputs.tools-url }}
debug: true
debug-artifact-name: my-debug-artifacts
+2 -2
View File
@@ -24,7 +24,7 @@ defaults:
jobs:
merge-back:
runs-on: ubuntu-slim
runs-on: ubuntu-latest
environment: Automation
if: github.repository == 'github/codeql-action'
env:
@@ -131,7 +131,7 @@ jobs:
echo "::endgroup::"
- name: Generate token
uses: actions/create-github-app-token@v3.0.0
uses: actions/create-github-app-token@v3.1.1
id: app-token
with:
app-id: ${{ vars.AUTOMATION_APP_ID }}
+1 -1
View File
@@ -29,7 +29,7 @@ defaults:
jobs:
prepare:
name: "Prepare release"
runs-on: ubuntu-slim
runs-on: ubuntu-latest
if: github.repository == 'github/codeql-action'
permissions:
+1 -1
View File
@@ -136,7 +136,7 @@ jobs:
- name: Generate token
if: github.event_name == 'workflow_dispatch'
uses: actions/create-github-app-token@v3.0.0
uses: actions/create-github-app-token@v3.1.1
id: app-token
with:
app-id: ${{ vars.AUTOMATION_APP_ID }}
@@ -1,64 +0,0 @@
#!/usr/bin/env bash
# Update the required checks based on the current branch.
set -euo pipefail
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
REPO_DIR="$(dirname "$SCRIPT_DIR")"
GRANDPARENT_DIR="$(dirname "$REPO_DIR")"
source "$GRANDPARENT_DIR/releases.ini"
if ! gh auth status 2>/dev/null; then
gh auth status
echo "Failed: Not authorized. This script requires admin access to github/codeql-action through the gh CLI."
exit 1
fi
if [ "$#" -eq 1 ]; then
# If we were passed an argument, use that as the SHA
GITHUB_SHA="$1"
elif [ "$#" -gt 1 ]; then
echo "Usage: $0 [SHA]"
echo "Update the required checks based on the SHA, or main."
exit 1
elif [ -z "$GITHUB_SHA" ]; then
# If we don't have a SHA, use main
GITHUB_SHA="$(git rev-parse main)"
fi
echo "Getting checks for $GITHUB_SHA"
# Ignore any checks with "https://", CodeQL, LGTM, Update, and ESLint checks.
CHECKS="$(gh api repos/github/codeql-action/commits/"${GITHUB_SHA}"/check-runs --paginate | jq --slurp --compact-output --raw-output '[.[].check_runs.[] | select(.conclusion != "skipped") | .name | select(contains("https://") or . == "CodeQL" or . == "Dependabot" or . == "check-expected-release-files" or contains("Update") or contains("ESLint") or contains("update") or contains("test-setup-python-scripts") or . == "Agent" or . == "Cleanup artifacts" or . == "Prepare" or . == "Upload results" or . == "Label PR with size" | not)] | unique | sort')"
echo "$CHECKS" | jq
# Fail if there are no checks
if [ -z "$CHECKS" ] || [ "$(echo "$CHECKS" | jq '. | length')" -eq 0 ]; then
echo "No checks found for $GITHUB_SHA"
exit 1
fi
echo "{\"contexts\": ${CHECKS}}" > checks.json
echo "Updating main"
gh api --silent -X "PATCH" "repos/github/codeql-action/branches/main/protection/required_status_checks" --input checks.json
# list all branchs on origin remote matching releases/v*
BRANCHES="$(git ls-remote --heads origin 'releases/v*' | sed 's?.*refs/heads/??' | sort -V)"
for BRANCH in $BRANCHES; do
# strip exact 'releases/v' prefix from $BRANCH using count of characters
VERSION="${BRANCH:10}"
if [ "$VERSION" -lt "$OLDEST_SUPPORTED_MAJOR_VERSION" ]; then
echo "Skipping $BRANCH"
continue
fi
echo "Updating $BRANCH"
gh api --silent -X "PATCH" "repos/github/codeql-action/branches/$BRANCH/protection/required_status_checks" --input checks.json
done
rm checks.json
+15 -1
View File
@@ -20,7 +20,7 @@ defaults:
jobs:
update-bundle:
if: github.event.release.prerelease && startsWith(github.event.release.tag_name, 'codeql-bundle-')
runs-on: ubuntu-slim
runs-on: ubuntu-latest
permissions:
contents: write # needed to push commits
pull-requests: write # needed to create pull requests
@@ -57,6 +57,20 @@ jobs:
- name: Update bundle
uses: ./.github/actions/update-bundle
- name: Set up CodeQL CLI from new bundle
id: setup-codeql
uses: ./setup-codeql
with:
tools: https://github.com/github/codeql-action/releases/download/${{ github.event.release.tag_name }}/codeql-bundle-linux64.tar.gz
- name: Update language aliases
env:
CODEQL_PATH: ${{ steps.setup-codeql.outputs.codeql-path }}
run: |
"$CODEQL_PATH" resolve languages --format=betterjson --extractor-include-aliases \
| jq -S '.aliases // {}' \
> src/known-language-aliases.json
- name: Bump Action minor version if new CodeQL minor version series
id: bump-action-version
run: |
+3 -3
View File
@@ -26,7 +26,7 @@ jobs:
update:
timeout-minutes: 45
runs-on: ubuntu-slim
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch'
needs: [prepare]
env:
@@ -77,7 +77,7 @@ jobs:
backport:
timeout-minutes: 45
runs-on: ubuntu-slim
runs-on: ubuntu-latest
environment: Automation
needs: [prepare]
if: ${{ (github.event_name == 'push') && needs.prepare.outputs.backport_target_branches != '[]' }}
@@ -93,7 +93,7 @@ jobs:
pull-requests: write # needed to create pull request
steps:
- name: Generate token
uses: actions/create-github-app-token@v3.0.0
uses: actions/create-github-app-token@v3.1.1
id: app-token
with:
app-id: ${{ vars.AUTOMATION_APP_ID }}
+2
View File
@@ -11,3 +11,5 @@ build/
eslint.sarif
# for local incremental compilation
tsconfig.tsbuildinfo
# esbuild metadata file
meta.json
+30
View File
@@ -0,0 +1,30 @@
{
// Place your codeql-action workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
// Placeholders with the same ids are connected.
// Example:
// "Print to console": {
// "scope": "javascript,typescript",
// "prefix": "log",
// "body": [
// "console.log('$1');",
// "$2"
// ],
// "description": "Log output to console"
// }
"Test Macro": {
"scope": "javascript, typescript",
"prefix": "testMacro",
"body": [
"const ${1:nameMacro} = test.macro({",
" exec: async (t: ExecutionContext<unknown>) => {},",
"",
" title: (providedTitle = \"\") => `${2:common title} - \\${providedTitle}`,",
"});",
],
"description": "An Ava test macro",
},
}
+46 -33
View File
@@ -2,16 +2,36 @@
See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs.
## [UNRELEASED]
## 3.35.2 - 15 Apr 2026
- The undocumented TRAP cache cleanup feature that could be enabled using the `CODEQL_ACTION_CLEANUP_TRAP_CACHES` environment variable is deprecated and will be removed in May 2026. If you are affected by this, we recommend disabling TRAP caching by passing the `trap-caching: false` input to the `init` Action. [#3795](https://github.com/github/codeql-action/pull/3795)
- The Git version 2.36.0 requirement for improved incremental analysis now only applies to repositories that contain submodules. [#3789](https://github.com/github/codeql-action/pull/3789)
- Python analysis on GHES no longer extracts the standard library, relying instead on models of the standard library. This should result in significantly faster extraction and analysis times, while the effect on alerts should be minimal. [#3794](https://github.com/github/codeql-action/pull/3794)
- Fixed a bug in the validation of OIDC configurations for private registries that was added in CodeQL Action 4.33.0 / 3.33.0. [#3807](https://github.com/github/codeql-action/pull/3807)
- Update default CodeQL bundle version to [2.25.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.2). [#3823](https://github.com/github/codeql-action/pull/3823)
## 3.35.1 - 27 Mar 2026
- Fix incorrect minimum required Git version for [improved incremental analysis](https://github.com/github/roadmap/issues/1158): it should have been 2.36.0, not 2.11.0. [#3781](https://github.com/github/codeql-action/pull/3781)
## 3.35.0 - 27 Mar 2026
- Reduced the minimum Git version required for [improved incremental analysis](https://github.com/github/roadmap/issues/1158) from 2.38.0 to 2.11.0. [#3767](https://github.com/github/codeql-action/pull/3767)
- Update default CodeQL bundle version to [2.25.1](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.1). [#3773](https://github.com/github/codeql-action/pull/3773)
## 3.34.1 - 20 Mar 2026
- Downgrade default CodeQL bundle version to [2.24.3](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.3) due to issues with a small percentage of Actions and JavaScript analyses. [#3762](https://github.com/github/codeql-action/pull/3762)
## 3.34.0 - 20 Mar 2026
- Added an experimental change which disables TRAP caching when [improved incremental analysis](https://github.com/github/roadmap/issues/1158) is enabled, since improved incremental analysis supersedes TRAP caching. This will improve performance and reduce Actions cache usage. We expect to roll this change out to everyone in March. [#3569](https://github.com/github/codeql-action/pull/3569)
- We are rolling out improved incremental analysis to C/C++ analyses that use build mode `none`. We expect this rollout to be complete by the end of April 2026. [#3584](https://github.com/github/codeql-action/pull/3584)
- Update default CodeQL bundle version to [2.25.0](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.0). [#3585](https://github.com/github/codeql-action/pull/3585)
## 4.33.0 - 16 Mar 2026
## 3.33.0 - 16 Mar 2026
- Upcoming change: Starting April 2026, the CodeQL Action will skip collecting file coverage information on pull requests to improve analysis performance. File coverage information will still be computed on non-PR analyses. Pull request analyses will log a warning about this upcoming change. [#3562](https://github.com/github/codeql-action/pull/3562)
To opt out of this change:
- **Repositories owned by an organization:** Create a custom repository property with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to `true` in the repository's settings. For more information, see [Managing custom properties for repositories in your organization](https://docs.github.com/en/organizations/managing-organization-settings/managing-custom-properties-for-repositories-in-your-organization). Alternatively, if you are using an advanced setup workflow, you can set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true` in your workflow.
- **User-owned repositories using default setup:** Switch to an advanced setup workflow and set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true` in your workflow.
@@ -22,11 +42,11 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th
- Fixed the retry mechanism for database uploads. Previously this would fail with the error "Response body object should not be disturbed or locked". [#3564](https://github.com/github/codeql-action/pull/3564)
- A warning is now emitted if the CodeQL Action detects a repository property whose name suggests that it relates to the CodeQL Action, but which is not one of the properties recognised by the current version of the CodeQL Action. [#3570](https://github.com/github/codeql-action/pull/3570)
## 4.32.6 - 05 Mar 2026
## 3.32.6 - 05 Mar 2026
- Update default CodeQL bundle version to [2.24.3](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.3). [#3548](https://github.com/github/codeql-action/pull/3548)
## 4.32.5 - 02 Mar 2026
## 3.32.5 - 02 Mar 2026
- Repositories owned by an organization can now set up the `github-codeql-disable-overlay` custom repository property to disable [improved incremental analysis for CodeQL](https://github.com/github/roadmap/issues/1158). First, create a custom repository property with the name `github-codeql-disable-overlay` and the type "True/false" in the organization's settings. Then in the repository's settings, set this property to `true` to disable improved incremental analysis. For more information, see [Managing custom properties for repositories in your organization](https://docs.github.com/en/organizations/managing-organization-settings/managing-custom-properties-for-repositories-in-your-organization). This feature is not yet available on GitHub Enterprise Server. [#3507](https://github.com/github/codeql-action/pull/3507)
- Added an experimental change so that when [improved incremental analysis](https://github.com/github/roadmap/issues/1158) fails on a runner — potentially due to insufficient disk space — the failure is recorded in the Actions cache so that subsequent runs will automatically skip improved incremental analysis until something changes (e.g. a larger runner is provisioned or a new CodeQL version is released). We expect to roll this change out to everyone in March. [#3487](https://github.com/github/codeql-action/pull/3487)
@@ -36,7 +56,7 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th
- Added an experimental change which allows the `start-proxy` action to resolve the CodeQL CLI version from feature flags instead of using the linked CLI bundle version. We expect to roll this change out to everyone in March. [#3512](https://github.com/github/codeql-action/pull/3512)
- The previously experimental changes from versions 4.32.3, 4.32.4, 3.32.3 and 3.32.4 are now enabled by default. [#3503](https://github.com/github/codeql-action/pull/3503), [#3504](https://github.com/github/codeql-action/pull/3504)
## 4.32.4 - 20 Feb 2026
## 3.32.4 - 20 Feb 2026
- Update default CodeQL bundle version to [2.24.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.2). [#3493](https://github.com/github/codeql-action/pull/3493)
- Added an experimental change which improves how certificates are generated for the authentication proxy that is used by the CodeQL Action in Default Setup when [private package registries are configured](https://docs.github.com/en/code-security/how-tos/secure-at-scale/configure-organization-security/manage-usage-and-access/giving-org-access-private-registries). This is expected to generate more widely compatible certificates and should have no impact on analyses which are working correctly already. We expect to roll this change out to everyone in February. [#3473](https://github.com/github/codeql-action/pull/3473)
@@ -44,88 +64,88 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th
- Added a setting which allows the CodeQL Action to enable network debugging for Java programs. This will help GitHub staff support customers with troubleshooting issues in GitHub-managed CodeQL workflows, such as Default Setup. This setting can only be enabled by GitHub staff. [#3485](https://github.com/github/codeql-action/pull/3485)
- Added a setting which enables GitHub-managed workflows, such as Default Setup, to use a [nightly CodeQL CLI release](https://github.com/dsp-testing/codeql-cli-nightlies) instead of the latest, stable release that is used by default. This will help GitHub staff support customers whose analyses for a given repository or organization require early access to a change in an upcoming CodeQL CLI release. This setting can only be enabled by GitHub staff. [#3484](https://github.com/github/codeql-action/pull/3484)
## 4.32.3 - 13 Feb 2026
## 3.32.3 - 13 Feb 2026
- Added experimental support for testing connections to [private package registries](https://docs.github.com/en/code-security/how-tos/secure-at-scale/configure-organization-security/manage-usage-and-access/giving-org-access-private-registries). This feature is not currently enabled for any analysis. In the future, it may be enabled by default for Default Setup. [#3466](https://github.com/github/codeql-action/pull/3466)
## 4.32.2 - 05 Feb 2026
## 3.32.2 - 05 Feb 2026
- Update default CodeQL bundle version to [2.24.1](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.1). [#3460](https://github.com/github/codeql-action/pull/3460)
## 4.32.1 - 02 Feb 2026
## 3.32.1 - 02 Feb 2026
- A warning is now shown in Default Setup workflow logs if a [private package registry is configured](https://docs.github.com/en/code-security/how-tos/secure-at-scale/configure-organization-security/manage-usage-and-access/giving-org-access-private-registries) using a GitHub Personal Access Token (PAT), but no username is configured. [#3422](https://github.com/github/codeql-action/pull/3422)
- Fixed a bug which caused the CodeQL Action to fail when repository properties cannot successfully be retrieved. [#3421](https://github.com/github/codeql-action/pull/3421)
## 4.32.0 - 26 Jan 2026
## 3.32.0 - 26 Jan 2026
- Update default CodeQL bundle version to [2.24.0](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.24.0). [#3425](https://github.com/github/codeql-action/pull/3425)
## 4.31.11 - 23 Jan 2026
## 3.31.11 - 23 Jan 2026
- When running a Default Setup workflow with [Actions debugging enabled](https://docs.github.com/en/actions/how-tos/monitor-workflows/enable-debug-logging), the CodeQL Action will now use more unique names when uploading logs from the Dependabot authentication proxy as workflow artifacts. This ensures that the artifact names do not clash between multiple jobs in a build matrix. [#3409](https://github.com/github/codeql-action/pull/3409)
- Improved error handling throughout the CodeQL Action. [#3415](https://github.com/github/codeql-action/pull/3415)
- Added experimental support for automatically excluding [generated files](https://docs.github.com/en/repositories/working-with-files/managing-files/customizing-how-changed-files-appear-on-github) from the analysis. This feature is not currently enabled for any analysis. In the future, it may be enabled by default for some GitHub-managed analyses. [#3318](https://github.com/github/codeql-action/pull/3318)
- The changelog extracts that are included with releases of the CodeQL Action are now shorter to avoid duplicated information from appearing in Dependabot PRs. [#3403](https://github.com/github/codeql-action/pull/3403)
## 4.31.10 - 12 Jan 2026
## 3.31.10 - 12 Jan 2026
- Update default CodeQL bundle version to 2.23.9. [#3393](https://github.com/github/codeql-action/pull/3393)
## 4.31.9 - 16 Dec 2025
## 3.31.9 - 16 Dec 2025
No user facing changes.
## 4.31.8 - 11 Dec 2025
## 3.31.8 - 11 Dec 2025
- Update default CodeQL bundle version to 2.23.8. [#3354](https://github.com/github/codeql-action/pull/3354)
## 4.31.7 - 05 Dec 2025
## 3.31.7 - 05 Dec 2025
- Update default CodeQL bundle version to 2.23.7. [#3343](https://github.com/github/codeql-action/pull/3343)
## 4.31.6 - 01 Dec 2025
## 3.31.6 - 01 Dec 2025
No user facing changes.
## 4.31.5 - 24 Nov 2025
## 3.31.5 - 24 Nov 2025
- Update default CodeQL bundle version to 2.23.6. [#3321](https://github.com/github/codeql-action/pull/3321)
## 4.31.4 - 18 Nov 2025
## 3.31.4 - 18 Nov 2025
No user facing changes.
## 4.31.3 - 13 Nov 2025
## 3.31.3 - 13 Nov 2025
- CodeQL Action v3 will be deprecated in December 2026. The Action now logs a warning for customers who are running v3 but could be running v4. For more information, see [Upcoming deprecation of CodeQL Action v3](https://github.blog/changelog/2025-10-28-upcoming-deprecation-of-codeql-action-v3/).
- Update default CodeQL bundle version to 2.23.5. [#3288](https://github.com/github/codeql-action/pull/3288)
## 4.31.2 - 30 Oct 2025
## 3.31.2 - 30 Oct 2025
No user facing changes.
## 4.31.1 - 30 Oct 2025
## 3.31.1 - 30 Oct 2025
- The `add-snippets` input has been removed from the `analyze` action. This input has been deprecated since CodeQL Action 3.26.4 in August 2024 when this removal was announced.
## 4.31.0 - 24 Oct 2025
## 3.31.0 - 24 Oct 2025
- Bump minimum CodeQL bundle version to 2.17.6. [#3223](https://github.com/github/codeql-action/pull/3223)
- When SARIF files are uploaded by the `analyze` or `upload-sarif` actions, the CodeQL Action automatically performs post-processing steps to prepare the data for the upload. Previously, these post-processing steps were only performed before an upload took place. We are now changing this so that the post-processing steps will always be performed, even when the SARIF files are not uploaded. This does not change anything for the `upload-sarif` action. For `analyze`, this may affect Advanced Setup for CodeQL users who specify a value other than `always` for the `upload` input. [#3222](https://github.com/github/codeql-action/pull/3222)
## 4.30.9 - 17 Oct 2025
## 3.30.9 - 17 Oct 2025
- Update default CodeQL bundle version to 2.23.3. [#3205](https://github.com/github/codeql-action/pull/3205)
- Experimental: A new `setup-codeql` action has been added which is similar to `init`, except it only installs the CodeQL CLI and does not initialize a database. Do not use this in production as it is part of an internal experiment and subject to change at any time. [#3204](https://github.com/github/codeql-action/pull/3204)
## 4.30.8 - 10 Oct 2025
## 3.30.8 - 10 Oct 2025
No user facing changes.
## 4.30.7 - 06 Oct 2025
## 3.30.7 - 06 Oct 2025
- [v4+ only] The CodeQL Action now runs on Node.js v24. [#3169](https://github.com/github/codeql-action/pull/3169)
No user facing changes.
## 3.30.6 - 02 Oct 2025
@@ -361,17 +381,13 @@ No user facing changes.
## 3.26.12 - 07 Oct 2024
- _Upcoming breaking change_: Add a deprecation warning for customers using CodeQL version 2.14.5 and earlier. These versions of CodeQL were discontinued on 24 September 2024 alongside GitHub Enterprise Server 3.10, and will be unsupported by CodeQL Action versions 3.27.0 and later and versions 2.27.0 and later. [#2520](https://github.com/github/codeql-action/pull/2520)
- If you are using one of these versions, please update to CodeQL CLI version 2.14.6 or later. For instance, if you have specified a custom version of the CLI using the 'tools' input to the 'init' Action, you can remove this input to use the default version.
- Alternatively, if you want to continue using a version of the CodeQL CLI between 2.13.5 and 2.14.5, you can replace `github/codeql-action/*@v3` by `github/codeql-action/*@v3.26.11` and `github/codeql-action/*@v2` by `github/codeql-action/*@v2.26.11` in your code scanning workflow to ensure you continue using this version of the CodeQL Action.
## 3.26.11 - 03 Oct 2024
- _Upcoming breaking change_: Add support for using `actions/download-artifact@v4` to programmatically consume CodeQL Action debug artifacts.
Starting November 30, 2024, GitHub.com customers will [no longer be able to use `actions/download-artifact@v3`](https://github.blog/changelog/2024-04-16-deprecation-notice-v3-of-the-artifact-actions/). Therefore, to avoid breakage, customers who programmatically download the CodeQL Action debug artifacts should set the `CODEQL_ACTION_ARTIFACT_V4_UPGRADE` environment variable to `true` and bump `actions/download-artifact@v3` to `actions/download-artifact@v4` in their workflows. The CodeQL Action will enable this behavior by default in early November and workflows that have not yet bumped `actions/download-artifact@v3` to `actions/download-artifact@v4` will begin failing then.
This change is currently unavailable for GitHub Enterprise Server customers, as `actions/upload-artifact@v4` and `actions/download-artifact@v4` are not yet compatible with GHES.
- Update default CodeQL bundle version to 2.19.1. [#2519](https://github.com/github/codeql-action/pull/2519)
@@ -494,12 +510,9 @@ No user facing changes.
## 3.25.0 - 15 Apr 2024
- The deprecated feature for extracting dependencies for a Python analysis has been removed. [#2224](https://github.com/github/codeql-action/pull/2224)
As a result, the following inputs and environment variables are now ignored:
- The `setup-python-dependencies` input to the `init` Action
- The `CODEQL_ACTION_DISABLE_PYTHON_DEPENDENCY_INSTALLATION` environment variable
We recommend removing any references to these from your workflows. For more information, see the release notes for CodeQL Action v3.23.0 and v2.23.0.
- Automatically overwrite an existing database if found on the filesystem. [#2229](https://github.com/github/codeql-action/pull/2229)
- Bump the minimum CodeQL bundle version to 2.12.6. [#2232](https://github.com/github/codeql-action/pull/2232)
+7 -5
View File
@@ -69,12 +69,14 @@ Once the mergeback and backport pull request have been merged, the release is co
## Keeping the PR checks up to date (admin access required)
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 [update-required-checks.sh](.github/workflows/script/update-required-checks.sh) script:
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:
- If you run the script without an argument, it will retrieve the set of workflows that ran for the latest commit on `main`. Make sure that your local `main` branch is up to date before running the script.
- You can specify a commit SHA as argument to retrieve the set of workflows for that commit instead. You will likely want to use this if you have a PR that removes or adds PR checks.
- 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.
- 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.
After running, go to the [branch protection rules settings page](https://github.com/github/codeql-action/settings/branches) and validate that the rules for `main`, `v3`, and any other currently supported major versions have been updated.
After running, go to the [branch protection rules settings page](https://github.com/github/codeql-action/settings/branches) and validate that the rules for `main`, `v4`, and any other currently supported major versions have been updated.
Note that any updates to checks on `main` need to be backported to all currently supported major version branches, in order to maintain the same set of names for required checks.
@@ -122,7 +124,7 @@ To deprecate an older version of the Action:
- Implement an Actions warning for customers using the deprecated version.
1. Wait for the deprecation period to pass.
1. Upgrade the Actions warning for customers using the deprecated version to a non-fatal error, and mention that this version of the Action is no longer supported.
1. Make a PR to bump the `OLDEST_SUPPORTED_MAJOR_VERSION` in [releases.ini](.github/releases.ini). Once this PR is merged, the release process will no longer backport changes to the deprecated release version.
1. Make a PR to bump the `OLDEST_SUPPORTED_MAJOR_VERSION` in [config.ts](pr-checks/config.ts). Once this PR is merged, the release process will no longer backport changes to the deprecated release version.
## Resources
+1 -1
View File
@@ -94,6 +94,6 @@ outputs:
sarif-id:
description: The ID of the uploaded SARIF file.
runs:
using: node24
using: node20
main: "../lib/analyze-action.js"
post: "../lib/analyze-action-post.js"
+1 -1
View File
@@ -15,5 +15,5 @@ inputs:
$GITHUB_WORKSPACE as its working directory.
required: false
runs:
using: node24
using: node20
main: '../lib/autobuild-action.js'
+10 -3
View File
@@ -1,4 +1,4 @@
import { copyFile, rm } from "node:fs/promises";
import { copyFile, rm, writeFile } from "node:fs/promises";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
@@ -64,7 +64,11 @@ const onEndPlugin = {
const context = await esbuild.context({
// Include upload-lib.ts as an entry point for use in testing environments.
entryPoints: globSync([`${SRC_DIR}/*-action.ts`, `${SRC_DIR}/*-action-post.ts`, "src/upload-lib.ts"]),
entryPoints: globSync([
`${SRC_DIR}/*-action.ts`,
`${SRC_DIR}/*-action-post.ts`,
"src/upload-lib.ts",
]),
bundle: true,
format: "cjs",
outdir: OUT_DIR,
@@ -74,7 +78,10 @@ const context = await esbuild.context({
define: {
__CODEQL_ACTION_VERSION__: JSON.stringify(pkg.version),
},
metafile: true,
});
await context.rebuild();
const result = await context.rebuild();
await writeFile(join(__dirname, "meta.json"), JSON.stringify(result.metafile));
await context.dispose();
+21 -6
View File
@@ -7,7 +7,11 @@ import noAsyncForeach from "eslint-plugin-no-async-foreach";
import jsdoc from "eslint-plugin-jsdoc";
import tseslint from "typescript-eslint";
import globals from "globals";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const githubFlatConfigs = github.getFlatConfigs();
export default [
@@ -43,7 +47,7 @@ export default [
plugins: {
"import-x": importX,
"no-async-foreach": fixupPluginRules(noAsyncForeach),
"jsdoc": jsdoc,
jsdoc: jsdoc,
},
languageOptions: {
@@ -67,7 +71,13 @@ export default [
typescript: {},
},
"import/ignore": ["sinon", "uuid", "@octokit/plugin-retry", "del", "get-folder-size"],
"import/ignore": [
"sinon",
"uuid",
"@octokit/plugin-retry",
"del",
"get-folder-size",
],
"import-x/resolver-next": [
createTypeScriptImportResolver(),
createNodeResolver({
@@ -143,7 +153,7 @@ export default [
// We don't currently require full JSDoc coverage, so this rule
// should not error on missing @param annotations.
disableMissingParamChecks: true,
}
},
],
},
},
@@ -162,9 +172,9 @@ export default [
"@typescript-eslint/no-unused-vars": [
"error",
{
"args": "all",
"argsIgnorePattern": "^_",
}
args: "all",
argsIgnorePattern: "^_",
},
],
"func-style": "off",
},
@@ -183,6 +193,11 @@ export default [
// The scripts in `pr-checks` are expected to output to the console.
"no-console": "off",
"import/no-extraneous-dependencies": [
"error",
{ packageDir: [__dirname, path.resolve(__dirname, "pr-checks")] },
],
"@typescript-eslint/no-floating-promises": [
"error",
{
+1 -1
View File
@@ -170,6 +170,6 @@ outputs:
codeql-version:
description: The version of the CodeQL binary used for analysis
runs:
using: node24
using: node20
main: '../lib/init-action.js'
post: '../lib/init-action-post.js'
+1602 -1496
View File
File diff suppressed because it is too large. Load diff
+515 -551
View File
File diff suppressed because it is too large. Load diff
+869 -759
View File
File diff suppressed because it is too large. Load diff
+4 -4
View File
@@ -1,6 +1,6 @@
{
"bundleVersion": "codeql-bundle-v2.25.0",
"cliVersion": "2.25.0",
"priorBundleVersion": "codeql-bundle-v2.24.3",
"priorCliVersion": "2.24.3"
"bundleVersion": "codeql-bundle-v2.25.2",
"cliVersion": "2.25.2",
"priorBundleVersion": "codeql-bundle-v2.25.1",
"priorCliVersion": "2.25.1"
}
+607 -492
View File
File diff suppressed because it is too large. Load diff
+924 -677
View File
File diff suppressed because it is too large. Load diff
+854 -748
View File
File diff suppressed because it is too large. Load diff
+1867 -1755
View File
File diff suppressed because it is too large. Load diff
+163 -137
View File
@@ -41057,18 +41057,18 @@ var init_dist_src2 = __esm({
}
});
// node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/version.js
// node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/version.js
var VERSION5;
var init_version2 = __esm({
"node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/version.js"() {
"node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/version.js"() {
VERSION5 = "17.0.0";
}
});
// node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/generated/endpoints.js
// node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/generated/endpoints.js
var Endpoints, endpoints_default;
var init_endpoints = __esm({
"node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/generated/endpoints.js"() {
"node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/generated/endpoints.js"() {
Endpoints = {
actions: {
addCustomLabelsToSelfHostedRunnerForOrg: [
@@ -43362,7 +43362,7 @@ var init_endpoints = __esm({
}
});
// node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/endpoints-to-methods.js
// node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/endpoints-to-methods.js
function endpointsToMethods(octokit) {
const newMethods = {};
for (const scope of endpointMethodsMap.keys()) {
@@ -43413,7 +43413,7 @@ function decorate(octokit, scope, methodName, defaults, decorations) {
}
var endpointMethodsMap, handler;
var init_endpoints_to_methods = __esm({
"node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/endpoints-to-methods.js"() {
"node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/endpoints-to-methods.js"() {
init_endpoints();
endpointMethodsMap = /* @__PURE__ */ new Map();
for (const [scope, endpoints] of Object.entries(endpoints_default)) {
@@ -43491,7 +43491,7 @@ var init_endpoints_to_methods = __esm({
}
});
// node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/index.js
// node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/index.js
var dist_src_exports2 = {};
__export(dist_src_exports2, {
legacyRestEndpointMethods: () => legacyRestEndpointMethods,
@@ -43511,7 +43511,7 @@ function legacyRestEndpointMethods(octokit) {
};
}
var init_dist_src3 = __esm({
"node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/index.js"() {
"node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/index.js"() {
init_version2();
init_endpoints_to_methods();
restEndpointMethods.VERSION = VERSION5;
@@ -43519,7 +43519,7 @@ var init_dist_src3 = __esm({
}
});
// node_modules/@actions/github/node_modules/@octokit/plugin-paginate-rest/dist-bundle/index.js
// node_modules/@octokit/plugin-paginate-rest/dist-bundle/index.js
var dist_bundle_exports = {};
__export(dist_bundle_exports, {
composePaginateRest: () => composePaginateRest,
@@ -43645,7 +43645,7 @@ function paginateRest(octokit) {
}
var VERSION6, composePaginateRest, paginatingEndpoints;
var init_dist_bundle5 = __esm({
"node_modules/@actions/github/node_modules/@octokit/plugin-paginate-rest/dist-bundle/index.js"() {
"node_modules/@octokit/plugin-paginate-rest/dist-bundle/index.js"() {
VERSION6 = "0.0.0-development";
composePaginateRest = Object.assign(paginate, {
iterator
@@ -47304,7 +47304,6 @@ var require_light = __commonJS({
var require_helpers = __commonJS({
"node_modules/jsonschema/lib/helpers.js"(exports2, module2) {
"use strict";
var uri = require("url");
var ValidationError = exports2.ValidationError = function ValidationError2(message, instance, schema2, path4, name, argument) {
if (Array.isArray(path4)) {
this.path = path4;
@@ -47379,7 +47378,7 @@ var require_helpers = __commonJS({
} });
module2.exports.ValidatorResultError = ValidatorResultError;
function ValidatorResultError(result) {
if (Error.captureStackTrace) {
if (typeof Error.captureStackTrace === "function") {
Error.captureStackTrace(this, ValidatorResultError);
}
this.instance = result.instance;
@@ -47394,7 +47393,9 @@ var require_helpers = __commonJS({
this.message = msg;
this.schema = schema2;
Error.call(this, msg);
Error.captureStackTrace(this, SchemaError2);
if (typeof Error.captureStackTrace === "function") {
Error.captureStackTrace(this, SchemaError2);
}
};
SchemaError.prototype = Object.create(
Error.prototype,
@@ -47418,12 +47419,12 @@ var require_helpers = __commonJS({
this.schemas = schemas;
};
SchemaContext.prototype.resolve = function resolve3(target) {
return uri.resolve(this.base, target);
return (() => resolveUrl(this.base, target))();
};
SchemaContext.prototype.makeChild = function makeChild(schema2, propertyName) {
var path4 = propertyName === void 0 ? this.path : this.path.concat([propertyName]);
var id = schema2.$id || schema2.id;
var base = uri.resolve(this.base, id || "");
let base = (() => resolveUrl(this.base, id || ""))();
var ctx = new SchemaContext(schema2, this.options, path4, base, Object.create(this.schemas));
if (id && !ctx.schemas[base]) {
ctx.schemas[base] = schema2;
@@ -47617,6 +47618,14 @@ var require_helpers = __commonJS({
exports2.isSchema = function isSchema(val) {
return typeof val === "object" && val || typeof val === "boolean";
};
var resolveUrl = exports2.resolveUrl = function resolveUrl2(from, to) {
const resolvedUrl = new URL(to, new URL(from, "resolve://"));
if (resolvedUrl.protocol === "resolve:") {
const { pathname, search, hash } = resolvedUrl;
return pathname + search + hash;
}
return resolvedUrl.toString();
};
}
});
@@ -48292,7 +48301,6 @@ var require_attribute = __commonJS({
var require_scan = __commonJS({
"node_modules/jsonschema/lib/scan.js"(exports2, module2) {
"use strict";
var urilib = require("url");
var helpers = require_helpers();
module2.exports.SchemaScanResult = SchemaScanResult;
function SchemaScanResult(found, ref) {
@@ -48303,12 +48311,13 @@ var require_scan = __commonJS({
function scanSchema(baseuri, schema3) {
if (!schema3 || typeof schema3 != "object") return;
if (schema3.$ref) {
var resolvedUri = urilib.resolve(baseuri, schema3.$ref);
let resolvedUri = helpers.resolveUrl(baseuri, schema3.$ref);
ref[resolvedUri] = ref[resolvedUri] ? ref[resolvedUri] + 1 : 0;
return;
}
var id = schema3.$id || schema3.id;
var ourBase = id ? urilib.resolve(baseuri, id) : baseuri;
let resolvedBase = helpers.resolveUrl(baseuri, id);
var ourBase = id ? resolvedBase : baseuri;
if (ourBase) {
if (ourBase.indexOf("#") < 0) ourBase += "#";
if (found[ourBase]) {
@@ -48360,7 +48369,6 @@ var require_scan = __commonJS({
var require_validator = __commonJS({
"node_modules/jsonschema/lib/validator.js"(exports2, module2) {
"use strict";
var urilib = require("url");
var attribute = require_attribute();
var helpers = require_helpers();
var scanSchema = require_scan().scan;
@@ -48425,7 +48433,7 @@ var require_validator = __commonJS({
options = {};
}
var id = schema2.$id || schema2.id;
var base = urilib.resolve(options.base || anonymousBase, id || "");
let base = helpers.resolveUrl(options.base, id || "");
if (!ctx) {
ctx = new SchemaContext(schema2, options, [], base, Object.create(this.schemas));
if (!ctx.schemas[base]) {
@@ -48520,8 +48528,8 @@ var require_validator = __commonJS({
if (ctx.schemas[switchSchema]) {
return { subschema: ctx.schemas[switchSchema], switchSchema };
}
var parsed = urilib.parse(switchSchema);
var fragment = parsed && parsed.hash;
let parsed = new URL(switchSchema, "thismessage::/");
let fragment = parsed.hash;
var document2 = fragment && fragment.length && switchSchema.substr(0, switchSchema.length - fragment.length);
if (!document2 || !ctx.schemas[document2]) {
throw new SchemaError("no such schema <" + switchSchema + ">", schema2);
@@ -49102,7 +49110,7 @@ var require_brace_expansion = __commonJS({
var x = numeric(n[0]);
var y = numeric(n[1]);
var width = Math.max(n[0].length, n[1].length);
var incr = n.length == 3 ? Math.abs(numeric(n[2])) : 1;
var incr = n.length == 3 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
var test = lte;
var reverse = y < x;
if (reverse) {
@@ -62029,7 +62037,7 @@ var require_fxp = __commonJS({
if (a.some((t3) => i2 === t3.toLowerCase())) throw new Error(`[SECURITY] Invalid ${e2}: "${t2}" is a reserved JavaScript keyword that could cause prototype pollution`);
}
function A(t2) {
return "boolean" == typeof t2 ? { enabled: t2, maxEntitySize: 1e4, maxExpansionDepth: 10, maxTotalExpansions: 1e3, maxExpandedLength: 1e5, maxEntityCount: 100, allowedTags: null, tagFilter: null } : "object" == typeof t2 && null !== t2 ? { enabled: false !== t2.enabled, maxEntitySize: t2.maxEntitySize ?? 1e4, maxExpansionDepth: t2.maxExpansionDepth ?? 10, maxTotalExpansions: t2.maxTotalExpansions ?? 1e3, maxExpandedLength: t2.maxExpandedLength ?? 1e5, maxEntityCount: t2.maxEntityCount ?? 100, allowedTags: t2.allowedTags ?? null, tagFilter: t2.tagFilter ?? null } : A(true);
return "boolean" == typeof t2 ? { enabled: t2, maxEntitySize: 1e4, maxExpansionDepth: 10, maxTotalExpansions: 1e3, maxExpandedLength: 1e5, maxEntityCount: 100, allowedTags: null, tagFilter: null } : "object" == typeof t2 && null !== t2 ? { enabled: false !== t2.enabled, maxEntitySize: Math.max(1, t2.maxEntitySize ?? 1e4), maxExpansionDepth: Math.max(1, t2.maxExpansionDepth ?? 10), maxTotalExpansions: Math.max(1, t2.maxTotalExpansions ?? 1e3), maxExpandedLength: Math.max(1, t2.maxExpandedLength ?? 1e5), maxEntityCount: Math.max(1, t2.maxEntityCount ?? 100), allowedTags: t2.allowedTags ?? null, tagFilter: t2.tagFilter ?? null } : A(true);
}
const C = function(t2) {
const e2 = Object.assign({}, P, t2), i2 = [{ value: e2.attributeNamePrefix, name: "attributeNamePrefix" }, { value: e2.attributesGroupName, name: "attributesGroupName" }, { value: e2.textNodeName, name: "textNodeName" }, { value: e2.cdataPropName, name: "cdataPropName" }, { value: e2.commentPropName, name: "commentPropName" }];
@@ -62070,7 +62078,7 @@ var require_fxp = __commonJS({
if (r2 && _2(t2, "!ENTITY", e2)) {
let s3, r3;
if (e2 += 7, [s3, r3, e2] = this.readEntityExp(t2, e2 + 1, this.suppressValidationErr), -1 === r3.indexOf("&")) {
if (false !== this.options.enabled && this.options.maxEntityCount && n2 >= this.options.maxEntityCount) throw new Error(`Entity count (${n2 + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`);
if (false !== this.options.enabled && null != this.options.maxEntityCount && n2 >= this.options.maxEntityCount) throw new Error(`Entity count (${n2 + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`);
const t3 = s3.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
i2[s3] = { regx: RegExp(`&${t3};`, "g"), val: r3 }, n2++;
}
@@ -62094,82 +62102,86 @@ var require_fxp = __commonJS({
return { entities: i2, i: e2 };
}
readEntityExp(t2, e2) {
e2 = j(t2, e2);
let i2 = "";
for (; e2 < t2.length && !/\s/.test(t2[e2]) && '"' !== t2[e2] && "'" !== t2[e2]; ) i2 += t2[e2], e2++;
if (D(i2), e2 = j(t2, e2), !this.suppressValidationErr) {
const i2 = e2 = j(t2, e2);
for (; e2 < t2.length && !/\s/.test(t2[e2]) && '"' !== t2[e2] && "'" !== t2[e2]; ) e2++;
let n2 = t2.substring(i2, e2);
if (D(n2), e2 = j(t2, e2), !this.suppressValidationErr) {
if ("SYSTEM" === t2.substring(e2, e2 + 6).toUpperCase()) throw new Error("External entities are not supported");
if ("%" === t2[e2]) throw new Error("Parameter entities are not supported");
}
let n2 = "";
if ([e2, n2] = this.readIdentifierVal(t2, e2, "entity"), false !== this.options.enabled && this.options.maxEntitySize && n2.length > this.options.maxEntitySize) throw new Error(`Entity "${i2}" size (${n2.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`);
return [i2, n2, --e2];
let s2 = "";
if ([e2, s2] = this.readIdentifierVal(t2, e2, "entity"), false !== this.options.enabled && null != this.options.maxEntitySize && s2.length > this.options.maxEntitySize) throw new Error(`Entity "${n2}" size (${s2.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`);
return [n2, s2, --e2];
}
readNotationExp(t2, e2) {
e2 = j(t2, e2);
let i2 = "";
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) i2 += t2[e2], e2++;
!this.suppressValidationErr && D(i2), e2 = j(t2, e2);
const n2 = t2.substring(e2, e2 + 6).toUpperCase();
if (!this.suppressValidationErr && "SYSTEM" !== n2 && "PUBLIC" !== n2) throw new Error(`Expected SYSTEM or PUBLIC, found "${n2}"`);
e2 += n2.length, e2 = j(t2, e2);
let s2 = null, r2 = null;
if ("PUBLIC" === n2) [e2, s2] = this.readIdentifierVal(t2, e2, "publicIdentifier"), '"' !== t2[e2 = j(t2, e2)] && "'" !== t2[e2] || ([e2, r2] = this.readIdentifierVal(t2, e2, "systemIdentifier"));
else if ("SYSTEM" === n2 && ([e2, r2] = this.readIdentifierVal(t2, e2, "systemIdentifier"), !this.suppressValidationErr && !r2)) throw new Error("Missing mandatory system identifier for SYSTEM notation");
return { notationName: i2, publicIdentifier: s2, systemIdentifier: r2, index: --e2 };
const i2 = e2 = j(t2, e2);
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) e2++;
let n2 = t2.substring(i2, e2);
!this.suppressValidationErr && D(n2), e2 = j(t2, e2);
const s2 = t2.substring(e2, e2 + 6).toUpperCase();
if (!this.suppressValidationErr && "SYSTEM" !== s2 && "PUBLIC" !== s2) throw new Error(`Expected SYSTEM or PUBLIC, found "${s2}"`);
e2 += s2.length, e2 = j(t2, e2);
let r2 = null, o2 = null;
if ("PUBLIC" === s2) [e2, r2] = this.readIdentifierVal(t2, e2, "publicIdentifier"), '"' !== t2[e2 = j(t2, e2)] && "'" !== t2[e2] || ([e2, o2] = this.readIdentifierVal(t2, e2, "systemIdentifier"));
else if ("SYSTEM" === s2 && ([e2, o2] = this.readIdentifierVal(t2, e2, "systemIdentifier"), !this.suppressValidationErr && !o2)) throw new Error("Missing mandatory system identifier for SYSTEM notation");
return { notationName: n2, publicIdentifier: r2, systemIdentifier: o2, index: --e2 };
}
readIdentifierVal(t2, e2, i2) {
let n2 = "";
const s2 = t2[e2];
if ('"' !== s2 && "'" !== s2) throw new Error(`Expected quoted string, found "${s2}"`);
for (e2++; e2 < t2.length && t2[e2] !== s2; ) n2 += t2[e2], e2++;
if (t2[e2] !== s2) throw new Error(`Unterminated ${i2} value`);
const r2 = ++e2;
for (; e2 < t2.length && t2[e2] !== s2; ) e2++;
if (n2 = t2.substring(r2, e2), t2[e2] !== s2) throw new Error(`Unterminated ${i2} value`);
return [++e2, n2];
}
readElementExp(t2, e2) {
e2 = j(t2, e2);
let i2 = "";
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) i2 += t2[e2], e2++;
if (!this.suppressValidationErr && !r(i2)) throw new Error(`Invalid element name: "${i2}"`);
let n2 = "";
const i2 = e2 = j(t2, e2);
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) e2++;
let n2 = t2.substring(i2, e2);
if (!this.suppressValidationErr && !r(n2)) throw new Error(`Invalid element name: "${n2}"`);
let s2 = "";
if ("E" === t2[e2 = j(t2, e2)] && _2(t2, "MPTY", e2)) e2 += 4;
else if ("A" === t2[e2] && _2(t2, "NY", e2)) e2 += 2;
else if ("(" === t2[e2]) {
for (e2++; e2 < t2.length && ")" !== t2[e2]; ) n2 += t2[e2], e2++;
if (")" !== t2[e2]) throw new Error("Unterminated content model");
const i3 = ++e2;
for (; e2 < t2.length && ")" !== t2[e2]; ) e2++;
if (s2 = t2.substring(i3, e2), ")" !== t2[e2]) throw new Error("Unterminated content model");
} else if (!this.suppressValidationErr) throw new Error(`Invalid Element Expression, found "${t2[e2]}"`);
return { elementName: i2, contentModel: n2.trim(), index: e2 };
return { elementName: n2, contentModel: s2.trim(), index: e2 };
}
readAttlistExp(t2, e2) {
let i2 = e2 = j(t2, e2);
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) e2++;
let n2 = t2.substring(i2, e2);
for (D(n2), i2 = e2 = j(t2, e2); e2 < t2.length && !/\s/.test(t2[e2]); ) e2++;
let s2 = t2.substring(i2, e2);
if (!D(s2)) throw new Error(`Invalid attribute name: "${s2}"`);
e2 = j(t2, e2);
let i2 = "";
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) i2 += t2[e2], e2++;
D(i2), e2 = j(t2, e2);
let n2 = "";
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) n2 += t2[e2], e2++;
if (!D(n2)) throw new Error(`Invalid attribute name: "${n2}"`);
e2 = j(t2, e2);
let s2 = "";
let r2 = "";
if ("NOTATION" === t2.substring(e2, e2 + 8).toUpperCase()) {
if (s2 = "NOTATION", "(" !== t2[e2 = j(t2, e2 += 8)]) throw new Error(`Expected '(', found "${t2[e2]}"`);
if (r2 = "NOTATION", "(" !== t2[e2 = j(t2, e2 += 8)]) throw new Error(`Expected '(', found "${t2[e2]}"`);
e2++;
let i3 = [];
for (; e2 < t2.length && ")" !== t2[e2]; ) {
let n3 = "";
for (; e2 < t2.length && "|" !== t2[e2] && ")" !== t2[e2]; ) n3 += t2[e2], e2++;
if (n3 = n3.trim(), !D(n3)) throw new Error(`Invalid notation name: "${n3}"`);
i3.push(n3), "|" === t2[e2] && (e2++, e2 = j(t2, e2));
const n3 = e2;
for (; e2 < t2.length && "|" !== t2[e2] && ")" !== t2[e2]; ) e2++;
let s3 = t2.substring(n3, e2);
if (s3 = s3.trim(), !D(s3)) throw new Error(`Invalid notation name: "${s3}"`);
i3.push(s3), "|" === t2[e2] && (e2++, e2 = j(t2, e2));
}
if (")" !== t2[e2]) throw new Error("Unterminated list of notations");
e2++, s2 += " (" + i3.join("|") + ")";
e2++, r2 += " (" + i3.join("|") + ")";
} else {
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) s2 += t2[e2], e2++;
const i3 = ["CDATA", "ID", "IDREF", "IDREFS", "ENTITY", "ENTITIES", "NMTOKEN", "NMTOKENS"];
if (!this.suppressValidationErr && !i3.includes(s2.toUpperCase())) throw new Error(`Invalid attribute type: "${s2}"`);
const i3 = e2;
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) e2++;
r2 += t2.substring(i3, e2);
const n3 = ["CDATA", "ID", "IDREF", "IDREFS", "ENTITY", "ENTITIES", "NMTOKEN", "NMTOKENS"];
if (!this.suppressValidationErr && !n3.includes(r2.toUpperCase())) throw new Error(`Invalid attribute type: "${r2}"`);
}
e2 = j(t2, e2);
let r2 = "";
return "#REQUIRED" === t2.substring(e2, e2 + 8).toUpperCase() ? (r2 = "#REQUIRED", e2 += 8) : "#IMPLIED" === t2.substring(e2, e2 + 7).toUpperCase() ? (r2 = "#IMPLIED", e2 += 7) : [e2, r2] = this.readIdentifierVal(t2, e2, "ATTLIST"), { elementName: i2, attributeName: n2, attributeType: s2, defaultValue: r2, index: e2 };
let o2 = "";
return "#REQUIRED" === t2.substring(e2, e2 + 8).toUpperCase() ? (o2 = "#REQUIRED", e2 += 8) : "#IMPLIED" === t2.substring(e2, e2 + 7).toUpperCase() ? (o2 = "#IMPLIED", e2 += 7) : [e2, o2] = this.readIdentifierVal(t2, e2, "ATTLIST"), { elementName: n2, attributeName: s2, attributeType: r2, defaultValue: o2, index: e2 };
}
}
const j = (t2, e2) => {
@@ -62184,9 +62196,9 @@ var require_fxp = __commonJS({
if (r(t2)) return t2;
throw new Error(`Invalid entity name ${t2}`);
}
const V = /^[-+]?0x[a-fA-F0-9]+$/, k = /^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/, F = { hex: true, leadingZeros: true, decimalPoint: ".", eNotation: true };
const L = /^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;
class M {
const V = /^[-+]?0x[a-fA-F0-9]+$/, k = /^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/, M = { hex: true, leadingZeros: true, decimalPoint: ".", eNotation: true, infinity: "original" };
const F = /^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;
class L {
constructor(t2 = {}) {
this.separator = t2.separator || ".", this.path = [], this.siblingStacks = [];
}
@@ -62393,7 +62405,7 @@ var require_fxp = __commonJS({
if ("string" == typeof i2 && t3 === i2) return true;
if (i2 instanceof RegExp && i2.test(t3)) return true;
}
} : () => false, this.entityExpansionCount = 0, this.currentExpandedLength = 0, this.matcher = new M(), this.isCurrentNodeStopNode = false, this.options.stopNodes && this.options.stopNodes.length > 0) {
} : () => false, this.entityExpansionCount = 0, this.currentExpandedLength = 0, this.matcher = new L(), this.isCurrentNodeStopNode = false, this.options.stopNodes && this.options.stopNodes.length > 0) {
this.stopNodeExpressions = [];
for (let t3 = 0; t3 < this.options.stopNodes.length; t3++) {
const e3 = this.options.stopNodes[t3];
@@ -62504,7 +62516,7 @@ var require_fxp = __commonJS({
let o2 = s3.tagName;
const a2 = s3.rawTagName;
let h2 = s3.tagExp, l2 = s3.attrExpPresent, p2 = s3.closeIndex;
if ({ tagName: o2, tagExp: h2 } = rt(this.options.transformTagName, o2, h2, this.options), this.options.strictReservedNames && (o2 === this.options.commentPropName || o2 === this.options.cdataPropName)) throw new Error(`Invalid tag name: ${o2}`);
if ({ tagName: o2, tagExp: h2 } = rt(this.options.transformTagName, o2, h2, this.options), this.options.strictReservedNames && (o2 === this.options.commentPropName || o2 === this.options.cdataPropName || o2 === this.options.textNodeName || o2 === this.options.attributesGroupName)) throw new Error(`Invalid tag name: ${o2}`);
i2 && n2 && "!xml" !== i2.tagname && (n2 = this.saveTextToParentTag(n2, i2, this.matcher, false));
const u2 = i2;
u2 && -1 !== this.options.unpairedTags.indexOf(u2.tagname) && (i2 = this.tagsNodeStack.pop(), this.matcher.pop());
@@ -62642,7 +62654,7 @@ var require_fxp = __commonJS({
if (e2 && "string" == typeof t2) {
const e3 = t2.trim();
return "true" === e3 || "false" !== e3 && (function(t3, e4 = {}) {
if (e4 = Object.assign({}, F, e4), !t3 || "string" != typeof t3) return t3;
if (e4 = Object.assign({}, M, e4), !t3 || "string" != typeof t3) return t3;
let i3 = t3.trim();
if (void 0 !== e4.skipLike && e4.skipLike.test(i3)) return t3;
if ("0" === t3) return 0;
@@ -62652,35 +62664,50 @@ var require_fxp = __commonJS({
if (window && window.parseInt) return window.parseInt(t4, 16);
throw new Error("parseInt, Number.parseInt, window.parseInt are not supported");
})(i3);
if (i3.includes("e") || i3.includes("E")) return (function(t4, e5, i4) {
if (!i4.eNotation) return t4;
const n3 = e5.match(L);
if (n3) {
let s2 = n3[1] || "";
const r2 = -1 === n3[3].indexOf("e") ? "E" : "e", o2 = n3[2], a2 = s2 ? t4[o2.length + 1] === r2 : t4[o2.length] === r2;
return o2.length > 1 && a2 ? t4 : 1 !== o2.length || !n3[3].startsWith(`.${r2}`) && n3[3][0] !== r2 ? i4.leadingZeros && !a2 ? (e5 = (n3[1] || "") + n3[3], Number(e5)) : t4 : Number(e5);
}
return t4;
})(t3, i3, e4);
{
const s2 = k.exec(i3);
if (s2) {
const r2 = s2[1] || "", o2 = s2[2];
let a2 = (n2 = s2[3]) && -1 !== n2.indexOf(".") ? ("." === (n2 = n2.replace(/0+$/, "")) ? n2 = "0" : "." === n2[0] ? n2 = "0" + n2 : "." === n2[n2.length - 1] && (n2 = n2.substring(0, n2.length - 1)), n2) : n2;
const h2 = r2 ? "." === t3[o2.length + 1] : "." === t3[o2.length];
if (!e4.leadingZeros && (o2.length > 1 || 1 === o2.length && !h2)) return t3;
{
const n3 = Number(i3), s3 = String(n3);
if (0 === n3) return n3;
if (-1 !== s3.search(/[eE]/)) return e4.eNotation ? n3 : t3;
if (-1 !== i3.indexOf(".")) return "0" === s3 || s3 === a2 || s3 === `${r2}${a2}` ? n3 : t3;
let h3 = o2 ? a2 : i3;
return o2 ? h3 === s3 || r2 + h3 === s3 ? n3 : t3 : h3 === s3 || h3 === r2 + s3 ? n3 : t3;
if (isFinite(i3)) {
if (i3.includes("e") || i3.includes("E")) return (function(t4, e5, i4) {
if (!i4.eNotation) return t4;
const n3 = e5.match(F);
if (n3) {
let s2 = n3[1] || "";
const r2 = -1 === n3[3].indexOf("e") ? "E" : "e", o2 = n3[2], a2 = s2 ? t4[o2.length + 1] === r2 : t4[o2.length] === r2;
return o2.length > 1 && a2 ? t4 : (1 !== o2.length || !n3[3].startsWith(`.${r2}`) && n3[3][0] !== r2) && o2.length > 0 ? i4.leadingZeros && !a2 ? (e5 = (n3[1] || "") + n3[3], Number(e5)) : t4 : Number(e5);
}
return t4;
})(t3, i3, e4);
{
const s2 = k.exec(i3);
if (s2) {
const r2 = s2[1] || "", o2 = s2[2];
let a2 = (n2 = s2[3]) && -1 !== n2.indexOf(".") ? ("." === (n2 = n2.replace(/0+$/, "")) ? n2 = "0" : "." === n2[0] ? n2 = "0" + n2 : "." === n2[n2.length - 1] && (n2 = n2.substring(0, n2.length - 1)), n2) : n2;
const h2 = r2 ? "." === t3[o2.length + 1] : "." === t3[o2.length];
if (!e4.leadingZeros && (o2.length > 1 || 1 === o2.length && !h2)) return t3;
{
const n3 = Number(i3), s3 = String(n3);
if (0 === n3) return n3;
if (-1 !== s3.search(/[eE]/)) return e4.eNotation ? n3 : t3;
if (-1 !== i3.indexOf(".")) return "0" === s3 || s3 === a2 || s3 === `${r2}${a2}` ? n3 : t3;
let h3 = o2 ? a2 : i3;
return o2 ? h3 === s3 || r2 + h3 === s3 ? n3 : t3 : h3 === s3 || h3 === r2 + s3 ? n3 : t3;
}
}
return t3;
}
return t3;
}
var n2;
return (function(t4, e5, i4) {
const n3 = e5 === 1 / 0;
switch (i4.infinity.toLowerCase()) {
case "null":
return null;
case "infinity":
return e5;
case "string":
return n3 ? "Infinity" : "-Infinity";
default:
return t4;
}
})(t3, Number(i3), e4);
})(t2, i2);
}
return void 0 !== t2 ? t2 : "";
@@ -62792,7 +62819,7 @@ var require_fxp = __commonJS({
const i3 = e2.stopNodes[t3];
"string" == typeof i3 ? n2.push(new G(i3)) : i3 instanceof G && n2.push(i3);
}
return mt(t2, e2, i2, new M(), n2);
return mt(t2, e2, i2, new L(), n2);
}
function mt(t2, e2, i2, n2, s2) {
let r2 = "", o2 = false;
@@ -62940,7 +62967,7 @@ var require_fxp = __commonJS({
if (this.options.preserveOrder) return gt(t2, this.options);
{
Array.isArray(t2) && this.options.arrayNodeName && this.options.arrayNodeName.length > 1 && (t2 = { [this.options.arrayNodeName]: t2 });
const e2 = new M();
const e2 = new L();
return this.j2x(t2, 0, e2).val;
}
}, Pt.prototype.j2x = function(t2, e2, i2) {
@@ -93191,7 +93218,7 @@ var require_cacheHttpClient = __commonJS({
exports2.getCacheEntry = getCacheEntry;
exports2.downloadCache = downloadCache;
exports2.reserveCache = reserveCache;
exports2.saveCache = saveCache5;
exports2.saveCache = saveCache4;
var core15 = __importStar2(require_core());
var http_client_1 = require_lib();
var auth_1 = require_auth();
@@ -93368,7 +93395,7 @@ Other caches with similar key:`);
}));
});
}
function saveCache5(cacheId, archivePath, signedUploadURL, options) {
function saveCache4(cacheId, archivePath, signedUploadURL, options) {
return __awaiter2(this, void 0, void 0, function* () {
const uploadOptions = (0, options_1.getUploadOptions)(options);
if (uploadOptions.useAzureSdk) {
@@ -98868,8 +98895,8 @@ var require_cache5 = __commonJS({
Object.defineProperty(exports2, "__esModule", { value: true });
exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0;
exports2.isFeatureAvailable = isFeatureAvailable;
exports2.restoreCache = restoreCache5;
exports2.saveCache = saveCache5;
exports2.restoreCache = restoreCache4;
exports2.saveCache = saveCache4;
var core15 = __importStar2(require_core());
var path4 = __importStar2(require("path"));
var utils = __importStar2(require_cacheUtils());
@@ -98926,7 +98953,7 @@ var require_cache5 = __commonJS({
return !!process.env["ACTIONS_CACHE_URL"];
}
}
function restoreCache5(paths_1, primaryKey_1, restoreKeys_1, options_1) {
function restoreCache4(paths_1, primaryKey_1, restoreKeys_1, options_1) {
return __awaiter2(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) {
const cacheServiceVersion = (0, config_1.getCacheServiceVersion)();
core15.debug(`Cache service version: ${cacheServiceVersion}`);
@@ -99070,7 +99097,7 @@ var require_cache5 = __commonJS({
return void 0;
});
}
function saveCache5(paths_1, key_1, options_1) {
function saveCache4(paths_1, key_1, options_1) {
return __awaiter2(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) {
const cacheServiceVersion = (0, config_1.getCacheServiceVersion)();
core15.debug(`Cache service version: ${cacheServiceVersion}`);
@@ -115616,7 +115643,7 @@ var require_commonjs19 = __commonJS({
var openPattern = /\\{/g;
var closePattern = /\\}/g;
var commaPattern = /\\,/g;
var periodPattern = /\\./g;
var periodPattern = /\\\./g;
exports2.EXPANSION_MAX = 1e5;
function numeric(str2) {
return !isNaN(str2) ? parseInt(str2, 10) : str2.charCodeAt(0);
@@ -115711,7 +115738,7 @@ var require_commonjs19 = __commonJS({
const x = numeric(n[0]);
const y = numeric(n[1]);
const width = Math.max(n[0].length, n[1].length);
let incr = n.length === 3 && n[2] !== void 0 ? Math.abs(numeric(n[2])) : 1;
let incr = n.length === 3 && n[2] !== void 0 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
let test = lte;
const reverse = y < x;
if (reverse) {
@@ -161479,7 +161506,7 @@ function getTemporaryDirectory() {
return value !== void 0 && value !== "" ? value : getRequiredEnvParam("RUNNER_TEMP");
}
function getActionVersion() {
return "4.34.0";
return "3.35.2";
}
var persistedInputsKey = "persisted_inputs";
var restoreInputs = function() {
@@ -161499,8 +161526,11 @@ var githubUtils = __toESM(require_utils5());
var import_light = __toESM(require_light(), 1);
init_dist_src();
var VERSION7 = "0.0.0-development";
function isRequestError(error3) {
return error3.request !== void 0;
}
async function errorRequest(state, octokit, error3, options) {
if (!error3.request || !error3.request.request) {
if (!isRequestError(error3) || !error3?.request.request) {
throw error3;
}
if (error3.status >= 400 && !state.doNotRetry.includes(error3.status)) {
@@ -161513,8 +161543,8 @@ async function errorRequest(state, octokit, error3, options) {
async function wrapRequest(state, octokit, request2, options) {
const limiter = new import_light.default();
limiter.on("failed", function(error3, info7) {
const maxRetries = ~~error3.request.request.retries;
const after = ~~error3.request.request.retryAfter;
const maxRetries = ~~error3.request.request?.retries;
const after = ~~error3.request.request?.retryAfter;
options.request.retryCount = info7.retryCount + 1;
if (maxRetries > info7.retryCount) {
return after * state.retryAfterBaseValue;
@@ -161526,7 +161556,7 @@ async function wrapRequest(state, octokit, request2, options) {
);
}
async function requestWithGraphqlErrorHandling(state, octokit, request2, options) {
const response = await request2(request2, options);
const response = await request2(options);
if (response.data && response.data.errors && response.data.errors.length > 0 && /Something went wrong while executing your query/.test(
response.data.errors[0].message
)) {
@@ -161548,11 +161578,7 @@ function retry(octokit, octokitOptions) {
},
octokitOptions.retry
);
if (state.enabled) {
octokit.hook.error("request", errorRequest.bind(null, state, octokit));
octokit.hook.wrap("request", wrapRequest.bind(null, state, octokit));
}
return {
const retryPlugin = {
retry: {
retryRequest: (error3, retries, retryAfter) => {
error3.request.request = Object.assign({}, error3.request.request, {
@@ -161563,6 +161589,11 @@ function retry(octokit, octokitOptions) {
}
}
};
if (state.enabled) {
octokit.hook.error("request", errorRequest.bind(null, state, retryPlugin));
octokit.hook.wrap("request", wrapRequest.bind(null, state, retryPlugin));
}
return retryPlugin;
}
retry.VERSION = VERSION7;
@@ -161680,9 +161711,6 @@ function getActionsLogger() {
// src/feature-flags.ts
var semver5 = __toESM(require_semver2());
// src/overlay/index.ts
var actionsCache = __toESM(require_cache5());
// src/git-utils.ts
var core8 = __toESM(require_core());
var toolrunner2 = __toESM(require_toolrunner());
@@ -161698,8 +161726,6 @@ var CODEQL_OVERLAY_MINIMUM_VERSION_JAVA = "2.23.8";
var CODEQL_OVERLAY_MINIMUM_VERSION_JAVASCRIPT = "2.23.9";
var CODEQL_OVERLAY_MINIMUM_VERSION_PYTHON = "2.23.9";
var CODEQL_OVERLAY_MINIMUM_VERSION_RUBY = "2.23.9";
var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500;
var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6;
// src/tools-features.ts
var semver4 = __toESM(require_semver2());
@@ -161879,12 +161905,6 @@ var featureConfig = {
envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_SKIP_RESOURCE_CHECKS",
minimumVersion: void 0
},
["python_default_is_to_not_extract_stdlib" /* PythonDefaultIsToNotExtractStdlib */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_DISABLE_PYTHON_STANDARD_LIBRARY_EXTRACTION",
minimumVersion: void 0,
toolsFeature: "pythonDefaultIsToNotExtractStdlib" /* PythonDefaultIsToNotExtractStdlib */
},
["qa_telemetry_enabled" /* QaTelemetryEnabled */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_QA_TELEMETRY",
@@ -161921,10 +161941,10 @@ var featureConfig = {
};
// src/overlay/status.ts
var actionsCache2 = __toESM(require_cache5());
var actionsCache = __toESM(require_cache5());
// src/trap-caching.ts
var actionsCache3 = __toESM(require_cache5());
var actionsCache2 = __toESM(require_cache5());
// src/config-utils.ts
var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB = 2e4;
@@ -162114,6 +162134,12 @@ var cliErrorsConfig = {
)
]
},
["SwiftIncompatibleOs" /* SwiftIncompatibleOs */]: {
cliErrorMessageCandidates: [
new RegExp("\\[incompatible-os\\]"),
new RegExp("Swift analysis is only supported on macOS")
]
},
["UnsupportedBuildMode" /* UnsupportedBuildMode */]: {
cliErrorMessageCandidates: [
new RegExp(
@@ -162148,7 +162174,7 @@ var semver7 = __toESM(require_semver2());
var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024;
// src/dependency-caching.ts
var actionsCache4 = __toESM(require_cache5());
var actionsCache3 = __toESM(require_cache5());
var glob = __toESM(require_glob());
// src/artifact-scanner.ts
+3329 -3227
View File
File diff suppressed because it is too large. Load diff
+348 -239
View File
File diff suppressed because it is too large. Load diff
+163 -137
View File
@@ -41057,18 +41057,18 @@ var init_dist_src2 = __esm({
}
});
// node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/version.js
// node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/version.js
var VERSION5;
var init_version2 = __esm({
"node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/version.js"() {
"node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/version.js"() {
VERSION5 = "17.0.0";
}
});
// node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/generated/endpoints.js
// node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/generated/endpoints.js
var Endpoints, endpoints_default;
var init_endpoints = __esm({
"node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/generated/endpoints.js"() {
"node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/generated/endpoints.js"() {
Endpoints = {
actions: {
addCustomLabelsToSelfHostedRunnerForOrg: [
@@ -43362,7 +43362,7 @@ var init_endpoints = __esm({
}
});
// node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/endpoints-to-methods.js
// node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/endpoints-to-methods.js
function endpointsToMethods(octokit) {
const newMethods = {};
for (const scope of endpointMethodsMap.keys()) {
@@ -43413,7 +43413,7 @@ function decorate(octokit, scope, methodName, defaults, decorations) {
}
var endpointMethodsMap, handler;
var init_endpoints_to_methods = __esm({
"node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/endpoints-to-methods.js"() {
"node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/endpoints-to-methods.js"() {
init_endpoints();
endpointMethodsMap = /* @__PURE__ */ new Map();
for (const [scope, endpoints] of Object.entries(endpoints_default)) {
@@ -43491,7 +43491,7 @@ var init_endpoints_to_methods = __esm({
}
});
// node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/index.js
// node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/index.js
var dist_src_exports2 = {};
__export(dist_src_exports2, {
legacyRestEndpointMethods: () => legacyRestEndpointMethods,
@@ -43511,7 +43511,7 @@ function legacyRestEndpointMethods(octokit) {
};
}
var init_dist_src3 = __esm({
"node_modules/@actions/github/node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/index.js"() {
"node_modules/@octokit/plugin-rest-endpoint-methods/dist-src/index.js"() {
init_version2();
init_endpoints_to_methods();
restEndpointMethods.VERSION = VERSION5;
@@ -43519,7 +43519,7 @@ var init_dist_src3 = __esm({
}
});
// node_modules/@actions/github/node_modules/@octokit/plugin-paginate-rest/dist-bundle/index.js
// node_modules/@octokit/plugin-paginate-rest/dist-bundle/index.js
var dist_bundle_exports = {};
__export(dist_bundle_exports, {
composePaginateRest: () => composePaginateRest,
@@ -43645,7 +43645,7 @@ function paginateRest(octokit) {
}
var VERSION6, composePaginateRest, paginatingEndpoints;
var init_dist_bundle5 = __esm({
"node_modules/@actions/github/node_modules/@octokit/plugin-paginate-rest/dist-bundle/index.js"() {
"node_modules/@octokit/plugin-paginate-rest/dist-bundle/index.js"() {
VERSION6 = "0.0.0-development";
composePaginateRest = Object.assign(paginate, {
iterator
@@ -64242,7 +64242,7 @@ var require_fxp = __commonJS({
if (a.some((t3) => i2 === t3.toLowerCase())) throw new Error(`[SECURITY] Invalid ${e2}: "${t2}" is a reserved JavaScript keyword that could cause prototype pollution`);
}
function A(t2) {
return "boolean" == typeof t2 ? { enabled: t2, maxEntitySize: 1e4, maxExpansionDepth: 10, maxTotalExpansions: 1e3, maxExpandedLength: 1e5, maxEntityCount: 100, allowedTags: null, tagFilter: null } : "object" == typeof t2 && null !== t2 ? { enabled: false !== t2.enabled, maxEntitySize: t2.maxEntitySize ?? 1e4, maxExpansionDepth: t2.maxExpansionDepth ?? 10, maxTotalExpansions: t2.maxTotalExpansions ?? 1e3, maxExpandedLength: t2.maxExpandedLength ?? 1e5, maxEntityCount: t2.maxEntityCount ?? 100, allowedTags: t2.allowedTags ?? null, tagFilter: t2.tagFilter ?? null } : A(true);
return "boolean" == typeof t2 ? { enabled: t2, maxEntitySize: 1e4, maxExpansionDepth: 10, maxTotalExpansions: 1e3, maxExpandedLength: 1e5, maxEntityCount: 100, allowedTags: null, tagFilter: null } : "object" == typeof t2 && null !== t2 ? { enabled: false !== t2.enabled, maxEntitySize: Math.max(1, t2.maxEntitySize ?? 1e4), maxExpansionDepth: Math.max(1, t2.maxExpansionDepth ?? 10), maxTotalExpansions: Math.max(1, t2.maxTotalExpansions ?? 1e3), maxExpandedLength: Math.max(1, t2.maxExpandedLength ?? 1e5), maxEntityCount: Math.max(1, t2.maxEntityCount ?? 100), allowedTags: t2.allowedTags ?? null, tagFilter: t2.tagFilter ?? null } : A(true);
}
const C = function(t2) {
const e2 = Object.assign({}, P, t2), i2 = [{ value: e2.attributeNamePrefix, name: "attributeNamePrefix" }, { value: e2.attributesGroupName, name: "attributesGroupName" }, { value: e2.textNodeName, name: "textNodeName" }, { value: e2.cdataPropName, name: "cdataPropName" }, { value: e2.commentPropName, name: "commentPropName" }];
@@ -64283,7 +64283,7 @@ var require_fxp = __commonJS({
if (r2 && _2(t2, "!ENTITY", e2)) {
let s3, r3;
if (e2 += 7, [s3, r3, e2] = this.readEntityExp(t2, e2 + 1, this.suppressValidationErr), -1 === r3.indexOf("&")) {
if (false !== this.options.enabled && this.options.maxEntityCount && n2 >= this.options.maxEntityCount) throw new Error(`Entity count (${n2 + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`);
if (false !== this.options.enabled && null != this.options.maxEntityCount && n2 >= this.options.maxEntityCount) throw new Error(`Entity count (${n2 + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`);
const t3 = s3.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
i2[s3] = { regx: RegExp(`&${t3};`, "g"), val: r3 }, n2++;
}
@@ -64307,82 +64307,86 @@ var require_fxp = __commonJS({
return { entities: i2, i: e2 };
}
readEntityExp(t2, e2) {
e2 = j(t2, e2);
let i2 = "";
for (; e2 < t2.length && !/\s/.test(t2[e2]) && '"' !== t2[e2] && "'" !== t2[e2]; ) i2 += t2[e2], e2++;
if (D(i2), e2 = j(t2, e2), !this.suppressValidationErr) {
const i2 = e2 = j(t2, e2);
for (; e2 < t2.length && !/\s/.test(t2[e2]) && '"' !== t2[e2] && "'" !== t2[e2]; ) e2++;
let n2 = t2.substring(i2, e2);
if (D(n2), e2 = j(t2, e2), !this.suppressValidationErr) {
if ("SYSTEM" === t2.substring(e2, e2 + 6).toUpperCase()) throw new Error("External entities are not supported");
if ("%" === t2[e2]) throw new Error("Parameter entities are not supported");
}
let n2 = "";
if ([e2, n2] = this.readIdentifierVal(t2, e2, "entity"), false !== this.options.enabled && this.options.maxEntitySize && n2.length > this.options.maxEntitySize) throw new Error(`Entity "${i2}" size (${n2.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`);
return [i2, n2, --e2];
let s2 = "";
if ([e2, s2] = this.readIdentifierVal(t2, e2, "entity"), false !== this.options.enabled && null != this.options.maxEntitySize && s2.length > this.options.maxEntitySize) throw new Error(`Entity "${n2}" size (${s2.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`);
return [n2, s2, --e2];
}
readNotationExp(t2, e2) {
e2 = j(t2, e2);
let i2 = "";
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) i2 += t2[e2], e2++;
!this.suppressValidationErr && D(i2), e2 = j(t2, e2);
const n2 = t2.substring(e2, e2 + 6).toUpperCase();
if (!this.suppressValidationErr && "SYSTEM" !== n2 && "PUBLIC" !== n2) throw new Error(`Expected SYSTEM or PUBLIC, found "${n2}"`);
e2 += n2.length, e2 = j(t2, e2);
let s2 = null, r2 = null;
if ("PUBLIC" === n2) [e2, s2] = this.readIdentifierVal(t2, e2, "publicIdentifier"), '"' !== t2[e2 = j(t2, e2)] && "'" !== t2[e2] || ([e2, r2] = this.readIdentifierVal(t2, e2, "systemIdentifier"));
else if ("SYSTEM" === n2 && ([e2, r2] = this.readIdentifierVal(t2, e2, "systemIdentifier"), !this.suppressValidationErr && !r2)) throw new Error("Missing mandatory system identifier for SYSTEM notation");
return { notationName: i2, publicIdentifier: s2, systemIdentifier: r2, index: --e2 };
const i2 = e2 = j(t2, e2);
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) e2++;
let n2 = t2.substring(i2, e2);
!this.suppressValidationErr && D(n2), e2 = j(t2, e2);
const s2 = t2.substring(e2, e2 + 6).toUpperCase();
if (!this.suppressValidationErr && "SYSTEM" !== s2 && "PUBLIC" !== s2) throw new Error(`Expected SYSTEM or PUBLIC, found "${s2}"`);
e2 += s2.length, e2 = j(t2, e2);
let r2 = null, o2 = null;
if ("PUBLIC" === s2) [e2, r2] = this.readIdentifierVal(t2, e2, "publicIdentifier"), '"' !== t2[e2 = j(t2, e2)] && "'" !== t2[e2] || ([e2, o2] = this.readIdentifierVal(t2, e2, "systemIdentifier"));
else if ("SYSTEM" === s2 && ([e2, o2] = this.readIdentifierVal(t2, e2, "systemIdentifier"), !this.suppressValidationErr && !o2)) throw new Error("Missing mandatory system identifier for SYSTEM notation");
return { notationName: n2, publicIdentifier: r2, systemIdentifier: o2, index: --e2 };
}
readIdentifierVal(t2, e2, i2) {
let n2 = "";
const s2 = t2[e2];
if ('"' !== s2 && "'" !== s2) throw new Error(`Expected quoted string, found "${s2}"`);
for (e2++; e2 < t2.length && t2[e2] !== s2; ) n2 += t2[e2], e2++;
if (t2[e2] !== s2) throw new Error(`Unterminated ${i2} value`);
const r2 = ++e2;
for (; e2 < t2.length && t2[e2] !== s2; ) e2++;
if (n2 = t2.substring(r2, e2), t2[e2] !== s2) throw new Error(`Unterminated ${i2} value`);
return [++e2, n2];
}
readElementExp(t2, e2) {
e2 = j(t2, e2);
let i2 = "";
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) i2 += t2[e2], e2++;
if (!this.suppressValidationErr && !r(i2)) throw new Error(`Invalid element name: "${i2}"`);
let n2 = "";
const i2 = e2 = j(t2, e2);
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) e2++;
let n2 = t2.substring(i2, e2);
if (!this.suppressValidationErr && !r(n2)) throw new Error(`Invalid element name: "${n2}"`);
let s2 = "";
if ("E" === t2[e2 = j(t2, e2)] && _2(t2, "MPTY", e2)) e2 += 4;
else if ("A" === t2[e2] && _2(t2, "NY", e2)) e2 += 2;
else if ("(" === t2[e2]) {
for (e2++; e2 < t2.length && ")" !== t2[e2]; ) n2 += t2[e2], e2++;
if (")" !== t2[e2]) throw new Error("Unterminated content model");
const i3 = ++e2;
for (; e2 < t2.length && ")" !== t2[e2]; ) e2++;
if (s2 = t2.substring(i3, e2), ")" !== t2[e2]) throw new Error("Unterminated content model");
} else if (!this.suppressValidationErr) throw new Error(`Invalid Element Expression, found "${t2[e2]}"`);
return { elementName: i2, contentModel: n2.trim(), index: e2 };
return { elementName: n2, contentModel: s2.trim(), index: e2 };
}
readAttlistExp(t2, e2) {
let i2 = e2 = j(t2, e2);
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) e2++;
let n2 = t2.substring(i2, e2);
for (D(n2), i2 = e2 = j(t2, e2); e2 < t2.length && !/\s/.test(t2[e2]); ) e2++;
let s2 = t2.substring(i2, e2);
if (!D(s2)) throw new Error(`Invalid attribute name: "${s2}"`);
e2 = j(t2, e2);
let i2 = "";
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) i2 += t2[e2], e2++;
D(i2), e2 = j(t2, e2);
let n2 = "";
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) n2 += t2[e2], e2++;
if (!D(n2)) throw new Error(`Invalid attribute name: "${n2}"`);
e2 = j(t2, e2);
let s2 = "";
let r2 = "";
if ("NOTATION" === t2.substring(e2, e2 + 8).toUpperCase()) {
if (s2 = "NOTATION", "(" !== t2[e2 = j(t2, e2 += 8)]) throw new Error(`Expected '(', found "${t2[e2]}"`);
if (r2 = "NOTATION", "(" !== t2[e2 = j(t2, e2 += 8)]) throw new Error(`Expected '(', found "${t2[e2]}"`);
e2++;
let i3 = [];
for (; e2 < t2.length && ")" !== t2[e2]; ) {
let n3 = "";
for (; e2 < t2.length && "|" !== t2[e2] && ")" !== t2[e2]; ) n3 += t2[e2], e2++;
if (n3 = n3.trim(), !D(n3)) throw new Error(`Invalid notation name: "${n3}"`);
i3.push(n3), "|" === t2[e2] && (e2++, e2 = j(t2, e2));
const n3 = e2;
for (; e2 < t2.length && "|" !== t2[e2] && ")" !== t2[e2]; ) e2++;
let s3 = t2.substring(n3, e2);
if (s3 = s3.trim(), !D(s3)) throw new Error(`Invalid notation name: "${s3}"`);
i3.push(s3), "|" === t2[e2] && (e2++, e2 = j(t2, e2));
}
if (")" !== t2[e2]) throw new Error("Unterminated list of notations");
e2++, s2 += " (" + i3.join("|") + ")";
e2++, r2 += " (" + i3.join("|") + ")";
} else {
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) s2 += t2[e2], e2++;
const i3 = ["CDATA", "ID", "IDREF", "IDREFS", "ENTITY", "ENTITIES", "NMTOKEN", "NMTOKENS"];
if (!this.suppressValidationErr && !i3.includes(s2.toUpperCase())) throw new Error(`Invalid attribute type: "${s2}"`);
const i3 = e2;
for (; e2 < t2.length && !/\s/.test(t2[e2]); ) e2++;
r2 += t2.substring(i3, e2);
const n3 = ["CDATA", "ID", "IDREF", "IDREFS", "ENTITY", "ENTITIES", "NMTOKEN", "NMTOKENS"];
if (!this.suppressValidationErr && !n3.includes(r2.toUpperCase())) throw new Error(`Invalid attribute type: "${r2}"`);
}
e2 = j(t2, e2);
let r2 = "";
return "#REQUIRED" === t2.substring(e2, e2 + 8).toUpperCase() ? (r2 = "#REQUIRED", e2 += 8) : "#IMPLIED" === t2.substring(e2, e2 + 7).toUpperCase() ? (r2 = "#IMPLIED", e2 += 7) : [e2, r2] = this.readIdentifierVal(t2, e2, "ATTLIST"), { elementName: i2, attributeName: n2, attributeType: s2, defaultValue: r2, index: e2 };
let o2 = "";
return "#REQUIRED" === t2.substring(e2, e2 + 8).toUpperCase() ? (o2 = "#REQUIRED", e2 += 8) : "#IMPLIED" === t2.substring(e2, e2 + 7).toUpperCase() ? (o2 = "#IMPLIED", e2 += 7) : [e2, o2] = this.readIdentifierVal(t2, e2, "ATTLIST"), { elementName: n2, attributeName: s2, attributeType: r2, defaultValue: o2, index: e2 };
}
}
const j = (t2, e2) => {
@@ -64397,9 +64401,9 @@ var require_fxp = __commonJS({
if (r(t2)) return t2;
throw new Error(`Invalid entity name ${t2}`);
}
const V = /^[-+]?0x[a-fA-F0-9]+$/, k = /^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/, F = { hex: true, leadingZeros: true, decimalPoint: ".", eNotation: true };
const L = /^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;
class M {
const V = /^[-+]?0x[a-fA-F0-9]+$/, k = /^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/, M = { hex: true, leadingZeros: true, decimalPoint: ".", eNotation: true, infinity: "original" };
const F = /^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;
class L {
constructor(t2 = {}) {
this.separator = t2.separator || ".", this.path = [], this.siblingStacks = [];
}
@@ -64606,7 +64610,7 @@ var require_fxp = __commonJS({
if ("string" == typeof i2 && t3 === i2) return true;
if (i2 instanceof RegExp && i2.test(t3)) return true;
}
} : () => false, this.entityExpansionCount = 0, this.currentExpandedLength = 0, this.matcher = new M(), this.isCurrentNodeStopNode = false, this.options.stopNodes && this.options.stopNodes.length > 0) {
} : () => false, this.entityExpansionCount = 0, this.currentExpandedLength = 0, this.matcher = new L(), this.isCurrentNodeStopNode = false, this.options.stopNodes && this.options.stopNodes.length > 0) {
this.stopNodeExpressions = [];
for (let t3 = 0; t3 < this.options.stopNodes.length; t3++) {
const e3 = this.options.stopNodes[t3];
@@ -64717,7 +64721,7 @@ var require_fxp = __commonJS({
let o2 = s3.tagName;
const a2 = s3.rawTagName;
let h2 = s3.tagExp, l2 = s3.attrExpPresent, p2 = s3.closeIndex;
if ({ tagName: o2, tagExp: h2 } = rt(this.options.transformTagName, o2, h2, this.options), this.options.strictReservedNames && (o2 === this.options.commentPropName || o2 === this.options.cdataPropName)) throw new Error(`Invalid tag name: ${o2}`);
if ({ tagName: o2, tagExp: h2 } = rt(this.options.transformTagName, o2, h2, this.options), this.options.strictReservedNames && (o2 === this.options.commentPropName || o2 === this.options.cdataPropName || o2 === this.options.textNodeName || o2 === this.options.attributesGroupName)) throw new Error(`Invalid tag name: ${o2}`);
i2 && n2 && "!xml" !== i2.tagname && (n2 = this.saveTextToParentTag(n2, i2, this.matcher, false));
const u2 = i2;
u2 && -1 !== this.options.unpairedTags.indexOf(u2.tagname) && (i2 = this.tagsNodeStack.pop(), this.matcher.pop());
@@ -64855,7 +64859,7 @@ var require_fxp = __commonJS({
if (e2 && "string" == typeof t2) {
const e3 = t2.trim();
return "true" === e3 || "false" !== e3 && (function(t3, e4 = {}) {
if (e4 = Object.assign({}, F, e4), !t3 || "string" != typeof t3) return t3;
if (e4 = Object.assign({}, M, e4), !t3 || "string" != typeof t3) return t3;
let i3 = t3.trim();
if (void 0 !== e4.skipLike && e4.skipLike.test(i3)) return t3;
if ("0" === t3) return 0;
@@ -64865,35 +64869,50 @@ var require_fxp = __commonJS({
if (window && window.parseInt) return window.parseInt(t4, 16);
throw new Error("parseInt, Number.parseInt, window.parseInt are not supported");
})(i3);
if (i3.includes("e") || i3.includes("E")) return (function(t4, e5, i4) {
if (!i4.eNotation) return t4;
const n3 = e5.match(L);
if (n3) {
let s2 = n3[1] || "";
const r2 = -1 === n3[3].indexOf("e") ? "E" : "e", o2 = n3[2], a2 = s2 ? t4[o2.length + 1] === r2 : t4[o2.length] === r2;
return o2.length > 1 && a2 ? t4 : 1 !== o2.length || !n3[3].startsWith(`.${r2}`) && n3[3][0] !== r2 ? i4.leadingZeros && !a2 ? (e5 = (n3[1] || "") + n3[3], Number(e5)) : t4 : Number(e5);
}
return t4;
})(t3, i3, e4);
{
const s2 = k.exec(i3);
if (s2) {
const r2 = s2[1] || "", o2 = s2[2];
let a2 = (n2 = s2[3]) && -1 !== n2.indexOf(".") ? ("." === (n2 = n2.replace(/0+$/, "")) ? n2 = "0" : "." === n2[0] ? n2 = "0" + n2 : "." === n2[n2.length - 1] && (n2 = n2.substring(0, n2.length - 1)), n2) : n2;
const h2 = r2 ? "." === t3[o2.length + 1] : "." === t3[o2.length];
if (!e4.leadingZeros && (o2.length > 1 || 1 === o2.length && !h2)) return t3;
{
const n3 = Number(i3), s3 = String(n3);
if (0 === n3) return n3;
if (-1 !== s3.search(/[eE]/)) return e4.eNotation ? n3 : t3;
if (-1 !== i3.indexOf(".")) return "0" === s3 || s3 === a2 || s3 === `${r2}${a2}` ? n3 : t3;
let h3 = o2 ? a2 : i3;
return o2 ? h3 === s3 || r2 + h3 === s3 ? n3 : t3 : h3 === s3 || h3 === r2 + s3 ? n3 : t3;
if (isFinite(i3)) {
if (i3.includes("e") || i3.includes("E")) return (function(t4, e5, i4) {
if (!i4.eNotation) return t4;
const n3 = e5.match(F);
if (n3) {
let s2 = n3[1] || "";
const r2 = -1 === n3[3].indexOf("e") ? "E" : "e", o2 = n3[2], a2 = s2 ? t4[o2.length + 1] === r2 : t4[o2.length] === r2;
return o2.length > 1 && a2 ? t4 : (1 !== o2.length || !n3[3].startsWith(`.${r2}`) && n3[3][0] !== r2) && o2.length > 0 ? i4.leadingZeros && !a2 ? (e5 = (n3[1] || "") + n3[3], Number(e5)) : t4 : Number(e5);
}
return t4;
})(t3, i3, e4);
{
const s2 = k.exec(i3);
if (s2) {
const r2 = s2[1] || "", o2 = s2[2];
let a2 = (n2 = s2[3]) && -1 !== n2.indexOf(".") ? ("." === (n2 = n2.replace(/0+$/, "")) ? n2 = "0" : "." === n2[0] ? n2 = "0" + n2 : "." === n2[n2.length - 1] && (n2 = n2.substring(0, n2.length - 1)), n2) : n2;
const h2 = r2 ? "." === t3[o2.length + 1] : "." === t3[o2.length];
if (!e4.leadingZeros && (o2.length > 1 || 1 === o2.length && !h2)) return t3;
{
const n3 = Number(i3), s3 = String(n3);
if (0 === n3) return n3;
if (-1 !== s3.search(/[eE]/)) return e4.eNotation ? n3 : t3;
if (-1 !== i3.indexOf(".")) return "0" === s3 || s3 === a2 || s3 === `${r2}${a2}` ? n3 : t3;
let h3 = o2 ? a2 : i3;
return o2 ? h3 === s3 || r2 + h3 === s3 ? n3 : t3 : h3 === s3 || h3 === r2 + s3 ? n3 : t3;
}
}
return t3;
}
return t3;
}
var n2;
return (function(t4, e5, i4) {
const n3 = e5 === 1 / 0;
switch (i4.infinity.toLowerCase()) {
case "null":
return null;
case "infinity":
return e5;
case "string":
return n3 ? "Infinity" : "-Infinity";
default:
return t4;
}
})(t3, Number(i3), e4);
})(t2, i2);
}
return void 0 !== t2 ? t2 : "";
@@ -65005,7 +65024,7 @@ var require_fxp = __commonJS({
const i3 = e2.stopNodes[t3];
"string" == typeof i3 ? n2.push(new G(i3)) : i3 instanceof G && n2.push(i3);
}
return mt(t2, e2, i2, new M(), n2);
return mt(t2, e2, i2, new L(), n2);
}
function mt(t2, e2, i2, n2, s2) {
let r2 = "", o2 = false;
@@ -65153,7 +65172,7 @@ var require_fxp = __commonJS({
if (this.options.preserveOrder) return gt(t2, this.options);
{
Array.isArray(t2) && this.options.arrayNodeName && this.options.arrayNodeName.length > 1 && (t2 = { [this.options.arrayNodeName]: t2 });
const e2 = new M();
const e2 = new L();
return this.j2x(t2, 0, e2).val;
}
}, Pt.prototype.j2x = function(t2, e2, i2) {
@@ -107800,7 +107819,7 @@ var require_commonjs19 = __commonJS({
var openPattern = /\\{/g;
var closePattern = /\\}/g;
var commaPattern = /\\,/g;
var periodPattern = /\\./g;
var periodPattern = /\\\./g;
exports2.EXPANSION_MAX = 1e5;
function numeric(str2) {
return !isNaN(str2) ? parseInt(str2, 10) : str2.charCodeAt(0);
@@ -107895,7 +107914,7 @@ var require_commonjs19 = __commonJS({
const x = numeric(n[0]);
const y = numeric(n[1]);
const width = Math.max(n[0].length, n[1].length);
let incr = n.length === 3 && n[2] !== void 0 ? Math.abs(numeric(n[2])) : 1;
let incr = n.length === 3 && n[2] !== void 0 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
let test = lte;
const reverse = y < x;
if (reverse) {
@@ -149531,7 +149550,6 @@ var require_artifact_client2 = __commonJS({
var require_helpers3 = __commonJS({
"node_modules/jsonschema/lib/helpers.js"(exports2, module2) {
"use strict";
var uri = require("url");
var ValidationError = exports2.ValidationError = function ValidationError2(message, instance, schema2, path3, name, argument) {
if (Array.isArray(path3)) {
this.path = path3;
@@ -149606,7 +149624,7 @@ var require_helpers3 = __commonJS({
} });
module2.exports.ValidatorResultError = ValidatorResultError;
function ValidatorResultError(result) {
if (Error.captureStackTrace) {
if (typeof Error.captureStackTrace === "function") {
Error.captureStackTrace(this, ValidatorResultError);
}
this.instance = result.instance;
@@ -149621,7 +149639,9 @@ var require_helpers3 = __commonJS({
this.message = msg;
this.schema = schema2;
Error.call(this, msg);
Error.captureStackTrace(this, SchemaError2);
if (typeof Error.captureStackTrace === "function") {
Error.captureStackTrace(this, SchemaError2);
}
};
SchemaError.prototype = Object.create(
Error.prototype,
@@ -149645,12 +149665,12 @@ var require_helpers3 = __commonJS({
this.schemas = schemas;
};
SchemaContext.prototype.resolve = function resolve2(target) {
return uri.resolve(this.base, target);
return (() => resolveUrl(this.base, target))();
};
SchemaContext.prototype.makeChild = function makeChild(schema2, propertyName) {
var path3 = propertyName === void 0 ? this.path : this.path.concat([propertyName]);
var id = schema2.$id || schema2.id;
var base = uri.resolve(this.base, id || "");
let base = (() => resolveUrl(this.base, id || ""))();
var ctx = new SchemaContext(schema2, this.options, path3, base, Object.create(this.schemas));
if (id && !ctx.schemas[base]) {
ctx.schemas[base] = schema2;
@@ -149844,6 +149864,14 @@ var require_helpers3 = __commonJS({
exports2.isSchema = function isSchema(val) {
return typeof val === "object" && val || typeof val === "boolean";
};
var resolveUrl = exports2.resolveUrl = function resolveUrl2(from, to) {
const resolvedUrl = new URL(to, new URL(from, "resolve://"));
if (resolvedUrl.protocol === "resolve:") {
const { pathname, search, hash } = resolvedUrl;
return pathname + search + hash;
}
return resolvedUrl.toString();
};
}
});
@@ -150519,7 +150547,6 @@ var require_attribute = __commonJS({
var require_scan = __commonJS({
"node_modules/jsonschema/lib/scan.js"(exports2, module2) {
"use strict";
var urilib = require("url");
var helpers = require_helpers3();
module2.exports.SchemaScanResult = SchemaScanResult;
function SchemaScanResult(found, ref) {
@@ -150530,12 +150557,13 @@ var require_scan = __commonJS({
function scanSchema(baseuri, schema3) {
if (!schema3 || typeof schema3 != "object") return;
if (schema3.$ref) {
var resolvedUri = urilib.resolve(baseuri, schema3.$ref);
let resolvedUri = helpers.resolveUrl(baseuri, schema3.$ref);
ref[resolvedUri] = ref[resolvedUri] ? ref[resolvedUri] + 1 : 0;
return;
}
var id = schema3.$id || schema3.id;
var ourBase = id ? urilib.resolve(baseuri, id) : baseuri;
let resolvedBase = helpers.resolveUrl(baseuri, id);
var ourBase = id ? resolvedBase : baseuri;
if (ourBase) {
if (ourBase.indexOf("#") < 0) ourBase += "#";
if (found[ourBase]) {
@@ -150587,7 +150615,6 @@ var require_scan = __commonJS({
var require_validator = __commonJS({
"node_modules/jsonschema/lib/validator.js"(exports2, module2) {
"use strict";
var urilib = require("url");
var attribute = require_attribute();
var helpers = require_helpers3();
var scanSchema = require_scan().scan;
@@ -150652,7 +150679,7 @@ var require_validator = __commonJS({
options = {};
}
var id = schema2.$id || schema2.id;
var base = urilib.resolve(options.base || anonymousBase, id || "");
let base = helpers.resolveUrl(options.base, id || "");
if (!ctx) {
ctx = new SchemaContext(schema2, options, [], base, Object.create(this.schemas));
if (!ctx.schemas[base]) {
@@ -150747,8 +150774,8 @@ var require_validator = __commonJS({
if (ctx.schemas[switchSchema]) {
return { subschema: ctx.schemas[switchSchema], switchSchema };
}
var parsed = urilib.parse(switchSchema);
var fragment = parsed && parsed.hash;
let parsed = new URL(switchSchema, "thismessage::/");
let fragment = parsed.hash;
var document2 = fragment && fragment.length && switchSchema.substr(0, switchSchema.length - fragment.length);
if (!document2 || !ctx.schemas[document2]) {
throw new SchemaError("no such schema <" + switchSchema + ">", schema2);
@@ -151274,7 +151301,7 @@ var require_brace_expansion2 = __commonJS({
var x = numeric(n[0]);
var y = numeric(n[1]);
var width = Math.max(n[0].length, n[1].length);
var incr = n.length == 3 ? Math.abs(numeric(n[2])) : 1;
var incr = n.length == 3 ? Math.max(Math.abs(numeric(n[2])), 1) : 1;
var test = lte;
var reverse = y < x;
if (reverse) {
@@ -155525,7 +155552,7 @@ var require_cacheHttpClient = __commonJS({
exports2.getCacheEntry = getCacheEntry;
exports2.downloadCache = downloadCache;
exports2.reserveCache = reserveCache;
exports2.saveCache = saveCache5;
exports2.saveCache = saveCache4;
var core15 = __importStar2(require_core());
var http_client_1 = require_lib();
var auth_1 = require_auth();
@@ -155702,7 +155729,7 @@ Other caches with similar key:`);
}));
});
}
function saveCache5(cacheId, archivePath, signedUploadURL, options) {
function saveCache4(cacheId, archivePath, signedUploadURL, options) {
return __awaiter2(this, void 0, void 0, function* () {
const uploadOptions = (0, options_1.getUploadOptions)(options);
if (uploadOptions.useAzureSdk) {
@@ -156976,8 +157003,8 @@ var require_cache6 = __commonJS({
Object.defineProperty(exports2, "__esModule", { value: true });
exports2.FinalizeCacheError = exports2.ReserveCacheError = exports2.ValidationError = void 0;
exports2.isFeatureAvailable = isFeatureAvailable;
exports2.restoreCache = restoreCache5;
exports2.saveCache = saveCache5;
exports2.restoreCache = restoreCache4;
exports2.saveCache = saveCache4;
var core15 = __importStar2(require_core());
var path3 = __importStar2(require("path"));
var utils = __importStar2(require_cacheUtils());
@@ -157034,7 +157061,7 @@ var require_cache6 = __commonJS({
return !!process.env["ACTIONS_CACHE_URL"];
}
}
function restoreCache5(paths_1, primaryKey_1, restoreKeys_1, options_1) {
function restoreCache4(paths_1, primaryKey_1, restoreKeys_1, options_1) {
return __awaiter2(this, arguments, void 0, function* (paths, primaryKey, restoreKeys, options, enableCrossOsArchive = false) {
const cacheServiceVersion = (0, config_1.getCacheServiceVersion)();
core15.debug(`Cache service version: ${cacheServiceVersion}`);
@@ -157178,7 +157205,7 @@ var require_cache6 = __commonJS({
return void 0;
});
}
function saveCache5(paths_1, key_1, options_1) {
function saveCache4(paths_1, key_1, options_1) {
return __awaiter2(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) {
const cacheServiceVersion = (0, config_1.getCacheServiceVersion)();
core15.debug(`Cache service version: ${cacheServiceVersion}`);
@@ -161479,7 +161506,7 @@ function getTemporaryDirectory() {
return value !== void 0 && value !== "" ? value : getRequiredEnvParam("RUNNER_TEMP");
}
function getActionVersion() {
return "4.34.0";
return "3.35.2";
}
var persistedInputsKey = "persisted_inputs";
var restoreInputs = function() {
@@ -161499,8 +161526,11 @@ var githubUtils = __toESM(require_utils5());
var import_light = __toESM(require_light(), 1);
init_dist_src();
var VERSION7 = "0.0.0-development";
function isRequestError(error3) {
return error3.request !== void 0;
}
async function errorRequest(state, octokit, error3, options) {
if (!error3.request || !error3.request.request) {
if (!isRequestError(error3) || !error3?.request.request) {
throw error3;
}
if (error3.status >= 400 && !state.doNotRetry.includes(error3.status)) {
@@ -161513,8 +161543,8 @@ async function errorRequest(state, octokit, error3, options) {
async function wrapRequest(state, octokit, request2, options) {
const limiter = new import_light.default();
limiter.on("failed", function(error3, info7) {
const maxRetries = ~~error3.request.request.retries;
const after = ~~error3.request.request.retryAfter;
const maxRetries = ~~error3.request.request?.retries;
const after = ~~error3.request.request?.retryAfter;
options.request.retryCount = info7.retryCount + 1;
if (maxRetries > info7.retryCount) {
return after * state.retryAfterBaseValue;
@@ -161526,7 +161556,7 @@ async function wrapRequest(state, octokit, request2, options) {
);
}
async function requestWithGraphqlErrorHandling(state, octokit, request2, options) {
const response = await request2(request2, options);
const response = await request2(options);
if (response.data && response.data.errors && response.data.errors.length > 0 && /Something went wrong while executing your query/.test(
response.data.errors[0].message
)) {
@@ -161548,11 +161578,7 @@ function retry(octokit, octokitOptions) {
},
octokitOptions.retry
);
if (state.enabled) {
octokit.hook.error("request", errorRequest.bind(null, state, octokit));
octokit.hook.wrap("request", wrapRequest.bind(null, state, octokit));
}
return {
const retryPlugin = {
retry: {
retryRequest: (error3, retries, retryAfter) => {
error3.request.request = Object.assign({}, error3.request.request, {
@@ -161563,6 +161589,11 @@ function retry(octokit, octokitOptions) {
}
}
};
if (state.enabled) {
octokit.hook.error("request", errorRequest.bind(null, state, retryPlugin));
octokit.hook.wrap("request", wrapRequest.bind(null, state, retryPlugin));
}
return retryPlugin;
}
retry.VERSION = VERSION7;
@@ -161772,6 +161803,12 @@ var cliErrorsConfig = {
)
]
},
["SwiftIncompatibleOs" /* SwiftIncompatibleOs */]: {
cliErrorMessageCandidates: [
new RegExp("\\[incompatible-os\\]"),
new RegExp("Swift analysis is only supported on macOS")
]
},
["UnsupportedBuildMode" /* UnsupportedBuildMode */]: {
cliErrorMessageCandidates: [
new RegExp(
@@ -161840,9 +161877,6 @@ function withGroup(groupName, f) {
// src/feature-flags.ts
var semver5 = __toESM(require_semver2());
// src/overlay/index.ts
var actionsCache = __toESM(require_cache6());
// src/git-utils.ts
var core8 = __toESM(require_core());
var toolrunner2 = __toESM(require_toolrunner());
@@ -161858,8 +161892,6 @@ var CODEQL_OVERLAY_MINIMUM_VERSION_JAVA = "2.23.8";
var CODEQL_OVERLAY_MINIMUM_VERSION_JAVASCRIPT = "2.23.9";
var CODEQL_OVERLAY_MINIMUM_VERSION_PYTHON = "2.23.9";
var CODEQL_OVERLAY_MINIMUM_VERSION_RUBY = "2.23.9";
var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500;
var OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES = OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1e6;
// src/tools-features.ts
var semver4 = __toESM(require_semver2());
@@ -162043,12 +162075,6 @@ var featureConfig = {
envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_SKIP_RESOURCE_CHECKS",
minimumVersion: void 0
},
["python_default_is_to_not_extract_stdlib" /* PythonDefaultIsToNotExtractStdlib */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_DISABLE_PYTHON_STANDARD_LIBRARY_EXTRACTION",
minimumVersion: void 0,
toolsFeature: "pythonDefaultIsToNotExtractStdlib" /* PythonDefaultIsToNotExtractStdlib */
},
["qa_telemetry_enabled" /* QaTelemetryEnabled */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_QA_TELEMETRY",
@@ -162085,10 +162111,10 @@ var featureConfig = {
};
// src/overlay/status.ts
var actionsCache2 = __toESM(require_cache6());
var actionsCache = __toESM(require_cache6());
// src/trap-caching.ts
var actionsCache3 = __toESM(require_cache6());
var actionsCache2 = __toESM(require_cache6());
// src/config-utils.ts
var OVERLAY_MINIMUM_AVAILABLE_DISK_SPACE_MB = 2e4;
@@ -162135,7 +162161,7 @@ var semver7 = __toESM(require_semver2());
var STREAMING_HIGH_WATERMARK_BYTES = 4 * 1024 * 1024;
// src/dependency-caching.ts
var actionsCache4 = __toESM(require_cache6());
var actionsCache3 = __toESM(require_cache6());
var glob = __toESM(require_glob2());
// src/artifact-scanner.ts
+1678 -1565
View File
File diff suppressed because it is too large. Load diff
+834 -327
View File
File diff suppressed because it is too large. Load diff
+14 -15
View File
@@ -1,11 +1,11 @@
{
"name": "codeql",
"version": "4.34.0",
"version": "3.35.2",
"private": true,
"description": "CodeQL action",
"scripts": {
"_build_comment": "echo 'Run the full build so we typecheck the project and can reuse the transpiled files in npm test'",
"build": "./scripts/check-node-modules.sh && npm run transpile && node build.mjs",
"build": "./scripts/check-node-modules.sh && npm run transpile && node build.mjs && npx tsx ./pr-checks/bundle-metadata.ts",
"lint": "eslint --report-unused-disable-directives --max-warnings=0 .",
"lint-ci": "SARIF_ESLINT_IGNORE_SUPPRESSED=true eslint --report-unused-disable-directives --max-warnings=0 . --format @microsoft/eslint-formatter-sarif --output-file=eslint.sarif",
"lint-fix": "eslint --report-unused-disable-directives --max-warnings=0 . --fix",
@@ -29,23 +29,22 @@
"@actions/http-client": "^3.0.0",
"@actions/io": "^2.0.0",
"@actions/tool-cache": "^3.0.1",
"@octokit/plugin-retry": "^8.0.0",
"@schemastore/package": "0.0.10",
"@octokit/plugin-retry": "^8.1.0",
"archiver": "^7.0.1",
"fast-deep-equal": "^3.1.3",
"follow-redirects": "^1.15.11",
"get-folder-size": "^5.0.0",
"https-proxy-agent": "^7.0.6",
"js-yaml": "^4.1.1",
"jsonschema": "1.4.1",
"jsonschema": "1.5.0",
"long": "^5.3.2",
"node-forge": "^1.3.3",
"node-forge": "^1.4.0",
"semver": "^7.7.4",
"uuid": "^13.0.0"
},
"devDependencies": {
"@ava/typescript": "6.0.0",
"@eslint/compat": "^2.0.3",
"@eslint/compat": "^2.0.4",
"@microsoft/eslint-formatter-sarif": "^3.1.0",
"@octokit/types": "^16.0.0",
"@types/archiver": "^7.0.0",
@@ -55,21 +54,21 @@
"@types/node-forge": "^1.3.14",
"@types/sarif": "^2.1.7",
"@types/semver": "^7.7.1",
"@types/sinon": "^21.0.0",
"@types/sinon": "^21.0.1",
"ava": "^7.0.0",
"esbuild": "^0.27.3",
"esbuild": "^0.28.0",
"eslint": "^9.39.2",
"eslint-import-resolver-typescript": "^3.8.7",
"eslint-plugin-github": "^6.0.0",
"eslint-plugin-import-x": "^4.16.1",
"eslint-plugin-jsdoc": "^62.7.1",
"eslint-plugin-import-x": "^4.16.2",
"eslint-plugin-jsdoc": "^62.9.0",
"eslint-plugin-no-async-foreach": "^0.1.1",
"glob": "^11.1.0",
"globals": "^17.4.0",
"nock": "^14.0.11",
"sinon": "^21.0.2",
"typescript": "^5.9.3",
"typescript-eslint": "^8.57.0"
"nock": "^14.0.12",
"sinon": "^21.0.3",
"typescript": "^6.0.2",
"typescript-eslint": "^8.58.0"
},
"overrides": {
"@actions/tool-cache": {
+13
View File
@@ -0,0 +1,13 @@
import * as githubUtils from "@actions/github/lib/utils";
import { type Octokit } from "@octokit/core";
import { type PaginateInterface } from "@octokit/plugin-paginate-rest";
import { type Api } from "@octokit/plugin-rest-endpoint-methods";
/** The type of the Octokit client. */
export type ApiClient = Octokit & Api & { paginate: PaginateInterface };
/** Constructs an `ApiClient` using `token` for authentication. */
export function getApiClient(token: string): ApiClient {
const opts = githubUtils.getOctokitOptions(token);
return new githubUtils.GitHub(opts);
}
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env npx tsx
import * as fs from "node:fs/promises";
import { BUNDLE_METADATA_FILE } from "./config";
interface InputInfo {
bytesInOutput: number;
}
type Inputs = Record<string, InputInfo>;
interface Output {
bytes: number;
inputs: Inputs;
}
interface Metadata {
outputs: Record<string, Output>;
}
function toMB(bytes: number): string {
return `${(bytes / (1024 * 1024)).toFixed(2)}MB`;
}
async function main() {
const fileContents = await fs.readFile(BUNDLE_METADATA_FILE);
const metadata = JSON.parse(String(fileContents)) as Metadata;
for (const [outputFile, outputData] of Object.entries(
metadata.outputs,
).reverse()) {
console.info(`${outputFile}: ${toMB(outputData.bytes)}`);
for (const [inputName, inputData] of Object.entries(outputData.inputs)) {
// Ignore any inputs that make up less than 5% of the output.
const percentage = (inputData.bytesInOutput / outputData.bytes) * 100.0;
if (percentage < 5.0) continue;
console.info(` ${inputName}: ${toMB(inputData.bytesInOutput)}`);
}
}
}
// Only call `main` if this script was run directly.
if (require.main === module) {
void main();
}
+2 -2
View File
@@ -5,12 +5,12 @@ versions:
steps:
- uses: ./../action/init
with:
languages: C#,java-kotlin,swift,typescript
languages: C#,java-kotlin,typescript
tools: ${{ steps.prepare-test.outputs.tools-url }}
- name: "Check languages"
run: |
expected_languages="csharp,java,swift,javascript"
expected_languages="csharp,java,javascript"
actual_languages=$(jq -r '.languages | join(",")' "$RUNNER_TEMP"/config)
if [ "$expected_languages" != "$actual_languages" ]; then
+1 -1
View File
@@ -5,7 +5,7 @@ versions:
- default
steps:
- name: Set up Ruby
uses: ruby/setup-ruby@09a7688d3b55cf0e976497ff046b70949eeaccfd # v1.288.0
uses: ruby/setup-ruby@4c56a21280b36d862b5fc31348f463d60bdc55d5 # v1.301.0
with:
ruby-version: 2.6
- name: Install Code Scanning integration
+18 -1
View File
@@ -16,7 +16,17 @@ steps:
id: proxy
uses: ./../action/start-proxy
with:
registry_secrets: '[{ "type": "nuget_feed", "url": "https://api.nuget.org/v3/index.json" }]'
registry_secrets: |
[
{
"type": "maven_repository",
"url": "https://repo.maven.apache.org/maven2/"
},
{
"type": "maven_repository",
"url": "https://repo1.maven.org/maven2"
}
]
- name: Print proxy outputs
run: |
@@ -27,3 +37,10 @@ steps:
- name: Fail if proxy outputs are not set
if: (!steps.proxy.outputs.proxy_host) || (!steps.proxy.outputs.proxy_port) || (!steps.proxy.outputs.proxy_ca_certificate) || (!steps.proxy.outputs.proxy_urls)
run: exit 1
- name: Fail if proxy_urls does not contain all registries
if: |
join(fromJSON(steps.proxy.outputs.proxy_urls)[*].type, ',') != 'maven_repository,maven_repository'
|| !contains(steps.proxy.outputs.proxy_urls, 'https://repo.maven.apache.org/maven2/')
|| !contains(steps.proxy.outputs.proxy_urls, 'https://repo1.maven.org/maven2')
run: exit 1
+13
View File
@@ -0,0 +1,13 @@
import path from "path";
/** The oldest supported major version of the CodeQL Action. */
export const OLDEST_SUPPORTED_MAJOR_VERSION = 3;
/** The `pr-checks` directory. */
export const PR_CHECKS_DIR = __dirname;
/** The path of the file configuring which checks shouldn't be required. */
export const PR_CHECK_EXCLUDED_FILE = path.join(PR_CHECKS_DIR, "excluded.yml");
/** The path to the esbuild metadata file. */
export const BUNDLE_METADATA_FILE = path.join(PR_CHECKS_DIR, "..", "meta.json");
+16
View File
@@ -0,0 +1,16 @@
# PR checks to exclude from required checks
contains:
- "https://"
- "Update"
- "ESLint"
- "update"
- "test-setup-python-scripts"
is:
- "CodeQL"
- "Dependabot"
- "check-expected-release-files"
- "Agent"
- "Cleanup artifacts"
- "Prepare"
- "Upload results"
- "Label PR with size"
+7 -3
View File
@@ -2,11 +2,15 @@
"private": true,
"description": "Dependencies for the sync.ts",
"dependencies": {
"yaml": "^2.8.2"
"@actions/core": "^2.0.3",
"@actions/github": "^8.0.1",
"@octokit/core": "^7.0.6",
"@octokit/plugin-paginate-rest": ">=9.2.2",
"@octokit/plugin-rest-endpoint-methods": "^17.0.0",
"yaml": "^2.8.3"
},
"devDependencies": {
"@types/node": "^20.19.9",
"tsx": "^4.21.0",
"typescript": "^5.9.3"
"tsx": "^4.21.0"
}
}
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env npx tsx
/*
Tests for the release-branches.ts script
*/
import * as assert from "node:assert/strict";
import { describe, it } from "node:test";
import { computeBackportBranches } from "./release-branches";
describe("computeBackportBranches", async () => {
await it("rejects invalid major versions", () => {
// The majorVersion is expected to be in vN format.
assert.throws(() => computeBackportBranches("3", "v4.28.0", 3));
assert.throws(() => computeBackportBranches("v3.1", "v4.28.0", 3));
});
await it("rejects invalid latest tags", () => {
// The latestTag is expected to be in vN.M.P format.
assert.throws(() => computeBackportBranches("v3", "v4", 3));
assert.throws(() => computeBackportBranches("v3", "4", 3));
assert.throws(() => computeBackportBranches("v3", "v4.28", 3));
assert.throws(() => computeBackportBranches("v3", "4.28", 3));
assert.throws(() => computeBackportBranches("v3", "4.28.0", 3));
});
await it("sets backport source branch based on major version", () => {
// Test that the backport source branch is releases/v{majorVersion}
const result = computeBackportBranches("v3", "v4.28.0", 3);
assert.equal(result.backportSourceBranch, "releases/v3");
});
await it("no backport targets when major version is the oldest supported", () => {
// When majorVersion equals the major version of latestTag and we do not support older major versions,
// then there are no older supported branches to backport to.
const result = computeBackportBranches("v3", "v3.28.0", 3);
assert.deepEqual(result.backportTargetBranches, []);
});
await it("backports to older supported major versions", () => {
const result = computeBackportBranches("v4", "v4.1.0", 3);
assert.equal(result.backportSourceBranch, "releases/v4");
assert.deepEqual(result.backportTargetBranches, ["releases/v3"]);
});
await it("backports to multiple older supported branches", () => {
const result = computeBackportBranches("v5", "v5.0.0", 3);
assert.equal(result.backportSourceBranch, "releases/v5");
assert.deepEqual(result.backportTargetBranches, [
"releases/v4",
"releases/v3",
]);
});
await it("does not backport when major version is older than latest tag", () => {
const result = computeBackportBranches("v2", "v3.28.0", 2);
assert.equal(result.backportSourceBranch, "releases/v2");
assert.deepEqual(result.backportTargetBranches, []);
});
});
+121
View File
@@ -0,0 +1,121 @@
#!/usr/bin/env npx tsx
import { parseArgs } from "node:util";
import * as core from "@actions/core";
import { OLDEST_SUPPORTED_MAJOR_VERSION } from "./config";
/** The results of checking which release branches to backport to. */
export interface BackportInfo {
/** The source release branch. */
backportSourceBranch: string;
/**
* The computed release branches we should backport to.
* Will be empty if there are no branches we need to backport to.
*/
backportTargetBranches: string[];
}
/**
* Compute the backport source and target branches for a release.
*
* @param majorVersion - The major version string (e.g. "v4").
* @param latestTag - The most recent tag published to the repository (e.g. "v4.32.6").
* @param oldestSupportedMajorVersion - The oldest supported major version number.
* @returns The names of the source branch and target branches.
*/
export function computeBackportBranches(
majorVersion: string,
latestTag: string,
oldestSupportedMajorVersion: number,
): BackportInfo {
// Perform some sanity checks on the inputs.
// For `majorVersion`, we expect exactly `vN` for some `N`.
const majorVersionMatch = majorVersion.match(/^v(\d+)$/);
if (!majorVersionMatch) {
throw new Error("--major-version value must be in `vN` format.");
}
// For latestTag, we expect something starting with `vN.M.P`
const latestTagMatch = latestTag.match(/^v(\d+)\.\d+\.\d+/);
if (!latestTagMatch) {
throw new Error(
`--latest-tag value must be in 'vN.M.P' format, but '${latestTag}' is not.`,
);
}
const majorVersionNumber = Number.parseInt(majorVersionMatch[1]);
const latestTagMajor = Number.parseInt(latestTagMatch[1]);
// If this is a primary release, we backport to all supported branches,
// so we check whether the majorVersion taken from the package.json
// is greater than or equal to the latest tag pulled from the repo.
// For example...
// 'v1' >= 'v2' is False # we're operating from an older release branch and should not backport
// 'v2' >= 'v2' is True # the normal case where we're updating the current version
// 'v3' >= 'v2' is True # in this case we are making the first release of a new major version
const considerBackports = majorVersionNumber >= latestTagMajor;
const backportSourceBranch = `releases/v${majorVersionNumber}`;
const backportTargetBranches: string[] = [];
if (considerBackports) {
for (let i = majorVersionNumber - 1; i > 0; i--) {
const branchName = `releases/v${i}`;
if (i >= oldestSupportedMajorVersion) {
backportTargetBranches.push(branchName);
}
}
}
return { backportSourceBranch, backportTargetBranches };
}
async function main() {
const { values: options } = parseArgs({
options: {
// The major version of the release in `vN` format (e.g. `v4`).
"major-version": {
type: "string",
},
// The most recent tag published to the repository (e.g. `v4.28.0`).
"latest-tag": {
type: "string",
},
},
strict: true,
});
if (options["major-version"] === undefined) {
throw Error("--major-version is required");
}
if (options["latest-tag"] === undefined) {
throw Error("--latest-tag is required");
}
const majorVersion = options["major-version"];
const latestTag = options["latest-tag"];
console.log(`Major version: ${majorVersion}`);
console.log(`Latest tag: ${latestTag}`);
const result = computeBackportBranches(
majorVersion,
latestTag,
OLDEST_SUPPORTED_MAJOR_VERSION,
);
core.setOutput("backport_source_branch", result.backportSourceBranch);
core.setOutput(
"backport_target_branches",
JSON.stringify(result.backportTargetBranches),
);
process.exit(0);
}
// Only call `main` if this script was run directly.
if (require.main === module) {
void main();
}
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env npx tsx
/*
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";
const defaultOptions: Options = {
apply: false,
verbose: false,
};
const toCheckInfo = (name: string) =>
({ context: name, app_id: -1 }) satisfies CheckInfo;
const expectedPartialMatches = ["PR Check - Foo", "https://example.com"].map(
toCheckInfo,
);
const expectedExactMatches = ["CodeQL", "Update"].map(toCheckInfo);
const testChecks = expectedExactMatches.concat(expectedPartialMatches);
const emptyExclusions: Exclusions = {
is: [],
contains: [],
};
describe("removeExcluded", async () => {
await it("retains all checks if no exclusions are configured", () => {
const retained = removeExcluded(
defaultOptions,
emptyExclusions,
testChecks,
);
assert.deepEqual(retained, testChecks);
});
await it("removes exact matches", () => {
const retained = removeExcluded(
defaultOptions,
{ ...emptyExclusions, is: ["CodeQL", "Update"] },
testChecks,
);
assert.deepEqual(retained, expectedPartialMatches);
});
await it("removes partial matches", () => {
const retained = removeExcluded(
defaultOptions,
{ ...emptyExclusions, contains: ["https://", "PR Check"] },
testChecks,
);
assert.deepEqual(retained, expectedExactMatches);
});
});
+287
View File
@@ -0,0 +1,287 @@
#!/usr/bin/env npx tsx
/** Update the required checks based on the current branch. */
import * as fs from "fs";
import { parseArgs } from "node:util";
import * as yaml from "yaml";
import { type ApiClient, getApiClient } from "./api-client";
import {
OLDEST_SUPPORTED_MAJOR_VERSION,
PR_CHECK_EXCLUDED_FILE,
} from "./config";
/** Represents the command-line options. */
export interface Options {
/** The token to use to authenticate to the GitHub API. */
token?: string;
/** The git ref to use the checks for. */
ref?: string;
/** Whether to actually apply the changes or not. */
apply: boolean;
/** Whether to output additional information. */
verbose: boolean;
}
/** Identifies the CodeQL Action repository. */
const codeqlActionRepo = {
owner: "github",
repo: "codeql-action",
};
/** 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. */
contains: string[];
/** A list of check names that are excluded if their name is an exact match. */
is: string[];
}
/** Loads the configuration for which checks to exclude. */
function loadExclusions(): Exclusions {
return yaml.parse(
fs.readFileSync(PR_CHECK_EXCLUDED_FILE, "utf-8"),
) as Exclusions;
}
/**
* Represents information about a check run. We track the `app_id` that generated the check,
* because the API will require it in addition to the name in the future.
*/
export interface CheckInfo {
/** The display name of the check. */
context: string;
/** The ID of the app that generated the check. */
app_id: number;
}
/** Removes entries from `checkInfos` based on the configuration. */
export function removeExcluded(
options: Options,
exclusions: Exclusions,
checkInfos: CheckInfo[],
): CheckInfo[] {
if (options.verbose) {
console.log(exclusions);
}
return checkInfos.filter((checkInfo) => {
if (exclusions.is.includes(checkInfo.context)) {
console.info(
`Excluding '${checkInfo.context}' because it is an exact exclusion.`,
);
return false;
}
for (const containsStr of exclusions.contains) {
if (checkInfo.context.includes(containsStr)) {
console.info(
`Excluding '${checkInfo.context}' because it contains '${containsStr}'.`,
);
return false;
}
}
// Keep.
return true;
});
}
/** Gets a list of check run names for `ref`. */
async function getChecksFor(
options: Options,
client: ApiClient,
ref: string,
): Promise<CheckInfo[]> {
console.info(`Getting checks for '${ref}'`);
const response = await client.paginate(
"GET /repos/{owner}/{repo}/commits/{ref}/check-runs",
{
...codeqlActionRepo,
ref,
},
);
if (response.length === 0) {
throw new Error(`No checks found for '${ref}'.`);
}
console.info(`Retrieved ${response.length} check runs.`);
const notSkipped = response.filter(
(checkRun) => checkRun.conclusion !== "skipped",
);
console.info(`Of those: ${notSkipped.length} were not skipped.`);
// We use the ID of the app that generated the check run when returned by the API,
// but default to -1 to tell the API that any check with the given name should be
// required.
const checkInfos = notSkipped.map((check) => ({
context: check.name,
app_id: check.app?.id || -1,
}));
// Load the configuration for which checks to exclude and apply it before
// returning the checks.
const exclusions = loadExclusions();
return removeExcluded(options, exclusions, checkInfos);
}
/** Gets the current list of release branches. */
async function getReleaseBranches(client: ApiClient): Promise<string[]> {
const refs = await client.rest.git.listMatchingRefs({
...codeqlActionRepo,
ref: "heads/releases/v",
});
return refs.data.map((ref) => ref.ref).sort();
}
/** Updates the required status checks for `branch` to `checks`. */
async function patchBranchProtectionRule(
client: ApiClient,
branch: string,
checks: Set<string>,
) {
await client.rest.repos.setStatusCheckContexts({
...codeqlActionRepo,
branch,
contexts: Array.from(checks),
});
}
/** Sets `checkNames` as required checks for `branch`. */
async function updateBranch(
options: Options,
client: ApiClient,
branch: string,
checkNames: Set<string>,
) {
console.info(`Updating '${branch}'...`);
// Query the current set of required checks for this branch.
const currentContexts = await client.rest.repos.getAllStatusCheckContexts({
...codeqlActionRepo,
branch,
});
// Identify which required checks we will remove and which ones we will add.
const currentCheckNames = new Set(currentContexts.data);
let additions = 0;
let removals = 0;
let unchanged = 0;
for (const currentCheck of currentCheckNames) {
if (!checkNames.has(currentCheck)) {
console.info(`- Removing '${currentCheck}' for branch '${branch}'`);
removals++;
} else {
unchanged++;
}
}
for (const newCheck of checkNames) {
if (!currentCheckNames.has(newCheck)) {
console.info(`+ Adding '${newCheck}' for branch '${branch}'`);
additions++;
}
}
console.info(
`For '${branch}': ${removals} removals; ${additions} additions; ${unchanged} unchanged`,
);
// Perform the update if there are changes and `--apply` was specified.
if (unchanged === checkNames.size && removals === 0 && additions === 0) {
console.info("Not applying changes because there is nothing to do.");
} else if (options.apply) {
await patchBranchProtectionRule(client, branch, checkNames);
} else {
console.info("Not applying changes because `--apply` was not specified.");
}
}
async function main(): Promise<void> {
const { values: options } = parseArgs({
options: {
// The token to use to authenticate to the API.
token: {
type: "string",
},
// The git ref for which to retrieve the check runs.
ref: {
type: "string",
default: "main",
},
// By default, we perform a dry-run. Setting `apply` to `true` actually applies the changes.
apply: {
type: "boolean",
default: false,
},
// Whether to output additional information.
verbose: {
type: "boolean",
default: false,
},
},
strict: true,
});
if (options.token === undefined) {
throw new Error("Missing --token");
}
console.info(
`Oldest supported major version is: ${OLDEST_SUPPORTED_MAJOR_VERSION}`,
);
// Initialise the API client.
const client = getApiClient(options.token);
// Find the check runs for the specified `ref` that we will later set as the required checks
// for the main and release branches.
const checkInfos = await getChecksFor(options, client, options.ref);
const checkNames = new Set(checkInfos.map((info) => info.context));
// Update the main branch.
await updateBranch(options, client, "main", checkNames);
// Retrieve the refs of the release branches.
const releaseBranches = await getReleaseBranches(client);
console.info(
`Found ${releaseBranches.length} release branches: ${releaseBranches.join(", ")}`,
);
for (const releaseBranchRef of releaseBranches) {
// Sanity check that the ref name is in the expected format and extract the major version.
const releaseBranchMatch = releaseBranchRef.match(
/^refs\/heads\/(releases\/v(\d+))/,
);
if (!releaseBranchMatch) {
console.warn(
`Branch ref '${releaseBranchRef}' not in the expected format.`,
);
continue;
}
const releaseBranch = releaseBranchMatch[1];
const releaseBranchMajor = Number.parseInt(releaseBranchMatch[2]);
// Update the required checks for this major version if it is still supported.
if (releaseBranchMajor < OLDEST_SUPPORTED_MAJOR_VERSION) {
console.info(
`Skipping '${releaseBranch}' since it is older than v${OLDEST_SUPPORTED_MAJOR_VERSION}`,
);
continue;
} else {
await updateBranch(options, client, releaseBranch, checkNames);
}
}
process.exit(0);
}
// Only call `main` if this script was run directly.
if (require.main === module) {
void main();
}
+1
View File
@@ -3,6 +3,7 @@
"compilerOptions": {
/* Basic Options */
"lib": ["esnext"],
"module": "preserve",
"rootDir": "..",
"sourceMap": false,
"noEmit": true,
+1 -1
View File
@@ -21,5 +21,5 @@ outputs:
environment:
description: The inferred build environment configuration.
runs:
using: node24
using: node20
main: '../lib/resolve-environment-action.js'
+1 -1
View File
@@ -35,5 +35,5 @@ outputs:
codeql-version:
description: The version of the CodeQL binary that was installed.
runs:
using: node24
using: node20
main: '../lib/setup-codeql-action.js'
+6
View File
@@ -53,6 +53,12 @@ export function getTemporaryDirectory(): string {
: getRequiredEnvParam("RUNNER_TEMP");
}
const PR_DIFF_RANGE_JSON_FILENAME = "pr-diff-range.json";
export function getDiffRangesJsonFilePath(): string {
return path.join(getTemporaryDirectory(), PR_DIFF_RANGE_JSON_FILENAME);
}
export function getActionVersion(): string {
return __CODEQL_ACTION_VERSION__;
}
+3 -10
View File
@@ -28,12 +28,11 @@ import {
DependencyCacheUploadStatusReport,
uploadDependencyCaches,
} from "./dependency-caching";
import { getDiffInformedAnalysisBranches } from "./diff-informed-analysis-utils";
import { EnvVar } from "./environment";
import { initFeatures } from "./feature-flags";
import { KnownLanguage } from "./languages";
import { getActionsLogger, Logger } from "./logging";
import { cleanupAndUploadOverlayBaseDatabaseToCache } from "./overlay";
import { cleanupAndUploadOverlayBaseDatabaseToCache } from "./overlay/caching";
import { getRepositoryNwo } from "./repository";
import * as statusReport from "./status-report";
import {
@@ -305,14 +304,8 @@ async function run(startedAt: Date) {
logger,
);
const branches = await getDiffInformedAnalysisBranches(
codeql,
features,
logger,
);
const diffRangePackDir = branches
? await setupDiffInformedQueryRun(branches, logger)
: undefined;
// Setup diff informed analysis if needed (based on whether init created the file)
const diffRangePackDir = await setupDiffInformedQueryRun(logger);
await warnIfGoInstalledAfterInit(config, logger);
await runAutobuildIfLegacyGoWorkflow(config, logger);
+11 -17
View File
@@ -5,11 +5,7 @@ import { performance } from "perf_hooks";
import * as io from "@actions/io";
import * as yaml from "js-yaml";
import {
getTemporaryDirectory,
getRequiredInput,
PullRequestBranches,
} from "./actions-util";
import { getTemporaryDirectory, getRequiredInput } from "./actions-util";
import * as analyses from "./analyses";
import { setupCppAutobuild } from "./autobuild";
import { type CodeQL } from "./codeql";
@@ -21,14 +17,13 @@ import {
import { addDiagnostic, makeDiagnostic } from "./diagnostics";
import {
DiffThunkRange,
writeDiffRangesJsonFile,
getPullRequestEditedDiffRanges,
readDiffRangesJsonFile,
} from "./diff-informed-analysis-utils";
import { EnvVar } from "./environment";
import { FeatureEnablement, Feature } from "./feature-flags";
import { KnownLanguage, Language } from "./languages";
import { Logger, withGroupAsync } from "./logging";
import { OverlayDatabaseMode } from "./overlay";
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
import type * as sarif from "./sarif";
import { DatabaseCreationTimings, EventReport } from "./status-report";
import { endTracingForCluster } from "./tracer-config";
@@ -237,16 +232,19 @@ async function finalizeDatabaseCreation(
* the diff range information, or `undefined` if the feature is disabled.
*/
export async function setupDiffInformedQueryRun(
branches: PullRequestBranches,
logger: Logger,
): Promise<string | undefined> {
return await withGroupAsync(
"Generating diff range extension pack",
async () => {
logger.info(
`Calculating diff ranges for ${branches.base}...${branches.head}`,
);
const diffRanges = await getPullRequestEditedDiffRanges(branches, logger);
const diffRanges = readDiffRangesJsonFile(logger);
if (diffRanges === undefined) {
logger.info(
"No precomputed diff ranges found; skipping diff-informed analysis stage.",
);
return undefined;
}
const checkoutPath = getRequiredInput("checkout_path");
const packDir = writeDiffRangeDataExtensionPack(
logger,
@@ -368,10 +366,6 @@ dataExtensions:
`Wrote pr-diff-range extension pack to ${extensionFilePath}:\n${extensionContents}`,
);
// Write the diff ranges to a JSON file, for action-side alert filtering by the
// upload-lib module.
writeDiffRangesJsonFile(logger, ranges);
return diffRangeDir;
}
+14
View File
@@ -299,6 +299,20 @@ test("wrapCliConfigurationError - swift build failed", (t) => {
t.true(wrappedError instanceof ConfigurationError);
});
test("wrapCliConfigurationError - swift incompatible os", (t) => {
const commandError = new CommandInvocationError(
"codeql",
["swift/tools/autobuild.sh"],
1,
"2026-04-01 18:35:00 EST ERRO [extractor/main] [incompatible-os] Currently, Swift analysis is only supported on macOS. (IncompatibleOs.cpp:26)",
);
const cliError = new CliError(commandError);
const wrappedError = wrapCliConfigurationError(cliError);
t.true(wrappedError instanceof ConfigurationError);
});
test("wrapCliConfigurationError - pack cannot be found", (t) => {
const commandError = new CommandInvocationError(
"codeql",
+7
View File
@@ -144,6 +144,7 @@ export enum CliConfigErrorCategory {
OutOfMemoryOrDisk = "OutOfMemoryOrDisk",
PackCannotBeFound = "PackCannotBeFound",
PackMissingAuth = "PackMissingAuth",
SwiftIncompatibleOs = "SwiftIncompatibleOs",
SwiftBuildFailed = "SwiftBuildFailed",
UnsupportedBuildMode = "UnsupportedBuildMode",
}
@@ -281,6 +282,12 @@ const cliErrorsConfig: Record<CliConfigErrorCategory, CliErrorConfiguration> = {
),
],
},
[CliConfigErrorCategory.SwiftIncompatibleOs]: {
cliErrorMessageCandidates: [
new RegExp("\\[incompatible-os\\]"),
new RegExp("Swift analysis is only supported on macOS"),
],
},
[CliConfigErrorCategory.UnsupportedBuildMode]: {
cliErrorMessageCandidates: [
new RegExp(
+2 -5
View File
@@ -24,11 +24,8 @@ import {
import { isAnalyzingDefaultBranch } from "./git-utils";
import { Language } from "./languages";
import { Logger } from "./logging";
import {
OverlayDatabaseMode,
writeBaseDatabaseOidsFile,
writeOverlayChangesFile,
} from "./overlay";
import { writeBaseDatabaseOidsFile, writeOverlayChangesFile } from "./overlay";
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
import * as setupCodeql from "./setup-codeql";
import { ZstdAvailability } from "./tar";
import { ToolsDownloadStatusReport } from "./tools-download";
+27 -8
View File
@@ -20,8 +20,9 @@ import * as gitUtils from "./git-utils";
import { GitVersionInfo } from "./git-utils";
import { KnownLanguage, Language } from "./languages";
import { getRunnerLogger } from "./logging";
import { CODEQL_OVERLAY_MINIMUM_VERSION, OverlayDatabaseMode } from "./overlay";
import { CODEQL_OVERLAY_MINIMUM_VERSION } from "./overlay";
import { OverlayDisabledReason } from "./overlay/diagnostics";
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
import * as overlayStatus from "./overlay/status";
import { parseRepositoryNwo } from "./repository";
import {
@@ -1004,6 +1005,7 @@ interface OverlayDatabaseModeTestSetup {
codeqlVersion: string;
gitRoot: string | undefined;
gitVersion: GitVersionInfo | undefined;
hasSubmodules: boolean;
codeScanningConfig: UserConfig;
diskUsage: DiskUsage | undefined;
memoryFlagValue: number;
@@ -1020,10 +1022,8 @@ const defaultOverlayDatabaseModeTestSetup: OverlayDatabaseModeTestSetup = {
languages: [KnownLanguage.javascript],
codeqlVersion: CODEQL_OVERLAY_MINIMUM_VERSION,
gitRoot: "/some/git/root",
gitVersion: new GitVersionInfo(
gitUtils.GIT_MINIMUM_VERSION_FOR_OVERLAY,
gitUtils.GIT_MINIMUM_VERSION_FOR_OVERLAY,
),
gitVersion: new GitVersionInfo("2.39.0", "2.39.0"),
hasSubmodules: false,
codeScanningConfig: {},
diskUsage: {
numAvailableBytes: 50_000_000_000,
@@ -1099,6 +1099,9 @@ const checkOverlayEnablementMacro = test.macro({
sinon.stub(gitUtils, "getGitRoot").resolves(setup.gitRoot);
}
// Mock submodule detection
sinon.stub(gitUtils, "hasSubmodules").returns(setup.hasSubmodules);
// Mock default branch detection
sinon
.stub(gitUtils, "isAnalyzingDefaultBranch")
@@ -1933,10 +1936,11 @@ test.serial(
test.serial(
checkOverlayEnablementMacro,
"Fallback due to old git version",
"Fallback due to old git version with submodules",
{
overlayDatabaseEnvVar: "overlay",
gitVersion: new GitVersionInfo("2.30.0", "2.30.0"), // Version below required 2.38.0
gitVersion: new GitVersionInfo("2.34.1", "2.34.1"), // Above 2.11.0 but below 2.36.0
hasSubmodules: true,
},
{
disabledReason: OverlayDisabledReason.IncompatibleGit,
@@ -1945,16 +1949,31 @@ test.serial(
test.serial(
checkOverlayEnablementMacro,
"Fallback when git version cannot be determined",
"Fallback when git version cannot be determined and repo has submodules",
{
overlayDatabaseEnvVar: "overlay",
gitVersion: undefined,
hasSubmodules: true,
},
{
disabledReason: OverlayDisabledReason.IncompatibleGit,
},
);
test.serial(
checkOverlayEnablementMacro,
"Overlay enabled when git version cannot be determined and repo has no submodules",
{
overlayDatabaseEnvVar: "overlay",
gitVersion: undefined,
hasSubmodules: false,
},
{
overlayDatabaseMode: OverlayDatabaseMode.Overlay,
useOverlayDatabaseCaching: false,
},
);
test.serial(
checkOverlayEnablementMacro,
"No overlay when disabled via repository property",
+26 -18
View File
@@ -43,17 +43,19 @@ import {
getGeneratedFiles,
getGitRoot,
getGitVersionOrThrow,
GIT_MINIMUM_VERSION_FOR_OVERLAY,
GIT_MINIMUM_VERSION_FOR_OVERLAY_WITH_SUBMODULES,
GitVersionInfo,
hasSubmodules,
isAnalyzingDefaultBranch,
} from "./git-utils";
import { KnownLanguage, Language } from "./languages";
import { Logger } from "./logging";
import { CODEQL_OVERLAY_MINIMUM_VERSION, OverlayDatabaseMode } from "./overlay";
import { CODEQL_OVERLAY_MINIMUM_VERSION } from "./overlay";
import {
addOverlayDisablementDiagnostics,
OverlayDisabledReason,
} from "./overlay/diagnostics";
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
import { shouldSkipOverlayAnalysis } from "./overlay/status";
import { RepositoryNwo } from "./repository";
import { ToolsFeature } from "./tools-features";
@@ -969,7 +971,8 @@ async function validateOverlayDatabaseMode(
);
return new Failure(OverlayDisabledReason.IncompatibleCodeQl);
}
if ((await getGitRoot(sourceRoot)) === undefined) {
const gitRoot = await getGitRoot(sourceRoot);
if (gitRoot === undefined) {
logger.warning(
`Cannot build an ${overlayDatabaseMode} database because ` +
`the source root "${sourceRoot}" is not inside a git repository. ` +
@@ -977,21 +980,26 @@ async function validateOverlayDatabaseMode(
);
return new Failure(OverlayDisabledReason.NoGitRoot);
}
if (gitVersion === undefined) {
logger.warning(
`Cannot build an ${overlayDatabaseMode} database because ` +
"the Git version could not be determined. " +
"Falling back to creating a normal full database instead.",
);
return new Failure(OverlayDisabledReason.IncompatibleGit);
}
if (!gitVersion.isAtLeast(GIT_MINIMUM_VERSION_FOR_OVERLAY)) {
logger.warning(
`Cannot build an ${overlayDatabaseMode} database because ` +
`the installed Git version is older than ${GIT_MINIMUM_VERSION_FOR_OVERLAY}. ` +
"Falling back to creating a normal full database instead.",
);
return new Failure(OverlayDisabledReason.IncompatibleGit);
if (hasSubmodules(gitRoot)) {
if (gitVersion === undefined) {
logger.warning(
`Cannot build an ${overlayDatabaseMode} database because ` +
"the repository has submodules and the Git version could not be determined. " +
"Falling back to creating a normal full database instead.",
);
return new Failure(OverlayDisabledReason.IncompatibleGit);
}
if (
!gitVersion.isAtLeast(GIT_MINIMUM_VERSION_FOR_OVERLAY_WITH_SUBMODULES)
) {
logger.warning(
`Cannot build an ${overlayDatabaseMode} database because ` +
"the repository has submodules and the installed Git version is older " +
`than ${GIT_MINIMUM_VERSION_FOR_OVERLAY_WITH_SUBMODULES}. ` +
"Falling back to creating a normal full database instead.",
);
return new Failure(OverlayDisabledReason.IncompatibleGit);
}
}
return new Success({
+1 -1
View File
@@ -12,7 +12,7 @@ import { Config } from "./config-utils";
import { Feature, FeatureEnablement } from "./feature-flags";
import * as gitUtils from "./git-utils";
import { Logger, withGroupAsync } from "./logging";
import { OverlayDatabaseMode } from "./overlay";
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
import { RepositoryNwo } from "./repository";
import * as util from "./util";
import { asHTTPError, bundleDb, CleanupLevel, parseGitHubUrl } from "./util";
+4 -4
View File
@@ -1,6 +1,6 @@
{
"bundleVersion": "codeql-bundle-v2.25.0",
"cliVersion": "2.25.0",
"priorBundleVersion": "codeql-bundle-v2.24.3",
"priorCliVersion": "2.24.3"
"bundleVersion": "codeql-bundle-v2.25.2",
"cliVersion": "2.25.2",
"priorBundleVersion": "codeql-bundle-v2.25.1",
"priorCliVersion": "2.25.1"
}
+10 -8
View File
@@ -1,5 +1,4 @@
import * as fs from "fs";
import * as path from "path";
import * as actionsUtil from "./actions-util";
import type { PullRequestBranches } from "./actions-util";
@@ -77,16 +76,12 @@ export interface DiffThunkRange {
endLine: number;
}
function getDiffRangesJsonFilePath(): string {
return path.join(actionsUtil.getTemporaryDirectory(), "pr-diff-range.json");
}
export function writeDiffRangesJsonFile(
logger: Logger,
ranges: DiffThunkRange[],
): void {
const jsonContents = JSON.stringify(ranges, null, 2);
const jsonFilePath = getDiffRangesJsonFilePath();
const jsonFilePath = actionsUtil.getDiffRangesJsonFilePath();
fs.writeFileSync(jsonFilePath, jsonContents);
logger.debug(
`Wrote pr-diff-range JSON file to ${jsonFilePath}:\n${jsonContents}`,
@@ -96,7 +91,7 @@ export function writeDiffRangesJsonFile(
export function readDiffRangesJsonFile(
logger: Logger,
): DiffThunkRange[] | undefined {
const jsonFilePath = getDiffRangesJsonFilePath();
const jsonFilePath = actionsUtil.getDiffRangesJsonFilePath();
if (!fs.existsSync(jsonFilePath)) {
logger.debug(`Diff ranges JSON file does not exist at ${jsonFilePath}`);
return undefined;
@@ -105,7 +100,14 @@ export function readDiffRangesJsonFile(
logger.debug(
`Read pr-diff-range JSON file from ${jsonFilePath}:\n${jsonContents}`,
);
return JSON.parse(jsonContents) as DiffThunkRange[];
try {
return JSON.parse(jsonContents) as DiffThunkRange[];
} catch (e) {
logger.warning(
`Failed to parse diff ranges JSON file at ${jsonFilePath}: ${e}`,
);
return undefined;
}
}
/**
-7
View File
@@ -85,7 +85,6 @@ export enum Feature {
OverlayAnalysisStatusCheck = "overlay_analysis_status_check",
/** Controls whether overlay build failures on the default branch are stored in the Actions cache. */
OverlayAnalysisStatusSave = "overlay_analysis_status_save",
PythonDefaultIsToNotExtractStdlib = "python_default_is_to_not_extract_stdlib",
QaTelemetryEnabled = "qa_telemetry_enabled",
/** Note that this currently only disables baseline file coverage information. */
SkipFileCoverageOnPrs = "skip_file_coverage_on_prs",
@@ -298,12 +297,6 @@ export const featureConfig = {
envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_SKIP_RESOURCE_CHECKS",
minimumVersion: undefined,
},
[Feature.PythonDefaultIsToNotExtractStdlib]: {
defaultValue: false,
envVar: "CODEQL_ACTION_DISABLE_PYTHON_STANDARD_LIBRARY_EXTRACTION",
minimumVersion: undefined,
toolsFeature: ToolsFeature.PythonDefaultIsToNotExtractStdlib,
},
[Feature.QaTelemetryEnabled]: {
defaultValue: false,
envVar: "CODEQL_ACTION_QA_TELEMETRY",
+118 -51
View File
@@ -343,75 +343,142 @@ test.serial("decodeGitFilePath quoted strings", async (t) => {
);
});
test.serial("getFileOidsUnderPath returns correct file mapping", async (t) => {
const runGitCommandStub = sinon
.stub(gitUtils as any, "runGitCommand")
.resolves(
"30d998ded095371488be3a729eb61d86ed721a18_lib/git-utils.js\n" +
"d89514599a9a99f22b4085766d40af7b99974827_lib/git-utils.js.map\n" +
"a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96_src/git-utils.ts",
);
test.serial(
"getFileOidsUnderPath uses --recurse-submodules when submodules exist",
async (t) => {
await withTmpDir(async (tmpDir) => {
fs.writeFileSync(path.join(tmpDir, ".gitmodules"), "");
const runGitCommandStub = sinon
.stub(gitUtils as any, "runGitCommand")
.callsFake(async (_cwd: any, args: any) => {
if (args[0] === "rev-parse") {
return `${tmpDir}\n`;
}
return (
"100644 30d998ded095371488be3a729eb61d86ed721a18 0\tlib/git-utils.js\n" +
"100644 d89514599a9a99f22b4085766d40af7b99974827 0\tlib/git-utils.js.map\n" +
"100644 a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96 0\tsrc/git-utils.ts"
);
});
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
t.deepEqual(result, {
"lib/git-utils.js": "30d998ded095371488be3a729eb61d86ed721a18",
"lib/git-utils.js.map": "d89514599a9a99f22b4085766d40af7b99974827",
"src/git-utils.ts": "a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96",
});
t.deepEqual(result, {
"lib/git-utils.js": "30d998ded095371488be3a729eb61d86ed721a18",
"lib/git-utils.js.map": "d89514599a9a99f22b4085766d40af7b99974827",
"src/git-utils.ts": "a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96",
});
t.deepEqual(runGitCommandStub.firstCall.args, [
"/fake/path",
["ls-files", "--recurse-submodules", "--format=%(objectname)_%(path)"],
"Cannot list Git OIDs of tracked files.",
]);
});
// Second call (after getGitRoot) should include --recurse-submodules
t.deepEqual(runGitCommandStub.secondCall.args[1], [
"ls-files",
"--recurse-submodules",
"--stage",
]);
});
},
);
test.serial(
"getFileOidsUnderPath omits --recurse-submodules when no submodules exist",
async (t) => {
await withTmpDir(async (tmpDir) => {
const runGitCommandStub = sinon
.stub(gitUtils as any, "runGitCommand")
.callsFake(async (_cwd: any, args: any) => {
if (args[0] === "rev-parse") {
return `${tmpDir}\n`;
}
return (
"100644 30d998ded095371488be3a729eb61d86ed721a18 0\tlib/git-utils.js\n" +
"100644 a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96 0\tsrc/git-utils.ts"
);
});
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
t.deepEqual(result, {
"lib/git-utils.js": "30d998ded095371488be3a729eb61d86ed721a18",
"src/git-utils.ts": "a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96",
});
// Second call (after getGitRoot) should NOT include --recurse-submodules
t.deepEqual(runGitCommandStub.secondCall.args[1], [
"ls-files",
"--stage",
]);
});
},
);
test.serial("getFileOidsUnderPath handles quoted paths", async (t) => {
sinon
.stub(gitUtils as any, "runGitCommand")
.resolves(
"30d998ded095371488be3a729eb61d86ed721a18_lib/normal-file.js\n" +
'd89514599a9a99f22b4085766d40af7b99974827_"lib/file with spaces.js"\n' +
'a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96_"lib/file\\twith\\ttabs.js"',
);
await withTmpDir(async (tmpDir) => {
sinon
.stub(gitUtils as any, "runGitCommand")
.callsFake(async (_cwd: any, args: any) => {
if (args[0] === "rev-parse") {
return `${tmpDir}\n`;
}
return (
"100644 30d998ded095371488be3a729eb61d86ed721a18 0\tlib/normal-file.js\n" +
'100644 d89514599a9a99f22b4085766d40af7b99974827 0\t"lib/file with spaces.js"\n' +
'100644 a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96 0\t"lib/file\\twith\\ttabs.js"'
);
});
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
t.deepEqual(result, {
"lib/normal-file.js": "30d998ded095371488be3a729eb61d86ed721a18",
"lib/file with spaces.js": "d89514599a9a99f22b4085766d40af7b99974827",
"lib/file\twith\ttabs.js": "a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96",
t.deepEqual(result, {
"lib/normal-file.js": "30d998ded095371488be3a729eb61d86ed721a18",
"lib/file with spaces.js": "d89514599a9a99f22b4085766d40af7b99974827",
"lib/file\twith\ttabs.js": "a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96",
});
});
});
test.serial("getFileOidsUnderPath handles empty output", async (t) => {
sinon.stub(gitUtils as any, "runGitCommand").resolves("");
await withTmpDir(async (tmpDir) => {
sinon
.stub(gitUtils as any, "runGitCommand")
.callsFake(async (_cwd: any, args: any) => {
if (args[0] === "rev-parse") {
return `${tmpDir}\n`;
}
return "";
});
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
t.deepEqual(result, {});
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
t.deepEqual(result, {});
});
});
test.serial(
"getFileOidsUnderPath throws on unexpected output format",
async (t) => {
sinon
.stub(gitUtils as any, "runGitCommand")
.resolves(
"30d998ded095371488be3a729eb61d86ed721a18_lib/git-utils.js\n" +
"invalid-line-format\n" +
"a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96_src/git-utils.ts",
);
await withTmpDir(async (tmpDir) => {
sinon
.stub(gitUtils as any, "runGitCommand")
.callsFake(async (_cwd: any, args: any) => {
if (args[0] === "rev-parse") {
return `${tmpDir}\n`;
}
return (
"100644 30d998ded095371488be3a729eb61d86ed721a18 0\tlib/git-utils.js\n" +
"invalid-line-format\n" +
"100644 a47c11f5bfdca7661942d2c8f1b7209fb0dfdf96 0\tsrc/git-utils.ts"
);
});
await t.throwsAsync(
async () => {
await gitUtils.getFileOidsUnderPath("/fake/path");
},
{
instanceOf: Error,
message: 'Unexpected "git ls-files" output: invalid-line-format',
},
);
await t.throwsAsync(
async () => {
await gitUtils.getFileOidsUnderPath("/fake/path");
},
{
instanceOf: Error,
message: 'Unexpected "git ls-files" output: invalid-line-format',
},
);
});
},
);
+38 -11
View File
@@ -1,4 +1,6 @@
import * as fs from "fs";
import * as os from "os";
import * as path from "path";
import * as core from "@actions/core";
import { ExecOptions } from "@actions/exec";
@@ -14,10 +16,11 @@ import {
import { ConfigurationError, getRequiredEnvParam } from "./util";
/**
* Minimum Git version required for overlay analysis. The `git ls-files --format`
* option, which is used by `getFileOidsUnderPath`, was introduced in Git 2.38.0.
* Minimum Git version required for overlay analysis in repositories that
* contain submodules. Support for using the `git ls-files
* --recurse-submodules` option with `--stage` was added in Git 2.36.0.
*/
export const GIT_MINIMUM_VERSION_FOR_OVERLAY = "2.38.0";
export const GIT_MINIMUM_VERSION_FOR_OVERLAY_WITH_SUBMODULES = "2.36.0";
/**
* Git version information
@@ -244,6 +247,16 @@ export const getGitRoot = async function (
}
};
/**
* Returns true if the Git repository has submodules registered (i.e. a
* `.gitmodules` file exists at the repository root).
*
* @param gitRoot The root of the Git repository.
*/
export function hasSubmodules(gitRoot: string): boolean {
return fs.existsSync(path.join(gitRoot, ".gitmodules"));
}
/**
* Returns the Git OIDs of all tracked files (in the index and in the working
* tree) that are under the given base path, including files in active
@@ -252,31 +265,45 @@ export const getGitRoot = async function (
*
* @param basePath A path into the Git repository.
* @returns a map from file paths (relative to `basePath`) to Git OIDs.
* @throws {Error} if "git ls-tree" produces unexpected output.
* @throws {Error} if "git ls-files" produces unexpected output.
*/
export const getFileOidsUnderPath = async function (
basePath: string,
): Promise<{ [key: string]: string }> {
// Without the --full-name flag, the path is relative to the current working
// directory of the git command, which is basePath.
//
// We use --stage rather than --format here because --format was only
// introduced in Git 2.38.0, which would limit overlay rollout.
//
// We only pass --recurse-submodules when the repository actually has
// submodules, because the combination of --recurse-submodules and --stage is
// only supported since Git 2.36.0.
const gitRoot = await getGitRoot(basePath);
const mayHaveSubmodules =
gitRoot === undefined ? true : hasSubmodules(gitRoot);
const args = mayHaveSubmodules
? ["ls-files", "--recurse-submodules", "--stage"]
: ["ls-files", "--stage"];
const stdout = await runGitCommand(
basePath,
["ls-files", "--recurse-submodules", "--format=%(objectname)_%(path)"],
args,
"Cannot list Git OIDs of tracked files.",
);
const fileOidMap: { [key: string]: string } = {};
// With --format=%(objectname)_%(path), the output is a list of lines like:
// 30d998ded095371488be3a729eb61d86ed721a18_lib/git-utils.js
// d89514599a9a99f22b4085766d40af7b99974827_lib/git-utils.js.map
const regex = /^([0-9a-f]{40})_(.+)$/;
// With --stage, the output is a list of lines like:
// 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(.+)$/;
for (const line of stdout.split("\n")) {
if (line) {
const match = line.match(regex);
if (match) {
const oid = match[1];
const path = decodeGitFilePath(match[2]);
fileOidMap[path] = oid;
const filePath = decodeGitFilePath(match[2]);
fileOidMap[filePath] = oid;
} else {
throw new Error(`Unexpected "git ls-files" output: ${line}`);
}
+1 -1
View File
@@ -12,7 +12,7 @@ import { EnvVar } from "./environment";
import { Feature } from "./feature-flags";
import * as initActionPostHelper from "./init-action-post-helper";
import { getRunnerLogger } from "./logging";
import { OverlayDatabaseMode } from "./overlay";
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
import * as overlayStatus from "./overlay/status";
import { parseRepositoryNwo } from "./repository";
import {
+1 -1
View File
@@ -21,7 +21,7 @@ import * as dependencyCaching from "./dependency-caching";
import { EnvVar } from "./environment";
import { Feature, FeatureEnablement } from "./feature-flags";
import { Logger } from "./logging";
import { OverlayDatabaseMode } from "./overlay";
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
import {
createOverlayStatus,
OverlayStatus,
+54 -33
View File
@@ -37,6 +37,11 @@ import {
makeDiagnostic,
makeTelemetryDiagnostic,
} from "./diagnostics";
import {
getDiffInformedAnalysisBranches,
getPullRequestEditedDiffRanges,
writeDiffRangesJsonFile,
} from "./diff-informed-analysis-utils";
import { EnvVar } from "./environment";
import { Feature, FeatureEnablement, initFeatures } from "./feature-flags";
import {
@@ -54,12 +59,12 @@ import {
runDatabaseInitCluster,
} from "./init";
import { JavaEnvVars, KnownLanguage } from "./languages";
import { getActionsLogger, Logger } from "./logging";
import { getActionsLogger, Logger, withGroupAsync } from "./logging";
import {
downloadOverlayBaseDatabaseFromCache,
OverlayBaseDatabaseDownloadStats,
OverlayDatabaseMode,
} from "./overlay";
} from "./overlay/caching";
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
import { getRepositoryNwo, RepositoryNwo } from "./repository";
import { ToolsSource } from "./setup-codeql";
import {
@@ -384,6 +389,15 @@ async function run(startedAt: Date) {
logger,
});
if (
config.languages.includes(KnownLanguage.swift) &&
process.platform !== "darwin"
) {
throw new ConfigurationError(
`Swift analysis is only supported on macOS runner images. Please migrate to a macOS runner.`,
);
}
if (repositoryPropertiesResult.isFailure()) {
addNoLanguageDiagnostic(
config,
@@ -413,6 +427,7 @@ async function run(startedAt: Date) {
}
await checkInstallPython311(config.languages, codeql);
await computeAndPersistDiffRanges(codeql, features, logger);
} catch (unwrappedError) {
const error = wrapError(unwrappedError);
core.setFailed(error.message);
@@ -493,15 +508,6 @@ async function run(startedAt: Date) {
);
}
if (
config.languages.includes(KnownLanguage.swift) &&
process.platform === "linux"
) {
logger.warning(
`Swift analysis on Ubuntu runner images is no longer supported. Please migrate to a macOS runner if this affects you.`,
);
}
if (
config.languages.includes(KnownLanguage.go) &&
process.platform === "linux"
@@ -639,27 +645,6 @@ async function run(startedAt: Date) {
);
}
if (
await codeql.supportsFeature(
ToolsFeature.PythonDefaultIsToNotExtractStdlib,
)
) {
if (process.env["CODEQL_EXTRACTOR_PYTHON_EXTRACT_STDLIB"]) {
logger.debug(
"CODEQL_EXTRACTOR_PYTHON_EXTRACT_STDLIB is already set, so the Action will not override it.",
);
} else if (
!(await features.getValue(
Feature.PythonDefaultIsToNotExtractStdlib,
codeql,
))
) {
// We are in a situation where the feature flag is not rolled out,
// so we need to suppress the new default CLI behavior.
core.exportVariable("CODEQL_EXTRACTOR_PYTHON_EXTRACT_STDLIB", "true");
}
}
// If we are doing a Java `build-mode: none` analysis, then set the environment variable that
// enables the option in the Java extractor to minimize dependency jars. We also only do this if
// dependency caching is enabled, since the option is intended to reduce the size of dependency
@@ -833,6 +818,42 @@ async function loadRepositoryProperties(
}
}
/**
* Compute and persist diff ranges when diff-informed analysis is enabled
* (feature flag + PR context). This writes the standard pr-diff-range.json
* file for later reuse in the analyze step. Failures are logged but non-fatal.
*/
async function computeAndPersistDiffRanges(
codeql: CodeQL,
features: FeatureEnablement,
logger: Logger,
): Promise<void> {
await withGroupAsync("Computing PR diff ranges", async () => {
try {
const branches = await getDiffInformedAnalysisBranches(
codeql,
features,
logger,
);
if (!branches) {
return;
}
const ranges = await getPullRequestEditedDiffRanges(branches, logger);
if (ranges === undefined) {
return;
}
writeDiffRangesJsonFile(logger, ranges);
const distinctFiles = new Set(ranges.map((r) => r.path)).size;
logger.info(
`Persisted ${ranges.length} diff range(s) across ${distinctFiles} file(s).`,
);
} catch (e) {
logger.warning(
`Failed to compute and persist PR diff ranges: ${getErrorMessage(e)}`,
);
}
});
}
async function recordZstdAvailability(
config: configUtils.Config,
zstdAvailability: ZstdAvailability,
+11
View File
@@ -0,0 +1,11 @@
{
"c": "cpp",
"c#": "csharp",
"c++": "cpp",
"c-c++": "cpp",
"c-cpp": "cpp",
"java-kotlin": "java",
"javascript-typescript": "javascript",
"kotlin": "java",
"typescript": "javascript"
}
+287
View File
@@ -0,0 +1,287 @@
import * as fs from "fs";
import * as path from "path";
import * as actionsCache from "@actions/cache";
import test from "ava";
import * as sinon from "sinon";
import * as actionsUtil from "../actions-util";
import * as apiClient from "../api-client";
import { ResolveDatabaseOutput } from "../codeql";
import * as gitUtils from "../git-utils";
import { KnownLanguage } from "../languages";
import { getRunnerLogger } from "../logging";
import {
createTestConfig,
mockCodeQLVersion,
setupTests,
} from "../testing-utils";
import * as utils from "../util";
import { withTmpDir } from "../util";
import {
downloadOverlayBaseDatabaseFromCache,
getCacheRestoreKeyPrefix,
getCacheSaveKey,
} from "./caching";
import { OverlayDatabaseMode } from "./overlay-database-mode";
setupTests(test);
interface DownloadOverlayBaseDatabaseTestCase {
overlayDatabaseMode: OverlayDatabaseMode;
useOverlayDatabaseCaching: boolean;
isInTestMode: boolean;
restoreCacheResult: string | undefined | Error;
hasBaseDatabaseOidsFile: boolean;
tryGetFolderBytesSucceeds: boolean;
codeQLVersion: string;
resolveDatabaseOutput: ResolveDatabaseOutput | Error;
}
const defaultDownloadTestCase: DownloadOverlayBaseDatabaseTestCase = {
overlayDatabaseMode: OverlayDatabaseMode.Overlay,
useOverlayDatabaseCaching: true,
isInTestMode: false,
restoreCacheResult: "cache-key",
hasBaseDatabaseOidsFile: true,
tryGetFolderBytesSucceeds: true,
codeQLVersion: "2.20.5",
resolveDatabaseOutput: { overlayBaseSpecifier: "20250626:XXX" },
};
const testDownloadOverlayBaseDatabaseFromCache = test.macro({
exec: async (
t,
_title: string,
partialTestCase: Partial<DownloadOverlayBaseDatabaseTestCase>,
expectDownloadSuccess: boolean,
) => {
await withTmpDir(async (tmpDir) => {
const dbLocation = path.join(tmpDir, "db");
await fs.promises.mkdir(dbLocation, { recursive: true });
const logger = getRunnerLogger(true);
const testCase = { ...defaultDownloadTestCase, ...partialTestCase };
const config = createTestConfig({
dbLocation,
languages: [KnownLanguage.java],
});
config.overlayDatabaseMode = testCase.overlayDatabaseMode;
config.useOverlayDatabaseCaching = testCase.useOverlayDatabaseCaching;
if (testCase.hasBaseDatabaseOidsFile) {
const baseDatabaseOidsFile = path.join(
dbLocation,
"base-database-oids.json",
);
await fs.promises.writeFile(baseDatabaseOidsFile, JSON.stringify({}));
}
const stubs: sinon.SinonStub[] = [];
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);
if (testCase.restoreCacheResult instanceof Error) {
const restoreCacheStub = sinon
.stub(actionsCache, "restoreCache")
.rejects(testCase.restoreCacheResult);
stubs.push(restoreCacheStub);
} else {
const restoreCacheStub = sinon
.stub(actionsCache, "restoreCache")
.resolves(testCase.restoreCacheResult);
stubs.push(restoreCacheStub);
}
const tryGetFolderBytesStub = 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
.stub(codeql, "resolveDatabase")
.rejects(testCase.resolveDatabaseOutput);
stubs.push(resolveDatabaseStub);
} else {
const resolveDatabaseStub = sinon
.stub(codeql, "resolveDatabase")
.resolves(testCase.resolveDatabaseOutput);
stubs.push(resolveDatabaseStub);
}
try {
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();
}
}
});
},
title: (_, title) => `downloadOverlayBaseDatabaseFromCache: ${title}`,
});
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns stats when successful",
{},
true,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when mode is OverlayDatabaseMode.OverlayBase",
{
overlayDatabaseMode: OverlayDatabaseMode.OverlayBase,
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when mode is OverlayDatabaseMode.None",
{
overlayDatabaseMode: OverlayDatabaseMode.None,
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when caching is disabled",
{
useOverlayDatabaseCaching: false,
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined in test mode",
{
isInTestMode: true,
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when cache miss",
{
restoreCacheResult: undefined,
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when download fails",
{
restoreCacheResult: new Error("Download failed"),
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when downloaded database is invalid",
{
hasBaseDatabaseOidsFile: false,
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when downloaded database doesn't have an overlayBaseSpecifier",
{
resolveDatabaseOutput: {},
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when resolving database metadata fails",
{
resolveDatabaseOutput: new Error("Failed to resolve database metadata"),
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when filesystem error occurs",
{
tryGetFolderBytesSucceeds: false,
},
false,
);
test.serial("overlay-base database cache keys remain stable", async (t) => {
const logger = getRunnerLogger(true);
const config = createTestConfig({ languages: ["python", "javascript"] });
const codeQlVersion = "2.23.0";
const commitOid = "abc123def456";
sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/");
sinon.stub(gitUtils, "getCommitOid").resolves(commitOid);
sinon.stub(actionsUtil, "getWorkflowRunID").returns(12345);
sinon.stub(actionsUtil, "getWorkflowRunAttempt").returns(1);
const saveKey = await getCacheSaveKey(
config,
codeQlVersion,
"checkout-path",
logger,
);
const expectedSaveKey =
"codeql-overlay-base-database-1-c5666c509a2d9895-javascript_python-2.23.0-abc123def456-12345-1";
t.is(
saveKey,
expectedSaveKey,
"Cache save key changed unexpectedly. " +
"This may indicate breaking changes in the cache key generation logic.",
);
const restoreKeyPrefix = await getCacheRestoreKeyPrefix(
config,
codeQlVersion,
);
const expectedRestoreKeyPrefix =
"codeql-overlay-base-database-1-c5666c509a2d9895-javascript_python-2.23.0-";
t.is(
restoreKeyPrefix,
expectedRestoreKeyPrefix,
"Cache restore key prefix changed unexpectedly. " +
"This may indicate breaking changes in the cache key generation logic.",
);
t.true(
saveKey.startsWith(restoreKeyPrefix),
`Expected save key "${saveKey}" to start with restore key prefix "${restoreKeyPrefix}"`,
);
});
+428
View File
@@ -0,0 +1,428 @@
import * as fs from "fs";
import * as actionsCache from "@actions/cache";
import {
getRequiredInput,
getWorkflowRunAttempt,
getWorkflowRunID,
} from "../actions-util";
import { getAutomationID } from "../api-client";
import { createCacheKeyHash } from "../caching-utils";
import { type CodeQL } from "../codeql";
import { type Config } from "../config-utils";
import { getCommitOid } from "../git-utils";
import { Logger, withGroupAsync } from "../logging";
import {
CleanupLevel,
getBaseDatabaseOidsFilePath,
getCodeQLDatabasePath,
getErrorMessage,
isInTestMode,
tryGetFolderBytes,
waitForResultWithTimeLimit,
} from "../util";
import { OverlayDatabaseMode } from "./overlay-database-mode";
/**
* The maximum (uncompressed) size of the overlay base database that we will
* upload. By default, the Actions Cache has an overall capacity of 10 GB, and
* the Actions Cache client library uses zstd compression.
*
* Ideally we would apply a size limit to the compressed overlay-base database,
* but we cannot do so because compression is handled transparently by the
* Actions Cache client library. Instead we place a limit on the uncompressed
* size of the overlay-base database.
*
* Assuming 2.5:1 compression ratio, the 7.5 GB limit on uncompressed data would
* translate to a limit of around 3 GB after compression.
*/
const OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500;
const OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES =
OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1_000_000;
// Constants for database caching
const CACHE_VERSION = 1;
const CACHE_PREFIX = "codeql-overlay-base-database";
// The purpose of this ten-minute limit is to guard against the possibility
// that the cache service is unresponsive, which would otherwise cause the
// entire action to hang. Normally we expect cache operations to complete
// within two minutes.
const MAX_CACHE_OPERATION_MS = 600_000;
/**
* Checks that the overlay-base database is valid by checking for the
* existence of the base database OIDs file.
*
* @param config The configuration object
* @param logger The logger instance
* @param warningPrefix Prefix for the check failure warning message
* @returns True if the verification succeeded, false otherwise
*/
async function checkOverlayBaseDatabase(
codeql: CodeQL,
config: Config,
logger: Logger,
warningPrefix: string,
): Promise<boolean> {
// An overlay-base database should contain the base database OIDs file.
const baseDatabaseOidsFilePath = getBaseDatabaseOidsFilePath(config);
if (!fs.existsSync(baseDatabaseOidsFilePath)) {
logger.warning(
`${warningPrefix}: ${baseDatabaseOidsFilePath} does not exist`,
);
return false;
}
for (const language of config.languages) {
const dbPath = getCodeQLDatabasePath(config, language);
try {
const resolveDatabaseOutput = await codeql.resolveDatabase(dbPath);
if (
resolveDatabaseOutput === undefined ||
!("overlayBaseSpecifier" in resolveDatabaseOutput)
) {
logger.info(`${warningPrefix}: no overlayBaseSpecifier defined`);
return false;
} else {
logger.debug(
`Overlay base specifier for ${language} overlay-base database found: ` +
`${resolveDatabaseOutput.overlayBaseSpecifier}`,
);
}
} catch (e) {
logger.warning(`${warningPrefix}: failed to resolve database: ${e}`);
return false;
}
}
return true;
}
/**
* Uploads the overlay-base database to the GitHub Actions cache. If conditions
* for uploading are not met, the function does nothing and returns false.
*
* This function uses the `checkout_path` input to determine the repository path
* and works only when called from `analyze` or `upload-sarif`.
*
* @param codeql The CodeQL instance
* @param config The configuration object
* @param logger The logger instance
* @returns A promise that resolves to true if the upload was performed and
* successfully completed, or false otherwise
*/
export async function cleanupAndUploadOverlayBaseDatabaseToCache(
codeql: CodeQL,
config: Config,
logger: Logger,
): Promise<boolean> {
const overlayDatabaseMode = config.overlayDatabaseMode;
if (overlayDatabaseMode !== OverlayDatabaseMode.OverlayBase) {
logger.debug(
`Overlay database mode is ${overlayDatabaseMode}. ` +
"Skip uploading overlay-base database to cache.",
);
return false;
}
if (!config.useOverlayDatabaseCaching) {
logger.debug(
"Overlay database caching is disabled. " +
"Skip uploading overlay-base database to cache.",
);
return false;
}
if (isInTestMode()) {
logger.debug(
"In test mode. Skip uploading overlay-base database to cache.",
);
return false;
}
const databaseIsValid = await checkOverlayBaseDatabase(
codeql,
config,
logger,
"Abort uploading overlay-base database to cache",
);
if (!databaseIsValid) {
return false;
}
// Clean up the database using the overlay cleanup level.
await withGroupAsync("Cleaning up databases", async () => {
await codeql.databaseCleanupCluster(config, CleanupLevel.Overlay);
});
const dbLocation = config.dbLocation;
const databaseSizeBytes = await tryGetFolderBytes(dbLocation, logger);
if (databaseSizeBytes === undefined) {
logger.warning(
"Failed to determine database size. " +
"Skip uploading overlay-base database to cache.",
);
return false;
}
if (databaseSizeBytes > OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES) {
const databaseSizeMB = Math.round(databaseSizeBytes / 1_000_000);
logger.warning(
`Database size (${databaseSizeMB} MB) ` +
`exceeds maximum upload size (${OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB} MB). ` +
"Skip uploading overlay-base database to cache.",
);
return false;
}
const codeQlVersion = (await codeql.getVersion()).version;
const checkoutPath = getRequiredInput("checkout_path");
const cacheSaveKey = await getCacheSaveKey(
config,
codeQlVersion,
checkoutPath,
logger,
);
logger.info(
`Uploading overlay-base database to Actions cache with key ${cacheSaveKey}`,
);
try {
const cacheId = await waitForResultWithTimeLimit(
MAX_CACHE_OPERATION_MS,
actionsCache.saveCache([dbLocation], cacheSaveKey),
() => {},
);
if (cacheId === undefined) {
logger.warning("Timed out while uploading overlay-base database");
return false;
}
} catch (error) {
logger.warning(
"Failed to upload overlay-base database to cache: " +
`${error instanceof Error ? error.message : String(error)}`,
);
return false;
}
logger.info(`Successfully uploaded overlay-base database from ${dbLocation}`);
return true;
}
export interface OverlayBaseDatabaseDownloadStats {
databaseSizeBytes: number;
databaseDownloadDurationMs: number;
}
/**
* Downloads the overlay-base database from the GitHub Actions cache. If conditions
* for downloading are not met, the function does nothing and returns false.
*
* @param codeql The CodeQL instance
* @param config The configuration object
* @param logger The logger instance
* @returns A promise that resolves to download statistics if an overlay-base
* database was successfully downloaded, or undefined if the download was
* either not performed or failed.
*/
export async function downloadOverlayBaseDatabaseFromCache(
codeql: CodeQL,
config: Config,
logger: Logger,
): Promise<OverlayBaseDatabaseDownloadStats | undefined> {
const overlayDatabaseMode = config.overlayDatabaseMode;
if (overlayDatabaseMode !== OverlayDatabaseMode.Overlay) {
logger.debug(
`Overlay database mode is ${overlayDatabaseMode}. ` +
"Skip downloading overlay-base database from cache.",
);
return undefined;
}
if (!config.useOverlayDatabaseCaching) {
logger.debug(
"Overlay database caching is disabled. " +
"Skip downloading overlay-base database from cache.",
);
return undefined;
}
if (isInTestMode()) {
logger.debug(
"In test mode. Skip downloading overlay-base database from cache.",
);
return undefined;
}
const dbLocation = config.dbLocation;
const codeQlVersion = (await codeql.getVersion()).version;
const cacheRestoreKeyPrefix = await getCacheRestoreKeyPrefix(
config,
codeQlVersion,
);
logger.info(
"Looking in Actions cache for overlay-base database with " +
`restore key ${cacheRestoreKeyPrefix}`,
);
let databaseDownloadDurationMs = 0;
try {
const databaseDownloadStart = performance.now();
const foundKey = await waitForResultWithTimeLimit(
// This ten-minute limit for the cache restore operation is mainly to
// guard against the possibility that the cache service is unresponsive
// and hangs outside the data download.
//
// Data download (which is normally the most time-consuming part of the
// restore operation) should not run long enough to hit this limit. Even
// for an extremely large 10GB database, at a download speed of 40MB/s
// (see below), the download should complete within five minutes. If we
// do hit this limit, there are likely more serious problems other than
// mere slow download speed.
//
// This is important because we don't want any ongoing file operations
// on the database directory when we do hit this limit. Hitting this
// time limit takes us to a fallback path where we re-initialize the
// database from scratch at dbLocation, and having the cache restore
// operation continue to write into dbLocation in the background would
// really mess things up. We want to hit this limit only in the case
// of a hung cache service, not just slow download speed.
MAX_CACHE_OPERATION_MS,
actionsCache.restoreCache(
[dbLocation],
cacheRestoreKeyPrefix,
undefined,
{
// Azure SDK download (which is the default) uses 128MB segments; see
// https://github.com/actions/toolkit/blob/main/packages/cache/README.md.
// Setting segmentTimeoutInMs to 3000 translates to segment download
// speed of about 40 MB/s, which should be achievable unless the
// download is unreliable (in which case we do want to abort).
segmentTimeoutInMs: 3000,
},
),
() => {
logger.info("Timed out downloading overlay-base database from cache");
},
);
databaseDownloadDurationMs = Math.round(
performance.now() - databaseDownloadStart,
);
if (foundKey === undefined) {
logger.info("No overlay-base database found in Actions cache");
return undefined;
}
logger.info(
`Downloaded overlay-base database in cache with key ${foundKey}`,
);
} catch (error) {
logger.warning(
"Failed to download overlay-base database from cache: " +
`${error instanceof Error ? error.message : String(error)}`,
);
return undefined;
}
const databaseIsValid = await checkOverlayBaseDatabase(
codeql,
config,
logger,
"Downloaded overlay-base database is invalid",
);
if (!databaseIsValid) {
logger.warning("Downloaded overlay-base database failed validation");
return undefined;
}
const databaseSizeBytes = await tryGetFolderBytes(dbLocation, logger);
if (databaseSizeBytes === undefined) {
logger.info(
"Filesystem error while accessing downloaded overlay-base database",
);
// The problem that warrants reporting download failure is not that we are
// unable to determine the size of the database. Rather, it is that we
// encountered a filesystem error while accessing the database, which
// indicates that an overlay analysis will likely fail.
return undefined;
}
logger.info(`Successfully downloaded overlay-base database to ${dbLocation}`);
return {
databaseSizeBytes: Math.round(databaseSizeBytes),
databaseDownloadDurationMs,
};
}
/**
* Computes the cache key for saving the overlay-base database to the GitHub
* Actions cache.
*
* The key consists of the restore key prefix (which does not include the
* commit SHA) and the commit SHA of the current checkout.
*/
export async function getCacheSaveKey(
config: Config,
codeQlVersion: string,
checkoutPath: string,
logger: Logger,
): Promise<string> {
let runId = 1;
let attemptId = 1;
try {
runId = getWorkflowRunID();
attemptId = getWorkflowRunAttempt();
} catch (e) {
logger.warning(
`Failed to get workflow run ID or attempt ID. Reason: ${getErrorMessage(e)}`,
);
}
const sha = await getCommitOid(checkoutPath);
const restoreKeyPrefix = await getCacheRestoreKeyPrefix(
config,
codeQlVersion,
);
return `${restoreKeyPrefix}${sha}-${runId}-${attemptId}`;
}
/**
* Computes the cache key prefix for restoring the overlay-base database from
* the GitHub Actions cache.
*
* Actions cache supports using multiple restore keys to indicate preference,
* and this function could in principle take advantage of that feature by
* returning a list of restore key prefixes. However, since overlay-base
* databases are built from the default branch and used in PR analysis, it is
* exceedingly unlikely that the commit SHA will ever be the same.
*
* Therefore, this function returns only a single restore key prefix, which does
* not include the commit SHA. This allows us to restore the most recent
* compatible overlay-base database.
*/
export async function getCacheRestoreKeyPrefix(
config: Config,
codeQlVersion: string,
): Promise<string> {
const languages = [...config.languages].sort().join("_");
const cacheKeyComponents = {
automationID: await getAutomationID(),
// Add more components here as needed in the future
};
const componentsHash = createCacheKeyHash(cacheKeyComponents);
// For a cached overlay-base database to be considered compatible for overlay
// analysis, all components in the cache restore key must match:
//
// CACHE_PREFIX: distinguishes overlay-base databases from other cache objects
// CACHE_VERSION: cache format version
// componentsHash: hash of additional components (see above for details)
// languages: the languages included in the overlay-base database
// codeQlVersion: CodeQL bundle version
//
// Technically we can also include languages and codeQlVersion in the
// componentsHash, but including them explicitly in the cache key makes it
// easier to debug and understand the cache key structure.
return `${CACHE_PREFIX}-${CACHE_VERSION}-${componentsHash}-${languages}-${codeQlVersion}-`;
}
+237 -259
View File
@@ -1,32 +1,16 @@
import * as fs from "fs";
import * as path from "path";
import * as actionsCache from "@actions/cache";
import test from "ava";
import * as sinon from "sinon";
import * as actionsUtil from "../actions-util";
import * as apiClient from "../api-client";
import { ResolveDatabaseOutput } from "../codeql";
import * as gitUtils from "../git-utils";
import { KnownLanguage } from "../languages";
import { getRunnerLogger } from "../logging";
import {
createTestConfig,
mockCodeQLVersion,
setupTests,
} from "../testing-utils";
import * as utils from "../util";
import { createTestConfig, setupTests } from "../testing-utils";
import { withTmpDir } from "../util";
import {
downloadOverlayBaseDatabaseFromCache,
getCacheRestoreKeyPrefix,
getCacheSaveKey,
OverlayDatabaseMode,
writeBaseDatabaseOidsFile,
writeOverlayChangesFile,
} from ".";
import { writeBaseDatabaseOidsFile, writeOverlayChangesFile } from ".";
setupTests(test);
@@ -34,12 +18,14 @@ test.serial(
"writeOverlayChangesFile generates correct changes file",
async (t) => {
await withTmpDir(async (tmpDir) => {
const dbLocation = path.join(tmpDir, "db");
await fs.promises.mkdir(dbLocation, { recursive: true });
const sourceRoot = path.join(tmpDir, "src");
await fs.promises.mkdir(sourceRoot, { recursive: true });
const tempDir = path.join(tmpDir, "temp");
await fs.promises.mkdir(tempDir, { recursive: true });
const [dbLocation, sourceRoot, tempDir] = ["db", "src", "temp"].map((d) =>
path.join(tmpDir, d),
);
await Promise.all(
[dbLocation, sourceRoot, tempDir].map((d) =>
fs.promises.mkdir(d, { recursive: true }),
),
);
const logger = getRunnerLogger(true);
const config = createTestConfig({ dbLocation });
@@ -70,9 +56,16 @@ test.serial(
// 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
.stub(actionsUtil, "getDiffRangesJsonFilePath")
.returns(diffRangeFilePath);
const getGitRootStub = sinon
.stub(gitUtils, "getGitRoot")
.resolves(sourceRoot);
const changesFilePath = await writeOverlayChangesFile(
config,
sourceRoot,
@@ -80,6 +73,8 @@ test.serial(
);
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[] };
@@ -93,260 +88,243 @@ test.serial(
},
);
interface DownloadOverlayBaseDatabaseTestCase {
overlayDatabaseMode: OverlayDatabaseMode;
useOverlayDatabaseCaching: boolean;
isInTestMode: boolean;
restoreCacheResult: string | undefined | Error;
hasBaseDatabaseOidsFile: boolean;
tryGetFolderBytesSucceeds: boolean;
codeQLVersion: string;
resolveDatabaseOutput: ResolveDatabaseOutput | Error;
}
const defaultDownloadTestCase: DownloadOverlayBaseDatabaseTestCase = {
overlayDatabaseMode: OverlayDatabaseMode.Overlay,
useOverlayDatabaseCaching: true,
isInTestMode: false,
restoreCacheResult: "cache-key",
hasBaseDatabaseOidsFile: true,
tryGetFolderBytesSucceeds: true,
codeQLVersion: "2.20.5",
resolveDatabaseOutput: { overlayBaseSpecifier: "20250626:XXX" },
};
const testDownloadOverlayBaseDatabaseFromCache = test.macro({
exec: async (
t,
_title: string,
partialTestCase: Partial<DownloadOverlayBaseDatabaseTestCase>,
expectDownloadSuccess: boolean,
) => {
test.serial(
"writeOverlayChangesFile merges additional diff files into overlay changes",
async (t) => {
await withTmpDir(async (tmpDir) => {
const dbLocation = path.join(tmpDir, "db");
await fs.promises.mkdir(dbLocation, { recursive: true });
const [dbLocation, sourceRoot, tempDir] = ["db", "src", "temp"].map((d) =>
path.join(tmpDir, d),
);
await Promise.all(
[dbLocation, sourceRoot, tempDir].map((d) =>
fs.promises.mkdir(d, { recursive: true }),
),
);
const logger = getRunnerLogger(true);
const testCase = { ...defaultDownloadTestCase, ...partialTestCase };
const config = createTestConfig({
dbLocation,
languages: [KnownLanguage.java],
});
const config = createTestConfig({ dbLocation });
config.overlayDatabaseMode = testCase.overlayDatabaseMode;
config.useOverlayDatabaseCaching = testCase.useOverlayDatabaseCaching;
// Mock the getFileOidsUnderPath function to return base OIDs
// "reverted.js" has the same OID in both base and current, simulating
// a revert PR where the file content matches the overlay-base
const baseOids = {
"unchanged.js": "aaa111",
"modified.js": "bbb222",
"reverted.js": "eee555",
};
const getFileOidsStubForBase = sinon
.stub(gitUtils, "getFileOidsUnderPath")
.resolves(baseOids);
if (testCase.hasBaseDatabaseOidsFile) {
const baseDatabaseOidsFile = path.join(
dbLocation,
"base-database-oids.json",
);
await fs.promises.writeFile(baseDatabaseOidsFile, JSON.stringify({}));
}
// Write the base database OIDs file
await writeBaseDatabaseOidsFile(config, sourceRoot);
getFileOidsStubForBase.restore();
const stubs: sinon.SinonStub[] = [];
// Mock the getFileOidsUnderPath function to return overlay OIDs
// "reverted.js" has the same OID as the base -- OID comparison alone
// would NOT include it, only additionalChangedFiles causes it to appear
const currentOids = {
"unchanged.js": "aaa111",
"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);
const getAutomationIDStub = sinon
.stub(apiClient, "getAutomationID")
.resolves("test-automation-id/");
stubs.push(getAutomationIDStub);
const diffRangeFilePath = path.join(tempDir, "pr-diff-range.json");
const getTempDirStub = sinon
.stub(actionsUtil, "getTemporaryDirectory")
.returns(tempDir);
const getDiffRangesStub = sinon
.stub(actionsUtil, "getDiffRangesJsonFilePath")
.returns(diffRangeFilePath);
const getGitRootStub = sinon
.stub(gitUtils, "getGitRoot")
.resolves(sourceRoot);
const isInTestModeStub = sinon
.stub(utils, "isInTestMode")
.returns(testCase.isInTestMode);
stubs.push(isInTestModeStub);
// Write a pr-diff-range.json file with diff ranges including
// "reverted.js" (unchanged OIDs) and "modified.js" (already in OID changes)
await fs.promises.writeFile(
diffRangeFilePath,
JSON.stringify([
{ path: "reverted.js", startLine: 1, endLine: 10 },
{ path: "modified.js", startLine: 1, endLine: 5 },
{ path: "diff-only.js", startLine: 1, endLine: 3 },
]),
);
if (testCase.restoreCacheResult instanceof Error) {
const restoreCacheStub = sinon
.stub(actionsCache, "restoreCache")
.rejects(testCase.restoreCacheResult);
stubs.push(restoreCacheStub);
} else {
const restoreCacheStub = sinon
.stub(actionsCache, "restoreCache")
.resolves(testCase.restoreCacheResult);
stubs.push(restoreCacheStub);
}
const changesFilePath = await writeOverlayChangesFile(
config,
sourceRoot,
logger,
);
getFileOidsStubForOverlay.restore();
getTempDirStub.restore();
getDiffRangesStub.restore();
getGitRootStub.restore();
const tryGetFolderBytesStub = sinon
.stub(utils, "tryGetFolderBytes")
.resolves(testCase.tryGetFolderBytesSucceeds ? 1024 * 1024 : undefined);
stubs.push(tryGetFolderBytesStub);
const fileContent = await fs.promises.readFile(changesFilePath, "utf-8");
const parsedContent = JSON.parse(fileContent) as { changes: string[] };
const codeql = mockCodeQLVersion(testCase.codeQLVersion);
if (testCase.resolveDatabaseOutput instanceof Error) {
const resolveDatabaseStub = sinon
.stub(codeql, "resolveDatabase")
.rejects(testCase.resolveDatabaseOutput);
stubs.push(resolveDatabaseStub);
} else {
const resolveDatabaseStub = sinon
.stub(codeql, "resolveDatabase")
.resolves(testCase.resolveDatabaseOutput);
stubs.push(resolveDatabaseStub);
}
try {
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();
}
}
t.deepEqual(
parsedContent.changes.sort(),
["diff-only.js", "modified.js", "reverted.js"],
"Should include OID-changed files, diff-only files, and deduplicate overlapping files",
);
});
},
title: (_, title) => `downloadOverlayBaseDatabaseFromCache: ${title}`,
});
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns stats when successful",
{},
true,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when mode is OverlayDatabaseMode.OverlayBase",
{
overlayDatabaseMode: OverlayDatabaseMode.OverlayBase,
"writeOverlayChangesFile works without additional diff files",
async (t) => {
await withTmpDir(async (tmpDir) => {
const [dbLocation, sourceRoot, tempDir] = ["db", "src", "temp"].map((d) =>
path.join(tmpDir, d),
);
await Promise.all(
[dbLocation, sourceRoot, tempDir].map((d) =>
fs.promises.mkdir(d, { recursive: true }),
),
);
const logger = getRunnerLogger(true);
const config = createTestConfig({ dbLocation });
// Mock the getFileOidsUnderPath function to return base OIDs
const baseOids = {
"unchanged.js": "aaa111",
"modified.js": "bbb222",
};
const getFileOidsStubForBase = sinon
.stub(gitUtils, "getFileOidsUnderPath")
.resolves(baseOids);
await writeBaseDatabaseOidsFile(config, sourceRoot);
getFileOidsStubForBase.restore();
const currentOids = {
"unchanged.js": "aaa111",
"modified.js": "ddd444",
};
const getFileOidsStubForOverlay = 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
.stub(actionsUtil, "getDiffRangesJsonFilePath")
.returns(diffRangeFilePath);
const getGitRootStub = sinon
.stub(gitUtils, "getGitRoot")
.resolves(sourceRoot);
// No pr-diff-range.json file exists - should work the same as before
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[] };
t.deepEqual(
parsedContent.changes.sort(),
["modified.js"],
"Should only include OID-changed files when no additional files provided",
);
});
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when mode is OverlayDatabaseMode.None",
{
overlayDatabaseMode: OverlayDatabaseMode.None,
"writeOverlayChangesFile converts diff range paths to sourceRoot-relative when sourceRoot is a subdirectory",
async (t) => {
await withTmpDir(async (tmpDir) => {
// Simulate: repo root = tmpDir, sourceRoot = tmpDir/src
const repoRoot = tmpDir;
const sourceRoot = path.join(tmpDir, "src");
const [dbLocation, tempDir] = ["db", "temp"].map((d) =>
path.join(tmpDir, d),
);
await Promise.all(
[dbLocation, sourceRoot, tempDir].map((d) =>
fs.promises.mkdir(d, { recursive: true }),
),
);
const logger = getRunnerLogger(true);
const config = createTestConfig({ dbLocation });
// Base OIDs (sourceRoot-relative paths)
const baseOids = {
"app.js": "aaa111",
"lib/util.js": "bbb222",
};
const getFileOidsStubForBase = sinon
.stub(gitUtils, "getFileOidsUnderPath")
.resolves(baseOids);
await writeBaseDatabaseOidsFile(config, sourceRoot);
getFileOidsStubForBase.restore();
// Current OIDs — same as base (no OID changes)
const currentOids = {
"app.js": "aaa111",
"lib/util.js": "bbb222",
};
const getFileOidsStubForOverlay = 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
.stub(actionsUtil, "getDiffRangesJsonFilePath")
.returns(diffRangeFilePath);
// getGitRoot returns the repo root (parent of sourceRoot)
const getGitRootStub = sinon
.stub(gitUtils, "getGitRoot")
.resolves(repoRoot);
// Diff ranges use repo-root-relative paths (as returned by the GitHub compare API)
await fs.promises.writeFile(
diffRangeFilePath,
JSON.stringify([
{ path: "src/app.js", startLine: 1, endLine: 10 },
{ path: "src/lib/util.js", startLine: 5, endLine: 8 },
{ path: "other/outside.js", startLine: 1, endLine: 3 }, // not under 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[] };
t.deepEqual(
parsedContent.changes.sort(),
["app.js", "lib/util.js"],
"Should convert repo-root-relative paths to sourceRoot-relative and filter out files outside sourceRoot",
);
});
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when caching is disabled",
{
useOverlayDatabaseCaching: false,
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined in test mode",
{
isInTestMode: true,
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when cache miss",
{
restoreCacheResult: undefined,
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when download fails",
{
restoreCacheResult: new Error("Download failed"),
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when downloaded database is invalid",
{
hasBaseDatabaseOidsFile: false,
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when downloaded database doesn't have an overlayBaseSpecifier",
{
resolveDatabaseOutput: {},
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when resolving database metadata fails",
{
resolveDatabaseOutput: new Error("Failed to resolve database metadata"),
},
false,
);
test.serial(
testDownloadOverlayBaseDatabaseFromCache,
"returns undefined when filesystem error occurs",
{
tryGetFolderBytesSucceeds: false,
},
false,
);
test.serial("overlay-base database cache keys remain stable", async (t) => {
const logger = getRunnerLogger(true);
const config = createTestConfig({ languages: ["python", "javascript"] });
const codeQlVersion = "2.23.0";
const commitOid = "abc123def456";
sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/");
sinon.stub(gitUtils, "getCommitOid").resolves(commitOid);
sinon.stub(actionsUtil, "getWorkflowRunID").returns(12345);
sinon.stub(actionsUtil, "getWorkflowRunAttempt").returns(1);
const saveKey = await getCacheSaveKey(
config,
codeQlVersion,
"checkout-path",
logger,
);
const expectedSaveKey =
"codeql-overlay-base-database-1-c5666c509a2d9895-javascript_python-2.23.0-abc123def456-12345-1";
t.is(
saveKey,
expectedSaveKey,
"Cache save key changed unexpectedly. " +
"This may indicate breaking changes in the cache key generation logic.",
);
const restoreKeyPrefix = await getCacheRestoreKeyPrefix(
config,
codeQlVersion,
);
const expectedRestoreKeyPrefix =
"codeql-overlay-base-database-1-c5666c509a2d9895-javascript_python-2.23.0-";
t.is(
restoreKeyPrefix,
expectedRestoreKeyPrefix,
"Cache restore key prefix changed unexpectedly. " +
"This may indicate breaking changes in the cache key generation logic.",
);
t.true(
saveKey.startsWith(restoreKeyPrefix),
`Expected save key "${saveKey}" to start with restore key prefix "${restoreKeyPrefix}"`,
);
});
+60 -416
View File
@@ -1,35 +1,12 @@
import * as fs from "fs";
import * as path from "path";
import * as actionsCache from "@actions/cache";
import {
getRequiredInput,
getTemporaryDirectory,
getWorkflowRunAttempt,
getWorkflowRunID,
} from "../actions-util";
import { getAutomationID } from "../api-client";
import { createCacheKeyHash } from "../caching-utils";
import { type CodeQL } from "../codeql";
import * as actionsUtil from "../actions-util";
import { getOptionalInput, getTemporaryDirectory } from "../actions-util";
import { type Config } from "../config-utils";
import { getCommitOid, getFileOidsUnderPath } from "../git-utils";
import { Logger, withGroupAsync } from "../logging";
import {
CleanupLevel,
getBaseDatabaseOidsFilePath,
getCodeQLDatabasePath,
getErrorMessage,
isInTestMode,
tryGetFolderBytes,
waitForResultWithTimeLimit,
} from "../util";
export enum OverlayDatabaseMode {
Overlay = "overlay",
OverlayBase = "overlay-base",
None = "none",
}
import { getFileOidsUnderPath, getGitRoot } from "../git-utils";
import { Logger } from "../logging";
import { getBaseDatabaseOidsFilePath } from "../util";
export const CODEQL_OVERLAY_MINIMUM_VERSION = "2.23.8";
@@ -43,23 +20,6 @@ export const CODEQL_OVERLAY_MINIMUM_VERSION_JAVASCRIPT = "2.23.9";
export const CODEQL_OVERLAY_MINIMUM_VERSION_PYTHON = "2.23.9";
export const CODEQL_OVERLAY_MINIMUM_VERSION_RUBY = "2.23.9";
/**
* The maximum (uncompressed) size of the overlay base database that we will
* upload. By default, the Actions Cache has an overall capacity of 10 GB, and
* the Actions Cache client library uses zstd compression.
*
* Ideally we would apply a size limit to the compressed overlay-base database,
* but we cannot do so because compression is handled transparently by the
* Actions Cache client library. Instead we place a limit on the uncompressed
* size of the overlay-base database.
*
* Assuming 2.5:1 compression ratio, the 7.5 GB limit on uncompressed data would
* translate to a limit of around 3 GB after compression.
*/
const OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB = 7500;
const OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES =
OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB * 1_000_000;
/**
* Writes a JSON file containing Git OIDs for all tracked files (represented
* by path relative to the source root) under the source root. The file is
@@ -130,11 +90,17 @@ export async function writeOverlayChangesFile(
): Promise<string> {
const baseFileOids = await readBaseDatabaseOidsFile(config, logger);
const overlayFileOids = await getFileOidsUnderPath(sourceRoot);
const changedFiles = computeChangedFiles(baseFileOids, overlayFileOids);
const oidChangedFiles = computeChangedFiles(baseFileOids, overlayFileOids);
logger.info(
`Found ${changedFiles.length} changed file(s) under ${sourceRoot}.`,
`Found ${oidChangedFiles.length} changed file(s) under ${sourceRoot} from OID comparison.`,
);
// Merge in any file paths from precomputed PR diff ranges to ensure the
// overlay always includes all files from the PR diff, even in edge cases
// like revert PRs where OID comparison shows no change.
const diffRangeFiles = await getDiffRangeFilePaths(sourceRoot, logger);
const changedFiles = [...new Set([...oidChangedFiles, ...diffRangeFiles])];
const changedFilesJson = JSON.stringify({ changes: changedFiles });
const overlayChangesFile = path.join(
getTemporaryDirectory(),
@@ -165,387 +131,65 @@ function computeChangedFiles(
return changes;
}
// Constants for database caching
const CACHE_VERSION = 1;
const CACHE_PREFIX = "codeql-overlay-base-database";
// The purpose of this ten-minute limit is to guard against the possibility
// that the cache service is unresponsive, which would otherwise cause the
// entire action to hang. Normally we expect cache operations to complete
// within two minutes.
const MAX_CACHE_OPERATION_MS = 600_000;
/**
* Checks that the overlay-base database is valid by checking for the
* existence of the base database OIDs file.
*
* @param config The configuration object
* @param logger The logger instance
* @param warningPrefix Prefix for the check failure warning message
* @returns True if the verification succeeded, false otherwise
*/
async function checkOverlayBaseDatabase(
codeql: CodeQL,
config: Config,
async function getDiffRangeFilePaths(
sourceRoot: string,
logger: Logger,
warningPrefix: string,
): Promise<boolean> {
// An overlay-base database should contain the base database OIDs file.
const baseDatabaseOidsFilePath = getBaseDatabaseOidsFilePath(config);
if (!fs.existsSync(baseDatabaseOidsFilePath)) {
logger.warning(
`${warningPrefix}: ${baseDatabaseOidsFilePath} does not exist`,
);
return false;
}
): Promise<string[]> {
const jsonFilePath = actionsUtil.getDiffRangesJsonFilePath();
for (const language of config.languages) {
const dbPath = getCodeQLDatabasePath(config, language);
try {
const resolveDatabaseOutput = await codeql.resolveDatabase(dbPath);
if (
resolveDatabaseOutput === undefined ||
!("overlayBaseSpecifier" in resolveDatabaseOutput)
) {
logger.info(`${warningPrefix}: no overlayBaseSpecifier defined`);
return false;
} else {
logger.debug(
`Overlay base specifier for ${language} overlay-base database found: ` +
`${resolveDatabaseOutput.overlayBaseSpecifier}`,
);
}
} catch (e) {
logger.warning(`${warningPrefix}: failed to resolve database: ${e}`);
return false;
}
}
return true;
}
/**
* Uploads the overlay-base database to the GitHub Actions cache. If conditions
* for uploading are not met, the function does nothing and returns false.
*
* This function uses the `checkout_path` input to determine the repository path
* and works only when called from `analyze` or `upload-sarif`.
*
* @param codeql The CodeQL instance
* @param config The configuration object
* @param logger The logger instance
* @returns A promise that resolves to true if the upload was performed and
* successfully completed, or false otherwise
*/
export async function cleanupAndUploadOverlayBaseDatabaseToCache(
codeql: CodeQL,
config: Config,
logger: Logger,
): Promise<boolean> {
const overlayDatabaseMode = config.overlayDatabaseMode;
if (overlayDatabaseMode !== OverlayDatabaseMode.OverlayBase) {
if (!fs.existsSync(jsonFilePath)) {
logger.debug(
`Overlay database mode is ${overlayDatabaseMode}. ` +
"Skip uploading overlay-base database to cache.",
`No diff ranges JSON file found at ${jsonFilePath}; skipping.`,
);
return false;
}
if (!config.useOverlayDatabaseCaching) {
logger.debug(
"Overlay database caching is disabled. " +
"Skip uploading overlay-base database to cache.",
);
return false;
}
if (isInTestMode()) {
logger.debug(
"In test mode. Skip uploading overlay-base database to cache.",
);
return false;
return [];
}
const databaseIsValid = await checkOverlayBaseDatabase(
codeql,
config,
logger,
"Abort uploading overlay-base database to cache",
);
if (!databaseIsValid) {
return false;
}
// Clean up the database using the overlay cleanup level.
await withGroupAsync("Cleaning up databases", async () => {
await codeql.databaseCleanupCluster(config, CleanupLevel.Overlay);
});
const dbLocation = config.dbLocation;
const databaseSizeBytes = await tryGetFolderBytes(dbLocation, logger);
if (databaseSizeBytes === undefined) {
logger.warning(
"Failed to determine database size. " +
"Skip uploading overlay-base database to cache.",
);
return false;
}
if (databaseSizeBytes > OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_BYTES) {
const databaseSizeMB = Math.round(databaseSizeBytes / 1_000_000);
logger.warning(
`Database size (${databaseSizeMB} MB) ` +
`exceeds maximum upload size (${OVERLAY_BASE_DATABASE_MAX_UPLOAD_SIZE_MB} MB). ` +
"Skip uploading overlay-base database to cache.",
);
return false;
}
const codeQlVersion = (await codeql.getVersion()).version;
const checkoutPath = getRequiredInput("checkout_path");
const cacheSaveKey = await getCacheSaveKey(
config,
codeQlVersion,
checkoutPath,
logger,
);
logger.info(
`Uploading overlay-base database to Actions cache with key ${cacheSaveKey}`,
);
let contents: string;
try {
const cacheId = await waitForResultWithTimeLimit(
MAX_CACHE_OPERATION_MS,
actionsCache.saveCache([dbLocation], cacheSaveKey),
() => {},
);
if (cacheId === undefined) {
logger.warning("Timed out while uploading overlay-base database");
return false;
}
} catch (error) {
logger.warning(
"Failed to upload overlay-base database to cache: " +
`${error instanceof Error ? error.message : String(error)}`,
);
return false;
}
logger.info(`Successfully uploaded overlay-base database from ${dbLocation}`);
return true;
}
export interface OverlayBaseDatabaseDownloadStats {
databaseSizeBytes: number;
databaseDownloadDurationMs: number;
}
/**
* Downloads the overlay-base database from the GitHub Actions cache. If conditions
* for downloading are not met, the function does nothing and returns false.
*
* @param codeql The CodeQL instance
* @param config The configuration object
* @param logger The logger instance
* @returns A promise that resolves to download statistics if an overlay-base
* database was successfully downloaded, or undefined if the download was
* either not performed or failed.
*/
export async function downloadOverlayBaseDatabaseFromCache(
codeql: CodeQL,
config: Config,
logger: Logger,
): Promise<OverlayBaseDatabaseDownloadStats | undefined> {
const overlayDatabaseMode = config.overlayDatabaseMode;
if (overlayDatabaseMode !== OverlayDatabaseMode.Overlay) {
logger.debug(
`Overlay database mode is ${overlayDatabaseMode}. ` +
"Skip downloading overlay-base database from cache.",
);
return undefined;
}
if (!config.useOverlayDatabaseCaching) {
logger.debug(
"Overlay database caching is disabled. " +
"Skip downloading overlay-base database from cache.",
);
return undefined;
}
if (isInTestMode()) {
logger.debug(
"In test mode. Skip downloading overlay-base database from cache.",
);
return undefined;
}
const dbLocation = config.dbLocation;
const codeQlVersion = (await codeql.getVersion()).version;
const cacheRestoreKeyPrefix = await getCacheRestoreKeyPrefix(
config,
codeQlVersion,
);
logger.info(
"Looking in Actions cache for overlay-base database with " +
`restore key ${cacheRestoreKeyPrefix}`,
);
let databaseDownloadDurationMs = 0;
try {
const databaseDownloadStart = performance.now();
const foundKey = await waitForResultWithTimeLimit(
// This ten-minute limit for the cache restore operation is mainly to
// guard against the possibility that the cache service is unresponsive
// and hangs outside the data download.
//
// Data download (which is normally the most time-consuming part of the
// restore operation) should not run long enough to hit this limit. Even
// for an extremely large 10GB database, at a download speed of 40MB/s
// (see below), the download should complete within five minutes. If we
// do hit this limit, there are likely more serious problems other than
// mere slow download speed.
//
// This is important because we don't want any ongoing file operations
// on the database directory when we do hit this limit. Hitting this
// time limit takes us to a fallback path where we re-initialize the
// database from scratch at dbLocation, and having the cache restore
// operation continue to write into dbLocation in the background would
// really mess things up. We want to hit this limit only in the case
// of a hung cache service, not just slow download speed.
MAX_CACHE_OPERATION_MS,
actionsCache.restoreCache(
[dbLocation],
cacheRestoreKeyPrefix,
undefined,
{
// Azure SDK download (which is the default) uses 128MB segments; see
// https://github.com/actions/toolkit/blob/main/packages/cache/README.md.
// Setting segmentTimeoutInMs to 3000 translates to segment download
// speed of about 40 MB/s, which should be achievable unless the
// download is unreliable (in which case we do want to abort).
segmentTimeoutInMs: 3000,
},
),
() => {
logger.info("Timed out downloading overlay-base database from cache");
},
);
databaseDownloadDurationMs = Math.round(
performance.now() - databaseDownloadStart,
);
if (foundKey === undefined) {
logger.info("No overlay-base database found in Actions cache");
return undefined;
}
logger.info(
`Downloaded overlay-base database in cache with key ${foundKey}`,
);
} catch (error) {
logger.warning(
"Failed to download overlay-base database from cache: " +
`${error instanceof Error ? error.message : String(error)}`,
);
return undefined;
}
const databaseIsValid = await checkOverlayBaseDatabase(
codeql,
config,
logger,
"Downloaded overlay-base database is invalid",
);
if (!databaseIsValid) {
logger.warning("Downloaded overlay-base database failed validation");
return undefined;
}
const databaseSizeBytes = await tryGetFolderBytes(dbLocation, logger);
if (databaseSizeBytes === undefined) {
logger.info(
"Filesystem error while accessing downloaded overlay-base database",
);
// The problem that warrants reporting download failure is not that we are
// unable to determine the size of the database. Rather, it is that we
// encountered a filesystem error while accessing the database, which
// indicates that an overlay analysis will likely fail.
return undefined;
}
logger.info(`Successfully downloaded overlay-base database to ${dbLocation}`);
return {
databaseSizeBytes: Math.round(databaseSizeBytes),
databaseDownloadDurationMs,
};
}
/**
* Computes the cache key for saving the overlay-base database to the GitHub
* Actions cache.
*
* The key consists of the restore key prefix (which does not include the
* commit SHA) and the commit SHA of the current checkout.
*/
export async function getCacheSaveKey(
config: Config,
codeQlVersion: string,
checkoutPath: string,
logger: Logger,
): Promise<string> {
let runId = 1;
let attemptId = 1;
try {
runId = getWorkflowRunID();
attemptId = getWorkflowRunAttempt();
contents = await fs.promises.readFile(jsonFilePath, "utf8");
} catch (e) {
logger.warning(
`Failed to get workflow run ID or attempt ID. Reason: ${getErrorMessage(e)}`,
`Failed to read diff ranges JSON file at ${jsonFilePath}: ${e}`,
);
return [];
}
const sha = await getCommitOid(checkoutPath);
const restoreKeyPrefix = await getCacheRestoreKeyPrefix(
config,
codeQlVersion,
let diffRanges: Array<{ path: string }>;
try {
diffRanges = JSON.parse(contents) as Array<{ path: string }>;
} catch (e) {
logger.warning(
`Failed to parse diff ranges JSON file at ${jsonFilePath}: ${e}`,
);
return [];
}
logger.debug(
`Read ${diffRanges.length} diff range(s) from ${jsonFilePath} for overlay changes.`,
);
return `${restoreKeyPrefix}${sha}-${runId}-${attemptId}`;
}
/**
* Computes the cache key prefix for restoring the overlay-base database from
* the GitHub Actions cache.
*
* Actions cache supports using multiple restore keys to indicate preference,
* and this function could in principle take advantage of that feature by
* returning a list of restore key prefixes. However, since overlay-base
* databases are built from the default branch and used in PR analysis, it is
* exceedingly unlikely that the commit SHA will ever be the same.
*
* Therefore, this function returns only a single restore key prefix, which does
* not include the commit SHA. This allows us to restore the most recent
* compatible overlay-base database.
*/
export async function getCacheRestoreKeyPrefix(
config: Config,
codeQlVersion: string,
): Promise<string> {
const languages = [...config.languages].sort().join("_");
// Diff-range paths are relative to the repo root (from the GitHub compare
// API), but overlay changed files must be relative to sourceRoot (to match
// getFileOidsUnderPath output). Convert and filter accordingly.
const repoRoot = await getGitRoot(sourceRoot);
if (repoRoot === undefined) {
if (getOptionalInput("source-root")) {
throw new Error(
"Cannot determine git root to convert diff range paths relative to source-root. " +
"Failing to avoid omitting files from the analysis.",
);
}
logger.warning(
"Cannot determine git root; returning diff range paths as-is.",
);
return [...new Set(diffRanges.map((r) => r.path))];
}
const cacheKeyComponents = {
automationID: await getAutomationID(),
// Add more components here as needed in the future
};
const componentsHash = createCacheKeyHash(cacheKeyComponents);
// For a cached overlay-base database to be considered compatible for overlay
// analysis, all components in the cache restore key must match:
//
// CACHE_PREFIX: distinguishes overlay-base databases from other cache objects
// CACHE_VERSION: cache format version
// componentsHash: hash of additional components (see above for details)
// languages: the languages included in the overlay-base database
// codeQlVersion: CodeQL bundle version
//
// Technically we can also include languages and codeQlVersion in the
// componentsHash, but including them explicitly in the cache key makes it
// easier to debug and understand the cache key structure.
return `${CACHE_PREFIX}-${CACHE_VERSION}-${componentsHash}-${languages}-${codeQlVersion}-`;
const relativePaths = diffRanges
.map((r) =>
path
.relative(sourceRoot, path.join(repoRoot, r.path))
.replaceAll(path.sep, "/"),
)
.filter((rel) => !rel.startsWith(".."));
return [...new Set(relativePaths)];
}
+5
View File
@@ -0,0 +1,5 @@
export enum OverlayDatabaseMode {
Overlay = "overlay",
OverlayBase = "overlay-base",
None = "none",
}
+200 -35
View File
@@ -14,9 +14,9 @@ import * as startProxyExports from "./start-proxy";
import { parseLanguage } from "./start-proxy";
import * as statusReport from "./status-report";
import {
assertNotLogged,
checkExpectedLogMessages,
createFeatures,
getRecordingLogger,
makeTestToken,
RecordingLogger,
setupTests,
@@ -252,6 +252,57 @@ test("getCredentials returns all for a language when specified", async (t) => {
t.assert(credentialsTypes.includes("git_source"));
});
test("getCredentials returns all goproxy_servers for Go when specified", async (t) => {
const multipleGoproxyServers = [
{ type: "goproxy_server", host: "goproxy1.example.com", token: "token1" },
{ type: "goproxy_server", host: "goproxy2.example.com", token: "token2" },
{ type: "git_source", host: "github.com/github", token: "mno" },
];
const credentials = startProxyExports.getCredentials(
getRunnerLogger(true),
undefined,
toEncodedJSON(multipleGoproxyServers),
KnownLanguage.go,
);
t.is(credentials.length, 3);
const goproxyServers = credentials.filter((c) => c.type === "goproxy_server");
t.is(goproxyServers.length, 2);
t.assert(goproxyServers.some((c) => c.host === "goproxy1.example.com"));
t.assert(goproxyServers.some((c) => c.host === "goproxy2.example.com"));
});
test("getCredentials returns all maven_repositories for Java when specified", async (t) => {
const multipleMavenRepositories = [
{
type: "maven_repository",
host: "maven1.pkg.github.com",
token: "token1",
},
{
type: "maven_repository",
host: "maven2.pkg.github.com",
token: "token2",
},
{ type: "git_source", host: "github.com/github", token: "mno" },
];
const credentials = startProxyExports.getCredentials(
getRunnerLogger(true),
undefined,
toEncodedJSON(multipleMavenRepositories),
KnownLanguage.java,
);
t.is(credentials.length, 2);
const mavenRepositories = credentials.filter(
(c) => c.type === "maven_repository",
);
t.assert(mavenRepositories.some((c) => c.host === "maven1.pkg.github.com"));
t.assert(mavenRepositories.some((c) => c.host === "maven2.pkg.github.com"));
});
test("getCredentials returns all credentials when no language specified", async (t) => {
const credentialsInput = toEncodedJSON(mixedCredentials);
@@ -300,23 +351,23 @@ test("getCredentials throws an error when non-printable characters are used", as
});
const validAzureCredential: startProxyExports.AzureConfig = {
tenant_id: "12345678-1234-1234-1234-123456789012",
client_id: "abcdef01-2345-6789-abcd-ef0123456789",
"tenant-id": "12345678-1234-1234-1234-123456789012",
"client-id": "abcdef01-2345-6789-abcd-ef0123456789",
};
const validAwsCredential: startProxyExports.AWSConfig = {
aws_region: "us-east-1",
account_id: "123456789012",
role_name: "MY_ROLE",
"aws-region": "us-east-1",
"account-id": "123456789012",
"role-name": "MY_ROLE",
domain: "MY_DOMAIN",
domain_owner: "987654321098",
"domain-owner": "987654321098",
audience: "custom-audience",
};
const validJFrogCredential: startProxyExports.JFrogConfig = {
jfrog_oidc_provider_name: "MY_PROVIDER",
"jfrog-oidc-provider-name": "MY_PROVIDER",
audience: "jfrog-audience",
identity_mapping_name: "my-mapping",
"identity-mapping-name": "my-mapping",
};
test("getCredentials throws an error when non-printable characters are used for Azure OIDC", (t) => {
@@ -439,41 +490,155 @@ test("getCredentials accepts OIDC configurations", (t) => {
t.assert(credentials.some((c) => startProxyExports.isJFrogConfig(c)));
});
test("getCredentials logs a warning when a PAT is used without a username", async (t) => {
const loggedMessages = [];
const logger = getRecordingLogger(loggedMessages);
const likelyWrongCredentials = toEncodedJSON([
const getCredentialsMacro = test.macro({
exec: async (
t: ExecutionContext<unknown>,
credentials: startProxyExports.RawCredential[],
checkAccepted: (
t: ExecutionContext<unknown>,
logger: RecordingLogger,
results: startProxyExports.Credential[],
) => void,
) => {
const logger = new RecordingLogger();
const credentialsString = toEncodedJSON(credentials);
const results = startProxyExports.getCredentials(
logger,
undefined,
credentialsString,
undefined,
);
checkAccepted(t, logger, results);
},
title: (providedTitle = "") => `getCredentials - ${providedTitle}`,
});
test(
"warns for PAT-like password without a username",
getCredentialsMacro,
[
{
type: "git_server",
host: "https://github.com/",
password: `ghp_${makeTestToken()}`,
},
]);
],
(t, logger, results) => {
// The configurations should be accepted, despite the likely problem.
t.assert(results);
t.is(results.length, 1);
t.is(results[0].type, "git_server");
t.is(results[0].host, "https://github.com/");
const results = startProxyExports.getCredentials(
logger,
undefined,
likelyWrongCredentials,
undefined,
);
if (startProxyExports.isUsernamePassword(results[0])) {
t.assert(results[0].password?.startsWith("ghp_"));
} else {
t.fail("Expected a `UsernamePassword`-based credential.");
}
// The configuration should be accepted, despite the likely problem.
t.assert(results);
t.is(results.length, 1);
t.is(results[0].type, "git_server");
t.is(results[0].host, "https://github.com/");
// A warning should have been logged.
checkExpectedLogMessages(t, logger.messages, [
"using a GitHub Personal Access Token (PAT), but no username was provided",
]);
},
);
if (startProxyExports.isUsernamePassword(results[0])) {
t.assert(results[0].password?.startsWith("ghp_"));
} else {
t.fail("Expected a `UsernamePassword`-based credential.");
}
test(
"no warning for PAT-like password with a username",
getCredentialsMacro,
[
{
type: "git_server",
host: "https://github.com/",
username: "someone",
password: `ghp_${makeTestToken()}`,
},
],
(t, logger, results) => {
// The configurations should be accepted, despite the likely problem.
t.assert(results);
t.is(results.length, 1);
t.is(results[0].type, "git_server");
t.is(results[0].host, "https://github.com/");
// A warning should have been logged.
checkExpectedLogMessages(t, loggedMessages, [
"using a GitHub Personal Access Token (PAT), but no username was provided",
]);
});
if (startProxyExports.isUsernamePassword(results[0])) {
t.assert(results[0].password?.startsWith("ghp_"));
} else {
t.fail("Expected a `UsernamePassword`-based credential.");
}
assertNotLogged(
t,
logger,
"using a GitHub Personal Access Token (PAT), but no username was provided",
);
},
);
test(
"warns for PAT-like token without a username",
getCredentialsMacro,
[
{
type: "git_server",
host: "https://github.com/",
token: `ghp_${makeTestToken()}`,
},
],
(t, logger, results) => {
// The configurations should be accepted, despite the likely problem.
t.assert(results);
t.is(results.length, 1);
t.is(results[0].type, "git_server");
t.is(results[0].host, "https://github.com/");
if (startProxyExports.isToken(results[0])) {
t.assert(results[0].token?.startsWith("ghp_"));
} else {
t.fail("Expected a `Token`-based credential.");
}
// A warning should have been logged.
checkExpectedLogMessages(t, logger.messages, [
"using a GitHub Personal Access Token (PAT), but no username was provided",
]);
},
);
test(
"no warning for PAT-like token with a username",
getCredentialsMacro,
[
{
type: "git_server",
host: "https://github.com/",
username: "someone",
token: `ghp_${makeTestToken()}`,
},
],
(t, logger, results) => {
// The configurations should be accepted, despite the likely problem.
t.assert(results);
t.is(results.length, 1);
t.is(results[0].type, "git_server");
t.is(results[0].host, "https://github.com/");
if (startProxyExports.isToken(results[0])) {
t.assert(results[0].token?.startsWith("ghp_"));
} else {
t.fail("Expected a `Token`-based credential.");
}
assertNotLogged(
t,
logger,
"using a GitHub Personal Access Token (PAT), but no username was provided",
);
},
);
test("getCredentials returns all credentials for Actions when using LANGUAGE_TO_REGISTRY_TYPE", async (t) => {
const credentialsInput = toEncodedJSON(mixedCredentials);
+32 -41
View File
@@ -18,6 +18,7 @@ import {
FeatureEnablement,
} from "./feature-flags";
import * as json from "./json";
import * as knownLanguageAliases from "./known-language-aliases.json";
import { KnownLanguage } from "./languages";
import { Logger } from "./logging";
import {
@@ -188,43 +189,30 @@ export const UPDATEJOB_PROXY_VERSION = "v2.0.20250624110901";
const UPDATEJOB_PROXY_URL_PREFIX =
"https://github.com/github/codeql-action/releases/download/codeql-bundle-v2.22.0/";
/*
* Language aliases supported by the start-proxy Action.
*
* In general, the CodeQL CLI is the source of truth for language aliases, and to
* allow us to more easily support new languages, we want to avoid hardcoding these
* aliases in the Action itself. However this is difficult to do in the start-proxy
* Action since this Action does not use CodeQL, so we're accepting some hardcoding
* for this Action.
*/
const LANGUAGE_ALIASES: { [lang: string]: KnownLanguage } = {
c: KnownLanguage.cpp,
"c++": KnownLanguage.cpp,
"c#": KnownLanguage.csharp,
kotlin: KnownLanguage.java,
typescript: KnownLanguage.javascript,
"javascript-typescript": KnownLanguage.javascript,
"java-kotlin": KnownLanguage.java,
};
/**
* Parse the start-proxy language input into its canonical CodeQL language name.
*
* Exported for testing. Do not use this outside of the start-proxy Action
* to avoid complicating the process of adding new CodeQL languages.
* This uses the language aliases shipped with the Action and will not be able to resolve aliases
* added by versions of the CodeQL CLI newer than the one mentioned in `defaults.json`. However,
* this is sufficient for the start-proxy Action since we are already specifying proxy
* configurations on a per-language basis.
*/
export function parseLanguage(language: string): KnownLanguage | undefined {
// Normalize to lower case
language = language.trim().toLowerCase();
// See if it's an exact match
if (language in KnownLanguage) {
if (Object.hasOwn(KnownLanguage, language)) {
return language as KnownLanguage;
}
// Check language aliases
if (language in LANGUAGE_ALIASES) {
return LANGUAGE_ALIASES[language];
if (Object.hasOwn(knownLanguageAliases, language)) {
language =
knownLanguageAliases[language as keyof typeof knownLanguageAliases];
if (Object.hasOwn(KnownLanguage, language)) {
return language as KnownLanguage;
}
}
return undefined;
@@ -301,22 +289,22 @@ export function getAuthConfig(
// which we can use to identify them.
if (isAzureConfig(config)) {
return {
tenant_id: config.tenant_id,
client_id: config.client_id,
"tenant-id": config["tenant-id"],
"client-id": config["client-id"],
} satisfies AzureConfig;
} else if (isAWSConfig(config)) {
return {
aws_region: config.aws_region,
account_id: config.account_id,
role_name: config.role_name,
"aws-region": config["aws-region"],
"account-id": config["account-id"],
"role-name": config["role-name"],
domain: config.domain,
domain_owner: config.domain_owner,
"domain-owner": config["domain-owner"],
audience: config.audience,
} satisfies AWSConfig;
} else if (isJFrogConfig(config)) {
return {
jfrog_oidc_provider_name: config.jfrog_oidc_provider_name,
identity_mapping_name: config.identity_mapping_name,
"jfrog-oidc-provider-name": config["jfrog-oidc-provider-name"],
"identity-mapping-name": config["identity-mapping-name"],
audience: config.audience,
} satisfies JFrogConfig;
} else if (isToken(config)) {
@@ -447,15 +435,18 @@ export function getCredentials(
}
// If the password or token looks like a GitHub PAT, warn if no username is configured.
if (
((!hasUsername(authConfig) || !isDefined(authConfig.username)) &&
isUsernamePassword(authConfig) &&
isDefined(authConfig.password) &&
isPAT(authConfig.password)) ||
(isToken(authConfig) &&
isDefined(authConfig.token) &&
isPAT(authConfig.token))
) {
const noUsername =
!hasUsername(authConfig) || !isDefined(authConfig.username);
const passwordIsPAT =
isUsernamePassword(authConfig) &&
isDefined(authConfig.password) &&
isPAT(authConfig.password);
const tokenIsPAT =
isToken(authConfig) &&
isDefined(authConfig.token) &&
isPAT(authConfig.token);
if (noUsername && (passwordIsPAT || tokenIsPAT)) {
logger.warning(
`A ${e.type} private registry is configured for ${e.host || e.url} using a GitHub Personal Access Token (PAT), but no username was provided. ` +
`This may not work correctly. When configuring a private registry using a PAT, select "Username and password" and enter the username of the user ` +
+8 -8
View File
@@ -7,23 +7,23 @@ import * as types from "./types";
setupTests(test);
const validAzureCredential: types.AzureConfig = {
tenant_id: "12345678-1234-1234-1234-123456789012",
client_id: "abcdef01-2345-6789-abcd-ef0123456789",
"tenant-id": "12345678-1234-1234-1234-123456789012",
"client-id": "abcdef01-2345-6789-abcd-ef0123456789",
};
const validAwsCredential: types.AWSConfig = {
aws_region: "us-east-1",
account_id: "123456789012",
role_name: "MY_ROLE",
"aws-region": "us-east-1",
"account-id": "123456789012",
"role-name": "MY_ROLE",
domain: "MY_DOMAIN",
domain_owner: "987654321098",
"domain-owner": "987654321098",
audience: "custom-audience",
};
const validJFrogCredential: types.JFrogConfig = {
jfrog_oidc_provider_name: "MY_PROVIDER",
"jfrog-oidc-provider-name": "MY_PROVIDER",
audience: "jfrog-audience",
identity_mapping_name: "my-mapping",
"identity-mapping-name": "my-mapping",
};
test("credentialToStr - pretty-prints valid username+password configurations", (t) => {
+34 -31
View File
@@ -59,29 +59,29 @@ export function isToken(
}
/** Configuration for Azure OIDC. */
export type AzureConfig = { tenant_id: string; client_id: string };
export type AzureConfig = { "tenant-id": string; "client-id": string };
/** Decides whether `config` is an Azure OIDC configuration. */
export function isAzureConfig(
config: UnvalidatedObject<AuthConfig>,
): config is AzureConfig {
return (
"tenant_id" in config &&
"client_id" in config &&
isDefined(config.tenant_id) &&
isDefined(config.client_id) &&
json.isString(config.tenant_id) &&
json.isString(config.client_id)
"tenant-id" in config &&
"client-id" in config &&
isDefined(config["tenant-id"]) &&
isDefined(config["client-id"]) &&
json.isString(config["tenant-id"]) &&
json.isString(config["client-id"])
);
}
/** Configuration for AWS OIDC. */
export type AWSConfig = {
aws_region: string;
account_id: string;
role_name: string;
"aws-region": string;
"account-id": string;
"role-name": string;
domain: string;
domain_owner: string;
"domain-owner": string;
audience?: string;
};
@@ -91,11 +91,11 @@ export function isAWSConfig(
): config is AWSConfig {
// All of these properties are required.
const requiredProperties = [
"aws_region",
"account_id",
"role_name",
"aws-region",
"account-id",
"role-name",
"domain",
"domain_owner",
"domain-owner",
];
for (const property of requiredProperties) {
@@ -118,30 +118,30 @@ export function isAWSConfig(
/** Configuration for JFrog OIDC. */
export type JFrogConfig = {
jfrog_oidc_provider_name: string;
"jfrog-oidc-provider-name": string;
audience?: string;
identity_mapping_name?: string;
"identity-mapping-name"?: string;
};
/** Decides whether `config` is a JFrog OIDC configuration. */
export function isJFrogConfig(
config: UnvalidatedObject<AuthConfig>,
): config is JFrogConfig {
// The "audience" and "identity_mapping_name" fields are optional, but should be strings if present.
// The "audience" and "identity-mapping-name" fields are optional, but should be strings if present.
if ("audience" in config && !json.isStringOrUndefined(config.audience)) {
return false;
}
if (
"identity_mapping_name" in config &&
!json.isStringOrUndefined(config.identity_mapping_name)
"identity-mapping-name" in config &&
!json.isStringOrUndefined(config["identity-mapping-name"])
) {
return false;
}
return (
"jfrog_oidc_provider_name" in config &&
isDefined(config.jfrog_oidc_provider_name) &&
json.isString(config.jfrog_oidc_provider_name)
"jfrog-oidc-provider-name" in config &&
isDefined(config["jfrog-oidc-provider-name"]) &&
json.isString(config["jfrog-oidc-provider-name"])
);
}
@@ -189,18 +189,21 @@ export function credentialToStr(credential: Credential): string {
}
if (isAzureConfig(credential)) {
appendIfDefined("Tenant", credential.tenant_id);
appendIfDefined("Client", credential.client_id);
appendIfDefined("Tenant", credential["tenant-id"]);
appendIfDefined("Client", credential["client-id"]);
} else if (isAWSConfig(credential)) {
appendIfDefined("AWS Region", credential.aws_region);
appendIfDefined("AWS Account", credential.account_id);
appendIfDefined("AWS Role", credential.role_name);
appendIfDefined("AWS Region", credential["aws-region"]);
appendIfDefined("AWS Account", credential["account-id"]);
appendIfDefined("AWS Role", credential["role-name"]);
appendIfDefined("AWS Domain", credential.domain);
appendIfDefined("AWS Domain Owner", credential.domain_owner);
appendIfDefined("AWS Domain Owner", credential["domain-owner"]);
appendIfDefined("AWS Audience", credential.audience);
} else if (isJFrogConfig(credential)) {
appendIfDefined("JFrog Provider", credential.jfrog_oidc_provider_name);
appendIfDefined("JFrog Identity Mapping", credential.identity_mapping_name);
appendIfDefined("JFrog Provider", credential["jfrog-oidc-provider-name"]);
appendIfDefined(
"JFrog Identity Mapping",
credential["identity-mapping-name"],
);
appendIfDefined("JFrog Audience", credential.audience);
}
+1 -1
View File
@@ -18,7 +18,7 @@ import { DocUrl } from "./doc-url";
import { EnvVar } from "./environment";
import { getRef } from "./git-utils";
import { Logger } from "./logging";
import { OverlayBaseDatabaseDownloadStats } from "./overlay";
import { OverlayBaseDatabaseDownloadStats } from "./overlay/caching";
import { getRepositoryNwo } from "./repository";
import { ToolsSource } from "./setup-codeql";
import {
+60 -43
View File
@@ -21,7 +21,7 @@ import {
FeatureEnablement,
} from "./feature-flags";
import { Logger } from "./logging";
import { OverlayDatabaseMode } from "./overlay";
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
import {
DEFAULT_DEBUG_ARTIFACT_NAME,
DEFAULT_DEBUG_DATABASE_NAME,
@@ -185,8 +185,8 @@ export interface LoggedMessage {
export class RecordingLogger implements Logger {
messages: LoggedMessage[] = [];
groups: string[] = [];
unfinishedGroups: Set<string> = new Set();
readonly groups: string[] = [];
readonly unfinishedGroups: Set<string> = new Set();
private currentGroup: string | undefined = undefined;
constructor(private readonly logToConsole: boolean = true) {}
@@ -200,6 +200,19 @@ export class RecordingLogger implements Logger {
}
}
/**
* Checks whether the logged messages contain `messageOrRegExp`.
*
* If `messageOrRegExp` is a string, this function returns true as long as
* `messageOrRegExp` appears as part of one of the `messages`.
*
* If `messageOrRegExp` is a regular expression, this function returns true as long as
* one of the `messages` matches `messageOrRegExp`.
*/
hasMessage(messageOrRegExp: string | RegExp): boolean {
return hasLoggedMessage(this.messages, messageOrRegExp);
}
isDebug() {
return true;
}
@@ -238,41 +251,37 @@ export function getRecordingLogger(
messages: LoggedMessage[],
{ logToConsole }: { logToConsole?: boolean } = { logToConsole: true },
): Logger {
return {
debug: (message: string) => {
messages.push({ type: "debug", message });
if (logToConsole) {
// eslint-disable-next-line no-console
console.debug(message);
}
},
info: (message: string) => {
messages.push({ type: "info", message });
if (logToConsole) {
// eslint-disable-next-line no-console
console.info(message);
}
},
warning: (message: string | Error) => {
messages.push({ type: "warning", message });
if (logToConsole) {
// eslint-disable-next-line no-console
console.warn(message);
}
},
error: (message: string | Error) => {
messages.push({ type: "error", message });
if (logToConsole) {
// eslint-disable-next-line no-console
console.error(message);
}
},
isDebug: () => true,
startGroup: () => undefined,
endGroup: () => undefined,
};
const logger = new RecordingLogger(logToConsole);
logger.messages = messages;
return logger;
}
/**
* Checks whether `messages` contains `messageOrRegExp`.
*
* If `messageOrRegExp` is a string, this function returns true as long as
* `messageOrRegExp` appears as part of one of the `messages`.
*
* If `messageOrRegExp` is a regular expression, this function returns true as long as
* one of the `messages` matches `messageOrRegExp`.
*/
function hasLoggedMessage(
messages: LoggedMessage[],
messageOrRegExp: string | RegExp,
): boolean {
const check = (val: string) =>
typeof messageOrRegExp === "string"
? val.includes(messageOrRegExp)
: messageOrRegExp.test(val);
return messages.some(
(msg) => typeof msg.message === "string" && check(msg.message),
);
}
/**
* Checks that `messages` contains all of `expectedMessages`.
*/
export function checkExpectedLogMessages(
t: ExecutionContext<any>,
messages: LoggedMessage[],
@@ -281,13 +290,7 @@ export function checkExpectedLogMessages(
const missingMessages: string[] = [];
for (const expectedMessage of expectedMessages) {
if (
!messages.some(
(msg) =>
typeof msg.message === "string" &&
msg.message.includes(expectedMessage),
)
) {
if (!hasLoggedMessage(messages, expectedMessage)) {
missingMessages.push(expectedMessage);
}
}
@@ -304,6 +307,20 @@ export function checkExpectedLogMessages(
}
}
/**
* Asserts that `message` should not have been logged to `logger`.
*/
export function assertNotLogged(
t: ExecutionContext<any>,
logger: RecordingLogger,
message: string | RegExp,
) {
t.false(
logger.hasMessage(message),
`'${message}' should not have been logged, but was.`,
);
}
/**
* Initialises a recording logger and calls `body` with it.
*
-1
View File
@@ -9,7 +9,6 @@ export enum ToolsFeature {
DatabaseInterpretResultsSupportsSarifRunProperty = "databaseInterpretResultsSupportsSarifRunProperty",
ForceOverwrite = "forceOverwrite",
IndirectTracingSupportsStaticBinaries = "indirectTracingSupportsStaticBinaries",
PythonDefaultIsToNotExtractStdlib = "pythonDefaultIsToNotExtractStdlib",
SuppressesMissingFileBaselineWarning = "suppressesMissingFileBaselineWarning",
}
+4
View File
@@ -185,6 +185,10 @@ export async function cleanupTrapCaches(
trap_cache_cleanup_skipped_because: "feature disabled",
};
}
logger.warning(
"TRAP cache cleanup is deprecated and will be removed in May 2026. " +
"We recommend instead disabling TRAP caching by passing the `trap-caching: false` input to the `init` Action.",
);
if (!(await gitUtils.isAnalyzingDefaultBranch())) {
return {
trap_cache_cleanup_skipped_because: "not analyzing default branch",
+1 -1
View File
@@ -29,6 +29,6 @@ outputs:
proxy_urls:
description: A stringified JSON array of objects containing the types and URLs of the configured registries.
runs:
using: node24
using: node20
main: "../lib/start-proxy-action.js"
post: "../lib/start-proxy-action-post.js"
+10 -1
View File
@@ -4,9 +4,11 @@
"lib": ["ES2022"],
"target": "ES2022",
"module": "commonjs",
"moduleResolution": "bundler",
"outDir": "./build",
"rootDir": "./src",
"sourceMap": true,
"types": ["node"],
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
@@ -16,7 +18,6 @@
"strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
"strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
"noUnusedLocals": false, /* Report errors on unused locals. */
@@ -27,6 +28,14 @@
/* Module Resolution Options */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"resolveJsonModule": true,
"skipLibCheck": true,
// @actions/github imports this path from @octokit/core but it's not in @octokit/core's
// exports map (only "@octokit/core/types" is). Under moduleResolution: "bundler", TypeScript
// checks exports maps and can't find it, causing all GitHub/Octokit types to degrade to `any`.
// This paths override restores the direct filesystem resolution that moduleResolution: "node10" used.
"paths": {
"@octokit/core/dist-types/types": ["./node_modules/@octokit/core/dist-types/types.d.ts"]
},
},
"exclude": ["node_modules", "pr-checks"]
}
+1 -1
View File
@@ -41,6 +41,6 @@ outputs:
{ "code-scanning": "some-id", "code-quality": "some-other-id" }
runs:
using: node24
using: node20
main: '../lib/upload-sarif-action.js'
post: '../lib/upload-sarif-action-post.js'