Compare commits

..

40 Commits

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

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-14 10:34:00 +00:00
Henry Mercer 3c8c0ae6cb Remove unnecessary sinon restore calls 2026-05-13 18:53:33 +01:00
Henry Mercer 93d215d874 Merge branch 'main' into henrymercer/sha256 2026-05-13 18:44:38 +01:00
Henry Mercer 9c3aedb4cd Update PR check testing matrix 2026-05-13 14:25:03 +01:00
Henry Mercer a66f7bbb5a Merge branch 'main' into henrymercer/sha256 2026-05-13 10:51:44 +01:00
Henry Mercer b986640672 Add note about CODEQL_VERSION_ZSTD_BUNDLE 2026-05-12 19:26:23 +01:00
Henry Mercer a333d64ec4 Remove DatabaseInterpretResultsSupportsSarifRunProperty tools feature
This feature has been supported since CodeQL CLI v2.19.0
2026-05-12 19:26:21 +01:00
Henry Mercer 97fb30df6b Remove ForceOverwrite tools feature
This feature has been supported since CodeQL CLI v2.18.0, which is below the new minimum version.
2026-05-12 19:26:20 +01:00
Henry Mercer d122da3c9f Bump minimum CodeQL CLI version to 2.19.4 2026-05-12 19:26:20 +01:00
Henry Mercer de3e561d12 Improve regex clarity 2026-05-12 19:06:04 +01:00
Henry Mercer 6a4e35fad9 Add support for SHA-256 Git object IDs 2026-05-12 18:24:21 +01:00
40 changed files with 573 additions and 512 deletions
+13 -8
View File
@@ -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')
+4 -4
View File
@@ -49,10 +49,6 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: stable-v2.17.6
- os: ubuntu-latest
version: stable-v2.18.4
- os: ubuntu-latest
version: stable-v2.19.4
- os: ubuntu-latest
@@ -61,6 +57,10 @@ jobs:
version: stable-v2.21.4
- os: ubuntu-latest
version: stable-v2.22.4
- os: ubuntu-latest
version: stable-v2.23.9
- os: ubuntu-latest
version: stable-v2.24.3
- os: ubuntu-latest
version: default
- os: ubuntu-latest
+4 -4
View File
@@ -49,10 +49,6 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: stable-v2.17.6
- os: ubuntu-latest
version: stable-v2.18.4
- os: ubuntu-latest
version: stable-v2.19.4
- os: ubuntu-latest
@@ -61,6 +57,10 @@ jobs:
version: stable-v2.21.4
- os: ubuntu-latest
version: stable-v2.22.4
- os: ubuntu-latest
version: stable-v2.23.9
- os: ubuntu-latest
version: stable-v2.24.3
- os: ubuntu-latest
version: default
- os: ubuntu-latest
+4 -4
View File
@@ -49,10 +49,6 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: stable-v2.17.6
- os: ubuntu-latest
version: stable-v2.18.4
- os: ubuntu-latest
version: stable-v2.19.4
- os: ubuntu-latest
@@ -61,6 +57,10 @@ jobs:
version: stable-v2.21.4
- os: ubuntu-latest
version: stable-v2.22.4
- os: ubuntu-latest
version: stable-v2.23.9
- os: ubuntu-latest
version: stable-v2.24.3
- os: ubuntu-latest
version: default
- os: ubuntu-latest
+15 -15
View File
@@ -59,41 +59,41 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: stable-v2.17.6
- os: macos-latest
version: stable-v2.17.6
- os: ubuntu-latest
version: stable-v2.18.4
- os: macos-latest
version: stable-v2.18.4
- os: ubuntu-latest
version: stable-v2.19.4
- os: macos-latest
- os: macos-latest-xlarge
version: stable-v2.19.4
- os: ubuntu-latest
version: stable-v2.20.7
- os: macos-latest
- os: macos-latest-xlarge
version: stable-v2.20.7
- os: ubuntu-latest
version: stable-v2.21.4
- os: macos-latest
- os: macos-latest-xlarge
version: stable-v2.21.4
- os: ubuntu-latest
version: stable-v2.22.4
- os: macos-latest
- os: macos-latest-xlarge
version: stable-v2.22.4
- os: ubuntu-latest
version: stable-v2.23.9
- os: macos-latest-xlarge
version: stable-v2.23.9
- os: ubuntu-latest
version: stable-v2.24.3
- os: macos-latest-xlarge
version: stable-v2.24.3
- os: ubuntu-latest
version: default
- os: macos-latest
- os: macos-latest-xlarge
version: default
- os: ubuntu-latest
version: linked
- os: macos-latest
- os: macos-latest-xlarge
version: linked
- os: ubuntu-latest
version: nightly-latest
- os: macos-latest
- os: macos-latest-xlarge
version: nightly-latest
name: Multi-language repository
if: github.triggering_actor != 'dependabot[bot]'
+1 -1
View File
@@ -40,7 +40,7 @@ jobs:
matrix:
include:
- os: ubuntu-latest
version: stable-v2.19.3
version: stable-v2.19.4
- os: ubuntu-latest
version: stable-v2.22.1
- os: ubuntu-latest
+1 -1
View File
@@ -39,7 +39,7 @@ jobs:
fail-fast: false
matrix:
include:
- os: macos-latest
- os: macos-latest-xlarge
version: nightly-latest
name: Swift analysis using autobuild
if: github.triggering_actor != 'dependabot[bot]'
+1 -1
View File
@@ -77,7 +77,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04,ubuntu-24.04,windows-2022,windows-2025,macos-14,macos-15]
os: [ubuntu-22.04,ubuntu-24.04,windows-2022,windows-2025,macos-14-xlarge,macos-15-xlarge]
tools: ${{ fromJson(needs.check-codeql-versions.outputs.versions) }}
runs-on: ${{ matrix.os }}
+4 -2
View File
@@ -64,11 +64,12 @@ jobs:
- name: Update current release branch
if: github.event_name == 'workflow_dispatch'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo SOURCE_BRANCH=${REF_NAME}
echo TARGET_BRANCH=releases/${MAJOR_VERSION}
python .github/update-release-branch.py \
--github-token ${{ secrets.GITHUB_TOKEN }} \
--repository-nwo ${{ github.repository }} \
--source-branch '${{ env.REF_NAME }}' \
--target-branch 'releases/${{ env.MAJOR_VERSION }}' \
@@ -107,11 +108,12 @@ jobs:
- uses: ./.github/actions/release-initialise
- name: Update older release branch
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo SOURCE_BRANCH=${SOURCE_BRANCH}
echo TARGET_BRANCH=${TARGET_BRANCH}
python .github/update-release-branch.py \
--github-token ${{ secrets.GITHUB_TOKEN }} \
--repository-nwo ${{ github.repository }} \
--source-branch ${SOURCE_BRANCH} \
--target-branch ${TARGET_BRANCH} \
+5
View File
@@ -2,6 +2,11 @@
See the [releases page](https://github.com/github/codeql-action/releases) for the relevant changes to the CodeQL CLI and language packs.
## [UNRELEASED]
- _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
- 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)
+1 -1
View File
@@ -71,7 +71,7 @@ Once the mergeback and backport pull request have been merged, the release is co
Since the `codeql-action` runs most of its testing through individual Actions workflows, there are over two hundred required jobs that need to pass in order for a PR to turn green. It would be too tedious to maintain that list manually. You can regenerate the set of required checks automatically by running the [sync-checks.ts](pr-checks/sync-checks.ts) script:
- At a minimum, you must provide an argument for the `--token` input. For example, `--token "$(gh auth token)"` to use the same token that `gh` uses. If no token is provided or the token has insufficient permissions, the script will fail.
- At a minimum, you must provide a token with permissions to update branch protection rules. For example, `gh auth token | pr-checks/sync-checks.ts --token-stdin` uses the same token that `gh` uses. You can also set the `GH_TOKEN` or `GITHUB_TOKEN` environment variable. If no token is provided or the token has insufficient permissions, the script will fail.
- By default, the script performs a dry run and outputs information about the changes it would make to the branch protection rules. To actually apply the changes, specify the `--apply` flag.
- If you run the script without any other arguments, it will retrieve the set of workflows that ran for the latest commit on `main`.
- You can specify a different git ref with the `--ref` input. You will likely want to use this if you have a PR that removes or adds PR checks. For example, `--ref "some/branch/name"` to use the HEAD of the `some/branch/name` branch.
-2
View File
@@ -78,8 +78,6 @@ We typically release new minor versions of the CodeQL Action and Bundle when a n
| `v3.28.21` | `2.21.3` | Enterprise Server 3.18 | |
| `v3.28.12` | `2.20.7` | Enterprise Server 3.17 | |
| `v3.28.6` | `2.20.3` | Enterprise Server 3.16 | |
| `v3.28.6` | `2.20.3` | Enterprise Server 3.15 | |
| `v3.28.6` | `2.20.3` | Enterprise Server 3.14 | |
See the full list of GHES release and deprecation dates at [GitHub Enterprise Server releases](https://docs.github.com/en/enterprise-server/admin/all-releases#releases-of-github-enterprise-server).
+7 -7
View File
@@ -66,8 +66,8 @@ const onEndPlugin = {
const SHARED_ENTRYPOINT = "entry-points";
/**
* This plugin finds all source files that contain action entry points.
* It then generates the virtual `entry-points` module which imports all identifies files,
* This plugin finds all source files that contain Action entry points.
* It then generates the virtual `entry-points` module which imports all identified files,
* and re-exports their `runWrapper` functions with suitable aliases.
* A tiny stub file is emitted for each Action entrypoint. Each stub imports the shared bundle
* and calls the respective entry point.
@@ -83,7 +83,7 @@ const entryPointsPlugin = {
const toPascal = (s) =>
s.replace(/(^|-)([a-z0-9])/gi, (_, __, c) => c.toUpperCase());
// Find the source files containing action entry points.
// Find the source files containing Action entry points.
build.onStart(() => {
const actionFiles = globSync("src/*-action{,-post}.ts");
for (const actionFile of actionFiles) {
@@ -112,7 +112,7 @@ const entryPointsPlugin = {
return { path: SHARED_ENTRYPOINT, namespace };
});
// Generate the virtual `entry-points` file based on the actions we discovered.
// Generate the virtual `entry-points` file based on the Actions we discovered.
// Restrict using the namespace. The path filter does not need to discriminate any further.
build.onLoad({ filter: /.*/, namespace }, async () => {
const wrapperTemplatePath = "entry-wrapper.js.tpl";
@@ -127,7 +127,7 @@ const entryPointsPlugin = {
const imports = actionsSorted
.map(
(action) =>
`import * as ${action.pascalCaseName} from "./src/${basename(action.path)}"`,
`import * as ${action.pascalCaseName} from "./src/${basename(action.path)}";`,
)
.join("\n");
const wrappers = actionsSorted
@@ -143,7 +143,7 @@ const entryPointsPlugin = {
};
});
// Emit entry point stubs for each action using the entry template.
// Emit entry point stubs for each Action using the entry template.
build.onEnd(async (result) => {
// Read the entry point template.
const templatePath = "action-entry.js.tpl";
@@ -152,7 +152,7 @@ const entryPointsPlugin = {
const makeHeader = (sourceFile) =>
`// Automatically generated from '${templatePath}' for 'src/${basename(sourceFile)}'.\n\n`;
// Write entry point stubs for each action.
// Write entry point stubs for each Action.
for (const action of actions) {
await writeFile(
join(
+19 -37
View File
@@ -148304,7 +148304,7 @@ function getDiffRangesJsonFilePath() {
return path2.join(getTemporaryDirectory(), PR_DIFF_RANGE_JSON_FILENAME);
}
function getActionVersion() {
return "4.35.5";
return "4.36.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);
@@ -149475,11 +149475,6 @@ var featureConfig = {
minimumVersion: void 0,
toolsFeature: "suppressesMissingFileBaselineWarning" /* SuppressesMissingFileBaselineWarning */
},
["start_proxy_remove_unused_registries" /* StartProxyRemoveUnusedRegistries */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_START_PROXY_REMOVE_UNUSED_REGISTRIES",
minimumVersion: void 0
},
["start_proxy_use_features_release" /* StartProxyUseFeaturesRelease */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_START_PROXY_USE_FEATURES_RELEASE",
@@ -153719,7 +153714,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 +153841,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 +153861,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 +153872,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 +154044,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 +154325,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
@@ -160350,15 +160346,6 @@ function isPAT(value) {
]);
}
var LANGUAGE_TO_REGISTRY_TYPE = {
java: ["maven_repository"],
csharp: ["nuget_feed"],
javascript: ["npm_registry"],
python: ["python_index"],
ruby: ["rubygems_server"],
rust: ["cargo_registry"],
go: ["goproxy_server", "git_source"]
};
var NEW_LANGUAGE_TO_REGISTRY_TYPE = {
actions: [],
cpp: [],
java: ["maven_repository"],
@@ -160387,9 +160374,8 @@ function getRegistryAddress(registry) {
);
}
}
function getCredentials(logger, registrySecrets, registriesCredentials, language, skipUnusedRegistries = false) {
const registryMapping = skipUnusedRegistries ? NEW_LANGUAGE_TO_REGISTRY_TYPE : LANGUAGE_TO_REGISTRY_TYPE;
const registryTypeForLanguage = language ? registryMapping[language] : void 0;
function getCredentials(logger, registrySecrets, registriesCredentials, language) {
const registryTypeForLanguage = language ? LANGUAGE_TO_REGISTRY_TYPE[language] : void 0;
let credentialsStr;
if (registriesCredentials !== void 0) {
logger.info(`Using registries_credentials input.`);
@@ -160913,15 +160899,11 @@ async function run7(startedAt) {
);
const languageInput = getOptionalInput("language");
language = languageInput ? parseBuiltInLanguage(languageInput) : void 0;
const skipUnusedRegistries = await features.getValue(
"start_proxy_remove_unused_registries" /* StartProxyRemoveUnusedRegistries */
);
const credentials = getCredentials(
logger,
getOptionalInput("registry_secrets"),
getOptionalInput("registries_credentials"),
language,
skipUnusedRegistries
language
);
if (credentials.length === 0) {
logger.info("No credentials found, skipping proxy setup.");
+16 -20
View File
@@ -88509,7 +88509,7 @@ function getDiffRangesJsonFilePath() {
return path2.join(getTemporaryDirectory(), PR_DIFF_RANGE_JSON_FILENAME);
}
function getActionVersion() {
return "4.35.5";
return "4.36.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);
@@ -89498,11 +89498,6 @@ var featureConfig = {
minimumVersion: void 0,
toolsFeature: "suppressesMissingFileBaselineWarning" /* SuppressesMissingFileBaselineWarning */
},
["start_proxy_remove_unused_registries" /* StartProxyRemoveUnusedRegistries */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_START_PROXY_REMOVE_UNUSED_REGISTRIES",
minimumVersion: void 0
},
["start_proxy_use_features_release" /* StartProxyUseFeaturesRelease */]: {
defaultValue: false,
envVar: "CODEQL_ACTION_START_PROXY_USE_FEATURES_RELEASE",
@@ -91212,7 +91207,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 +91334,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 +91354,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 +91365,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 +91537,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 +91818,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
+14 -14
View File
@@ -1,12 +1,12 @@
{
"name": "codeql",
"version": "4.35.5",
"version": "4.36.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "codeql",
"version": "4.35.5",
"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",
+4 -3
View File
@@ -1,6 +1,6 @@
{
"name": "codeql",
"version": "4.35.5",
"version": "4.36.0",
"private": true,
"description": "CodeQL action",
"scripts": {
@@ -12,7 +12,8 @@
"ava": "npm run transpile && ava --verbose",
"test": "npm run ava -- src/",
"test-debug": "npm run test -- --timeout=20m",
"transpile": "tsc --build --verbose tsconfig.json"
"transpile": "tsc --build --verbose tsconfig.json",
"update-pr-checks": "./pr-checks/sync.sh"
},
"license": "MIT",
"workspaces": [
@@ -66,7 +67,7 @@
"glob": "^11.1.0",
"globals": "^17.6.0",
"nock": "^14.0.12",
"sinon": "^21.1.2",
"sinon": "^22.0.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.59.2"
},
@@ -2,7 +2,8 @@ name: "Multi-language repository"
description: "An end-to-end integration test of a multi-language repository using automatic language detection"
operatingSystems:
- ubuntu
- macos
- os: macos
runner-image: macos-latest-xlarge
env:
CODEQL_ACTION_RESOLVE_SUPPORTED_LANGUAGES_USING_CLI: true
installGo: true
+1 -1
View File
@@ -2,7 +2,7 @@ name: "Rust analysis"
description: "Tests creation of a Rust database"
versions:
# experimental rust support introduced, requires action to set `CODEQL_ENABLE_EXPERIMENTAL_FEATURES`
- stable-v2.19.3
- stable-v2.19.4
# first public preview version
- stable-v2.22.1
- linked
+2 -1
View File
@@ -3,7 +3,8 @@ description: "Tests creation of a Swift database using autobuild"
versions:
- nightly-latest
operatingSystems:
- macos
- os: macos
runner-image: macos-latest-xlarge
steps:
- uses: ./../action/init
id: init
+50 -1
View File
@@ -7,7 +7,13 @@ Tests for the sync-checks.ts script
import * as assert from "node:assert/strict";
import { describe, it } from "node:test";
import { CheckInfo, Exclusions, Options, removeExcluded } from "./sync-checks";
import {
CheckInfo,
Exclusions,
Options,
removeExcluded,
resolveToken,
} from "./sync-checks";
const defaultOptions: Options = {
apply: false,
@@ -58,3 +64,46 @@ describe("removeExcluded", async () => {
assert.deepEqual(retained, expectedExactMatches);
});
});
describe("resolveToken", async () => {
await it("reads the token from standard input", async () => {
const token = await resolveToken(
{ tokenStdin: true },
{ env: {}, readStdin: async () => " stdin-token\n" },
);
assert.equal(token, "stdin-token");
});
await it("reads the token from the GH_TOKEN environment variable", async () => {
const token = await resolveToken(
{},
{ env: { GH_TOKEN: "env-token" }, readStdin: async () => "" },
);
assert.equal(token, "env-token");
});
await it("reads the token from the GITHUB_TOKEN environment variable", async () => {
const token = await resolveToken(
{},
{ env: { GITHUB_TOKEN: "env-token" }, readStdin: async () => "" },
);
assert.equal(token, "env-token");
});
await it("rejects an empty standard input token", async () => {
await assert.rejects(
resolveToken(
{ tokenStdin: true },
{ env: {}, readStdin: async () => "\n" },
),
/No token received on standard input/,
);
});
await it("rejects missing token sources", async () => {
await assert.rejects(
resolveToken({}, { env: {}, readStdin: async () => "" }),
/Missing authentication token/,
);
});
});
+69 -9
View File
@@ -15,8 +15,8 @@ import {
/** Represents the command-line options. */
export interface Options {
/** The token to use to authenticate to the GitHub API. */
token?: string;
/** Whether to read the GitHub API token from standard input. */
tokenStdin?: boolean;
/** The git ref to use the checks for. */
ref?: string;
/** Whether to actually apply the changes or not. */
@@ -31,6 +31,65 @@ const codeqlActionRepo = {
repo: "codeql-action",
};
/** Environment variables to check for a GitHub API token. */
const TOKEN_ENVIRONMENT_VARIABLES = ["GH_TOKEN", "GITHUB_TOKEN"];
/** Represents the sources from which we can retrieve the GitHub API token. */
interface TokenSource {
/** Environment variables to inspect. */
env: NodeJS.ProcessEnv;
/** Reads a token from standard input. */
readStdin: () => Promise<string>;
}
/** Reads the GitHub API token from standard input. */
async function readTokenFromStdin(): Promise<string> {
let token = "";
process.stdin.setEncoding("utf8");
for await (const chunk of process.stdin) {
token += chunk;
}
return token.trim();
}
/** Gets a GitHub API token from one of the supported environment variables. */
function getTokenFromEnvironment(env: NodeJS.ProcessEnv): string | undefined {
for (const variableName of TOKEN_ENVIRONMENT_VARIABLES) {
const token = env[variableName]?.trim();
if (token) {
return token;
}
}
return undefined;
}
/** Gets the token to use to authenticate to the GitHub API. */
export async function resolveToken(
options: Pick<Options, "tokenStdin">,
tokenSource: TokenSource = {
env: process.env,
readStdin: readTokenFromStdin,
},
): Promise<string> {
if (options.tokenStdin) {
const token = (await tokenSource.readStdin()).trim();
if (token.length === 0) {
throw new Error("No token received on standard input.");
}
return token;
}
const environmentToken = getTokenFromEnvironment(tokenSource.env);
if (environmentToken !== undefined) {
return environmentToken;
}
throw new Error(
"Missing authentication token. Set GH_TOKEN/GITHUB_TOKEN or pipe a token " +
"to --token-stdin.",
);
}
/** Represents a configuration of which checks should not be set up as required checks. */
export interface Exclusions {
/** A list of strings that, if contained in a check name, are excluded. */
@@ -205,9 +264,10 @@ async function updateBranch(
async function main(): Promise<void> {
const { values: options } = parseArgs({
options: {
// The token to use to authenticate to the API.
token: {
type: "string",
// Read the token to use to authenticate to the API from standard input.
"token-stdin": {
type: "boolean",
default: false,
},
// The git ref for which to retrieve the check runs.
ref: {
@@ -228,16 +288,16 @@ async function main(): Promise<void> {
strict: true,
});
if (options.token === undefined) {
throw new Error("Missing --token");
}
const token = await resolveToken({
tokenStdin: options["token-stdin"],
});
console.info(
`Oldest supported major version is: ${OLDEST_SUPPORTED_MAJOR_VERSION}`,
);
// Initialise the API client.
const client = getApiClient(options.token);
const client = getApiClient(token);
// Find the check runs for the specified `ref` that we will later set as the required checks
// for the main and release branches.
+42 -11
View File
@@ -28,6 +28,24 @@ interface WorkflowInput {
/** A partial mapping from known input names to input definitions. */
type WorkflowInputs = Partial<Record<KnownInputName, WorkflowInput>>;
/** An operating system identifier. */
type OperatingSystemIdentifier = "ubuntu" | "macos" | "windows";
/**
* Represents an operating system matrix entry for a generated PR check workflow.
*
* Either a string containing the OS identifier or an object containing the OS identifier and an
* optional runner image label.
*/
type OperatingSystem =
| OperatingSystemIdentifier
| {
/** OS identifier. */
os: OperatingSystemIdentifier;
/** Optional runner image label. */
"runner-image"?: string;
};
/**
* Represents PR check specifications.
*/
@@ -36,8 +54,8 @@ interface Specification extends JobSpecification {
inputs?: Record<string, WorkflowInput>;
/** CodeQL bundle versions to test against. Defaults to `DEFAULT_TEST_VERSIONS`. */
versions?: string[];
/** Operating system prefixes used to select runner images (e.g. `["ubuntu", "macos"]`). */
operatingSystems?: string[];
/** Operating system prefixes, either as strings or with explicit runner image labels. */
operatingSystems?: OperatingSystem[];
/** Per-OS version overrides. If specified for an OS, only those versions are tested on that OS. */
osCodeQlVersions?: Record<string, string[]>;
/** Whether to use the all-platform CodeQL bundle. */
@@ -97,10 +115,6 @@ type LanguageSetups = Partial<Record<BuiltInLanguage, LanguageSetup>>;
// The default set of CodeQL Bundle versions to use for the PR checks.
const defaultTestVersions = [
// The oldest supported CodeQL version. If bumping, update `CODEQL_MINIMUM_VERSION` in `codeql.ts`
"stable-v2.17.6",
// The last CodeQL release in the 2.18 series.
"stable-v2.18.4",
// The last CodeQL release in the 2.19 series.
"stable-v2.19.4",
// The last CodeQL release in the 2.20 series.
"stable-v2.20.7",
@@ -108,6 +122,10 @@ const defaultTestVersions = [
"stable-v2.21.4",
// The last CodeQL release in the 2.22 series.
"stable-v2.22.4",
// The last CodeQL release in the 2.23 series.
"stable-v2.23.9",
// The last CodeQL release in the 2.24 series.
"stable-v2.24.3",
// The default version of CodeQL for Dotcom, as determined by feature flags.
"default",
// The version of CodeQL shipped with the Action in `defaults.json`. During the release process
@@ -311,10 +329,19 @@ function generateJobMatrix(
);
}
const runnerImages = ["ubuntu-latest", "macos-latest", "windows-latest"];
const defaultRunnerImages = [
"ubuntu-latest",
"macos-latest",
"windows-latest",
];
const operatingSystems = checkSpecification.operatingSystems ?? ["ubuntu"];
for (const operatingSystem of operatingSystems) {
for (const operatingSystemConfig of operatingSystems) {
const operatingSystem =
typeof operatingSystemConfig === "string"
? operatingSystemConfig
: operatingSystemConfig.os;
// If osCodeQlVersions is set for this OS, only include the specified CodeQL versions.
const allowedVersions =
checkSpecification.osCodeQlVersions?.[operatingSystem];
@@ -322,9 +349,13 @@ function generateJobMatrix(
continue;
}
const runnerImagesForOs = runnerImages.filter((image) =>
image.startsWith(operatingSystem),
);
const runnerImagesForOs =
typeof operatingSystemConfig === "string" ||
operatingSystemConfig["runner-image"] === undefined
? defaultRunnerImages.filter((image) =>
image.startsWith(operatingSystem),
)
: [operatingSystemConfig["runner-image"]];
for (const runnerImage of runnerImagesForOs) {
matrix.push({
-85
View File
@@ -1,85 +0,0 @@
import test from "ava";
import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import * as analyze from "./analyze";
import { runWrapper } from "./analyze-action";
import * as api from "./api-client";
import * as configUtils from "./config-utils";
import * as gitUtils from "./git-utils";
import * as statusReport from "./status-report";
import {
setupTests,
setupActionsVars,
mockFeatureFlagApiEndpoint,
} from "./testing-utils";
import * as util from "./util";
setupTests(test);
// This test needs to be in its own file so that ava would run it in its own
// nodejs process. The code being tested is in analyze-action.ts, which runs
// immediately on load. So the file needs to be loaded during part of the test,
// and that can happen only once per nodejs process. If multiple such tests are
// in the same test file, ava would run them in the same nodejs process, and all
// but the first test would fail.
test("analyze action with RAM & threads from environment variables", async (t) => {
// This test frequently times out on Windows with the default timeout, so we bump
// it a bit to 20s.
t.timeout(1000 * 20);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
sinon
.stub(statusReport, "createStatusReportBase")
.resolves({} as statusReport.StatusReportBase);
sinon.stub(statusReport, "sendStatusReport").resolves();
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
const gitHubVersion: util.GitHubVersion = {
type: util.GitHubVariant.DOTCOM,
};
sinon.stub(configUtils, "getConfig").resolves({
gitHubVersion,
augmentationProperties: {},
languages: [],
packs: [],
trapCaches: {},
} as unknown as configUtils.Config);
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
requiredInputStub.withArgs("token").returns("fake-token");
requiredInputStub.withArgs("upload-database").returns("false");
requiredInputStub.withArgs("output").returns("out");
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
optionalInputStub.withArgs("expect-error").returns("false");
sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion);
mockFeatureFlagApiEndpoint(200, {});
// When there are no action inputs for RAM and threads, the action uses
// environment variables (passed down from the init action) to set RAM and
// threads usage.
process.env["CODEQL_THREADS"] = "-1";
process.env["CODEQL_RAM"] = "4992";
const runFinalizeStub = sinon.stub(analyze, "runFinalize");
const runQueriesStub = sinon.stub(analyze, "runQueries");
await runWrapper();
t.assert(
runFinalizeStub.calledOnceWith(
sinon.match.any,
sinon.match.any,
"--threads=-1",
"--ram=4992",
),
);
t.assert(
runQueriesStub.calledOnceWith(
sinon.match.any,
"--ram=4992",
"--threads=-1",
),
);
});
});
-83
View File
@@ -1,83 +0,0 @@
import test from "ava";
import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import * as analyze from "./analyze";
import { runWrapper } from "./analyze-action";
import * as api from "./api-client";
import * as configUtils from "./config-utils";
import * as gitUtils from "./git-utils";
import * as statusReport from "./status-report";
import {
setupTests,
setupActionsVars,
mockFeatureFlagApiEndpoint,
} from "./testing-utils";
import * as util from "./util";
setupTests(test);
// This test needs to be in its own file so that ava would run it in its own
// nodejs process. The code being tested is in analyze-action.ts, which runs
// immediately on load. So the file needs to be loaded during part of the test,
// and that can happen only once per nodejs process. If multiple such tests are
// in the same test file, ava would run them in the same nodejs process, and all
// but the first test would fail.
test("analyze action with RAM & threads from action inputs", async (t) => {
t.timeout(1000 * 20);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
sinon
.stub(statusReport, "createStatusReportBase")
.resolves({} as statusReport.StatusReportBase);
sinon.stub(statusReport, "sendStatusReport").resolves();
const gitHubVersion: util.GitHubVersion = {
type: util.GitHubVariant.DOTCOM,
};
sinon.stub(configUtils, "getConfig").resolves({
gitHubVersion,
augmentationProperties: {},
languages: [],
packs: [],
trapCaches: {},
} as unknown as configUtils.Config);
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
requiredInputStub.withArgs("token").returns("fake-token");
requiredInputStub.withArgs("upload-database").returns("false");
requiredInputStub.withArgs("output").returns("out");
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
optionalInputStub.withArgs("expect-error").returns("false");
sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion);
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
mockFeatureFlagApiEndpoint(200, {});
process.env["CODEQL_THREADS"] = "1";
process.env["CODEQL_RAM"] = "4992";
// Action inputs have precedence over environment variables.
optionalInputStub.withArgs("threads").returns("-1");
optionalInputStub.withArgs("ram").returns("3012");
const runFinalizeStub = sinon.stub(analyze, "runFinalize");
const runQueriesStub = sinon.stub(analyze, "runQueries");
await runWrapper();
t.assert(
runFinalizeStub.calledOnceWith(
sinon.match.any,
sinon.match.any,
"--threads=-1",
"--ram=3012",
),
);
t.assert(
runQueriesStub.calledOnceWith(
sinon.match.any,
"--ram=3012",
"--threads=-1",
),
);
});
});
+142
View File
@@ -0,0 +1,142 @@
import test from "ava";
import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import * as analyze from "./analyze";
import { runWrapper } from "./analyze-action";
import * as api from "./api-client";
import * as configUtils from "./config-utils";
import * as gitUtils from "./git-utils";
import * as statusReport from "./status-report";
import {
setupTests,
setupActionsVars,
mockFeatureFlagApiEndpoint,
} from "./testing-utils";
import * as util from "./util";
setupTests(test);
test.serial(
"analyze action with RAM & threads from environment variables",
async (t) => {
// This test frequently times out on Windows with the default timeout, so we bump
// it a bit to 20s.
t.timeout(1000 * 20);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
sinon
.stub(statusReport, "createStatusReportBase")
.resolves({} as statusReport.StatusReportBase);
sinon.stub(statusReport, "sendStatusReport").resolves();
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
const gitHubVersion: util.GitHubVersion = {
type: util.GitHubVariant.DOTCOM,
};
sinon.stub(configUtils, "getConfig").resolves({
gitHubVersion,
augmentationProperties: {},
languages: [],
packs: [],
trapCaches: {},
} as unknown as configUtils.Config);
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
requiredInputStub.withArgs("token").returns("fake-token");
requiredInputStub.withArgs("upload-database").returns("false");
requiredInputStub.withArgs("output").returns("out");
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
optionalInputStub.withArgs("expect-error").returns("false");
sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion);
mockFeatureFlagApiEndpoint(200, {});
// When there are no action inputs for RAM and threads, the action uses
// environment variables (passed down from the init action) to set RAM and
// threads usage.
process.env["CODEQL_THREADS"] = "-1";
process.env["CODEQL_RAM"] = "4992";
const runFinalizeStub = sinon.stub(analyze, "runFinalize");
const runQueriesStub = sinon.stub(analyze, "runQueries");
await runWrapper();
t.assert(
runFinalizeStub.calledOnceWith(
sinon.match.any,
sinon.match.any,
"--threads=-1",
"--ram=4992",
),
);
t.assert(
runQueriesStub.calledOnceWith(
sinon.match.any,
"--ram=4992",
"--threads=-1",
),
);
});
},
);
test.serial(
"analyze action with RAM & threads from action inputs",
async (t) => {
t.timeout(1000 * 20);
await util.withTmpDir(async (tmpDir) => {
setupActionsVars(tmpDir, tmpDir);
sinon
.stub(statusReport, "createStatusReportBase")
.resolves({} as statusReport.StatusReportBase);
sinon.stub(statusReport, "sendStatusReport").resolves();
const gitHubVersion: util.GitHubVersion = {
type: util.GitHubVariant.DOTCOM,
};
sinon.stub(configUtils, "getConfig").resolves({
gitHubVersion,
augmentationProperties: {},
languages: [],
packs: [],
trapCaches: {},
} as unknown as configUtils.Config);
const requiredInputStub = sinon.stub(actionsUtil, "getRequiredInput");
requiredInputStub.withArgs("token").returns("fake-token");
requiredInputStub.withArgs("upload-database").returns("false");
requiredInputStub.withArgs("output").returns("out");
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
optionalInputStub.withArgs("expect-error").returns("false");
sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion);
sinon.stub(gitUtils, "isAnalyzingDefaultBranch").resolves(true);
mockFeatureFlagApiEndpoint(200, {});
process.env["CODEQL_THREADS"] = "1";
process.env["CODEQL_RAM"] = "4992";
// Action inputs have precedence over environment variables.
optionalInputStub.withArgs("threads").returns("-1");
optionalInputStub.withArgs("ram").returns("3012");
const runFinalizeStub = sinon.stub(analyze, "runFinalize");
const runQueriesStub = sinon.stub(analyze, "runQueries");
await runWrapper();
t.assert(
runFinalizeStub.calledOnceWith(
sinon.match.any,
sinon.match.any,
"--threads=-1",
"--ram=3012",
),
);
t.assert(
runQueriesStub.calledOnceWith(
sinon.match.any,
"--ram=3012",
"--threads=-1",
),
);
});
},
);
+4 -4
View File
@@ -1072,7 +1072,7 @@ test.serial(
);
test.serial(
"Avoids duplicating --overwrite flag if specified in CODEQL_ACTION_EXTRA_OPTIONS",
"Avoids duplicating --force-overwrite flag if specified in CODEQL_ACTION_EXTRA_OPTIONS",
async (t) => {
const runnerConstructorStub = stubToolRunnerConstructor();
const codeqlObject = await stubCodeql();
@@ -1080,7 +1080,7 @@ test.serial(
sinon.stub(io, "which").resolves("");
process.env["CODEQL_ACTION_EXTRA_OPTIONS"] =
'{ "database": { "init": ["--overwrite"] } }';
'{ "database": { "init": ["--force-overwrite"] } }';
await codeqlObject.databaseInitCluster(
stubConfig,
@@ -1093,9 +1093,9 @@ test.serial(
t.true(runnerConstructorStub.calledOnce);
const args = runnerConstructorStub.firstCall.args[1] as string[];
t.is(
args.filter((option: string) => option === "--overwrite").length,
args.filter((option: string) => option === "--force-overwrite").length,
1,
"--overwrite should only be passed once",
"--force-overwrite should only be passed once",
);
// Clean up
+13 -18
View File
@@ -277,7 +277,7 @@ let cachedCodeQL: CodeQL | undefined = undefined;
* The version flags below can be used to conditionally enable certain features
* on versions newer than this.
*/
const CODEQL_MINIMUM_VERSION = "2.17.6";
const CODEQL_MINIMUM_VERSION = "2.19.4";
/**
* This version will shortly become the oldest version of CodeQL that the Action will run with.
@@ -592,13 +592,6 @@ async function getCodeQLForCmd(
extraArgs.push(`--qlconfig-file=${qlconfigFile}`);
}
const overwriteFlag = isSupportedToolsFeature(
await this.getVersion(),
ToolsFeature.ForceOverwrite,
)
? "--force-overwrite"
: "--overwrite";
const overlayDatabaseMode = config.overlayDatabaseMode;
if (overlayDatabaseMode === OverlayDatabaseMode.Overlay) {
const overlayChangesFile = await writeOverlayChangesFile(
@@ -625,7 +618,7 @@ async function getCodeQLForCmd(
"init",
...(overlayDatabaseMode === OverlayDatabaseMode.Overlay
? []
: [overwriteFlag]),
: ["--force-overwrite"]),
"--db-cluster",
config.dbLocation,
`--source-root=${sourceRoot}`,
@@ -636,7 +629,14 @@ async function getCodeQLForCmd(
// Some user configs specify `--no-calculate-baseline` as an additional
// argument to `codeql database init`. Therefore ignore the baseline file
// options here to avoid specifying the same argument twice and erroring.
ignoringOptions: ["--overwrite", ...baselineFilesOptions],
//
// Ignore `--overwrite` to avoid passing both `--force-overwrite` and `--overwrite` if
// the user has configured `--overwrite`.
ignoringOptions: [
"--force-overwrite",
"--overwrite",
...baselineFilesOptions,
],
}),
],
{ stdin: externalRepositoryToken },
@@ -853,7 +853,7 @@ async function getCodeQLForCmd(
"--sarif-group-rules-by-pack",
"--sarif-include-query-help=always",
"--sublanguage-file-coverage",
...(await getJobRunUuidSarifOptions(this)),
...(await getJobRunUuidSarifOptions()),
...getExtraOptionsFromEnv(["database", "interpret-results"]),
];
if (sarifRunPropertyFlag !== undefined) {
@@ -1283,13 +1283,8 @@ function applyAutobuildAzurePipelinesTimeoutFix() {
].join(" ");
}
async function getJobRunUuidSarifOptions(codeql: CodeQL) {
async function getJobRunUuidSarifOptions() {
const jobRunUuid = process.env[EnvVar.JOB_RUN_UUID];
return jobRunUuid &&
(await codeql.supportsFeature(
ToolsFeature.DatabaseInterpretResultsSupportsSarifRunProperty,
))
? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`]
: [];
return jobRunUuid ? [`--sarif-run-property=jobRunUuid=${jobRunUuid}`] : [];
}
+2 -5
View File
@@ -75,10 +75,10 @@ const testShouldPerformDiffInformedAnalysis = makeMacro({
[Feature.DiffInformedQueries]: testCase.featureEnabled,
});
const getGitHubVersionStub = sinon
sinon
.stub(apiClient, "getGitHubVersion")
.resolves(testCase.gitHubVersion);
const getPullRequestBranchesStub = sinon
sinon
.stub(actionsUtil, "getPullRequestBranches")
.returns(testCase.pullRequestBranches);
@@ -91,9 +91,6 @@ const testShouldPerformDiffInformedAnalysis = makeMacro({
t.is(branches !== undefined, expectedResult);
delete process.env.CODEQL_ACTION_DIFF_INFORMED_QUERIES;
getGitHubVersionStub.restore();
getPullRequestBranchesStub.restore();
});
},
title: (title) => `getDiffInformedAnalysisBranches: ${title}`,
+3 -6
View File
@@ -26,6 +26,9 @@ const DEFAULT_VERSION_FEATURE_FLAG_SUFFIX = "_enabled";
/**
* The first version of the CodeQL Bundle that shipped with zstd-compressed bundles.
*
* This is now below the minimum version of CodeQL, but we keep this around because we currently set
* up CodeQL before checking that the version is new enough.
*/
export const CODEQL_VERSION_ZSTD_BUNDLE = "2.19.0";
@@ -126,7 +129,6 @@ export enum Feature {
QaTelemetryEnabled = "qa_telemetry_enabled",
/** Note that this currently only disables baseline file coverage information. */
SkipFileCoverageOnPrs = "skip_file_coverage_on_prs",
StartProxyRemoveUnusedRegistries = "start_proxy_remove_unused_registries",
StartProxyUseFeaturesRelease = "start_proxy_use_features_release",
UploadOverlayDbToApi = "upload_overlay_db_to_api",
ValidateDbConfig = "validate_db_config",
@@ -362,11 +364,6 @@ export const featureConfig = {
minimumVersion: undefined,
toolsFeature: ToolsFeature.SuppressesMissingFileBaselineWarning,
},
[Feature.StartProxyRemoveUnusedRegistries]: {
defaultValue: false,
envVar: "CODEQL_ACTION_START_PROXY_REMOVE_UNUSED_REGISTRIES",
minimumVersion: undefined,
},
[Feature.StartProxyUseFeaturesRelease]: {
defaultValue: false,
envVar: "CODEQL_ACTION_START_PROXY_USE_FEATURES_RELEASE",
+77 -14
View File
@@ -33,7 +33,6 @@ test.serial(
const actualRef = await gitUtils.getRef();
t.deepEqual(actualRef, expectedRef);
callback.restore();
});
},
);
@@ -54,7 +53,6 @@ test.serial(
const actualRef = await gitUtils.getRef();
t.deepEqual(actualRef, expectedRef);
callback.restore();
});
},
);
@@ -73,7 +71,6 @@ test.serial(
const actualRef = await gitUtils.getRef();
t.deepEqual(actualRef, "refs/pull/1/head");
callback.restore();
});
},
);
@@ -100,8 +97,6 @@ test.serial(
const actualRef = await gitUtils.getRef();
t.deepEqual(actualRef, "refs/pull/2/merge");
callback.restore();
getAdditionalInputStub.restore();
});
},
);
@@ -161,7 +156,6 @@ test.serial(
"Both 'ref' and 'sha' are required if one of them is provided.",
},
);
getAdditionalInputStub.restore();
});
},
);
@@ -188,7 +182,6 @@ test.serial(
"Both 'ref' and 'sha' are required if one of them is provided.",
},
);
getAdditionalInputStub.restore();
});
},
);
@@ -242,7 +235,6 @@ test.serial("isAnalyzingDefaultBranch()", async (t) => {
process.env["GITHUB_EVENT_NAME"] = "schedule";
process.env["GITHUB_REF"] = "refs/heads/main";
t.deepEqual(await gitUtils.isAnalyzingDefaultBranch(), false);
getAdditionalInputStub.restore();
});
});
@@ -254,8 +246,6 @@ test.serial("determineBaseBranchHeadCommitOid non-pullrequest", async (t) => {
const result = await gitUtils.determineBaseBranchHeadCommitOid(__dirname);
t.deepEqual(result, undefined);
t.deepEqual(0, infoStub.callCount);
infoStub.restore();
});
test.serial(
@@ -276,8 +266,6 @@ test.serial(
"git call failed. Will calculate the base branch SHA on the server. Error: " +
"The checkout path provided to the action does not appear to be a git repository.",
);
infoStub.restore();
},
);
@@ -301,10 +289,27 @@ test.serial("determineBaseBranchHeadCommitOid other error", async (t) => {
"The checkout path provided to the action does not appear to be a git repository.",
),
);
infoStub.restore();
});
test.serial(
"determineBaseBranchHeadCommitOid accepts SHA-256 OIDs",
async (t) => {
const mergeSha = "a".repeat(64);
const baseOid = "b".repeat(64);
const headOid = "c".repeat(64);
process.env["GITHUB_EVENT_NAME"] = "pull_request";
process.env["GITHUB_SHA"] = mergeSha;
sinon
.stub(gitUtils as any, "runGitCommand")
.resolves(`commit ${mergeSha}\nparent ${baseOid}\nparent ${headOid}\n`);
const result = await gitUtils.determineBaseBranchHeadCommitOid(__dirname);
t.deepEqual(result, baseOid);
},
);
test.serial("decodeGitFilePath unquoted strings", async (t) => {
t.deepEqual(gitUtils.decodeGitFilePath("foo"), "foo");
t.deepEqual(gitUtils.decodeGitFilePath("foo bar"), "foo bar");
@@ -436,6 +441,64 @@ test.serial("getFileOidsUnderPath handles quoted paths", async (t) => {
});
});
test.serial("getFileOidsUnderPath handles SHA-256 OIDs", async (t) => {
await withTmpDir(async (tmpDir) => {
const sha256OidA =
"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2c0d4b7e8f9a1234567890ab";
const sha256OidB =
"aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899";
sinon
.stub(gitUtils as any, "runGitCommand")
.callsFake(async (_cwd: any, args: any) => {
if (args[0] === "rev-parse") {
return `${tmpDir}\n`;
}
return (
`100644 ${sha256OidA} 0\tlib/sha256-file-a.js\n` +
`100644 ${sha256OidB} 0\tsrc/sha256-file-b.ts`
);
});
const result = await gitUtils.getFileOidsUnderPath("/fake/path");
t.deepEqual(result, {
"lib/sha256-file-a.js": sha256OidA,
"src/sha256-file-b.ts": sha256OidB,
});
});
});
test.serial(
"getFileOidsUnderPath rejects OIDs of unsupported length",
async (t) => {
await withTmpDir(async (tmpDir) => {
// 50-char OID: not a valid SHA-1 (40) or SHA-256 (64) length. The regex
// must not accept this even though every character is a valid hex digit.
const invalidLine =
"100644 30d998ded095371488be3a729eb61d86ed721a1830d998ded0 0\tlib/bad.js";
sinon
.stub(gitUtils as any, "runGitCommand")
.callsFake(async (_cwd: any, args: any) => {
if (args[0] === "rev-parse") {
return `${tmpDir}\n`;
}
return invalidLine;
});
await t.throwsAsync(
async () => {
await gitUtils.getFileOidsUnderPath("/fake/path");
},
{
instanceOf: Error,
message: `Unexpected "git ls-files" output: ${invalidLine}`,
},
);
});
},
);
test.serial("getFileOidsUnderPath handles empty output", async (t) => {
await withTmpDir(async (tmpDir) => {
sinon
+6 -4
View File
@@ -163,11 +163,12 @@ export const determineBaseBranchHeadCommitOid = async function (
}
}
// Let's confirm our assumptions: We had a merge commit and the parsed parent data looks correct
// Let's confirm our assumptions: We had a merge commit and the parsed parent
// data looks correct. OIDs are either 40 (SHA-1) or 64 (SHA-256) hex characters.
if (
commitOid === mergeSha &&
headOid.length === 40 &&
baseOid.length === 40
(headOid.length === 40 || headOid.length === 64) &&
(baseOid.length === 40 || baseOid.length === 64)
) {
return baseOid;
}
@@ -296,7 +297,8 @@ export const getFileOidsUnderPath = async function (
// 100644 4c51bc1d9e86cd86e01b0f340cb8ce095c33b283 0\tsrc/git-utils.test.ts
// 100644 6b792ea543ce75d7a8a03df591e3c85311ecb64f 0\tsrc/git-utils.ts
// The fields are: <mode> <oid> <stage>\t<path>
const regex = /^[0-9]+ ([0-9a-f]{40}) [0-9]+\t(.+)$/;
// The OID is either 40 (SHA-1) or 64 (SHA-256) hex characters.
const regex = /^[0-9]+ ([0-9a-f]{40}|[0-9a-f]{64}) [0-9]+\t(.+)$/;
for (const line of stdout.split("\n")) {
if (line) {
const match = line.match(regex);
+16 -35
View File
@@ -80,65 +80,46 @@ const testDownloadOverlayBaseDatabaseFromCache = makeMacro({
await fs.promises.writeFile(baseDatabaseOidsFile, JSON.stringify({}));
}
const stubs: sinon.SinonStub[] = [];
sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/");
const getAutomationIDStub = sinon
.stub(apiClient, "getAutomationID")
.resolves("test-automation-id/");
stubs.push(getAutomationIDStub);
const isInTestModeStub = sinon
.stub(utils, "isInTestMode")
.returns(testCase.isInTestMode);
stubs.push(isInTestModeStub);
sinon.stub(utils, "isInTestMode").returns(testCase.isInTestMode);
if (testCase.restoreCacheResult instanceof Error) {
const restoreCacheStub = sinon
sinon
.stub(actionsCache, "restoreCache")
.rejects(testCase.restoreCacheResult);
stubs.push(restoreCacheStub);
} else {
const restoreCacheStub = sinon
sinon
.stub(actionsCache, "restoreCache")
.resolves(testCase.restoreCacheResult);
stubs.push(restoreCacheStub);
}
const tryGetFolderBytesStub = sinon
sinon
.stub(utils, "tryGetFolderBytes")
.resolves(testCase.tryGetFolderBytesSucceeds ? 1024 * 1024 : undefined);
stubs.push(tryGetFolderBytesStub);
const codeql = mockCodeQLVersion(testCase.codeQLVersion);
if (testCase.resolveDatabaseOutput instanceof Error) {
const resolveDatabaseStub = sinon
sinon
.stub(codeql, "resolveDatabase")
.rejects(testCase.resolveDatabaseOutput);
stubs.push(resolveDatabaseStub);
} else {
const resolveDatabaseStub = sinon
sinon
.stub(codeql, "resolveDatabase")
.resolves(testCase.resolveDatabaseOutput);
stubs.push(resolveDatabaseStub);
}
try {
const result = await downloadOverlayBaseDatabaseFromCache(
codeql,
config,
logger,
);
const result = await downloadOverlayBaseDatabaseFromCache(
codeql,
config,
logger,
);
if (expectDownloadSuccess) {
t.truthy(result);
} else {
t.is(result, undefined);
}
} finally {
for (const stub of stubs) {
stub.restore();
}
if (expectDownloadSuccess) {
t.truthy(result);
} else {
t.is(result, undefined);
}
});
},
+16 -56
View File
@@ -50,31 +50,21 @@ test.serial(
"modified.js": "ddd444", // Changed OID
"added.js": "eee555", // New file
};
const getFileOidsStubForOverlay = sinon
.stub(gitUtils, "getFileOidsUnderPath")
.resolves(currentOids);
sinon.stub(gitUtils, "getFileOidsUnderPath").resolves(currentOids);
// Write the overlay changes file, which uses the mocked overlay OIDs
// and the base database OIDs file
const diffRangeFilePath = path.join(tempDir, "pr-diff-range.json");
const getTempDirStub = sinon
.stub(actionsUtil, "getTemporaryDirectory")
.returns(tempDir);
const getDiffRangesStub = sinon
sinon.stub(actionsUtil, "getTemporaryDirectory").returns(tempDir);
sinon
.stub(actionsUtil, "getDiffRangesJsonFilePath")
.returns(diffRangeFilePath);
const getGitRootStub = sinon
.stub(gitUtils, "getGitRoot")
.resolves(sourceRoot);
sinon.stub(gitUtils, "getGitRoot").resolves(sourceRoot);
const changesFilePath = await writeOverlayChangesFile(
config,
sourceRoot,
logger,
);
getFileOidsStubForOverlay.restore();
getTempDirStub.restore();
getDiffRangesStub.restore();
getGitRootStub.restore();
const fileContent = await fs.promises.readFile(changesFilePath, "utf-8");
const parsedContent = JSON.parse(fileContent) as { changes: string[] };
@@ -128,20 +118,14 @@ test.serial(
"modified.js": "ddd444", // Changed OID
"reverted.js": "eee555", // Same OID as base -- not detected by OID comparison
};
const getFileOidsStubForOverlay = sinon
.stub(gitUtils, "getFileOidsUnderPath")
.resolves(currentOids);
sinon.stub(gitUtils, "getFileOidsUnderPath").resolves(currentOids);
const diffRangeFilePath = path.join(tempDir, "pr-diff-range.json");
const getTempDirStub = sinon
.stub(actionsUtil, "getTemporaryDirectory")
.returns(tempDir);
const getDiffRangesStub = sinon
sinon.stub(actionsUtil, "getTemporaryDirectory").returns(tempDir);
sinon
.stub(actionsUtil, "getDiffRangesJsonFilePath")
.returns(diffRangeFilePath);
const getGitRootStub = sinon
.stub(gitUtils, "getGitRoot")
.resolves(sourceRoot);
sinon.stub(gitUtils, "getGitRoot").resolves(sourceRoot);
// Write a pr-diff-range.json file with diff ranges including
// "reverted.js" (unchanged OIDs) and "modified.js" (already in OID changes)
@@ -159,10 +143,6 @@ test.serial(
sourceRoot,
logger,
);
getFileOidsStubForOverlay.restore();
getTempDirStub.restore();
getDiffRangesStub.restore();
getGitRootStub.restore();
const fileContent = await fs.promises.readFile(changesFilePath, "utf-8");
const parsedContent = JSON.parse(fileContent) as { changes: string[] };
@@ -208,20 +188,14 @@ test.serial(
"unchanged.js": "aaa111",
"modified.js": "ddd444",
};
const getFileOidsStubForOverlay = sinon
.stub(gitUtils, "getFileOidsUnderPath")
.resolves(currentOids);
sinon.stub(gitUtils, "getFileOidsUnderPath").resolves(currentOids);
const diffRangeFilePath = path.join(tempDir, "pr-diff-range.json");
const getTempDirStub = sinon
.stub(actionsUtil, "getTemporaryDirectory")
.returns(tempDir);
const getDiffRangesStub = sinon
sinon.stub(actionsUtil, "getTemporaryDirectory").returns(tempDir);
sinon
.stub(actionsUtil, "getDiffRangesJsonFilePath")
.returns(diffRangeFilePath);
const getGitRootStub = sinon
.stub(gitUtils, "getGitRoot")
.resolves(sourceRoot);
sinon.stub(gitUtils, "getGitRoot").resolves(sourceRoot);
// No pr-diff-range.json file exists - should work the same as before
const changesFilePath = await writeOverlayChangesFile(
@@ -229,10 +203,6 @@ test.serial(
sourceRoot,
logger,
);
getFileOidsStubForOverlay.restore();
getTempDirStub.restore();
getDiffRangesStub.restore();
getGitRootStub.restore();
const fileContent = await fs.promises.readFile(changesFilePath, "utf-8");
const parsedContent = JSON.parse(fileContent) as { changes: string[] };
@@ -281,21 +251,15 @@ test.serial(
"app.js": "aaa111",
"lib/util.js": "bbb222",
};
const getFileOidsStubForOverlay = sinon
.stub(gitUtils, "getFileOidsUnderPath")
.resolves(currentOids);
sinon.stub(gitUtils, "getFileOidsUnderPath").resolves(currentOids);
const diffRangeFilePath = path.join(tempDir, "pr-diff-range.json");
const getTempDirStub = sinon
.stub(actionsUtil, "getTemporaryDirectory")
.returns(tempDir);
const getDiffRangesStub = sinon
sinon.stub(actionsUtil, "getTemporaryDirectory").returns(tempDir);
sinon
.stub(actionsUtil, "getDiffRangesJsonFilePath")
.returns(diffRangeFilePath);
// getGitRoot returns the repo root (parent of sourceRoot)
const getGitRootStub = sinon
.stub(gitUtils, "getGitRoot")
.resolves(repoRoot);
sinon.stub(gitUtils, "getGitRoot").resolves(repoRoot);
// Diff ranges use repo-root-relative paths (as returned by the GitHub compare API)
await fs.promises.writeFile(
@@ -312,10 +276,6 @@ test.serial(
sourceRoot,
logger,
);
getFileOidsStubForOverlay.restore();
getTempDirStub.restore();
getDiffRangesStub.restore();
getGitRootStub.restore();
const fileContent = await fs.promises.readFile(changesFilePath, "utf-8");
const parsedContent = JSON.parse(fileContent) as { changes: string[] };
+1 -7
View File
@@ -5,7 +5,7 @@ import * as core from "@actions/core";
import * as actionsUtil from "./actions-util";
import { getGitHubVersion } from "./api-client";
import { Feature, FeatureEnablement, initFeatures } from "./feature-flags";
import { FeatureEnablement, initFeatures } from "./feature-flags";
import { BuiltInLanguage, parseBuiltInLanguage } from "./languages";
import { getActionsLogger, Logger } from "./logging";
import { getRepositoryNwo } from "./repository";
@@ -57,18 +57,12 @@ async function run(startedAt: Date) {
const languageInput = actionsUtil.getOptionalInput("language");
language = languageInput ? parseBuiltInLanguage(languageInput) : undefined;
// Query the FF for whether we should use the reduced registry mapping.
const skipUnusedRegistries = await features.getValue(
Feature.StartProxyRemoveUnusedRegistries,
);
// Get the registry configurations from one of the inputs.
const credentials = getCredentials(
logger,
actionsUtil.getOptionalInput("registry_secrets"),
actionsUtil.getOptionalInput("registries_credentials"),
language,
skipUnusedRegistries,
);
if (credentials.length === 0) {
+4 -22
View File
@@ -585,7 +585,6 @@ test("getCredentials validates 'replaces-base' correctly", async (t) => {
undefined,
credentialsInput,
BuiltInLanguage.java,
false,
);
t.is(credentials.length, 3);
@@ -604,8 +603,7 @@ test("getCredentials validates 'replaces-base' correctly", async (t) => {
getRunnerLogger(true),
undefined,
toEncodedJSON([{ ...baseInvalid, "replaces-base": null }]),
BuiltInLanguage.actions,
false,
BuiltInLanguage.java,
),
);
t.throws(() =>
@@ -613,8 +611,7 @@ test("getCredentials validates 'replaces-base' correctly", async (t) => {
getRunnerLogger(true),
undefined,
toEncodedJSON([{ ...baseInvalid, "replaces-base": 123 }]),
BuiltInLanguage.actions,
false,
BuiltInLanguage.java,
),
);
t.throws(() =>
@@ -622,13 +619,12 @@ test("getCredentials validates 'replaces-base' correctly", async (t) => {
getRunnerLogger(true),
undefined,
toEncodedJSON([{ ...baseInvalid, "replaces-base": "true" }]),
BuiltInLanguage.actions,
false,
BuiltInLanguage.java,
),
);
});
test("getCredentials returns all credentials for Actions when using LANGUAGE_TO_REGISTRY_TYPE", async (t) => {
test("getCredentials returns no credentials for Actions", async (t) => {
const credentialsInput = toEncodedJSON(mixedCredentials);
const credentials = startProxyExports.getCredentials(
@@ -636,20 +632,6 @@ test("getCredentials returns all credentials for Actions when using LANGUAGE_TO_
undefined,
credentialsInput,
BuiltInLanguage.actions,
false,
);
t.is(credentials.length, mixedCredentials.length);
});
test("getCredentials returns no credentials for Actions when using NEW_LANGUAGE_TO_REGISTRY_TYPE", async (t) => {
const credentialsInput = toEncodedJSON(mixedCredentials);
const credentials = startProxyExports.getCredentials(
getRunnerLogger(true),
undefined,
credentialsInput,
BuiltInLanguage.actions,
true,
);
t.deepEqual(credentials, []);
});
+2 -16
View File
@@ -189,17 +189,7 @@ function isPAT(value: string) {
type RegistryMapping = Partial<Record<BuiltInLanguage, string[]>>;
const LANGUAGE_TO_REGISTRY_TYPE: RegistryMapping = {
java: ["maven_repository"],
csharp: ["nuget_feed"],
javascript: ["npm_registry"],
python: ["python_index"],
ruby: ["rubygems_server"],
rust: ["cargo_registry"],
go: ["goproxy_server", "git_source"],
} as const;
const NEW_LANGUAGE_TO_REGISTRY_TYPE: Required<RegistryMapping> = {
const LANGUAGE_TO_REGISTRY_TYPE: Required<RegistryMapping> = {
actions: [],
cpp: [],
java: ["maven_repository"],
@@ -251,13 +241,9 @@ export function getCredentials(
registrySecrets: string | undefined,
registriesCredentials: string | undefined,
language: BuiltInLanguage | undefined,
skipUnusedRegistries: boolean = false,
): Credential[] {
const registryMapping = skipUnusedRegistries
? NEW_LANGUAGE_TO_REGISTRY_TYPE
: LANGUAGE_TO_REGISTRY_TYPE;
const registryTypeForLanguage = language
? registryMapping[language]
? LANGUAGE_TO_REGISTRY_TYPE[language]
: undefined;
let credentialsStr: string;
+7 -3
View File
@@ -6,9 +6,13 @@ import { ToolsFeature, isSupportedToolsFeature } from "./tools-features";
test("isSupportedToolsFeature", async (t) => {
const versionInfo = makeVersionInfo("1.0.0");
t.false(isSupportedToolsFeature(versionInfo, ToolsFeature.ForceOverwrite));
t.false(
isSupportedToolsFeature(versionInfo, ToolsFeature.BundleSupportsOverlay),
);
versionInfo.features = { forceOverwrite: true };
versionInfo.features = { bundleSupportsOverlay: true };
t.true(isSupportedToolsFeature(versionInfo, ToolsFeature.ForceOverwrite));
t.true(
isSupportedToolsFeature(versionInfo, ToolsFeature.BundleSupportsOverlay),
);
});
-2
View File
@@ -6,8 +6,6 @@ export enum ToolsFeature {
BuiltinExtractorsSpecifyDefaultQueries = "builtinExtractorsSpecifyDefaultQueries",
BundleSupportsIncludeOption = "bundleSupportsIncludeOption",
BundleSupportsOverlay = "bundleSupportsOverlay",
DatabaseInterpretResultsSupportsSarifRunProperty = "databaseInterpretResultsSupportsSarifRunProperty",
ForceOverwrite = "forceOverwrite",
IndirectTracingSupportsStaticBinaries = "indirectTracingSupportsStaticBinaries",
SuppressesMissingFileBaselineWarning = "suppressesMissingFileBaselineWarning",
}
+1 -4
View File
@@ -418,9 +418,7 @@ for (const [
`checkActionVersion ${reportErrorDescription} for ${versionsDescription}`,
async (t) => {
const warningSpy = sinon.spy(core, "warning");
const versionStub = sinon
.stub(api, "getGitHubVersion")
.resolves(githubVersion);
sinon.stub(api, "getGitHubVersion").resolves(githubVersion);
// call checkActionVersion twice and assert below that warning is reported only once
util.checkActionVersion(version, await api.getGitHubVersion());
@@ -437,7 +435,6 @@ for (const [
} else {
t.false(warningSpy.called);
}
versionStub.restore();
},
);
}