mirror of
https://github.com/github/codeql-action.git
synced 2026-10-31 09:59:43 +00:00
Use version information to construct payload
This commit is contained in:
@@ -19,7 +19,7 @@ test("emptyPaths", async (t) => {
|
||||
tempDir: tmpDir,
|
||||
toolCacheDir: tmpDir,
|
||||
codeQLCmd: "",
|
||||
ghesVersion: { type: "dotcom" } as util.GHESVersion,
|
||||
gitHubVersion: { type: "dotcom" } as util.GitHubVersion,
|
||||
};
|
||||
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
||||
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
|
||||
@@ -39,7 +39,7 @@ test("nonEmptyPaths", async (t) => {
|
||||
tempDir: tmpDir,
|
||||
toolCacheDir: tmpDir,
|
||||
codeQLCmd: "",
|
||||
ghesVersion: { type: "dotcom" } as util.GHESVersion,
|
||||
gitHubVersion: { type: "dotcom" } as util.GitHubVersion,
|
||||
};
|
||||
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
||||
t.is(process.env["LGTM_INDEX_INCLUDE"], "path1\npath2");
|
||||
@@ -63,7 +63,7 @@ test("exclude temp dir", async (t) => {
|
||||
tempDir,
|
||||
toolCacheDir,
|
||||
codeQLCmd: "",
|
||||
ghesVersion: { type: "dotcom" } as util.GHESVersion,
|
||||
gitHubVersion: { type: "dotcom" } as util.GitHubVersion,
|
||||
};
|
||||
analysisPaths.includeAndExcludeAnalysisPaths(config);
|
||||
t.is(process.env["LGTM_INDEX_INCLUDE"], undefined);
|
||||
|
||||
@@ -34,7 +34,7 @@ test("status report fields", async (t) => {
|
||||
tempDir: tmpDir,
|
||||
toolCacheDir: tmpDir,
|
||||
codeQLCmd: "",
|
||||
ghesVersion: { type: "dotcom" } as util.GHESVersion,
|
||||
gitHubVersion: { type: "dotcom" } as util.GitHubVersion,
|
||||
};
|
||||
fs.mkdirSync(util.getCodeQLDatabasePath(config.tempDir, language), {
|
||||
recursive: true,
|
||||
|
||||
@@ -268,7 +268,7 @@ export async function runAnalyze(
|
||||
workflowRunID,
|
||||
checkoutPath,
|
||||
environment,
|
||||
config.ghesVersion,
|
||||
config.gitHubVersion,
|
||||
apiDetails,
|
||||
mode,
|
||||
logger
|
||||
|
||||
@@ -35,7 +35,7 @@ export const getApiClient = function (
|
||||
function getApiUrl(githubUrl: string): string {
|
||||
const url = new URL(githubUrl);
|
||||
|
||||
// If we detect this is trying to be to github.com
|
||||
// If we detect this is trying to connect to github.com
|
||||
// then return with a fixed canonical URL.
|
||||
if (url.hostname === "github.com" || url.hostname === "api.github.com") {
|
||||
return "https://api.github.com";
|
||||
|
||||
@@ -190,13 +190,11 @@ async function getCodeQLBundleDownloadURL(
|
||||
}
|
||||
const [repositoryOwner, repositoryName] = repository.split("/");
|
||||
try {
|
||||
const release = await api
|
||||
.getApiClient(apiDetails)
|
||||
.repos.getReleaseByTag({
|
||||
owner: repositoryOwner,
|
||||
repo: repositoryName,
|
||||
tag: CODEQL_BUNDLE_VERSION,
|
||||
});
|
||||
const release = await api.getApiClient(apiDetails).repos.getReleaseByTag({
|
||||
owner: repositoryOwner,
|
||||
repo: repositoryName,
|
||||
tag: CODEQL_BUNDLE_VERSION,
|
||||
});
|
||||
for (const asset of release.data.assets) {
|
||||
if (asset.name === codeQLBundleName) {
|
||||
logger.info(
|
||||
|
||||
@@ -20,7 +20,7 @@ const sampleApiDetails = {
|
||||
url: "https://github.example.com",
|
||||
};
|
||||
|
||||
const ghesVersion = { type: "dotcom" } as util.GHESVersion;
|
||||
const gitHubVersion = { type: "dotcom" } as util.GitHubVersion;
|
||||
|
||||
// Returns the filepath of the newly-created file
|
||||
function createConfigFile(inputFileContents: string, tmpDir: string): string {
|
||||
@@ -83,7 +83,7 @@ test("load empty config", async (t) => {
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
logger
|
||||
);
|
||||
@@ -98,7 +98,7 @@ test("load empty config", async (t) => {
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
logger
|
||||
)
|
||||
@@ -135,7 +135,7 @@ test("loading config saves config", async (t) => {
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
logger
|
||||
);
|
||||
@@ -161,7 +161,7 @@ test("load input outside of workspace", async (t) => {
|
||||
tmpDir,
|
||||
getCachedCodeQL(),
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -194,7 +194,7 @@ test("load non-local input with invalid repo syntax", async (t) => {
|
||||
tmpDir,
|
||||
getCachedCodeQL(),
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -228,7 +228,7 @@ test("load non-existent input", async (t) => {
|
||||
tmpDir,
|
||||
getCachedCodeQL(),
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -298,7 +298,7 @@ test("load non-empty input", async (t) => {
|
||||
tempDir: tmpDir,
|
||||
toolCacheDir: tmpDir,
|
||||
codeQLCmd: codeQL.getPath(),
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
};
|
||||
|
||||
const languages = "javascript";
|
||||
@@ -313,7 +313,7 @@ test("load non-empty input", async (t) => {
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -374,7 +374,7 @@ test("Default queries are used", async (t) => {
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -443,7 +443,7 @@ test("Queries can be specified in config file", async (t) => {
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -506,7 +506,7 @@ test("Queries from config file can be overridden in workflow file", async (t) =>
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -567,7 +567,7 @@ test("Queries in workflow file can be used in tandem with the 'disable default q
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -618,7 +618,7 @@ test("Multiple queries can be specified in workflow file, no config file require
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -687,7 +687,7 @@ test("Queries in workflow file can be added to the set of queries without overri
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -749,7 +749,7 @@ test("Invalid queries in workflow file handled correctly", async (t) => {
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -811,7 +811,7 @@ test("API client used when reading remote config", async (t) => {
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -835,7 +835,7 @@ test("Remote config handles the case where a directory is provided", async (t) =
|
||||
tmpDir,
|
||||
getCachedCodeQL(),
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -867,7 +867,7 @@ test("Invalid format of remote config handled correctly", async (t) => {
|
||||
tmpDir,
|
||||
getCachedCodeQL(),
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -895,7 +895,7 @@ test("No detected languages", async (t) => {
|
||||
tmpDir,
|
||||
getCachedCodeQL(),
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -920,7 +920,7 @@ test("Unknown languages", async (t) => {
|
||||
tmpDir,
|
||||
getCachedCodeQL(),
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
@@ -966,7 +966,7 @@ function doInvalidInputTest(
|
||||
tmpDir,
|
||||
codeQL,
|
||||
tmpDir,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
sampleApiDetails,
|
||||
getRunnerLogger(true)
|
||||
);
|
||||
|
||||
@@ -9,7 +9,7 @@ import * as externalQueries from "./external-queries";
|
||||
import { Language, parseLanguage } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { RepositoryNwo } from "./repository";
|
||||
import { GHESVersion } from "./util";
|
||||
import { GitHubVersion } from "./util";
|
||||
|
||||
// Property names from the user-supplied config file.
|
||||
const NAME_PROPERTY = "name";
|
||||
@@ -97,7 +97,7 @@ export interface Config {
|
||||
* Version of GHES that we have determined that we are talking to, or undefined
|
||||
* if talking to github.com.
|
||||
*/
|
||||
ghesVersion: GHESVersion;
|
||||
gitHubVersion: GitHubVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -729,7 +729,7 @@ export async function getDefaultConfig(
|
||||
toolCacheDir: string,
|
||||
codeQL: CodeQL,
|
||||
checkoutPath: string,
|
||||
ghesVersion: GHESVersion,
|
||||
gitHubVersion: GitHubVersion,
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
logger: Logger
|
||||
): Promise<Config> {
|
||||
@@ -763,7 +763,7 @@ export async function getDefaultConfig(
|
||||
tempDir,
|
||||
toolCacheDir,
|
||||
codeQLCmd: codeQL.getPath(),
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -779,7 +779,7 @@ async function loadConfig(
|
||||
toolCacheDir: string,
|
||||
codeQL: CodeQL,
|
||||
checkoutPath: string,
|
||||
ghesVersion: GHESVersion,
|
||||
gitHubVersion: GitHubVersion,
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
logger: Logger
|
||||
): Promise<Config> {
|
||||
@@ -927,7 +927,7 @@ async function loadConfig(
|
||||
tempDir,
|
||||
toolCacheDir,
|
||||
codeQLCmd: codeQL.getPath(),
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -946,7 +946,7 @@ export async function initConfig(
|
||||
toolCacheDir: string,
|
||||
codeQL: CodeQL,
|
||||
checkoutPath: string,
|
||||
ghesVersion: GHESVersion,
|
||||
gitHubVersion: GitHubVersion,
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
logger: Logger
|
||||
): Promise<Config> {
|
||||
@@ -963,7 +963,7 @@ export async function initConfig(
|
||||
toolCacheDir,
|
||||
codeQL,
|
||||
checkoutPath,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
apiDetails,
|
||||
logger
|
||||
);
|
||||
@@ -977,7 +977,7 @@ export async function initConfig(
|
||||
toolCacheDir,
|
||||
codeQL,
|
||||
checkoutPath,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
apiDetails,
|
||||
logger
|
||||
);
|
||||
@@ -1025,14 +1025,12 @@ async function getRemoteConfig(
|
||||
throw new Error(getConfigFileRepoFormatInvalidMessage(configFile));
|
||||
}
|
||||
|
||||
const response = await api
|
||||
.getApiClient(apiDetails, true)
|
||||
.repos.getContent({
|
||||
owner: pieces.groups.owner,
|
||||
repo: pieces.groups.repo,
|
||||
path: pieces.groups.path,
|
||||
ref: pieces.groups.ref,
|
||||
});
|
||||
const response = await api.getApiClient(apiDetails, true).repos.getContent({
|
||||
owner: pieces.groups.owner,
|
||||
repo: pieces.groups.repo,
|
||||
path: pieces.groups.path,
|
||||
ref: pieces.groups.ref,
|
||||
});
|
||||
|
||||
let fileContents: string;
|
||||
if ("content" in response.data && response.data.content !== undefined) {
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import { Language } from "./languages";
|
||||
import { getActionsLogger } from "./logging";
|
||||
import { parseRepositoryNwo } from "./repository";
|
||||
import { checkGHESVersionInRange, getGHESVersion } from "./util";
|
||||
import { checkGitHubVersionInRange, getGitHubVersion } from "./util";
|
||||
|
||||
interface InitSuccessStatusReport extends actionsUtil.StatusReportBase {
|
||||
// Comma-separated list of languages that analysis was run for
|
||||
@@ -99,9 +99,9 @@ async function run() {
|
||||
url: actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||
};
|
||||
|
||||
const ghesVersion = await getGHESVersion(apiDetails);
|
||||
if (ghesVersion !== undefined) {
|
||||
checkGHESVersionInRange(ghesVersion, "actions", logger);
|
||||
const gitHubVersion = await getGitHubVersion(apiDetails);
|
||||
if (gitHubVersion !== undefined) {
|
||||
checkGitHubVersionInRange(gitHubVersion, "actions", logger);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -146,7 +146,7 @@ async function run() {
|
||||
actionsUtil.getRequiredEnvParam("RUNNER_TOOL_CACHE"),
|
||||
codeql,
|
||||
actionsUtil.getRequiredEnvParam("GITHUB_WORKSPACE"),
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
apiDetails,
|
||||
logger
|
||||
);
|
||||
|
||||
@@ -44,7 +44,7 @@ export async function initConfig(
|
||||
toolCacheDir: string,
|
||||
codeQL: CodeQL,
|
||||
checkoutPath: string,
|
||||
ghesVersion: util.GHESVersion,
|
||||
gitHubVersion: util.GitHubVersion,
|
||||
apiDetails: GitHubApiDetails,
|
||||
logger: Logger
|
||||
): Promise<configUtils.Config> {
|
||||
@@ -58,7 +58,7 @@ export async function initConfig(
|
||||
toolCacheDir,
|
||||
codeQL,
|
||||
checkoutPath,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
apiDetails,
|
||||
logger
|
||||
);
|
||||
|
||||
@@ -14,9 +14,9 @@ import { getRunnerLogger } from "./logging";
|
||||
import { parseRepositoryNwo } from "./repository";
|
||||
import * as upload_lib from "./upload-lib";
|
||||
import {
|
||||
checkGHESVersionInRange,
|
||||
checkGitHubVersionInRange,
|
||||
getAddSnippetsFlag,
|
||||
getGHESVersion,
|
||||
getGitHubVersion,
|
||||
getMemoryFlag,
|
||||
getThreadsFlag,
|
||||
parseGithubUrl,
|
||||
@@ -153,9 +153,9 @@ program
|
||||
url: parseGithubUrl(cmd.githubUrl),
|
||||
};
|
||||
|
||||
const ghesVersion = await getGHESVersion(apiDetails);
|
||||
if (ghesVersion !== undefined) {
|
||||
checkGHESVersionInRange(ghesVersion, "runner", logger);
|
||||
const gitHubVersion = await getGitHubVersion(apiDetails);
|
||||
if (gitHubVersion !== undefined) {
|
||||
checkGitHubVersionInRange(gitHubVersion, "runner", logger);
|
||||
}
|
||||
|
||||
let codeql: CodeQL;
|
||||
@@ -183,7 +183,7 @@ program
|
||||
toolsDir,
|
||||
codeql,
|
||||
cmd.checkoutPath || process.cwd(),
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
apiDetails,
|
||||
logger
|
||||
);
|
||||
@@ -447,7 +447,7 @@ program
|
||||
url: parseGithubUrl(cmd.githubUrl),
|
||||
};
|
||||
try {
|
||||
const ghesVersion = await getGHESVersion(apiDetails);
|
||||
const gitHubVersion = await getGitHubVersion(apiDetails);
|
||||
await upload_lib.upload(
|
||||
cmd.sarifFile,
|
||||
parseRepositoryNwo(cmd.repository),
|
||||
@@ -458,7 +458,7 @@ program
|
||||
undefined,
|
||||
cmd.checkoutPath || process.cwd(),
|
||||
undefined,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
apiDetails,
|
||||
"runner",
|
||||
logger
|
||||
|
||||
446
src/testdata/pull_request.json
vendored
Normal file
446
src/testdata/pull_request.json
vendored
Normal file
@@ -0,0 +1,446 @@
|
||||
{
|
||||
"action": "opened",
|
||||
"number": 2,
|
||||
"pull_request": {
|
||||
"url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/2",
|
||||
"id": 279147437,
|
||||
"node_id": "MDExOlB1bGxSZXF1ZXN0Mjc5MTQ3NDM3",
|
||||
"html_url": "https://github.com/Codertocat/Hello-World/pull/2",
|
||||
"diff_url": "https://github.com/Codertocat/Hello-World/pull/2.diff",
|
||||
"patch_url": "https://github.com/Codertocat/Hello-World/pull/2.patch",
|
||||
"issue_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/2",
|
||||
"number": 2,
|
||||
"state": "open",
|
||||
"locked": false,
|
||||
"title": "Update the README with new information.",
|
||||
"user": {
|
||||
"login": "Codertocat",
|
||||
"id": 21031067,
|
||||
"node_id": "MDQ6VXNlcjIxMDMxMDY3",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/Codertocat",
|
||||
"html_url": "https://github.com/Codertocat",
|
||||
"followers_url": "https://api.github.com/users/Codertocat/followers",
|
||||
"following_url": "https://api.github.com/users/Codertocat/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/Codertocat/orgs",
|
||||
"repos_url": "https://api.github.com/users/Codertocat/repos",
|
||||
"events_url": "https://api.github.com/users/Codertocat/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/Codertocat/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"body": "This is a pretty simple change that we need to pull into master.",
|
||||
"created_at": "2019-05-15T15:20:33Z",
|
||||
"updated_at": "2019-05-15T15:20:33Z",
|
||||
"closed_at": null,
|
||||
"merged_at": null,
|
||||
"merge_commit_sha": null,
|
||||
"assignee": null,
|
||||
"assignees": [],
|
||||
"requested_reviewers": [],
|
||||
"requested_teams": [],
|
||||
"labels": [],
|
||||
"milestone": null,
|
||||
"commits_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/2/commits",
|
||||
"review_comments_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/2/comments",
|
||||
"review_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/comments{/number}",
|
||||
"comments_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/2/comments",
|
||||
"statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/ec26c3e57ca3a959ca5aad62de7213c562f8c821",
|
||||
"head": {
|
||||
"label": "Codertocat:changes",
|
||||
"ref": "changes",
|
||||
"sha": "ec26c3e57ca3a959ca5aad62de7213c562f8c821",
|
||||
"user": {
|
||||
"login": "Codertocat",
|
||||
"id": 21031067,
|
||||
"node_id": "MDQ6VXNlcjIxMDMxMDY3",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/Codertocat",
|
||||
"html_url": "https://github.com/Codertocat",
|
||||
"followers_url": "https://api.github.com/users/Codertocat/followers",
|
||||
"following_url": "https://api.github.com/users/Codertocat/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/Codertocat/orgs",
|
||||
"repos_url": "https://api.github.com/users/Codertocat/repos",
|
||||
"events_url": "https://api.github.com/users/Codertocat/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/Codertocat/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"repo": {
|
||||
"id": 186853002,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnkxODY4NTMwMDI=",
|
||||
"name": "Hello-World",
|
||||
"full_name": "Codertocat/Hello-World",
|
||||
"private": false,
|
||||
"owner": {
|
||||
"login": "Codertocat",
|
||||
"id": 21031067,
|
||||
"node_id": "MDQ6VXNlcjIxMDMxMDY3",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/Codertocat",
|
||||
"html_url": "https://github.com/Codertocat",
|
||||
"followers_url": "https://api.github.com/users/Codertocat/followers",
|
||||
"following_url": "https://api.github.com/users/Codertocat/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/Codertocat/orgs",
|
||||
"repos_url": "https://api.github.com/users/Codertocat/repos",
|
||||
"events_url": "https://api.github.com/users/Codertocat/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/Codertocat/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"html_url": "https://github.com/Codertocat/Hello-World",
|
||||
"description": null,
|
||||
"fork": false,
|
||||
"url": "https://api.github.com/repos/Codertocat/Hello-World",
|
||||
"forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks",
|
||||
"keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}",
|
||||
"collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}",
|
||||
"teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams",
|
||||
"hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks",
|
||||
"issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}",
|
||||
"events_url": "https://api.github.com/repos/Codertocat/Hello-World/events",
|
||||
"assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}",
|
||||
"branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}",
|
||||
"tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags",
|
||||
"blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}",
|
||||
"git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}",
|
||||
"git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}",
|
||||
"trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}",
|
||||
"statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}",
|
||||
"languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages",
|
||||
"stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers",
|
||||
"contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors",
|
||||
"subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers",
|
||||
"subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription",
|
||||
"commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}",
|
||||
"git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}",
|
||||
"comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}",
|
||||
"issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}",
|
||||
"contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}",
|
||||
"compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}",
|
||||
"merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges",
|
||||
"archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}",
|
||||
"downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads",
|
||||
"issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}",
|
||||
"pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}",
|
||||
"milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}",
|
||||
"notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}",
|
||||
"labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}",
|
||||
"releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}",
|
||||
"deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments",
|
||||
"created_at": "2019-05-15T15:19:25Z",
|
||||
"updated_at": "2019-05-15T15:19:27Z",
|
||||
"pushed_at": "2019-05-15T15:20:32Z",
|
||||
"git_url": "git://github.com/Codertocat/Hello-World.git",
|
||||
"ssh_url": "git@github.com:Codertocat/Hello-World.git",
|
||||
"clone_url": "https://github.com/Codertocat/Hello-World.git",
|
||||
"svn_url": "https://github.com/Codertocat/Hello-World",
|
||||
"homepage": null,
|
||||
"size": 0,
|
||||
"stargazers_count": 0,
|
||||
"watchers_count": 0,
|
||||
"language": null,
|
||||
"has_issues": true,
|
||||
"has_projects": true,
|
||||
"has_downloads": true,
|
||||
"has_wiki": true,
|
||||
"has_pages": true,
|
||||
"forks_count": 0,
|
||||
"mirror_url": null,
|
||||
"archived": false,
|
||||
"disabled": false,
|
||||
"open_issues_count": 2,
|
||||
"license": null,
|
||||
"forks": 0,
|
||||
"open_issues": 2,
|
||||
"watchers": 0,
|
||||
"default_branch": "master"
|
||||
}
|
||||
},
|
||||
"base": {
|
||||
"label": "Codertocat:master",
|
||||
"ref": "master",
|
||||
"sha": "f95f852bd8fca8fcc58a9a2d6c842781e32a215e",
|
||||
"user": {
|
||||
"login": "Codertocat",
|
||||
"id": 21031067,
|
||||
"node_id": "MDQ6VXNlcjIxMDMxMDY3",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/Codertocat",
|
||||
"html_url": "https://github.com/Codertocat",
|
||||
"followers_url": "https://api.github.com/users/Codertocat/followers",
|
||||
"following_url": "https://api.github.com/users/Codertocat/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/Codertocat/orgs",
|
||||
"repos_url": "https://api.github.com/users/Codertocat/repos",
|
||||
"events_url": "https://api.github.com/users/Codertocat/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/Codertocat/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"repo": {
|
||||
"id": 186853002,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnkxODY4NTMwMDI=",
|
||||
"name": "Hello-World",
|
||||
"full_name": "Codertocat/Hello-World",
|
||||
"private": false,
|
||||
"owner": {
|
||||
"login": "Codertocat",
|
||||
"id": 21031067,
|
||||
"node_id": "MDQ6VXNlcjIxMDMxMDY3",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/Codertocat",
|
||||
"html_url": "https://github.com/Codertocat",
|
||||
"followers_url": "https://api.github.com/users/Codertocat/followers",
|
||||
"following_url": "https://api.github.com/users/Codertocat/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/Codertocat/orgs",
|
||||
"repos_url": "https://api.github.com/users/Codertocat/repos",
|
||||
"events_url": "https://api.github.com/users/Codertocat/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/Codertocat/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"html_url": "https://github.com/Codertocat/Hello-World",
|
||||
"description": null,
|
||||
"fork": false,
|
||||
"url": "https://api.github.com/repos/Codertocat/Hello-World",
|
||||
"forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks",
|
||||
"keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}",
|
||||
"collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}",
|
||||
"teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams",
|
||||
"hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks",
|
||||
"issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}",
|
||||
"events_url": "https://api.github.com/repos/Codertocat/Hello-World/events",
|
||||
"assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}",
|
||||
"branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}",
|
||||
"tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags",
|
||||
"blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}",
|
||||
"git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}",
|
||||
"git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}",
|
||||
"trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}",
|
||||
"statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}",
|
||||
"languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages",
|
||||
"stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers",
|
||||
"contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors",
|
||||
"subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers",
|
||||
"subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription",
|
||||
"commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}",
|
||||
"git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}",
|
||||
"comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}",
|
||||
"issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}",
|
||||
"contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}",
|
||||
"compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}",
|
||||
"merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges",
|
||||
"archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}",
|
||||
"downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads",
|
||||
"issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}",
|
||||
"pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}",
|
||||
"milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}",
|
||||
"notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}",
|
||||
"labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}",
|
||||
"releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}",
|
||||
"deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments",
|
||||
"created_at": "2019-05-15T15:19:25Z",
|
||||
"updated_at": "2019-05-15T15:19:27Z",
|
||||
"pushed_at": "2019-05-15T15:20:32Z",
|
||||
"git_url": "git://github.com/Codertocat/Hello-World.git",
|
||||
"ssh_url": "git@github.com:Codertocat/Hello-World.git",
|
||||
"clone_url": "https://github.com/Codertocat/Hello-World.git",
|
||||
"svn_url": "https://github.com/Codertocat/Hello-World",
|
||||
"homepage": null,
|
||||
"size": 0,
|
||||
"stargazers_count": 0,
|
||||
"watchers_count": 0,
|
||||
"language": null,
|
||||
"has_issues": true,
|
||||
"has_projects": true,
|
||||
"has_downloads": true,
|
||||
"has_wiki": true,
|
||||
"has_pages": true,
|
||||
"forks_count": 0,
|
||||
"mirror_url": null,
|
||||
"archived": false,
|
||||
"disabled": false,
|
||||
"open_issues_count": 2,
|
||||
"license": null,
|
||||
"forks": 0,
|
||||
"open_issues": 2,
|
||||
"watchers": 0,
|
||||
"default_branch": "master"
|
||||
}
|
||||
},
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/2"
|
||||
},
|
||||
"html": {
|
||||
"href": "https://github.com/Codertocat/Hello-World/pull/2"
|
||||
},
|
||||
"issue": {
|
||||
"href": "https://api.github.com/repos/Codertocat/Hello-World/issues/2"
|
||||
},
|
||||
"comments": {
|
||||
"href": "https://api.github.com/repos/Codertocat/Hello-World/issues/2/comments"
|
||||
},
|
||||
"review_comments": {
|
||||
"href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/2/comments"
|
||||
},
|
||||
"review_comment": {
|
||||
"href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/comments{/number}"
|
||||
},
|
||||
"commits": {
|
||||
"href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/2/commits"
|
||||
},
|
||||
"statuses": {
|
||||
"href": "https://api.github.com/repos/Codertocat/Hello-World/statuses/ec26c3e57ca3a959ca5aad62de7213c562f8c821"
|
||||
}
|
||||
},
|
||||
"author_association": "OWNER",
|
||||
"draft": false,
|
||||
"merged": false,
|
||||
"mergeable": null,
|
||||
"rebaseable": null,
|
||||
"mergeable_state": "unknown",
|
||||
"merged_by": null,
|
||||
"comments": 0,
|
||||
"review_comments": 0,
|
||||
"maintainer_can_modify": false,
|
||||
"commits": 1,
|
||||
"additions": 1,
|
||||
"deletions": 1,
|
||||
"changed_files": 1
|
||||
},
|
||||
"repository": {
|
||||
"id": 186853002,
|
||||
"node_id": "MDEwOlJlcG9zaXRvcnkxODY4NTMwMDI=",
|
||||
"name": "Hello-World",
|
||||
"full_name": "Codertocat/Hello-World",
|
||||
"private": false,
|
||||
"owner": {
|
||||
"login": "Codertocat",
|
||||
"id": 21031067,
|
||||
"node_id": "MDQ6VXNlcjIxMDMxMDY3",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/Codertocat",
|
||||
"html_url": "https://github.com/Codertocat",
|
||||
"followers_url": "https://api.github.com/users/Codertocat/followers",
|
||||
"following_url": "https://api.github.com/users/Codertocat/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/Codertocat/orgs",
|
||||
"repos_url": "https://api.github.com/users/Codertocat/repos",
|
||||
"events_url": "https://api.github.com/users/Codertocat/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/Codertocat/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
},
|
||||
"html_url": "https://github.com/Codertocat/Hello-World",
|
||||
"description": null,
|
||||
"fork": false,
|
||||
"url": "https://api.github.com/repos/Codertocat/Hello-World",
|
||||
"forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks",
|
||||
"keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}",
|
||||
"collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}",
|
||||
"teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams",
|
||||
"hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks",
|
||||
"issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}",
|
||||
"events_url": "https://api.github.com/repos/Codertocat/Hello-World/events",
|
||||
"assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}",
|
||||
"branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}",
|
||||
"tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags",
|
||||
"blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}",
|
||||
"git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}",
|
||||
"git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}",
|
||||
"trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}",
|
||||
"statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}",
|
||||
"languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages",
|
||||
"stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers",
|
||||
"contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors",
|
||||
"subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers",
|
||||
"subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription",
|
||||
"commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}",
|
||||
"git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}",
|
||||
"comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}",
|
||||
"issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}",
|
||||
"contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}",
|
||||
"compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}",
|
||||
"merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges",
|
||||
"archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}",
|
||||
"downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads",
|
||||
"issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}",
|
||||
"pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}",
|
||||
"milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}",
|
||||
"notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}",
|
||||
"labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}",
|
||||
"releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}",
|
||||
"deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments",
|
||||
"created_at": "2019-05-15T15:19:25Z",
|
||||
"updated_at": "2019-05-15T15:19:27Z",
|
||||
"pushed_at": "2019-05-15T15:20:32Z",
|
||||
"git_url": "git://github.com/Codertocat/Hello-World.git",
|
||||
"ssh_url": "git@github.com:Codertocat/Hello-World.git",
|
||||
"clone_url": "https://github.com/Codertocat/Hello-World.git",
|
||||
"svn_url": "https://github.com/Codertocat/Hello-World",
|
||||
"homepage": null,
|
||||
"size": 0,
|
||||
"stargazers_count": 0,
|
||||
"watchers_count": 0,
|
||||
"language": null,
|
||||
"has_issues": true,
|
||||
"has_projects": true,
|
||||
"has_downloads": true,
|
||||
"has_wiki": true,
|
||||
"has_pages": true,
|
||||
"forks_count": 0,
|
||||
"mirror_url": null,
|
||||
"archived": false,
|
||||
"disabled": false,
|
||||
"open_issues_count": 2,
|
||||
"license": null,
|
||||
"forks": 0,
|
||||
"open_issues": 2,
|
||||
"watchers": 0,
|
||||
"default_branch": "master"
|
||||
},
|
||||
"sender": {
|
||||
"login": "Codertocat",
|
||||
"id": 21031067,
|
||||
"node_id": "MDQ6VXNlcjIxMDMxMDY3",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4",
|
||||
"gravatar_id": "",
|
||||
"url": "https://api.github.com/users/Codertocat",
|
||||
"html_url": "https://github.com/Codertocat",
|
||||
"followers_url": "https://api.github.com/users/Codertocat/followers",
|
||||
"following_url": "https://api.github.com/users/Codertocat/following{/other_user}",
|
||||
"gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}",
|
||||
"starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}",
|
||||
"subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions",
|
||||
"organizations_url": "https://api.github.com/users/Codertocat/orgs",
|
||||
"repos_url": "https://api.github.com/users/Codertocat/repos",
|
||||
"events_url": "https://api.github.com/users/Codertocat/events{/privacy}",
|
||||
"received_events_url": "https://api.github.com/users/Codertocat/received_events",
|
||||
"type": "User",
|
||||
"site_admin": false
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ function getTestConfig(tmpDir: string): configUtils.Config {
|
||||
tempDir: tmpDir,
|
||||
toolCacheDir: tmpDir,
|
||||
codeQLCmd: "",
|
||||
ghesVersion: { type: "dotcom" } as util.GHESVersion,
|
||||
gitHubVersion: { type: "dotcom" } as util.GitHubVersion,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import test from "ava";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { setupTests } from "./testing-utils";
|
||||
import * as uploadLib from "./upload-lib";
|
||||
import { GitHubVersion } from "./util";
|
||||
|
||||
setupTests(test);
|
||||
|
||||
@@ -19,3 +20,74 @@ test("validateSarifFileSchema - invalid", (t) => {
|
||||
uploadLib.validateSarifFileSchema(inputFile, getRunnerLogger(true))
|
||||
);
|
||||
});
|
||||
|
||||
test("validate correct payload used per version", async (t) => {
|
||||
const newVersions: GitHubVersion[] = [
|
||||
{ type: "dotcom" },
|
||||
{ type: "ghes", version: "3.1.0" },
|
||||
];
|
||||
const oldVersions: GitHubVersion[] = [
|
||||
{ type: "ghes", version: "2.22.1" },
|
||||
{ type: "ghes", version: "3.0.0" },
|
||||
];
|
||||
const allVersions = newVersions.concat(oldVersions);
|
||||
|
||||
for (const version of allVersions) {
|
||||
const payload: any = uploadLib.buildPayload(
|
||||
"commit",
|
||||
"refs/heads/master",
|
||||
"key",
|
||||
undefined,
|
||||
"",
|
||||
undefined,
|
||||
"/opt/src",
|
||||
undefined,
|
||||
["CodeQL", "eslint"],
|
||||
version,
|
||||
"actions"
|
||||
);
|
||||
// Not triggered by a pull request
|
||||
t.falsy(payload.base_ref);
|
||||
t.falsy(payload.base_sha);
|
||||
}
|
||||
|
||||
process.env["GITHUB_EVENT_NAME"] = "pull_request";
|
||||
process.env[
|
||||
"GITHUB_EVENT_PATH"
|
||||
] = `${__dirname}/../src/testdata/pull_request.json`;
|
||||
for (const version of newVersions) {
|
||||
const payload: any = uploadLib.buildPayload(
|
||||
"commit",
|
||||
"refs/pull/123/merge",
|
||||
"key",
|
||||
undefined,
|
||||
"",
|
||||
undefined,
|
||||
"/opt/src",
|
||||
undefined,
|
||||
["CodeQL", "eslint"],
|
||||
version,
|
||||
"actions"
|
||||
);
|
||||
t.truthy(payload.base_ref);
|
||||
t.truthy(payload.base_sha);
|
||||
}
|
||||
|
||||
for (const version of oldVersions) {
|
||||
const payload: any = uploadLib.buildPayload(
|
||||
"commit",
|
||||
"refs/pull/123/merge",
|
||||
"key",
|
||||
undefined,
|
||||
"",
|
||||
undefined,
|
||||
"/opt/src",
|
||||
undefined,
|
||||
["CodeQL", "eslint"],
|
||||
version,
|
||||
"actions"
|
||||
);
|
||||
t.falsy(payload.base_ref);
|
||||
t.falsy(payload.base_sha);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -94,7 +94,7 @@ export async function upload(
|
||||
workflowRunID: number | undefined,
|
||||
checkoutPath: string,
|
||||
environment: string | undefined,
|
||||
ghesVersion: util.GHESVersion,
|
||||
gitHubVersion: util.GitHubVersion,
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
mode: util.Mode,
|
||||
logger: Logger
|
||||
@@ -128,7 +128,7 @@ export async function upload(
|
||||
workflowRunID,
|
||||
checkoutPath,
|
||||
environment,
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
apiDetails,
|
||||
mode,
|
||||
logger
|
||||
@@ -170,6 +170,65 @@ export function validateSarifFileSchema(sarifFilePath: string, logger: Logger) {
|
||||
}
|
||||
}
|
||||
|
||||
// buildPayload constructs a map ready to be uploaded to the API from the given
|
||||
// parameters, respecting the current mode and target GitHub instance version.
|
||||
export function buildPayload(
|
||||
commitOid: string,
|
||||
ref: string,
|
||||
analysisKey: string | undefined,
|
||||
analysisName: string | undefined,
|
||||
zippedSarif: string,
|
||||
workflowRunID: number | undefined,
|
||||
checkoutURI: string,
|
||||
environment: string | undefined,
|
||||
toolNames: string[],
|
||||
gitHubVersion: util.GitHubVersion,
|
||||
mode: util.Mode
|
||||
) {
|
||||
if (mode === "actions") {
|
||||
const payloadObj = {
|
||||
commit_oid: commitOid,
|
||||
ref,
|
||||
analysis_key: analysisKey,
|
||||
analysis_name: analysisName,
|
||||
sarif: zippedSarif,
|
||||
workflow_run_id: workflowRunID,
|
||||
checkout_uri: checkoutURI,
|
||||
environment,
|
||||
started_at: process.env[sharedEnv.CODEQL_WORKFLOW_STARTED_AT],
|
||||
tool_names: toolNames,
|
||||
base_ref: undefined,
|
||||
base_sha: undefined,
|
||||
};
|
||||
|
||||
// This behaviour can be made the default when support for GHES 3.0 is discontinued.
|
||||
if (
|
||||
gitHubVersion.type === "dotcom" ||
|
||||
semver.satisfies(gitHubVersion.version, `>=3.1`)
|
||||
) {
|
||||
if (
|
||||
process.env.GITHUB_EVENT_NAME === "pull_request" &&
|
||||
process.env.GITHUB_EVENT_PATH
|
||||
) {
|
||||
const githubEvent = JSON.parse(
|
||||
fs.readFileSync(process.env.GITHUB_EVENT_PATH, "utf8")
|
||||
);
|
||||
payloadObj.base_ref = githubEvent.pull_request.base.ref;
|
||||
payloadObj.base_sha = githubEvent.pull_request.base.sha;
|
||||
}
|
||||
}
|
||||
return payloadObj;
|
||||
} else {
|
||||
return {
|
||||
commit_sha: commitOid,
|
||||
ref,
|
||||
sarif: zippedSarif,
|
||||
checkout_uri: checkoutURI,
|
||||
tool_name: toolNames[0],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Uploads the given set of sarif files.
|
||||
// Returns true iff the upload occurred and succeeded
|
||||
async function uploadFiles(
|
||||
@@ -182,7 +241,7 @@ async function uploadFiles(
|
||||
workflowRunID: number | undefined,
|
||||
checkoutPath: string,
|
||||
environment: string | undefined,
|
||||
ghesVersion: util.GHESVersion,
|
||||
gitHubVersion: util.GitHubVersion,
|
||||
apiDetails: api.GitHubApiDetails,
|
||||
mode: util.Mode,
|
||||
logger: Logger
|
||||
@@ -212,43 +271,29 @@ async function uploadFiles(
|
||||
logger
|
||||
);
|
||||
|
||||
const zipped_sarif = zlib.gzipSync(sarifPayload).toString("base64");
|
||||
const zippedSarif = zlib.gzipSync(sarifPayload).toString("base64");
|
||||
const checkoutURI = fileUrl(checkoutPath);
|
||||
|
||||
const toolNames = util.getToolNames(sarifPayload);
|
||||
|
||||
let payload: string;
|
||||
if (mode === "actions") {
|
||||
const payloadObj = {
|
||||
commit_oid: commitOid,
|
||||
ref,
|
||||
analysis_key: analysisKey,
|
||||
analysis_name: analysisName,
|
||||
sarif: zipped_sarif,
|
||||
workflow_run_id: workflowRunID,
|
||||
checkout_uri: checkoutURI,
|
||||
environment,
|
||||
started_at: process.env[sharedEnv.CODEQL_WORKFLOW_STARTED_AT],
|
||||
tool_names: toolNames,
|
||||
};
|
||||
if (ghesVersion.type !== "ghes" || semver.satisfies(ghesVersion.version, `>=3.0`)) {
|
||||
// add base_ref / base_sha
|
||||
}
|
||||
payload = JSON.stringify(payloadObj);
|
||||
} else {
|
||||
payload = JSON.stringify({
|
||||
commit_sha: commitOid,
|
||||
ref,
|
||||
sarif: zipped_sarif,
|
||||
checkout_uri: checkoutURI,
|
||||
tool_name: toolNames[0],
|
||||
});
|
||||
}
|
||||
const payload = buildPayload(
|
||||
commitOid,
|
||||
ref,
|
||||
analysisKey,
|
||||
analysisName,
|
||||
zippedSarif,
|
||||
workflowRunID,
|
||||
checkoutURI,
|
||||
environment,
|
||||
toolNames,
|
||||
gitHubVersion,
|
||||
mode
|
||||
);
|
||||
|
||||
// Log some useful debug info about the info
|
||||
const rawUploadSizeBytes = sarifPayload.length;
|
||||
logger.debug(`Raw upload size: ${rawUploadSizeBytes} bytes`);
|
||||
const zippedUploadSizeBytes = zipped_sarif.length;
|
||||
const zippedUploadSizeBytes = zippedSarif.length;
|
||||
logger.debug(`Base64 zipped upload size: ${zippedUploadSizeBytes} bytes`);
|
||||
const numResultInSarif = countResultsInSarif(sarifPayload);
|
||||
logger.debug(`Number of results in upload: ${numResultInSarif}`);
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as actionsUtil from "./actions-util";
|
||||
import { getActionsLogger } from "./logging";
|
||||
import { parseRepositoryNwo } from "./repository";
|
||||
import * as upload_lib from "./upload-lib";
|
||||
import { getGHESVersion } from "./util";
|
||||
import { getGitHubVersion } from "./util";
|
||||
|
||||
interface UploadSarifStatusReport
|
||||
extends actionsUtil.StatusReportBase,
|
||||
@@ -46,7 +46,7 @@ async function run() {
|
||||
url: actionsUtil.getRequiredEnvParam("GITHUB_SERVER_URL"),
|
||||
};
|
||||
|
||||
const ghesVersion = await getGHESVersion(apiDetails);
|
||||
const gitHubVersion = await getGitHubVersion(apiDetails);
|
||||
|
||||
const uploadStats = await upload_lib.upload(
|
||||
actionsUtil.getRequiredInput("sarif_file"),
|
||||
@@ -58,7 +58,7 @@ async function run() {
|
||||
actionsUtil.getWorkflowRunID(),
|
||||
actionsUtil.getRequiredInput("checkout_path"),
|
||||
actionsUtil.getRequiredInput("matrix"),
|
||||
ghesVersion,
|
||||
gitHubVersion,
|
||||
apiDetails,
|
||||
"actions",
|
||||
getActionsLogger()
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import * as fs from "fs";
|
||||
import * as os from "os";
|
||||
|
||||
import * as github from "@actions/github";
|
||||
import test from "ava";
|
||||
import sinon from "sinon";
|
||||
|
||||
import * as api from "./api-client";
|
||||
import { getRunnerLogger } from "./logging";
|
||||
import { setupTests } from "./testing-utils";
|
||||
import * as util from "./util";
|
||||
@@ -195,3 +198,42 @@ test("allowed API versions", async (t) => {
|
||||
util.DisallowedAPIVersionReason.ACTION_TOO_OLD
|
||||
);
|
||||
});
|
||||
|
||||
function mockGetMetaVersionHeader(
|
||||
versionHeader: string | undefined
|
||||
): sinon.SinonStub<any, any> {
|
||||
// Passing an auth token is required, so we just use a dummy value
|
||||
const client = github.getOctokit("123");
|
||||
const response = {
|
||||
headers: {
|
||||
"x-github-enterprise-version": versionHeader,
|
||||
},
|
||||
};
|
||||
const spyGetContents = sinon
|
||||
.stub(client.meta, "get")
|
||||
.resolves(response as any);
|
||||
sinon.stub(api, "getApiClient").value(() => client);
|
||||
return spyGetContents;
|
||||
}
|
||||
|
||||
test("getGitHubVersion", async (t) => {
|
||||
const v = await util.getGitHubVersion({
|
||||
auth: "",
|
||||
url: "https://github.com",
|
||||
});
|
||||
t.deepEqual("dotcom", v.type);
|
||||
|
||||
mockGetMetaVersionHeader("2.0");
|
||||
const v2 = await util.getGitHubVersion({
|
||||
auth: "",
|
||||
url: "https://ghe.example.com",
|
||||
});
|
||||
t.deepEqual({ type: "ghes", version: "2.0" }, v2);
|
||||
|
||||
mockGetMetaVersionHeader(undefined);
|
||||
const v3 = await util.getGitHubVersion({
|
||||
auth: "",
|
||||
url: "https://ghe.example.com",
|
||||
});
|
||||
t.deepEqual({ type: "dotcom" }, v3);
|
||||
});
|
||||
|
||||
34
src/util.ts
34
src/util.ts
@@ -5,10 +5,10 @@ import * as path from "path";
|
||||
import * as core from "@actions/core";
|
||||
import * as semver from "semver";
|
||||
|
||||
import { getApiClient, GitHubApiDetails } from "./api-client";
|
||||
import * as apiCompatibility from "./api-compatibility.json";
|
||||
import { Language } from "./languages";
|
||||
import { Logger } from "./logging";
|
||||
import { getApiClient, GitHubApiDetails } from "./api-client";
|
||||
|
||||
/**
|
||||
* Are we running on actions, or not.
|
||||
@@ -219,28 +219,38 @@ const CODEQL_ACTION_WARNED_ABOUT_VERSION_ENV_VAR =
|
||||
"CODEQL_ACTION_WARNED_ABOUT_VERSION";
|
||||
let hasBeenWarnedAboutVersion = false;
|
||||
|
||||
export type GHESVersion = { type: "dotcom" } | { type: "ghes"; version: string };
|
||||
export type GitHubVersion =
|
||||
| { type: "dotcom" }
|
||||
| { type: "ghes"; version: string };
|
||||
|
||||
export async function getGitHubVersion(
|
||||
apiDetails: GitHubApiDetails
|
||||
): Promise<GitHubVersion> {
|
||||
// We can avoid making an API request in the standard dotcom case
|
||||
if (parseGithubUrl(apiDetails.url) === GITHUB_DOTCOM_URL) {
|
||||
return { type: "dotcom" };
|
||||
}
|
||||
|
||||
export async function getGHESVersion(apiDetails: GitHubApiDetails): Promise<GHESVersion> {
|
||||
// Doesn't strictly have to be the meta endpoint as we're only
|
||||
// using the response headers which are available on every request.
|
||||
const apiClient = getApiClient(apiDetails);
|
||||
const response = await apiClient.meta.get();
|
||||
|
||||
// This happens on dotcom
|
||||
if (
|
||||
response.headers[GITHUB_ENTERPRISE_VERSION_HEADER] === undefined
|
||||
) {
|
||||
|
||||
// This happens on dotcom, although we expect to have already returned in that
|
||||
// case. This can also serve as a fallback in cases we haven't foreseen.
|
||||
if (response.headers[GITHUB_ENTERPRISE_VERSION_HEADER] === undefined) {
|
||||
return { type: "dotcom" };
|
||||
}
|
||||
|
||||
const version = response.headers[
|
||||
GITHUB_ENTERPRISE_VERSION_HEADER
|
||||
] as string;
|
||||
const version = response.headers[GITHUB_ENTERPRISE_VERSION_HEADER] as string;
|
||||
return { type: "ghes", version };
|
||||
}
|
||||
|
||||
export function checkGHESVersionInRange(version: GHESVersion, mode: Mode, logger: Logger) {
|
||||
export function checkGitHubVersionInRange(
|
||||
version: GitHubVersion,
|
||||
mode: Mode,
|
||||
logger: Logger
|
||||
) {
|
||||
if (hasBeenWarnedAboutVersion || version.type !== "ghes") {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user