Skip to content

Commit 6b17302

Browse files
authored
fix: increase label retry window to prevent race condition with opened-event required-label checks (#28896)
1 parent 15b767a commit 6b17302

2 files changed

Lines changed: 11 additions & 6 deletions

File tree

actions/setup/js/create_pull_request.cjs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,11 @@ function isLabelTransientError(error) {
8686
}
8787

8888
/** @type {number} Number of retry attempts for label operations */
89-
const LABEL_MAX_RETRIES = 3;
90-
/** @type {number} Initial delay in ms before the first label retry (3 seconds) */
89+
const LABEL_MAX_RETRIES = 5;
90+
/** @type {number} Base delay in ms used to calculate label retry backoff (3 seconds) */
9191
const LABEL_INITIAL_DELAY_MS = 3000;
92+
/** @type {number} Maximum delay in ms between label retries (30 seconds) */
93+
const LABEL_MAX_DELAY_MS = 30000;
9294

9395
/**
9496
* Parse allowed base branch patterns from config value (array or comma-separated string)
@@ -1694,6 +1696,7 @@ ${patchPreview}`;
16941696
{
16951697
maxRetries: LABEL_MAX_RETRIES,
16961698
initialDelayMs: LABEL_INITIAL_DELAY_MS,
1699+
maxDelayMs: LABEL_MAX_DELAY_MS,
16971700
backoffMultiplier: 2,
16981701
shouldRetry: isLabelTransientError,
16991702
},
@@ -1704,6 +1707,8 @@ ${patchPreview}`;
17041707
// Label addition is non-critical - warn but don't fail the PR creation.
17051708
// GitHub's API may transiently fail to resolve the PR node ID immediately
17061709
// after creation, which causes label operations to fail with an unprocessable error.
1710+
// If this warning appears, repository checks that require labels on the opened event
1711+
// may fail transiently; consider triggering required-label checks on the labeled event instead.
17071712
core.warning(`Failed to add labels to PR #${pullRequest.number}: ${labelError instanceof Error ? labelError.message : String(labelError)}`);
17081713
}
17091714
}

actions/setup/js/create_pull_request.test.cjs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,7 +1181,7 @@ describe("create_pull_request - configured reviewers", () => {
11811181

11821182
it("should retry addLabels on race condition and warn after all retries exhausted", async () => {
11831183
// GitHub API transiently fails to resolve the PR node ID immediately after creation.
1184-
// withRetry retries 3 times (4 total calls); after exhaustion it should warn but NOT fall back to an issue.
1184+
// withRetry retries 5 times (6 total calls); after exhaustion it should warn but NOT fall back to an issue.
11851185
vi.useFakeTimers();
11861186
try {
11871187
global.github.rest.issues.addLabels.mockRejectedValue(new Error("Validation Failed: Could not resolve to a node with the global id of 'PR_kwDOPc1QR87OOJzM'."));
@@ -1191,15 +1191,15 @@ describe("create_pull_request - configured reviewers", () => {
11911191

11921192
const resultPromise = handler({ title: "Test PR", body: "Test body", labels: ["automation"] }, {});
11931193

1194-
// Advance all fake timers to skip the retry delays (3s, 6s, 12s)
1194+
// Advance all fake timers to skip the retry delays (6s, 12s, 24s, 30s, 30s)
11951195
await vi.runAllTimersAsync();
11961196

11971197
const result = await resultPromise;
11981198

11991199
expect(result.success).toBe(true);
12001200
expect(result.fallback_used).toBeUndefined();
1201-
// addLabels called once initially + 3 retries = 4 total
1202-
expect(global.github.rest.issues.addLabels).toHaveBeenCalledTimes(4);
1201+
// addLabels called once initially + 5 retries = 6 total
1202+
expect(global.github.rest.issues.addLabels).toHaveBeenCalledTimes(6);
12031203
expect(global.core.warning).toHaveBeenCalledWith(expect.stringContaining("Failed to add labels to PR #42"));
12041204
} finally {
12051205
vi.useRealTimers();

0 commit comments

Comments
 (0)