Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix usage system parameters #243

Merged
merged 22 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 32 additions & 7 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,9 @@ class Utils {
const exchangeUrl = jfrogCredentials.jfrogUrl.replace(/\/$/, '') + '/access/api/v1/oidc/token';
core.debug('Exchanging GitHub JSON web token with a JFrog access token...');
let projectKey = process.env.JF_PROJECT || '';
let jobId = process.env.GITHUB_JOB || '';
let jobId = this.getGithubJobId();
let runId = process.env.GITHUB_RUN_ID || '';
let githubRepository = process.env.GITHUB_REPOSITORY || '';
const httpClient = new http_client_1.HttpClient();
const data = `{
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
Expand All @@ -202,6 +203,7 @@ class Utils {
"project_key": "${projectKey}",
"gh_job_id": "${jobId}",
"gh_run_id": "${runId}",
"gh_repo": "${githubRepository}",
"application_key": "${applicationKey}"
}`;
const additionalHeaders = {
Expand Down Expand Up @@ -825,13 +827,16 @@ class Utils {
}
static getUsageBadge() {
const platformUrl = Utils.getPlatformUrl();
const githubJobId = Utils.encodeForUrl(process.env.GITHUB_JOB || '');
const gitRepo = Utils.encodeForUrl(process.env.GITHUB_REPOSITORY || '');
const githubJobId = this.getGithubJobId();
const gitRepo = process.env.GITHUB_REPOSITORY || '';
const runId = process.env.GITHUB_RUN_ID || '';
return `![](${platformUrl}ui/api/v1/u?s=1&m=1&job_id=${githubJobId}&run_id=${runId}&git_repo=${gitRepo})`;
}
static encodeForUrl(value) {
return encodeURIComponent(value);
const url = new URL(`${platformUrl}ui/api/v1/u`);
url.searchParams.set(Utils.SOURCE_PARAM_KEY, Utils.SOURCE_PARAM_VALUE);
url.searchParams.set(Utils.METRIC_PARAM_KEY, Utils.METRIC_PARAM_VALUE);
url.searchParams.set(Utils.JOB_ID_PARAM_KEY, githubJobId);
url.searchParams.set(Utils.RUN_ID_PARAM_KEY, runId);
url.searchParams.set(Utils.GIT_REPO_PARAM_KEY, gitRepo);
return `![](${url.toString()})`;
}
/**
* Checks if the header image is accessible via the internet.
Expand Down Expand Up @@ -872,6 +877,14 @@ class Utils {
}
return tempDir;
}
/**
* Retrieves the GitHub job ID, which in this context refers to the GitHub workflow name.
* Note: We use "job" instead of "workflow" to align with our terminology, where "GitHub job summary"
* refers to the entire workflow summary. Here, "job ID" means the workflow name, not individual jobs within the workflow.
*/
static getGithubJobId() {
return process.env.GITHUB_WORKFLOW || '';
}
}
exports.Utils = Utils;
// eslint-disable-next-line @typescript-eslint/no-var-requires
Expand Down Expand Up @@ -939,3 +952,15 @@ Utils.CUSTOM_SERVER_ID = 'custom-server-id';
Utils.MARKDOWN_HEADER_PNG_URL = 'https://media.jfrog.com/wp-content/uploads/2024/09/02161430/jfrog-job-summary.svg';
// Flag to indicate if the summary header is accessible, can be undefined if not checked yet.
Utils.isSummaryHeaderAccessible = undefined;
// Job ID query parameter key
Utils.JOB_ID_PARAM_KEY = 'job_id';
// Run ID query parameter key
Utils.RUN_ID_PARAM_KEY = 'run_id';
// Git repository query parameter key
Utils.GIT_REPO_PARAM_KEY = 'git_repo';
// Source query parameter indicating the source of the request
Utils.SOURCE_PARAM_KEY = 's';
Utils.SOURCE_PARAM_VALUE = '1';
// Metric query parameter indicating the metric type
Utils.METRIC_PARAM_KEY = 'm';
Utils.METRIC_PARAM_VALUE = '1';
41 changes: 33 additions & 8 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,18 @@ export class Utils {
private static MARKDOWN_HEADER_PNG_URL: string = 'https://media.jfrog.com/wp-content/uploads/2024/09/02161430/jfrog-job-summary.svg';
// Flag to indicate if the summary header is accessible, can be undefined if not checked yet.
private static isSummaryHeaderAccessible: boolean | undefined = undefined;
// Job ID query parameter key
private static readonly JOB_ID_PARAM_KEY: string = 'job_id';
// Run ID query parameter key
private static readonly RUN_ID_PARAM_KEY: string = 'run_id';
// Git repository query parameter key
private static readonly GIT_REPO_PARAM_KEY: string = 'git_repo';
// Source query parameter indicating the source of the request
private static readonly SOURCE_PARAM_KEY: string = 's';
private static readonly SOURCE_PARAM_VALUE: string = '1';
// Metric query parameter indicating the metric type
private static readonly METRIC_PARAM_KEY: string = 'm';
private static readonly METRIC_PARAM_VALUE: string = '1';

/**
* Retrieves server credentials for accessing JFrog's server
Expand Down Expand Up @@ -234,8 +246,9 @@ export class Utils {
core.debug('Exchanging GitHub JSON web token with a JFrog access token...');

let projectKey: string = process.env.JF_PROJECT || '';
let jobId: string = process.env.GITHUB_JOB || '';
let jobId: string = this.getGithubJobId();
let runId: string = process.env.GITHUB_RUN_ID || '';
let githubRepository: string = process.env.GITHUB_REPOSITORY || '';

const httpClient: HttpClient = new HttpClient();
const data: string = `{
Expand All @@ -246,6 +259,7 @@ export class Utils {
"project_key": "${projectKey}",
"gh_job_id": "${jobId}",
"gh_run_id": "${runId}",
"gh_repo": "${githubRepository}",
"application_key": "${applicationKey}"
}`;

Expand Down Expand Up @@ -912,15 +926,17 @@ export class Utils {

static getUsageBadge(): string {
const platformUrl: string = Utils.getPlatformUrl();
const githubJobId: string = Utils.encodeForUrl(process.env.GITHUB_JOB || '');
const gitRepo: string = Utils.encodeForUrl(process.env.GITHUB_REPOSITORY || '');
const githubJobId: string = this.getGithubJobId();
const gitRepo: string = process.env.GITHUB_REPOSITORY || '';
const runId: string = process.env.GITHUB_RUN_ID || '';
const url: URL = new URL(`${platformUrl}ui/api/v1/u`);

return `![](${platformUrl}ui/api/v1/u?s=1&m=1&job_id=${githubJobId}&run_id=${runId}&git_repo=${gitRepo})`;
}

private static encodeForUrl(value: string): string {
return encodeURIComponent(value);
url.searchParams.set(Utils.SOURCE_PARAM_KEY, Utils.SOURCE_PARAM_VALUE);
url.searchParams.set(Utils.METRIC_PARAM_KEY, Utils.METRIC_PARAM_VALUE);
url.searchParams.set(Utils.JOB_ID_PARAM_KEY, githubJobId);
url.searchParams.set(Utils.RUN_ID_PARAM_KEY, runId);
url.searchParams.set(Utils.GIT_REPO_PARAM_KEY, gitRepo);
return `![](${url.toString()})`;
}

/**
Expand Down Expand Up @@ -959,6 +975,15 @@ export class Utils {
}
return tempDir;
}

/**
* Retrieves the GitHub job ID, which in this context refers to the GitHub workflow name.
* Note: We use "job" instead of "workflow" to align with our terminology, where "GitHub job summary"
* refers to the entire workflow summary. Here, "job ID" means the workflow name, not individual jobs within the workflow.
*/
static getGithubJobId(): string {
return process.env.GITHUB_WORKFLOW || '';
}
}

export interface DownloadDetails {
Expand Down
24 changes: 16 additions & 8 deletions test/main.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -568,36 +568,44 @@ describe('setUsageEnvVars', () => {
});
});

describe('Utils', () => {
describe('Test correct encoding of badge URL', () => {
describe('getUsageBadge', () => {
beforeEach(() => {
process.env.JF_URL = 'https://example.jfrog.io/';
process.env.GITHUB_JOB = 'test-job';
process.env.GITHUB_REPOSITORY = 'test/repo';
process.env.GITHUB_RUN_ID = '123';
});

afterEach(() => {
delete process.env.JF_URL;
delete process.env.GITHUB_JOB;
delete process.env.GITHUB_WORKFLOW;
delete process.env.GITHUB_REPOSITORY;
delete process.env.GITHUB_RUN_ID;
});

it('should return the correct usage badge URL', () => {
process.env.GITHUB_WORKFLOW = 'test-job';
process.env.GITHUB_REPOSITORY = 'test/repo';
const expectedBadge: string = '![](https://example.jfrog.io/ui/api/v1/u?s=1&m=1&job_id=test-job&run_id=123&git_repo=test%2Frepo)';
expect(Utils.getUsageBadge()).toBe(expectedBadge);
});

it('should URL encode the job ID and repository', () => {
process.env.GITHUB_JOB = 'test job';
it('should URL encode the job ID and repository with spaces', () => {
process.env.GITHUB_WORKFLOW = 'test job';
process.env.GITHUB_REPOSITORY = 'test repo';
const expectedBadge: string = '![](https://example.jfrog.io/ui/api/v1/u?s=1&m=1&job_id=test%20job&run_id=123&git_repo=test%20repo)';
const expectedBadge: string = '![](https://example.jfrog.io/ui/api/v1/u?s=1&m=1&job_id=test+job&run_id=123&git_repo=test+repo)';
expect(Utils.getUsageBadge()).toBe(expectedBadge);
});

it('should URL encode the job ID and repository with special characters', () => {
process.env.GITHUB_WORKFLOW = 'test/job@workflow';
process.env.GITHUB_REPOSITORY = 'test/repo@special';
const expectedBadge: string =
'![](https://example.jfrog.io/ui/api/v1/u?s=1&m=1&job_id=test%2Fjob%40workflow&run_id=123&git_repo=test%2Frepo%40special)';
expect(Utils.getUsageBadge()).toBe(expectedBadge);
});

it('should handle missing environment variables gracefully', () => {
delete process.env.GITHUB_JOB;
delete process.env.GITHUB_WORKFLOW;
delete process.env.GITHUB_REPOSITORY;
const expectedBadge: string = '![](https://example.jfrog.io/ui/api/v1/u?s=1&m=1&job_id=&run_id=123&git_repo=)';
expect(Utils.getUsageBadge()).toBe(expectedBadge);
Expand Down
Loading