Skip to content

Commit

Permalink
Use the checkout_path for getting the commit oid
Browse files Browse the repository at this point in the history
This commit also adds a new integration check to verify this.

When running in test mode, payloads will not be uploaded. Instead, they
will be saved to disk so that they can be inspected later.
  • Loading branch information
aeisenberg committed Mar 1, 2022
1 parent 117a67b commit 9acab1b
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 14 deletions.
100 changes: 100 additions & 0 deletions .github/workflows/__with-checkout-path.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 9 additions & 4 deletions lib/actions-util.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/actions-util.js.map

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions lib/upload-lib.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/upload-lib.js.map

Large diffs are not rendered by default.

64 changes: 64 additions & 0 deletions pr-checks/checks/with-checkout-path.yml
@@ -0,0 +1,64 @@
name: "Use a custom `checkout_path`"
description: "Checks that a custom `checkout_path` will find the proper commit_oid"
# Build tracing currently does not support Windows 2022, so use `windows-2019` instead of
# `windows-latest`.
# Must test on all three platforms since this test does path manipulation
os: [ubuntu-latest, macos-latest, windows-2019]
steps:
# Check out the actions repo again, but at a different location.
# choose an arbitrary SHA so that we can later test that the commit_oid is not from main
- uses: actions/checkout@v2
with:
ref: 474bbf07f9247ffe1856c6a0f94aeeb10e7afee6
path: x/y/z/some-path
- uses: ./../action/init
with:
tools: ${{ steps.prepare-test.outputs.tools-url }}
# it's enough to test one compiled language and one interpreted language
languages: java,javascript
source-path: x/y/z/some-path/tests/multi-language-repo
debug: true

- name: Build code
shell: bash
run: x/y/z/some-path/tests/multi-language-repo/build.sh
- uses: ./../action/analyze
with:
checkout_path: x/y/z/some-path/tests/multi-language-repo
ref: v1.1.0
sha: 474bbf07f9247ffe1856c6a0f94aeeb10e7afee6
upload: false
env:
TEST_MODE: true
- uses: ./../action/upload-sarif
with:
ref: v1.1.0
sha: 474bbf07f9247ffe1856c6a0f94aeeb10e7afee6
checkout_path: x/y/z/some-path/tests/multi-language-repo
env:
TEST_MODE: true

- name: Verify SARIF
run: |
EXPECTED_COMMIT_OID="474bbf07f9247ffe1856c6a0f94aeeb10e7afee6"
EXPECTED_REF="v1.1.0"
EXPECTED_CHECKOUT_URI_SUFFIX="/x/y/z/some-path/tests/multi-language-repo"
ACTUAL_COMMIT_OID="$(cat "$RUNNER_TEMP/payload.json" | jq -r .commit_oid)"
ACTUAL_REF="$(cat "$RUNNER_TEMP/payload.json" | jq -r .ref)"
ACTUAL_CHECKOUT_URI="$(cat "$RUNNER_TEMP/payload.json" | jq -r .checkout_uri)"
if [[ "$EXPECTED_COMMIT_OID" != "$ACTUAL_COMMIT_OID" ]]; then
echo "Invalid commit oid. Expected: $EXPECTED_COMMIT_OID Actual: $ACTUAL_COMMIT_OID"
exit 1
fi
if [[ "$EXPECTED_REF" != "$ACTUAL_REF" ]]; then
echo "Invalid ref. Expected: '$EXPECTED_REF' Actual: '$ACTUAL_REF'"
exit 1
fi
if [[ "$ACTUAL_CHECKOUT_URI" != *$EXPECTED_CHECKOUT_URI_SUFFIX ]]; then
echo "Invalid checkout URI suffix. Expected suffix: $EXPECTED_CHECKOUT_URI_SUFFIX Actual uri: $ACTUAL_CHECKOUT_URI"
exit 1
fi
20 changes: 16 additions & 4 deletions src/actions-util.ts
Expand Up @@ -60,7 +60,10 @@ export function getToolCacheDirectory(): string {
/**
* Gets the SHA of the commit that is currently checked out.
*/
export const getCommitOid = async function (ref = "HEAD"): Promise<string> {
export const getCommitOid = async function (
checkoutPath: string,
ref = "HEAD"
): Promise<string> {
// Try to use git to get the current commit SHA. If that fails then
// log but otherwise silently fall back to using the SHA from the environment.
// The only time these two values will differ is during analysis of a PR when
Expand All @@ -83,6 +86,7 @@ export const getCommitOid = async function (ref = "HEAD"): Promise<string> {
process.stderr.write(data);
},
},
cwd: checkoutPath,
}
).exec();
return commitOid.trim();
Expand All @@ -107,6 +111,7 @@ export const determineMergeBaseCommitOid = async function (): Promise<
}

const mergeSha = getRequiredEnvParam("GITHUB_SHA");
const checkoutPath = getRequiredInput("checkout_path");

try {
let commitOid = "";
Expand Down Expand Up @@ -134,6 +139,7 @@ export const determineMergeBaseCommitOid = async function (): Promise<
process.stderr.write(data);
},
},
cwd: checkoutPath,
}
).exec();

Expand Down Expand Up @@ -498,6 +504,10 @@ export async function getRef(): Promise<string> {
// or in the form "refs/pull/N/merge" on a pull_request event
const refInput = getOptionalInput("ref");
const shaInput = getOptionalInput("sha");
const checkoutPath =
getOptionalInput("checkout_path") ||
getOptionalInput("source-root") ||
getRequiredEnvParam("GITHUB_WORKSPACE");

const hasRefInput = !!refInput;
const hasShaInput = !!shaInput;
Expand Down Expand Up @@ -526,7 +536,7 @@ export async function getRef(): Promise<string> {
return ref;
}

const head = await getCommitOid("HEAD");
const head = await getCommitOid(checkoutPath, "HEAD");

// in actions/checkout@v2 we can check if git rev-parse HEAD == GITHUB_SHA
// in actions/checkout@v1 this may not be true as it checks out the repository
Expand All @@ -535,8 +545,10 @@ export async function getRef(): Promise<string> {
// git git-parse GITHUB_REF == git rev-parse HEAD instead.
const hasChangedRef =
sha !== head &&
(await getCommitOid(ref.replace(/^refs\/pull\//, "refs/remotes/pull/"))) !==
head;
(await getCommitOid(
checkoutPath,
ref.replace(/^refs\/pull\//, "refs/remotes/pull/")
)) !== head;

if (hasChangedRef) {
const newRef = ref.replace(pull_ref_regex, "refs/pull/$1/head");
Expand Down
14 changes: 12 additions & 2 deletions src/upload-lib.ts
Expand Up @@ -100,7 +100,15 @@ async function uploadPayload(
// If in test mode we don't want to upload the results
const testMode = process.env["TEST_MODE"] === "true" || false;
if (testMode) {
logger.debug("In test mode. Results are not uploaded.");
const payloadSaveFile = path.join(
actionsUtil.getTemporaryDirectory(),
"payload.json"
);
logger.info(
`In test mode. Results are not uploaded. Saving to ${payloadSaveFile}`
);
logger.info(`Payload: ${JSON.stringify(payload, null, 2)}`);
fs.writeFileSync(payloadSaveFile, JSON.stringify(payload, null, 2));
return;
}

Expand Down Expand Up @@ -165,7 +173,9 @@ export async function uploadFromActions(
return await uploadFiles(
getSarifFilePaths(sarifPath),
parseRepositoryNwo(util.getRequiredEnvParam("GITHUB_REPOSITORY")),
await actionsUtil.getCommitOid(),
await actionsUtil.getCommitOid(
actionsUtil.getRequiredInput("checkout_path")
),
await actionsUtil.getRef(),
await actionsUtil.getAnalysisKey(),
actionsUtil.getOptionalInput("category"),
Expand Down

0 comments on commit 9acab1b

Please sign in to comment.