diff --git a/create-pull-request.go b/create-pull-request.go deleted file mode 100644 index f87f903..0000000 --- a/create-pull-request.go +++ /dev/null @@ -1,129 +0,0 @@ -package main - -import ( - "code.gitea.io/sdk/gitea" - "slices" -) - -type Agent struct { - client *gitea.Client -} - -type CreatePrConfig struct { - // the organization where the PR is created - Org string - // the repository where the PR is created - Repo string - // the branch where the changes are made - HeadBranch string - // the branch where the changes will be added - BaseBranch string - // the title of the pull requests - Title string - // the body of the pull requests - Body string - // the list of assignees - Assignees []string - // the list of requested labels - Labels []string -} - -func (a *Agent) branchHasOpenPullRequest(config CreatePrConfig) (bool, error) { - currentPage := 1 - - for currentPage != 0 { - pulls, response, err := a.client.ListRepoPullRequests(config.Org, config.Repo, - gitea.ListPullRequestsOptions{State: gitea.StateOpen, ListOptions: gitea.ListOptions{Page: currentPage}}) - - if err != nil { - return true, err - } - - for _, p := range pulls { - if p.Head.Name == config.HeadBranch { - return true, nil - } - } - - currentPage = response.NextPage - } - - return false, nil -} - -func (a *Agent) labelsFromString(config CreatePrConfig) ([]gitea.Label, error) { - foundLabels := []gitea.Label{} - - currentPage := 1 - for currentPage != 0 { - labels, response, err := a.client.ListRepoLabels(config.Org, config.Repo, gitea.ListLabelsOptions{ListOptions: gitea.ListOptions{Page: currentPage}}) - - if err != nil { - return nil, err - } - - for _, label := range labels { - if slices.Contains(config.Labels, label.Name) { - foundLabels = append(foundLabels, *label) - } - } - - currentPage = response.NextPage - } - - return foundLabels, nil -} - -func (a *Agent) createPullRequestGitea(config CreatePrConfig) (*gitea.PullRequest, error) { - labelIds := []int64{} - labels, err := a.labelsFromString(config) - if err != nil { - return nil, err - } - - for _, label := range labels { - labelIds = append(labelIds, label.ID) - } - - if err != nil { - return nil, err - } - - pr, _, err := a.client.CreatePullRequest(config.Org, config.Repo, gitea.CreatePullRequestOption{ - Head: config.HeadBranch, - Base: config.BaseBranch, - Title: config.Title, - Body: config.Body, - Assignees: config.Assignees, - Labels: labelIds, - Deadline: nil, - }) - if err != nil { - return nil, err - } - - return pr, nil -} - -func createPullRequest(apiUrl string, token string, config CreatePrConfig) (*gitea.PullRequest, error) { - - client, _ := gitea.NewClient(apiUrl, gitea.SetToken(token)) - agent := &Agent{client: client} - - has, err := agent.branchHasOpenPullRequest(config) - if err != nil { - return nil, err - } - - if has { - return nil, nil - } - - pr, err := agent.createPullRequestGitea(config) - - if err != nil { - return nil, err - } - - return pr, nil -} diff --git a/main.go b/main.go index 7169b83..27bbbfc 100644 --- a/main.go +++ b/main.go @@ -1,14 +1,20 @@ package main import ( + "code.gitea.io/sdk/gitea" "errors" "fmt" "github.com/sethvargo/go-githubactions" + "slices" "strconv" "strings" ) func ParseActionConfig() (*CreatePrConfig, error) { + ctx, err := githubactions.Context() + if err != nil { + return nil, nil + } base := githubactions.GetInput("base") if base == "" { return nil, errors.New("base branch name cannot be empty") @@ -43,7 +49,7 @@ func ParseActionConfig() (*CreatePrConfig, error) { } return &CreatePrConfig{ - Org: rawRepo[0], + Org: ctx.RepositoryOwner, Repo: rawRepo[1], HeadBranch: githubactions.GetInput("GITHUB_REF_NAME"), BaseBranch: base, @@ -77,3 +83,156 @@ func main() { githubactions.SetOutput("pull-request-url", pr.URL) } + +// Agent which will perform changes on gitea +type Agent struct { + client *gitea.Client +} + +// CreatePrConfig represents the configuration for creating a pull request +type CreatePrConfig struct { + // the organization where the PR is created + Org string + // the repository where the PR is created + Repo string + // the branch where the changes are made + HeadBranch string + // the branch where the changes will be added + BaseBranch string + // the title of the pull requests + Title string + // the body of the pull requests + Body string + // the list of assignees + Assignees []string + // the list of requested labels + Labels []string +} + +// branchHasOpenPullRequest checks if there is an open pull request with the given branch name in a repository. +// It uses the Gitea client to list all open pull requests in the repository and checks if the branch name matches any of them. +// If a match is found, it returns true indicating that the branch has an open pull request. +// If there is an error listing the pull requests, it returns true along with the error. +// If there are no open pull requests with the branch name, it returns false. +// The method takes a CreatePrConfig struct as a parameter which contains the organization, repository, and branch details. +// It returns a boolean indicating if there is an open pull request and an error if any occurred. +func (a *Agent) branchHasOpenPullRequest(config CreatePrConfig) (bool, error) { + currentPage := 1 + + for currentPage != 0 { + pulls, response, err := a.client.ListRepoPullRequests(config.Org, config.Repo, + gitea.ListPullRequestsOptions{State: gitea.StateOpen, ListOptions: gitea.ListOptions{Page: currentPage}}) + + if err != nil { + return true, err + } + + for _, p := range pulls { + if p.Head.Name == config.HeadBranch { + return true, nil + } + } + + currentPage = response.NextPage + } + + return false, nil +} + +// labelsFromString retrieves a list of labels from a repository based on the provided configuration. +// It uses the Gitea client to list all labels in the repository and filters them based on the provided label names. +// The method takes a CreatePrConfig struct as a parameter which contains the organization, repository, and label details. +// It returns a slice of gitea.Label that matches the provided label names and an error if any occurred. +func (a *Agent) labelsFromString(config CreatePrConfig) ([]gitea.Label, error) { + foundLabels := []gitea.Label{} + + currentPage := 1 + for currentPage != 0 { + labels, response, err := a.client.ListRepoLabels(config.Org, config.Repo, gitea.ListLabelsOptions{ListOptions: gitea.ListOptions{Page: currentPage}}) + + if err != nil { + return nil, err + } + + for _, label := range labels { + if slices.Contains(config.Labels, label.Name) { + foundLabels = append(foundLabels, *label) + } + } + + currentPage = response.NextPage + } + + return foundLabels, nil +} + +// createPullRequestGitea creates a pull request in a Gitea repository based on the provided configuration. +// It retrieves the label IDs for the given labels and uses them when creating the pull request. +// The method takes a CreatePrConfig struct as a parameter which contains the organization, repository, and pull request details. +// It returns the created pull request and any error encountered during the process. +func (a *Agent) createPullRequestGitea(config CreatePrConfig) (*gitea.PullRequest, error) { + labelIds := []int64{} + labels, err := a.labelsFromString(config) + if err != nil { + return nil, err + } + + for _, label := range labels { + labelIds = append(labelIds, label.ID) + } + + if err != nil { + return nil, err + } + + pr, _, err := a.client.CreatePullRequest(config.Org, config.Repo, gitea.CreatePullRequestOption{ + Head: config.HeadBranch, + Base: config.BaseBranch, + Title: config.Title, + Body: config.Body, + Assignees: config.Assignees, + Labels: labelIds, + Deadline: nil, + }) + if err != nil { + return nil, err + } + + return pr, nil +} + +// createPullRequest takes in the API URL, access token, and configuration for creating a pull request. +// It initializes a Gitea client using the API URL and access token. +// It creates an instance of the Agent struct using the Gitea client. +// It checks if there is an open pull request with the given branch name in the repository using the branchHasOpenPullRequest method of Agent. +// If an open pull request already exists, it returns nil as the pull request and nil error. +// If no open pull request exists, it creates a new pull request using the createPullRequestGitea method of Agent. +// It returns the created pull request and nil error if successful. +// If there is an error while checking for existing pull requests or creating a new pull request, it returns nil as the pull request and the error. +// The function takes in the following parameters: +// - apiUrl: The URL of the Gitea API. +// - token: The access token for authenticating with the Gitea API. +// - config: The configuration for creating the pull request, including the organization, repository, branch details, title, body, assignees, and labels. +// It returns a pointer to the created pull request and an error. +func createPullRequest(apiUrl string, token string, config CreatePrConfig) (*gitea.PullRequest, error) { + + client, _ := gitea.NewClient(apiUrl, gitea.SetToken(token)) + agent := &Agent{client: client} + + has, err := agent.branchHasOpenPullRequest(config) + if err != nil { + return nil, err + } + + if has { + return nil, nil + } + + pr, err := agent.createPullRequestGitea(config) + + if err != nil { + return nil, err + } + + return pr, nil +}