Documentation
¶
Index ¶
- Variables
- func ClassifyCheckRuns(checkRuns []CheckRun) (status CheckRunStatus, pending, failed []CheckRun)
- func IsBotLogin(login string) bool
- func MergeableStateAccepted(mergeableState string) bool
- type BoardProbeItem
- type CheckRun
- type CheckRunStatus
- type Client
- func (c *Client) AddBlockedByIssue(issueNodeID, blockerNodeID string) error
- func (c *Client) AddComment(owner, repo string, issueNumber int, body string) (int, error)
- func (c *Client) AddCommentReaction(owner, repo string, commentDatabaseID int, content string) error
- func (c *Client) AddLabelToIssue(owner, repo string, issueNumber int, labelName string) error
- func (c *Client) AddPRReviewCommentReaction(owner, repo string, commentDatabaseID int, content string) error
- func (c *Client) AddProjectV2ItemById(projectID, contentNodeID string) (string, error)
- func (c *Client) AddReviewRequest(owner, repo string, prNumber int, reviewers []string) error
- func (c *Client) ArchiveProjectItem(projectID, itemID string) error
- func (c *Client) CloseIssue(owner, repo string, issueNumber int) error
- func (c *Client) CreateDraftPR(owner, repo, title, head, base, body string, _ int) (int, error)
- func (c *Client) CreateIssue(owner, repo, title, body string) (number int, nodeID string, err error)
- func (c *Client) CreatePR(owner, repo, title, head, base, body string) (int, error)
- func (c *Client) DeleteForwardingHooks(owner, repo string) error
- func (c *Client) DeleteReviewRequest(owner, repo string, prNumber int, reviewers []string) error
- func (c *Client) DequeuePullRequest(owner, repo string, prNumber int) error
- func (c *Client) EnablePullRequestAutoMerge(owner, repo string, prNumber int, strategy string) error
- func (c *Client) EnqueuePullRequest(owner, repo string, prNumber int, expectedHeadOID string) error
- func (c *Client) FetchAllowAutoMerge(owner, repo string) (bool, error)
- func (c *Client) FetchCheckRuns(owner, repo, sha string) ([]CheckRun, error)
- func (c *Client) FetchCommitsBehind(owner, repo, base, head string) (int, error)
- func (c *Client) FetchIssue(owner, repo string, issueNumber int) (*IssueData, error)
- func (c *Client) FetchItemDetails(item *ProjectItem) error
- func (c *Client) FetchLabelAppliedAt(owner, repo string, issueNumber int, labelName string) (time.Time, error)
- func (c *Client) FetchLabels(owner, repo string, issueNumber int) ([]string, error)
- func (c *Client) FetchLatestRelease(owner, repo string) (*LatestRelease, error)
- func (c *Client) FetchLinkedPR(owner, repo string, issueNumber int) (*PRDetails, error)
- func (c *Client) FetchPRClosingIssues(owner, repo string, prNumber int) ([]int, error)
- func (c *Client) FetchPRDetails(owner, repo string, prNumber int) (*PRDetails, error)
- func (c *Client) FetchPRMergeable(owner, repo string, prNumber int) (*bool, error)
- func (c *Client) FetchPRMergeableFields(owner, repo string, prNumber int) (mergeable *bool, mergeableState string, err error)
- func (c *Client) FetchPRMergeableState(owner, repo string, prNumber int) (string, error)
- func (c *Client) FetchPRMerged(owner, repo string, prNumber int) (bool, error)
- func (c *Client) FetchPRsForSHA(owner, repo, sha string) ([]int, error)
- func (c *Client) FetchProjectBoard(owner, repo string, projectNum int, ownerType string) (*ProjectBoard, error)
- func (c *Client) FetchProjectItem(owner, repo string, issueNumber int) (*ProjectItem, error)
- func (c *Client) FetchProjectItemStatus(itemID string) (string, error)
- func (c *Client) FetchProjectItemStatusBatch(projectID string) (map[string]string, error)
- func (c *Client) FetchProjectUpdatedAt(projectID string) (time.Time, error)
- func (c *Client) FetchStatusField(projectID string) (*StatusField, error)
- func (c *Client) FindPRForIssue(owner, repo string, issueNumber int) (int, error)
- func (c *Client) GetIssueBody(owner, repo string, issueNumber int) (string, error)
- func (c *Client) GetPRBase(owner, repo string, prNumber int) (string, error)
- func (c *Client) ListPRs(owner, repo string) ([]PRDetails, error)
- func (c *Client) LookupIssueProjectItem(projectID, repo string, issueNumber int) (itemID string, status string, err error)
- func (c *Client) MarkPRReady(owner, repo string, prNumber int) error
- func (c *Client) MergePR(owner, repo string, prNumber int) error
- func (c *Client) ProbeProjectBoard(owner, repo string, projectNum int, ownerType string) ([]BoardProbeItem, string, error)
- func (c *Client) RateLimitStats() (rest, graphql RateLimitStats)
- func (c *Client) RemoveLabelFromIssue(owner, repo string, issueNumber int, labelName string) error
- func (c *Client) ResolveReviewThread(threadID string) error
- func (c *Client) SeedLabels(owner, repo string, stageNames []string, lockedUser string) error
- func (c *Client) UpdateComment(owner, repo string, commentDatabaseID int, body string) error
- func (c *Client) UpdateIssueBody(owner, repo string, issueNumber int, body string) error
- func (c *Client) UpdatePRBase(owner, repo string, prNumber int, newBase string) error
- func (c *Client) UpdateProjectItemStatus(projectID, itemID, statusFieldID, statusOptionID string) error
- type Comment
- type Dependency
- type IssueData
- type LatestRelease
- type MergeQueueEntry
- type PRDetails
- type PRReview
- type ProjectBoard
- type ProjectItem
- type RateLimitStats
- type ReactionGroup
- type ReleaseAsset
- type ReviewRequest
- type SearchResult
- type StatusField
Constants ¶
This section is empty.
Variables ¶
var ErrAutoMergeAlreadyClean = errors.New("PR is already in clean status — merge directly")
ErrAutoMergeAlreadyClean is returned by EnablePullRequestAutoMerge when the PR is already in CLEAN status (all checks passed, immediately mergeable). GitHub rejects auto-merge enablement in this state — the caller must merge directly instead. Matched on the string "Pull request is in clean status" from the GitHub GraphQL API (confirmed from production logs).
var ErrAutoMergeNotEnabled = errors.New("repository has not enabled auto-merge")
ErrAutoMergeNotEnabled is returned by EnablePullRequestAutoMerge when the repository has not enabled the auto-merge feature in its settings.
var ErrMethodNotAllowed = errors.New("method not allowed")
ErrMethodNotAllowed is returned by REST methods when the server responds with 405. Callers may use errors.Is(err, github.ErrMethodNotAllowed) to detect unsupported operations (e.g. rebase merge not allowed by repo policy).
var ErrNoRepoConfigured = errors.New("repo must not be empty")
ErrNoRepoConfigured is returned by SeedLabels when repo is empty.
var ErrNotFound = errors.New("not found")
ErrNotFound is returned by REST methods when the server responds with 404. Callers may use errors.Is(err, github.ErrNotFound) to distinguish "not found" from other failures without fragile string matching.
var ErrNotMergeable = errors.New("PR is not mergeable")
ErrNotMergeable is returned by MergePR when the PR cannot be merged because GitHub reports mergeable as false or null (not yet computed). Callers may use errors.Is(err, github.ErrNotMergeable) to distinguish this from API failures.
var ErrUnprocessableEntity = errors.New("unprocessable entity")
ErrUnprocessableEntity is returned by REST methods when the server responds with 422. Callers may use errors.Is(err, github.ErrUnprocessableEntity) to detect "already exists" or validation failures without fragile string matching.
var Logf func(issueNumber int, tag, format string, args ...any)
Logf is an optional package-level logger callback. When non-nil, internal retry/diagnostic warnings (e.g. project board indexer mismatches) are routed here. Engine wires this to its own logf during construction so messages land in fabrik.log; tests that don't set it get silent retries.
Functions ¶
func ClassifyCheckRuns ¶ added in v0.0.71
func ClassifyCheckRuns(checkRuns []CheckRun) (status CheckRunStatus, pending, failed []CheckRun)
ClassifyCheckRuns reduces checkRuns to the latest run per check name (highest ID wins — GitHub check-run IDs are monotonically increasing, so this discards a stale completed/failed entry left behind when a check is rerun under a new ID) and classifies the result. Any pending run, at any name, takes global precedence over any failed run: a check still running is never outweighed by a different check (or a superseded run of the same check) that has already failed.
This is the single source of truth for check-run classification, shared by settlePRMergeState (engine/pr_settle.go) and checkCIGate (engine/ci.go) so the two call sites cannot drift out of agreement.
func IsBotLogin ¶
IsBotLogin returns true if the login matches known bot patterns. Used as a fallback when the GraphQL __typename field is absent or not "Bot".
func MergeableStateAccepted ¶
MergeableStateAccepted reports whether GitHub's mergeable_state value indicates the PR is mergeable per branch protection rules. "clean" means fully ready; "unstable" means non-required checks have failed but the PR is still mergeable. Other values ("blocked", "behind", "dirty", "draft", "has_hooks", "unknown", "") fall through to the per-check classification.
"has_hooks" is treated as not-accepted here because pre-merge hooks may modify the merge outcome; conservative to use the per-check path.
Types ¶
type BoardProbeItem ¶
type BoardProbeItem struct {
ItemID string
ContentID string
Number int
IsPR bool
IsClosed bool
State string
Repo string
EffectiveUpdatedAt time.Time
LinkedPRNumber int
LinkedPRUpdatedAt time.Time
LinkedPRHeadSHA string // headRefOid from GraphQL probe query; empty if no linked PR
Status string
}
BoardProbeItem is the per-item result from ProbeProjectBoard. It contains only scalar identity fields — no labels or full comment history — to minimise GraphQL cost on idle polls. effectiveUpdatedAt is max(content.updatedAt, projectItem.updatedAt, linkedPR.updatedAt); used for cache staleness checks.
type CheckRun ¶
type CheckRun struct {
ID int64 // GitHub check run ID
Name string
Status string // "queued", "in_progress", "completed"
Conclusion string // "success", "failure", "neutral", "cancelled", "skipped", "timed_out", "action_required", or ""
}
CheckRun holds the result of a single CI check run.
type CheckRunStatus ¶ added in v0.0.71
type CheckRunStatus int
CheckRunStatus is the aggregate classification of a set of check runs.
const ( // CheckRunsReady means every latest-per-name run completed successfully // (or there are no check runs at all). CheckRunsReady CheckRunStatus = iota // CheckRunsPending means at least one latest-per-name run is still // queued/in_progress. Pending always takes precedence over failed — // a fresh rerun in progress must never be shadowed by a stale failure // of a different check (or of the same check under an older ID). CheckRunsPending // CheckRunsFailed means at least one latest-per-name run completed with // a failing conclusion and none are pending. CheckRunsFailed )
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a GitHub GraphQL API client.
func NewClientWithBaseURL ¶
NewClientWithBaseURL creates a client with a custom base URL (for testing).
func (*Client) AddBlockedByIssue ¶
AddBlockedByIssue creates a "blocked by" dependency edge: issueNodeID is blocked by blockerNodeID. After this call, blockerNodeID will appear in issueNodeID's blockedBy(first: N) GraphQL field.
NOTE: GitHub's API is asymmetrically named: the read field is Issue.blockedBy but the write mutation is addBlockedBy (not addBlockedByIssue). The input field is blockingIssueId (not blockedById). Verified via schema introspection against api.github.com/graphql on 2026-05-24.
func (*Client) AddComment ¶
AddComment posts a comment on an issue and returns the comment's database ID.
func (*Client) AddCommentReaction ¶
func (c *Client) AddCommentReaction(owner, repo string, commentDatabaseID int, content string) error
AddCommentReaction adds a reaction to an issue comment (or issue-level PR comment). Content can be "+1", "-1", "eyes", etc. For PR review thread (inline) comments, use AddPRReviewCommentReaction instead — they live at a different endpoint.
func (*Client) AddLabelToIssue ¶
AddLabelToIssue adds a label to an issue. Creates the label if it doesn't exist.
func (*Client) AddPRReviewCommentReaction ¶
func (c *Client) AddPRReviewCommentReaction(owner, repo string, commentDatabaseID int, content string) error
AddPRReviewCommentReaction adds a reaction to a PR review thread (inline) comment. These live at /repos/.../pulls/comments/{id}/reactions rather than /repos/.../issues/comments/{id}/reactions.
func (*Client) AddProjectV2ItemById ¶
AddProjectV2ItemById adds an issue or PR (identified by its GraphQL node ID) to a GitHub Projects v2 board. Returns the new project item's node ID.
func (*Client) AddReviewRequest ¶
AddReviewRequest adds one or more reviewer requests to a pull request.
func (*Client) ArchiveProjectItem ¶
ArchiveProjectItem archives a project item so it no longer appears in paginated board results. Archiving is idempotent — calling it on an already-archived item is a no-op.
func (*Client) CloseIssue ¶
CloseIssue closes a GitHub issue via the REST API.
func (*Client) CreateDraftPR ¶
CreateDraftPR creates a draft pull request for the given issue branch. Returns the PR number. Callers should first call FindPRForIssue to avoid duplicates. The body parameter is the full PR body; callers are responsible for including "Closes #N".
func (*Client) CreateIssue ¶
func (c *Client) CreateIssue(owner, repo, title, body string) (number int, nodeID string, err error)
CreateIssue creates a new GitHub issue via the REST API and returns the issue number and GraphQL node ID. The node ID is required for project board and blockedBy mutations.
func (*Client) CreatePR ¶ added in v0.0.71
CreatePR creates a non-draft pull request. Returns the PR number. Unlike CreateDraftPR, the PR is immediately ready for review and CI.
func (*Client) DeleteForwardingHooks ¶
DeleteForwardingHooks deletes repo hooks matching webhookForwarderURL; 404 on DELETE is success.
func (*Client) DeleteReviewRequest ¶
DeleteReviewRequest removes one or more reviewer requests from a pull request. GitHub's DELETE endpoint requires a JSON body with the reviewer list, so this uses restRequest("DELETE", ...) rather than restDelete (which sends no body).
func (*Client) DequeuePullRequest ¶ added in v0.0.71
DequeuePullRequest removes a pull request from the repository's merge queue.
Uses the same two-step pattern as MarkPRReady: fetch the PR node ID via GraphQL, then call the dequeuePullRequest mutation.
func (*Client) EnablePullRequestAutoMerge ¶ added in v0.0.68
func (c *Client) EnablePullRequestAutoMerge(owner, repo string, prNumber int, strategy string) error
EnablePullRequestAutoMerge enables GitHub's native auto-merge on a pull request. strategy must be one of "MERGE", "SQUASH", or "REBASE". GitHub merges the PR atomically when all branch-protection requirements are satisfied.
Returns ErrAutoMergeNotEnabled when the repository setting is disabled.
func (*Client) EnqueuePullRequest ¶ added in v0.0.71
EnqueuePullRequest adds a pull request to the repository's merge queue. expectedHeadOID is the current head SHA of the PR; if the PR has been force-pushed since the caller read the SHA, the mutation fails safely (optimistic concurrency).
Uses the same two-step pattern as MarkPRReady: fetch the PR node ID via GraphQL, then call the enqueuePullRequest mutation.
func (*Client) FetchAllowAutoMerge ¶ added in v0.0.68
FetchAllowAutoMerge calls GET /repos/{owner}/{repo} and returns the value of the allow_auto_merge field. Returns an error if the request fails.
func (*Client) FetchCheckRuns ¶
FetchCheckRuns retrieves check runs for a given commit SHA via the REST API.
func (*Client) FetchCommitsBehind ¶ added in v0.0.68
FetchCommitsBehind returns how many commits base is ahead of head using the GitHub compare API. A positive result means head is that many commits behind base. Returns 0, nil when head is up to date.
func (*Client) FetchIssue ¶
FetchIssue retrieves a single issue via the REST API.
func (*Client) FetchItemDetails ¶
func (c *Client) FetchItemDetails(item *ProjectItem) error
FetchItemDetails populates the Comments, Labels, Body, URL, Author, Assignees, and BlockedBy fields of a ProjectItem by fetching full item data via individual node queries. This is the "deep" phase of the two-phase fetch approach. If item.Number is zero (e.g., for projects_v2_item.created with only a node_id), it is populated from the GraphQL response.
func (*Client) FetchLabelAppliedAt ¶
func (c *Client) FetchLabelAppliedAt(owner, repo string, issueNumber int, labelName string) (time.Time, error)
FetchLabelAppliedAt returns the time when labelName was last applied to the given issue, using the GitHub issue events API. Returns time.Time{} (zero) without error if the event is not found (fail-open: timeout will not fire). Pages through all events to find the most recent application.
func (*Client) FetchLabels ¶
FetchLabels returns the current labels on an issue.
func (*Client) FetchLatestRelease ¶
func (c *Client) FetchLatestRelease(owner, repo string) (*LatestRelease, error)
FetchLatestRelease calls GET /repos/{owner}/{repo}/releases/latest and returns the tag name and asset list. Returns an error if the request fails or returns a non-2xx status.
func (*Client) FetchLinkedPR ¶
FetchLinkedPR finds the PR linked to an issue by searching for a PR with the head branch fabrik/issue-N (Fabrik's naming convention). Returns nil, nil if no PR is found.
func (*Client) FetchPRClosingIssues ¶
FetchPRClosingIssues returns the issue numbers referenced by GitHub closing keywords (Closes, Fixes, Resolves + #N) in the body of the given pull request. Only same-repo references are returned; cross-repo references are out of scope. Returns nil, nil on 404 or when the PR body contains no recognized closing references.
func (*Client) FetchPRDetails ¶
FetchPRDetails retrieves a single pull request via the REST API.
func (*Client) FetchPRMergeable ¶
FetchPRMergeable returns GitHub's mergeable flag for a single PR.
The returned pointer is nil when GitHub has not yet computed mergeability (the field is null on the REST response); callers should treat this as "unknown — try again on the next poll". A non-nil *false indicates a confirmed conflict with the base branch.
Only the single-PR endpoint (/pulls/{number}) returns this field reliably; the list endpoint used by FetchLinkedPR does not.
func (*Client) FetchPRMergeableFields ¶ added in v0.0.70
func (c *Client) FetchPRMergeableFields(owner, repo string, prNumber int) (mergeable *bool, mergeableState string, err error)
FetchPRMergeableFields fetches both the mergeable flag and mergeable_state for a single PR in one REST call, eliminating the read-after-write window that existed when the two fields were fetched separately by different gate functions.
Returns (nil, "", nil) when mergeable is null (GitHub still computing).
func (*Client) FetchPRMergeableState ¶
FetchPRMergeableState returns GitHub's branch-protection-aware mergeable_state for a single PR (e.g. "clean", "unstable", "blocked", "behind", "dirty", "draft", "has_hooks", "unknown"). Used by Fabrik's CI gate as the authoritative signal for whether non-required check_run failures should block a merge.
Returns "" when GitHub has not yet computed it. Only the single-PR endpoint returns this field reliably; the list endpoint used by FetchLinkedPR omits it (returns null).
func (*Client) FetchPRMerged ¶ added in v0.0.70
FetchPRMerged returns GitHub's authoritative `merged` flag for a single PR.
Only the single-PR endpoint (/pulls/{number}) reports `merged` reliably. The list endpoint used by FetchLinkedPR returns merged=false for several seconds after a merge (and is generally unreliable for this field), so a PR the engine just merged briefly looks like state=closed, merged=false there. Use this to confirm whether a PR observed as closed was actually merged before treating it as "closed without merging".
func (*Client) FetchPRsForSHA ¶
FetchPRsForSHA returns the PR numbers associated with the given commit SHA via GET /repos/{owner}/{repo}/commits/{sha}/pulls. Returns nil, nil on 404 or empty.
func (*Client) FetchProjectBoard ¶
func (c *Client) FetchProjectBoard(owner, repo string, projectNum int, ownerType string) (*ProjectBoard, error)
FetchProjectBoard pulls the project board with shallow item data (no comments or linked PRs). Use FetchItemDetails to populate comments for specific items. This two-phase approach dramatically reduces GraphQL rate limit cost.
When ownerType is non-empty ("user" or "organization"), the board is fetched directly using that type, skipping the try-org-then-user fallback. When ownerType is empty, the original fallback behavior is preserved.
func (*Client) FetchProjectItem ¶
func (c *Client) FetchProjectItem(owner, repo string, issueNumber int) (*ProjectItem, error)
FetchProjectItem fetches a minimal ProjectItem for an issue via REST GET /repos/{owner}/{repo}/issues/{number}. Used by the boardcache fallback path when a webhook event arrives for an issue not yet in the cache.
func (*Client) FetchProjectItemStatus ¶
FetchProjectItemStatus fetches only the Status field value for a single project item identified by its node ID (PVTI_...). Returns "" when no status is set.
func (*Client) FetchProjectItemStatusBatch ¶
FetchProjectItemStatusBatch fetches a map of projectItemNodeID → statusName for every item in the project. Dramatically cheaper than FetchProjectBoard because it fetches no nested fields. Paginates identically to fetchProjectBoardOnce.
func (*Client) FetchProjectUpdatedAt ¶
FetchProjectUpdatedAt returns the updatedAt timestamp for the given project node ID. Used as a cheap gate in the poll loop to skip the full status batch when the project hasn't changed since the last cycle.
func (*Client) FetchStatusField ¶
func (c *Client) FetchStatusField(projectID string) (*StatusField, error)
FetchStatusField retrieves the Status field ID and its option IDs for a project.
func (*Client) FindPRForIssue ¶
FindPRForIssue finds the PR associated with an issue by looking for a PR whose head branch matches the fabrik/issue-N convention. Returns the PR number, or 0 if no matching PR is found.
Uses FetchLinkedPR internally, which hits the core REST pulls endpoint (/repos/{owner}/{repo}/pulls?head=...). Previously this used the GitHub search API (/search/issues) which has a 30/minute rate limit — heavy polling exhausted that quota. Core REST has a 5000/hour limit, ~167x more headroom.
func (*Client) GetIssueBody ¶
GetIssueBody fetches the body of an issue (or PR, since PRs are issues on the REST API).
func (*Client) GetPRBase ¶
GetPRBase fetches the current base branch reference of an open pull request. Returns the base branch name (e.g. "main" or "feature/foo"), or an error if the API call fails.
func (*Client) ListPRs ¶ added in v0.0.71
ListPRs returns recent pull requests (open and closed) for a repository, including their body text. Capped at the 50 most-recently-updated PRs. Used for idempotency detection (e.g. finding an existing integration PR).
func (*Client) LookupIssueProjectItem ¶
func (c *Client) LookupIssueProjectItem(projectID, repo string, issueNumber int) (itemID string, status string, err error)
LookupIssueProjectItem fetches the project-item node ID and current Status for a given issue, filtered to the specified projectID. It queries repository.issue.projectItems (first: 20), iterating nodes until one whose project.id matches projectID is found. Returns ("", "", nil) when the issue is not in the specified project. Returns an error on any GraphQL failure.
Note: first:20 covers issues in up to 20 GitHub Projects. Issues belonging to more than 20 projects are not supported (vanishingly rare in practice).
func (*Client) MarkPRReady ¶
MarkPRReady transitions a draft PR to ready-for-review. Uses the GraphQL markPullRequestReadyForReview mutation, which is the supported path — REST PATCH does not reliably support draft→ready transitions.
func (*Client) MergePR ¶
MergePR merges the pull request identified by prNumber. It first checks GitHub's mergeable status: if null (not yet computed) or false, it returns ErrNotMergeable. It attempts a rebase merge first; if the repository does not allow rebase merges (405), it falls back to a regular merge commit.
func (*Client) ProbeProjectBoard ¶
func (c *Client) ProbeProjectBoard(owner, repo string, projectNum int, ownerType string) ([]BoardProbeItem, string, error)
ProbeProjectBoard fetches a minimal probe of the project board — only scalar identity fields and one linked-PR node per item, no labels. Used by the per-poll refresh path to detect updatedAt drift without the GraphQL cost of labels(first:30) and closedByPullRequestsReferences(first:5).
Returns []BoardProbeItem (one per non-draft item), the projectID string, and any error. Items whose content node ID is empty (draft issues) are skipped.
When ownerType is non-empty ("user" or "organization"), the board is fetched directly using that type, skipping the try-org-then-user fallback.
func (*Client) RateLimitStats ¶
func (c *Client) RateLimitStats() (rest, graphql RateLimitStats)
RateLimitStats returns the most recently observed REST and GraphQL rate limit stats.
func (*Client) RemoveLabelFromIssue ¶
RemoveLabelFromIssue removes a label from an issue.
func (*Client) ResolveReviewThread ¶
ResolveReviewThread marks a PR review thread as resolved ("Resolve conversation" in the GitHub UI). threadID is the GraphQL node ID of the thread (available via ProjectItem.LinkedPRReviewThreadComments[*].ReviewThreadID).
func (*Client) SeedLabels ¶
SeedLabels ensures all known Fabrik labels exist on the given repo. It enforces the correct color on existing labels and backfills empty descriptions. Non-empty descriptions are never overwritten. stageNames is the list of stage names from the loaded config; lockedUser is the current Fabrik user. Returns ErrNoRepoConfigured when repo is empty. Per-label failures are logged internally and do not cause an early return.
func (*Client) UpdateComment ¶
UpdateComment replaces the body of an existing issue comment.
func (*Client) UpdateIssueBody ¶
UpdateIssueBody updates the body of an issue.
func (*Client) UpdatePRBase ¶
UpdatePRBase changes the base branch of an open pull request via the GitHub REST API. GitHub accepts base-branch changes on open PRs; the PR may become unmergeable if the head and new base have diverged, but the API call itself succeeds.
func (*Client) UpdateProjectItemStatus ¶
func (c *Client) UpdateProjectItemStatus(projectID, itemID, statusFieldID, statusOptionID string) error
UpdateProjectItemStatus moves an item to a different status column on the project board.
type Comment ¶
type Comment struct {
ID string
DatabaseID int // Numeric ID needed for REST API (reactions, etc.)
Author string
Body string
CreatedAt time.Time
Reactions []ReactionGroup
FromPR int // Non-zero if this comment is from a linked PR
// ReviewThreadID is the GraphQL node ID of the PR review thread this
// comment belongs to. Empty for non-review-thread comments. Needed to
// call resolveReviewThread after the feedback is addressed.
ReviewThreadID string
// Path is the file path targeted by the PR review thread comment.
// Empty for regular issue and PR body comments.
Path string
// Line is the line number in the current diff. Zero when not applicable
// (e.g., regular comments) or when the comment targets a deleted line.
Line int
// OriginalLine is the line number in the original base diff. Used as a
// fallback when Line is 0. Zero when not applicable.
OriginalLine int
// DiffHunk is the diff context hunk surrounding the comment. Empty for
// regular issue and PR body comments.
DiffHunk string
}
Comment represents a comment on an issue or linked PR.
func (Comment) HasReaction ¶
HasReaction returns true if the comment has at least one reaction of the given type.
type Dependency ¶
type Dependency struct {
Number int // Issue number of the blocking issue
State string // "OPEN" or "CLOSED" (GitHub GraphQL enum)
Repo string // "owner/repo" of the blocking issue; empty if same repo
}
Dependency represents a blocking issue relationship fetched from the GitHub API.
type LatestRelease ¶
type LatestRelease struct {
TagName string `json:"tag_name"`
Assets []ReleaseAsset `json:"assets"`
}
LatestRelease represents the response from GET /repos/{owner}/{repo}/releases/latest.
type MergeQueueEntry ¶ added in v0.0.71
type MergeQueueEntry struct {
State string // e.g. "QUEUED", "AWAITING_CHECKS", "MERGEABLE", "UNMERGEABLE"
Position int // 1-indexed position in the queue; 0 when not yet positioned
EnqueuerLogin string // GitHub login of the user who enqueued the PR
}
MergeQueueEntry holds the merge-queue position and state for a pull request. The pointer on ProjectItem and PRDetails is nil when no merge queue entry exists.
type PRDetails ¶
type PRDetails struct {
Number int
Title string
State string // "open", "closed"
Merged bool
Draft bool
HeadSHA string
// HeadRefName is the PR's head branch name (e.g. "fabrik/merge-train/…").
// Populated by ListPRs (from head.ref); other constructors may leave it empty.
HeadRefName string
Body string
// MergeableState reflects GitHub's branch-protection-aware mergeable
// status: "clean" (ready to merge), "unstable" (non-required checks
// failing but still mergeable), "blocked" (required checks pending or
// failing), "behind" (head is out of date with base), "dirty" (merge
// conflict), "draft" (PR is a draft), "has_hooks" (clean but hooks
// will run on merge), "unknown" (not yet computed). Used by Fabrik's
// CI gate as the authoritative signal — non-required check_run
// failures (e.g., workflow cleanup jobs) do not block "clean"/"unstable".
MergeableState string
// AutoMergeEnabled is true when GitHub's native auto-merge is enabled on
// the PR (auto_merge field is non-null). False when the user or engine
// has disabled it, or when it was never enabled.
AutoMergeEnabled bool
// IsMergeQueueEnabled is true when the repository has the merge queue feature
// enabled. Always false when populated via REST (GraphQL-only field).
IsMergeQueueEnabled bool
// IsInMergeQueue is true when the PR is currently in the merge queue.
// Always false when populated via REST (GraphQL-only field).
IsInMergeQueue bool
// MergeQueueEntry holds the queue position and state when the PR is enqueued.
// Nil when not in queue or populated via REST. Pointer because GitHub returns
// null after dequeueing and Go's json decoder maps null to nil only on pointers.
MergeQueueEntry *MergeQueueEntry
}
PRDetails holds the fields from a GitHub pull request needed by fabrik watch.
type PRReview ¶
type PRReview struct {
Author string // GitHub login of the reviewer
State string // "APPROVED", "CHANGES_REQUESTED", or "COMMENTED"
Body string // Review summary body (may be empty for comment-only reviews)
DatabaseID int // Numeric PR review ID (0 if not fetched or unavailable)
}
PRReview represents a submitted review on a pull request.
type ProjectBoard ¶
type ProjectBoard struct {
ProjectID string
Title string // display name of the project board (from projectV2.title)
OwnerType string // "organization" or "user", resolved by FetchProjectBoard
Items []ProjectItem
}
ProjectBoard represents the full state of a GitHub Project (v2) board.
type ProjectItem ¶
type ProjectItem struct {
ID string
ItemID string // The project item ID (needed for mutations)
Number int
Title string
Body string
Status string // The column/status on the board
URL string
Repo string // "owner/repo" (e.g., "acme/widgets")
IsPR bool // True if this item is a Pull Request (vs an Issue)
IsClosed bool // True if the underlying GitHub Issue is closed (always false for PRs)
UpdatedAt time.Time
Labels []string
Assignees []string
Comments []Comment
Author string
BlockedBy []Dependency // Issues that must be closed before this one can advance
LinkedPRNumber int // PR number of the first linked PR (0 if none); for REST re-request calls
// LinkedPRNumberShallow is the PR number of the first linked PR from the shallow board query (0 if none).
// Populated only during shallow board parse. Linkage drift detection was previously performed
// by Reconcile using this field; that responsibility has moved to the probe loop
// (runProbeAndDeepFetch via BoardProbeItem.LinkedPRNumber). Retained for compatibility; no longer
// read by Reconcile.
LinkedPRNumberShallow int
LinkedPRHeadSHA string // HeadSHA from headRefOid in the GraphQL query (empty if not fetched)
LinkedPRReviewRequests []ReviewRequest // Outstanding reviewer requests on the linked PR
LinkedPRReviews []PRReview // Reviews already submitted on the linked PR
// LinkedPRReviewThreadComments holds the inline (per-line) comments from
// unresolved review threads on the linked PR. These are real GitHub
// comments with DatabaseIDs and can be reacted to / resolved.
LinkedPRReviewThreadComments []Comment
// LinkedPRResolvedThreadCount is the number of review threads on the linked PR
// that are currently resolved. Used by progress detection during turn extension.
LinkedPRResolvedThreadCount int
// LinkedPRIsMergeQueueEnabled is true when the repository has the merge queue
// feature enabled. Zero (false) when no queue exists or the field was not fetched.
LinkedPRIsMergeQueueEnabled bool
// LinkedPRIsInMergeQueue is true when the linked PR is currently in the merge queue.
LinkedPRIsInMergeQueue bool
// LinkedPRMergeQueueEntry holds the queue position and state when the PR is
// enqueued. Nil when the PR is not in the queue or mergeQueueEntry was null.
LinkedPRMergeQueueEntry *MergeQueueEntry
}
ProjectItem represents an issue or pull request card on the project board.
type RateLimitStats ¶
RateLimitStats holds the latest GitHub API rate limit values parsed from response headers.
type ReactionGroup ¶
ReactionGroup represents a reaction type and its count on a comment.
type ReleaseAsset ¶
type ReleaseAsset struct {
Name string `json:"name"`
BrowserDownloadURL string `json:"browser_download_url"`
APIURL string `json:"url"` // API URL for downloading with Accept: application/octet-stream
Size int64 `json:"size"`
}
ReleaseAsset represents a single downloadable asset in a GitHub release.
type ReviewRequest ¶
type ReviewRequest struct {
Login string // GitHub login of the requested reviewer (user or bot)
IsBot bool // True if the reviewer is a bot (from __typename or login-pattern fallback)
}
ReviewRequest represents a pending review request on a pull request.
type SearchResult ¶
type SearchResult struct {
Items []struct {
Number int `json:"number"`
} `json:"items"`
}
SearchResult represents the response from GitHub's search API.