| # Pull Request Capabilities |
| |
| This package now includes comprehensive pull request (PR) capabilities that support both GitHub and Gerrit platforms. The implementation provides a unified interface for managing pull requests across different code hosting platforms. |
| |
| ## Features |
| |
| - **Unified Interface**: Same API for both GitHub and Gerrit |
| - **Full CRUD Operations**: Create, read, update, delete pull requests |
| - **Advanced Filtering**: List pull requests with various filters |
| - **Merge Operations**: Support for different merge strategies |
| - **Error Handling**: Comprehensive error handling with detailed messages |
| - **Authentication**: Support for token-based and basic authentication |
| |
| ## Supported Platforms |
| |
| ### GitHub |
| - Uses GitHub REST API v3 |
| - Supports personal access tokens for authentication |
| - Full support for all pull request operations |
| - Handles GitHub-specific features like draft PRs, labels, assignees, and reviewers |
| |
| ### Gerrit |
| - Uses Gerrit REST API |
| - Supports HTTP password or API token authentication |
| - Maps Gerrit "changes" to pull requests |
| - Handles Gerrit-specific features like topics and review workflows |
| |
| ## Quick Start |
| |
| ### GitHub Example |
| |
| ```go |
| package main |
| |
| import ( |
| "context" |
| "github.com/iomodo/staff/git" |
| "net/http" |
| "time" |
| ) |
| |
| func main() { |
| ctx := context.Background() |
| |
| // Create GitHub configuration |
| githubConfig := git.GitHubConfig{ |
| Token: "your-github-token", |
| BaseURL: "https://api.github.com", |
| HTTPClient: &http.Client{Timeout: 30 * time.Second}, |
| } |
| |
| // Create GitHub provider |
| githubProvider := git.NewGitHubPullRequestProvider("owner", "repo", githubConfig) |
| |
| // Create Git instance with pull request capabilities |
| git := git.NewGitWithPullRequests("/path/to/repo", git.GitConfig{}, githubProvider) |
| |
| // Create a pull request |
| prOptions := git.PullRequestOptions{ |
| Title: "Add new feature", |
| Description: "This PR adds a new feature to the application.", |
| BaseBranch: "main", |
| HeadBranch: "feature/new-feature", |
| Labels: []string{"enhancement", "feature"}, |
| Assignees: []string{"username1", "username2"}, |
| Reviewers: []string{"reviewer1", "reviewer2"}, |
| Draft: false, |
| } |
| |
| pr, err := git.CreatePullRequest(ctx, prOptions) |
| if err != nil { |
| log.Fatal(err) |
| } |
| |
| fmt.Printf("Created pull request: %s (#%d)\n", pr.Title, pr.Number) |
| } |
| ``` |
| |
| ### Gerrit Example |
| |
| ```go |
| package main |
| |
| import ( |
| "context" |
| "github.com/iomodo/staff/git" |
| "net/http" |
| "time" |
| ) |
| |
| func main() { |
| ctx := context.Background() |
| |
| // Create Gerrit configuration |
| gerritConfig := git.GerritConfig{ |
| Username: "your-username", |
| Password: "your-http-password-or-api-token", |
| BaseURL: "https://gerrit.example.com", |
| HTTPClient: &http.Client{Timeout: 30 * time.Second}, |
| } |
| |
| // Create Gerrit provider |
| gerritProvider := git.NewGerritPullRequestProvider("project-name", gerritConfig) |
| |
| // Create Git instance with pull request capabilities |
| git := git.NewGitWithPullRequests("/path/to/repo", git.GitConfig{}, gerritProvider) |
| |
| // Create a change (pull request) |
| prOptions := git.PullRequestOptions{ |
| Title: "Add new feature", |
| Description: "This change adds a new feature to the application.", |
| BaseBranch: "master", |
| HeadBranch: "feature/new-feature", |
| } |
| |
| pr, err := git.CreatePullRequest(ctx, prOptions) |
| if err != nil { |
| log.Fatal(err) |
| } |
| |
| fmt.Printf("Created change: %s (#%d)\n", pr.Title, pr.Number) |
| } |
| ``` |
| |
| ## API Reference |
| |
| ### Types |
| |
| #### PullRequest |
| Represents a pull request or merge request across platforms. |
| |
| ```go |
| type PullRequest struct { |
| ID string |
| Number int |
| Title string |
| Description string |
| State string // "open", "closed", "merged" |
| Author Author |
| CreatedAt time.Time |
| UpdatedAt time.Time |
| BaseBranch string |
| HeadBranch string |
| BaseRepo string |
| HeadRepo string |
| Labels []string |
| Assignees []Author |
| Reviewers []Author |
| Commits []Commit |
| Comments []PullRequestComment |
| } |
| ``` |
| |
| #### PullRequestOptions |
| Options for creating or updating pull requests. |
| |
| ```go |
| type PullRequestOptions struct { |
| Title string |
| Description string |
| BaseBranch string |
| HeadBranch string |
| BaseRepo string |
| HeadRepo string |
| Labels []string |
| Assignees []string |
| Reviewers []string |
| Draft bool |
| } |
| ``` |
| |
| #### ListPullRequestOptions |
| Options for listing pull requests. |
| |
| ```go |
| type ListPullRequestOptions struct { |
| State string // "open", "closed", "all" |
| Author string |
| Assignee string |
| BaseBranch string |
| HeadBranch string |
| Labels []string |
| Limit int |
| } |
| ``` |
| |
| #### MergePullRequestOptions |
| Options for merging pull requests. |
| |
| ```go |
| type MergePullRequestOptions struct { |
| MergeMethod string // "merge", "squash", "rebase" |
| CommitTitle string |
| CommitMsg string |
| } |
| ``` |
| |
| ### Methods |
| |
| #### CreatePullRequest |
| Creates a new pull request. |
| |
| ```go |
| func (g *Git) CreatePullRequest(ctx context.Context, options PullRequestOptions) (*PullRequest, error) |
| ``` |
| |
| #### GetPullRequest |
| Retrieves a pull request by ID. |
| |
| ```go |
| func (g *Git) GetPullRequest(ctx context.Context, id string) (*PullRequest, error) |
| ``` |
| |
| #### ListPullRequests |
| Lists pull requests with optional filtering. |
| |
| ```go |
| func (g *Git) ListPullRequests(ctx context.Context, options ListPullRequestOptions) ([]PullRequest, error) |
| ``` |
| |
| #### UpdatePullRequest |
| Updates an existing pull request. |
| |
| ```go |
| func (g *Git) UpdatePullRequest(ctx context.Context, id string, options PullRequestOptions) (*PullRequest, error) |
| ``` |
| |
| #### ClosePullRequest |
| Closes a pull request. |
| |
| ```go |
| func (g *Git) ClosePullRequest(ctx context.Context, id string) error |
| ``` |
| |
| #### MergePullRequest |
| Merges a pull request. |
| |
| ```go |
| func (g *Git) MergePullRequest(ctx context.Context, id string, options MergePullRequestOptions) error |
| ``` |
| |
| ## Configuration |
| |
| ### GitHub Configuration |
| |
| ```go |
| type GitHubConfig struct { |
| Token string // GitHub personal access token |
| BaseURL string // GitHub API base URL (default: https://api.github.com) |
| HTTPClient *http.Client // Custom HTTP client (optional) |
| } |
| ``` |
| |
| ### Gerrit Configuration |
| |
| ```go |
| type GerritConfig struct { |
| Username string // Gerrit username |
| Password string // HTTP password or API token |
| BaseURL string // Gerrit instance URL |
| HTTPClient *http.Client // Custom HTTP client (optional) |
| } |
| ``` |
| |
| ## Error Handling |
| |
| All pull request operations return detailed error information through the `GitError` type: |
| |
| ```go |
| type GitError struct { |
| Command string |
| Output string |
| Err error |
| } |
| ``` |
| |
| Common error scenarios: |
| - Authentication failures |
| - Invalid repository or project names |
| - Network connectivity issues |
| - API rate limiting |
| - Invalid pull request data |
| |
| ## Platform-Specific Notes |
| |
| ### GitHub |
| - Requires a personal access token with appropriate permissions |
| - Supports draft pull requests |
| - Full support for labels, assignees, and reviewers |
| - Uses GitHub's REST API v3 |
| |
| ### Gerrit |
| - Requires HTTP password or API token |
| - Uses "changes" instead of "pull requests" |
| - Topics are used to group related changes |
| - Review workflow is more structured |
| - Uses Gerrit's REST API |
| |
| ## Examples |
| |
| See `pull_request_example.go` for comprehensive examples of using both GitHub and Gerrit providers. |
| |
| ## Testing |
| |
| Run the tests to ensure everything works correctly: |
| |
| ```bash |
| go test ./git/... -v |
| ``` |
| |
| ## Contributing |
| |
| When adding support for new platforms: |
| |
| 1. Implement the `PullRequestProvider` interface |
| 2. Add platform-specific configuration types |
| 3. Create conversion functions to map platform-specific data to our unified types |
| 4. Add comprehensive tests |
| 5. Update this documentation |
| |
| ## License |
| |
| This code is part of the staff project and follows the same licensing terms. |