Skip to content

Retry transient slash-command provenance checks - #59313

Merged
pelikhan merged 4 commits into
mainfrom
copilot/fix-pre-activation-error-handling
Sep 8, 2026
Merged

pelikhan merged 4 commits into
mainfrom
copilot/fix-pre-activation-error-handling

Conversation

Copilot AI commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

Centralized slash-command workflows treated transient GitHub API failures during PR provenance checks as authorization denials, silently skipping downstream execution and leaving status comments unresolved.

  • Retry transient failures
    • Wrap PR provenance lookup with the existing retry utility.
    • Retry 5xx, rate-limit, timeout, and network failures with bounded exponential backoff.
  • Preserve security behavior
    • Continue failing closed after retries are exhausted.
    • Do not retry permanent API failures or alter fork-provenance validation.
  • Regression coverage
    • Cover recovery from a transient 500 response.
    • Cover fail-closed behavior after retry exhaustion.

pr-sous-chef

Run: https://github.com/github/gh-aw/actions/runs/34178092363

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 31.2 AIC · ⌖ 8.62 AIC · ⊞ 9.2K · ◷
Comment /souschef to run again

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix pre_activation handling of transient GitHub API errors Retry transient slash-command provenance checks Sep 7, 2026
Copilot AI requested a review from pelikhan September 7, 2026 23:20
@pelikhan
pelikhan marked this pull request as ready for review September 8, 2026 01:35
Copilot AI balanced review requested due to automatic review settings September 8, 2026 01:35
@github-actions

github-actions Bot commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

✅ Ponytail Reviewer completed successfully!

Lean already. Ship.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • ab.chatgpt.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"

See Network Configuration for more information.

Generated by Ponytail Reviewer for #59313

@github-actions

github-actions Bot commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

✅ Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel analysis complete: 90/100 Excellent. 2 new tests (retry & provenance) with 100% design contract coverage and 100% error path testing. No violations.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See Network Configuration for more information.

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

✅ PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

✅ Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

No ADR enforcement needed: PR does not have the 'implementation' label and has <=100 new lines of code in business logic directories.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-09-08T01:39:02Z
review_event: COMMENT
top_themes:
  - no actionable blocking issues found
files_reviewed:
  - actions/setup/js/check_membership.cjs
  - actions/setup/js/check_membership.test.cjs
comment_count: 0

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 23.4 AIC · ⌖ 7.31 AIC · ⊞ 21.8K · ◷
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 23.4 AIC · ⌖ 7.31 AIC · ⊞ 21.8K
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /diagnosing-bugs — the fix is targeted (retries only transient 5xx/network/rate-limit failures via the existing withRetry/isTransientError utilities) and is backed by two focused regression tests covering both recovery and fail-closed-after-exhaustion.

📋 Key Themes & Highlights

Positive Highlights

  • ✅ Reuses the existing error_recovery.cjs retry utility instead of inventing bespoke retry logic, consistent with usage elsewhere in the codebase (add_labels.cjs, create_check_run.cjs).
  • ✅ shouldRetry correctly combines an explicit 5xx status check with isTransientError rather than retrying blindly, preserving fail-closed security semantics on permanent errors (404/403 without rate-limit headers, etc.).
  • ✅ Regression tests exercise both the happy recovery path (transient 500 then success) and the fail-closed path (exhausted retries → is_team_member: false, result: api_error) using fake timers, which is the right approach for testing backoff without slowing down the suite.

Minor Suggestion

  • One inline comment suggests adding a test for a permanent API failure (e.g. 404) to explicitly lock in the "do not retry permanent failures" claim from the PR description — currently only the transient path is asserted for retry count, so a regression that widens shouldRetry wouldn't be caught by these tests alone.

No blocking issues found.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 33.4 AIC · ⌖ 14.7 AIC · ⊞ 10.3K
Comment /matt to run again

expect(mockCore.setOutput).toHaveBeenCalledWith("is_team_member", "false");
expect(mockCore.setOutput).toHaveBeenCalledWith("result", "api_error");
} finally {
vi.useRealTimers();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] Both new tests cover the transient-500 path, but the PR description also claims "Do not retry permanent API failures" — that invariant isn't exercised by a test.

💡 Suggested regression test

Add a case where mockGithub.rest.pulls.get rejects with a non-retryable error (e.g. status: 404) and assert it's called exactly once (no retries) and still fails closed with result: "api_error". This locks in the "preserve security behavior" claim and guards against a future change to shouldRetry accidentally widening the retry surface to permanent failures.

it("should not retry a permanent (404) provenance failure", async () => {
  const apiError = Object.assign(new Error("Not Found"), { status: 404 });
  mockGithub.rest.pulls.get.mockRejectedValue(apiError);
  await runScript();
  expect(mockGithub.rest.pulls.get).toHaveBeenCalledTimes(1);
  expect(mockCore.setOutput).toHaveBeenCalledWith("result", "api_error");
});

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the requested 404 provenance regression test in actions/setup/js/check_membership.test.cjs. It asserts pulls.get is called once and the check fails closed with result: "api_error"; targeted tests pass.

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel Report

PR #59313 — Retry transient slash-command provenance checks

Score: 90/100 ✅ Excellent

Summary: Added 2 behavioral tests covering critical security contracts for retry resilience and fail-closed behavior. Both tests are high-value design tests with 100% edge-case coverage. No violations detected.

Details:

  • Test 1: Retry transient provenance failure (5xx recovery with fake timers)
  • Test 2: Fail closed after exhausting retries (security-critical path)

Metrics:

  • Design Tests: 2/2 (100%)
  • Implementation Ratio: 0% (<30% ✅)
  • Error Coverage: Comprehensive
  • Violations: None

Status: Approve

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See Network Configuration for more information.

🧪 Test quality analysis by Test Quality Sentinel · copilot · haiku45 · 21.2 AIC · ⌖ 8.92 AIC · ⊞ 8.3K · ◷
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Test Quality Sentinel: 90/100 Excellent. 2 new behavioral tests with 100% design coverage. Retry resilience and fail-closed security paths are well-tested. 0% implementation-test ratio (threshold: ≤30%). No violations detected.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed with Impeccable harden/audit lenses (bug-fix / error-handling change).

Findings: No blocking issues.

  • Retry is correctly scoped to the PR provenance lookup only (github.rest.pulls.get), with a custom shouldRetry that retries 5xx/transient errors but leaves 4xx (e.g. 404 missing PR) to fail immediately — preserving fail-closed behavior for permanent errors.
  • Worst-case added latency is bounded (~3 retries, initialDelay 2500ms, backoff x2, capped at 30000ms) — acceptable for a pre-activation gate step.
  • Test coverage validates both the retry-then-success path (2 calls) and retry-exhaustion fail-closed path (4 calls → api_error), matching maxRetries: 3.
  • Test harness correctly loads the real error_recovery.cjs via createRequire so withRetry/isTransientError behavior isn't mocked away, keeping the test meaningful.

Nothing actionable to request changes on.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • registry.npmjs.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "registry.npmjs.org"

See Network Configuration for more information.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet50 · 35.8 AIC · ⌖ 13.2 AIC · ⊞ 8.3K

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Permanent API failure behavior needs direct regression coverage.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds bounded retries to centralized slash-command PR provenance checks while preserving fail-closed authorization behavior.

Changes:

  • Retries transient GitHub API failures with exponential backoff.
  • Adds recovery and retry-exhaustion tests.
File summaries
File Description
actions/setup/js/check_membership.cjs Applies retry handling to provenance lookup.
actions/setup/js/check_membership.test.cjs Tests transient recovery and exhaustion.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread actions/setup/js/check_membership.test.cjs
@gh-aw-bot

Copy link
Copy Markdown
Collaborator
pr-sous-chef

@copilot Please take the next forward-progress pass on PR #59313.

  • Re-check the latest branch, review feedback, and CI state on current HEAD.
  • A branch refresh was requested from this run: https://github.com/github/gh-aw/actions/runs/34178092363
  • There is a Copilot review note about adding direct regression coverage for permanent API failures; address that if still applicable, then run the pr-finisher skill.
  • If no code changes are needed after review, provide a concise maintainer-facing blocker summary instead of repeating prior status.

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 31.2 AIC · ⌖ 8.62 AIC · ⊞ 9.2K · ◷
Comment /souschef to run again

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Copilot AI requested a review from gh-aw-bot September 8, 2026 02:06
@pelikhan
pelikhan merged commit b32439d into main Sep 8, 2026
10 checks passed
@pelikhan
pelikhan deleted the copilot/fix-pre-activation-error-handling branch September 8, 2026 03:49
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.88.7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

4 participants