Skip to content

Commit 904d0ac

Browse files
authored
Merge pull request #858 from github/use-better-base-sha
Declare the merge base as base for code scanning comparisons
2 parents ff33f03 + 9b14aa7 commit 904d0ac

9 files changed

+198
-28
lines changed

Diff for: lib/actions-util.js

+50-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: lib/actions-util.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: lib/upload-lib.js

+19-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: lib/upload-lib.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: lib/upload-lib.test.js

+12-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: lib/upload-lib.test.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: src/actions-util.ts

+60
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,66 @@ export const getCommitOid = async function (ref = "HEAD"): Promise<string> {
9090
}
9191
};
9292

93+
/**
94+
* If the action was triggered by a pull request, determine the commit sha of the merge base.
95+
* Returns undefined if run by other triggers or the merge base cannot be determined.
96+
*/
97+
export const determineMergeBaseCommitOid = async function (): Promise<
98+
string | undefined
99+
> {
100+
if (process.env.GITHUB_EVENT_NAME !== "pull_request") {
101+
return undefined;
102+
}
103+
104+
const mergeSha = getRequiredEnvParam("GITHUB_SHA");
105+
106+
try {
107+
let commitOid = "";
108+
let baseOid = "";
109+
let headOid = "";
110+
111+
await new toolrunner.ToolRunner(
112+
await safeWhich.safeWhich("git"),
113+
["show", "-s", "--format=raw", mergeSha],
114+
{
115+
silent: true,
116+
listeners: {
117+
stdline: (data) => {
118+
if (data.startsWith("commit ") && commitOid === "") {
119+
commitOid = data.substring(7);
120+
} else if (data.startsWith("parent ")) {
121+
if (baseOid === "") {
122+
baseOid = data.substring(7);
123+
} else if (headOid === "") {
124+
headOid = data.substring(7);
125+
}
126+
}
127+
},
128+
stderr: (data) => {
129+
process.stderr.write(data);
130+
},
131+
},
132+
}
133+
).exec();
134+
135+
// Let's confirm our assumptions: We had a merge commit and the parsed parent data looks correct
136+
if (
137+
commitOid === mergeSha &&
138+
headOid.length === 40 &&
139+
baseOid.length === 40
140+
) {
141+
return baseOid;
142+
}
143+
return undefined;
144+
} catch (e) {
145+
core.info(
146+
`Failed to call git to determine merge base. Continuing with data from environment: ${e}`
147+
);
148+
core.info((e as Error).stack || "NO STACK");
149+
return undefined;
150+
}
151+
};
152+
93153
interface WorkflowJobStep {
94154
run: any;
95155
}

Diff for: src/upload-lib.test.ts

+28-3
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,17 @@ test("validate correct payload used per version", async (t) => {
5757
"/opt/src",
5858
undefined,
5959
["CodeQL", "eslint"],
60-
version
60+
version,
61+
"mergeBaseCommit"
6162
);
6263
// Not triggered by a pull request
6364
t.falsy(payload.base_ref);
6465
t.falsy(payload.base_sha);
6566
}
6667

6768
process.env["GITHUB_EVENT_NAME"] = "pull_request";
69+
process.env["GITHUB_SHA"] = "commit";
70+
process.env["GITHUB_BASE_REF"] = "master";
6871
process.env[
6972
"GITHUB_EVENT_PATH"
7073
] = `${__dirname}/../src/testdata/pull_request.json`;
@@ -79,8 +82,29 @@ test("validate correct payload used per version", async (t) => {
7982
"/opt/src",
8083
undefined,
8184
["CodeQL", "eslint"],
82-
version
85+
version,
86+
"mergeBaseCommit"
8387
);
88+
// Uploads for a merge commit use the merge base
89+
t.deepEqual(payload.base_ref, "refs/heads/master");
90+
t.deepEqual(payload.base_sha, "mergeBaseCommit");
91+
}
92+
93+
for (const version of newVersions) {
94+
const payload: any = uploadLib.buildPayload(
95+
"headCommit",
96+
"refs/pull/123/head",
97+
"key",
98+
undefined,
99+
"",
100+
undefined,
101+
"/opt/src",
102+
undefined,
103+
["CodeQL", "eslint"],
104+
version,
105+
"mergeBaseCommit"
106+
);
107+
// Uploads for the head use the PR base
84108
t.deepEqual(payload.base_ref, "refs/heads/master");
85109
t.deepEqual(payload.base_sha, "f95f852bd8fca8fcc58a9a2d6c842781e32a215e");
86110
}
@@ -96,7 +120,8 @@ test("validate correct payload used per version", async (t) => {
96120
"/opt/src",
97121
undefined,
98122
["CodeQL", "eslint"],
99-
version
123+
version,
124+
"mergeBaseCommit"
100125
);
101126
// These older versions won't expect these values
102127
t.falsy(payload.base_ref);

Diff for: src/upload-lib.ts

+26-11
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,8 @@ export function buildPayload(
291291
checkoutURI: string,
292292
environment: string | undefined,
293293
toolNames: string[],
294-
gitHubVersion: util.GitHubVersion
294+
gitHubVersion: util.GitHubVersion,
295+
mergeBaseCommitOid: string | undefined
295296
) {
296297
if (util.isActions()) {
297298
const payloadObj = {
@@ -314,15 +315,28 @@ export function buildPayload(
314315
gitHubVersion.type !== util.GitHubVariant.GHES ||
315316
semver.satisfies(gitHubVersion.version, `>=3.1`)
316317
) {
317-
if (
318-
process.env.GITHUB_EVENT_NAME === "pull_request" &&
319-
process.env.GITHUB_EVENT_PATH
320-
) {
321-
const githubEvent = JSON.parse(
322-
fs.readFileSync(process.env.GITHUB_EVENT_PATH, "utf8")
323-
);
324-
payloadObj.base_ref = `refs/heads/${githubEvent.pull_request.base.ref}`;
325-
payloadObj.base_sha = githubEvent.pull_request.base.sha;
318+
if (process.env.GITHUB_EVENT_NAME === "pull_request") {
319+
if (
320+
commitOid === util.getRequiredEnvParam("GITHUB_SHA") &&
321+
mergeBaseCommitOid
322+
) {
323+
// We're uploading results for the merge commit
324+
// and were able to determine the merge base.
325+
// So we use that as the most accurate base.
326+
payloadObj.base_ref = `refs/heads/${util.getRequiredEnvParam(
327+
"GITHUB_BASE_REF"
328+
)}`;
329+
payloadObj.base_sha = mergeBaseCommitOid;
330+
} else if (process.env.GITHUB_EVENT_PATH) {
331+
// Either we're not uploading results for the merge commit
332+
// or we could not determine the merge base.
333+
// Using the PR base is the only option here
334+
const githubEvent = JSON.parse(
335+
fs.readFileSync(process.env.GITHUB_EVENT_PATH, "utf8")
336+
);
337+
payloadObj.base_ref = `refs/heads/${githubEvent.pull_request.base.ref}`;
338+
payloadObj.base_sha = githubEvent.pull_request.base.sha;
339+
}
326340
}
327341
}
328342
return payloadObj;
@@ -389,7 +403,8 @@ async function uploadFiles(
389403
checkoutURI,
390404
environment,
391405
toolNames,
392-
gitHubVersion
406+
gitHubVersion,
407+
await actionsUtil.determineMergeBaseCommitOid()
393408
);
394409

395410
// Log some useful debug info about the info

0 commit comments

Comments
 (0)