Compare commits

..
316 Commits
Author SHA1 Message Date
Mario Campos 4bfa242aa4 Merge pull request #4259 from github/backport-v3.39.1-9b3254085
Merge releases/v4 into releases/v3
2026-10-21 11:29:39 -05:00
Mario Campos fca87a63d4 Trigger workflows 2026-10-21 11:10:05 -05:00
github-actions[bot] bc3fac49cf Rebuild 2026-10-21 15:50:19 +00:00
github-actions[bot] 2bdfb07d33 Update version and changelog for v3.39.1 2026-10-21 15:50:10 +00:00
github-actions[bot] bfa15a230a Merge remote-tracking branch 'origin/releases/v4' into backport-v3.39.1-9b3254085 2026-10-21 15:50:10 +00:00
github-actions[bot] 6f8ca3e0c5 Revert "Rebuild"
This reverts commit 67cc5f0aac.
2026-10-21 15:50:10 +00:00
github-actions[bot] 71fd480d3c Revert "Update version and changelog for v3.39.0"
This reverts commit c157d4497c.
2026-10-21 15:50:10 +00:00
Michael B. Gale ce5e7eeac3 Merge pull request #4241 from github/backport-v3.39.0-6f2ac81f5
Merge releases/v4 into releases/v3
2026-10-15 12:39:31 +01:00
github-actions[bot] 67cc5f0aac Rebuild 2026-10-15 10:58:58 +00:00
github-actions[bot] c157d4497c Update version and changelog for v3.39.0 2026-10-15 10:58:49 +00:00
github-actions[bot] adb09ff87a Merge remote-tracking branch 'origin/releases/v4' into backport-v3.39.0-6f2ac81f5 2026-10-15 10:58:49 +00:00
github-actions[bot] e8f64d6fac Revert "Rebuild"
This reverts commit 472ce8f9d0.
2026-10-15 10:58:49 +00:00
github-actions[bot] c823e5d850 Revert "Update version and changelog for v3.38.3"
This reverts commit 9c17bbcb81.
2026-10-15 10:58:49 +00:00
Mads Navntoft 9f759ee644 Merge pull request #4216 from github/backport-v3.38.3-24c54180a
Merge releases/v4 into releases/v3
2026-10-08 16:43:50 +02:00
github-actions[bot] 472ce8f9d0 Rebuild 2026-10-08 13:02:55 +00:00
github-actions[bot] 9c17bbcb81 Update version and changelog for v3.38.3 2026-10-08 13:02:45 +00:00
github-actions[bot] 1d986a146a Merge remote-tracking branch 'origin/releases/v4' into backport-v3.38.3-24c54180a 2026-10-08 13:02:45 +00:00
github-actions[bot] 1720989ad1 Revert "Rebuild"
This reverts commit a09a142526.
2026-10-08 13:02:45 +00:00
github-actions[bot] 45d97c3a6c Revert "Update version and changelog for v3.38.2"
This reverts commit aa62ed54ed.
2026-10-08 13:02:45 +00:00
Michael B. Gale 1190a975f9 Merge pull request #4171 from github/backport-v3.38.2-2892aa5e1
Merge releases/v4 into releases/v3
2026-09-24 12:00:34 +01:00
github-actions[bot] a09a142526 Rebuild 2026-09-24 10:29:19 +00:00
github-actions[bot] aa62ed54ed Update version and changelog for v3.38.2 2026-09-24 10:29:11 +00:00
github-actions[bot] aca72b1c31 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.38.2-2892aa5e1 2026-09-24 10:29:11 +00:00
github-actions[bot] 259e857114 Revert "Rebuild"
This reverts commit 39e5c2d42c.
2026-09-24 10:29:11 +00:00
github-actions[bot] 37fc051b5d Revert "Update version and changelog for v3.38.1"
This reverts commit d7512d4cfe.
2026-09-24 10:29:11 +00:00
Michael B. Gale 3ea06614da Merge pull request #4154 from github/backport-v3.38.1-1c5b67565
Merge releases/v4 into releases/v3
2026-09-18 15:06:05 +01:00
github-actions[bot] 39e5c2d42c Rebuild 2026-09-18 13:12:36 +00:00
github-actions[bot] d7512d4cfe Update version and changelog for v3.38.1 2026-09-18 13:12:27 +00:00
github-actions[bot] 41500c6922 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.38.1-1c5b67565 2026-09-18 13:12:27 +00:00
github-actions[bot] 693d869c25 Revert "Rebuild"
This reverts commit 3490969653.
2026-09-18 13:12:27 +00:00
github-actions[bot] dc38ccb025 Revert "Update version and changelog for v3.38.0"
This reverts commit ce74b7377b.
2026-09-18 13:12:27 +00:00
Henry Mercer faaca9a8f6 Merge pull request #4133 from github/backport-v3.38.0-b96794f01
Merge releases/v4 into releases/v3
2026-09-09 15:51:52 +01:00
github-actions[bot] 3490969653 Rebuild 2026-09-09 14:37:28 +00:00
github-actions[bot] ce74b7377b Update version and changelog for v3.38.0 2026-09-09 14:37:15 +00:00
github-actions[bot] 739ee7214d Merge remote-tracking branch 'origin/releases/v4' into backport-v3.38.0-b96794f01 2026-09-09 14:37:15 +00:00
github-actions[bot] a3c61c3ab4 Revert "Rebuild"
This reverts commit 2907452324.
2026-09-09 14:37:15 +00:00
github-actions[bot] 16e21b98bd Revert "Update version and changelog for v3.37.9"
This reverts commit a4f1d2dfeb.
2026-09-09 14:37:14 +00:00
Henry Mercer 6f5948dfac Merge pull request #4109 from github/backport-v3.37.9-cdf488f59
Merge releases/v4 into releases/v3
2026-08-26 18:02:02 +01:00
github-actions[bot] 2907452324 Rebuild 2026-08-26 14:42:27 +00:00
github-actions[bot] a4f1d2dfeb Update version and changelog for v3.37.9 2026-08-26 14:42:12 +00:00
github-actions[bot] a87239a309 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.37.9-cdf488f59 2026-08-26 14:42:12 +00:00
github-actions[bot] c68e6e8e04 Revert "Rebuild"
This reverts commit 771aacb2ad.
2026-08-26 14:42:12 +00:00
github-actions[bot] 65e1329896 Revert "Update version and changelog for v3.37.8"
This reverts commit 0692998c5c.
2026-08-26 14:42:12 +00:00
Henry Mercer 42947a3404 Merge pull request #4104 from github/backport-v3.37.8-db488ddef
Merge releases/v4 into releases/v3
2026-08-21 13:48:33 +01:00
github-actions[bot] 771aacb2ad Rebuild 2026-08-21 12:27:02 +00:00
github-actions[bot] 0692998c5c Update version and changelog for v3.37.8 2026-08-21 12:26:47 +00:00
github-actions[bot] 57a845ca5d Merge remote-tracking branch 'origin/releases/v4' into backport-v3.37.8-db488ddef 2026-08-21 12:26:47 +00:00
github-actions[bot] 2b5f0e6784 Revert "Rebuild"
This reverts commit 2a073c8c9a.
2026-08-21 12:26:47 +00:00
github-actions[bot] 77571dc418 Revert "Update version and changelog for v3.37.7"
This reverts commit 5f47b57df6.
2026-08-21 12:26:47 +00:00
Michael B. Gale f3712979fa Merge pull request #4095 from github/backport-v3.37.7-ff2f1c621
Merge releases/v4 into releases/v3
2026-08-13 14:57:21 +01:00
github-actions[bot] 2a073c8c9a Rebuild 2026-08-13 13:31:29 +00:00
github-actions[bot] 5f47b57df6 Update version and changelog for v3.37.7 2026-08-13 13:31:20 +00:00
github-actions[bot] 272e6d3b25 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.37.7-ff2f1c621 2026-08-13 13:31:20 +00:00
github-actions[bot] 4da5eae9f4 Revert "Rebuild"
This reverts commit b4d147f9bc.
2026-08-13 13:31:20 +00:00
github-actions[bot] 8b2ec470a0 Revert "Update version and changelog for v3.37.6"
This reverts commit f6580d2b8f.
2026-08-13 13:31:20 +00:00
Michael B. Gale c4dd10e44a Merge pull request #4074 from github/backport-v3.37.6-5595ccaf9
Merge releases/v4 into releases/v3
2026-08-04 15:34:13 +01:00
Michael B. Gale 2ba473f582 Trigger workflows 2026-08-04 15:21:43 +01:00
github-actions[bot] b4d147f9bc Rebuild 2026-08-04 13:36:10 +00:00
github-actions[bot] f6580d2b8f Update version and changelog for v3.37.6 2026-08-04 13:36:01 +00:00
github-actions[bot] 5e7686d132 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.37.6-5595ccaf9 2026-08-04 13:36:01 +00:00
github-actions[bot] 324dd69df0 Revert "Rebuild"
This reverts commit 01b30f9112.
2026-08-04 13:36:00 +00:00
github-actions[bot] 200d550080 Revert "Update version and changelog for v3.37.5"
This reverts commit f44d029dbc.
2026-08-04 13:36:00 +00:00
Henry Mercer e60ea984bd Merge pull request #4069 from github/backport-v3.37.5-d1ba80a13
Merge releases/v4 into releases/v3
2026-08-03 12:29:14 +01:00
github-actions[bot] 01b30f9112 Rebuild 2026-08-03 11:09:54 +00:00
github-actions[bot] f44d029dbc Update version and changelog for v3.37.5 2026-08-03 11:09:41 +00:00
github-actions[bot] a7b3986136 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.37.5-d1ba80a13 2026-08-03 11:09:40 +00:00
github-actions[bot] 5667eabe3b Revert "Rebuild"
This reverts commit 85722ca3f8.
2026-08-03 11:09:40 +00:00
github-actions[bot] 2c538e6403 Revert "Update version and changelog for v3.37.4"
This reverts commit 93539ac81b.
2026-08-03 11:09:40 +00:00
Michael B. Gale fa3b8d4aca Merge pull request #4060 from github/fix/revert-rebuild
Fix `releases/v3` branch
2026-07-31 12:05:49 +01:00
Michael B. Gale 85722ca3f8 Rebuild 2026-07-30 18:08:41 +01:00
github-actions[bot] 93539ac81b Update version and changelog for v3.37.4 2026-07-30 18:08:17 +01:00
Michael B. Gale a2225dced3 Resolve merge conflict 2026-07-30 18:05:04 +01:00
Michael B. Gale 4d950cddc8 Revert "Rebuild"
This reverts commit 30d6d12c17.
2026-07-30 18:04:02 +01:00
Michael B. Gale b7ae332965 Revert "Update version and changelog for v3.37.4"
This reverts commit 14e2e60bf8.
2026-07-30 18:03:51 +01:00
Óscar San José a2983b8bed Merge pull request #4058 from github/backport-v3.37.4-f205ea1c3
Merge releases/v4 into releases/v3
2026-07-30 15:37:05 +02:00
Óscar San José 30d6d12c17 Rebuild 2026-07-30 13:55:35 +02:00
github-actions[bot] 14e2e60bf8 Update version and changelog for v3.37.4 2026-07-30 09:22:37 +00:00
github-actions[bot] 5d3f01e177 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.37.4-f205ea1c3
# Conflicts:
#	lib/entry-points.js
2026-07-30 09:22:37 +00:00
github-actions[bot] 3f405c7726 Revert "Rebuild"
This reverts commit ae71ce6a2d.
2026-07-30 09:22:37 +00:00
github-actions[bot] 19d11a3383 Revert "Update version and changelog for v3.37.3"
This reverts commit d2305d0114.
2026-07-30 09:22:37 +00:00
Michael B. Gale 4187e74d05 Merge pull request #4034 from github/backport-v3.37.3-e4fba868f
Merge releases/v4 into releases/v3
2026-07-22 07:01:42 +01:00
Michael B. Gale ae71ce6a2d Rebuild 2026-07-22 06:45:17 +01:00
github-actions[bot] d2305d0114 Update version and changelog for v3.37.3 2026-07-22 05:38:23 +00:00
github-actions[bot] 994a21a0b3 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.37.3-e4fba868f
# Conflicts:
#	lib/entry-points.js
2026-07-22 05:38:23 +00:00
github-actions[bot] 0c52f3f086 Revert "Rebuild"
This reverts commit 74406f0856.
2026-07-22 05:38:22 +00:00
github-actions[bot] 933494d539 Revert "Update version and changelog for v3.37.2"
This reverts commit 8dfbacbba5.
2026-07-22 05:38:22 +00:00
Michael B. Gale 08d09a53f0 Merge pull request #4029 from github/backport-v3.37.2-e0647621c
Merge releases/v4 into releases/v3
2026-07-21 16:06:02 +01:00
Michael B. Gale 74406f0856 Rebuild 2026-07-21 15:31:11 +01:00
github-actions[bot] 8dfbacbba5 Update version and changelog for v3.37.2 2026-07-21 14:28:11 +00:00
github-actions[bot] ab2931b320 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.37.2-e0647621c
# Conflicts:
#	lib/entry-points.js
2026-07-21 14:28:11 +00:00
github-actions[bot] c87e7fae54 Revert "Rebuild"
This reverts commit 1138fefa2b.
2026-07-21 14:28:11 +00:00
github-actions[bot] 5a1ba3bdf6 Revert "Update version and changelog for v3.37.1"
This reverts commit 3fa858af16.
2026-07-21 14:28:10 +00:00
Óscar San José b7351df727 Merge pull request #4022 from github/backport-v3.37.1-7188fc363
Merge releases/v4 into releases/v3
2026-07-16 20:17:18 +02:00
Óscar San José 27e669d3d6 run pr-checks/sync-back.ts 2026-07-16 18:57:25 +02:00
Óscar San José 1138fefa2b Rebuild 2026-07-16 18:36:30 +02:00
github-actions[bot] 3fa858af16 Update version and changelog for v3.37.1 2026-07-16 15:38:11 +00:00
github-actions[bot] 4b646a0e5d Merge remote-tracking branch 'origin/releases/v4' into backport-v3.37.1-7188fc363
# Conflicts:
#	lib/entry-points.js
2026-07-16 15:38:11 +00:00
github-actions[bot] 44c5914b66 Revert "Rebuild"
This reverts commit af1b30ee40.
2026-07-16 15:38:10 +00:00
github-actions[bot] 0d531cfd92 Revert "Update version and changelog for v3.37.0"
This reverts commit 530c909a55.
2026-07-16 15:38:10 +00:00
Michael B. Gale 02c5e83432 Merge pull request #3998 from github/backport-v3.37.0-99df26d4f
Merge releases/v4 into releases/v3
2026-07-08 14:15:11 +01:00
Michael B. Gale af1b30ee40 Rebuild 2026-07-08 13:43:18 +01:00
github-actions[bot] 530c909a55 Update version and changelog for v3.37.0 2026-07-08 12:11:58 +00:00
github-actions[bot] 0507814306 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.37.0-99df26d4f
# Conflicts:
#	lib/entry-points.js
2026-07-08 12:11:58 +00:00
github-actions[bot] 157d34d3cf Revert "Rebuild"
This reverts commit d56b7d789e.
2026-07-08 12:11:58 +00:00
github-actions[bot] b8c8426f7c Revert "Update version and changelog for v3.36.3"
This reverts commit 66185e671d.
2026-07-08 12:11:58 +00:00
Michael B. Gale 411c4c9a36 Merge pull request #3992 from github/backport-v3.36.3-54f647b7e
Merge releases/v4 into releases/v3
2026-07-02 12:09:38 +01:00
github-actions[bot] 6153c156f7 Rebuild and trigger workflows 2026-07-02 11:56:57 +01:00
github-actions[bot] 66185e671d Update version and changelog for v3.36.3 2026-07-02 09:32:14 +00:00
github-actions[bot] 51edd47ebb Merge remote-tracking branch 'origin/releases/v4' into backport-v3.36.3-54f647b7e 2026-07-02 09:32:14 +00:00
github-actions[bot] a90bc064bf Revert "Rebuild"
This reverts commit 0d313a3b02.
2026-07-02 09:32:13 +00:00
github-actions[bot] ac8484ec8f Revert "Update version and changelog for v3.36.2"
This reverts commit ee98575270.
2026-07-02 09:32:13 +00:00
Henry Mercer dd903d2e4f Merge pull request #3952 from github/backport-v3.36.2-8aad20d15
Merge releases/v4 into releases/v3
2026-06-04 15:51:55 +01:00
github-actions[bot] 0d313a3b02 Rebuild 2026-06-04 14:29:11 +00:00
github-actions[bot] ee98575270 Update version and changelog for v3.36.2 2026-06-04 14:28:59 +00:00
github-actions[bot] 7d9a983ed4 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.36.2-8aad20d15 2026-06-04 14:28:59 +00:00
github-actions[bot] 6016976cee Revert "Rebuild"
This reverts commit e816d2e818.
2026-06-04 14:28:58 +00:00
github-actions[bot] 72c906de81 Revert "Update version and changelog for v3.36.1"
This reverts commit b6eff7b44a.
2026-06-04 14:28:58 +00:00
Henry Mercer d77b13a0df Merge pull request #3942 from github/backport-v3.36.1-87557b9c8
Merge releases/v4 into releases/v3
2026-06-02 11:35:41 +01:00
github-actions[bot] e816d2e818 Rebuild 2026-06-02 10:11:09 +00:00
github-actions[bot] b6eff7b44a Update version and changelog for v3.36.1 2026-06-02 10:10:55 +00:00
github-actions[bot] 3b37ae1c9b Merge remote-tracking branch 'origin/releases/v4' into backport-v3.36.1-87557b9c8 2026-06-02 10:10:55 +00:00
github-actions[bot] 2587a4beb2 Revert "Rebuild"
This reverts commit bc887cab05.
2026-06-02 10:10:55 +00:00
github-actions[bot] c02b552b1a Revert "Update version and changelog for v3.36.0"
This reverts commit a9739a6bf0.
2026-06-02 10:10:55 +00:00
Óscar San José 03e4368ac7 Merge pull request #3929 from github/backport-v3.36.0-7211b7c80
Merge releases/v4 into releases/v3
2026-05-22 13:27:24 +02:00
github-actions[bot] bc887cab05 Rebuild 2026-05-22 11:10:26 +00:00
github-actions[bot] a9739a6bf0 Update version and changelog for v3.36.0 2026-05-22 11:10:14 +00:00
github-actions[bot] 2be5c61e31 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.36.0-7211b7c80 2026-05-22 11:10:14 +00:00
github-actions[bot] 9b64c8b76e Revert "Rebuild"
This reverts commit 4b79f1ba10.
2026-05-22 11:10:14 +00:00
github-actions[bot] c45c87a4c5 Revert "Update version and changelog for v3.35.5"
This reverts commit b2dd803f6e.
2026-05-22 11:10:14 +00:00
Michael B. Gale 458d36d7d4 Merge pull request #3907 from github/backport-v3.35.5-9e0d7b8d2
Merge releases/v4 into releases/v3
2026-05-15 13:40:29 +01:00
Michael B. Gale 70a1165f9a Resolve conflicts in action.yml files 2026-05-15 13:21:17 +01:00
github-actions[bot] 4b79f1ba10 Rebuild 2026-05-15 12:17:32 +00:00
github-actions[bot] b2dd803f6e Update version and changelog for v3.35.5 2026-05-15 11:26:47 +00:00
github-actions[bot] 0e6a98bb2f Merge remote-tracking branch 'origin/releases/v4' into backport-v3.35.5-9e0d7b8d2
# Conflicts:
#	analyze/action.yml
#	autobuild/action.yml
#	init/action.yml
#	resolve-environment/action.yml
#	setup-codeql/action.yml
#	start-proxy/action.yml
#	upload-sarif/action.yml
2026-05-15 11:26:47 +00:00
github-actions[bot] cb4dbcd837 Revert "Rebuild"
This reverts commit ea18e99ca3.
2026-05-15 11:26:46 +00:00
github-actions[bot] cad7075882 Revert "Update version and changelog for v3.35.4"
This reverts commit 19f4654991.
2026-05-15 11:26:45 +00:00
Paolo Tranquilli 7fd177fa68 Merge pull request #3887 from github/backport-v3.35.4-68bde559d
Merge releases/v4 into releases/v3
2026-05-08 08:19:44 +02:00
github-actions[bot] ea18e99ca3 Rebuild 2026-05-07 16:19:46 +00:00
github-actions[bot] 19f4654991 Update version and changelog for v3.35.4 2026-05-07 15:56:10 +00:00
github-actions[bot] 8f15c6f1ad Merge remote-tracking branch 'origin/releases/v4' into backport-v3.35.4-68bde559d 2026-05-07 15:56:06 +00:00
github-actions[bot] 349cedea3b Revert "Rebuild"
This reverts commit 30f0c9d081.
2026-05-07 15:56:06 +00:00
github-actions[bot] f0ffd5714c Revert "Update version and changelog for v3.35.3"
This reverts commit 3530cdd15e.
2026-05-07 15:56:05 +00:00
Michael B. Gale 0daab03d71 Merge pull request #3869 from github/backport-v3.35.3-e46ed2cbd 2026-05-01 15:42:49 +01:00
github-actions[bot] 30f0c9d081 Rebuild 2026-05-01 14:16:34 +00:00
github-actions[bot] 3530cdd15e Update version and changelog for v3.35.3 2026-05-01 14:09:52 +00:00
github-actions[bot] 8280251823 Merge remote-tracking branch 'origin/releases/v4' into backport-v3.35.3-e46ed2cbd 2026-05-01 14:09:51 +00:00
github-actions[bot] e511c7b2e0 Revert "Rebuild"
This reverts commit c186c7b484.
2026-05-01 14:09:50 +00:00
github-actions[bot] 50052a22af Revert "Update version and changelog for v3.35.2"
This reverts commit 8bcc8f23a2.
2026-05-01 14:09:50 +00:00
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 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
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
Ó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] b1a5f00cf1 Rebuild 2026-03-27 12:23:35 +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
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] 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
Ó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] 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
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
97 changed files with 2004 additions and 2520 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
+4 -7
View File
@@ -6,11 +6,11 @@ inputs:
required: true
use-all-platform-bundle:
description: "If true, we output a tools URL with codeql-bundle.tar.gz file rather than platform-specific URL"
default: "false"
default: 'false'
required: false
setup-kotlin:
description: "If true, we setup kotlin"
default: "true"
default: 'true'
required: true
outputs:
tools-url:
@@ -73,10 +73,7 @@ runs:
exit 1
fi
- uses: fwilhe2/setup-kotlin@b325539ca8f6e1d9ee04efed06f49bdbf5426dbb # v2.1
- uses: fwilhe2/setup-kotlin@9c245a6425255f5e98ba1ce6c15d31fce7eca9da
if: ${{ inputs.setup-kotlin == 'true' }}
with:
# Kotlin is installed on the runners by default, but the version that is pre-installed is too new
# to be supported by CodeQL. This Kotlin version is selected to be compatible with both the default Java
# version on the `ubuntu-latest` runners and CodeQL.
version: 2.1.20
version: 1.8.21
@@ -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
+1 -1
View File
@@ -26,7 +26,7 @@ updates:
- package-ecosystem: github-actions
directories:
- "/.github/workflows"
- "/.github/actions/*/"
- "/.github/actions"
schedule:
interval: weekly
cooldown:
@@ -63,7 +63,7 @@ jobs:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Java
uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6 # v6.0.1
with:
java-version: ${{ inputs.java-version || '17' }}
distribution: temurin
+1 -1
View File
@@ -63,7 +63,7 @@ jobs:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Java
uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6 # v6.0.1
with:
java-version: ${{ inputs.java-version || '17' }}
distribution: temurin
+19 -17
View File
@@ -46,15 +46,6 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Node.js
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: 20.x
cache: npm
- name: Install newer npm
run: npm install -g npm@11.19.1
- name: Install dependencies
run: npm ci
- name: Prepare test
id: prepare-test
uses: ./.github/actions/prepare-test
@@ -62,20 +53,31 @@ jobs:
version: ${{ matrix.version }}
use-all-platform-bundle: 'false'
setup-kotlin: 'true'
- name: Install @actions/tool-cache
run: npm install @actions/tool-cache@3
- name: Check toolcache contains CodeQL
continue-on-error: true
run: |
cd ./../action
npx tsx ./pr-checks/toolcache.ts installed
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const toolcache = require('@actions/tool-cache');
const allCodeqlVersions = toolcache.findAllVersions('CodeQL');
if (allCodeqlVersions.length === 0) {
throw new Error(`CodeQL could not be found in the toolcache`);
}
- id: setup-codeql
uses: ./../action/setup-codeql
with:
tools: ${{ steps.prepare-test.outputs.tools-url }}
- name: Check CodeQL is installed within the toolcache
run: |
cd ./../action
npx tsx ./pr-checks/toolcache.ts installed
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const toolcache = require('@actions/tool-cache');
const allCodeqlVersions = toolcache.findAllVersions('CodeQL');
console.log(`Found CodeQL versions: ${allCodeqlVersions}`);
if (allCodeqlVersions.length === 0) {
throw new Error('CodeQL not found in toolcache');
}
env:
CODEQL_ACTION_TEST_MODE: true
+30 -22
View File
@@ -50,15 +50,6 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Node.js
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: 20.x
cache: npm
- name: Install newer npm
run: npm install -g npm@11.19.1
- name: Install dependencies
run: npm ci
- name: Prepare test
id: prepare-test
uses: ./.github/actions/prepare-test
@@ -67,30 +58,47 @@ jobs:
use-all-platform-bundle: 'false'
setup-kotlin: 'true'
- name: Remove CodeQL from toolcache
run: |
cd ./../action
npx tsx ./pr-checks/toolcache.ts clear
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const fs = require('fs');
const path = require('path');
const codeqlPath = path.join(process.env['RUNNER_TOOL_CACHE'], 'CodeQL');
fs.rmdirSync(codeqlPath, { recursive: true });
- name: Install @actions/tool-cache
run: npm install @actions/tool-cache@3
- name: Check toolcache does not contain CodeQL
run: |
cd ./../action
npx tsx ./pr-checks/toolcache.ts absent
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const toolcache = require('@actions/tool-cache');
const allCodeqlVersions = toolcache.findAllVersions('CodeQL');
if (allCodeqlVersions.length !== 0) {
throw new Error(`CodeQL should not be found in the toolcache, but found ${allCodeqlVersions}`);
}
console.log('No versions of CodeQL found in the toolcache');
- id: init
uses: ./../action/init
with:
# Request multiple languages so this check uses the combined bundle.
languages: javascript,python
tools: ${{ steps.prepare-test.outputs.tools-url }}
- uses: ./../action/analyze
with:
output: ${{ runner.temp }}/results
upload-database: false
- name: Check CodeQL is installed within the toolcache
run: |
cd ./../action
npx tsx ./pr-checks/toolcache.ts installed -n 1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const toolcache = require('@actions/tool-cache');
const allCodeqlVersions = toolcache.findAllVersions('CodeQL');
console.log(`Found CodeQL versions: ${allCodeqlVersions}`);
if (allCodeqlVersions.length === 0) {
throw new Error('CodeQL not found in toolcache');
}
if (allCodeqlVersions.length > 1) {
throw new Error('Multiple CodeQL versions found in toolcache');
}
env:
CODEQL_ACTION_TEST_MODE: true
-143
View File
@@ -1,143 +0,0 @@
# Warning: This file is generated automatically, and should not be modified.
# Instead, please modify the template in the pr-checks directory and run:
# pr-checks/sync.sh
# to regenerate this file.
name: PR Check - Diagnostic export without database
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GO111MODULE: auto
on:
push:
branches:
- main
- releases/v*
pull_request: {}
merge_group:
types:
- checks_requested
schedule:
- cron: '0 5 * * *'
workflow_dispatch:
inputs: {}
workflow_call:
inputs: {}
defaults:
run:
shell: bash
concurrency:
cancel-in-progress: ${{ github.event_name == 'pull_request' || false }}
group: diagnostics-without-db-${{github.ref}}
jobs:
diagnostics-without-db:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: linked
name: Diagnostic export without database
if: github.triggering_actor != 'dependabot[bot]'
permissions:
contents: read
security-events: read
timeout-minutes: 45
runs-on: ${{ matrix.os }}
steps:
# We deliberately need to make this step fail before the database is initialised, but after
# some diagnostic has been produced. The simplest way to do that right now is to:
#
# - Produce a diagnostic before the db is initialised by forcing the use of a nightly release
# with the `CODEQL_ACTION_FORCE_NIGHTLY` feature flag.
# - Cause `init` to abort because we are attempting to analyse Swift on a non-macOS runner.
#
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Node.js
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: 20.x
cache: npm
- name: Install newer npm
run: npm install -g npm@11.19.1
- name: Install dependencies
run: npm ci
- name: Prepare test
id: prepare-test
uses: ./.github/actions/prepare-test
with:
version: ${{ matrix.version }}
use-all-platform-bundle: 'false'
setup-kotlin: 'true'
- name: Initialise failing analysis
id: init
uses: ./../action/init
continue-on-error: true
env:
CODEQL_ACTION_FORCE_NIGHTLY: true
with:
languages: swift
tools: ${{ steps.prepare-test.outputs.tools-url }}
- name: Analyze
uses: ./analyze
# In a real workflow, this step wouldn't run. Since we used `continue-on-error`
# above, we manually disable it with an `if` condition. Having this step is required
# for the init post-action because it checks the workflow definition for e.g. the
# `category` input. Without this step, that part of the init post-action would fail.
if: false
with:
category: '/test-codeql-version:${{ matrix.version }}'
- name: Check diagnostics appear on disk
env:
DIAGNOSTICS_DIR: '${{ runner.temp }}/codeql-action-temp-diagnostics/'
run: |
cd ../action
npx tsx ./pr-checks/diagnostics-without-db.ts
env:
CODEQL_ACTION_SKIP_GENERATE_FAILED_SARIF: false
CODEQL_ACTION_SKIP_SARIF_UPLOAD: true
CODEQL_ACTION_TESTING_ENVIRONMENT: codeql-action-pr-checks
CODEQL_ACTION_TEST_MODE: true
diagnostics-without-db-validation:
if: github.triggering_actor != 'dependabot[bot]'
needs:
- diagnostics-without-db
permissions:
contents: read
security-events: read
timeout-minutes: 5
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Node.js
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: 20.x
cache: npm
- name: Install newer npm
run: npm install -g npm@11.19.1
- name: Install dependencies
run: npm ci
- name: Download workflow artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: test-mode-sarif-*
path: sarif
- name: List artifact contents
run: ls -laR ./sarif
- name: Check diagnostics appear in SARIF
env:
SARIF_PATH: "./sarif/codeql-failed-run.sarif"
DIAGNOSTIC_ID: "codeql-action/forced-nightly-cli"
DIAGNOSTIC_NAME: "A nightly release of CodeQL was used"
EXPECTED_LOCATIONS: "0"
EXPECTED_MESSAGE: |
GitHub configured this analysis to use a nightly release of CodeQL to allow you to preview changes from an upcoming release.
run: npx tsx ./pr-checks/check-diagnostics.ts
env:
CODEQL_ACTION_TEST_MODE: true
+1 -5
View File
@@ -91,11 +91,6 @@ jobs:
with:
languages: javascript
tools: ${{ steps.prepare-test.outputs.tools-url }}
# To balance speed and coverage, analyze only JavaScript but use the combined bundle so
# baseline information is reported for every language in the multi-language repository. A
# custom configuration prevents per-language bundles from being used.
config: |
paths-ignore: []
- name: Build code
run: ./build.sh
- uses: ./../action/analyze
@@ -129,4 +124,5 @@ jobs:
env:
CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS: false
CODEQL_ACTION_SUBLANGUAGE_FILE_COVERAGE: true
CODEQL_ACTION_PER_LANGUAGE_BUNDLES: false
CODEQL_ACTION_TEST_MODE: true
+1 -1
View File
@@ -44,7 +44,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
- os: ubuntu-latest
version: stable-v2.20.7
- os: ubuntu-latest
version: stable-v2.21.4
+1 -1
View File
@@ -44,7 +44,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
- os: ubuntu-latest
version: stable-v2.20.7
- os: ubuntu-latest
version: stable-v2.21.4
+1 -1
View File
@@ -44,7 +44,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
- os: ubuntu-latest
version: stable-v2.20.7
- os: ubuntu-latest
version: stable-v2.21.4
+1 -1
View File
@@ -54,7 +54,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
- os: ubuntu-latest
version: stable-v2.20.7
- os: macos-15-xlarge
version: stable-v2.20.7
+14 -25
View File
@@ -36,40 +36,40 @@ jobs:
include:
- language: actions
os: ubuntu-latest
version: linked
version: nightly-latest
expected-extractors: actions javascript
- language: cpp
os: ubuntu-latest
version: linked
version: nightly-latest
build-mode: manual
build-command: gcc -o main main.c
- language: csharp
os: ubuntu-latest
version: linked
version: nightly-latest
build-mode: none
- language: go
os: ubuntu-latest
version: linked
version: nightly-latest
build-mode: autobuild
- language: java
os: ubuntu-latest
version: linked
version: nightly-latest
build-mode: none
- language: javascript
os: ubuntu-latest
version: linked
version: nightly-latest
- language: python
os: ubuntu-latest
version: linked
version: nightly-latest
- language: ruby
os: ubuntu-latest
version: linked
version: nightly-latest
- language: rust
os: ubuntu-latest
version: linked
version: nightly-latest
- language: swift
os: macos-latest-xlarge
version: linked
version: nightly-latest
build-mode: autobuild
name: Per-language bundles
if: github.triggering_actor != 'dependabot[bot]'
@@ -81,15 +81,6 @@ jobs:
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install Node.js
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: 20.x
cache: npm
- name: Install newer npm
run: npm install -g npm@11.19.1
- name: Install dependencies
run: npm ci
- name: Prepare test
id: prepare-test
uses: ./.github/actions/prepare-test
@@ -97,10 +88,6 @@ jobs:
version: ${{ matrix.version }}
use-all-platform-bundle: 'false'
setup-kotlin: 'true'
- name: Remove CodeQL from toolcache
run: |
cd ./../action
npx tsx ./pr-checks/toolcache.ts clear
- uses: ./../action/init
id: init
with:
@@ -141,8 +128,9 @@ jobs:
CODEQL_PATH: ${{ steps.init.outputs.codeql-path }}
run: |
# A bundle that is missing most of its extractors must never be left in the toolcache,
# where a later job analyzing a different language could pick it up. Per-language bundles
# must instead be extracted under the runner's temporary directory.
# where a later job analyzing a different language could pick it up. The runner image
# ships with its own CodeQL in the toolcache, so check where this bundle was extracted to
# rather than whether the toolcache contains CodeQL at all.
echo "CodeQL is at $CODEQL_PATH"
if [[ "$CODEQL_PATH" == "$RUNNER_TOOL_CACHE"/* ]]; then
echo "::error::The per-language bundle was added to the toolcache at $CODEQL_PATH."
@@ -172,4 +160,5 @@ jobs:
fi
echo "Created a ${LANGUAGE} database at ${database}."
env:
CODEQL_ACTION_PER_LANGUAGE_BUNDLES: true
CODEQL_ACTION_TEST_MODE: true
+74
View File
@@ -0,0 +1,74 @@
# Warning: This file is generated automatically, and should not be modified.
# Instead, please modify the template in the pr-checks directory and run:
# pr-checks/sync.sh
# to regenerate this file.
name: PR Check - RuboCop multi-language
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GO111MODULE: auto
on:
push:
branches:
- main
- releases/v*
pull_request: {}
merge_group:
types:
- checks_requested
schedule:
- cron: '0 5 * * *'
workflow_dispatch:
inputs: {}
workflow_call:
inputs: {}
defaults:
run:
shell: bash
concurrency:
cancel-in-progress: ${{ github.event_name == 'pull_request' || false }}
group: rubocop-multi-language-${{github.ref}}
jobs:
rubocop-multi-language:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: default
name: RuboCop multi-language
if: github.triggering_actor != 'dependabot[bot]'
permissions:
contents: read
security-events: read
timeout-minutes: 45
runs-on: ${{ matrix.os }}
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Prepare test
id: prepare-test
uses: ./.github/actions/prepare-test
with:
version: ${{ matrix.version }}
use-all-platform-bundle: 'false'
setup-kotlin: 'true'
- name: Set up Ruby
uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 # v1.327.0
with:
ruby-version: 2.6
- name: Install Code Scanning integration
run: bundle add code-scanning-rubocop --version 0.3.0 --skip-install
- name: Install dependencies
run: bundle install
- name: RuboCop run
run: |
bash -c "
bundle exec rubocop --require code_scanning --format CodeScanning::SarifFormatter -o rubocop.sarif
[[ $? -ne 2 ]]
"
- uses: ./../action/upload-sarif
with:
sarif_file: rubocop.sarif
env:
CODEQL_ACTION_TEST_MODE: true
+1 -1
View File
@@ -34,7 +34,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
- os: ubuntu-latest
version: stable-v2.20.7
- os: ubuntu-latest
version: stable-v2.22.1
+1 -3
View File
@@ -71,9 +71,7 @@ jobs:
run: exit 1
- uses: ./analyze
# In a real workflow, this step wouldn't run. Since we used `continue-on-error`
# above, we manually disable it with an `if` condition. Having this step is required
# for the init post-action because it checks the workflow definition for e.g. the
# `category` input. Without this step, that part of the init post-action would fail.
# above, we manually disable it with an `if` condition.
if: false
with:
category: '/test-codeql-version:${{ matrix.version }}'
@@ -6,13 +6,13 @@ env:
on:
push:
branches:
- main
- releases/v*
- main
- releases/v*
pull_request:
merge_group:
types: [checks_requested]
schedule:
- cron: "0 5 * * *"
- cron: '0 5 * * *'
workflow_dispatch:
concurrency:
@@ -30,10 +30,10 @@ jobs:
fail-fast: false
matrix:
version:
- stable-v2.20.7
- default
- linked
- nightly-latest
- stable-v2.20.7
- default
- linked
- nightly-latest
name: Upload debug artifacts after failure in analyze
continue-on-error: true
env:
@@ -43,12 +43,7 @@ jobs:
# We currently need `security-events: read` to access feature flags.
security-events: read
timeout-minutes: 45
# stable-v2.20.7 requires an older version of Java than the default on `ubuntu-latest` (`ubuntu-26.04`).
# We could install that older version on the newer runners, or use the older runner.
# We do the latter here. This can be removed once we stop supporting `v2.20.7`.
runs-on: ${{ case(matrix.version == 'stable-v2.20.7', 'ubuntu-24.04', 'ubuntu-latest') }}
runs-on: ubuntu-latest
steps:
- name: Dump GitHub event
run: cat "${GITHUB_EVENT_PATH}"
@@ -65,7 +60,7 @@ jobs:
- name: Install .NET
uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
with:
dotnet-version: "9.x"
dotnet-version: '9.x'
- name: Assert best-effort artifact scan completed
uses: ./../action/.github/actions/verify-debug-artifact-scan-completed
- uses: ./../action/init
+9 -14
View File
@@ -5,13 +5,13 @@ env:
on:
push:
branches:
- main
- releases/v*
- main
- releases/v*
pull_request:
merge_group:
types: [checks_requested]
schedule:
- cron: "0 5 * * *"
- cron: '0 5 * * *'
workflow_dispatch:
concurrency:
@@ -29,10 +29,10 @@ jobs:
fail-fast: false
matrix:
version:
- stable-v2.20.7
- default
- linked
- nightly-latest
- stable-v2.20.7
- default
- linked
- nightly-latest
name: Upload debug artifacts
env:
CODEQL_ACTION_TEST_MODE: true
@@ -41,12 +41,7 @@ jobs:
contents: read
# We currently need `security-events: read` to access feature flags.
security-events: read
# stable-v2.20.7 requires an older version of Java than the default on `ubuntu-latest` (`ubuntu-26.04`).
# We could install that older version on the newer runners, or use the older runner.
# We do the latter here. This can be removed once we stop supporting `v2.20.7`.
runs-on: ${{ case(matrix.version == 'stable-v2.20.7', 'ubuntu-24.04', 'ubuntu-latest') }}
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -61,7 +56,7 @@ jobs:
- name: Install .NET
uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6.0.0
with:
dotnet-version: "9.x"
dotnet-version: '9.x'
- name: Assert best-effort artifact scan completed
uses: ./../action/.github/actions/verify-debug-artifact-scan-completed
- uses: ./../action/init
+1
View File
@@ -60,6 +60,7 @@ on:
- "PR Check - Proxy test"
- "PR Check - Remote config file"
- "PR Check - Resolve environment"
- "PR Check - RuboCop multi-language"
- "PR Check - Ruby analysis"
- "PR Check - Rust analysis"
- "PR Check - Split workflow"
+1 -1
View File
@@ -134,7 +134,7 @@ jobs:
echo "::endgroup::"
- name: Generate token
uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
id: app-token
with:
app-id: ${{ vars.AUTOMATION_APP_ID }}
+2 -2
View File
@@ -126,10 +126,10 @@ jobs:
if: ${{ !cancelled() && steps.install-deps.outcome == 'success' }}
run: .github/workflows/script/verify-pr-checks.sh
- name: Run pr-checks checks
- name: Run pr-checks tests
if: ${{ !cancelled() && steps.install-deps.outcome == 'success' }}
working-directory: pr-checks
run: npm run checks
run: npx tsx --test
- name: Run `pr-checks/changenotes.ts` to ensure that all unreleased change notes are valid
if: ${{ !cancelled() && steps.install-deps.outcome == 'success' }}
-28
View File
@@ -1,28 +0,0 @@
name: PR dequeued
on:
pull_request:
types:
- dequeued
jobs:
notify:
name: Notify
runs-on: ubuntu-slim
if: github.event.pull_request.merged != true
permissions:
pull-requests: write
steps:
- name: Notify that the PR was removed from the merge queue
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REASON: ${{ github.event.reason }}
USER: ${{ github.event.pull_request.user.login }}
run: |
echo "@$USER The pull request was removed from the merge queue (\`$REASON\`)." \
"Please resolve any issues if required and enqueue the PR again." |
gh pr comment --body-file - --repo github/codeql-action "$PR_NUMBER"
+1 -1
View File
@@ -139,7 +139,7 @@ jobs:
- name: Generate token
if: github.event_name == 'workflow_dispatch'
uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
id: app-token
with:
app-id: ${{ vars.AUTOMATION_APP_ID }}
+1 -1
View File
@@ -95,7 +95,7 @@ jobs:
pull-requests: write # needed to create pull request
steps:
- name: Generate token
uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
id: app-token
with:
app-id: ${{ vars.AUTOMATION_APP_ID }}
+52 -56
View File
@@ -2,117 +2,113 @@
See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs.
## [UNRELEASED]
No user facing changes.
## 4.39.1 - 21 Oct 2026
## 3.39.1 - 21 Oct 2026
- Update default CodeQL bundle version to [2.27.3](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.3). [#4256](https://github.com/github/codeql-action/pull/4256)
## 4.39.0 - 15 Oct 2026
## 3.39.0 - 15 Oct 2026
- _Breaking change_: Bump the minimum required CodeQL bundle version to 2.20.7. [#4205](https://github.com/github/codeql-action/pull/4205)
- The `codeql-action/analyze` step now validates that a correct argument for the `checkout_path` input has been provided. The `checkout_path` input must be set to the path where the repository that is being analyzed is checked out at on the runner, if that path is something other than the workspace root. If the path does not point to a repository checkout or is different from the path that was used by `codeql-action/init`, then the CodeQL Action now produces a warning. [#4148](https://github.com/github/codeql-action/pull/4148)
- Resolved an issue with third-party caching implementations that prevented caches from being restored correctly. [#4206](https://github.com/github/codeql-action/pull/4206)
- The `codeql-action/start-proxy` step that is used in Code Scanning Default Setup now finds CodeQL releases using the same logic as `codeql-action/init`. This primarily benefits customers who are using GitHub instances other than `github.com` where the `codeql-action/start-proxy` step may previously have been unable to locate recent releases and ended up using outdated versions of the private registry authentication proxy as a result. [#4198](https://github.com/github/codeql-action/pull/4198)
## 4.38.3 - 08 Oct 2026
## 3.38.3 - 08 Oct 2026
- _Upcoming breaking change_: CodeQL version 2.21.2 and earlier were discontinued on 24 September 2026 alongside GitHub Enterprise Server 3.17, and will be unsupported by the next minor release of the CodeQL Action. Added a deprecation warning for customers using these versions of CodeQL. [#4188](https://github.com/github/codeql-action/pull/4188)
- Update default CodeQL bundle version to [2.27.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.2). [#4203](https://github.com/github/codeql-action/pull/4203)
- Fixed a bug where the decision of whether to use a per-language bundle did not account for custom configurations that reference queries outside of compiled CodeQL packs. This issue was caught during internal testing and did not affect any customer repositories. We will resume the roll out of per-language bundles in the coming weeks. [#4184](https://github.com/github/codeql-action/pull/4184)
## 4.38.2 - 24 Sept 2026
## 3.38.2 - 24 Sept 2026
- Update default CodeQL bundle version to [2.27.1](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.1). [#4160](https://github.com/github/codeql-action/pull/4160)
## 4.38.1 - 18 Sept 2026
## 3.38.1 - 18 Sept 2026
- The CodeQL Action now has experimental support for CodeQL releases for which per-language bundles are available. Per-language bundles support analysis for a single language and are therefore smaller than the combined bundles that allow analysis for all supported languages. As a result, per-language bundles take up less space on disk and are faster to download. We expect to roll this change out to everyone in the coming weeks. [#4146](https://github.com/github/codeql-action/pull/4146)
## 4.38.0 - 09 Sept 2026
## 3.38.0 - 09 Sept 2026
- On GitHub-hosted runners, the CodeQL Action now deletes unused CodeQL bundles from the toolcache before downloading a different bundle, which frees up disk space for the analysis. We expect to roll this change out to everyone in September. [#4124](https://github.com/github/codeql-action/pull/4124)
- The CodeQL Action now supports CodeQL releases that are compatible with Linux Arm64 and downloads the native `linux-arm64` CodeQL bundle when available. [#4072](https://github.com/github/codeql-action/pull/4072)
- Update default CodeQL bundle version to [2.27.0](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.27.0). [#4129](https://github.com/github/codeql-action/pull/4129)
## 4.37.9 - 26 Aug 2026
## 3.37.9 - 26 Aug 2026
- Update default CodeQL bundle version to [2.26.4](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.4). [#4106](https://github.com/github/codeql-action/pull/4106)
## 4.37.8 - 21 Aug 2026
## 3.37.8 - 21 Aug 2026
No user facing changes.
## 4.37.7 - 13 Aug 2026
## 3.37.7 - 13 Aug 2026
- Update default CodeQL bundle version to [2.26.3](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.3). [#4085](https://github.com/github/codeql-action/pull/4085)
## 4.37.6 - 04 Aug 2026
## 3.37.6 - 04 Aug 2026
- Changed the default filepath for the new remote file address format that was introduced in CodeQL Action 4.37.0 / 3.37.0 to `.github/codeql-config.yml` to align it with the suggested path that is used elsewhere. [#4070](https://github.com/github/codeql-action/pull/4070)
## 4.37.5 - 03 Aug 2026
## 3.37.5 - 03 Aug 2026
- Fixed a bug where a network error while streaming the download of the CodeQL bundle could terminate the `init` Action instead of falling back to downloading the bundle before extracting it. [#4061](https://github.com/github/codeql-action/pull/4061)
## 4.37.4 - 29 Jul 2026
## 3.37.4 - 29 Jul 2026
- This version of the CodeQL Action adds support for the `tools` input for the `codeql-action/init` step to be specified using a `github-codeql-tools` [repository property](https://docs.github.com/en/organizations/managing-organization-settings/managing-custom-properties-for-repositories-in-your-organization). This feature will gradually be rolled out following the release of this version. Once rolled out, this allows for the CodeQL CLI version that is used in GitHub-managed workflows, such as Default Setup, to be set to a custom value. For example, customers who run into issues with rate limits when a new CodeQL CLI version is released can set the value to `toolcache` to always use the CodeQL CLI version that is available in the runner toolcache. For Advanced Setup workflows, the value provided for `tools` in the workflow definition always takes precedence unless the value of the repository property starts with `!`. [#4037](https://github.com/github/codeql-action/pull/4037)
- Update default CodeQL bundle version to [2.26.2](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.2). [#4051](https://github.com/github/codeql-action/pull/4051)
## 4.37.3 - 22 Jul 2026
## 3.37.3 - 22 Jul 2026
No user facing changes.
## 4.37.2 - 21 Jul 2026
## 3.37.2 - 21 Jul 2026
- The new address format for the `config-file` input that was introduced in CodeQL Action 4.37.0 is now enabled by default. In addition to the format described there, the `remote=` prefix can now be used to explicitly indicate that the input refers to a remote file. All previous input formats continue to be accepted as well. [#4023](https://github.com/github/codeql-action/pull/4023)
- The CodeQL Action can now make use of [configured private 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) in Default Setup to retrieve CodeQL configuration files from remote repositories that require authentication. This will allow customers to store their CodeQL configuration in a single repository that can then be referenced by Default Setup workflows in other repositories. We expect to roll this and other, related changes out to everyone in July. [#4007](https://github.com/github/codeql-action/pull/4007)
## 4.37.1 - 16 Jul 2026
## 3.37.1 - 16 Jul 2026
- _Upcoming breaking change_: Add a deprecation warning for customers using CodeQL version 2.20.6 and earlier. These versions of CodeQL were discontinued on 1 July 2026 alongside GitHub Enterprise Server 3.16, and will be unsupported by the next minor release of the CodeQL Action. [#3956](https://github.com/github/codeql-action/pull/3956)
- Update default CodeQL bundle version to [2.26.1](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.1). [#4019](https://github.com/github/codeql-action/pull/4019)
## 4.37.0 - 08 Jul 2026
## 3.37.0 - 08 Jul 2026
- Update default CodeQL bundle version to [2.26.0](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.26.0). [#3995](https://github.com/github/codeql-action/pull/3995)
- In addition to the existing input format, the `config-file` input for the `codeql-action/init` step will soon support a new `[owner/]repo[@ref][:path]` format. All components except the repository name are optional. If omitted, `owner` defaults to the same owner as the repository the analysis is running for, `ref` to `main`, and `path` to `.github/codeql-action.yaml`. Support for this format ships in this version of the CodeQL Action, but will only be enabled over the coming weeks. [#3973](https://github.com/github/codeql-action/pull/3973)
## 4.36.3 - 01 Jul 2026
## 3.36.3 - 01 Jul 2026
No user facing changes.
## 4.36.2 - 04 Jun 2026
## 3.36.2 - 04 Jun 2026
- Cache CodeQL CLI version information across Actions steps. [#3943](https://github.com/github/codeql-action/pull/3943)
- Reduce requests while waiting for analysis processing by using exponential backoff when polling SARIF processing status. [#3937](https://github.com/github/codeql-action/pull/3937)
- Update default CodeQL bundle version to [2.25.6](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.6). [#3948](https://github.com/github/codeql-action/pull/3948)
## 4.36.1 - 02 Jun 2026
## 3.36.1 - 02 Jun 2026
No user facing changes.
## 4.36.0 - 22 May 2026
## 3.36.0 - 22 May 2026
- _Breaking change_: Bump the minimum required CodeQL bundle version to 2.19.4. [#3894](https://github.com/github/codeql-action/pull/3894)
- Add support for SHA-256 Git object IDs. [#3893](https://github.com/github/codeql-action/pull/3893)
- Update default CodeQL bundle version to [2.25.5](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.5). [#3926](https://github.com/github/codeql-action/pull/3926)
## 4.35.5 - 15 May 2026
## 3.35.5 - 15 May 2026
- We have improved how the JavaScript bundles for the CodeQL Action are generated to avoid duplication across bundles and reduce the size of the repository by around 70%. This should have no effect on the runtime behaviour of the CodeQL Action. [#3899](https://github.com/github/codeql-action/pull/3899)
- For performance and accuracy reasons, [improved incremental analysis](https://github.com/github/roadmap/issues/1158) will now only be enabled on a pull request when diff-informed analysis is also enabled for that run. If diff-informed analysis is unavailable (for example, because the PR diff ranges could not be computed), the action will fall back to a full analysis. [#3791](https://github.com/github/codeql-action/pull/3791)
- If multiple inputs are provided for the GitHub-internal `analysis-kinds` input, only `code-scanning` will be enabled. The `analysis-kinds` input is experimental, for GitHub-internal use only, and may change without notice at any time. [#3892](https://github.com/github/codeql-action/pull/3892)
- Added an experimental change which, when running a Code Scanning analysis for a PR with [improved incremental analysis](https://github.com/github/roadmap/issues/1158) enabled, prefers CodeQL CLI versions that have a cached overlay-base database for the configured languages. This speeds up analysis for a repository when there is not yet a cached overlay-base database for the latest CLI version. We expect to roll this change out to everyone in May. [#3880](https://github.com/github/codeql-action/pull/3880)
## 4.35.4 - 07 May 2026
## 3.35.4 - 07 May 2026
- Update default CodeQL bundle version to [2.25.4](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.4). [#3881](https://github.com/github/codeql-action/pull/3881)
## 4.35.3 - 01 May 2026
## 3.35.3 - 01 May 2026
- _Upcoming breaking change_: Add a deprecation warning for customers using CodeQL version 2.19.3 and earlier. These versions of CodeQL were discontinued on 9 April 2026 alongside GitHub Enterprise Server 3.15, and will be unsupported by the next minor release of the CodeQL Action. [#3837](https://github.com/github/codeql-action/pull/3837)
- Configurations for private registries that use Cloudsmith or GCP OIDC are now accepted. [#3850](https://github.com/github/codeql-action/pull/3850)
@@ -120,7 +116,7 @@ No user facing changes.
- Fixed a bug where two diagnostics produced within the same millisecond could overwrite each other on disk, causing one of them to be lost. [#3852](https://github.com/github/codeql-action/pull/3852)
- Update default CodeQL bundle version to [2.25.3](https://github.com/github/codeql-action/releases/tag/codeql-bundle-v2.25.3). [#3865](https://github.com/github/codeql-action/pull/3865)
## 4.35.2 - 15 Apr 2026
## 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)
@@ -128,26 +124,26 @@ No user facing changes.
- 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)
## 4.35.1 - 27 Mar 2026
## 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)
## 4.35.0 - 27 Mar 2026
## 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)
## 4.34.1 - 20 Mar 2026
## 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)
## 4.34.0 - 20 Mar 2026
## 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)
@@ -161,11 +157,11 @@ No user facing changes.
- 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)
@@ -175,7 +171,7 @@ No user facing changes.
- 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)
@@ -183,89 +179,89 @@ No user facing changes.
- 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
- Update default CodeQL bundle version to 2.23.2. [#3168](https://github.com/github/codeql-action/pull/3168)
+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-entry.js"
post: "../lib/analyze-post-entry.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-entry.js'
+1 -1
View File
@@ -180,6 +180,6 @@ outputs:
codeql-version:
description: The version of the CodeQL binary used for analysis
runs:
using: node24
using: node20
main: '../lib/init-entry.js'
post: '../lib/init-post-entry.js'
+621 -582
View File
File diff suppressed because it is too large. Load diff
+72 -73
View File
@@ -1,12 +1,12 @@
{
"name": "codeql",
"version": "4.39.2",
"version": "4.39.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "codeql",
"version": "4.39.2",
"version": "4.39.1",
"license": "MIT",
"workspaces": [
"pr-checks"
@@ -36,7 +36,7 @@
"node-forge": "^1.4.0",
"semver": "^7.8.5",
"undici": "^6.28.0",
"uuid": "^14.0.3"
"uuid": "^14.0.2"
},
"devDependencies": {
"@ava/typescript": "6.0.0",
@@ -57,14 +57,14 @@
"eslint-import-resolver-typescript": "^4.4.5",
"eslint-plugin-github": "^6.1.2",
"eslint-plugin-import-x": "^4.17.1",
"eslint-plugin-jsdoc": "^65.3.4",
"eslint-plugin-jsdoc": "^65.2.0",
"eslint-plugin-no-async-foreach": "^0.1.1",
"glob": "^13.0.6",
"globals": "^17.13.0",
"nock": "^14.0.17",
"sinon": "^22.1.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.71.2"
"typescript-eslint": "^8.71.1"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -2702,17 +2702,17 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.71.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.71.2.tgz",
"integrity": "sha512-K72/pvT7qpm8q3k8G5u93NCSN1RcLxX5h7Gw0bQpbMXviBHeY6Nx1WEwmk9wP+eKTSQ8ecxvcgt/ZX/rB938xQ==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.71.1.tgz",
"integrity": "sha512-nNlBf6HuotqMgZvSkWD5hNdemiBIxQ2NmrlgfcUIeZRs+BbakjscCQRq/Hb74EFVnFiSWWdL12JruqwBy3ERDw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.12.2",
"@typescript-eslint/scope-manager": "8.71.2",
"@typescript-eslint/type-utils": "8.71.2",
"@typescript-eslint/utils": "8.71.2",
"@typescript-eslint/visitor-keys": "8.71.2",
"@typescript-eslint/scope-manager": "8.71.1",
"@typescript-eslint/type-utils": "8.71.1",
"@typescript-eslint/utils": "8.71.1",
"@typescript-eslint/visitor-keys": "8.71.1",
"ignore": "^7.0.5",
"natural-compare": "^1.4.0",
"ts-api-utils": "^2.5.0"
@@ -2725,7 +2725,7 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.71.2",
"@typescript-eslint/parser": "^8.71.1",
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.1.0"
}
@@ -2741,16 +2741,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.71.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.71.2.tgz",
"integrity": "sha512-aTtmZjp/x3gsGHkDs04/1I8kNogBJkpQaeGaN0PfiG43NzDEmW2n+OP5im9wfsvyX0yP1UZWBrAGtDBfH9jEVw==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.71.1.tgz",
"integrity": "sha512-oM/5sAqz/l1v/zYK1qTOPrn2+JIrBGC1V6uNYucRO5gh6eT9vWJ/RhPbGE59byvZEUQ4VP6XkLBaS5Jti5jpvw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/scope-manager": "8.71.2",
"@typescript-eslint/types": "8.71.2",
"@typescript-eslint/typescript-estree": "8.71.2",
"@typescript-eslint/visitor-keys": "8.71.2",
"@typescript-eslint/scope-manager": "8.71.1",
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/typescript-estree": "8.71.1",
"@typescript-eslint/visitor-keys": "8.71.1",
"debug": "^4.4.3"
},
"engines": {
@@ -2784,14 +2784,14 @@
}
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.71.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.71.2.tgz",
"integrity": "sha512-Pd68GsLVh5ZXlcEccFPdhSOvtHZ/2WU0XsA8zmXOS3F158lVlcTLhfQ6qvtL1RzbMie0Kp8xtbVwAg4nejKPHw==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.71.1.tgz",
"integrity": "sha512-Oijc9RUsohHjncg6iGi7gCtjnEjYt9FWv9u6ygK8uKcHK5eLjLAkqERQ9BaytbpceOFdk6kifPCS/zAZE+A99g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.71.2",
"@typescript-eslint/types": "^8.71.2",
"@typescript-eslint/tsconfig-utils": "^8.71.1",
"@typescript-eslint/types": "^8.71.1",
"debug": "^4.4.3"
},
"engines": {
@@ -2824,14 +2824,14 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.71.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.71.2.tgz",
"integrity": "sha512-YF4wgg5iUX5Obywoac27B56FhozMNFhdJSbh11H5GBAwmBtfyRhmgTQqW9tRNNmHDvsZ2CX6UGzoz+YfYn2Leg==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.71.1.tgz",
"integrity": "sha512-1YUDZXdTnXLlob03SFHBipdyMBsDVm7zoSz0ytTJ39dk5J1TgsTK03VlR/dLXG/RLLUrPcYbD4rp23BmHxHP0w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.71.2",
"@typescript-eslint/visitor-keys": "8.71.2"
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/visitor-keys": "8.71.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2842,9 +2842,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.71.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.71.2.tgz",
"integrity": "sha512-jz49TAWokm/7yWD9/o837nYax9DyALxIPOImdImvVzo6canBCZYzin8zJyqNR5k1j9K1DE0bVvr0XYB+99uAdg==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.71.1.tgz",
"integrity": "sha512-oTvkml5SxXhgg+WWKhod5qWQICDXtOB+/Hi9VdPKFAANJ2b7YOgMffgvzXuqog7R6A/JtrzRf128dsxummyWhg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2859,15 +2859,15 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.71.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.71.2.tgz",
"integrity": "sha512-cC8UaalCViJkb3rH/xLIvidEwoFRtMZMUqDjjJMGEKaTFwYRHYBcoczlEGHuvkHEO8svRDrgZ0yQgOArFmwang==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.71.1.tgz",
"integrity": "sha512-kH3t3jZCYv2PZSBEWPKTariLrCaoF1CLoPitYFBJOhAGEwWnSRAtGEifrfrpBa4K9JlwWNZotgA5w3/wLSk/FQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.71.2",
"@typescript-eslint/typescript-estree": "8.71.2",
"@typescript-eslint/utils": "8.71.2",
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/typescript-estree": "8.71.1",
"@typescript-eslint/utils": "8.71.1",
"debug": "^4.4.3",
"ts-api-utils": "^2.5.0"
},
@@ -2902,9 +2902,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.71.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.71.2.tgz",
"integrity": "sha512-y5Ukl3oVp7e/VGxqIoEXoeb/Roj71PAJ4WG/N/RGj+eeDvKRLM15kGr9MijLbN0i03S52zxu31Z98E5gWChJKw==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.71.1.tgz",
"integrity": "sha512-ybYnPTUwg3VQQOFEiBPLs8Jxl1ry2vXdn1kVKguomBbvxpetdu3MKTNDqFNUrlG8ylP9MpZosmXMFYlGQHk1oQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2916,16 +2916,16 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.71.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.71.2.tgz",
"integrity": "sha512-DgNOEsl4pdYzwSL+N/Cl33tX1Hlw3FvId73LnKXfq7jnrF2viOEn7X+P7RBkkSWCVm92gnWd28GIC5vJuLREeA==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.71.1.tgz",
"integrity": "sha512-pSKSEK1JJpHs6KiKVtABCE4iJK5d7FLFzDXQNBQ2oRY7LEd3UwOt3TZemTgu9syTIf56dJWlTn/pdmrO9oKUXQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.71.2",
"@typescript-eslint/tsconfig-utils": "8.71.2",
"@typescript-eslint/types": "8.71.2",
"@typescript-eslint/visitor-keys": "8.71.2",
"@typescript-eslint/project-service": "8.71.1",
"@typescript-eslint/tsconfig-utils": "8.71.1",
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/visitor-keys": "8.71.1",
"debug": "^4.4.3",
"minimatch": "^10.2.2",
"semver": "^7.7.3",
@@ -3001,16 +3001,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "8.71.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.71.2.tgz",
"integrity": "sha512-RyKa1G1M9rKHDhrk+HJtiF1MvLD5Ux2JW3TSkzw+02pRALdpJb+QzG1Y5em+LvCgzGwgg8H7mBRFKljNz7ImPw==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.71.1.tgz",
"integrity": "sha512-CBjT6gfAz3DW2j9Q4moFnqt208Aq+506sVGXfpRcyAeqn0EpayL0mjdWoCO2t3RC7GewNrFxdeehuEaPg6DMzQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.9.1",
"@typescript-eslint/scope-manager": "8.71.2",
"@typescript-eslint/types": "8.71.2",
"@typescript-eslint/typescript-estree": "8.71.2"
"@typescript-eslint/scope-manager": "8.71.1",
"@typescript-eslint/types": "8.71.1",
"@typescript-eslint/typescript-estree": "8.71.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3025,13 +3025,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.71.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.71.2.tgz",
"integrity": "sha512-zozlN0UA32bSG2zkKAgQyRYSbEISVoyU6vvkKYo2aSny74D8Jh4e+POkJ6Lk0dlezZi5x7TtD+88Xb06IB8nhg==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.71.1.tgz",
"integrity": "sha512-0GxiUGqMU0qXJt58cBsiG3DP8lUmBaFo2vChtUX+CT7PnR3v/VGLLrzVP4K9r1lNiZXjHYefMBbPunplr09v6w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.71.2",
"@typescript-eslint/types": "8.71.1",
"eslint-visitor-keys": "^5.0.0"
},
"engines": {
@@ -5365,9 +5365,9 @@
}
},
"node_modules/eslint-plugin-jsdoc": {
"version": "65.3.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-65.3.4.tgz",
"integrity": "sha512-Z3/ro8sZPqnXKhyAzCNa3F7KCZ3js5xVx/q9BEvTjUGzN6OIQfdb+q3Sc9lJ3zCfyPnN0tI524ulZjYRxAwnAw==",
"version": "65.2.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-65.2.0.tgz",
"integrity": "sha512-IMZaNwdDa5otUQYGWN1pzywZLsGKswitvFFNhcO8IOsBfaWpWIDXYuZh2sYhe9MNyKN9hz0YryOFaKdpbTP5Bw==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -9981,16 +9981,16 @@
}
},
"node_modules/typescript-eslint": {
"version": "8.71.2",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.71.2.tgz",
"integrity": "sha512-Rz4effbMy2g9wnvOJZG6SbVavX313Lap1vNEbk1RUochzickvzP8P4HB+bkNg5e50eVz1hQGjh9K1omI1xB4Bw==",
"version": "8.71.1",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.71.1.tgz",
"integrity": "sha512-oiNVPC3/NbV1FpaHU07l8O6ynqG9v4PAiW2WvTrAmZdR0f2HI/gE668ElMLCK7Xbsu5k2fK5C4fXNiq05j7/nQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "8.71.2",
"@typescript-eslint/parser": "8.71.2",
"@typescript-eslint/typescript-estree": "8.71.2",
"@typescript-eslint/utils": "8.71.2"
"@typescript-eslint/eslint-plugin": "8.71.1",
"@typescript-eslint/parser": "8.71.1",
"@typescript-eslint/typescript-estree": "8.71.1",
"@typescript-eslint/utils": "8.71.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -10167,9 +10167,9 @@
"license": "MIT"
},
"node_modules/uuid": {
"version": "14.0.3",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.3.tgz",
"integrity": "sha512-Sc5u1VVln93y1Xnz4R+CunOZc7R9LUcTmhj7Rc7Eg3HVcf7rVn2FOoa812fe0W8p3jD7xeoGSYbfqCGGH2B6xw==",
"version": "14.0.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.2.tgz",
"integrity": "sha512-xZe/16rV4aa+HGSOCiY2YeLT1OybRLrrkL/Rqaq7p7GMVXjFh+6wN4oMYgjFmnSnhY8t6Xpdl2l9qmnHYuMHwQ==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
@@ -10484,7 +10484,6 @@
"dependencies": {
"@actions/core": "^2.0.3",
"@actions/github": "^8.0.1",
"@actions/tool-cache": "^3.0.1",
"@octokit/core": "^7.0.8",
"@octokit/plugin-paginate-rest": ">=16.0.0",
"@octokit/plugin-rest-endpoint-methods": "^18.0.0",
+5 -6
View File
@@ -1,6 +1,6 @@
{
"name": "codeql",
"version": "4.39.2",
"version": "3.39.1",
"private": true,
"description": "CodeQL action",
"scripts": {
@@ -13,8 +13,7 @@
"test": "npm run ava -- src/",
"test-debug": "npm run test -- --timeout=20m",
"transpile": "tsc --build --verbose tsconfig.json",
"update-pr-checks": "./pr-checks/sync.sh",
"typecheck": "tsc --noEmit"
"update-pr-checks": "./pr-checks/sync.sh"
},
"license": "MIT",
"workspaces": [
@@ -45,7 +44,7 @@
"node-forge": "^1.4.0",
"semver": "^7.8.5",
"undici": "^6.28.0",
"uuid": "^14.0.3"
"uuid": "^14.0.2"
},
"devDependencies": {
"@ava/typescript": "6.0.0",
@@ -66,14 +65,14 @@
"eslint-import-resolver-typescript": "^4.4.5",
"eslint-plugin-github": "^6.1.2",
"eslint-plugin-import-x": "^4.17.1",
"eslint-plugin-jsdoc": "^65.3.4",
"eslint-plugin-jsdoc": "^65.2.0",
"eslint-plugin-no-async-foreach": "^0.1.1",
"glob": "^13.0.6",
"globals": "^17.13.0",
"nock": "^14.0.17",
"sinon": "^22.1.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.71.2"
"typescript-eslint": "^8.71.1"
},
"overrides": {
"@actions/tool-cache": {
+14 -29
View File
@@ -4,32 +4,16 @@ import * as core from "@actions/core";
import * as sarif from "../src/sarif";
const DIAGNOSTIC_ID =
process.env["DIAGNOSTIC_ID"] ?? "lang/diagnostics/example";
const DIAGNOSTIC_NAME = process.env["DIAGNOSTIC_NAME"] ?? "Diagnostic name";
const EXPECTED_MESSAGE = process.env["EXPECTED_MESSAGE"] ?? "Plaintext message";
const EXPECTED_LOCATIONS = Number.parseInt(
process.env["EXPECTED_LOCATIONS"] ?? "1",
);
function checkStatusPageNotification(n: sarif.Notification) {
const expectedMessage = EXPECTED_MESSAGE.trim();
if (!n.message.text?.includes(expectedMessage)) {
if (n.message.text !== undefined) {
core.setFailed(
`Expected the status page diagnostic to contain the message '${expectedMessage}', but found '${n.message.text.replaceAll("\n", "\\n")}'.`,
);
} else {
core.setFailed(
`Expected the status page diagnostic to contain the message '${expectedMessage}', but found nothing.`,
);
}
}
const locationCount = n.locations?.length ?? 0;
if (locationCount !== EXPECTED_LOCATIONS) {
function checkStatusPageNotification(n) {
const expectedMessage = "Plaintext message";
if (n.message.text !== expectedMessage) {
core.setFailed(
`Expected the status page diagnostic to have exactly ${EXPECTED_LOCATIONS} location(s), but found ${locationCount}.`,
`Expected the status page diagnostic to have the message '${expectedMessage}', but found '${n.message.text}'.`,
);
}
if (n.locations.length !== 1) {
core.setFailed(
`Expected the status page diagnostic to have exactly 1 location, but found ${n.locations.length}.`,
);
}
}
@@ -56,7 +40,8 @@ if (toolExecutionNotifications === undefined) {
const statusPageNotifications = toolExecutionNotifications.filter(
(n) =>
n.descriptor?.id === DIAGNOSTIC_ID && n.properties?.visibility?.statusPage,
n.descriptor?.id === "lang/diagnostics/example" &&
n.properties?.visibility?.statusPage,
);
if (statusPageNotifications.length !== 1) {
core.setFailed(
@@ -76,9 +61,9 @@ if (notifications === undefined) {
const diagnosticNotification = notifications.filter(
(n) =>
n.id === DIAGNOSTIC_ID &&
n.name === DIAGNOSTIC_ID &&
n.fullDescription?.text === DIAGNOSTIC_NAME,
n.id === "lang/diagnostics/example" &&
n.name === "lang/diagnostics/example" &&
n.fullDescription?.text === "Diagnostic name",
);
if (diagnosticNotification.length !== 1) {
core.setFailed(
+19 -9
View File
@@ -2,20 +2,30 @@ name: "Bundle: From toolcache"
description: "The CodeQL bundle should be cached within the toolcache"
versions:
- toolcache
installNode: true
steps:
- name: Install @actions/tool-cache
run: npm install @actions/tool-cache@3
- name: Check toolcache contains CodeQL
continue-on-error: true
run: |
cd ./../action
npx tsx ./pr-checks/toolcache.ts installed
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const toolcache = require('@actions/tool-cache');
const allCodeqlVersions = toolcache.findAllVersions('CodeQL');
if (allCodeqlVersions.length === 0) {
throw new Error(`CodeQL could not be found in the toolcache`);
}
- id: setup-codeql
uses: ./../action/setup-codeql
with:
tools: ${{ steps.prepare-test.outputs.tools-url }}
- name: Check CodeQL is installed within the toolcache
run: |
cd ./../action
npx tsx ./pr-checks/toolcache.ts installed
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const toolcache = require('@actions/tool-cache');
const allCodeqlVersions = toolcache.findAllVersions('CodeQL');
console.log(`Found CodeQL versions: ${allCodeqlVersions}`);
if (allCodeqlVersions.length === 0) {
throw new Error('CodeQL not found in toolcache');
}
+30 -14
View File
@@ -6,31 +6,47 @@ operatingSystems:
- ubuntu
- macos
- windows
installNode: true
steps:
- name: Remove CodeQL from toolcache
run: |
cd ./../action
npx tsx ./pr-checks/toolcache.ts clear
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const fs = require('fs');
const path = require('path');
const codeqlPath = path.join(process.env['RUNNER_TOOL_CACHE'], 'CodeQL');
fs.rmdirSync(codeqlPath, { recursive: true });
- name: Install @actions/tool-cache
run: npm install @actions/tool-cache@3
- name: Check toolcache does not contain CodeQL
run: |
cd ./../action
npx tsx ./pr-checks/toolcache.ts absent
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const toolcache = require('@actions/tool-cache');
const allCodeqlVersions = toolcache.findAllVersions('CodeQL');
if (allCodeqlVersions.length !== 0) {
throw new Error(`CodeQL should not be found in the toolcache, but found ${allCodeqlVersions}`);
}
console.log('No versions of CodeQL found in the toolcache');
- id: init
uses: ./../action/init
with:
# Request multiple languages so this check uses the combined bundle.
languages: javascript,python
tools: ${{ steps.prepare-test.outputs.tools-url }}
- uses: ./../action/analyze
with:
output: ${{ runner.temp }}/results
upload-database: false
- name: Check CodeQL is installed within the toolcache
run: |
cd ./../action
npx tsx ./pr-checks/toolcache.ts installed -n 1
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const toolcache = require('@actions/tool-cache');
const allCodeqlVersions = toolcache.findAllVersions('CodeQL');
console.log(`Found CodeQL versions: ${allCodeqlVersions}`);
if (allCodeqlVersions.length === 0) {
throw new Error('CodeQL not found in toolcache');
}
if (allCodeqlVersions.length > 1) {
throw new Error('Multiple CodeQL versions found in toolcache');
}
@@ -1,72 +0,0 @@
name: "Diagnostic export without database"
description: "Tests that temporary diagnostics are correctly included in the failed SARIF."
versions:
# Overridden by the FF in the `init` step below.
- linked
installNode: true
env:
# Allow the failed SARIF file to be generated.
CODEQL_ACTION_SKIP_GENERATE_FAILED_SARIF: false
# But don't actually upload it.
CODEQL_ACTION_SKIP_SARIF_UPLOAD: true
# Mark telemetry for this workflow so it can be treated separately.
CODEQL_ACTION_TESTING_ENVIRONMENT: codeql-action-pr-checks
steps:
# We deliberately need to make this step fail before the database is initialised, but after
# some diagnostic has been produced. The simplest way to do that right now is to:
#
# - Produce a diagnostic before the db is initialised by forcing the use of a nightly release
# with the `CODEQL_ACTION_FORCE_NIGHTLY` feature flag.
# - Cause `init` to abort because we are attempting to analyse Swift on a non-macOS runner.
#
- name: Initialise failing analysis
id: init
uses: ./../action/init
continue-on-error: true
env:
CODEQL_ACTION_FORCE_NIGHTLY: true
with:
languages: swift
tools: ${{ steps.prepare-test.outputs.tools-url }}
- name: Analyze
uses: ./analyze
# In a real workflow, this step wouldn't run. Since we used `continue-on-error`
# above, we manually disable it with an `if` condition. Having this step is required
# for the init post-action because it checks the workflow definition for e.g. the
# `category` input. Without this step, that part of the init post-action would fail.
if: false
with:
category: "/test-codeql-version:${{ matrix.version }}"
- name: Check diagnostics appear on disk
env:
DIAGNOSTICS_DIR: "${{ runner.temp }}/codeql-action-temp-diagnostics/"
run: |
cd ../action
npx tsx ./pr-checks/diagnostics-without-db.ts
validationJobs:
diagnostics-without-db-validation:
checkout: true
installNode: true
steps:
- name: Download workflow artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: test-mode-sarif-*
path: sarif
- name: List artifact contents
run: ls -laR ./sarif
- name: Check diagnostics appear in SARIF
env:
SARIF_PATH: "./sarif/codeql-failed-run.sarif"
DIAGNOSTIC_ID: "codeql-action/forced-nightly-cli"
DIAGNOSTIC_NAME: "A nightly release of CodeQL was used"
EXPECTED_LOCATIONS: "0"
EXPECTED_MESSAGE: |
GitHub configured this analysis to use a nightly release of CodeQL to allow you to preview changes from an upcoming release.
run: npx tsx ./pr-checks/check-diagnostics.ts
@@ -11,17 +11,16 @@ installDotNet: true
env:
CODEQL_ACTION_SKIP_FILE_COVERAGE_ON_PRS: false
CODEQL_ACTION_SUBLANGUAGE_FILE_COVERAGE: true
# To balance speed and coverage, we analyze only a single language (JavaScript), but use the
# combined bundle so we can test that baseline information is reported for each language in the
# multi-language source directory.
CODEQL_ACTION_PER_LANGUAGE_BUNDLES: false
steps:
- uses: ./../action/init
id: init
with:
languages: javascript
tools: ${{ steps.prepare-test.outputs.tools-url }}
# To balance speed and coverage, analyze only JavaScript but use the combined bundle so
# baseline information is reported for every language in the multi-language repository. A
# custom configuration prevents per-language bundles from being used.
config: |
paths-ignore: []
- name: Build code
run: ./build.sh
- uses: ./../action/analyze
@@ -1,51 +1,49 @@
name: Per-language bundles
description: Validates extraction and analysis using each per-language CodeQL bundle.
# TODO: Use a released bundle once releases include per-language bundles.
matrix:
include:
- language: actions
os: ubuntu-latest
version: linked
version: nightly-latest
# Actions also needs the JavaScript extractor.
expected-extractors: actions javascript
- language: cpp
os: ubuntu-latest
version: linked
version: nightly-latest
build-mode: manual
build-command: gcc -o main main.c
- language: csharp
os: ubuntu-latest
version: linked
version: nightly-latest
build-mode: none
- language: go
os: ubuntu-latest
version: linked
version: nightly-latest
build-mode: autobuild
- language: java
os: ubuntu-latest
version: linked
version: nightly-latest
build-mode: none
- language: javascript
os: ubuntu-latest
version: linked
version: nightly-latest
- language: python
os: ubuntu-latest
version: linked
version: nightly-latest
- language: ruby
os: ubuntu-latest
version: linked
version: nightly-latest
- language: rust
os: ubuntu-latest
version: linked
version: nightly-latest
- language: swift
os: macos-latest-xlarge
version: linked
version: nightly-latest
build-mode: autobuild
installNode: true
env:
CODEQL_ACTION_PER_LANGUAGE_BUNDLES: true
steps:
- name: Remove CodeQL from toolcache
run: |
cd ./../action
npx tsx ./pr-checks/toolcache.ts clear
- uses: ./../action/init
id: init
with:
@@ -86,8 +84,9 @@ steps:
CODEQL_PATH: ${{ steps.init.outputs.codeql-path }}
run: |
# A bundle that is missing most of its extractors must never be left in the toolcache,
# where a later job analyzing a different language could pick it up. Per-language bundles
# must instead be extracted under the runner's temporary directory.
# where a later job analyzing a different language could pick it up. The runner image
# ships with its own CodeQL in the toolcache, so check where this bundle was extracted to
# rather than whether the toolcache contains CodeQL at all.
echo "CodeQL is at $CODEQL_PATH"
if [[ "$CODEQL_PATH" == "$RUNNER_TOOL_CACHE"/* ]]; then
echo "::error::The per-language bundle was added to the toolcache at $CODEQL_PATH."
@@ -0,0 +1,23 @@
name: "RuboCop multi-language"
description: "Tests using RuboCop to analyze a multi-language repository and then using the CodeQL Action to upload the resulting SARIF"
# This check doesn't use CodeQL, so the `version` matrix variable is unused.
versions:
- default
steps:
- name: Set up Ruby
uses: ruby/setup-ruby@14594264cd68ce8a2345dd349bc3d138a4ef85c8 # v1.327.0
with:
ruby-version: 2.6
- name: Install Code Scanning integration
run: bundle add code-scanning-rubocop --version 0.3.0 --skip-install
- name: Install dependencies
run: bundle install
- name: RuboCop run
run: |
bash -c "
bundle exec rubocop --require code_scanning --format CodeScanning::SarifFormatter -o rubocop.sarif
[[ $? -ne 2 ]]
"
- uses: ./../action/upload-sarif
with:
sarif_file: rubocop.sarif
+1 -3
View File
@@ -35,9 +35,7 @@ steps:
run: exit 1
- uses: ./analyze
# In a real workflow, this step wouldn't run. Since we used `continue-on-error`
# above, we manually disable it with an `if` condition. Having this step is required
# for the init post-action because it checks the workflow definition for e.g. the
# `category` input. Without this step, that part of the init post-action would fail.
# above, we manually disable it with an `if` condition.
if: false
with:
category: "/test-codeql-version:${{ matrix.version }}"
-48
View File
@@ -1,48 +0,0 @@
import * as fs from "fs";
import * as path from "path";
import * as core from "@actions/core";
import type * as diagnostics from "../src/diagnostics";
const DIAGNOSTIC_ID = "codeql-action/forced-nightly-cli";
const diagnosticDirectory = process.env["DIAGNOSTICS_DIR"];
if (diagnosticDirectory === undefined) {
throw new Error("DIAGNOSTICS_DIR is undefined.");
}
const paths = fs
.readdirSync(diagnosticDirectory, {
recursive: true,
encoding: "utf-8",
})
.filter((p) => p.endsWith(".json"));
core.info(`Found ${paths.length} paths in '${diagnosticDirectory}'.`);
core.info(`Searching for a diagnostic with id '${DIAGNOSTIC_ID}'...`);
let found = false;
for (const diagnosticPath of paths) {
if (path.extname(diagnosticPath) !== ".json") {
core.info(`Skipping ${diagnosticPath}.`);
continue;
}
core.info(`Found ${diagnosticPath}.`);
const contents = JSON.parse(
fs.readFileSync(path.resolve(diagnosticDirectory, diagnosticPath), "utf-8"),
) as diagnostics.DiagnosticMessage;
if (contents.source.id === DIAGNOSTIC_ID) {
core.info(
`Found '${DIAGNOSTIC_ID}' in '${diagnosticPath}'. Skipping remaining files.`,
);
found = true;
break;
}
}
if (!found) {
throw new Error(`Didn't find '${DIAGNOSTIC_ID}' diagnostic.`);
}
-4
View File
@@ -20,7 +20,3 @@ is:
- "Release info"
- "Upload results"
- "Update release branch"
# These checks are known not to run on every PR (for example, some release
# PRs), so requiring them would block the PRs they don't run on.
- "github-advanced-security"
- "License compliance check"
-6
View File
@@ -2,15 +2,9 @@
"private": true,
"description": "Dependencies for codeql-action scripts",
"type": "module",
"scripts": {
"typecheck": "tsc --noEmit",
"test": "npx tsx --test",
"checks": "npm run typecheck && npm run test"
},
"dependencies": {
"@actions/core": "^2.0.3",
"@actions/github": "^8.0.1",
"@actions/tool-cache": "^3.0.1",
"@octokit/core": "^7.0.8",
"@octokit/plugin-paginate-rest": ">=16.0.0",
"@octokit/plugin-rest-endpoint-methods": "^18.0.0",
+23 -63
View File
@@ -90,7 +90,7 @@ interface Specification extends JobSpecification {
services?: any;
/** Additional jobs to run after the main PR check job. */
validationJobs?: Record<string, ValidationJobSpecification>;
validationJobs?: Record<string, JobSpecification>;
/** If set, this check is part of a named collection that gets its own caller workflow. */
collection?: string;
@@ -122,10 +122,6 @@ interface JobSpecification {
installYq?: boolean;
}
type ValidationJobSpecification = JobSpecification & {
checkout?: boolean;
};
/** Describes language/framework-specific steps and inputs. */
interface LanguageSetup {
specProperty: keyof JobSpecification;
@@ -137,15 +133,7 @@ interface LanguageSetup {
/** Describes partial mappings from built-in languages to their specific setup information. */
type LanguageSetups = Partial<Record<BuiltInLanguage, LanguageSetup>>;
/** A type representing version identifiers. */
type Version =
| "default"
| "linked"
| "nightly-latest"
// This is an approximation, but sufficient validation for our needs here.
| `stable-v${number}.${number}.${number}`;
/** The default set of CodeQL Bundle versions to use for the PR checks. */
// The default set of CodeQL Bundle versions to use for the PR checks.
const defaultTestVersions = [
// The oldest supported CodeQL version. If bumping, update `CODEQL_MINIMUM_VERSION` in `codeql.ts`
"stable-v2.20.7",
@@ -167,10 +155,7 @@ const defaultTestVersions = [
"linked",
// A nightly build directly from the our private repo, built in the last 24 hours.
"nightly-latest",
] as const satisfies Version[];
/** A type representing the default test versions. */
type DefaultTestVersion = (typeof defaultTestVersions)[number];
];
/** The default versions we use for languages / frameworks, if not specified as a workflow input. */
const defaultLanguageVersions = {
@@ -278,8 +263,8 @@ const languageSetups: LanguageSetups = {
name: "Install Java",
uses: pinnedUses(
"actions/setup-java",
"b843ebf9b913146b38da2eaa7aeddf76074ae1ad",
"v6.1.0",
"de7274f081f381c8f8158605e0321c36c376e2e6",
"v6.0.1",
),
with: {
"java-version": `\${{ inputs.java-version || '${defaultLanguageVersions.java}' }}`,
@@ -324,11 +309,9 @@ const languageSetups: LanguageSetups = {
},
};
/**
* This is essentially an arbitrary version of `yq`, which happened to be the one that
* `choco` fetched when we moved away from using that here.
* See https://github.com/github/codeql-action/pull/3423
*/
// This is essentially an arbitrary version of `yq`, which happened to be the one that
// `choco` fetched when we moved away from using that here.
// See https://github.com/github/codeql-action/pull/3423
const YQ_VERSION = "v4.50.1";
const CHECKS_DIR = path.join(PR_CHECKS_DIR, "checks");
@@ -455,23 +438,10 @@ function generateJobMatrix(
: [operatingSystemConfig["runner-image"]];
for (const runnerImage of runnerImagesForOs) {
// stable-v2.20.7 requires an older version of Java than the default on `ubuntu-latest`.
// We could install that older version on the newer runners, or use the older runner.
// We do the latter here. This can be removed once we stop supporting `v2.20.7`.
// Since this is typed as `DefaultTestVersion`, it will become an error once `stable-v2.20.7`
// is removed from `defaultTestVersions`.
const requiresOlderRunnerImage: DefaultTestVersion = "stable-v2.20.7";
if (
runnerImage === "ubuntu-latest" &&
version === requiresOlderRunnerImage
) {
matrix.push({ os: "ubuntu-24.04", version });
} else {
matrix.push({
os: runnerImage,
version,
});
}
matrix.push({
os: runnerImage,
version,
});
}
}
}
@@ -492,20 +462,6 @@ function generateJobMatrix(
return matrix;
}
/**
* Gets the `actions/checkout` step.
*/
function getCheckoutStep(): Step {
return {
name: "Check out repository",
uses: pinnedUses(
"actions/checkout",
"3d3c42e5aac5ba805825da76410c181273ba90b1",
"v7.0.1",
),
};
}
/**
* Retrieves setup steps and additional input definitions based on specific languages or frameworks
* that are requested by the `checkSpecification`.
@@ -575,7 +531,14 @@ function generateJob(
// Construct the workflow steps needed for this check.
const steps: Step[] = [
getCheckoutStep(),
{
name: "Check out repository",
uses: pinnedUses(
"actions/checkout",
"3d3c42e5aac5ba805825da76410c181273ba90b1",
"v7.0.1",
),
},
...setupInfo.steps,
{
name: "Prepare test",
@@ -646,16 +609,13 @@ function generateJob(
/** Generates a validation job. */
function generateValidationJob(
specDocument: yaml.Document,
jobSpecification: ValidationJobSpecification,
jobSpecification: JobSpecification,
checkName: string,
name: string,
) {
// Determine which languages or frameworks have to be installed.
const { inputs, steps } = getSetupSteps(jobSpecification);
// Construct a checkout step if requested.
const checkoutStep = jobSpecification.checkout ? [getCheckoutStep()] : [];
// Extract the sequence of steps from the YAML document to persist as much formatting as possible.
const specSteps = specDocument.getIn([
"validationJobs",
@@ -664,7 +624,7 @@ function generateValidationJob(
]) as yaml.YAMLSeq;
// Add the generated steps in front of the ones from the specification.
specSteps.items.unshift(...checkoutStep, ...steps);
specSteps.items.unshift(...steps);
const validationJob: Record<string, any> = {
name: jobSpecification.name,
@@ -675,7 +635,7 @@ function generateValidationJob(
"security-events": "read",
},
"timeout-minutes": 5,
"runs-on": "ubuntu-latest",
"runs-on": "ubuntu-slim",
steps: specSteps,
};
-94
View File
@@ -1,94 +0,0 @@
#!/usr/bin/env npx tsx
/**
* Provides utility commands for working with the Actions toolcache in PR checks.
*/
import fs from "fs";
import { parseArgs } from "node:util";
import path from "path";
import * as core from "@actions/core";
import * as toolcache from "@actions/tool-cache";
function removeCodeQLFromToolcache() {
const toolcachePath = process.env["RUNNER_TOOL_CACHE"];
if (toolcachePath === undefined) {
throw new Error("Expected RUNNER_TOOL_CACHE to be defined");
}
const codeqlPath = path.join(toolcachePath, "CodeQL");
fs.rmSync(codeqlPath, { recursive: true });
core.info(`Removed '${codeqlPath}' from the toolcache.`);
}
function findCodeQL() {
return toolcache.findAllVersions("CodeQL");
}
function checkNoCodeQLInToolcache() {
const allCodeqlVersions = findCodeQL();
if (allCodeqlVersions.length !== 0) {
throw new Error(
`CodeQL should not be found in the toolcache, but found ${allCodeqlVersions}`,
);
}
core.info("No versions of CodeQL found in the toolcache");
}
function hasCodeQLInToolcache(expectedNumber?: string) {
const expected =
expectedNumber !== undefined
? Number.parseInt(expectedNumber, 10)
: undefined;
const allCodeqlVersions = findCodeQL();
if (allCodeqlVersions.length === 0) {
throw new Error("CodeQL not found in toolcache");
}
core.info(`Found CodeQL versions: ${allCodeqlVersions.join(", ")}`);
if (expected !== undefined && allCodeqlVersions.length !== expected) {
throw new Error(
`Expected ${expected} versions of CodeQL in the toolcache, but found ${allCodeqlVersions.length}`,
);
}
}
function main() {
const { positionals, values } = parseArgs({
options: {
// The number of expected versions in the toolcache.
"expected-version-count": { type: "string", short: "n" },
},
allowPositionals: true,
});
if (positionals.length < 1) {
throw new Error("Command not specified.");
}
const cmd = positionals[0];
switch (cmd.trim().toLowerCase()) {
case "clear":
removeCodeQLFromToolcache();
return;
case "absent":
checkNoCodeQLInToolcache();
return;
case "installed":
hasCodeQLInToolcache(values["expected-version-count"]);
return;
default:
throw new Error(`Unknown command '${cmd}'.`);
}
}
try {
main();
} catch (err) {
core.setFailed(err instanceof Error ? err.message : String(err));
}
+1 -1
View File
@@ -9,5 +9,5 @@
"noEmit": true
},
"include": ["./**/*.ts", "../src/**/*.ts"],
"exclude": ["node_modules", "../src/**/*.test.ts"]
"exclude": ["node_modules"]
}
+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-entry.js'
+1 -1
View File
@@ -51,5 +51,5 @@ outputs:
codeql-version:
description: The version of the CodeQL binary that was installed.
runs:
using: node24
using: node20
main: '../lib/setup-codeql-entry.js'
+2 -1
View File
@@ -11,6 +11,7 @@ import {
} from "./actions-util";
import { computeAutomationID } from "./api-client";
import { EnvVar } from "./environment";
import { getRunnerLogger } from "./logging";
import { RecordingLogger, setupTests } from "./testing-utils";
import { initializeEnvironment, withTmpDir } from "./util";
@@ -237,7 +238,7 @@ test.serial("fixCodeQualityCategory", (t) => {
GITHUB_EVENT_NAME: "dynamic",
},
() => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
// Categories that should get adjusted.
t.is(fixCodeQualityCategory(logger, "/language:c#"), "/language:csharp");
+6 -5
View File
@@ -15,6 +15,7 @@ import {
supportedAnalysisKinds,
} from "./analyses";
import { EnvVar } from "./environment";
import { getRunnerLogger } from "./logging";
import {
createFeatures,
RecordingLogger,
@@ -64,7 +65,7 @@ test.serial(
.withArgs("analysis-kinds")
.returns("code-scanning,code-quality");
const result = await getAnalysisKinds(
new RecordingLogger(),
getRunnerLogger(true),
features,
true,
);
@@ -138,7 +139,7 @@ test.serial(
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
optionalInputStub.withArgs("quality-queries").returns("code-quality");
const result = await getAnalysisKinds(
new RecordingLogger(),
getRunnerLogger(true),
features,
true,
);
@@ -154,7 +155,7 @@ test.serial(
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
requiredInputStub.withArgs("analysis-kinds").returns("no-such-thing");
await t.throwsAsync(
getAnalysisKinds(new RecordingLogger(), features, true),
getAnalysisKinds(getRunnerLogger(true), features, true),
);
},
);
@@ -180,7 +181,7 @@ for (let i = 0; i < analysisKinds.length; i++) {
.withArgs("analysis-kinds")
.returns([analysisKind, otherAnalysis].join(","));
const result = await getAnalysisKinds(
new RecordingLogger(),
getRunnerLogger(true),
features,
true,
);
@@ -198,7 +199,7 @@ for (let i = 0; i < analysisKinds.length; i++) {
.withArgs("analysis-kinds")
.returns([analysisKind, otherAnalysis].join(","));
await t.throwsAsync(
getAnalysisKinds(new RecordingLogger(), features, true),
getAnalysisKinds(getRunnerLogger(true), features, true),
{
instanceOf: ConfigurationError,
message: `${analysisKind} and ${otherAnalysis} cannot be enabled at the same time`,
+17 -3
View File
@@ -50,8 +50,9 @@ import {
StatusReportBase,
} from "./status-report";
import {
cleanupTrapCaches,
TrapCacheCleanupStatusReport,
uploadTrapCaches,
warnIfTrapCacheCleanupEnvVarIsSet,
} from "./trap-caching";
import * as uploadLib from "./upload-lib";
import { UploadResult } from "./upload-lib";
@@ -85,6 +86,7 @@ async function sendStatusReport(
trapCacheUploadTime: number | undefined,
dbCreationTimings: DatabaseCreationTimings | undefined,
didUploadTrapCaches: boolean,
trapCacheCleanup: TrapCacheCleanupStatusReport | undefined,
dependencyCacheResults: DependencyCacheUploadStatusReport | undefined,
databaseUploadResults: DatabaseUploadResult[],
logger: Logger,
@@ -105,6 +107,7 @@ async function sendStatusReport(
...statusReportBase,
...(stats || {}),
...(dbCreationTimings || {}),
...(trapCacheCleanup || {}),
dependency_caching_upload_results: dependencyCacheResults,
database_upload_results: databaseUploadResults,
};
@@ -226,6 +229,8 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) {
| undefined = undefined;
let runStats: QueriesStatusReport | undefined = undefined;
let config: Config | undefined = undefined;
let trapCacheCleanupTelemetry: TrapCacheCleanupStatusReport | undefined =
undefined;
let trapCacheUploadTime: number | undefined = undefined;
let dbCreationTimings: DatabaseCreationTimings | undefined = undefined;
let didUploadTrapCaches = false;
@@ -273,8 +278,6 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) {
);
}
warnIfTrapCacheCleanupEnvVarIsSet(action);
const apiDetails = getApiDetails();
const outputDir = actionsUtil.getRequiredInput("output");
action.env.export(EnvVar.SARIF_RESULTS_OUTPUT_DIR, outputDir);
@@ -413,6 +416,13 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) {
didUploadTrapCaches = await uploadTrapCaches(codeql, config, logger);
trapCacheUploadTime = performance.now() - trapCacheUploadStartTime;
// Clean up TRAP caches
trapCacheCleanupTelemetry = await cleanupTrapCaches(
config,
features,
logger,
);
// Store dependency cache(s) if dependency caching is enabled.
if (shouldStoreCache(config.dependencyCachingEnabled)) {
dependencyCacheResults = await uploadDependencyCaches(
@@ -464,6 +474,7 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) {
trapCacheUploadTime,
dbCreationTimings,
didUploadTrapCaches,
trapCacheCleanupTelemetry,
dependencyCacheResults,
databaseUploadResults,
logger,
@@ -486,6 +497,7 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) {
trapCacheUploadTime,
dbCreationTimings,
didUploadTrapCaches,
trapCacheCleanupTelemetry,
dependencyCacheResults,
databaseUploadResults,
logger,
@@ -499,6 +511,7 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) {
trapCacheUploadTime,
dbCreationTimings,
didUploadTrapCaches,
trapCacheCleanupTelemetry,
dependencyCacheResults,
databaseUploadResults,
logger,
@@ -512,6 +525,7 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) {
trapCacheUploadTime,
dbCreationTimings,
didUploadTrapCaches,
trapCacheCleanupTelemetry,
dependencyCacheResults,
databaseUploadResults,
logger,
+2 -2
View File
@@ -17,12 +17,12 @@ import { defaultSuites } from "./config/db-config";
import { Feature } from "./feature-flags";
import * as gitUtils from "./git-utils";
import { BuiltInLanguage } from "./languages";
import { getRunnerLogger } from "./logging";
import {
setupTests,
setupActionsVars,
createFeatures,
createTestConfig,
RecordingLogger,
callee,
} from "./testing-utils";
import * as uploadLib from "./upload-lib";
@@ -195,7 +195,7 @@ test.serial("status report fields", async (t) => {
undefined,
codeql,
config,
new RecordingLogger(),
getRunnerLogger(true),
createFeatures([Feature.QaTelemetryEnabled]),
);
t.deepEqual(Object.keys(statusReport).sort(), [
+15
View File
@@ -401,6 +401,21 @@ export async function listActionsCaches(
);
}
/**
* Delete an Actions cache item by its ID.
*
* See https://docs.github.com/en/rest/actions/cache#delete-a-github-actions-cache-for-a-repository-using-a-cache-id.
*/
export async function deleteActionsCache(id: number) {
const repositoryNwo = getRepositoryNwo();
await getApiClient().rest.actions.deleteActionsCacheById({
owner: repositoryNwo.owner,
repo: repositoryNwo.repo,
cache_id: id,
});
}
/**
* Retrieve all custom repository properties.
*
+2 -2
View File
@@ -10,12 +10,12 @@ import {
scanArtifactsForTokens,
TokenType,
} from "./artifact-scanner";
import { getRunnerLogger } from "./logging";
import {
checkExpectedLogMessages,
getRecordingLogger,
LoggedMessage,
makeTestToken,
RecordingLogger,
} from "./testing-utils";
test("makeTestToken", (t) => {
@@ -121,7 +121,7 @@ for (const { type, value, checkPattern } of testTokens) {
}
test("scanArtifactsForTokens handles files without tokens", async (t) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "scanner-test-"));
try {
+3 -2
View File
@@ -3,14 +3,15 @@ import path from "path";
import test from "ava";
import { RecordingLogger, setupTests } from "../testing-utils";
import { getRunnerLogger } from "../logging";
import { setupTests } from "../testing-utils";
import * as util from "../util";
import { getCachedCodeQlVersion } from "./output-cache";
setupTests(test);
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
test.serial(
"getCachedCodeQlVersion reuses a version persisted by an earlier step",
+15 -16
View File
@@ -22,6 +22,7 @@ import type { Config } from "./config-utils";
import * as defaults from "./defaults.json";
import { DocUrl } from "./doc-url";
import { BuiltInLanguage } from "./languages";
import { getRunnerLogger } from "./logging";
import { ToolsSource } from "./setup-codeql";
import {
setupTests,
@@ -33,8 +34,6 @@ import {
makeVersionInfo,
createTestConfig,
makeMacro,
getCodeQLForTesting,
RecordingLogger,
} from "./testing-utils";
import { ToolsDownloadStatusReport } from "./tools-download";
import * as util from "./util";
@@ -103,7 +102,7 @@ async function installIntoToolcache({
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
createFeatures([]),
new RecordingLogger(),
getRunnerLogger(true),
false,
);
}
@@ -141,7 +140,7 @@ function mockApiDetails(apiDetails: Required<GitHubApiDetails>) {
}
async function stubCodeql(): Promise<codeql.CodeQL> {
const codeqlObject = await getCodeQLForTesting();
const codeqlObject = await codeql.getCodeQLForTesting();
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.17.6"));
sinon
.stub(codeqlObject, "isTracedLanguage")
@@ -177,7 +176,7 @@ test.serial(
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
features,
new RecordingLogger(),
getRunnerLogger(true),
false,
);
@@ -213,7 +212,7 @@ test.serial(
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
features,
new RecordingLogger(),
getRunnerLogger(true),
false,
);
@@ -253,7 +252,7 @@ test.serial(
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
features,
new RecordingLogger(),
getRunnerLogger(true),
false,
);
t.assert(toolcache.find("CodeQL", "0.0.0-20200610"));
@@ -363,7 +362,7 @@ for (const {
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
features,
new RecordingLogger(),
getRunnerLogger(true),
false,
);
t.assert(toolcache.find("CodeQL", expectedToolcacheVersion));
@@ -406,7 +405,7 @@ for (const toolcacheVersion of [
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
features,
new RecordingLogger(),
getRunnerLogger(true),
false,
);
t.is(
@@ -451,7 +450,7 @@ test.serial(
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
features,
new RecordingLogger(),
getRunnerLogger(true),
false,
);
t.deepEqual(result.toolsVersion, "0.0.0-20200601");
@@ -498,7 +497,7 @@ test.serial(
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
features,
new RecordingLogger(),
getRunnerLogger(true),
false,
);
t.deepEqual(result.toolsVersion, defaults.cliVersion);
@@ -538,7 +537,7 @@ test.serial(
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
features,
new RecordingLogger(),
getRunnerLogger(true),
false,
);
t.deepEqual(result.toolsVersion, defaults.cliVersion);
@@ -580,7 +579,7 @@ test.serial(
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
features,
new RecordingLogger(),
getRunnerLogger(true),
false,
);
@@ -665,7 +664,7 @@ const injectedConfigMacro = makeMacro({
tempDir,
};
thisStubConfig.computedConfig = generateCodeScanningConfig(
new RecordingLogger(),
getRunnerLogger(true),
thisStubConfig.originalUserInput,
augmentationProperties,
);
@@ -1040,7 +1039,7 @@ test.serial("runTool summarizes autobuilder errors", async (t) => {
[2019-09-18 12:00:01] [autobuild] A non-error message
`;
stubToolRunnerConstructor(1, stderr);
const codeqlObject = await getCodeQLForTesting();
const codeqlObject = await codeql.getCodeQLForTesting();
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.17.6"));
sinon.stub(codeqlObject, "resolveExtractor").resolves("/path/to/extractor");
// io throws because of the test CodeQL object.
@@ -1096,7 +1095,7 @@ test.serial("runTool recognizes fatal internal errors", async (t) => {
com.semmle.util.exception.CatastrophicError: An error occurred while evaluating ControlFlowGraph::ControlFlow::Root.isRootOf/1#dispred#f610e6ed/2@86282cc8
Severe disk cache trouble (corruption or out of space) at /home/runner/work/_temp/codeql_databases/go/db-go/default/cache/pages/28/33.pack: Failed to write item to disk`;
stubToolRunnerConstructor(1, stderr);
const codeqlObject = await getCodeQLForTesting();
const codeqlObject = await codeql.getCodeQLForTesting();
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.17.6"));
sinon.stub(codeqlObject, "resolveExtractor").resolves("/path/to/extractor");
// io throws because of the test CodeQL object.
+17 -34
View File
@@ -26,7 +26,7 @@ import {
} from "./feature-flags";
import { isAnalyzingDefaultBranch } from "./git-utils";
import { Language } from "./languages";
import type { Logger } from "./logging";
import { getRunnerLogger, Logger } from "./logging";
import { writeBaseDatabaseOidsFile, writeOverlayChangesFile } from "./overlay";
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
import * as setupCodeql from "./setup-codeql";
@@ -199,7 +199,6 @@ export interface CodeQL {
sarifFile: string,
automationDetailsId: string | undefined,
config: ActionConfig<"tempDir">,
diagnosticDir: string | undefined,
): Promise<void>;
/** Get the location of an extractor for the specified language. */
resolveExtractor(language: Language): Promise<string>;
@@ -487,6 +486,18 @@ export function createStubCodeQL(partialCodeql: Partial<CodeQL>): CodeQL {
};
}
/**
* Get a real, newly created CodeQL instance for testing. The instance refers to
* a non-existent placeholder codeql command, so tests that use this function
* should also stub the toolrunner.ToolRunner constructor.
*/
export async function getCodeQLForTesting(
cmd = "codeql-for-testing",
logger: Logger = getRunnerLogger(true),
): Promise<CodeQL> {
return getCodeQLForCmd(logger, cmd, false);
}
/**
* Return a CodeQL object for CodeQL CLI access.
*
@@ -495,7 +506,7 @@ export function createStubCodeQL(partialCodeql: Partial<CodeQL>): CodeQL {
* version requirement. Must be set to true outside tests.
* @returns A new CodeQL object
*/
export async function getCodeQLForCmd(
async function getCodeQLForCmd(
logger: Logger,
cmd: string,
checkVersion: boolean,
@@ -904,43 +915,15 @@ export async function getCodeQLForCmd(
sarifFile: string,
automationDetailsId: string | undefined,
config: ActionConfig<"tempDir">,
diagnosticDir: string | undefined,
): Promise<void> {
// We may be exporting diagnostics for a failed SARIF, in which case the configuration
// file may not have been written to disk and there may not be a database. The CLI
// will produce a SARIF for diagnostics from `diagnosticDir` without it. Therefore,
// we check whether `configPath` exists and only provide it to the CLI if it does.
// Although not needed, the CLI will produce an error if it
// is provided with an argument to `--sarif-codescanning-config` that does not exist.
let configPath: string | undefined =
getGeneratedCodeScanningConfigPath(config);
if (!fs.existsSync(configPath)) {
// Warn if there is no configuration file, even though `config` claims that `init`
// was successful. This shouldn't be happening.
if (config.successfullyInitialised) {
logger.warning(
[
`Expected a configuration file at '${configPath}', which does not exist.`,
"Continuing with diagnostics export anyway, without a configuration file.",
].join(" "),
);
}
configPath = undefined;
}
const args = [
"diagnostics",
"export",
"--format=sarif-latest",
`--output=${sarifFile}`,
...(configPath !== undefined
? [`--sarif-codescanning-config=${configPath}`]
: []),
...(diagnosticDir !== undefined
? [`--diagnostic-dir=${diagnosticDir}`]
: []),
`--sarif-codescanning-config=${getGeneratedCodeScanningConfigPath(
config,
)}`,
...getExtraOptionsFromEnv(["diagnostics", "export"]),
];
if (automationDetailsId !== undefined) {
+16 -16
View File
@@ -21,6 +21,7 @@ import { RepositoryProperties } from "./feature-flags/properties";
import * as gitUtils from "./git-utils";
import { GitVersionInfo } from "./git-utils";
import { BuiltInLanguage, Language } from "./languages";
import { getRunnerLogger } from "./logging";
import { CODEQL_OVERLAY_MINIMUM_VERSION } from "./overlay";
import * as overlayDiagnostics from "./overlay/diagnostics";
import { OverlayDisabledReason } from "./overlay/diagnostics";
@@ -41,7 +42,6 @@ import {
callee,
SAMPLE_DOTCOM_API_DETAILS,
AssertableTarget,
RecordingLogger,
} from "./testing-utils";
import {
GitHubVariant,
@@ -102,7 +102,7 @@ function createTestInitConfigInputs(
features: createFeatures([]),
repositoryProperties: {},
enableFileCoverageInformation: true,
logger: new RecordingLogger(),
logger: getRunnerLogger(true),
} satisfies configUtils.InitConfigInputs,
overrides,
);
@@ -150,7 +150,7 @@ function mockListLanguages(languages: string[]) {
test.serial("load empty config", async (t) => {
return await withTmpDir(async (tempDir) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const languages = "javascript,python";
setupActionsVars(tempDir, tempDir);
@@ -196,7 +196,7 @@ test.serial("load empty config", async (t) => {
test.serial("load code quality config", async (t) => {
return await withTmpDir(async (tempDir) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const languages = "actions";
setupActionsVars(tempDir, tempDir);
@@ -252,7 +252,7 @@ test.serial(
"initActionState doesn't throw if there are queries configured in the repository properties",
async (t) => {
return await withTmpDir(async (tempDir) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const languages = "javascript";
setupActionsVars(tempDir, tempDir);
@@ -315,7 +315,7 @@ test.serial(
test.serial("loading a saved config produces the same config", async (t) => {
return await withTmpDir(async (tempDir) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const codeql = createStubCodeQL({
async resolveLanguages() {
@@ -363,7 +363,7 @@ test.serial("loading a saved config produces the same config", async (t) => {
test.serial("loading config with version mismatch throws", async (t) => {
return await withTmpDir(async (tempDir) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const codeql = createStubCodeQL({
async resolveLanguages() {
@@ -788,12 +788,12 @@ test.serial("Unknown languages", async (t) => {
});
});
const mockLogger = new RecordingLogger();
const mockLogger = getRunnerLogger(true);
test.serial("no generateRegistries when registries is undefined", async (t) => {
return await withTmpDir(async (tmpDir) => {
const registriesInput = undefined;
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const { registriesAuthTokens, qlconfigFile } =
await configUtils.generateRegistries(registriesInput, tmpDir, logger);
@@ -814,7 +814,7 @@ test.serial(
token: "not-a-token",
},
]);
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const { registriesAuthTokens, qlconfigFile } =
await configUtils.generateRegistries(registriesInput, tmpDir, logger);
@@ -2225,7 +2225,7 @@ test("applyIncrementalAnalysisSettings: no-op when mode is not Overlay and diff
const config = createTestConfig({});
config.overlayDatabaseMode = OverlayDatabaseMode.None;
const codeql = createStubCodeQL({});
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
await configUtils.applyIncrementalAnalysisSettings(
config,
@@ -2243,7 +2243,7 @@ test("applyIncrementalAnalysisSettings: keeps overlay mode and adds exclusions w
overlayDatabaseMode: OverlayDatabaseMode.Overlay,
});
const codeql = createStubCodeQL({});
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
await configUtils.applyIncrementalAnalysisSettings(
config,
@@ -2266,7 +2266,7 @@ test.serial(
});
config.useOverlayDatabaseCaching = true;
const codeql = createStubCodeQL({});
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const addDiagnosticsStub = sinon
.stub(overlayDiagnostics, "addOverlayDisablementDiagnostics")
.resolves();
@@ -2298,7 +2298,7 @@ test.serial(
config.useOverlayDatabaseCaching = false;
config.overlayModeSetExplicitly = true;
const codeql = createStubCodeQL({});
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const addDiagnosticsStub = sinon
.stub(overlayDiagnostics, "addOverlayDisablementDiagnostics")
.resolves();
@@ -2321,7 +2321,7 @@ test("applyIncrementalAnalysisSettings: adds exclusions for diff-informed-only r
const config = createTestConfig({});
config.overlayDatabaseMode = OverlayDatabaseMode.None;
const codeql = createStubCodeQL({});
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
await configUtils.applyIncrementalAnalysisSettings(
config,
@@ -2535,7 +2535,7 @@ test("determineUserConfig - merges configs if FF is enabled in Default Setup", a
// also check whether loading the configuration from disk that was written
// by `determineUserConfig` matches our expectations.
const loadedFromDisk = configUtils.getLocalConfig(
new RecordingLogger(),
getRunnerLogger(true),
expectedConfigPath,
false,
);
-2
View File
@@ -465,8 +465,6 @@ export async function initActionState(
overlayModeSetExplicitly: false,
repositoryProperties,
enableFileCoverageInformation,
// We don't set this to `true` until `init` is successful.
successfullyInitialised: false,
};
}
-3
View File
@@ -130,9 +130,6 @@ export interface Config {
* Whether to enable file coverage information.
*/
enableFileCoverageInformation: boolean;
/** Whether the analysis was successfully initialised using the configuration. */
successfullyInitialised: boolean;
}
/** Properties available in `Config`. */
+59 -74
View File
@@ -2,15 +2,15 @@ import test, { ExecutionContext } from "ava";
import { RepositoryProperties } from "../feature-flags/properties";
import { BuiltInLanguage, Language } from "../languages";
import { getRunnerLogger } from "../logging";
import {
checkExpectedLogMessages,
getRecordingLogger,
LoggedMessage,
makeMacro,
RecordingLogger,
setupActionsVars,
} from "../testing-utils";
import { ConfigurationError, prettyPrintPack, withTmpDir } from "../util";
import { ConfigurationError, prettyPrintPack } from "../util";
import * as dbConfig from "./db-config";
@@ -384,7 +384,7 @@ calculateAugmentationErrorMacro(
test("parseUserConfig - successfully parses valid YAML", (t) => {
const result = dbConfig.parseUserConfig(
new RecordingLogger(),
getRunnerLogger(true),
"test",
`
paths-ignore:
@@ -410,7 +410,7 @@ test("parseUserConfig - throws a ConfigurationError if the file is not valid YAM
t.throws(
() =>
dbConfig.parseUserConfig(
new RecordingLogger(),
getRunnerLogger(true),
"test",
`
paths-ignore:
@@ -562,89 +562,74 @@ test("mergeDefaultSetupAndUserConfigs - keeps other properties from user-supplie
t.deepEqual(result, configFile);
});
test.serial(
"mergeDefaultSetupAndUserConfigs - ignores, but warns about, unknown keys from Default Setup",
async (t) => {
const logger = new RecordingLogger();
const configFile: dbConfig.UserConfig = {
"query-filters": [{ exclude: { a: "b" } }],
"paths-ignore": ["path"],
};
test("mergeDefaultSetupAndUserConfigs - ignores, but warns about, unknown keys from Default Setup", async (t) => {
const logger = new RecordingLogger();
const configFile: dbConfig.UserConfig = {
"query-filters": [{ exclude: { a: "b" } }],
"paths-ignore": ["path"],
};
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const result = dbConfig.mergeDefaultSetupAndUserConfigs(
logger,
{
"default-setup": {
borg: [],
org: {
unknown: "foo",
"model-packs": [],
},
} as unknown as dbConfig.DefaultSetupConfig,
"paths-ignore": ["other-path"],
const result = dbConfig.mergeDefaultSetupAndUserConfigs(
logger,
{
"default-setup": {
borg: [],
org: {
unknown: "foo",
"model-packs": [],
},
configFile,
);
} as unknown as dbConfig.DefaultSetupConfig,
"paths-ignore": ["other-path"],
},
configFile,
);
t.deepEqual(result, {
...configFile,
"default-setup": { org: { "model-packs": [] } },
});
t.deepEqual(result, {
...configFile,
"default-setup": { org: { "model-packs": [] } },
});
const expectedUnrecognisedKeys = [
".default-setup.org.unknown",
".default-setup.borg",
".paths-ignore",
].join(", ");
checkExpectedLogMessages(t, logger.messages, [
`Unrecognised keys in Default Setup configuration: ${expectedUnrecognisedKeys}`,
]);
});
},
);
const expectedUnrecognisedKeys = [
".default-setup.org.unknown",
".default-setup.borg",
".paths-ignore",
].join(", ");
checkExpectedLogMessages(t, logger.messages, [
`Unrecognised keys in Default Setup configuration: ${expectedUnrecognisedKeys}`,
]);
});
test.serial(
"mergeDefaultSetupAndUserConfigs - warns about invalid keys from Default Setup",
async (t) => {
const logger = new RecordingLogger();
const configFile: dbConfig.UserConfig = {};
test("mergeDefaultSetupAndUserConfigs - warns about invalid keys from Default Setup", async (t) => {
const logger = new RecordingLogger();
const configFile: dbConfig.UserConfig = {};
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const result = dbConfig.mergeDefaultSetupAndUserConfigs(
logger,
{
"default-setup": {
org: {
"model-packs": [123],
},
} as unknown as dbConfig.DefaultSetupConfig,
const result = dbConfig.mergeDefaultSetupAndUserConfigs(
logger,
{
"default-setup": {
org: {
"model-packs": [123],
},
configFile,
);
} as unknown as dbConfig.DefaultSetupConfig,
},
configFile,
);
t.deepEqual(result, {
...configFile,
"default-setup": { org: { "model-packs": [123] } },
});
t.deepEqual(result, {
...configFile,
"default-setup": { org: { "model-packs": [123] } },
});
const expectedInvalidKeys = [".default-setup.org.model-packs[0]"].join(
", ",
);
checkExpectedLogMessages(t, logger.messages, [
`Invalid keys in Default Setup configuration: ${expectedInvalidKeys}`,
]);
});
},
);
const expectedInvalidKeys = [".default-setup.org.model-packs[0]"].join(", ");
checkExpectedLogMessages(t, logger.messages, [
`Invalid keys in Default Setup configuration: ${expectedInvalidKeys}`,
]);
});
/** Parses `contents` as a configuration without validating it. */
function parseUnvalidatedConfig(contents: string): dbConfig.UserConfig {
return dbConfig.parseUserConfig(
new RecordingLogger(),
getRunnerLogger(true),
"test",
contents,
false,
-165
View File
@@ -1,165 +0,0 @@
import * as fs from "fs";
import path from "path";
import test, { type ExecutionContext } from "ava";
import * as diagnostics from "./diagnostics";
import { BuiltInLanguage } from "./languages";
import {
checkExpectedLogMessages,
createTestConfig,
initAllState,
RecordingLogger,
setupTests,
} from "./testing-utils";
import { withTmpDir } from "./util";
setupTests(test);
const id = "codeql-action/test-diagnostic";
const name = "Test title";
test("makeDiagnostic - adds expected properties", (t) => {
const diagnostic = diagnostics.makeDiagnostic(id, name, {});
t.truthy(diagnostic.timestamp);
t.is(diagnostic.source.id, id);
t.is(diagnostic.source.name, name);
});
test("getLanguageDiagnosticsPath gets language-specific path", async (t) =>
withTmpDir(async (tmpDir) => {
for (const language of Object.values(BuiltInLanguage)) {
t.is(
diagnostics.getLanguageDiagnosticsPath(tmpDir, language),
path.resolve(
tmpDir,
language,
...diagnostics.CODEQL_ACTION_DIAGNOSTIC_SUBDIR_PARTS,
),
);
}
}));
test("getTempLanguageDiagnosticsPath returns path without language", async (t) =>
withTmpDir(async (tmpDir) => {
t.is(
diagnostics.getTempLanguageDiagnosticsPath(tmpDir),
path.resolve(
tmpDir,
diagnostics.TEMP_DIAGNOSTIC_DIR_NAME,
...diagnostics.CODEQL_ACTION_DIAGNOSTIC_SUBDIR_PARTS,
),
);
}));
test("getTempLanguageDiagnosticsPath returns language-specific path if a language is provided", async (t) =>
withTmpDir(async (tmpDir) => {
t.is(
diagnostics.getTempLanguageDiagnosticsPath(tmpDir, BuiltInLanguage.swift),
path.resolve(
tmpDir,
diagnostics.TEMP_DIAGNOSTIC_DIR_NAME,
BuiltInLanguage.swift,
...diagnostics.CODEQL_ACTION_DIAGNOSTIC_SUBDIR_PARTS,
),
);
}));
test("getDatabaseDiagnosticsPath returns language-specific path", async (t) =>
withTmpDir(async (tmpDir) => {
t.is(
diagnostics.getDatabaseDiagnosticsPath(
createTestConfig({ dbLocation: tmpDir }),
BuiltInLanguage.swift,
),
path.resolve(
tmpDir,
BuiltInLanguage.swift,
...diagnostics.CODEQL_ACTION_DIAGNOSTIC_SUBDIR_PARTS,
),
);
}));
/**
* Diagnostic files that are written to disk don't have deterministic names.
* This function recursively finds all `.json` files at {@link rootPath},
* asserts that there is exactly one, and that it matches {@link expected}.
*
* @param rootPath The path to start searching from.
*/
function assertSingleDiagnosticIn(
t: ExecutionContext<unknown>,
rootPath: string,
expected: diagnostics.DiagnosticMessage,
) {
// Find all `.json` files in `rootPath` and check that there is exactly one.
const filePaths = fs
.readdirSync(rootPath, {
recursive: true,
encoding: "utf-8",
})
.filter((p) => p.endsWith(".json"));
t.is(filePaths.length, 1);
// Check that the written diagnostic matches the one we added.
const contents = fs.readFileSync(
path.resolve(rootPath, filePaths[0]),
"utf-8",
);
const readDiagnostic = JSON.parse(contents) as diagnostics.DiagnosticMessage;
t.deepEqual(readDiagnostic, expected);
}
test("addDiagnostic writes temporary diagnostics and flushDiagnostics moves them to the database", async (t) =>
withTmpDir(async (tmpDir) => {
const logger = new RecordingLogger();
const tempDiagDir = path.resolve(tmpDir, "temp");
const testDbDir = path.resolve(tmpDir, "test", "database");
const diagnostic = diagnostics.makeDiagnostic(id, name, {});
// Write the diagnostic. The path provided for `dbLocation` doesn't exist,
// so the diagnostic will be written to a temporary location.
t.notThrows(() => {
diagnostics.addDiagnostic(
createTestConfig({ tempDir: tempDiagDir, dbLocation: testDbDir }),
BuiltInLanguage.actions,
diagnostic,
logger,
);
});
// Check that `tempDiagDir` was created.
t.true(fs.existsSync(tempDiagDir));
// Check that the diagnostic exists under `tempDiagDir`.
assertSingleDiagnosticIn(t, tempDiagDir, diagnostic);
// Flush the diagnostics. This will cause the diagnostic we wrote previously to
// be moved to a location under `dbLocation`.
t.notThrows(() => {
diagnostics.flushDiagnostics(
initAllState({ logger }),
createTestConfig({
tempDir: tempDiagDir,
dbLocation: testDbDir,
}),
);
});
// Check that `testDbDir` was created.
t.true(fs.existsSync(testDbDir));
// Check that the diagnostic exists under `testDbDir`.
assertSingleDiagnosticIn(t, testDbDir, diagnostic);
// Check that we logged that the database directory doesn't exist yet
// and that we moved one diagnostic.
checkExpectedLogMessages(t, logger.messages, [
`but the database at ${path.join(testDbDir, "actions")} does not exist yet`,
"Moving 1 diagnostic(s) to their respective databases.",
]);
}));
+83 -218
View File
@@ -1,24 +1,10 @@
import * as fs from "fs";
import { existsSync, mkdirSync, writeFileSync } from "fs";
import path from "path";
import type { ActionState } from "./action-common";
import { getTemporaryDirectory } from "./actions-util";
import type { Config } from "./config-utils";
import { Language } from "./languages";
import { getActionsLogger, type Logger } from "./logging";
import {
getCodeQLDatabasePath,
getErrorMessage,
isErrnoException,
} from "./util";
/** The name of the directory we use to temporarily store diagnostics. */
export const TEMP_DIAGNOSTIC_DIR_NAME = "codeql-action-temp-diagnostics";
export const CODEQL_ACTION_DIAGNOSTIC_SUBDIR_PARTS = [
"diagnostic",
"codeql-action",
];
import { getActionsLogger } from "./logging";
import { getCodeQLDatabasePath } from "./util";
/**
* Known tags for diagnostics. There is currently only "internal-error",
@@ -98,16 +84,22 @@ export type DiagnosticMessage = DiagnosticMessageOptions & {
source: DiagnosticSource;
};
/** Represents a diagnostic message that has not yet been saved to the database. */
interface TemporaryDiagnostic {
/** The path to which the diagnostic has temporarily been written to. */
path: string;
/** The language the diagnostic is for, if any. */
language?: Language;
/** Represents a diagnostic message that has not yet been written to the database. */
interface UnwrittenDiagnostic {
/** The diagnostic message that has not yet been written. */
diagnostic: DiagnosticMessage;
/** The language the diagnostic is for. */
language: Language;
}
/** A list of diagnostics which have not yet been saved to the database. */
let temporaryDiagnostics: TemporaryDiagnostic[] = [];
/** A list of diagnostics which have not yet been written to disk. */
let unwrittenDiagnostics: UnwrittenDiagnostic[] = [];
/**
* A list of diagnostics which have not yet been written to disk,
* and where the language does not matter.
*/
let unwrittenDefaultLanguageDiagnostics: DiagnosticMessage[] = [];
/**
* Counter used to generate a unique suffix for each diagnostic filename, so that
@@ -136,51 +128,6 @@ export function makeDiagnostic(
};
}
/**
* Gets a path relative to {@link basePath} where diagnostics for {@link language} should be stored at.
*/
export function getLanguageDiagnosticsPath(
basePath: string,
language: Language,
) {
return path.resolve(
basePath,
language,
...CODEQL_ACTION_DIAGNOSTIC_SUBDIR_PARTS,
);
}
/**
* Gets a path relative to {@link tmpDir} where diagnostics should temporarily be stored
* until they can be moved to the database.
*/
export function getTempDiagnosticsRoot(tmpDir: string): string {
return path.resolve(tmpDir, TEMP_DIAGNOSTIC_DIR_NAME);
}
/**
* Gets a path relative to {@link tmpDir} where diagnostics for {@link language}
* can temporarily be stored at before the database is initialised. If {@link language}
* is `undefined`, then a non-language-specific path is returned.
*/
export function getTempLanguageDiagnosticsPath(
tmpDir: string,
language?: Language,
) {
const root = getTempDiagnosticsRoot(tmpDir);
if (language !== undefined) {
return getLanguageDiagnosticsPath(root, language);
}
return path.resolve(root, ...CODEQL_ACTION_DIAGNOSTIC_SUBDIR_PARTS);
}
/** Gets the path where diagnostics for {@link language} should be stored in the database. */
export function getDatabaseDiagnosticsPath(config: Config, language: Language) {
return getLanguageDiagnosticsPath(config.dbLocation, language);
}
/**
* Adds the given diagnostic to the database. If the database does not yet exist,
* the diagnostic will be written to it once it has been created.
@@ -193,23 +140,22 @@ export function addDiagnostic(
config: Config,
language: Language,
diagnostic: DiagnosticMessage,
logger: Logger = getActionsLogger(),
) {
const logger = getActionsLogger();
const databasePath = language
? getCodeQLDatabasePath(config, language)
: config.dbLocation;
// Check that the database exists before writing to it. If the database does not yet exist,
// store the diagnostic in a temporary location and move it to the database later.
if (fs.existsSync(databasePath)) {
writeDiagnostic({ logger }, config, language, diagnostic);
// store the diagnostic in memory and write it later.
if (existsSync(databasePath)) {
writeDiagnostic(config, language, diagnostic);
} else {
logger.debug(
`Writing a diagnostic for ${language}, but the database at ${databasePath} does not exist yet.`,
);
// Write the diagnostic to a temporary location.
writeTemporaryDiagnosticFile(logger, config.tempDir, language, diagnostic);
unwrittenDiagnostics.push({ diagnostic, language });
}
}
@@ -217,7 +163,6 @@ export function addDiagnostic(
export function addNoLanguageDiagnostic(
config: Config | undefined,
diagnostic: DiagnosticMessage,
logger: Logger = getActionsLogger(),
) {
if (config !== undefined) {
addDiagnostic(
@@ -228,74 +173,10 @@ export function addNoLanguageDiagnostic(
diagnostic,
);
} else {
logger.debug(
`Writing a diagnostic not associated with any language, but we have no configuration to tell us where the database is yet.`,
);
// Write the diagnostic to a temporary location.
writeTemporaryDiagnosticFile(
logger,
getTemporaryDirectory(),
undefined,
diagnostic,
);
unwrittenDefaultLanguageDiagnostics.push(diagnostic);
}
}
/**
* Writes {@link diagnostic} for an optional {@link language} to a subdirectory of {@link tempDir}
* and tracks it as a diagnostic that was written to a temporary location.
*/
function writeTemporaryDiagnosticFile(
logger: Logger,
tempDir: string,
language: Language | undefined,
diagnostic: DiagnosticMessage,
) {
const tempDiagnosticsPath = getTempLanguageDiagnosticsPath(tempDir, language);
try {
// Write the diagnostic to a temporary location.
const diagnosticPath = writeDiagnosticFile(tempDiagnosticsPath, diagnostic);
// Track the temporary file.
temporaryDiagnostics.push({ path: diagnosticPath, language });
} catch (err) {
logger.warning(
`Unable to write temporary diagnostic to '${tempDiagnosticsPath}': ${getErrorMessage(err)}\n\n${JSON.stringify(diagnostic)}`,
);
}
}
/**
* Writes {@link diagnostic} to a file in {@link diagnosticsPath}.
*/
function writeDiagnosticFile(
diagnosticsPath: string,
diagnostic: DiagnosticMessage,
): string {
// Create the directory if it doesn't exist yet.
fs.mkdirSync(diagnosticsPath, { recursive: true });
// Include a monotonically increasing suffix to avoid filename collisions
// between diagnostics produced within the same millisecond.
const uniqueSuffix = (diagnosticCounter++).toString();
// We should only need to remove colons, but to be defensive, only allow a restricted set of
// characters.
const sanitizedTimestamp = diagnostic.timestamp.replace(
/[^a-zA-Z0-9.-]/g,
"",
);
const jsonPath = path.resolve(
diagnosticsPath,
`codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json`,
);
fs.writeFileSync(jsonPath, JSON.stringify(diagnostic));
return jsonPath;
}
/**
* Writes the given diagnostic to the database.
*
@@ -304,94 +185,78 @@ function writeDiagnosticFile(
* @param diagnostic The diagnostic message to add to the database.
*/
function writeDiagnostic(
action: ActionState<["Logger"]>,
config: Config,
language: Language,
language: Language | undefined,
diagnostic: DiagnosticMessage,
) {
const diagnosticsPath = getDatabaseDiagnosticsPath(config, language);
try {
writeDiagnosticFile(diagnosticsPath, diagnostic);
} catch (err) {
action.logger.warning(
`Unable to write diagnostic message to database: ${err}`,
);
action.logger.debug(JSON.stringify(diagnostic));
}
}
/** Report if there are temporary diagnostics and write them to the log. */
export function logTemporaryDiagnostics(action: ActionState<["Logger"]>) {
const num = temporaryDiagnostics.length;
if (num > 0 && action.logger.isDebug()) {
action.logger.startGroup("Diagnostics in temporary location");
action.logger.debug(
`${num} diagnostic(s) were not moved to the database and remain in the temporary directory.`,
);
for (const temporary of temporaryDiagnostics) {
try {
action.logger.debug(fs.readFileSync(temporary.path, "utf-8"));
} catch (err) {
action.logger.debug(
`Failed to read diagnostics from temporary location at '${temporary.path}': ${getErrorMessage(err)}`,
);
}
}
action.logger.endGroup();
}
}
/** Relocates all temporary diagnostics to the respective databases. */
export function flushDiagnostics(
action: ActionState<["Logger"]>,
config: Config,
) {
const diagnosticsCount = temporaryDiagnostics.length;
action.logger.debug(
`Moving ${diagnosticsCount} diagnostic(s) to their respective databases.`,
const logger = getActionsLogger();
const databasePath = language
? getCodeQLDatabasePath(config, language)
: config.dbLocation;
const diagnosticsPath = path.resolve(
databasePath,
"diagnostic",
"codeql-action",
);
const failedFlushDiagnostics: TemporaryDiagnostic[] = [];
for (const temporary of temporaryDiagnostics) {
// If `temporary.language` is `undefined`, then we didn't have a `config` at the time that
// `addNoLanguageDiagnostic` was called. In that case, we arbitrarily choose the first
// configured language here like we would have done in `addNoLanguageDiagnostic`.
const directory = getDatabaseDiagnosticsPath(
config,
temporary.language ?? config.languages[0],
try {
// Create the directory if it doesn't exist yet.
mkdirSync(diagnosticsPath, { recursive: true });
// Include a monotonically increasing suffix to avoid filename collisions
// between diagnostics produced within the same millisecond.
const uniqueSuffix = (diagnosticCounter++).toString();
// We should only need to remove colons, but to be defensive, only allow a restricted set of
// characters.
const sanitizedTimestamp = diagnostic.timestamp.replace(
/[^a-zA-Z0-9.-]/g,
"",
);
const jsonPath = path.resolve(
diagnosticsPath,
`codeql-action-${sanitizedTimestamp}-${uniqueSuffix}.json`,
);
const filename = path.basename(temporary.path);
const destination = path.join(directory, filename);
try {
fs.mkdirSync(directory, { recursive: true });
try {
fs.renameSync(temporary.path, destination);
} catch (renameErr: unknown) {
// Rethrow the error if it isn't an EXDEV one.
if (!isErrnoException(renameErr) || renameErr.code !== "EXDEV") {
throw renameErr;
}
writeFileSync(jsonPath, JSON.stringify(diagnostic));
} catch (err) {
logger.warning(`Unable to write diagnostic message to database: ${err}`);
logger.debug(JSON.stringify(diagnostic));
}
}
// The error was an EXDEV one: try to copy the file and delete the temporary one.
fs.copyFileSync(temporary.path, destination);
fs.unlinkSync(temporary.path);
}
} catch (err) {
action.logger.warning(
`Failed to relocate '${temporary.path}' to '${destination}': ${getErrorMessage(err)}`,
);
/** Report if there are unwritten diagnostics and write them to the log. */
export function logUnwrittenDiagnostics() {
const logger = getActionsLogger();
const num = unwrittenDiagnostics.length;
if (num > 0) {
logger.warning(
`${num} diagnostic(s) could not be written to the database and will not appear on the Tool Status Page.`,
);
failedFlushDiagnostics.push(temporary);
for (const unwritten of unwrittenDiagnostics) {
logger.debug(JSON.stringify(unwritten.diagnostic));
}
}
}
// Reset the temporary diagnostics arrays.
temporaryDiagnostics = failedFlushDiagnostics;
/** Writes all unwritten diagnostics to disk. */
export function flushDiagnostics(config: Config) {
const logger = getActionsLogger();
const diagnosticsCount =
unwrittenDiagnostics.length + unwrittenDefaultLanguageDiagnostics.length;
logger.debug(`Writing ${diagnosticsCount} diagnostic(s) to database.`);
for (const unwritten of unwrittenDiagnostics) {
writeDiagnostic(config, unwritten.language, unwritten.diagnostic);
}
for (const unwritten of unwrittenDefaultLanguageDiagnostics) {
addNoLanguageDiagnostic(config, unwritten);
}
// Reset the unwritten diagnostics arrays.
unwrittenDiagnostics = [];
unwrittenDefaultLanguageDiagnostics = [];
}
/**
+7 -7
View File
@@ -10,6 +10,7 @@ import {
exportedForTesting,
} from "./diff-informed-analysis-utils";
import { Feature, FeatureEnablement, initFeatures } from "./feature-flags";
import { getRunnerLogger } from "./logging";
import { parseRepositoryNwo } from "./repository";
import {
setupTests,
@@ -18,7 +19,6 @@ import {
mockFeatureFlagApiEndpoint,
setupActionsVars,
makeMacro,
RecordingLogger,
} from "./testing-utils";
import { GitHubVariant, withTmpDir } from "./util";
import type { GitHubVersion } from "./util";
@@ -55,7 +55,7 @@ const testShouldPerformDiffInformedAnalysis = makeMacro({
setupActionsVars(tmpDir, tmpDir);
const testCase = { ...defaultTestCase, ...partialTestCase };
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const codeql = mockCodeQLVersion(testCase.codeQLVersion);
if (testCase.diffInformedQueriesEnvVar !== undefined) {
@@ -182,7 +182,7 @@ test.serial(
async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const codeql = mockCodeQLVersion("2.21.0");
const features = createFeatures([Feature.DiffInformedQueries]);
@@ -207,7 +207,7 @@ test.serial(
async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const codeql = mockCodeQLVersion("2.21.0");
// A features implementation whose getValue rejects, simulating an
// unexpected failure when determining whether diff-informed analysis
@@ -237,7 +237,7 @@ test.serial(
async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const codeql = mockCodeQLVersion("2.21.0");
const features = createFeatures([Feature.DiffInformedQueries]);
@@ -274,7 +274,7 @@ test.serial(
async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const codeql = mockCodeQLVersion("2.21.0");
const features = createFeatures([Feature.DiffInformedQueries]);
@@ -313,7 +313,7 @@ function runGetDiffRanges(changes: number, patch: string[] | undefined): any {
changes,
patch: patch?.join("\n"),
},
new RecordingLogger(),
getRunnerLogger(true),
);
}
+1
View File
@@ -3,6 +3,7 @@
*/
export enum DocUrl {
ASSIGNING_PERMISSIONS_TO_JOBS = "https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs",
AUTOMATIC_BUILD_FAILED = "https://docs.github.com/en/code-security/code-scanning/troubleshooting-code-scanning/automatic-build-failed",
CODEQL_BUILD_MODES = "https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages#codeql-build-modes",
DEFINE_ENV_VARIABLES = "https://docs.github.com/en/actions/learn-github-actions/variables#defining-environment-variables-for-a-single-workflow",
+39
View File
@@ -74,6 +74,7 @@ export enum Feature {
AllowMergeConfigFiles = "allow_merge_config_files",
/** Controls whether we allow multiple values for the `analysis-kinds` input. */
AllowMultipleAnalysisKinds = "allow_multiple_analysis_kinds",
CleanupTrapCaches = "cleanup_trap_caches",
/** Whether to allow the `config-file` input to be specified via a repository property. */
ConfigFileRepositoryProperty = "config_file_repository_property",
CppDependencyInstallation = "cpp_dependency_installation_enabled",
@@ -105,6 +106,19 @@ export enum Feature {
OverlayAnalysisGo = "overlay_analysis_go",
OverlayAnalysisJava = "overlay_analysis_java",
OverlayAnalysisJavascript = "overlay_analysis_javascript",
/**
* When set, chooses the default CodeQL CLI version as the highest version that is both enabled by
* feature flags and present as an overlay-base database in the Actions cache for the configured
* languages. Falls back to the highest feature flagged version if no intersecting overlay-base
* database exists in the cache.
*/
OverlayAnalysisMatchCodeqlVersion = "overlay_analysis_match_codeql_version",
/**
* Like `OverlayAnalysisMatchCodeqlVersion`, but only logs a diagnostic with the version that
* would have been chosen instead of actually changing the default CodeQL CLI version.
* `OverlayAnalysisMatchCodeqlVersion` overrides this flag.
*/
OverlayAnalysisMatchCodeqlVersionDryRun = "overlay_analysis_match_codeql_version_dry_run",
/**
* Lowers the overlay minimum available disk space to 8 GB. The lowest enabled limit wins; if
* none are enabled, the default applies.
@@ -143,6 +157,11 @@ 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",
/**
* Controls whether we may download a bundle containing only the single language being analysed,
* rather than the combined bundle that contains every language.
*/
PerLanguageBundles = "per_language_bundles_v2",
QaTelemetryEnabled = "qa_telemetry_enabled",
/** Routes (some) API requests through the registry proxy. */
ProxyApiRequests = "proxy_api_requests",
@@ -195,6 +214,11 @@ export const featureConfig = {
envVar: "CODEQL_ACTION_ALLOW_MULTIPLE_ANALYSIS_KINDS",
minimumVersion: undefined,
},
[Feature.CleanupTrapCaches]: {
defaultValue: false,
envVar: "CODEQL_ACTION_CLEANUP_TRAP_CACHES",
minimumVersion: undefined,
},
[Feature.ConfigFileRepositoryProperty]: {
defaultValue: false,
envVar: "CODEQL_ACTION_CONFIG_FILE_REPOSITORY_PROPERTY",
@@ -343,6 +367,16 @@ export const featureConfig = {
minimumVersion: CODEQL_OVERLAY_MINIMUM_VERSION_RUBY,
},
// Other overlay-related feature flags
[Feature.OverlayAnalysisMatchCodeqlVersion]: {
defaultValue: false,
envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION",
minimumVersion: undefined,
},
[Feature.OverlayAnalysisMatchCodeqlVersionDryRun]: {
defaultValue: false,
envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MATCH_CODEQL_VERSION_DRY_RUN",
minimumVersion: undefined,
},
[Feature.OverlayAnalysisMinDisk8Gb]: {
defaultValue: false,
envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_MIN_DISK_8_GB",
@@ -388,6 +422,11 @@ export const featureConfig = {
envVar: "CODEQL_ACTION_OVERLAY_ANALYSIS_SKIP_RESOURCE_CHECKS",
minimumVersion: undefined,
},
[Feature.PerLanguageBundles]: {
defaultValue: false,
envVar: "CODEQL_ACTION_PER_LANGUAGE_BUNDLES",
minimumVersion: undefined,
},
[Feature.QaTelemetryEnabled]: {
defaultValue: false,
envVar: "CODEQL_ACTION_QA_TELEMETRY",
+9 -8
View File
@@ -2,6 +2,7 @@ import test from "ava";
import * as sinon from "sinon";
import * as api from "../api-client";
import { getRunnerLogger } from "../logging";
import { parseRepositoryNwo } from "../repository";
import { RecordingLogger, setupTests } from "../testing-utils";
@@ -18,7 +19,7 @@ test.serial(
url: "",
data: {},
});
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
await t.throwsAsync(
properties.loadPropertiesFromApi(logger, mockRepositoryNwo),
@@ -38,7 +39,7 @@ test.serial(
url: "",
data: [{}],
});
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
await t.throwsAsync(
properties.loadPropertiesFromApi(logger, mockRepositoryNwo),
@@ -62,7 +63,7 @@ test.serial(
{ property_name: "also-not-used-by-us", value: ["A", "B", "C"] },
],
});
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
await t.notThrowsAsync(
properties.loadPropertiesFromApi(logger, mockRepositoryNwo),
@@ -85,7 +86,7 @@ test.serial("loadPropertiesFromApi loads known properties", async (t) => {
{ property_name: "unknown-property", value: "something" },
] satisfies properties.GitHubPropertiesResponse,
});
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
const response = await properties.loadPropertiesFromApi(
logger,
@@ -112,7 +113,7 @@ test.serial("loadPropertiesFromApi parses true boolean property", async (t) => {
{ property_name: "github-codeql-extra-queries", value: "+queries" },
] satisfies properties.GitHubPropertiesResponse,
});
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const warningSpy = sinon.spy(logger, "warning");
const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
const response = await properties.loadPropertiesFromApi(
@@ -140,7 +141,7 @@ test.serial(
},
] satisfies properties.GitHubPropertiesResponse,
});
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const warningSpy = sinon.spy(logger, "warning");
const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
const response = await properties.loadPropertiesFromApi(
@@ -163,7 +164,7 @@ test.serial(
url: "",
data: [{ property_name: "github-codeql-extra-queries", value: 123 }],
});
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
await t.throwsAsync(
properties.loadPropertiesFromApi(logger, mockRepositoryNwo),
@@ -189,7 +190,7 @@ test.serial(
},
] satisfies properties.GitHubPropertiesResponse,
});
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const warningSpy = sinon.spy(logger, "warning");
const mockRepositoryNwo = parseRepositoryNwo("owner/repo");
const response = await properties.loadPropertiesFromApi(
+2 -3
View File
@@ -8,12 +8,11 @@ import {
FeatureWithoutCLI,
initFeatures,
} from "../feature-flags";
import type { Logger } from "../logging";
import { getRunnerLogger } from "../logging";
import { parseRepositoryNwo } from "../repository";
import {
LoggedMessage,
mockCodeQLVersion,
RecordingLogger,
setupActionsVars,
} from "../testing-utils";
import { ToolsFeature } from "../tools-features";
@@ -52,7 +51,7 @@ export function assertAllFeaturesUndefinedInApi(
export function setUpFeatureFlagTests(
tmpDir: string,
logger: Logger = new RecordingLogger(),
logger = getRunnerLogger(true),
gitHubVersion = { type: GitHubVariant.DOTCOM } as util.GitHubVersion,
): FeatureEnablement {
setupActionsVars(tmpDir, tmpDir);
+5 -4
View File
@@ -5,8 +5,9 @@ import * as ava from "ava";
import test from "ava";
import * as fingerprints from "./fingerprints";
import { getRunnerLogger } from "./logging";
import * as sarif from "./sarif";
import { RecordingLogger, setupTests } from "./testing-utils";
import { setupTests } from "./testing-utils";
import * as util from "./util";
setupTests(test);
@@ -130,7 +131,7 @@ function testResolveUriToFile(uri: any, index: any, artifactsURIs: any[]) {
location,
artifacts,
process.cwd(),
new RecordingLogger(),
getRunnerLogger(true),
);
}
@@ -217,7 +218,7 @@ test("addFingerprints", async (t) => {
await fingerprints.addFingerprints(
input,
sourceRoot,
new RecordingLogger(),
getRunnerLogger(true),
),
expected,
);
@@ -245,7 +246,7 @@ test("missingRegions", async (t) => {
await fingerprints.addFingerprints(
input,
sourceRoot,
new RecordingLogger(),
getRunnerLogger(true),
),
expected,
);
+11 -56
View File
@@ -1,6 +1,3 @@
import * as fs from "fs";
import * as path from "path";
import * as core from "@actions/core";
import test, { ExecutionContext } from "ava";
import * as sinon from "sinon";
@@ -11,10 +8,10 @@ import * as apiClient from "./api-client";
import * as codeql from "./codeql";
import * as configUtils from "./config-utils";
import * as debugArtifacts from "./debug-artifacts";
import { getTempDiagnosticsRoot } from "./diagnostics";
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/overlay-database-mode";
import * as overlayStatus from "./overlay/status";
import { parseRepositoryNwo } from "./repository";
@@ -23,7 +20,6 @@ import {
createFeatures,
createTestConfig,
DEFAULT_ACTIONS_VARS,
getCodeQLForTesting,
getTestEnv,
makeMacro,
makeVersionInfo,
@@ -39,47 +35,6 @@ const NUM_BYTES_PER_GIB = 1024 * 1024 * 1024;
setupTests(test);
test.serial("generateFailedSarif picks up unwritten diagnostics", async (t) =>
util.withTmpDir(async (tmpDir) => {
const logger = new RecordingLogger();
const tempDiagDir = getTempDiagnosticsRoot(tmpDir);
fs.mkdirSync(tempDiagDir, { recursive: true });
const codeqlObject = await getCodeQLForTesting();
const diagnosticsExport = sinon
.stub(codeqlObject, "diagnosticsExport")
.resolves();
sinon.stub(codeql, "getCodeQL").resolves(codeqlObject);
const sarifFile = path.join(tmpDir, "failed.sarif");
const result = await initActionPostHelper.generateFailedSarif(
logger,
createFeatures([Feature.ExportDiagnosticsEnabled]),
createTestConfig({
tempDir: tmpDir,
// Explicitly undefined to ensure we get the "no database" path.
dbLocation: undefined,
}),
"category",
"",
sarifFile,
);
t.truthy(result);
t.is(diagnosticsExport.callCount, 1);
t.true(
diagnosticsExport.calledOnceWith(
sarifFile,
"category",
sinon.match.any,
tempDiagDir,
),
);
}),
);
test.serial("init-post action with debug mode off", async (t) => {
return await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -107,7 +62,7 @@ test.serial("init-post action with debug mode off", async (t) => {
createFeatures([]),
"success",
getTestEnv(),
new RecordingLogger(),
getRunnerLogger(true),
);
t.assert(uploadAllAvailableDebugArtifactsSpy.notCalled);
@@ -131,7 +86,7 @@ test.serial("init-post action with debug mode on", async (t) => {
createFeatures([]),
"success",
getTestEnv(),
new RecordingLogger(),
getRunnerLogger(true),
);
t.assert(uploadAllAvailableDebugArtifactsSpy.called);
@@ -428,7 +383,7 @@ test.serial(
createFeatures([Feature.OverlayAnalysisStatusSave]),
"success",
getTestEnv(),
new RecordingLogger(),
getRunnerLogger(true),
);
t.true(
@@ -498,7 +453,7 @@ test.serial(
createFeatures([]),
"success",
getTestEnv(),
new RecordingLogger(),
getRunnerLogger(true),
);
t.true(
@@ -542,7 +497,7 @@ test.serial("does not save overlay status when build successful", async (t) => {
createFeatures([Feature.OverlayAnalysisStatusSave]),
"success",
env,
new RecordingLogger(),
getRunnerLogger(true),
);
t.true(
@@ -581,7 +536,7 @@ test.serial(
createFeatures([]),
"success",
getTestEnv(),
new RecordingLogger(),
getRunnerLogger(true),
);
t.true(
@@ -634,7 +589,7 @@ async function runOverlayPostStep({
createFeatures([Feature.OverlayAnalysisStatusSave]),
jobStatus,
env,
new RecordingLogger(),
getRunnerLogger(true),
);
return { saveOverlayStatusStub };
@@ -782,7 +737,7 @@ async function testFailedSarifUpload(
.withArgs("matrix")
.returns(JSON.stringify(matrix));
const codeqlObject = await getCodeQLForTesting();
const codeqlObject = await codeql.getCodeQLForTesting();
sinon.stub(codeql, "getCodeQL").resolves(codeqlObject);
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.17.6"));
const databaseExportDiagnosticsStub = sinon.stub(
@@ -809,7 +764,7 @@ async function testFailedSarifUpload(
config,
parseRepositoryNwo("github/codeql-action"),
createFeatures(features),
new RecordingLogger(),
getRunnerLogger(true),
);
if (expectUpload) {
t.deepEqual(result, {
@@ -878,7 +833,7 @@ async function mockRiskAssessmentEnv(matrix: string) {
.stub(apiClient, "getGitHubVersion")
.resolves({ type: util.GitHubVariant.GHES, version: "3.0.0" });
const codeqlObject = await getCodeQLForTesting();
const codeqlObject = await codeql.getCodeQLForTesting();
const databaseExportDiagnostics = sinon
.stub(codeqlObject, "databaseExportDiagnostics")
.resolves();
+6 -31
View File
@@ -24,7 +24,6 @@ import {
type UploadDebugArtifactsConfig,
} from "./debug-artifacts";
import * as dependencyCaching from "./dependency-caching";
import { getTempDiagnosticsRoot } from "./diagnostics";
import { EnvVar, ReadOnlyEnv } from "./environment";
import { Feature, FeatureEnablement } from "./feature-flags";
import { Logger } from "./logging";
@@ -178,16 +177,7 @@ async function prepareFailedSarif(
}
}
/**
* Generates a SARIF file for a failed run, i.e. an analysis where no SARIF was produced as a result of the analysis.
*
* Not intended to be called directly, other than by `prepareFailedSarif`.
*
* @param category The analysis category to include in the SARIF.
* @param checkoutPath The path where the repository was checked out at.
* @param sarifFile The SARIF file to produce.
*/
export async function generateFailedSarif(
async function generateFailedSarif(
logger: Logger,
features: FeatureEnablement,
config: ActionConfig<"codeQLCmd" | "tempDir">,
@@ -204,26 +194,11 @@ export async function generateFailedSarif(
}
// If there is no database or the feature flag is off, we run 'export diagnostics'
const exportDiagnosticsEnabled = await features.getValue(
Feature.ExportDiagnosticsEnabled,
codeql,
);
if (databasePath === undefined || !exportDiagnosticsEnabled) {
// If we don't have a database path, then we may have diagnostics that were written to a
// temporary location. Get the path that they would have been written to and check whether
// it exists. If so, pass it on to the CLI. The CLI will not complain if we give it a
// path that doesn't exist, so we are just being extra defensive here.
// We also don't pass the path to the CLI if `exportDiagnosticsEnabled` is not enabled, to preserve
// its intended behaviour of controlling whether diagnostics are included in the SARIF or not.
let diagnosticDir: string | undefined = getTempDiagnosticsRoot(
config.tempDir,
);
if (!exportDiagnosticsEnabled || !fs.existsSync(diagnosticDir)) {
diagnosticDir = undefined;
}
await codeql.diagnosticsExport(sarifFile, category, config, diagnosticDir);
if (
databasePath === undefined ||
!(await features.getValue(Feature.ExportDiagnosticsEnabled, codeql))
) {
await codeql.diagnosticsExport(sarifFile, category, config);
} else {
// We call 'database export-diagnostics' to find any per-database diagnostics.
await codeql.databaseExportDiagnostics(databasePath, sarifFile, category);
+5 -7
View File
@@ -40,7 +40,7 @@ import {
addDiagnostic,
addNoLanguageDiagnostic,
flushDiagnostics,
logTemporaryDiagnostics,
logUnwrittenDiagnostics,
makeDiagnostic,
makeTelemetryDiagnostic,
} from "./diagnostics";
@@ -484,7 +484,6 @@ async function run(
if (statusReportBase !== undefined) {
await sendStatusReport(statusReportBase);
}
logTemporaryDiagnostics(actionState);
return;
}
@@ -767,15 +766,14 @@ async function run(
);
}
// Move diagnostics to the database that we previously kept in a temporary location
// because the database did not exist until now
flushDiagnostics(actionState, config);
// Write diagnostics to the database that we previously stored in memory because the database
// did not exist until now.
flushDiagnostics(config);
// We save the config here instead of at the end of `initConfig` because we
// may have updated the config returned from `initConfig`, e.g. to revert to
// `OverlayDatabaseMode.None` if we failed to download an overlay-base
// database.
config.successfullyInitialised = true;
await configUtils.saveConfig(config, logger);
core.setOutput("codeql-path", config.codeQLCmd);
@@ -799,7 +797,7 @@ async function run(
);
return;
} finally {
logTemporaryDiagnostics(actionState);
logUnwrittenDiagnostics();
}
await sendCompletedStatusReport(
startedAt,
-17
View File
@@ -1,17 +0,0 @@
import test from "ava";
import { joinMessageStrings } from "./logging";
import { setupTests } from "./testing-utils";
setupTests(test);
test("joinMessageStrings", async (t) => {
// For strings and errors, it is the identity function.
t.deepEqual(joinMessageStrings("Hello"), "Hello");
const error = new Error("Some error");
t.deepEqual(joinMessageStrings(error), error);
// For arrays of strings, we get a join-ed string.
t.deepEqual(joinMessageStrings(["foo", "bar"]), "foo bar");
});
+25 -72
View File
@@ -1,92 +1,45 @@
import * as core from "@actions/core";
/** Types that all of our logging functions accept. */
export type Loggable = string | string[];
/** Some logging functions also accept errors directly. */
export type LoggableError = Loggable | Error;
export interface Logger {
/**
* Logs {@link message} at debug-level.
* In Actions, this will only be output if workflow debugging is enabled.
*
* @param message
* A string or an array of strings. If an array of strings is provided, they are joined using
* space as the delimiter and printed as a single line.
*/
debug: (message: Loggable) => void;
/**
* Logs {@link message} at info-level.
* In Actions, this will always be output.
*
* @param message
* A string or an array of strings. If an array of strings is provided, they are joined using
* space as the delimiter and printed as a single line.
*/
info: (message: Loggable) => void;
/**
* Logs {@link message} at warning-level.
* In Actions, this will always be output and highlighted as a warning. It will additionally
* result in a warning-level workflow annotation.
*
* @param message
* A string or an array of strings. If an array of strings is provided, they are joined using
* space as the delimiter and printed as a single line.
*/
warning: (message: LoggableError) => void;
/**
* Logs {@link message} at error-level.
* In Actions, this will always be output and highlighted as an error. It will additionally
* result in an error-level workflow annotation.
*
* @param message
* A string or an array of strings. If an array of strings is provided, they are joined using
* space as the delimiter and printed as a single line.
*/
error: (message: LoggableError) => void;
/**
* Gets a value indicating whether debugging is enabled.
*/
debug: (message: string) => void;
info: (message: string) => void;
warning: (message: string | Error) => void;
error: (message: string | Error) => void;
isDebug: () => boolean;
startGroup: (name: string) => void;
endGroup: () => void;
}
/** If `message` is an array of strings, the array is `join`-ed into one string separated by spaces. */
export const joinMessageStrings = <T>(
message: string[] | string | T,
): string | T => {
if (Array.isArray(message)) {
return message.join(" ");
} else {
return message;
}
};
/**
* Wraps a logging function so that `joinMessageStrings` is applied to the input before
* calling the wrapped logging function.
*/
const autoJoinMessageStrings = <T>(fn: (msg: string | T) => void) => {
return (message: string[] | string | T) => {
return fn(joinMessageStrings(message));
};
};
export function getActionsLogger(): Logger {
return {
debug: autoJoinMessageStrings(core.debug),
info: autoJoinMessageStrings(core.info),
warning: autoJoinMessageStrings(core.warning),
error: autoJoinMessageStrings(core.error),
debug: core.debug,
info: core.info,
warning: core.warning,
error: core.error,
isDebug: core.isDebug,
startGroup: core.startGroup,
endGroup: core.endGroup,
};
}
export function getRunnerLogger(debugMode: boolean): Logger {
return {
// eslint-disable-next-line no-console
debug: debugMode ? console.debug : () => undefined,
// eslint-disable-next-line no-console
info: console.info,
// eslint-disable-next-line no-console
warning: console.warn,
// eslint-disable-next-line no-console
error: console.error,
isDebug: () => debugMode,
startGroup: () => undefined,
endGroup: () => undefined,
};
}
export function withGroup<T>(groupName: string, f: () => T): T {
core.startGroup(groupName);
try {
+10 -10
View File
@@ -11,11 +11,11 @@ import type { ResolveDatabaseOutput } from "../codeql";
import * as environment from "../environment";
import * as gitUtils from "../git-utils";
import { BuiltInLanguage } from "../languages";
import { getRunnerLogger } from "../logging";
import {
createTestConfig,
makeMacro,
mockCodeQLVersion,
RecordingLogger,
setupTests,
} from "../testing-utils";
import * as utils from "../util";
@@ -63,7 +63,7 @@ const testDownloadOverlayBaseDatabaseFromCache = makeMacro({
const dbLocation = path.join(tmpDir, "db");
await fs.promises.mkdir(dbLocation, { recursive: true });
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const testCase = { ...defaultDownloadTestCase, ...partialTestCase };
const config = createTestConfig({
dbLocation,
@@ -214,7 +214,7 @@ testDownloadOverlayBaseDatabaseFromCache.serial(
);
test.serial("overlay-base database cache keys remain stable", async (t) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const config = createTestConfig({ languages: ["python", "javascript"] });
const codeQlVersion = "2.23.0";
const commitOid = "abc123def456";
@@ -261,7 +261,7 @@ test.serial("overlay-base database cache keys remain stable", async (t) => {
test.serial(
"getCodeQlVersionsForOverlayBaseDatabases returns unique versions sorted latest first",
async (t) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/");
sinon.stub(apiClient, "listActionsCaches").resolves([
@@ -287,7 +287,7 @@ test.serial(
test.serial(
"getCodeQlVersionsForOverlayBaseDatabases returns empty list when no caches exist",
async (t) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/");
sinon.stub(apiClient, "listActionsCaches").resolves([]);
@@ -303,7 +303,7 @@ test.serial(
test.serial(
"getCodeQlVersionsForOverlayBaseDatabases returns empty list when cache keys are unparseable",
async (t) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/");
sinon.stub(apiClient, "listActionsCaches").resolves([
@@ -324,7 +324,7 @@ test.serial(
test.serial(
"getCodeQlVersionsForOverlayBaseDatabases returns the single version when only one cache exists",
async (t) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/");
sinon.stub(apiClient, "listActionsCaches").resolves([
@@ -344,7 +344,7 @@ test.serial(
test.serial(
"getCodeQlVersionsForOverlayBaseDatabases resolves language aliases",
async (t) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
// The alias `c++` should be resolved to "cpp" and match cache entries keyed with "cpp"
sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/");
@@ -365,7 +365,7 @@ test.serial(
test.serial(
"getCodeQlVersionsForOverlayBaseDatabases de-duplicates resolved language aliases",
async (t) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/");
const listActionsCachesStub = sinon
@@ -391,7 +391,7 @@ test.serial(
test.serial(
"getCodeQlVersionsForOverlayBaseDatabases ignores nightly versions with build metadata",
async (t) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/");
sinon.stub(apiClient, "listActionsCaches").resolves([
+6 -9
View File
@@ -6,11 +6,8 @@ import * as sinon from "sinon";
import * as actionsUtil from "../actions-util";
import * as gitUtils from "../git-utils";
import {
createTestConfig,
RecordingLogger,
setupTests,
} from "../testing-utils";
import { getRunnerLogger } from "../logging";
import { createTestConfig, setupTests } from "../testing-utils";
import { withTmpDir } from "../util";
import { writeBaseDatabaseOidsFile, writeOverlayChangesFile } from ".";
@@ -30,7 +27,7 @@ test.serial(
),
);
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const config = createTestConfig({ dbLocation });
// Mock the getFileOidsUnderPath function to return base OIDs
@@ -94,7 +91,7 @@ test.serial(
),
);
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const config = createTestConfig({ dbLocation });
// Mock the getFileOidsUnderPath function to return base OIDs
@@ -172,7 +169,7 @@ test.serial(
),
);
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const config = createTestConfig({ dbLocation });
// Mock the getFileOidsUnderPath function to return base OIDs
@@ -235,7 +232,7 @@ test.serial(
),
);
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const config = createTestConfig({ dbLocation });
// Base OIDs (sourceRoot-relative paths)
+28
View File
@@ -1,6 +1,7 @@
import test from "ava";
import { ActionsEnvVars } from "./environment";
import { Feature } from "./feature-flags";
import { BuiltInLanguage } from "./languages";
import {
getOtherLanguagePacksReason,
@@ -11,6 +12,7 @@ import {
} from "./per-language-bundles";
import { BundlePlatform } from "./platform";
import {
createFeatures,
getRecordingLogger,
getTestEnv,
initAllState,
@@ -38,6 +40,7 @@ async function checkEligibility(
env: getTestEnv({
[ActionsEnvVars.RUNNER_ENVIRONMENT]: "github-hosted",
}),
features: createFeatures([Feature.PerLanguageBundles]),
...stateOverrides,
}),
{ ...ELIGIBLE_OPTIONS, ...overrides },
@@ -142,6 +145,27 @@ test("getPerLanguageBundleLanguage requires a supported release version", async
t.is(await checkEligibility({ cliVersion: "2.27.1" }), BuiltInLanguage.java);
});
test("getPerLanguageBundleLanguage requires the feature flag", async (t) => {
t.is(await checkEligibility({}, { features: createFeatures([]) }), undefined);
});
test("getPerLanguageBundleLanguage explains a disabled feature before checking eligibility", async (t) => {
const messages: LoggedMessage[] = [];
const language = await getPerLanguageBundleLanguage(
initAllState({
features: createFeatures([]),
logger: getRecordingLogger(messages, { logToConsole: false }),
}),
{ ...ELIGIBLE_OPTIONS, rawLanguages: undefined, cliVersion: undefined },
);
t.is(language, undefined);
t.deepEqual(
messages.map((message) => message.message),
["Not using a per-language CodeQL bundle since the feature is disabled."],
);
});
test("getPerLanguageBundleLanguage skips only the release version check for the latest nightly", async (t) => {
const nightly = { isLatestNightly: true, cliVersion: undefined };
t.is(await checkEligibility(nightly), BuiltInLanguage.java);
@@ -157,6 +181,10 @@ test("getPerLanguageBundleLanguage skips only the release version check for the
]) {
t.is(await checkEligibility({ ...nightly, ...overrides }), undefined);
}
t.is(
await checkEligibility(nightly, { features: createFeatures([]) }),
undefined,
);
t.is(
await checkEligibility(nightly, {
env: getTestEnv({ [ActionsEnvVars.RUNNER_ENVIRONMENT]: "self-hosted" }),
+14 -7
View File
@@ -9,6 +9,7 @@ import {
QuerySpec,
UserConfig,
} from "./config/db-config";
import { Feature } from "./feature-flags";
import { RepositoryPropertyName } from "./feature-flags/properties";
import { BuiltInLanguage, parseBuiltInLanguage } from "./languages";
import { BundlePlatform } from "./platform";
@@ -138,10 +139,14 @@ export interface PerLanguageBundleOptions {
}
/** Returns the eligible bundle language, or undefined for the combined bundle. */
export function getPerLanguageBundleLanguage(
action: ActionState<["Logger", "ReadOnlyEnv"]>,
export async function getPerLanguageBundleLanguage(
{
env,
features,
logger,
}: ActionState<["Logger", "ReadOnlyEnv", "FeatureFlags"]>,
options: PerLanguageBundleOptions,
): BuiltInLanguage | undefined {
): Promise<BuiltInLanguage | undefined> {
const {
rawLanguages,
otherLanguagePacksReason,
@@ -153,12 +158,14 @@ export function getPerLanguageBundleLanguage(
} = options;
const explain = (reason: string) => {
action.logger.debug(
`Not using a per-language CodeQL bundle since ${reason}.`,
);
logger.debug(`Not using a per-language CodeQL bundle since ${reason}.`);
return undefined;
};
if (!(await features.getValue(Feature.PerLanguageBundles))) {
return explain("the feature is disabled");
}
// A defined reason means the CodeQL CLI may need packs for other languages, for example because
// of the configured queries. That applies whichever languages were requested, so check it first
// to avoid suggesting that requesting a single language would be enough.
@@ -190,7 +197,7 @@ export function getPerLanguageBundleLanguage(
return explain(`we are running against ${variant}`);
}
if (!isGitHubHostedRunner(action.env)) {
if (!isGitHubHostedRunner(env)) {
// Per-language installs stay out of the toolcache; self-hosted runners should retain
// the reusable combined bundle instead.
return explain("the job is not running on a GitHub-hosted runner");
+189 -191
View File
@@ -14,6 +14,7 @@ import * as diagnostics from "./diagnostics";
import { ActionsEnvVars, Env, EnvVar, ReadOnlyEnv } from "./environment";
import { Feature } from "./feature-flags";
import { BuiltInLanguage } from "./languages";
import { getRunnerLogger } from "./logging";
import { getCacheRestoreKeyPrefix } from "./overlay/caching";
import { MIN_PER_LANGUAGE_BUNDLE_CLI_VERSION } from "./per-language-bundles";
import * as setupCodeql from "./setup-codeql";
@@ -21,7 +22,6 @@ import * as tar from "./tar";
import {
LINKED_CLI_VERSION,
LoggedMessage,
RecordingLogger,
SAMPLE_DEFAULT_CLI_VERSION,
SAMPLE_DOTCOM_API_DETAILS,
checkExpectedLogMessages,
@@ -117,7 +117,7 @@ test.serial("convert to semver", (t) => {
try {
const parsedVersion = setupCodeql.convertToSemVer(
version,
new RecordingLogger(),
getRunnerLogger(true),
);
t.deepEqual(parsedVersion, expectedVersion);
} catch (e) {
@@ -145,7 +145,7 @@ test.serial(
GitHubVariant.DOTCOM,
false,
features,
new RecordingLogger(),
getRunnerLogger(true),
);
t.deepEqual(source, {
@@ -231,7 +231,7 @@ for (const {
GitHubVariant.DOTCOM,
tarSupportsZstd,
features,
new RecordingLogger(),
getRunnerLogger(true),
);
t.is(source.toolsVersion, LINKED_CLI_VERSION.cliVersion);
@@ -439,7 +439,7 @@ test.serial(
tmpDir,
GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
undefined, // rawLanguages
["javascript"],
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
features,
@@ -597,7 +597,7 @@ test.serial(
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
createFeatures([]),
new RecordingLogger(),
getRunnerLogger(true),
);
t.is(result.toolsVersion, "local");
@@ -633,8 +633,8 @@ for (const toolsInput of ["nightly", "nightly-latest"]) {
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
true, // tarSupportsZstd
createFeatures([]),
new RecordingLogger(),
createFeatures([Feature.PerLanguageBundles]),
getRunnerLogger(true),
);
t.deepEqual(source, {
@@ -664,16 +664,24 @@ test.serial(
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
for (const { languages, otherLanguagePacksReason } of [
for (const { languages, otherLanguagePacksReason, features } of [
// The per-language feature is disabled.
{
languages: ["java"],
otherLanguagePacksReason: undefined,
features: createFeatures([]),
},
// More than one language requires a combined bundle.
{
languages: ["java", "python"],
otherLanguagePacksReason: undefined,
features: createFeatures([Feature.PerLanguageBundles]),
},
// The configured queries may need library packs for other languages.
{
languages: ["java"],
otherLanguagePacksReason: "an example reason",
features: createFeatures([Feature.PerLanguageBundles]),
},
]) {
const source = await setupCodeql.getCodeQLSource(
@@ -685,8 +693,8 @@ test.serial(
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
true, // tarSupportsZstd
createFeatures([]),
new RecordingLogger(),
features,
getRunnerLogger(true),
);
t.is(source.sourceType, "download");
@@ -701,48 +709,58 @@ test.serial(
},
);
test.serial(
"getCodeQLSource uses the latest per-language bundle for a forced nightly",
async (t) => {
const expectedTag = "codeql-bundle-30260213";
const baseURL = `https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/${expectedTag}`;
const latestNightlyRequest = stubHostedNightly(expectedTag);
for (const perLanguageBundles of [false, true]) {
test.serial(
`getCodeQLSource uses the latest ${perLanguageBundles ? "per-language" : "combined"} bundle for a forced nightly`,
async (t) => {
const expectedTag = "codeql-bundle-30260213";
const baseURL = `https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/${expectedTag}`;
const latestNightlyRequest = stubHostedNightly(expectedTag);
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir, { GITHUB_EVENT_NAME: "dynamic" });
const source = await setupCodeql.getCodeQLSource(
undefined, // toolsInput: the nightly is selected by ForceNightly
SAMPLE_DEFAULT_CLI_VERSION,
["java"],
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
true, // tarSupportsZstd
createFeatures([Feature.ForceNightly]),
new RecordingLogger(),
);
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir, { GITHUB_EVENT_NAME: "dynamic" });
const source = await setupCodeql.getCodeQLSource(
undefined, // toolsInput: the nightly is selected by ForceNightly
SAMPLE_DEFAULT_CLI_VERSION,
["java"],
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
true, // tarSupportsZstd
createFeatures(
perLanguageBundles
? [Feature.ForceNightly, Feature.PerLanguageBundles]
: [Feature.ForceNightly],
),
getRunnerLogger(true),
);
t.is(source.sourceType, "download");
t.true(latestNightlyRequest.calledOnce);
if (source.sourceType === "download") {
t.deepEqual(source.bundle, {
kind: "per-language",
language: BuiltInLanguage.java,
url: `${baseURL}/codeql-bundle-java-linux64.tar.zst`,
combinedBundleURL: `${baseURL}/codeql-bundle-linux64.tar.zst`,
});
}
});
},
);
t.is(source.sourceType, "download");
t.true(latestNightlyRequest.calledOnce);
if (source.sourceType === "download") {
const combinedURL = `${baseURL}/codeql-bundle-linux64.tar.zst`;
t.deepEqual(
source.bundle,
perLanguageBundles
? {
kind: "per-language",
language: BuiltInLanguage.java,
url: `${baseURL}/codeql-bundle-java-linux64.tar.zst`,
combinedBundleURL: combinedURL,
}
: { kind: "combined", url: combinedURL },
);
}
});
},
);
}
for (const date of ["20200101", "30260213"]) {
for (const bundle of ["combined", "per-language"] as const) {
test.serial(
`getCodeQLSource preserves an explicit ${bundle} nightly URL for ${date}${
bundle === "per-language" ? " on GHES" : ""
}`,
`getCodeQLSource preserves an explicit ${bundle} nightly URL for ${date}`,
async (t) => {
const latestNightlyRequest = stubHostedNightly(
"codeql-bundle-30260213",
@@ -752,9 +770,7 @@ for (const date of ["20200101", "30260213"]) {
? "codeql-bundle-linux64.tar.zst"
: "codeql-bundle-java-linux64.tar.zst";
const url = `https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/codeql-bundle-${date}/${asset}`;
const features = createFeatures([]);
const variant =
bundle === "per-language" ? GitHubVariant.GHES : GitHubVariant.DOTCOM;
const features = createFeatures([Feature.PerLanguageBundles]);
const logger = getRecordingLogger([], { logToConsole: false });
const error = new HTTPError("Not Found", 404);
const extractStub = sinon
@@ -770,7 +786,7 @@ for (const date of ["20200101", "30260213"]) {
undefined, // otherLanguagePacksReason
false,
SAMPLE_DOTCOM_API_DETAILS,
variant,
GitHubVariant.DOTCOM,
true,
features,
logger,
@@ -792,7 +808,7 @@ for (const date of ["20200101", "30260213"]) {
url,
SAMPLE_DOTCOM_API_DETAILS,
tmpDir,
variant,
GitHubVariant.DOTCOM,
SAMPLE_DEFAULT_CLI_VERSION,
["java"],
undefined, // otherLanguagePacksReason
@@ -832,7 +848,7 @@ test.serial(
GitHubVariant.DOTCOM,
true,
createFeatures([]),
new RecordingLogger(),
getRunnerLogger(true),
),
{
message:
@@ -1004,7 +1020,7 @@ test.serial(
t.is(
setupCodeql.tryGetTagNameFromUrl(
"https://github.com/org/codeql-bundle-testing/releases/download/codeql-bundle-v2.19.0/codeql-bundle-linux64.tar.zst",
new RecordingLogger(),
getRunnerLogger(true),
),
"codeql-bundle-v2.19.0",
);
@@ -1016,7 +1032,7 @@ test.serial(
(t) => {
sinon.stub(toolcache, "findAllVersions").returns([]);
t.is(
setupCodeql.getLatestToolcacheVersion(new RecordingLogger()),
setupCodeql.getLatestToolcacheVersion(getRunnerLogger(true)),
undefined,
);
},
@@ -1028,7 +1044,7 @@ test.serial(
const testVersions = ["2.3.1", "3.2.1", "1.2.3"];
sinon.stub(toolcache, "findAllVersions").returns(testVersions);
t.is(setupCodeql.getLatestToolcacheVersion(new RecordingLogger()), "3.2.1");
t.is(setupCodeql.getLatestToolcacheVersion(getRunnerLogger(true)), "3.2.1");
},
);
@@ -1054,7 +1070,7 @@ async function fakeOverlayBaseCacheKey(
}
test.serial(
"getCodeQLSource uses overlay-aware default version for a Code Scanning PR",
"getCodeQLSource uses overlay-aware default version when requested for a PR",
async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -1081,8 +1097,8 @@ test.serial(
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
createFeatures([]),
new RecordingLogger(),
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]),
getRunnerLogger(true),
);
t.assert(listStub.calledOnce);
@@ -1093,95 +1109,7 @@ test.serial(
);
test.serial(
"getCodeQLSource skips the Actions cache when only one default version is enabled",
async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
process.env[EnvVar.CODE_SCANNING_REF] = "refs/heads/feature-branch";
process.env[EnvVar.CODE_SCANNING_BASE_BRANCH] = "main";
sinon.stub(api, "getAutomationID").resolves("test/");
const listStub = sinon.stub(api, "listActionsCaches").resolves([
{
key: await fakeOverlayBaseCacheKey(
"javascript",
SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion,
"abc-1-1",
),
},
]);
sinon
.stub(toolcache, "find")
.withArgs(
"CodeQL",
SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion,
)
.returns("/path/to/codeql");
const source = await setupCodeql.getCodeQLSource(
undefined,
SAMPLE_DEFAULT_CLI_VERSION,
["javascript"],
undefined, // otherLanguagePacksReason
true,
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
createFeatures([]),
new RecordingLogger(),
);
t.assert(listStub.notCalled);
t.is(source.sourceType, "toolcache");
t.is(
source.toolsVersion,
SAMPLE_DEFAULT_CLI_VERSION.enabledVersions[0].cliVersion,
);
});
},
);
test.serial(
"getCodeQLSource skips overlay-aware default version outside pull request analysis",
async (t) => {
sinon.stub(actionsUtil, "isAnalyzingPullRequest").returns(false);
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
sinon.stub(api, "getAutomationID").resolves("test/");
const listStub = sinon.stub(api, "listActionsCaches").resolves([
{
key: await fakeOverlayBaseCacheKey("javascript", "2.20.1", "abc-1-1"),
},
]);
sinon
.stub(toolcache, "find")
.withArgs("CodeQL", "2.20.2")
.returns("/path/to/codeql-2.20.2");
const source = await setupCodeql.getCodeQLSource(
undefined,
overlayMatchEnabledVersions,
["javascript"],
undefined, // otherLanguagePacksReason
true,
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
createFeatures([]),
new RecordingLogger(),
);
t.assert(listStub.notCalled);
t.is(source.sourceType, "toolcache");
t.is(source.toolsVersion, "2.20.2");
});
},
);
test.serial(
"getCodeQLSource skips overlay-aware default version when not requested for Code Scanning",
"getCodeQLSource skips overlay-aware default version when not requested",
async (t) => {
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -1208,8 +1136,8 @@ test.serial(
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
false,
createFeatures([]),
new RecordingLogger(),
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]),
getRunnerLogger(true),
);
t.assert(listStub.notCalled);
@@ -1246,8 +1174,8 @@ test.serial(
SAMPLE_DOTCOM_API_DETAILS,
GitHubVariant.DOTCOM,
true, // tarSupportsZstd
createFeatures([]),
new RecordingLogger(),
createFeatures([Feature.PerLanguageBundles]),
getRunnerLogger(true),
);
t.is(source.sourceType, "download");
@@ -1279,16 +1207,13 @@ test.serial(
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
for (const { otherLanguagePacksReason, variant } of [
// Automatic per-language selection is limited to GitHub.com.
{
otherLanguagePacksReason: undefined,
variant: GitHubVariant.GHES,
},
for (const { otherLanguagePacksReason, features } of [
// The per-language feature is disabled.
{ otherLanguagePacksReason: undefined, features: createFeatures([]) },
// The configured queries may need library packs for other languages.
{
otherLanguagePacksReason: "an example reason",
variant: GitHubVariant.DOTCOM,
features: createFeatures([Feature.PerLanguageBundles]),
},
]) {
const source = await setupCodeql.getCodeQLSource(
@@ -1298,10 +1223,10 @@ test.serial(
otherLanguagePacksReason,
false, // useOverlayAwareDefaultCliVersion
SAMPLE_DOTCOM_API_DETAILS,
variant,
GitHubVariant.DOTCOM,
true, // tarSupportsZstd
createFeatures([]),
new RecordingLogger(),
features,
getRunnerLogger(true),
);
t.is(source.sourceType, "download");
@@ -1370,8 +1295,8 @@ for (const fallback of [false, true]) {
["java"],
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
createFeatures([]),
new RecordingLogger(),
createFeatures([Feature.PerLanguageBundles]),
getRunnerLogger(true),
);
t.true(fetchRelease.calledTwice);
@@ -1450,7 +1375,7 @@ for (const bundle of ["per-language", "combined", "fallback"] as const) {
};
});
const addDiagnostic = sinon.stub(diagnostics, "addNoLanguageDiagnostic");
const features = createFeatures([]);
const features = createFeatures([Feature.PerLanguageBundles]);
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
@@ -1635,8 +1560,8 @@ for (const error of [
["java"],
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
createFeatures([]),
new RecordingLogger(),
createFeatures([Feature.PerLanguageBundles]),
getRunnerLogger(true),
),
{ is: error },
);
@@ -1672,7 +1597,7 @@ test.serial(
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
createFeatures([]),
new RecordingLogger(),
getRunnerLogger(true),
),
{ is: error },
);
@@ -1683,7 +1608,7 @@ test.serial(
);
test.serial(
"getEnabledVersionsWithOverlayBaseDatabases returns enabled versions present in cache, sorted desc",
"getEnabledVersionsWithOverlayBaseDatabases returns flag-enabled versions present in cache, sorted desc",
async (t) => {
sinon.stub(api, "getAutomationID").resolves("test/");
sinon.stub(api, "listActionsCaches").resolves([
@@ -1701,24 +1626,21 @@ test.serial(
},
]);
await withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
const result =
await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
["javascript"],
new RecordingLogger(),
);
t.deepEqual(result, [
{ cliVersion: "2.20.1", tagName: "codeql-bundle-v2.20.1" },
{ cliVersion: "2.20.0", tagName: "codeql-bundle-v2.20.0" },
]);
});
const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
["javascript"],
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]),
getRunnerLogger(true),
);
t.deepEqual(result, [
{ cliVersion: "2.20.1", tagName: "codeql-bundle-v2.20.1" },
{ cliVersion: "2.20.0", tagName: "codeql-bundle-v2.20.0" },
]);
},
);
test.serial(
"getEnabledVersionsWithOverlayBaseDatabases returns empty when no cached version is enabled",
"getEnabledVersionsWithOverlayBaseDatabases returns empty when no cached version is flag-enabled",
async (t) => {
sinon.stub(api, "getAutomationID").resolves("test/");
sinon.stub(api, "listActionsCaches").resolves([
@@ -1730,7 +1652,8 @@ test.serial(
const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
["javascript"],
new RecordingLogger(),
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]),
getRunnerLogger(true),
);
t.deepEqual(result, []);
},
@@ -1746,7 +1669,8 @@ const noLanguagesMacro = makeMacro({
const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
rawLanguages,
new RecordingLogger(),
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]),
getRunnerLogger(true),
);
t.deepEqual(result, []);
t.assert(
@@ -1770,7 +1694,8 @@ test.serial(
const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
["javascript"],
new RecordingLogger(),
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]),
getRunnerLogger(true),
);
t.deepEqual(result, []);
},
@@ -1789,7 +1714,8 @@ test.serial(
const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
["javascript"],
new RecordingLogger(),
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersion]),
getRunnerLogger(true),
);
t.deepEqual(result, [
{ cliVersion: "2.20.2", tagName: "codeql-bundle-v2.20.2" },
@@ -1797,6 +1723,78 @@ test.serial(
},
);
test.serial(
"getEnabledVersionsWithOverlayBaseDatabases does not list caches when both gates are off",
async (t) => {
const listStub = sinon.stub(api, "listActionsCaches").resolves([]);
const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
["javascript"],
createFeatures([]),
getRunnerLogger(true),
);
t.deepEqual(result, []);
t.assert(
listStub.notCalled,
"Should not list Actions caches when both gating feature flags are off.",
);
},
);
test.serial(
"getEnabledVersionsWithOverlayBaseDatabases dry-run returns empty but lists caches",
async (t) => {
sinon.stub(api, "getAutomationID").resolves("test/");
const listStub = sinon.stub(api, "listActionsCaches").resolves([
{
key: await fakeOverlayBaseCacheKey("javascript", "2.20.1", "abc-1-1"),
},
]);
const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
["javascript"],
createFeatures([Feature.OverlayAnalysisMatchCodeqlVersionDryRun]),
getRunnerLogger(true),
);
t.deepEqual(
result,
[],
"Dry-run should return an empty list so the caller falls back.",
);
t.assert(
listStub.calledOnce,
"Dry-run should still list Actions caches to populate the diagnostic.",
);
},
);
test.serial(
"getEnabledVersionsWithOverlayBaseDatabases match flag wins over dry-run",
async (t) => {
sinon.stub(api, "getAutomationID").resolves("test/");
sinon.stub(api, "listActionsCaches").resolves([
{
key: await fakeOverlayBaseCacheKey("javascript", "2.20.1", "abc-1-1"),
},
]);
const result = await setupCodeql.getEnabledVersionsWithOverlayBaseDatabases(
overlayMatchEnabledVersions,
["javascript"],
createFeatures([
Feature.OverlayAnalysisMatchCodeqlVersion,
Feature.OverlayAnalysisMatchCodeqlVersionDryRun,
]),
getRunnerLogger(true),
);
t.deepEqual(result, [
{ cliVersion: "2.20.1", tagName: "codeql-bundle-v2.20.1" },
]);
},
);
/** The CLI version that the toolcache cleanup tests download. */
const CLEANUP_CLI_VERSION = "2.21.0";
/** The bundle version that the toolcache cleanup tests download. */
@@ -2095,7 +2093,7 @@ test.serial(
env: new ReadOnlyEnv({
[ActionsEnvVars.RUNNER_TOOL_CACHE]: injectedRoot,
}),
logger: new RecordingLogger(),
logger: getRunnerLogger(true),
});
t.deepEqual(result, {
@@ -2250,7 +2248,7 @@ test.serial(
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
createFeatures([]),
new RecordingLogger(),
getRunnerLogger(true),
);
t.is(
@@ -2290,7 +2288,7 @@ test.serial(
undefined, // otherLanguagePacksReason
false, // useOverlayAwareDefaultCliVersion
createFeatures([]),
new RecordingLogger(),
getRunnerLogger(true),
),
{ is: error },
);
@@ -2405,7 +2403,7 @@ test.serial(
"isToolcacheOnWorkspaceFilesystem assumes a different filesystem when it cannot tell",
async (t) => {
await withTmpDir(async (tmpDir) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
setupActionsVars(tmpDir, tmpDir);
t.true(toolsDownload.isToolcacheOnWorkspaceFilesystem(logger));
+71 -22
View File
@@ -183,16 +183,29 @@ async function findOverridingToolsInCache(
/**
* Returns the sorted set of enabled versions that have cached overlay-base databases for the
* given languages.
* given languages, or an empty list if neither the `OverlayAnalysisMatchCodeqlVersion` nor the
* `OverlayAnalysisMatchCodeqlVersionDryRun` feature flag is enabled. When only the dry-run flag
* is enabled, this performs the lookup and emits a telemetry diagnostic with the version that
* would have been chosen, but still returns an empty list so the caller falls back.
*/
export async function getEnabledVersionsWithOverlayBaseDatabases(
defaultCliVersion: CodeQLDefaultVersionInfo,
rawLanguages: string[] | undefined,
features: FeatureEnablement,
logger: Logger,
): Promise<CodeQLVersionInfo[]> {
if (rawLanguages === undefined || rawLanguages.length === 0) {
return [];
}
const isEnabled = await features.getValue(
Feature.OverlayAnalysisMatchCodeqlVersion,
);
const isDryRun =
!isEnabled &&
(await features.getValue(Feature.OverlayAnalysisMatchCodeqlVersionDryRun));
if (!isEnabled && !isDryRun) {
return [];
}
let cachedVersions: string[] | undefined;
try {
@@ -213,35 +226,66 @@ export async function getEnabledVersionsWithOverlayBaseDatabases(
}
const cachedVersionsSet = new Set(cachedVersions);
return defaultCliVersion.enabledVersions.filter((v) =>
const overlayVersions = defaultCliVersion.enabledVersions.filter((v) =>
cachedVersionsSet.has(v.cliVersion),
);
if (overlayVersions.length === 0) {
return [];
}
const isCachedVersionDifferent =
overlayVersions[0].cliVersion !==
defaultCliVersion.enabledVersions[0].cliVersion;
if (isCachedVersionDifferent) {
addNoLanguageDiagnostic(
undefined,
makeTelemetryDiagnostic(
"codeql-action/overlay-aware-default-codeql-version",
"Overlay-aware default CodeQL version selection",
{
cachedVersions,
enabledVersions: defaultCliVersion.enabledVersions.map(
(v) => v.cliVersion,
),
isDryRun,
overlayAwareVersion: overlayVersions[0].cliVersion,
},
),
);
}
if (isDryRun) {
logger.debug(
`Overlay-aware default CodeQL version selection is running in dry-run mode. Would have used version ${overlayVersions[0].cliVersion}.`,
);
return [];
}
return overlayVersions;
}
/**
* Resolves the newest enabled default CLI version that has a cached overlay-base database for the
* relevant languages, if this is a Code Scanning analysis of a pull request, multiple default
* versions are enabled, and such a version exists. Otherwise, falls back to the newest enabled
* default CLI version.
* relevant languages, if running a Code Scanning analysis for a pull request and one exists.
* Otherwise, falls back to the newest enabled default CLI version.
*/
async function resolveDefaultCliVersion(
defaultCliVersion: CodeQLDefaultVersionInfo,
rawLanguages: string[] | undefined,
useOverlayAwareDefaultCliVersion: boolean,
features: FeatureEnablement,
logger: Logger,
): Promise<CodeQLVersionInfo> {
if (
!useOverlayAwareDefaultCliVersion ||
// Listing the Actions cache can't change which version we use if only one version is enabled.
defaultCliVersion.enabledVersions.length === 1 ||
!isAnalyzingPullRequest()
) {
if (!useOverlayAwareDefaultCliVersion || !isAnalyzingPullRequest()) {
return defaultCliVersion.enabledVersions[0];
}
const overlayVersions = await getEnabledVersionsWithOverlayBaseDatabases(
defaultCliVersion,
rawLanguages,
features,
logger,
);
if (overlayVersions.length > 0) {
@@ -364,7 +408,7 @@ export async function getCodeQLSource(
);
}
bundle = await getLatestNightlyBundle(
{ env: getEnv(), logger },
{ env: getEnv(), features, logger },
rawLanguages,
otherLanguagePacksReason,
variant,
@@ -438,6 +482,7 @@ export async function getCodeQLSource(
defaultCliVersion,
rawLanguages,
useOverlayAwareDefaultCliVersion,
features,
logger,
);
cliVersion = version.cliVersion;
@@ -460,6 +505,7 @@ export async function getCodeQLSource(
defaultCliVersion,
rawLanguages,
useOverlayAwareDefaultCliVersion,
features,
logger,
);
cliVersion = version.cliVersion;
@@ -605,14 +651,17 @@ export async function getCodeQLSource(
const action = { env: getEnv(), logger };
const platform = getBundlePlatform();
const perLanguageBundleLanguage = getPerLanguageBundleLanguage(action, {
rawLanguages,
otherLanguagePacksReason,
cliVersion,
compressionMethod,
platform,
variant,
});
const perLanguageBundleLanguage = await getPerLanguageBundleLanguage(
{ ...action, features },
{
rawLanguages,
otherLanguagePacksReason,
cliVersion,
compressionMethod,
platform,
variant,
},
);
// Resolves the combined or per-language bundle URL for the requested release.
const resolveBundleURL = (language?: BuiltInLanguage) =>
@@ -1040,7 +1089,7 @@ function getTempExtractionDir(tempDir: string) {
* Records the combined bundle URL from that release for use if the selected asset is missing.
*/
async function getLatestNightlyBundle(
action: ActionState<["Logger", "ReadOnlyEnv"]>,
action: ActionState<["Logger", "ReadOnlyEnv", "FeatureFlags"]>,
rawLanguages: string[] | undefined,
otherLanguagePacksReason: string | undefined,
variant: util.GitHubVariant,
@@ -1056,7 +1105,7 @@ async function getLatestNightlyBundle(
: "gzip";
const platform = getBundlePlatform();
const language = getPerLanguageBundleLanguage(action, {
const language = await getPerLanguageBundleLanguage(action, {
rawLanguages,
otherLanguagePacksReason,
cliVersion: undefined,
+20 -20
View File
@@ -13,7 +13,7 @@ import { setUpFeatureFlagTests } from "./feature-flags/testing-util";
import { UnvalidatedObject, validateSchema } from "./json";
import { makeFromSchema } from "./json/testing-util";
import { BuiltInLanguage } from "./languages";
import { Logger } from "./logging";
import { getRunnerLogger, Logger } from "./logging";
import { BundlePlatform, getBundlePlatform } from "./platform";
import * as repository from "./setup/repository";
import * as startProxyExports from "./start-proxy";
@@ -67,7 +67,7 @@ test("getCredentials prefers registriesCredentials over registrySecrets", async
]);
const credentials = startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
registrySecrets,
registryCredentials,
undefined,
@@ -84,7 +84,7 @@ test("getCredentials throws an error when configurations are not an array", asyn
t.throws(
() =>
startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
registryCredentials,
undefined,
@@ -103,7 +103,7 @@ test("getCredentials throws error when credential is not an object", async (t) =
t.throws(
() =>
startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
testCredential,
undefined,
@@ -124,7 +124,7 @@ test("getCredentials throws error when credential is missing type", async (t) =>
t.throws(
() =>
startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
testCredential,
undefined,
@@ -147,7 +147,7 @@ test("getCredentials throws error when credential missing host and url", async (
t.throws(
() =>
startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
testCredential,
undefined,
@@ -161,7 +161,7 @@ test("getCredentials throws error when credential missing host and url", async (
test("getCredentials filters by language when specified", async (t) => {
const credentials = startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
toEncodedJSON(mixedCredentials),
BuiltInLanguage.java,
@@ -172,7 +172,7 @@ test("getCredentials filters by language when specified", async (t) => {
test("getCredentials returns all for a language when specified", async (t) => {
const credentials = startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
toEncodedJSON([...mixedCredentials, gitSourceCredential]),
BuiltInLanguage.go,
@@ -192,7 +192,7 @@ test("getCredentials returns all goproxy_servers for Go when specified", async (
];
const credentials = startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
toEncodedJSON(multipleGoproxyServers),
BuiltInLanguage.go,
@@ -221,7 +221,7 @@ test("getCredentials returns all maven_repositories for Java when specified", as
];
const credentials = startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
toEncodedJSON(multipleMavenRepositories),
BuiltInLanguage.java,
@@ -239,7 +239,7 @@ test("getCredentials returns all credentials when no language specified", async
const credentialsInput = toEncodedJSON(mixedCredentials);
const credentials = startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
credentialsInput,
undefined,
@@ -269,7 +269,7 @@ test("getCredentials throws an error when non-printable characters are used", as
t.throws(
() =>
startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
credentialsInput,
undefined,
@@ -300,7 +300,7 @@ for (const oidcSchemaInfo of startProxyExports.oidcSchemas) {
t.throws(
() =>
startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
credentialsInput,
undefined,
@@ -324,7 +324,7 @@ test("getCredentials accepts OIDC configurations", (t) => {
);
const credentials = startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
toEncodedJSON(oidcConfigurations),
BuiltInLanguage.csharp,
@@ -514,7 +514,7 @@ test("getCredentials validates 'replaces-base' correctly", async (t) => {
]);
const credentials = startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
credentialsInput,
BuiltInLanguage.java,
@@ -533,7 +533,7 @@ test("getCredentials validates 'replaces-base' correctly", async (t) => {
};
t.throws(() =>
startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
toEncodedJSON([{ ...baseInvalid, "replaces-base": null }]),
BuiltInLanguage.java,
@@ -541,7 +541,7 @@ test("getCredentials validates 'replaces-base' correctly", async (t) => {
);
t.throws(() =>
startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
toEncodedJSON([{ ...baseInvalid, "replaces-base": 123 }]),
BuiltInLanguage.java,
@@ -549,7 +549,7 @@ test("getCredentials validates 'replaces-base' correctly", async (t) => {
);
t.throws(() =>
startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
toEncodedJSON([{ ...baseInvalid, "replaces-base": "true" }]),
BuiltInLanguage.java,
@@ -565,7 +565,7 @@ test("getCredentials returns only ALWAYS_ENABLED_REGISTRY_TYPE credentials for A
]);
const credentials = startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
credentialsInput,
BuiltInLanguage.actions,
@@ -597,7 +597,7 @@ test("getCredentials always returns ALWAYS_ENABLED_REGISTRY_TYPE credentials for
// Test all languages.
for (const language of Object.values(BuiltInLanguage)) {
const credentials = startProxyExports.getCredentials(
new RecordingLogger(),
getRunnerLogger(true),
undefined,
credentialsInput,
language,
+11 -10
View File
@@ -6,6 +6,7 @@ import * as actionsUtil from "./actions-util";
import { Config } from "./config-utils";
import { EnvVar, RegistryProxyVars } from "./environment";
import { BuiltInLanguage } from "./languages";
import { getRunnerLogger } from "./logging";
import { ToolsSource } from "./setup-codeql";
import type { Registry } from "./start-proxy";
import {
@@ -153,7 +154,7 @@ test.serial("createStatusReportBase", async (t) => {
languages: [BuiltInLanguage.java, BuiltInLanguage.swift],
}),
{ numAvailableBytes: 100, numTotalBytes: 500 },
new RecordingLogger(),
getRunnerLogger(false),
"failure cause",
"exception stack trace",
);
@@ -202,7 +203,7 @@ test.serial("createStatusReportBase - empty configuration", async (t) => {
new Date("May 19, 2023 05:19:00"),
{},
{ numAvailableBytes: 100, numTotalBytes: 500 },
new RecordingLogger(),
getRunnerLogger(false),
);
if (t.truthy(statusReport)) {
@@ -224,7 +225,7 @@ test.serial("createStatusReportBase - partial configuration", async (t) => {
languages: ["go"],
},
{ numAvailableBytes: 100, numTotalBytes: 500 },
new RecordingLogger(),
getRunnerLogger(false),
);
if (t.truthy(statusReport)) {
@@ -247,7 +248,7 @@ test.serial("createStatusReportBase_firstParty", async (t) => {
new Date("May 19, 2023 05:19:00"),
createTestConfig({}),
{ numAvailableBytes: 100, numTotalBytes: 500 },
new RecordingLogger(),
getRunnerLogger(false),
"failure cause",
"exception stack trace",
)
@@ -263,7 +264,7 @@ test.serial("createStatusReportBase_firstParty", async (t) => {
new Date("May 19, 2023 05:19:00"),
createTestConfig({}),
{ numAvailableBytes: 100, numTotalBytes: 500 },
new RecordingLogger(),
getRunnerLogger(false),
"failure cause",
"exception stack trace",
)
@@ -280,7 +281,7 @@ test.serial("createStatusReportBase_firstParty", async (t) => {
new Date("May 19, 2023 05:19:00"),
createTestConfig({}),
{ numAvailableBytes: 100, numTotalBytes: 500 },
new RecordingLogger(),
getRunnerLogger(false),
"failure cause",
"exception stack trace",
)
@@ -296,7 +297,7 @@ test.serial("createStatusReportBase_firstParty", async (t) => {
new Date("May 19, 2023 05:19:00"),
createTestConfig({}),
{ numAvailableBytes: 100, numTotalBytes: 500 },
new RecordingLogger(),
getRunnerLogger(false),
"failure cause",
"exception stack trace",
)
@@ -313,7 +314,7 @@ test.serial("createStatusReportBase_firstParty", async (t) => {
new Date("May 19, 2023 05:19:00"),
createTestConfig({}),
{ numAvailableBytes: 100, numTotalBytes: 500 },
new RecordingLogger(),
getRunnerLogger(false),
"failure cause",
"exception stack trace",
)
@@ -329,7 +330,7 @@ test.serial("createStatusReportBase_firstParty", async (t) => {
new Date("May 19, 2023 05:19:00"),
createTestConfig({}),
{ numAvailableBytes: 100, numTotalBytes: 500 },
new RecordingLogger(),
getRunnerLogger(false),
"failure cause",
"exception stack trace",
)
@@ -410,7 +411,7 @@ const testCreateInitWithConfigStatusReport = makeMacro({
new Date("May 19, 2023 05:19:00"),
config,
{ numAvailableBytes: 100, numTotalBytes: 500 },
new RecordingLogger(),
getRunnerLogger(false),
"failure cause",
"exception stack trace",
);
+3 -2
View File
@@ -3,8 +3,9 @@ import * as stream from "stream";
import test from "ava";
import { getRunnerLogger } from "./logging";
import { extractTarZst } from "./tar";
import { RecordingLogger, setupTests } from "./testing-utils";
import { setupTests } from "./testing-utils";
import { withTmpDir } from "./util";
setupTests(test);
@@ -16,7 +17,7 @@ test("extractTarZst rejects if the input stream errors", async (t) => {
archive,
path.join(tmpDir, "dest"),
{ type: "gnu", version: "1.34" },
new RecordingLogger(),
getRunnerLogger(true),
);
archive.destroy(
+8 -22
View File
@@ -30,7 +30,7 @@ import {
featureConfig,
FeatureEnablement,
} from "./feature-flags";
import { joinMessageStrings, Loggable, LoggableError, Logger } from "./logging";
import { Logger } from "./logging";
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
import { getBundlePlatform } from "./platform";
import { ActionName } from "./status-report";
@@ -658,13 +658,12 @@ export class RecordingLogger implements Logger {
constructor(private readonly logToConsole: boolean = true) {}
private addMessage(level: LogLevel, message: LoggableError): void {
const joinedMessage = joinMessageStrings(message);
this.messages.push({ type: level, message: joinedMessage });
private addMessage(level: LogLevel, message: string | Error): void {
this.messages.push({ type: level, message });
if (this.logToConsole) {
// eslint-disable-next-line no-console
console.debug(joinedMessage);
console.debug(message);
}
}
@@ -685,19 +684,19 @@ export class RecordingLogger implements Logger {
return true;
}
debug(message: Loggable) {
debug(message: string) {
this.addMessage("debug", message);
}
info(message: Loggable) {
info(message: string) {
this.addMessage("info", message);
}
warning(message: LoggableError) {
warning(message: string | Error) {
this.addMessage("warning", message);
}
error(message: LoggableError) {
error(message: string | Error) {
this.addMessage("error", message);
}
@@ -1032,7 +1031,6 @@ export function createTestConfig(overrides: Partial<Config>): Config {
overlayModeSetExplicitly: false,
repositoryProperties: {},
enableFileCoverageInformation: true,
successfullyInitialised: false,
} satisfies Config,
overrides,
);
@@ -1043,15 +1041,3 @@ export function makeTestToken(length: number = 36) {
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return chars.repeat(Math.ceil(length / chars.length)).slice(0, length);
}
/**
* Get a real, newly created CodeQL instance for testing. The instance refers to
* a non-existent placeholder codeql command, so tests that use this function
* should also stub the toolrunner.ToolRunner constructor.
*/
export async function getCodeQLForTesting(
cmd = "codeql-for-testing",
logger: Logger = new RecordingLogger(),
): Promise<codeql.CodeQL> {
return codeql.getCodeQLForCmd(logger, cmd, false);
}
+8 -7
View File
@@ -10,8 +10,9 @@ import { https } from "follow-redirects";
import nock from "nock";
import * as sinon from "sinon";
import { getRunnerLogger } from "./logging";
import * as tar from "./tar";
import { RecordingLogger, setupTests } from "./testing-utils";
import { setupTests } from "./testing-utils";
import { downloadAndExtract } from "./tools-download";
import * as util from "./util";
@@ -33,7 +34,7 @@ test.serial(
undefined,
{},
undefined,
new RecordingLogger(),
getRunnerLogger(true),
);
t.assert(Number.isInteger(statusReport.downloadDurationMs));
@@ -71,7 +72,7 @@ test.serial(
undefined,
{},
{ type: "gnu", version: "1.34" },
new RecordingLogger(),
getRunnerLogger(true),
);
t.assert(Number.isInteger(statusReport.downloadDurationMs));
@@ -104,7 +105,7 @@ test.serial(
undefined,
{},
{ type: "gnu", version: "1.34" },
new RecordingLogger(),
getRunnerLogger(true),
),
{
instanceOf: util.HTTPError,
@@ -148,7 +149,7 @@ test.serial(
undefined,
{},
{ type: "gnu", version: "1.34" },
new RecordingLogger(),
getRunnerLogger(true),
);
t.assert(Number.isInteger(statusReport.downloadDurationMs));
@@ -188,7 +189,7 @@ test.serial(
undefined,
{},
{ type: "gnu", version: "1.34" },
new RecordingLogger(),
getRunnerLogger(true),
);
t.is(
@@ -236,7 +237,7 @@ test.serial(
undefined,
{},
{ type: "gnu", version: "1.34" },
new RecordingLogger(),
getRunnerLogger(true),
);
t.assert(Number.isInteger(statusReport.totalDurationMs));
+1 -2
View File
@@ -4,12 +4,11 @@ import * as path from "path";
import test from "ava";
import * as sinon from "sinon";
import type { CodeQL } from "./codeql";
import { CodeQL, getCodeQLForTesting } from "./codeql";
import * as configUtils from "./config-utils";
import { BuiltInLanguage } from "./languages";
import {
createTestConfig,
getCodeQLForTesting,
makeVersionInfo,
RecordingLogger,
setupTests,
+83 -24
View File
@@ -6,26 +6,29 @@ import test from "ava";
import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import * as apiClient from "./api-client";
import {
getTrapCachingExtractorConfigArgs,
getTrapCachingExtractorConfigArgsForLang,
createStubCodeQL,
} from "./codeql";
import * as configUtils from "./config-utils";
import { Feature } from "./feature-flags";
import * as gitUtils from "./git-utils";
import { BuiltInLanguage } from "./languages";
import { getRunnerLogger } from "./logging";
import {
callee,
createFeatures,
createTestConfig,
getRecordingLogger,
makeVersionInfo,
setupTests,
} from "./testing-utils";
import {
cleanupTrapCaches,
downloadTrapCaches,
getLanguagesSupportingCaching,
uploadTrapCaches,
warnIfTrapCacheCleanupEnvVarIsSet,
} from "./trap-caching";
import * as util from "./util";
@@ -197,27 +200,83 @@ test.serial(
},
);
// `CODEQL_ACTION_CLEANUP_TRAP_CACHES` has no effect with either value, so we warn even when it's
// set to `false`.
for (const value of ["true", "false"]) {
test(`warnIfTrapCacheCleanupEnvVarIsSet warns when CODEQL_ACTION_CLEANUP_TRAP_CACHES is '${value}'`, async (t) => {
const target = callee(warnIfTrapCacheCleanupEnvVarIsSet)
.withEnv((env) => env.set("CODEQL_ACTION_CLEANUP_TRAP_CACHES", value))
.withArgs()
.logs(
t,
"CODEQL_ACTION_CLEANUP_TRAP_CACHES environment variable no longer has any effect",
);
await target.passes(t.is, undefined);
t.deepEqual(
target.getLogger().messages.map((m) => m.type),
["warning"],
);
});
}
test.serial("cleanup removes only old CodeQL TRAP caches", async (t) => {
await util.withTmpDir(async (tmpDir) => {
// This config specifies that we are analyzing JavaScript and Ruby, but not Swift.
const config = getTestConfigWithTempDir(tmpDir);
test("warnIfTrapCacheCleanupEnvVarIsSet doesn't warn when CODEQL_ACTION_CLEANUP_TRAP_CACHES is unset", async (t) => {
const target = callee(warnIfTrapCacheCleanupEnvVarIsSet).withArgs();
await target.passes(t.is, undefined);
t.deepEqual(target.getLogger().messages, []);
sinon.stub(gitUtils, "getRef").resolves("refs/heads/main");
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
const listStub = sinon.stub(apiClient, "listActionsCaches").resolves([
// Should be kept, since it's not relevant to CodeQL. In reality, the API shouldn't return
// this in the first place, but this is a defensive check.
{
id: 1,
key: "some-other-key",
created_at: "2024-05-23T14:25:00Z",
size_in_bytes: 100 * 1024 * 1024,
},
// Should be kept, since it's the newest TRAP cache for JavaScript
{
id: 2,
key: "codeql-trap-1-2.0.0-javascript-newest",
created_at: "2024-04-23T14:25:00Z",
size_in_bytes: 50 * 1024 * 1024,
},
// Should be cleaned up
{
id: 3,
key: "codeql-trap-1-2.0.0-javascript-older",
created_at: "2024-03-22T14:25:00Z",
size_in_bytes: 200 * 1024 * 1024,
},
// Should be cleaned up
{
id: 4,
key: "codeql-trap-1-2.0.0-javascript-oldest",
created_at: "2024-02-21T14:25:00Z",
size_in_bytes: 300 * 1024 * 1024,
},
// Should be kept, since it's the newest TRAP cache for Ruby
{
id: 5,
key: "codeql-trap-1-2.0.0-ruby-newest",
created_at: "2024-02-20T14:25:00Z",
size_in_bytes: 300 * 1024 * 1024,
},
// Should be kept, since we aren't analyzing Swift
{
id: 6,
key: "codeql-trap-1-2.0.0-swift-newest",
created_at: "2024-02-22T14:25:00Z",
size_in_bytes: 300 * 1024 * 1024,
},
// Should be kept, since we aren't analyzing Swift
{
id: 7,
key: "codeql-trap-1-2.0.0-swift-older",
created_at: "2024-02-21T14:25:00Z",
size_in_bytes: 300 * 1024 * 1024,
},
]);
const deleteStub = sinon.stub(apiClient, "deleteActionsCache").resolves();
const statusReport = await cleanupTrapCaches(
config,
createFeatures([Feature.CleanupTrapCaches]),
getRunnerLogger(true),
);
t.is(listStub.callCount, 1);
t.assert(listStub.calledWithExactly("codeql-trap", "refs/heads/main"));
t.deepEqual(statusReport, {
trap_cache_cleanup_size_bytes: 500 * 1024 * 1024,
});
t.is(deleteStub.callCount, 2);
t.assert(deleteStub.calledWithExactly(3));
t.assert(deleteStub.calledWithExactly(4));
});
});
+114 -18
View File
@@ -3,14 +3,22 @@ import * as path from "path";
import * as actionsCache from "@actions/cache";
import { type ActionState } from "./action-common";
import * as actionsUtil from "./actions-util";
import * as apiClient from "./api-client";
import { type CodeQL } from "./codeql";
import { type Config } from "./config-utils";
import { DocUrl } from "./doc-url";
import { Feature, FeatureEnablement } from "./feature-flags";
import * as gitUtils from "./git-utils";
import { Language } from "./languages";
import { Logger } from "./logging";
import { getEnv, tryGetFolderBytes, waitForResultWithTimeLimit } from "./util";
import {
asHTTPError,
getEnv,
getErrorMessage,
tryGetFolderBytes,
waitForResultWithTimeLimit,
} from "./util";
// This constant should be bumped if we make a breaking change
// to how the CodeQL Action stores or retrieves the TRAP cache,
@@ -170,23 +178,111 @@ export async function uploadTrapCaches(
return true;
}
/**
* Warns if the `CODEQL_ACTION_CLEANUP_TRAP_CACHES` environment variable is set to a non-empty
* value. That variable controlled the removed TRAP cache cleanup feature, so setting it has no
* effect.
*/
export function warnIfTrapCacheCleanupEnvVarIsSet({
env,
logger,
}: ActionState<["Logger", "ReadOnlyEnv"]>): void {
if (env.getOptional("CODEQL_ACTION_CLEANUP_TRAP_CACHES") !== undefined) {
logger.warning(
"TRAP cache cleanup has been removed, so the CODEQL_ACTION_CLEANUP_TRAP_CACHES environment " +
"variable no longer has any effect and can be removed from your workflow. If you used TRAP " +
"cache cleanup to limit Actions cache usage, we recommend disabling TRAP caching instead by " +
"passing the `trap-caching: false` input to the `init` Action.",
);
export interface TrapCacheCleanupStatusReport {
trap_cache_cleanup_error?: string;
trap_cache_cleanup_size_bytes?: number;
trap_cache_cleanup_skipped_because?: string;
}
export async function cleanupTrapCaches(
config: Config,
features: FeatureEnablement,
logger: Logger,
): Promise<TrapCacheCleanupStatusReport> {
const env = getEnv();
if (!(await features.getValue(Feature.CleanupTrapCaches))) {
return {
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(env, config.repositoryRoot))) {
return {
trap_cache_cleanup_skipped_because: "not analyzing default branch",
};
}
try {
let totalBytesCleanedUp = 0;
const allCaches = await apiClient.listActionsCaches(
CODEQL_TRAP_CACHE_PREFIX,
await gitUtils.getRef(env, config.repositoryRoot),
);
for (const language of config.languages) {
if (config.trapCaches[language]) {
const cachesToRemove = await getTrapCachesForLanguage(
allCaches,
language,
logger,
);
// Dates returned by the API are in ISO 8601 format, so we can sort them lexicographically
cachesToRemove.sort((a, b) => a.created_at.localeCompare(b.created_at));
// Keep the most recent cache
const mostRecentCache = cachesToRemove.pop();
logger.debug(
`Keeping most recent TRAP cache (${JSON.stringify(mostRecentCache)})`,
);
if (cachesToRemove.length === 0) {
logger.info(`No TRAP caches to clean up for ${language}.`);
continue;
}
for (const cache of cachesToRemove) {
logger.debug(`Cleaning up TRAP cache (${JSON.stringify(cache)})`);
await apiClient.deleteActionsCache(cache.id);
}
const bytesCleanedUp = cachesToRemove.reduce(
(acc, item) => acc + item.size_in_bytes,
0,
);
totalBytesCleanedUp += bytesCleanedUp;
const megabytesCleanedUp = (bytesCleanedUp / (1024 * 1024)).toFixed(2);
logger.info(
`Cleaned up ${megabytesCleanedUp} MiB of old TRAP caches for ${language}.`,
);
}
}
return { trap_cache_cleanup_size_bytes: totalBytesCleanedUp };
} catch (e) {
if (asHTTPError(e)?.status === 403) {
logger.warning(
"Could not cleanup TRAP caches as the token did not have the required permissions. " +
'To clean up TRAP caches, ensure the token has the "actions:write" permission. ' +
`See ${DocUrl.ASSIGNING_PERMISSIONS_TO_JOBS} for more information.`,
);
} else {
logger.info(`Failed to cleanup TRAP caches, continuing. Details: ${e}`);
}
return { trap_cache_cleanup_error: getErrorMessage(e) };
}
}
async function getTrapCachesForLanguage(
allCaches: apiClient.ActionsCacheItem[],
language: Language,
logger: Logger,
): Promise<Array<Required<apiClient.ActionsCacheItem>>> {
logger.debug(`Listing TRAP caches for ${language}`);
for (const cache of allCaches) {
if (!cache.created_at || !cache.id || !cache.key || !cache.size_in_bytes) {
throw new Error(
"An unexpected cache item was returned from the API that was missing one or " +
`more required fields: ${JSON.stringify(cache)}`,
);
}
}
return allCaches.filter((cache) => {
return cache.key?.includes(`-${language}-`);
}) as Array<Required<apiClient.ActionsCacheItem>>;
}
export async function getLanguagesSupportingCaching(
+11 -11
View File
@@ -10,9 +10,9 @@ import * as analyses from "./analyses";
import { AnalysisKind, CodeQuality, CodeScanning } from "./analyses";
import * as api from "./api-client";
import * as diffUtils from "./diff-informed-analysis-utils";
import { Logger } from "./logging";
import { getRunnerLogger, Logger } from "./logging";
import * as sarif from "./sarif";
import { RecordingLogger, setupTests } from "./testing-utils";
import { setupTests } from "./testing-utils";
import * as uploadLib from "./upload-lib";
import { UploadPayload } from "./upload-lib/types";
import { GitHubVariant, initializeEnvironment, withTmpDir } from "./util";
@@ -29,7 +29,7 @@ test.serial("validateSarifFileSchema - valid", (t) => {
uploadLib.validateSarifFileSchema(
uploadLib.readSarifFileOrThrow(inputFile),
inputFile,
new RecordingLogger(),
getRunnerLogger(true),
),
);
});
@@ -40,7 +40,7 @@ test.serial("validateSarifFileSchema - invalid", (t) => {
uploadLib.validateSarifFileSchema(
uploadLib.readSarifFileOrThrow(inputFile),
inputFile,
new RecordingLogger(),
getRunnerLogger(true),
),
);
});
@@ -179,7 +179,7 @@ test.serial("finding SARIF files", async (t) => {
}
const groupedSarifFiles = await uploadLib.getGroupedSarifFilePaths(
new RecordingLogger(),
getRunnerLogger(true),
tmpDir,
);
@@ -200,7 +200,7 @@ test.serial("getGroupedSarifFilePaths - Risk Assessment files", async (t) => {
fs.writeFileSync(sarifPath, "");
const groupedSarifFiles = await uploadLib.getGroupedSarifFilePaths(
new RecordingLogger(),
getRunnerLogger(true),
sarifPath,
);
@@ -218,7 +218,7 @@ test.serial("getGroupedSarifFilePaths - Code Quality file", async (t) => {
fs.writeFileSync(sarifPath, "");
const groupedSarifFiles = await uploadLib.getGroupedSarifFilePaths(
new RecordingLogger(),
getRunnerLogger(true),
sarifPath,
);
@@ -236,7 +236,7 @@ test.serial("getGroupedSarifFilePaths - Code Scanning file", async (t) => {
fs.writeFileSync(sarifPath, "");
const groupedSarifFiles = await uploadLib.getGroupedSarifFilePaths(
new RecordingLogger(),
getRunnerLogger(true),
sarifPath,
);
@@ -254,7 +254,7 @@ test.serial("getGroupedSarifFilePaths - Other file", async (t) => {
fs.writeFileSync(sarifPath, "");
const groupedSarifFiles = await uploadLib.getGroupedSarifFilePaths(
new RecordingLogger(),
getRunnerLogger(true),
sarifPath,
);
@@ -932,7 +932,7 @@ function uploadPayloadFixtures(analysis: analyses.AnalysisConfig) {
owner: mockData.owner,
repo: mockData.repo,
},
new RecordingLogger(),
getRunnerLogger(true),
analysis,
);
@@ -1019,7 +1019,7 @@ function runFilterAlertsByDiffRange(
diffRanges: diffUtils.DiffThunkRange[],
): Partial<sarif.Log> {
sinon.stub(diffUtils, "readDiffRangesJsonFile").returns(diffRanges);
return uploadLib.filterAlertsByDiffRange(new RecordingLogger(), input);
return uploadLib.filterAlertsByDiffRange(getRunnerLogger(true), input);
}
test.serial(
+5 -9
View File
@@ -5,12 +5,8 @@ import test, { ExecutionContext } from "ava";
import * as sinon from "sinon";
import { AnalysisKind, getAnalysisConfig } from "./analyses";
import {
createFeatures,
makeMacro,
RecordingLogger,
setupTests,
} from "./testing-utils";
import { getRunnerLogger } from "./logging";
import { createFeatures, makeMacro, setupTests } from "./testing-utils";
import { UploadResult } from "./upload-lib";
import * as uploadLib from "./upload-lib";
import { postProcessAndUploadSarif } from "./upload-sarif";
@@ -56,7 +52,7 @@ const postProcessAndUploadSarifMacro = makeMacro({
expectedResult: Partial<Record<AnalysisKind, UploadSarifExpectedResult>>,
) => {
await util.withTmpDir(async (tempDir) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const testPath = sarifPath(tempDir);
const features = createFeatures([]);
@@ -214,7 +210,7 @@ test.serial(
"postProcessAndUploadSarif doesn't upload if upload is disabled",
async (t) => {
await util.withTmpDir(async (tempDir) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const features = createFeatures([]);
const toFullPath = (filename: string) => path.join(tempDir, filename);
@@ -248,7 +244,7 @@ test.serial(
"postProcessAndUploadSarif writes post-processed SARIF files if output directory is provided",
async (t) => {
await util.withTmpDir(async (tempDir) => {
const logger = new RecordingLogger();
const logger = getRunnerLogger(true);
const features = createFeatures([]);
const toFullPath = (filename: string) => path.join(tempDir, filename);
+9 -8
View File
@@ -10,7 +10,8 @@ import * as sinon from "sinon";
import * as api from "./api-client";
import { EnvVar } from "./environment";
import { RecordingLogger, setupTests, getTestEnv } from "./testing-utils";
import { getRunnerLogger } from "./logging";
import { getTestEnv, setupTests } from "./testing-utils";
import * as util from "./util";
setupTests(test);
@@ -91,7 +92,7 @@ for (const {
test("getMemoryFlag() throws if the ram input is < 0 or NaN", async (t) => {
for (const input of ["-1", "hello!"]) {
t.throws(() => util.getMemoryFlag(input, new RecordingLogger()));
t.throws(() => util.getMemoryFlag(input, getRunnerLogger(true)));
}
});
@@ -108,13 +109,13 @@ test("getThreadsFlag() should return the correct --threads flag", (t) => {
];
for (const [input, expectedFlag] of tests) {
const flag = util.getThreadsFlag(input, new RecordingLogger());
const flag = util.getThreadsFlag(input, getRunnerLogger(true));
t.deepEqual(flag, expectedFlag);
}
});
test("getThreadsFlag() throws if the threads input is not an integer", (t) => {
t.throws(() => util.getThreadsFlag("hello!", new RecordingLogger()));
t.throws(() => util.getThreadsFlag("hello!", getRunnerLogger(true)));
});
test.serial(
@@ -384,7 +385,7 @@ test("getCgroupCpuCountFromCpus calculates the number of CPUs correctly", async
const testCpuFile = `${tmpDir}/cpus-file`;
fs.writeFileSync(testCpuFile, "1, 9-10\n", "utf-8");
t.deepEqual(
util.getCgroupCpuCountFromCpus(testCpuFile, new RecordingLogger()),
util.getCgroupCpuCountFromCpus(testCpuFile, getRunnerLogger(true)),
3,
);
});
@@ -395,7 +396,7 @@ test("getCgroupCpuCountFromCpus returns undefined if the CPU file doesn't exist"
const testCpuFile = `${tmpDir}/cpus-file`;
t.false(fs.existsSync(testCpuFile));
t.deepEqual(
util.getCgroupCpuCountFromCpus(testCpuFile, new RecordingLogger()),
util.getCgroupCpuCountFromCpus(testCpuFile, getRunnerLogger(true)),
undefined,
);
});
@@ -406,7 +407,7 @@ test("getCgroupCpuCountFromCpus returns undefined if the CPU file exists but is
const testCpuFile = `${tmpDir}/cpus-file`;
fs.writeFileSync(testCpuFile, "\n", "utf-8");
t.deepEqual(
util.getCgroupCpuCountFromCpus(testCpuFile, new RecordingLogger()),
util.getCgroupCpuCountFromCpus(testCpuFile, getRunnerLogger(true)),
undefined,
);
});
@@ -416,7 +417,7 @@ test.serial(
"checkDiskUsage succeeds and produces positive numbers",
async (t) => {
process.env["GITHUB_WORKSPACE"] = os.tmpdir();
const diskUsage = await util.checkDiskUsage(new RecordingLogger());
const diskUsage = await util.checkDiskUsage(getRunnerLogger(true));
if (t.truthy(diskUsage)) {
t.true(diskUsage.numAvailableBytes > 0);
t.true(diskUsage.numTotalBytes > 0);
-15
View File
@@ -900,21 +900,6 @@ export function getErrorMessage(error: unknown): string {
return error instanceof Error ? error.message : String(error);
}
/**
* Approximates whether {@link error} is like a {@link NodeJS.ErrnoException}.
* We only typically care about the `code` property, so that's what we check for here.
*/
export function isErrnoException(
error: unknown,
): error is NodeJS.ErrnoException {
return (
typeof error === "object" &&
error !== null &&
"code" in error &&
typeof error.code === "string"
);
}
export function prettyPrintPack(pack: Pack) {
return `${pack.name}${pack.version ? `@${pack.version}` : ""}${
pack.path ? `:${pack.path}` : ""
+1 -2
View File
@@ -3,11 +3,10 @@ import * as yaml from "js-yaml";
import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import { createStubCodeQL } from "./codeql";
import { createStubCodeQL, getCodeQLForTesting } from "./codeql";
import { ActionsEnvVars, EnvVar } from "./environment";
import {
checkExpectedLogMessages,
getCodeQLForTesting,
createTestConfig,
getRecordingLogger,
getTestEnv,
+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-entry.js"
post: "../lib/start-proxy-post-entry.js"
@@ -1 +0,0 @@
- The undocumented TRAP cache cleanup feature that could be enabled using the `CODEQL_ACTION_CLEANUP_TRAP_CACHES` environment variable has been removed, as announced in the release notes for CodeQL Action 4.35.2. The `analyze` Action now warns if this environment variable is set. If you used TRAP cache cleanup to limit Actions cache usage, we recommend disabling TRAP caching by passing the `trap-caching: false` input to the `init` Action. [#4243](https://github.com/github/codeql-action/pull/4243)
+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-entry.js'
post: '../lib/upload-sarif-post-entry.js'