first implementation of the action

This commit is contained in:
Julien Fastré 2024-03-08 00:37:15 +01:00
parent 5c5d1fcf5b
commit cde3aa9ed6
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
6 changed files with 222 additions and 18 deletions

View File

@ -1 +1,5 @@
# Gitea action to Create a Pull Request
Gitea action to create a pull request.
Inspired by https://github.com/peter-evans/create-pull-request, but without the ability to commit the changes.

View File

@ -3,3 +3,25 @@ description: 'Create pull requests in gitea'
runs:
using: 'go'
main: 'main.go'
inputs:
title:
required: false
description: The title of the pull request
default: Changes by create-pull-request action
body:
required: false
description: The body of the pull request
default: Automated changes by create-pull-request Gitea action
labels:
description: 'A comma or newline separated list of labels.'
assignees:
description: 'A comma or newline separated list of assignees (GitHub usernames).'
base:
description: >
The pull request base branch.
required: true
outputs:
pull-request-number:
description: 'The pull request number'
pull-request-url:
description: 'The URL of the pull request.'

129
create-pull-request.go Normal file
View File

@ -0,0 +1,129 @@
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
}

1
go.mod
View File

@ -7,6 +7,7 @@ require (
github.com/davidmz/go-pageant v1.0.2 // indirect
github.com/go-fed/httpsig v1.1.0 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/sethvargo/go-githubactions v1.2.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/sys v0.15.0 // indirect
)

2
go.sum
View File

@ -8,6 +8,8 @@ github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sethvargo/go-githubactions v1.2.0 h1:Gbr36trCAj6uq7Rx1DolY1NTIg0wnzw3/N5WHdKIjME=
github.com/sethvargo/go-githubactions v1.2.0/go.mod h1:7/4WeHgYfSz9U5vwuToCK9KPnELVHAhGtRwLREOQV80=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=

82
main.go
View File

@ -1,33 +1,79 @@
package main
import (
"code.gitea.io/sdk/gitea"
"errors"
"fmt"
"os"
"github.com/sethvargo/go-githubactions"
"strconv"
"strings"
)
func main() {
fmt.Println("hello")
client, err := gitea.NewClient("https://gitea.champs-libres.be")
if nil != err {
fmt.Println("could not create a client, {}", err)
func ParseActionConfig() (*CreatePrConfig, error) {
base := githubactions.GetInput("base")
if base == "" {
return nil, errors.New("base branch name cannot be empty")
}
repos, _, err := client.ListOrgRepos("Chill-project", gitea.ListOrgReposOptions{})
if nil != err {
fmt.Printf("could not list repos, %#v\n", err.Error())
rawRepo := strings.Split(githubactions.GetInput("GITHUB_REPOSITORY"), "/")
if len(rawRepo) != 2 {
return nil, fmt.Errorf("incorrect number of string from string: %v, %d", githubactions.GetInput("GITHUB_REPOSITORY"), len(rawRepo))
}
for _, repo := range repos {
fmt.Printf("repository: %v\n", repo.FullName)
title := githubactions.GetInput("title")
if title == "" {
return nil, errors.New("title cannot be empty")
}
for _, e := range os.Environ() {
pair := strings.SplitN(e, "=", 2)
fmt.Println(pair[0])
body := githubactions.GetInput("body")
assigneesRaw := githubactions.GetInput("assignees")
assignees := []string{}
for _, a := range strings.Split(assigneesRaw, ",") {
assignees = append(assignees, strings.TrimSpace(a))
}
labelsRaw := githubactions.GetInput("labels")
labels := []string{}
for _, l := range strings.Split(labelsRaw, ",") {
labels = append(labels, strings.TrimSpace(l))
}
if githubactions.GetInput("GITHUB_REF_TYPE") != "branch" {
return nil, fmt.Errorf("only branch can create a pull request: %v given", githubactions.GetInput("GITHUB_REF_TYPE"))
}
return &CreatePrConfig{
Org: rawRepo[0],
Repo: rawRepo[1],
HeadBranch: githubactions.GetInput("GITHUB_REF_NAME"),
BaseBranch: base,
Title: title,
Body: body,
Assignees: assignees,
Labels: labels,
}, nil
}
func main() {
fmt.Println("Starting action CreatePullRequest, main")
token := githubactions.GetInput("GITHUB_TOKEN")
apiUrl := githubactions.GetInput("GITHUB_API_URL")
fmt.Printf("Api url is %v\n", apiUrl)
config, err := ParseActionConfig()
if err != nil {
githubactions.Fatalf("%v", err.Error())
}
pr, err := createPullRequest(apiUrl, token, *config)
if err != nil {
githubactions.Fatalf("Error while creating pr: %v", err.Error())
}
fmt.Printf("Created PR with id %d\n", pr.ID)
githubactions.SetOutput("pull-request-number", strconv.FormatInt(pr.Index, 10))
githubactions.SetOutput("pull-request-url", pr.URL)
}