Skip to content

Commit 464a313

Browse files
authored
add retry logic to the action (#5)
1 parent 0496e14 commit 464a313

7 files changed

Lines changed: 96 additions & 25 deletions

File tree

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,23 @@ jobs:
4848
skip-labels: "wip,do-not-merge"
4949
```
5050
51+
### Enqueue Retry Options
52+
53+
Sometimes, the pull request check runs haven't finished yet, so the action will retry the enqueue after some time. You can control this behavior with the following options:
54+
55+
- `enqueue-retries`: Number of times to retry enqueuing if it fails. Default is 6. Set to 0 to disable retry logic.
56+
- `enqueue-retry-sleep`: Time (in milliseconds) to sleep between retries. Default is 5000 (5 seconds). Set to 0 to disable sleeping between retries.
57+
58+
Example usage:
59+
60+
```yaml
61+
- uses: waheedahmed/enqueue-pullrequest@v1
62+
with:
63+
github-token: ${{ secrets.GITHUB_TOKEN }}
64+
enqueue-retries: 8
65+
enqueue-retry-sleep: 7000
66+
```
67+
5168
Then add the `enqueue-pullrequest` label to any PR you want automatically enqueued once it's ready.
5269

5370
To process only PRs from a specific branch (useful for `schedule` or `workflow_dispatch` triggers), set `branch`:
@@ -80,6 +97,8 @@ To enqueue **all** open PRs without requiring a label, set `label` to an empty s
8097
| `base-branches` | Comma-separated list of allowed base branches. Empty = all branches. | `""` |
8198
| `skip-drafts` | Skip draft pull requests. | `true` |
8299
| `required-approvals` | Minimum approving reviews before enqueuing. `0` = rely on branch protection rules. | `0` |
100+
| `enqueue-retries` | Number of times to retry enqueuing if it fails. | `6` |
101+
| `enqueue-retry-sleep` | Time (in milliseconds) to sleep between retries. | `5000` |
83102

84103
## Token permissions
85104

action.yml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ inputs:
3131
skip-labels:
3232
description: >
3333
Comma-separated list of labels that prevent a PR from being added to the
34-
merge queue (e.g. "wip, do-not-merge, blocked").
34+
merge queue (e.g. "wip, do-not-enqueue, blocked").
3535
required: false
3636
default: ""
3737

@@ -54,8 +54,20 @@ inputs:
5454
required: false
5555
default: "0"
5656

57+
enqueue-retries:
58+
description: >
59+
Number of times to retry enqueuing if it fails. Default is 6. Set to 0 to disable retry logic.
60+
required: false
61+
default: "6"
62+
63+
enqueue-retry-sleep:
64+
description: >
65+
Time (in milliseconds) to sleep between retries. Default is 5000 (5 seconds). Set to 0 to disable sleeping between retries.
66+
required: false
67+
default: "5000"
68+
5769
runs:
58-
using: "node20"
70+
using: "node22"
5971
main: "dist/index.js"
6072

6173
branding:

dist/index.js

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29949,6 +29949,8 @@ function getConfig() {
2994929949
.filter(Boolean),
2995029950
skipDrafts: core.getInput("skip-drafts") !== "false",
2995129951
requiredApprovals: parseInt(core.getInput("required-approvals"), 10) || 0,
29952+
enqueueRetries: parseInt(core.getInput("enqueue-retries"), 10),
29953+
enqueueRetrySleep: parseInt(core.getInput("enqueue-retry-sleep"), 10),
2995229954
};
2995329955
}
2995429956

@@ -30122,17 +30124,34 @@ async function processPR(octokit, owner, repo, prNumber, config) {
3012230124

3012330125
core.info("Adding to merge queue…");
3012430126

30125-
try {
30126-
const entry = await enqueue(octokit, pr.id);
30127-
if (entry) {
30128-
core.info(
30129-
`Added to merge queue: position=${entry.position}, state=${entry.state}`
30130-
);
30131-
} else {
30132-
core.info("Added to merge queue (no entry details returned)");
30127+
// Retry logic for enqueue
30128+
const maxRetries = typeof config.enqueueRetries === 'number' && !isNaN(config.enqueueRetries) ? config.enqueueRetries : 6;
30129+
const retrySleep = typeof config.enqueueRetrySleep === 'number' && !isNaN(config.enqueueRetrySleep) ? config.enqueueRetrySleep : 5000;
30130+
30131+
let attempt = 0;
30132+
while (attempt <= maxRetries) {
30133+
try {
30134+
const entry = await enqueue(octokit, pr.id);
30135+
if (entry) {
30136+
core.info(
30137+
`Added to merge queue: position=${entry.position}, state=${entry.state}`
30138+
);
30139+
} else {
30140+
core.info("Added to merge queue (no entry details returned)");
30141+
}
30142+
return;
30143+
} catch (err) {
30144+
if (maxRetries === 0 || attempt === maxRetries) {
30145+
core.setFailed(`Failed to enqueue PR #${prNumber}: ${err.message}`);
30146+
return;
30147+
}
30148+
core.warning(`Enqueue failed (attempt ${attempt + 1}/${maxRetries + 1}): ${err.message}`);
30149+
if (retrySleep > 0) {
30150+
core.info(`Sleeping for ${retrySleep}ms before retrying…`);
30151+
await new Promise((resolve) => setTimeout(resolve, retrySleep));
30152+
}
3013330153
}
30134-
} catch (err) {
30135-
core.setFailed(`Failed to enqueue PR #${prNumber}: ${err.message}`);
30154+
attempt++;
3013630155
}
3013730156
}
3013830157

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "enqueue-pullrequest",
3-
"version": "0.0.1",
3+
"version": "0.0.5",
44
"description": "GitHub Action to automatically enqueue pull requests into GitHub's native merge queue",
55
"main": "dist/index.js",
66
"scripts": {

src/__tests__/index.test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ describe("enqueue-pullrequest action", () => {
5050
"base-branches": "",
5151
"skip-drafts": "true",
5252
"required-approvals": "0",
53+
"enqueue-retries": "0",
54+
"enqueue-retry-sleep": "0",
5355
};
5456
jest.spyOn(core, "getInput").mockImplementation(
5557
(name) => ({ ...defaults, ...overrides }[name] ?? "")

src/api.js

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ function getConfig() {
2121
.filter(Boolean),
2222
skipDrafts: core.getInput("skip-drafts") !== "false",
2323
requiredApprovals: parseInt(core.getInput("required-approvals"), 10) || 0,
24+
enqueueRetries: parseInt(core.getInput("enqueue-retries"), 10),
25+
enqueueRetrySleep: parseInt(core.getInput("enqueue-retry-sleep"), 10),
2426
};
2527
}
2628

@@ -194,17 +196,34 @@ async function processPR(octokit, owner, repo, prNumber, config) {
194196

195197
core.info("Adding to merge queue…");
196198

197-
try {
198-
const entry = await enqueue(octokit, pr.id);
199-
if (entry) {
200-
core.info(
201-
`Added to merge queue: position=${entry.position}, state=${entry.state}`
202-
);
203-
} else {
204-
core.info("Added to merge queue (no entry details returned)");
199+
// Retry logic for enqueue
200+
const maxRetries = typeof config.enqueueRetries === 'number' && !isNaN(config.enqueueRetries) ? config.enqueueRetries : 6;
201+
const retrySleep = typeof config.enqueueRetrySleep === 'number' && !isNaN(config.enqueueRetrySleep) ? config.enqueueRetrySleep : 5000;
202+
203+
let attempt = 0;
204+
while (attempt <= maxRetries) {
205+
try {
206+
const entry = await enqueue(octokit, pr.id);
207+
if (entry) {
208+
core.info(
209+
`Added to merge queue: position=${entry.position}, state=${entry.state}`
210+
);
211+
} else {
212+
core.info("Added to merge queue (no entry details returned)");
213+
}
214+
return;
215+
} catch (err) {
216+
if (maxRetries === 0 || attempt === maxRetries) {
217+
core.setFailed(`Failed to enqueue PR #${prNumber}: ${err.message}`);
218+
return;
219+
}
220+
core.warning(`Enqueue failed (attempt ${attempt + 1}/${maxRetries + 1}): ${err.message}`);
221+
if (retrySleep > 0) {
222+
core.info(`Sleeping for ${retrySleep}ms before retrying…`);
223+
await new Promise((resolve) => setTimeout(resolve, retrySleep));
224+
}
205225
}
206-
} catch (err) {
207-
core.setFailed(`Failed to enqueue PR #${prNumber}: ${err.message}`);
226+
attempt++;
208227
}
209228
}
210229

0 commit comments

Comments
 (0)