From e62277a12a98cec1433a58dcbc120f54df1c6168 Mon Sep 17 00:00:00 2001 From: p4r53c Date: Tue, 26 Aug 2025 14:00:53 +0300 Subject: [PATCH 1/3] feat(ghes): add ghe-base-url input and honor baseUrl for Octokit when uploading SARIF --- lib/job-summary.js | 31 +++++++++---- src/job-summary.ts | 31 +++++++++---- test/job-summary.sarif.baseurl.spec.ts | 64 ++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 17 deletions(-) create mode 100644 test/job-summary.sarif.baseurl.spec.ts diff --git a/lib/job-summary.js b/lib/job-summary.js index 67b226b2f..e6b58c7d4 100644 --- a/lib/job-summary.js +++ b/lib/job-summary.js @@ -38,7 +38,6 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.JobSummary = void 0; const core = __importStar(require("@actions/core")); const semver_1 = require("semver"); -const core_1 = require("@octokit/core"); const github = __importStar(require("@actions/github")); const util_1 = require("util"); const zlib_1 = require("zlib"); @@ -107,16 +106,29 @@ class JobSummary { }); } /** - * Uploads the code scanning SARIF content to the code-scanning GitHub API. - * @param encodedSarif - The final compressed and encoded sarif content. - * @param token - GitHub token to use for the request. Has to have 'security-events: write' permission. - * @private + * Uploads a gzip-compressed, base64-encoded SARIF payload to GitHub Code Scanning. + * + * Uses the current GitHub Actions context (owner, repo, commit SHA, and ref) for the target. + * If a GitHub Enterprise Server base URL is provided via the 'ghe-base-url' or 'ghe_base_url' + * action input, the request is sent to that endpoint; otherwise, it targets github.com. + * + * @param encodedSarif - The SARIF report content after gzip compression and base64 encoding, + * as required by the POST /repos/{owner}/{repo}/code-scanning/sarifs API. + * Typically produced by compressing raw SARIF with gzip and encoding to base64. + * @param token - GitHub token used to authenticate the upload request. Must have + * security_events: write permission on the target repository (e.g., a PAT or GITHUB_TOKEN + * with the appropriate permission). + * + * @returns A promise that resolves when the upload completes successfully. + * @throws Error if the API response status is not 2xx; the thrown error includes the resolved baseUrl + * and a serialized response summary to aid debugging. */ static uploadCodeScanningSarif(encodedSarif, token) { return __awaiter(this, void 0, void 0, function* () { - const octokit = new core_1.Octokit({ auth: token }); - let response; - response = yield octokit.request('POST /repos/{owner}/{repo}/code-scanning/sarifs', { + var _a, _b, _c; + const inputBaseUrl = core.getInput('ghe-base-url', { required: false }) || core.getInput('ghe_base_url', { required: false }) || ''; + const octokit = inputBaseUrl ? github.getOctokit(token, { baseUrl: inputBaseUrl }) : github.getOctokit(token); + const response = yield octokit.request('POST /repos/{owner}/{repo}/code-scanning/sarifs', { owner: github.context.repo.owner, repo: github.context.repo.repo, commit_sha: github.context.sha, @@ -124,7 +136,8 @@ class JobSummary { sarif: encodedSarif, }); if (response.status < 200 || response.status >= 300) { - throw new Error(`Failed to upload SARIF file: ` + JSON.stringify(response)); + const usedBaseUrl = ((_c = (_b = (_a = octokit.request) === null || _a === void 0 ? void 0 : _a.endpoint) === null || _b === void 0 ? void 0 : _b.DEFAULTS) === null || _c === void 0 ? void 0 : _c.baseUrl) || 'unknown'; + throw new Error(`Failed to upload SARIF file (status ${response.status}). baseUrl=${usedBaseUrl}; response=` + JSON.stringify(response)); } core.info('SARIF file uploaded successfully'); }); diff --git a/src/job-summary.ts b/src/job-summary.ts index fe1f47efc..e2f4c852e 100644 --- a/src/job-summary.ts +++ b/src/job-summary.ts @@ -105,15 +105,29 @@ export class JobSummary { } /** - * Uploads the code scanning SARIF content to the code-scanning GitHub API. - * @param encodedSarif - The final compressed and encoded sarif content. - * @param token - GitHub token to use for the request. Has to have 'security-events: write' permission. - * @private + * Uploads a gzip-compressed, base64-encoded SARIF payload to GitHub Code Scanning. + * + * Uses the current GitHub Actions context (owner, repo, commit SHA, and ref) for the target. + * If a GitHub Enterprise Server base URL is provided via the 'ghe-base-url' or 'ghe_base_url' + * action input, the request is sent to that endpoint; otherwise, it targets github.com. + * + * @param encodedSarif - The SARIF report content after gzip compression and base64 encoding, + * as required by the POST /repos/{owner}/{repo}/code-scanning/sarifs API. + * Typically produced by compressing raw SARIF with gzip and encoding to base64. + * @param token - GitHub token used to authenticate the upload request. Must have + * security_events: write permission on the target repository (e.g., a PAT or GITHUB_TOKEN + * with the appropriate permission). + * + * @returns A promise that resolves when the upload completes successfully. + * @throws Error if the API response status is not 2xx; the thrown error includes the resolved baseUrl + * and a serialized response summary to aid debugging. */ private static async uploadCodeScanningSarif(encodedSarif: string, token: string) { - const octokit: Octokit = new Octokit({ auth: token }); - let response: OctokitResponse | undefined; - response = await octokit.request('POST /repos/{owner}/{repo}/code-scanning/sarifs', { + const inputBaseUrl = core.getInput('ghe-base-url', { required: false }) || core.getInput('ghe_base_url', { required: false }) || ''; + + const octokit = inputBaseUrl ? github.getOctokit(token, { baseUrl: inputBaseUrl }) : github.getOctokit(token); + + const response = await octokit.request('POST /repos/{owner}/{repo}/code-scanning/sarifs', { owner: github.context.repo.owner, repo: github.context.repo.repo, commit_sha: github.context.sha, @@ -122,7 +136,8 @@ export class JobSummary { }); if (response.status < 200 || response.status >= 300) { - throw new Error(`Failed to upload SARIF file: ` + JSON.stringify(response)); + const usedBaseUrl = (octokit as any).request?.endpoint?.DEFAULTS?.baseUrl || 'unknown'; + throw new Error(`Failed to upload SARIF file (status ${response.status}). baseUrl=${usedBaseUrl}; response=` + JSON.stringify(response)); } core.info('SARIF file uploaded successfully'); diff --git a/test/job-summary.sarif.baseurl.spec.ts b/test/job-summary.sarif.baseurl.spec.ts new file mode 100644 index 000000000..f05571a3a --- /dev/null +++ b/test/job-summary.sarif.baseurl.spec.ts @@ -0,0 +1,64 @@ +/** + * test/job-summary.sarif.baseurl.spec.ts + * Checking baseUrl selection when loading SARIF on GHES. + */ + +import * as core from '@actions/core'; + +jest.mock('@actions/github', () => { + const actual = jest.requireActual('@actions/github'); + return { + ...actual, + getOctokit: jest.fn((token: string, opts?: { baseUrl?: string }) => { + const usedBaseUrl = (opts && opts.baseUrl) || process.env.__AUTO_BASE_URL__ || 'https://api.github.com'; + + const req = jest.fn(async (_route: string, _params: any) => { + (global as any).__USED_BASE_URL__ = usedBaseUrl; + return { status: 201, data: {} }; + }) as unknown as any; + + req.endpoint = { DEFAULTS: { baseUrl: usedBaseUrl } }; + + return { request: req } as any; + }), + context: { + repo: { owner: 'o', repo: 'r' }, + sha: 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + ref: 'refs/heads/main', + }, + }; +}); + +import { JobSummary } from '../src/job-summary'; + +describe('uploadCodeScanningSarif baseUrl selection (GHES)', () => { + beforeEach(() => { + jest.resetModules(); + jest.clearAllMocks(); + + jest.spyOn(core, 'getInput').mockImplementation((_name: string) => ''); + + delete process.env.__AUTO_BASE_URL__; + delete (global as any).__USED_BASE_URL__; + }); + + it('Should use explicit input ghe-base-url if given', async () => { + (core.getInput as jest.Mock).mockImplementation((name: string) => { + if (name === 'ghe-base-url') return 'https://github.enterprise.local/api/v3'; + if (name === 'ghe_base_url') return ''; + return ''; + }); + + await (JobSummary as any).uploadCodeScanningSarif('eJx4YWJj', 'ghs_token'); + + expect((global as any).__USED_BASE_URL__).toBe('https://github.enterprise.local/api/v3'); + }); + + it('Should falls back to auto GHES baseUrl via @actions/github if input is not specified', async () => { + process.env.__AUTO_BASE_URL__ = 'https://ghe.corp.local/api/v3'; + + await (JobSummary as any).uploadCodeScanningSarif('eJx4YWJj', 'ghs_token'); + + expect((global as any).__USED_BASE_URL__).toBe('https://ghe.corp.local/api/v3'); + }); +}); From 979fd4ddddfe1731acd7469ff00938faeabc2c47 Mon Sep 17 00:00:00 2001 From: p4r53c Date: Tue, 26 Aug 2025 14:06:17 +0300 Subject: [PATCH 2/3] Revert "feat(ghes): add ghe-base-url input and honor baseUrl for Octokit when uploading SARIF" This reverts commit e62277a12a98cec1433a58dcbc120f54df1c6168. --- lib/job-summary.js | 31 ++++--------- src/job-summary.ts | 31 ++++--------- test/job-summary.sarif.baseurl.spec.ts | 64 -------------------------- 3 files changed, 17 insertions(+), 109 deletions(-) delete mode 100644 test/job-summary.sarif.baseurl.spec.ts diff --git a/lib/job-summary.js b/lib/job-summary.js index e6b58c7d4..67b226b2f 100644 --- a/lib/job-summary.js +++ b/lib/job-summary.js @@ -38,6 +38,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.JobSummary = void 0; const core = __importStar(require("@actions/core")); const semver_1 = require("semver"); +const core_1 = require("@octokit/core"); const github = __importStar(require("@actions/github")); const util_1 = require("util"); const zlib_1 = require("zlib"); @@ -106,29 +107,16 @@ class JobSummary { }); } /** - * Uploads a gzip-compressed, base64-encoded SARIF payload to GitHub Code Scanning. - * - * Uses the current GitHub Actions context (owner, repo, commit SHA, and ref) for the target. - * If a GitHub Enterprise Server base URL is provided via the 'ghe-base-url' or 'ghe_base_url' - * action input, the request is sent to that endpoint; otherwise, it targets github.com. - * - * @param encodedSarif - The SARIF report content after gzip compression and base64 encoding, - * as required by the POST /repos/{owner}/{repo}/code-scanning/sarifs API. - * Typically produced by compressing raw SARIF with gzip and encoding to base64. - * @param token - GitHub token used to authenticate the upload request. Must have - * security_events: write permission on the target repository (e.g., a PAT or GITHUB_TOKEN - * with the appropriate permission). - * - * @returns A promise that resolves when the upload completes successfully. - * @throws Error if the API response status is not 2xx; the thrown error includes the resolved baseUrl - * and a serialized response summary to aid debugging. + * Uploads the code scanning SARIF content to the code-scanning GitHub API. + * @param encodedSarif - The final compressed and encoded sarif content. + * @param token - GitHub token to use for the request. Has to have 'security-events: write' permission. + * @private */ static uploadCodeScanningSarif(encodedSarif, token) { return __awaiter(this, void 0, void 0, function* () { - var _a, _b, _c; - const inputBaseUrl = core.getInput('ghe-base-url', { required: false }) || core.getInput('ghe_base_url', { required: false }) || ''; - const octokit = inputBaseUrl ? github.getOctokit(token, { baseUrl: inputBaseUrl }) : github.getOctokit(token); - const response = yield octokit.request('POST /repos/{owner}/{repo}/code-scanning/sarifs', { + const octokit = new core_1.Octokit({ auth: token }); + let response; + response = yield octokit.request('POST /repos/{owner}/{repo}/code-scanning/sarifs', { owner: github.context.repo.owner, repo: github.context.repo.repo, commit_sha: github.context.sha, @@ -136,8 +124,7 @@ class JobSummary { sarif: encodedSarif, }); if (response.status < 200 || response.status >= 300) { - const usedBaseUrl = ((_c = (_b = (_a = octokit.request) === null || _a === void 0 ? void 0 : _a.endpoint) === null || _b === void 0 ? void 0 : _b.DEFAULTS) === null || _c === void 0 ? void 0 : _c.baseUrl) || 'unknown'; - throw new Error(`Failed to upload SARIF file (status ${response.status}). baseUrl=${usedBaseUrl}; response=` + JSON.stringify(response)); + throw new Error(`Failed to upload SARIF file: ` + JSON.stringify(response)); } core.info('SARIF file uploaded successfully'); }); diff --git a/src/job-summary.ts b/src/job-summary.ts index e2f4c852e..fe1f47efc 100644 --- a/src/job-summary.ts +++ b/src/job-summary.ts @@ -105,29 +105,15 @@ export class JobSummary { } /** - * Uploads a gzip-compressed, base64-encoded SARIF payload to GitHub Code Scanning. - * - * Uses the current GitHub Actions context (owner, repo, commit SHA, and ref) for the target. - * If a GitHub Enterprise Server base URL is provided via the 'ghe-base-url' or 'ghe_base_url' - * action input, the request is sent to that endpoint; otherwise, it targets github.com. - * - * @param encodedSarif - The SARIF report content after gzip compression and base64 encoding, - * as required by the POST /repos/{owner}/{repo}/code-scanning/sarifs API. - * Typically produced by compressing raw SARIF with gzip and encoding to base64. - * @param token - GitHub token used to authenticate the upload request. Must have - * security_events: write permission on the target repository (e.g., a PAT or GITHUB_TOKEN - * with the appropriate permission). - * - * @returns A promise that resolves when the upload completes successfully. - * @throws Error if the API response status is not 2xx; the thrown error includes the resolved baseUrl - * and a serialized response summary to aid debugging. + * Uploads the code scanning SARIF content to the code-scanning GitHub API. + * @param encodedSarif - The final compressed and encoded sarif content. + * @param token - GitHub token to use for the request. Has to have 'security-events: write' permission. + * @private */ private static async uploadCodeScanningSarif(encodedSarif: string, token: string) { - const inputBaseUrl = core.getInput('ghe-base-url', { required: false }) || core.getInput('ghe_base_url', { required: false }) || ''; - - const octokit = inputBaseUrl ? github.getOctokit(token, { baseUrl: inputBaseUrl }) : github.getOctokit(token); - - const response = await octokit.request('POST /repos/{owner}/{repo}/code-scanning/sarifs', { + const octokit: Octokit = new Octokit({ auth: token }); + let response: OctokitResponse | undefined; + response = await octokit.request('POST /repos/{owner}/{repo}/code-scanning/sarifs', { owner: github.context.repo.owner, repo: github.context.repo.repo, commit_sha: github.context.sha, @@ -136,8 +122,7 @@ export class JobSummary { }); if (response.status < 200 || response.status >= 300) { - const usedBaseUrl = (octokit as any).request?.endpoint?.DEFAULTS?.baseUrl || 'unknown'; - throw new Error(`Failed to upload SARIF file (status ${response.status}). baseUrl=${usedBaseUrl}; response=` + JSON.stringify(response)); + throw new Error(`Failed to upload SARIF file: ` + JSON.stringify(response)); } core.info('SARIF file uploaded successfully'); diff --git a/test/job-summary.sarif.baseurl.spec.ts b/test/job-summary.sarif.baseurl.spec.ts deleted file mode 100644 index f05571a3a..000000000 --- a/test/job-summary.sarif.baseurl.spec.ts +++ /dev/null @@ -1,64 +0,0 @@ -/** - * test/job-summary.sarif.baseurl.spec.ts - * Checking baseUrl selection when loading SARIF on GHES. - */ - -import * as core from '@actions/core'; - -jest.mock('@actions/github', () => { - const actual = jest.requireActual('@actions/github'); - return { - ...actual, - getOctokit: jest.fn((token: string, opts?: { baseUrl?: string }) => { - const usedBaseUrl = (opts && opts.baseUrl) || process.env.__AUTO_BASE_URL__ || 'https://api.github.com'; - - const req = jest.fn(async (_route: string, _params: any) => { - (global as any).__USED_BASE_URL__ = usedBaseUrl; - return { status: 201, data: {} }; - }) as unknown as any; - - req.endpoint = { DEFAULTS: { baseUrl: usedBaseUrl } }; - - return { request: req } as any; - }), - context: { - repo: { owner: 'o', repo: 'r' }, - sha: 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef', - ref: 'refs/heads/main', - }, - }; -}); - -import { JobSummary } from '../src/job-summary'; - -describe('uploadCodeScanningSarif baseUrl selection (GHES)', () => { - beforeEach(() => { - jest.resetModules(); - jest.clearAllMocks(); - - jest.spyOn(core, 'getInput').mockImplementation((_name: string) => ''); - - delete process.env.__AUTO_BASE_URL__; - delete (global as any).__USED_BASE_URL__; - }); - - it('Should use explicit input ghe-base-url if given', async () => { - (core.getInput as jest.Mock).mockImplementation((name: string) => { - if (name === 'ghe-base-url') return 'https://github.enterprise.local/api/v3'; - if (name === 'ghe_base_url') return ''; - return ''; - }); - - await (JobSummary as any).uploadCodeScanningSarif('eJx4YWJj', 'ghs_token'); - - expect((global as any).__USED_BASE_URL__).toBe('https://github.enterprise.local/api/v3'); - }); - - it('Should falls back to auto GHES baseUrl via @actions/github if input is not specified', async () => { - process.env.__AUTO_BASE_URL__ = 'https://ghe.corp.local/api/v3'; - - await (JobSummary as any).uploadCodeScanningSarif('eJx4YWJj', 'ghs_token'); - - expect((global as any).__USED_BASE_URL__).toBe('https://ghe.corp.local/api/v3'); - }); -}); From e007127449b31ef9109f9aac345693cee12bb76b Mon Sep 17 00:00:00 2001 From: p4r53c Date: Tue, 26 Aug 2025 14:25:45 +0300 Subject: [PATCH 3/3] feat(ghes): add ghe-base-url input and honor baseUrl for SARIF uploads --- lib/job-summary.js | 23 +++++---- package-lock.json | 4 +- src/job-summary.ts | 25 ++++++---- test/job-summary.sarif.baseurl.spec.ts | 64 ++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 20 deletions(-) create mode 100644 test/job-summary.sarif.baseurl.spec.ts diff --git a/lib/job-summary.js b/lib/job-summary.js index 67b226b2f..564465922 100644 --- a/lib/job-summary.js +++ b/lib/job-summary.js @@ -38,7 +38,6 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.JobSummary = void 0; const core = __importStar(require("@actions/core")); const semver_1 = require("semver"); -const core_1 = require("@octokit/core"); const github = __importStar(require("@actions/github")); const util_1 = require("util"); const zlib_1 = require("zlib"); @@ -107,16 +106,21 @@ class JobSummary { }); } /** - * Uploads the code scanning SARIF content to the code-scanning GitHub API. - * @param encodedSarif - The final compressed and encoded sarif content. - * @param token - GitHub token to use for the request. Has to have 'security-events: write' permission. - * @private + * Uploads a SARIF (Static Analysis Results Interchange Format) file to GitHub's code scanning API. + * This method handles the communication with GitHub's REST API to populate the code scanning tab with security analysis results. + * Supports both GitHub.com and GitHub Enterprise Server installations. + * @param encodedSarif - The SARIF content that has been compressed using gzip and encoded to base64 format. + * This encoding is required by GitHub's code-scanning/sarifs API endpoint. + * @param token - GitHub authentication token with appropriate permissions to upload SARIF files. + * Must have 'security_events: write' and 'contents: read' permissions. + * @throws Will throw an error if the HTTP response status is not in the 2xx range or if authentication fails. */ static uploadCodeScanningSarif(encodedSarif, token) { return __awaiter(this, void 0, void 0, function* () { - const octokit = new core_1.Octokit({ auth: token }); - let response; - response = yield octokit.request('POST /repos/{owner}/{repo}/code-scanning/sarifs', { + var _a, _b, _c; + const inputBaseUrl = core.getInput('ghe-base-url', { required: false }) || core.getInput('ghe_base_url', { required: false }) || ''; + const octokit = inputBaseUrl ? github.getOctokit(token, { baseUrl: inputBaseUrl }) : github.getOctokit(token); + const response = yield octokit.request('POST /repos/{owner}/{repo}/code-scanning/sarifs', { owner: github.context.repo.owner, repo: github.context.repo.repo, commit_sha: github.context.sha, @@ -124,7 +128,8 @@ class JobSummary { sarif: encodedSarif, }); if (response.status < 200 || response.status >= 300) { - throw new Error(`Failed to upload SARIF file: ` + JSON.stringify(response)); + const usedBaseUrl = ((_c = (_b = (_a = octokit.request) === null || _a === void 0 ? void 0 : _a.endpoint) === null || _b === void 0 ? void 0 : _b.DEFAULTS) === null || _c === void 0 ? void 0 : _c.baseUrl) || 'unknown'; + throw new Error(`Failed to upload SARIF file (status ${response.status}). baseUrl=${usedBaseUrl}; response=` + JSON.stringify(response)); } core.info('SARIF file uploaded successfully'); }); diff --git a/package-lock.json b/package-lock.json index b0f0b9374..1950b0c9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@jfrog/setup-jfrog-cli", - "version": "4.5.13", + "version": "4.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@jfrog/setup-jfrog-cli", - "version": "4.5.13", + "version": "4.6.0", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/src/job-summary.ts b/src/job-summary.ts index fe1f47efc..8206446dc 100644 --- a/src/job-summary.ts +++ b/src/job-summary.ts @@ -103,17 +103,23 @@ export class JobSummary { core.warning(`Failed populating code scanning sarif: ${error}`); } } - + /** - * Uploads the code scanning SARIF content to the code-scanning GitHub API. - * @param encodedSarif - The final compressed and encoded sarif content. - * @param token - GitHub token to use for the request. Has to have 'security-events: write' permission. - * @private + * Uploads a SARIF (Static Analysis Results Interchange Format) file to GitHub's code scanning API. + * This method handles the communication with GitHub's REST API to populate the code scanning tab with security analysis results. + * Supports both GitHub.com and GitHub Enterprise Server installations. + * @param encodedSarif - The SARIF content that has been compressed using gzip and encoded to base64 format. + * This encoding is required by GitHub's code-scanning/sarifs API endpoint. + * @param token - GitHub authentication token with appropriate permissions to upload SARIF files. + * Must have 'security_events: write' and 'contents: read' permissions. + * @throws Will throw an error if the HTTP response status is not in the 2xx range or if authentication fails. */ private static async uploadCodeScanningSarif(encodedSarif: string, token: string) { - const octokit: Octokit = new Octokit({ auth: token }); - let response: OctokitResponse | undefined; - response = await octokit.request('POST /repos/{owner}/{repo}/code-scanning/sarifs', { + const inputBaseUrl = core.getInput('ghe-base-url', { required: false }) || core.getInput('ghe_base_url', { required: false }) || ''; + + const octokit = inputBaseUrl ? github.getOctokit(token, { baseUrl: inputBaseUrl }) : github.getOctokit(token); + + const response = await octokit.request('POST /repos/{owner}/{repo}/code-scanning/sarifs', { owner: github.context.repo.owner, repo: github.context.repo.repo, commit_sha: github.context.sha, @@ -122,7 +128,8 @@ export class JobSummary { }); if (response.status < 200 || response.status >= 300) { - throw new Error(`Failed to upload SARIF file: ` + JSON.stringify(response)); + const usedBaseUrl = (octokit as any).request?.endpoint?.DEFAULTS?.baseUrl || 'unknown'; + throw new Error(`Failed to upload SARIF file (status ${response.status}). baseUrl=${usedBaseUrl}; response=` + JSON.stringify(response)); } core.info('SARIF file uploaded successfully'); diff --git a/test/job-summary.sarif.baseurl.spec.ts b/test/job-summary.sarif.baseurl.spec.ts new file mode 100644 index 000000000..f05571a3a --- /dev/null +++ b/test/job-summary.sarif.baseurl.spec.ts @@ -0,0 +1,64 @@ +/** + * test/job-summary.sarif.baseurl.spec.ts + * Checking baseUrl selection when loading SARIF on GHES. + */ + +import * as core from '@actions/core'; + +jest.mock('@actions/github', () => { + const actual = jest.requireActual('@actions/github'); + return { + ...actual, + getOctokit: jest.fn((token: string, opts?: { baseUrl?: string }) => { + const usedBaseUrl = (opts && opts.baseUrl) || process.env.__AUTO_BASE_URL__ || 'https://api.github.com'; + + const req = jest.fn(async (_route: string, _params: any) => { + (global as any).__USED_BASE_URL__ = usedBaseUrl; + return { status: 201, data: {} }; + }) as unknown as any; + + req.endpoint = { DEFAULTS: { baseUrl: usedBaseUrl } }; + + return { request: req } as any; + }), + context: { + repo: { owner: 'o', repo: 'r' }, + sha: 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef', + ref: 'refs/heads/main', + }, + }; +}); + +import { JobSummary } from '../src/job-summary'; + +describe('uploadCodeScanningSarif baseUrl selection (GHES)', () => { + beforeEach(() => { + jest.resetModules(); + jest.clearAllMocks(); + + jest.spyOn(core, 'getInput').mockImplementation((_name: string) => ''); + + delete process.env.__AUTO_BASE_URL__; + delete (global as any).__USED_BASE_URL__; + }); + + it('Should use explicit input ghe-base-url if given', async () => { + (core.getInput as jest.Mock).mockImplementation((name: string) => { + if (name === 'ghe-base-url') return 'https://github.enterprise.local/api/v3'; + if (name === 'ghe_base_url') return ''; + return ''; + }); + + await (JobSummary as any).uploadCodeScanningSarif('eJx4YWJj', 'ghs_token'); + + expect((global as any).__USED_BASE_URL__).toBe('https://github.enterprise.local/api/v3'); + }); + + it('Should falls back to auto GHES baseUrl via @actions/github if input is not specified', async () => { + process.env.__AUTO_BASE_URL__ = 'https://ghe.corp.local/api/v3'; + + await (JobSummary as any).uploadCodeScanningSarif('eJx4YWJj', 'ghs_token'); + + expect((global as any).__USED_BASE_URL__).toBe('https://ghe.corp.local/api/v3'); + }); +});