From 358b8d696b47991417b1b4ae7491deb22bf02bc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 8 Mar 2024 11:56:17 +0100 Subject: [PATCH] Refactor code by merging create-pull-request.go into main.go The create-pull-request.go has been deleted and its functionalities have been incorporated into main.go. This refactor improves the code structure, by eliminating the file separation which was unnecessary. It maintains all original functionalities, including managing pull requests and labels on Gitea repositories. --- create-pull-request.go | 129 --------------------------------- main.go | 161 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 160 insertions(+), 130 deletions(-) delete mode 100644 create-pull-request.go 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 +}