From 14f113adc453fc0b11873e103d4fce7c2c62864d Mon Sep 17 00:00:00 2001 From: Yutaka Kamei Date: Wed, 3 Apr 2024 23:39:13 +0900 Subject: [PATCH] Add range input to narrow data range --- action.yml | 7 +++++++ dist/index.js | 38 ++++++++++++++++++++++++++++++++++++++ src/APIClient.ts | 2 ++ src/GitHubAPIClient.ts | 26 ++++++++++++++++++++++++++ src/Input.ts | 15 +++++++++++++++ src/main.ts | 1 + tests/Input.test.ts | 14 ++++++++++++++ 7 files changed, 103 insertions(+) diff --git a/action.yml b/action.yml index d226888..cfaf6e2 100644 --- a/action.yml +++ b/action.yml @@ -1,6 +1,13 @@ name: GitHub Workflow Metrics description: TODO inputs: + range: + description: | + The range of time to measure the workflows. + This can be: + 7days, 14days, 30days + required: false + default: 30days only: description: Only the specified workflows will be measured. This is supposed to be comma-separated list required: false diff --git a/dist/index.js b/dist/index.js index a2f084c..e33b246 100644 --- a/dist/index.js +++ b/dist/index.js @@ -29174,6 +29174,7 @@ class GitHubAPIClient { page, exclude_pull_requests: options?.excludePullRequests, status: options?.status, + created: options?.created && rangeToCreated(options.created), }); link = response.headers.link || ""; page += 1; @@ -29254,6 +29255,29 @@ class GitHubAPIClient { }); } } +const rangeToCreated = (range) => { + const now = new Date(); + switch (range) { + case "7days": { + now.setDate(now.getDate() - 7); + break; + } + case "14days": { + now.setDate(now.getDate() - 14); + break; + } + case "30days": { + now.setDate(now.getDate() - 30); + break; + } + } + const date = now.toLocaleDateString("en-CA", { + year: "numeric", + month: "2-digit", + day: "2-digit", + }); + return `>=${date}`; +}; ;// CONCATENATED MODULE: ./src/GitHubIssueContent.ts class GitHubIssueContent { @@ -29375,6 +29399,19 @@ class Input { return undefined; } } + get range() { + const s = this.getInputFn("range"); + switch (s) { + case "7days": + return s; + case "14days": + return s; + case "30days": + return s; + default: + throw new Error("range must be one of 7days, 14days, or 30days"); + } + } get token() { return this.getInputFn("token", { required: true }); } @@ -29457,6 +29494,7 @@ const main = async () => { const charts = await Promise.all(workflows.map(async (w) => { const runs = await repository.getWorkflowRuns(w, { status: input.status, + created: input.range, }); return new MermaidXYChart(w, runs, input); })); diff --git a/src/APIClient.ts b/src/APIClient.ts index 429a4d0..2a2b24e 100644 --- a/src/APIClient.ts +++ b/src/APIClient.ts @@ -2,6 +2,7 @@ import type { GitHubIssue } from "./GitHubIssue"; import type { GitHubIssueContent } from "./GitHubIssueContent"; import type { GitHubWorkflow } from "./GitHubWorkflow"; import type { GitHubWorkflowRun } from "./GitHubWorkflowRun"; +import type { RangeString } from "./Input"; import type { Usage } from "./Usage"; export type WorkflowStatus = @@ -23,6 +24,7 @@ export type WorkflowStatus = export type GetWorkflowRunsOptions = { readonly excludePullRequests?: boolean; readonly status?: WorkflowStatus; + readonly created?: RangeString; }; export interface APIClient { diff --git a/src/GitHubAPIClient.ts b/src/GitHubAPIClient.ts index 6c7e626..26be4da 100644 --- a/src/GitHubAPIClient.ts +++ b/src/GitHubAPIClient.ts @@ -8,6 +8,7 @@ import { GitHubIssue } from "./GitHubIssue"; import type { GitHubIssueContent } from "./GitHubIssueContent"; import { GitHubWorkflow } from "./GitHubWorkflow"; import { GitHubWorkflowRun } from "./GitHubWorkflowRun"; +import type { RangeString } from "./Input"; import { Usage } from "./Usage"; const GITHUB_LINK_REL_REXT = 'rel="next"'; @@ -102,6 +103,7 @@ export class GitHubAPIClient implements APIClient { page, exclude_pull_requests: options?.excludePullRequests, status: options?.status, + created: options?.created && rangeToCreated(options.created), }, ); link = response.headers.link || ""; @@ -217,3 +219,27 @@ export class GitHubAPIClient implements APIClient { }); } } + +const rangeToCreated = (range: RangeString) => { + const now = new Date(); + switch (range) { + case "7days": { + now.setDate(now.getDate() - 7); + break; + } + case "14days": { + now.setDate(now.getDate() - 14); + break; + } + case "30days": { + now.setDate(now.getDate() - 30); + break; + } + } + const date = now.toLocaleDateString("en-CA", { + year: "numeric", + month: "2-digit", + day: "2-digit", + }); + return `>=${date}`; +}; diff --git a/src/Input.ts b/src/Input.ts index ba713b3..91d3c99 100644 --- a/src/Input.ts +++ b/src/Input.ts @@ -3,6 +3,7 @@ import { context } from "@actions/github"; import type { Context } from "@actions/github/lib/context"; import type { WorkflowStatus } from "./APIClient"; +export type RangeString = "7days" | "14days" | "30days"; export class Input { constructor( private readonly ctx: Context = context, @@ -68,6 +69,20 @@ export class Input { } } + get range(): RangeString { + const s = this.getInputFn("range"); + switch (s) { + case "7days": + return s; + case "14days": + return s; + case "30days": + return s; + default: + throw new Error("range must be one of 7days, 14days, or 30days"); + } + } + get token(): string { return this.getInputFn("token", { required: true }); } diff --git a/src/main.ts b/src/main.ts index 8e51aaf..f0cf64c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -14,6 +14,7 @@ const main = async () => { workflows.map(async (w) => { const runs = await repository.getWorkflowRuns(w, { status: input.status, + created: input.range, }); return new MermaidXYChart(w, runs, input); }), diff --git a/tests/Input.test.ts b/tests/Input.test.ts index 82c2615..ff2ef65 100644 --- a/tests/Input.test.ts +++ b/tests/Input.test.ts @@ -23,6 +23,8 @@ describe("Input", () => { return ""; case "status": return "failure"; + case "range": + return "30days"; default: throw new Error("Unsupported key"); } @@ -33,6 +35,7 @@ describe("Input", () => { expect(input.label).toEqual("github-workflows-metrics"); expect(input.only).toBeNull(); expect(input.status).toEqual("failure"); + expect(input.range).toEqual("30days"); expect(input.token).toEqual("my-token"); }); @@ -85,4 +88,15 @@ describe("Input", () => { const input = new Input(context, getInput); expect(input.status).toBeUndefined(); }); + + it("should throw an error with the unsupported range", () => { + const context = new Context(); + vi.spyOn(context, "repo", "get").mockReturnValue({ + owner: "yykamei", + repo: "test-repo", + }); + const getInput = vi.fn(() => "unknown"); + const input = new Input(context, getInput); + expect(() => input.range).toThrowError; + }); });