Skip to main content

ADR-0008: Close semantics and idempotency

  • Status: Accepted
  • Date: 2026-10-25

Context​

Closing a pull request does not mean merging it. Providers also treat terminal states differently: a merged or completed pull request cannot normally be closed again, and some APIs return an error when the requested transition is not valid. Callers need one predictable rule.

Decision​

ClosePullRequestAsync means transition an open or draft pull request to closed without merging it.

Current stateResult
Open or draftPull request becomes closed; the updated pull request is returned
ClosedNo-op; the current pull request is returned
Merged or completedNo-op; the current pull request is returned unchanged

Close is therefore idempotent. It never throws because the pull request is already closed or already merged.

Mapping:

ProviderClose operationNo-op handling
GitHubPATCH /repos/{owner}/{repo}/pulls/{number} with state = closedRead state first; skip the write when the pull request is closed or merged
GitLabPUT /projects/:id/merge_requests/:iid with state_event = closeRead state first; skip the write when the merge request is closed or merged
Azure DevOpsPATCH .../pullrequests/{id} with status = abandonedRead status first; skip the write when the pull request is abandoned or completed

Additional rules:

  • A missing repository or pull request maps to the core not-found error.
  • A permission failure maps to the core authentication or authorization error.
  • Closing does not delete the source branch and does not change the target branch.
  • Merging is a separate operation (ADR-0007). A close call never merges as a side effect.
  • The provider returns the pull request as it exists after the operation, so callers can observe the final state without a second request.

Consequences​

  • Repeated close calls are safe for retry logic and idempotent jobs.
  • The read-before-write adds one request for close. This is the cost of consistent no-op behavior across providers.
  • Tests cover open, closed, and merged/completed states for each provider.

References​