reconcile

package
v0.17.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 24, 2026 License: MIT Imports: 9 Imported by: 0

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

View Source
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.

View Source
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 Closer

type Closer interface {
	MarkClosed(ctx context.Context, repository string, prNumber int) error
}

Closer marks a PR's row closed.

type Deleter

type Deleter interface {
	Delete(ctx context.Context, repository string, prNumber int) error
}

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.

func (*GitHubChecker) IsOpen

func (c *GitHubChecker) IsOpen(ctx context.Context, repository string, number int) (bool, error)

IsOpen reports whether the PR's GitHub state is "open" (merged and closed PRs both report "closed").

type OpenLister

type OpenLister interface {
	ListOpen(ctx context.Context) ([]store.SlackMessage, 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).

type Summary

type Summary struct {
	Checked   int
	Closed    int // marked closed (in dry-run: would be marked)
	Removed   int // PR 404s or is a draft; dropped from the digest (would be, in dry-run)
	StillOpen int
	Errors    int
}

Summary tallies one reconcile run.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL