@@ -255,33 +255,53 @@ class Backport {
255
255
console.info(`Push branch to ${this.getRemote()}`);
256
256
const pushExitCode = await this.git.push(branchname, this.getRemote(), this.config.pwd);
257
257
if (pushExitCode != 0) {
258
- const message = this.composeMessageForGitPushFailure(target, pushExitCode);
259
- console.error(message);
260
- successByTarget.set(target, false);
261
- await this.github.createComment({
262
- owner: workflowOwner,
263
- repo: workflowRepo,
264
- issue_number: pull_number,
265
- body: message,
266
- });
267
- continue;
258
+ try {
259
+ // If the branch already exists, ignore the error and keep going.
260
+ console.info(`Branch ${branchname} may already exist, fetching it instead to recover previous run`);
261
+ await this.git.fetch(branchname, this.config.pwd, 1, this.getRemote());
262
+ console.info(`Previous branch successfully recovered, retrying PR creation`);
263
+ // note that the recovered branch is not guaranteed to be up-to-date
264
+ }
265
+ catch {
266
+ // Fetching the branch failed as well, so report the original push error.
267
+ const message = this.composeMessageForGitPushFailure(target, pushExitCode);
268
+ console.error(message);
269
+ successByTarget.set(target, false);
270
+ await this.github.createComment({
271
+ owner: workflowOwner,
272
+ repo: workflowRepo,
273
+ issue_number: pull_number,
274
+ body: message,
275
+ });
276
+ continue;
277
+ }
268
278
}
269
279
console.info(`Create PR for ${branchname}`);
270
280
const { title, body } = this.composePRContent(target, mainpr);
271
- const new_pr_response = await this.github.createPR({
272
- owner,
273
- repo,
274
- title,
275
- body,
276
- head: branchname,
277
- base: target,
278
- maintainer_can_modify: true,
279
- draft: uncommitedShas !== null,
280
- });
281
- if (new_pr_response.status != 201) {
282
- console.error(JSON.stringify(new_pr_response));
281
+ let new_pr_response;
282
+ try {
283
+ new_pr_response = await this.github.createPR({
284
+ owner,
285
+ repo,
286
+ title,
287
+ body,
288
+ head: branchname,
289
+ base: target,
290
+ maintainer_can_modify: true,
291
+ draft: uncommitedShas !== null,
292
+ });
293
+ }
294
+ catch (error) {
295
+ if (!(error instanceof github_1.RequestError))
296
+ throw error;
297
+ if (error.status == 422 &&
298
+ (error.response?.data).errors.some((err) => err.message.startsWith("A pull request already exists for "))) {
299
+ console.info(`PR for ${branchname} already exists, skipping.`);
300
+ continue;
301
+ }
302
+ console.error(JSON.stringify(error.response?.data));
283
303
successByTarget.set(target, false);
284
- const message = this.composeMessageForCreatePRFailed(new_pr_response );
304
+ const message = this.composeMessageForCreatePRFailed(error );
285
305
await this.github.createComment({
286
306
owner: workflowOwner,
287
307
repo: workflowRepo,
@@ -295,22 +315,30 @@ class Backport {
295
315
const milestone = mainpr.milestone?.number;
296
316
if (milestone) {
297
317
console.info("Setting milestone to " + milestone);
298
- const set_milestone_response = await this.github.setMilestone(new_pr.number, milestone);
299
- if (set_milestone_response.status != 200) {
300
- console.error(JSON.stringify(set_milestone_response));
318
+ try {
319
+ await this.github.setMilestone(new_pr.number, milestone);
320
+ }
321
+ catch (error) {
322
+ if (!(error instanceof github_1.RequestError))
323
+ throw error;
324
+ console.error(JSON.stringify(error.response));
301
325
}
302
326
}
303
327
}
304
328
if (this.config.copy_assignees == true) {
305
329
const assignees = mainpr.assignees.map((label) => label.login);
306
330
if (assignees.length > 0) {
307
331
console.info("Setting assignees " + assignees);
308
- const add_assignee_response = await this.github.addAssignees(new_pr.number, assignees, {
309
- owner,
310
- repo,
311
- });
312
- if (add_assignee_response.status != 201) {
313
- console.error(JSON.stringify(add_assignee_response));
332
+ try {
333
+ await this.github.addAssignees(new_pr.number, assignees, {
334
+ owner,
335
+ repo,
336
+ });
337
+ }
338
+ catch (error) {
339
+ if (!(error instanceof github_1.RequestError))
340
+ throw error;
341
+ console.error(JSON.stringify(error.response));
314
342
}
315
343
}
316
344
}
@@ -324,9 +352,13 @@ class Backport {
324
352
pull_number: new_pr.number,
325
353
reviewers: reviewers,
326
354
};
327
- const set_reviewers_response = await this.github.requestReviewers(reviewRequest);
328
- if (set_reviewers_response.status != 201) {
329
- console.error(JSON.stringify(set_reviewers_response));
355
+ try {
356
+ await this.github.requestReviewers(reviewRequest);
357
+ }
358
+ catch (error) {
359
+ if (!(error instanceof github_1.RequestError))
360
+ throw error;
361
+ console.error(JSON.stringify(error.response));
330
362
}
331
363
}
332
364
}
@@ -335,24 +367,32 @@ class Backport {
335
367
...new Set([...labelsToCopy, ...this.config.add_labels]),
336
368
];
337
369
if (labels.length > 0) {
338
- const label_response = await this.github.labelPR(new_pr.number, labels, {
339
- owner,
340
- repo,
341
- });
342
- if (label_response.status != 200) {
343
- console.error(JSON.stringify(label_response));
370
+ try {
371
+ await this.github.labelPR(new_pr.number, labels, {
372
+ owner,
373
+ repo,
374
+ });
375
+ }
376
+ catch (error) {
377
+ if (!(error instanceof github_1.RequestError))
378
+ throw error;
379
+ console.error(JSON.stringify(error.response));
344
380
// The PR was still created so let's still comment on the original.
345
381
}
346
382
}
347
383
if (this.config.add_author_as_assignee == true) {
348
384
const author = mainpr.user.login;
349
385
console.info("Setting " + author + " as assignee");
350
- const add_assignee_response = await this.github.addAssignees(new_pr.number, [author], {
351
- owner,
352
- repo,
353
- });
354
- if (add_assignee_response.status != 201) {
355
- console.error(JSON.stringify(add_assignee_response));
386
+ try {
387
+ await this.github.addAssignees(new_pr.number, [author], {
388
+ owner,
389
+ repo,
390
+ });
391
+ }
392
+ catch (error) {
393
+ if (!(error instanceof github_1.RequestError))
394
+ throw error;
395
+ console.error(JSON.stringify(error.response));
356
396
}
357
397
}
358
398
// post success message to original pr
@@ -473,9 +513,9 @@ class Backport {
473
513
//TODO better error messages depending on exit code
474
514
return (0, dedent_1.default) `Git push to origin failed for ${target} with exitcode ${exitcode}`;
475
515
}
476
- composeMessageForCreatePRFailed(response ) {
516
+ composeMessageForCreatePRFailed(error ) {
477
517
return (0, dedent_1.default) `Backport branch created but failed to create PR.
478
- Request to create PR rejected with status ${response .status}.
518
+ Request to create PR rejected with status ${error .status}.
479
519
480
520
(see action log for full response)`;
481
521
}
@@ -738,8 +778,10 @@ var __importStar = (this && this.__importStar) || (function () {
738
778
};
739
779
})();
740
780
Object.defineProperty(exports, "__esModule", ({ value: true }));
741
- exports.MergeStrategy = exports.Github = void 0;
781
+ exports.MergeStrategy = exports.Github = exports.RequestError = void 0;
742
782
const github = __importStar(__nccwpck_require__(3228));
783
+ var request_error_1 = __nccwpck_require__(3708);
784
+ Object.defineProperty(exports, "RequestError", ({ enumerable: true, get: function () { return request_error_1.RequestError; } }));
743
785
class Github {
744
786
#octokit;
745
787
#context;
0 commit comments