github

package module
v0.0.0-...-e7f9bc8 Latest Latest
Warning

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

Go to latest
Published: Nov 22, 2025 License: MIT Imports: 6 Imported by: 0

README

GitHub

Idiomatic Go wrapper for GitHub operations with pluggable backend implementations (SDK and CLI providers).

Quick start

# Prerequisites: Go 1.25.3+
go get github.com/jmgilman/go/github

Hello world with SDK provider:

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/jmgilman/go/github"
    "github.com/jmgilman/go/github/providers/sdk"
)

func main() {
    // Create SDK provider with personal access token
    provider, err := sdk.NewSDKProvider(
        sdk.WithToken("ghp_xxxxxxxxxxxx"),
    )
    if err != nil {
        log.Fatal(err)
    }

    // Create client and fetch repository
    client := github.NewClient(provider, "myorg")
    repo := client.Repository("myrepo")

    ctx := context.Background()
    if err := repo.Get(ctx); err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Repository: %s\n", repo.FullName())
    fmt.Printf("Default Branch: %s\n", repo.DefaultBranch())
}

Usage

Common tasks:

// 1) Create and manage issues
issue, err := repo.CreateIssue(ctx, "Bug: Login validation",
    "The login form doesn't validate email addresses properly.",
    github.WithLabels("bug", "high-priority"),
    github.WithAssignees("developer1"),
)

// List open issues with specific labels
issues, err := repo.ListIssues(ctx,
    github.WithState("open"),
    github.WithIssueLabels("bug"),
)

// 2) Create and merge pull requests
pr, err := repo.CreatePullRequest(ctx, github.CreatePullRequestOptions{
    Title: "Add new feature",
    Body:  "This PR adds a new feature that...",
    Head:  "feature-branch",
    Base:  "main",
})

// Merge with squash
err = pr.Merge(ctx,
    github.WithMergeMethod("squash"),
    github.WithCommitMessage("Merge feature branch"),
)

// 3) Monitor workflows
run, err := repo.GetWorkflowRun(ctx, runID)
if err := run.Wait(ctx, 10*time.Second); err != nil {
    log.Fatal(err)
}

if !run.IsSuccessful() {
    jobs, _ := run.GetJobs(ctx)
    // Handle failed jobs
}

// 4) Use CLI provider (inherits gh CLI auth)
provider, err := cli.NewCLIProvider()
client := github.NewClient(provider, "myorg")

Configuration

Provider Selection
Provider Use Case Authentication
SDK Fine-grained control, existing go-github usage Personal access token or custom client
CLI Scripts, automation, environments with gh CLI Inherits from gh CLI config
SDK Provider Options
// With personal access token
provider, err := sdk.NewSDKProvider(
    sdk.WithToken("ghp_xxxxxxxxxxxx"),
)

// With custom GitHub client (for GitHub Apps, etc.)
provider, err := sdk.NewSDKProvider(
    sdk.WithClient(customGitHubClient),
)
CLI Provider Options
// Default (uses gh CLI authentication)
provider, err := cli.NewCLIProvider()

// With custom executor (for testing)
provider, err := cli.NewCLIProvider(
    cli.WithExecutor(mockExecutor),
)

Troubleshooting

  • Authentication failed: Verify token has required scopes (repo, workflow, etc.) for SDK provider. For CLI provider, run gh auth status to check gh CLI authentication.
  • Repository not found: Check repository name format (use "myrepo" not "owner/myrepo") and verify access permissions.
  • Rate limit exceeded: SDK provider respects GitHub API rate limits. Implement exponential backoff or use authenticated requests for higher limits.

Error Handling

All errors use the workspace errors library with consistent error codes:

repo := client.Repository("myrepo")
if err := repo.Get(ctx); err != nil {
    var platformErr errors.PlatformError
    if errors.As(err, &platformErr) {
        switch platformErr.Code() {
        case errors.CodeNotFound:
            fmt.Println("Repository not found")
        case errors.CodeUnauthorized:
            fmt.Println("Authentication failed")
        case errors.CodeForbidden:
            fmt.Println("Access denied")
        }
    }
}

Architecture

The library follows a layered architecture:

  1. Provider interface - Abstracts GitHub API implementation
  2. Two concrete providers - SDK (go-github) and CLI (gh CLI)
  3. High-level types - Client, Repository, Issue, PullRequest, WorkflowRun
  4. Escape hatches - Direct provider access for advanced use cases

Contributing

Submit issues and PRs to the workspace repository. Follow Go conventions and include tests for new features.

Testing

Use mock providers for testing:

import "github.com/jmgilman/go/github/testutil"

mockProvider := testutil.NewMockProvider()
mockProvider.OnGetRepository = func(ctx context.Context, owner, repo string) (*github.RepositoryData, error) {
    return &github.RepositoryData{
        ID:   123,
        Name: repo,
        Owner: owner,
    }, nil
}

client := github.NewClient(mockProvider, "testorg")

License

See workspace LICENSE file.

Documentation

Overview

Package github provides a clean, idiomatic wrapper around GitHub operations.

This library provides two pluggable backend implementations: one using the official Go GitHub SDK (go-github) and another using the gh CLI tool. The provider abstraction allows users to choose the implementation that best fits their needs while providing a consistent, high-level API for GitHub operations.

Architecture

The library is built on several key principles:

  1. Provider abstraction through the Provider interface
  2. Two concrete provider implementations (SDK and CLI)
  3. High-level types (Client, Repository, Issue, PullRequest, WorkflowRun)
  4. Escape hatches for accessing underlying implementations
  5. Consistent error handling using workspace errors library
  6. Context support for cancellation and timeouts

Core Types

Client is the main entry point and provides access to GitHub resources.

Repository represents a GitHub repository with methods for repository operations.

Provider interface abstracts the underlying implementation (SDK or CLI).

Provider Implementations

## SDK Provider

Uses the official google/go-github SDK for GitHub API operations. Best for applications that need fine-grained control or are already using go-github.

Authentication options:

  • Personal access token
  • Custom GitHub client (for advanced auth like GitHub Apps)

## CLI Provider

Uses the gh CLI tool for GitHub operations. Best for scripts, automation, or environments where gh CLI is already configured. Inherits authentication from gh CLI configuration.

Usage Examples

## Example 1: Using SDK Provider with Token

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/jmgilman/go/github"
    "github.com/jmgilman/go/github/providers/sdk"
)

func main() {
    // Create SDK provider with personal access token
    provider, err := sdk.NewSDKProvider(
        sdk.WithToken("ghp_xxxxxxxxxxxx"),
    )
    if err != nil {
        log.Fatal(err)
    }

    // Create client for organization
    client := github.NewClient(provider, "myorg")

    // Access repository
    repo := client.Repository("myrepo")

    // Fetch repository data
    ctx := context.Background()
    if err := repo.Get(ctx); err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Repository: %s\n", repo.FullName())
    fmt.Printf("Description: %s\n", repo.Description())
    fmt.Printf("Default Branch: %s\n", repo.DefaultBranch())
    fmt.Printf("Clone URL: %s\n", repo.CloneURL())
}

## Example 2: Using CLI Provider

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/jmgilman/go/github"
    "github.com/jmgilman/go/github/providers/cli"
)

func main() {
    // Create CLI provider (uses gh CLI authentication)
    provider, err := cli.NewCLIProvider()
    if err != nil {
        log.Fatal(err)
    }

    // Create GitHub client
    ghClient := github.NewClient(provider, "myorg")

    // List repositories
    ctx := context.Background()
    repos, err := client.Provider().ListRepositories(ctx, "myorg", github.ListOptions{
        PerPage: 10,
    })
    if err != nil {
        log.Fatal(err)
    }

    for _, repo := range repos {
        fmt.Printf("- %s\n", repo.FullName)
    }
}

## Example 3: Creating and Managing Issues (Phase 2)

func manageIssues(ctx context.Context, client *github.Client) error {
    repo := client.Repository("myrepo")

    // Create issue with labels
    issue, err := repo.CreateIssue(ctx,
        "Bug: Login form validation",
        "The login form doesn't validate email addresses properly.",
        github.WithLabels("bug", "high-priority"),
        github.WithAssignees("developer1"),
    )
    if err != nil {
        return err
    }

    fmt.Printf("Created issue #%d: %s\n", issue.Number(), issue.HTMLURL())

    // List open issues with specific labels
    issues, err := repo.ListIssues(ctx,
        github.WithState("open"),
        github.WithIssueLabels("bug"),
    )
    if err != nil {
        return err
    }

    for _, issue := range issues {
        fmt.Printf("#%d: %s\n", issue.Number(), issue.Title())
    }

    return nil
}

## Example 4: Managing Pull Requests (Phase 2)

func managePullRequests(ctx context.Context, client *github.Client) error {
    repo := client.Repository("myrepo")

    // Create pull request
    pr, err := repo.CreatePullRequest(ctx, github.CreatePullRequestOptions{
        Title: "Add new feature",
        Body:  "This PR adds a new feature that...",
        Head:  "feature-branch",
        Base:  "main",
        Draft: false,
    })
    if err != nil {
        return err
    }

    fmt.Printf("Created PR #%d: %s\n", pr.Number(), pr.HTMLURL())

    // Wait for checks to complete, then merge
    if err := pr.Refresh(ctx); err != nil {
        return err
    }

    if pr.IsMerged() {
        fmt.Println("Already merged")
        return nil
    }

    // Merge with squash
    err = pr.Merge(ctx,
        github.WithMergeMethod("squash"),
        github.WithCommitMessage("Merge feature branch"),
    )
    if err != nil {
        return err
    }

    fmt.Println("Pull request merged successfully")
    return nil
}

## Example 5: Monitoring Workflows (Phase 3)

func monitorWorkflow(ctx context.Context, repo *github.Repository, runID int64) error {
    // Get workflow run
    run, err := repo.GetWorkflowRun(ctx, runID)
    if err != nil {
        return err
    }

    fmt.Printf("Workflow: %s\n", run.Name())
    fmt.Printf("Status: %s\n", run.Status())

    // Poll until complete
    if err := run.Wait(ctx, 10*time.Second); err != nil {
        return err
    }

    // Check result
    if !run.IsSuccessful() {
        // Get job details
        jobs, err := run.GetJobs(ctx)
        if err != nil {
            return err
        }

        fmt.Println("Failed jobs:")
        for _, job := range jobs {
            if job.Conclusion != github.WorkflowConclusionSuccess {
                fmt.Printf("  - %s: %s\n", job.Name, job.Conclusion)
            }
        }

        return fmt.Errorf("workflow failed: %s", run.Conclusion())
    }

    fmt.Println("Workflow completed successfully")
    return nil
}

Error Handling

The library uses the workspace errors library for consistent error handling. All errors are wrapped with appropriate error codes:

  • ErrCodeNotFound: Repository, issue, PR, or workflow run not found
  • ErrCodeAuthenticationFailed: Invalid or missing authentication
  • ErrCodePermissionDenied: Insufficient permissions
  • ErrCodeRateLimited: API rate limit exceeded
  • ErrCodeInvalidInput: Invalid parameters
  • ErrCodeConflict: Resource conflict (already exists, merge conflict, etc.)
  • ErrCodeNetwork: Network or connectivity issues
  • ErrCodeInternal: Internal errors or unexpected responses

Example error handling:

repo := client.Repository("myrepo")
if err := repo.Get(ctx); err != nil {
    var platformErr errors.PlatformError
    if errors.As(err, &platformErr) {
        switch platformErr.Code() {
        case errors.CodeNotFound:
            fmt.Println("Repository not found")
        case errors.CodeUnauthorized:
            fmt.Println("Authentication failed")
        case errors.CodeForbidden:
            fmt.Println("Access denied")
        default:
            fmt.Printf("Error: %v\n", err)
        }
    }
    return err
}

Context and Cancellation

All operations that interact with GitHub accept a context.Context parameter for cancellation and timeout control:

// With timeout
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

repo := client.Repository("myrepo")
if err := repo.Get(ctx); err != nil {
    // Handle timeout or other errors
    return err
}

// With cancellation
ctx, cancel := context.WithCancel(context.Background())
go func() {
    // Cancel after some condition
    <-someChannel
    cancel()
}()

repos, err := client.Provider().ListRepositories(ctx, "myorg", github.ListOptions{})

Testing

The library provides testing utilities in the testutil sub-package:

import "github.com/jmgilman/go/github/testutil"

// Mock provider for testing
mockProvider := testutil.NewMockProvider()
mockProvider.OnGetRepository = func(ctx context.Context, owner, repo string) (*github.RepositoryData, error) {
    return &github.RepositoryData{
        ID:   123,
        Name: repo,
        Owner: owner,
    }, nil
}

client := github.NewClient(mockProvider, "testorg")
// Test your code with the mock provider

For testing CLI provider without gh CLI installed:

mockExecutor := testutil.NewMockExecutor()
mockExecutor.OnRun = func(args ...string) (*exec.Result, error) {
    return &exec.Result{
        Stdout: `{"id": 123, "name": "test"}`,
    }, nil
}

provider, err := cli.NewCLIProvider(cli.WithExecutor(mockExecutor))

Provider Interface

The Provider interface allows direct access to lower-level operations:

// Access provider directly for operations not wrapped by high-level types
provider := client.Provider()

// Direct provider calls
repos, err := provider.ListRepositories(ctx, "myorg", github.ListOptions{
    Page: 1,
    PerPage: 50,
})

Implementation Status

Phase 1 (Foundation) - Complete:

  • Provider interface
  • SDKProvider with repository operations
  • Client and Repository types
  • Error handling and options patterns

Phase 2 (Core Resources) - Planned:

  • Issue type and operations
  • PullRequest type and operations

Phase 3 (Workflows) - Planned:

  • WorkflowRun and WorkflowJob types
  • Workflow triggering and monitoring

Phase 4 (CLI Provider) - Planned:

  • CLIProvider implementation
  • CLI-based operations for all resource types

Dependencies

This library depends on:

  • github.com/google/go-github/v67 - Official GitHub SDK (for SDKProvider)
  • github.com/jmgilman/go/errors - Workspace errors library
  • github.com/jmgilman/go/exec - Workspace exec library (for CLIProvider)

References

For more information:

Package github provides a clean, idiomatic wrapper around GitHub operations.

Index

Constants

View Source
const (
	// ErrCodeNotFound indicates a requested resource was not found.
	ErrCodeNotFound = errors.CodeNotFound

	// ErrCodeAuthenticationFailed indicates authentication failure.
	ErrCodeAuthenticationFailed = errors.CodeUnauthorized

	// ErrCodePermissionDenied indicates insufficient permissions.
	ErrCodePermissionDenied = errors.CodeForbidden

	// ErrCodeRateLimited indicates rate limit exceeded.
	ErrCodeRateLimited = errors.CodeRateLimit

	// ErrCodeInvalidInput indicates invalid parameters or malformed data.
	ErrCodeInvalidInput = errors.CodeInvalidInput

	// ErrCodeConflict indicates a conflict (e.g., resource already exists).
	ErrCodeConflict = errors.CodeConflict

	// ErrCodeNetwork indicates network-related errors.
	ErrCodeNetwork = errors.CodeNetwork

	// ErrCodeInternal indicates internal errors.
	ErrCodeInternal = errors.CodeInternal
)

GitHub-specific error codes (use existing codes from errors library). These are convenience aliases for readability in GitHub context.

View Source
const (
	// StateOpen indicates an issue or pull request is open.
	StateOpen = "open"

	// StateClosed indicates an issue or pull request is closed.
	StateClosed = "closed"

	// StateAll is used for filtering to include all states.
	StateAll = "all"
)

State constants for issues and pull requests.

View Source
const (
	// WorkflowStatusQueued indicates a workflow run is queued.
	WorkflowStatusQueued = "queued"

	// WorkflowStatusInProgress indicates a workflow run is in progress.
	WorkflowStatusInProgress = "in_progress"

	// WorkflowStatusCompleted indicates a workflow run is completed.
	WorkflowStatusCompleted = "completed"
)

Workflow run statuses.

View Source
const (
	// WorkflowConclusionSuccess indicates successful completion.
	WorkflowConclusionSuccess = "success"

	// WorkflowConclusionFailure indicates the workflow failed.
	WorkflowConclusionFailure = "failure"

	// WorkflowConclusionCancelled indicates the workflow was cancelled.
	WorkflowConclusionCancelled = "cancelled"

	// WorkflowConclusionSkipped indicates the workflow was skipped.
	WorkflowConclusionSkipped = "skipped"

	// WorkflowConclusionTimedOut indicates the workflow timed out.
	WorkflowConclusionTimedOut = "timed_out"

	// WorkflowConclusionActionRequired indicates action is required.
	WorkflowConclusionActionRequired = "action_required"

	// WorkflowConclusionNeutral indicates a neutral conclusion.
	WorkflowConclusionNeutral = "neutral"
)

Workflow run conclusions.

View Source
const (
	// MergeMethodMerge creates a merge commit.
	MergeMethodMerge = "merge"

	// MergeMethodSquash squashes all commits into one.
	MergeMethodSquash = "squash"

	// MergeMethodRebase rebases and merges commits.
	MergeMethodRebase = "rebase"
)

Merge methods for pull requests.

Variables

This section is empty.

Functions

func ParseGitHubTime

func ParseGitHubTime(s string) (time.Time, error)

ParseGitHubTime parses a timestamp string from the GitHub API. GitHub uses RFC3339 format for timestamps.

func WrapHTTPError

func WrapHTTPError(err error, statusCode int, message string) error

WrapHTTPError wraps an error based on HTTP status code from GitHub API.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client provides high-level GitHub operations. It serves as the main entry point for interacting with GitHub resources.

Example usage:

// Create provider
provider, err := github.NewSDKProvider(github.SDKWithToken("ghp_..."))
if err != nil {
    log.Fatal(err)
}

// Create GitHub client
ghClient := github.NewClient(provider, "myorg")

// Access repositories
repo := client.Repository("myrepo")

func NewClient

func NewClient(provider Provider, owner string) *Client

NewClient creates a new GitHub client with the specified provider. The owner parameter sets a default owner for operations (can be overridden in individual method calls).

The owner is typically an organization name or username that will be used as the default for repository and other resource operations.

func (*Client) Owner

func (c *Client) Owner() string

Owner returns the default owner for this client.

func (*Client) Provider

func (c *Client) Provider() Provider

Provider returns the underlying Provider. This is an escape hatch that allows direct access to the provider for operations not covered by the high-level Client API.

func (*Client) Repository

func (c *Client) Repository(name string) *Repository

Repository returns a Repository instance for the given repository name. The repository name should not include the owner (e.g., "myrepo" not "owner/myrepo"). The repository uses the client's default owner unless overridden.

Note: This method does not validate that the repository exists. Call Get() on the returned Repository to fetch its data and ensure it exists.

type CreateIssueOptions

type CreateIssueOptions struct {
	// Title is the issue title (required)
	Title string

	// Body is the issue description
	Body string

	// Labels is the list of labels to apply
	Labels []string

	// Assignees is the list of usernames to assign
	Assignees []string

	// Milestone is the milestone name to assign
	Milestone string
}

CreateIssueOptions contains options for creating an issue.

type CreatePullRequestOptions

type CreatePullRequestOptions struct {
	// Title is the pull request title (required)
	Title string

	// Body is the pull request description
	Body string

	// Head is the name of the branch where changes are implemented (required)
	Head string

	// Base is the name of the branch to merge into (required)
	Base string

	// Draft indicates whether to create as a draft pull request
	Draft bool

	// MaintainerCanModify indicates whether maintainers can modify the pull request
	MaintainerCanModify bool
}

CreatePullRequestOptions contains options for creating a pull request.

type CreateRepositoryOptions

type CreateRepositoryOptions struct {
	// Name is the repository name (required)
	Name string

	// Description is the repository description
	Description string

	// Private indicates whether the repository should be private
	Private bool

	// AutoInit indicates whether to initialize with README
	AutoInit bool
}

CreateRepositoryOptions contains options for creating a repository.

type Issue

type Issue struct {
	// contains filtered or unexported fields
}

Issue represents a GitHub issue.

Issue instances are typically created through a Repository:

repo := client.Repository("myrepo")
issue, err := repo.CreateIssue(ctx, "Bug title", "Description",
    github.WithLabels("bug"),
)

Or by retrieving an existing issue:

issues, err := repo.ListIssues(ctx, github.WithState("open"))
for _, issue := range issues {
    fmt.Println(issue.Title())
}

func (*Issue) AddLabels

func (i *Issue) AddLabels(ctx context.Context, labels ...string) error

AddLabels adds labels to the issue. Labels that don't exist will be created.

func (*Issue) Assignees

func (i *Issue) Assignees() []string

Assignees returns the list of usernames assigned to the issue.

func (*Issue) Author

func (i *Issue) Author() string

Author returns the username of the issue creator.

func (*Issue) Body

func (i *Issue) Body() string

Body returns the issue body/description.

func (*Issue) Close

func (i *Issue) Close(ctx context.Context) error

Close closes the issue.

func (*Issue) Data

func (i *Issue) Data() *IssueData

Data returns the underlying issue data. This provides access to all issue fields including timestamps.

func (*Issue) HTMLURL

func (i *Issue) HTMLURL() string

HTMLURL returns the URL to view the issue on GitHub.

func (*Issue) IsClosed

func (i *Issue) IsClosed() bool

IsClosed returns true if the issue is closed.

func (*Issue) IsOpen

func (i *Issue) IsOpen() bool

IsOpen returns true if the issue is open.

func (*Issue) Labels

func (i *Issue) Labels() []string

Labels returns the list of labels applied to the issue.

func (*Issue) Milestone

func (i *Issue) Milestone() string

Milestone returns the milestone name (empty string if no milestone).

func (*Issue) Number

func (i *Issue) Number() int

Number returns the issue number.

func (*Issue) Refresh

func (i *Issue) Refresh(ctx context.Context) error

Refresh refreshes the issue data from GitHub.

func (*Issue) RemoveLabel

func (i *Issue) RemoveLabel(ctx context.Context, label string) error

RemoveLabel removes a label from the issue. No error if the label wasn't applied to the issue.

func (*Issue) State

func (i *Issue) State() string

State returns the issue state ("open" or "closed").

func (*Issue) Title

func (i *Issue) Title() string

Title returns the issue title.

func (*Issue) Update

func (i *Issue) Update(ctx context.Context, opts ...IssueUpdateOption) error

Update updates the issue with the provided options. Only non-nil fields in the options are updated.

Example:

err := issue.Update(ctx,
    github.WithTitle("New title"),
    github.WithIssueState("closed"),
)

type IssueData

type IssueData struct {
	// Identification
	Number int `json:"number"`

	// Content
	Title string `json:"title"`
	Body  string `json:"body"`

	// State and metadata
	State     string   `json:"state"`
	Author    string   `json:"author"`
	Labels    []string `json:"labels"`
	Assignees []string `json:"assignees"`
	Milestone string   `json:"milestone"`

	// URL
	HTMLURL string `json:"html_url"`

	// Timestamps
	CreatedAt time.Time  `json:"created_at"`
	UpdatedAt time.Time  `json:"updated_at"`
	ClosedAt  *time.Time `json:"closed_at,omitempty"`
}

IssueData contains issue information from the provider.

type IssueFilterOption

type IssueFilterOption func(*ListIssuesOptions)

IssueFilterOption configures issue filtering.

func WithAssignee

func WithAssignee(assignee string) IssueFilterOption

WithAssignee filters issues by assignee username.

func WithIssueLabels

func WithIssueLabels(labels ...string) IssueFilterOption

WithIssueLabels filters issues by labels (all must match).

func WithState

func WithState(state string) IssueFilterOption

WithState filters issues by state ("open", "closed", "all").

type IssueOption

type IssueOption func(*CreateIssueOptions)

IssueOption configures issue creation.

func WithAssignees

func WithAssignees(assignees ...string) IssueOption

WithAssignees sets assignees for an issue.

func WithLabels

func WithLabels(labels ...string) IssueOption

WithLabels sets labels for an issue.

func WithMilestone

func WithMilestone(milestone string) IssueOption

WithMilestone sets the milestone for an issue.

type IssueUpdateOption

type IssueUpdateOption func(*UpdateIssueOptions)

IssueUpdateOption configures issue updates.

func WithBody

func WithBody(body string) IssueUpdateOption

WithBody sets a new body for an issue.

func WithIssueState

func WithIssueState(state string) IssueUpdateOption

WithIssueState sets a new state for an issue.

func WithTitle

func WithTitle(title string) IssueUpdateOption

WithTitle sets a new title for an issue.

type ListIssuesOptions

type ListIssuesOptions struct {
	// State filters by issue state ("open", "closed", "all")
	State string

	// Labels filters by labels (all must match)
	Labels []string

	// Assignee filters by assignee username
	Assignee string

	// Since filters issues updated after this time
	Since *time.Time

	// ListOptions for pagination
	ListOptions
}

ListIssuesOptions contains options for listing issues.

type ListOptions

type ListOptions struct {
	// Page is the page number for pagination (1-indexed)
	Page int

	// PerPage is the number of items per page
	PerPage int
}

ListOptions contains options for list operations.

type ListPullRequestsOptions

type ListPullRequestsOptions struct {
	// State filters by pull request state ("open", "closed", "all")
	State string

	// Head filters by head branch (format: "user:ref-name" or "ref-name")
	Head string

	// Base filters by base branch
	Base string

	// ListOptions for pagination
	ListOptions
}

ListPullRequestsOptions contains options for listing pull requests.

type ListWorkflowRunsOptions

type ListWorkflowRunsOptions struct {
	// Branch filters by branch name
	Branch string

	// Event filters by event type (e.g., "push", "pull_request")
	Event string

	// Status filters by status ("queued", "in_progress", "completed")
	Status string

	// ListOptions for pagination
	ListOptions
}

ListWorkflowRunsOptions contains options for listing workflow runs.

type MergeOption

type MergeOption func(*MergePullRequestOptions)

MergeOption configures pull request merging.

func WithCommitMessage

func WithCommitMessage(message string) MergeOption

WithCommitMessage sets the message for the merge commit.

func WithCommitTitle

func WithCommitTitle(title string) MergeOption

WithCommitTitle sets the title for the merge commit.

func WithMergeMethod

func WithMergeMethod(method string) MergeOption

WithMergeMethod sets the merge method ("merge", "squash", "rebase").

type MergePullRequestOptions

type MergePullRequestOptions struct {
	// MergeMethod is the merge method to use ("merge", "squash", "rebase")
	MergeMethod string

	// CommitTitle is the title for the merge commit
	CommitTitle string

	// CommitMessage is the message for the merge commit
	CommitMessage string
}

MergePullRequestOptions contains options for merging a pull request.

type PRFilterOption

type PRFilterOption func(*ListPullRequestsOptions)

PRFilterOption configures pull request filtering.

func WithBase

func WithBase(base string) PRFilterOption

WithBase filters pull requests by base branch.

func WithHead

func WithHead(head string) PRFilterOption

WithHead filters pull requests by head branch.

func WithPRState

func WithPRState(state string) PRFilterOption

WithPRState filters pull requests by state ("open", "closed", "all").

type PRUpdateOption

type PRUpdateOption func(*UpdatePullRequestOptions)

PRUpdateOption configures pull request updates.

func WithPRBase

func WithPRBase(base string) PRUpdateOption

WithPRBase sets a new base branch for a pull request.

func WithPRBody

func WithPRBody(body string) PRUpdateOption

WithPRBody sets a new body for a pull request.

func WithPRTitle

func WithPRTitle(title string) PRUpdateOption

WithPRTitle sets a new title for a pull request.

func WithPRUpdateState

func WithPRUpdateState(state string) PRUpdateOption

WithPRUpdateState sets a new state for a pull request.

type Provider

type Provider interface {

	// GetRepository retrieves repository information.
	// Returns ErrNotFound if the repository doesn't exist.
	// Returns ErrAuthenticationFailed if authentication is invalid.
	// Returns ErrPermissionDenied if the user lacks access to the repository.
	GetRepository(ctx context.Context, owner, repo string) (*RepositoryData, error)

	// ListRepositories lists repositories for the given owner.
	// For organizations, this lists organization repositories.
	// For users, this lists user repositories.
	// Returns an empty slice if no repositories are found.
	ListRepositories(ctx context.Context, owner string, opts ListOptions) ([]*RepositoryData, error)

	// CreateRepository creates a new repository.
	// For organizations, creates an organization repository.
	// For users, creates a user repository.
	// Returns ErrConflict if a repository with the same name already exists.
	// Returns ErrInvalidInput if the repository name is invalid.
	CreateRepository(ctx context.Context, owner string, opts CreateRepositoryOptions) (*RepositoryData, error)

	// GetIssue retrieves a specific issue by number.
	// Returns ErrNotFound if the issue doesn't exist.
	GetIssue(ctx context.Context, owner, repo string, number int) (*IssueData, error)

	// ListIssues lists issues for a repository with optional filtering.
	// Returns an empty slice if no issues match the criteria.
	ListIssues(ctx context.Context, owner, repo string, opts ListIssuesOptions) ([]*IssueData, error)

	// CreateIssue creates a new issue.
	// Returns ErrInvalidInput if required fields are missing or invalid.
	CreateIssue(ctx context.Context, owner, repo string, opts CreateIssueOptions) (*IssueData, error)

	// UpdateIssue updates an existing issue.
	// Only non-nil fields in opts are updated.
	// Returns ErrNotFound if the issue doesn't exist.
	UpdateIssue(ctx context.Context, owner, repo string, number int, opts UpdateIssueOptions) (*IssueData, error)

	// CloseIssue closes an issue.
	// Returns ErrNotFound if the issue doesn't exist.
	CloseIssue(ctx context.Context, owner, repo string, number int) error

	// AddLabels adds labels to an issue.
	// Labels that don't exist will be created.
	// Returns ErrNotFound if the issue doesn't exist.
	AddLabels(ctx context.Context, owner, repo string, number int, labels []string) error

	// RemoveLabel removes a label from an issue.
	// No error if the label wasn't applied to the issue.
	// Returns ErrNotFound if the issue doesn't exist.
	RemoveLabel(ctx context.Context, owner, repo string, number int, label string) error

	// GetPullRequest retrieves a specific pull request by number.
	// Returns ErrNotFound if the pull request doesn't exist.
	GetPullRequest(ctx context.Context, owner, repo string, number int) (*PullRequestData, error)

	// ListPullRequests lists pull requests for a repository with optional filtering.
	// Returns an empty slice if no pull requests match the criteria.
	ListPullRequests(ctx context.Context, owner, repo string, opts ListPullRequestsOptions) ([]*PullRequestData, error)

	// CreatePullRequest creates a new pull request.
	// Returns ErrInvalidInput if required fields are missing or invalid.
	// Returns ErrConflict if a pull request already exists for the branch.
	CreatePullRequest(ctx context.Context, owner, repo string, opts CreatePullRequestOptions) (*PullRequestData, error)

	// UpdatePullRequest updates an existing pull request.
	// Only non-nil fields in opts are updated.
	// Returns ErrNotFound if the pull request doesn't exist.
	UpdatePullRequest(ctx context.Context, owner, repo string, number int, opts UpdatePullRequestOptions) (*PullRequestData, error)

	// MergePullRequest merges a pull request.
	// Returns ErrNotFound if the pull request doesn't exist.
	// Returns ErrConflict if the pull request cannot be merged (conflicts, checks failing, etc.).
	MergePullRequest(ctx context.Context, owner, repo string, number int, opts MergePullRequestOptions) error

	// GetWorkflowRun retrieves a specific workflow run by ID.
	// Returns ErrNotFound if the workflow run doesn't exist.
	GetWorkflowRun(ctx context.Context, owner, repo string, runID int64) (*WorkflowRunData, error)

	// ListWorkflowRuns lists workflow runs for a repository with optional filtering.
	// Returns an empty slice if no workflow runs match the criteria.
	ListWorkflowRuns(ctx context.Context, owner, repo string, opts ListWorkflowRunsOptions) ([]*WorkflowRunData, error)

	// GetWorkflowRunJobs retrieves the jobs for a specific workflow run.
	// Returns an empty slice if the workflow run has no jobs yet.
	// Returns ErrNotFound if the workflow run doesn't exist.
	GetWorkflowRunJobs(ctx context.Context, owner, repo string, runID int64) ([]*WorkflowJobData, error)

	// TriggerWorkflow manually triggers a workflow run.
	// workflowFileName is the filename of the workflow (e.g., "ci.yml").
	// ref is the git ref (branch, tag, or SHA) to run the workflow from.
	// inputs contains workflow inputs as key-value pairs (can be nil if workflow has no inputs).
	// Returns ErrNotFound if the workflow doesn't exist.
	// Returns ErrInvalidInput if required inputs are missing or invalid.
	TriggerWorkflow(ctx context.Context, owner, repo, workflowFileName string, ref string, inputs map[string]interface{}) error
}

Provider defines the interface for interacting with GitHub. Implementations include SDKProvider (using go-github) and CLIProvider (using gh CLI).

The provider interface abstracts the underlying GitHub API implementation, allowing users to choose between the official SDK or the gh CLI tool based on their needs. This design enables easy testing through mock implementations and provides flexibility in authentication and deployment scenarios.

All methods accept a context.Context as the first parameter for cancellation and timeout control. Methods return structured data types (e.g., RepositoryData, IssueData) that are independent of the underlying implementation.

Example using SDK provider:

provider, err := github.NewSDKProvider(github.SDKWithToken("ghp_..."))
if err != nil {
    log.Fatal(err)
}
repo, err := provider.GetRepository(ctx, "owner", "repo")

Example using CLI provider:

provider, err := github.NewCLIProvider()
if err != nil {
    log.Fatal(err)
}
issues, err := provider.ListIssues(ctx, "owner", "repo", ListIssuesOptions{State: "open"})

type PullRequest

type PullRequest struct {
	// contains filtered or unexported fields
}

PullRequest represents a GitHub pull request.

PullRequest instances are typically created through a Repository:

repo := client.Repository("myrepo")
pr, err := repo.CreatePullRequest(ctx, github.CreatePullRequestOptions{
    Title: "Add new feature",
    Body:  "Description of changes",
    Head:  "feature-branch",
    Base:  "main",
})

Or by retrieving existing pull requests:

prs, err := repo.ListPullRequests(ctx, github.WithPRState("open"))
for _, pr := range prs {
    fmt.Println(pr.Title())
}

func (*PullRequest) AddLabels

func (pr *PullRequest) AddLabels(ctx context.Context, labels ...string) error

AddLabels adds labels to the pull request. Labels that don't exist will be created.

func (*PullRequest) Author

func (pr *PullRequest) Author() string

Author returns the username of the pull request creator.

func (*PullRequest) BaseRef

func (pr *PullRequest) BaseRef() string

BaseRef returns the base branch name.

func (*PullRequest) Body

func (pr *PullRequest) Body() string

Body returns the pull request body/description.

func (*PullRequest) Data

func (pr *PullRequest) Data() *PullRequestData

Data returns the underlying pull request data. This provides access to all pull request fields including timestamps.

func (*PullRequest) HTMLURL

func (pr *PullRequest) HTMLURL() string

HTMLURL returns the URL to view the pull request on GitHub.

func (*PullRequest) HeadRef

func (pr *PullRequest) HeadRef() string

HeadRef returns the head branch name.

func (*PullRequest) HeadSHA

func (pr *PullRequest) HeadSHA() string

HeadSHA returns the commit SHA of the head branch.

func (*PullRequest) IsClosed

func (pr *PullRequest) IsClosed() bool

IsClosed returns true if the pull request is closed (either merged or closed without merging).

func (*PullRequest) IsDraft

func (pr *PullRequest) IsDraft() bool

IsDraft returns true if the pull request is a draft.

func (*PullRequest) IsMergeable

func (pr *PullRequest) IsMergeable() bool

IsMergeable returns true if the pull request can be merged. Returns false if mergeable status is unknown or if it can't be merged.

func (*PullRequest) IsMerged

func (pr *PullRequest) IsMerged() bool

IsMerged returns true if the pull request has been merged.

func (*PullRequest) IsOpen

func (pr *PullRequest) IsOpen() bool

IsOpen returns true if the pull request is open.

func (*PullRequest) Labels

func (pr *PullRequest) Labels() []string

Labels returns the list of labels applied to the pull request.

func (*PullRequest) Merge

func (pr *PullRequest) Merge(ctx context.Context, opts ...MergeOption) error

Merge merges the pull request with the provided options.

Example:

err := pr.Merge(ctx,
    github.WithMergeMethod("squash"),
    github.WithCommitMessage("Merge feature branch"),
)

func (*PullRequest) Number

func (pr *PullRequest) Number() int

Number returns the pull request number.

func (*PullRequest) Refresh

func (pr *PullRequest) Refresh(ctx context.Context) error

Refresh refreshes the pull request data from GitHub.

func (*PullRequest) RemoveLabel

func (pr *PullRequest) RemoveLabel(ctx context.Context, label string) error

RemoveLabel removes a label from the pull request. No error if the label wasn't applied to the pull request.

func (*PullRequest) State

func (pr *PullRequest) State() string

State returns the pull request state ("open", "closed", or "merged").

func (*PullRequest) Title

func (pr *PullRequest) Title() string

Title returns the pull request title.

func (*PullRequest) Update

func (pr *PullRequest) Update(ctx context.Context, opts ...PRUpdateOption) error

Update updates the pull request with the provided options. Only non-nil fields in the options are updated.

Example:

err := pr.Update(ctx,
    github.WithPRTitle("Updated title"),
    github.WithPRBody("Updated description"),
)

type PullRequestData

type PullRequestData struct {
	// Identification
	Number int `json:"number"`

	// Content
	Title string `json:"title"`
	Body  string `json:"body"`

	// Branch information
	HeadRef string `json:"head_ref"`
	BaseRef string `json:"base_ref"`
	HeadSHA string `json:"head_sha"`

	// State and metadata
	State     string   `json:"state"`
	Author    string   `json:"author"`
	Labels    []string `json:"labels"`
	Draft     bool     `json:"draft"`
	Mergeable *bool    `json:"mergeable,omitempty"`
	Merged    bool     `json:"merged"`

	// URL
	HTMLURL string `json:"html_url"`

	// Timestamps
	CreatedAt time.Time  `json:"created_at"`
	UpdatedAt time.Time  `json:"updated_at"`
	MergedAt  *time.Time `json:"merged_at,omitempty"`
	ClosedAt  *time.Time `json:"closed_at,omitempty"`
}

PullRequestData contains pull request information from the provider.

type Repository

type Repository struct {
	// contains filtered or unexported fields
}

Repository represents a GitHub repository and provides repository-scoped operations.

Repository instances are typically created through a Client:

client := github.NewClient(provider, "myorg")
repo := client.Repository("myrepo")

Call Get() to fetch the repository data:

if err := repo.Get(ctx); err != nil {
    log.Fatal(err)
}
fmt.Println("Repository:", repo.FullName())

func (*Repository) CloneURL

func (r *Repository) CloneURL() string

CloneURL returns the HTTPS clone URL. Returns empty string if repository data hasn't been fetched yet.

func (*Repository) CreateIssue

func (r *Repository) CreateIssue(ctx context.Context, title, body string, opts ...IssueOption) (*Issue, error)

CreateIssue creates a new issue in the repository.

Example:

issue, err := repo.CreateIssue(ctx, "Bug title", "Description",
    github.WithLabels("bug", "high-priority"),
    github.WithAssignees("user1"),
)

func (*Repository) CreatePullRequest

func (r *Repository) CreatePullRequest(ctx context.Context, opts CreatePullRequestOptions) (*PullRequest, error)

CreatePullRequest creates a new pull request in the repository.

Example:

pr, err := repo.CreatePullRequest(ctx, github.CreatePullRequestOptions{
    Title: "Add new feature",
    Body:  "This PR adds...",
    Head:  "feature-branch",
    Base:  "main",
})

func (*Repository) Data

func (r *Repository) Data() *RepositoryData

Data returns the underlying repository data. Returns nil if repository data hasn't been fetched yet. This provides access to all repository fields including timestamps.

func (*Repository) DefaultBranch

func (r *Repository) DefaultBranch() string

DefaultBranch returns the default branch name. Returns empty string if repository data hasn't been fetched yet.

func (*Repository) Description

func (r *Repository) Description() string

Description returns the repository description. Returns empty string if repository data hasn't been fetched yet.

func (*Repository) FullName

func (r *Repository) FullName() string

FullName returns the full repository name (owner/name). If repository data has been fetched, returns the data's full name. Otherwise, constructs it from owner and name.

func (*Repository) Get

func (r *Repository) Get(ctx context.Context) error

Get fetches the repository data from GitHub. This method must be called before accessing repository properties. Returns ErrNotFound if the repository doesn't exist.

func (*Repository) GetIssue

func (r *Repository) GetIssue(ctx context.Context, number int) (*Issue, error)

GetIssue retrieves a specific issue by number.

Example:

issue, err := repo.GetIssue(ctx, 42)

func (*Repository) GetPullRequest

func (r *Repository) GetPullRequest(ctx context.Context, number int) (*PullRequest, error)

GetPullRequest retrieves a specific pull request by number.

Example:

pr, err := repo.GetPullRequest(ctx, 42)

func (*Repository) GetWorkflowRun

func (r *Repository) GetWorkflowRun(ctx context.Context, runID int64) (*WorkflowRun, error)

GetWorkflowRun retrieves a specific workflow run by ID.

Example:

run, err := repo.GetWorkflowRun(ctx, 123456789)

func (*Repository) HTMLURL

func (r *Repository) HTMLURL() string

HTMLURL returns the URL to view the repository on GitHub. Returns empty string if repository data hasn't been fetched yet.

func (*Repository) IsArchived

func (r *Repository) IsArchived() bool

IsArchived returns true if the repository is archived. Returns false if repository data hasn't been fetched yet.

func (*Repository) IsFork

func (r *Repository) IsFork() bool

IsFork returns true if the repository is a fork. Returns false if repository data hasn't been fetched yet.

func (*Repository) IsPrivate

func (r *Repository) IsPrivate() bool

IsPrivate returns true if the repository is private. Returns false if repository data hasn't been fetched yet.

func (*Repository) ListIssues

func (r *Repository) ListIssues(ctx context.Context, opts ...IssueFilterOption) ([]*Issue, error)

ListIssues lists issues in the repository with optional filtering.

Example:

issues, err := repo.ListIssues(ctx,
    github.WithState("open"),
    github.WithIssueLabels("bug"),
)

func (*Repository) ListPullRequests

func (r *Repository) ListPullRequests(ctx context.Context, opts ...PRFilterOption) ([]*PullRequest, error)

ListPullRequests lists pull requests in the repository with optional filtering.

Example:

prs, err := repo.ListPullRequests(ctx,
    github.WithPRState("open"),
    github.WithBase("main"),
)

func (*Repository) ListWorkflowRuns

func (r *Repository) ListWorkflowRuns(ctx context.Context, opts ...WorkflowFilterOption) ([]*WorkflowRun, error)

ListWorkflowRuns lists workflow runs in the repository with optional filtering.

Example:

runs, err := repo.ListWorkflowRuns(ctx,
    github.WithStatus("completed"),
    github.WithBranch("main"),
)

func (*Repository) Name

func (r *Repository) Name() string

Name returns the repository name (without owner).

func (*Repository) Owner

func (r *Repository) Owner() string

Owner returns the repository owner (organization or username).

func (*Repository) Refresh

func (r *Repository) Refresh(ctx context.Context) error

Refresh refreshes the repository data from GitHub. This is an alias for Get() that makes the intent clearer when updating existing data.

func (*Repository) SSHURL

func (r *Repository) SSHURL() string

SSHURL returns the SSH clone URL. Returns empty string if repository data hasn't been fetched yet.

func (*Repository) TriggerWorkflow

func (r *Repository) TriggerWorkflow(ctx context.Context, workflowFileName, ref string, inputs map[string]interface{}) error

TriggerWorkflow manually triggers a workflow run. workflowFileName is the filename of the workflow (e.g., "ci.yml"). ref is the git ref (branch, tag, or SHA) to run the workflow from. inputs contains workflow inputs as key-value pairs (can be nil if workflow has no inputs).

Example:

err := repo.TriggerWorkflow(ctx, "ci.yml", "main", map[string]interface{}{
    "environment": "production",
    "debug": true,
})

type RepositoryData

type RepositoryData struct {
	// Identification
	ID       int64  `json:"id"`
	Owner    string `json:"owner"`
	Name     string `json:"name"`
	FullName string `json:"full_name"`

	// Metadata
	Description   string `json:"description"`
	DefaultBranch string `json:"default_branch"`
	Private       bool   `json:"private"`
	Fork          bool   `json:"fork"`
	Archived      bool   `json:"archived"`

	// URLs
	CloneURL string `json:"clone_url"`
	SSHURL   string `json:"ssh_url"`
	HTMLURL  string `json:"html_url"`

	// Timestamps
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

RepositoryData contains repository information from the provider.

type UpdateIssueOptions

type UpdateIssueOptions struct {
	// Title is the new issue title
	Title *string

	// Body is the new issue body
	Body *string

	// State is the new issue state ("open" or "closed")
	State *string

	// Labels is the new list of labels (replaces existing)
	Labels []string

	// Assignees is the new list of assignees (replaces existing)
	Assignees []string
}

UpdateIssueOptions contains options for updating an issue.

type UpdatePullRequestOptions

type UpdatePullRequestOptions struct {
	// Title is the new pull request title
	Title *string

	// Body is the new pull request body
	Body *string

	// State is the new pull request state ("open" or "closed")
	State *string

	// Base is the new base branch
	Base *string
}

UpdatePullRequestOptions contains options for updating a pull request.

type WorkflowFilterOption

type WorkflowFilterOption func(*ListWorkflowRunsOptions)

WorkflowFilterOption configures workflow run filtering.

func WithBranch

func WithBranch(branch string) WorkflowFilterOption

WithBranch filters workflow runs by branch name.

func WithEvent

func WithEvent(event string) WorkflowFilterOption

WithEvent filters workflow runs by event type.

func WithStatus

func WithStatus(status string) WorkflowFilterOption

WithStatus filters workflow runs by status.

type WorkflowJob

type WorkflowJob struct {
	// contains filtered or unexported fields
}

WorkflowJob represents a GitHub Actions workflow job.

WorkflowJob instances are typically retrieved through a WorkflowRun:

run, err := repo.GetWorkflowRun(ctx, 123456789)
jobs, err := run.GetJobs(ctx)
for _, job := range jobs {
    fmt.Printf("Job: %s - %s\n", job.Name(), job.Conclusion())
}

func (*WorkflowJob) CompletedAt

func (wj *WorkflowJob) CompletedAt() *time.Time

CompletedAt returns when the job completed (nil if not completed).

func (*WorkflowJob) Conclusion

func (wj *WorkflowJob) Conclusion() string

Conclusion returns the job conclusion ("success", "failure", "cancelled", etc.).

func (*WorkflowJob) Data

func (wj *WorkflowJob) Data() *WorkflowJobData

Data returns the underlying workflow job data. This provides access to all job fields including step details.

func (*WorkflowJob) ID

func (wj *WorkflowJob) ID() int64

ID returns the unique identifier for the job.

func (*WorkflowJob) IsCancelled

func (wj *WorkflowJob) IsCancelled() bool

IsCancelled returns true if the job was cancelled.

func (*WorkflowJob) IsComplete

func (wj *WorkflowJob) IsComplete() bool

IsComplete returns true if the job has completed.

func (*WorkflowJob) IsFailed

func (wj *WorkflowJob) IsFailed() bool

IsFailed returns true if the job failed.

func (*WorkflowJob) IsSuccessful

func (wj *WorkflowJob) IsSuccessful() bool

IsSuccessful returns true if the job completed successfully.

func (*WorkflowJob) Name

func (wj *WorkflowJob) Name() string

Name returns the name of the job.

func (*WorkflowJob) RunID

func (wj *WorkflowJob) RunID() int64

RunID returns the workflow run ID this job belongs to.

func (*WorkflowJob) StartedAt

func (wj *WorkflowJob) StartedAt() *time.Time

StartedAt returns when the job started (nil if not started).

func (*WorkflowJob) Status

func (wj *WorkflowJob) Status() string

Status returns the job status ("queued", "in_progress", "completed").

func (*WorkflowJob) Steps

func (wj *WorkflowJob) Steps() []WorkflowStepData

Steps returns the list of steps in the job.

type WorkflowJobData

type WorkflowJobData struct {
	// Identification
	ID    int64 `json:"id"`
	RunID int64 `json:"run_id"`

	// Content
	Name string `json:"name"`

	// Status and conclusion
	Status     string `json:"status"`
	Conclusion string `json:"conclusion,omitempty"`

	// Steps
	Steps []WorkflowStepData `json:"steps"`

	// Timestamps
	StartedAt   *time.Time `json:"started_at,omitempty"`
	CompletedAt *time.Time `json:"completed_at,omitempty"`
}

WorkflowJobData contains individual job information.

type WorkflowRun

type WorkflowRun struct {
	// contains filtered or unexported fields
}

WorkflowRun represents a GitHub Actions workflow run.

WorkflowRun instances are typically created through a Repository:

repo := client.Repository("myrepo")
run, err := repo.GetWorkflowRun(ctx, 123456789)

Or by listing workflow runs:

runs, err := repo.ListWorkflowRuns(ctx, github.WithWorkflowStatus("completed"))
for _, run := range runs {
    fmt.Printf("Run #%d: %s - %s\n", run.RunNumber(), run.Status(), run.Conclusion())
}

func (*WorkflowRun) Conclusion

func (wr *WorkflowRun) Conclusion() string

Conclusion returns the run conclusion ("success", "failure", "cancelled", etc.). Only meaningful when Status() is "completed".

func (*WorkflowRun) Data

func (wr *WorkflowRun) Data() *WorkflowRunData

Data returns the underlying workflow run data. This provides access to all workflow run fields including timestamps.

func (*WorkflowRun) Event

func (wr *WorkflowRun) Event() string

Event returns the event that triggered the workflow (e.g., "push", "pull_request").

func (*WorkflowRun) GetJobs

func (wr *WorkflowRun) GetJobs(ctx context.Context) ([]*WorkflowJob, error)

GetJobs retrieves the jobs for this workflow run.

func (*WorkflowRun) HTMLURL

func (wr *WorkflowRun) HTMLURL() string

HTMLURL returns the URL to view the workflow run on GitHub.

func (*WorkflowRun) HeadBranch

func (wr *WorkflowRun) HeadBranch() string

HeadBranch returns the branch that triggered the workflow.

func (*WorkflowRun) HeadSHA

func (wr *WorkflowRun) HeadSHA() string

HeadSHA returns the commit SHA that triggered the workflow.

func (*WorkflowRun) ID

func (wr *WorkflowRun) ID() int64

ID returns the unique identifier for the workflow run.

func (*WorkflowRun) IsCancelled

func (wr *WorkflowRun) IsCancelled() bool

IsCancelled returns true if the workflow run was cancelled.

func (*WorkflowRun) IsComplete

func (wr *WorkflowRun) IsComplete() bool

IsComplete returns true if the workflow run has completed.

func (*WorkflowRun) IsFailed

func (wr *WorkflowRun) IsFailed() bool

IsFailed returns true if the workflow run failed.

func (*WorkflowRun) IsInProgress

func (wr *WorkflowRun) IsInProgress() bool

IsInProgress returns true if the workflow run is in progress.

func (*WorkflowRun) IsQueued

func (wr *WorkflowRun) IsQueued() bool

IsQueued returns true if the workflow run is queued.

func (*WorkflowRun) IsSuccessful

func (wr *WorkflowRun) IsSuccessful() bool

IsSuccessful returns true if the workflow run completed successfully.

func (*WorkflowRun) Name

func (wr *WorkflowRun) Name() string

Name returns the name of the workflow.

func (*WorkflowRun) Refresh

func (wr *WorkflowRun) Refresh(ctx context.Context) error

Refresh refreshes the workflow run data from GitHub.

func (*WorkflowRun) RunNumber

func (wr *WorkflowRun) RunNumber() int

RunNumber returns the sequential run number for this workflow.

func (*WorkflowRun) Status

func (wr *WorkflowRun) Status() string

Status returns the run status ("queued", "in_progress", "completed").

func (*WorkflowRun) Wait

func (wr *WorkflowRun) Wait(ctx context.Context, pollInterval time.Duration) error

Wait polls the workflow run until it completes or the context is cancelled. The pollInterval parameter specifies how often to check the status.

Example:

// Wait for workflow to complete, checking every 10 seconds
err := run.Wait(ctx, 10*time.Second)
if err != nil {
    log.Fatal(err)
}
if run.IsSuccessful() {
    fmt.Println("Workflow succeeded!")
}

func (*WorkflowRun) WorkflowID

func (wr *WorkflowRun) WorkflowID() int64

WorkflowID returns the ID of the workflow definition.

type WorkflowRunData

type WorkflowRunData struct {
	// Identification
	ID         int64 `json:"id"`
	WorkflowID int64 `json:"workflow_id"`
	RunNumber  int   `json:"run_number"`

	// Content
	Name string `json:"name"`

	// Status and conclusion
	Status     string `json:"status"`
	Conclusion string `json:"conclusion,omitempty"` // Only set when Status is "completed"

	// Trigger information
	HeadBranch string `json:"head_branch"`
	HeadSHA    string `json:"head_sha"`
	Event      string `json:"event"` // e.g., "push", "pull_request"

	// URL
	HTMLURL string `json:"html_url"`

	// Timestamps
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

WorkflowRunData contains workflow run information.

type WorkflowStepData

type WorkflowStepData struct {
	// Identification
	Number int `json:"number"`

	// Content
	Name string `json:"name"`

	// Status and conclusion
	Status     string `json:"status"`
	Conclusion string `json:"conclusion,omitempty"`

	// Timestamps
	StartedAt   *time.Time `json:"started_at,omitempty"`
	CompletedAt *time.Time `json:"completed_at,omitempty"`
}

WorkflowStepData contains step information.

Directories

Path Synopsis
providers
cli
sdk
Package sdk provides a GitHub provider implementation using the go-github SDK.
Package sdk provides a GitHub provider implementation using the go-github SDK.

Jump to

Keyboard shortcuts

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