github

package
v0.1.0-alpha.3 Latest Latest
Warning

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

Go to latest
Published: Feb 2, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExtractRepoFromPRURL

func ExtractRepoFromPRURL(prURL string) (string, error)

ExtractRepoFromPRURL extracts just the owner/repo from a GitHub PR URL. This is a convenience wrapper around ParsePRURL for callers that only need the repo.

func ParsePRURL

func ParsePRURL(prURL string) (prNumber, repo string, err error)

ParsePRURL extracts the repo and PR number from a GitHub PR URL. Expected format: https://github.com/owner/repo/pull/123

Types

type CICheckContext

type CICheckContext struct {
	CheckName string // Name of the status check
	State     string // State of the check (e.g., FAILURE, ERROR)
}

CICheckContext holds context specific to CI status check failures.

type Client

type Client struct{}

Client wraps the gh CLI for GitHub API operations.

func NewClient

func NewClient() *Client

NewClient creates a new GitHub client.

func (*Client) GetJobLogs

func (c *Client) GetJobLogs(ctx context.Context, repo string, jobID int64) (string, error)

GetJobLogs fetches the logs for a specific job.

func (*Client) GetPRMetadata

func (c *Client) GetPRMetadata(ctx context.Context, prURLOrNumber string, repo string) (*PRMetadata, error)

GetPRMetadata fetches comprehensive PR metadata for import operations. prURLOrNumber can be a full PR URL or just the PR number. If prURLOrNumber is a URL, repo is ignored. If prURLOrNumber is a number, repo must be provided in owner/repo format.

func (*Client) GetPRStatus

func (c *Client) GetPRStatus(ctx context.Context, prURL string) (*PRStatus, error)

GetPRStatus fetches comprehensive PR status information.

func (*Client) PostPRComment

func (c *Client) PostPRComment(ctx context.Context, prURL string, body string) error

PostPRComment posts a comment on a PR issue.

func (*Client) PostReplyToComment

func (c *Client) PostReplyToComment(ctx context.Context, prURL string, commentID int, body string) error

PostReplyToComment posts a reply to a specific comment on a PR. This is used to acknowledge when we've created a bead from feedback.

func (*Client) PostReviewReply

func (c *Client) PostReviewReply(ctx context.Context, prURL string, reviewCommentID int, body string) error

PostReviewReply posts a reply to a review comment. Since review comments are different from issue comments, this uses the review API.

func (*Client) ResolveReviewThread

func (c *Client) ResolveReviewThread(ctx context.Context, prURL string, commentID int) error

ResolveReviewThread resolves a review thread containing the specified comment. This uses the GraphQL API since the REST API doesn't support resolving threads.

func (*Client) WatchWorkflowRun

func (c *Client) WatchWorkflowRun(ctx context.Context, repo string, runID int64) error

WatchWorkflowRun blocks until a workflow run completes. Returns nil on success, error on failure. If the workflow run itself fails (non-zero exit status), the error will wrap an *exec.ExitError which the caller can check using errors.As.

type ClientInterface

type ClientInterface interface {
	// GetPRStatus fetches comprehensive PR status information.
	GetPRStatus(ctx context.Context, prURL string) (*PRStatus, error)
	// GetPRMetadata fetches metadata for a PR suitable for import.
	GetPRMetadata(ctx context.Context, prURLOrNumber string, repo string) (*PRMetadata, error)
	// PostPRComment posts a comment on a PR issue.
	PostPRComment(ctx context.Context, prURL string, body string) error
	// PostReplyToComment posts a reply to a specific comment on a PR.
	PostReplyToComment(ctx context.Context, prURL string, commentID int, body string) error
	// PostReviewReply posts a reply to a review comment.
	PostReviewReply(ctx context.Context, prURL string, reviewCommentID int, body string) error
	// ResolveReviewThread resolves a review thread containing the specified comment.
	ResolveReviewThread(ctx context.Context, prURL string, commentID int) error
	// GetJobLogs fetches the logs for a specific job.
	GetJobLogs(ctx context.Context, repo string, jobID int64) (string, error)
	// WatchWorkflowRun blocks until a workflow run completes.
	// Returns nil on success, error on failure. If the workflow run itself fails
	// (non-zero exit status), the error will wrap an *exec.ExitError.
	WatchWorkflowRun(ctx context.Context, repo string, runID int64) error
}

ClientInterface defines the interface for GitHub API operations. This abstraction enables testing without actual GitHub API calls.

type Comment

type Comment struct {
	ID        int       `json:"id"`
	Body      string    `json:"body"`
	Author    string    `json:"author"`
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

Comment represents a PR comment.

type FeedbackContext

type FeedbackContext struct {
	CI       *CICheckContext      `json:"ci,omitempty"`
	Workflow *WorkflowContext     `json:"workflow,omitempty"`
	Review   *ReviewContext       `json:"review,omitempty"`
	Comment  *IssueCommentContext `json:"comment,omitempty"`
}

FeedbackContext holds source-specific context data. Only one field will be non-nil, based on the source type.

type FeedbackItem

type FeedbackItem struct {
	Type        FeedbackType
	Title       string
	Description string
	Source      SourceInfo // Structured source information
	Priority    int        // 0-4 (0=critical, 4=backlog)

	// Typed context fields (only one will be set based on Source.Type)
	CICheck      *CICheckContext      // Set when Source.Type == SourceTypeCI
	Workflow     *WorkflowContext     // Set when Source.Type == SourceTypeWorkflow
	Review       *ReviewContext       // Set when Source.Type == SourceTypeReviewComment
	IssueComment *IssueCommentContext // Set when Source.Type == SourceTypeIssueComment
}

FeedbackItem represents a piece of feedback from GitHub that could become a bead.

func (FeedbackItem) GetInReplyToID

func (f FeedbackItem) GetInReplyToID() string

GetInReplyToID returns the ID of the parent comment if this is a reply. Returns empty string if this is not a reply.

func (FeedbackItem) GetSourceID

func (f FeedbackItem) GetSourceID() string

GetSourceID returns the source ID used for resolution tracking. Returns empty string if not applicable.

func (FeedbackItem) GetSourceName

func (f FeedbackItem) GetSourceName() string

GetSourceName returns a human-readable source name (e.g., "CI: test-suite").

func (FeedbackItem) ToFeedbackContext

func (f FeedbackItem) ToFeedbackContext() *FeedbackContext

ToFeedbackContext creates a FeedbackContext from the item's typed context fields.

type FeedbackType

type FeedbackType string

FeedbackType categorizes the type of feedback.

const (
	FeedbackTypeCI       FeedbackType = "ci_failure"
	FeedbackTypeTest     FeedbackType = "test_failure"
	FeedbackTypeLint     FeedbackType = "lint_error"
	FeedbackTypeBuild    FeedbackType = "build_error"
	FeedbackTypeReview   FeedbackType = "review_comment"
	FeedbackTypeSecurity FeedbackType = "security_issue"
	FeedbackTypeGeneral  FeedbackType = "general"
	FeedbackTypeConflict FeedbackType = "merge_conflict"
)

type GitHubClientMock

type GitHubClientMock struct {
	// GetJobLogsFunc mocks the GetJobLogs method.
	GetJobLogsFunc func(ctx context.Context, repo string, jobID int64) (string, error)

	// GetPRMetadataFunc mocks the GetPRMetadata method.
	GetPRMetadataFunc func(ctx context.Context, prURLOrNumber string, repo string) (*PRMetadata, error)

	// GetPRStatusFunc mocks the GetPRStatus method.
	GetPRStatusFunc func(ctx context.Context, prURL string) (*PRStatus, error)

	// PostPRCommentFunc mocks the PostPRComment method.
	PostPRCommentFunc func(ctx context.Context, prURL string, body string) error

	// PostReplyToCommentFunc mocks the PostReplyToComment method.
	PostReplyToCommentFunc func(ctx context.Context, prURL string, commentID int, body string) error

	// PostReviewReplyFunc mocks the PostReviewReply method.
	PostReviewReplyFunc func(ctx context.Context, prURL string, reviewCommentID int, body string) error

	// ResolveReviewThreadFunc mocks the ResolveReviewThread method.
	ResolveReviewThreadFunc func(ctx context.Context, prURL string, commentID int) error

	// WatchWorkflowRunFunc mocks the WatchWorkflowRun method.
	WatchWorkflowRunFunc func(ctx context.Context, repo string, runID int64) error
	// contains filtered or unexported fields
}

GitHubClientMock is a mock implementation of ClientInterface.

func TestSomethingThatUsesClientInterface(t *testing.T) {

	// make and configure a mocked ClientInterface
	mockedClientInterface := &GitHubClientMock{
		GetJobLogsFunc: func(ctx context.Context, repo string, jobID int64) (string, error) {
			panic("mock out the GetJobLogs method")
		},
		GetPRMetadataFunc: func(ctx context.Context, prURLOrNumber string, repo string) (*PRMetadata, error) {
			panic("mock out the GetPRMetadata method")
		},
		GetPRStatusFunc: func(ctx context.Context, prURL string) (*PRStatus, error) {
			panic("mock out the GetPRStatus method")
		},
		PostPRCommentFunc: func(ctx context.Context, prURL string, body string) error {
			panic("mock out the PostPRComment method")
		},
		PostReplyToCommentFunc: func(ctx context.Context, prURL string, commentID int, body string) error {
			panic("mock out the PostReplyToComment method")
		},
		PostReviewReplyFunc: func(ctx context.Context, prURL string, reviewCommentID int, body string) error {
			panic("mock out the PostReviewReply method")
		},
		ResolveReviewThreadFunc: func(ctx context.Context, prURL string, commentID int) error {
			panic("mock out the ResolveReviewThread method")
		},
		WatchWorkflowRunFunc: func(ctx context.Context, repo string, runID int64) error {
			panic("mock out the WatchWorkflowRun method")
		},
	}

	// use mockedClientInterface in code that requires ClientInterface
	// and then make assertions.

}

func (*GitHubClientMock) GetJobLogs

func (mock *GitHubClientMock) GetJobLogs(ctx context.Context, repo string, jobID int64) (string, error)

GetJobLogs calls GetJobLogsFunc.

func (*GitHubClientMock) GetJobLogsCalls

func (mock *GitHubClientMock) GetJobLogsCalls() []struct {
	Ctx   context.Context
	Repo  string
	JobID int64
}

GetJobLogsCalls gets all the calls that were made to GetJobLogs. Check the length with:

len(mockedClientInterface.GetJobLogsCalls())

func (*GitHubClientMock) GetPRMetadata

func (mock *GitHubClientMock) GetPRMetadata(ctx context.Context, prURLOrNumber string, repo string) (*PRMetadata, error)

GetPRMetadata calls GetPRMetadataFunc.

func (*GitHubClientMock) GetPRMetadataCalls

func (mock *GitHubClientMock) GetPRMetadataCalls() []struct {
	Ctx           context.Context
	PrURLOrNumber string
	Repo          string
}

GetPRMetadataCalls gets all the calls that were made to GetPRMetadata. Check the length with:

len(mockedClientInterface.GetPRMetadataCalls())

func (*GitHubClientMock) GetPRStatus

func (mock *GitHubClientMock) GetPRStatus(ctx context.Context, prURL string) (*PRStatus, error)

GetPRStatus calls GetPRStatusFunc.

func (*GitHubClientMock) GetPRStatusCalls

func (mock *GitHubClientMock) GetPRStatusCalls() []struct {
	Ctx   context.Context
	PrURL string
}

GetPRStatusCalls gets all the calls that were made to GetPRStatus. Check the length with:

len(mockedClientInterface.GetPRStatusCalls())

func (*GitHubClientMock) PostPRComment

func (mock *GitHubClientMock) PostPRComment(ctx context.Context, prURL string, body string) error

PostPRComment calls PostPRCommentFunc.

func (*GitHubClientMock) PostPRCommentCalls

func (mock *GitHubClientMock) PostPRCommentCalls() []struct {
	Ctx   context.Context
	PrURL string
	Body  string
}

PostPRCommentCalls gets all the calls that were made to PostPRComment. Check the length with:

len(mockedClientInterface.PostPRCommentCalls())

func (*GitHubClientMock) PostReplyToComment

func (mock *GitHubClientMock) PostReplyToComment(ctx context.Context, prURL string, commentID int, body string) error

PostReplyToComment calls PostReplyToCommentFunc.

func (*GitHubClientMock) PostReplyToCommentCalls

func (mock *GitHubClientMock) PostReplyToCommentCalls() []struct {
	Ctx       context.Context
	PrURL     string
	CommentID int
	Body      string
}

PostReplyToCommentCalls gets all the calls that were made to PostReplyToComment. Check the length with:

len(mockedClientInterface.PostReplyToCommentCalls())

func (*GitHubClientMock) PostReviewReply

func (mock *GitHubClientMock) PostReviewReply(ctx context.Context, prURL string, reviewCommentID int, body string) error

PostReviewReply calls PostReviewReplyFunc.

func (*GitHubClientMock) PostReviewReplyCalls

func (mock *GitHubClientMock) PostReviewReplyCalls() []struct {
	Ctx             context.Context
	PrURL           string
	ReviewCommentID int
	Body            string
}

PostReviewReplyCalls gets all the calls that were made to PostReviewReply. Check the length with:

len(mockedClientInterface.PostReviewReplyCalls())

func (*GitHubClientMock) ResolveReviewThread

func (mock *GitHubClientMock) ResolveReviewThread(ctx context.Context, prURL string, commentID int) error

ResolveReviewThread calls ResolveReviewThreadFunc.

func (*GitHubClientMock) ResolveReviewThreadCalls

func (mock *GitHubClientMock) ResolveReviewThreadCalls() []struct {
	Ctx       context.Context
	PrURL     string
	CommentID int
}

ResolveReviewThreadCalls gets all the calls that were made to ResolveReviewThread. Check the length with:

len(mockedClientInterface.ResolveReviewThreadCalls())

func (*GitHubClientMock) WatchWorkflowRun

func (mock *GitHubClientMock) WatchWorkflowRun(ctx context.Context, repo string, runID int64) error

WatchWorkflowRun calls WatchWorkflowRunFunc.

func (*GitHubClientMock) WatchWorkflowRunCalls

func (mock *GitHubClientMock) WatchWorkflowRunCalls() []struct {
	Ctx   context.Context
	Repo  string
	RunID int64
}

WatchWorkflowRunCalls gets all the calls that were made to WatchWorkflowRun. Check the length with:

len(mockedClientInterface.WatchWorkflowRunCalls())

type IssueCommentContext

type IssueCommentContext struct {
	Author    string // Username of the comment author
	CommentID int64  // ID of the comment
}

IssueCommentContext holds context specific to issue/PR comments.

type Job

type Job struct {
	ID         int64  `json:"id"`
	Name       string `json:"name"`
	Status     string `json:"status"`
	Conclusion string `json:"conclusion"`
	Steps      []Step `json:"steps"`
	URL        string `json:"url"`
}

Job represents a job within a workflow run.

type PRMetadata

type PRMetadata struct {
	Number      int       `json:"number"`
	URL         string    `json:"url"`
	Title       string    `json:"title"`
	Body        string    `json:"body"`
	State       string    `json:"state"`       // OPEN, CLOSED, MERGED
	HeadRefName string    `json:"headRefName"` // Branch name
	BaseRefName string    `json:"baseRefName"` // Target branch (e.g., main)
	HeadRefOid  string    `json:"headRefOid"`  // Head commit SHA
	Author      string    `json:"author"`
	Labels      []string  `json:"labels"`
	IsDraft     bool      `json:"isDraft"`
	Merged      bool      `json:"merged"`
	MergedAt    time.Time `json:"mergedAt,omitempty"`
	CreatedAt   time.Time `json:"createdAt"`
	UpdatedAt   time.Time `json:"updatedAt"`
	Repo        string    `json:"repo"` // owner/repo format
}

PRMetadata contains comprehensive PR metadata for import operations.

type PRStatus

type PRStatus struct {
	URL            string        `json:"url"`
	State          string        `json:"state"`
	Mergeable      bool          `json:"mergeable"`
	MergeableState string        `json:"mergeableState"`
	StatusChecks   []StatusCheck `json:"statusCheckRollup"`
	Comments       []Comment     `json:"comments"`
	Reviews        []Review      `json:"reviews"`
	Workflows      []WorkflowRun `json:"workflows"`
}

PRStatus represents the status of a PR.

type Review

type Review struct {
	ID        int             `json:"id"`
	State     string          `json:"state"` // APPROVED, CHANGES_REQUESTED, COMMENTED
	Body      string          `json:"body"`
	Author    string          `json:"author"`
	CreatedAt time.Time       `json:"createdAt"`
	Comments  []ReviewComment `json:"comments"`
}

Review represents a PR review.

type ReviewComment

type ReviewComment struct {
	ID           int       `json:"id"`
	Path         string    `json:"path"`
	Line         int       `json:"line"`
	OriginalLine int       `json:"originalLine"` // Fallback when Line is null
	Body         string    `json:"body"`
	Author       string    `json:"author"`
	CreatedAt    time.Time `json:"createdAt"`
	InReplyToID  int       `json:"inReplyToId"` // Non-zero if this is a reply to another comment
}

ReviewComment represents a comment on a specific line in a PR.

type ReviewContext

type ReviewContext struct {
	File        string // Path to the file being reviewed
	Line        int    // Line number in the file
	Reviewer    string // Username of the reviewer
	CommentID   int64  // ID of the review comment
	InReplyToID int64  // ID of parent comment if this is a reply (0 if not a reply)
}

ReviewContext holds context specific to review comments.

type SourceInfo

type SourceInfo struct {
	Type SourceType // The type of source (CI, workflow, review, comment)
	ID   string     // Unique identifier (comment ID, check run ID, workflow run ID)
	Name string     // Human-readable name (check name, workflow name, reviewer username)
	URL  string     // Link to the specific item
}

SourceInfo provides structured metadata about the source of feedback. It replaces the fragile Source string and parts of the Context map.

type SourceType

type SourceType string

SourceType categorizes the origin of feedback.

const (
	SourceTypeCI            SourceType = "ci"
	SourceTypeWorkflow      SourceType = "workflow"
	SourceTypeReviewComment SourceType = "review_comment"
	SourceTypeIssueComment  SourceType = "issue_comment"
)

type StatusCheck

type StatusCheck struct {
	Context     string    `json:"context"`
	State       string    `json:"state"`
	Description string    `json:"description"`
	TargetURL   string    `json:"targetUrl"`
	CreatedAt   time.Time `json:"createdAt"`
}

StatusCheck represents a PR status check.

type Step

type Step struct {
	Name       string `json:"name"`
	Status     string `json:"status"`
	Conclusion string `json:"conclusion"`
	Number     int    `json:"number"`
}

Step represents a step within a job.

type WorkflowContext

type WorkflowContext struct {
	WorkflowName  string // Name of the workflow
	FailureDetail string // Description of what failed
	RunID         int64  // Workflow run ID
	JobName       string // Name of the failed job (if available)
	StepName      string // Name of the failed step (if available)
}

WorkflowContext holds context specific to workflow run failures.

type WorkflowRun

type WorkflowRun struct {
	ID         int64     `json:"id"`
	Name       string    `json:"name"`
	Status     string    `json:"status"`     // completed, in_progress, queued
	Conclusion string    `json:"conclusion"` // success, failure, cancelled, skipped
	URL        string    `json:"url"`
	CreatedAt  time.Time `json:"createdAt"`
	UpdatedAt  time.Time `json:"updatedAt"`
	Jobs       []Job     `json:"jobs"`
}

WorkflowRun represents a GitHub Actions workflow run.

Jump to

Keyboard shortcuts

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