Skip to content

Commit 9bc19d7

Browse files
authored
feat(duplicates): edit existing issues (#201)
1 parent 666c591 commit 9bc19d7

File tree

3 files changed

+96
-18
lines changed

3 files changed

+96
-18
lines changed

create-node-meeting-artifacts.mjs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -78,20 +78,6 @@ const meetingTitle = meetings.generateMeetingTitle(
7878
meetingDate
7979
);
8080

81-
// Look for existing issues
82-
if (!config.force) {
83-
const existingIssue = await github.findIssueByTitle(
84-
githubClient,
85-
meetingTitle,
86-
meetingConfig
87-
);
88-
89-
if (existingIssue) {
90-
console.log(`${existingIssue.html_url} already exists. Exiting.`);
91-
process.exit(0);
92-
}
93-
}
94-
9581
// Step 9: Get agenda information using native implementation
9682
const gitHubAgendaIssues = await github.getAgendaIssues(
9783
githubClient,
@@ -103,10 +89,10 @@ const gitHubAgendaIssues = await github.getAgendaIssues(
10389
const meetingAgenda = meetings.generateMeetingAgenda(gitHubAgendaIssues);
10490

10591
// Step 11: Create HackMD document with meeting notes and tags
106-
const hackmdNote = await hackmd.createMeetingNotesDocument(
92+
const hackmdNote = await hackmd.getOrCreateMeetingNotesDocument(
10793
hackmdClient,
10894
meetingTitle,
109-
''
95+
config
11096
);
11197

11298
// Step 12: Get the HackMD document link
@@ -123,8 +109,9 @@ const issueContent = await meetings.generateMeetingIssue(
123109
);
124110

125111
// Step 14: Create GitHub issue with HackMD link
126-
const githubIssue = await github.createGitHubIssue(
112+
const githubIssue = await github.createOrUpdateGitHubIssue(
127113
githubClient,
114+
config,
128115
meetingConfig,
129116
meetingTitle,
130117
issueContent

src/github.mjs

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,46 @@ export const createGitHubIssue = async (
4242
return response.data;
4343
};
4444

45+
/**
46+
* Creates or updates a GitHub issue with meeting information and Google Doc link
47+
* @param {import('@octokit/rest').Octokit} githubClient - Authenticated GitHub API client
48+
* @param {import('./types.d.ts').AppConfig} config - The application config
49+
* @param {import('./types.d.ts').MeetingConfig} meetingConfig - Meeting configuration object
50+
* @param {string} title - Issue title
51+
* @param {string} content - Issue content
52+
* @returns {Promise<GitHubIssue>} Created issue data
53+
*/
54+
export const createOrUpdateGitHubIssue = async (
55+
githubClient,
56+
{ force },
57+
meetingConfig,
58+
title,
59+
content
60+
) => {
61+
if (!force) {
62+
const existingIssue = await findGitHubIssueByTitle(
63+
githubClient,
64+
title,
65+
meetingConfig
66+
);
67+
68+
if (existingIssue) {
69+
if (content !== existingIssue.body) {
70+
await updateGitHubIssue(
71+
githubClient,
72+
existingIssue.number,
73+
content,
74+
meetingConfig
75+
);
76+
}
77+
78+
return existingIssue;
79+
}
80+
}
81+
82+
return createGitHubIssue(githubClient, meetingConfig, title, content);
83+
};
84+
4585
/**
4686
* Sorts issues by repository
4787
* @param {Array<GitHubIssue>} issues The issues to sort
@@ -55,13 +95,40 @@ export const sortIssuesByRepo = issues =>
5595
return obj;
5696
}, {});
5797

98+
/**
99+
* Updates an existing GitHub issue with new content
100+
* @param {import('@octokit/rest').Octokit} githubClient - Authenticated GitHub API client
101+
* @param {number} number - The issue number
102+
* @param {string} content - The new content
103+
* @param {import('./types.d.ts').MeetingConfig} meetingConfig - Meeting configuration
104+
*/
105+
export const updateGitHubIssue = async (
106+
githubClient,
107+
number,
108+
content,
109+
{ properties }
110+
) => {
111+
const githubOrg = properties.USER ?? DEFAULT_CONFIG.githubOrg;
112+
113+
return githubClient.issues.update({
114+
issue_number: number,
115+
body: content,
116+
owner: githubOrg,
117+
repo: properties.REPO,
118+
});
119+
};
120+
58121
/**
59122
* Fetches GitHub issue from a repo with a given title
60123
* @param {import('@octokit/rest').Octokit} githubClient - Authenticated GitHub API client
61124
* @param {string} title - The title to find
62125
* @param {import('./types.d.ts').MeetingConfig} meetingConfig - Meeting configuration
63126
*/
64-
export const findIssueByTitle = async (githubClient, title, { properties }) => {
127+
export const findGitHubIssueByTitle = async (
128+
githubClient,
129+
title,
130+
{ properties }
131+
) => {
65132
const githubOrg = properties.USER ?? DEFAULT_CONFIG.githubOrg;
66133

67134
const issues = await githubClient.request('GET /search/issues', {

src/hackmd.mjs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,30 @@ export const createMeetingNotesDocument = (hackmdClient, title, content) => {
4040
.then(response => response?.note ?? response);
4141
};
4242

43+
/**
44+
* Creates a new meeting notes document in HackMD with appropriate tags
45+
* @param {HackMDAPI} hackmdClient - HackMD API client
46+
* @param {string} title - Document title
47+
* @param {import('./types.d.ts').AppConfig} config - Configuration
48+
* @returns {Promise<HackMDNote>} The created / fetched note
49+
*/
50+
export const getOrCreateMeetingNotesDocument = async (
51+
hackmdClient,
52+
title,
53+
{ force }
54+
) => {
55+
if (!force) {
56+
const notes = await hackmdClient.getNoteList();
57+
const existingNote = notes.find(note => note.title === title);
58+
59+
if (existingNote) {
60+
return existingNote;
61+
}
62+
}
63+
64+
return createMeetingNotesDocument(hackmdClient, title, '');
65+
};
66+
4367
/**
4468
* Updates an existing meeting notes document in HackMD with retry logic
4569
* @param {HackMDClient} hackmdClient - HackMD API client

0 commit comments

Comments
 (0)