Skip to content

Commit 58ad646

Browse files
committed
improve rendering of links, add additional checks
1 parent 40cbdd9 commit 58ad646

File tree

6 files changed

+40
-27
lines changed

6 files changed

+40
-27
lines changed

dist/index.js

+18-8
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ class IssueContentParser {
169169
const contentLines = issue.body?.split("\n") ?? [];
170170
return contentLines
171171
.filter(x => this.isTaskListLine(x))
172+
.map(x => x.substring(6))
172173
.map(x => (0, utils_1.parseIssueUrl)(x))
173174
.filter((x) => x !== null);
174175
}
@@ -194,6 +195,9 @@ class IssueContentParser {
194195
...contentLines.slice(sectionEndIndex !== -1 ? sectionEndIndex : contentLines.length),
195196
].join("\n");
196197
}
198+
isIssueClosed(issue) {
199+
return issue.state === "closed";
200+
}
197201
isIssueContentIdentical(issue, newIssueContent) {
198202
// GitHub automatically replace "\n" to "\r\n" line endings when issue body is modified through GitHub UI.
199203
// Replace "\r\n" to "\n" before comparing content to avoid unnecessary issue updates.
@@ -272,8 +276,16 @@ const run = async () => {
272276
const issueContentParser = new issue_content_parser_1.IssueContentParser();
273277
const mermaidRender = new mermaid_render_1.MermaidRender(inputs.includeLegend);
274278
const rootIssue = await githubApiClient.getIssue(inputs.rootIssue);
279+
if (issueContentParser.isIssueClosed(rootIssue)) {
280+
core.info("Skipping generation of mermaid diagram because issue is closed");
281+
return;
282+
}
275283
const rootIssueTasklist = issueContentParser.extractIssueTasklist(rootIssue);
276284
core.info(`Found ${rootIssueTasklist.length} work items in task list.`);
285+
if (rootIssueTasklist.length === 0) {
286+
core.info("Skipping generation of mermaid diagram because there is no issues in tasklist");
287+
return;
288+
}
277289
core.info("Building dependency graph...");
278290
const graphBuilder = new graph_builder_1.GraphBuilder(inputs.includeFinishNode);
279291
for (const issueRef of rootIssueTasklist) {
@@ -435,11 +447,9 @@ ${renderedGraphIssues}
435447
`;
436448
}
437449
renderIssue(issue) {
438-
let result = `${issue.nodeId}("${issue.getWrappedTitle()}"):::${issue.status};`;
439-
if (issue.url) {
440-
result += `\nclick ${issue.nodeId} href "${issue.url}" _blank;`;
441-
}
442-
return result;
450+
const title = issue.getWrappedTitle();
451+
const linkedTitle = issue.url ? `<a href='${issue.url}' style='text-decoration:none;color: inherit;'>${title}</a>` : title;
452+
return `${issue.nodeId}("${linkedTitle}"):::${issue.status};`;
443453
}
444454
renderDependencies(dependencies) {
445455
const renderedDependencies = dependencies.map(x => this.renderDependency(x)).join("\n");
@@ -467,10 +477,10 @@ exports.MermaidRender = MermaidRender;
467477

468478
Object.defineProperty(exports, "__esModule", ({ value: true }));
469479
exports.parseIssuesUrls = exports.parseIssueUrl = void 0;
470-
const issueUrlRegex = /github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/i;
471-
const issueUrlsRegex = new RegExp(issueUrlRegex, "ig");
480+
const issueUrlRegex = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)$/i;
481+
const issueUrlsRegex = /github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/gi;
472482
const parseIssueUrl = (str) => {
473-
const found = str.match(issueUrlRegex);
483+
const found = str.trim().match(issueUrlRegex);
474484
if (!found) {
475485
return null;
476486
}

src/issue-content-parser.ts

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export class IssueContentParser {
77

88
return contentLines
99
.filter(x => this.isTaskListLine(x))
10+
.map(x => x.substring(6))
1011
.map(x => parseIssueUrl(x))
1112
.filter((x): x is GitHubIssueReference => x !== null);
1213
}
@@ -41,6 +42,10 @@ export class IssueContentParser {
4142
].join("\n");
4243
}
4344

45+
public isIssueClosed(issue: GitHubIssue): boolean {
46+
return issue.state === "closed";
47+
}
48+
4449
public isIssueContentIdentical(issue: GitHubIssue, newIssueContent: string) {
4550
// GitHub automatically replace "\n" to "\r\n" line endings when issue body is modified through GitHub UI.
4651
// Replace "\r\n" to "\n" before comparing content to avoid unnecessary issue updates.

src/main.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,17 @@ const run = async (): Promise<void> => {
1414
const mermaidRender = new MermaidRender(inputs.includeLegend);
1515

1616
const rootIssue = await githubApiClient.getIssue(inputs.rootIssue);
17-
const rootIssueTasklist = issueContentParser.extractIssueTasklist(rootIssue);
17+
if (issueContentParser.isIssueClosed(rootIssue)) {
18+
core.info("Skipping generation of mermaid diagram because issue is closed");
19+
return;
20+
}
1821

22+
const rootIssueTasklist = issueContentParser.extractIssueTasklist(rootIssue);
1923
core.info(`Found ${rootIssueTasklist.length} work items in task list.`);
24+
if (rootIssueTasklist.length === 0) {
25+
core.info("Skipping generation of mermaid diagram because there is no issues in tasklist");
26+
return;
27+
}
2028

2129
core.info("Building dependency graph...");
2230
const graphBuilder = new GraphBuilder(inputs.includeFinishNode);

src/mermaid-render.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,9 @@ ${renderedGraphIssues}
6161
}
6262

6363
private renderIssue(issue: MermaidNode): string {
64-
let result = `${issue.nodeId}("${issue.getWrappedTitle()}"):::${issue.status};`;
65-
if (issue.url) {
66-
result += `\nclick ${issue.nodeId} href "${issue.url}" _blank;`;
67-
}
68-
69-
return result;
64+
const title = issue.getWrappedTitle();
65+
const linkedTitle = issue.url ? `<a href='${issue.url}' style='text-decoration:none;color: inherit;'>${title}</a>` : title;
66+
return `${issue.nodeId}("${linkedTitle}"):::${issue.status};`;
7067
}
7168

7269
private renderDependencies(dependencies: GraphEdge[]): string {

src/utils.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import { GitHubIssueReference } from "./models";
33
// Analogue of TypeScript "Partial" type but for null values
44
export type NullablePartial<T> = { [P in keyof T]: T[P] | null | undefined };
55

6-
const issueUrlRegex = /github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/i;
7-
const issueUrlsRegex = new RegExp(issueUrlRegex, "ig");
6+
const issueUrlRegex = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)$/i;
7+
const issueUrlsRegex = /github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/gi;
88

99
export const parseIssueUrl = (str: string): GitHubIssueReference | null => {
10-
const found = str.match(issueUrlRegex);
10+
const found = str.trim().match(issueUrlRegex);
1111
if (!found) {
1212
return null;
1313
}

tests/utils.test.ts

+2-9
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,8 @@ describe("parseIssueUrl", () => {
3131
expect(actual).toStrictEqual({ repoOwner: "actions", repoName: "setup-node", issueNumber: 5663 });
3232
});
3333

34-
it("parses correct issue url with task list marker", () => {
35-
const actual = parseIssueUrl("- [ ] https://github.com/actions/setup-node/issues/5663");
36-
expect(actual).toStrictEqual({ repoOwner: "actions", repoName: "setup-node", issueNumber: 5663 });
37-
});
38-
39-
it("parses correct issue url if more than one issue in input line", () => {
40-
const actual = parseIssueUrl(
41-
"- [ ] https://github.com/actions/setup-node/issues/5663, https://github.com/actions/setup-node/issues/5665"
42-
);
34+
it("parses correct issue url with trailing spaces", () => {
35+
const actual = parseIssueUrl(" https://github.com/actions/setup-node/issues/5663");
4336
expect(actual).toStrictEqual({ repoOwner: "actions", repoName: "setup-node", issueNumber: 5663 });
4437
});
4538

0 commit comments

Comments
 (0)