diff --git a/.github/update-release-branch.py b/.github/update-release-branch.py index 90e059259..0c749e7b2 100644 --- a/.github/update-release-branch.py +++ b/.github/update-release-branch.py @@ -16,12 +16,23 @@ No user facing changes. """ # NB: This exact commit message is used to find commits for reverting during backports. -# Changing it requires a transition period where both old and new versions are supported. +# Changing it requires a transition period where both old and new versions are supported. BACKPORT_COMMIT_MESSAGE = 'Update version and changelog for v' # Name of the remote ORIGIN = 'origin' +# Environment variables to check for a GitHub API token. +TOKEN_ENVIRONMENT_VARIABLES = ('GH_TOKEN', 'GITHUB_TOKEN') + +# Gets a GitHub API token from one of the supported environment variables. +def get_github_token(): + for variable_name in TOKEN_ENVIRONMENT_VARIABLES: + token = os.environ.get(variable_name, '').strip() + if token: + return token + raise Exception('Missing GitHub token. Set GITHUB_TOKEN or GH_TOKEN.') + # Runs git with the given args and returns the stdout. # Raises an error if git does not exit successfully (unless passed # allow_non_zero_exit_code=True). @@ -270,12 +281,6 @@ def update_changelog(version): def main(): parser = argparse.ArgumentParser('update-release-branch.py') - parser.add_argument( - '--github-token', - type=str, - required=True, - help='GitHub token, typically from GitHub Actions.' - ) parser.add_argument( '--repository-nwo', type=str, @@ -313,7 +318,7 @@ def main(): target_branch = args.target_branch is_primary_release = args.is_primary_release - repo = Github(args.github_token).get_repo(args.repository_nwo) + repo = Github(get_github_token()).get_repo(args.repository_nwo) # the target branch will be of the form releases/vN, where N is the major version number target_branch_major_version = target_branch.strip('releases/v') diff --git a/.github/workflows/__go-tracing-autobuilder.yml b/.github/workflows/__go-tracing-autobuilder.yml index f014d2cf6..f44a512f8 100644 --- a/.github/workflows/__go-tracing-autobuilder.yml +++ b/.github/workflows/__go-tracing-autobuilder.yml @@ -49,10 +49,6 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - version: stable-v2.17.6 - - os: ubuntu-latest - version: stable-v2.18.4 - os: ubuntu-latest version: stable-v2.19.4 - os: ubuntu-latest @@ -61,6 +57,10 @@ jobs: version: stable-v2.21.4 - os: ubuntu-latest version: stable-v2.22.4 + - os: ubuntu-latest + version: stable-v2.23.9 + - os: ubuntu-latest + version: stable-v2.24.3 - os: ubuntu-latest version: default - os: ubuntu-latest diff --git a/.github/workflows/__go-tracing-custom-build-steps.yml b/.github/workflows/__go-tracing-custom-build-steps.yml index 4b4782572..aae22d8c0 100644 --- a/.github/workflows/__go-tracing-custom-build-steps.yml +++ b/.github/workflows/__go-tracing-custom-build-steps.yml @@ -49,10 +49,6 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - version: stable-v2.17.6 - - os: ubuntu-latest - version: stable-v2.18.4 - os: ubuntu-latest version: stable-v2.19.4 - os: ubuntu-latest @@ -61,6 +57,10 @@ jobs: version: stable-v2.21.4 - os: ubuntu-latest version: stable-v2.22.4 + - os: ubuntu-latest + version: stable-v2.23.9 + - os: ubuntu-latest + version: stable-v2.24.3 - os: ubuntu-latest version: default - os: ubuntu-latest diff --git a/.github/workflows/__go-tracing-legacy-workflow.yml b/.github/workflows/__go-tracing-legacy-workflow.yml index 101ad8024..cce010257 100644 --- a/.github/workflows/__go-tracing-legacy-workflow.yml +++ b/.github/workflows/__go-tracing-legacy-workflow.yml @@ -49,10 +49,6 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - version: stable-v2.17.6 - - os: ubuntu-latest - version: stable-v2.18.4 - os: ubuntu-latest version: stable-v2.19.4 - os: ubuntu-latest @@ -61,6 +57,10 @@ jobs: version: stable-v2.21.4 - os: ubuntu-latest version: stable-v2.22.4 + - os: ubuntu-latest + version: stable-v2.23.9 + - os: ubuntu-latest + version: stable-v2.24.3 - os: ubuntu-latest version: default - os: ubuntu-latest diff --git a/.github/workflows/__multi-language-autodetect.yml b/.github/workflows/__multi-language-autodetect.yml index ff54c07eb..8115b66ee 100644 --- a/.github/workflows/__multi-language-autodetect.yml +++ b/.github/workflows/__multi-language-autodetect.yml @@ -59,14 +59,6 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - version: stable-v2.17.6 - - os: macos-latest-xlarge - version: stable-v2.17.6 - - os: ubuntu-latest - version: stable-v2.18.4 - - os: macos-latest-xlarge - version: stable-v2.18.4 - os: ubuntu-latest version: stable-v2.19.4 - os: macos-latest-xlarge @@ -83,6 +75,14 @@ jobs: version: stable-v2.22.4 - os: macos-latest-xlarge version: stable-v2.22.4 + - os: ubuntu-latest + version: stable-v2.23.9 + - os: macos-latest-xlarge + version: stable-v2.23.9 + - os: ubuntu-latest + version: stable-v2.24.3 + - os: macos-latest-xlarge + version: stable-v2.24.3 - os: ubuntu-latest version: default - os: macos-latest-xlarge diff --git a/.github/workflows/__rust.yml b/.github/workflows/__rust.yml index 92793f54a..1c3d18d16 100644 --- a/.github/workflows/__rust.yml +++ b/.github/workflows/__rust.yml @@ -40,7 +40,7 @@ jobs: matrix: include: - os: ubuntu-latest - version: stable-v2.19.3 + version: stable-v2.19.4 - os: ubuntu-latest version: stable-v2.22.1 - os: ubuntu-latest diff --git a/.github/workflows/update-release-branch.yml b/.github/workflows/update-release-branch.yml index 147689ace..40d25e216 100644 --- a/.github/workflows/update-release-branch.yml +++ b/.github/workflows/update-release-branch.yml @@ -64,11 +64,12 @@ jobs: - name: Update current release branch if: github.event_name == 'workflow_dispatch' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | echo SOURCE_BRANCH=${REF_NAME} echo TARGET_BRANCH=releases/${MAJOR_VERSION} python .github/update-release-branch.py \ - --github-token ${{ secrets.GITHUB_TOKEN }} \ --repository-nwo ${{ github.repository }} \ --source-branch '${{ env.REF_NAME }}' \ --target-branch 'releases/${{ env.MAJOR_VERSION }}' \ @@ -107,11 +108,12 @@ jobs: - uses: ./.github/actions/release-initialise - name: Update older release branch + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | echo SOURCE_BRANCH=${SOURCE_BRANCH} echo TARGET_BRANCH=${TARGET_BRANCH} python .github/update-release-branch.py \ - --github-token ${{ secrets.GITHUB_TOKEN }} \ --repository-nwo ${{ github.repository }} \ --source-branch ${SOURCE_BRANCH} \ --target-branch ${TARGET_BRANCH} \ diff --git a/CHANGELOG.md b/CHANGELOG.md index d19019fff..45fccfb9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ See the [releases page](https://github.com/github/codeql-action/releases) for th ## [UNRELEASED] -No user facing changes. +- _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) ## 4.35.5 - 15 May 2026 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2360f19f9..b67ccb13b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,7 +71,7 @@ Once the mergeback and backport pull request have been merged, the release is co Since the `codeql-action` runs most of its testing through individual Actions workflows, there are over two hundred required jobs that need to pass in order for a PR to turn green. It would be too tedious to maintain that list manually. You can regenerate the set of required checks automatically by running the [sync-checks.ts](pr-checks/sync-checks.ts) script: -- At a minimum, you must provide an argument for the `--token` input. For example, `--token "$(gh auth token)"` to use the same token that `gh` uses. If no token is provided or the token has insufficient permissions, the script will fail. +- At a minimum, you must provide a token with permissions to update branch protection rules. For example, `gh auth token | pr-checks/sync-checks.ts --token-stdin` uses the same token that `gh` uses. You can also set the `GH_TOKEN` or `GITHUB_TOKEN` environment variable. If no token is provided or the token has insufficient permissions, the script will fail. - By default, the script performs a dry run and outputs information about the changes it would make to the branch protection rules. To actually apply the changes, specify the `--apply` flag. - If you run the script without any other arguments, it will retrieve the set of workflows that ran for the latest commit on `main`. - You can specify a different git ref with the `--ref` input. You will likely want to use this if you have a PR that removes or adds PR checks. For example, `--ref "some/branch/name"` to use the HEAD of the `some/branch/name` branch. diff --git a/README.md b/README.md index bee9072a0..530c028f9 100644 --- a/README.md +++ b/README.md @@ -78,8 +78,6 @@ We typically release new minor versions of the CodeQL Action and Bundle when a n | `v3.28.21` | `2.21.3` | Enterprise Server 3.18 | | | `v3.28.12` | `2.20.7` | Enterprise Server 3.17 | | | `v3.28.6` | `2.20.3` | Enterprise Server 3.16 | | -| `v3.28.6` | `2.20.3` | Enterprise Server 3.15 | | -| `v3.28.6` | `2.20.3` | Enterprise Server 3.14 | | See the full list of GHES release and deprecation dates at [GitHub Enterprise Server releases](https://docs.github.com/en/enterprise-server/admin/all-releases#releases-of-github-enterprise-server). diff --git a/lib/entry-points.js b/lib/entry-points.js index eb048fc9c..079b8eee5 100644 --- a/lib/entry-points.js +++ b/lib/entry-points.js @@ -148304,7 +148304,7 @@ function getDiffRangesJsonFilePath() { return path2.join(getTemporaryDirectory(), PR_DIFF_RANGE_JSON_FILENAME); } function getActionVersion() { - return "4.35.6"; + return "4.36.0"; } function getWorkflowEventName() { return getRequiredEnvParam("GITHUB_EVENT_NAME"); @@ -148973,7 +148973,7 @@ var determineBaseBranchHeadCommitOid = async function(checkoutPathOverride) { } } } - if (commitOid === mergeSha && headOid.length === 40 && baseOid.length === 40) { + if (commitOid === mergeSha && (headOid.length === 40 || headOid.length === 64) && (baseOid.length === 40 || baseOid.length === 64)) { return baseOid; } return void 0; @@ -149039,7 +149039,7 @@ var getFileOidsUnderPath = async function(basePath) { "Cannot list Git OIDs of tracked files." ); const fileOidMap = {}; - const regex = /^[0-9]+ ([0-9a-f]{40}) [0-9]+\t(.+)$/; + const regex = /^[0-9]+ ([0-9a-f]{40}|[0-9a-f]{64}) [0-9]+\t(.+)$/; for (const line of stdout.split("\n")) { if (line) { const match = line.match(regex); @@ -153719,7 +153719,7 @@ async function getCombinedTracerConfig(codeql, config) { // src/codeql.ts var cachedCodeQL = void 0; -var CODEQL_MINIMUM_VERSION = "2.17.6"; +var CODEQL_MINIMUM_VERSION = "2.19.4"; var CODEQL_NEXT_MINIMUM_VERSION = "2.19.4"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09"; @@ -153846,10 +153846,6 @@ async function getCodeQLForCmd(cmd, checkVersion) { if (qlconfigFile !== void 0) { extraArgs.push(`--qlconfig-file=${qlconfigFile}`); } - const overwriteFlag = isSupportedToolsFeature( - await this.getVersion(), - "forceOverwrite" /* ForceOverwrite */ - ) ? "--force-overwrite" : "--overwrite"; const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode === "overlay" /* Overlay */) { const overlayChangesFile = await writeOverlayChangesFile( @@ -153870,7 +153866,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { [ "database", "init", - ...overlayDatabaseMode === "overlay" /* Overlay */ ? [] : [overwriteFlag], + ...overlayDatabaseMode === "overlay" /* Overlay */ ? [] : ["--force-overwrite"], "--db-cluster", config.dbLocation, `--source-root=${sourceRoot}`, @@ -153881,7 +153877,14 @@ async function getCodeQLForCmd(cmd, checkVersion) { // Some user configs specify `--no-calculate-baseline` as an additional // argument to `codeql database init`. Therefore ignore the baseline file // options here to avoid specifying the same argument twice and erroring. - ignoringOptions: ["--overwrite", ...baselineFilesOptions] + // + // Ignore `--overwrite` to avoid passing both `--force-overwrite` and `--overwrite` if + // the user has configured `--overwrite`. + ignoringOptions: [ + "--force-overwrite", + "--overwrite", + ...baselineFilesOptions + ] }) ], { stdin: externalRepositoryToken } @@ -154046,7 +154049,7 @@ ${output}` "--sarif-group-rules-by-pack", "--sarif-include-query-help=always", "--sublanguage-file-coverage", - ...await getJobRunUuidSarifOptions(this), + ...await getJobRunUuidSarifOptions(), ...getExtraOptionsFromEnv(["database", "interpret-results"]) ]; if (sarifRunPropertyFlag !== void 0) { @@ -154327,11 +154330,9 @@ function applyAutobuildAzurePipelinesTimeoutFix() { "-Dmaven.wagon.http.pool=false" ].join(" "); } -async function getJobRunUuidSarifOptions(codeql) { +async function getJobRunUuidSarifOptions() { const jobRunUuid = process.env["JOB_RUN_UUID" /* JOB_RUN_UUID */]; - return jobRunUuid && await codeql.supportsFeature( - "databaseInterpretResultsSupportsSarifRunProperty" /* DatabaseInterpretResultsSupportsSarifRunProperty */ - ) ? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`] : []; + return jobRunUuid ? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`] : []; } // src/autobuild.ts diff --git a/lib/upload-lib.js b/lib/upload-lib.js index 476db6ff2..d355fedf4 100644 --- a/lib/upload-lib.js +++ b/lib/upload-lib.js @@ -88509,7 +88509,7 @@ function getDiffRangesJsonFilePath() { return path2.join(getTemporaryDirectory(), PR_DIFF_RANGE_JSON_FILENAME); } function getActionVersion() { - return "4.35.6"; + return "4.36.0"; } function getWorkflowEventName() { return getRequiredEnvParam("GITHUB_EVENT_NAME"); @@ -89032,7 +89032,7 @@ var determineBaseBranchHeadCommitOid = async function(checkoutPathOverride) { } } } - if (commitOid === mergeSha && headOid.length === 40 && baseOid.length === 40) { + if (commitOid === mergeSha && (headOid.length === 40 || headOid.length === 64) && (baseOid.length === 40 || baseOid.length === 64)) { return baseOid; } return void 0; @@ -89098,7 +89098,7 @@ var getFileOidsUnderPath = async function(basePath) { "Cannot list Git OIDs of tracked files." ); const fileOidMap = {}; - const regex = /^[0-9]+ ([0-9a-f]{40}) [0-9]+\t(.+)$/; + const regex = /^[0-9]+ ([0-9a-f]{40}|[0-9a-f]{64}) [0-9]+\t(.+)$/; for (const line of stdout.split("\n")) { if (line) { const match = line.match(regex); @@ -91212,7 +91212,7 @@ async function shouldEnableIndirectTracing(codeql, config) { // src/codeql.ts var cachedCodeQL = void 0; -var CODEQL_MINIMUM_VERSION = "2.17.6"; +var CODEQL_MINIMUM_VERSION = "2.19.4"; var CODEQL_NEXT_MINIMUM_VERSION = "2.19.4"; var GHES_VERSION_MOST_RECENTLY_DEPRECATED = "3.15"; var GHES_MOST_RECENT_DEPRECATION_DATE = "2026-04-09"; @@ -91339,10 +91339,6 @@ async function getCodeQLForCmd(cmd, checkVersion) { if (qlconfigFile !== void 0) { extraArgs.push(`--qlconfig-file=${qlconfigFile}`); } - const overwriteFlag = isSupportedToolsFeature( - await this.getVersion(), - "forceOverwrite" /* ForceOverwrite */ - ) ? "--force-overwrite" : "--overwrite"; const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode === "overlay" /* Overlay */) { const overlayChangesFile = await writeOverlayChangesFile( @@ -91363,7 +91359,7 @@ async function getCodeQLForCmd(cmd, checkVersion) { [ "database", "init", - ...overlayDatabaseMode === "overlay" /* Overlay */ ? [] : [overwriteFlag], + ...overlayDatabaseMode === "overlay" /* Overlay */ ? [] : ["--force-overwrite"], "--db-cluster", config.dbLocation, `--source-root=${sourceRoot}`, @@ -91374,7 +91370,14 @@ async function getCodeQLForCmd(cmd, checkVersion) { // Some user configs specify `--no-calculate-baseline` as an additional // argument to `codeql database init`. Therefore ignore the baseline file // options here to avoid specifying the same argument twice and erroring. - ignoringOptions: ["--overwrite", ...baselineFilesOptions] + // + // Ignore `--overwrite` to avoid passing both `--force-overwrite` and `--overwrite` if + // the user has configured `--overwrite`. + ignoringOptions: [ + "--force-overwrite", + "--overwrite", + ...baselineFilesOptions + ] }) ], { stdin: externalRepositoryToken } @@ -91539,7 +91542,7 @@ ${output}` "--sarif-group-rules-by-pack", "--sarif-include-query-help=always", "--sublanguage-file-coverage", - ...await getJobRunUuidSarifOptions(this), + ...await getJobRunUuidSarifOptions(), ...getExtraOptionsFromEnv(["database", "interpret-results"]) ]; if (sarifRunPropertyFlag !== void 0) { @@ -91820,11 +91823,9 @@ function applyAutobuildAzurePipelinesTimeoutFix() { "-Dmaven.wagon.http.pool=false" ].join(" "); } -async function getJobRunUuidSarifOptions(codeql) { +async function getJobRunUuidSarifOptions() { const jobRunUuid = process.env["JOB_RUN_UUID" /* JOB_RUN_UUID */]; - return jobRunUuid && await codeql.supportsFeature( - "databaseInterpretResultsSupportsSarifRunProperty" /* DatabaseInterpretResultsSupportsSarifRunProperty */ - ) ? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`] : []; + return jobRunUuid ? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`] : []; } // src/fingerprints.ts diff --git a/package-lock.json b/package-lock.json index ff0319736..c4c542a01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codeql", - "version": "4.35.6", + "version": "4.36.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codeql", - "version": "4.35.6", + "version": "4.36.0", "license": "MIT", "workspaces": [ "pr-checks" @@ -59,7 +59,7 @@ "glob": "^11.1.0", "globals": "^17.6.0", "nock": "^14.0.12", - "sinon": "^21.1.2", + "sinon": "^22.0.0", "typescript": "^6.0.3", "typescript-eslint": "^8.59.2" } @@ -2379,9 +2379,9 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "15.3.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz", - "integrity": "sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw==", + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz", + "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -4458,9 +4458,9 @@ } }, "node_modules/diff": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", - "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-9.0.0.tgz", + "integrity": "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -8511,16 +8511,16 @@ } }, "node_modules/sinon": { - "version": "21.1.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-21.1.2.tgz", - "integrity": "sha512-FS6mN+/bx7e2ajpXkEmOcWB6xBzWiuNoAQT18/+a20SS4U7FSYl8Ms7N6VTUxN/1JAjkx7aXp+THMC8xdpp0gA==", + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-22.0.0.tgz", + "integrity": "sha512-sq/6DpdXOrLyfbKlXLg/Usc7xu8YXPeLkOFZRvA3bNUSA2lhbrZ06yuXbH1fkzBPCbz9O10+7hznzUsjaYNm0Q==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.1", - "@sinonjs/fake-timers": "^15.3.2", + "@sinonjs/fake-timers": "^15.4.0", "@sinonjs/samsam": "^10.0.2", - "diff": "^8.0.4" + "diff": "^9.0.0" }, "funding": { "type": "opencollective", @@ -10409,7 +10409,7 @@ "devDependencies": { "@types/node": "^20.19.39", "@types/sinon": "^21.0.1", - "sinon": "^21.1.2", + "sinon": "^22.0.0", "tsx": "^4.21.0" } } diff --git a/package.json b/package.json index db78e980e..39b7adc3d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codeql", - "version": "4.35.6", + "version": "4.36.0", "private": true, "description": "CodeQL action", "scripts": { @@ -67,7 +67,7 @@ "glob": "^11.1.0", "globals": "^17.6.0", "nock": "^14.0.12", - "sinon": "^21.1.2", + "sinon": "^22.0.0", "typescript": "^6.0.3", "typescript-eslint": "^8.59.2" }, diff --git a/pr-checks/checks/rust.yml b/pr-checks/checks/rust.yml index c19fc986d..8589ba80e 100644 --- a/pr-checks/checks/rust.yml +++ b/pr-checks/checks/rust.yml @@ -2,7 +2,7 @@ name: "Rust analysis" description: "Tests creation of a Rust database" versions: # experimental rust support introduced, requires action to set `CODEQL_ENABLE_EXPERIMENTAL_FEATURES` - - stable-v2.19.3 + - stable-v2.19.4 # first public preview version - stable-v2.22.1 - linked diff --git a/pr-checks/package.json b/pr-checks/package.json index ff4b45238..0032b5fc5 100644 --- a/pr-checks/package.json +++ b/pr-checks/package.json @@ -12,7 +12,7 @@ "devDependencies": { "@types/node": "^20.19.39", "@types/sinon": "^21.0.1", - "sinon": "^21.1.2", + "sinon": "^22.0.0", "tsx": "^4.21.0" } } diff --git a/pr-checks/sync-checks.test.ts b/pr-checks/sync-checks.test.ts index 4d49084cb..18d288582 100644 --- a/pr-checks/sync-checks.test.ts +++ b/pr-checks/sync-checks.test.ts @@ -7,7 +7,13 @@ Tests for the sync-checks.ts script import * as assert from "node:assert/strict"; import { describe, it } from "node:test"; -import { CheckInfo, Exclusions, Options, removeExcluded } from "./sync-checks"; +import { + CheckInfo, + Exclusions, + Options, + removeExcluded, + resolveToken, +} from "./sync-checks"; const defaultOptions: Options = { apply: false, @@ -58,3 +64,46 @@ describe("removeExcluded", async () => { assert.deepEqual(retained, expectedExactMatches); }); }); + +describe("resolveToken", async () => { + await it("reads the token from standard input", async () => { + const token = await resolveToken( + { tokenStdin: true }, + { env: {}, readStdin: async () => " stdin-token\n" }, + ); + assert.equal(token, "stdin-token"); + }); + + await it("reads the token from the GH_TOKEN environment variable", async () => { + const token = await resolveToken( + {}, + { env: { GH_TOKEN: "env-token" }, readStdin: async () => "" }, + ); + assert.equal(token, "env-token"); + }); + + await it("reads the token from the GITHUB_TOKEN environment variable", async () => { + const token = await resolveToken( + {}, + { env: { GITHUB_TOKEN: "env-token" }, readStdin: async () => "" }, + ); + assert.equal(token, "env-token"); + }); + + await it("rejects an empty standard input token", async () => { + await assert.rejects( + resolveToken( + { tokenStdin: true }, + { env: {}, readStdin: async () => "\n" }, + ), + /No token received on standard input/, + ); + }); + + await it("rejects missing token sources", async () => { + await assert.rejects( + resolveToken({}, { env: {}, readStdin: async () => "" }), + /Missing authentication token/, + ); + }); +}); diff --git a/pr-checks/sync-checks.ts b/pr-checks/sync-checks.ts index ef0753110..afebc5831 100755 --- a/pr-checks/sync-checks.ts +++ b/pr-checks/sync-checks.ts @@ -15,8 +15,8 @@ import { /** Represents the command-line options. */ export interface Options { - /** The token to use to authenticate to the GitHub API. */ - token?: string; + /** Whether to read the GitHub API token from standard input. */ + tokenStdin?: boolean; /** The git ref to use the checks for. */ ref?: string; /** Whether to actually apply the changes or not. */ @@ -31,6 +31,65 @@ const codeqlActionRepo = { repo: "codeql-action", }; +/** Environment variables to check for a GitHub API token. */ +const TOKEN_ENVIRONMENT_VARIABLES = ["GH_TOKEN", "GITHUB_TOKEN"]; + +/** Represents the sources from which we can retrieve the GitHub API token. */ +interface TokenSource { + /** Environment variables to inspect. */ + env: NodeJS.ProcessEnv; + /** Reads a token from standard input. */ + readStdin: () => Promise; +} + +/** Reads the GitHub API token from standard input. */ +async function readTokenFromStdin(): Promise { + let token = ""; + process.stdin.setEncoding("utf8"); + for await (const chunk of process.stdin) { + token += chunk; + } + return token.trim(); +} + +/** Gets a GitHub API token from one of the supported environment variables. */ +function getTokenFromEnvironment(env: NodeJS.ProcessEnv): string | undefined { + for (const variableName of TOKEN_ENVIRONMENT_VARIABLES) { + const token = env[variableName]?.trim(); + if (token) { + return token; + } + } + return undefined; +} + +/** Gets the token to use to authenticate to the GitHub API. */ +export async function resolveToken( + options: Pick, + tokenSource: TokenSource = { + env: process.env, + readStdin: readTokenFromStdin, + }, +): Promise { + if (options.tokenStdin) { + const token = (await tokenSource.readStdin()).trim(); + if (token.length === 0) { + throw new Error("No token received on standard input."); + } + return token; + } + + const environmentToken = getTokenFromEnvironment(tokenSource.env); + if (environmentToken !== undefined) { + return environmentToken; + } + + throw new Error( + "Missing authentication token. Set GH_TOKEN/GITHUB_TOKEN or pipe a token " + + "to --token-stdin.", + ); +} + /** Represents a configuration of which checks should not be set up as required checks. */ export interface Exclusions { /** A list of strings that, if contained in a check name, are excluded. */ @@ -205,9 +264,10 @@ async function updateBranch( async function main(): Promise { const { values: options } = parseArgs({ options: { - // The token to use to authenticate to the API. - token: { - type: "string", + // Read the token to use to authenticate to the API from standard input. + "token-stdin": { + type: "boolean", + default: false, }, // The git ref for which to retrieve the check runs. ref: { @@ -228,16 +288,16 @@ async function main(): Promise { strict: true, }); - if (options.token === undefined) { - throw new Error("Missing --token"); - } + const token = await resolveToken({ + tokenStdin: options["token-stdin"], + }); console.info( `Oldest supported major version is: ${OLDEST_SUPPORTED_MAJOR_VERSION}`, ); // Initialise the API client. - const client = getApiClient(options.token); + const client = getApiClient(token); // Find the check runs for the specified `ref` that we will later set as the required checks // for the main and release branches. diff --git a/pr-checks/sync.ts b/pr-checks/sync.ts index c810e7cbf..27b1d9264 100755 --- a/pr-checks/sync.ts +++ b/pr-checks/sync.ts @@ -115,10 +115,6 @@ type LanguageSetups = Partial>; // The default set of CodeQL Bundle versions to use for the PR checks. const defaultTestVersions = [ // The oldest supported CodeQL version. If bumping, update `CODEQL_MINIMUM_VERSION` in `codeql.ts` - "stable-v2.17.6", - // The last CodeQL release in the 2.18 series. - "stable-v2.18.4", - // The last CodeQL release in the 2.19 series. "stable-v2.19.4", // The last CodeQL release in the 2.20 series. "stable-v2.20.7", @@ -126,6 +122,10 @@ const defaultTestVersions = [ "stable-v2.21.4", // The last CodeQL release in the 2.22 series. "stable-v2.22.4", + // The last CodeQL release in the 2.23 series. + "stable-v2.23.9", + // The last CodeQL release in the 2.24 series. + "stable-v2.24.3", // The default version of CodeQL for Dotcom, as determined by feature flags. "default", // The version of CodeQL shipped with the Action in `defaults.json`. During the release process diff --git a/src/codeql.test.ts b/src/codeql.test.ts index 77fce4d3b..dea4cf04a 100644 --- a/src/codeql.test.ts +++ b/src/codeql.test.ts @@ -1072,7 +1072,7 @@ test.serial( ); test.serial( - "Avoids duplicating --overwrite flag if specified in CODEQL_ACTION_EXTRA_OPTIONS", + "Avoids duplicating --force-overwrite flag if specified in CODEQL_ACTION_EXTRA_OPTIONS", async (t) => { const runnerConstructorStub = stubToolRunnerConstructor(); const codeqlObject = await stubCodeql(); @@ -1080,7 +1080,7 @@ test.serial( sinon.stub(io, "which").resolves(""); process.env["CODEQL_ACTION_EXTRA_OPTIONS"] = - '{ "database": { "init": ["--overwrite"] } }'; + '{ "database": { "init": ["--force-overwrite"] } }'; await codeqlObject.databaseInitCluster( stubConfig, @@ -1093,9 +1093,9 @@ test.serial( t.true(runnerConstructorStub.calledOnce); const args = runnerConstructorStub.firstCall.args[1] as string[]; t.is( - args.filter((option: string) => option === "--overwrite").length, + args.filter((option: string) => option === "--force-overwrite").length, 1, - "--overwrite should only be passed once", + "--force-overwrite should only be passed once", ); // Clean up diff --git a/src/codeql.ts b/src/codeql.ts index 66ed8cebe..19f933c39 100644 --- a/src/codeql.ts +++ b/src/codeql.ts @@ -277,7 +277,7 @@ let cachedCodeQL: CodeQL | undefined = undefined; * The version flags below can be used to conditionally enable certain features * on versions newer than this. */ -const CODEQL_MINIMUM_VERSION = "2.17.6"; +const CODEQL_MINIMUM_VERSION = "2.19.4"; /** * This version will shortly become the oldest version of CodeQL that the Action will run with. @@ -592,13 +592,6 @@ async function getCodeQLForCmd( extraArgs.push(`--qlconfig-file=${qlconfigFile}`); } - const overwriteFlag = isSupportedToolsFeature( - await this.getVersion(), - ToolsFeature.ForceOverwrite, - ) - ? "--force-overwrite" - : "--overwrite"; - const overlayDatabaseMode = config.overlayDatabaseMode; if (overlayDatabaseMode === OverlayDatabaseMode.Overlay) { const overlayChangesFile = await writeOverlayChangesFile( @@ -625,7 +618,7 @@ async function getCodeQLForCmd( "init", ...(overlayDatabaseMode === OverlayDatabaseMode.Overlay ? [] - : [overwriteFlag]), + : ["--force-overwrite"]), "--db-cluster", config.dbLocation, `--source-root=${sourceRoot}`, @@ -636,7 +629,14 @@ async function getCodeQLForCmd( // Some user configs specify `--no-calculate-baseline` as an additional // argument to `codeql database init`. Therefore ignore the baseline file // options here to avoid specifying the same argument twice and erroring. - ignoringOptions: ["--overwrite", ...baselineFilesOptions], + // + // Ignore `--overwrite` to avoid passing both `--force-overwrite` and `--overwrite` if + // the user has configured `--overwrite`. + ignoringOptions: [ + "--force-overwrite", + "--overwrite", + ...baselineFilesOptions, + ], }), ], { stdin: externalRepositoryToken }, @@ -853,7 +853,7 @@ async function getCodeQLForCmd( "--sarif-group-rules-by-pack", "--sarif-include-query-help=always", "--sublanguage-file-coverage", - ...(await getJobRunUuidSarifOptions(this)), + ...(await getJobRunUuidSarifOptions()), ...getExtraOptionsFromEnv(["database", "interpret-results"]), ]; if (sarifRunPropertyFlag !== undefined) { @@ -1283,13 +1283,8 @@ function applyAutobuildAzurePipelinesTimeoutFix() { ].join(" "); } -async function getJobRunUuidSarifOptions(codeql: CodeQL) { +async function getJobRunUuidSarifOptions() { const jobRunUuid = process.env[EnvVar.JOB_RUN_UUID]; - return jobRunUuid && - (await codeql.supportsFeature( - ToolsFeature.DatabaseInterpretResultsSupportsSarifRunProperty, - )) - ? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`] - : []; + return jobRunUuid ? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`] : []; } diff --git a/src/diff-informed-analysis-utils.test.ts b/src/diff-informed-analysis-utils.test.ts index 6d185e564..e07240e32 100644 --- a/src/diff-informed-analysis-utils.test.ts +++ b/src/diff-informed-analysis-utils.test.ts @@ -75,10 +75,10 @@ const testShouldPerformDiffInformedAnalysis = makeMacro({ [Feature.DiffInformedQueries]: testCase.featureEnabled, }); - const getGitHubVersionStub = sinon + sinon .stub(apiClient, "getGitHubVersion") .resolves(testCase.gitHubVersion); - const getPullRequestBranchesStub = sinon + sinon .stub(actionsUtil, "getPullRequestBranches") .returns(testCase.pullRequestBranches); @@ -91,9 +91,6 @@ const testShouldPerformDiffInformedAnalysis = makeMacro({ t.is(branches !== undefined, expectedResult); delete process.env.CODEQL_ACTION_DIFF_INFORMED_QUERIES; - - getGitHubVersionStub.restore(); - getPullRequestBranchesStub.restore(); }); }, title: (title) => `getDiffInformedAnalysisBranches: ${title}`, diff --git a/src/feature-flags.ts b/src/feature-flags.ts index 145fa00cd..6b40d04da 100644 --- a/src/feature-flags.ts +++ b/src/feature-flags.ts @@ -26,6 +26,9 @@ const DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled"; /** * The first version of the CodeQL Bundle that shipped with zstd-compressed bundles. + * + * This is now below the minimum version of CodeQL, but we keep this around because we currently set + * up CodeQL before checking that the version is new enough. */ export const CODEQL_VERSION_ZSTD_BUNDLE = "2.19.0"; diff --git a/src/git-utils.test.ts b/src/git-utils.test.ts index 8804e1f99..b77d40a7e 100644 --- a/src/git-utils.test.ts +++ b/src/git-utils.test.ts @@ -33,7 +33,6 @@ test.serial( const actualRef = await gitUtils.getRef(); t.deepEqual(actualRef, expectedRef); - callback.restore(); }); }, ); @@ -54,7 +53,6 @@ test.serial( const actualRef = await gitUtils.getRef(); t.deepEqual(actualRef, expectedRef); - callback.restore(); }); }, ); @@ -73,7 +71,6 @@ test.serial( const actualRef = await gitUtils.getRef(); t.deepEqual(actualRef, "refs/pull/1/head"); - callback.restore(); }); }, ); @@ -100,8 +97,6 @@ test.serial( const actualRef = await gitUtils.getRef(); t.deepEqual(actualRef, "refs/pull/2/merge"); - callback.restore(); - getAdditionalInputStub.restore(); }); }, ); @@ -161,7 +156,6 @@ test.serial( "Both 'ref' and 'sha' are required if one of them is provided.", }, ); - getAdditionalInputStub.restore(); }); }, ); @@ -188,7 +182,6 @@ test.serial( "Both 'ref' and 'sha' are required if one of them is provided.", }, ); - getAdditionalInputStub.restore(); }); }, ); @@ -242,7 +235,6 @@ test.serial("isAnalyzingDefaultBranch()", async (t) => { process.env["GITHUB_EVENT_NAME"] = "schedule"; process.env["GITHUB_REF"] = "refs/heads/main"; t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(), false); - getAdditionalInputStub.restore(); }); }); @@ -254,8 +246,6 @@ test.serial("determineBaseBranchHeadCommitOid non-pullrequest", async (t) => { const result = await gitUtils.determineBaseBranchHeadCommitOid(__dirname); t.deepEqual(result, undefined); t.deepEqual(0, infoStub.callCount); - - infoStub.restore(); }); test.serial( @@ -276,8 +266,6 @@ test.serial( "git call failed. Will calculate the base branch SHA on the server. Error: " + "The checkout path provided to the action does not appear to be a git repository.", ); - - infoStub.restore(); }, ); @@ -301,10 +289,27 @@ test.serial("determineBaseBranchHeadCommitOid other error", async (t) => { "The checkout path provided to the action does not appear to be a git repository.", ), ); - - infoStub.restore(); }); +test.serial( + "determineBaseBranchHeadCommitOid accepts SHA-256 OIDs", + async (t) => { + const mergeSha = "a".repeat(64); + const baseOid = "b".repeat(64); + const headOid = "c".repeat(64); + + process.env["GITHUB_EVENT_NAME"] = "pull_request"; + process.env["GITHUB_SHA"] = mergeSha; + + sinon + .stub(gitUtils as any, "runGitCommand") + .resolves(`commit ${mergeSha}\nparent ${baseOid}\nparent ${headOid}\n`); + + const result = await gitUtils.determineBaseBranchHeadCommitOid(__dirname); + t.deepEqual(result, baseOid); + }, +); + test.serial("decodeGitFilePath unquoted strings", async (t) => { t.deepEqual(gitUtils.decodeGitFilePath("foo"), "foo"); t.deepEqual(gitUtils.decodeGitFilePath("foo bar"), "foo bar"); @@ -436,6 +441,64 @@ test.serial("getFileOidsUnderPath handles quoted paths", async (t) => { }); }); +test.serial("getFileOidsUnderPath handles SHA-256 OIDs", async (t) => { + await withTmpDir(async (tmpDir) => { + const sha256OidA = + "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2c0d4b7e8f9a1234567890ab"; + const sha256OidB = + "aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899"; + + sinon + .stub(gitUtils as any, "runGitCommand") + .callsFake(async (_cwd: any, args: any) => { + if (args[0] === "rev-parse") { + return `${tmpDir}\n`; + } + return ( + `100644 ${sha256OidA} 0\tlib/sha256-file-a.js\n` + + `100644 ${sha256OidB} 0\tsrc/sha256-file-b.ts` + ); + }); + + const result = await gitUtils.getFileOidsUnderPath("/fake/path"); + + t.deepEqual(result, { + "lib/sha256-file-a.js": sha256OidA, + "src/sha256-file-b.ts": sha256OidB, + }); + }); +}); + +test.serial( + "getFileOidsUnderPath rejects OIDs of unsupported length", + async (t) => { + await withTmpDir(async (tmpDir) => { + // 50-char OID: not a valid SHA-1 (40) or SHA-256 (64) length. The regex + // must not accept this even though every character is a valid hex digit. + const invalidLine = + "100644 30d998ded095371488be3a729eb61d86ed721a1830d998ded0 0\tlib/bad.js"; + sinon + .stub(gitUtils as any, "runGitCommand") + .callsFake(async (_cwd: any, args: any) => { + if (args[0] === "rev-parse") { + return `${tmpDir}\n`; + } + return invalidLine; + }); + + await t.throwsAsync( + async () => { + await gitUtils.getFileOidsUnderPath("/fake/path"); + }, + { + instanceOf: Error, + message: `Unexpected "git ls-files" output: ${invalidLine}`, + }, + ); + }); + }, +); + test.serial("getFileOidsUnderPath handles empty output", async (t) => { await withTmpDir(async (tmpDir) => { sinon diff --git a/src/git-utils.ts b/src/git-utils.ts index ec0478fa8..0f5bf52a4 100644 --- a/src/git-utils.ts +++ b/src/git-utils.ts @@ -163,11 +163,12 @@ export const determineBaseBranchHeadCommitOid = async function ( } } - // Let's confirm our assumptions: We had a merge commit and the parsed parent data looks correct + // Let's confirm our assumptions: We had a merge commit and the parsed parent + // data looks correct. OIDs are either 40 (SHA-1) or 64 (SHA-256) hex characters. if ( commitOid === mergeSha && - headOid.length === 40 && - baseOid.length === 40 + (headOid.length === 40 || headOid.length === 64) && + (baseOid.length === 40 || baseOid.length === 64) ) { return baseOid; } @@ -296,7 +297,8 @@ export const getFileOidsUnderPath = async function ( // 100644 4c51bc1d9e86cd86e01b0f340cb8ce095c33b283 0\tsrc/git-utils.test.ts // 100644 6b792ea543ce75d7a8a03df591e3c85311ecb64f 0\tsrc/git-utils.ts // The fields are: \t - const regex = /^[0-9]+ ([0-9a-f]{40}) [0-9]+\t(.+)$/; + // The OID is either 40 (SHA-1) or 64 (SHA-256) hex characters. + const regex = /^[0-9]+ ([0-9a-f]{40}|[0-9a-f]{64}) [0-9]+\t(.+)$/; for (const line of stdout.split("\n")) { if (line) { const match = line.match(regex); diff --git a/src/overlay/caching.test.ts b/src/overlay/caching.test.ts index 618a25451..daf3483ed 100644 --- a/src/overlay/caching.test.ts +++ b/src/overlay/caching.test.ts @@ -80,65 +80,46 @@ const testDownloadOverlayBaseDatabaseFromCache = makeMacro({ await fs.promises.writeFile(baseDatabaseOidsFile, JSON.stringify({})); } - const stubs: sinon.SinonStub[] = []; + sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/"); - const getAutomationIDStub = sinon - .stub(apiClient, "getAutomationID") - .resolves("test-automation-id/"); - stubs.push(getAutomationIDStub); - - const isInTestModeStub = sinon - .stub(utils, "isInTestMode") - .returns(testCase.isInTestMode); - stubs.push(isInTestModeStub); + sinon.stub(utils, "isInTestMode").returns(testCase.isInTestMode); if (testCase.restoreCacheResult instanceof Error) { - const restoreCacheStub = sinon + sinon .stub(actionsCache, "restoreCache") .rejects(testCase.restoreCacheResult); - stubs.push(restoreCacheStub); } else { - const restoreCacheStub = sinon + sinon .stub(actionsCache, "restoreCache") .resolves(testCase.restoreCacheResult); - stubs.push(restoreCacheStub); } - const tryGetFolderBytesStub = sinon + sinon .stub(utils, "tryGetFolderBytes") .resolves(testCase.tryGetFolderBytesSucceeds ? 1024 * 1024 : undefined); - stubs.push(tryGetFolderBytesStub); const codeql = mockCodeQLVersion(testCase.codeQLVersion); if (testCase.resolveDatabaseOutput instanceof Error) { - const resolveDatabaseStub = sinon + sinon .stub(codeql, "resolveDatabase") .rejects(testCase.resolveDatabaseOutput); - stubs.push(resolveDatabaseStub); } else { - const resolveDatabaseStub = sinon + sinon .stub(codeql, "resolveDatabase") .resolves(testCase.resolveDatabaseOutput); - stubs.push(resolveDatabaseStub); } - try { - const result = await downloadOverlayBaseDatabaseFromCache( - codeql, - config, - logger, - ); + const result = await downloadOverlayBaseDatabaseFromCache( + codeql, + config, + logger, + ); - if (expectDownloadSuccess) { - t.truthy(result); - } else { - t.is(result, undefined); - } - } finally { - for (const stub of stubs) { - stub.restore(); - } + if (expectDownloadSuccess) { + t.truthy(result); + } else { + t.is(result, undefined); } }); }, diff --git a/src/overlay/index.test.ts b/src/overlay/index.test.ts index 860f32c7b..967ccf3a7 100644 --- a/src/overlay/index.test.ts +++ b/src/overlay/index.test.ts @@ -50,31 +50,21 @@ test.serial( "modified.js": "ddd444", // Changed OID "added.js": "eee555", // New file }; - const getFileOidsStubForOverlay = sinon - .stub(gitUtils, "getFileOidsUnderPath") - .resolves(currentOids); + sinon.stub(gitUtils, "getFileOidsUnderPath").resolves(currentOids); // Write the overlay changes file, which uses the mocked overlay OIDs // and the base database OIDs file const diffRangeFilePath = path.join(tempDir, "pr-diff-range.json"); - const getTempDirStub = sinon - .stub(actionsUtil, "getTemporaryDirectory") - .returns(tempDir); - const getDiffRangesStub = sinon + sinon.stub(actionsUtil, "getTemporaryDirectory").returns(tempDir); + sinon .stub(actionsUtil, "getDiffRangesJsonFilePath") .returns(diffRangeFilePath); - const getGitRootStub = sinon - .stub(gitUtils, "getGitRoot") - .resolves(sourceRoot); + sinon.stub(gitUtils, "getGitRoot").resolves(sourceRoot); const changesFilePath = await writeOverlayChangesFile( config, sourceRoot, logger, ); - getFileOidsStubForOverlay.restore(); - getTempDirStub.restore(); - getDiffRangesStub.restore(); - getGitRootStub.restore(); const fileContent = await fs.promises.readFile(changesFilePath, "utf-8"); const parsedContent = JSON.parse(fileContent) as { changes: string[] }; @@ -128,20 +118,14 @@ test.serial( "modified.js": "ddd444", // Changed OID "reverted.js": "eee555", // Same OID as base -- not detected by OID comparison }; - const getFileOidsStubForOverlay = sinon - .stub(gitUtils, "getFileOidsUnderPath") - .resolves(currentOids); + sinon.stub(gitUtils, "getFileOidsUnderPath").resolves(currentOids); const diffRangeFilePath = path.join(tempDir, "pr-diff-range.json"); - const getTempDirStub = sinon - .stub(actionsUtil, "getTemporaryDirectory") - .returns(tempDir); - const getDiffRangesStub = sinon + sinon.stub(actionsUtil, "getTemporaryDirectory").returns(tempDir); + sinon .stub(actionsUtil, "getDiffRangesJsonFilePath") .returns(diffRangeFilePath); - const getGitRootStub = sinon - .stub(gitUtils, "getGitRoot") - .resolves(sourceRoot); + sinon.stub(gitUtils, "getGitRoot").resolves(sourceRoot); // Write a pr-diff-range.json file with diff ranges including // "reverted.js" (unchanged OIDs) and "modified.js" (already in OID changes) @@ -159,10 +143,6 @@ test.serial( sourceRoot, logger, ); - getFileOidsStubForOverlay.restore(); - getTempDirStub.restore(); - getDiffRangesStub.restore(); - getGitRootStub.restore(); const fileContent = await fs.promises.readFile(changesFilePath, "utf-8"); const parsedContent = JSON.parse(fileContent) as { changes: string[] }; @@ -208,20 +188,14 @@ test.serial( "unchanged.js": "aaa111", "modified.js": "ddd444", }; - const getFileOidsStubForOverlay = sinon - .stub(gitUtils, "getFileOidsUnderPath") - .resolves(currentOids); + sinon.stub(gitUtils, "getFileOidsUnderPath").resolves(currentOids); const diffRangeFilePath = path.join(tempDir, "pr-diff-range.json"); - const getTempDirStub = sinon - .stub(actionsUtil, "getTemporaryDirectory") - .returns(tempDir); - const getDiffRangesStub = sinon + sinon.stub(actionsUtil, "getTemporaryDirectory").returns(tempDir); + sinon .stub(actionsUtil, "getDiffRangesJsonFilePath") .returns(diffRangeFilePath); - const getGitRootStub = sinon - .stub(gitUtils, "getGitRoot") - .resolves(sourceRoot); + sinon.stub(gitUtils, "getGitRoot").resolves(sourceRoot); // No pr-diff-range.json file exists - should work the same as before const changesFilePath = await writeOverlayChangesFile( @@ -229,10 +203,6 @@ test.serial( sourceRoot, logger, ); - getFileOidsStubForOverlay.restore(); - getTempDirStub.restore(); - getDiffRangesStub.restore(); - getGitRootStub.restore(); const fileContent = await fs.promises.readFile(changesFilePath, "utf-8"); const parsedContent = JSON.parse(fileContent) as { changes: string[] }; @@ -281,21 +251,15 @@ test.serial( "app.js": "aaa111", "lib/util.js": "bbb222", }; - const getFileOidsStubForOverlay = sinon - .stub(gitUtils, "getFileOidsUnderPath") - .resolves(currentOids); + sinon.stub(gitUtils, "getFileOidsUnderPath").resolves(currentOids); const diffRangeFilePath = path.join(tempDir, "pr-diff-range.json"); - const getTempDirStub = sinon - .stub(actionsUtil, "getTemporaryDirectory") - .returns(tempDir); - const getDiffRangesStub = sinon + sinon.stub(actionsUtil, "getTemporaryDirectory").returns(tempDir); + sinon .stub(actionsUtil, "getDiffRangesJsonFilePath") .returns(diffRangeFilePath); // getGitRoot returns the repo root (parent of sourceRoot) - const getGitRootStub = sinon - .stub(gitUtils, "getGitRoot") - .resolves(repoRoot); + sinon.stub(gitUtils, "getGitRoot").resolves(repoRoot); // Diff ranges use repo-root-relative paths (as returned by the GitHub compare API) await fs.promises.writeFile( @@ -312,10 +276,6 @@ test.serial( sourceRoot, logger, ); - getFileOidsStubForOverlay.restore(); - getTempDirStub.restore(); - getDiffRangesStub.restore(); - getGitRootStub.restore(); const fileContent = await fs.promises.readFile(changesFilePath, "utf-8"); const parsedContent = JSON.parse(fileContent) as { changes: string[] }; diff --git a/src/tools-features.test.ts b/src/tools-features.test.ts index 2192ea7a4..825b9c1eb 100644 --- a/src/tools-features.test.ts +++ b/src/tools-features.test.ts @@ -6,9 +6,13 @@ import { ToolsFeature, isSupportedToolsFeature } from "./tools-features"; test("isSupportedToolsFeature", async (t) => { const versionInfo = makeVersionInfo("1.0.0"); - t.false(isSupportedToolsFeature(versionInfo, ToolsFeature.ForceOverwrite)); + t.false( + isSupportedToolsFeature(versionInfo, ToolsFeature.BundleSupportsOverlay), + ); - versionInfo.features = { forceOverwrite: true }; + versionInfo.features = { bundleSupportsOverlay: true }; - t.true(isSupportedToolsFeature(versionInfo, ToolsFeature.ForceOverwrite)); + t.true( + isSupportedToolsFeature(versionInfo, ToolsFeature.BundleSupportsOverlay), + ); }); diff --git a/src/tools-features.ts b/src/tools-features.ts index bba64de23..ff87b754d 100644 --- a/src/tools-features.ts +++ b/src/tools-features.ts @@ -6,8 +6,6 @@ export enum ToolsFeature { BuiltinExtractorsSpecifyDefaultQueries = "builtinExtractorsSpecifyDefaultQueries", BundleSupportsIncludeOption = "bundleSupportsIncludeOption", BundleSupportsOverlay = "bundleSupportsOverlay", - DatabaseInterpretResultsSupportsSarifRunProperty = "databaseInterpretResultsSupportsSarifRunProperty", - ForceOverwrite = "forceOverwrite", IndirectTracingSupportsStaticBinaries = "indirectTracingSupportsStaticBinaries", SuppressesMissingFileBaselineWarning = "suppressesMissingFileBaselineWarning", } diff --git a/src/util.test.ts b/src/util.test.ts index 63b9263e0..cca457cbe 100644 --- a/src/util.test.ts +++ b/src/util.test.ts @@ -418,9 +418,7 @@ for (const [ `checkActionVersion ${reportErrorDescription} for ${versionsDescription}`, async (t) => { const warningSpy = sinon.spy(core, "warning"); - const versionStub = sinon - .stub(api, "getGitHubVersion") - .resolves(githubVersion); + sinon.stub(api, "getGitHubVersion").resolves(githubVersion); // call checkActionVersion twice and assert below that warning is reported only once util.checkActionVersion(version, await api.getGitHubVersion()); @@ -437,7 +435,6 @@ for (const [ } else { t.false(warningSpy.called); } - versionStub.restore(); }, ); }