diff --git a/dist/index.js b/dist/index.js index 517cee7..8e87d00 100644 --- a/dist/index.js +++ b/dist/index.js @@ -169,6 +169,7 @@ class IssueContentParser { const contentLines = issue.body?.split("\n") ?? []; return contentLines .filter(x => this.isTaskListLine(x)) + .map(x => x.substring(6)) .map(x => (0, utils_1.parseIssueUrl)(x)) .filter((x) => x !== null); } @@ -194,6 +195,9 @@ class IssueContentParser { ...contentLines.slice(sectionEndIndex !== -1 ? sectionEndIndex : contentLines.length), ].join("\n"); } + isIssueClosed(issue) { + return issue.state === "closed"; + } isIssueContentIdentical(issue, newIssueContent) { // GitHub automatically replace "\n" to "\r\n" line endings when issue body is modified through GitHub UI. // Replace "\r\n" to "\n" before comparing content to avoid unnecessary issue updates. @@ -272,8 +276,16 @@ const run = async () => { const issueContentParser = new issue_content_parser_1.IssueContentParser(); const mermaidRender = new mermaid_render_1.MermaidRender(inputs.includeLegend); const rootIssue = await githubApiClient.getIssue(inputs.rootIssue); + if (issueContentParser.isIssueClosed(rootIssue)) { + core.info("Skipping generation of mermaid diagram because issue is closed"); + return; + } const rootIssueTasklist = issueContentParser.extractIssueTasklist(rootIssue); core.info(`Found ${rootIssueTasklist.length} work items in task list.`); + if (rootIssueTasklist.length === 0) { + core.info("Skipping generation of mermaid diagram because there is no issues in tasklist"); + return; + } core.info("Building dependency graph..."); const graphBuilder = new graph_builder_1.GraphBuilder(inputs.includeFinishNode); for (const issueRef of rootIssueTasklist) { @@ -435,11 +447,9 @@ ${renderedGraphIssues} `; } renderIssue(issue) { - let result = `${issue.nodeId}("${issue.getWrappedTitle()}"):::${issue.status};`; - if (issue.url) { - result += `\nclick ${issue.nodeId} href "${issue.url}" _blank;`; - } - return result; + const title = issue.getWrappedTitle(); + const linkedTitle = issue.url ? `${title}` : title; + return `${issue.nodeId}("${linkedTitle}"):::${issue.status};`; } renderDependencies(dependencies) { const renderedDependencies = dependencies.map(x => this.renderDependency(x)).join("\n"); @@ -467,10 +477,10 @@ exports.MermaidRender = MermaidRender; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.parseIssuesUrls = exports.parseIssueUrl = void 0; -const issueUrlRegex = /github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/i; -const issueUrlsRegex = new RegExp(issueUrlRegex, "ig"); +const issueUrlRegex = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)$/i; +const issueUrlsRegex = /github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/gi; const parseIssueUrl = (str) => { - const found = str.match(issueUrlRegex); + const found = str.trim().match(issueUrlRegex); if (!found) { return null; } diff --git a/src/issue-content-parser.ts b/src/issue-content-parser.ts index d6f8f86..8b05ab7 100644 --- a/src/issue-content-parser.ts +++ b/src/issue-content-parser.ts @@ -7,6 +7,7 @@ export class IssueContentParser { return contentLines .filter(x => this.isTaskListLine(x)) + .map(x => x.substring(6)) .map(x => parseIssueUrl(x)) .filter((x): x is GitHubIssueReference => x !== null); } @@ -41,6 +42,10 @@ export class IssueContentParser { ].join("\n"); } + public isIssueClosed(issue: GitHubIssue): boolean { + return issue.state === "closed"; + } + public isIssueContentIdentical(issue: GitHubIssue, newIssueContent: string) { // GitHub automatically replace "\n" to "\r\n" line endings when issue body is modified through GitHub UI. // Replace "\r\n" to "\n" before comparing content to avoid unnecessary issue updates. diff --git a/src/main.ts b/src/main.ts index 7e387d5..b81185c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -14,9 +14,17 @@ const run = async (): Promise => { const mermaidRender = new MermaidRender(inputs.includeLegend); const rootIssue = await githubApiClient.getIssue(inputs.rootIssue); - const rootIssueTasklist = issueContentParser.extractIssueTasklist(rootIssue); + if (issueContentParser.isIssueClosed(rootIssue)) { + core.info("Skipping generation of mermaid diagram because issue is closed"); + return; + } + const rootIssueTasklist = issueContentParser.extractIssueTasklist(rootIssue); core.info(`Found ${rootIssueTasklist.length} work items in task list.`); + if (rootIssueTasklist.length === 0) { + core.info("Skipping generation of mermaid diagram because there is no issues in tasklist"); + return; + } core.info("Building dependency graph..."); const graphBuilder = new GraphBuilder(inputs.includeFinishNode); diff --git a/src/mermaid-render.ts b/src/mermaid-render.ts index 3afdd96..590f2a3 100644 --- a/src/mermaid-render.ts +++ b/src/mermaid-render.ts @@ -61,12 +61,9 @@ ${renderedGraphIssues} } private renderIssue(issue: MermaidNode): string { - let result = `${issue.nodeId}("${issue.getWrappedTitle()}"):::${issue.status};`; - if (issue.url) { - result += `\nclick ${issue.nodeId} href "${issue.url}" _blank;`; - } - - return result; + const title = issue.getWrappedTitle(); + const linkedTitle = issue.url ? `${title}` : title; + return `${issue.nodeId}("${linkedTitle}"):::${issue.status};`; } private renderDependencies(dependencies: GraphEdge[]): string { diff --git a/src/utils.ts b/src/utils.ts index 74c38bd..b0f48d9 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -3,11 +3,11 @@ import { GitHubIssueReference } from "./models"; // Analogue of TypeScript "Partial" type but for null values export type NullablePartial = { [P in keyof T]: T[P] | null | undefined }; -const issueUrlRegex = /github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/i; -const issueUrlsRegex = new RegExp(issueUrlRegex, "ig"); +const issueUrlRegex = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)$/i; +const issueUrlsRegex = /github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/gi; export const parseIssueUrl = (str: string): GitHubIssueReference | null => { - const found = str.match(issueUrlRegex); + const found = str.trim().match(issueUrlRegex); if (!found) { return null; } diff --git a/tests/utils.test.ts b/tests/utils.test.ts index 61f38b5..a6c65d6 100644 --- a/tests/utils.test.ts +++ b/tests/utils.test.ts @@ -31,15 +31,8 @@ describe("parseIssueUrl", () => { expect(actual).toStrictEqual({ repoOwner: "actions", repoName: "setup-node", issueNumber: 5663 }); }); - it("parses correct issue url with task list marker", () => { - const actual = parseIssueUrl("- [ ] https://github.com/actions/setup-node/issues/5663"); - expect(actual).toStrictEqual({ repoOwner: "actions", repoName: "setup-node", issueNumber: 5663 }); - }); - - it("parses correct issue url if more than one issue in input line", () => { - const actual = parseIssueUrl( - "- [ ] https://github.com/actions/setup-node/issues/5663, https://github.com/actions/setup-node/issues/5665" - ); + it("parses correct issue url with trailing spaces", () => { + const actual = parseIssueUrl(" https://github.com/actions/setup-node/issues/5663"); expect(actual).toStrictEqual({ repoOwner: "actions", repoName: "setup-node", issueNumber: 5663 }); });