Skip to content

Commit

Permalink
Showing 22 changed files with 338 additions and 24 deletions.
63 changes: 63 additions & 0 deletions .github/workflows/__analyze-ref-input.yml

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

2 changes: 1 addition & 1 deletion .github/workflows/__remote-config.yml

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

70 changes: 70 additions & 0 deletions .github/workflows/__upload-ref-sha-input.yml

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

3 changes: 2 additions & 1 deletion CHANGELOG.md
@@ -2,7 +2,8 @@

## [UNRELEASED]

No user facing changes.
- Add `sarif-id` as an output for the `upload-sarif` and `analyze` actions. [#889](https://github.com/github/codeql-action/pull/889)
- Add `ref` and `sha` inputs to the `analyze` action, which override the defaults provided by the GitHub Action context. [#889](https://github.com/github/codeql-action/pull/889)

## 1.0.31 - 31 Jan 2022

8 changes: 8 additions & 0 deletions analyze/action.yml
@@ -45,6 +45,12 @@ inputs:
description: "The path at which the analyzed repository was checked out. Used to relativize any absolute paths in the uploaded SARIF file."
required: false
default: ${{ github.workspace }}
ref:
description: "The ref where results will be uploaded. If not provided, the Action will use the GITHUB_REF environment variable. If provided, the sha input must be provided as well. This input is not available in pull requests from forks."
required: false
sha:
description: "The sha of the HEAD of the ref where results will be uploaded. If not provided, the Action will use the GITHUB_SHA environment variable. If provided, the ref input must be provided as well. This input is not available in pull requests from forks."
required: false
category:
description: String used by Code Scanning for matching the analyses
required: false
@@ -63,6 +69,8 @@ inputs:
outputs:
db-locations:
description: A map from language to absolute path for each database created by CodeQL.
sarif-id:
description: The ID of the uploaded SARIF file.
runs:
using: "node12"
main: "../lib/analyze-action.js"
29 changes: 21 additions & 8 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.

37 changes: 37 additions & 0 deletions lib/actions-util.test.js
2 changes: 1 addition & 1 deletion lib/actions-util.test.js.map

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions lib/analyze-action.js
2 changes: 1 addition & 1 deletion lib/analyze-action.js.map

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions lib/upload-sarif-action.js
2 changes: 1 addition & 1 deletion lib/upload-sarif-action.js.map
17 changes: 17 additions & 0 deletions pr-checks/checks/analyze-ref-input.yml
@@ -0,0 +1,17 @@
name: "Analyze: 'ref' and 'sha' from inputs"
description: "Checks that specifying 'ref' and 'sha' as inputs works"
steps:
- uses: ./../action/init
with:
tools: ${{ steps.prepare-test.outputs.tools-url }}
languages: cpp,csharp,java,javascript,python
config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }}
- name: Build code
shell: bash
run: ./build.sh
- uses: ./../action/analyze
with:
ref: 'refs/heads/main'
sha: '5e235361806c361d4d3f8859e3c897658025a9a2'
env:
TEST_MODE: true
2 changes: 1 addition & 1 deletion pr-checks/checks/remote-config.yml
@@ -5,7 +5,7 @@ steps:
with:
tools: ${{ steps.prepare-test.outputs.tools-url }}
languages: cpp,csharp,java,javascript,python
config-file: github/codeql-action/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }}
config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }}
- name: Build code
shell: bash
run: ./build.sh
24 changes: 24 additions & 0 deletions pr-checks/checks/upload-ref-sha-input.yml
@@ -0,0 +1,24 @@
name: "Upload-sarif: 'ref' and 'sha' from inputs"
description: "Checks that specifying 'ref' and 'sha' as inputs works"
steps:
- uses: ./../action/init
with:
tools: ${{ steps.prepare-test.outputs.tools-url }}
languages: cpp,csharp,java,javascript,python
config-file: ${{ github.repository }}/tests/multi-language-repo/.github/codeql/custom-queries.yml@${{ github.sha }}
- name: Build code
shell: bash
run: ./build.sh
- uses: ./../action/analyze
with:
ref: 'refs/heads/main'
sha: '5e235361806c361d4d3f8859e3c897658025a9a2'
upload: false
env:
TEST_MODE: true
- uses: ./../action/upload-sarif
with:
ref: 'refs/heads/main'
sha: '5e235361806c361d4d3f8859e3c897658025a9a2'
env:
TEST_MODE: true
1 change: 0 additions & 1 deletion pr-checks/sync.py
@@ -23,7 +23,6 @@
"""


class NonAliasingRTRepresenter(ruamel.yaml.representer.RoundTripRepresenter):
def ignore_aliases(self, data):
return True
51 changes: 51 additions & 0 deletions src/actions-util.test.ts
@@ -65,6 +65,57 @@ test("getRef() returns head PR ref if GITHUB_REF no longer checked out", async (
callback.restore();
});

test("getRef() returns ref provided as an input and ignores current HEAD", async (t) => {
const getAdditionalInputStub = sinon.stub(actionsutil, "getOptionalInput");
getAdditionalInputStub.withArgs("ref").resolves("refs/pull/2/merge");
getAdditionalInputStub.withArgs("sha").resolves("b".repeat(40));

// These values are be ignored
process.env["GITHUB_REF"] = "refs/pull/1/merge";
process.env["GITHUB_SHA"] = "a".repeat(40);

const callback = sinon.stub(actionsutil, "getCommitOid");
callback.withArgs("refs/pull/1/merge").resolves("b".repeat(40));
callback.withArgs("HEAD").resolves("b".repeat(40));

const actualRef = await actionsutil.getRef();
t.deepEqual(actualRef, "refs/pull/2/merge");
callback.restore();
getAdditionalInputStub.restore();
});

test("getRef() throws an error if only `ref` is provided as an input", async (t) => {
const getAdditionalInputStub = sinon.stub(actionsutil, "getOptionalInput");
getAdditionalInputStub.withArgs("ref").resolves("refs/pull/1/merge");

await t.throwsAsync(
async () => {
await actionsutil.getRef();
},
{
instanceOf: Error,
message: "Both 'ref' and 'sha' are required if one of them is provided.",
}
);
getAdditionalInputStub.restore();
});

test("getRef() throws an error if only `sha` is provided as an input", async (t) => {
const getAdditionalInputStub = sinon.stub(actionsutil, "getOptionalInput");
getAdditionalInputStub.withArgs("sha").resolves("a".repeat(40));

await t.throwsAsync(
async () => {
await actionsutil.getRef();
},
{
instanceOf: Error,
message: "Both 'ref' and 'sha' are required if one of them is provided.",
}
);
getAdditionalInputStub.restore();
});

test("computeAutomationID()", async (t) => {
let actualAutomationID = actionsutil.computeAutomationID(
".github/workflows/codeql-analysis.yml:analyze",
34 changes: 26 additions & 8 deletions src/actions-util.ts
@@ -33,10 +33,10 @@ export function getRequiredInput(name: string): string {
* This allows us to get stronger type checking of required/optional inputs
* and make behaviour more consistent between actions and the runner.
*/
export function getOptionalInput(name: string): string | undefined {
export const getOptionalInput = function (name: string): string | undefined {
const value = core.getInput(name);
return value.length > 0 ? value : undefined;
}
};

export function getTemporaryDirectory(): string {
const value = process.env["CODEQL_ACTION_TEMP"];
@@ -83,10 +83,10 @@ export const getCommitOid = async function (ref = "HEAD"): Promise<string> {
return commitOid.trim();
} catch (e) {
core.info(
`Failed to call git to get current commit. Continuing with data from environment: ${e}`
`Failed to call git to get current commit. Continuing with data from environment or input: ${e}`
);
core.info((e as Error).stack || "NO STACK");
return getRequiredEnvParam("GITHUB_SHA");
return getOptionalInput("sha") || getRequiredEnvParam("GITHUB_SHA");
}
};

@@ -431,8 +431,26 @@ export function computeAutomationID(
export async function getRef(): Promise<string> {
// Will be in the form "refs/heads/master" on a push event
// or in the form "refs/pull/N/merge" on a pull_request event
const ref = getRequiredEnvParam("GITHUB_REF");
const sha = getRequiredEnvParam("GITHUB_SHA");
const refInput = getOptionalInput("ref");
const shaInput = getOptionalInput("sha");

const hasRefInput = !!refInput;
const hasShaInput = !!shaInput;
// If one of 'ref' or 'sha' are provided, both are required
if ((hasRefInput || hasShaInput) && !(hasRefInput && hasShaInput)) {
throw new Error(
"Both 'ref' and 'sha' are required if one of them is provided."
);
}

const ref = refInput || getRequiredEnvParam("GITHUB_REF");
const sha = shaInput || getRequiredEnvParam("GITHUB_SHA");

// If the ref is a user-provided input, we have to skip logic
// and assume that it is really where they want to upload the results.
if (refInput) {
return refInput;
}

// For pull request refs we want to detect whether the workflow
// has run `git checkout HEAD^2` to analyze the 'head' ref rather
@@ -520,7 +538,7 @@ export async function createStatusReportBase(
cause?: string,
exception?: string
): Promise<StatusReportBase> {
const commitOid = process.env["GITHUB_SHA"] || "";
const commitOid = getOptionalInput("sha") || process.env["GITHUB_SHA"] || "";
const ref = await getRef();
const workflowRunIDStr = process.env["GITHUB_RUN_ID"];
let workflowRunID = -1;
@@ -580,7 +598,7 @@ export async function createStatusReportBase(
const GENERIC_403_MSG =
"The repo on which this action is running is not opted-in to CodeQL code scanning.";
const GENERIC_404_MSG =
"Not authorized to used the CodeQL code scanning feature on this repo.";
"Not authorized to use the CodeQL code scanning feature on this repo.";
const OUT_OF_DATE_MSG =
"CodeQL Action is out-of-date. Please upgrade to the latest version of codeql-action.";
const INCOMPATIBLE_MSG =
1 change: 1 addition & 0 deletions src/analyze-action.ts
@@ -187,6 +187,7 @@ async function run() {
apiDetails,
logger
);
core.setOutput("sarif-id", uploadResult.sarifID);
} else {
logger.info("Not uploading results");
}
1 change: 1 addition & 0 deletions src/upload-sarif-action.ts
@@ -63,6 +63,7 @@ async function run() {
apiDetails,
getActionsLogger()
);
core.setOutput("sarif-id", uploadResult.sarifID);
if (actionsUtil.getRequiredInput("wait-for-processing") === "true") {
await upload_lib.waitForProcessing(
parseRepositoryNwo(getRequiredEnvParam("GITHUB_REPOSITORY")),
9 changes: 9 additions & 0 deletions upload-sarif/action.yml
@@ -13,6 +13,12 @@ inputs:
description: "The path at which the analyzed repository was checked out. Used to relativize any absolute paths in the uploaded SARIF file."
required: false
default: ${{ github.workspace }}
ref:
description: "The ref where results will be uploaded. If not provided, the Action will use the GITHUB_REF environment variable. If provided, the sha input must be provided as well. This input is not available in pull requests from forks."
required: false
sha:
description: "The sha of the HEAD of the ref where results will be uploaded. If not provided, the Action will use the GITHUB_SHA environment variable. If provided, the ref input must be provided as well. This input is not available in pull requests from forks."
required: false
token:
default: ${{ github.token }}
matrix:
@@ -24,6 +30,9 @@ inputs:
description: If true, the Action will wait for the uploaded SARIF to be processed before completing.
required: true
default: "false"
outputs:
sarif-id:
description: The ID of the uploaded SARIF file.
runs:
using: 'node12'
main: '../lib/upload-sarif-action.js'

0 comments on commit 6a6a320

Please sign in to comment.