-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.ts
244 lines (234 loc) · 11.5 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
// import octokit
import * as core from '@actions/core';
import * as github from "@actions/github";
import { Octokit } from "octokit";
import { Issue, IssueComment } from "./issue";
import { IssueSyncer } from './issueSyncer';
import { LabelSyncer } from "./labelSyncer";
// use label from ./Label.ts
let owner_source = "";
let repo_source = "";
let owner_target = "";
let repo_target = "";
let source_pat = core.getInput("source_pat") || process.env.GITHUB_TOKEN;
let target_pat = core.getInput("target_pat") || source_pat;
let source_url = core.getInput("source_url") || "api.github.com";
let target_url = core.getInput("target_url") || source_url;
let ONLY_SYNC_ON_LABEL: string;
// Determine which context we are running from
if (process.env.CI == "true") {
console.log("Reading params from actions context...");
// Read source and target repos
repo_source = core.getInput("source_repo")? core.getInput("source_repo") : github.context.repo.owner + '/' + github.context.repo.repo;
owner_source = repo_source.split('/')[0];
repo_source = repo_source.split('/')[1];
repo_target = core.getInput("target_repo");
owner_target = repo_target.split('/')[0];
repo_target = repo_target.split('/')[1];
// Read params
ONLY_SYNC_ON_LABEL = core.getInput("only_sync_on_label");
console.log("Repos: " + owner_source + "/" + repo_source + " -> " + owner_target + "/" + repo_target);
console.log("Only sync on label: " + ONLY_SYNC_ON_LABEL);
console.log("Do not sync comments: " + core.getBooleanInput("only_sync_main_issue"));
} else {
console.log("Reading params from CLI context...");
// read all variables from launch parameters
const launchArgs = process.argv;
for (let i = 0; i < launchArgs.length; i++) {
if (launchArgs[i] === "--source_owner") {
owner_source = launchArgs[i + 1];
} else if (launchArgs[i] === "--source_repo") {
repo_source = launchArgs[i + 1];
} else if (launchArgs[i] === "--target_owner") {
owner_target = launchArgs[i + 1];
} else if (launchArgs[i] === "--target_repo") {
repo_target = launchArgs[i + 1];
} else if (launchArgs[i] === "--source_pat") {
source_pat = launchArgs[i + 1];
} else if (launchArgs[i] === "--target_pat") {
target_pat = launchArgs[i + 1];
} else if (launchArgs[i] === "--source_url") {
source_url = launchArgs[i + 1];
} else if (launchArgs[i] === "--target_url") {
target_url = launchArgs[i + 1];
}
}
}
// Init octokit for source and target
const octokit_source = new Octokit({
auth: source_pat,
baseUrl: `https://${source_url}`
});
const octokit_target = new Octokit({
auth: target_pat,
baseUrl: `https://${target_url}`
});
LabelSyncer.syncLabels(
octokit_source,
octokit_target,
owner_source,
repo_source,
owner_target,
repo_target
).then(() => console.log("Successfully synced labels")
).then(() => {
const payload = require(process.env.GITHUB_EVENT_PATH as string);
const number = (payload.issue || payload.pull_request || payload).number;
// retrieve issue by owner, repo and number from octokit_source
octokit_source.request('GET /repos/{owner}/{repo}/issues/{number}', {
owner: owner_source,
repo: repo_source,
number: number,
}).then((response) => {
// Retrieved issue
const issue: Issue = response.data;
console.log("Found issue:", issue.title);
console.log("Labels:", issue.labels.map(label => label.name));
// If flag for only syncing labelled issues is set, check if issue has label of specified sync type
if (ONLY_SYNC_ON_LABEL && !issue.labels.find(label => label.name === ONLY_SYNC_ON_LABEL))
return;
switch (process.env.GITHUB_EVENT_NAME) {
case "issue_comment":
// If flag for only syncing issue bodies is set and skip if true
if (core.getBooleanInput("only_sync_main_issue"))
return;
if (payload.action !== "created") {
console.warn("This will only sync new comments, events of current type are ignored", payload.action);
return;
}
// Retrieve new comment
let issueComment: IssueComment;
octokit_source.request('GET /repos/{owner}/{repo}/issues/comments/{comment_id}', {
owner: owner_source,
repo: repo_source,
issue_number: number,
comment_id: payload.comment.id,
}).then((response) => {
issueComment = response.data;
IssueSyncer.getIssueNumberByTitle(
octokit_target,
owner_target,
repo_target,
issue.title
).then((targetIssueNumber) => {
// Transfer new comment to target issue
octokit_target.request('POST /repos/{owner}/{repo}/issues/{issue_number}/comments', {
owner: owner_target,
repo: repo_target,
issue_number: targetIssueNumber,
body: issueComment.body || "",
}).then(() => {
console.info("Successfully created new comment on issue");
}).catch((err) => {
let msg = "Failed to create new comment on issue";
console.error(msg, err);
core.setFailed(msg + " ${err}");
})
});
}).catch((err) => {
let msg = "Failed to retrieve issue comments"
console.error(msg, err);
core.setFailed(msg + " ${err}");
});
break;
case "issues":
// If the issue was updated, we need to sync labels
switch(payload.action) {
case "opened":
// Create new issue in target repo
octokit_target.request('POST /repos/{owner}/{repo}/issues', {
owner: owner_target,
repo: repo_target,
title: issue.title,
body: issue.body,
labels: issue.labels.map(label => label.name),
})
.then((response) => {
console.log("Created issue:", response.data.title);
// Add comment to source issue for tracking
octokit_source.request('PATCH /repos/{owner}/{repo}/issues/{issue_number}', {
owner: owner_source,
repo: repo_source,
issue_number: number,
body: issue.body + "\n\nNote: This issue has been copied to " + response.data.html_url + " !",
}).then(() => {
console.info("Successfully created comment on issue");
}).catch((err) => {
let msg = "Failed to create comment on issue";
console.error(msg, err);
core.setFailed(msg + " ${err}");
});
}).catch((error) => {
let msg = "Error creating issue:"
console.error(msg, error);
core.setFailed(msg + " ${error}");
});
break;
case "edited":
case "closed":
case "reopened":
case "labeled":
case "unlabeled":
// Find issue number from target repo where the issue title matches the title of the issue in the source repo
octokit_target.request('GET /repos/{owner}/{repo}/issues', {
owner: owner_target,
repo: repo_target,
filter: "all",
state: "all",
title: issue.title,
}).then((response) => {
// Found issue in target repo
const targetIssue = response.data.find(targetIssue => targetIssue.title === issue.title);
if (targetIssue) {
// Update issue in target repo
// Update issue in target repo, identify target repo issue number by title match
octokit_target.request('PATCH /repos/{owner}/{repo}/issues/{issue_number}', {
owner: owner_target,
repo: repo_target,
title: issue.title,
body: issue.body,
state: issue.state,
issue_number: targetIssue.number,
labels: issue.labels.map(label => label.name),
})
.then((response) => {
console.log("Updated issue:", response.data.title);
}).catch((error) => {
console.error("Error updating issue:", error);
});
} else {
console.error("Could not find matching issue in target repo for title", issue.title);
// Create issue anew
octokit_target.request('POST /repos/{owner}/{repo}/issues', {
owner: owner_target,
repo: repo_target,
title: issue.title,
body: issue.body,
labels: issue.labels.map(label => label.name),
}).then((response) => {
console.log("Created issue for lack of a match:", response.data.title);
}).catch((error) => {
let msg = "Error creating issue for lack of a match:"
console.error(msg, error);
core.setFailed(msg + " ${error}");
});
}
}).catch((error) => {
let msg = "Error finding issue in target repo:";
console.error(msg, error);
core.setFailed(msg + " ${error}");
});
break;
default:
console.log("We are currently not handling events of type " + payload.action);
break;
}
break;
default:
break;
}
}).catch((err) => {
console.error("Failed to retrieve issue", err);
core.setFailed("Failed to retrieve issue ${err}");
});
});