Skip to content

Commit 4eabea6

Browse files
committed
Merge remote-tracking branch 'origin/main' into mbg/start-proxy/report-version
2 parents 1580058 + ee07b50 commit 4eabea6

41 files changed

Lines changed: 1958 additions & 1288 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎lib/entry-points.js‎

Lines changed: 853 additions & 780 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package-lock.json‎

Lines changed: 96 additions & 111 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"dependencies": {
2323
"@actions/artifact": "^5.0.3",
2424
"@actions/artifact-legacy": "npm:@actions/artifact@^1.1.2",
25-
"@actions/cache": "^5.2.0",
25+
"@actions/cache": "^5.3.0",
2626
"@actions/core": "^2.0.3",
2727
"@actions/exec": "^2.0.0",
2828
"@actions/github": "^8.0.1",
@@ -31,15 +31,14 @@
3131
"@actions/io": "^2.0.0",
3232
"@actions/tool-cache": "^3.0.1",
3333
"@octokit/core": "^7.0.8",
34-
"@octokit/plugin-paginate-rest": "^15.0.0",
34+
"@octokit/plugin-paginate-rest": "^16.0.0",
3535
"@octokit/plugin-rest-endpoint-methods": "^18.0.0",
3636
"@octokit/plugin-retry": "^8.1.1",
3737
"archiver": "^8.0.0",
38-
"fast-deep-equal": "^3.1.3",
39-
"follow-redirects": "^1.16.0",
38+
"follow-redirects": "^1.16.1",
4039
"get-folder-size": "^5.0.0",
4140
"https-proxy-agent": "^7.0.6",
42-
"js-yaml": "^5.4.2",
41+
"js-yaml": "^5.4.3",
4342
"jsonschema": "1.5.0",
4443
"long": "^5.3.2",
4544
"node-forge": "^1.4.0",
@@ -66,14 +65,14 @@
6665
"eslint-import-resolver-typescript": "^4.4.5",
6766
"eslint-plugin-github": "^6.1.2",
6867
"eslint-plugin-import-x": "^4.17.1",
69-
"eslint-plugin-jsdoc": "^65.0.1",
68+
"eslint-plugin-jsdoc": "^65.2.0",
7069
"eslint-plugin-no-async-foreach": "^0.1.1",
7170
"glob": "^13.0.6",
72-
"globals": "^17.12.0",
71+
"globals": "^17.13.0",
7372
"nock": "^14.0.17",
7473
"sinon": "^22.1.0",
7574
"typescript": "^6.0.3",
76-
"typescript-eslint": "^8.70.1"
75+
"typescript-eslint": "^8.71.1"
7776
},
7877
"overrides": {
7978
"@actions/tool-cache": {

‎pr-checks/package.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
"@actions/core": "^2.0.3",
77
"@actions/github": "^8.0.1",
88
"@octokit/core": "^7.0.8",
9-
"@octokit/plugin-paginate-rest": ">=15.0.0",
9+
"@octokit/plugin-paginate-rest": ">=16.0.0",
1010
"@octokit/plugin-rest-endpoint-methods": "^18.0.0",
1111
"lite-matter": "^0.1.2",
12-
"mdast-util-from-markdown": "^2.0.3",
12+
"mdast-util-from-markdown": "^2.1.0",
1313
"semver": "^7.8.5",
1414
"yaml": "^2.9.1"
1515
},

‎src/actions-util.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,15 @@ export function getActionVersion(): string {
9393
*
9494
* This will be "dynamic" for default setup workflow runs.
9595
*/
96-
export function getWorkflowEventName(env: Env = getEnv()) {
96+
export function getWorkflowEventName(env: ReadOnlyEnv = getEnv()) {
9797
return env.getRequired(ActionsEnvVars.GITHUB_EVENT_NAME);
9898
}
9999

100100
/**
101101
* Returns whether the current workflow is executing a local copy of the Action, e.g. we're running
102102
* a workflow on the codeql-action repo itself.
103103
*/
104-
export function isRunningLocalAction(env: Env = getEnv()): boolean {
104+
export function isRunningLocalAction(env: ReadOnlyEnv = getEnv()): boolean {
105105
const relativeScriptPath = getRelativeScriptPath(env);
106106
return (
107107
relativeScriptPath.startsWith("..") || path.isAbsolute(relativeScriptPath)
@@ -113,14 +113,14 @@ export function isRunningLocalAction(env: Env = getEnv()): boolean {
113113
*
114114
* This can be used to get the Action's name or tell if we're running a local Action.
115115
*/
116-
function getRelativeScriptPath(env: Env): string {
116+
function getRelativeScriptPath(env: ReadOnlyEnv): string {
117117
const runnerTemp = env.getRequired(ActionsEnvVars.RUNNER_TEMP);
118118
const actionsDirectory = path.join(path.dirname(runnerTemp), "_actions");
119119
return path.relative(actionsDirectory, __filename);
120120
}
121121

122122
/** Returns the contents of `GITHUB_EVENT_PATH` as a JSON object. */
123-
export function getWorkflowEvent(env: Env = getEnv()): any {
123+
export function getWorkflowEvent(env: ReadOnlyEnv = getEnv()): any {
124124
const eventJsonFile = env.getRequired(ActionsEnvVars.GITHUB_EVENT_PATH);
125125
try {
126126
return JSON.parse(fs.readFileSync(eventJsonFile, "utf-8"));

‎src/analyze-action.test.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ test.serial(
4545
requiredInputStub.withArgs("token").returns("fake-token");
4646
requiredInputStub.withArgs("upload-database").returns("false");
4747
requiredInputStub.withArgs("output").returns("out");
48+
requiredInputStub.withArgs("checkout_path").returns("");
4849
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
4950
optionalInputStub.withArgs("expect-error").returns("false");
5051
sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion);
@@ -104,6 +105,7 @@ test.serial(
104105
requiredInputStub.withArgs("token").returns("fake-token");
105106
requiredInputStub.withArgs("upload-database").returns("false");
106107
requiredInputStub.withArgs("output").returns("out");
108+
requiredInputStub.withArgs("checkout_path").returns("");
107109
const optionalInputStub = sinon.stub(actionsUtil, "getOptionalInput");
108110
optionalInputStub.withArgs("expect-error").returns("false");
109111
sinon.stub(api, "getGitHubVersion").resolves(gitHubVersion);

‎src/analyze-action.ts‎

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,18 @@ import { performance } from "perf_hooks";
44

55
import * as core from "@actions/core";
66

7-
import { Action, ActionState, runInActions } from "./action-common";
7+
import {
8+
Action,
9+
ActionState,
10+
extendActionState,
11+
runInActions,
12+
} from "./action-common";
813
import * as actionsUtil from "./actions-util";
914
import * as analyses from "./analyses";
1015
import {
1116
CodeQLAnalysisError,
1217
dbIsFinalized,
18+
determineCheckoutPath,
1319
QueriesStatusReport,
1420
runFinalize,
1521
runQueries,
@@ -212,14 +218,11 @@ async function runAutobuildIfLegacyGoWorkflow(config: Config, logger: Logger) {
212218
await runAutobuild(config, BuiltInLanguage.go, logger);
213219
}
214220

215-
async function run({
216-
startedAt,
217-
env,
218-
logger,
219-
actions,
220-
}: ActionState<["Base", "Env", "Logger", "Actions"]>) {
221+
async function run(action: ActionState<["Base", "Logger", "Env", "Actions"]>) {
221222
// To capture errors appropriately, keep as much code within the try-catch as
222223
// possible, and only use safe functions outside.
224+
const startedAt = action.startedAt;
225+
const logger = action.logger;
223226

224227
let uploadResults:
225228
| Partial<Record<analyses.AnalysisKind, UploadResult>>
@@ -277,7 +280,7 @@ async function run({
277280

278281
const apiDetails = getApiDetails();
279282
const outputDir = actionsUtil.getRequiredInput("output");
280-
env.export(EnvVar.SARIF_RESULTS_OUTPUT_DIR, outputDir);
283+
action.env.export(EnvVar.SARIF_RESULTS_OUTPUT_DIR, outputDir);
281284
const threads = util.getThreadsFlag(
282285
actionsUtil.getOptionalInput("threads") || process.env["CODEQL_THREADS"],
283286
logger,
@@ -301,7 +304,7 @@ async function run({
301304
logger,
302305
);
303306

304-
const checkoutPath = actions.getRequiredInput("checkout_path");
307+
const checkoutPath = await determineCheckoutPath(action, config);
305308

306309
// Setup diff informed analysis if needed (based on whether init created the file)
307310
const diffRangePackDir = await setupDiffInformedQueryRun(
@@ -393,11 +396,13 @@ async function run({
393396
checkoutPath,
394397
);
395398

399+
const actionWithFeatures = extendActionState(action, { features });
400+
396401
// Possibly upload the database bundles for remote queries.
397402
// Note: Take care with the ordering of this call since databases may be cleaned up
398403
// at the `overlay` or `clear` level.
399404
databaseUploadResults = await cleanupAndUploadDatabases(
400-
{ logger, features },
405+
actionWithFeatures,
401406
repositoryNwo,
402407
codeql,
403408
config,
@@ -446,7 +451,7 @@ async function run({
446451
`expect-error input was set to true but no error was thrown.`,
447452
);
448453
}
449-
env.export(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY, "true");
454+
action.env.export(EnvVar.ANALYZE_DID_COMPLETE_SUCCESSFULLY, "true");
450455
} catch (unwrappedError) {
451456
const error = util.wrapError(unwrappedError);
452457
if (

‎src/analyze.test.ts‎

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,111 @@ import {
1010
resolveQuerySuiteAlias,
1111
addSarifExtension,
1212
diffRangeExtensionPackContents,
13+
determineCheckoutPath,
1314
} from "./analyze";
1415
import { createStubCodeQL } from "./codeql";
1516
import { defaultSuites } from "./config/db-config";
1617
import { Feature } from "./feature-flags";
18+
import * as gitUtils from "./git-utils";
1719
import { BuiltInLanguage } from "./languages";
1820
import { getRunnerLogger } from "./logging";
1921
import {
2022
setupTests,
2123
setupActionsVars,
2224
createFeatures,
2325
createTestConfig,
26+
callee,
2427
} from "./testing-utils";
2528
import * as uploadLib from "./upload-lib";
2629
import * as util from "./util";
2730

2831
setupTests(test);
2932

33+
test.serial(
34+
"determineCheckoutPath - logs when checkout_path is not in a work tree",
35+
async (t) => {
36+
const expectedPath = path.resolve("/checkout/path");
37+
const target = callee(determineCheckoutPath)
38+
.withActions((actions) => {
39+
sinon
40+
.stub(actions, "getRequiredInput")
41+
.withArgs("checkout_path")
42+
.returns(expectedPath);
43+
})
44+
.withArgs(createTestConfig({}));
45+
sinon.stub(gitUtils, "getGitRoot").resolves(undefined);
46+
47+
await target
48+
.logs(t, "is not in the work tree of a git repository")
49+
.passes(t.is, expectedPath);
50+
},
51+
);
52+
53+
test.serial(
54+
"determineCheckoutPath - logs when checkout_path is not a repo root",
55+
async (t) => {
56+
const expectedPath = path.resolve("/checkout/path");
57+
const target = callee(determineCheckoutPath)
58+
.withActions((actions) => {
59+
sinon
60+
.stub(actions, "getRequiredInput")
61+
.withArgs("checkout_path")
62+
.returns(expectedPath);
63+
})
64+
.withArgs(createTestConfig({}));
65+
sinon.stub(gitUtils, "getGitRoot").resolves("/checkout");
66+
67+
await target
68+
.logs(t, "is not the root of the repository")
69+
.passes(t.is, expectedPath);
70+
},
71+
);
72+
73+
test.serial(
74+
"determineCheckoutPath - logs when checkout_path is not the same as repo root in config",
75+
async (t) => {
76+
const expectedPath = path.resolve("/checkout/path");
77+
const target = callee(determineCheckoutPath)
78+
.withActions((actions) => {
79+
sinon
80+
.stub(actions, "getRequiredInput")
81+
.withArgs("checkout_path")
82+
.returns(expectedPath);
83+
})
84+
.withArgs(createTestConfig({ repositoryRoot: "/some/other/path" }));
85+
sinon.stub(gitUtils, "getGitRoot").resolves(expectedPath);
86+
87+
await target
88+
.logs(t, "does not match that found by the 'codeql-action/init' step")
89+
.passes(t.is, expectedPath);
90+
},
91+
);
92+
93+
test.serial(
94+
"determineCheckoutPath - doesn't log any of the messages when all is as expected",
95+
async (t) => {
96+
const expectedPath = path.resolve("/checkout/path");
97+
const target = callee(determineCheckoutPath)
98+
.withActions((actions) => {
99+
sinon
100+
.stub(actions, "getRequiredInput")
101+
.withArgs("checkout_path")
102+
.returns(expectedPath);
103+
})
104+
.withArgs(createTestConfig({ repositoryRoot: expectedPath }));
105+
sinon.stub(gitUtils, "getGitRoot").resolves(expectedPath);
106+
107+
await target
108+
.notLogs(
109+
t,
110+
"is not in the work tree of a git repository",
111+
"is not the root of the repository",
112+
"does not match that found by the 'codeql-action/init' step",
113+
)
114+
.passes(t.is, expectedPath);
115+
},
116+
);
117+
30118
/**
31119
* Checks the status report produced by the analyze Action.
32120
*

‎src/analyze.ts‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { performance } from "perf_hooks";
55
import * as io from "@actions/io";
66
import * as yaml from "js-yaml";
77

8+
import type { ActionState } from "./action-common";
89
import { getTemporaryDirectory } from "./actions-util";
910
import * as analyses from "./analyses";
1011
import { setupCppAutobuild } from "./autobuild";
@@ -23,6 +24,7 @@ import {
2324
} from "./diff-informed-analysis-utils";
2425
import { EnvVar } from "./environment";
2526
import { FeatureEnablement, Feature } from "./feature-flags";
27+
import { getGitRoot } from "./git-utils";
2628
import { BuiltInLanguage, Language } from "./languages";
2729
import { Logger, withGroupAsync } from "./logging";
2830
import { OverlayDatabaseMode } from "./overlay/overlay-database-mode";
@@ -87,6 +89,58 @@ export interface QueriesStatusReport
8789
event_reports?: EventReport[];
8890
}
8991

92+
/**
93+
* Determines the path at which the repository being analysed is checked out at.
94+
* Returns the value of the required `checkout_path` input and validates that it
95+
* refers to the root of a repository.
96+
*
97+
* @param action The action state.
98+
* @param config The CodeQL Action configuration state.
99+
*/
100+
export async function determineCheckoutPath(
101+
action: ActionState<["Logger", "Actions"]>,
102+
config: configUtils.Config,
103+
) {
104+
const checkoutPathInput = action.actions.getRequiredInput("checkout_path");
105+
106+
// Try to obtain the root path of the repository and validate that it matches the input.
107+
const absCheckoutPathInput = path.resolve(checkoutPathInput);
108+
const repositoryRoot = await getGitRoot(absCheckoutPathInput);
109+
110+
if (repositoryRoot === undefined) {
111+
action.logger.warning(
112+
[
113+
`The directory at '${absCheckoutPathInput}' is not in the work tree of a git repository.`,
114+
"If the repository being analyzed is checked out elsewhere,",
115+
"you must explicitly set the 'checkout_path' input for the 'codeql-action/analyze' step to",
116+
"the checkout path.",
117+
].join(" "),
118+
);
119+
} else if (repositoryRoot !== absCheckoutPathInput) {
120+
action.logger.warning(
121+
[
122+
`The directory at '${absCheckoutPathInput}' is not the root of the repository ('${repositoryRoot}').`,
123+
"Set the 'checkout_path' input for the 'codeql-action/analyze' step to the root path of the checkout.",
124+
].join(" "),
125+
);
126+
} else if (
127+
config.repositoryRoot !== undefined &&
128+
repositoryRoot !== config.repositoryRoot
129+
) {
130+
// The repository root that was persisted by the `init` step doesn't match the one we have found here.
131+
action.logger.warning(
132+
[
133+
`The repository path at '${repositoryRoot}' does not match that found by the 'codeql-action/init' step: '${config.repositoryRoot}'.`,
134+
"Ensure that the 'checkout_path' input for the 'codeql-action/analyze' step is set to the path of the same repository that",
135+
"the 'codeql-action/init' step determined. This is either the GitHub Actions workspace or the repository root corresponding to",
136+
"the 'source-root' input if that was provided.",
137+
].join(" "),
138+
);
139+
}
140+
141+
return absCheckoutPathInput;
142+
}
143+
90144
async function setupPythonExtractor(logger: Logger) {
91145
const codeqlPython = process.env["CODEQL_PYTHON"];
92146
if (codeqlPython === undefined || codeqlPython.length === 0) {

‎src/codeql.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,7 @@ export async function getTrapCachingExtractorConfigArgsForLang(
12251225
): Promise<string[]> {
12261226
const cacheDir = config.trapCaches[language];
12271227
if (cacheDir === undefined) return [];
1228-
const write = await isAnalyzingDefaultBranch();
1228+
const write = await isAnalyzingDefaultBranch(getEnv(), config.repositoryRoot);
12291229
return [
12301230
`-O=${language}.trap.cache.dir=${cacheDir}`,
12311231
`-O=${language}.trap.cache.bound=${TRAP_CACHE_SIZE_MB}`,

0 commit comments

Comments
 (0)