Documentation
¶
Overview ¶
Package reconcile backfills the closed_at column on slack_messages rows whose PR is no longer open on GitHub. It exists for the one-time migration to stuck-PR digest tracking: rows created before the close handler recorded closed_at all have closed_at = NULL and look open to the digest, including PRs that were already merged. Running it once (it is idempotent) drops that backlog out of the digest.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrPRDraft = errors.New("reconcile: pull request is a draft")
ErrPRDraft marks a draft PR. A draft must never stay in the database (regardless of open/closed state), so the reconciler deletes its row the same way the live converted_to_draft webhook does — the difference being this catches drafts in the pre-tracking backlog.
var ErrPRNotFound = errors.New("reconcile: pull request not found")
ErrPRNotFound marks a PR that GitHub reports as 404 — deleted, or in a repo that was renamed or is no longer accessible. The reconciler treats it distinctly from other API errors: rather than leave the row untouched, it removes the PR from the digest (a 404 will never resolve on its own).
Functions ¶
This section is empty.
Types ¶
type Deleter ¶
Deleter removes a PR's row entirely. Used for drafts, which must not stay in the database at all (a draft is not review-ready; the row is recreated by the open webhook if it is later marked ready_for_review).
type GitHubChecker ¶
type GitHubChecker struct {
// contains filtered or unexported fields
}
GitHubChecker adapts the GitHub client to PRChecker: it splits "owner/repo" and reports whether the PR's state is "open". A 404 is mapped to ErrPRNotFound and a draft PR (any state) to ErrPRDraft, so the reconciler can drop either from the digest; any other API error is propagated verbatim, so the reconciler leaves the row untouched rather than wrongly acting on a PR it could not read (e.g. a transient 5xx).
func NewGitHubChecker ¶
func NewGitHubChecker(gh prGetter) *GitHubChecker
NewGitHubChecker wraps a GitHub client.
type OpenLister ¶
type OpenLister interface {
ListOpen(ctx context.Context) ([]store.PullRequest, error)
}
OpenLister returns the rows not yet marked closed.
type PRChecker ¶
type PRChecker interface {
IsOpen(ctx context.Context, repository string, prNumber int) (bool, error)
}
PRChecker reports whether a PR is still open on GitHub.
type Reconciler ¶
type Reconciler struct {
// contains filtered or unexported fields
}
Reconciler marks rows closed whose PR GitHub reports as no longer open.
func NewReconciler ¶
func NewReconciler(lister OpenLister, checker PRChecker, closer Closer, deleter Deleter, logger *slog.Logger, dryRun bool) *Reconciler
NewReconciler constructs a Reconciler. When dryRun is true it reports what it would change without writing.
func (*Reconciler) Run ¶
func (r *Reconciler) Run(ctx context.Context) (Summary, error)
Run checks every not-yet-closed row against GitHub and resolves it. Per-PR errors are logged and counted, never fatal — a row we cannot confirm is left untouched (so a token-scope miss never wrongly hides an open PR), and re-running is safe. Two states are dropped rather than left to nag: a 404 (the PR is gone for good, marked closed) and a draft (deleted outright — a draft must never stay in the database, mirroring the converted_to_draft webhook).