diff --git a/.github/workflows/metrics.yml b/.github/workflows/metrics.yml index 0f608cf..6ccac5b 100644 --- a/.github/workflows/metrics.yml +++ b/.github/workflows/metrics.yml @@ -11,3 +11,5 @@ jobs: steps: - uses: actions/checkout@v4 - uses: ./ + with: + only: ci.yml diff --git a/action.yml b/action.yml index b2ba38e..86c3810 100644 --- a/action.yml +++ b/action.yml @@ -1,6 +1,10 @@ name: GitHub Workflow Metrics description: TODO inputs: + only: + description: Only the specified workflows will be measured. This is supposed to be comma-separated list + required: false + default: "" label: description: The label for GitHub issues that the GitHub Action creates required: false diff --git a/dist/index.js b/dist/index.js index 5a7bda2..b042f22 100644 --- a/dist/index.js +++ b/dist/index.js @@ -29241,8 +29241,14 @@ class GitHubRepository { this.repo = repo; this.apiClient = apiClient; } - async getWorkflows() { - return this.apiClient.getWorkflows(this.owner, this.repo); + async getWorkflows(only) { + const workflows = await this.apiClient.getWorkflows(this.owner, this.repo); + if (only) { + return workflows.filter((w) => { + return only.some((o) => w.path.endsWith(o)); + }); + } + return workflows; } async getWorkflow(path) { return this.apiClient.getWorkflow(this.owner, this.repo, path); @@ -29280,6 +29286,13 @@ class Input { get label() { return this.getInputFn("label"); } + get only() { + const only = this.getInputFn("only"); + if (only.length === 0) { + return null; + } + return only.split(/\s*,\s*/); + } get token() { return this.getInputFn("token", { required: true }); } @@ -29328,7 +29341,7 @@ const main = async () => { const input = new Input(); const apiClient = new GitHubAPIClient(input.token); const repository = new GitHubRepository(input.owner, input.repo, apiClient); - const workflows = await repository.getWorkflows(); + const workflows = await repository.getWorkflows(input.only); const charts = await Promise.all(workflows.map(async (w) => { const runs = await repository.getWorkflowRuns(w); return new MermaidXYChart(w, runs); diff --git a/src/GitHubRepository.ts b/src/GitHubRepository.ts index c1f307b..cb498c3 100644 --- a/src/GitHubRepository.ts +++ b/src/GitHubRepository.ts @@ -11,8 +11,14 @@ export class GitHubRepository { private readonly apiClient: APIClient, ) {} - async getWorkflows(): Promise { - return this.apiClient.getWorkflows(this.owner, this.repo); + async getWorkflows(only?: string[] | null): Promise { + const workflows = await this.apiClient.getWorkflows(this.owner, this.repo); + if (only) { + return workflows.filter((w) => { + return only.some((o) => w.path.endsWith(o)); + }); + } + return workflows; } async getWorkflow(path: string): Promise { diff --git a/src/Input.ts b/src/Input.ts index b0d6c3f..3806219 100644 --- a/src/Input.ts +++ b/src/Input.ts @@ -23,6 +23,14 @@ export class Input { return this.getInputFn("label"); } + get only(): string[] | null { + const only = this.getInputFn("only"); + if (only.length === 0) { + return null; + } + return only.split(/\s*,\s*/); + } + get token(): string { return this.getInputFn("token", { required: true }); } diff --git a/src/TestClient.ts b/src/TestClient.ts index 875e99b..d677b07 100644 --- a/src/TestClient.ts +++ b/src/TestClient.ts @@ -7,7 +7,10 @@ import { GitHubWorkflowRun } from "./GitHubWorkflowRun"; export class TestClient implements APIClient { async getWorkflows(_owner: string, _repo: string): Promise { - return [new GitHubWorkflow(1234, "My Workflow", "my_workflow.yml")]; + return [ + new GitHubWorkflow(1234, "My Workflow", "my_workflow.yml"), + new GitHubWorkflow(1235, "XYZ", "xyz.yml"), + ]; } async getWorkflow( _owner: string, diff --git a/src/main.ts b/src/main.ts index d7436d6..419eb21 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,7 +9,7 @@ const main = async () => { const input = new Input(); const apiClient = new GitHubAPIClient(input.token); const repository = new GitHubRepository(input.owner, input.repo, apiClient); - const workflows = await repository.getWorkflows(); + const workflows = await repository.getWorkflows(input.only); const charts = await Promise.all( workflows.map(async (w) => { const runs = await repository.getWorkflowRuns(w); diff --git a/tests/GitHubRepository.test.ts b/tests/GitHubRepository.test.ts index e0dc214..c53f6c1 100644 --- a/tests/GitHubRepository.test.ts +++ b/tests/GitHubRepository.test.ts @@ -1,4 +1,4 @@ -import { describe, it } from "vitest"; +import { describe, expect, it } from "vitest"; import { GitHubIssue } from "../src/GitHubIssue"; import { GitHubIssueContent } from "../src/GitHubIssueContent"; import { GitHubRepository } from "../src/GitHubRepository"; @@ -6,15 +6,17 @@ import { GitHubWorkflow } from "../src/GitHubWorkflow"; import { TestClient } from "../src/TestClient"; describe("GitHubRepository", () => { - it("should call functions declared in APIClient", () => { + it("should call functions declared in APIClient", async () => { const client = new TestClient(); const repository = new GitHubRepository("owner", "repo", client); - repository.getWorkflows(); - repository.getWorkflow("abc.yml"); - repository.getWorkflowRuns(new GitHubWorkflow(8, "Eight", "eight.yml")); - repository.getIssues([]); - repository.createIssue(new GitHubIssueContent([], "title")); - repository.closeIssue( + await repository.getWorkflows(); + await repository.getWorkflow("abc.yml"); + await repository.getWorkflowRuns( + new GitHubWorkflow(8, "Eight", "eight.yml"), + ); + await repository.getIssues([]); + await repository.createIssue(new GitHubIssueContent([], "title")); + await repository.closeIssue( new GitHubIssue({ id: 1, number: 1, @@ -25,4 +27,12 @@ describe("GitHubRepository", () => { }), ); }); + + it("should filter workflows with only", async () => { + const client = new TestClient(); + const repository = new GitHubRepository("owner", "repo", client); + const workflows = await repository.getWorkflows(["xyz.yml"]); + expect(workflows.length).toEqual(1); + expect(workflows.map((w) => w.path)).toEqual(["xyz.yml"]); + }); }); diff --git a/tests/Input.test.ts b/tests/Input.test.ts index 5748c33..1b1a7b9 100644 --- a/tests/Input.test.ts +++ b/tests/Input.test.ts @@ -19,6 +19,8 @@ describe("Input", () => { return "my-token"; case "label": return "github-workflows-metrics"; + case "only": + return ""; default: throw new Error("Unsupported key"); } @@ -27,6 +29,24 @@ describe("Input", () => { expect(input.owner).toEqual("yykamei"); expect(input.repo).toEqual("test-repo"); expect(input.label).toEqual("github-workflows-metrics"); + expect(input.only).toBeNull(); expect(input.token).toEqual("my-token"); }); + it("should return an Array for only when specified", () => { + const context = new Context(); + vi.spyOn(context, "repo", "get").mockReturnValue({ + owner: "yykamei", + repo: "test-repo", + }); + const getInput = vi.fn((key: string) => { + switch (key) { + case "only": + return "a.yml , b.yml,c.yml"; + default: + throw new Error("Unsupported key"); + } + }); + const input = new Input(context, getInput); + expect(input.only).toEqual(["a.yml", "b.yml", "c.yml"]); + }); });