Compare commits

..
Author SHA1 Message Date
Henry Mercer 0db2f2b4a5 Merge pull request #4205 from github/henrymercer/require-codeql-2-20-7
Bump minimum CodeQL CLI version to 2.20.7
2026-10-12 10:04:43 +00:00
Henry MercerandCopilot App ae96eed5bb Merge remote-tracking branch 'origin/main' into henrymercer/require-codeql-2-20-7
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-12 10:11:02 +01:00
Mario Campos e4e9b269fe Merge pull request #4211 from github/mario-campos/document-changenotes
Document change-notes process
2026-10-09 23:05:41 +00:00
Michael B. Gale 6e7fe2e990 Merge pull request #4220 from github/mbg/fix-action-state-type-inference
Fix type inference for `ActionState`
2026-10-09 22:31:18 +00:00
Mario Campos fa56eef12f Delete unnecessary filename/frontmatter validation instructions 2026-10-09 16:48:00 -05:00
Michael B. Gale 71f2680f85 Merge pull request #4209 from github/dependabot/npm_and_yarn/eslint-plugin-jsdoc-65.0.1
Bump eslint-plugin-jsdoc from 64.5.4 to 65.0.1
2026-10-09 17:59:37 +00:00
Michael B. Gale 3b399fec34 Merge branch 'main' into dependabot/npm_and_yarn/eslint-plugin-jsdoc-65.0.1 2026-10-09 18:47:49 +01:00
Mario Campos 5532d8e11e Merge pull request #4218 from github/mario-campos/loosen-changenote-validation
Do not validate change-note file names or frontmatter
2026-10-09 17:45:19 +00:00
Michael B. Gale 68f5b579fa Merge pull request #4212 from github/mbg/tests/fix-export-variable-2
Do not use `core.exportVariable` in unit tests (2nd attempt)
2026-10-09 17:38:52 +00:00
Mario Campos 45cda5b577 Delete unused path import 2026-10-09 08:57:09 -05:00
Michael B. Gale e57c0e65dd Fix type inference for ActionState 2026-10-09 14:21:47 +01:00
Mario Campos 1ced68ed2f Do not validate change-note file names or frontmatter
Presently, the strict filename or frontmatter are not being used; so we're validating them unnecessarily. So, for now, remove these checks until we decide to either do something with them, or delete the code entirely.
2026-10-08 15:11:43 -05:00
Mario CamposandMichael B. Gale 13b1321685 Refine misc. wording of unreleased-change-notes/README.md
Co-authored-by: Michael B. Gale <mbg@github.com>
2026-10-08 15:01:05 -05:00
Mario Campos cc826bb8e3 Delete unnecessary guidance for change-note body 2026-10-08 14:57:03 -05:00
Mario Campos 40d76bc727 Use actual CHANGELOG.md entries for example change-note 2026-10-08 14:55:23 -05:00
Michael B. Gale bd97dda6bf Add and use __CODEQL_ACTION_TEST_ENV__ in tests 2026-10-08 20:23:37 +01:00
Michael B. Gale d6196d8703 Rename exportVariable wrapper to exportEnvVar 2026-10-08 20:06:51 +01:00
Mario Campos 3acc10a2ce Exclude README.md from change-note validation and assembly 2026-10-08 12:53:37 -05:00
Mario Campos 2a935ca93d Move change-note documentation to unreleased-change-notes/README.md 2026-10-08 12:48:24 -05:00
Mads Navntoft 5aa5056e2d Merge pull request #4215 from github/mergeback/v4.38.3-to-main-24c54180
Mergeback v4.38.3 refs/heads/releases/v4 into main
2026-10-08 13:58:42 +00:00
Henry Mercer 768784f193 Merge branch 'main' into henrymercer/require-codeql-2-20-7 2026-10-08 14:29:21 +01:00
github-actions[bot] ea60dc6408 Rebuild 2026-10-08 13:01:10 +00:00
github-actions[bot] ce3f825b1d Update changelog and version after v4.38.3 2026-10-08 13:01:02 +00:00
Mario Campos 38fee79b02 Specify allowed characters in change-note filename 2026-10-07 15:21:38 -05:00
Michael B. Gale ebd711ff66 Deprecate isInTestMode in favour of a more clearly named method 2026-10-07 20:12:01 +01:00
Michael B. Gale 75ea4cb2e4 Add NODE_ENV as safe environment variable 2026-10-07 20:12:01 +01:00
Michael B. Gale 59ff83ecef Add basic eslint enforcement 2026-10-07 20:12:01 +01:00
Michael B. Gale 1728f0c676 Add wrapper around core.exportVariable 2026-10-07 20:12:00 +01:00
Michael B. Gale 63c5299790 Move isInTestMode to environment.ts 2026-10-07 20:12:00 +01:00
Mario Campos 39f1b3fa8d Document change-notes process 2026-10-07 13:11:34 -05:00
dependabot[bot] d5b1e793ce Bump eslint-plugin-jsdoc from 64.5.4 to 65.0.1
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 64.5.4 to 65.0.1.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v64.5.4...v65.0.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-version: 65.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-07 17:55:31 +00:00
Henry MercerandCopilot App 5d90bea8a6 Add PR number to changelog entry and list it first
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-07 14:44:12 +01:00
Henry MercerandCopilot App 8e7104f197 Clarify the oldest-version comment in the Rust PR check
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-07 14:41:20 +01:00
Henry MercerandCopilot App 0b5c1fb069 Remove redundant CLI version requirement from CppDependencyInstallation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-07 14:41:15 +01:00
Henry MercerandCopilot App a8c7110b26 Remove unreachable minimum version check for Rust analysis
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-07 14:41:09 +01:00
Henry MercerandCopilot App 3c1b1b65a3 Remove CodeQL version check from debug artifact upload
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-07 14:41:03 +01:00
Henry MercerandCopilot App 10e415aae1 Remove Kotlin version limit workaround for CodeQL CLI 2.20.3
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-07 14:40:58 +01:00
Henry MercerandCopilot App b97fbb3711 Remove CODEQL_PROXY_* workaround for CLIs older than 2.20.7
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-07 14:40:52 +01:00
Henry MercerandCopilot App 17e7897d6c Add CodeQL 2.25.6 to the PR check matrix
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-07 14:40:49 +01:00
Henry MercerandCopilot App 74aeac99e7 Stop testing CodeQL versions older than 2.20.7 in PR checks
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-07 14:40:46 +01:00
Henry MercerandCopilot App 05d28f2f71 Bump version to 4.39.0
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-07 14:40:38 +01:00
Henry MercerandCopilot App 772ffcd999 Bump minimum CodeQL CLI version to 2.20.7
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-10-07 14:40:35 +01:00
53 changed files with 975 additions and 902 deletions

No files matched your search

+2 -2
View File
@@ -44,8 +44,6 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: stable-v2.19.4
- os: ubuntu-latest
version: stable-v2.20.7
- os: ubuntu-latest
@@ -56,6 +54,8 @@ jobs:
version: stable-v2.23.9
- os: ubuntu-latest
version: stable-v2.24.3
- os: ubuntu-latest
version: stable-v2.25.6
- os: ubuntu-latest
version: default
- os: ubuntu-latest
+2 -2
View File
@@ -44,8 +44,6 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: stable-v2.19.4
- os: ubuntu-latest
version: stable-v2.20.7
- os: ubuntu-latest
@@ -56,6 +54,8 @@ jobs:
version: stable-v2.23.9
- os: ubuntu-latest
version: stable-v2.24.3
- os: ubuntu-latest
version: stable-v2.25.6
- os: ubuntu-latest
version: default
- os: ubuntu-latest
+2 -2
View File
@@ -44,8 +44,6 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: stable-v2.19.4
- os: ubuntu-latest
version: stable-v2.20.7
- os: ubuntu-latest
@@ -56,6 +54,8 @@ jobs:
version: stable-v2.23.9
- os: ubuntu-latest
version: stable-v2.24.3
- os: ubuntu-latest
version: stable-v2.25.6
- os: ubuntu-latest
version: default
- os: ubuntu-latest
+4 -4
View File
@@ -54,10 +54,6 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
version: stable-v2.19.4
- os: macos-15-xlarge
version: stable-v2.19.4
- os: ubuntu-latest
version: stable-v2.20.7
- os: macos-15-xlarge
@@ -78,6 +74,10 @@ jobs:
version: stable-v2.24.3
- os: macos-latest-xlarge
version: stable-v2.24.3
- os: ubuntu-latest
version: stable-v2.25.6
- os: macos-latest-xlarge
version: stable-v2.25.6
- os: ubuntu-latest
version: default
- os: macos-latest-xlarge
+1 -1
View File
@@ -35,7 +35,7 @@ jobs:
matrix:
include:
- os: ubuntu-latest
version: stable-v2.19.4
version: stable-v2.20.7
- os: ubuntu-latest
version: stable-v2.22.1
- os: ubuntu-latest
@@ -30,7 +30,7 @@ jobs:
fail-fast: false
matrix:
version:
- stable-v2.20.3
- stable-v2.20.7
- default
- linked
- nightly-latest
+2 -2
View File
@@ -29,7 +29,7 @@ jobs:
fail-fast: false
matrix:
version:
- stable-v2.20.3
- stable-v2.20.7
- default
- linked
- nightly-latest
@@ -85,7 +85,7 @@ jobs:
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
- name: Check expected artifacts exist
run: |
VERSIONS="stable-v2.20.3 default linked nightly-latest"
VERSIONS="stable-v2.20.7 default linked nightly-latest"
LANGUAGES="cpp csharp go java javascript python"
for version in $VERSIONS; do
pushd "./my-debug-artifacts-${version//./}"
+4
View File
@@ -2,6 +2,10 @@
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.20.7. [#4205](https://github.com/github/codeql-action/pull/4205)
## 4.38.3 - 08 Oct 2026
- _Upcoming breaking change_: CodeQL version 2.21.2 and earlier were discontinued on 24 September 2026 alongside GitHub Enterprise Server 3.17, and will be unsupported by the next minor release of the CodeQL Action. Added a deprecation warning for customers using these versions of CodeQL. [#4188](https://github.com/github/codeql-action/pull/4188)
+1
View File
@@ -53,6 +53,7 @@ Here are a few things you can do that will increase the likelihood of your pull
- Write tests.
- Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests.
- Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
- For user-facing changes, add a change-note file. See [unreleased-change-notes/README.md](unreleased-change-notes/README.md).
## Releasing (write access required)
+1
View File
@@ -1,3 +1,4 @@
import pkg from "./package.json" with { type: "json" };
globalThis.__CODEQL_ACTION_VERSION__ = pkg.version;
globalThis.__CODEQL_ACTION_TEST_ENV__ = "unit-test";
+2 -1
View File
@@ -78,7 +78,7 @@ const UPLOAD_LIB_SRC = "./src/upload-lib";
*
* The virtual module additionally re-exports `upload-lib` under the `uploadLib` namespace so that
* external consumers can access it via the small `lib/upload-lib.js` stub emitted below.
*
*
* A tiny stub file is emitted for each Action entrypoint, and one for `upload-lib`. Each stub
* imports the shared bundle and calls/re-exports from the respective entry point.
*
@@ -212,6 +212,7 @@ const context = await esbuild.context({
target: ["node20"],
define: {
__CODEQL_ACTION_VERSION__: JSON.stringify(pkg.version),
__CODEQL_ACTION_TEST_ENV__: JSON.stringify(""),
},
metafile: true,
});
+20
View File
@@ -140,6 +140,17 @@ export default [
"no-async-foreach/no-async-foreach": "error",
"no-sequences": "error",
"no-shadow": "off",
// A basic check that we don't use `exportVariable` from `@actions/core`.
"no-restricted-syntax": [
"error",
{
selector: "MemberExpression[property.name='exportVariable']",
message:
"Use the `export` method of an `Env` instance or `exportEnvVar` from `environment.ts` instead.",
},
],
// This is overly restrictive with unsetting `EnvVar`s
"@typescript-eslint/no-dynamic-delete": "off",
"@typescript-eslint/no-shadow": "error",
@@ -157,6 +168,15 @@ export default [
],
},
},
{
files: ["src/environment.ts"],
// We allow `exportVariable` from `@actions/core` to be used in this file
// since it defines the wrapper around it that other modules use.
rules: {
"no-restricted-syntax": "off",
},
},
{
files: ["**/*.ts", "**/*.js"],
+571 -568
View File
File diff suppressed because it is too large. Load diff
+7 -7
View File
@@ -1,12 +1,12 @@
{
"name": "codeql",
"version": "4.38.3",
"version": "4.39.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "codeql",
"version": "4.38.3",
"version": "4.39.0",
"license": "MIT",
"workspaces": [
"pr-checks"
@@ -58,7 +58,7 @@
"eslint-import-resolver-typescript": "^4.4.5",
"eslint-plugin-github": "^6.1.2",
"eslint-plugin-import-x": "^4.17.1",
"eslint-plugin-jsdoc": "^64.5.4",
"eslint-plugin-jsdoc": "^65.0.1",
"eslint-plugin-no-async-foreach": "^0.1.1",
"glob": "^13.0.6",
"globals": "^17.12.0",
@@ -5381,15 +5381,15 @@
}
},
"node_modules/eslint-plugin-jsdoc": {
"version": "64.5.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-64.5.4.tgz",
"integrity": "sha512-xfRhXPSSWT612muJ6XTvxuVJ8zYHv99qNgBqPVqF28aSqoy4s4XbSkrWXnYA2hl5ejC02yEpk6fqkj3BmJ6Xbg==",
"version": "65.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-65.0.1.tgz",
"integrity": "sha512-7IvB+ZS71WCw5tGKh6f6D5k55qtXKdrGTnIpQTBKWdpyZ5IfhGHfh0i6ArWlCJ4JEtz22YRk5Bqu1MvbOlpMKQ==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"@es-joy/jsdoccomment": "~0.98.0",
"@es-joy/resolve.exports": "1.2.0",
"@typescript-eslint/utils": "^8.70.0",
"@typescript-eslint/utils": "^8.70.1",
"are-docs-informative": "^0.1.1",
"comment-parser": "1.4.9",
"debug": "^4.4.3",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "codeql",
"version": "4.38.3",
"version": "4.39.0",
"private": true,
"description": "CodeQL action",
"scripts": {
@@ -66,7 +66,7 @@
"eslint-import-resolver-typescript": "^4.4.5",
"eslint-plugin-github": "^6.1.2",
"eslint-plugin-import-x": "^4.17.1",
"eslint-plugin-jsdoc": "^64.5.4",
"eslint-plugin-jsdoc": "^65.0.1",
"eslint-plugin-no-async-foreach": "^0.1.1",
"glob": "^13.0.6",
"globals": "^17.12.0",
-20
View File
@@ -154,26 +154,6 @@ await describe("isValidChangenoteFile", async () => {
assert.equal(isValidChangenoteFile("non-existent-file.md"), false);
});
await it("rejects invalid filename", async () => {
await withTmpFile(
"fix-bug.md",
"---\ncategory: fix\n---\n- Fixed a bug\n",
(filePath) => {
assert.equal(isValidChangenoteFile(filePath), false);
},
);
});
await it("rejects missing frontmatter", async () => {
await withTmpFile(
"2026-01-01-fix-bug.md",
"- Fixed a bug\n",
(filePath) => {
assert.equal(isValidChangenoteFile(filePath), false);
},
);
});
await it("rejects invalid Markdown", async () => {
await withTmpFile(
"2026-01-01-fix-bug.md",
+1 -16
View File
@@ -1,5 +1,4 @@
import * as fs from "node:fs";
import * as path from "node:path";
import { matter } from "lite-matter";
import type { List, ListItem } from "mdast";
@@ -95,21 +94,7 @@ export function isValidChangenoteFile(filename: string): boolean {
return false;
}
const { data: frontmatter, content } = matter(fileData);
if (!isValidChangenoteFilename(path.basename(filename))) {
isValid = false;
console.error(
`${filename}: invalid filename; must match pattern YYYY-MM-DD-id.md`,
);
}
if (!hasValidChangenoteCategory(frontmatter)) {
isValid = false;
const categories = Object.keys(VALID_CHANGE_NOTE_CATEGORIES).join(", ");
console.error(
`${filename}: invalid category; must be one of: ${categories}`,
);
}
const { content } = matter(fileData);
if (!isValidChangenoteContent(content)) {
isValid = false;
console.error(
+2 -2
View File
@@ -28,12 +28,12 @@ interface ChangenoteFile {
/**
* Returns the absolute file paths of all files in
* {@link CHANGENOTES_DIR} (except ".gitkeep").
* {@link CHANGENOTES_DIR} (except ".gitkeep" and "README.md").
* */
function listUnreleasedChangenoteDir(): string[] {
return fs
.readdirSync(CHANGENOTES_DIR)
.filter((name) => name !== ".gitkeep")
.filter((name) => ![".gitkeep", "README.md"].includes(name))
.map((name) => path.join(CHANGENOTES_DIR, name));
}
@@ -10,7 +10,6 @@ operatingSystems:
- os: macos
runner-image: macos-15-xlarge
codeql-versions:
- stable-v2.19.4
- stable-v2.20.7
- stable-v2.21.4
- stable-v2.22.4
+2 -2
View File
@@ -1,8 +1,8 @@
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.4
# oldest CodeQL version supported by the Action, where Rust support is experimental and requires the Action to set `CODEQL_ENABLE_EXPERIMENTAL_FEATURES`
- stable-v2.20.7
# first public preview version
- stable-v2.22.1
- linked
+2 -2
View File
@@ -136,8 +136,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.19.4",
// The last CodeQL release in the 2.20 series.
"stable-v2.20.7",
// The last CodeQL release in the 2.21 series.
"stable-v2.21.4",
@@ -147,6 +145,8 @@ const defaultTestVersions = [
"stable-v2.23.9",
// The last CodeQL release in the 2.24 series.
"stable-v2.24.3",
// The last CodeQL release in the 2.25 series.
"stable-v2.25.6",
// 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
@@ -23,7 +23,8 @@ predicate isSafeForDefaultSetup(string envVar) {
"GITHUB_BASE_REF", "GITHUB_EVENT_NAME", "GITHUB_JOB", "GITHUB_RUN_ATTEMPT", "GITHUB_RUN_ID",
"GITHUB_SHA", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "GITHUB_TOKEN", "GITHUB_WORKFLOW",
"GITHUB_WORKSPACE", "GOFLAGS", "ImageVersion", "JAVA_TOOL_OPTIONS", "RUNNER_ARCH",
"RUNNER_ENVIRONMENT", "RUNNER_NAME", "RUNNER_OS", "RUNNER_TEMP", "RUNNER_TOOL_CACHE"
"RUNNER_ENVIRONMENT", "RUNNER_NAME", "RUNNER_OS", "RUNNER_TEMP", "RUNNER_TOOL_CACHE",
"NODE_ENV"
]
}
+70 -1
View File
@@ -56,6 +56,29 @@ export interface FeatureState {
/** Identifies a type of state an Action may have. */
export type StateFeature = keyof FeatureState;
/**
* The `Env` feature implies the availability of the `ReadOnlyEnv` feature.
*
* If `T` is `Env`, this returns `Env | ReadOnlyEnv`.
* Otherwise, it is the identity and returns T.
*/
type ImpliedFeatures<T extends StateFeature> = T extends "Env"
? "Env" | "ReadOnlyEnv"
: T;
/**
* Given an object type `Obj`, this tries to lookup a corresponding `StateFeature`
* to which the object type belongs in `FeatureState`. Resolves to `never` if there
* is no match.
*/
type FeatureNameFor<Obj extends object> = {
[K in StateFeature]: [Obj] extends [FeatureState[K]]
? [FeatureState[K]] extends [Obj]
? K
: never
: never;
}[StateFeature];
/** Constructs the intersection of all state types identifies by `Fs`. */
export type FieldsOf<Fs extends readonly StateFeature[]> = Fs extends []
? Record<never, never>
@@ -66,8 +89,54 @@ export type FieldsOf<Fs extends readonly StateFeature[]> = Fs extends []
? FeatureState[Head] & FieldsOf<Tail>
: never;
/**
* Symbol used for a field in `ActionState` that carries the type array of state features.
* This is a Symbol so that it doesn't clash with any property names we might want to have.
*/
const stateFeatures = Symbol();
/** Describes the state of an Action that has access to the state corresponding to `Fs`. */
export type ActionState<Fs extends readonly StateFeature[]> = FieldsOf<Fs>;
export type ActionState<Fs extends readonly StateFeature[]> = FieldsOf<Fs> & {
/**
* When given a chance, TypeScript will simplify an `ActionState<Fs>` type as much as possible,
* which results in a concrete object type that doesn't mention `Fs`.
*
* That causes problems for functions which accept `ActionState<Fs>` values, but need to know the
* feature keys `Fs`. This property here explicitly captures `Fs` in the concrete object type
* that results from simplifying `ActionState<Fs>`.
*
* This is a function rather than a field, because we want to be able to provide values of type
* `ActionState<Fs>` to functions expecting `ActionState<As>` where `As` is a subset of `Fs`.
*
* Since function types are contravariant in the types of their parameters, using a function
* type here allows that to happen.
*
* Because the field is optional, we don't have to explicitly provide a value
* for it anywhere while the type is still inferred.
*
* `Fs[number]` returns the union of all features in `Fs`. We wrap it in `ImpliedFeatures`
* so that `Env` is expanded into `Env | ReadOnlyEnv`, allowing functions that expect the
* `ReadOnlyEnv` feature to be provided with an `ActionState` that has the `Env` feature
* without requiring this to be made explicit.
*/
readonly [stateFeatures]?: (ts: ImpliedFeatures<Fs[number]>) => void;
};
/** Extends `state` with an `extra` feature. */
export function extendActionState<
// In first position, so that it can be explicitly provided if `FeatureNameFor`
// should not work on `extra`.
F extends StateFeature,
Fs extends readonly StateFeature[],
E extends FeatureState[F],
>(
state: ActionState<Fs>,
extra: E,
): ActionState<[...Fs, FeatureNameFor<E> & F]> {
return { ...state, ...extra } as unknown as ActionState<
[...Fs, FeatureNameFor<E> & F]
>;
}
/** The type of an Action's main entry point. This is a function that is provided
* with a basic `ActionState` object with features that are always available.
-2
View File
@@ -30,7 +30,6 @@ declare const __CODEQL_ACTION_VERSION__: string;
export interface ActionsEnv {
getRequiredInput: (name: string) => string;
getOptionalInput: (name: string) => string | undefined;
exportVariable: (name: string, value: string) => void;
}
/**
@@ -40,7 +39,6 @@ export function getActionsEnv(): ActionsEnv {
return {
getRequiredInput,
getOptionalInput,
exportVariable: core.exportVariable,
};
}
-4
View File
@@ -9,7 +9,6 @@ import * as core from "@actions/core";
import * as actionsUtil from "./actions-util";
import { getGitHubVersion } from "./api-client";
import { getCodeQL } from "./codeql";
import { getConfig } from "./config-utils";
import * as debugArtifacts from "./debug-artifacts";
import {
@@ -38,12 +37,9 @@ export async function runWrapper() {
logger,
);
if (config !== undefined) {
const codeql = await getCodeQL(logger, config.codeQLCmd);
const version = await codeql.getVersion();
await debugArtifacts.uploadCombinedSarifArtifacts(
logger,
config.gitHubVersion.type,
version.version,
);
}
}
+4 -14
View File
@@ -214,9 +214,10 @@ async function runAutobuildIfLegacyGoWorkflow(config: Config, logger: Logger) {
async function run({
startedAt,
env,
logger,
actions,
}: ActionState<["Base", "Logger", "Actions"]>) {
}: ActionState<["Base", "Env", "Logger", "Actions"]>) {
// To capture errors appropriately, keep as much code within the try-catch as
// possible, and only use safe functions outside.
@@ -267,17 +268,6 @@ async function run({
);
}
// Unset the CODEQL_PROXY_* environment variables when using older CodeQL
// CLIs, as they are not needed and can cause issues.
if (
process.env.CODEQL_PROXY_HOST === "" &&
!(await util.codeQlVersionAtLeast(codeql, "2.20.7"))
) {
delete process.env.CODEQL_PROXY_HOST;
delete process.env.CODEQL_PROXY_PORT;
delete process.env.CODEQL_PROXY_CA_CERTIFICATE;
}
if (actionsUtil.getOptionalInput("cleanup-level")) {
logger.info(
"The 'cleanup-level' input is ignored since the CodeQL Action now automatically " +
@@ -287,7 +277,7 @@ async function run({
const apiDetails = getApiDetails();
const outputDir = actionsUtil.getRequiredInput("output");
core.exportVariable(EnvVar.SARIF_RESULTS_OUTPUT_DIR, outputDir);
env.export(EnvVar.SARIF_RESULTS_OUTPUT_DIR, outputDir);
const threads = util.getThreadsFlag(
actionsUtil.getOptionalInput("threads") || process.env["CODEQL_THREADS"],
logger,
@@ -456,7 +446,7 @@ async function run({
`expect-error input was set to true but no error was thrown.`,
);
}
core.exportVariable(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY, "true");
env.export(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY, "true");
} catch (unwrappedError) {
const error = util.wrapError(unwrappedError);
if (
+1 -1
View File
@@ -124,7 +124,7 @@ export async function runExtraction(
language === BuiltInLanguage.cpp &&
config.buildMode === BuildMode.Autobuild
) {
await setupCppAutobuild(codeql, logger);
await setupCppAutobuild(logger);
}
// The Java and C# `build-mode: none` extractors place dependencies in the
+2 -1
View File
@@ -17,6 +17,7 @@ import {
ReadOnlyEnv,
RegistryProxyVars,
getEnv,
exportEnvVar,
} from "./environment";
import { Logger } from "./logging";
import { getRepositoryNwo, RepositoryNwo } from "./repository";
@@ -316,7 +317,7 @@ export async function getAnalysisKey(): Promise<string> {
const jobName = getRequiredEnvParam("GITHUB_JOB");
analysisKey = `${workflowPath}:${jobName}`;
core.exportVariable(EnvVar.ANALYSIS_KEY, analysisKey);
exportEnvVar(EnvVar.ANALYSIS_KEY, analysisKey);
return analysisKey;
}
+6 -2
View File
@@ -68,7 +68,11 @@ async function sendCompletedStatusReport(
}
}
async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) {
async function run({
startedAt,
env,
logger,
}: ActionState<["Base", "Env", "Logger"]>) {
// To capture errors appropriately, keep as much code within the try-catch as
// possible, and only use safe functions outside.
@@ -135,7 +139,7 @@ async function run({ startedAt, logger }: ActionState<["Base", "Logger"]>) {
return;
}
core.exportVariable(EnvVar.AUTOBUILD_DID_COMPLETE_SUCCESSFULLY, "true");
env.export(EnvVar.AUTOBUILD_DID_COMPLETE_SUCCESSFULLY, "true");
await sendCompletedStatusReport(config, logger, startedAt, languages ?? []);
}
+8 -10
View File
@@ -1,11 +1,9 @@
import * as core from "@actions/core";
import { getTemporaryDirectory, getWorkflowEventName } from "./actions-util";
import { getGitHubVersion } from "./api-client";
import { CodeQL, getCodeQL } from "./codeql";
import * as configUtils from "./config-utils";
import { DocUrl } from "./doc-url";
import { ActionsEnvVars, EnvVar } from "./environment";
import { ActionsEnvVars, EnvVar, exportEnvVar } from "./environment";
import { Feature, featureConfig, initFeatures } from "./feature-flags";
import { BuiltInLanguage, Language } from "./languages";
import { Logger } from "./logging";
@@ -112,7 +110,7 @@ export async function determineAutobuildLanguages(
return languages;
}
export async function setupCppAutobuild(codeql: CodeQL, logger: Logger) {
export async function setupCppAutobuild(logger: Logger) {
const envVar = featureConfig[Feature.CppDependencyInstallation].envVar;
const featureName = "C++ automatic installation of dependencies";
const gitHubVersion = await getGitHubVersion();
@@ -123,7 +121,7 @@ export async function setupCppAutobuild(codeql: CodeQL, logger: Logger) {
getTemporaryDirectory(),
logger,
);
if (await features.getValue(Feature.CppDependencyInstallation, codeql)) {
if (await features.getValue(Feature.CppDependencyInstallation)) {
// disable autoinstall on self-hosted runners unless explicitly requested
if (
process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] === "self-hosted" &&
@@ -136,16 +134,16 @@ export async function setupCppAutobuild(codeql: CodeQL, logger: Logger) {
: ""
}`,
);
core.exportVariable(envVar, "false");
exportEnvVar(envVar, "false");
} else {
logger.info(
`Enabling ${featureName}. This can be disabled by setting the ${envVar} environment variable to 'false'. See ${DocUrl.DEFINE_ENV_VARIABLES} for more information.`,
);
core.exportVariable(envVar, "true");
exportEnvVar(envVar, "true");
}
} else {
logger.info(`Disabling ${featureName}.`);
core.exportVariable(envVar, "false");
exportEnvVar(envVar, "false");
}
}
@@ -157,7 +155,7 @@ export async function runAutobuild(
logger.startGroup(`Attempting to automatically build ${language} code`);
const codeQL = await getCodeQL(logger, config.codeQLCmd);
if (language === BuiltInLanguage.cpp) {
await setupCppAutobuild(codeQL, logger);
await setupCppAutobuild(logger);
}
if (config.buildMode) {
await codeQL.extractUsingBuildMode(config, language);
@@ -165,7 +163,7 @@ export async function runAutobuild(
await codeQL.runAutobuild(config, language);
}
if (language === BuiltInLanguage.go) {
core.exportVariable(EnvVar.DID_AUTOBUILD_GOLANG, "true");
exportEnvVar(EnvVar.DID_AUTOBUILD_GOLANG, "true");
}
logger.endGroup();
}
+3 -3
View File
@@ -17,7 +17,7 @@ import type { VersionInfo } from "./cli/types";
import { CliError, wrapCliConfigurationError } from "./cli-errors";
import { appendExtraQueryExclusions, type Config } from "./config-utils";
import { DocUrl } from "./doc-url";
import { EnvVar, getEnv } from "./environment";
import { EnvVar, getEnv, exportEnvVar } from "./environment";
import {
CodeQLDefaultVersionInfo,
Feature,
@@ -253,7 +253,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.19.4";
const CODEQL_MINIMUM_VERSION = "2.20.7";
/**
* This version will shortly become the oldest version of CodeQL that the Action will run with.
@@ -1054,7 +1054,7 @@ async function getCodeQLForCmd(
}' by 'github/codeql-action/*@v${getActionVersion()}' in your code scanning workflow to ` +
"continue using this version of the CodeQL Action.",
);
core.exportVariable(EnvVar.SUPPRESS_DEPRECATED_SOON_WARNING, "true");
exportEnvVar(EnvVar.SUPPRESS_DEPRECATED_SOON_WARNING, "true");
}
return codeql;
}
+3 -4
View File
@@ -2,7 +2,6 @@ import * as fs from "fs";
import * as path from "path";
import { performance } from "perf_hooks";
import * as core from "@actions/core";
import * as yaml from "js-yaml";
import { ActionState } from "./action-common";
@@ -46,7 +45,7 @@ import {
makeTelemetryDiagnostic,
} from "./diagnostics";
import { prepareDiffInformedAnalysis } from "./diff-informed-analysis-utils";
import { EnvVar } from "./environment";
import { EnvVar, exportEnvVar } from "./environment";
import * as errorMessages from "./error-messages";
import { Feature, FeatureEnablement, FeatureWithoutCLI } from "./feature-flags";
import {
@@ -965,10 +964,10 @@ async function setCppTrapCachingEnvironmentVariables(
);
} else if (config.trapCaches[BuiltInLanguage.cpp]) {
logger.info("Enabling TRAP caching for C/C++.");
core.exportVariable(envVar, "true");
exportEnvVar(envVar, "true");
} else {
logger.debug(`Disabling TRAP caching for C/C++.`);
core.exportVariable(envVar, "false");
exportEnvVar(envVar, "false");
}
}
}
+7 -55
View File
@@ -55,25 +55,20 @@ test("getArtifactSuffix", (t) => {
}
});
// These next tests check the correctness of the logic to determine whether or not
// artifacts are uploaded in debug mode. Since it's not easy to mock the actual
// call to upload an artifact, we just check that we get an "upload-failed" result,
// instead of actually uploading the artifact.
//
// For tests where we expect artifact upload to be blocked, we check for a different
// response from the function.
// These next tests check whether `uploadArtifacts` attempts to upload an artifact. Since it's not
// easy to mock the actual call to upload an artifact, we check that we get an "upload-failed"
// result, instead of actually uploading the artifact.
test("uploadDebugArtifacts when artifacts empty should emit 'no-artifacts-to-upload'", async (t) => {
test("uploadArtifacts returns 'no-artifacts-to-upload' when there are no files to upload", async (t) => {
// Test that no error is thrown if artifacts list is empty.
const logger = getActionsLogger();
await t.notThrowsAsync(async () => {
const uploaded = await debugArtifacts.uploadDebugArtifacts(
const uploaded = await debugArtifacts.uploadArtifacts(
logger,
[],
"i-dont-exist",
"artifactName",
GitHubVariant.DOTCOM,
undefined,
);
t.is(
uploaded,
@@ -83,17 +78,15 @@ test("uploadDebugArtifacts when artifacts empty should emit 'no-artifacts-to-upl
});
});
test("uploadDebugArtifacts when no codeql version is used should invoke artifact upload", async (t) => {
// Test that the artifact is uploaded.
test("uploadArtifacts attempts an upload when there are files to upload", async (t) => {
const logger = getActionsLogger();
await t.notThrowsAsync(async () => {
const uploaded = await debugArtifacts.uploadDebugArtifacts(
const uploaded = await debugArtifacts.uploadArtifacts(
logger,
["hucairz"],
"i-dont-exist",
"artifactName",
GitHubVariant.DOTCOM,
undefined,
);
t.is(
uploaded,
@@ -103,44 +96,3 @@ test("uploadDebugArtifacts when no codeql version is used should invoke artifact
);
});
});
test("uploadDebugArtifacts when new codeql version is used should invoke artifact upload", async (t) => {
// Test that the artifact is uploaded.
const logger = getActionsLogger();
await t.notThrowsAsync(async () => {
const uploaded = await debugArtifacts.uploadDebugArtifacts(
logger,
["hucairz"],
"i-dont-exist",
"artifactName",
GitHubVariant.DOTCOM,
"2.20.3",
);
t.is(
uploaded,
// The failure is expected since we don't want to actually upload any artifacts in unit tests.
"upload-failed",
"Expect failure to upload artifacts since root dir does not exist",
);
});
});
test("uploadDebugArtifacts when old codeql is used should avoid trying to upload artifacts", async (t) => {
// Test that the artifact is not uploaded.
const logger = getActionsLogger();
await t.notThrowsAsync(async () => {
const uploaded = await debugArtifacts.uploadDebugArtifacts(
logger,
["hucairz"],
"i-dont-exist",
"artifactName",
GitHubVariant.DOTCOM,
"2.20.2",
);
t.is(
uploaded,
"upload-not-supported",
"Expected artifact upload to be blocked because of old CodeQL version",
);
});
});
+4 -32
View File
@@ -11,14 +11,10 @@ import { dbIsFinalized } from "./analyze";
import { scanArtifactsForTokens } from "./artifact-scanner";
import { type CodeQL } from "./codeql";
import { Config } from "./config-utils";
import { EnvVar } from "./environment";
import { EnvVar, exportEnvVar } from "./environment";
import * as json from "./json";
import { Language } from "./languages";
import { Logger, withGroup } from "./logging";
import {
isSafeArtifactUpload,
SafeArtifactUploadVersion,
} from "./tools-features";
import {
bundleDb,
doesDirectoryExist,
@@ -40,7 +36,6 @@ export function sanitizeArtifactName(name: string): string {
export async function uploadCombinedSarifArtifacts(
logger: Logger,
gitHubVariant: GitHubVariant,
codeQlVersion: string | undefined,
) {
const tempDir = getTemporaryDirectory();
@@ -70,13 +65,12 @@ export async function uploadCombinedSarifArtifacts(
}
try {
await uploadDebugArtifacts(
await uploadArtifacts(
logger,
toUpload,
baseTempDir,
"combined-sarif-artifacts",
gitHubVariant,
codeQlVersion,
);
} catch (e) {
logger.warning(
@@ -172,7 +166,6 @@ export async function tryUploadAllAvailableDebugArtifacts(
codeql: CodeQL,
config: Config,
logger: Logger,
codeQlVersion: string | undefined,
) {
const filesToUpload: string[] = [];
try {
@@ -231,13 +224,12 @@ export async function tryUploadAllAvailableDebugArtifacts(
try {
await withGroup("Uploading debug artifacts", async () =>
uploadDebugArtifacts(
uploadArtifacts(
logger,
filesToUpload,
config.dbLocation,
config.debugArtifactName,
config.gitHubVersion.type,
codeQlVersion,
),
);
} catch (e) {
@@ -283,26 +275,6 @@ export type UploadArtifactsResult =
| "upload-successful"
| "upload-failed";
export async function uploadDebugArtifacts(
logger: Logger,
toUpload: string[],
rootDir: string,
artifactName: string,
ghVariant: GitHubVariant,
codeQlVersion: string | undefined,
): Promise<UploadArtifactsResult | "upload-not-supported"> {
const uploadSupported = isSafeArtifactUpload(codeQlVersion);
if (!uploadSupported) {
core.info(
`Skipping debug artifact upload because the current CLI does not support safe upload. Please upgrade to CLI v${SafeArtifactUploadVersion} or later.`,
);
return "upload-not-supported";
}
return uploadArtifacts(logger, toUpload, rootDir, artifactName, ghVariant);
}
/**
* Uploads the specified files as a single workflow artifact.
*
@@ -330,7 +302,7 @@ export async function uploadArtifacts(
// some issues early.
if (isInTestMode()) {
await scanArtifactsForTokens(toUpload, logger);
core.exportVariable("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true");
exportEnvVar("CODEQL_ACTION_ARTIFACT_SCAN_FINISHED", "true");
}
const suffix = getArtifactSuffix(getOptionalInput("matrix"));
+12
View File
@@ -0,0 +1,12 @@
import test from "ava";
import { Env, ReadOnlyEnv } from "./environment";
import { getTestEnv, setupTests } from "./testing-utils";
setupTests(test);
test("isTestingEnv() is true", (t) => {
t.true(new ReadOnlyEnv(process.env).isTestingEnv());
t.true(new Env(process.env).isTestingEnv());
t.true(getTestEnv().isTestingEnv());
});
+91 -1
View File
@@ -1,3 +1,10 @@
import * as core from "@actions/core";
/**
* This constant is set in `ava.setup.mjs` for tests.
*/
declare const __CODEQL_ACTION_TEST_ENV__: string | undefined;
/**
* Environment variables used by Default Setup to communicate the private registry proxy configuration.
*/
@@ -211,8 +218,20 @@ export enum ActionsEnvVars {
RUNNER_TOOL_CACHE = "RUNNER_TOOL_CACHE",
}
/** Environment variables which are not specific to CodeQL. */
export enum SystemEnvVar {
/**
* Used by Node and related tools to indicate what kind of environment we are running in.
*/
NODE_ENV = "NODE_ENV",
}
/** A type representing all known environment variables. */
export type KnownEnvVar = EnvVar | ActionsEnvVars | RegistryProxyVars;
export type KnownEnvVar =
| EnvVar
| ActionsEnvVars
| RegistryProxyVars
| SystemEnvVar;
/**
* Gets an environment variable, but throws an error if it is not set.
@@ -289,6 +308,26 @@ export class ReadOnlyEnv<T extends string | undefined = string | undefined> {
public entries(): Array<[string, T]> {
return Object.entries(this.vars);
}
/**
* Gets a value indicating whether we should skip uploads of
* all kinds (SARIF results, status reports, DBs, ...).
*
* This is not guaranteed to be set in all test environments.
*/
public isSkippingUploadsInTests(): boolean {
return this.getOptional(EnvVar.TEST_MODE) === "true";
}
/**
* Gets a value indicative of whether we are in a testing environment
* by testing whether the value of the `NODE_ENV` variable is "test".
* This is expected to be the case if e.g. `ava` is running the tests
* or if this instance was constructed by `getTestEnv`.
*/
public isTestingEnv(): boolean {
return __CODEQL_ACTION_TEST_ENV__ === "unit-test";
}
}
/**
@@ -307,6 +346,26 @@ export class Env<
this.changed = true;
}
/**
* Wrapper around `core.exportVariable` which does not call `core.exportVariable`
* when running unit tests. This is important, because otherwise `core.exportVariable`
* sets environment variables for other steps in a workflow when we run unit tests in CI.
*
* @param name The name of the environment variable to set and export.
* @param val The value to set and export for the environment variable.
*/
public export(name: string, val: T): void {
// Setting the environment variable for this instance is always OK, including
// in tests, since we use fresh `Env` instances whenever needed. This allows
// tests to pass that rely on that part of the `core.exportVariable` behaviour.
this.set(name, val);
// Call `core.exportVariable` whenever we are not in a test environment.
if (!this.isTestingEnv()) {
core.exportVariable(name, val);
}
}
/** Gets a value indicating whether `set` was called at least once. */
public hasChanged(): boolean {
return this.changed;
@@ -317,3 +376,34 @@ export class Env<
export function getEnv(env: NodeJS.ProcessEnv = process.env): Env {
return new Env(env);
}
/**
* Returns whether we are in test mode. This is used by CodeQL Action PR checks.
*
* In test mode, we skip several uploads (SARIF results, status reports, DBs, ...).
*
* @deprecated
* The purpose of this function is ambiguous. Use `isSkippingUploadsInTests` on
* a `ReadOnlyEnv` instance instead for equivalent behaviour. Use `isTestingEnv`
* to determine if we are running in a unit test.
*/
export function isInTestMode(): boolean {
return getEnv().isSkippingUploadsInTests();
}
/**
* Wrapper around `core.exportVariable` which does not call `core.exportVariable`
* when running unit tests. This is important, because otherwise `core.exportVariable`
* sets environment variables for other steps in a workflow when we run unit tests in CI.
*
* @deprecated Use `export` on an `Env` instance instead.
*/
export function exportEnvVar(name: string, val: any): void {
const env = getEnv();
if (typeof val === "string") {
env.export(name, val);
} else {
env.export(name, JSON.stringify(val));
}
}
+1 -1
View File
@@ -240,7 +240,7 @@ export const featureConfig = {
defaultValue: false,
envVar: "CODEQL_EXTRACTOR_CPP_AUTOINSTALL_DEPENDENCIES",
legacyApi: true,
minimumVersion: "2.15.0",
minimumVersion: undefined,
},
[Feature.CsharpCacheBuildModeNone]: {
defaultValue: false,
+1 -8
View File
@@ -326,7 +326,6 @@ export async function uploadFailureInfo(
codeql: CodeQL,
config: Config,
logger: Logger,
codeQlVersion: string,
) => Promise<void>,
printDebugLogs: (config: Config) => Promise<void>,
codeql: CodeQL,
@@ -381,13 +380,7 @@ export async function uploadFailureInfo(
logger.info(
"Debug mode is on. Uploading available database bundles and logs as Actions debugging artifacts...",
);
const version = await codeql.getVersion();
await uploadAllAvailableDebugArtifacts(
codeql,
config,
logger,
version.version,
);
await uploadAllAvailableDebugArtifacts(codeql, config, logger);
await printDebugLogs(config);
}
+3 -3
View File
@@ -21,7 +21,7 @@ import {
DependencyCachingUsageReport,
getDependencyCacheUsage,
} from "./dependency-caching";
import { EnvVar, getEnv } from "./environment";
import { EnvVar, getEnv, exportEnvVar } from "./environment";
import { initFeatures } from "./feature-flags";
import * as gitUtils from "./git-utils";
import * as initActionPostHelper from "./init-action-post-helper";
@@ -166,7 +166,7 @@ function getFinalJobStatus(config: Config | undefined): JobStatus {
let jobStatus: JobStatus;
if (process.env[EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY] === "true") {
core.exportVariable(EnvVar.JOB_STATUS, JobStatus.SuccessStatus);
exportEnvVar(EnvVar.JOB_STATUS, JobStatus.SuccessStatus);
jobStatus = JobStatus.SuccessStatus;
} else if (config !== undefined) {
// - We have computed a CodeQL config
@@ -191,7 +191,7 @@ function getFinalJobStatus(config: Config | undefined): JobStatus {
// This shouldn't be necessary, but in the odd case that we run more than one
// `init` post step, ensure the job status is consistent between them.
core.exportVariable(EnvVar.JOB_STATUS, jobStatus);
exportEnvVar(EnvVar.JOB_STATUS, jobStatus);
return jobStatus;
}
+27 -33
View File
@@ -5,7 +5,12 @@ import * as core from "@actions/core";
import * as io from "@actions/io";
import * as semver from "semver";
import { Action, ActionState, runInActions } from "./action-common";
import {
Action,
ActionState,
extendActionState,
runInActions,
} from "./action-common";
import {
FileCmdNotFoundError,
getActionVersion,
@@ -93,7 +98,6 @@ import {
checkActionVersion,
getErrorMessage,
BuildMode,
getOptionalEnvVar,
} from "./util";
import { checkWorkflow } from "./workflow";
@@ -253,7 +257,7 @@ async function run(
);
const repositoryProperties = repositoryPropertiesResult.orElse({});
core.exportVariable(EnvVar.INIT_ACTION_HAS_RUN, "true");
actionState.env.export(EnvVar.INIT_ACTION_HAS_RUN, "true");
// path.resolve() respects the intended semantics of source-root. If
// source-root is relative, it is relative to the GITHUB_WORKSPACE. If
@@ -278,7 +282,9 @@ async function run(
}
// Compute the value of the `config-file` input.
const actionStateWithFeatures = { ...actionState, features };
const actionStateWithFeatures = extendActionState(actionState, {
features,
});
configFile = await getConfigFileInput(
actionStateWithFeatures,
repositoryProperties,
@@ -349,7 +355,7 @@ async function run(
// to the workflow log. No exceptions are thrown.
await checkWorkflow(logger, codeql);
// Set CODEQL_ENABLE_EXPERIMENTAL_FEATURES for Rust if between 2.19.3 (included) and 2.22.1 (excluded)
// Set CODEQL_ENABLE_EXPERIMENTAL_FEATURES for Rust if the CLI is older than 2.22.1.
// We need to set this environment variable before initializing the config, otherwise Rust
// analysis will not be enabled (experimental language packs are only active with that environment
// variable set to `true`).
@@ -360,16 +366,10 @@ async function run(
.getRawLanguagesNoAutodetect(getOptionalInput("languages"))
.includes(BuiltInLanguage.rust)
) {
const experimental = "2.19.3";
const publicPreview = "2.22.1";
const actualVer = (await codeql.getVersion()).version;
if (semver.lt(actualVer, experimental)) {
throw new ConfigurationError(
`Rust analysis is supported by CodeQL CLI version ${experimental} or higher, but found version ${actualVer}`,
);
}
if (semver.lt(actualVer, publicPreview)) {
core.exportVariable(EnvVar.EXPERIMENTAL_FEATURES, "true");
actionState.env.export(EnvVar.EXPERIMENTAL_FEATURES, "true");
logger.info("Experimental Rust analysis enabled");
}
}
@@ -517,9 +517,9 @@ async function run(
}
// Forward Go flags
const goFlags = process.env["GOFLAGS"];
const goFlags = actionState.env.getOptional("GOFLAGS");
if (goFlags) {
core.exportVariable("GOFLAGS", goFlags);
actionState.env.export("GOFLAGS", goFlags);
core.warning(
"Passing the GOFLAGS env parameter to the init action is deprecated. Please move this to the analyze action.",
);
@@ -565,7 +565,7 @@ async function run(
// Store the original location of our wrapper script somewhere where we can
// later retrieve it from and cross-check that it hasn't been changed.
core.exportVariable(EnvVar.GO_BINARY_LOCATION, goWrapperPath);
actionState.env.export(EnvVar.GO_BINARY_LOCATION, goWrapperPath);
} catch (e) {
logger.warning(
`Analyzing Go on Linux, but failed to install wrapper script. Tracing custom builds may fail: ${e}`,
@@ -574,7 +574,7 @@ async function run(
} else {
// Store the location of the original Go binary, so we can check that no setup tasks were performed after the
// `init` Action ran.
core.exportVariable(EnvVar.GO_BINARY_LOCATION, goBinaryPath);
actionState.env.export(EnvVar.GO_BINARY_LOCATION, goBinaryPath);
}
} catch (e) {
logger.warning(
@@ -609,12 +609,12 @@ async function run(
// threads it would ask extractors to use. See help text for the "--ram" and "--threads"
// options at https://codeql.github.com/docs/codeql-cli/manual/database-trace-command/
// for details.
core.exportVariable(
actionState.env.export(
"CODEQL_RAM",
process.env["CODEQL_RAM"] ||
getCodeQLMemoryLimit(getOptionalInput("ram"), logger).toString(),
);
core.exportVariable(
actionState.env.export(
"CODEQL_THREADS",
process.env["CODEQL_THREADS"] ||
getThreadsFlagValue(getOptionalInput("threads"), logger).toString(),
@@ -622,21 +622,15 @@ async function run(
// Disable Kotlin extractor if feature flag set
if (await features.getValue(Feature.DisableKotlinAnalysisEnabled)) {
core.exportVariable("CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN", "true");
actionState.env.export(
"CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN",
"true",
);
}
// Emergency override to force the CodeQL CLI back to the JGit-based Git backend.
if (await features.getValue(Feature.ForceJGit)) {
core.exportVariable("CODEQL_GIT_BACKEND", "jgit");
}
const kotlinLimitVar =
"CODEQL_EXTRACTOR_KOTLIN_OVERRIDE_MAXIMUM_VERSION_LIMIT";
if (
(await codeQlVersionAtLeast(codeql, "2.20.3")) &&
!(await codeQlVersionAtLeast(codeql, "2.20.4"))
) {
core.exportVariable(kotlinLimitVar, "2.1.20");
actionState.env.export("CODEQL_GIT_BACKEND", "jgit");
}
// Restore dependency cache(s), if they exist.
@@ -685,7 +679,7 @@ async function run(
config.buildMode === BuildMode.None &&
config.languages.includes(BuiltInLanguage.java)
) {
core.exportVariable(
actionState.env.export(
EnvVar.JAVA_EXTRACTOR_MINIMIZE_DEPENDENCY_JARS,
"true",
);
@@ -743,7 +737,7 @@ async function run(
const tracerConfig = await getCombinedTracerConfig(logger, codeql, config);
if (tracerConfig !== undefined) {
for (const [key, value] of Object.entries(tracerConfig.env)) {
core.exportVariable(key, value);
actionState.env.export(key, value);
}
}
@@ -751,10 +745,10 @@ async function run(
if (await features.getValue(Feature.JavaNetworkDebugging)) {
// Get the existing value of `JAVA_TOOL_OPTIONS`, if any.
const existingJavaToolOptions =
getOptionalEnvVar(JavaEnvVars.JAVA_TOOL_OPTIONS) || "";
actionState.env.getOptional(JavaEnvVars.JAVA_TOOL_OPTIONS) ?? "";
// Add the network debugging options.
core.exportVariable(
actionState.env.export(
JavaEnvVars.JAVA_TOOL_OPTIONS,
`${existingJavaToolOptions} -Djavax.net.debug=all`,
);
+16 -17
View File
@@ -1,14 +1,13 @@
import * as fs from "fs";
import path from "path";
import * as core from "@actions/core";
import * as github from "@actions/github";
import test, { ExecutionContext } from "ava";
import * as sinon from "sinon";
import * as actionsUtil from "./actions-util";
import { createStubCodeQL } from "./codeql";
import { ActionsEnvVars } from "./environment";
import * as environment from "./environment";
import { Feature } from "./feature-flags";
import {
checkPacksForOverlayCompatibility,
@@ -85,7 +84,7 @@ for (const { runnerEnv, ErrorConstructor, message } of [
`cleanupDatabaseClusterDirectory throws a ${ErrorConstructor.name} when cleanup fails on ${runnerEnv} runner`,
async (t) => {
await withTmpDir(async (tmpDir: string) => {
process.env[ActionsEnvVars.RUNNER_ENVIRONMENT] = runnerEnv;
process.env[environment.ActionsEnvVars.RUNNER_ENVIRONMENT] = runnerEnv;
const dbLocation = path.resolve(tmpDir, "dbs");
fs.mkdirSync(dbLocation, { recursive: true });
@@ -546,7 +545,7 @@ test.serial(
test.serial(
"file coverage deprecation warning for org-owned repo with default setup recommends repo property",
(t) => {
const exportVariableStub = sinon.stub(core, "exportVariable");
const exportEnvVarStub = sinon.stub(environment, "exportEnvVar");
sinon.stub(actionsUtil, "isDefaultSetup").returns(true);
github.context.payload = {
repository: {
@@ -566,14 +565,14 @@ test.serial(
'with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to ' +
"`true` in the repository's settings.",
);
t.true(exportVariableStub.calledOnce);
t.true(exportEnvVarStub.calledOnce);
},
);
test.serial(
"file coverage deprecation warning for org-owned repo with advanced setup recommends env var and repo property",
(t) => {
const exportVariableStub = sinon.stub(core, "exportVariable");
const exportEnvVarStub = sinon.stub(environment, "exportEnvVar");
sinon.stub(actionsUtil, "isDefaultSetup").returns(false);
github.context.payload = {
repository: {
@@ -594,14 +593,14 @@ test.serial(
'with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to ' +
"`true` in the repository's settings.",
);
t.true(exportVariableStub.calledOnce);
t.true(exportEnvVarStub.calledOnce);
},
);
test.serial(
"file coverage deprecation warning for user-owned repo with default setup recommends advanced setup",
(t) => {
const exportVariableStub = sinon.stub(core, "exportVariable");
const exportEnvVarStub = sinon.stub(environment, "exportEnvVar");
sinon.stub(actionsUtil, "isDefaultSetup").returns(true);
github.context.payload = {
repository: {
@@ -620,14 +619,14 @@ test.serial(
"To opt out of this change, switch to an advanced setup workflow and " +
"set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.",
);
t.true(exportVariableStub.calledOnce);
t.true(exportEnvVarStub.calledOnce);
},
);
test.serial(
"file coverage deprecation warning for user-owned repo with advanced setup recommends env var",
(t) => {
const exportVariableStub = sinon.stub(core, "exportVariable");
const exportEnvVarStub = sinon.stub(environment, "exportEnvVar");
sinon.stub(actionsUtil, "isDefaultSetup").returns(false);
github.context.payload = {
repository: {
@@ -645,14 +644,14 @@ test.serial(
"to improve analysis performance. File coverage information will still be computed on non-PR analyses.\n\n" +
"To opt out of this change, set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.",
);
t.true(exportVariableStub.calledOnce);
t.true(exportEnvVarStub.calledOnce);
},
);
test.serial(
"file coverage deprecation warning for unknown owner type with default setup recommends advanced setup",
(t) => {
const exportVariableStub = sinon.stub(core, "exportVariable");
const exportEnvVarStub = sinon.stub(environment, "exportEnvVar");
sinon.stub(actionsUtil, "isDefaultSetup").returns(true);
github.context.payload = { repository: undefined };
const messages: LoggedMessage[] = [];
@@ -666,14 +665,14 @@ test.serial(
"To opt out of this change, switch to an advanced setup workflow and " +
"set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.",
);
t.true(exportVariableStub.calledOnce);
t.true(exportEnvVarStub.calledOnce);
},
);
test.serial(
"file coverage deprecation warning for unknown owner type with advanced setup recommends env var",
(t) => {
const exportVariableStub = sinon.stub(core, "exportVariable");
const exportEnvVarStub = sinon.stub(environment, "exportEnvVar");
sinon.stub(actionsUtil, "isDefaultSetup").returns(false);
github.context.payload = { repository: undefined };
const messages: LoggedMessage[] = [];
@@ -686,7 +685,7 @@ test.serial(
"to improve analysis performance. File coverage information will still be computed on non-PR analyses.\n\n" +
"To opt out of this change, set the `CODEQL_ACTION_FILE_COVERAGE_ON_PRS` environment variable to `true`.",
);
t.true(exportVariableStub.calledOnce);
t.true(exportEnvVarStub.calledOnce);
},
);
@@ -695,10 +694,10 @@ test.serial(
(t) => {
process.env["CODEQL_ACTION_DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION"] =
"true";
const exportVariableStub = sinon.stub(core, "exportVariable");
const exportEnvVarStub = sinon.stub(environment, "exportEnvVar");
const messages: LoggedMessage[] = [];
logFileCoverageOnPrsDeprecationWarning(getRecordingLogger(messages));
t.is(messages.length, 0);
t.true(exportVariableStub.notCalled);
t.true(exportEnvVarStub.notCalled);
},
);
+2 -3
View File
@@ -1,7 +1,6 @@
import * as fs from "fs";
import * as path from "path";
import * as core from "@actions/core";
import * as toolrunner from "@actions/exec/lib/toolrunner";
import * as github from "@actions/github";
import * as io from "@actions/io";
@@ -17,7 +16,7 @@ import {
import { GitHubApiDetails } from "./api-client";
import { CodeQL, setupCodeQL } from "./codeql";
import * as configUtils from "./config-utils";
import { EnvVar } from "./environment";
import { EnvVar, exportEnvVar } from "./environment";
import {
CodeQLDefaultVersionInfo,
Feature,
@@ -411,5 +410,5 @@ export function logFileCoverageOnPrsDeprecationWarning(logger: Logger): void {
}
logger.warning(message);
core.exportVariable(EnvVar.DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION, "true");
exportEnvVar(EnvVar.DID_LOG_FILE_COVERAGE_ON_PRS_DEPRECATION, "true");
}
+2 -1
View File
@@ -8,6 +8,7 @@ import * as sinon from "sinon";
import * as actionsUtil from "../actions-util";
import * as apiClient from "../api-client";
import type { ResolveDatabaseOutput } from "../codeql";
import * as environment from "../environment";
import * as gitUtils from "../git-utils";
import { BuiltInLanguage } from "../languages";
import { getRunnerLogger } from "../logging";
@@ -82,7 +83,7 @@ const testDownloadOverlayBaseDatabaseFromCache = makeMacro({
sinon.stub(apiClient, "getAutomationID").resolves("test-automation-id/");
sinon.stub(utils, "isInTestMode").returns(testCase.isInTestMode);
sinon.stub(environment, "isInTestMode").returns(testCase.isInTestMode);
if (testCase.restoreCacheResult instanceof Error) {
sinon
+10 -3
View File
@@ -1,6 +1,11 @@
import * as core from "@actions/core";
import { Action, ActionState, runInActions } from "./action-common";
import {
Action,
ActionState,
extendActionState,
runInActions,
} from "./action-common";
import {
getActionVersion,
getOptionalInput,
@@ -131,7 +136,9 @@ async function run(
);
const repositoryProperties = repositoryPropertiesResult.orElse({});
const actionStateWithFeatures = { ...actionState, features };
const actionStateWithFeatures = extendActionState(actionState, {
features,
});
const statusReportBase = await createStatusReportBase(
ActionName.SetupCodeQL,
@@ -184,7 +191,7 @@ async function run(
core.setOutput("codeql-path", codeql.getPath());
core.setOutput("codeql-version", (await codeql.getVersion()).version);
core.exportVariable(EnvVar.SETUP_CODEQL_ACTION_HAS_RUN, "true");
actionState.env.export(EnvVar.SETUP_CODEQL_ACTION_HAS_RUN, "true");
} catch (unwrappedError) {
const error = wrapError(unwrappedError);
core.setFailed(error.message);
+2 -3
View File
@@ -3,7 +3,6 @@ import { OutgoingHttpHeaders } from "http";
import * as path from "path";
import { performance } from "perf_hooks";
import * as core from "@actions/core";
import * as toolcache from "@actions/tool-cache";
import { default as deepEqual } from "fast-deep-equal";
import * as semver from "semver";
@@ -29,7 +28,7 @@ import {
makeDiagnostic,
makeTelemetryDiagnostic,
} from "./diagnostics";
import { EnvVar, getEnv } from "./environment";
import { EnvVar, exportEnvVar, getEnv } from "./environment";
import {
CODEQL_VERSION_ZSTD_BUNDLE,
CodeQLDefaultVersionInfo,
@@ -1071,7 +1070,7 @@ export async function setupCodeQLBundle(
// Record that this job now has a copy of the CodeQL tools, so that a later step doesn't delete
// the toolcache out from under the path we are about to return.
core.exportVariable(EnvVar.HAS_SET_UP_CODEQL, "true");
exportEnvVar(EnvVar.HAS_SET_UP_CODEQL, "true");
return {
codeqlFolder,
+8 -2
View File
@@ -3,7 +3,12 @@ import * as path from "path";
import * as core from "@actions/core";
import { Action, ActionState, runInActions } from "./action-common";
import {
Action,
ActionState,
extendActionState,
runInActions,
} from "./action-common";
import * as actionsUtil from "./actions-util";
import { getGitHubVersion } from "./api-client";
import { FeatureEnablement, initFeatures } from "./feature-flags";
@@ -98,7 +103,8 @@ async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) {
};
// Start the Proxy
const proxyBin = await getProxyBinaryPath({ ...action, features });
const actionWithFeatures = extendActionState(action, { features });
const proxyBin = await getProxyBinaryPath(actionWithFeatures);
const proxyInfo = await startProxy(
proxyBin,
proxyConfig,
+13 -9
View File
@@ -23,7 +23,13 @@ import type { ComputedInput, InputName } from "./config/inputs";
import { parseRegistriesWithoutCredentials } from "./config/pack-registries";
import type { DependencyCacheRestoreStatusReport } from "./dependency-caching";
import { DocUrl } from "./doc-url";
import { EnvVar, getEnv, ReadOnlyEnv, RegistryProxyVars } from "./environment";
import {
EnvVar,
getEnv,
ReadOnlyEnv,
RegistryProxyVars,
exportEnvVar,
} from "./environment";
import { getRef } from "./git-utils";
import * as json from "./json";
import type { Logger } from "./logging";
@@ -71,9 +77,7 @@ export function getDisplayActionName(actionName: ActionName): string {
* environment and returns it.
* If a new UUID is generated, it is also exported as an environment variable.
*/
export function getJobUUID(
action: ActionState<["Logger", "ReadOnlyEnv", "Actions"]>,
) {
export function getJobUUID(action: ActionState<["Logger", "Env", "Actions"]>) {
// Check if we already have a UUID for the analysis and return it if so.
const existingJobRunUuid = action.env.getOptional(EnvVar.JOB_RUN_UUID);
@@ -86,7 +90,7 @@ export function getJobUUID(
const jobRunUuid = uuid.v4();
action.logger.info(`Job run UUID is ${jobRunUuid}.`);
action.actions.exportVariable(EnvVar.JOB_RUN_UUID, jobRunUuid);
action.env.export(EnvVar.JOB_RUN_UUID, jobRunUuid);
return jobRunUuid;
}
@@ -268,12 +272,12 @@ export function getJobStatusDisplayName(status: JobStatus): string {
*/
function setJobStatusIfUnsuccessful(actionStatus: ActionStatus) {
if (actionStatus === "user-error") {
core.exportVariable(
exportEnvVar(
EnvVar.JOB_STATUS,
process.env[EnvVar.JOB_STATUS] ?? JobStatus.ConfigErrorStatus,
);
} else if (actionStatus === "failure" || actionStatus === "aborted") {
core.exportVariable(
exportEnvVar(
EnvVar.JOB_STATUS,
process.env[EnvVar.JOB_STATUS] ?? JobStatus.FailureStatus,
);
@@ -376,7 +380,7 @@ export async function createStatusReportBase(
let workflowStartedAt = process.env[EnvVar.WORKFLOW_STARTED_AT];
if (workflowStartedAt === undefined) {
workflowStartedAt = actionStartedAt.toISOString();
core.exportVariable(EnvVar.WORKFLOW_STARTED_AT, workflowStartedAt);
exportEnvVar(EnvVar.WORKFLOW_STARTED_AT, workflowStartedAt);
}
const runnerOs = getRequiredEnvParam("RUNNER_OS");
const codeQlCliVersion = getCachedCodeQlVersion(
@@ -388,7 +392,7 @@ export async function createStatusReportBase(
// re-export the testing environment variable so that it is available to subsequent steps,
// even if it was only set for this step
if (testingEnvironment) {
core.exportVariable(EnvVar.TESTING_ENVIRONMENT, testingEnvironment);
exportEnvVar(EnvVar.TESTING_ENVIRONMENT, testingEnvironment);
}
const isSteadyStateDefaultSetupRun =
process.env["CODE_SCANNING_IS_STEADY_STATE_DEFAULT_SETUP"] === "true";
-4
View File
@@ -202,10 +202,6 @@ class TestActionsEnv implements ActionsEnv {
public getOptionalInput(_name: string): string | undefined {
return undefined;
}
public exportVariable(name: string, value: string): void {
this.env.set(name, value);
}
}
/**
-20
View File
@@ -1,5 +1,3 @@
import * as semver from "semver";
import type { VersionInfo } from "./cli/types";
export enum ToolsFeature {
@@ -23,21 +21,3 @@ export function isSupportedToolsFeature(
): boolean {
return !!versionInfo.features && versionInfo.features[feature];
}
export const SafeArtifactUploadVersion = "2.20.3";
/**
* The first version of the CodeQL CLI where artifact upload is safe to use
* for failed runs. This is not really a feature flag, but it is easiest to
* model the behavior as a feature flag.
*
* This was not captured in a tools feature, so we need to use semver.
*
* @param codeQlVersion The version of the CodeQL CLI to check. If not provided, it is assumed to be safe.
* @returns True if artifact upload is safe to use for failed runs or false otherwise.
*/
export function isSafeArtifactUpload(codeQlVersion?: string): boolean {
return !codeQlVersion
? true
: semver.gte(codeQlVersion, SafeArtifactUploadVersion);
}
+3 -3
View File
@@ -14,7 +14,7 @@ import { getGitHubVersion, wrapApiConfigurationError } from "./api-client";
import { CodeQL, getCodeQL } from "./codeql";
import { getConfig } from "./config-utils";
import { readDiffRangesJsonFile } from "./diff-informed-analysis-utils";
import { EnvVar } from "./environment";
import { EnvVar, exportEnvVar } from "./environment";
import { FeatureEnablement } from "./feature-flags";
import * as fingerprints from "./fingerprints";
import * as gitUtils from "./git-utils";
@@ -126,7 +126,7 @@ async function combineSarifFilesUsingCLI(
logger.warning(
`Uploading multiple SARIF runs with the same category is deprecated ${deprecationWarningMessage}. Please update your workflow to upload a single run per category. ${deprecationMoreInformationMessage}`,
);
core.exportVariable("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true");
exportEnvVar("CODEQL_MERGE_SARIF_DEPRECATION_WARNING", "true");
}
// If not, use the naive method of combining the files.
@@ -1032,7 +1032,7 @@ export function validateUniqueCategory(
`Category: (${id ? id : "none"}) Tool: (${tool ? tool : "none"})`,
);
}
core.exportVariable(sentinelEnvVar, sentinelEnvVar);
exportEnvVar(sentinelEnvVar, sentinelEnvVar);
}
}
+1 -7
View File
@@ -34,13 +34,7 @@ export async function runWrapper() {
return;
}
await withGroup("Uploading combined SARIF debug artifact", () =>
debugArtifacts.uploadCombinedSarifArtifacts(
logger,
gitHubVersion.type,
// The codeqlVersion is not applicable for uploading non-codeql sarif.
// We can assume all versions are safe to upload.
undefined,
),
debugArtifacts.uploadCombinedSarifArtifacts(logger, gitHubVersion.type),
);
}
} catch (error) {
+20 -19
View File
@@ -14,13 +14,23 @@ import * as apiCompatibility from "./api-compatibility.json";
import type { CodeQL } from "./codeql";
import type { Pack } from "./config/db-config";
import type { Config } from "./config-utils";
import { EnvVar, getRequiredEnvParam } from "./environment";
import {
EnvVar,
getRequiredEnvParam,
isInTestMode,
exportEnvVar,
} from "./environment";
import * as json from "./json";
import { Language } from "./languages";
import { Logger } from "./logging";
// Re-export for backwards compatibility to avoid updating a lot of imports elsewhere.
export { getRequiredEnvParam, getOptionalEnvVar, getEnv } from "./environment";
export {
getRequiredEnvParam,
getOptionalEnvVar,
getEnv,
isInTestMode,
} from "./environment";
/**
* The name of the file containing the base database OIDs, as stored in the
@@ -542,7 +552,7 @@ export function checkGitHubVersionInRange(
);
}
hasBeenWarnedAboutVersion = true;
core.exportVariable(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true);
exportEnvVar(CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR, true);
}
export enum DisallowedAPIVersionReason {
@@ -586,11 +596,11 @@ export function assertNever(value: never): never {
* knowing what version of CodeQL we're running.
*/
export function initializeEnvironment(version: string) {
core.exportVariable(EnvVar.FEATURE_MULTI_LANGUAGE, "false");
core.exportVariable(EnvVar.FEATURE_SANDWICH, "false");
core.exportVariable(EnvVar.FEATURE_SARIF_COMBINE, "true");
core.exportVariable(EnvVar.FEATURE_WILL_UPLOAD, "true");
core.exportVariable(EnvVar.VERSION, version);
exportEnvVar(EnvVar.FEATURE_MULTI_LANGUAGE, "false");
exportEnvVar(EnvVar.FEATURE_SANDWICH, "false");
exportEnvVar(EnvVar.FEATURE_SARIF_COMBINE, "true");
exportEnvVar(EnvVar.FEATURE_WILL_UPLOAD, "true");
exportEnvVar(EnvVar.VERSION, version);
}
export class HTTPError extends Error {
@@ -711,15 +721,6 @@ export function isGoodVersion(versionSpec: string) {
return !BROKEN_VERSIONS.includes(versionSpec);
}
/**
* Returns whether we are in test mode. This is used by CodeQL Action PR checks.
*
* In test mode, we skip several uploads (SARIF results, status reports, DBs, ...).
*/
export function isInTestMode(): boolean {
return process.env[EnvVar.TEST_MODE] === "true";
}
/**
* Returns whether we specifically want to skip uploading SARIF files.
*/
@@ -948,7 +949,7 @@ export async function checkDiskUsage(
} else {
logger.debug(message);
}
core.exportVariable(EnvVar.HAS_WARNED_ABOUT_DISK_SPACE, "true");
exportEnvVar(EnvVar.HAS_WARNED_ABOUT_DISK_SPACE, "true");
}
return {
numAvailableBytes: diskUsage.bavail * blockSizeInBytes,
@@ -997,7 +998,7 @@ export function checkActionVersion(
"https://github.blog/changelog/2025-10-28-upcoming-deprecation-of-codeql-action-v3/",
);
// set LOG_VERSION_DEPRECATION env var to prevent the warning from being logged multiple times
core.exportVariable(EnvVar.LOG_VERSION_DEPRECATION, "true");
exportEnvVar(EnvVar.LOG_VERSION_DEPRECATION, "true");
}
}
}
+24
View File
@@ -0,0 +1,24 @@
## Change notes
Change-notes are Markdown files used to document user-facing changes. When making a change that affects users, create a Markdown file here that describes the change. During the next release, the change-note files in `unreleased-change-notes/` will automatically be added to `CHANGELOG.md`.
### Change-note file format
Change-note files must follow a certain format so that they can be automatically validated and processed. Failure to follow the format will result in a failed PR check.
You may validate your change-note file locally by running `npx tsx pr-checks/changenotes.ts validate`. This command will scan all change-note files in `unreleased-change-notes/` and report any errors.
#### Body
The body of the change-note file must:
- Be written in valid [GitHub-Flavored Markdown](https://github.github.com/gfm/).
- Be structured as a single unordered Markdown list with hyphen (`-`) bullets. Each list item should describe a single change. If there are multiple changes, use multiple list items.
### Example change-note file
```
- Fixed a bug where a network error while streaming the download of the CodeQL bundle could terminate the `init` Action instead of falling back to downloading the bundle before extracting it. [#4061](https://github.com/github/codeql-action/pull/4061)
- Fix incorrect minimum required Git version for [improved incremental analysis](https://github.com/github/roadmap/issues/1158): it should have been 2.36.0, not 2.11.0. [#3781](https://github.com/github/codeql-action/pull/3781)
```