Compare commits

..

24 Commits

Author SHA1 Message Date
Michael B. Gale 25599b3fc8 Use doc.toString rather than yaml.stringify 2026-03-09 14:29:04 +00:00
Michael B. Gale 639dddc728 Add missing newline at the end of action-versions.ts 2026-03-09 14:29:04 +00:00
Michael B. Gale 0b27c71731 Generate and use action-versions.ts 2026-03-07 00:29:11 +00:00
Michael B. Gale 6679b049d5 Generate separate TS file with version mappings 2026-03-07 00:24:18 +00:00
Michael B. Gale 13e47f85a5 Type options and add --force option 2026-03-07 00:24:17 +00:00
Michael B. Gale 5f152be4c2 Minor adjustments to PR check templates
These are needed to render them correctly in `sync_back.ts`
2026-03-06 23:40:49 +00:00
Michael B. Gale f4b6bd982f Parse/render YAML documents for sync_back.ts 2026-03-06 19:56:16 +00:00
Óscar San José d1a65275e8 Merge pull request #3552 from github/mergeback/v4.32.6-to-main-0d579ffd
Mergeback v4.32.6 refs/heads/releases/v4 into main
2026-03-06 10:03:43 +00:00
github-actions[bot] 0ccdcb8c0a Rebuild 2026-03-05 19:44:36 +00:00
github-actions[bot] 05a48207b3 Update changelog and version after v4.32.6 2026-03-05 19:33:19 +00:00
Óscar San José 0d579ffd05 Merge pull request #3551 from github/update-v4.32.6-72d2d850d
Merge main into releases/v4
2026-03-05 20:29:07 +01:00
github-actions[bot] d4c6be7cf1 Update changelog for v4.32.6 2026-03-05 18:58:14 +00:00
Óscar San José 72d2d850d1 Merge pull request #3548 from github/update-bundle/codeql-bundle-v2.24.3
Update default bundle to 2.24.3
2026-03-05 16:02:55 +00:00
Michael B. Gale 23f983ce00 Merge pull request #3544 from github/dependabot/github_actions/dot-github/workflows/actions/download-artifact-8
Bump actions/download-artifact from 7 to 8 in /.github/workflows
2026-03-05 15:54:50 +00:00
Michael B. Gale 832e97ccad Merge pull request #3545 from github/dependabot/github_actions/dot-github/workflows/actions/upload-artifact-7
Bump actions/upload-artifact from 6 to 7 in /.github/workflows
2026-03-05 15:52:06 +00:00
Michael B. Gale 5ef38c0b13 Merge pull request #3546 from github/dependabot/npm_and_yarn/tar-7.5.10
Bump tar from 7.5.7 to 7.5.10
2026-03-05 15:48:25 +00:00
github-actions[bot] 80c9cda739 Add changelog note 2026-03-05 15:34:29 +00:00
github-actions[bot] f2669dd916 Update default bundle to codeql-bundle-v2.24.3 2026-03-05 15:34:19 +00:00
Michael B. Gale bd03c44cf4 Merge branch 'main' into dependabot/github_actions/dot-github/workflows/actions/download-artifact-8 2026-03-05 15:32:00 +00:00
dependabot[bot] 102d7627b6 Bump tar from 7.5.7 to 7.5.10
Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.7 to 7.5.10.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.7...v7.5.10)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.10
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-05 14:47:50 +00:00
github-actions[bot] e96635d9ff Rebuild 2026-03-05 13:19:38 +00:00
github-actions[bot] e681b9fb11 Merge remote-tracking branch 'origin/main' into dependabot/github_actions/dot-github/workflows/actions/upload-artifact-7 2026-03-05 13:18:44 +00:00
dependabot[bot] 31d26f2397 Bump actions/upload-artifact from 6 to 7 in /.github/workflows
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 18:01:17 +00:00
dependabot[bot] 4d433615e7 Bump actions/download-artifact from 7 to 8 in /.github/workflows
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 18:00:15 +00:00
38 changed files with 353 additions and 231 deletions
+2 -2
View File
@@ -92,7 +92,7 @@ jobs:
post-processed-sarif-path: '${{ runner.temp }}/post-processed'
- name: Upload SARIF files
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: |
analysis-kinds-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}
@@ -100,7 +100,7 @@ jobs:
retention-days: 7
- name: Upload post-processed SARIF
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: |
post-processed-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}
+1 -1
View File
@@ -82,7 +82,7 @@ jobs:
output: ${{ runner.temp }}/results
upload-database: false
- name: Upload SARIF
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.os }}-zstd-bundle.sarif
path: ${{ runner.temp }}/results/javascript.sarif
+1 -1
View File
@@ -70,7 +70,7 @@ jobs:
output: '${{ runner.temp }}/results'
upload-database: false
- name: Upload SARIF
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: config-export-${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: '${{ runner.temp }}/results/javascript.sarif'
+1 -1
View File
@@ -81,7 +81,7 @@ jobs:
output: '${{ runner.temp }}/results'
upload-database: false
- name: Upload SARIF
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: diagnostics-export-${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: '${{ runner.temp }}/results/javascript.sarif'
+1 -1
View File
@@ -102,7 +102,7 @@ jobs:
with:
output: '${{ runner.temp }}/results'
- name: Upload SARIF
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: with-baseline-information-${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: '${{ runner.temp }}/results/javascript.sarif'
+1 -1
View File
@@ -67,7 +67,7 @@ jobs:
with:
output: '${{ runner.temp }}/results'
- name: Upload SARIF
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: '${{ runner.temp }}/results/javascript.sarif'
@@ -89,7 +89,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
- name: Check expected artifacts exist
run: |
LANGUAGES="cpp csharp go java javascript python"
+1 -1
View File
@@ -83,7 +83,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v7
uses: actions/download-artifact@v8
- name: Check expected artifacts exist
run: |
VERSIONS="stable-v2.20.3 default linked nightly-latest"
+4
View File
@@ -6,6 +6,10 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th
No user facing changes.
## 4.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
- 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)
+1 -1
View File
@@ -45986,7 +45986,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.32.6",
version: "4.32.7",
private: true,
description: "CodeQL action",
scripts: {
+3 -3
View File
@@ -45986,7 +45986,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.32.6",
version: "4.32.7",
private: true,
description: "CodeQL action",
scripts: {
@@ -107350,8 +107350,8 @@ var path5 = __toESM(require("path"));
var semver5 = __toESM(require_semver2());
// src/defaults.json
var bundleVersion = "codeql-bundle-v2.24.2";
var cliVersion = "2.24.2";
var bundleVersion = "codeql-bundle-v2.24.3";
var cliVersion = "2.24.3";
// src/overlay/index.ts
var fs3 = __toESM(require("fs"));
+3 -3
View File
@@ -45986,7 +45986,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.32.6",
version: "4.32.7",
private: true,
description: "CodeQL action",
scripts: {
@@ -103820,8 +103820,8 @@ var path3 = __toESM(require("path"));
var semver5 = __toESM(require_semver2());
// src/defaults.json
var bundleVersion = "codeql-bundle-v2.24.2";
var cliVersion = "2.24.2";
var bundleVersion = "codeql-bundle-v2.24.3";
var cliVersion = "2.24.3";
// src/overlay/index.ts
var fs2 = __toESM(require("fs"));
+4 -4
View File
@@ -1,6 +1,6 @@
{
"bundleVersion": "codeql-bundle-v2.24.2",
"cliVersion": "2.24.2",
"priorBundleVersion": "codeql-bundle-v2.24.1",
"priorCliVersion": "2.24.1"
"bundleVersion": "codeql-bundle-v2.24.3",
"cliVersion": "2.24.3",
"priorBundleVersion": "codeql-bundle-v2.24.2",
"priorCliVersion": "2.24.2"
}
+3 -3
View File
@@ -45986,7 +45986,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.32.6",
version: "4.32.7",
private: true,
description: "CodeQL action",
scripts: {
@@ -165218,8 +165218,8 @@ var path5 = __toESM(require("path"));
var semver5 = __toESM(require_semver2());
// src/defaults.json
var bundleVersion = "codeql-bundle-v2.24.2";
var cliVersion = "2.24.2";
var bundleVersion = "codeql-bundle-v2.24.3";
var cliVersion = "2.24.3";
// src/overlay/index.ts
var fs3 = __toESM(require("fs"));
+3 -3
View File
@@ -45986,7 +45986,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.32.6",
version: "4.32.7",
private: true,
description: "CodeQL action",
scripts: {
@@ -104857,8 +104857,8 @@ var path6 = __toESM(require("path"));
var semver5 = __toESM(require_semver2());
// src/defaults.json
var bundleVersion = "codeql-bundle-v2.24.2";
var cliVersion = "2.24.2";
var bundleVersion = "codeql-bundle-v2.24.3";
var cliVersion = "2.24.3";
// src/overlay/index.ts
var fs3 = __toESM(require("fs"));
+1 -1
View File
@@ -45986,7 +45986,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.32.6",
version: "4.32.7",
private: true,
description: "CodeQL action",
scripts: {
+3 -3
View File
@@ -45986,7 +45986,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.32.6",
version: "4.32.7",
private: true,
description: "CodeQL action",
scripts: {
@@ -103679,8 +103679,8 @@ var path4 = __toESM(require("path"));
var semver4 = __toESM(require_semver2());
// src/defaults.json
var bundleVersion = "codeql-bundle-v2.24.2";
var cliVersion = "2.24.2";
var bundleVersion = "codeql-bundle-v2.24.3";
var cliVersion = "2.24.3";
// src/overlay/index.ts
var fs3 = __toESM(require("fs"));
+1 -1
View File
@@ -45986,7 +45986,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.32.6",
version: "4.32.7",
private: true,
description: "CodeQL action",
scripts: {
+3 -3
View File
@@ -45986,7 +45986,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.32.6",
version: "4.32.7",
private: true,
description: "CodeQL action",
scripts: {
@@ -120612,8 +120612,8 @@ var path = __toESM(require("path"));
var semver4 = __toESM(require_semver2());
// src/defaults.json
var bundleVersion = "codeql-bundle-v2.24.2";
var cliVersion = "2.24.2";
var bundleVersion = "codeql-bundle-v2.24.3";
var cliVersion = "2.24.3";
// src/overlay/index.ts
var actionsCache = __toESM(require_cache5());
+3 -3
View File
@@ -47283,7 +47283,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.32.6",
version: "4.32.7",
private: true,
description: "CodeQL action",
scripts: {
@@ -106934,8 +106934,8 @@ var path5 = __toESM(require("path"));
var semver5 = __toESM(require_semver2());
// src/defaults.json
var bundleVersion = "codeql-bundle-v2.24.2";
var cliVersion = "2.24.2";
var bundleVersion = "codeql-bundle-v2.24.3";
var cliVersion = "2.24.3";
// src/overlay/index.ts
var fs3 = __toESM(require("fs"));
+1 -1
View File
@@ -45986,7 +45986,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.32.6",
version: "4.32.7",
private: true,
description: "CodeQL action",
scripts: {
+3 -3
View File
@@ -45986,7 +45986,7 @@ var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "codeql",
version: "4.32.6",
version: "4.32.7",
private: true,
description: "CodeQL action",
scripts: {
@@ -106618,8 +106618,8 @@ var path4 = __toESM(require("path"));
var semver4 = __toESM(require_semver2());
// src/defaults.json
var bundleVersion = "codeql-bundle-v2.24.2";
var cliVersion = "2.24.2";
var bundleVersion = "codeql-bundle-v2.24.3";
var cliVersion = "2.24.3";
// src/overlay/index.ts
var fs3 = __toESM(require("fs"));
+5 -5
View File
@@ -1,12 +1,12 @@
{
"name": "codeql",
"version": "4.32.6",
"version": "4.32.7",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "codeql",
"version": "4.32.6",
"version": "4.32.7",
"license": "MIT",
"dependencies": {
"@actions/artifact": "^5.0.3",
@@ -8870,9 +8870,9 @@
}
},
"node_modules/tar": {
"version": "7.5.7",
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.7.tgz",
"integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==",
"version": "7.5.10",
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.10.tgz",
"integrity": "sha512-8mOPs1//5q/rlkNSPcCegA6hiHJYDmSLEI8aMH/CdSQJNWztHC9WHNam5zdQlfpTwB9Xp7IBEsHfV5LKMJGVAw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "codeql",
"version": "4.32.6",
"version": "4.32.7",
"private": true,
"description": "CodeQL action",
"scripts": {
+30
View File
@@ -0,0 +1,30 @@
export const ACTION_VERSIONS = {
"actions/checkout": {
"version": "v6"
},
"actions/setup-go": {
"version": "v6"
},
"actions/setup-dotnet": {
"version": "v5"
},
"actions/upload-artifact": {
"version": "v7"
},
"actions/github-script": {
"version": "v8"
},
"actions/setup-python": {
"version": "v6"
},
"actions/setup-java": {
"version": "v5"
},
"actions/setup-node": {
"version": "v6"
},
"ruby/setup-ruby": {
"version": "09a7688d3b55cf0e976497ff046b70949eeaccfd",
"comment": " v1.288.0"
}
};
+2 -2
View File
@@ -40,7 +40,7 @@ steps:
post-processed-sarif-path: "${{ runner.temp }}/post-processed"
- name: Upload SARIF files
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: |
analysis-kinds-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}
@@ -48,7 +48,7 @@ steps:
retention-days: 7
- name: Upload post-processed SARIF
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: |
post-processed-${{ matrix.os }}-${{ matrix.version }}-${{ matrix.analysis-kinds }}
@@ -1,5 +1,5 @@
name: "Autobuild direct tracing (custom working directory)"
description: >
description: |
An end-to-end integration test of a Java repository built using 'build-mode: autobuild',
with direct tracing enabled and a custom working directory specified as the input to the
autobuild Action.
+1 -1
View File
@@ -27,7 +27,7 @@ steps:
output: ${{ runner.temp }}/results
upload-database: false
- name: Upload SARIF
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.os }}-zstd-bundle.sarif
path: ${{ runner.temp }}/results/javascript.sarif
+1 -1
View File
@@ -12,7 +12,7 @@ steps:
output: "${{ runner.temp }}/results"
upload-database: false
- name: Upload SARIF
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: config-export-${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: "${{ runner.temp }}/results/javascript.sarif"
+1 -1
View File
@@ -25,7 +25,7 @@ steps:
output: "${{ runner.temp }}/results"
upload-database: false
- name: Upload SARIF
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: diagnostics-export-${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: "${{ runner.temp }}/results/javascript.sarif"
@@ -19,7 +19,7 @@ steps:
with:
output: "${{ runner.temp }}/results"
- name: Upload SARIF
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: with-baseline-information-${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: "${{ runner.temp }}/results/javascript.sarif"
+8 -9
View File
@@ -4,12 +4,11 @@
# basic mechanics of multi-registry auth is working.
name: "Packaging: Download using registries"
description: "Checks that specifying a registries block and associated auth works as expected"
versions: [
# This feature is not compatible with older CLIs
"default",
"linked",
"nightly-latest",
]
versions:
# This feature is not compatible with older CLIs
- "default"
- "linked"
- "nightly-latest"
permissions:
contents: read
@@ -24,9 +23,9 @@ steps:
config-file: ./.github/codeql/codeql-config-registries.yml
languages: javascript
registries: |
- url: "https://ghcr.io/v2/"
packages: "*/*"
token: "${{ secrets.GITHUB_TOKEN }}"
- url: "https://ghcr.io/v2/"
packages: "*/*"
token: "${{ secrets.GITHUB_TOKEN }}"
- name: Verify packages installed
run: |
+1 -1
View File
@@ -11,7 +11,7 @@ steps:
with:
output: "${{ runner.temp }}/results"
- name: Upload SARIF
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.os }}-${{ matrix.version }}.sarif.json
path: "${{ runner.temp }}/results/javascript.sarif"
+1 -1
View File
@@ -4,7 +4,7 @@ versions: ["linked", "nightly-latest"]
steps:
- uses: ./../action/init
with:
languages: actions # Any language without overlay support will do
languages: actions # Any language without overlay support will do
tools: ${{ steps.prepare-test.outputs.tools-url }}
env:
CODEQL_OVERLAY_DATABASE_MODE: overlay-base
+17 -6
View File
@@ -5,6 +5,8 @@ import * as path from "path";
import * as yaml from "yaml";
import { ACTION_VERSIONS } from "./action-versions";
/** Known workflow input names. */
enum KnownInputName {
GoVersion = "go-version",
@@ -13,6 +15,9 @@ enum KnownInputName {
DotnetVersion = "dotnet-version",
}
/** Known Action names that we have version information for. */
type KnownAction = keyof typeof ACTION_VERSIONS;
/**
* Represents workflow input definitions.
*/
@@ -94,6 +99,12 @@ const THIS_DIR = __dirname;
const CHECKS_DIR = path.join(THIS_DIR, "checks");
const OUTPUT_DIR = path.join(THIS_DIR, "..", ".github", "workflows");
/** Gets an `actionName@ref` string for `actionName`. */
function getActionRef(actionName: KnownAction): string {
const versionInfo = ACTION_VERSIONS[actionName];
return `${actionName}@${versionInfo.version}`;
}
/**
* Loads and parses a YAML file.
*/
@@ -216,7 +227,7 @@ function main(): void {
const steps: any[] = [
{
name: "Check out repository",
uses: "actions/checkout@v6",
uses: getActionRef("actions/checkout"),
},
];
@@ -226,7 +237,7 @@ function main(): void {
steps.push(
{
name: "Install Node.js",
uses: "actions/setup-node@v6",
uses: getActionRef("actions/setup-node"),
with: {
"node-version": "20.x",
cache: "npm",
@@ -265,7 +276,7 @@ function main(): void {
steps.push({
name: "Install Go",
uses: "actions/setup-go@v6",
uses: getActionRef("actions/setup-go"),
with: {
"go-version":
"${{ inputs.go-version || '" + baseGoVersionExpr + "' }}",
@@ -289,7 +300,7 @@ function main(): void {
steps.push({
name: "Install Java",
uses: "actions/setup-java@v5",
uses: getActionRef("actions/setup-java"),
with: {
"java-version":
"${{ inputs.java-version || '" + baseJavaVersionExpr + "' }}",
@@ -312,7 +323,7 @@ function main(): void {
steps.push({
name: "Install Python",
if: "matrix.version != 'nightly-latest'",
uses: "actions/setup-python@v6",
uses: getActionRef("actions/setup-python"),
with: {
"python-version":
"${{ inputs.python-version || '" + basePythonVersionExpr + "' }}",
@@ -333,7 +344,7 @@ function main(): void {
steps.push({
name: "Install .NET",
uses: "actions/setup-dotnet@v5",
uses: getActionRef("actions/setup-dotnet"),
with: {
"dotnet-version":
"${{ inputs.dotnet-version || '" + baseDotNetVersionExpr + "' }}",
+95 -80
View File
@@ -11,15 +11,18 @@ import * as path from "node:path";
import { afterEach, beforeEach, describe, it } from "node:test";
import {
Options,
scanGeneratedWorkflows,
updateSyncTs,
updateActionVersions,
updateTemplateFiles,
} from "./sync_back";
let testDir: string;
let workflowDir: string;
let checksDir: string;
let syncTsPath: string;
let actionVersionsTsPath: string;
const defaultOptions: Options = { verbose: false, force: false };
beforeEach(() => {
/** Set up temporary directories and files for testing */
@@ -29,8 +32,8 @@ beforeEach(() => {
fs.mkdirSync(workflowDir, { recursive: true });
fs.mkdirSync(checksDir, { recursive: true });
// Create sync.ts file path
syncTsPath = path.join(testDir, "pr-checks", "sync.ts");
// Create action-versions.ts file path
actionVersionsTsPath = path.join(testDir, "pr-checks", "action-versions.ts");
});
afterEach(() => {
@@ -56,9 +59,18 @@ jobs:
const result = scanGeneratedWorkflows(workflowDir);
assert.equal(result["actions/checkout"], "v4");
assert.equal(result["actions/setup-node"], "v5");
assert.equal(result["actions/setup-go"], "v6");
assert.deepEqual(result["actions/checkout"], {
version: "v4",
comment: undefined,
});
assert.deepEqual(result["actions/setup-node"], {
version: "v5",
comment: undefined,
});
assert.deepEqual(result["actions/setup-go"], {
version: "v6",
comment: undefined,
});
});
it("scanning workflows with version comments", () => {
@@ -78,12 +90,18 @@ jobs:
const result = scanGeneratedWorkflows(workflowDir);
assert.equal(result["actions/checkout"], "v4");
assert.equal(
result["ruby/setup-ruby"],
"44511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0",
);
assert.equal(result["actions/setup-python"], "v6 # Latest Python");
assert.deepEqual(result["actions/checkout"], {
version: "v4",
comment: undefined,
});
assert.deepEqual(result["ruby/setup-ruby"], {
version: "44511735964dcb71245e7e55f72539531f7bc0eb",
comment: " v1.257.0",
});
assert.deepEqual(result["actions/setup-python"], {
version: "v6",
comment: " Latest Python",
});
});
it("ignores local actions", () => {
@@ -103,89 +121,76 @@ jobs:
const result = scanGeneratedWorkflows(workflowDir);
assert.equal(result["actions/checkout"], "v4");
assert.deepEqual(result["actions/checkout"], {
version: "v4",
comment: undefined,
});
assert.equal("./.github/actions/local-action" in result, false);
assert.equal("./another-local-action" in result, false);
});
});
describe("updateSyncTs", () => {
it("updates sync.ts file", () => {
/** Test updating sync.ts file */
const syncTsContent = `
const steps = [
{
uses: "actions/setup-node@v4",
with: { "node-version": "16" },
describe("updateActionVersions", () => {
it("updates action-versions.ts file", () => {
/** Test updating action-versions.ts file */
const actionVersionsTsContent = `
export const ACTION_VERSIONS = {
"actions/setup-node": {
"version": "v4"
},
{
uses: "actions/setup-go@v5",
with: { "go-version": "1.19" },
},
];
`;
"actions/setup-go": {
"version": "v5"
}
};
`.trim();
fs.writeFileSync(syncTsPath, syncTsContent);
fs.writeFileSync(actionVersionsTsPath, actionVersionsTsContent);
const actionVersions = {
"actions/setup-node": "v5",
"actions/setup-go": "v6",
"actions/setup-node": { version: "v5" },
"actions/setup-go": { version: "v6" },
};
const result = updateSyncTs(syncTsPath, actionVersions);
const result = updateActionVersions(
defaultOptions,
actionVersionsTsPath,
actionVersions,
);
assert.equal(result, true);
const updatedContent = fs.readFileSync(syncTsPath, "utf8");
const updatedContent = fs.readFileSync(actionVersionsTsPath, "utf8");
assert.ok(updatedContent.includes('uses: "actions/setup-node@v5"'));
assert.ok(updatedContent.includes('uses: "actions/setup-go@v6"'));
});
it("strips comments from versions", () => {
/** Test updating sync.ts file when versions have comments */
const syncTsContent = `
const steps = [
{
uses: "actions/setup-node@v4",
with: { "node-version": "16" },
},
];
`;
fs.writeFileSync(syncTsPath, syncTsContent);
const actionVersions = {
"actions/setup-node": "v5 # Latest version",
};
const result = updateSyncTs(syncTsPath, actionVersions);
assert.equal(result, true);
const updatedContent = fs.readFileSync(syncTsPath, "utf8");
// sync.ts should get the version without comment
assert.ok(updatedContent.includes('uses: "actions/setup-node@v5"'));
assert.ok(!updatedContent.includes("# Latest version"));
assert.ok(
updatedContent.includes('"actions/setup-node": {\n "version": "v5"'),
);
assert.ok(
updatedContent.includes('"actions/setup-go": {\n "version": "v6"'),
);
});
it("returns false when no changes are needed", () => {
/** Test that updateSyncTs returns false when no changes are needed */
const syncTsContent = `
const steps = [
{
uses: "actions/setup-node@v5",
with: { "node-version": "16" },
},
];
`;
/** Test that updateActionVersions returns false when no changes are needed */
const actionVersionsTsContent = `
export const ACTION_VERSIONS = {
"actions/setup-node": {
"version": "v5"
}
};
`.trimStart();
fs.writeFileSync(syncTsPath, syncTsContent);
fs.writeFileSync(actionVersionsTsPath, actionVersionsTsContent);
const actionVersions = {
"actions/setup-node": "v5",
"actions/setup-node": { version: "v5" },
};
const result = updateSyncTs(syncTsPath, actionVersions);
const result = updateActionVersions(
defaultOptions,
actionVersionsTsPath,
actionVersions,
);
const updatedContent = fs.readFileSync(actionVersionsTsPath, "utf8");
assert.equal(updatedContent, actionVersionsTsContent);
assert.equal(result, false);
});
});
@@ -206,11 +211,15 @@ steps:
fs.writeFileSync(templatePath, templateContent);
const actionVersions = {
"actions/checkout": "v4",
"actions/setup-node": "v5 # Latest",
"actions/checkout": { version: "v4" },
"actions/setup-node": { version: "v5", comment: " Latest" },
};
const result = updateTemplateFiles(checksDir, actionVersions);
const result = updateTemplateFiles(
defaultOptions,
checksDir,
actionVersions,
);
assert.equal(result.length, 1);
assert.ok(result.includes(templatePath));
@@ -232,11 +241,17 @@ steps:
fs.writeFileSync(templatePath, templateContent);
const actionVersions = {
"ruby/setup-ruby":
"55511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0",
"ruby/setup-ruby": {
version: "55511735964dcb71245e7e55f72539531f7bc0eb",
comment: " v1.257.0",
},
};
const result = updateTemplateFiles(checksDir, actionVersions);
const result = updateTemplateFiles(
defaultOptions,
checksDir,
actionVersions,
);
assert.equal(result.length, 1);
const updatedContent = fs.readFileSync(templatePath, "utf8");
+139 -76
View File
@@ -1,5 +1,7 @@
#!/usr/bin/env npx tsx
import * as yaml from "yaml";
/*
Sync-back script to automatically update action versions in source templates
from the generated workflow files after Dependabot updates.
@@ -25,7 +27,71 @@ import * as path from "path";
const THIS_DIR = __dirname;
const CHECKS_DIR = path.join(THIS_DIR, "checks");
const WORKFLOW_DIR = path.join(THIS_DIR, "..", ".github", "workflows");
const SYNC_TS_PATH = path.join(THIS_DIR, "sync.ts");
const ACTION_VERSIONS_PATH = path.join(THIS_DIR, "action-versions.ts");
/** Command-line options for this program. */
export type Options = {
verbose: boolean;
force: boolean;
};
/** Records information about the version of an Action with an optional comment. */
type ActionVersion = { version: string; comment?: string };
/** Converts `info` to a string that includes the version and comment. */
function versionWithCommentStr(info: ActionVersion): string {
const comment = info.comment ? ` #${info.comment}` : "";
return `${info.version}${comment}`;
}
/**
* Constructs a `yaml.visitor` which calls `fn` for `yaml.Pair` nodes where the key is "uses" and
* the value is a `yaml.Scalar`.
*/
function usesVisitor(
fn: (
pair: yaml.Pair<yaml.Scalar, yaml.Scalar>,
actionName: string,
actionVersion: ActionVersion,
) => void,
): yaml.visitor {
return {
Pair(_, pair) {
if (
yaml.isScalar(pair.key) &&
yaml.isScalar(pair.value) &&
pair.key.value === "uses" &&
typeof pair.value.value === "string"
) {
const usesValue = pair.value.value;
// Only track non-local actions (those with / but not starting with ./)
if (!usesValue.startsWith("./")) {
const parts = (pair.value.value as string).split("@");
if (parts.length !== 2) {
throw new Error(`Unexpected 'uses' value: ${usesValue}`);
}
const actionName = parts[0];
const actionVersion = parts[1].trimEnd();
const comment = pair.value.comment?.trimEnd();
fn(pair as yaml.Pair<yaml.Scalar, yaml.Scalar>, actionName, {
version: actionVersion,
comment,
});
}
// Do not visit the children of this node.
return yaml.visit.SKIP;
}
// Do nothing and continue.
return undefined;
},
};
}
/**
* Scan generated workflow files to extract the latest action versions.
@@ -33,8 +99,10 @@ const SYNC_TS_PATH = path.join(THIS_DIR, "sync.ts");
* @param workflowDir - Path to .github/workflows directory
* @returns Map from action names to their latest versions (including comments)
*/
export function scanGeneratedWorkflows(workflowDir: string): Record<string, string> {
const actionVersions: Record<string, string> = {};
export function scanGeneratedWorkflows(
workflowDir: string,
): Record<string, ActionVersion> {
const actionVersions: Record<string, ActionVersion> = {};
const generatedFiles = fs
.readdirSync(workflowDir)
@@ -43,86 +111,63 @@ export function scanGeneratedWorkflows(workflowDir: string): Record<string, stri
for (const filePath of generatedFiles) {
const content = fs.readFileSync(filePath, "utf8");
const doc = yaml.parseDocument(content);
// Find all action uses in the file, including potential comments
// This pattern captures: action_name@version_with_possible_comment
const pattern = /uses:\s+([^/\s]+\/[^@\s]+)@([^@\n]+)/g;
let match: RegExpExecArray | null;
while ((match = pattern.exec(content)) !== null) {
const actionName = match[1];
const versionWithComment = match[2].trimEnd();
// Only track non-local actions (those with / but not starting with ./)
if (!actionName.startsWith("./")) {
yaml.visit(
doc,
usesVisitor((_node, actionName, actionVersion) => {
// Assume that version numbers are consistent (this should be the case on a Dependabot update PR)
actionVersions[actionName] = versionWithComment;
}
}
actionVersions[actionName] = actionVersion;
}),
);
}
return actionVersions;
}
/**
* Update hardcoded action versions in pr-checks/sync.ts
* Update hardcoded action versions in pr-checks/action-versions.ts
*
* @param syncTsPath - Path to sync.ts file
* @param options - The command-line options.
* @param actionVersionsTsPath - Path to action-versions.ts file
* @param actionVersions - Map of action names to versions (may include comments)
* @returns True if the file was modified, false otherwise
*/
export function updateSyncTs(
syncTsPath: string,
actionVersions: Record<string, string>,
export function updateActionVersions(
options: Options,
actionVersionsTsPath: string,
actionVersions: Record<string, ActionVersion>,
): boolean {
if (!fs.existsSync(syncTsPath)) {
throw new Error(`Could not find ${syncTsPath}`);
}
// Build content for the file.
let newContent: string = `export const ACTION_VERSIONS = ${JSON.stringify(actionVersions, null, 2)};\n`;
let content = fs.readFileSync(syncTsPath, "utf8");
const originalContent = content;
if (fs.existsSync(actionVersionsTsPath)) {
const content = fs.readFileSync(actionVersionsTsPath, "utf8");
if (content === newContent && !options.force) {
console.info(`No changes needed in ${actionVersionsTsPath}`);
return false;
}
}
// Update hardcoded action versions
for (const [actionName, versionWithComment] of Object.entries(
actionVersions,
)) {
// Extract just the version part (before any comment) for sync.ts
const version = versionWithComment.includes("#")
? versionWithComment.split("#")[0].trim()
: versionWithComment.trim();
// Look for patterns like uses: "actions/setup-node@v4"
// Note that this will break if we store an Action uses reference in a
// variable - that's a risk we're happy to take since in that case the
// PR checks will just fail.
const escaped = actionName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const pattern = new RegExp(
`(uses:\\s*")${escaped}@(?:[^"]+)(")`,
"g",
);
content = content.replace(pattern, `$1${actionName}@${version}$2`);
}
if (content !== originalContent) {
fs.writeFileSync(syncTsPath, content, "utf8");
console.info(`Updated ${syncTsPath}`);
return true;
} else {
console.info(`No changes needed in ${syncTsPath}`);
return false;
}
fs.writeFileSync(actionVersionsTsPath, newContent, "utf8");
console.info(`Updated ${actionVersionsTsPath}`);
return true;
}
/**
* Update action versions in template files in pr-checks/checks/
*
* @param options - The command-line options.
* @param checksDir - Path to pr-checks/checks directory
* @param actionVersions - Map of action names to versions (may include comments)
* @returns List of files that were modified
*/
export function updateTemplateFiles(
options: Options,
checksDir: string,
actionVersions: Record<string, string>,
actionVersions: Record<string, ActionVersion>,
): string[] {
const modifiedFiles: string[] = [];
@@ -132,24 +177,33 @@ export function updateTemplateFiles(
.map((f) => path.join(checksDir, f));
for (const filePath of templateFiles) {
let content = fs.readFileSync(filePath, "utf8");
const originalContent = content;
const content = fs.readFileSync(filePath, "utf8");
const doc = yaml.parseDocument(content, { keepSourceTokens: true });
let modified: boolean = false;
// Update action versions
for (const [actionName, versionWithComment] of Object.entries(
actionVersions,
)) {
// Look for patterns like 'uses: actions/setup-node@v4' or 'uses: actions/setup-node@sha # comment'
const escaped = actionName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const pattern = new RegExp(
`(uses:\\s+${escaped})@(?:[^@\n]+)`,
"g",
yaml.visit(
doc,
usesVisitor((pair, actionName, actionVersion) => {
// Try to look up version information for this action.
const versionInfo = actionVersions[actionName];
// If we found version information, and the version is different from that in the template,
// then update the pair node accordingly.
if (versionInfo && versionInfo.version !== actionVersion.version) {
pair.value.value = `${actionName}@${versionInfo.version}`;
pair.value.comment = versionInfo.comment;
modified = true;
}
}),
);
// Write the YAML document back to the file if we made changes.
if (modified || options.force) {
fs.writeFileSync(
filePath,
doc.toString({ lineWidth: 0, flowCollectionPadding: false }),
"utf8",
);
content = content.replace(pattern, `$1@${versionWithComment}`);
}
if (content !== originalContent) {
fs.writeFileSync(filePath, content, "utf8");
modifiedFiles.push(filePath);
console.info(`Updated ${filePath}`);
}
@@ -166,6 +220,11 @@ function main(): number {
short: "v",
default: false,
},
force: {
type: "boolean",
short: "f",
default: false,
},
},
strict: true,
});
@@ -178,7 +237,7 @@ function main(): number {
if (verbose) {
console.info("Found action versions:");
for (const [action, version] of Object.entries(actionVersions)) {
console.info(` ${action}@${version}`);
console.info(` ${action}@${versionWithCommentStr(version)}`);
}
}
@@ -192,12 +251,16 @@ function main(): number {
const modifiedFiles: string[] = [];
// Update sync.ts
if (updateSyncTs(SYNC_TS_PATH, actionVersions)) {
modifiedFiles.push(SYNC_TS_PATH);
if (updateActionVersions(values, ACTION_VERSIONS_PATH, actionVersions)) {
modifiedFiles.push(ACTION_VERSIONS_PATH);
}
// Update template files
const templateModified = updateTemplateFiles(CHECKS_DIR, actionVersions);
const templateModified = updateTemplateFiles(
values,
CHECKS_DIR,
actionVersions,
);
modifiedFiles.push(...templateModified);
if (modifiedFiles.length > 0) {
+4 -4
View File
@@ -1,6 +1,6 @@
{
"bundleVersion": "codeql-bundle-v2.24.2",
"cliVersion": "2.24.2",
"priorBundleVersion": "codeql-bundle-v2.24.1",
"priorCliVersion": "2.24.1"
"bundleVersion": "codeql-bundle-v2.24.3",
"cliVersion": "2.24.3",
"priorBundleVersion": "codeql-bundle-v2.24.2",
"priorCliVersion": "2.24.2"
}