2
1
forked from adamm/autogits

1 Commits

Author SHA256 Message Date
fa61af0db6 Implement detection for local repositories
Repositories which build against another repo in the same project need
to do so also in the forked project. This is eg for consuming rpms
from one repo in an image build from same project.
2025-05-05 11:26:07 +02:00
125 changed files with 2004 additions and 12983 deletions

View File

@@ -1,15 +1,13 @@
all: build all: build
api.json:: api.json:
curl -o api.json https://src.opensuse.org/swagger.v1.json curl -o api.json https://src.opensuse.org/swagger.v1.json
gitea-generated/client/gitea_api_client.go: api.json gitea-generated/client/gitea_api_client.go:: api.json
[ -d gitea-generated ] || mkdir gitea-generated [ -d gitea-generated ] || mkdir gitea-generated
podman run --rm -v $$(pwd)/..:/api ghcr.io/go-swagger/go-swagger generate client -f /api/common/api.json -t /api/common/gitea-generated podman run --rm -v $$(pwd):/api ghcr.io/go-swagger/go-swagger generate client -f /api/api.json -t /api/gitea-generated
swagger: gitea-generated/client/gitea_api_client.go api: gitea-generated/client/gitea_api_client.go mock_gitea_utils.go
api:
go generate go generate
build: api build: api

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,7 @@ type BasicPR struct {
Num int64 Num int64
} }
var validOrgAndRepoRx *regexp.Regexp = regexp.MustCompile("^[A-Za-z0-9_\\.-]+$") var validOrgAndRepoRx *regexp.Regexp = regexp.MustCompile("^[A-Za-z0-9_-]+$")
func parsePrLine(line string) (BasicPR, error) { func parsePrLine(line string) (BasicPR, error) {
var ret BasicPR var ret BasicPR

View File

@@ -58,11 +58,6 @@ type AutogitConfig struct {
Branch string // branch name of PkgGit that aligns with PrjGit submodules Branch string // branch name of PkgGit that aligns with PrjGit submodules
Reviewers []string // only used by `pr` workflow Reviewers []string // only used by `pr` workflow
ReviewGroups []ReviewGroup ReviewGroups []ReviewGroup
Committers []string // group in addition to Reviewers and Maintainers that can order the bot around, mostly as helper for factory-maintainers
Subdirs []string // list of directories to sort submodules into. Needed b/c _manifest cannot list non-existent directories
ManualMergeOnly bool // only merge with "Merge OK" comment by Project Maintainers and/or Package Maintainers and/or reviewers
ManualMergeProject bool // require merge of ProjectGit PRs with "Merge OK" by ProjectMaintainers and/or reviewers
} }
type AutogitConfigs []*AutogitConfig type AutogitConfigs []*AutogitConfig
@@ -100,7 +95,7 @@ type GiteaFileContentAndRepoFetcher interface {
GiteaRepoFetcher GiteaRepoFetcher
} }
func UnmarshalWorkflowConfig(data []byte) (*AutogitConfig, error) { func PartiallyParseWorkflowConfig(data []byte) (*AutogitConfig, error) {
var config AutogitConfig var config AutogitConfig
data, err := hujson.Standardize(data) data, err := hujson.Standardize(data)
if err != nil { if err != nil {
@@ -135,7 +130,7 @@ func ReadWorkflowConfig(gitea GiteaFileContentAndRepoFetcher, git_project string
return nil, fmt.Errorf("Error fetching 'workflow.config' for %s/%s#%s: %w", a[0], prjGitRepo, branch, err) return nil, fmt.Errorf("Error fetching 'workflow.config' for %s/%s#%s: %w", a[0], prjGitRepo, branch, err)
} }
config, err := UnmarshalWorkflowConfig(data) config, err := PartiallyParseWorkflowConfig(data)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -229,9 +224,8 @@ func (config *AutogitConfig) GetRemoteBranch() string {
} }
type StagingConfig struct { type StagingConfig struct {
ObsProject string ObsProject string
RebuildAll bool RebuildAll bool
CleanupDelay int // cleanup delay, in hours, for unmerged closed PRs (def: 48)
// if set, then only use pull request numbers as unique identifiers // if set, then only use pull request numbers as unique identifiers
StagingProject string StagingProject string
@@ -244,7 +238,6 @@ func ParseStagingConfig(data []byte) (*StagingConfig, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
staging.CleanupDelay = 48
if err := json.Unmarshal(data, &staging); err != nil { if err := json.Unmarshal(data, &staging); err != nil {
return nil, err return nil, err
} }

View File

@@ -10,62 +10,6 @@ import (
mock_common "src.opensuse.org/autogits/common/mock" mock_common "src.opensuse.org/autogits/common/mock"
) )
func TestProjectConfigMatcher(t *testing.T) {
configs := common.AutogitConfigs{
{
Organization: "test",
GitProjectName: "test/prjgit#main",
},
{
Organization: "test",
Branch: "main",
GitProjectName: "test/prjgit#main",
},
}
tests := []struct {
name string
org string
repo string
branch string
config int
}{
{
name: "invalid match",
org: "foo",
repo: "bar",
config: -1,
},
{
name: "default branch",
org: "test",
repo: "foo",
branch: "",
config: 0,
},
{
name: "main branch",
org: "test",
repo: "foo",
branch: "main",
config: 1,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
c := configs.GetPrjGitConfig(test.org, test.repo, test.branch)
if test.config < 0 {
if c != nil {
t.Fatal("Expected nil. Got:", *c)
}
} else if config := configs[test.config]; c != config {
t.Fatal("Expected", *config, "got", *c)
}
})
}
}
func TestConfigWorkflowParser(t *testing.T) { func TestConfigWorkflowParser(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
@@ -97,14 +41,10 @@ func TestConfigWorkflowParser(t *testing.T) {
gitea.EXPECT().GetRepositoryFileContent("foo", "bar", "", "workflow.config").Return([]byte(test.config_json), "abc", nil) gitea.EXPECT().GetRepositoryFileContent("foo", "bar", "", "workflow.config").Return([]byte(test.config_json), "abc", nil)
gitea.EXPECT().GetRepository("foo", "bar").Return(&test.repo, nil) gitea.EXPECT().GetRepository("foo", "bar").Return(&test.repo, nil)
config, err := common.ReadWorkflowConfig(gitea, "foo/bar") _, err := common.ReadWorkflowConfig(gitea, "foo/bar")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if config.ManualMergeOnly != false {
t.Fatal("This should be false")
}
}) })
} }
} }
@@ -142,7 +82,7 @@ func TestProjectGitParser(t *testing.T) {
res: [3]string{"oorg", "foo.bar", "point"}, res: [3]string{"oorg", "foo.bar", "point"},
}, },
{ {
name: "whitespace shouldn't matter", name: "whitespace shouldn't matter",
prjgit: " oorg / \nfoo.bar\t # point ", prjgit: " oorg / \nfoo.bar\t # point ",
res: [3]string{"oorg", "foo.bar", "point"}, res: [3]string{"oorg", "foo.bar", "point"},
}, },

View File

@@ -33,6 +33,3 @@ const (
TopicApp = "src" TopicApp = "src"
) )
// when set, pushing to remote does not happen, and other remote side-effects should also not happen
var IsDryRun bool

View File

@@ -28,7 +28,6 @@ import (
"os/exec" "os/exec"
"path" "path"
"path/filepath" "path/filepath"
"slices"
"strings" "strings"
"sync" "sync"
) )
@@ -44,10 +43,6 @@ type GitStatusLister interface {
GitStatus(cwd string) ([]GitStatusData, error) GitStatus(cwd string) ([]GitStatusData, error)
} }
type GitDiffLister interface {
GitDiff(cwd, base, head string) (string, error)
}
type Git interface { type Git interface {
// error if git, but wrong remote // error if git, but wrong remote
GitClone(repo, branch, remoteUrl string) (string, error) // clone, or check if path is already checked out remote and force pulls, error otherwise. Return remotename, errror GitClone(repo, branch, remoteUrl string) (string, error) // clone, or check if path is already checked out remote and force pulls, error otherwise. Return remotename, errror
@@ -67,8 +62,6 @@ type Git interface {
GitExecOrPanic(cwd string, params ...string) GitExecOrPanic(cwd string, params ...string)
GitExec(cwd string, params ...string) error GitExec(cwd string, params ...string) error
GitExecWithOutput(cwd string, params ...string) (string, error) GitExecWithOutput(cwd string, params ...string) (string, error)
GitDiffLister
} }
type GitHandlerImpl struct { type GitHandlerImpl struct {
@@ -139,7 +132,6 @@ func (s *gitHandlerGeneratorImpl) CreateGitHandler(org string) (Git, error) {
} }
func (s *gitHandlerGeneratorImpl) ReadExistingPath(org string) (Git, error) { func (s *gitHandlerGeneratorImpl) ReadExistingPath(org string) (Git, error) {
LogDebug("Locking git org:", org)
s.lock_lock.Lock() s.lock_lock.Lock()
defer s.lock_lock.Unlock() defer s.lock_lock.Unlock()
@@ -161,7 +153,6 @@ func (s *gitHandlerGeneratorImpl) ReadExistingPath(org string) (Git, error) {
func (s *gitHandlerGeneratorImpl) ReleaseLock(org string) { func (s *gitHandlerGeneratorImpl) ReleaseLock(org string) {
m, ok := s.lock[org] m, ok := s.lock[org]
if ok { if ok {
LogDebug("Unlocking git org:", org)
m.Unlock() m.Unlock()
} }
} }
@@ -205,26 +196,19 @@ func (refs *GitReferences) addReference(id, branch string) {
} }
func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) (string, error) { func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) (string, error) {
LogDebug("Cloning", remoteUrl, " repo:", repo, " branch:", branch)
remoteUrlComp, err := ParseGitRemoteUrl(remoteUrl) remoteUrlComp, err := ParseGitRemoteUrl(remoteUrl)
if err != nil { if err != nil {
return "", fmt.Errorf("Cannot parse remote URL: %w", err) return "", fmt.Errorf("Cannot parse remote URL: %w", err)
} }
remoteBranch := "HEAD" if len(branch) == 0 {
if len(branch) == 0 && remoteUrlComp != nil {
branch = remoteUrlComp.Commit branch = remoteUrlComp.Commit
remoteBranch = branch }
} else if len(branch) > 0 { if len(branch) == 0 {
remoteBranch = branch branch = "HEAD"
} }
remoteName := remoteUrlComp.RemoteName() remoteName := remoteUrlComp.RemoteName()
if remoteUrlComp != nil { LogDebug("Clone", *remoteUrlComp, " -> ", remoteName)
LogDebug("Clone", *remoteUrlComp, " -> ", remoteName)
} else {
LogDebug("Clone", "[default] -> ", remoteName)
}
remoteRef := remoteName + "/" + remoteBranch
if fi, err := os.Stat(path.Join(e.GitPath, repo)); os.IsNotExist(err) { if fi, err := os.Stat(path.Join(e.GitPath, repo)); os.IsNotExist(err) {
if err = e.GitExec("", "clone", "--origin", remoteName, remoteUrl, repo); err != nil { if err = e.GitExec("", "clone", "--origin", remoteName, remoteUrl, repo); err != nil {
return remoteName, err return remoteName, err
@@ -238,39 +222,9 @@ func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) (string, error
e.GitExecOrPanic(repo, "remote", "set-url", remoteName, remoteUrl) e.GitExecOrPanic(repo, "remote", "set-url", remoteName, remoteUrl)
} }
// check if we have submodule to deinit e.GitExecOrPanic(repo, "fetch", remoteName, branch)
if list, _ := e.GitSubmoduleList(repo, "HEAD"); len(list) > 0 {
e.GitExecOrPanic(repo, "submodule", "deinit", "--all", "--force")
}
e.GitExecOrPanic(repo, "fetch", "--prune", remoteName, remoteBranch)
} }
return remoteName, e.GitExec(repo, "checkout", "-B", branch, "refs/remotes/"+remoteName+"/"+branch)
refsBytes, err := os.ReadFile(path.Join(e.GitPath, repo, ".git/refs/remotes", remoteName, "HEAD"))
if err != nil {
LogError("Cannot read HEAD of remote", remoteName)
return remoteName, fmt.Errorf("Cannot read HEAD of remote %s", remoteName)
}
refs := string(refsBytes)
if refs[0:5] != "ref: " {
LogError("Unexpected format of remote HEAD ref:", refs)
return remoteName, fmt.Errorf("Unexpected format of remote HEAD ref: %s", refs)
}
if len(branch) == 0 || branch == "HEAD" {
remoteRef = strings.TrimSpace(refs[5:])
branch = remoteRef[strings.LastIndex(remoteRef, "/")+1:]
LogDebug("remoteRef", remoteRef)
LogDebug("branch", branch)
}
args := []string{"fetch", "--prune", remoteName, branch}
if strings.TrimSpace(e.GitExecWithOutputOrPanic(repo, "rev-parse", "--is-shallow-repository")) == "true" {
args = slices.Insert(args, 1, "--unshallow")
}
e.GitExecOrPanic(repo, args...)
return remoteName, e.GitExec(repo, "checkout", "--track", "-B", branch, remoteRef)
} }
func (e *GitHandlerImpl) GitBranchHead(gitDir, branchName string) (string, error) { func (e *GitHandlerImpl) GitBranchHead(gitDir, branchName string) (string, error) {
@@ -292,7 +246,6 @@ func (e *GitHandlerImpl) GitRemoteHead(gitDir, remote, branchName string) (strin
} }
func (e *GitHandlerImpl) Close() error { func (e *GitHandlerImpl) Close() error {
LogDebug("Unlocking git lock")
e.lock.Unlock() e.lock.Unlock()
return nil return nil
} }
@@ -353,7 +306,7 @@ func (e *GitHandlerImpl) GitExecWithOutput(cwd string, params ...string) (string
cmd.Dir = filepath.Join(e.GitPath, cwd) cmd.Dir = filepath.Join(e.GitPath, cwd)
cmd.Stdin = nil cmd.Stdin = nil
LogDebug("git execute @", cwd, ":", cmd.Args) LogDebug("git execute:", cmd.Args)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
LogDebug(string(out)) LogDebug(string(out))
if err != nil { if err != nil {
@@ -493,29 +446,21 @@ func parseGitMsg(data <-chan byte) (GitMsg, error) {
}, nil }, nil
} }
func parseGitCommitHdr(oldHdr [2]string, data <-chan byte) ([2]string, int, error) { func parseGitCommitHdr(data <-chan byte) ([2]string, error) {
hdr := make([]byte, 0, 60) hdr := make([]byte, 0, 60)
val := make([]byte, 0, 1000) val := make([]byte, 0, 1000)
c := <-data c := <-data
size := 1
if c != '\n' { // end of header marker if c != '\n' { // end of header marker
for ; c != ' '; c = <-data { for ; c != ' '; c = <-data {
hdr = append(hdr, c) hdr = append(hdr, c)
size++
}
if size == 1 { // continuation header here
hdr = []byte(oldHdr[0])
val = append([]byte(oldHdr[1]), '\n')
} }
for c := <-data; c != '\n'; c = <-data { for c := <-data; c != '\n'; c = <-data {
val = append(val, c) val = append(val, c)
size++
} }
size++
} }
return [2]string{string(hdr), string(val)}, size, nil return [2]string{string(hdr), string(val)}, nil
} }
func parseGitCommitMsg(data <-chan byte, l int) (string, error) { func parseGitCommitMsg(data <-chan byte, l int) (string, error) {
@@ -525,6 +470,7 @@ func parseGitCommitMsg(data <-chan byte, l int) (string, error) {
msg = append(msg, c) msg = append(msg, c)
l-- l--
} }
// l--
if l != 0 { if l != 0 {
return "", fmt.Errorf("Unexpected data in the git commit msg: l=%d", l) return "", fmt.Errorf("Unexpected data in the git commit msg: l=%d", l)
@@ -544,14 +490,12 @@ func parseGitCommit(data <-chan byte) (GitCommit, error) {
var c GitCommit var c GitCommit
l := hdr.size l := hdr.size
for { for {
var hdr [2]string hdr, err := parseGitCommitHdr(data)
hdr, size, err := parseGitCommitHdr(hdr, data)
if err != nil { if err != nil {
return GitCommit{}, nil return GitCommit{}, nil
} }
l -= size
if size == 1 { if len(hdr[0])+len(hdr[1]) == 0 { // hdr end marker
break break
} }
@@ -559,7 +503,10 @@ func parseGitCommit(data <-chan byte) (GitCommit, error) {
case "tree": case "tree":
c.Tree = hdr[1] c.Tree = hdr[1]
} }
l -= len(hdr[0]) + len(hdr[1]) + 2
} }
l--
c.Msg, err = parseGitCommitMsg(data, l) c.Msg, err = parseGitCommitMsg(data, l)
return c, err return c, err
@@ -648,7 +595,7 @@ func (e *GitHandlerImpl) GitParseCommits(cwd string, commitIDs []string) (parsed
var done sync.Mutex var done sync.Mutex
done.Lock() done.Lock()
data_in, data_out := ChanIO{make(chan byte)}, ChanIO{make(chan byte)} data_in, data_out := ChanIO{make(chan byte, 256)}, ChanIO{make(chan byte, 70)}
parsedCommits = make([]GitCommit, 0, len(commitIDs)) parsedCommits = make([]GitCommit, 0, len(commitIDs))
go func() { go func() {
@@ -682,12 +629,7 @@ func (e *GitHandlerImpl) GitParseCommits(cwd string, commitIDs []string) (parsed
return len(data), nil return len(data), nil
}) })
LogDebug("command run:", cmd.Args) LogDebug("command run:", cmd.Args)
if e := cmd.Run(); e != nil { err = cmd.Run()
LogError(e)
close(data_in.ch)
close(data_out.ch)
return nil, e
}
done.Lock() done.Lock()
return return
@@ -698,7 +640,7 @@ func (e *GitHandlerImpl) GitCatFile(cwd, commitId, filename string) (data []byte
var done sync.Mutex var done sync.Mutex
done.Lock() done.Lock()
data_in, data_out := ChanIO{make(chan byte)}, ChanIO{make(chan byte)} data_in, data_out := ChanIO{make(chan byte, 256)}, ChanIO{make(chan byte, 70)}
go func() { go func() {
defer done.Unlock() defer done.Unlock()
@@ -752,7 +694,6 @@ func (e *GitHandlerImpl) GitCatFile(cwd, commitId, filename string) (data []byte
}) })
LogDebug("command run:", cmd.Args) LogDebug("command run:", cmd.Args)
if e := cmd.Run(); e != nil { if e := cmd.Run(); e != nil {
LogError(e)
close(data_in.ch) close(data_in.ch)
close(data_out.ch) close(data_out.ch)
return nil, e return nil, e
@@ -767,9 +708,7 @@ func (e *GitHandlerImpl) GitSubmoduleList(gitPath, commitId string) (submoduleLi
submoduleList = make(map[string]string) submoduleList = make(map[string]string)
done.Lock() done.Lock()
data_in, data_out := ChanIO{make(chan byte)}, ChanIO{make(chan byte)} data_in, data_out := ChanIO{make(chan byte, 256)}, ChanIO{make(chan byte, 70)}
LogDebug("Getting submodules for:", commitId)
go func() { go func() {
defer done.Unlock() defer done.Unlock()
@@ -827,19 +766,14 @@ func (e *GitHandlerImpl) GitSubmoduleList(gitPath, commitId string) (submoduleLi
return len(data), nil return len(data), nil
}) })
LogDebug("command run:", cmd.Args) LogDebug("command run:", cmd.Args)
if e := cmd.Run(); e != nil { err = cmd.Run()
LogError(e)
close(data_in.ch)
close(data_out.ch)
return submoduleList, e
}
done.Lock() done.Lock()
return submoduleList, err return submoduleList, err
} }
func (e *GitHandlerImpl) GitSubmoduleCommitId(cwd, packageName, commitId string) (subCommitId string, valid bool) { func (e *GitHandlerImpl) GitSubmoduleCommitId(cwd, packageName, commitId string) (subCommitId string, valid bool) {
data_in, data_out := ChanIO{make(chan byte)}, ChanIO{make(chan byte)} data_in, data_out := ChanIO{make(chan byte, 256)}, ChanIO{make(chan byte, 70)}
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(1) wg.Add(1)
@@ -848,7 +782,7 @@ func (e *GitHandlerImpl) GitSubmoduleCommitId(cwd, packageName, commitId string)
go func() { go func() {
defer func() { defer func() {
if recover() != nil { if recover() != nil {
subCommitId = "" subCommitId = "wrong"
commitId = "ok" commitId = "ok"
valid = false valid = false
} }
@@ -895,15 +829,12 @@ func (e *GitHandlerImpl) GitSubmoduleCommitId(cwd, packageName, commitId string)
return len(data), nil return len(data), nil
}) })
LogDebug("command run:", cmd.Args) LogDebug("command run:", cmd.Args)
if e := cmd.Run(); e != nil { if err := cmd.Run(); err != nil {
LogError(e) LogError("Error running command:", cmd.Args, err)
close(data_in.ch)
close(data_out.ch)
return subCommitId, false
} }
wg.Wait() wg.Wait()
return subCommitId, len(subCommitId) > 0 return subCommitId, len(subCommitId) == len(commitId)
} }
const ( const (
@@ -918,16 +849,6 @@ type GitStatusData struct {
Path string Path string
Status int Status int
States [3]string States [3]string
/*
<sub> A 4 character field describing the submodule state.
"N..." when the entry is not a submodule.
"S<c><m><u>" when the entry is a submodule.
<c> is "C" if the commit changed; otherwise ".".
<m> is "M" if it has tracked changes; otherwise ".".
<u> is "U" if there are untracked changes; otherwise ".".
*/
SubmoduleChanges string
} }
func parseGitStatusHexString(data io.ByteReader) (string, error) { func parseGitStatusHexString(data io.ByteReader) (string, error) {
@@ -950,20 +871,6 @@ func parseGitStatusHexString(data io.ByteReader) (string, error) {
} }
} }
func parseGitStatusString(data io.ByteReader) (string, error) { func parseGitStatusString(data io.ByteReader) (string, error) {
str := make([]byte, 0, 100)
for {
c, err := data.ReadByte()
if err != nil {
return "", errors.New("Unexpected EOF. Expected NUL string term")
}
if c == 0 || c == ' ' {
return string(str), nil
}
str = append(str, c)
}
}
func parseGitStatusStringWithSpace(data io.ByteReader) (string, error) {
str := make([]byte, 0, 100) str := make([]byte, 0, 100)
for { for {
c, err := data.ReadByte() c, err := data.ReadByte()
@@ -1004,7 +911,7 @@ func parseSingleStatusEntry(data io.ByteReader) (*GitStatusData, error) {
return nil, err return nil, err
} }
ret.Status = GitStatus_Modified ret.Status = GitStatus_Modified
ret.Path, err = parseGitStatusStringWithSpace(data) ret.Path, err = parseGitStatusString(data)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -1014,11 +921,11 @@ func parseSingleStatusEntry(data io.ByteReader) (*GitStatusData, error) {
return nil, err return nil, err
} }
ret.Status = GitStatus_Renamed ret.Status = GitStatus_Renamed
ret.Path, err = parseGitStatusStringWithSpace(data) ret.Path, err = parseGitStatusString(data)
if err != nil { if err != nil {
return nil, err return nil, err
} }
ret.States[0], err = parseGitStatusStringWithSpace(data) ret.States[0], err = parseGitStatusString(data)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -1028,7 +935,7 @@ func parseSingleStatusEntry(data io.ByteReader) (*GitStatusData, error) {
return nil, err return nil, err
} }
ret.Status = GitStatus_Untracked ret.Status = GitStatus_Untracked
ret.Path, err = parseGitStatusStringWithSpace(data) ret.Path, err = parseGitStatusString(data)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -1038,22 +945,15 @@ func parseSingleStatusEntry(data io.ByteReader) (*GitStatusData, error) {
return nil, err return nil, err
} }
ret.Status = GitStatus_Ignored ret.Status = GitStatus_Ignored
ret.Path, err = parseGitStatusStringWithSpace(data) ret.Path, err = parseGitStatusString(data)
if err != nil { if err != nil {
return nil, err return nil, err
} }
case 'u': case 'u':
var err error var err error
if err = skipGitStatusEntry(data, 2); err != nil { if err = skipGitStatusEntry(data, 7); err != nil {
return nil, err return nil, err
} }
if ret.SubmoduleChanges, err = parseGitStatusString(data); err != nil {
return nil, err
}
if err = skipGitStatusEntry(data, 4); err != nil {
return nil, err
}
if ret.States[0], err = parseGitStatusHexString(data); err != nil { if ret.States[0], err = parseGitStatusHexString(data); err != nil {
return nil, err return nil, err
} }
@@ -1064,7 +964,7 @@ func parseSingleStatusEntry(data io.ByteReader) (*GitStatusData, error) {
return nil, err return nil, err
} }
ret.Status = GitStatus_Unmerged ret.Status = GitStatus_Unmerged
ret.Path, err = parseGitStatusStringWithSpace(data) ret.Path, err = parseGitStatusString(data)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -1111,26 +1011,3 @@ func (e *GitHandlerImpl) GitStatus(cwd string) (ret []GitStatusData, err error)
return parseGitStatusData(bufio.NewReader(bytes.NewReader(out))) return parseGitStatusData(bufio.NewReader(bytes.NewReader(out)))
} }
func (e *GitHandlerImpl) GitDiff(cwd, base, head string) (string, error) {
LogDebug("getting diff from", base, "..", head)
cmd := exec.Command("/usr/bin/git", "diff", base+".."+head)
cmd.Env = []string{
"GIT_CEILING_DIRECTORIES=" + e.GitPath,
"GIT_LFS_SKIP_SMUDGE=1",
"GIT_CONFIG_GLOBAL=/dev/null",
}
cmd.Dir = filepath.Join(e.GitPath, cwd)
cmd.Stderr = writeFunc(func(data []byte) (int, error) {
LogError(string(data))
return len(data), nil
})
LogDebug("command run:", cmd.Args)
out, err := cmd.Output()
if err != nil {
LogError("Error running command", cmd.Args, err)
}
return string(out), nil
}

View File

@@ -54,8 +54,6 @@ func TestGitClone(t *testing.T) {
}, },
} }
return
execPath, err := os.Getwd() execPath, err := os.Getwd()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@@ -200,7 +198,7 @@ committer Adam Majer <amajer@suse.com> 1720709149 +0200
}) })
t.Run("parse multiline headers", func(t *testing.T) { t.Run("parse multiline headers", func(t *testing.T) {
const commitData = "cae5831ab48470ff060a5aaa12eb6e5a7acaf91e commit 1492\000" + const commitData = "cae5831ab48470ff060a5aaa12eb6e5a7acaf91e commit 1491\x00" +
`tree 1f9c8fe8099615d6d3921528402ac53f09213b02 `tree 1f9c8fe8099615d6d3921528402ac53f09213b02
parent e08a654fae0ecc91678819e0b62a2e014bad3339 parent e08a654fae0ecc91678819e0b62a2e014bad3339
author Yagiz Nizipli <yagiz@nizipli.com> 1720967314 -0400 author Yagiz Nizipli <yagiz@nizipli.com> 1720967314 -0400
@@ -232,7 +230,7 @@ Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ulises Gascón <ulisesgascongonzalez@gmail.com> Reviewed-By: Ulises Gascón <ulisesgascongonzalez@gmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com> Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>` + "\000" Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>` + "\x00"
ch := make(chan byte, 5000) ch := make(chan byte, 5000)
for _, b := range []byte(commitData) { for _, b := range []byte(commitData) {
@@ -253,51 +251,6 @@ Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>` + "\000"
} }
}) })
t.Run("parse multiline headers", func(t *testing.T) {
const commitData = "c07c52c57a10fb355956df3caad2986613838f149274fbe312ad76560764829d commit 1150\000" + `tree 3e06b280ea056141ed5e8af9794a41ae5281930c45321803eab53a240cb60044
parent 19362a2cecb1fd25a89e03611d08ac68dcb1732f9dc0a68a40926356787fa4ca
author Adrian Schröter <adrian@suse.de> 1746600403 +0200
committer Adrian Schröter <adrian@suse.de> 1746600403 +0200
gpgsig-sha256 -----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEE1QF1zm/pNbvyhgLFkY2MlUwI22cFAmgbAd0ACgkQkY2MlUwI
22dxtA//eUCzIqxVdaEnOrFeTyxKig/mCOjaAyctmwr0vXUyElRtjXe4TzVG3QtR
uDfhIrKYLZ2tU/0TewTW/4XopWxLuqEzVQLrjuYl7K5P3GoYk52W1yGT0szzm7/i
87j4UdRL9YGU/gYO7nSzstcfTP6AcmYzVUoOnwYR0K2vyOVjO4niL3mFXxLkIgIt
jd82xcE4JpQz9Yjyq2nDdz4A55kLAwsqY+dOct4oC6bZmj1/JeoGQfPvUsvsQgcI
syCHVh0GBxjvSv50V/VPzxQTFMal/TdtvAD4kmP/9RDi/5THzus8Peam8pV0gEIC
Q15ZcuLwIsC9i7ifUDYgzLgBBRdpSI0qji4Y6clWULPVjsyghgyfQw1trBSySpC8
O1XfajUM+rXyrBLP6kzY+zl/zyzRdJ8JhljmC+SmNuyyEB77Hkn83k0f+aBhhqC2
4b3fIsKtwJZ1w6gr6SSz1BottiT9ShQzRaL8iRoF/2l5MkHPR+QFg2J7EIBqCbCQ
hFUjdvWAXQBWkkTQlJmLmJBXDOLQg3o6xCbnZM0gPFjZWE7e3Mpky7H0+xPnoeg9
ukuvkexXQ6yrdiekA7HRLc76Te/I0m7KDOOWZ3rbJV6uH/3ps4FbLQTZO12AtZ6J
n8hYdYfw9yjCxiKUjnEtXtDRe8DJpqv+hO0Wj4MI5gIA2JE2lzY=
=Keg5
-----END PGP SIGNATURE-----
dummy change, don't merge
` + "\000"
ch := make(chan byte)
go func() {
for _, b := range []byte(commitData) {
ch <- b
}
}()
commit, err := parseGitCommit(ch)
if err != nil {
t.Error(err)
}
if commit.Tree != "3e06b280ea056141ed5e8af9794a41ae5281930c45321803eab53a240cb60044" {
t.Errorf("Invalid commit object: %#v", commit)
}
if commit.Msg != "dummy change, don't merge\n" {
t.Errorf("Invalid commit msg: '%s'", commit.Msg)
}
})
t.Run("parse tree object", func(t *testing.T) { t.Run("parse tree object", func(t *testing.T) {
const treeData = "\x31\x61\x30\x35\x64\x62\x37\x33\x36\x39\x33\x37\x34\x33\x30\x65\x31\x38\x64\x66\x34\x33\x61\x32\x37\x61\x39\x38\x30\x30\x31\x30\x31\x32\x65\x31\x65\x64\x32\x30\x34\x38\x32\x39\x38\x36\x37\x31\x32\x38\x66\x32\x63\x65\x38\x34\x30\x36\x62\x35\x63\x66\x63\x39\x20\x74\x72\x65\x65\x20\x32\x30\x35\x00\x34\x30\x30\x30\x30\x20\x62\x6f\x74\x73\x2d\x63\x6f\x6d\x6d\x6f\x6e\x00\x93\x17\xaa\x47\xf6\xea\x37\xe8\xbc\xe2\x80\x77\x57\x90\xf4\xa8\x01\xd7\xe3\x70\x2f\x84\xfb\xe1\xb0\x0e\x4a\x2c\x1c\x75\x2c\x2b\x34\x30\x30\x30\x30\x20\x6f\x62\x73\x2d\x73\x74\x61\x67\x69\x6e\x67\x2d\x62\x6f\x74\x00\x79\x77\x8b\x28\x7d\x37\x10\x59\xb9\x71\x28\x36\xed\x20\x31\x5f\xfb\xe1\xed\xb5\xba\x4f\x5e\xbb\x65\x65\x68\x23\x77\x32\x58\xfe\x34\x30\x30\x30\x30\x20\x70\x72\x2d\x72\x65\x76\x69\x65\x77\x00\x36\x0d\x45\xcb\x76\xb8\x93\xb3\x21\xba\xfa\xd5\x00\x9d\xfc\x59\xab\x88\xc1\x3c\x81\xcb\x48\x5a\xe0\x29\x29\x0f\xe3\x6b\x3c\x5e\x34\x30\x30\x30\x30\x20\x70\x72\x6a\x67\x69\x74\x2d\x75\x70\x64\x61\x74\x65\x72\x00\xb4\x0b\x1c\xf5\xfb\xec\x9a\xb2\x9f\x48\x3e\x21\x18\x0d\x51\xb7\x98\x6e\x21\x99\x74\x84\x67\x71\x41\x24\x42\xfc\xc9\x04\x12\x99\x00" const treeData = "\x31\x61\x30\x35\x64\x62\x37\x33\x36\x39\x33\x37\x34\x33\x30\x65\x31\x38\x64\x66\x34\x33\x61\x32\x37\x61\x39\x38\x30\x30\x31\x30\x31\x32\x65\x31\x65\x64\x32\x30\x34\x38\x32\x39\x38\x36\x37\x31\x32\x38\x66\x32\x63\x65\x38\x34\x30\x36\x62\x35\x63\x66\x63\x39\x20\x74\x72\x65\x65\x20\x32\x30\x35\x00\x34\x30\x30\x30\x30\x20\x62\x6f\x74\x73\x2d\x63\x6f\x6d\x6d\x6f\x6e\x00\x93\x17\xaa\x47\xf6\xea\x37\xe8\xbc\xe2\x80\x77\x57\x90\xf4\xa8\x01\xd7\xe3\x70\x2f\x84\xfb\xe1\xb0\x0e\x4a\x2c\x1c\x75\x2c\x2b\x34\x30\x30\x30\x30\x20\x6f\x62\x73\x2d\x73\x74\x61\x67\x69\x6e\x67\x2d\x62\x6f\x74\x00\x79\x77\x8b\x28\x7d\x37\x10\x59\xb9\x71\x28\x36\xed\x20\x31\x5f\xfb\xe1\xed\xb5\xba\x4f\x5e\xbb\x65\x65\x68\x23\x77\x32\x58\xfe\x34\x30\x30\x30\x30\x20\x70\x72\x2d\x72\x65\x76\x69\x65\x77\x00\x36\x0d\x45\xcb\x76\xb8\x93\xb3\x21\xba\xfa\xd5\x00\x9d\xfc\x59\xab\x88\xc1\x3c\x81\xcb\x48\x5a\xe0\x29\x29\x0f\xe3\x6b\x3c\x5e\x34\x30\x30\x30\x30\x20\x70\x72\x6a\x67\x69\x74\x2d\x75\x70\x64\x61\x74\x65\x72\x00\xb4\x0b\x1c\xf5\xfb\xec\x9a\xb2\x9f\x48\x3e\x21\x18\x0d\x51\xb7\x98\x6e\x21\x99\x74\x84\x67\x71\x41\x24\x42\xfc\xc9\x04\x12\x99\x00"
@@ -555,8 +508,6 @@ func TestGitStatusParse(t *testing.T) {
Path: ".gitmodules", Path: ".gitmodules",
Status: GitStatus_Unmerged, Status: GitStatus_Unmerged,
States: [3]string{"587ec403f01113f2629da538f6e14b84781f70ac59c41aeedd978ea8b1253a76", "d23eb05d9ca92883ab9f4d28f3ec90c05f667f3a5c8c8e291bd65e03bac9ae3c", "087b1d5f22dbf0aa4a879fff27fff03568b334c90daa5f2653f4a7961e24ea33"}, States: [3]string{"587ec403f01113f2629da538f6e14b84781f70ac59c41aeedd978ea8b1253a76", "d23eb05d9ca92883ab9f4d28f3ec90c05f667f3a5c8c8e291bd65e03bac9ae3c", "087b1d5f22dbf0aa4a879fff27fff03568b334c90daa5f2653f4a7961e24ea33"},
SubmoduleChanges: "N...",
}, },
}, },
}, },

View File

@@ -36,12 +36,6 @@ func (o *IssueEditIssueAttachmentReader) ReadResponse(response runtime.ClientRes
return nil, err return nil, err
} }
return nil, result return nil, result
case 422:
result := NewIssueEditIssueAttachmentUnprocessableEntity()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 423: case 423:
result := NewIssueEditIssueAttachmentLocked() result := NewIssueEditIssueAttachmentLocked()
if err := result.readResponse(response, consumer, o.formats); err != nil { if err := result.readResponse(response, consumer, o.formats); err != nil {
@@ -195,78 +189,6 @@ func (o *IssueEditIssueAttachmentNotFound) readResponse(response runtime.ClientR
return nil return nil
} }
// NewIssueEditIssueAttachmentUnprocessableEntity creates a IssueEditIssueAttachmentUnprocessableEntity with default headers values
func NewIssueEditIssueAttachmentUnprocessableEntity() *IssueEditIssueAttachmentUnprocessableEntity {
return &IssueEditIssueAttachmentUnprocessableEntity{}
}
/*
IssueEditIssueAttachmentUnprocessableEntity describes a response with status code 422, with default header values.
APIValidationError is error format response related to input validation
*/
type IssueEditIssueAttachmentUnprocessableEntity struct {
Message string
URL string
}
// IsSuccess returns true when this issue edit issue attachment unprocessable entity response has a 2xx status code
func (o *IssueEditIssueAttachmentUnprocessableEntity) IsSuccess() bool {
return false
}
// IsRedirect returns true when this issue edit issue attachment unprocessable entity response has a 3xx status code
func (o *IssueEditIssueAttachmentUnprocessableEntity) IsRedirect() bool {
return false
}
// IsClientError returns true when this issue edit issue attachment unprocessable entity response has a 4xx status code
func (o *IssueEditIssueAttachmentUnprocessableEntity) IsClientError() bool {
return true
}
// IsServerError returns true when this issue edit issue attachment unprocessable entity response has a 5xx status code
func (o *IssueEditIssueAttachmentUnprocessableEntity) IsServerError() bool {
return false
}
// IsCode returns true when this issue edit issue attachment unprocessable entity response a status code equal to that given
func (o *IssueEditIssueAttachmentUnprocessableEntity) IsCode(code int) bool {
return code == 422
}
// Code gets the status code for the issue edit issue attachment unprocessable entity response
func (o *IssueEditIssueAttachmentUnprocessableEntity) Code() int {
return 422
}
func (o *IssueEditIssueAttachmentUnprocessableEntity) Error() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/issues/{index}/assets/{attachment_id}][%d] issueEditIssueAttachmentUnprocessableEntity", 422)
}
func (o *IssueEditIssueAttachmentUnprocessableEntity) String() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/issues/{index}/assets/{attachment_id}][%d] issueEditIssueAttachmentUnprocessableEntity", 422)
}
func (o *IssueEditIssueAttachmentUnprocessableEntity) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}
// NewIssueEditIssueAttachmentLocked creates a IssueEditIssueAttachmentLocked with default headers values // NewIssueEditIssueAttachmentLocked creates a IssueEditIssueAttachmentLocked with default headers values
func NewIssueEditIssueAttachmentLocked() *IssueEditIssueAttachmentLocked { func NewIssueEditIssueAttachmentLocked() *IssueEditIssueAttachmentLocked {
return &IssueEditIssueAttachmentLocked{} return &IssueEditIssueAttachmentLocked{}

View File

@@ -36,12 +36,6 @@ func (o *IssueEditIssueCommentAttachmentReader) ReadResponse(response runtime.Cl
return nil, err return nil, err
} }
return nil, result return nil, result
case 422:
result := NewIssueEditIssueCommentAttachmentUnprocessableEntity()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 423: case 423:
result := NewIssueEditIssueCommentAttachmentLocked() result := NewIssueEditIssueCommentAttachmentLocked()
if err := result.readResponse(response, consumer, o.formats); err != nil { if err := result.readResponse(response, consumer, o.formats); err != nil {
@@ -195,78 +189,6 @@ func (o *IssueEditIssueCommentAttachmentNotFound) readResponse(response runtime.
return nil return nil
} }
// NewIssueEditIssueCommentAttachmentUnprocessableEntity creates a IssueEditIssueCommentAttachmentUnprocessableEntity with default headers values
func NewIssueEditIssueCommentAttachmentUnprocessableEntity() *IssueEditIssueCommentAttachmentUnprocessableEntity {
return &IssueEditIssueCommentAttachmentUnprocessableEntity{}
}
/*
IssueEditIssueCommentAttachmentUnprocessableEntity describes a response with status code 422, with default header values.
APIValidationError is error format response related to input validation
*/
type IssueEditIssueCommentAttachmentUnprocessableEntity struct {
Message string
URL string
}
// IsSuccess returns true when this issue edit issue comment attachment unprocessable entity response has a 2xx status code
func (o *IssueEditIssueCommentAttachmentUnprocessableEntity) IsSuccess() bool {
return false
}
// IsRedirect returns true when this issue edit issue comment attachment unprocessable entity response has a 3xx status code
func (o *IssueEditIssueCommentAttachmentUnprocessableEntity) IsRedirect() bool {
return false
}
// IsClientError returns true when this issue edit issue comment attachment unprocessable entity response has a 4xx status code
func (o *IssueEditIssueCommentAttachmentUnprocessableEntity) IsClientError() bool {
return true
}
// IsServerError returns true when this issue edit issue comment attachment unprocessable entity response has a 5xx status code
func (o *IssueEditIssueCommentAttachmentUnprocessableEntity) IsServerError() bool {
return false
}
// IsCode returns true when this issue edit issue comment attachment unprocessable entity response a status code equal to that given
func (o *IssueEditIssueCommentAttachmentUnprocessableEntity) IsCode(code int) bool {
return code == 422
}
// Code gets the status code for the issue edit issue comment attachment unprocessable entity response
func (o *IssueEditIssueCommentAttachmentUnprocessableEntity) Code() int {
return 422
}
func (o *IssueEditIssueCommentAttachmentUnprocessableEntity) Error() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/issues/comments/{id}/assets/{attachment_id}][%d] issueEditIssueCommentAttachmentUnprocessableEntity", 422)
}
func (o *IssueEditIssueCommentAttachmentUnprocessableEntity) String() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/issues/comments/{id}/assets/{attachment_id}][%d] issueEditIssueCommentAttachmentUnprocessableEntity", 422)
}
func (o *IssueEditIssueCommentAttachmentUnprocessableEntity) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}
// NewIssueEditIssueCommentAttachmentLocked creates a IssueEditIssueCommentAttachmentLocked with default headers values // NewIssueEditIssueCommentAttachmentLocked creates a IssueEditIssueCommentAttachmentLocked with default headers values
func NewIssueEditIssueCommentAttachmentLocked() *IssueEditIssueCommentAttachmentLocked { func NewIssueEditIssueCommentAttachmentLocked() *IssueEditIssueCommentAttachmentLocked {
return &IssueEditIssueCommentAttachmentLocked{} return &IssueEditIssueCommentAttachmentLocked{}

View File

@@ -64,13 +64,13 @@ type IssueSearchIssuesParams struct {
/* Assigned. /* Assigned.
Filter issues or pulls assigned to the authenticated user filter (issues / pulls) assigned to you, default is false
*/ */
Assigned *bool Assigned *bool
/* Before. /* Before.
Only show issues updated before the given time (RFC 3339 format) Only show notifications updated before the given time. This is a timestamp in RFC 3339 format
Format: date-time Format: date-time
*/ */
@@ -78,51 +78,49 @@ type IssueSearchIssuesParams struct {
/* Created. /* Created.
Filter issues or pulls created by the authenticated user filter (issues / pulls) created by you, default is false
*/ */
Created *bool Created *bool
/* Labels. /* Labels.
Comma-separated list of label names. Fetch only issues that have any of these labels. Non existent labels are discarded. comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded
*/ */
Labels *string Labels *string
/* Limit. /* Limit.
Number of items per page page size of results
*/ */
Limit *int64 Limit *int64
/* Mentioned. /* Mentioned.
Filter issues or pulls mentioning the authenticated user filter (issues / pulls) mentioning you, default is false
*/ */
Mentioned *bool Mentioned *bool
/* Milestones. /* Milestones.
Comma-separated list of milestone names. Fetch only issues that have any of these milestones. Non existent milestones are discarded. comma separated list of milestone names. Fetch only issues that have any of this milestones. Non existent are discarded
*/ */
Milestones *string Milestones *string
/* Owner. /* Owner.
Filter by repository owner filter by owner
*/ */
Owner *string Owner *string
/* Page. /* Page.
Page number of results to return (1-based) page number of results to return (1-based)
Default: 1
*/ */
Page *int64 Page *int64
/* PriorityRepoID. /* PriorityRepoID.
Repository ID to prioritize in the results repository to prioritize in the results
Format: int64 Format: int64
*/ */
@@ -130,25 +128,25 @@ type IssueSearchIssuesParams struct {
/* Q. /* Q.
Search string search string
*/ */
Q *string Q *string
/* ReviewRequested. /* ReviewRequested.
Filter pull requests where the authenticated user's review was requested filter pulls requesting your review, default is false
*/ */
ReviewRequested *bool ReviewRequested *bool
/* Reviewed. /* Reviewed.
Filter pull requests reviewed by the authenticated user filter pulls reviewed by you, default is false
*/ */
Reviewed *bool Reviewed *bool
/* Since. /* Since.
Only show issues updated after the given time (RFC 3339 format) Only show notifications updated after the given time. This is a timestamp in RFC 3339 format
Format: date-time Format: date-time
*/ */
@@ -156,21 +154,19 @@ type IssueSearchIssuesParams struct {
/* State. /* State.
State of the issue whether issue is open or closed
Default: "open"
*/ */
State *string State *string
/* Team. /* Team.
Filter by team (requires organization owner parameter) filter by team (requires organization owner parameter to be provided)
*/ */
Team *string Team *string
/* Type. /* Type.
Filter by issue type filter by type (issues / pulls) if set
*/ */
Type *string Type *string
@@ -191,36 +187,7 @@ func (o *IssueSearchIssuesParams) WithDefaults() *IssueSearchIssuesParams {
// //
// All values with no default are reset to their zero value. // All values with no default are reset to their zero value.
func (o *IssueSearchIssuesParams) SetDefaults() { func (o *IssueSearchIssuesParams) SetDefaults() {
var ( // no default values defined for this parameter
assignedDefault = bool(false)
createdDefault = bool(false)
mentionedDefault = bool(false)
pageDefault = int64(1)
reviewRequestedDefault = bool(false)
reviewedDefault = bool(false)
stateDefault = string("open")
)
val := IssueSearchIssuesParams{
Assigned: &assignedDefault,
Created: &createdDefault,
Mentioned: &mentionedDefault,
Page: &pageDefault,
ReviewRequested: &reviewRequestedDefault,
Reviewed: &reviewedDefault,
State: &stateDefault,
}
val.timeout = o.timeout
val.Context = o.Context
val.HTTPClient = o.HTTPClient
*o = val
} }
// WithTimeout adds the timeout to the issue search issues params // WithTimeout adds the timeout to the issue search issues params

View File

@@ -30,18 +30,6 @@ func (o *IssueSearchIssuesReader) ReadResponse(response runtime.ClientResponse,
return nil, err return nil, err
} }
return result, nil return result, nil
case 400:
result := NewIssueSearchIssuesBadRequest()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 422:
result := NewIssueSearchIssuesUnprocessableEntity()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default: default:
return nil, runtime.NewAPIError("[GET /repos/issues/search] issueSearchIssues", response, response.Code()) return nil, runtime.NewAPIError("[GET /repos/issues/search] issueSearchIssues", response, response.Code())
} }
@@ -114,147 +102,3 @@ func (o *IssueSearchIssuesOK) readResponse(response runtime.ClientResponse, cons
return nil return nil
} }
// NewIssueSearchIssuesBadRequest creates a IssueSearchIssuesBadRequest with default headers values
func NewIssueSearchIssuesBadRequest() *IssueSearchIssuesBadRequest {
return &IssueSearchIssuesBadRequest{}
}
/*
IssueSearchIssuesBadRequest describes a response with status code 400, with default header values.
APIError is error format response
*/
type IssueSearchIssuesBadRequest struct {
Message string
URL string
}
// IsSuccess returns true when this issue search issues bad request response has a 2xx status code
func (o *IssueSearchIssuesBadRequest) IsSuccess() bool {
return false
}
// IsRedirect returns true when this issue search issues bad request response has a 3xx status code
func (o *IssueSearchIssuesBadRequest) IsRedirect() bool {
return false
}
// IsClientError returns true when this issue search issues bad request response has a 4xx status code
func (o *IssueSearchIssuesBadRequest) IsClientError() bool {
return true
}
// IsServerError returns true when this issue search issues bad request response has a 5xx status code
func (o *IssueSearchIssuesBadRequest) IsServerError() bool {
return false
}
// IsCode returns true when this issue search issues bad request response a status code equal to that given
func (o *IssueSearchIssuesBadRequest) IsCode(code int) bool {
return code == 400
}
// Code gets the status code for the issue search issues bad request response
func (o *IssueSearchIssuesBadRequest) Code() int {
return 400
}
func (o *IssueSearchIssuesBadRequest) Error() string {
return fmt.Sprintf("[GET /repos/issues/search][%d] issueSearchIssuesBadRequest", 400)
}
func (o *IssueSearchIssuesBadRequest) String() string {
return fmt.Sprintf("[GET /repos/issues/search][%d] issueSearchIssuesBadRequest", 400)
}
func (o *IssueSearchIssuesBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}
// NewIssueSearchIssuesUnprocessableEntity creates a IssueSearchIssuesUnprocessableEntity with default headers values
func NewIssueSearchIssuesUnprocessableEntity() *IssueSearchIssuesUnprocessableEntity {
return &IssueSearchIssuesUnprocessableEntity{}
}
/*
IssueSearchIssuesUnprocessableEntity describes a response with status code 422, with default header values.
APIValidationError is error format response related to input validation
*/
type IssueSearchIssuesUnprocessableEntity struct {
Message string
URL string
}
// IsSuccess returns true when this issue search issues unprocessable entity response has a 2xx status code
func (o *IssueSearchIssuesUnprocessableEntity) IsSuccess() bool {
return false
}
// IsRedirect returns true when this issue search issues unprocessable entity response has a 3xx status code
func (o *IssueSearchIssuesUnprocessableEntity) IsRedirect() bool {
return false
}
// IsClientError returns true when this issue search issues unprocessable entity response has a 4xx status code
func (o *IssueSearchIssuesUnprocessableEntity) IsClientError() bool {
return true
}
// IsServerError returns true when this issue search issues unprocessable entity response has a 5xx status code
func (o *IssueSearchIssuesUnprocessableEntity) IsServerError() bool {
return false
}
// IsCode returns true when this issue search issues unprocessable entity response a status code equal to that given
func (o *IssueSearchIssuesUnprocessableEntity) IsCode(code int) bool {
return code == 422
}
// Code gets the status code for the issue search issues unprocessable entity response
func (o *IssueSearchIssuesUnprocessableEntity) Code() int {
return 422
}
func (o *IssueSearchIssuesUnprocessableEntity) Error() string {
return fmt.Sprintf("[GET /repos/issues/search][%d] issueSearchIssuesUnprocessableEntity", 422)
}
func (o *IssueSearchIssuesUnprocessableEntity) String() string {
return fmt.Sprintf("[GET /repos/issues/search][%d] issueSearchIssuesUnprocessableEntity", 422)
}
func (o *IssueSearchIssuesUnprocessableEntity) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}

View File

@@ -1,242 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// NewListActionTasksParams creates a new ListActionTasksParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewListActionTasksParams() *ListActionTasksParams {
return &ListActionTasksParams{
timeout: cr.DefaultTimeout,
}
}
// NewListActionTasksParamsWithTimeout creates a new ListActionTasksParams object
// with the ability to set a timeout on a request.
func NewListActionTasksParamsWithTimeout(timeout time.Duration) *ListActionTasksParams {
return &ListActionTasksParams{
timeout: timeout,
}
}
// NewListActionTasksParamsWithContext creates a new ListActionTasksParams object
// with the ability to set a context for a request.
func NewListActionTasksParamsWithContext(ctx context.Context) *ListActionTasksParams {
return &ListActionTasksParams{
Context: ctx,
}
}
// NewListActionTasksParamsWithHTTPClient creates a new ListActionTasksParams object
// with the ability to set a custom HTTPClient for a request.
func NewListActionTasksParamsWithHTTPClient(client *http.Client) *ListActionTasksParams {
return &ListActionTasksParams{
HTTPClient: client,
}
}
/*
ListActionTasksParams contains all the parameters to send to the API endpoint
for the list action tasks operation.
Typically these are written to a http.Request.
*/
type ListActionTasksParams struct {
/* Limit.
page size of results, default maximum page size is 50
*/
Limit *int64
/* Owner.
owner of the repo
*/
Owner string
/* Page.
page number of results to return (1-based)
*/
Page *int64
/* Repo.
name of the repo
*/
Repo string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the list action tasks params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *ListActionTasksParams) WithDefaults() *ListActionTasksParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the list action tasks params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *ListActionTasksParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the list action tasks params
func (o *ListActionTasksParams) WithTimeout(timeout time.Duration) *ListActionTasksParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the list action tasks params
func (o *ListActionTasksParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the list action tasks params
func (o *ListActionTasksParams) WithContext(ctx context.Context) *ListActionTasksParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the list action tasks params
func (o *ListActionTasksParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the list action tasks params
func (o *ListActionTasksParams) WithHTTPClient(client *http.Client) *ListActionTasksParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the list action tasks params
func (o *ListActionTasksParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithLimit adds the limit to the list action tasks params
func (o *ListActionTasksParams) WithLimit(limit *int64) *ListActionTasksParams {
o.SetLimit(limit)
return o
}
// SetLimit adds the limit to the list action tasks params
func (o *ListActionTasksParams) SetLimit(limit *int64) {
o.Limit = limit
}
// WithOwner adds the owner to the list action tasks params
func (o *ListActionTasksParams) WithOwner(owner string) *ListActionTasksParams {
o.SetOwner(owner)
return o
}
// SetOwner adds the owner to the list action tasks params
func (o *ListActionTasksParams) SetOwner(owner string) {
o.Owner = owner
}
// WithPage adds the page to the list action tasks params
func (o *ListActionTasksParams) WithPage(page *int64) *ListActionTasksParams {
o.SetPage(page)
return o
}
// SetPage adds the page to the list action tasks params
func (o *ListActionTasksParams) SetPage(page *int64) {
o.Page = page
}
// WithRepo adds the repo to the list action tasks params
func (o *ListActionTasksParams) WithRepo(repo string) *ListActionTasksParams {
o.SetRepo(repo)
return o
}
// SetRepo adds the repo to the list action tasks params
func (o *ListActionTasksParams) SetRepo(repo string) {
o.Repo = repo
}
// WriteToRequest writes these params to a swagger request
func (o *ListActionTasksParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if o.Limit != nil {
// query param limit
var qrLimit int64
if o.Limit != nil {
qrLimit = *o.Limit
}
qLimit := swag.FormatInt64(qrLimit)
if qLimit != "" {
if err := r.SetQueryParam("limit", qLimit); err != nil {
return err
}
}
}
// path param owner
if err := r.SetPathParam("owner", o.Owner); err != nil {
return err
}
if o.Page != nil {
// query param page
var qrPage int64
if o.Page != nil {
qrPage = *o.Page
}
qPage := swag.FormatInt64(qrPage)
if qPage != "" {
if err := r.SetQueryParam("page", qPage); err != nil {
return err
}
}
}
// path param repo
if err := r.SetPathParam("repo", o.Repo); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,464 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
// ListActionTasksReader is a Reader for the ListActionTasks structure.
type ListActionTasksReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *ListActionTasksReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewListActionTasksOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 400:
result := NewListActionTasksBadRequest()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 403:
result := NewListActionTasksForbidden()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 404:
result := NewListActionTasksNotFound()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 409:
result := NewListActionTasksConflict()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 422:
result := NewListActionTasksUnprocessableEntity()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[GET /repos/{owner}/{repo}/actions/tasks] ListActionTasks", response, response.Code())
}
}
// NewListActionTasksOK creates a ListActionTasksOK with default headers values
func NewListActionTasksOK() *ListActionTasksOK {
return &ListActionTasksOK{}
}
/*
ListActionTasksOK describes a response with status code 200, with default header values.
TasksList
*/
type ListActionTasksOK struct {
Payload *models.ActionTaskResponse
}
// IsSuccess returns true when this list action tasks o k response has a 2xx status code
func (o *ListActionTasksOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this list action tasks o k response has a 3xx status code
func (o *ListActionTasksOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this list action tasks o k response has a 4xx status code
func (o *ListActionTasksOK) IsClientError() bool {
return false
}
// IsServerError returns true when this list action tasks o k response has a 5xx status code
func (o *ListActionTasksOK) IsServerError() bool {
return false
}
// IsCode returns true when this list action tasks o k response a status code equal to that given
func (o *ListActionTasksOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the list action tasks o k response
func (o *ListActionTasksOK) Code() int {
return 200
}
func (o *ListActionTasksOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /repos/{owner}/{repo}/actions/tasks][%d] listActionTasksOK %s", 200, payload)
}
func (o *ListActionTasksOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /repos/{owner}/{repo}/actions/tasks][%d] listActionTasksOK %s", 200, payload)
}
func (o *ListActionTasksOK) GetPayload() *models.ActionTaskResponse {
return o.Payload
}
func (o *ListActionTasksOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.ActionTaskResponse)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewListActionTasksBadRequest creates a ListActionTasksBadRequest with default headers values
func NewListActionTasksBadRequest() *ListActionTasksBadRequest {
return &ListActionTasksBadRequest{}
}
/*
ListActionTasksBadRequest describes a response with status code 400, with default header values.
APIError is error format response
*/
type ListActionTasksBadRequest struct {
Message string
URL string
}
// IsSuccess returns true when this list action tasks bad request response has a 2xx status code
func (o *ListActionTasksBadRequest) IsSuccess() bool {
return false
}
// IsRedirect returns true when this list action tasks bad request response has a 3xx status code
func (o *ListActionTasksBadRequest) IsRedirect() bool {
return false
}
// IsClientError returns true when this list action tasks bad request response has a 4xx status code
func (o *ListActionTasksBadRequest) IsClientError() bool {
return true
}
// IsServerError returns true when this list action tasks bad request response has a 5xx status code
func (o *ListActionTasksBadRequest) IsServerError() bool {
return false
}
// IsCode returns true when this list action tasks bad request response a status code equal to that given
func (o *ListActionTasksBadRequest) IsCode(code int) bool {
return code == 400
}
// Code gets the status code for the list action tasks bad request response
func (o *ListActionTasksBadRequest) Code() int {
return 400
}
func (o *ListActionTasksBadRequest) Error() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/actions/tasks][%d] listActionTasksBadRequest", 400)
}
func (o *ListActionTasksBadRequest) String() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/actions/tasks][%d] listActionTasksBadRequest", 400)
}
func (o *ListActionTasksBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}
// NewListActionTasksForbidden creates a ListActionTasksForbidden with default headers values
func NewListActionTasksForbidden() *ListActionTasksForbidden {
return &ListActionTasksForbidden{}
}
/*
ListActionTasksForbidden describes a response with status code 403, with default header values.
APIForbiddenError is a forbidden error response
*/
type ListActionTasksForbidden struct {
Message string
URL string
}
// IsSuccess returns true when this list action tasks forbidden response has a 2xx status code
func (o *ListActionTasksForbidden) IsSuccess() bool {
return false
}
// IsRedirect returns true when this list action tasks forbidden response has a 3xx status code
func (o *ListActionTasksForbidden) IsRedirect() bool {
return false
}
// IsClientError returns true when this list action tasks forbidden response has a 4xx status code
func (o *ListActionTasksForbidden) IsClientError() bool {
return true
}
// IsServerError returns true when this list action tasks forbidden response has a 5xx status code
func (o *ListActionTasksForbidden) IsServerError() bool {
return false
}
// IsCode returns true when this list action tasks forbidden response a status code equal to that given
func (o *ListActionTasksForbidden) IsCode(code int) bool {
return code == 403
}
// Code gets the status code for the list action tasks forbidden response
func (o *ListActionTasksForbidden) Code() int {
return 403
}
func (o *ListActionTasksForbidden) Error() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/actions/tasks][%d] listActionTasksForbidden", 403)
}
func (o *ListActionTasksForbidden) String() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/actions/tasks][%d] listActionTasksForbidden", 403)
}
func (o *ListActionTasksForbidden) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}
// NewListActionTasksNotFound creates a ListActionTasksNotFound with default headers values
func NewListActionTasksNotFound() *ListActionTasksNotFound {
return &ListActionTasksNotFound{}
}
/*
ListActionTasksNotFound describes a response with status code 404, with default header values.
APINotFound is a not found empty response
*/
type ListActionTasksNotFound struct {
}
// IsSuccess returns true when this list action tasks not found response has a 2xx status code
func (o *ListActionTasksNotFound) IsSuccess() bool {
return false
}
// IsRedirect returns true when this list action tasks not found response has a 3xx status code
func (o *ListActionTasksNotFound) IsRedirect() bool {
return false
}
// IsClientError returns true when this list action tasks not found response has a 4xx status code
func (o *ListActionTasksNotFound) IsClientError() bool {
return true
}
// IsServerError returns true when this list action tasks not found response has a 5xx status code
func (o *ListActionTasksNotFound) IsServerError() bool {
return false
}
// IsCode returns true when this list action tasks not found response a status code equal to that given
func (o *ListActionTasksNotFound) IsCode(code int) bool {
return code == 404
}
// Code gets the status code for the list action tasks not found response
func (o *ListActionTasksNotFound) Code() int {
return 404
}
func (o *ListActionTasksNotFound) Error() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/actions/tasks][%d] listActionTasksNotFound", 404)
}
func (o *ListActionTasksNotFound) String() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/actions/tasks][%d] listActionTasksNotFound", 404)
}
func (o *ListActionTasksNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}
// NewListActionTasksConflict creates a ListActionTasksConflict with default headers values
func NewListActionTasksConflict() *ListActionTasksConflict {
return &ListActionTasksConflict{}
}
/*
ListActionTasksConflict describes a response with status code 409, with default header values.
APIConflict is a conflict empty response
*/
type ListActionTasksConflict struct {
}
// IsSuccess returns true when this list action tasks conflict response has a 2xx status code
func (o *ListActionTasksConflict) IsSuccess() bool {
return false
}
// IsRedirect returns true when this list action tasks conflict response has a 3xx status code
func (o *ListActionTasksConflict) IsRedirect() bool {
return false
}
// IsClientError returns true when this list action tasks conflict response has a 4xx status code
func (o *ListActionTasksConflict) IsClientError() bool {
return true
}
// IsServerError returns true when this list action tasks conflict response has a 5xx status code
func (o *ListActionTasksConflict) IsServerError() bool {
return false
}
// IsCode returns true when this list action tasks conflict response a status code equal to that given
func (o *ListActionTasksConflict) IsCode(code int) bool {
return code == 409
}
// Code gets the status code for the list action tasks conflict response
func (o *ListActionTasksConflict) Code() int {
return 409
}
func (o *ListActionTasksConflict) Error() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/actions/tasks][%d] listActionTasksConflict", 409)
}
func (o *ListActionTasksConflict) String() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/actions/tasks][%d] listActionTasksConflict", 409)
}
func (o *ListActionTasksConflict) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}
// NewListActionTasksUnprocessableEntity creates a ListActionTasksUnprocessableEntity with default headers values
func NewListActionTasksUnprocessableEntity() *ListActionTasksUnprocessableEntity {
return &ListActionTasksUnprocessableEntity{}
}
/*
ListActionTasksUnprocessableEntity describes a response with status code 422, with default header values.
APIValidationError is error format response related to input validation
*/
type ListActionTasksUnprocessableEntity struct {
Message string
URL string
}
// IsSuccess returns true when this list action tasks unprocessable entity response has a 2xx status code
func (o *ListActionTasksUnprocessableEntity) IsSuccess() bool {
return false
}
// IsRedirect returns true when this list action tasks unprocessable entity response has a 3xx status code
func (o *ListActionTasksUnprocessableEntity) IsRedirect() bool {
return false
}
// IsClientError returns true when this list action tasks unprocessable entity response has a 4xx status code
func (o *ListActionTasksUnprocessableEntity) IsClientError() bool {
return true
}
// IsServerError returns true when this list action tasks unprocessable entity response has a 5xx status code
func (o *ListActionTasksUnprocessableEntity) IsServerError() bool {
return false
}
// IsCode returns true when this list action tasks unprocessable entity response a status code equal to that given
func (o *ListActionTasksUnprocessableEntity) IsCode(code int) bool {
return code == 422
}
// Code gets the status code for the list action tasks unprocessable entity response
func (o *ListActionTasksUnprocessableEntity) Code() int {
return 422
}
func (o *ListActionTasksUnprocessableEntity) Error() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/actions/tasks][%d] listActionTasksUnprocessableEntity", 422)
}
func (o *ListActionTasksUnprocessableEntity) String() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/actions/tasks][%d] listActionTasksUnprocessableEntity", 422)
}
func (o *ListActionTasksUnprocessableEntity) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}

View File

@@ -1,194 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
// NewRepoCreateTagProtectionParams creates a new RepoCreateTagProtectionParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewRepoCreateTagProtectionParams() *RepoCreateTagProtectionParams {
return &RepoCreateTagProtectionParams{
timeout: cr.DefaultTimeout,
}
}
// NewRepoCreateTagProtectionParamsWithTimeout creates a new RepoCreateTagProtectionParams object
// with the ability to set a timeout on a request.
func NewRepoCreateTagProtectionParamsWithTimeout(timeout time.Duration) *RepoCreateTagProtectionParams {
return &RepoCreateTagProtectionParams{
timeout: timeout,
}
}
// NewRepoCreateTagProtectionParamsWithContext creates a new RepoCreateTagProtectionParams object
// with the ability to set a context for a request.
func NewRepoCreateTagProtectionParamsWithContext(ctx context.Context) *RepoCreateTagProtectionParams {
return &RepoCreateTagProtectionParams{
Context: ctx,
}
}
// NewRepoCreateTagProtectionParamsWithHTTPClient creates a new RepoCreateTagProtectionParams object
// with the ability to set a custom HTTPClient for a request.
func NewRepoCreateTagProtectionParamsWithHTTPClient(client *http.Client) *RepoCreateTagProtectionParams {
return &RepoCreateTagProtectionParams{
HTTPClient: client,
}
}
/*
RepoCreateTagProtectionParams contains all the parameters to send to the API endpoint
for the repo create tag protection operation.
Typically these are written to a http.Request.
*/
type RepoCreateTagProtectionParams struct {
// Body.
Body *models.CreateTagProtectionOption
/* Owner.
owner of the repo
*/
Owner string
/* Repo.
name of the repo
*/
Repo string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the repo create tag protection params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoCreateTagProtectionParams) WithDefaults() *RepoCreateTagProtectionParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the repo create tag protection params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoCreateTagProtectionParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the repo create tag protection params
func (o *RepoCreateTagProtectionParams) WithTimeout(timeout time.Duration) *RepoCreateTagProtectionParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the repo create tag protection params
func (o *RepoCreateTagProtectionParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the repo create tag protection params
func (o *RepoCreateTagProtectionParams) WithContext(ctx context.Context) *RepoCreateTagProtectionParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the repo create tag protection params
func (o *RepoCreateTagProtectionParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the repo create tag protection params
func (o *RepoCreateTagProtectionParams) WithHTTPClient(client *http.Client) *RepoCreateTagProtectionParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the repo create tag protection params
func (o *RepoCreateTagProtectionParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the repo create tag protection params
func (o *RepoCreateTagProtectionParams) WithBody(body *models.CreateTagProtectionOption) *RepoCreateTagProtectionParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the repo create tag protection params
func (o *RepoCreateTagProtectionParams) SetBody(body *models.CreateTagProtectionOption) {
o.Body = body
}
// WithOwner adds the owner to the repo create tag protection params
func (o *RepoCreateTagProtectionParams) WithOwner(owner string) *RepoCreateTagProtectionParams {
o.SetOwner(owner)
return o
}
// SetOwner adds the owner to the repo create tag protection params
func (o *RepoCreateTagProtectionParams) SetOwner(owner string) {
o.Owner = owner
}
// WithRepo adds the repo to the repo create tag protection params
func (o *RepoCreateTagProtectionParams) WithRepo(repo string) *RepoCreateTagProtectionParams {
o.SetRepo(repo)
return o
}
// SetRepo adds the repo to the repo create tag protection params
func (o *RepoCreateTagProtectionParams) SetRepo(repo string) {
o.Repo = repo
}
// WriteToRequest writes these params to a swagger request
func (o *RepoCreateTagProtectionParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if o.Body != nil {
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
}
// path param owner
if err := r.SetPathParam("owner", o.Owner); err != nil {
return err
}
// path param repo
if err := r.SetPathParam("repo", o.Repo); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,402 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
// RepoCreateTagProtectionReader is a Reader for the RepoCreateTagProtection structure.
type RepoCreateTagProtectionReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *RepoCreateTagProtectionReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 201:
result := NewRepoCreateTagProtectionCreated()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 403:
result := NewRepoCreateTagProtectionForbidden()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 404:
result := NewRepoCreateTagProtectionNotFound()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 422:
result := NewRepoCreateTagProtectionUnprocessableEntity()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 423:
result := NewRepoCreateTagProtectionLocked()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[POST /repos/{owner}/{repo}/tag_protections] repoCreateTagProtection", response, response.Code())
}
}
// NewRepoCreateTagProtectionCreated creates a RepoCreateTagProtectionCreated with default headers values
func NewRepoCreateTagProtectionCreated() *RepoCreateTagProtectionCreated {
return &RepoCreateTagProtectionCreated{}
}
/*
RepoCreateTagProtectionCreated describes a response with status code 201, with default header values.
TagProtection
*/
type RepoCreateTagProtectionCreated struct {
Payload *models.TagProtection
}
// IsSuccess returns true when this repo create tag protection created response has a 2xx status code
func (o *RepoCreateTagProtectionCreated) IsSuccess() bool {
return true
}
// IsRedirect returns true when this repo create tag protection created response has a 3xx status code
func (o *RepoCreateTagProtectionCreated) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo create tag protection created response has a 4xx status code
func (o *RepoCreateTagProtectionCreated) IsClientError() bool {
return false
}
// IsServerError returns true when this repo create tag protection created response has a 5xx status code
func (o *RepoCreateTagProtectionCreated) IsServerError() bool {
return false
}
// IsCode returns true when this repo create tag protection created response a status code equal to that given
func (o *RepoCreateTagProtectionCreated) IsCode(code int) bool {
return code == 201
}
// Code gets the status code for the repo create tag protection created response
func (o *RepoCreateTagProtectionCreated) Code() int {
return 201
}
func (o *RepoCreateTagProtectionCreated) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /repos/{owner}/{repo}/tag_protections][%d] repoCreateTagProtectionCreated %s", 201, payload)
}
func (o *RepoCreateTagProtectionCreated) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /repos/{owner}/{repo}/tag_protections][%d] repoCreateTagProtectionCreated %s", 201, payload)
}
func (o *RepoCreateTagProtectionCreated) GetPayload() *models.TagProtection {
return o.Payload
}
func (o *RepoCreateTagProtectionCreated) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.TagProtection)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewRepoCreateTagProtectionForbidden creates a RepoCreateTagProtectionForbidden with default headers values
func NewRepoCreateTagProtectionForbidden() *RepoCreateTagProtectionForbidden {
return &RepoCreateTagProtectionForbidden{}
}
/*
RepoCreateTagProtectionForbidden describes a response with status code 403, with default header values.
APIForbiddenError is a forbidden error response
*/
type RepoCreateTagProtectionForbidden struct {
Message string
URL string
}
// IsSuccess returns true when this repo create tag protection forbidden response has a 2xx status code
func (o *RepoCreateTagProtectionForbidden) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo create tag protection forbidden response has a 3xx status code
func (o *RepoCreateTagProtectionForbidden) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo create tag protection forbidden response has a 4xx status code
func (o *RepoCreateTagProtectionForbidden) IsClientError() bool {
return true
}
// IsServerError returns true when this repo create tag protection forbidden response has a 5xx status code
func (o *RepoCreateTagProtectionForbidden) IsServerError() bool {
return false
}
// IsCode returns true when this repo create tag protection forbidden response a status code equal to that given
func (o *RepoCreateTagProtectionForbidden) IsCode(code int) bool {
return code == 403
}
// Code gets the status code for the repo create tag protection forbidden response
func (o *RepoCreateTagProtectionForbidden) Code() int {
return 403
}
func (o *RepoCreateTagProtectionForbidden) Error() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/tag_protections][%d] repoCreateTagProtectionForbidden", 403)
}
func (o *RepoCreateTagProtectionForbidden) String() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/tag_protections][%d] repoCreateTagProtectionForbidden", 403)
}
func (o *RepoCreateTagProtectionForbidden) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}
// NewRepoCreateTagProtectionNotFound creates a RepoCreateTagProtectionNotFound with default headers values
func NewRepoCreateTagProtectionNotFound() *RepoCreateTagProtectionNotFound {
return &RepoCreateTagProtectionNotFound{}
}
/*
RepoCreateTagProtectionNotFound describes a response with status code 404, with default header values.
APINotFound is a not found empty response
*/
type RepoCreateTagProtectionNotFound struct {
}
// IsSuccess returns true when this repo create tag protection not found response has a 2xx status code
func (o *RepoCreateTagProtectionNotFound) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo create tag protection not found response has a 3xx status code
func (o *RepoCreateTagProtectionNotFound) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo create tag protection not found response has a 4xx status code
func (o *RepoCreateTagProtectionNotFound) IsClientError() bool {
return true
}
// IsServerError returns true when this repo create tag protection not found response has a 5xx status code
func (o *RepoCreateTagProtectionNotFound) IsServerError() bool {
return false
}
// IsCode returns true when this repo create tag protection not found response a status code equal to that given
func (o *RepoCreateTagProtectionNotFound) IsCode(code int) bool {
return code == 404
}
// Code gets the status code for the repo create tag protection not found response
func (o *RepoCreateTagProtectionNotFound) Code() int {
return 404
}
func (o *RepoCreateTagProtectionNotFound) Error() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/tag_protections][%d] repoCreateTagProtectionNotFound", 404)
}
func (o *RepoCreateTagProtectionNotFound) String() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/tag_protections][%d] repoCreateTagProtectionNotFound", 404)
}
func (o *RepoCreateTagProtectionNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}
// NewRepoCreateTagProtectionUnprocessableEntity creates a RepoCreateTagProtectionUnprocessableEntity with default headers values
func NewRepoCreateTagProtectionUnprocessableEntity() *RepoCreateTagProtectionUnprocessableEntity {
return &RepoCreateTagProtectionUnprocessableEntity{}
}
/*
RepoCreateTagProtectionUnprocessableEntity describes a response with status code 422, with default header values.
APIValidationError is error format response related to input validation
*/
type RepoCreateTagProtectionUnprocessableEntity struct {
Message string
URL string
}
// IsSuccess returns true when this repo create tag protection unprocessable entity response has a 2xx status code
func (o *RepoCreateTagProtectionUnprocessableEntity) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo create tag protection unprocessable entity response has a 3xx status code
func (o *RepoCreateTagProtectionUnprocessableEntity) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo create tag protection unprocessable entity response has a 4xx status code
func (o *RepoCreateTagProtectionUnprocessableEntity) IsClientError() bool {
return true
}
// IsServerError returns true when this repo create tag protection unprocessable entity response has a 5xx status code
func (o *RepoCreateTagProtectionUnprocessableEntity) IsServerError() bool {
return false
}
// IsCode returns true when this repo create tag protection unprocessable entity response a status code equal to that given
func (o *RepoCreateTagProtectionUnprocessableEntity) IsCode(code int) bool {
return code == 422
}
// Code gets the status code for the repo create tag protection unprocessable entity response
func (o *RepoCreateTagProtectionUnprocessableEntity) Code() int {
return 422
}
func (o *RepoCreateTagProtectionUnprocessableEntity) Error() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/tag_protections][%d] repoCreateTagProtectionUnprocessableEntity", 422)
}
func (o *RepoCreateTagProtectionUnprocessableEntity) String() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/tag_protections][%d] repoCreateTagProtectionUnprocessableEntity", 422)
}
func (o *RepoCreateTagProtectionUnprocessableEntity) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}
// NewRepoCreateTagProtectionLocked creates a RepoCreateTagProtectionLocked with default headers values
func NewRepoCreateTagProtectionLocked() *RepoCreateTagProtectionLocked {
return &RepoCreateTagProtectionLocked{}
}
/*
RepoCreateTagProtectionLocked describes a response with status code 423, with default header values.
APIRepoArchivedError is an error that is raised when an archived repo should be modified
*/
type RepoCreateTagProtectionLocked struct {
Message string
URL string
}
// IsSuccess returns true when this repo create tag protection locked response has a 2xx status code
func (o *RepoCreateTagProtectionLocked) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo create tag protection locked response has a 3xx status code
func (o *RepoCreateTagProtectionLocked) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo create tag protection locked response has a 4xx status code
func (o *RepoCreateTagProtectionLocked) IsClientError() bool {
return true
}
// IsServerError returns true when this repo create tag protection locked response has a 5xx status code
func (o *RepoCreateTagProtectionLocked) IsServerError() bool {
return false
}
// IsCode returns true when this repo create tag protection locked response a status code equal to that given
func (o *RepoCreateTagProtectionLocked) IsCode(code int) bool {
return code == 423
}
// Code gets the status code for the repo create tag protection locked response
func (o *RepoCreateTagProtectionLocked) Code() int {
return 423
}
func (o *RepoCreateTagProtectionLocked) Error() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/tag_protections][%d] repoCreateTagProtectionLocked", 423)
}
func (o *RepoCreateTagProtectionLocked) String() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/tag_protections][%d] repoCreateTagProtectionLocked", 423)
}
func (o *RepoCreateTagProtectionLocked) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}

View File

@@ -1,196 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// NewRepoDeleteTagProtectionParams creates a new RepoDeleteTagProtectionParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewRepoDeleteTagProtectionParams() *RepoDeleteTagProtectionParams {
return &RepoDeleteTagProtectionParams{
timeout: cr.DefaultTimeout,
}
}
// NewRepoDeleteTagProtectionParamsWithTimeout creates a new RepoDeleteTagProtectionParams object
// with the ability to set a timeout on a request.
func NewRepoDeleteTagProtectionParamsWithTimeout(timeout time.Duration) *RepoDeleteTagProtectionParams {
return &RepoDeleteTagProtectionParams{
timeout: timeout,
}
}
// NewRepoDeleteTagProtectionParamsWithContext creates a new RepoDeleteTagProtectionParams object
// with the ability to set a context for a request.
func NewRepoDeleteTagProtectionParamsWithContext(ctx context.Context) *RepoDeleteTagProtectionParams {
return &RepoDeleteTagProtectionParams{
Context: ctx,
}
}
// NewRepoDeleteTagProtectionParamsWithHTTPClient creates a new RepoDeleteTagProtectionParams object
// with the ability to set a custom HTTPClient for a request.
func NewRepoDeleteTagProtectionParamsWithHTTPClient(client *http.Client) *RepoDeleteTagProtectionParams {
return &RepoDeleteTagProtectionParams{
HTTPClient: client,
}
}
/*
RepoDeleteTagProtectionParams contains all the parameters to send to the API endpoint
for the repo delete tag protection operation.
Typically these are written to a http.Request.
*/
type RepoDeleteTagProtectionParams struct {
/* ID.
id of protected tag
*/
ID int64
/* Owner.
owner of the repo
*/
Owner string
/* Repo.
name of the repo
*/
Repo string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the repo delete tag protection params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoDeleteTagProtectionParams) WithDefaults() *RepoDeleteTagProtectionParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the repo delete tag protection params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoDeleteTagProtectionParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the repo delete tag protection params
func (o *RepoDeleteTagProtectionParams) WithTimeout(timeout time.Duration) *RepoDeleteTagProtectionParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the repo delete tag protection params
func (o *RepoDeleteTagProtectionParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the repo delete tag protection params
func (o *RepoDeleteTagProtectionParams) WithContext(ctx context.Context) *RepoDeleteTagProtectionParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the repo delete tag protection params
func (o *RepoDeleteTagProtectionParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the repo delete tag protection params
func (o *RepoDeleteTagProtectionParams) WithHTTPClient(client *http.Client) *RepoDeleteTagProtectionParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the repo delete tag protection params
func (o *RepoDeleteTagProtectionParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithID adds the id to the repo delete tag protection params
func (o *RepoDeleteTagProtectionParams) WithID(id int64) *RepoDeleteTagProtectionParams {
o.SetID(id)
return o
}
// SetID adds the id to the repo delete tag protection params
func (o *RepoDeleteTagProtectionParams) SetID(id int64) {
o.ID = id
}
// WithOwner adds the owner to the repo delete tag protection params
func (o *RepoDeleteTagProtectionParams) WithOwner(owner string) *RepoDeleteTagProtectionParams {
o.SetOwner(owner)
return o
}
// SetOwner adds the owner to the repo delete tag protection params
func (o *RepoDeleteTagProtectionParams) SetOwner(owner string) {
o.Owner = owner
}
// WithRepo adds the repo to the repo delete tag protection params
func (o *RepoDeleteTagProtectionParams) WithRepo(repo string) *RepoDeleteTagProtectionParams {
o.SetRepo(repo)
return o
}
// SetRepo adds the repo to the repo delete tag protection params
func (o *RepoDeleteTagProtectionParams) SetRepo(repo string) {
o.Repo = repo
}
// WriteToRequest writes these params to a swagger request
func (o *RepoDeleteTagProtectionParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param id
if err := r.SetPathParam("id", swag.FormatInt64(o.ID)); err != nil {
return err
}
// path param owner
if err := r.SetPathParam("owner", o.Owner); err != nil {
return err
}
// path param repo
if err := r.SetPathParam("repo", o.Repo); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,150 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"fmt"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
)
// RepoDeleteTagProtectionReader is a Reader for the RepoDeleteTagProtection structure.
type RepoDeleteTagProtectionReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *RepoDeleteTagProtectionReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 204:
result := NewRepoDeleteTagProtectionNoContent()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 404:
result := NewRepoDeleteTagProtectionNotFound()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[DELETE /repos/{owner}/{repo}/tag_protections/{id}] repoDeleteTagProtection", response, response.Code())
}
}
// NewRepoDeleteTagProtectionNoContent creates a RepoDeleteTagProtectionNoContent with default headers values
func NewRepoDeleteTagProtectionNoContent() *RepoDeleteTagProtectionNoContent {
return &RepoDeleteTagProtectionNoContent{}
}
/*
RepoDeleteTagProtectionNoContent describes a response with status code 204, with default header values.
APIEmpty is an empty response
*/
type RepoDeleteTagProtectionNoContent struct {
}
// IsSuccess returns true when this repo delete tag protection no content response has a 2xx status code
func (o *RepoDeleteTagProtectionNoContent) IsSuccess() bool {
return true
}
// IsRedirect returns true when this repo delete tag protection no content response has a 3xx status code
func (o *RepoDeleteTagProtectionNoContent) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo delete tag protection no content response has a 4xx status code
func (o *RepoDeleteTagProtectionNoContent) IsClientError() bool {
return false
}
// IsServerError returns true when this repo delete tag protection no content response has a 5xx status code
func (o *RepoDeleteTagProtectionNoContent) IsServerError() bool {
return false
}
// IsCode returns true when this repo delete tag protection no content response a status code equal to that given
func (o *RepoDeleteTagProtectionNoContent) IsCode(code int) bool {
return code == 204
}
// Code gets the status code for the repo delete tag protection no content response
func (o *RepoDeleteTagProtectionNoContent) Code() int {
return 204
}
func (o *RepoDeleteTagProtectionNoContent) Error() string {
return fmt.Sprintf("[DELETE /repos/{owner}/{repo}/tag_protections/{id}][%d] repoDeleteTagProtectionNoContent", 204)
}
func (o *RepoDeleteTagProtectionNoContent) String() string {
return fmt.Sprintf("[DELETE /repos/{owner}/{repo}/tag_protections/{id}][%d] repoDeleteTagProtectionNoContent", 204)
}
func (o *RepoDeleteTagProtectionNoContent) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}
// NewRepoDeleteTagProtectionNotFound creates a RepoDeleteTagProtectionNotFound with default headers values
func NewRepoDeleteTagProtectionNotFound() *RepoDeleteTagProtectionNotFound {
return &RepoDeleteTagProtectionNotFound{}
}
/*
RepoDeleteTagProtectionNotFound describes a response with status code 404, with default header values.
APINotFound is a not found empty response
*/
type RepoDeleteTagProtectionNotFound struct {
}
// IsSuccess returns true when this repo delete tag protection not found response has a 2xx status code
func (o *RepoDeleteTagProtectionNotFound) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo delete tag protection not found response has a 3xx status code
func (o *RepoDeleteTagProtectionNotFound) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo delete tag protection not found response has a 4xx status code
func (o *RepoDeleteTagProtectionNotFound) IsClientError() bool {
return true
}
// IsServerError returns true when this repo delete tag protection not found response has a 5xx status code
func (o *RepoDeleteTagProtectionNotFound) IsServerError() bool {
return false
}
// IsCode returns true when this repo delete tag protection not found response a status code equal to that given
func (o *RepoDeleteTagProtectionNotFound) IsCode(code int) bool {
return code == 404
}
// Code gets the status code for the repo delete tag protection not found response
func (o *RepoDeleteTagProtectionNotFound) Code() int {
return 404
}
func (o *RepoDeleteTagProtectionNotFound) Error() string {
return fmt.Sprintf("[DELETE /repos/{owner}/{repo}/tag_protections/{id}][%d] repoDeleteTagProtectionNotFound", 404)
}
func (o *RepoDeleteTagProtectionNotFound) String() string {
return fmt.Sprintf("[DELETE /repos/{owner}/{repo}/tag_protections/{id}][%d] repoDeleteTagProtectionNotFound", 404)
}
func (o *RepoDeleteTagProtectionNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}

View File

@@ -36,12 +36,6 @@ func (o *RepoEditReleaseAttachmentReader) ReadResponse(response runtime.ClientRe
return nil, err return nil, err
} }
return nil, result return nil, result
case 422:
result := NewRepoEditReleaseAttachmentUnprocessableEntity()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default: default:
return nil, runtime.NewAPIError("[PATCH /repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}] repoEditReleaseAttachment", response, response.Code()) return nil, runtime.NewAPIError("[PATCH /repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}] repoEditReleaseAttachment", response, response.Code())
} }
@@ -172,75 +166,3 @@ func (o *RepoEditReleaseAttachmentNotFound) readResponse(response runtime.Client
return nil return nil
} }
// NewRepoEditReleaseAttachmentUnprocessableEntity creates a RepoEditReleaseAttachmentUnprocessableEntity with default headers values
func NewRepoEditReleaseAttachmentUnprocessableEntity() *RepoEditReleaseAttachmentUnprocessableEntity {
return &RepoEditReleaseAttachmentUnprocessableEntity{}
}
/*
RepoEditReleaseAttachmentUnprocessableEntity describes a response with status code 422, with default header values.
APIValidationError is error format response related to input validation
*/
type RepoEditReleaseAttachmentUnprocessableEntity struct {
Message string
URL string
}
// IsSuccess returns true when this repo edit release attachment unprocessable entity response has a 2xx status code
func (o *RepoEditReleaseAttachmentUnprocessableEntity) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo edit release attachment unprocessable entity response has a 3xx status code
func (o *RepoEditReleaseAttachmentUnprocessableEntity) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo edit release attachment unprocessable entity response has a 4xx status code
func (o *RepoEditReleaseAttachmentUnprocessableEntity) IsClientError() bool {
return true
}
// IsServerError returns true when this repo edit release attachment unprocessable entity response has a 5xx status code
func (o *RepoEditReleaseAttachmentUnprocessableEntity) IsServerError() bool {
return false
}
// IsCode returns true when this repo edit release attachment unprocessable entity response a status code equal to that given
func (o *RepoEditReleaseAttachmentUnprocessableEntity) IsCode(code int) bool {
return code == 422
}
// Code gets the status code for the repo edit release attachment unprocessable entity response
func (o *RepoEditReleaseAttachmentUnprocessableEntity) Code() int {
return 422
}
func (o *RepoEditReleaseAttachmentUnprocessableEntity) Error() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}][%d] repoEditReleaseAttachmentUnprocessableEntity", 422)
}
func (o *RepoEditReleaseAttachmentUnprocessableEntity) String() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}][%d] repoEditReleaseAttachmentUnprocessableEntity", 422)
}
func (o *RepoEditReleaseAttachmentUnprocessableEntity) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}

View File

@@ -1,217 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
// NewRepoEditTagProtectionParams creates a new RepoEditTagProtectionParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewRepoEditTagProtectionParams() *RepoEditTagProtectionParams {
return &RepoEditTagProtectionParams{
timeout: cr.DefaultTimeout,
}
}
// NewRepoEditTagProtectionParamsWithTimeout creates a new RepoEditTagProtectionParams object
// with the ability to set a timeout on a request.
func NewRepoEditTagProtectionParamsWithTimeout(timeout time.Duration) *RepoEditTagProtectionParams {
return &RepoEditTagProtectionParams{
timeout: timeout,
}
}
// NewRepoEditTagProtectionParamsWithContext creates a new RepoEditTagProtectionParams object
// with the ability to set a context for a request.
func NewRepoEditTagProtectionParamsWithContext(ctx context.Context) *RepoEditTagProtectionParams {
return &RepoEditTagProtectionParams{
Context: ctx,
}
}
// NewRepoEditTagProtectionParamsWithHTTPClient creates a new RepoEditTagProtectionParams object
// with the ability to set a custom HTTPClient for a request.
func NewRepoEditTagProtectionParamsWithHTTPClient(client *http.Client) *RepoEditTagProtectionParams {
return &RepoEditTagProtectionParams{
HTTPClient: client,
}
}
/*
RepoEditTagProtectionParams contains all the parameters to send to the API endpoint
for the repo edit tag protection operation.
Typically these are written to a http.Request.
*/
type RepoEditTagProtectionParams struct {
// Body.
Body *models.EditTagProtectionOption
/* ID.
id of protected tag
*/
ID int64
/* Owner.
owner of the repo
*/
Owner string
/* Repo.
name of the repo
*/
Repo string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the repo edit tag protection params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoEditTagProtectionParams) WithDefaults() *RepoEditTagProtectionParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the repo edit tag protection params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoEditTagProtectionParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the repo edit tag protection params
func (o *RepoEditTagProtectionParams) WithTimeout(timeout time.Duration) *RepoEditTagProtectionParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the repo edit tag protection params
func (o *RepoEditTagProtectionParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the repo edit tag protection params
func (o *RepoEditTagProtectionParams) WithContext(ctx context.Context) *RepoEditTagProtectionParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the repo edit tag protection params
func (o *RepoEditTagProtectionParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the repo edit tag protection params
func (o *RepoEditTagProtectionParams) WithHTTPClient(client *http.Client) *RepoEditTagProtectionParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the repo edit tag protection params
func (o *RepoEditTagProtectionParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the repo edit tag protection params
func (o *RepoEditTagProtectionParams) WithBody(body *models.EditTagProtectionOption) *RepoEditTagProtectionParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the repo edit tag protection params
func (o *RepoEditTagProtectionParams) SetBody(body *models.EditTagProtectionOption) {
o.Body = body
}
// WithID adds the id to the repo edit tag protection params
func (o *RepoEditTagProtectionParams) WithID(id int64) *RepoEditTagProtectionParams {
o.SetID(id)
return o
}
// SetID adds the id to the repo edit tag protection params
func (o *RepoEditTagProtectionParams) SetID(id int64) {
o.ID = id
}
// WithOwner adds the owner to the repo edit tag protection params
func (o *RepoEditTagProtectionParams) WithOwner(owner string) *RepoEditTagProtectionParams {
o.SetOwner(owner)
return o
}
// SetOwner adds the owner to the repo edit tag protection params
func (o *RepoEditTagProtectionParams) SetOwner(owner string) {
o.Owner = owner
}
// WithRepo adds the repo to the repo edit tag protection params
func (o *RepoEditTagProtectionParams) WithRepo(repo string) *RepoEditTagProtectionParams {
o.SetRepo(repo)
return o
}
// SetRepo adds the repo to the repo edit tag protection params
func (o *RepoEditTagProtectionParams) SetRepo(repo string) {
o.Repo = repo
}
// WriteToRequest writes these params to a swagger request
func (o *RepoEditTagProtectionParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if o.Body != nil {
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
}
// path param id
if err := r.SetPathParam("id", swag.FormatInt64(o.ID)); err != nil {
return err
}
// path param owner
if err := r.SetPathParam("owner", o.Owner); err != nil {
return err
}
// path param repo
if err := r.SetPathParam("repo", o.Repo); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,324 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
// RepoEditTagProtectionReader is a Reader for the RepoEditTagProtection structure.
type RepoEditTagProtectionReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *RepoEditTagProtectionReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewRepoEditTagProtectionOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 404:
result := NewRepoEditTagProtectionNotFound()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 422:
result := NewRepoEditTagProtectionUnprocessableEntity()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 423:
result := NewRepoEditTagProtectionLocked()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[PATCH /repos/{owner}/{repo}/tag_protections/{id}] repoEditTagProtection", response, response.Code())
}
}
// NewRepoEditTagProtectionOK creates a RepoEditTagProtectionOK with default headers values
func NewRepoEditTagProtectionOK() *RepoEditTagProtectionOK {
return &RepoEditTagProtectionOK{}
}
/*
RepoEditTagProtectionOK describes a response with status code 200, with default header values.
TagProtection
*/
type RepoEditTagProtectionOK struct {
Payload *models.TagProtection
}
// IsSuccess returns true when this repo edit tag protection o k response has a 2xx status code
func (o *RepoEditTagProtectionOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this repo edit tag protection o k response has a 3xx status code
func (o *RepoEditTagProtectionOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo edit tag protection o k response has a 4xx status code
func (o *RepoEditTagProtectionOK) IsClientError() bool {
return false
}
// IsServerError returns true when this repo edit tag protection o k response has a 5xx status code
func (o *RepoEditTagProtectionOK) IsServerError() bool {
return false
}
// IsCode returns true when this repo edit tag protection o k response a status code equal to that given
func (o *RepoEditTagProtectionOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the repo edit tag protection o k response
func (o *RepoEditTagProtectionOK) Code() int {
return 200
}
func (o *RepoEditTagProtectionOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/tag_protections/{id}][%d] repoEditTagProtectionOK %s", 200, payload)
}
func (o *RepoEditTagProtectionOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/tag_protections/{id}][%d] repoEditTagProtectionOK %s", 200, payload)
}
func (o *RepoEditTagProtectionOK) GetPayload() *models.TagProtection {
return o.Payload
}
func (o *RepoEditTagProtectionOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.TagProtection)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewRepoEditTagProtectionNotFound creates a RepoEditTagProtectionNotFound with default headers values
func NewRepoEditTagProtectionNotFound() *RepoEditTagProtectionNotFound {
return &RepoEditTagProtectionNotFound{}
}
/*
RepoEditTagProtectionNotFound describes a response with status code 404, with default header values.
APINotFound is a not found empty response
*/
type RepoEditTagProtectionNotFound struct {
}
// IsSuccess returns true when this repo edit tag protection not found response has a 2xx status code
func (o *RepoEditTagProtectionNotFound) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo edit tag protection not found response has a 3xx status code
func (o *RepoEditTagProtectionNotFound) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo edit tag protection not found response has a 4xx status code
func (o *RepoEditTagProtectionNotFound) IsClientError() bool {
return true
}
// IsServerError returns true when this repo edit tag protection not found response has a 5xx status code
func (o *RepoEditTagProtectionNotFound) IsServerError() bool {
return false
}
// IsCode returns true when this repo edit tag protection not found response a status code equal to that given
func (o *RepoEditTagProtectionNotFound) IsCode(code int) bool {
return code == 404
}
// Code gets the status code for the repo edit tag protection not found response
func (o *RepoEditTagProtectionNotFound) Code() int {
return 404
}
func (o *RepoEditTagProtectionNotFound) Error() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/tag_protections/{id}][%d] repoEditTagProtectionNotFound", 404)
}
func (o *RepoEditTagProtectionNotFound) String() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/tag_protections/{id}][%d] repoEditTagProtectionNotFound", 404)
}
func (o *RepoEditTagProtectionNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}
// NewRepoEditTagProtectionUnprocessableEntity creates a RepoEditTagProtectionUnprocessableEntity with default headers values
func NewRepoEditTagProtectionUnprocessableEntity() *RepoEditTagProtectionUnprocessableEntity {
return &RepoEditTagProtectionUnprocessableEntity{}
}
/*
RepoEditTagProtectionUnprocessableEntity describes a response with status code 422, with default header values.
APIValidationError is error format response related to input validation
*/
type RepoEditTagProtectionUnprocessableEntity struct {
Message string
URL string
}
// IsSuccess returns true when this repo edit tag protection unprocessable entity response has a 2xx status code
func (o *RepoEditTagProtectionUnprocessableEntity) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo edit tag protection unprocessable entity response has a 3xx status code
func (o *RepoEditTagProtectionUnprocessableEntity) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo edit tag protection unprocessable entity response has a 4xx status code
func (o *RepoEditTagProtectionUnprocessableEntity) IsClientError() bool {
return true
}
// IsServerError returns true when this repo edit tag protection unprocessable entity response has a 5xx status code
func (o *RepoEditTagProtectionUnprocessableEntity) IsServerError() bool {
return false
}
// IsCode returns true when this repo edit tag protection unprocessable entity response a status code equal to that given
func (o *RepoEditTagProtectionUnprocessableEntity) IsCode(code int) bool {
return code == 422
}
// Code gets the status code for the repo edit tag protection unprocessable entity response
func (o *RepoEditTagProtectionUnprocessableEntity) Code() int {
return 422
}
func (o *RepoEditTagProtectionUnprocessableEntity) Error() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/tag_protections/{id}][%d] repoEditTagProtectionUnprocessableEntity", 422)
}
func (o *RepoEditTagProtectionUnprocessableEntity) String() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/tag_protections/{id}][%d] repoEditTagProtectionUnprocessableEntity", 422)
}
func (o *RepoEditTagProtectionUnprocessableEntity) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}
// NewRepoEditTagProtectionLocked creates a RepoEditTagProtectionLocked with default headers values
func NewRepoEditTagProtectionLocked() *RepoEditTagProtectionLocked {
return &RepoEditTagProtectionLocked{}
}
/*
RepoEditTagProtectionLocked describes a response with status code 423, with default header values.
APIRepoArchivedError is an error that is raised when an archived repo should be modified
*/
type RepoEditTagProtectionLocked struct {
Message string
URL string
}
// IsSuccess returns true when this repo edit tag protection locked response has a 2xx status code
func (o *RepoEditTagProtectionLocked) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo edit tag protection locked response has a 3xx status code
func (o *RepoEditTagProtectionLocked) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo edit tag protection locked response has a 4xx status code
func (o *RepoEditTagProtectionLocked) IsClientError() bool {
return true
}
// IsServerError returns true when this repo edit tag protection locked response has a 5xx status code
func (o *RepoEditTagProtectionLocked) IsServerError() bool {
return false
}
// IsCode returns true when this repo edit tag protection locked response a status code equal to that given
func (o *RepoEditTagProtectionLocked) IsCode(code int) bool {
return code == 423
}
// Code gets the status code for the repo edit tag protection locked response
func (o *RepoEditTagProtectionLocked) Code() int {
return 423
}
func (o *RepoEditTagProtectionLocked) Error() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/tag_protections/{id}][%d] repoEditTagProtectionLocked", 423)
}
func (o *RepoEditTagProtectionLocked) String() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/tag_protections/{id}][%d] repoEditTagProtectionLocked", 423)
}
func (o *RepoEditTagProtectionLocked) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}

View File

@@ -1,173 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
// NewRepoGetLicensesParams creates a new RepoGetLicensesParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewRepoGetLicensesParams() *RepoGetLicensesParams {
return &RepoGetLicensesParams{
timeout: cr.DefaultTimeout,
}
}
// NewRepoGetLicensesParamsWithTimeout creates a new RepoGetLicensesParams object
// with the ability to set a timeout on a request.
func NewRepoGetLicensesParamsWithTimeout(timeout time.Duration) *RepoGetLicensesParams {
return &RepoGetLicensesParams{
timeout: timeout,
}
}
// NewRepoGetLicensesParamsWithContext creates a new RepoGetLicensesParams object
// with the ability to set a context for a request.
func NewRepoGetLicensesParamsWithContext(ctx context.Context) *RepoGetLicensesParams {
return &RepoGetLicensesParams{
Context: ctx,
}
}
// NewRepoGetLicensesParamsWithHTTPClient creates a new RepoGetLicensesParams object
// with the ability to set a custom HTTPClient for a request.
func NewRepoGetLicensesParamsWithHTTPClient(client *http.Client) *RepoGetLicensesParams {
return &RepoGetLicensesParams{
HTTPClient: client,
}
}
/*
RepoGetLicensesParams contains all the parameters to send to the API endpoint
for the repo get licenses operation.
Typically these are written to a http.Request.
*/
type RepoGetLicensesParams struct {
/* Owner.
owner of the repo
*/
Owner string
/* Repo.
name of the repo
*/
Repo string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the repo get licenses params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoGetLicensesParams) WithDefaults() *RepoGetLicensesParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the repo get licenses params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoGetLicensesParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the repo get licenses params
func (o *RepoGetLicensesParams) WithTimeout(timeout time.Duration) *RepoGetLicensesParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the repo get licenses params
func (o *RepoGetLicensesParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the repo get licenses params
func (o *RepoGetLicensesParams) WithContext(ctx context.Context) *RepoGetLicensesParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the repo get licenses params
func (o *RepoGetLicensesParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the repo get licenses params
func (o *RepoGetLicensesParams) WithHTTPClient(client *http.Client) *RepoGetLicensesParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the repo get licenses params
func (o *RepoGetLicensesParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithOwner adds the owner to the repo get licenses params
func (o *RepoGetLicensesParams) WithOwner(owner string) *RepoGetLicensesParams {
o.SetOwner(owner)
return o
}
// SetOwner adds the owner to the repo get licenses params
func (o *RepoGetLicensesParams) SetOwner(owner string) {
o.Owner = owner
}
// WithRepo adds the repo to the repo get licenses params
func (o *RepoGetLicensesParams) WithRepo(repo string) *RepoGetLicensesParams {
o.SetRepo(repo)
return o
}
// SetRepo adds the repo to the repo get licenses params
func (o *RepoGetLicensesParams) SetRepo(repo string) {
o.Repo = repo
}
// WriteToRequest writes these params to a swagger request
func (o *RepoGetLicensesParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param owner
if err := r.SetPathParam("owner", o.Owner); err != nil {
return err
}
// path param repo
if err := r.SetPathParam("repo", o.Repo); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,164 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
)
// RepoGetLicensesReader is a Reader for the RepoGetLicenses structure.
type RepoGetLicensesReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *RepoGetLicensesReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewRepoGetLicensesOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 404:
result := NewRepoGetLicensesNotFound()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[GET /repos/{owner}/{repo}/licenses] repoGetLicenses", response, response.Code())
}
}
// NewRepoGetLicensesOK creates a RepoGetLicensesOK with default headers values
func NewRepoGetLicensesOK() *RepoGetLicensesOK {
return &RepoGetLicensesOK{}
}
/*
RepoGetLicensesOK describes a response with status code 200, with default header values.
LicensesList
*/
type RepoGetLicensesOK struct {
Payload []string
}
// IsSuccess returns true when this repo get licenses o k response has a 2xx status code
func (o *RepoGetLicensesOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this repo get licenses o k response has a 3xx status code
func (o *RepoGetLicensesOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo get licenses o k response has a 4xx status code
func (o *RepoGetLicensesOK) IsClientError() bool {
return false
}
// IsServerError returns true when this repo get licenses o k response has a 5xx status code
func (o *RepoGetLicensesOK) IsServerError() bool {
return false
}
// IsCode returns true when this repo get licenses o k response a status code equal to that given
func (o *RepoGetLicensesOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the repo get licenses o k response
func (o *RepoGetLicensesOK) Code() int {
return 200
}
func (o *RepoGetLicensesOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /repos/{owner}/{repo}/licenses][%d] repoGetLicensesOK %s", 200, payload)
}
func (o *RepoGetLicensesOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /repos/{owner}/{repo}/licenses][%d] repoGetLicensesOK %s", 200, payload)
}
func (o *RepoGetLicensesOK) GetPayload() []string {
return o.Payload
}
func (o *RepoGetLicensesOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewRepoGetLicensesNotFound creates a RepoGetLicensesNotFound with default headers values
func NewRepoGetLicensesNotFound() *RepoGetLicensesNotFound {
return &RepoGetLicensesNotFound{}
}
/*
RepoGetLicensesNotFound describes a response with status code 404, with default header values.
APINotFound is a not found empty response
*/
type RepoGetLicensesNotFound struct {
}
// IsSuccess returns true when this repo get licenses not found response has a 2xx status code
func (o *RepoGetLicensesNotFound) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo get licenses not found response has a 3xx status code
func (o *RepoGetLicensesNotFound) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo get licenses not found response has a 4xx status code
func (o *RepoGetLicensesNotFound) IsClientError() bool {
return true
}
// IsServerError returns true when this repo get licenses not found response has a 5xx status code
func (o *RepoGetLicensesNotFound) IsServerError() bool {
return false
}
// IsCode returns true when this repo get licenses not found response a status code equal to that given
func (o *RepoGetLicensesNotFound) IsCode(code int) bool {
return code == 404
}
// Code gets the status code for the repo get licenses not found response
func (o *RepoGetLicensesNotFound) Code() int {
return 404
}
func (o *RepoGetLicensesNotFound) Error() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/licenses][%d] repoGetLicensesNotFound", 404)
}
func (o *RepoGetLicensesNotFound) String() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/licenses][%d] repoGetLicensesNotFound", 404)
}
func (o *RepoGetLicensesNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}

View File

@@ -63,7 +63,7 @@ type RepoGetRawFileOrLFSParams struct {
/* Filepath. /* Filepath.
path of the file to get, it should be "{ref}/{filepath}". If there is no ref could be inferred, it will be treated as the default branch filepath of the file to get
*/ */
Filepath string Filepath string
@@ -75,7 +75,7 @@ type RepoGetRawFileOrLFSParams struct {
/* Ref. /* Ref.
The name of the commit/branch/tag. Default the repositorys default branch The name of the commit/branch/tag. Default the repositorys default branch (usually master)
*/ */
Ref *string Ref *string

View File

@@ -63,7 +63,7 @@ type RepoGetRawFileParams struct {
/* Filepath. /* Filepath.
path of the file to get, it should be "{ref}/{filepath}". If there is no ref could be inferred, it will be treated as the default branch filepath of the file to get
*/ */
Filepath string Filepath string
@@ -75,7 +75,7 @@ type RepoGetRawFileParams struct {
/* Ref. /* Ref.
The name of the commit/branch/tag. Default the repositorys default branch The name of the commit/branch/tag. Default the repositorys default branch (usually master)
*/ */
Ref *string Ref *string

View File

@@ -27,7 +27,7 @@ func (o *RepoGetRunnerRegistrationTokenReader) ReadResponse(response runtime.Cli
} }
return result, nil return result, nil
default: default:
return nil, runtime.NewAPIError("[GET /repos/{owner}/{repo}/actions/runners/registration-token] repoGetRunnerRegistrationToken", response, response.Code()) return nil, runtime.NewAPIError("[GET /repos/{owner}/{repo}/runners/registration-token] repoGetRunnerRegistrationToken", response, response.Code())
} }
} }
@@ -76,11 +76,11 @@ func (o *RepoGetRunnerRegistrationTokenOK) Code() int {
} }
func (o *RepoGetRunnerRegistrationTokenOK) Error() string { func (o *RepoGetRunnerRegistrationTokenOK) Error() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/actions/runners/registration-token][%d] repoGetRunnerRegistrationTokenOK", 200) return fmt.Sprintf("[GET /repos/{owner}/{repo}/runners/registration-token][%d] repoGetRunnerRegistrationTokenOK", 200)
} }
func (o *RepoGetRunnerRegistrationTokenOK) String() string { func (o *RepoGetRunnerRegistrationTokenOK) String() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/actions/runners/registration-token][%d] repoGetRunnerRegistrationTokenOK", 200) return fmt.Sprintf("[GET /repos/{owner}/{repo}/runners/registration-token][%d] repoGetRunnerRegistrationTokenOK", 200)
} }
func (o *RepoGetRunnerRegistrationTokenOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { func (o *RepoGetRunnerRegistrationTokenOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {

View File

@@ -1,196 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// NewRepoGetTagProtectionParams creates a new RepoGetTagProtectionParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewRepoGetTagProtectionParams() *RepoGetTagProtectionParams {
return &RepoGetTagProtectionParams{
timeout: cr.DefaultTimeout,
}
}
// NewRepoGetTagProtectionParamsWithTimeout creates a new RepoGetTagProtectionParams object
// with the ability to set a timeout on a request.
func NewRepoGetTagProtectionParamsWithTimeout(timeout time.Duration) *RepoGetTagProtectionParams {
return &RepoGetTagProtectionParams{
timeout: timeout,
}
}
// NewRepoGetTagProtectionParamsWithContext creates a new RepoGetTagProtectionParams object
// with the ability to set a context for a request.
func NewRepoGetTagProtectionParamsWithContext(ctx context.Context) *RepoGetTagProtectionParams {
return &RepoGetTagProtectionParams{
Context: ctx,
}
}
// NewRepoGetTagProtectionParamsWithHTTPClient creates a new RepoGetTagProtectionParams object
// with the ability to set a custom HTTPClient for a request.
func NewRepoGetTagProtectionParamsWithHTTPClient(client *http.Client) *RepoGetTagProtectionParams {
return &RepoGetTagProtectionParams{
HTTPClient: client,
}
}
/*
RepoGetTagProtectionParams contains all the parameters to send to the API endpoint
for the repo get tag protection operation.
Typically these are written to a http.Request.
*/
type RepoGetTagProtectionParams struct {
/* ID.
id of the tag protect to get
*/
ID int64
/* Owner.
owner of the repo
*/
Owner string
/* Repo.
name of the repo
*/
Repo string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the repo get tag protection params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoGetTagProtectionParams) WithDefaults() *RepoGetTagProtectionParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the repo get tag protection params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoGetTagProtectionParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the repo get tag protection params
func (o *RepoGetTagProtectionParams) WithTimeout(timeout time.Duration) *RepoGetTagProtectionParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the repo get tag protection params
func (o *RepoGetTagProtectionParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the repo get tag protection params
func (o *RepoGetTagProtectionParams) WithContext(ctx context.Context) *RepoGetTagProtectionParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the repo get tag protection params
func (o *RepoGetTagProtectionParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the repo get tag protection params
func (o *RepoGetTagProtectionParams) WithHTTPClient(client *http.Client) *RepoGetTagProtectionParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the repo get tag protection params
func (o *RepoGetTagProtectionParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithID adds the id to the repo get tag protection params
func (o *RepoGetTagProtectionParams) WithID(id int64) *RepoGetTagProtectionParams {
o.SetID(id)
return o
}
// SetID adds the id to the repo get tag protection params
func (o *RepoGetTagProtectionParams) SetID(id int64) {
o.ID = id
}
// WithOwner adds the owner to the repo get tag protection params
func (o *RepoGetTagProtectionParams) WithOwner(owner string) *RepoGetTagProtectionParams {
o.SetOwner(owner)
return o
}
// SetOwner adds the owner to the repo get tag protection params
func (o *RepoGetTagProtectionParams) SetOwner(owner string) {
o.Owner = owner
}
// WithRepo adds the repo to the repo get tag protection params
func (o *RepoGetTagProtectionParams) WithRepo(repo string) *RepoGetTagProtectionParams {
o.SetRepo(repo)
return o
}
// SetRepo adds the repo to the repo get tag protection params
func (o *RepoGetTagProtectionParams) SetRepo(repo string) {
o.Repo = repo
}
// WriteToRequest writes these params to a swagger request
func (o *RepoGetTagProtectionParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param id
if err := r.SetPathParam("id", swag.FormatInt64(o.ID)); err != nil {
return err
}
// path param owner
if err := r.SetPathParam("owner", o.Owner); err != nil {
return err
}
// path param repo
if err := r.SetPathParam("repo", o.Repo); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,168 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
// RepoGetTagProtectionReader is a Reader for the RepoGetTagProtection structure.
type RepoGetTagProtectionReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *RepoGetTagProtectionReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewRepoGetTagProtectionOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 404:
result := NewRepoGetTagProtectionNotFound()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[GET /repos/{owner}/{repo}/tag_protections/{id}] repoGetTagProtection", response, response.Code())
}
}
// NewRepoGetTagProtectionOK creates a RepoGetTagProtectionOK with default headers values
func NewRepoGetTagProtectionOK() *RepoGetTagProtectionOK {
return &RepoGetTagProtectionOK{}
}
/*
RepoGetTagProtectionOK describes a response with status code 200, with default header values.
TagProtection
*/
type RepoGetTagProtectionOK struct {
Payload *models.TagProtection
}
// IsSuccess returns true when this repo get tag protection o k response has a 2xx status code
func (o *RepoGetTagProtectionOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this repo get tag protection o k response has a 3xx status code
func (o *RepoGetTagProtectionOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo get tag protection o k response has a 4xx status code
func (o *RepoGetTagProtectionOK) IsClientError() bool {
return false
}
// IsServerError returns true when this repo get tag protection o k response has a 5xx status code
func (o *RepoGetTagProtectionOK) IsServerError() bool {
return false
}
// IsCode returns true when this repo get tag protection o k response a status code equal to that given
func (o *RepoGetTagProtectionOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the repo get tag protection o k response
func (o *RepoGetTagProtectionOK) Code() int {
return 200
}
func (o *RepoGetTagProtectionOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /repos/{owner}/{repo}/tag_protections/{id}][%d] repoGetTagProtectionOK %s", 200, payload)
}
func (o *RepoGetTagProtectionOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /repos/{owner}/{repo}/tag_protections/{id}][%d] repoGetTagProtectionOK %s", 200, payload)
}
func (o *RepoGetTagProtectionOK) GetPayload() *models.TagProtection {
return o.Payload
}
func (o *RepoGetTagProtectionOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.TagProtection)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewRepoGetTagProtectionNotFound creates a RepoGetTagProtectionNotFound with default headers values
func NewRepoGetTagProtectionNotFound() *RepoGetTagProtectionNotFound {
return &RepoGetTagProtectionNotFound{}
}
/*
RepoGetTagProtectionNotFound describes a response with status code 404, with default header values.
APINotFound is a not found empty response
*/
type RepoGetTagProtectionNotFound struct {
}
// IsSuccess returns true when this repo get tag protection not found response has a 2xx status code
func (o *RepoGetTagProtectionNotFound) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo get tag protection not found response has a 3xx status code
func (o *RepoGetTagProtectionNotFound) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo get tag protection not found response has a 4xx status code
func (o *RepoGetTagProtectionNotFound) IsClientError() bool {
return true
}
// IsServerError returns true when this repo get tag protection not found response has a 5xx status code
func (o *RepoGetTagProtectionNotFound) IsServerError() bool {
return false
}
// IsCode returns true when this repo get tag protection not found response a status code equal to that given
func (o *RepoGetTagProtectionNotFound) IsCode(code int) bool {
return code == 404
}
// Code gets the status code for the repo get tag protection not found response
func (o *RepoGetTagProtectionNotFound) Code() int {
return 404
}
func (o *RepoGetTagProtectionNotFound) Error() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/tag_protections/{id}][%d] repoGetTagProtectionNotFound", 404)
}
func (o *RepoGetTagProtectionNotFound) String() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/tag_protections/{id}][%d] repoGetTagProtectionNotFound", 404)
}
func (o *RepoGetTagProtectionNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}

View File

@@ -70,7 +70,7 @@ type RepoListPullRequestsParams struct {
/* Limit. /* Limit.
Page size of results page size of results
*/ */
Limit *int64 Limit *int64
@@ -84,27 +84,19 @@ type RepoListPullRequestsParams struct {
/* Owner. /* Owner.
Owner of the repo owner of the repo
*/ */
Owner string Owner string
/* Page. /* Page.
Page number of results to return (1-based) page number of results to return (1-based)
Default: 1
*/ */
Page *int64 Page *int64
/* Poster.
Filter by pull request author
*/
Poster *string
/* Repo. /* Repo.
Name of the repo name of the repo
*/ */
Repo string Repo string
@@ -116,9 +108,7 @@ type RepoListPullRequestsParams struct {
/* State. /* State.
State of pull request State of pull request: open or closed (optional)
Default: "open"
*/ */
State *string State *string
@@ -139,21 +129,7 @@ func (o *RepoListPullRequestsParams) WithDefaults() *RepoListPullRequestsParams
// //
// All values with no default are reset to their zero value. // All values with no default are reset to their zero value.
func (o *RepoListPullRequestsParams) SetDefaults() { func (o *RepoListPullRequestsParams) SetDefaults() {
var ( // no default values defined for this parameter
pageDefault = int64(1)
stateDefault = string("open")
)
val := RepoListPullRequestsParams{
Page: &pageDefault,
State: &stateDefault,
}
val.timeout = o.timeout
val.Context = o.Context
val.HTTPClient = o.HTTPClient
*o = val
} }
// WithTimeout adds the timeout to the repo list pull requests params // WithTimeout adds the timeout to the repo list pull requests params
@@ -244,17 +220,6 @@ func (o *RepoListPullRequestsParams) SetPage(page *int64) {
o.Page = page o.Page = page
} }
// WithPoster adds the poster to the repo list pull requests params
func (o *RepoListPullRequestsParams) WithPoster(poster *string) *RepoListPullRequestsParams {
o.SetPoster(poster)
return o
}
// SetPoster adds the poster to the repo list pull requests params
func (o *RepoListPullRequestsParams) SetPoster(poster *string) {
o.Poster = poster
}
// WithRepo adds the repo to the repo list pull requests params // WithRepo adds the repo to the repo list pull requests params
func (o *RepoListPullRequestsParams) WithRepo(repo string) *RepoListPullRequestsParams { func (o *RepoListPullRequestsParams) WithRepo(repo string) *RepoListPullRequestsParams {
o.SetRepo(repo) o.SetRepo(repo)
@@ -363,23 +328,6 @@ func (o *RepoListPullRequestsParams) WriteToRequest(r runtime.ClientRequest, reg
} }
} }
if o.Poster != nil {
// query param poster
var qrPoster string
if o.Poster != nil {
qrPoster = *o.Poster
}
qPoster := qrPoster
if qPoster != "" {
if err := r.SetQueryParam("poster", qPoster); err != nil {
return err
}
}
}
// path param repo // path param repo
if err := r.SetPathParam("repo", o.Repo); err != nil { if err := r.SetPathParam("repo", o.Repo); err != nil {
return err return err

View File

@@ -36,12 +36,6 @@ func (o *RepoListPullRequestsReader) ReadResponse(response runtime.ClientRespons
return nil, err return nil, err
} }
return nil, result return nil, result
case 500:
result := NewRepoListPullRequestsInternalServerError()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default: default:
return nil, runtime.NewAPIError("[GET /repos/{owner}/{repo}/pulls] repoListPullRequests", response, response.Code()) return nil, runtime.NewAPIError("[GET /repos/{owner}/{repo}/pulls] repoListPullRequests", response, response.Code())
} }
@@ -170,75 +164,3 @@ func (o *RepoListPullRequestsNotFound) readResponse(response runtime.ClientRespo
return nil return nil
} }
// NewRepoListPullRequestsInternalServerError creates a RepoListPullRequestsInternalServerError with default headers values
func NewRepoListPullRequestsInternalServerError() *RepoListPullRequestsInternalServerError {
return &RepoListPullRequestsInternalServerError{}
}
/*
RepoListPullRequestsInternalServerError describes a response with status code 500, with default header values.
APIError is error format response
*/
type RepoListPullRequestsInternalServerError struct {
Message string
URL string
}
// IsSuccess returns true when this repo list pull requests internal server error response has a 2xx status code
func (o *RepoListPullRequestsInternalServerError) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo list pull requests internal server error response has a 3xx status code
func (o *RepoListPullRequestsInternalServerError) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo list pull requests internal server error response has a 4xx status code
func (o *RepoListPullRequestsInternalServerError) IsClientError() bool {
return false
}
// IsServerError returns true when this repo list pull requests internal server error response has a 5xx status code
func (o *RepoListPullRequestsInternalServerError) IsServerError() bool {
return true
}
// IsCode returns true when this repo list pull requests internal server error response a status code equal to that given
func (o *RepoListPullRequestsInternalServerError) IsCode(code int) bool {
return code == 500
}
// Code gets the status code for the repo list pull requests internal server error response
func (o *RepoListPullRequestsInternalServerError) Code() int {
return 500
}
func (o *RepoListPullRequestsInternalServerError) Error() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/pulls][%d] repoListPullRequestsInternalServerError", 500)
}
func (o *RepoListPullRequestsInternalServerError) String() string {
return fmt.Sprintf("[GET /repos/{owner}/{repo}/pulls][%d] repoListPullRequestsInternalServerError", 500)
}
func (o *RepoListPullRequestsInternalServerError) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}

View File

@@ -1,173 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
)
// NewRepoListTagProtectionParams creates a new RepoListTagProtectionParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewRepoListTagProtectionParams() *RepoListTagProtectionParams {
return &RepoListTagProtectionParams{
timeout: cr.DefaultTimeout,
}
}
// NewRepoListTagProtectionParamsWithTimeout creates a new RepoListTagProtectionParams object
// with the ability to set a timeout on a request.
func NewRepoListTagProtectionParamsWithTimeout(timeout time.Duration) *RepoListTagProtectionParams {
return &RepoListTagProtectionParams{
timeout: timeout,
}
}
// NewRepoListTagProtectionParamsWithContext creates a new RepoListTagProtectionParams object
// with the ability to set a context for a request.
func NewRepoListTagProtectionParamsWithContext(ctx context.Context) *RepoListTagProtectionParams {
return &RepoListTagProtectionParams{
Context: ctx,
}
}
// NewRepoListTagProtectionParamsWithHTTPClient creates a new RepoListTagProtectionParams object
// with the ability to set a custom HTTPClient for a request.
func NewRepoListTagProtectionParamsWithHTTPClient(client *http.Client) *RepoListTagProtectionParams {
return &RepoListTagProtectionParams{
HTTPClient: client,
}
}
/*
RepoListTagProtectionParams contains all the parameters to send to the API endpoint
for the repo list tag protection operation.
Typically these are written to a http.Request.
*/
type RepoListTagProtectionParams struct {
/* Owner.
owner of the repo
*/
Owner string
/* Repo.
name of the repo
*/
Repo string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the repo list tag protection params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoListTagProtectionParams) WithDefaults() *RepoListTagProtectionParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the repo list tag protection params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoListTagProtectionParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the repo list tag protection params
func (o *RepoListTagProtectionParams) WithTimeout(timeout time.Duration) *RepoListTagProtectionParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the repo list tag protection params
func (o *RepoListTagProtectionParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the repo list tag protection params
func (o *RepoListTagProtectionParams) WithContext(ctx context.Context) *RepoListTagProtectionParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the repo list tag protection params
func (o *RepoListTagProtectionParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the repo list tag protection params
func (o *RepoListTagProtectionParams) WithHTTPClient(client *http.Client) *RepoListTagProtectionParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the repo list tag protection params
func (o *RepoListTagProtectionParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithOwner adds the owner to the repo list tag protection params
func (o *RepoListTagProtectionParams) WithOwner(owner string) *RepoListTagProtectionParams {
o.SetOwner(owner)
return o
}
// SetOwner adds the owner to the repo list tag protection params
func (o *RepoListTagProtectionParams) SetOwner(owner string) {
o.Owner = owner
}
// WithRepo adds the repo to the repo list tag protection params
func (o *RepoListTagProtectionParams) WithRepo(repo string) *RepoListTagProtectionParams {
o.SetRepo(repo)
return o
}
// SetRepo adds the repo to the repo list tag protection params
func (o *RepoListTagProtectionParams) SetRepo(repo string) {
o.Repo = repo
}
// WriteToRequest writes these params to a swagger request
func (o *RepoListTagProtectionParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param owner
if err := r.SetPathParam("owner", o.Owner); err != nil {
return err
}
// path param repo
if err := r.SetPathParam("repo", o.Repo); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,104 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
// RepoListTagProtectionReader is a Reader for the RepoListTagProtection structure.
type RepoListTagProtectionReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *RepoListTagProtectionReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewRepoListTagProtectionOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
default:
return nil, runtime.NewAPIError("[GET /repos/{owner}/{repo}/tag_protections] repoListTagProtection", response, response.Code())
}
}
// NewRepoListTagProtectionOK creates a RepoListTagProtectionOK with default headers values
func NewRepoListTagProtectionOK() *RepoListTagProtectionOK {
return &RepoListTagProtectionOK{}
}
/*
RepoListTagProtectionOK describes a response with status code 200, with default header values.
TagProtectionList
*/
type RepoListTagProtectionOK struct {
Payload []*models.TagProtection
}
// IsSuccess returns true when this repo list tag protection o k response has a 2xx status code
func (o *RepoListTagProtectionOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this repo list tag protection o k response has a 3xx status code
func (o *RepoListTagProtectionOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo list tag protection o k response has a 4xx status code
func (o *RepoListTagProtectionOK) IsClientError() bool {
return false
}
// IsServerError returns true when this repo list tag protection o k response has a 5xx status code
func (o *RepoListTagProtectionOK) IsServerError() bool {
return false
}
// IsCode returns true when this repo list tag protection o k response a status code equal to that given
func (o *RepoListTagProtectionOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the repo list tag protection o k response
func (o *RepoListTagProtectionOK) Code() int {
return 200
}
func (o *RepoListTagProtectionOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /repos/{owner}/{repo}/tag_protections][%d] repoListTagProtectionOK %s", 200, payload)
}
func (o *RepoListTagProtectionOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[GET /repos/{owner}/{repo}/tag_protections][%d] repoListTagProtectionOK %s", 200, payload)
}
func (o *RepoListTagProtectionOK) GetPayload() []*models.TagProtection {
return o.Payload
}
func (o *RepoListTagProtectionOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// response payload
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View File

@@ -1,194 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
// NewRepoMergeUpstreamParams creates a new RepoMergeUpstreamParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewRepoMergeUpstreamParams() *RepoMergeUpstreamParams {
return &RepoMergeUpstreamParams{
timeout: cr.DefaultTimeout,
}
}
// NewRepoMergeUpstreamParamsWithTimeout creates a new RepoMergeUpstreamParams object
// with the ability to set a timeout on a request.
func NewRepoMergeUpstreamParamsWithTimeout(timeout time.Duration) *RepoMergeUpstreamParams {
return &RepoMergeUpstreamParams{
timeout: timeout,
}
}
// NewRepoMergeUpstreamParamsWithContext creates a new RepoMergeUpstreamParams object
// with the ability to set a context for a request.
func NewRepoMergeUpstreamParamsWithContext(ctx context.Context) *RepoMergeUpstreamParams {
return &RepoMergeUpstreamParams{
Context: ctx,
}
}
// NewRepoMergeUpstreamParamsWithHTTPClient creates a new RepoMergeUpstreamParams object
// with the ability to set a custom HTTPClient for a request.
func NewRepoMergeUpstreamParamsWithHTTPClient(client *http.Client) *RepoMergeUpstreamParams {
return &RepoMergeUpstreamParams{
HTTPClient: client,
}
}
/*
RepoMergeUpstreamParams contains all the parameters to send to the API endpoint
for the repo merge upstream operation.
Typically these are written to a http.Request.
*/
type RepoMergeUpstreamParams struct {
// Body.
Body *models.MergeUpstreamRequest
/* Owner.
owner of the repo
*/
Owner string
/* Repo.
name of the repo
*/
Repo string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the repo merge upstream params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoMergeUpstreamParams) WithDefaults() *RepoMergeUpstreamParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the repo merge upstream params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoMergeUpstreamParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the repo merge upstream params
func (o *RepoMergeUpstreamParams) WithTimeout(timeout time.Duration) *RepoMergeUpstreamParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the repo merge upstream params
func (o *RepoMergeUpstreamParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the repo merge upstream params
func (o *RepoMergeUpstreamParams) WithContext(ctx context.Context) *RepoMergeUpstreamParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the repo merge upstream params
func (o *RepoMergeUpstreamParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the repo merge upstream params
func (o *RepoMergeUpstreamParams) WithHTTPClient(client *http.Client) *RepoMergeUpstreamParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the repo merge upstream params
func (o *RepoMergeUpstreamParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the repo merge upstream params
func (o *RepoMergeUpstreamParams) WithBody(body *models.MergeUpstreamRequest) *RepoMergeUpstreamParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the repo merge upstream params
func (o *RepoMergeUpstreamParams) SetBody(body *models.MergeUpstreamRequest) {
o.Body = body
}
// WithOwner adds the owner to the repo merge upstream params
func (o *RepoMergeUpstreamParams) WithOwner(owner string) *RepoMergeUpstreamParams {
o.SetOwner(owner)
return o
}
// SetOwner adds the owner to the repo merge upstream params
func (o *RepoMergeUpstreamParams) SetOwner(owner string) {
o.Owner = owner
}
// WithRepo adds the repo to the repo merge upstream params
func (o *RepoMergeUpstreamParams) WithRepo(repo string) *RepoMergeUpstreamParams {
o.SetRepo(repo)
return o
}
// SetRepo adds the repo to the repo merge upstream params
func (o *RepoMergeUpstreamParams) SetRepo(repo string) {
o.Repo = repo
}
// WriteToRequest writes these params to a swagger request
func (o *RepoMergeUpstreamParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if o.Body != nil {
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
}
// path param owner
if err := r.SetPathParam("owner", o.Owner); err != nil {
return err
}
// path param repo
if err := r.SetPathParam("repo", o.Repo); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,246 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"encoding/json"
"fmt"
"io"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
// RepoMergeUpstreamReader is a Reader for the RepoMergeUpstream structure.
type RepoMergeUpstreamReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *RepoMergeUpstreamReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewRepoMergeUpstreamOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 400:
result := NewRepoMergeUpstreamBadRequest()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 404:
result := NewRepoMergeUpstreamNotFound()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[POST /repos/{owner}/{repo}/merge-upstream] repoMergeUpstream", response, response.Code())
}
}
// NewRepoMergeUpstreamOK creates a RepoMergeUpstreamOK with default headers values
func NewRepoMergeUpstreamOK() *RepoMergeUpstreamOK {
return &RepoMergeUpstreamOK{}
}
/*
RepoMergeUpstreamOK describes a response with status code 200, with default header values.
RepoMergeUpstreamOK repo merge upstream o k
*/
type RepoMergeUpstreamOK struct {
Payload *models.MergeUpstreamResponse
}
// IsSuccess returns true when this repo merge upstream o k response has a 2xx status code
func (o *RepoMergeUpstreamOK) IsSuccess() bool {
return true
}
// IsRedirect returns true when this repo merge upstream o k response has a 3xx status code
func (o *RepoMergeUpstreamOK) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo merge upstream o k response has a 4xx status code
func (o *RepoMergeUpstreamOK) IsClientError() bool {
return false
}
// IsServerError returns true when this repo merge upstream o k response has a 5xx status code
func (o *RepoMergeUpstreamOK) IsServerError() bool {
return false
}
// IsCode returns true when this repo merge upstream o k response a status code equal to that given
func (o *RepoMergeUpstreamOK) IsCode(code int) bool {
return code == 200
}
// Code gets the status code for the repo merge upstream o k response
func (o *RepoMergeUpstreamOK) Code() int {
return 200
}
func (o *RepoMergeUpstreamOK) Error() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /repos/{owner}/{repo}/merge-upstream][%d] repoMergeUpstreamOK %s", 200, payload)
}
func (o *RepoMergeUpstreamOK) String() string {
payload, _ := json.Marshal(o.Payload)
return fmt.Sprintf("[POST /repos/{owner}/{repo}/merge-upstream][%d] repoMergeUpstreamOK %s", 200, payload)
}
func (o *RepoMergeUpstreamOK) GetPayload() *models.MergeUpstreamResponse {
return o.Payload
}
func (o *RepoMergeUpstreamOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.MergeUpstreamResponse)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewRepoMergeUpstreamBadRequest creates a RepoMergeUpstreamBadRequest with default headers values
func NewRepoMergeUpstreamBadRequest() *RepoMergeUpstreamBadRequest {
return &RepoMergeUpstreamBadRequest{}
}
/*
RepoMergeUpstreamBadRequest describes a response with status code 400, with default header values.
APIError is error format response
*/
type RepoMergeUpstreamBadRequest struct {
Message string
URL string
}
// IsSuccess returns true when this repo merge upstream bad request response has a 2xx status code
func (o *RepoMergeUpstreamBadRequest) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo merge upstream bad request response has a 3xx status code
func (o *RepoMergeUpstreamBadRequest) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo merge upstream bad request response has a 4xx status code
func (o *RepoMergeUpstreamBadRequest) IsClientError() bool {
return true
}
// IsServerError returns true when this repo merge upstream bad request response has a 5xx status code
func (o *RepoMergeUpstreamBadRequest) IsServerError() bool {
return false
}
// IsCode returns true when this repo merge upstream bad request response a status code equal to that given
func (o *RepoMergeUpstreamBadRequest) IsCode(code int) bool {
return code == 400
}
// Code gets the status code for the repo merge upstream bad request response
func (o *RepoMergeUpstreamBadRequest) Code() int {
return 400
}
func (o *RepoMergeUpstreamBadRequest) Error() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/merge-upstream][%d] repoMergeUpstreamBadRequest", 400)
}
func (o *RepoMergeUpstreamBadRequest) String() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/merge-upstream][%d] repoMergeUpstreamBadRequest", 400)
}
func (o *RepoMergeUpstreamBadRequest) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}
// NewRepoMergeUpstreamNotFound creates a RepoMergeUpstreamNotFound with default headers values
func NewRepoMergeUpstreamNotFound() *RepoMergeUpstreamNotFound {
return &RepoMergeUpstreamNotFound{}
}
/*
RepoMergeUpstreamNotFound describes a response with status code 404, with default header values.
APINotFound is a not found empty response
*/
type RepoMergeUpstreamNotFound struct {
}
// IsSuccess returns true when this repo merge upstream not found response has a 2xx status code
func (o *RepoMergeUpstreamNotFound) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo merge upstream not found response has a 3xx status code
func (o *RepoMergeUpstreamNotFound) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo merge upstream not found response has a 4xx status code
func (o *RepoMergeUpstreamNotFound) IsClientError() bool {
return true
}
// IsServerError returns true when this repo merge upstream not found response has a 5xx status code
func (o *RepoMergeUpstreamNotFound) IsServerError() bool {
return false
}
// IsCode returns true when this repo merge upstream not found response a status code equal to that given
func (o *RepoMergeUpstreamNotFound) IsCode(code int) bool {
return code == 404
}
// Code gets the status code for the repo merge upstream not found response
func (o *RepoMergeUpstreamNotFound) Code() int {
return 404
}
func (o *RepoMergeUpstreamNotFound) Error() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/merge-upstream][%d] repoMergeUpstreamNotFound", 404)
}
func (o *RepoMergeUpstreamNotFound) String() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/merge-upstream][%d] repoMergeUpstreamNotFound", 404)
}
func (o *RepoMergeUpstreamNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}

View File

@@ -132,7 +132,7 @@ type RepoSearchParams struct {
/* Sort. /* Sort.
sort repos by attribute. Supported values are "alpha", "created", "updated", "size", "git_size", "lfs_size", "stars", "forks" and "id". Default is "alpha" sort repos by attribute. Supported values are "alpha", "created", "updated", "size", and "id". Default is "alpha"
*/ */
Sort *string Sort *string

View File

@@ -1,216 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
// NewRepoUpdateBranchParams creates a new RepoUpdateBranchParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewRepoUpdateBranchParams() *RepoUpdateBranchParams {
return &RepoUpdateBranchParams{
timeout: cr.DefaultTimeout,
}
}
// NewRepoUpdateBranchParamsWithTimeout creates a new RepoUpdateBranchParams object
// with the ability to set a timeout on a request.
func NewRepoUpdateBranchParamsWithTimeout(timeout time.Duration) *RepoUpdateBranchParams {
return &RepoUpdateBranchParams{
timeout: timeout,
}
}
// NewRepoUpdateBranchParamsWithContext creates a new RepoUpdateBranchParams object
// with the ability to set a context for a request.
func NewRepoUpdateBranchParamsWithContext(ctx context.Context) *RepoUpdateBranchParams {
return &RepoUpdateBranchParams{
Context: ctx,
}
}
// NewRepoUpdateBranchParamsWithHTTPClient creates a new RepoUpdateBranchParams object
// with the ability to set a custom HTTPClient for a request.
func NewRepoUpdateBranchParamsWithHTTPClient(client *http.Client) *RepoUpdateBranchParams {
return &RepoUpdateBranchParams{
HTTPClient: client,
}
}
/*
RepoUpdateBranchParams contains all the parameters to send to the API endpoint
for the repo update branch operation.
Typically these are written to a http.Request.
*/
type RepoUpdateBranchParams struct {
// Body.
Body *models.UpdateBranchRepoOption
/* Branch.
name of the branch
*/
Branch string
/* Owner.
owner of the repo
*/
Owner string
/* Repo.
name of the repo
*/
Repo string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the repo update branch params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoUpdateBranchParams) WithDefaults() *RepoUpdateBranchParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the repo update branch params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoUpdateBranchParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the repo update branch params
func (o *RepoUpdateBranchParams) WithTimeout(timeout time.Duration) *RepoUpdateBranchParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the repo update branch params
func (o *RepoUpdateBranchParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the repo update branch params
func (o *RepoUpdateBranchParams) WithContext(ctx context.Context) *RepoUpdateBranchParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the repo update branch params
func (o *RepoUpdateBranchParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the repo update branch params
func (o *RepoUpdateBranchParams) WithHTTPClient(client *http.Client) *RepoUpdateBranchParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the repo update branch params
func (o *RepoUpdateBranchParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the repo update branch params
func (o *RepoUpdateBranchParams) WithBody(body *models.UpdateBranchRepoOption) *RepoUpdateBranchParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the repo update branch params
func (o *RepoUpdateBranchParams) SetBody(body *models.UpdateBranchRepoOption) {
o.Body = body
}
// WithBranch adds the branch to the repo update branch params
func (o *RepoUpdateBranchParams) WithBranch(branch string) *RepoUpdateBranchParams {
o.SetBranch(branch)
return o
}
// SetBranch adds the branch to the repo update branch params
func (o *RepoUpdateBranchParams) SetBranch(branch string) {
o.Branch = branch
}
// WithOwner adds the owner to the repo update branch params
func (o *RepoUpdateBranchParams) WithOwner(owner string) *RepoUpdateBranchParams {
o.SetOwner(owner)
return o
}
// SetOwner adds the owner to the repo update branch params
func (o *RepoUpdateBranchParams) SetOwner(owner string) {
o.Owner = owner
}
// WithRepo adds the repo to the repo update branch params
func (o *RepoUpdateBranchParams) WithRepo(repo string) *RepoUpdateBranchParams {
o.SetRepo(repo)
return o
}
// SetRepo adds the repo to the repo update branch params
func (o *RepoUpdateBranchParams) SetRepo(repo string) {
o.Repo = repo
}
// WriteToRequest writes these params to a swagger request
func (o *RepoUpdateBranchParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if o.Body != nil {
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
}
// path param branch
if err := r.SetPathParam("branch", o.Branch); err != nil {
return err
}
// path param owner
if err := r.SetPathParam("owner", o.Owner); err != nil {
return err
}
// path param repo
if err := r.SetPathParam("repo", o.Repo); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,194 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"net/http"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
// NewRepoUpdateBranchProtectionPrioriesParams creates a new RepoUpdateBranchProtectionPrioriesParams object,
// with the default timeout for this client.
//
// Default values are not hydrated, since defaults are normally applied by the API server side.
//
// To enforce default values in parameter, use SetDefaults or WithDefaults.
func NewRepoUpdateBranchProtectionPrioriesParams() *RepoUpdateBranchProtectionPrioriesParams {
return &RepoUpdateBranchProtectionPrioriesParams{
timeout: cr.DefaultTimeout,
}
}
// NewRepoUpdateBranchProtectionPrioriesParamsWithTimeout creates a new RepoUpdateBranchProtectionPrioriesParams object
// with the ability to set a timeout on a request.
func NewRepoUpdateBranchProtectionPrioriesParamsWithTimeout(timeout time.Duration) *RepoUpdateBranchProtectionPrioriesParams {
return &RepoUpdateBranchProtectionPrioriesParams{
timeout: timeout,
}
}
// NewRepoUpdateBranchProtectionPrioriesParamsWithContext creates a new RepoUpdateBranchProtectionPrioriesParams object
// with the ability to set a context for a request.
func NewRepoUpdateBranchProtectionPrioriesParamsWithContext(ctx context.Context) *RepoUpdateBranchProtectionPrioriesParams {
return &RepoUpdateBranchProtectionPrioriesParams{
Context: ctx,
}
}
// NewRepoUpdateBranchProtectionPrioriesParamsWithHTTPClient creates a new RepoUpdateBranchProtectionPrioriesParams object
// with the ability to set a custom HTTPClient for a request.
func NewRepoUpdateBranchProtectionPrioriesParamsWithHTTPClient(client *http.Client) *RepoUpdateBranchProtectionPrioriesParams {
return &RepoUpdateBranchProtectionPrioriesParams{
HTTPClient: client,
}
}
/*
RepoUpdateBranchProtectionPrioriesParams contains all the parameters to send to the API endpoint
for the repo update branch protection priories operation.
Typically these are written to a http.Request.
*/
type RepoUpdateBranchProtectionPrioriesParams struct {
// Body.
Body *models.UpdateBranchProtectionPriories
/* Owner.
owner of the repo
*/
Owner string
/* Repo.
name of the repo
*/
Repo string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithDefaults hydrates default values in the repo update branch protection priories params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoUpdateBranchProtectionPrioriesParams) WithDefaults() *RepoUpdateBranchProtectionPrioriesParams {
o.SetDefaults()
return o
}
// SetDefaults hydrates default values in the repo update branch protection priories params (not the query body).
//
// All values with no default are reset to their zero value.
func (o *RepoUpdateBranchProtectionPrioriesParams) SetDefaults() {
// no default values defined for this parameter
}
// WithTimeout adds the timeout to the repo update branch protection priories params
func (o *RepoUpdateBranchProtectionPrioriesParams) WithTimeout(timeout time.Duration) *RepoUpdateBranchProtectionPrioriesParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the repo update branch protection priories params
func (o *RepoUpdateBranchProtectionPrioriesParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the repo update branch protection priories params
func (o *RepoUpdateBranchProtectionPrioriesParams) WithContext(ctx context.Context) *RepoUpdateBranchProtectionPrioriesParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the repo update branch protection priories params
func (o *RepoUpdateBranchProtectionPrioriesParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the repo update branch protection priories params
func (o *RepoUpdateBranchProtectionPrioriesParams) WithHTTPClient(client *http.Client) *RepoUpdateBranchProtectionPrioriesParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the repo update branch protection priories params
func (o *RepoUpdateBranchProtectionPrioriesParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithBody adds the body to the repo update branch protection priories params
func (o *RepoUpdateBranchProtectionPrioriesParams) WithBody(body *models.UpdateBranchProtectionPriories) *RepoUpdateBranchProtectionPrioriesParams {
o.SetBody(body)
return o
}
// SetBody adds the body to the repo update branch protection priories params
func (o *RepoUpdateBranchProtectionPrioriesParams) SetBody(body *models.UpdateBranchProtectionPriories) {
o.Body = body
}
// WithOwner adds the owner to the repo update branch protection priories params
func (o *RepoUpdateBranchProtectionPrioriesParams) WithOwner(owner string) *RepoUpdateBranchProtectionPrioriesParams {
o.SetOwner(owner)
return o
}
// SetOwner adds the owner to the repo update branch protection priories params
func (o *RepoUpdateBranchProtectionPrioriesParams) SetOwner(owner string) {
o.Owner = owner
}
// WithRepo adds the repo to the repo update branch protection priories params
func (o *RepoUpdateBranchProtectionPrioriesParams) WithRepo(repo string) *RepoUpdateBranchProtectionPrioriesParams {
o.SetRepo(repo)
return o
}
// SetRepo adds the repo to the repo update branch protection priories params
func (o *RepoUpdateBranchProtectionPrioriesParams) SetRepo(repo string) {
o.Repo = repo
}
// WriteToRequest writes these params to a swagger request
func (o *RepoUpdateBranchProtectionPrioriesParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
if o.Body != nil {
if err := r.SetBodyParam(o.Body); err != nil {
return err
}
}
// path param owner
if err := r.SetPathParam("owner", o.Owner); err != nil {
return err
}
// path param repo
if err := r.SetPathParam("repo", o.Repo); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -1,306 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"fmt"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
)
// RepoUpdateBranchProtectionPrioriesReader is a Reader for the RepoUpdateBranchProtectionPriories structure.
type RepoUpdateBranchProtectionPrioriesReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *RepoUpdateBranchProtectionPrioriesReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 204:
result := NewRepoUpdateBranchProtectionPrioriesNoContent()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 404:
result := NewRepoUpdateBranchProtectionPrioriesNotFound()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 422:
result := NewRepoUpdateBranchProtectionPrioriesUnprocessableEntity()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 423:
result := NewRepoUpdateBranchProtectionPrioriesLocked()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[POST /repos/{owner}/{repo}/branch_protections/priority] repoUpdateBranchProtectionPriories", response, response.Code())
}
}
// NewRepoUpdateBranchProtectionPrioriesNoContent creates a RepoUpdateBranchProtectionPrioriesNoContent with default headers values
func NewRepoUpdateBranchProtectionPrioriesNoContent() *RepoUpdateBranchProtectionPrioriesNoContent {
return &RepoUpdateBranchProtectionPrioriesNoContent{}
}
/*
RepoUpdateBranchProtectionPrioriesNoContent describes a response with status code 204, with default header values.
APIEmpty is an empty response
*/
type RepoUpdateBranchProtectionPrioriesNoContent struct {
}
// IsSuccess returns true when this repo update branch protection priories no content response has a 2xx status code
func (o *RepoUpdateBranchProtectionPrioriesNoContent) IsSuccess() bool {
return true
}
// IsRedirect returns true when this repo update branch protection priories no content response has a 3xx status code
func (o *RepoUpdateBranchProtectionPrioriesNoContent) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo update branch protection priories no content response has a 4xx status code
func (o *RepoUpdateBranchProtectionPrioriesNoContent) IsClientError() bool {
return false
}
// IsServerError returns true when this repo update branch protection priories no content response has a 5xx status code
func (o *RepoUpdateBranchProtectionPrioriesNoContent) IsServerError() bool {
return false
}
// IsCode returns true when this repo update branch protection priories no content response a status code equal to that given
func (o *RepoUpdateBranchProtectionPrioriesNoContent) IsCode(code int) bool {
return code == 204
}
// Code gets the status code for the repo update branch protection priories no content response
func (o *RepoUpdateBranchProtectionPrioriesNoContent) Code() int {
return 204
}
func (o *RepoUpdateBranchProtectionPrioriesNoContent) Error() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/branch_protections/priority][%d] repoUpdateBranchProtectionPrioriesNoContent", 204)
}
func (o *RepoUpdateBranchProtectionPrioriesNoContent) String() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/branch_protections/priority][%d] repoUpdateBranchProtectionPrioriesNoContent", 204)
}
func (o *RepoUpdateBranchProtectionPrioriesNoContent) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}
// NewRepoUpdateBranchProtectionPrioriesNotFound creates a RepoUpdateBranchProtectionPrioriesNotFound with default headers values
func NewRepoUpdateBranchProtectionPrioriesNotFound() *RepoUpdateBranchProtectionPrioriesNotFound {
return &RepoUpdateBranchProtectionPrioriesNotFound{}
}
/*
RepoUpdateBranchProtectionPrioriesNotFound describes a response with status code 404, with default header values.
APINotFound is a not found empty response
*/
type RepoUpdateBranchProtectionPrioriesNotFound struct {
}
// IsSuccess returns true when this repo update branch protection priories not found response has a 2xx status code
func (o *RepoUpdateBranchProtectionPrioriesNotFound) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo update branch protection priories not found response has a 3xx status code
func (o *RepoUpdateBranchProtectionPrioriesNotFound) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo update branch protection priories not found response has a 4xx status code
func (o *RepoUpdateBranchProtectionPrioriesNotFound) IsClientError() bool {
return true
}
// IsServerError returns true when this repo update branch protection priories not found response has a 5xx status code
func (o *RepoUpdateBranchProtectionPrioriesNotFound) IsServerError() bool {
return false
}
// IsCode returns true when this repo update branch protection priories not found response a status code equal to that given
func (o *RepoUpdateBranchProtectionPrioriesNotFound) IsCode(code int) bool {
return code == 404
}
// Code gets the status code for the repo update branch protection priories not found response
func (o *RepoUpdateBranchProtectionPrioriesNotFound) Code() int {
return 404
}
func (o *RepoUpdateBranchProtectionPrioriesNotFound) Error() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/branch_protections/priority][%d] repoUpdateBranchProtectionPrioriesNotFound", 404)
}
func (o *RepoUpdateBranchProtectionPrioriesNotFound) String() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/branch_protections/priority][%d] repoUpdateBranchProtectionPrioriesNotFound", 404)
}
func (o *RepoUpdateBranchProtectionPrioriesNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}
// NewRepoUpdateBranchProtectionPrioriesUnprocessableEntity creates a RepoUpdateBranchProtectionPrioriesUnprocessableEntity with default headers values
func NewRepoUpdateBranchProtectionPrioriesUnprocessableEntity() *RepoUpdateBranchProtectionPrioriesUnprocessableEntity {
return &RepoUpdateBranchProtectionPrioriesUnprocessableEntity{}
}
/*
RepoUpdateBranchProtectionPrioriesUnprocessableEntity describes a response with status code 422, with default header values.
APIValidationError is error format response related to input validation
*/
type RepoUpdateBranchProtectionPrioriesUnprocessableEntity struct {
Message string
URL string
}
// IsSuccess returns true when this repo update branch protection priories unprocessable entity response has a 2xx status code
func (o *RepoUpdateBranchProtectionPrioriesUnprocessableEntity) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo update branch protection priories unprocessable entity response has a 3xx status code
func (o *RepoUpdateBranchProtectionPrioriesUnprocessableEntity) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo update branch protection priories unprocessable entity response has a 4xx status code
func (o *RepoUpdateBranchProtectionPrioriesUnprocessableEntity) IsClientError() bool {
return true
}
// IsServerError returns true when this repo update branch protection priories unprocessable entity response has a 5xx status code
func (o *RepoUpdateBranchProtectionPrioriesUnprocessableEntity) IsServerError() bool {
return false
}
// IsCode returns true when this repo update branch protection priories unprocessable entity response a status code equal to that given
func (o *RepoUpdateBranchProtectionPrioriesUnprocessableEntity) IsCode(code int) bool {
return code == 422
}
// Code gets the status code for the repo update branch protection priories unprocessable entity response
func (o *RepoUpdateBranchProtectionPrioriesUnprocessableEntity) Code() int {
return 422
}
func (o *RepoUpdateBranchProtectionPrioriesUnprocessableEntity) Error() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/branch_protections/priority][%d] repoUpdateBranchProtectionPrioriesUnprocessableEntity", 422)
}
func (o *RepoUpdateBranchProtectionPrioriesUnprocessableEntity) String() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/branch_protections/priority][%d] repoUpdateBranchProtectionPrioriesUnprocessableEntity", 422)
}
func (o *RepoUpdateBranchProtectionPrioriesUnprocessableEntity) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}
// NewRepoUpdateBranchProtectionPrioriesLocked creates a RepoUpdateBranchProtectionPrioriesLocked with default headers values
func NewRepoUpdateBranchProtectionPrioriesLocked() *RepoUpdateBranchProtectionPrioriesLocked {
return &RepoUpdateBranchProtectionPrioriesLocked{}
}
/*
RepoUpdateBranchProtectionPrioriesLocked describes a response with status code 423, with default header values.
APIRepoArchivedError is an error that is raised when an archived repo should be modified
*/
type RepoUpdateBranchProtectionPrioriesLocked struct {
Message string
URL string
}
// IsSuccess returns true when this repo update branch protection priories locked response has a 2xx status code
func (o *RepoUpdateBranchProtectionPrioriesLocked) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo update branch protection priories locked response has a 3xx status code
func (o *RepoUpdateBranchProtectionPrioriesLocked) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo update branch protection priories locked response has a 4xx status code
func (o *RepoUpdateBranchProtectionPrioriesLocked) IsClientError() bool {
return true
}
// IsServerError returns true when this repo update branch protection priories locked response has a 5xx status code
func (o *RepoUpdateBranchProtectionPrioriesLocked) IsServerError() bool {
return false
}
// IsCode returns true when this repo update branch protection priories locked response a status code equal to that given
func (o *RepoUpdateBranchProtectionPrioriesLocked) IsCode(code int) bool {
return code == 423
}
// Code gets the status code for the repo update branch protection priories locked response
func (o *RepoUpdateBranchProtectionPrioriesLocked) Code() int {
return 423
}
func (o *RepoUpdateBranchProtectionPrioriesLocked) Error() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/branch_protections/priority][%d] repoUpdateBranchProtectionPrioriesLocked", 423)
}
func (o *RepoUpdateBranchProtectionPrioriesLocked) String() string {
return fmt.Sprintf("[POST /repos/{owner}/{repo}/branch_protections/priority][%d] repoUpdateBranchProtectionPrioriesLocked", 423)
}
func (o *RepoUpdateBranchProtectionPrioriesLocked) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}

View File

@@ -1,306 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package repository
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"fmt"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
)
// RepoUpdateBranchReader is a Reader for the RepoUpdateBranch structure.
type RepoUpdateBranchReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *RepoUpdateBranchReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 204:
result := NewRepoUpdateBranchNoContent()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 403:
result := NewRepoUpdateBranchForbidden()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 404:
result := NewRepoUpdateBranchNotFound()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
case 422:
result := NewRepoUpdateBranchUnprocessableEntity()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("[PATCH /repos/{owner}/{repo}/branches/{branch}] repoUpdateBranch", response, response.Code())
}
}
// NewRepoUpdateBranchNoContent creates a RepoUpdateBranchNoContent with default headers values
func NewRepoUpdateBranchNoContent() *RepoUpdateBranchNoContent {
return &RepoUpdateBranchNoContent{}
}
/*
RepoUpdateBranchNoContent describes a response with status code 204, with default header values.
APIEmpty is an empty response
*/
type RepoUpdateBranchNoContent struct {
}
// IsSuccess returns true when this repo update branch no content response has a 2xx status code
func (o *RepoUpdateBranchNoContent) IsSuccess() bool {
return true
}
// IsRedirect returns true when this repo update branch no content response has a 3xx status code
func (o *RepoUpdateBranchNoContent) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo update branch no content response has a 4xx status code
func (o *RepoUpdateBranchNoContent) IsClientError() bool {
return false
}
// IsServerError returns true when this repo update branch no content response has a 5xx status code
func (o *RepoUpdateBranchNoContent) IsServerError() bool {
return false
}
// IsCode returns true when this repo update branch no content response a status code equal to that given
func (o *RepoUpdateBranchNoContent) IsCode(code int) bool {
return code == 204
}
// Code gets the status code for the repo update branch no content response
func (o *RepoUpdateBranchNoContent) Code() int {
return 204
}
func (o *RepoUpdateBranchNoContent) Error() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/branches/{branch}][%d] repoUpdateBranchNoContent", 204)
}
func (o *RepoUpdateBranchNoContent) String() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/branches/{branch}][%d] repoUpdateBranchNoContent", 204)
}
func (o *RepoUpdateBranchNoContent) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}
// NewRepoUpdateBranchForbidden creates a RepoUpdateBranchForbidden with default headers values
func NewRepoUpdateBranchForbidden() *RepoUpdateBranchForbidden {
return &RepoUpdateBranchForbidden{}
}
/*
RepoUpdateBranchForbidden describes a response with status code 403, with default header values.
APIForbiddenError is a forbidden error response
*/
type RepoUpdateBranchForbidden struct {
Message string
URL string
}
// IsSuccess returns true when this repo update branch forbidden response has a 2xx status code
func (o *RepoUpdateBranchForbidden) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo update branch forbidden response has a 3xx status code
func (o *RepoUpdateBranchForbidden) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo update branch forbidden response has a 4xx status code
func (o *RepoUpdateBranchForbidden) IsClientError() bool {
return true
}
// IsServerError returns true when this repo update branch forbidden response has a 5xx status code
func (o *RepoUpdateBranchForbidden) IsServerError() bool {
return false
}
// IsCode returns true when this repo update branch forbidden response a status code equal to that given
func (o *RepoUpdateBranchForbidden) IsCode(code int) bool {
return code == 403
}
// Code gets the status code for the repo update branch forbidden response
func (o *RepoUpdateBranchForbidden) Code() int {
return 403
}
func (o *RepoUpdateBranchForbidden) Error() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/branches/{branch}][%d] repoUpdateBranchForbidden", 403)
}
func (o *RepoUpdateBranchForbidden) String() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/branches/{branch}][%d] repoUpdateBranchForbidden", 403)
}
func (o *RepoUpdateBranchForbidden) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}
// NewRepoUpdateBranchNotFound creates a RepoUpdateBranchNotFound with default headers values
func NewRepoUpdateBranchNotFound() *RepoUpdateBranchNotFound {
return &RepoUpdateBranchNotFound{}
}
/*
RepoUpdateBranchNotFound describes a response with status code 404, with default header values.
APINotFound is a not found empty response
*/
type RepoUpdateBranchNotFound struct {
}
// IsSuccess returns true when this repo update branch not found response has a 2xx status code
func (o *RepoUpdateBranchNotFound) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo update branch not found response has a 3xx status code
func (o *RepoUpdateBranchNotFound) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo update branch not found response has a 4xx status code
func (o *RepoUpdateBranchNotFound) IsClientError() bool {
return true
}
// IsServerError returns true when this repo update branch not found response has a 5xx status code
func (o *RepoUpdateBranchNotFound) IsServerError() bool {
return false
}
// IsCode returns true when this repo update branch not found response a status code equal to that given
func (o *RepoUpdateBranchNotFound) IsCode(code int) bool {
return code == 404
}
// Code gets the status code for the repo update branch not found response
func (o *RepoUpdateBranchNotFound) Code() int {
return 404
}
func (o *RepoUpdateBranchNotFound) Error() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/branches/{branch}][%d] repoUpdateBranchNotFound", 404)
}
func (o *RepoUpdateBranchNotFound) String() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/branches/{branch}][%d] repoUpdateBranchNotFound", 404)
}
func (o *RepoUpdateBranchNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}
// NewRepoUpdateBranchUnprocessableEntity creates a RepoUpdateBranchUnprocessableEntity with default headers values
func NewRepoUpdateBranchUnprocessableEntity() *RepoUpdateBranchUnprocessableEntity {
return &RepoUpdateBranchUnprocessableEntity{}
}
/*
RepoUpdateBranchUnprocessableEntity describes a response with status code 422, with default header values.
APIValidationError is error format response related to input validation
*/
type RepoUpdateBranchUnprocessableEntity struct {
Message string
URL string
}
// IsSuccess returns true when this repo update branch unprocessable entity response has a 2xx status code
func (o *RepoUpdateBranchUnprocessableEntity) IsSuccess() bool {
return false
}
// IsRedirect returns true when this repo update branch unprocessable entity response has a 3xx status code
func (o *RepoUpdateBranchUnprocessableEntity) IsRedirect() bool {
return false
}
// IsClientError returns true when this repo update branch unprocessable entity response has a 4xx status code
func (o *RepoUpdateBranchUnprocessableEntity) IsClientError() bool {
return true
}
// IsServerError returns true when this repo update branch unprocessable entity response has a 5xx status code
func (o *RepoUpdateBranchUnprocessableEntity) IsServerError() bool {
return false
}
// IsCode returns true when this repo update branch unprocessable entity response a status code equal to that given
func (o *RepoUpdateBranchUnprocessableEntity) IsCode(code int) bool {
return code == 422
}
// Code gets the status code for the repo update branch unprocessable entity response
func (o *RepoUpdateBranchUnprocessableEntity) Code() int {
return 422
}
func (o *RepoUpdateBranchUnprocessableEntity) Error() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/branches/{branch}][%d] repoUpdateBranchUnprocessableEntity", 422)
}
func (o *RepoUpdateBranchUnprocessableEntity) String() string {
return fmt.Sprintf("[PATCH /repos/{owner}/{repo}/branches/{branch}][%d] repoUpdateBranchUnprocessableEntity", 422)
}
func (o *RepoUpdateBranchUnprocessableEntity) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
// hydrates response header message
hdrMessage := response.GetHeader("message")
if hdrMessage != "" {
o.Message = hdrMessage
}
// hydrates response header url
hdrURL := response.GetHeader("url")
if hdrURL != "" {
o.URL = hdrURL
}
return nil
}

View File

@@ -127,8 +127,6 @@ type ClientService interface {
GetTree(params *GetTreeParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetTreeOK, error) GetTree(params *GetTreeParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*GetTreeOK, error)
ListActionTasks(params *ListActionTasksParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListActionTasksOK, error)
AcceptRepoTransfer(params *AcceptRepoTransferParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*AcceptRepoTransferAccepted, error) AcceptRepoTransfer(params *AcceptRepoTransferParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*AcceptRepoTransferAccepted, error)
CreateCurrentUserRepo(params *CreateCurrentUserRepoParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*CreateCurrentUserRepoCreated, error) CreateCurrentUserRepo(params *CreateCurrentUserRepoParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*CreateCurrentUserRepoCreated, error)
@@ -195,8 +193,6 @@ type ClientService interface {
RepoCreateTag(params *RepoCreateTagParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoCreateTagOK, error) RepoCreateTag(params *RepoCreateTagParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoCreateTagOK, error)
RepoCreateTagProtection(params *RepoCreateTagProtectionParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoCreateTagProtectionCreated, error)
RepoCreateWikiPage(params *RepoCreateWikiPageParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoCreateWikiPageCreated, error) RepoCreateWikiPage(params *RepoCreateWikiPageParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoCreateWikiPageCreated, error)
RepoDelete(params *RepoDeleteParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoDeleteNoContent, error) RepoDelete(params *RepoDeleteParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoDeleteNoContent, error)
@@ -231,8 +227,6 @@ type ClientService interface {
RepoDeleteTag(params *RepoDeleteTagParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoDeleteTagNoContent, error) RepoDeleteTag(params *RepoDeleteTagParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoDeleteTagNoContent, error)
RepoDeleteTagProtection(params *RepoDeleteTagProtectionParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoDeleteTagProtectionNoContent, error)
RepoDeleteTeam(params *RepoDeleteTeamParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoDeleteTeamNoContent, error) RepoDeleteTeam(params *RepoDeleteTeamParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoDeleteTeamNoContent, error)
RepoDeleteTopic(params *RepoDeleteTopicParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoDeleteTopicNoContent, error) RepoDeleteTopic(params *RepoDeleteTopicParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoDeleteTopicNoContent, error)
@@ -259,8 +253,6 @@ type ClientService interface {
RepoEditReleaseAttachment(params *RepoEditReleaseAttachmentParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoEditReleaseAttachmentCreated, error) RepoEditReleaseAttachment(params *RepoEditReleaseAttachmentParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoEditReleaseAttachmentCreated, error)
RepoEditTagProtection(params *RepoEditTagProtectionParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoEditTagProtectionOK, error)
RepoEditWikiPage(params *RepoEditWikiPageParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoEditWikiPageOK, error) RepoEditWikiPage(params *RepoEditWikiPageParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoEditWikiPageOK, error)
RepoGet(params *RepoGetParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetOK, error) RepoGet(params *RepoGetParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetOK, error)
@@ -301,8 +293,6 @@ type ClientService interface {
RepoGetLatestRelease(params *RepoGetLatestReleaseParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetLatestReleaseOK, error) RepoGetLatestRelease(params *RepoGetLatestReleaseParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetLatestReleaseOK, error)
RepoGetLicenses(params *RepoGetLicensesParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetLicensesOK, error)
RepoGetNote(params *RepoGetNoteParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetNoteOK, error) RepoGetNote(params *RepoGetNoteParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetNoteOK, error)
RepoGetPullRequest(params *RepoGetPullRequestParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetPullRequestOK, error) RepoGetPullRequest(params *RepoGetPullRequestParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetPullRequestOK, error)
@@ -339,8 +329,6 @@ type ClientService interface {
RepoGetTag(params *RepoGetTagParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetTagOK, error) RepoGetTag(params *RepoGetTagParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetTagOK, error)
RepoGetTagProtection(params *RepoGetTagProtectionParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetTagProtectionOK, error)
RepoGetWikiPage(params *RepoGetWikiPageParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetWikiPageOK, error) RepoGetWikiPage(params *RepoGetWikiPageParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetWikiPageOK, error)
RepoGetWikiPageRevisions(params *RepoGetWikiPageRevisionsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetWikiPageRevisionsOK, error) RepoGetWikiPageRevisions(params *RepoGetWikiPageRevisionsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetWikiPageRevisionsOK, error)
@@ -389,8 +377,6 @@ type ClientService interface {
RepoListSubscribers(params *RepoListSubscribersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoListSubscribersOK, error) RepoListSubscribers(params *RepoListSubscribersParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoListSubscribersOK, error)
RepoListTagProtection(params *RepoListTagProtectionParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoListTagProtectionOK, error)
RepoListTags(params *RepoListTagsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoListTagsOK, error) RepoListTags(params *RepoListTagsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoListTagsOK, error)
RepoListTeams(params *RepoListTeamsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoListTeamsOK, error) RepoListTeams(params *RepoListTeamsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoListTeamsOK, error)
@@ -399,8 +385,6 @@ type ClientService interface {
RepoMergePullRequest(params *RepoMergePullRequestParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoMergePullRequestOK, error) RepoMergePullRequest(params *RepoMergePullRequestParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoMergePullRequestOK, error)
RepoMergeUpstream(params *RepoMergeUpstreamParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoMergeUpstreamOK, error)
RepoMigrate(params *RepoMigrateParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoMigrateCreated, error) RepoMigrate(params *RepoMigrateParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoMigrateCreated, error)
RepoMirrorSync(params *RepoMirrorSyncParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoMirrorSyncOK, error) RepoMirrorSync(params *RepoMirrorSyncParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoMirrorSyncOK, error)
@@ -427,10 +411,6 @@ type ClientService interface {
RepoUpdateAvatar(params *RepoUpdateAvatarParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoUpdateAvatarNoContent, error) RepoUpdateAvatar(params *RepoUpdateAvatarParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoUpdateAvatarNoContent, error)
RepoUpdateBranch(params *RepoUpdateBranchParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoUpdateBranchNoContent, error)
RepoUpdateBranchProtectionPriories(params *RepoUpdateBranchProtectionPrioriesParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoUpdateBranchProtectionPrioriesNoContent, error)
RepoUpdateFile(params *RepoUpdateFileParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoUpdateFileOK, error) RepoUpdateFile(params *RepoUpdateFileParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoUpdateFileOK, error)
RepoUpdatePullRequest(params *RepoUpdatePullRequestParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoUpdatePullRequestOK, error) RepoUpdatePullRequest(params *RepoUpdatePullRequestParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoUpdatePullRequestOK, error)
@@ -573,45 +553,6 @@ func (a *Client) GetTree(params *GetTreeParams, authInfo runtime.ClientAuthInfoW
panic(msg) panic(msg)
} }
/*
ListActionTasks lists a repository s action tasks
*/
func (a *Client) ListActionTasks(params *ListActionTasksParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*ListActionTasksOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewListActionTasksParams()
}
op := &runtime.ClientOperation{
ID: "ListActionTasks",
Method: "GET",
PathPattern: "/repos/{owner}/{repo}/actions/tasks",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json", "text/plain"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &ListActionTasksReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*ListActionTasksOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for ListActionTasks: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/* /*
AcceptRepoTransfer accepts a repo transfer AcceptRepoTransfer accepts a repo transfer
*/ */
@@ -1046,7 +987,7 @@ func (a *Client) RejectRepoTransfer(params *RejectRepoTransferParams, authInfo r
} }
/* /*
RepoAddCollaborator adds or update a collaborator to a repository RepoAddCollaborator adds a collaborator to a repository
*/ */
func (a *Client) RepoAddCollaborator(params *RepoAddCollaboratorParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoAddCollaboratorNoContent, error) { func (a *Client) RepoAddCollaborator(params *RepoAddCollaboratorParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoAddCollaboratorNoContent, error) {
// TODO: Validate the params before sending // TODO: Validate the params before sending
@@ -1903,45 +1844,6 @@ func (a *Client) RepoCreateTag(params *RepoCreateTagParams, authInfo runtime.Cli
panic(msg) panic(msg)
} }
/*
RepoCreateTagProtection creates a tag protections for a repository
*/
func (a *Client) RepoCreateTagProtection(params *RepoCreateTagProtectionParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoCreateTagProtectionCreated, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewRepoCreateTagProtectionParams()
}
op := &runtime.ClientOperation{
ID: "repoCreateTagProtection",
Method: "POST",
PathPattern: "/repos/{owner}/{repo}/tag_protections",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &RepoCreateTagProtectionReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*RepoCreateTagProtectionCreated)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for repoCreateTagProtection: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/* /*
RepoCreateWikiPage creates a wiki page RepoCreateWikiPage creates a wiki page
*/ */
@@ -2605,45 +2507,6 @@ func (a *Client) RepoDeleteTag(params *RepoDeleteTagParams, authInfo runtime.Cli
panic(msg) panic(msg)
} }
/*
RepoDeleteTagProtection deletes a specific tag protection for the repository
*/
func (a *Client) RepoDeleteTagProtection(params *RepoDeleteTagProtectionParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoDeleteTagProtectionNoContent, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewRepoDeleteTagProtectionParams()
}
op := &runtime.ClientOperation{
ID: "repoDeleteTagProtection",
Method: "DELETE",
PathPattern: "/repos/{owner}/{repo}/tag_protections/{id}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json", "text/plain"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &RepoDeleteTagProtectionReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*RepoDeleteTagProtectionNoContent)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for repoDeleteTagProtection: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/* /*
RepoDeleteTeam deletes a team from a repository RepoDeleteTeam deletes a team from a repository
*/ */
@@ -3151,45 +3014,6 @@ func (a *Client) RepoEditReleaseAttachment(params *RepoEditReleaseAttachmentPara
panic(msg) panic(msg)
} }
/*
RepoEditTagProtection edits a tag protections for a repository only fields that are set will be changed
*/
func (a *Client) RepoEditTagProtection(params *RepoEditTagProtectionParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoEditTagProtectionOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewRepoEditTagProtectionParams()
}
op := &runtime.ClientOperation{
ID: "repoEditTagProtection",
Method: "PATCH",
PathPattern: "/repos/{owner}/{repo}/tag_protections/{id}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &RepoEditTagProtectionReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*RepoEditTagProtectionOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for repoEditTagProtection: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/* /*
RepoEditWikiPage edits a wiki page RepoEditWikiPage edits a wiki page
*/ */
@@ -3542,7 +3366,7 @@ func (a *Client) RepoGetCombinedStatusByRef(params *RepoGetCombinedStatusByRefPa
} }
/* /*
RepoGetCommitPullRequest gets the merged pull request of the commit RepoGetCommitPullRequest gets the pull request of the commit
*/ */
func (a *Client) RepoGetCommitPullRequest(params *RepoGetCommitPullRequestParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetCommitPullRequestOK, error) { func (a *Client) RepoGetCommitPullRequest(params *RepoGetCommitPullRequestParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetCommitPullRequestOK, error) {
// TODO: Validate the params before sending // TODO: Validate the params before sending
@@ -3970,45 +3794,6 @@ func (a *Client) RepoGetLatestRelease(params *RepoGetLatestReleaseParams, authIn
panic(msg) panic(msg)
} }
/*
RepoGetLicenses gets repo licenses
*/
func (a *Client) RepoGetLicenses(params *RepoGetLicensesParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetLicensesOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewRepoGetLicensesParams()
}
op := &runtime.ClientOperation{
ID: "repoGetLicenses",
Method: "GET",
PathPattern: "/repos/{owner}/{repo}/licenses",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json", "text/plain"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &RepoGetLicensesReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*RepoGetLicensesOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for repoGetLicenses: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/* /*
RepoGetNote gets a note corresponding to a single commit from a repository RepoGetNote gets a note corresponding to a single commit from a repository
*/ */
@@ -4334,7 +4119,7 @@ func (a *Client) RepoGetRawFile(params *RepoGetRawFileParams, authInfo runtime.C
Method: "GET", Method: "GET",
PathPattern: "/repos/{owner}/{repo}/raw/{filepath}", PathPattern: "/repos/{owner}/{repo}/raw/{filepath}",
ProducesMediaTypes: []string{"application/octet-stream"}, ProducesMediaTypes: []string{"application/octet-stream"},
ConsumesMediaTypes: []string{"application/json", "text/plain"}, ConsumesMediaTypes: []string{"application/octet-stream"},
Schemes: []string{"http", "https"}, Schemes: []string{"http", "https"},
Params: params, Params: params,
Reader: &RepoGetRawFileReader{formats: a.formats, writer: writer}, Reader: &RepoGetRawFileReader{formats: a.formats, writer: writer},
@@ -4605,7 +4390,7 @@ func (a *Client) RepoGetRunnerRegistrationToken(params *RepoGetRunnerRegistratio
op := &runtime.ClientOperation{ op := &runtime.ClientOperation{
ID: "repoGetRunnerRegistrationToken", ID: "repoGetRunnerRegistrationToken",
Method: "GET", Method: "GET",
PathPattern: "/repos/{owner}/{repo}/actions/runners/registration-token", PathPattern: "/repos/{owner}/{repo}/runners/registration-token",
ProducesMediaTypes: []string{"application/json"}, ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json", "text/plain"}, ConsumesMediaTypes: []string{"application/json", "text/plain"},
Schemes: []string{"http", "https"}, Schemes: []string{"http", "https"},
@@ -4711,45 +4496,6 @@ func (a *Client) RepoGetTag(params *RepoGetTagParams, authInfo runtime.ClientAut
panic(msg) panic(msg)
} }
/*
RepoGetTagProtection gets a specific tag protection for the repository
*/
func (a *Client) RepoGetTagProtection(params *RepoGetTagProtectionParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetTagProtectionOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewRepoGetTagProtectionParams()
}
op := &runtime.ClientOperation{
ID: "repoGetTagProtection",
Method: "GET",
PathPattern: "/repos/{owner}/{repo}/tag_protections/{id}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json", "text/plain"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &RepoGetTagProtectionReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*RepoGetTagProtectionOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for repoGetTagProtection: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/* /*
RepoGetWikiPage gets a wiki page RepoGetWikiPage gets a wiki page
*/ */
@@ -5686,45 +5432,6 @@ func (a *Client) RepoListSubscribers(params *RepoListSubscribersParams, authInfo
panic(msg) panic(msg)
} }
/*
RepoListTagProtection lists tag protections for a repository
*/
func (a *Client) RepoListTagProtection(params *RepoListTagProtectionParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoListTagProtectionOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewRepoListTagProtectionParams()
}
op := &runtime.ClientOperation{
ID: "repoListTagProtection",
Method: "GET",
PathPattern: "/repos/{owner}/{repo}/tag_protections",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json", "text/plain"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &RepoListTagProtectionReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*RepoListTagProtectionOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for repoListTagProtection: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/* /*
RepoListTags lists a repository s tags RepoListTags lists a repository s tags
*/ */
@@ -5881,45 +5588,6 @@ func (a *Client) RepoMergePullRequest(params *RepoMergePullRequestParams, authIn
panic(msg) panic(msg)
} }
/*
RepoMergeUpstream merges a branch from upstream
*/
func (a *Client) RepoMergeUpstream(params *RepoMergeUpstreamParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoMergeUpstreamOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewRepoMergeUpstreamParams()
}
op := &runtime.ClientOperation{
ID: "repoMergeUpstream",
Method: "POST",
PathPattern: "/repos/{owner}/{repo}/merge-upstream",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json", "text/plain"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &RepoMergeUpstreamReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*RepoMergeUpstreamOK)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for repoMergeUpstream: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/* /*
RepoMigrate migrates a remote git repository RepoMigrate migrates a remote git repository
*/ */
@@ -6427,84 +6095,6 @@ func (a *Client) RepoUpdateAvatar(params *RepoUpdateAvatarParams, authInfo runti
panic(msg) panic(msg)
} }
/*
RepoUpdateBranch updates a branch
*/
func (a *Client) RepoUpdateBranch(params *RepoUpdateBranchParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoUpdateBranchNoContent, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewRepoUpdateBranchParams()
}
op := &runtime.ClientOperation{
ID: "repoUpdateBranch",
Method: "PATCH",
PathPattern: "/repos/{owner}/{repo}/branches/{branch}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &RepoUpdateBranchReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*RepoUpdateBranchNoContent)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for repoUpdateBranch: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/*
RepoUpdateBranchProtectionPriories updates the priorities of branch protections for a repository
*/
func (a *Client) RepoUpdateBranchProtectionPriories(params *RepoUpdateBranchProtectionPrioriesParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoUpdateBranchProtectionPrioriesNoContent, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewRepoUpdateBranchProtectionPrioriesParams()
}
op := &runtime.ClientOperation{
ID: "repoUpdateBranchProtectionPriories",
Method: "POST",
PathPattern: "/repos/{owner}/{repo}/branch_protections/priority",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &RepoUpdateBranchProtectionPrioriesReader{formats: a.formats},
AuthInfo: authInfo,
Context: params.Context,
Client: params.HTTPClient,
}
for _, opt := range opts {
opt(op)
}
result, err := a.transport.Submit(op)
if err != nil {
return nil, err
}
success, ok := result.(*RepoUpdateBranchProtectionPrioriesNoContent)
if ok {
return success, nil
}
// unexpected success response
// safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue
msg := fmt.Sprintf("unexpected success response for repoUpdateBranchProtectionPriories: API contract not enforced by server. Client expected to get an error, but got: %T", result)
panic(msg)
}
/* /*
RepoUpdateFile updates a file in a repository RepoUpdateFile updates a file in a repository
*/ */

View File

@@ -1,144 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// ActionTask ActionTask represents a ActionTask
//
// swagger:model ActionTask
type ActionTask struct {
// created at
// Format: date-time
CreatedAt strfmt.DateTime `json:"created_at,omitempty"`
// display title
DisplayTitle string `json:"display_title,omitempty"`
// event
Event string `json:"event,omitempty"`
// head branch
HeadBranch string `json:"head_branch,omitempty"`
// head s h a
HeadSHA string `json:"head_sha,omitempty"`
// ID
ID int64 `json:"id,omitempty"`
// name
Name string `json:"name,omitempty"`
// run number
RunNumber int64 `json:"run_number,omitempty"`
// run started at
// Format: date-time
RunStartedAt strfmt.DateTime `json:"run_started_at,omitempty"`
// status
Status string `json:"status,omitempty"`
// URL
URL string `json:"url,omitempty"`
// updated at
// Format: date-time
UpdatedAt strfmt.DateTime `json:"updated_at,omitempty"`
// workflow ID
WorkflowID string `json:"workflow_id,omitempty"`
}
// Validate validates this action task
func (m *ActionTask) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateCreatedAt(formats); err != nil {
res = append(res, err)
}
if err := m.validateRunStartedAt(formats); err != nil {
res = append(res, err)
}
if err := m.validateUpdatedAt(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ActionTask) validateCreatedAt(formats strfmt.Registry) error {
if swag.IsZero(m.CreatedAt) { // not required
return nil
}
if err := validate.FormatOf("created_at", "body", "date-time", m.CreatedAt.String(), formats); err != nil {
return err
}
return nil
}
func (m *ActionTask) validateRunStartedAt(formats strfmt.Registry) error {
if swag.IsZero(m.RunStartedAt) { // not required
return nil
}
if err := validate.FormatOf("run_started_at", "body", "date-time", m.RunStartedAt.String(), formats); err != nil {
return err
}
return nil
}
func (m *ActionTask) validateUpdatedAt(formats strfmt.Registry) error {
if swag.IsZero(m.UpdatedAt) { // not required
return nil
}
if err := validate.FormatOf("updated_at", "body", "date-time", m.UpdatedAt.String(), formats); err != nil {
return err
}
return nil
}
// ContextValidate validates this action task based on context it is used
func (m *ActionTask) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *ActionTask) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ActionTask) UnmarshalBinary(b []byte) error {
var res ActionTask
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -1,124 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// ActionTaskResponse ActionTaskResponse returns a ActionTask
//
// swagger:model ActionTaskResponse
type ActionTaskResponse struct {
// entries
Entries []*ActionTask `json:"workflow_runs"`
// total count
TotalCount int64 `json:"total_count,omitempty"`
}
// Validate validates this action task response
func (m *ActionTaskResponse) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateEntries(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ActionTaskResponse) validateEntries(formats strfmt.Registry) error {
if swag.IsZero(m.Entries) { // not required
return nil
}
for i := 0; i < len(m.Entries); i++ {
if swag.IsZero(m.Entries[i]) { // not required
continue
}
if m.Entries[i] != nil {
if err := m.Entries[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("workflow_runs" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("workflow_runs" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// ContextValidate validate this action task response based on the context it is used
func (m *ActionTaskResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateEntries(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ActionTaskResponse) contextValidateEntries(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Entries); i++ {
if m.Entries[i] != nil {
if swag.IsZero(m.Entries[i]) { // not required
return nil
}
if err := m.Entries[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("workflow_runs" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("workflow_runs" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
// MarshalBinary interface implementation
func (m *ActionTaskResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ActionTaskResponse) UnmarshalBinary(b []byte) error {
var res ActionTaskResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -7,7 +7,6 @@ package models
import ( import (
"context" "context"
"encoding/json"
"github.com/go-openapi/errors" "github.com/go-openapi/errors"
"github.com/go-openapi/strfmt" "github.com/go-openapi/strfmt"
@@ -39,8 +38,7 @@ type Activity struct {
// is private // is private
IsPrivate bool `json:"is_private,omitempty"` IsPrivate bool `json:"is_private,omitempty"`
// the type of action // op type
// Enum: ["create_repo","rename_repo","star_repo","watch_repo","commit_repo","create_issue","create_pull_request","transfer_repo","push_tag","comment_issue","merge_pull_request","close_issue","reopen_issue","close_pull_request","reopen_pull_request","delete_tag","delete_branch","mirror_sync_push","mirror_sync_create","mirror_sync_delete","approve_pull_request","reject_pull_request","comment_pull","publish_release","pull_review_dismissed","pull_request_ready_for_review","auto_merge_pull_request"]
OpType string `json:"op_type,omitempty"` OpType string `json:"op_type,omitempty"`
// ref name // ref name
@@ -70,10 +68,6 @@ func (m *Activity) Validate(formats strfmt.Registry) error {
res = append(res, err) res = append(res, err)
} }
if err := m.validateOpType(formats); err != nil {
res = append(res, err)
}
if err := m.validateActUser(formats); err != nil { if err := m.validateActUser(formats); err != nil {
res = append(res, err) res = append(res, err)
} }
@@ -104,123 +98,6 @@ func (m *Activity) validateCreated(formats strfmt.Registry) error {
return nil return nil
} }
var activityTypeOpTypePropEnum []interface{}
func init() {
var res []string
if err := json.Unmarshal([]byte(`["create_repo","rename_repo","star_repo","watch_repo","commit_repo","create_issue","create_pull_request","transfer_repo","push_tag","comment_issue","merge_pull_request","close_issue","reopen_issue","close_pull_request","reopen_pull_request","delete_tag","delete_branch","mirror_sync_push","mirror_sync_create","mirror_sync_delete","approve_pull_request","reject_pull_request","comment_pull","publish_release","pull_review_dismissed","pull_request_ready_for_review","auto_merge_pull_request"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
activityTypeOpTypePropEnum = append(activityTypeOpTypePropEnum, v)
}
}
const (
// ActivityOpTypeCreateRepo captures enum value "create_repo"
ActivityOpTypeCreateRepo string = "create_repo"
// ActivityOpTypeRenameRepo captures enum value "rename_repo"
ActivityOpTypeRenameRepo string = "rename_repo"
// ActivityOpTypeStarRepo captures enum value "star_repo"
ActivityOpTypeStarRepo string = "star_repo"
// ActivityOpTypeWatchRepo captures enum value "watch_repo"
ActivityOpTypeWatchRepo string = "watch_repo"
// ActivityOpTypeCommitRepo captures enum value "commit_repo"
ActivityOpTypeCommitRepo string = "commit_repo"
// ActivityOpTypeCreateIssue captures enum value "create_issue"
ActivityOpTypeCreateIssue string = "create_issue"
// ActivityOpTypeCreatePullRequest captures enum value "create_pull_request"
ActivityOpTypeCreatePullRequest string = "create_pull_request"
// ActivityOpTypeTransferRepo captures enum value "transfer_repo"
ActivityOpTypeTransferRepo string = "transfer_repo"
// ActivityOpTypePushTag captures enum value "push_tag"
ActivityOpTypePushTag string = "push_tag"
// ActivityOpTypeCommentIssue captures enum value "comment_issue"
ActivityOpTypeCommentIssue string = "comment_issue"
// ActivityOpTypeMergePullRequest captures enum value "merge_pull_request"
ActivityOpTypeMergePullRequest string = "merge_pull_request"
// ActivityOpTypeCloseIssue captures enum value "close_issue"
ActivityOpTypeCloseIssue string = "close_issue"
// ActivityOpTypeReopenIssue captures enum value "reopen_issue"
ActivityOpTypeReopenIssue string = "reopen_issue"
// ActivityOpTypeClosePullRequest captures enum value "close_pull_request"
ActivityOpTypeClosePullRequest string = "close_pull_request"
// ActivityOpTypeReopenPullRequest captures enum value "reopen_pull_request"
ActivityOpTypeReopenPullRequest string = "reopen_pull_request"
// ActivityOpTypeDeleteTag captures enum value "delete_tag"
ActivityOpTypeDeleteTag string = "delete_tag"
// ActivityOpTypeDeleteBranch captures enum value "delete_branch"
ActivityOpTypeDeleteBranch string = "delete_branch"
// ActivityOpTypeMirrorSyncPush captures enum value "mirror_sync_push"
ActivityOpTypeMirrorSyncPush string = "mirror_sync_push"
// ActivityOpTypeMirrorSyncCreate captures enum value "mirror_sync_create"
ActivityOpTypeMirrorSyncCreate string = "mirror_sync_create"
// ActivityOpTypeMirrorSyncDelete captures enum value "mirror_sync_delete"
ActivityOpTypeMirrorSyncDelete string = "mirror_sync_delete"
// ActivityOpTypeApprovePullRequest captures enum value "approve_pull_request"
ActivityOpTypeApprovePullRequest string = "approve_pull_request"
// ActivityOpTypeRejectPullRequest captures enum value "reject_pull_request"
ActivityOpTypeRejectPullRequest string = "reject_pull_request"
// ActivityOpTypeCommentPull captures enum value "comment_pull"
ActivityOpTypeCommentPull string = "comment_pull"
// ActivityOpTypePublishRelease captures enum value "publish_release"
ActivityOpTypePublishRelease string = "publish_release"
// ActivityOpTypePullReviewDismissed captures enum value "pull_review_dismissed"
ActivityOpTypePullReviewDismissed string = "pull_review_dismissed"
// ActivityOpTypePullRequestReadyForReview captures enum value "pull_request_ready_for_review"
ActivityOpTypePullRequestReadyForReview string = "pull_request_ready_for_review"
// ActivityOpTypeAutoMergePullRequest captures enum value "auto_merge_pull_request"
ActivityOpTypeAutoMergePullRequest string = "auto_merge_pull_request"
)
// prop value enum
func (m *Activity) validateOpTypeEnum(path, location string, value string) error {
if err := validate.EnumCase(path, location, value, activityTypeOpTypePropEnum, true); err != nil {
return err
}
return nil
}
func (m *Activity) validateOpType(formats strfmt.Registry) error {
if swag.IsZero(m.OpType) { // not required
return nil
}
// value enum
if err := m.validateOpTypeEnum("op_type", "body", m.OpType); err != nil {
return err
}
return nil
}
func (m *Activity) validateActUser(formats strfmt.Registry) error { func (m *Activity) validateActUser(formats strfmt.Registry) error {
if swag.IsZero(m.ActUser) { // not required if swag.IsZero(m.ActUser) { // not required
return nil return nil

View File

@@ -7,12 +7,9 @@ package models
import ( import (
"context" "context"
"encoding/json"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt" "github.com/go-openapi/strfmt"
"github.com/go-openapi/swag" "github.com/go-openapi/swag"
"github.com/go-openapi/validate"
) )
// AddCollaboratorOption AddCollaboratorOption options when adding a user as a collaborator of a repository // AddCollaboratorOption AddCollaboratorOption options when adding a user as a collaborator of a repository
@@ -21,66 +18,11 @@ import (
type AddCollaboratorOption struct { type AddCollaboratorOption struct {
// permission // permission
// Enum: ["read","write","admin"]
Permission string `json:"permission,omitempty"` Permission string `json:"permission,omitempty"`
} }
// Validate validates this add collaborator option // Validate validates this add collaborator option
func (m *AddCollaboratorOption) Validate(formats strfmt.Registry) error { func (m *AddCollaboratorOption) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validatePermission(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
var addCollaboratorOptionTypePermissionPropEnum []interface{}
func init() {
var res []string
if err := json.Unmarshal([]byte(`["read","write","admin"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
addCollaboratorOptionTypePermissionPropEnum = append(addCollaboratorOptionTypePermissionPropEnum, v)
}
}
const (
// AddCollaboratorOptionPermissionRead captures enum value "read"
AddCollaboratorOptionPermissionRead string = "read"
// AddCollaboratorOptionPermissionWrite captures enum value "write"
AddCollaboratorOptionPermissionWrite string = "write"
// AddCollaboratorOptionPermissionAdmin captures enum value "admin"
AddCollaboratorOptionPermissionAdmin string = "admin"
)
// prop value enum
func (m *AddCollaboratorOption) validatePermissionEnum(path, location string, value string) error {
if err := validate.EnumCase(path, location, value, addCollaboratorOptionTypePermissionPropEnum, true); err != nil {
return err
}
return nil
}
func (m *AddCollaboratorOption) validatePermission(formats strfmt.Registry) error {
if swag.IsZero(m.Permission) { // not required
return nil
}
// value enum
if err := m.validatePermissionEnum("permission", "body", m.Permission); err != nil {
return err
}
return nil return nil
} }

View File

@@ -25,9 +25,6 @@ type BranchProtection struct {
// approvals whitelist usernames // approvals whitelist usernames
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"` ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
// block admin merge override
BlockAdminMergeOverride bool `json:"block_admin_merge_override,omitempty"`
// block on official review requests // block on official review requests
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests,omitempty"` BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests,omitempty"`
@@ -50,12 +47,6 @@ type BranchProtection struct {
// enable approvals whitelist // enable approvals whitelist
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist,omitempty"` EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist,omitempty"`
// enable force push
EnableForcePush bool `json:"enable_force_push,omitempty"`
// enable force push allowlist
EnableForcePushAllowlist bool `json:"enable_force_push_allowlist,omitempty"`
// enable merge whitelist // enable merge whitelist
EnableMergeWhitelist bool `json:"enable_merge_whitelist,omitempty"` EnableMergeWhitelist bool `json:"enable_merge_whitelist,omitempty"`
@@ -68,15 +59,6 @@ type BranchProtection struct {
// enable status check // enable status check
EnableStatusCheck bool `json:"enable_status_check,omitempty"` EnableStatusCheck bool `json:"enable_status_check,omitempty"`
// force push allowlist deploy keys
ForcePushAllowlistDeployKeys bool `json:"force_push_allowlist_deploy_keys,omitempty"`
// force push allowlist teams
ForcePushAllowlistTeams []string `json:"force_push_allowlist_teams"`
// force push allowlist usernames
ForcePushAllowlistUsernames []string `json:"force_push_allowlist_usernames"`
// ignore stale approvals // ignore stale approvals
IgnoreStaleApprovals bool `json:"ignore_stale_approvals,omitempty"` IgnoreStaleApprovals bool `json:"ignore_stale_approvals,omitempty"`
@@ -86,9 +68,6 @@ type BranchProtection struct {
// merge whitelist usernames // merge whitelist usernames
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
// priority
Priority int64 `json:"priority,omitempty"`
// protected file patterns // protected file patterns
ProtectedFilePatterns string `json:"protected_file_patterns,omitempty"` ProtectedFilePatterns string `json:"protected_file_patterns,omitempty"`

View File

@@ -24,7 +24,6 @@ type CreateAccessTokenOption struct {
Name *string `json:"name"` Name *string `json:"name"`
// scopes // scopes
// Example: ["all","read:activitypub","read:issue","write:misc","read:notification","read:organization","read:package","read:repository","read:user"]
Scopes []string `json:"scopes"` Scopes []string `json:"scopes"`
} }

View File

@@ -23,9 +23,6 @@ type CreateBranchProtectionOption struct {
// approvals whitelist usernames // approvals whitelist usernames
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"` ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
// block admin merge override
BlockAdminMergeOverride bool `json:"block_admin_merge_override,omitempty"`
// block on official review requests // block on official review requests
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests,omitempty"` BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests,omitempty"`
@@ -44,12 +41,6 @@ type CreateBranchProtectionOption struct {
// enable approvals whitelist // enable approvals whitelist
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist,omitempty"` EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist,omitempty"`
// enable force push
EnableForcePush bool `json:"enable_force_push,omitempty"`
// enable force push allowlist
EnableForcePushAllowlist bool `json:"enable_force_push_allowlist,omitempty"`
// enable merge whitelist // enable merge whitelist
EnableMergeWhitelist bool `json:"enable_merge_whitelist,omitempty"` EnableMergeWhitelist bool `json:"enable_merge_whitelist,omitempty"`
@@ -62,15 +53,6 @@ type CreateBranchProtectionOption struct {
// enable status check // enable status check
EnableStatusCheck bool `json:"enable_status_check,omitempty"` EnableStatusCheck bool `json:"enable_status_check,omitempty"`
// force push allowlist deploy keys
ForcePushAllowlistDeployKeys bool `json:"force_push_allowlist_deploy_keys,omitempty"`
// force push allowlist teams
ForcePushAllowlistTeams []string `json:"force_push_allowlist_teams"`
// force push allowlist usernames
ForcePushAllowlistUsernames []string `json:"force_push_allowlist_usernames"`
// ignore stale approvals // ignore stale approvals
IgnoreStaleApprovals bool `json:"ignore_stale_approvals,omitempty"` IgnoreStaleApprovals bool `json:"ignore_stale_approvals,omitempty"`
@@ -80,9 +62,6 @@ type CreateBranchProtectionOption struct {
// merge whitelist usernames // merge whitelist usernames
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
// priority
Priority int64 `json:"priority,omitempty"`
// protected file patterns // protected file patterns
ProtectedFilePatterns string `json:"protected_file_patterns,omitempty"` ProtectedFilePatterns string `json:"protected_file_patterns,omitempty"`

View File

@@ -25,9 +25,6 @@ type CreateOAuth2ApplicationOptions struct {
// redirect u r is // redirect u r is
RedirectURIs []string `json:"redirect_uris"` RedirectURIs []string `json:"redirect_uris"`
// skip secondary authorization
SkipSecondaryAuthorization bool `json:"skip_secondary_authorization,omitempty"`
} }
// Validate validates this create o auth2 application options // Validate validates this create o auth2 application options

View File

@@ -44,12 +44,6 @@ type CreatePullRequestOption struct {
// milestone // milestone
Milestone int64 `json:"milestone,omitempty"` Milestone int64 `json:"milestone,omitempty"`
// reviewers
Reviewers []string `json:"reviewers"`
// team reviewers
TeamReviewers []string `json:"team_reviewers"`
// title // title
Title string `json:"title,omitempty"` Title string `json:"title,omitempty"`
} }

View File

@@ -1,56 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// CreateTagProtectionOption CreateTagProtectionOption options for creating a tag protection
//
// swagger:model CreateTagProtectionOption
type CreateTagProtectionOption struct {
// name pattern
NamePattern string `json:"name_pattern,omitempty"`
// whitelist teams
WhitelistTeams []string `json:"whitelist_teams"`
// whitelist usernames
WhitelistUsernames []string `json:"whitelist_usernames"`
}
// Validate validates this create tag protection option
func (m *CreateTagProtectionOption) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this create tag protection option based on context it is used
func (m *CreateTagProtectionOption) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *CreateTagProtectionOption) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *CreateTagProtectionOption) UnmarshalBinary(b []byte) error {
var res CreateTagProtectionOption
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -23,9 +23,6 @@ type EditBranchProtectionOption struct {
// approvals whitelist usernames // approvals whitelist usernames
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"` ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
// block admin merge override
BlockAdminMergeOverride bool `json:"block_admin_merge_override,omitempty"`
// block on official review requests // block on official review requests
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests,omitempty"` BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests,omitempty"`
@@ -41,12 +38,6 @@ type EditBranchProtectionOption struct {
// enable approvals whitelist // enable approvals whitelist
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist,omitempty"` EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist,omitempty"`
// enable force push
EnableForcePush bool `json:"enable_force_push,omitempty"`
// enable force push allowlist
EnableForcePushAllowlist bool `json:"enable_force_push_allowlist,omitempty"`
// enable merge whitelist // enable merge whitelist
EnableMergeWhitelist bool `json:"enable_merge_whitelist,omitempty"` EnableMergeWhitelist bool `json:"enable_merge_whitelist,omitempty"`
@@ -59,15 +50,6 @@ type EditBranchProtectionOption struct {
// enable status check // enable status check
EnableStatusCheck bool `json:"enable_status_check,omitempty"` EnableStatusCheck bool `json:"enable_status_check,omitempty"`
// force push allowlist deploy keys
ForcePushAllowlistDeployKeys bool `json:"force_push_allowlist_deploy_keys,omitempty"`
// force push allowlist teams
ForcePushAllowlistTeams []string `json:"force_push_allowlist_teams"`
// force push allowlist usernames
ForcePushAllowlistUsernames []string `json:"force_push_allowlist_usernames"`
// ignore stale approvals // ignore stale approvals
IgnoreStaleApprovals bool `json:"ignore_stale_approvals,omitempty"` IgnoreStaleApprovals bool `json:"ignore_stale_approvals,omitempty"`
@@ -77,9 +59,6 @@ type EditBranchProtectionOption struct {
// merge whitelist usernames // merge whitelist usernames
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
// priority
Priority int64 `json:"priority,omitempty"`
// protected file patterns // protected file patterns
ProtectedFilePatterns string `json:"protected_file_patterns,omitempty"` ProtectedFilePatterns string `json:"protected_file_patterns,omitempty"`

View File

@@ -1,56 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// EditTagProtectionOption EditTagProtectionOption options for editing a tag protection
//
// swagger:model EditTagProtectionOption
type EditTagProtectionOption struct {
// name pattern
NamePattern string `json:"name_pattern,omitempty"`
// whitelist teams
WhitelistTeams []string `json:"whitelist_teams"`
// whitelist usernames
WhitelistUsernames []string `json:"whitelist_usernames"`
}
// Validate validates this edit tag protection option
func (m *EditTagProtectionOption) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this edit tag protection option based on context it is used
func (m *EditTagProtectionOption) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *EditTagProtectionOption) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *EditTagProtectionOption) UnmarshalBinary(b []byte) error {
var res EditTagProtectionOption
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -40,11 +40,8 @@ type IssueTemplate struct {
// title // title
Title string `json:"title,omitempty"` Title string `json:"title,omitempty"`
// assignees
Assignees IssueTemplateStringSlice `json:"assignees,omitempty"`
// labels // labels
Labels IssueTemplateStringSlice `json:"labels,omitempty"` Labels IssueTemplateLabels `json:"labels,omitempty"`
} }
// Validate validates this issue template // Validate validates this issue template
@@ -55,10 +52,6 @@ func (m *IssueTemplate) Validate(formats strfmt.Registry) error {
res = append(res, err) res = append(res, err)
} }
if err := m.validateAssignees(formats); err != nil {
res = append(res, err)
}
if err := m.validateLabels(formats); err != nil { if err := m.validateLabels(formats); err != nil {
res = append(res, err) res = append(res, err)
} }
@@ -95,23 +88,6 @@ func (m *IssueTemplate) validateFields(formats strfmt.Registry) error {
return nil return nil
} }
func (m *IssueTemplate) validateAssignees(formats strfmt.Registry) error {
if swag.IsZero(m.Assignees) { // not required
return nil
}
if err := m.Assignees.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("assignees")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("assignees")
}
return err
}
return nil
}
func (m *IssueTemplate) validateLabels(formats strfmt.Registry) error { func (m *IssueTemplate) validateLabels(formats strfmt.Registry) error {
if swag.IsZero(m.Labels) { // not required if swag.IsZero(m.Labels) { // not required
return nil return nil
@@ -137,10 +113,6 @@ func (m *IssueTemplate) ContextValidate(ctx context.Context, formats strfmt.Regi
res = append(res, err) res = append(res, err)
} }
if err := m.contextValidateAssignees(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateLabels(ctx, formats); err != nil { if err := m.contextValidateLabels(ctx, formats); err != nil {
res = append(res, err) res = append(res, err)
} }
@@ -176,20 +148,6 @@ func (m *IssueTemplate) contextValidateFields(ctx context.Context, formats strfm
return nil return nil
} }
func (m *IssueTemplate) contextValidateAssignees(ctx context.Context, formats strfmt.Registry) error {
if err := m.Assignees.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("assignees")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("assignees")
}
return err
}
return nil
}
func (m *IssueTemplate) contextValidateLabels(ctx context.Context, formats strfmt.Registry) error { func (m *IssueTemplate) contextValidateLabels(ctx context.Context, formats strfmt.Registry) error {
if err := m.Labels.ContextValidate(ctx, formats); err != nil { if err := m.Labels.ContextValidate(ctx, formats); err != nil {

View File

@@ -1,27 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
)
// IssueTemplateStringSlice issue template string slice
//
// swagger:model IssueTemplateStringSlice
type IssueTemplateStringSlice []string
// Validate validates this issue template string slice
func (m IssueTemplateStringSlice) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this issue template string slice based on context it is used
func (m IssueTemplateStringSlice) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}

View File

@@ -23,7 +23,7 @@ type MarkdownOption struct {
// in: body // in: body
Context string `json:"Context,omitempty"` Context string `json:"Context,omitempty"`
// Mode to render (markdown, comment, wiki, file) // Mode to render (comment, gfm, markdown)
// //
// in: body // in: body
Mode string `json:"Mode,omitempty"` Mode string `json:"Mode,omitempty"`
@@ -33,9 +33,8 @@ type MarkdownOption struct {
// in: body // in: body
Text string `json:"Text,omitempty"` Text string `json:"Text,omitempty"`
// Is it a wiki page? (use mode=wiki instead) // Is it a wiki page ?
// //
// Deprecated: true
// in: body // in: body
Wiki bool `json:"Wiki,omitempty"` Wiki bool `json:"Wiki,omitempty"`
} }

View File

@@ -28,7 +28,7 @@ type MarkupOption struct {
// in: body // in: body
FilePath string `json:"FilePath,omitempty"` FilePath string `json:"FilePath,omitempty"`
// Mode to render (markdown, comment, wiki, file) // Mode to render (comment, gfm, markdown, file)
// //
// in: body // in: body
Mode string `json:"Mode,omitempty"` Mode string `json:"Mode,omitempty"`
@@ -38,9 +38,8 @@ type MarkupOption struct {
// in: body // in: body
Text string `json:"Text,omitempty"` Text string `json:"Text,omitempty"`
// Is it a wiki page? (use mode=wiki instead) // Is it a wiki page ?
// //
// Deprecated: true
// in: body // in: body
Wiki bool `json:"Wiki,omitempty"` Wiki bool `json:"Wiki,omitempty"`
} }

View File

@@ -1,50 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// MergeUpstreamRequest merge upstream request
//
// swagger:model MergeUpstreamRequest
type MergeUpstreamRequest struct {
// branch
Branch string `json:"branch,omitempty"`
}
// Validate validates this merge upstream request
func (m *MergeUpstreamRequest) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this merge upstream request based on context it is used
func (m *MergeUpstreamRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *MergeUpstreamRequest) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *MergeUpstreamRequest) UnmarshalBinary(b []byte) error {
var res MergeUpstreamRequest
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -1,50 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// MergeUpstreamResponse merge upstream response
//
// swagger:model MergeUpstreamResponse
type MergeUpstreamResponse struct {
// merge style
MergeStyle string `json:"merge_type,omitempty"`
}
// Validate validates this merge upstream response
func (m *MergeUpstreamResponse) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this merge upstream response based on context it is used
func (m *MergeUpstreamResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *MergeUpstreamResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *MergeUpstreamResponse) UnmarshalBinary(b []byte) error {
var res MergeUpstreamResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -21,12 +21,6 @@ import (
// swagger:model MigrateRepoOptions // swagger:model MigrateRepoOptions
type MigrateRepoOptions struct { type MigrateRepoOptions struct {
// a w s access key ID
AWSAccessKeyID string `json:"aws_access_key_id,omitempty"`
// a w s secret access key
AWSSecretAccessKey string `json:"aws_secret_access_key,omitempty"`
// auth password // auth password
AuthPassword string `json:"auth_password,omitempty"` AuthPassword string `json:"auth_password,omitempty"`

View File

@@ -40,9 +40,6 @@ type OAuth2Application struct {
// redirect u r is // redirect u r is
RedirectURIs []string `json:"redirect_uris"` RedirectURIs []string `json:"redirect_uris"`
// skip secondary authorization
SkipSecondaryAuthorization bool `json:"skip_secondary_authorization,omitempty"`
} }
// Validate validates this o auth2 application // Validate validates this o auth2 application

View File

@@ -99,9 +99,6 @@ type PullRequest struct {
// requested reviewers // requested reviewers
RequestedReviewers []*User `json:"requested_reviewers"` RequestedReviewers []*User `json:"requested_reviewers"`
// requested reviewers teams
RequestedReviewersTeams []*Team `json:"requested_reviewers_teams"`
// number of review comments made on the diff of a PR review (not including comments on commits or issues in a PR) // number of review comments made on the diff of a PR review (not including comments on commits or issues in a PR)
ReviewComments int64 `json:"review_comments,omitempty"` ReviewComments int64 `json:"review_comments,omitempty"`
@@ -169,10 +166,6 @@ func (m *PullRequest) Validate(formats strfmt.Registry) error {
res = append(res, err) res = append(res, err)
} }
if err := m.validateRequestedReviewersTeams(formats); err != nil {
res = append(res, err)
}
if err := m.validateUpdated(formats); err != nil { if err := m.validateUpdated(formats); err != nil {
res = append(res, err) res = append(res, err)
} }
@@ -337,32 +330,6 @@ func (m *PullRequest) validateRequestedReviewers(formats strfmt.Registry) error
return nil return nil
} }
func (m *PullRequest) validateRequestedReviewersTeams(formats strfmt.Registry) error {
if swag.IsZero(m.RequestedReviewersTeams) { // not required
return nil
}
for i := 0; i < len(m.RequestedReviewersTeams); i++ {
if swag.IsZero(m.RequestedReviewersTeams[i]) { // not required
continue
}
if m.RequestedReviewersTeams[i] != nil {
if err := m.RequestedReviewersTeams[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("requested_reviewers_teams" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("requested_reviewers_teams" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *PullRequest) validateUpdated(formats strfmt.Registry) error { func (m *PullRequest) validateUpdated(formats strfmt.Registry) error {
if swag.IsZero(m.Updated) { // not required if swag.IsZero(m.Updated) { // not required
return nil return nil
@@ -522,10 +489,6 @@ func (m *PullRequest) ContextValidate(ctx context.Context, formats strfmt.Regist
res = append(res, err) res = append(res, err)
} }
if err := m.contextValidateRequestedReviewersTeams(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateAssignee(ctx, formats); err != nil { if err := m.contextValidateAssignee(ctx, formats); err != nil {
res = append(res, err) res = append(res, err)
} }
@@ -635,31 +598,6 @@ func (m *PullRequest) contextValidateRequestedReviewers(ctx context.Context, for
return nil return nil
} }
func (m *PullRequest) contextValidateRequestedReviewersTeams(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.RequestedReviewersTeams); i++ {
if m.RequestedReviewersTeams[i] != nil {
if swag.IsZero(m.RequestedReviewersTeams[i]) { // not required
return nil
}
if err := m.RequestedReviewersTeams[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("requested_reviewers_teams" + "." + strconv.Itoa(i))
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("requested_reviewers_teams" + "." + strconv.Itoa(i))
}
return err
}
}
}
return nil
}
func (m *PullRequest) contextValidateAssignee(ctx context.Context, formats strfmt.Registry) error { func (m *PullRequest) contextValidateAssignee(ctx context.Context, formats strfmt.Registry) error {
if m.Assignee != nil { if m.Assignee != nil {

View File

@@ -23,9 +23,6 @@ type Repository struct {
// allow fast forward only // allow fast forward only
AllowFastForwardOnly bool `json:"allow_fast_forward_only_merge,omitempty"` AllowFastForwardOnly bool `json:"allow_fast_forward_only_merge,omitempty"`
// allow manual merge
AllowManualMerge bool `json:"allow_manual_merge,omitempty"`
// allow merge // allow merge
AllowMerge bool `json:"allow_merge_commits,omitempty"` AllowMerge bool `json:"allow_merge_commits,omitempty"`
@@ -48,9 +45,6 @@ type Repository struct {
// Format: date-time // Format: date-time
ArchivedAt strfmt.DateTime `json:"archived_at,omitempty"` ArchivedAt strfmt.DateTime `json:"archived_at,omitempty"`
// autodetect manual merge
AutodetectManualMerge bool `json:"autodetect_manual_merge,omitempty"`
// avatar URL // avatar URL
AvatarURL string `json:"avatar_url,omitempty"` AvatarURL string `json:"avatar_url,omitempty"`
@@ -127,9 +121,6 @@ type Repository struct {
// languages URL // languages URL
LanguagesURL string `json:"languages_url,omitempty"` LanguagesURL string `json:"languages_url,omitempty"`
// licenses
Licenses []string `json:"licenses"`
// link // link
Link string `json:"link,omitempty"` Link string `json:"link,omitempty"`
@@ -180,9 +171,6 @@ type Repository struct {
// template // template
Template bool `json:"template,omitempty"` Template bool `json:"template,omitempty"`
// topics
Topics []string `json:"topics"`
// URL // URL
URL string `json:"url,omitempty"` URL string `json:"url,omitempty"`

View File

@@ -1,106 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// TagProtection TagProtection represents a tag protection
//
// swagger:model TagProtection
type TagProtection struct {
// created
// Format: date-time
Created strfmt.DateTime `json:"created_at,omitempty"`
// ID
ID int64 `json:"id,omitempty"`
// name pattern
NamePattern string `json:"name_pattern,omitempty"`
// updated
// Format: date-time
Updated strfmt.DateTime `json:"updated_at,omitempty"`
// whitelist teams
WhitelistTeams []string `json:"whitelist_teams"`
// whitelist usernames
WhitelistUsernames []string `json:"whitelist_usernames"`
}
// Validate validates this tag protection
func (m *TagProtection) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateCreated(formats); err != nil {
res = append(res, err)
}
if err := m.validateUpdated(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *TagProtection) validateCreated(formats strfmt.Registry) error {
if swag.IsZero(m.Created) { // not required
return nil
}
if err := validate.FormatOf("created_at", "body", "date-time", m.Created.String(), formats); err != nil {
return err
}
return nil
}
func (m *TagProtection) validateUpdated(formats strfmt.Registry) error {
if swag.IsZero(m.Updated) { // not required
return nil
}
if err := validate.FormatOf("updated_at", "body", "date-time", m.Updated.String(), formats); err != nil {
return err
}
return nil
}
// ContextValidate validates this tag protection based on context it is used
func (m *TagProtection) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *TagProtection) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *TagProtection) UnmarshalBinary(b []byte) error {
var res TagProtection
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -1,50 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// UpdateBranchProtectionPriories UpdateBranchProtectionPriories a list to update the branch protection rule priorities
//
// swagger:model UpdateBranchProtectionPriories
type UpdateBranchProtectionPriories struct {
// i ds
IDs []int64 `json:"ids"`
}
// Validate validates this update branch protection priories
func (m *UpdateBranchProtectionPriories) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this update branch protection priories based on context it is used
func (m *UpdateBranchProtectionPriories) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *UpdateBranchProtectionPriories) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *UpdateBranchProtectionPriories) UnmarshalBinary(b []byte) error {
var res UpdateBranchProtectionPriories
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -1,71 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// UpdateBranchRepoOption UpdateBranchRepoOption options when updating a branch in a repository
//
// swagger:model UpdateBranchRepoOption
type UpdateBranchRepoOption struct {
// New branch name
// Required: true
Name *string `json:"name"`
}
// Validate validates this update branch repo option
func (m *UpdateBranchRepoOption) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateName(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *UpdateBranchRepoOption) validateName(formats strfmt.Registry) error {
if err := validate.Required("name", "body", m.Name); err != nil {
return err
}
return nil
}
// ContextValidate validates this update branch repo option based on context it is used
func (m *UpdateBranchRepoOption) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *UpdateBranchRepoOption) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *UpdateBranchRepoOption) UnmarshalBinary(b []byte) error {
var res UpdateBranchRepoOption
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -29,6 +29,7 @@ import (
"path" "path"
"path/filepath" "path/filepath"
"slices" "slices"
"strings"
"time" "time"
transport "github.com/go-openapi/runtime/client" transport "github.com/go-openapi/runtime/client"
@@ -66,18 +67,10 @@ const (
ReviewStateUnknown models.ReviewStateType = "" ReviewStateUnknown models.ReviewStateType = ""
) )
type GiteaTimelineFetcher interface {
GetTimeline(org, repo string, idx int64) ([]*models.TimelineComment, error)
}
type GiteaComment interface { type GiteaComment interface {
AddComment(pr *models.PullRequest, comment string) error AddComment(pr *models.PullRequest, comment string) error
} }
type GiteaSetRepoOptions interface {
SetRepoOptions(owner, repo string, manual_merge bool) (*models.Repository, error)
}
type GiteaMaintainershipReader interface { type GiteaMaintainershipReader interface {
FetchMaintainershipFile(org, prjGit, branch string) ([]byte, string, error) FetchMaintainershipFile(org, prjGit, branch string) ([]byte, string, error)
FetchMaintainershipDirFile(org, prjGit, branch, pkg string) ([]byte, string, error) FetchMaintainershipDirFile(org, prjGit, branch, pkg string) ([]byte, string, error)
@@ -85,19 +78,7 @@ type GiteaMaintainershipReader interface {
type GiteaPRFetcher interface { type GiteaPRFetcher interface {
GetPullRequest(org, project string, num int64) (*models.PullRequest, error) GetPullRequest(org, project string, num int64) (*models.PullRequest, error)
} GetAssociatedPrjGitPR(prjGitOrg, prjGitRepo, refOrg, refRepo string, Index int64) (*models.PullRequest, error)
type GiteaPRUpdater interface {
UpdatePullRequest(org, repo string, num int64, options *models.EditPullRequestOption) (*models.PullRequest, error)
}
type GiteaPRTimelineFetcher interface {
GiteaPRFetcher
GiteaTimelineFetcher
}
type GiteaCommitFetcher interface {
GetCommit(org, repo, sha string) (*models.Commit, error)
} }
type GiteaReviewFetcher interface { type GiteaReviewFetcher interface {
@@ -108,19 +89,14 @@ type GiteaCommentFetcher interface {
GetIssueComments(org, project string, issueNo int64) ([]*models.Comment, error) GetIssueComments(org, project string, issueNo int64) ([]*models.Comment, error)
} }
type GiteaReviewTimelineFetcher interface {
GiteaReviewFetcher
GiteaTimelineFetcher
}
type GiteaPRChecker interface { type GiteaPRChecker interface {
GiteaReviewTimelineFetcher GiteaReviewFetcher
GiteaCommentFetcher GiteaCommentFetcher
GiteaMaintainershipReader GiteaMaintainershipReader
} }
type GiteaReviewFetcherAndRequester interface { type GiteaReviewFetcherAndRequester interface {
GiteaReviewTimelineFetcher GiteaReviewFetcher
GiteaCommentFetcher GiteaCommentFetcher
GiteaReviewRequester GiteaReviewRequester
} }
@@ -129,10 +105,6 @@ type GiteaReviewRequester interface {
RequestReviews(pr *models.PullRequest, reviewer ...string) ([]*models.PullReview, error) RequestReviews(pr *models.PullRequest, reviewer ...string) ([]*models.PullReview, error)
} }
type GiteaReviewUnrequester interface {
UnrequestReview(org, repo string, id int64, reviwers ...string) error
}
type GiteaReviewer interface { type GiteaReviewer interface {
AddReviewComment(pr *models.PullRequest, state models.ReviewStateType, comment string) (*models.PullReview, error) AddReviewComment(pr *models.PullRequest, state models.ReviewStateType, comment string) (*models.PullReview, error)
} }
@@ -152,44 +124,41 @@ const (
CommitStatus_Error = "error" CommitStatus_Error = "error"
) )
type CommitStatus struct {
Context string
Description string
CommitStatus string
}
type GiteaCommitStatusSetter interface { type GiteaCommitStatusSetter interface {
SetCommitStatus(org, repo, hash string, status *models.CommitStatus) (*models.CommitStatus, error) SetCommitStatus(org, repo, hash string, status *CommitStatus) error
} }
type GiteaCommitStatusGetter interface { type GiteaCommitStatusGetter interface {
GetCommitStatus(org, repo, hash string) ([]*models.CommitStatus, error) GetCommitStatus(org, repo, hash string) ([]*CommitStatus, error)
} }
type Gitea interface { type Gitea interface {
GiteaComment GiteaComment
GiteaRepoFetcher GiteaRepoFetcher
GiteaReviewRequester GiteaReviewRequester
GiteaReviewUnrequester
GiteaReviewer GiteaReviewer
GiteaPRFetcher GiteaPRFetcher
GiteaPRUpdater
GiteaCommitFetcher
GiteaReviewFetcher GiteaReviewFetcher
GiteaCommentFetcher GiteaCommentFetcher
GiteaTimelineFetcher
GiteaMaintainershipReader GiteaMaintainershipReader
GiteaFileContentReader GiteaFileContentReader
GiteaCommitStatusGetter
GiteaCommitStatusSetter
GiteaSetRepoOptions
GiteaTimelineFetcher
GetNotifications(Type string, since *time.Time) ([]*models.NotificationThread, error) GetPullNotifications(since *time.Time) ([]*models.NotificationThread, error)
GetDoneNotifications(Type string, page int64) ([]*models.NotificationThread, error)
SetNotificationRead(notificationId int64) error SetNotificationRead(notificationId int64) error
GetOrganization(orgName string) (*models.Organization, error) GetOrganization(orgName string) (*models.Organization, error)
GetOrganizationRepositories(orgName string) ([]*models.Repository, error) GetOrganizationRepositories(orgName string) ([]*models.Repository, error)
CreateRepositoryIfNotExist(git Git, org, repoName string) (*models.Repository, error) CreateRepositoryIfNotExist(git Git, org, repoName string) (*models.Repository, error)
CreatePullRequestIfNotExist(repo *models.Repository, srcId, targetId, title, body string) (*models.PullRequest, error) CreatePullRequestIfNotExist(repo *models.Repository, srcId, targetId, title, body string) (*models.PullRequest, error)
GetAssociatedPrjGitPR(prjGitOrg, prjGitRepo, refOrg, refRepo string, Index int64) (*models.PullRequest, error)
GetPullRequestFileContent(pr *models.PullRequest, path string) ([]byte, string, error) GetPullRequestFileContent(pr *models.PullRequest, path string) ([]byte, string, error)
GetRecentPullRequests(org, repo, branch string) ([]*models.PullRequest, error) GetRecentPullRequests(org, repo, branch string) ([]*models.PullRequest, error)
GetRecentCommits(org, repo, branch string, commitNo int64) ([]*models.Commit, error) GetRecentCommits(org, repo, branch string, commitNo int64) ([]*models.Commit, error)
GetPullRequests(org, project string) ([]*models.PullRequest, error)
GetCurrentUser() (*models.User, error) GetCurrentUser() (*models.User, error)
} }
@@ -236,96 +205,6 @@ func (gitea *GiteaTransport) GetPullRequest(org, project string, num int64) (*mo
return pr.Payload, err return pr.Payload, err
} }
func (gitea *GiteaTransport) UpdatePullRequest(org, repo string, num int64, options *models.EditPullRequestOption) (*models.PullRequest, error) {
pr, err := gitea.client.Repository.RepoEditPullRequest(
repository.NewRepoEditPullRequestParams().
WithOwner(org).
WithRepo(repo).
WithIndex(num).
WithBody(options),
gitea.transport.DefaultAuthentication,
)
return pr.Payload, err
}
func (gitea *GiteaTransport) GetPullRequests(org, repo string) ([]*models.PullRequest, error) {
var page, limit int64
prs := make([]*models.PullRequest, 0)
limit = 20
state := "open"
for {
page++
req, err := gitea.client.Repository.RepoListPullRequests(
repository.
NewRepoListPullRequestsParams().
WithDefaults().
WithOwner(org).
WithRepo(repo).
WithState(&state).
WithPage(&page).
WithLimit(&limit),
gitea.transport.DefaultAuthentication)
if err != nil {
return nil, fmt.Errorf("cannot fetch PR list for %s / %s : %w", org, repo, err)
}
prs = slices.Concat(prs, req.Payload)
if len(req.Payload) < int(limit) {
break
}
}
return prs, nil
}
func (gitea *GiteaTransport) GetCommitStatus(org, repo, hash string) ([]*models.CommitStatus, error) {
page := int64(1)
limit := int64(10)
var res []*models.CommitStatus
for {
r, err := gitea.client.Repository.RepoListStatuses(
repository.NewRepoListStatusesParams().WithDefaults().WithOwner(org).WithRepo(repo).WithSha(hash).WithPage(&page).WithLimit(&limit),
gitea.transport.DefaultAuthentication)
if err != nil {
return res, err
}
res = append(res, r.Payload...)
if len(r.Payload) < int(limit) {
break
}
}
return res, nil
}
func (gitea *GiteaTransport) SetCommitStatus(org, repo, hash string, status *models.CommitStatus) (*models.CommitStatus, error) {
res, err := gitea.client.Repository.RepoCreateStatus(
repository.NewRepoCreateStatusParams().
WithDefaults().
WithOwner(org).
WithRepo(repo).
WithSha(hash).
WithBody(&models.CreateStatusOption{
TargetURL: status.TargetURL,
Description: status.Description,
Context: status.Context,
State: models.CommitStatusState(status.Status),
}),
gitea.transport.DefaultAuthentication,
)
if err != nil {
return nil, err
}
return res.Payload, err
}
func (gitea *GiteaTransport) GetRepository(org, pkg string) (*models.Repository, error) { func (gitea *GiteaTransport) GetRepository(org, pkg string) (*models.Repository, error) {
repo, err := gitea.client.Repository.RepoGet(repository.NewRepoGetParams().WithDefaults().WithOwner(org).WithRepo(pkg), gitea.transport.DefaultAuthentication) repo, err := gitea.client.Repository.RepoGet(repository.NewRepoGetParams().WithDefaults().WithOwner(org).WithRepo(pkg), gitea.transport.DefaultAuthentication)
if err != nil { if err != nil {
@@ -370,25 +249,6 @@ func (gitea *GiteaTransport) GetPullRequestReviews(org, project string, PRnum in
return allReviews, nil return allReviews, nil
} }
func (gitea *GiteaTransport) GetCommit(org, repo, sha string) (*models.Commit, error) {
f := false
r, err := gitea.client.Repository.RepoGetSingleCommit(
repository.NewRepoGetSingleCommitParams().
WithOwner(org).
WithRepo(repo).
WithSha(sha).
WithStat(&f).
WithFiles(&f).
WithVerification(&f),
gitea.transport.DefaultAuthentication)
if err != nil {
return nil, err
}
return r.Payload, nil
}
func (gitea *GiteaTransport) GetIssueComments(org, project string, issueNo int64) ([]*models.Comment, error) { func (gitea *GiteaTransport) GetIssueComments(org, project string, issueNo int64) ([]*models.Comment, error) {
// limit := int64(20) // limit := int64(20)
// var page int64 // var page int64
@@ -413,73 +273,25 @@ func (gitea *GiteaTransport) GetIssueComments(org, project string, issueNo int64
} }
func (gitea *GiteaTransport) SetRepoOptions(owner, repo string, manual_merge bool) (*models.Repository, error) { func (gitea *GiteaTransport) GetPullNotifications(since *time.Time) ([]*models.NotificationThread, error) {
ok, err := gitea.client.Repository.RepoEdit(repository.NewRepoEditParams().WithOwner(owner).WithRepo(repo).WithBody( bigLimit := int64(100000)
&models.EditRepoOption{
AllowManualMerge: manual_merge,
AutodetectManualMerge: manual_merge,
}), gitea.transport.DefaultAuthentication)
params := notification.NewNotifyGetListParams().
WithDefaults().
WithSubjectType([]string{"Pull"}).
WithStatusTypes([]string{"unread"}).
WithLimit(&bigLimit)
if since != nil {
s := strfmt.DateTime(*since)
params.SetSince(&s)
}
list, err := gitea.client.Notification.NotifyGetList(params, gitea.transport.DefaultAuthentication)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return ok.Payload, err
}
const (
GiteaNotificationType_Pull = "Pull"
)
func (gitea *GiteaTransport) GetNotifications(Type string, since *time.Time) ([]*models.NotificationThread, error) {
bigLimit := int64(20)
ret := make([]*models.NotificationThread, 0, 100)
for page := int64(1); ; page++ {
params := notification.NewNotifyGetListParams().
WithDefaults().
WithSubjectType([]string{Type}).
WithStatusTypes([]string{"unread"}).
WithLimit(&bigLimit).
WithPage(&page)
if since != nil {
s := strfmt.DateTime(*since)
params.SetSince(&s)
}
list, err := gitea.client.Notification.NotifyGetList(params, gitea.transport.DefaultAuthentication)
if err != nil {
return nil, err
}
ret = slices.Concat(ret, list.Payload)
if len(list.Payload) < int(bigLimit) {
break
}
}
return ret, nil
}
func (gitea *GiteaTransport) GetDoneNotifications(Type string, page int64) ([]*models.NotificationThread, error) {
limit := int64(20)
t := true
if page <= 0 {
return nil, fmt.Errorf("Page is 1-base positive int...")
}
list, err := gitea.client.Notification.NotifyGetList(
notification.NewNotifyGetListParams().
WithAll(&t).
WithSubjectType([]string{Type}).
WithStatusTypes([]string{"read"}).
WithLimit(&limit).
WithPage(&page),
gitea.transport.DefaultAuthentication)
if err != nil {
return nil, err
}
return list.Payload, nil return list.Payload, nil
} }
@@ -603,14 +415,14 @@ func (gitea *GiteaTransport) CreateRepositoryIfNotExist(git Git, org, repoName s
func (gitea *GiteaTransport) CreatePullRequestIfNotExist(repo *models.Repository, srcId, targetId, title, body string) (*models.PullRequest, error) { func (gitea *GiteaTransport) CreatePullRequestIfNotExist(repo *models.Repository, srcId, targetId, title, body string) (*models.PullRequest, error) {
prOptions := models.CreatePullRequestOption{ prOptions := models.CreatePullRequestOption{
Base: targetId, Base: repo.DefaultBranch,
Head: srcId, Head: srcId,
Title: title, Title: title,
Body: body, Body: body,
} }
if pr, err := gitea.client.Repository.RepoGetPullRequestByBaseHead( if pr, err := gitea.client.Repository.RepoGetPullRequestByBaseHead(
repository.NewRepoGetPullRequestByBaseHeadParams().WithOwner(repo.Owner.UserName).WithRepo(repo.Name).WithBase(targetId).WithHead(srcId), repository.NewRepoGetPullRequestByBaseHeadParams().WithOwner(repo.Owner.UserName).WithRepo(repo.Name).WithBase(repo.DefaultBranch).WithHead(srcId),
gitea.transport.DefaultAuthentication, gitea.transport.DefaultAuthentication,
); err == nil { ); err == nil {
return pr.Payload, nil return pr.Payload, nil
@@ -633,6 +445,46 @@ func (gitea *GiteaTransport) CreatePullRequestIfNotExist(repo *models.Repository
return pr.GetPayload(), nil return pr.GetPayload(), nil
} }
func (gitea *GiteaTransport) GetAssociatedPrjGitPR(prjGitOrg, prjGitRepo, refOrg, refRepo string, Index int64) (*models.PullRequest, error) {
var page int64
state := "open"
for {
page++
prs, err := gitea.client.Repository.RepoListPullRequests(
repository.
NewRepoListPullRequestsParams().
WithDefaults().
WithOwner(prjGitOrg).
WithRepo(prjGitRepo).
WithState(&state).
WithPage(&page),
gitea.transport.DefaultAuthentication)
if err != nil {
return nil, fmt.Errorf("cannot fetch PR list for %s / %s : %w", prjGitOrg, prjGitRepo, err)
}
prLine := fmt.Sprintf(PrPattern, refOrg, refRepo, Index)
// payload_processing:
for _, pr := range prs.Payload {
lines := strings.Split(pr.Body, "\n")
for _, line := range lines {
if strings.TrimSpace(line) == prLine {
return pr, nil
}
}
}
if len(prs.Payload) < 10 {
break
}
}
return nil, nil
}
func (gitea *GiteaTransport) RequestReviews(pr *models.PullRequest, reviewers ...string) ([]*models.PullReview, error) { func (gitea *GiteaTransport) RequestReviews(pr *models.PullRequest, reviewers ...string) ([]*models.PullReview, error) {
reviewOptions := models.PullReviewRequestOptions{ reviewOptions := models.PullReviewRequestOptions{
Reviewers: reviewers, Reviewers: reviewers,
@@ -655,14 +507,6 @@ func (gitea *GiteaTransport) RequestReviews(pr *models.PullRequest, reviewers ..
return review.GetPayload(), nil return review.GetPayload(), nil
} }
func (gitea *GiteaTransport) UnrequestReview(org, repo string, id int64, reviwers ...string) error {
_, err := gitea.client.Repository.RepoDeletePullReviewRequests(
repository.NewRepoDeletePullReviewRequestsParams().WithOwner(org).WithRepo(repo).WithIndex(id).WithBody(&models.PullReviewRequestOptions{
Reviewers: reviwers,
}), gitea.transport.DefaultAuthentication)
return err
}
func (gitea *GiteaTransport) AddReviewComment(pr *models.PullRequest, state models.ReviewStateType, comment string) (*models.PullReview, error) { func (gitea *GiteaTransport) AddReviewComment(pr *models.PullRequest, state models.ReviewStateType, comment string) (*models.PullReview, error) {
c, err := gitea.client.Repository.RepoCreatePullReview( c, err := gitea.client.Repository.RepoCreatePullReview(
repository.NewRepoCreatePullReviewParams(). repository.NewRepoCreatePullReviewParams().
@@ -717,41 +561,6 @@ func (gitea *GiteaTransport) AddComment(pr *models.PullRequest, comment string)
return nil return nil
} }
func (gitea *GiteaTransport) GetTimeline(org, repo string, idx int64) ([]*models.TimelineComment, error) {
page := int64(1)
resCount := 1
retData := []*models.TimelineComment{}
for resCount > 0 {
res, err := gitea.client.Issue.IssueGetCommentsAndTimeline(
issue.NewIssueGetCommentsAndTimelineParams().
WithOwner(org).
WithRepo(repo).
WithIndex(idx).
WithPage(&page),
gitea.transport.DefaultAuthentication,
)
if err != nil {
return nil, err
}
resCount = len(res.Payload)
LogDebug("page:", page, "len:", resCount)
page++
retData = append(retData, res.Payload...)
}
LogDebug("total results:", len(retData))
slices.SortFunc(retData, func(a, b *models.TimelineComment) int {
return time.Time(b.Created).Compare(time.Time(a.Created))
})
return retData, nil
}
func (gitea *GiteaTransport) GetRepositoryFileContent(org, repo, hash, path string) ([]byte, string, error) { func (gitea *GiteaTransport) GetRepositoryFileContent(org, repo, hash, path string) ([]byte, string, error) {
params := repository.NewRepoGetContentsParams().WithOwner(org).WithRepo(repo).WithFilepath(path) params := repository.NewRepoGetContentsParams().WithOwner(org).WithRepo(repo).WithFilepath(path)
if len(hash) > 0 { if len(hash) > 0 {
@@ -823,7 +632,7 @@ endPrs:
} }
// if pr is closed for more than a week, assume that we are done too // if pr is closed for more than a week, assume that we are done too
if pr.State == "closed" && time.Since(time.Time(pr.Updated)) > 7*24*time.Hour { if time.Since(time.Time(pr.Updated)) > 7*24*time.Hour {
break endPrs break endPrs
} }

317
common/listen.go Normal file
View File

@@ -0,0 +1,317 @@
package common
/*
* This file is part of Autogits.
*
* Copyright © 2024 SUSE LLC
*
* Autogits is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 2 of the License, or (at your option) any later
* version.
*
* Autogits is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"crypto/tls"
"fmt"
"net/url"
"runtime/debug"
"slices"
"strings"
"time"
rabbitmq "github.com/rabbitmq/amqp091-go"
)
const RequestType_CreateBrachTag = "create"
const RequestType_DeleteBranchTag = "delete"
const RequestType_Fork = "fork"
const RequestType_Issue = "issues"
const RequestType_IssueAssign = "issue_assign"
const RequestType_IssueComment = "issue_comment"
const RequestType_IssueLabel = "issue_label"
const RequestType_IssueMilestone = "issue_milestone"
const RequestType_Push = "push"
const RequestType_Repository = "repository"
const RequestType_Release = "release"
const RequestType_PR = "pull_request"
const RequestType_PRAssign = "pull_request_assign"
const RequestType_PRLabel = "pull_request_label"
const RequestType_PRComment = "pull_request_comment"
const RequestType_PRMilestone = "pull_request_milestone"
const RequestType_PRSync = "pull_request_sync"
const RequestType_PRReviewAccepted = "pull_request_review_approved"
const RequestType_PRReviewRejected = "pull_request_review_rejected"
const RequestType_PRReviewRequest = "pull_request_review_request"
const RequestType_PRReviewComment = "pull_request_review_comment"
const RequestType_Wiki = "wiki"
type RequestProcessor interface {
ProcessFunc(*Request) error
}
type ListenDefinitions struct {
RabbitURL *url.URL // amqps://user:password@host/queue
GitAuthor string
Handlers map[string]RequestProcessor
Orgs []string
topics []string
topicSubChanges chan string // +topic = subscribe, -topic = unsubscribe
}
type RabbitMessage rabbitmq.Delivery
func (l *ListenDefinitions) processTopicChanges(ch *rabbitmq.Channel, queueName string) {
for {
topic, ok := <-l.topicSubChanges
if !ok {
return
}
LogDebug(" topic change:", topic)
switch topic[0] {
case '+':
if err := ch.QueueBind(queueName, topic[1:], "pubsub", false, nil); err != nil {
LogError(err)
}
case '-':
if err := ch.QueueUnbind(queueName, topic[1:], "pubsub", nil); err != nil {
LogError(err)
}
default:
LogInfo("Ignoring unknown topic change:", topic)
}
}
}
func (l *ListenDefinitions) processRabbitMQ(msgCh chan<- RabbitMessage) error {
queueName := l.RabbitURL.Path
l.RabbitURL.Path = ""
if len(queueName) > 0 && queueName[0] == '/' {
queueName = queueName[1:]
}
connection, err := rabbitmq.DialTLS(l.RabbitURL.String(), &tls.Config{
ServerName: l.RabbitURL.Hostname(),
})
if err != nil {
return fmt.Errorf("Cannot connect to %s . Err: %w", l.RabbitURL.Hostname(), err)
}
defer connection.Close()
ch, err := connection.Channel()
if err != nil {
return fmt.Errorf("Cannot create a channel. Err: %w", err)
}
defer ch.Close()
if err = ch.ExchangeDeclarePassive("pubsub", "topic", true, false, false, false, nil); err != nil {
return fmt.Errorf("Cannot find pubsub exchange? Err: %w", err)
}
var q rabbitmq.Queue
if len(queueName) == 0 {
q, err = ch.QueueDeclare("", false, true, true, false, nil)
} else {
q, err = ch.QueueDeclarePassive(queueName, true, false, true, false, nil)
if err != nil {
LogInfo("queue not found .. trying to create it:", err)
if ch.IsClosed() {
ch, err = connection.Channel()
if err != nil {
return fmt.Errorf("Channel cannot be re-opened. Err: %w", err)
}
}
q, err = ch.QueueDeclare(queueName, true, false, true, false, nil)
if err != nil {
LogInfo("can't create persistent queue ... falling back to temporaty queue:", err)
if ch.IsClosed() {
ch, err = connection.Channel()
return fmt.Errorf("Channel cannot be re-opened. Err: %w", err)
}
q, err = ch.QueueDeclare("", false, true, true, false, nil)
}
}
}
if err != nil {
return fmt.Errorf("Cannot declare queue. Err: %w", err)
}
// log.Printf("queue: %s:%d", q.Name, q.Consumers)
LogInfo(" -- listening to topics:")
l.topicSubChanges = make(chan string)
defer close(l.topicSubChanges)
go l.processTopicChanges(ch, q.Name)
for _, topic := range l.topics {
l.topicSubChanges <- "+" + topic
}
msgs, err := ch.Consume(q.Name, "", true, true, false, false, nil)
if err != nil {
return fmt.Errorf("Cannot start consumer. Err: %w", err)
}
// log.Printf("queue: %s:%d", q.Name, q.Consumers)
for {
msg, ok := <-msgs
if !ok {
return fmt.Errorf("channel/connection closed?\n")
}
msgCh <- RabbitMessage(msg)
}
}
func (l *ListenDefinitions) connectAndProcessRabbitMQ(ch chan<- RabbitMessage) {
defer func() {
if r := recover(); r != nil {
LogError(r)
LogError("'crash' RabbitMQ worker. Recovering... reconnecting...")
time.Sleep(5 * time.Second)
go l.connectAndProcessRabbitMQ(ch)
}
}()
for {
err := l.processRabbitMQ(ch)
if err != nil {
LogError("Error in RabbitMQ connection. %#v", err)
LogInfo("Reconnecting in 2 seconds...")
time.Sleep(2 * time.Second)
}
}
}
func (l *ListenDefinitions) connectToRabbitMQ() chan RabbitMessage {
ch := make(chan RabbitMessage, 100)
go l.connectAndProcessRabbitMQ(ch)
return ch
}
func ProcessEvent(f RequestProcessor, request *Request) {
defer func() {
if r := recover(); r != nil {
LogError("panic caught")
if err, ok := r.(error); !ok {
LogError(err)
}
LogError(string(debug.Stack()))
}
}()
if err := f.ProcessFunc(request); err != nil {
LogError(err)
}
}
func (l *ListenDefinitions) generateTopics() []string {
topics := make([]string, 0, len(l.Handlers)*len(l.Orgs))
scope := "suse"
if l.RabbitURL.Hostname() == "rabbit.opensuse.org" {
scope = "opensuse"
}
for _, org := range l.Orgs {
for requestType, _ := range l.Handlers {
topics = append(topics, fmt.Sprintf("%s.src.%s.%s.#", scope, org, requestType))
}
}
slices.Sort(topics)
return slices.Compact(topics)
}
func (l *ListenDefinitions) UpdateTopics() {
newTopics := l.generateTopics()
j := 0
next_new_topic:
for i := 0; i < len(newTopics); i++ {
topic := newTopics[i]
for j < len(l.topics) {
cmp := strings.Compare(topic, l.topics[j])
if cmp == 0 {
j++
continue next_new_topic
}
if cmp < 0 {
l.topicSubChanges <- "+" + topic
break
}
l.topicSubChanges <- "-" + l.topics[j]
j++
}
if j == len(l.topics) {
l.topicSubChanges <- "+" + topic
}
}
}
func (l *ListenDefinitions) ProcessRabbitMQEvents() error {
LogInfo("RabbitMQ connection:", l.RabbitURL.String())
LogDebug("# Handlers:", len(l.Handlers))
LogDebug("# Orgs:", len(l.Orgs))
l.RabbitURL.User = url.UserPassword(rabbitUser, rabbitPassword)
l.topics = l.generateTopics()
ch := l.connectToRabbitMQ()
for {
msg, ok := <-ch
if !ok {
return nil
}
LogDebug("event:", msg.RoutingKey)
route := strings.Split(msg.RoutingKey, ".")
if len(route) > 3 {
reqType := route[3]
org := route[2]
if !slices.Contains(l.Orgs, org) {
LogInfo("Got event for unhandeled org:", org)
continue
}
LogDebug("org:", org, "type:", reqType)
if handler, found := l.Handlers[reqType]; found {
/* h, err := CreateRequestHandler()
if err != nil {
log.Println("Cannot create request handler", err)
continue
}
*/
req, err := ParseRequestJSON(reqType, msg.Body)
if err != nil {
LogError("Error parsing request JSON:", err)
continue
} else {
LogDebug("processing req", req.Type)
// h.Request = req
ProcessEvent(handler, req)
}
}
}
}
}

48
common/listen_test.go Normal file
View File

@@ -0,0 +1,48 @@
package common
import (
"net/url"
"testing"
)
func TestListenDefinitionsTopicUpdate(t *testing.T) {
tests := []struct {
name string
handlers []string
orgs1, orgs2 []string
topicDelta []string
}{
{
name: "no handlers, no orgs",
},
{
name: "adding one org",
handlers: []string{"foo"},
orgs2: []string{"newOrg"},
topicDelta: []string{"+suse"},
},
}
u, _ := url.Parse("amqps://rabbit.example.com")
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
l := ListenDefinitions{
Orgs: test.orgs1,
Handlers: make(map[string]RequestProcessor),
topicSubChanges: make(chan string, len(test.topicDelta)*10),
RabbitURL: u,
}
for _, r := range test.handlers {
l.Handlers[r] = nil
}
l.UpdateTopics()
if len(l.topicSubChanges) != len(test.topicDelta) {
t.Fatal("topicSubChanges", len(l.topicSubChanges), " != topicDelta", len(test.topicDelta))
}
})
}
}

View File

@@ -36,14 +36,13 @@ func CreateStdoutLogger(stdout, stderr io.Writer) (*log.Logger, *log.Logger) {
func PanicOnError(err error) { func PanicOnError(err error) {
if err != nil { if err != nil {
LogError(err)
panic(err) panic(err)
} }
} }
func PanicOnErrorWithMsg(err error, msg ...any) { func PanicOnErrorWithMsg(err error, msg string) {
if err != nil { if err != nil {
LogError(msg...) LogError(msg)
panic(err) panic(err)
} }
} }
@@ -52,38 +51,18 @@ type LogLevel int
const ( const (
LogLevelNone = 0 LogLevelNone = 0
LogLevelError = 2
LogLevelInfo = 5 LogLevelInfo = 5
LogLevelDebug = 10 LogLevelDebug = 10
) )
var logLevel LogLevel = LogLevelInfo var logLevel LogLevel
func SetLoggingLevel(ll LogLevel) { func SetLoggingLevel(ll LogLevel) {
logLevel = ll logLevel = ll
} }
func SetLoggingLevelFromString(ll string) error {
switch ll {
case "info":
SetLoggingLevel(LogLevelInfo)
case "debug":
SetLoggingLevel(LogLevelDebug)
case "error":
SetLoggingLevel(LogLevelError)
case "none":
SetLoggingLevel(LogLevelNone)
default:
return fmt.Errorf("Unknown logging level: %s", ll)
}
return nil
}
func LogError(params ...any) { func LogError(params ...any) {
if logLevel >= LogLevelError { log.Println(append([]any{"[E]"}, params...)...)
log.Println(append([]any{"[E]"}, params...)...)
}
} }
func LogDebug(params ...any) { func LogDebug(params ...any) {

View File

@@ -16,7 +16,7 @@ type MaintainershipData interface {
ListProjectMaintainers() []string ListProjectMaintainers() []string
ListPackageMaintainers(pkg string) []string ListPackageMaintainers(pkg string) []string
IsApproved(pkg string, reviews []*models.PullReview, submitter string) bool IsApproved(pkg string, reviews []*models.PullReview) bool
} }
const ProjectKey = "" const ProjectKey = ""
@@ -44,13 +44,12 @@ func FetchProjectMaintainershipData(gitea GiteaMaintainershipReader, org, prjGit
dir := true dir := true
if err != nil || data == nil { if err != nil || data == nil {
dir = false dir = false
if _, notFound := err.(*repository.RepoGetContentsNotFound); !notFound { if _, notFound := err.(*repository.RepoGetRawFileNotFound); !notFound {
return nil, err return nil, err
} }
LogDebug("Falling back to maintainership file")
data, _, err = gitea.FetchMaintainershipFile(org, prjGit, branch) data, _, err = gitea.FetchMaintainershipFile(org, prjGit, branch)
if err != nil || data == nil { if err != nil || data == nil {
if _, notFound := err.(*repository.RepoGetContentsNotFound); !notFound { if _, notFound := err.(*repository.RepoGetRawFileNotFound); !notFound {
return nil, err return nil, err
} }
@@ -63,7 +62,7 @@ func FetchProjectMaintainershipData(gitea GiteaMaintainershipReader, org, prjGit
if m != nil { if m != nil {
m.IsDir = dir m.IsDir = dir
m.FetchPackage = func(pkg string) ([]byte, error) { m.FetchPackage = func(pkg string) ([]byte, error) {
data, _, err := gitea.FetchMaintainershipDirFile(org, prjGit, branch, pkg) data , _, err := gitea.FetchMaintainershipDirFile(org, prjGit, branch, pkg)
return data, err return data, err
} }
} }
@@ -126,27 +125,27 @@ prjMaintainer:
return pkgMaintainers return pkgMaintainers
} }
func (data *MaintainershipMap) IsApproved(pkg string, reviews []*models.PullReview, submitter string) bool { func (data *MaintainershipMap) IsApproved(pkg string, reviews []*models.PullReview) bool {
var reviewers []string reviewers, found := data.Data[pkg]
if pkg != ProjectKey { if !found {
reviewers = data.ListPackageMaintainers(pkg) if pkg != ProjectKey && data.IsDir {
} else { r, err := data.FetchPackage(pkg)
reviewers = data.ListProjectMaintainers() if err != nil {
return false
}
reviewers = parsePkgDirData(pkg, r)
data.Data[pkg] = reviewers
} else {
return true
}
} }
if len(reviewers) == 0 { if len(reviewers) == 0 {
return true return true
} }
LogDebug("Looking for review by:", reviewers)
if slices.Contains(reviewers, submitter) {
LogDebug("Submitter is maintainer. Approving.")
return true
}
for _, review := range reviews { for _, review := range reviews {
if !review.Stale && review.State == ReviewStateApproved && slices.Contains(reviewers, review.User.UserName) { if !review.Stale && review.State == ReviewStateApproved && slices.Contains(reviewers, review.User.UserName) {
LogDebug("Reviewed by", review.User.UserName)
return true return true
} }
@@ -184,7 +183,7 @@ func (data *MaintainershipMap) WriteMaintainershipFile(writer io.StringWriter) e
keys = slices.Delete(keys, i, len(keys)) keys = slices.Delete(keys, i, len(keys))
} }
slices.Sort(keys) slices.Sort(keys)
for i, pkg := range keys { for i, pkg := range(keys) {
eol := "," eol := ","
if i == len(keys)-1 { if i == len(keys)-1 {
eol = "" eol = ""

View File

@@ -120,7 +120,7 @@ func TestMaintainership(t *testing.T) {
}, },
} }
notFoundError := repository.NewRepoGetContentsNotFound() notFoundError := repository.NewRepoGetRawFileNotFound()
for _, test := range packageTests { for _, test := range packageTests {
runTests := func(t *testing.T, mi common.GiteaMaintainershipReader) { runTests := func(t *testing.T, mi common.GiteaMaintainershipReader) {
maintainers, err := common.FetchProjectMaintainershipData(mi, config.Organization, config.GitProjectName, config.Branch) maintainers, err := common.FetchProjectMaintainershipData(mi, config.Organization, config.GitProjectName, config.Branch)

View File

@@ -1,56 +0,0 @@
package common
import (
"os"
"path"
"strings"
"gopkg.in/yaml.v3"
)
type Manifest struct {
Subdirectories []string
}
func (m *Manifest) SubdirForPackage(pkg string) string {
if m == nil {
return pkg
}
idx := -1
matchLen := 0
basePkg := path.Base(pkg)
lowercasePkg := strings.ToLower(basePkg)
for i, sub := range m.Subdirectories {
basename := strings.ToLower(path.Base(sub))
if strings.HasPrefix(lowercasePkg, basename) && matchLen < len(basename) {
idx = i
matchLen = len(basename)
}
}
if idx > -1 {
return path.Join(m.Subdirectories[idx], basePkg)
}
return pkg
}
func ReadManifestFile(filename string) (*Manifest, error) {
data, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
return ParseManifestFile(data)
}
func ParseManifestFile(data []byte) (*Manifest, error) {
ret := &Manifest{}
err := yaml.Unmarshal(data, ret)
if err != nil {
return nil, err
}
return ret, nil
}

View File

@@ -1,56 +0,0 @@
package common_test
import (
"testing"
"src.opensuse.org/autogits/common"
)
func TestManifestSubdirAssignments(t *testing.T) {
tests := []struct {
Name string
ManifestContent string
Packages []string
ManifestLocations []string
}{
{
Name: "empty manifest",
Packages: []string{"atom", "blarg", "Foobar", "X-Ray", "boost", "NodeJS"},
ManifestLocations: []string{"atom", "blarg", "Foobar", "X-Ray", "boost", "NodeJS"},
},
{
Name: "only few subdirs manifest",
ManifestContent: "subdirectories:\n - a\n - b",
Packages: []string{"atom", "blarg", "Foobar", "X-Ray", "Boost", "NodeJS"},
ManifestLocations: []string{"a/atom", "b/blarg", "Foobar", "X-Ray", "b/Boost", "NodeJS"},
},
{
Name: "multilayer subdirs manifest",
ManifestContent: "subdirectories:\n - a\n - b\n - libs/boo",
Packages: []string{"atom", "blarg", "Foobar", "X-Ray", "Boost", "NodeJS"},
ManifestLocations: []string{"a/atom", "b/blarg", "Foobar", "X-Ray", "libs/boo/Boost", "NodeJS"},
},
{
Name: "multilayer subdirs manifest with trailing /",
ManifestContent: "subdirectories:\n - a\n - b\n - libs/boo/\n - somedir/Node/",
Packages: []string{"atom", "blarg", "Foobar", "X-Ray", "Boost", "NodeJS", "foobar/node2"},
ManifestLocations: []string{"a/atom", "b/blarg", "Foobar", "X-Ray", "libs/boo/Boost", "somedir/Node/NodeJS", "somedir/Node/node2"},
},
}
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
m, err := common.ParseManifestFile([]byte(test.ManifestContent))
if err != nil {
t.Fatal(err)
}
for i, pkg := range test.Packages {
expected := test.ManifestLocations[i]
if l := m.SubdirForPackage(pkg); l != expected {
t.Error("Expected:", expected, "but got:", l)
}
}
})
}
}

View File

@@ -25,6 +25,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"log"
"net/http" "net/http"
"net/url" "net/url"
"os/exec" "os/exec"
@@ -58,7 +59,7 @@ type ObsClient struct {
} }
func NewObsClient(host string) (*ObsClient, error) { func NewObsClient(host string) (*ObsClient, error) {
baseUrl, err := url.Parse(host) baseUrl, err := url.Parse("https://" + host)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -156,34 +157,6 @@ type GroupMeta struct {
Persons PersonGroup `xml:"person"` Persons PersonGroup `xml:"person"`
} }
type RequestStateMeta struct {
XMLName xml.Name `xml:"state"`
State string `xml:"name,attr"`
}
type RequestActionTarget struct {
XMLName xml.Name
Project string `xml:"project,attr"`
Package string `xml:"package,attr"`
Revision *string `xml:"rev,attr,optional"`
}
type RequestActionMeta struct {
XMLName xml.Name `xml:"action"`
Type string `xml:"type,attr"`
Source *RequestActionTarget `xml:"source,optional"`
Target *RequestActionTarget `xml:"target,optional"`
}
type RequestMeta struct {
XMLName xml.Name `xml:"request"`
Id int `xml:"id,attr"`
Creator string `xml:"creator,attr"`
Action *RequestActionMeta `xml:"action"`
State RequestStateMeta `xml:"state"`
}
func parseProjectMeta(data []byte) (*ProjectMeta, error) { func parseProjectMeta(data []byte) (*ProjectMeta, error) {
var meta ProjectMeta var meta ProjectMeta
err := xml.Unmarshal(data, &meta) err := xml.Unmarshal(data, &meta)
@@ -194,83 +167,8 @@ func parseProjectMeta(data []byte) (*ProjectMeta, error) {
return &meta, nil return &meta, nil
} }
const (
RequestStatus_Unknown = "unknown"
RequestStatus_Accepted = "accepted"
RequestStatus_Superseded = "superseded"
RequestStatus_Declined = "declined"
RequestStatus_Revoked = "revoked"
RequestStatus_New = "new"
RequestStatus_Review = "review"
)
func (status *RequestStateMeta) IsFinal() bool {
switch status.State {
case RequestStatus_Declined, RequestStatus_Revoked, RequestStatus_Accepted, RequestStatus_Superseded:
return true
}
return false
}
func parseRequestXml(data []byte) (*RequestMeta, error) {
ret := RequestMeta{}
LogDebug("parsing: ", string(data))
if err := xml.Unmarshal(data, &ret); err != nil {
return nil, err
}
return &ret, nil
}
func (c *ObsClient) CreateSubmitRequest(sourcePrj, sourcePkg, targetPrj string) (*RequestMeta, error) {
url := c.baseUrl.JoinPath("request")
query := url.Query()
query.Add("cmd", "create")
url.RawQuery = query.Encode()
request := `<request>
<action type="submit">
<source project="` + sourcePrj + `" package="` + sourcePkg + `">
</source>
<target project="` + targetPrj + `" package="` + sourcePkg + `">
</target>
</action>
</request>`
res, err := c.ObsRequestRaw("POST", url.String(), strings.NewReader(request))
if err != nil {
return nil, err
} else if res.StatusCode != 200 {
return nil, fmt.Errorf("Unexpected return code: %d", res.StatusCode)
}
data, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}
return parseRequestXml(data)
}
func (c *ObsClient) RequestStatus(requestID int) (*RequestMeta, error) {
res, err := c.ObsRequest("GET", []string{"request", fmt.Sprint(requestID)}, nil)
if err != nil {
return nil, err
}
if res.StatusCode != 200 {
return nil, fmt.Errorf("Unexpected return code: %d", res.StatusCode)
}
data, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}
return parseRequestXml(data)
}
func (c *ObsClient) GetGroupMeta(gid string) (*GroupMeta, error) { func (c *ObsClient) GetGroupMeta(gid string) (*GroupMeta, error) {
res, err := c.ObsRequest("GET", []string{"group", gid}, nil) res, err := c.ObsRequest("GET", c.baseUrl.JoinPath("group", gid).String(), nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -288,7 +186,6 @@ func (c *ObsClient) GetGroupMeta(gid string) (*GroupMeta, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer res.Body.Close()
var meta GroupMeta var meta GroupMeta
err = xml.Unmarshal(data, &meta) err = xml.Unmarshal(data, &meta)
@@ -300,7 +197,7 @@ func (c *ObsClient) GetGroupMeta(gid string) (*GroupMeta, error) {
} }
func (c *ObsClient) GetUserMeta(uid string) (*UserMeta, error) { func (c *ObsClient) GetUserMeta(uid string) (*UserMeta, error) {
res, err := c.ObsRequest("GET", []string{"person", uid}, nil) res, err := c.ObsRequest("GET", c.baseUrl.JoinPath("person", uid).String(), nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -318,7 +215,6 @@ func (c *ObsClient) GetUserMeta(uid string) (*UserMeta, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer res.Body.Close()
var meta UserMeta var meta UserMeta
err = xml.Unmarshal(data, &meta) err = xml.Unmarshal(data, &meta)
@@ -329,11 +225,7 @@ func (c *ObsClient) GetUserMeta(uid string) (*UserMeta, error) {
return &meta, nil return &meta, nil
} }
func (c *ObsClient) ObsRequest(method string, url_path []string, body io.Reader) (*http.Response, error) { func (c *ObsClient) ObsRequest(method string, url string, body io.Reader) (*http.Response, error) {
return c.ObsRequestRaw(method, c.baseUrl.JoinPath(url_path...).String(), body)
}
func (c *ObsClient) ObsRequestRaw(method string, url string, body io.Reader) (*http.Response, error) {
req, err := http.NewRequest(method, url, body) req, err := http.NewRequest(method, url, body)
if err != nil { if err != nil {
@@ -346,12 +238,6 @@ func (c *ObsClient) ObsRequestRaw(method string, url string, body io.Reader) (*h
req.Header.Add("cookie", c.cookie) req.Header.Add("cookie", c.cookie)
} }
res, err := c.client.Do(req) res, err := c.client.Do(req)
if err != nil && res == nil {
LogDebug("No res headers:", err)
return res, err
}
if err == nil && res.StatusCode == 200 { if err == nil && res.StatusCode == 200 {
auth_cookie := res.Header.Get("set-cookie") auth_cookie := res.Header.Get("set-cookie")
if auth_cookie != "" { if auth_cookie != "" {
@@ -362,7 +248,6 @@ func (c *ObsClient) ObsRequestRaw(method string, url string, body io.Reader) (*h
if res.StatusCode == 401 { if res.StatusCode == 401 {
if c.sshkey == "" { if c.sshkey == "" {
LogDebug("setting basic auth")
req.SetBasicAuth(c.user, c.password) req.SetBasicAuth(c.user, c.password)
} else { } else {
www := res.Header.Get("www-authenticate") www := res.Header.Get("www-authenticate")
@@ -405,57 +290,52 @@ func (c *ObsClient) ObsRequestRaw(method string, url string, body io.Reader) (*h
// log.Printf("Add Authorization Signature ", authorization) // log.Printf("Add Authorization Signature ", authorization)
req.Header.Add("Authorization", "Signature "+authorization) req.Header.Add("Authorization", "Signature "+authorization)
} }
// Another time with authentification header
LogDebug("Trying again with authorization for", req.URL.String())
res, err = c.client.Do(req)
if err != nil {
if res != nil {
LogError("Authentification failed:", res.StatusCode)
}
return nil, err
}
} }
if err == nil { // Another time with authentification header
// Store the cookie for next call // log.Printf("Trying again with authorization: %s", req.Header.Get("Authorization"))
auth_cookie := res.Header.Get("set-cookie")
if auth_cookie != "" { res, err = c.client.Do(req)
c.cookie = auth_cookie if err != nil {
} log.Println("Authentification failed:", res.StatusCode)
return nil, err
}
// Store the cookie for next call
auth_cookie := res.Header.Get("set-cookie")
if auth_cookie != "" {
c.cookie = auth_cookie
} }
return res, err return res, err
} }
func (c *ObsClient) GetProjectMeta(project string) (*ProjectMeta, error) { func (c *ObsClient) GetProjectMeta(project string) (*ProjectMeta, error) {
req := []string{"source", project, "_meta"} res, err := c.ObsRequest("GET", c.baseUrl.JoinPath("source", project, "_meta").String(), nil)
res, err := c.ObsRequest("GET", req, nil)
if err != nil {
if err != nil { return nil, err
return nil, err }
}
switch res.StatusCode {
switch res.StatusCode { case 200:
case 200: break
break case 404:
case 404: return nil, nil
return nil, nil default:
default: return nil, fmt.Errorf("Unexpected return code: %d", res.StatusCode)
return nil, fmt.Errorf("Unexpected return code: %d %s %w", res.StatusCode, req, err) }
}
data, err := io.ReadAll(res.Body)
data, err := io.ReadAll(res.Body) if err != nil {
if err != nil { return nil, err
return nil, err }
}
return parseProjectMeta(data)
defer res.Body.Close() }
return parseProjectMeta(data)
} func (c *ObsClient) GetPackageMeta(project, pkg string) (*PackageMeta, error) {
res, err := c.ObsRequest("GET", c.baseUrl.JoinPath("source", project, pkg, "_meta").String(), nil)
func (c *ObsClient) GetPackageMeta(project, pkg string) (*PackageMeta, error) {
res, err := c.ObsRequest("GET", []string{"source", project, pkg, "_meta"}, nil)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -474,7 +354,6 @@ func (c *ObsClient) GetPackageMeta(project, pkg string) (*PackageMeta, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer res.Body.Close()
var meta PackageMeta var meta PackageMeta
err = xml.Unmarshal(data, &meta) err = xml.Unmarshal(data, &meta)
@@ -529,11 +408,10 @@ func (c *ObsClient) SetProjectMeta(meta *ProjectMeta) error {
return err return err
} }
res, err := c.ObsRequest("PUT", []string{"source", meta.Name, "_meta"}, io.NopCloser(bytes.NewReader(xml))) res, err := c.ObsRequest("PUT", c.baseUrl.JoinPath("source", meta.Name, "_meta").String(), io.NopCloser(bytes.NewReader(xml)))
if err != nil { if err != nil {
return err return err
} }
defer res.Body.Close()
switch res.StatusCode { switch res.StatusCode {
case 200: case 200:
@@ -546,37 +424,17 @@ func (c *ObsClient) SetProjectMeta(meta *ProjectMeta) error {
} }
func (c *ObsClient) DeleteProject(project string) error { func (c *ObsClient) DeleteProject(project string) error {
url := c.baseUrl.JoinPath("source", project) res, err := c.ObsRequest("DELETE", c.baseUrl.JoinPath("source", project).String(), nil)
query := url.Query()
query.Add("force", "1")
url.RawQuery = query.Encode()
res, err := c.ObsRequestRaw("DELETE", url.String(), nil)
if err != nil { if err != nil {
return err return err
} }
defer res.Body.Close()
if res.StatusCode != 200 { if res.StatusCode != 200 {
return fmt.Errorf("Unexpected return code: %d", res.StatusCode) return fmt.Errorf("Unexpected return code: %d", res.StatusCode)
} }
return nil return nil
}
func (c *ObsClient) BuildLog(prj, pkg, repo, arch string) (io.ReadCloser, error) {
url := c.baseUrl.JoinPath("build", prj, repo, arch, pkg, "_log")
query := url.Query()
query.Add("nostream", "1")
query.Add("start", "0")
url.RawQuery = query.Encode()
res, err := c.ObsRequestRaw("GET", url.String(), nil)
if err != nil {
return nil, err
}
return res.Body, nil
} }
type PackageBuildStatus struct { type PackageBuildStatus struct {
@@ -612,8 +470,6 @@ type BuildResultList struct {
XMLName xml.Name `xml:"resultlist"` XMLName xml.Name `xml:"resultlist"`
State string `xml:"state,attr"` State string `xml:"state,attr"`
Result []BuildResult `xml:"result"` Result []BuildResult `xml:"result"`
isLastBuild bool
} }
func (r *BuildResultList) GetPackageList() []string { func (r *BuildResultList) GetPackageList() []string {
@@ -638,7 +494,7 @@ func (r *BuildResultList) GetPackageList() []string {
func (r *BuildResultList) BuildResultSummary() (success, finished bool) { func (r *BuildResultList) BuildResultSummary() (success, finished bool) {
if r == nil { if r == nil {
return false, false return true, true
} }
finished = len(r.Result) > 0 && len(r.Result[0].Status) > 0 finished = len(r.Result) > 0 && len(r.Result[0].Status) > 0
@@ -651,7 +507,7 @@ func (r *BuildResultList) BuildResultSummary() (success, finished bool) {
panic("Unknown repo result code: " + resultSet.Code) panic("Unknown repo result code: " + resultSet.Code)
} }
finished = r.isLastBuild || repoDetail.Finished finished = repoDetail.Finished
if !finished || resultSet.Dirty { if !finished || resultSet.Dirty {
return return
} }
@@ -662,11 +518,6 @@ func (r *BuildResultList) BuildResultSummary() (success, finished bool) {
if !ok { if !ok {
panic("Unknown result code: " + result.Code) panic("Unknown result code: " + result.Code)
} }
if r.isLastBuild && result.Code == "unknown" {
// it means the package has never build yet,
// but we don't know the reason
detail.Finished = true
}
finished = finished && detail.Finished finished = finished && detail.Finished
success = success && detail.Success success = success && detail.Success
@@ -762,7 +613,7 @@ var ObsBuildStatusDetails map[string]ObsBuildStatusDetail = map[string]ObsBuildS
}, },
"unknown": ObsBuildStatusDetail{ "unknown": ObsBuildStatusDetail{
Code: "unknown", Code: "unknown",
Description: "The scheduler has not yet evaluated this package. Should be a short intermediate state for new packages. When used for lastbuild state it means it was never possible to attempt a build", Description: "The scheduler has not yet evaluated this package. Should be a short intermediate state for new packages.",
Finished: false, Finished: false,
}, },
@@ -839,13 +690,14 @@ func (obs ObsProjectNotFound) Error() string {
} }
func (c *ObsClient) ProjectConfig(project string) (string, error) { func (c *ObsClient) ProjectConfig(project string) (string, error) {
res, err := c.ObsRequest("GET", []string{"source", project, "_config"}, nil) u := c.baseUrl.JoinPath("source", project, "_config")
res, err := c.ObsRequest("GET", u.String(), nil)
if err != nil { if err != nil {
return "", err return "", err
} }
if data, err := io.ReadAll(res.Body); err == nil { if data, err := io.ReadAll(res.Body); err == nil {
defer res.Body.Close()
return string(data), nil return string(data), nil
} else { } else {
return "", err return "", err
@@ -880,7 +732,7 @@ func (c *ObsClient) BuildStatusWithState(project string, opts *BuildResultOption
} }
} }
u.RawQuery = query.Encode() u.RawQuery = query.Encode()
res, err := c.ObsRequestRaw("GET", u.String(), nil) res, err := c.ObsRequest("GET", u.String(), nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -898,10 +750,5 @@ func (c *ObsClient) BuildStatusWithState(project string, opts *BuildResultOption
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer res.Body.Close() return parseBuildResults(data)
ret, err := parseBuildResults(data)
if ret != nil {
ret.isLastBuild = opts.LastBuild
}
return ret, err
} }

View File

@@ -55,52 +55,6 @@ func TestParsingOfBuildResults(t *testing.T) {
} }
} }
func TestParsingRequestResults(t *testing.T) {
res, err := parseRequestXml([]byte(metaRequestData))
if err != nil {
t.Fatal(err)
}
if res.Id != 42 ||
res.Action.Source.Project != "home:foo-user" ||
res.Action.Source.Package != "obs-server" ||
*res.Action.Source.Revision != "521e" ||
res.Action.Target.Project != "OBS:Unstable" ||
res.Action.Target.Revision != nil {
t.Fatal(res)
}
}
const metaRequestData = `<?xml version="1.0" encoding="UTF-8"?>
<request id="42" creator="foo-user">
<action type="submit">
<source project="home:foo-user" package="obs-server" rev="521e">
</source>
<target project="OBS:Unstable" package="obs-server">
</target>
<options>
<sourceupdate>cleanup</sourceupdate>
</options>
</action>
<state name="accepted" who="bar-user" when="2021-01-15T13:39:43">
<comment>allright</comment>
</state>
<review state="accepted" when="2021-01-15T15:49:32" who="obs-maintainer" by_user="obs-maintainer">
</review>
<review state="accepted" when="2021-01-15T15:49:32" who="obs-maintainer" by_group="obs-group">
</review>
<review state="accepted" when="2021-01-15T15:49:32" who="obs-maintainer" by_project="OBS:Unstable">
</review>
<review state="accepted" when="2021-01-15T15:49:32" who="obs-maintainer" by_package="obs-server">
</review>
<history who="foo" when="2021-01-15T13:39:43">
<description>Request created</description>
<comment>Please review sources</comment>
</history>
<description>A little version update</description>
</request>`
const metaPrjData = ` const metaPrjData = `
<project name="home:adamm"> <project name="home:adamm">
<title>Adam's Home Projects</title> <title>Adam's Home Projects</title>

View File

@@ -13,36 +13,25 @@ import (
) )
type PRInfo struct { type PRInfo struct {
PR *models.PullRequest PR *models.PullRequest
Reviews *PRReviews Reviews *PRReviews
RemoteName string
} }
type PRSet struct { type PRSet struct {
PRs []*PRInfo PRs []PRInfo
Config *AutogitConfig Config *AutogitConfig
BotUser string
} }
func (prinfo *PRInfo) PRComponents() (org string, repo string, idx int64) { func readPRData(gitea GiteaPRFetcher, pr *models.PullRequest, currentSet []PRInfo, config *AutogitConfig) ([]PRInfo, error) {
org = prinfo.PR.Base.Repo.Owner.UserName
repo = prinfo.PR.Base.Repo.Name
idx = prinfo.PR.Index
return
}
func readPRData(gitea GiteaPRFetcher, pr *models.PullRequest, currentSet []*PRInfo, config *AutogitConfig) ([]*PRInfo, error) {
for _, p := range currentSet { for _, p := range currentSet {
if pr.Index == p.PR.Index && pr.Base.Repo.Name == p.PR.Base.Repo.Name && pr.Base.Repo.Owner.UserName == p.PR.Base.Repo.Owner.UserName { if pr.Index == p.PR.Index && pr.Base.Repo.Name == p.PR.Base.Repo.Name && pr.Base.Repo.Owner.UserName == p.PR.Base.Repo.Owner.UserName {
return nil, nil return nil, nil
} }
} }
retSet := []*PRInfo{&PRInfo{PR: pr}} retSet := []PRInfo{PRInfo{PR: pr}}
// only need to extact there on PrjGit PR // only need to extact there on PrjGit PR
org, repo, _ := config.GetPrjGit() if pr.Base.Repo.Name == config.GitProjectName && pr.Base.Repo.Owner.UserName == config.Organization {
if pr.Base.Repo.Name == repo && pr.Base.Repo.Owner.UserName == org {
_, refPRs := ExtractDescriptionAndPRs(bufio.NewScanner(strings.NewReader(pr.Body))) _, refPRs := ExtractDescriptionAndPRs(bufio.NewScanner(strings.NewReader(pr.Body)))
for _, prdata := range refPRs { for _, prdata := range refPRs {
pr, err := gitea.GetPullRequest(prdata.Org, prdata.Repo, prdata.Num) pr, err := gitea.GetPullRequest(prdata.Org, prdata.Repo, prdata.Num)
@@ -60,52 +49,13 @@ func readPRData(gitea GiteaPRFetcher, pr *models.PullRequest, currentSet []*PRIn
return retSet, nil return retSet, nil
} }
var Timeline_RefIssueNotFound error = errors.New("RefIssue not found on the timeline") func FetchPRSet(gitea GiteaPRFetcher, org, repo string, num int64, config *AutogitConfig) (*PRSet, error) {
func LastPrjGitRefOnTimeline(gitea GiteaPRTimelineFetcher, org, repo string, num int64, prjGitOrg, prjGitRepo string) (*models.PullRequest, error) {
prRefLine := fmt.Sprintf(PrPattern, org, repo, num)
timeline, err := gitea.GetTimeline(org, repo, num)
if err != nil {
LogError("Failed to fetch timeline for", org, repo, "#", num, err)
return nil, err
}
for idx := len(timeline) - 1; idx >= 0; idx-- {
item := timeline[idx]
issue := item.RefIssue
if item.Type == TimelineCommentType_PullRequestRef &&
issue != nil &&
issue.Repository != nil &&
issue.Repository.Owner == prjGitOrg &&
issue.Repository.Name == prjGitRepo {
lines := SplitLines(item.RefIssue.Body)
for _, line := range lines {
if strings.TrimSpace(line) == prRefLine {
LogDebug("Found PrjGit PR in Timeline:", issue.Index)
// found prjgit PR in timeline. Return it
return gitea.GetPullRequest(prjGitOrg, prjGitRepo, issue.Index)
}
}
}
}
LogDebug("PrjGit RefIssue not found on timeline in", org, repo, num)
return nil, Timeline_RefIssueNotFound
}
func FetchPRSet(user string, gitea GiteaPRTimelineFetcher, org, repo string, num int64, config *AutogitConfig) (*PRSet, error) {
var pr *models.PullRequest var pr *models.PullRequest
var err error var err error
prjGitOrg, prjGitRepo, _ := config.GetPrjGit() prjGitOrg, prjGitRepo, _ := config.GetPrjGit()
if prjGitOrg == org && prjGitRepo == repo { if prjGitOrg != org || prjGitRepo != config.GitProjectName {
if pr, err = gitea.GetPullRequest(org, repo, num); err != nil { if pr, err = gitea.GetAssociatedPrjGitPR(prjGitOrg, prjGitRepo, org, repo, num); err != nil {
return nil, err
}
} else {
if pr, err = LastPrjGitRefOnTimeline(gitea, org, repo, num, prjGitOrg, prjGitRepo); err != nil && err != Timeline_RefIssueNotFound {
return nil, err return nil, err
} }
@@ -114,6 +64,10 @@ func FetchPRSet(user string, gitea GiteaPRTimelineFetcher, org, repo string, num
return nil, err return nil, err
} }
} }
} else {
if pr, err = gitea.GetPullRequest(org, repo, num); err != nil {
return nil, err
}
} }
prs, err := readPRData(gitea, pr, nil, config) prs, err := readPRData(gitea, pr, nil, config)
@@ -121,54 +75,22 @@ func FetchPRSet(user string, gitea GiteaPRTimelineFetcher, org, repo string, num
return nil, err return nil, err
} }
return &PRSet{ return &PRSet{PRs: prs, Config: config}, nil
PRs: prs,
Config: config,
BotUser: user,
}, nil
}
func (rs *PRSet) Find(pr *models.PullRequest) (*PRInfo, bool) {
for _, p := range rs.PRs {
if p.PR.Base.RepoID == pr.Base.RepoID &&
p.PR.Head.Sha == pr.Head.Sha &&
p.PR.Base.Name == pr.Base.Name {
return p, true
}
}
return nil, false
}
func (rs *PRSet) AddPR(pr *models.PullRequest) *PRInfo {
if pr, found := rs.Find(pr); found {
return pr
}
prinfo := &PRInfo{
PR: pr,
}
rs.PRs = append(rs.PRs, prinfo)
return prinfo
} }
func (rs *PRSet) IsPrjGitPR(pr *models.PullRequest) bool { func (rs *PRSet) IsPrjGitPR(pr *models.PullRequest) bool {
org, repo, branch := rs.Config.GetPrjGit() return pr.Base.Repo.Name == rs.Config.GitProjectName && pr.Base.Repo.Owner.UserName == rs.Config.Organization
return pr.Base.Name == branch && pr.Base.Repo.Name == repo && pr.Base.Repo.Owner.UserName == org
} }
var PRSet_PrjGitMissing error = errors.New("No PrjGit PR found") func (rs *PRSet) GetPrjGitPR() (*models.PullRequest, error) {
var PRSet_MultiplePrjGit error = errors.New("Multiple PrjGit PRs in one review set") var ret *models.PullRequest
func (rs *PRSet) GetPrjGitPR() (*PRInfo, error) {
var ret *PRInfo
for _, prinfo := range rs.PRs { for _, prinfo := range rs.PRs {
if rs.IsPrjGitPR(prinfo.PR) { if rs.IsPrjGitPR(prinfo.PR) {
if ret == nil { if ret == nil {
ret = prinfo ret = prinfo.PR
} else { } else {
return nil, PRSet_MultiplePrjGit return nil, errors.New("Multiple PrjGit PRs in one review set")
} }
} }
} }
@@ -177,37 +99,21 @@ func (rs *PRSet) GetPrjGitPR() (*PRInfo, error) {
return ret, nil return ret, nil
} }
return nil, PRSet_PrjGitMissing return nil, errors.New("No PrjGit PR found")
}
func (rs *PRSet) NeedRecreatingPrjGit(currentBranchHash string) bool {
pr, err := rs.GetPrjGitPR()
if err != nil {
return true
}
return pr.PR.Base.Sha == currentBranchHash
} }
func (rs *PRSet) IsConsistent() bool { func (rs *PRSet) IsConsistent() bool {
prjpr_info, err := rs.GetPrjGitPR() prjpr, err := rs.GetPrjGitPR()
if err != nil { if err != nil {
return false return false
} }
prjpr := prjpr_info.PR
_, prjpr_set := ExtractDescriptionAndPRs(bufio.NewScanner(strings.NewReader(prjpr.Body))) _, prjpr_set := ExtractDescriptionAndPRs(bufio.NewScanner(strings.NewReader(prjpr.Body)))
if len(prjpr_set) != len(rs.PRs)-1 { // 1 to many mapping if len(prjpr_set) != len(rs.PRs)-1 { // 1 to many mapping
LogDebug("Number of PR from links:", len(prjpr_set), "is not what's expected", len(rs.PRs)-1)
return false return false
} }
next_rs: next_rs:
for _, prinfo := range rs.PRs { for _, prinfo := range rs.PRs {
if prinfo.PR.State != "open" {
return false
}
if prjpr == prinfo.PR { if prjpr == prinfo.PR {
continue continue
} }
@@ -227,33 +133,24 @@ func (rs *PRSet) AssignReviewers(gitea GiteaReviewFetcherAndRequester, maintaine
for _, pr := range rs.PRs { for _, pr := range rs.PRs {
reviewers := []string{} reviewers := []string{}
if rs.IsPrjGitPR(pr.PR) { if rs.IsPrjGitPR(pr.PR) {
reviewers = slices.Concat(configReviewers.Prj, configReviewers.PrjOptional) reviewers = configReviewers.Prj
LogDebug("PrjGit submitter:", pr.PR.User.UserName)
if len(rs.PRs) == 1 { if len(rs.PRs) == 1 {
reviewers = slices.Concat(reviewers, maintainers.ListProjectMaintainers()) reviewers = slices.Concat(reviewers, maintainers.ListProjectMaintainers())
} }
} else { } else {
pkg := pr.PR.Base.Repo.Name pkg := pr.PR.Base.Repo.Name
reviewers = slices.Concat(configReviewers.Pkg, maintainers.ListProjectMaintainers(), maintainers.ListPackageMaintainers(pkg), configReviewers.PkgOptional) reviewers = slices.Concat(configReviewers.Pkg, maintainers.ListProjectMaintainers(), maintainers.ListPackageMaintainers(pkg))
} }
slices.Sort(reviewers)
reviewers = slices.Compact(reviewers)
// submitters do not need to review their own work // submitters do not need to review their own work
if idx := slices.Index(reviewers, pr.PR.User.UserName); idx != -1 { if idx := slices.Index(reviewers, pr.PR.User.UserName); idx != -1 {
reviewers = slices.Delete(reviewers, idx, idx+1) reviewers = slices.Delete(reviewers, idx, idx+1)
} }
LogDebug("PR: ", pr.PR.Base.Repo.Name, pr.PR.Index)
LogDebug("reviewers for PR:", reviewers)
// remove reviewers that were already requested and are not stale // remove reviewers that were already requested and are not stale
reviews, err := FetchGiteaReviews(gitea, reviewers, pr.PR.Base.Repo.Owner.UserName, pr.PR.Base.Repo.Name, pr.PR.Index) reviews, err := FetchGiteaReviews(gitea, reviewers, pr.PR.Base.Repo.Owner.UserName, pr.PR.Base.Repo.Name, pr.PR.Index)
if err != nil { if err != nil {
LogError("Error fetching reviews:", err)
return err return err
} }
@@ -261,7 +158,6 @@ func (rs *PRSet) AssignReviewers(gitea GiteaReviewFetcherAndRequester, maintaine
user := reviewers[idx] user := reviewers[idx]
if reviews.HasPendingReviewBy(user) || reviews.IsReviewedBy(user) { if reviews.HasPendingReviewBy(user) || reviews.IsReviewedBy(user) {
reviewers = slices.Delete(reviewers, idx, idx+1) reviewers = slices.Delete(reviewers, idx, idx+1)
LogDebug("removing reviewer:", user)
} else { } else {
idx++ idx++
} }
@@ -269,13 +165,8 @@ func (rs *PRSet) AssignReviewers(gitea GiteaReviewFetcherAndRequester, maintaine
// get maintainers associated with the PR too // get maintainers associated with the PR too
if len(reviewers) > 0 { if len(reviewers) > 0 {
LogDebug("Requesting reviews from:", reviewers) if _, err := gitea.RequestReviews(pr.PR, reviewers...); err != nil {
if !IsDryRun { return fmt.Errorf("Cannot create reviews on %s/%s#%d for [%s]: %w", pr.PR.Base.Repo.Owner.UserName, pr.PR.Base.Repo.Name, pr.PR.Index, strings.Join(reviewers, ", "), err)
for _, r := range reviewers {
if _, err := gitea.RequestReviews(pr.PR, r); err != nil {
LogError("Cannot create reviews on", fmt.Sprintf("%s/%s#%d for [%s]", pr.PR.Base.Repo.Owner.UserName, pr.PR.Base.Repo.Name, pr.PR.Index, strings.Join(reviewers, ", ")), err)
}
}
} }
} }
} }
@@ -285,54 +176,7 @@ func (rs *PRSet) AssignReviewers(gitea GiteaReviewFetcherAndRequester, maintaine
func (rs *PRSet) IsApproved(gitea GiteaPRChecker, maintainers MaintainershipData) bool { func (rs *PRSet) IsApproved(gitea GiteaPRChecker, maintainers MaintainershipData) bool {
configReviewers := ParseReviewers(rs.Config.Reviewers) configReviewers := ParseReviewers(rs.Config.Reviewers)
is_manually_reviewed_ok := false is_reviewed := false
if need_manual_review := rs.Config.ManualMergeOnly || rs.Config.ManualMergeProject; need_manual_review {
prjgit, err := rs.GetPrjGitPR()
if err == nil && prjgit != nil {
reviewers := slices.Concat(configReviewers.Prj, maintainers.ListProjectMaintainers())
LogDebug("Fetching reviews for", prjgit.PR.Base.Repo.Owner.UserName, prjgit.PR.Base.Repo.Name, prjgit.PR.Index)
r, err := FetchGiteaReviews(gitea, reviewers, prjgit.PR.Base.Repo.Owner.UserName, prjgit.PR.Base.Repo.Name, prjgit.PR.Index)
if err != nil {
LogError("Cannot fetch gita reaviews for PR:", err)
return false
}
prjgit.Reviews = r
if prjgit.Reviews.IsManualMergeOK() {
is_manually_reviewed_ok = true
}
}
if !is_manually_reviewed_ok && !rs.Config.ManualMergeProject {
for _, pr := range rs.PRs {
if rs.IsPrjGitPR(pr.PR) {
continue
}
pkg := pr.PR.Base.Repo.Name
reviewers := slices.Concat(configReviewers.Pkg, maintainers.ListPackageMaintainers(pkg))
LogDebug("Fetching reviews for", pr.PR.Base.Repo.Owner.UserName, pr.PR.Base.Repo.Name, pr.PR.Index)
r, err := FetchGiteaReviews(gitea, reviewers, pr.PR.Base.Repo.Owner.UserName, pr.PR.Base.Repo.Name, pr.PR.Index)
if err != nil {
LogError("Cannot fetch gita reaviews for PR:", err)
return false
}
pr.Reviews = r
if !pr.Reviews.IsManualMergeOK() {
LogInfo("Not approved manual merge. PR:", pr.PR.URL)
return false
}
}
is_manually_reviewed_ok = true
}
if !is_manually_reviewed_ok {
LogInfo("manual merge not ok")
return false
}
}
for _, pr := range rs.PRs { for _, pr := range rs.PRs {
var reviewers []string var reviewers []string
var pkg string var pkg string
@@ -344,60 +188,48 @@ func (rs *PRSet) IsApproved(gitea GiteaPRChecker, maintainers MaintainershipData
pkg = pr.PR.Base.Repo.Name pkg = pr.PR.Base.Repo.Name
} }
if strings.HasPrefix(pr.PR.Title, "WIP:") {
LogInfo("WIP PR. Ignoring")
return false
}
r, err := FetchGiteaReviews(gitea, reviewers, pr.PR.Base.Repo.Owner.UserName, pr.PR.Base.Repo.Name, pr.PR.Index) r, err := FetchGiteaReviews(gitea, reviewers, pr.PR.Base.Repo.Owner.UserName, pr.PR.Base.Repo.Name, pr.PR.Index)
if err != nil { if err != nil {
LogError("Cannot fetch gita reaviews for PR:", err) return false
}
is_reviewed = r.IsApproved()
if !is_reviewed {
return false return false
} }
is_manually_reviewed_ok = r.IsApproved() if is_reviewed = maintainers.IsApproved(pkg, r.reviews); !is_reviewed {
LogDebug(pr.PR.Base.Repo.Name, is_manually_reviewed_ok)
if !is_manually_reviewed_ok {
return false return false
} }
if need_maintainer_review := !rs.IsPrjGitPR(pr.PR) || pr.PR.User.UserName != rs.BotUser; need_maintainer_review {
if is_manually_reviewed_ok = maintainers.IsApproved(pkg, r.reviews, pr.PR.User.UserName); !is_manually_reviewed_ok {
LogDebug(" not approved?", pkg)
return false
}
} else {
LogDebug("PrjGit PR -- bot created, no need for review")
}
} }
return is_manually_reviewed_ok return is_reviewed
} }
func (rs *PRSet) Merge(gitea GiteaReviewUnrequester, git Git) error { func (rs *PRSet) Merge(gh GitHandlerGenerator) error {
prjgit_info, err := rs.GetPrjGitPR() prjgit, err := rs.GetPrjGitPR()
if err != nil { if err != nil {
return err return err
} }
prjgit := prjgit_info.PR
remote, err := git.GitClone(DefaultGitPrj, rs.Config.Branch, prjgit.Base.Repo.SSHURL) git, err := gh.CreateGitHandler(rs.Config.Organization)
PanicOnError(err) defer git.Close()
git.GitExecOrPanic(DefaultGitPrj, "fetch", remote, prjgit.Head.Sha) if err != nil {
return err
}
git.GitExecOrPanic("", "clone", "--depth", "1", prjgit.Base.Repo.SSHURL, DefaultGitPrj)
git.GitExecOrPanic(DefaultGitPrj, "fetch", "origin", prjgit.Base.Sha, prjgit.Head.Sha)
// if other changes merged, check if we have conflicts // if other changes merged, check if we have conflicts
/* rev := strings.TrimSpace(git.GitExecWithOutputOrPanic(DefaultGitPrj, "merge-base", "HEAD", prjgit.Base.Sha, prjgit.Head.Sha))
rev := strings.TrimSpace(git.GitExecWithOutputOrPanic(DefaultGitPrj, "merge-base", "HEAD", prjgit.Base.Sha, prjgit.Head.Sha)) if rev != prjgit.Base.Sha {
if rev != prjgit.Base.Sha { return fmt.Errorf("Base.Sha (%s) not yet merged into project-git. Aborting merge.", prjgit.Base.Sha)
return fmt.Errorf("Base.Sha (%s) not yet merged into project-git. Aborting merge.", prjgit.Base.Sha) }
}
*/
/* /*
rev := git.GitExecWithOutputOrPanic(common.DefaultGitPrj, "rev-list", "-1", "HEAD") rev := git.GitExecWithOutputOrPanic(common.DefaultGitPrj, "rev-list", "-1", "HEAD")
if rev != prjgit.Base.Sha { if rev != prjgit.Base.Sha {
panic("FIXME") panic("FIXME")
} }
*/ */
msg := fmt.Sprintf("Merging\n\nPR: %s/%s#%d", prjgit.Base.Repo.Owner.UserName, prjgit.Base.Repo.Name, prjgit.Index) msg := "merging"
err = git.GitExec(DefaultGitPrj, "merge", "--no-ff", "-m", msg, prjgit.Head.Sha) err = git.GitExec(DefaultGitPrj, "merge", "--no-ff", "-m", msg, prjgit.Head.Sha)
if err != nil { if err != nil {
@@ -471,58 +303,31 @@ func (rs *PRSet) Merge(gitea GiteaReviewUnrequester, git Git) error {
return fmt.Errorf("Can't close .gitmodules: %w", err) return fmt.Errorf("Can't close .gitmodules: %w", err)
} }
os.CopyFS("/tmp/test", os.DirFS(git.GetPath()))
git.GitExecOrPanic(DefaultGitPrj, "add", ".gitmodules") git.GitExecOrPanic(DefaultGitPrj, "add", ".gitmodules")
git.GitExecOrPanic(DefaultGitPrj, "-c", "core.editor=true", "merge", "--continue") git.GitExecOrPanic(DefaultGitPrj, "-c", "core.editor=true", "merge", "--continue")
} }
} }
} }
// FF all non-prj git and unrequest reviews. // FF all non-prj git
for _, prinfo := range rs.PRs { for _, prinfo := range rs.PRs {
// remove pending review requests
repo := prinfo.PR.Base.Repo
head := prinfo.PR.Head
id := prinfo.PR.Index
reviewers := make([]string, len(prinfo.PR.RequestedReviewers))
for idx := range prinfo.PR.RequestedReviewers {
r := prinfo.PR.RequestedReviewers[idx]
if r != nil {
reviewers[idx] = r.UserName
}
}
if err := gitea.UnrequestReview(repo.Owner.UserName, repo.Name, id, reviewers...); err != nil {
LogError("Cannot unrequest reviews in PR:", repo.Owner.UserName, repo.Name, id, reviewers, ": ", err)
}
// PrjGit already merged above, so skip here.
if rs.IsPrjGitPR(prinfo.PR) { if rs.IsPrjGitPR(prinfo.PR) {
continue continue
} }
prinfo.RemoteName, err = git.GitClone(repo.Name, rs.Config.Branch, repo.SSHURL) git.GitExecOrPanic("", "clone", prinfo.PR.Base.Repo.SSHURL, prinfo.PR.Base.Name)
PanicOnError(err) git.GitExecOrPanic(prinfo.PR.Base.Name, "fetch", "origin", prinfo.PR.Head.Sha)
git.GitExecOrPanic(repo.Name, "fetch", prinfo.RemoteName, head.Sha) git.GitExecOrPanic(prinfo.PR.Base.Name, "merge", "--ff", prinfo.PR.Head.Sha)
git.GitExecOrPanic(repo.Name, "merge", "--ff", head.Sha)
} }
// push changes // push changes
if !IsDryRun { git.GitExecOrPanic(DefaultGitPrj, "push", "origin")
git.GitExecOrPanic(DefaultGitPrj, "push", remote)
} else {
LogInfo("*** WOULD push", DefaultGitPrj, "changes to", remote)
}
for _, prinfo := range rs.PRs { for _, prinfo := range rs.PRs {
if rs.IsPrjGitPR(prinfo.PR) { if rs.IsPrjGitPR(prinfo.PR) {
continue continue
} }
repo := prinfo.PR.Base.Repo git.GitExecOrPanic(prinfo.PR.Base.Name, "push", "origin")
if !IsDryRun {
git.GitExecOrPanic(repo.Name, "push", prinfo.RemoteName)
} else {
LogInfo("*** WOULD push", repo.Name, "to", prinfo.RemoteName)
}
} }
return nil return nil

View File

@@ -6,7 +6,6 @@ import (
"os" "os"
"os/exec" "os/exec"
"path" "path"
"slices"
"strings" "strings"
"testing" "testing"
@@ -15,37 +14,6 @@ import (
"src.opensuse.org/autogits/common/gitea-generated/models" "src.opensuse.org/autogits/common/gitea-generated/models"
mock_common "src.opensuse.org/autogits/common/mock" mock_common "src.opensuse.org/autogits/common/mock"
) )
/*
func TestCockpit(t *testing.T) {
common.SetLoggingLevel(common.LogLevelDebug)
gitea := common.AllocateGiteaTransport("https://src.opensuse.org")
tl, err := gitea.GetTimeline("cockpit", "cockpit", 29)
if err != nil {
t.Fatal("Fail to timeline", err)
}
t.Log(tl)
r, err := common.FetchGiteaReviews(gitea, []string{}, "cockpit", "cockpit", 29)
if err != nil {
t.Fatal("Error:", err)
}
t.Error(r)
}
*/
func reviewsToTimeline(reviews []*models.PullReview) []*models.TimelineComment {
timeline := make([]*models.TimelineComment, len(reviews))
for idx, review := range reviews {
if review.ID == 0 {
review.ID = int64(idx) + 100
}
timeline[idx] = &models.TimelineComment{
Type: common.TimelineCommentType_Review,
ReviewID: review.ID,
}
}
return timeline
}
func TestPR(t *testing.T) { func TestPR(t *testing.T) {
baseConfig := common.AutogitConfig{ baseConfig := common.AutogitConfig{
@@ -59,7 +27,6 @@ func TestPR(t *testing.T) {
pr *models.PullRequest pr *models.PullRequest
pr_err error pr_err error
reviews []*models.PullReview reviews []*models.PullReview
timeline []*models.TimelineComment
review_error error review_error error
} }
@@ -73,26 +40,26 @@ func TestPR(t *testing.T) {
consistentSet bool consistentSet bool
prjGitPRIndex int prjGitPRIndex int
reviewSetFetcher func(*mock_common.MockGiteaPRTimelineFetcher) (*common.PRSet, error) reviewSetFetcher func(*mock_common.MockGiteaPRFetcher) (*common.PRSet, error)
}{ }{
{ {
name: "Error fetching PullRequest", name: "Error fetching PullRequest",
data: []prdata{ data: []prdata{
{pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}, State: "opened"}, pr_err: errors.New("Missing PR")}, {pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}}, pr_err: errors.New("Missing PR")},
}, },
prjGitPRIndex: -1, prjGitPRIndex: -1,
}, },
{ {
name: "Error fetching PullRequest in PrjGit", name: "Error fetching PullRequest in PrjGit",
data: []prdata{ data: []prdata{
{pr: &models.PullRequest{Body: "PR: foo/barPrj#22", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}, State: "opened"}, pr_err: errors.New("missing PR")}, {pr: &models.PullRequest{Body: "PR: foo/barPrj#22", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}}, pr_err: errors.New("missing PR")},
{pr: &models.PullRequest{Body: "", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, State: "opened"}}, {pr: &models.PullRequest{Body: "", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}}},
}, },
}, },
{ {
name: "Error fetching prjgit", name: "Error fetching prjgit",
data: []prdata{ data: []prdata{
{pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}, State: "opened"}}, {pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}}},
}, },
resLen: 1, resLen: 1,
prjGitPRIndex: -1, prjGitPRIndex: -1,
@@ -100,8 +67,8 @@ func TestPR(t *testing.T) {
{ {
name: "Review set is consistent", name: "Review set is consistent",
data: []prdata{ data: []prdata{
{pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}, State: "opened"}}, {pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}}},
{pr: &models.PullRequest{Body: "PR: test/repo#42", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, State: "opened"}}, {pr: &models.PullRequest{Body: "PR: test/repo#42", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}}},
}, },
resLen: 2, resLen: 2,
prjGitPRIndex: 1, prjGitPRIndex: 1,
@@ -111,8 +78,8 @@ func TestPR(t *testing.T) {
{ {
name: "Review set is consistent: 1pkg", name: "Review set is consistent: 1pkg",
data: []prdata{ data: []prdata{
{pr: &models.PullRequest{Body: "PR: foo/barPrj#22", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}, State: "opened"}}, {pr: &models.PullRequest{Body: "PR: foo/barPrj#22", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}}},
{pr: &models.PullRequest{Body: "PR: test/repo#42", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, State: "opened"}}, {pr: &models.PullRequest{Body: "PR: test/repo#42", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}}},
}, },
resLen: 2, resLen: 2,
prjGitPRIndex: 1, prjGitPRIndex: 1,
@@ -121,9 +88,9 @@ func TestPR(t *testing.T) {
{ {
name: "Review set is consistent: 2pkg", name: "Review set is consistent: 2pkg",
data: []prdata{ data: []prdata{
{pr: &models.PullRequest{Body: "some desc", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}, State: "opened"}}, {pr: &models.PullRequest{Body: "some desc", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}}},
{pr: &models.PullRequest{Body: "PR: test/repo#42\nPR: test/repo2#41", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, State: "opened"}}, {pr: &models.PullRequest{Body: "PR: test/repo#42\nPR: test/repo2#41", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}}},
{pr: &models.PullRequest{Body: "some other desc\nPR: foo/fer#33", Index: 41, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo2", Owner: &models.User{UserName: "test"}}}, State: "opened"}}, {pr: &models.PullRequest{Body: "some other desc\nPR: foo/fer#33", Index: 41, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo2", Owner: &models.User{UserName: "test"}}}}},
}, },
resLen: 3, resLen: 3,
prjGitPRIndex: 1, prjGitPRIndex: 1,
@@ -133,7 +100,7 @@ func TestPR(t *testing.T) {
name: "Review set of prjgit PR is consistent", name: "Review set of prjgit PR is consistent",
data: []prdata{ data: []prdata{
{ {
pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"}, pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}},
reviews: []*models.PullReview{ reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m2"}, State: common.ReviewStateApproved}, {Body: "LGTM", User: &models.User{UserName: "m2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved}, {Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
@@ -145,385 +112,38 @@ func TestPR(t *testing.T) {
prjGitPRIndex: 0, prjGitPRIndex: 0,
consistentSet: true, consistentSet: true,
reviewed: true, reviewed: true,
reviewSetFetcher: func(mock *mock_common.MockGiteaPRTimelineFetcher) (*common.PRSet, error) { reviewSetFetcher: func(mock *mock_common.MockGiteaPRFetcher) (*common.PRSet, error) {
return common.FetchPRSet("test", mock, "foo", "barPrj", 42, &baseConfig) return common.FetchPRSet(mock, "foo", "barPrj", 42, &baseConfig)
}, },
}, },
{ {
name: "Review set is consistent: 2pkg", name: "Review set is consistent: 2pkg",
data: []prdata{ data: []prdata{
{pr: &models.PullRequest{Body: "PR: foo/barPrj#222", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}, State: "opened"}}, {pr: &models.PullRequest{Body: "PR: foo/barPrj#222", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}}},
{pr: &models.PullRequest{Body: "PR: test/repo2#41", Index: 20, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, State: "opened"}}, {pr: &models.PullRequest{Body: "PR: test/repo2#41", Index: 20, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}}},
{pr: &models.PullRequest{Body: "PR: test/repo#42\nPR: test/repo2#41", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, State: "opened"}}, {pr: &models.PullRequest{Body: "PR: test/repo#42\nPR: test/repo2#41", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}}},
{pr: &models.PullRequest{Body: "PR: foo/barPrj#20", Index: 41, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo2", Owner: &models.User{UserName: "test"}}}, State: "opened"}}, {pr: &models.PullRequest{Body: "PR: foo/barPrj#20", Index: 41, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo2", Owner: &models.User{UserName: "test"}}}}},
}, },
resLen: 3, resLen: 3,
prjGitPRIndex: 2, prjGitPRIndex: 2,
consistentSet: true, consistentSet: true,
}, },
{
name: "WIP PR is not approved",
data: []prdata{
{
pr: &models.PullRequest{Body: "", Title: "WIP: some title", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: common.Bot_BuildReview}, State: common.ReviewStateApproved},
},
},
},
resLen: 1,
prjGitPRIndex: 0,
consistentSet: true,
reviewed: false,
reviewSetFetcher: func(mock *mock_common.MockGiteaPRTimelineFetcher) (*common.PRSet, error) {
return common.FetchPRSet("test", mock, "foo", "barPrj", 42, &baseConfig)
},
},
{
name: "Manual review is missing",
data: []prdata{
{
pr: &models.PullRequest{Body: "PR: foo/repo#20", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: common.Bot_BuildReview}, State: common.ReviewStateApproved},
},
},
{
pr: &models.PullRequest{Body: "PR: foo/barPrj#42", Index: 20, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
},
},
},
resLen: 2,
prjGitPRIndex: 0,
consistentSet: true,
reviewed: false,
reviewSetFetcher: func(mock *mock_common.MockGiteaPRTimelineFetcher) (*common.PRSet, error) {
return common.FetchPRSet("test", mock, "foo", "barPrj", 42, &common.AutogitConfig{
Reviewers: []string{"+super1", "*super2", "m1", "-m2"},
Branch: "branch",
Organization: "foo",
GitProjectName: "barPrj",
ManualMergeOnly: true,
})
},
},
{
name: "Manual review is done, via PrjGit",
data: []prdata{
{
pr: &models.PullRequest{Body: "PR: foo/repo#20", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "merge ok", User: &models.User{UserName: "m2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: common.Bot_BuildReview}, State: common.ReviewStateApproved},
},
},
{
pr: &models.PullRequest{Body: "PR: foo/barPrj#42", Index: 20, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
},
},
},
resLen: 2,
prjGitPRIndex: 0,
consistentSet: true,
reviewed: true,
reviewSetFetcher: func(mock *mock_common.MockGiteaPRTimelineFetcher) (*common.PRSet, error) {
return common.FetchPRSet("test", mock, "foo", "barPrj", 42, &common.AutogitConfig{
Reviewers: []string{"+super1", "*super2", "m1", "-m2"},
Branch: "branch",
Organization: "foo",
GitProjectName: "barPrj",
ManualMergeOnly: true,
})
},
},
{
name: "Manual review is done, via PrjGit",
data: []prdata{
{
pr: &models.PullRequest{Body: "PR: foo/repo#20", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "merge ok", User: &models.User{UserName: "m2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: common.Bot_BuildReview}, State: common.ReviewStateApproved},
},
},
{
pr: &models.PullRequest{Body: "PR: foo/barPrj#42", Index: 20, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
},
},
},
resLen: 2,
prjGitPRIndex: 0,
consistentSet: true,
reviewed: true,
reviewSetFetcher: func(mock *mock_common.MockGiteaPRTimelineFetcher) (*common.PRSet, error) {
return common.FetchPRSet("test", mock, "foo", "barPrj", 42, &common.AutogitConfig{
Reviewers: []string{"+super1", "*super2", "m1", "-m2"},
Branch: "branch",
Organization: "foo",
GitProjectName: "barPrj",
ManualMergeOnly: true,
ManualMergeProject: true,
})
},
},
{
name: "Manual review is not done, via PrjGit",
data: []prdata{
{
pr: &models.PullRequest{Body: "PR: foo/repo#20", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "merge ok", User: &models.User{UserName: "notm2"}, State: common.ReviewStateApproved},
{Body: "merge not ok", User: &models.User{UserName: "m2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: common.Bot_BuildReview}, State: common.ReviewStateApproved},
},
},
{
pr: &models.PullRequest{Body: "PR: foo/barPrj#42", Index: 20, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
},
},
},
resLen: 2,
prjGitPRIndex: 0,
consistentSet: true,
reviewed: false,
reviewSetFetcher: func(mock *mock_common.MockGiteaPRTimelineFetcher) (*common.PRSet, error) {
return common.FetchPRSet("test", mock, "foo", "barPrj", 42, &common.AutogitConfig{
Reviewers: []string{"+super1", "*super2", "m1", "-m2"},
Branch: "branch",
Organization: "foo",
GitProjectName: "barPrj",
ManualMergeOnly: true,
ManualMergeProject: true,
})
},
},
{
name: "Manual review is done via PackageGit",
data: []prdata{
{
pr: &models.PullRequest{Body: "PR: foo/repo#20", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: common.Bot_BuildReview}, State: common.ReviewStateApproved},
},
},
{
pr: &models.PullRequest{Body: "PR: foo/barPrj#42", Index: 20, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m1"}, State: common.ReviewStateApproved},
{Body: "Merge ok", User: &models.User{UserName: "super1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
},
},
},
resLen: 2,
prjGitPRIndex: 0,
consistentSet: true,
reviewed: true,
reviewSetFetcher: func(mock *mock_common.MockGiteaPRTimelineFetcher) (*common.PRSet, error) {
return common.FetchPRSet("test", mock, "foo", "barPrj", 42, &common.AutogitConfig{
Reviewers: []string{"+super1", "*super2", "m1", "-m2"},
Branch: "branch",
Organization: "foo",
GitProjectName: "barPrj",
ManualMergeOnly: true,
})
},
},
{
name: "Manual review done via PkgGits",
data: []prdata{
{
pr: &models.PullRequest{Body: "PR: foo/repo#20\nPR: foo/repo#21", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: common.Bot_BuildReview}, State: common.ReviewStateApproved},
},
},
{
pr: &models.PullRequest{Body: "PR: foo/barPrj#42", Index: 20, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m1"}, State: common.ReviewStateApproved},
{Body: "Merge OK!", User: &models.User{UserName: "super1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
},
},
{
pr: &models.PullRequest{Body: "PR: foo/barPrj#42", Index: 21, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m1"}, State: common.ReviewStateApproved},
{Body: "merge ok", User: &models.User{UserName: "super1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
},
},
},
resLen: 3,
prjGitPRIndex: 0,
consistentSet: true,
reviewed: true,
reviewSetFetcher: func(mock *mock_common.MockGiteaPRTimelineFetcher) (*common.PRSet, error) {
return common.FetchPRSet("test", mock, "foo", "barPrj", 42, &common.AutogitConfig{
Reviewers: []string{"+super1", "*super2", "m1", "-m2"},
Branch: "branch",
Organization: "foo",
GitProjectName: "barPrj",
ManualMergeOnly: true,
})
},
},
{
name: "Manual review done via PkgGits not allowed",
data: []prdata{
{
pr: &models.PullRequest{Body: "PR: foo/repo#20\nPR: foo/repo#21", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: common.Bot_BuildReview}, State: common.ReviewStateApproved},
},
},
{
pr: &models.PullRequest{Body: "PR: foo/barPrj#42", Index: 20, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m1"}, State: common.ReviewStateApproved},
{Body: "Merge OK!", User: &models.User{UserName: "super1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
},
},
{
pr: &models.PullRequest{Body: "PR: foo/barPrj#42", Index: 21, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m1"}, State: common.ReviewStateApproved},
{Body: "merge ok", User: &models.User{UserName: "super1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
},
},
},
resLen: 3,
prjGitPRIndex: 0,
consistentSet: true,
reviewed: false,
reviewSetFetcher: func(mock *mock_common.MockGiteaPRTimelineFetcher) (*common.PRSet, error) {
return common.FetchPRSet("test", mock, "foo", "barPrj", 42, &common.AutogitConfig{
Reviewers: []string{"+super1", "*super2", "m1", "-m2"},
Branch: "branch",
Organization: "foo",
GitProjectName: "barPrj",
ManualMergeOnly: true,
ManualMergeProject: true,
})
},
},
{
name: "Manual review is is missing on one PR",
data: []prdata{
{
pr: &models.PullRequest{Body: "PR: foo/repo#20\nPR: foo/repo#21", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: common.Bot_BuildReview}, State: common.ReviewStateApproved},
},
},
{
pr: &models.PullRequest{Body: "PR: foo/barPrj#42", Index: 20, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
},
},
{
pr: &models.PullRequest{Body: "PR: foo/barPrj#42", Index: 21, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super1"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
},
},
},
resLen: 3,
prjGitPRIndex: 0,
consistentSet: true,
reviewed: false,
reviewSetFetcher: func(mock *mock_common.MockGiteaPRTimelineFetcher) (*common.PRSet, error) {
return common.FetchPRSet("test", mock, "foo", "barPrj", 42, &common.AutogitConfig{
Reviewers: []string{"+super1", "*super2", "m1", "-m2"},
Branch: "branch",
Organization: "foo",
GitProjectName: "barPrj",
ManualMergeOnly: true,
})
},
},
{
name: "PR is approved with negative optional review",
data: []prdata{
{
pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, User: &models.User{UserName: "submitter"}, State: "opened"},
reviews: []*models.PullReview{
{Body: "LGTM", User: &models.User{UserName: "m2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "super2"}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: common.Bot_BuildReview}, State: common.ReviewStateApproved},
{Body: "LGTM", User: &models.User{UserName: "bot"}, State: common.ReviewStateRequestChanges},
},
},
},
resLen: 1,
prjGitPRIndex: 0,
consistentSet: true,
reviewed: true,
reviewSetFetcher: func(mock *mock_common.MockGiteaPRTimelineFetcher) (*common.PRSet, error) {
config := common.AutogitConfig{
Reviewers: []string{"+super1", "*super2", "m1", "-m2", "~*bot"},
Branch: "branch",
Organization: "foo",
GitProjectName: "barPrj",
}
return common.FetchPRSet("test", mock, "foo", "barPrj", 42, &config)
},
},
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
ctl := gomock.NewController(t) ctl := gomock.NewController(t)
pr_mock := mock_common.NewMockGiteaPRTimelineFetcher(ctl) pr_mock := mock_common.NewMockGiteaPRFetcher(ctl)
review_mock := mock_common.NewMockGiteaPRChecker(ctl) review_mock := mock_common.NewMockGiteaPRChecker(ctl)
// reviewer_mock := mock_common.NewMockGiteaReviewRequester(ctl) // reviewer_mock := mock_common.NewMockGiteaReviewRequester(ctl)
if test.reviewSetFetcher == nil { // if we are fetching the prjgit directly, the these mocks are not called if test.reviewSetFetcher == nil { // if we are fetching the prjgit directly, the these mocks are not called
if test.prjGitPRIndex >= 0 { if test.prjGitPRIndex >= 0 {
pr_mock.EXPECT().GetPullRequest(baseConfig.Organization, baseConfig.GitProjectName, test.prjGitPRIndex). pr_mock.EXPECT().GetAssociatedPrjGitPR(baseConfig.Organization, baseConfig.GitProjectName, test.data[0].pr.Base.Repo.Owner.UserName, test.data[0].pr.Base.Repo.Name, test.data[0].pr.Index).
Return(test.data[test.prjGitPRIndex].pr, test.data[test.prjGitPRIndex].pr_err) Return(test.data[test.prjGitPRIndex].pr, test.data[test.prjGitPRIndex].pr_err)
} else if test.prjGitPRIndex < 0 { } else if test.prjGitPRIndex < 0 {
// no prjgit PR // no prjgit PR
pr_mock.EXPECT().GetPullRequest(baseConfig.Organization, baseConfig.GitProjectName, gomock.Any()). pr_mock.EXPECT().GetAssociatedPrjGitPR(baseConfig.Organization, baseConfig.GitProjectName, test.data[0].pr.Base.Repo.Owner.UserName, test.data[0].pr.Base.Repo.Name, test.data[0].pr.Index).
Return(nil, nil) Return(nil, nil)
} }
} }
@@ -535,10 +155,6 @@ func TestPR(t *testing.T) {
test_err = data.pr_err test_err = data.pr_err
} }
review_mock.EXPECT().GetPullRequestReviews(data.pr.Base.Repo.Owner.UserName, data.pr.Base.Repo.Name, data.pr.Index).Return(data.reviews, data.review_error).AnyTimes() review_mock.EXPECT().GetPullRequestReviews(data.pr.Base.Repo.Owner.UserName, data.pr.Base.Repo.Name, data.pr.Index).Return(data.reviews, data.review_error).AnyTimes()
if data.timeline == nil {
data.timeline = reviewsToTimeline(data.reviews)
}
review_mock.EXPECT().GetTimeline(data.pr.Base.Repo.Owner.UserName, data.pr.Base.Repo.Name, data.pr.Index).Return(data.timeline, nil).AnyTimes()
} }
var res *common.PRSet var res *common.PRSet
@@ -547,7 +163,7 @@ func TestPR(t *testing.T) {
if test.reviewSetFetcher != nil { if test.reviewSetFetcher != nil {
res, err = test.reviewSetFetcher(pr_mock) res, err = test.reviewSetFetcher(pr_mock)
} else { } else {
res, err = common.FetchPRSet("test", pr_mock, "test", "repo", 42, &baseConfig) res, err = common.FetchPRSet(pr_mock, "test", "repo", 42, &baseConfig)
} }
if err == nil { if err == nil {
@@ -582,7 +198,7 @@ func TestPR(t *testing.T) {
pr_found := false pr_found := false
if test.prjGitPRIndex >= 0 { if test.prjGitPRIndex >= 0 {
for i := range test.data { for i := range test.data {
if PrjGitPR.PR == test.data[i].pr && i == test.prjGitPRIndex { if PrjGitPR == test.data[i].pr && i == test.prjGitPRIndex {
t.Log("found at index", i) t.Log("found at index", i)
pr_found = true pr_found = true
} }
@@ -606,9 +222,7 @@ func TestPR(t *testing.T) {
*/ */
maintainers := mock_common.NewMockMaintainershipData(ctl) maintainers := mock_common.NewMockMaintainershipData(ctl)
maintainers.EXPECT().ListPackageMaintainers(gomock.Any()).Return([]string{}).AnyTimes() maintainers.EXPECT().IsApproved(gomock.Any(), gomock.Any()).Return(true).AnyTimes()
maintainers.EXPECT().ListProjectMaintainers().Return([]string{}).AnyTimes()
maintainers.EXPECT().IsApproved(gomock.Any(), gomock.Any(), gomock.Any()).Return(true).AnyTimes()
if isApproved := res.IsApproved(review_mock, maintainers); isApproved != test.reviewed { if isApproved := res.IsApproved(review_mock, maintainers); isApproved != test.reviewed {
t.Error("expected reviewed to be NOT", isApproved) t.Error("expected reviewed to be NOT", isApproved)
@@ -628,10 +242,8 @@ func TestPRAssignReviewers(t *testing.T) {
reviewer string reviewer string
} }
pkgReviews []*models.PullReview pkgReviews []*models.PullReview
pkgTimeline []*models.TimelineComment prjReviews []*models.PullReview
prjReviews []*models.PullReview
prjTimeline []*models.TimelineComment
expectedReviewerCall [2][]string expectedReviewerCall [2][]string
}{ }{
@@ -719,8 +331,8 @@ func TestPRAssignReviewers(t *testing.T) {
}, },
pkgReviews: []*models.PullReview{ pkgReviews: []*models.PullReview{
{ {
State: common.ReviewStateApproved, State: common.ReviewStateApproved,
User: &models.User{UserName: "user2"}, User: &models.User{UserName: "user2"},
}, },
{ {
State: common.ReviewStatePending, State: common.ReviewStatePending,
@@ -741,59 +353,15 @@ func TestPRAssignReviewers(t *testing.T) {
}, },
expectedReviewerCall: [2][]string{{"user1", "autogits_obs_staging_bot"}, {"pkgmaintainer"}}, expectedReviewerCall: [2][]string{{"user1", "autogits_obs_staging_bot"}, {"pkgmaintainer"}},
}, },
{
name: "Stale optional review is not done, re-request it",
config: common.AutogitConfig{
GitProjectName: "repo",
Organization: "org",
Branch: "main",
Reviewers: []string{"-user1", "user2", "~bot"},
},
pkgReviews: []*models.PullReview{
{
State: common.ReviewStateApproved,
User: &models.User{UserName: "bot"},
Stale: true,
},
{
State: common.ReviewStateApproved,
User: &models.User{UserName: "user2"},
},
{
State: common.ReviewStatePending,
User: &models.User{UserName: "prjmaintainer"},
},
},
prjReviews: []*models.PullReview{
{
State: common.ReviewStateRequestChanges,
User: &models.User{UserName: "user1"},
Stale: true,
},
{
State: common.ReviewStateRequestReview,
Stale: true,
User: &models.User{UserName: "autogits_obs_staging_bot"},
},
},
expectedReviewerCall: [2][]string{{"user1", "autogits_obs_staging_bot"}, {"pkgmaintainer", "bot"}},
},
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
ctl := gomock.NewController(t) ctl := gomock.NewController(t)
pr_mock := mock_common.NewMockGiteaPRTimelineFetcher(ctl) pr_mock := mock_common.NewMockGiteaPRFetcher(ctl)
review_mock := mock_common.NewMockGiteaReviewFetcherAndRequester(ctl) review_mock := mock_common.NewMockGiteaReviewFetcherAndRequester(ctl)
maintainership_mock := mock_common.NewMockMaintainershipData(ctl) maintainership_mock := mock_common.NewMockMaintainershipData(ctl)
if test.pkgTimeline == nil {
test.pkgTimeline = reviewsToTimeline(test.pkgReviews)
}
if test.prjTimeline == nil {
test.prjTimeline = reviewsToTimeline(test.prjReviews)
}
pr_mock.EXPECT().GetPullRequest("other", "pkgrepo", int64(1)).Return(&models.PullRequest{ pr_mock.EXPECT().GetPullRequest("other", "pkgrepo", int64(1)).Return(&models.PullRequest{
Body: "Some description is here", Body: "Some description is here",
User: &models.User{UserName: "submitter"}, User: &models.User{UserName: "submitter"},
@@ -803,8 +371,7 @@ func TestPRAssignReviewers(t *testing.T) {
Index: 1, Index: 1,
}, nil) }, nil)
review_mock.EXPECT().GetPullRequestReviews("other", "pkgrepo", int64(1)).Return(test.pkgReviews, nil) review_mock.EXPECT().GetPullRequestReviews("other", "pkgrepo", int64(1)).Return(test.pkgReviews, nil)
review_mock.EXPECT().GetTimeline("other", "pkgrepo", int64(1)).Return(test.pkgTimeline, nil) pr_mock.EXPECT().GetAssociatedPrjGitPR("org", "repo", "other", "pkgrepo", int64(1)).Return(&models.PullRequest{
pr_mock.EXPECT().GetPullRequest("org", "repo", int64(1)).Return(&models.PullRequest{
Body: fmt.Sprintf(common.PrPattern, "other", "pkgrepo", 1), Body: fmt.Sprintf(common.PrPattern, "other", "pkgrepo", 1),
User: &models.User{UserName: "bot1"}, User: &models.User{UserName: "bot1"},
RequestedReviewers: []*models.User{{UserName: "main_reviewer"}}, RequestedReviewers: []*models.User{{UserName: "main_reviewer"}},
@@ -813,12 +380,11 @@ func TestPRAssignReviewers(t *testing.T) {
Index: 42, Index: 42,
}, nil) }, nil)
review_mock.EXPECT().GetPullRequestReviews("org", "repo", int64(42)).Return(test.prjReviews, nil) review_mock.EXPECT().GetPullRequestReviews("org", "repo", int64(42)).Return(test.prjReviews, nil)
review_mock.EXPECT().GetTimeline("org", "repo", int64(42)).Return(test.prjTimeline, nil)
maintainership_mock.EXPECT().ListProjectMaintainers().Return([]string{"prjmaintainer"}).AnyTimes() maintainership_mock.EXPECT().ListProjectMaintainers().Return([]string{"prjmaintainer"}).AnyTimes()
maintainership_mock.EXPECT().ListPackageMaintainers("pkgrepo").Return([]string{"pkgmaintainer"}).AnyTimes() maintainership_mock.EXPECT().ListPackageMaintainers("pkgrepo").Return([]string{"pkgmaintainer"}).AnyTimes()
prs, _ := common.FetchPRSet("test", pr_mock, "other", "pkgrepo", int64(1), &test.config) prs, _ := common.FetchPRSet(pr_mock, "other", "pkgrepo", int64(1), &test.config)
if len(prs.PRs) != 2 { if len(prs.PRs) != 2 {
t.Fatal("PRs not fetched") t.Fatal("PRs not fetched")
} }
@@ -827,9 +393,8 @@ func TestPRAssignReviewers(t *testing.T) {
if !prs.IsPrjGitPR(pr.PR) { if !prs.IsPrjGitPR(pr.PR) {
r = test.expectedReviewerCall[1] r = test.expectedReviewerCall[1]
} }
slices.Sort(r) if len(r) > 0 {
for _, reviewer := range r { review_mock.EXPECT().RequestReviews(pr.PR, r).Return(nil, nil)
review_mock.EXPECT().RequestReviews(pr.PR, reviewer).Return(nil, nil)
} }
} }
prs.AssignReviewers(review_mock, maintainership_mock) prs.AssignReviewers(review_mock, maintainership_mock)
@@ -863,7 +428,7 @@ func TestPRAssignReviewers(t *testing.T) {
for _, test := range prjgit_tests { for _, test := range prjgit_tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
ctl := gomock.NewController(t) ctl := gomock.NewController(t)
pr_mock := mock_common.NewMockGiteaPRTimelineFetcher(ctl) pr_mock := mock_common.NewMockGiteaPRFetcher(ctl)
review_mock := mock_common.NewMockGiteaReviewFetcherAndRequester(ctl) review_mock := mock_common.NewMockGiteaReviewFetcherAndRequester(ctl)
maintainership_mock := mock_common.NewMockMaintainershipData(ctl) maintainership_mock := mock_common.NewMockMaintainershipData(ctl)
@@ -876,11 +441,10 @@ func TestPRAssignReviewers(t *testing.T) {
Index: 1, Index: 1,
}, nil) }, nil)
review_mock.EXPECT().GetPullRequestReviews("org", "repo", int64(1)).Return(test.prjReviews, nil) review_mock.EXPECT().GetPullRequestReviews("org", "repo", int64(1)).Return(test.prjReviews, nil)
review_mock.EXPECT().GetTimeline("org", "repo", int64(1)).Return(nil, nil)
maintainership_mock.EXPECT().ListProjectMaintainers().Return([]string{"prjmaintainer"}).AnyTimes() maintainership_mock.EXPECT().ListProjectMaintainers().Return([]string{"prjmaintainer"}).AnyTimes()
prs, _ := common.FetchPRSet("test", pr_mock, "org", "repo", int64(1), &test.config) prs, _ := common.FetchPRSet(pr_mock, "org", "repo", int64(1), &test.config)
if len(prs.PRs) != 1 { if len(prs.PRs) != 1 {
t.Fatal("PRs not fetched") t.Fatal("PRs not fetched")
} }
@@ -889,8 +453,8 @@ func TestPRAssignReviewers(t *testing.T) {
if !prs.IsPrjGitPR(pr.PR) { if !prs.IsPrjGitPR(pr.PR) {
t.Fatal("only prjgit pr here") t.Fatal("only prjgit pr here")
} }
for _, reviewer := range r { if len(r) > 0 {
review_mock.EXPECT().RequestReviews(pr.PR, reviewer).Return(nil, nil) review_mock.EXPECT().RequestReviews(pr.PR, r).Return(nil, nil)
} }
} }
prs.AssignReviewers(review_mock, maintainership_mock) prs.AssignReviewers(review_mock, maintainership_mock)
@@ -899,11 +463,9 @@ func TestPRAssignReviewers(t *testing.T) {
} }
func TestPRMerge(t *testing.T) { func TestPRMerge(t *testing.T) {
repoDir := t.TempDir()
cwd, _ := os.Getwd() cwd, _ := os.Getwd()
cmd := exec.Command(path.Join(cwd, "test_repo_setup.sh")) cmd := exec.Command("/usr/bin/bash", path.Join(cwd, "test_repo_setup.sh"))
cmd.Dir = repoDir cmd.Dir = t.TempDir()
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Fatal(string(out)) t.Fatal(string(out))
} }
@@ -942,7 +504,7 @@ func TestPRMerge(t *testing.T) {
Owner: &models.User{ Owner: &models.User{
UserName: "org", UserName: "org",
}, },
SSHURL: "file://" + path.Join(repoDir, "prjgit"), SSHURL: path.Join(cmd.Dir, "prjgit"),
}, },
}, },
Head: &models.PRBranchInfo{ Head: &models.PRBranchInfo{
@@ -952,7 +514,7 @@ func TestPRMerge(t *testing.T) {
mergeError: "Aborting merge", mergeError: "Aborting merge",
}, },
{ {
name: "Merge conflict in modules, auto-resolved", name: "Merge conflict in modules",
pr: &models.PullRequest{ pr: &models.PullRequest{
Base: &models.PRBranchInfo{ Base: &models.PRBranchInfo{
@@ -962,7 +524,7 @@ func TestPRMerge(t *testing.T) {
Owner: &models.User{ Owner: &models.User{
UserName: "org", UserName: "org",
}, },
SSHURL: "file://" + path.Join(cmd.Dir, "prjgit"), SSHURL: path.Join(cmd.Dir, "prjgit"),
}, },
}, },
Head: &models.PRBranchInfo{ Head: &models.PRBranchInfo{
@@ -975,79 +537,19 @@ func TestPRMerge(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
ctl := gomock.NewController(t) ctl := gomock.NewController(t)
mock := mock_common.NewMockGiteaPRTimelineFetcher(ctl) mock := mock_common.NewMockGiteaPRFetcher(ctl)
reviewUnrequestMock := mock_common.NewMockGiteaReviewUnrequester(ctl)
reviewUnrequestMock.EXPECT().UnrequestReview(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
testDir := t.TempDir()
t.Log("dir:", testDir)
mock.EXPECT().GetPullRequest("org", "prj", int64(1)).Return(test.pr, nil) mock.EXPECT().GetPullRequest("org", "prj", int64(1)).Return(test.pr, nil)
set, err := common.FetchPRSet("test", mock, "org", "prj", 1, config) set, err := common.FetchPRSet(mock, "org", "prj", 1, config)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
gh, _ := common.AllocateGitWorkTree(testDir, "", "") gh, _ := common.AllocateGitWorkTree("", "", "")
git, err := gh.CreateGitHandler("org") if err = set.Merge(gh); err != nil && (test.mergeError == "" || (len(test.mergeError) > 0 && !strings.Contains(err.Error(), test.mergeError))) {
err = set.Merge(reviewUnrequestMock, git)
if err != nil && (test.mergeError == "" || (len(test.mergeError) > 0 && !strings.Contains(err.Error(), test.mergeError))) {
os.CopyFS("/tmp/upstream", os.DirFS(repoDir))
os.CopyFS("/tmp/out", os.DirFS(testDir))
t.Fatal(err) t.Fatal(err)
} }
}) })
} }
} }
func TestPRChanges(t *testing.T) {
tests := []struct {
name string
PRs []*models.PullRequest
PrjPRs *models.PullRequest
}{
{
name: "Pkg PR is closed",
PRs: []*models.PullRequest{
{
Base: &models.PRBranchInfo{Repo: &models.Repository{Owner: &models.User{UserName: "org"}, Name: "repo"}},
Index: 42,
State: "merged",
},
},
PrjPRs: &models.PullRequest{
Title: "some PR",
Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "prjgit", Owner: &models.User{UserName: "org"}}},
Body: "PR: org/repo#42",
State: "opened",
},
},
}
config := common.AutogitConfig{
Branch: "main",
GitProjectName: "org/prjgit#branch",
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctl := gomock.NewController(t)
mock_fetcher := mock_common.NewMockGiteaPRTimelineFetcher(ctl)
mock_fetcher.EXPECT().GetPullRequest("org", "prjgit", int64(42)).Return(test.PrjPRs, nil)
for _, pr := range test.PRs {
mock_fetcher.EXPECT().GetPullRequest(pr.Base.Repo.Owner.UserName, pr.Base.Repo.Name, pr.Index).Return(pr, nil)
}
PRs, err := common.FetchPRSet("user", mock_fetcher, "org", "repo", 42, &config)
if err != nil {
t.Fatal(err)
}
if PRs.IsConsistent() {
t.Fatal("Inconsistent set!")
}
})
}
}

View File

@@ -1,238 +0,0 @@
package common
/*
* This file is part of Autogits.
*
* Copyright © 2024 SUSE LLC
*
* Autogits is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 2 of the License, or (at your option) any later
* version.
*
* Autogits is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"crypto/tls"
"fmt"
"net/url"
"strings"
"time"
rabbitmq "github.com/rabbitmq/amqp091-go"
)
type RabbitConnection struct {
RabbitURL *url.URL // amqps://user:password@host/queue
queueName string
ch *rabbitmq.Channel
topics []string
topicSubChanges chan string // +topic = subscribe, -topic = unsubscribe
}
type RabbitProcessor interface {
GenerateTopics() []string
Connection() *RabbitConnection
ProcessRabbitMessage(msg RabbitMessage) error
}
type RabbitMessage rabbitmq.Delivery
func (l *RabbitConnection) ProcessTopicChanges() {
for {
topic, ok := <-l.topicSubChanges
if !ok {
return
}
LogDebug(" topic change:", topic)
switch topic[0] {
case '+':
if err := l.ch.QueueBind(l.queueName, topic[1:], "pubsub", false, nil); err != nil {
LogError(err)
}
case '-':
if err := l.ch.QueueUnbind(l.queueName, topic[1:], "pubsub", nil); err != nil {
LogError(err)
}
default:
LogInfo("Ignoring unknown topic change:", topic)
}
}
}
func (l *RabbitConnection) ProcessRabbitMQ(msgCh chan<- RabbitMessage) error {
queueName := l.RabbitURL.Path
l.RabbitURL.Path = ""
if len(queueName) > 0 && queueName[0] == '/' {
queueName = queueName[1:]
}
connection, err := rabbitmq.DialTLS(l.RabbitURL.String(), &tls.Config{
ServerName: l.RabbitURL.Hostname(),
})
if err != nil {
return fmt.Errorf("Cannot connect to %s . Err: %w", l.RabbitURL.Hostname(), err)
}
defer connection.Close()
l.ch, err = connection.Channel()
if err != nil {
return fmt.Errorf("Cannot create a channel. Err: %w", err)
}
defer l.ch.Close()
if err = l.ch.ExchangeDeclarePassive("pubsub", "topic", true, false, false, false, nil); err != nil {
return fmt.Errorf("Cannot find pubsub exchange? Err: %w", err)
}
var q rabbitmq.Queue
if len(queueName) == 0 {
q, err = l.ch.QueueDeclare("", false, true, true, false, nil)
} else {
q, err = l.ch.QueueDeclarePassive(queueName, true, false, true, false, nil)
if err != nil {
LogInfo("queue not found .. trying to create it:", err)
if l.ch.IsClosed() {
l.ch, err = connection.Channel()
if err != nil {
return fmt.Errorf("Channel cannot be re-opened. Err: %w", err)
}
}
q, err = l.ch.QueueDeclare(queueName, true, false, true, false, nil)
if err != nil {
LogInfo("can't create persistent queue ... falling back to temporaty queue:", err)
if l.ch.IsClosed() {
l.ch, err = connection.Channel()
return fmt.Errorf("Channel cannot be re-opened. Err: %w", err)
}
q, err = l.ch.QueueDeclare("", false, true, true, false, nil)
}
}
}
if err != nil {
return fmt.Errorf("Cannot declare queue. Err: %w", err)
}
// log.Printf("queue: %s:%d", q.Name, q.Consumers)
LogDebug(" -- listening to topics:")
l.topicSubChanges = make(chan string)
defer close(l.topicSubChanges)
go l.ProcessTopicChanges()
for _, topic := range l.topics {
l.topicSubChanges <- "+" + topic
}
msgs, err := l.ch.Consume(q.Name, "", true, true, false, false, nil)
if err != nil {
return fmt.Errorf("Cannot start consumer. Err: %w", err)
}
// log.Printf("queue: %s:%d", q.Name, q.Consumers)
for {
msg, ok := <-msgs
if !ok {
return fmt.Errorf("channel/connection closed?\n")
}
msgCh <- RabbitMessage(msg)
}
}
func (l *RabbitConnection) ConnectAndProcessRabbitMQ(ch chan<- RabbitMessage) {
defer func() {
if r := recover(); r != nil {
LogError(r)
LogError("'crash' RabbitMQ worker. Recovering... reconnecting...")
time.Sleep(5 * time.Second)
go l.ConnectAndProcessRabbitMQ(ch)
}
}()
for {
err := l.ProcessRabbitMQ(ch)
if err != nil {
LogError("Error in RabbitMQ connection. %#v", err)
LogInfo("Reconnecting in 2 seconds...")
time.Sleep(2 * time.Second)
}
}
}
func (l *RabbitConnection) ConnectToRabbitMQ(processor RabbitProcessor) <-chan RabbitMessage {
LogInfo("RabbitMQ connection:", l.RabbitURL.String())
l.RabbitURL.User = url.UserPassword(rabbitUser, rabbitPassword)
l.topics = processor.GenerateTopics()
ch := make(chan RabbitMessage, 100)
go l.ConnectAndProcessRabbitMQ(ch)
return ch
}
func (l *RabbitConnection) UpdateTopics(processor RabbitProcessor) {
newTopics := processor.GenerateTopics()
j := 0
next_new_topic:
for i := 0; i < len(newTopics); i++ {
topic := newTopics[i]
for j < len(l.topics) {
cmp := strings.Compare(topic, l.topics[j])
if cmp == 0 {
j++
continue next_new_topic
}
if cmp < 0 {
l.topicSubChanges <- "+" + topic
break
}
l.topicSubChanges <- "-" + l.topics[j]
j++
}
if j == len(l.topics) {
l.topicSubChanges <- "+" + topic
}
}
for j < len(l.topics) {
l.topicSubChanges <- "-" + l.topics[j]
j++
}
l.topics = newTopics
}
func ProcessRabbitMQEvents(processor RabbitProcessor) error {
ch := processor.Connection().ConnectToRabbitMQ(processor)
for {
msg, ok := <-ch
if !ok {
return nil
}
LogDebug("event:", msg.RoutingKey)
if err := processor.ProcessRabbitMessage(msg); err != nil {
LogError("Error processing", msg.RoutingKey, err)
}
}
}

View File

@@ -1,128 +0,0 @@
package common
/*
* This file is part of Autogits.
*
* Copyright © 2024 SUSE LLC
*
* Autogits is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 2 of the License, or (at your option) any later
* version.
*
* Autogits is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* Foobar. If not, see <https://www.gnu.org/licenses/>.
*/
import (
"fmt"
"runtime/debug"
"slices"
"strings"
)
const RequestType_CreateBrachTag = "create"
const RequestType_DeleteBranchTag = "delete"
const RequestType_Fork = "fork"
const RequestType_Issue = "issues"
const RequestType_IssueAssign = "issue_assign"
const RequestType_IssueComment = "issue_comment"
const RequestType_IssueLabel = "issue_label"
const RequestType_IssueMilestone = "issue_milestone"
const RequestType_Push = "push"
const RequestType_Repository = "repository"
const RequestType_Release = "release"
const RequestType_PR = "pull_request"
const RequestType_PRAssign = "pull_request_assign"
const RequestType_PRLabel = "pull_request_label"
const RequestType_PRComment = "pull_request_comment"
const RequestType_PRMilestone = "pull_request_milestone"
const RequestType_PRSync = "pull_request_sync"
const RequestType_PRReviewAccepted = "pull_request_review_approved"
const RequestType_PRReviewRejected = "pull_request_review_rejected"
const RequestType_PRReviewRequest = "pull_request_review_request"
const RequestType_PRReviewComment = "pull_request_review_comment"
const RequestType_Wiki = "wiki"
type RequestProcessor interface {
ProcessFunc(*Request) error
}
type RabbitMQGiteaEventsProcessor struct {
Handlers map[string]RequestProcessor
Orgs []string
c *RabbitConnection
}
func (gitea *RabbitMQGiteaEventsProcessor) Connection() *RabbitConnection {
if gitea.c == nil {
gitea.c = &RabbitConnection{}
}
return gitea.c
}
func (gitea *RabbitMQGiteaEventsProcessor) GenerateTopics() []string {
topics := make([]string, 0, len(gitea.Handlers)*len(gitea.Orgs))
scope := "suse"
if gitea.c.RabbitURL.Hostname() == "rabbit.opensuse.org" {
scope = "opensuse"
}
for _, org := range gitea.Orgs {
for requestType, _ := range gitea.Handlers {
topics = append(topics, fmt.Sprintf("%s.src.%s.%s.#", scope, org, requestType))
}
}
slices.Sort(topics)
return slices.Compact(topics)
}
func (gitea *RabbitMQGiteaEventsProcessor) ProcessRabbitMessage(msg RabbitMessage) error {
route := strings.Split(msg.RoutingKey, ".")
if len(route) > 3 {
reqType := route[3]
org := route[2]
if !slices.Contains(gitea.Orgs, org) {
LogInfo("Got event for unhandeled org:", org)
return nil
}
LogDebug("org:", org, "type:", reqType)
if handler, found := gitea.Handlers[reqType]; found {
req, err := ParseRequestJSON(reqType, msg.Body)
if err != nil {
LogError("Error parsing request JSON:", err)
return nil
} else {
LogDebug("processing req", req.Type)
// h.Request = req
ProcessEvent(handler, req)
}
}
}
return fmt.Errorf("Invalid routing key: %s", route)
}
func ProcessEvent(f RequestProcessor, request *Request) {
defer func() {
if r := recover(); r != nil {
LogError("panic caught")
if err, ok := r.(error); !ok {
LogError(err)
}
LogError(string(debug.Stack()))
}
}()
if err := f.ProcessFunc(request); err != nil {
LogError(err)
}
}

View File

@@ -1,22 +0,0 @@
package common
type RabbitMQObsBuildStatusProcessor struct {
c *RabbitConnection
}
func (o *RabbitMQObsBuildStatusProcessor) GenerateTopics() []string {
return []string{}
}
func (o *RabbitMQObsBuildStatusProcessor) Connection() *RabbitConnection {
if o.c == nil {
o.c = &RabbitConnection{}
}
return o.c
}
func (o *RabbitMQObsBuildStatusProcessor) ProcessRabbitMessage(msg RabbitMessage) error {
return nil
}

View File

@@ -1,101 +0,0 @@
package common
import (
"net/url"
"slices"
"testing"
)
func TestListenDefinitionsTopicUpdate(t *testing.T) {
tests := []struct {
name string
handlers []string
orgs1, orgs2 []string
topicDelta []string
}{
{
name: "no handlers, no orgs",
},
{
name: "adding one org",
handlers: []string{"foo"},
orgs2: []string{"NewOrg"},
topicDelta: []string{"+suse.src.NewOrg.foo.#"},
},
{
name: "adding two orgs",
handlers: []string{"foo", "bar"},
orgs1: []string{"old"},
orgs2: []string{"old", "NewOrg", "NewOrg2"},
topicDelta: []string{"+suse.src.NewOrg.foo.#", "+suse.src.NewOrg2.foo.#", "+suse.src.NewOrg.bar.#", "+suse.src.NewOrg2.bar.#"},
},
{
name: "adding one org and removing old one",
handlers: []string{"foo", "bar"},
orgs1: []string{"old"},
orgs2: []string{"NewOrg"},
topicDelta: []string{"+suse.src.NewOrg.foo.#", "+suse.src.NewOrg.bar.#", "-suse.src.old.foo.#", "-suse.src.old.bar.#"},
},
{
name: "adding one org and removing old one",
handlers: []string{"foo", "bar"},
orgs1: []string{"NewOrg"},
orgs2: []string{"old"},
topicDelta: []string{"-suse.src.NewOrg.foo.#", "-suse.src.NewOrg.bar.#", "+suse.src.old.foo.#", "+suse.src.old.bar.#"},
},
}
u, _ := url.Parse("amqps://rabbit.example.com")
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
l := &RabbitMQGiteaEventsProcessor{
Orgs: test.orgs1,
Handlers: make(map[string]RequestProcessor),
c: &RabbitConnection{
RabbitURL: u,
topicSubChanges: make(chan string, len(test.topicDelta)*10),
},
}
slices.Sort(test.topicDelta)
for _, r := range test.handlers {
l.Handlers[r] = nil
}
changes := []string{}
l.c.UpdateTopics(l)
a:
for {
select {
case c := <-l.c.topicSubChanges:
changes = append(changes, c)
default:
changes = []string{}
break a
}
}
l.Orgs = test.orgs2
l.c.UpdateTopics(l)
changes = []string{}
b:
for {
select {
case c := <-l.c.topicSubChanges:
changes = append(changes, c)
default:
slices.Sort(changes)
break b
}
}
if !slices.Equal(changes, test.topicDelta) {
t.Error("got:", changes, " expected:", test.topicDelta)
}
})
}
}

View File

@@ -7,33 +7,21 @@ import (
type Reviewers struct { type Reviewers struct {
Prj []string Prj []string
Pkg []string Pkg []string
PrjOptional []string
PkgOptional []string
} }
func ParseReviewers(input []string) *Reviewers { func ParseReviewers(input []string) *Reviewers {
r := &Reviewers{} r := &Reviewers{}
for _, reviewer := range input { for _, reviewer := range input {
pkg := &r.Pkg
prj := &r.Prj
if reviewer[0] == '~' {
pkg = &r.PkgOptional
prj = &r.PrjOptional
reviewer = reviewer[1:]
}
switch reviewer[0] { switch reviewer[0] {
case '*': case '*':
*prj = append(*prj, reviewer[1:]) r.Prj = append(r.Prj, reviewer[1:])
*pkg = append(*pkg, reviewer[1:]) r.Pkg = append(r.Pkg, reviewer[1:])
case '-': case '-':
*prj = append(*prj, reviewer[1:]) r.Prj = append(r.Prj, reviewer[1:])
case '+': case '+':
*pkg = append(*pkg, reviewer[1:]) r.Pkg = append(r.Pkg, reviewer[1:])
default: default:
*pkg = append(*pkg, reviewer) r.Pkg = append(r.Pkg, reviewer)
} }
} }

View File

@@ -12,10 +12,8 @@ func TestReviewers(t *testing.T) {
name string name string
input []string input []string
prj []string prj []string
pkg []string pkg []string
pkg_optional []string
prj_optional []string
}{ }{
{ {
name: "project and package reviewers", name: "project and package reviewers",
@@ -24,15 +22,6 @@ func TestReviewers(t *testing.T) {
prj: []string{"5", "7", common.Bot_BuildReview}, prj: []string{"5", "7", common.Bot_BuildReview},
pkg: []string{"1", "2", "3", "5", "6"}, pkg: []string{"1", "2", "3", "5", "6"},
}, },
{
name: "optional project and package reviewers",
input: []string{"~1", "2", "3", "~*5", "+6", "-7"},
prj: []string{"7", common.Bot_BuildReview},
pkg: []string{"2", "3", "6"},
prj_optional: []string{"5"},
pkg_optional: []string{"1", "5"},
},
} }
for _, test := range tests { for _, test := range tests {
@@ -42,13 +31,7 @@ func TestReviewers(t *testing.T) {
t.Error("unexpected return of ForProject():", reviewers.Prj) t.Error("unexpected return of ForProject():", reviewers.Prj)
} }
if !slices.Equal(reviewers.Pkg, test.pkg) { if !slices.Equal(reviewers.Pkg, test.pkg) {
t.Error("unexpected return of ForPackage():", reviewers.Pkg) t.Error("unexpected return of ForProject():", reviewers.Pkg)
}
if !slices.Equal(reviewers.PrjOptional, test.prj_optional) {
t.Error("unexpected return of ForProjectOptional():", reviewers.Prj)
}
if !slices.Equal(reviewers.PkgOptional, test.pkg_optional) {
t.Error("unexpected return of ForPackageOptional():", reviewers.Pkg)
} }
}) })
} }

View File

@@ -1,9 +1,7 @@
package common package common
import ( import (
"regexp"
"slices" "slices"
"strings"
"src.opensuse.org/autogits/common/gitea-generated/models" "src.opensuse.org/autogits/common/gitea-generated/models"
) )
@@ -11,110 +9,27 @@ import (
type PRReviews struct { type PRReviews struct {
reviews []*models.PullReview reviews []*models.PullReview
reviewers []string reviewers []string
comments []*models.TimelineComment
} }
func FetchGiteaReviews(rf GiteaReviewTimelineFetcher, reviewers []string, org, repo string, no int64) (*PRReviews, error) { func FetchGiteaReviews(rf GiteaReviewFetcher, reviewers []string, org, repo string, no int64) (*PRReviews, error) {
timeline, err := rf.GetTimeline(org, repo, no) reviews, err := rf.GetPullRequestReviews(org, repo, no)
if err != nil { if err != nil {
return nil, err return nil, err
} }
rawReviews, err := rf.GetPullRequestReviews(org, repo, no)
if err != nil {
return nil, err
}
reviews := make([]*models.PullReview, 0, len(reviewers))
var comments []*models.TimelineComment
alreadyHaveUserReview := func(user string) bool {
for _, r := range reviews {
if r.User != nil && r.User.UserName == user {
return true
}
}
return false
}
for idx, item := range timeline {
if item.Type == TimelineCommentType_Review {
for _, r := range rawReviews {
if r.ID == item.ReviewID {
if !alreadyHaveUserReview(r.User.UserName) {
reviews = append(reviews, r)
}
break
}
}
} else if item.Type == TimelineCommentType_Comment {
comments = append(comments, item)
} else if item.Type == TimelineCommentType_PushPull {
LogDebug("cut-off", item.Created)
timeline = timeline[0:idx]
break
} else {
LogDebug("Unhandled timeline type:", item.Type)
}
}
LogDebug("num comments:", len(comments), "reviews:", len(reviews), len(timeline))
return &PRReviews{ return &PRReviews{
reviews: reviews, reviews: reviews,
reviewers: reviewers, reviewers: reviewers,
comments: comments,
}, nil }, nil
} }
const ManualMergeOK = "^merge\\s+ok(\\W|$)"
var merge_ok_regex *regexp.Regexp = regexp.MustCompile(ManualMergeOK)
func bodyCommandManualMergeOK(body string) bool {
lines := SplitLines(body)
for _, line := range lines {
if merge_ok_regex.MatchString(strings.ToLower(line)) {
return true
}
}
return false
}
func (r *PRReviews) IsManualMergeOK() bool {
for _, c := range r.comments {
if c.Updated != c.Created {
continue
}
LogDebug("comment:", c.User.UserName, c.Body)
if slices.Contains(r.reviewers, c.User.UserName) {
if bodyCommandManualMergeOK(c.Body) {
return true
}
}
}
for _, c := range r.reviews {
if c.Updated != c.Submitted {
continue
}
if slices.Contains(r.reviewers, c.User.UserName) {
if bodyCommandManualMergeOK(c.Body) {
return true
}
}
}
return false
}
func (r *PRReviews) IsApproved() bool { func (r *PRReviews) IsApproved() bool {
goodReview := true goodReview := false
for _, reviewer := range r.reviewers { for _, reviewer := range r.reviewers {
goodReview = false goodReview = false
for _, review := range r.reviews { for _, review := range r.reviews {
if review.User.UserName == reviewer && review.State == ReviewStateApproved && !review.Stale && !review.Dismissed { if review.User.UserName == reviewer && review.State == ReviewStateApproved && !review.Stale && !review.Dismissed {
LogDebug(" -- found review: ", review.User.UserName)
goodReview = true goodReview = true
break break
} }

View File

@@ -14,7 +14,6 @@ func TestReviews(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
reviews []*models.PullReview reviews []*models.PullReview
timeline []*models.TimelineComment
reviewers []string reviewers []string
fetchErr error fetchErr error
isApproved bool isApproved bool
@@ -22,21 +21,21 @@ func TestReviews(t *testing.T) {
isPendingByTest1 bool isPendingByTest1 bool
}{ }{
{ {
name: "Reviews of PR with no review requirements", name: "Reviews of unreviews PR",
isApproved: true, isApproved: false,
}, },
{ {
name: "Single reviewer done", name: "Single reviewer done",
reviews: []*models.PullReview{&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}}, reviews: []*models.PullReview{&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}},
reviewers: []string{"user1"}, reviewers: []string{"user1"},
isApproved: true, isApproved: true,
isReviewedByTest1: true, isReviewedByTest1: true,
}, },
{ {
name: "Two reviewer, one not approved", name: "Two reviewer, one not approved",
reviews: []*models.PullReview{&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}}, reviews: []*models.PullReview{&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}},
reviewers: []string{"user1", "user2"}, reviewers: []string{"user1", "user2"},
isApproved: false, isApproved: false,
isReviewedByTest1: true, isReviewedByTest1: true,
}, },
{ {
@@ -45,8 +44,8 @@ func TestReviews(t *testing.T) {
&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}},
&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}, Stale: true}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}, Stale: true},
}, },
reviewers: []string{"user1", "user2"}, reviewers: []string{"user1", "user2"},
isApproved: false, isApproved: false,
isReviewedByTest1: true, isReviewedByTest1: true,
}, },
{ {
@@ -55,8 +54,8 @@ func TestReviews(t *testing.T) {
&models.PullReview{State: common.ReviewStateRequestReview, User: &models.User{UserName: "user1"}}, &models.PullReview{State: common.ReviewStateRequestReview, User: &models.User{UserName: "user1"}},
&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}},
}, },
reviewers: []string{"user1", "user2"}, reviewers: []string{"user1", "user2"},
isApproved: false, isApproved: false,
isPendingByTest1: true, isPendingByTest1: true,
}, },
{ {
@@ -64,9 +63,9 @@ func TestReviews(t *testing.T) {
reviews: []*models.PullReview{ reviews: []*models.PullReview{
&models.PullReview{State: common.ReviewStateRequestReview, User: &models.User{UserName: "user1"}, Stale: true}, &models.PullReview{State: common.ReviewStateRequestReview, User: &models.User{UserName: "user1"}, Stale: true},
}, },
reviewers: []string{"user1", "user2"}, reviewers: []string{"user1", "user2"},
isApproved: false, isApproved: false,
isPendingByTest1: false, isPendingByTest1: false,
isReviewedByTest1: false, isReviewedByTest1: false,
}, },
{ {
@@ -75,8 +74,8 @@ func TestReviews(t *testing.T) {
&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}},
&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}},
}, },
reviewers: []string{"user1", "user2"}, reviewers: []string{"user1", "user2"},
isApproved: true, isApproved: true,
isReviewedByTest1: true, isReviewedByTest1: true,
}, },
{ {
@@ -85,8 +84,8 @@ func TestReviews(t *testing.T) {
&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}},
&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}, Dismissed: true}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}, Dismissed: true},
}, },
reviewers: []string{"user1", "user2"}, reviewers: []string{"user1", "user2"},
isApproved: false, isApproved: false,
isReviewedByTest1: true, isReviewedByTest1: true,
}, },
{ {
@@ -95,9 +94,9 @@ func TestReviews(t *testing.T) {
&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}},
&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}},
}, },
reviewers: []string{"user1", "user2"}, reviewers: []string{"user1", "user2"},
fetchErr: errors.New("System error fetching reviews."), fetchErr: errors.New("System error fetching reviews."),
isApproved: true, isApproved: true,
isReviewedByTest1: true, isReviewedByTest1: true,
}, },
{ {
@@ -107,23 +106,8 @@ func TestReviews(t *testing.T) {
&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user4"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user4"}},
&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}}, &models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}},
}, },
reviewers: []string{"user1", "user2"}, reviewers: []string{"user1", "user2"},
isApproved: true, isApproved: true,
isReviewedByTest1: true,
},
{
name: "Review ignored before push",
reviews: []*models.PullReview{
&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user1"}, ID: 1001},
&models.PullReview{State: common.ReviewStateApproved, User: &models.User{UserName: "user2"}, ID: 1000},
},
timeline: []*models.TimelineComment{
&models.TimelineComment{Type: common.TimelineCommentType_Review, ReviewID: 1001},
&models.TimelineComment{Type: common.TimelineCommentType_PushPull},
&models.TimelineComment{Type: common.TimelineCommentType_Review, ReviewID: 1000},
},
reviewers: []string{"user1", "user2"},
isApproved: false,
isReviewedByTest1: true, isReviewedByTest1: true,
}, },
} }
@@ -131,12 +115,8 @@ func TestReviews(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
ctl := gomock.NewController(t) ctl := gomock.NewController(t)
rf := mock_common.NewMockGiteaReviewTimelineFetcher(ctl) rf := mock_common.NewMockGiteaReviewFetcher(ctl)
if test.timeline == nil {
test.timeline = reviewsToTimeline(test.reviews)
}
rf.EXPECT().GetTimeline("test", "pr", int64(1)).Return(test.timeline, nil)
rf.EXPECT().GetPullRequestReviews("test", "pr", int64(1)).Return(test.reviews, test.fetchErr) rf.EXPECT().GetPullRequestReviews("test", "pr", int64(1)).Return(test.reviews, test.fetchErr)
reviews, err := common.FetchGiteaReviews(rf, test.reviewers, "test", "pr", 1) reviews, err := common.FetchGiteaReviews(rf, test.reviewers, "test", "pr", 1)

View File

@@ -113,10 +113,6 @@ func (s *Submodule) parseKeyValue(line string) error {
return nil return nil
} }
func (s *Submodule) ManifestSubmodulePath(manifest *Manifest) string {
return manifest.SubdirForPackage(s.Path)
}
func ParseSubmodulesFile(reader io.Reader) ([]Submodule, error) { func ParseSubmodulesFile(reader io.Reader) ([]Submodule, error) {
data, err := io.ReadAll(reader) data, err := io.ReadAll(reader)
if err != nil { if err != nil {

View File

@@ -1,63 +0,0 @@
package common
import (
"encoding/json"
"slices"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
const (
TimelineCommentType_ReviewRequested = "review_request"
TimelineCommentType_Review = "review"
TimelineCommentType_PushPull = "pull_push"
TimelineCommentType_PullRequestRef = "pull_ref"
TimelineCommentType_DismissReview = "dismiss_review"
TimelineCommentType_Comment = "comment"
)
func FetchTimelineSinceLastPush(gitea GiteaTimelineFetcher, headSha, org, repo string, id int64) ([]*models.TimelineComment, error) {
timeline, err := gitea.GetTimeline(org, repo, id)
if err != nil {
return nil, err
}
//{"is_force_push":true,"commit_ids":["36e43509be1b13a1a8fc63a4361405de04cc621ab16935f88968c46193221bb6","732246a48fbc6bac9df16c0b0ca23ce0f6fbabd9990795863b6d1f0ef3f242c8"]}
type PullPushData struct {
IsForcePush bool `json:"is_force_push"`
CommitIds []string `json:"commit_ids"`
}
// trim timeline to last push update or last time review request was requested
for i, e := range timeline {
if e.Type == TimelineCommentType_PushPull {
var push PullPushData
if err := json.Unmarshal([]byte(e.Body), &push); err != nil {
LogError(err)
}
if slices.Contains(push.CommitIds, headSha) {
return timeline[0:i], nil
}
}
}
return timeline, nil
}
func FetchTimelineSinceReviewRequestOrPush(gitea GiteaTimelineFetcher, groupName, headSha, org, repo string, id int64) ([]*models.TimelineComment, error) {
timeline, err := FetchTimelineSinceLastPush(gitea, headSha, org, repo, id)
if err != nil {
return nil, err
}
// trim timeline to last push update or last time review request was requested
for i, e := range timeline {
if e.Type == TimelineCommentType_ReviewRequested && e.Assignee != nil && e.Assignee.UserName == groupName {
// review request is cut-off for reviews too
return timeline[0:i], nil
}
}
return timeline, nil
}

View File

@@ -19,16 +19,11 @@ package common
*/ */
import ( import (
"bufio"
"errors"
"fmt" "fmt"
"net/http"
"net/url" "net/url"
"regexp" "regexp"
"slices" "slices"
"strings" "strings"
"src.opensuse.org/autogits/common/gitea-generated/models"
) )
func SplitLines(str string) []string { func SplitLines(str string) []string {
@@ -89,11 +84,6 @@ var valid_schemas []string = []string{"https", "ssh", "http", "file"}
func ParseGitRemoteUrl(urlString string) (*GitUrl, error) { func ParseGitRemoteUrl(urlString string) (*GitUrl, error) {
url, err := url.Parse(urlString) url, err := url.Parse(urlString)
if url != nil && url.Scheme == "file" && err == nil {
return nil, nil
}
if err != nil || !slices.Contains(valid_schemas, url.Scheme) { if err != nil || !slices.Contains(valid_schemas, url.Scheme) {
u, err := TranslateSshNativeToUrl(urlString) u, err := TranslateSshNativeToUrl(urlString)
if err != nil { if err != nil {
@@ -108,7 +98,10 @@ func ParseGitRemoteUrl(urlString string) (*GitUrl, error) {
} }
org := e[0] org := e[0]
repo := strings.TrimSuffix(e[1], ".git") repo := e[1]
if len(repo) > 4 && repo[len(repo)-4:] == ".git" {
repo = repo[0 : len(repo)-4]
}
u := GitUrl{ u := GitUrl{
Org: org, Org: org,
@@ -126,51 +119,3 @@ func (giturl *GitUrl) RemoteName() string {
return strings.ToLower(giturl.Org) + "_" + strings.ToLower(giturl.Repo) return strings.ToLower(giturl.Org) + "_" + strings.ToLower(giturl.Repo)
} }
func PRtoString(pr *models.PullRequest) string {
if pr == nil {
return "(null)"
}
return fmt.Sprintf("%s/%s#%d", pr.Base.Repo.Owner.UserName, pr.Base.Repo.Name, pr.Index)
}
type DevelProject struct {
Project, Package string
}
type DevelProjects []*DevelProject
func FetchDevelProjects() (DevelProjects, error) {
res, err := http.Get("https://src.opensuse.org/openSUSE/Factory/raw/branch/main/pkgs/_meta/devel_packages")
if err != nil {
return nil, err
}
defer res.Body.Close()
scanner := bufio.NewScanner(res.Body)
ret := []*DevelProject{}
for scanner.Scan() {
d := SplitStringNoEmpty(scanner.Text(), " ")
if len(d) == 2 {
ret = append(ret, &DevelProject{
Project: d[1],
Package: d[0],
})
}
}
return ret, nil
}
var DevelProjectNotFound = errors.New("Devel project not found")
func (d DevelProjects) GetDevelProject(pkg string) (string, error) {
for _, item := range d {
if item.Package == pkg {
return item.Project, nil
}
}
return "", DevelProjectNotFound
}

View File

@@ -73,10 +73,6 @@ func runObsCommand(args ...string) ([]string, error) {
var DebugMode bool var DebugMode bool
func giteaPackage(pkg string) string {
return strings.ReplaceAll(pkg, "+", "_")
}
func projectMaintainer(obs *common.ObsClient, prj string) ([]string, []string) { // users, groups func projectMaintainer(obs *common.ObsClient, prj string) ([]string, []string) { // users, groups
meta, err := obs.GetProjectMeta(prj) meta, err := obs.GetProjectMeta(prj)
if err != nil { if err != nil {
@@ -172,14 +168,13 @@ func gitImporter(prj, pkg string) error {
func cloneDevel(git common.Git, gitDir, outName, urlString string) error { func cloneDevel(git common.Git, gitDir, outName, urlString string) error {
url, err := url.Parse(urlString) url, err := url.Parse(urlString)
// branch := url.Fragment branch := url.Fragment
url.Fragment = "" url.Fragment = ""
params := []string{"clone"} params := []string{"clone"}
/* if len(branch) > 0 { if len(branch) > 0 {
params = append(params, "-b", branch) params = append(params, "-b", branch)
} }
*/
params = append(params, url.String(), outName) params = append(params, url.String(), outName)
if err != nil { if err != nil {
@@ -190,16 +185,13 @@ func cloneDevel(git common.Git, gitDir, outName, urlString string) error {
} }
func importRepos(packages []string) { func importRepos(packages []string) {
RepoToObsName := make(map[string]string)
factoryRepos := make([]*models.Repository, 0, len(packages)*2) factoryRepos := make([]*models.Repository, 0, len(packages)*2)
develProjectPackages := make([]string, 0, len(packages)) develProjectPackages := make([]string, 0, len(packages))
for _, pkg := range packages { for _, pkg := range packages {
src_pkg_name := strings.Split(pkg, ":") src_pkg_name := strings.Split(pkg, ":")
RepoToObsName[giteaPackage(src_pkg_name[0])] = src_pkg_name[0]
repo, err := client.Repository.RepoGet( repo, err := client.Repository.RepoGet(
repository.NewRepoGetParams(). repository.NewRepoGetParams().
WithDefaults().WithOwner("pool").WithRepo(giteaPackage(src_pkg_name[0])), WithDefaults().WithOwner("pool").WithRepo(src_pkg_name[0]),
r.DefaultAuthentication) r.DefaultAuthentication)
if err != nil { if err != nil {
@@ -214,19 +206,10 @@ func importRepos(packages []string) {
} }
} }
log.Println("Num repos found:", len(factoryRepos)) log.Println("Num repos found:", len(factoryRepos))
if len(develProjectPackages) > 0 {
log.Println("Num of repos that need to create:", len(develProjectPackages))
log.Println("Create the following packages in pool to continue:", strings.Join(develProjectPackages, " "))
if forceNonPoolPackages {
log.Println(" IGNORING and will create these as non-pool packages!")
} else {
os.Exit(1)
}
}
oldPackageNames := make([]string, 0, len(factoryRepos)) oldPackageNames := make([]string, 0, len(factoryRepos))
for _, repo := range factoryRepos { for _, repo := range factoryRepos {
oldPackageNames = append(oldPackageNames, RepoToObsName[repo.Name]) oldPackageNames = append(oldPackageNames, repo.Name)
} }
// fork packags from pool // fork packags from pool
@@ -248,60 +231,48 @@ func importRepos(packages []string) {
log.Println("adding remotes...") log.Println("adding remotes...")
for i := 0; i < len(factoryRepos); i++ { for i := 0; i < len(factoryRepos); i++ {
pkg := factoryRepos[i] pkg := factoryRepos[i]
pkgName := RepoToObsName[pkg.Name]
gitName := pkg.Name
// verify that package was created by `git-importer`, or it's scmsync package and clone it // verify that package was created by `git-importer`, or it's scmsync package and clone it
fi, err := os.Stat(filepath.Join(git.GetPath(), gitName)) fi, err := os.Stat(filepath.Join(git.GetPath(), pkg.Name))
if os.IsNotExist(err) { if os.IsNotExist(err) {
if slices.Contains(develProjectPackages, pkgName) { if slices.Contains(develProjectPackages, pkg.Name) {
// failed import of former factory package // failed import of former factory package
log.Println("Failed to import former factory pkg:", pkgName)
continue continue
} }
// scmsync? // scmsync?
devel_project, err := devel_projects.GetDevelProject(pkgName) devel_project, err := runObsCommand("develproject", "openSUSE:Factory", pkg.Name)
if err != nil { if err != nil || len(devel_project) != 1 {
log.Panicln("devel project not found for", RepoToObsName[pkg.Name], "err:", err) log.Panicln("devel project len:", len(devel_project), "for", pkg.Name, "err:", err)
} }
meta, _ := obs.GetPackageMeta(devel_project, pkgName) d := strings.Split(devel_project[0], "/")
if len(d) != 2 {
log.Panicln("expected devel project/package. got:", d)
}
meta, _ := obs.GetPackageMeta(d[0], d[1])
if len(meta.ScmSync) > 0 { if len(meta.ScmSync) > 0 {
if err2 := cloneDevel(git, "", gitName, meta.ScmSync); err != nil { if err2 := cloneDevel(git, "", pkg.Name, meta.ScmSync); err != nil {
log.Panicln(err2) log.Panicln(err2)
} }
if err2 := git.GitExec(gitName, "checkout", "-B", "main"); err2 != nil { git.GitExecOrPanic(pkg.Name, "checkout", "-B", "main")
git.GitExecOrPanic(gitName, "checkout", "-B", "master")
}
continue continue
} }
// try again, should now exist // try again, should now exist
if fi, err = os.Stat(filepath.Join(git.GetPath(), gitName)); err != nil { if fi, err = os.Stat(filepath.Join(git.GetPath(), pkg.Name)); err != nil {
log.Panicln(err) log.Panicln(err)
} }
} else if err != nil { } else if err != nil {
log.Panicln(err) log.Panicln(err)
} else { } else {
// verify that we do not have scmsync for imported packages // verify that we do not have scmsync for imported packages
meta, err := obs.GetPackageMeta(prj, pkgName) meta, err := obs.GetPackageMeta(prj, pkg.Name)
if err != nil { if err != nil {
log.Panicln(err) log.Panicln(err)
} }
if len(meta.ScmSync) > 0 { if len(meta.ScmSync) > 0 {
u, err := url.Parse(meta.ScmSync) log.Panicln("importing an scmsync package??:", prj, pkg.Name)
if err != nil {
log.Println("Invlid scmsync in", pkg, meta.ScmSync, err)
}
o, err := url.Parse(strings.TrimSpace(git.GitExecWithOutputOrPanic(gitName, "remote", "get-url", "origin")))
log.Println("Invlid scmsync in git repo", pkg, meta.ScmSync, err)
if u.Host != o.Host || u.Path != u.Path {
log.Panicln("importing an scmsync package??:", prj, gitName)
} else {
log.Println("previous SCMSYNC package. Pull.")
git.GitExecOrPanic(gitName, "pull", "origin", "HEAD:main")
}
} }
} }
@@ -310,11 +281,11 @@ func importRepos(packages []string) {
} }
// add remote repos // add remote repos
out := git.GitExecWithOutputOrPanic(gitName, "remote", "show", "-n") out := git.GitExecWithOutputOrPanic(pkg.Name, "remote", "show", "-n")
switch pkg.Owner.UserName { switch pkg.Owner.UserName {
case "pool": case "pool":
if !slices.Contains(strings.Split(out, "\n"), "pool") { if !slices.Contains(strings.Split(out, "\n"), "pool") {
out := git.GitExecWithOutputOrPanic(gitName, "remote", "add", "pool", pkg.CloneURL) out := git.GitExecWithOutputOrPanic(pkg.Name, "remote", "add", "pool", pkg.CloneURL)
if len(strings.TrimSpace(out)) > 1 { if len(strings.TrimSpace(out)) > 1 {
log.Println(out) log.Println(out)
} }
@@ -324,8 +295,7 @@ func importRepos(packages []string) {
} }
} }
for idx := 0; idx < len(oldPackageNames); idx++ { for _, pkgName := range oldPackageNames {
pkgName := oldPackageNames[idx]
log.Println("fetching git:", pkgName) log.Println("fetching git:", pkgName)
remotes := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(pkgName, "remote", "show", "-n"), "\n") remotes := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(pkgName, "remote", "show", "-n"), "\n")
@@ -356,10 +326,10 @@ func importRepos(packages []string) {
if forceBadPool { if forceBadPool {
log.Println(" *** factory has no branches!!! Treating as a devel package.") log.Println(" *** factory has no branches!!! Treating as a devel package.")
develProjectPackages = append(develProjectPackages, pkgName) develProjectPackages = append(develProjectPackages, pkgName)
continue break
} else { } else {
log.Panicln(" *** factory has no branches", branches) log.Panicln(" *** factory has no branches", branches)
} }
} }
pool_branch := "factory" pool_branch := "factory"
@@ -414,34 +384,20 @@ func importRepos(packages []string) {
if !found { if !found {
log.Println("*** WARNING: Cannot find same tree for pkg", pkgName, "Will use current import instead") log.Println("*** WARNING: Cannot find same tree for pkg", pkgName, "Will use current import instead")
git.GitExecOrPanic(pkgName, "checkout", "-B", "main", "heads/"+import_branch) git.GitExecOrPanic(pkgName, "checkout", "-B", "main", "heads/"+import_branch)
log.Println("setting main to", "heads/"+import_branch)
} }
} else { } else {
log.Println("setting main to", "heads/"+import_branch)
git.GitExecOrPanic(pkgName, "checkout", "-B", "main", "heads/"+import_branch) git.GitExecOrPanic(pkgName, "checkout", "-B", "main", "heads/"+import_branch)
} }
} }
for i := 0; i < len(develProjectPackages); i++ { for i := 0; i < len(develProjectPackages); i++ {
pkg := develProjectPackages[i] pkg := develProjectPackages[i]
log.Println("setting main branch for devel package:", pkg) meta, _ := obs.GetPackageMeta(prj, pkg)
meta, err := obs.GetPackageMeta(prj, pkg) if len(meta.ScmSync) > 0 {
if err != nil { if err2 := cloneDevel(git, "", pkg, meta.ScmSync); err2 != nil {
meta, err = obs.GetPackageMeta(prj, pkg) log.Panicln(err2)
if err != nil {
log.Println("Error fetching pkg meta for:", prj, pkg, err)
} }
} git.GitExecOrPanic(pkg, "checkout", "-B", "main")
if meta == nil {
log.Println(" **** pkg meta is nil? ****")
} else if len(meta.ScmSync) > 0 {
if _, err := os.Stat(path.Join(git.GetPath(), pkg)); os.IsNotExist(err) {
if err2 := cloneDevel(git, "", pkg, meta.ScmSync); err2 != nil {
log.Panicln(err2)
}
git.GitExecOrPanic(pkg, "checkout", "-B", "main")
}
log.Println("skip for scmsync")
continue continue
} else { } else {
common.PanicOnError(gitImporter(prj, pkg)) common.PanicOnError(gitImporter(prj, pkg))
@@ -459,7 +415,6 @@ func importRepos(packages []string) {
log.Println(" *** pool branch 'devel' ahead. Switching branches.") log.Println(" *** pool branch 'devel' ahead. Switching branches.")
branch = "devel" branch = "devel"
} }
log.Println("setting main to", branch)
git.GitExecOrPanic(pkg, "checkout", "-B", "main", branch) git.GitExecOrPanic(pkg, "checkout", "-B", "main", branch)
} }
@@ -482,7 +437,6 @@ func importRepos(packages []string) {
}) })
for _, pkg := range factoryRepos { for _, pkg := range factoryRepos {
log.Println("factory fork creator for develProjectPackage:", pkg.Name)
var repo *models.Repository var repo *models.Repository
if repoData, err := client.Repository.RepoGet(repository.NewRepoGetParams().WithOwner(org).WithRepo(pkg.Name), r.DefaultAuthentication); err != nil { if repoData, err := client.Repository.RepoGet(repository.NewRepoGetParams().WithOwner(org).WithRepo(pkg.Name), r.DefaultAuthentication); err != nil {
// update package // update package
@@ -505,24 +459,16 @@ func importRepos(packages []string) {
remotes := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(pkg.Name, "remote", "show"), "\n") remotes := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(pkg.Name, "remote", "show"), "\n")
if !slices.Contains(remotes, "develorigin") { if !slices.Contains(remotes, "develorigin") {
git.GitExecOrPanic(pkg.Name, "remote", "add", "develorigin", repo.SSHURL) git.GitExecOrPanic(pkg.Name, "remote", "add", "develorigin", repo.SSHURL)
// git.GitExecOrPanic(pkgName, "fetch", "devel") // git.GitExecOrPanic(pkg.Name, "fetch", "devel")
} }
if slices.Contains(remotes, "origin") { if slices.Contains(remotes, "origin") {
git.GitExecOrPanic(pkg.Name, "lfs", "fetch", "--all") git.GitExecOrPanic(pkg.Name, "lfs", "fetch", "--all")
git.GitExecOrPanic(pkg.Name, "lfs", "push", "develorigin", "--all") git.GitExecOrPanic(pkg.Name, "lfs", "push", "develorigin", "--all")
} }
git.GitExecOrPanic(pkg.Name, "push", "develorigin", "main", "-f") git.GitExecOrPanic(pkg.Name, "push", "develorigin", "main", "-f")
branches := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(pkg.Name, "branch", "-r"), "\n") git.GitExec(pkg.Name, "push", "develorigin", "--delete", "factory", "devel")
for _, b := range branches { // git.GitExecOrPanic(pkg.Name, "checkout", "-B", "main", "devel/main")
if len(b) > 12 && b[0:12] == "develorigin/" { _, err := client.Repository.RepoEdit(repository.NewRepoEditParams().WithOwner(org).WithRepo(repo.Name).WithBody(&models.EditRepoOption{
b = b[12:]
if b == "factory" || b == "devel" {
git.GitExec(pkg.Name, "push", "develorigin", "--delete", b)
}
}
}
// git.GitExecOrPanic(pkg.ame, "checkout", "-B", "main", "devel/main")
_, err := client.Repository.RepoEdit(repository.NewRepoEditParams().WithOwner(org).WithRepo(giteaPackage(repo.Name)).WithBody(&models.EditRepoOption{
DefaultBranch: "main", DefaultBranch: "main",
DefaultMergeStyle: "fast-forward-only", DefaultMergeStyle: "fast-forward-only",
HasPullRequests: true, HasPullRequests: true,
@@ -546,15 +492,13 @@ func importRepos(packages []string) {
} }
for _, pkg := range develProjectPackages { for _, pkg := range develProjectPackages {
log.Println("repo creator for develProjectPackage:", pkg)
var repo *models.Repository var repo *models.Repository
if repoData, err := client.Repository.RepoGet(repository.NewRepoGetParams().WithOwner(org).WithRepo(giteaPackage(pkg)), r.DefaultAuthentication); err != nil { if repoData, err := client.Repository.RepoGet(repository.NewRepoGetParams().WithOwner(org).WithRepo(pkg), r.DefaultAuthentication); err != nil {
giteaPkg := giteaPackage(pkg)
_, err := client.Organization.CreateOrgRepo(organization.NewCreateOrgRepoParams().WithOrg(org).WithBody( _, err := client.Organization.CreateOrgRepo(organization.NewCreateOrgRepoParams().WithOrg(org).WithBody(
&models.CreateRepoOption{ &models.CreateRepoOption{
ObjectFormatName: "sha256", ObjectFormatName: "sha256",
AutoInit: false, AutoInit: false,
Name: &giteaPkg, Name: &pkg,
DefaultBranch: "main", DefaultBranch: "main",
}), }),
r.DefaultAuthentication, r.DefaultAuthentication,
@@ -564,7 +508,7 @@ func importRepos(packages []string) {
log.Panicln("Error creating new package repository:", pkg, err) log.Panicln("Error creating new package repository:", pkg, err)
} }
ret, err := client.Repository.RepoEdit(repository.NewRepoEditParams().WithOwner(org).WithRepo(giteaPkg).WithBody( ret, err := client.Repository.RepoEdit(repository.NewRepoEditParams().WithOwner(org).WithRepo(pkg).WithBody(
&models.EditRepoOption{ &models.EditRepoOption{
HasPullRequests: true, HasPullRequests: true,
HasPackages: false, HasPackages: false,
@@ -602,17 +546,9 @@ func importRepos(packages []string) {
git.GitExecOrPanic(pkg, "lfs", "push", "develorigin", "--all") git.GitExecOrPanic(pkg, "lfs", "push", "develorigin", "--all")
} }
git.GitExecOrPanic(pkg, "push", "develorigin", "main", "-f") git.GitExecOrPanic(pkg, "push", "develorigin", "main", "-f")
branches := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(pkg, "branch", "-r"), "\n") git.GitExec(pkg, "push", "develorigin", "--delete", "factory", "devel")
for _, b := range branches {
if len(b) > 12 && b[0:12] == "develorigin/" {
b = b[12:]
if b == "factory" || b == "devel" {
git.GitExec(pkg, "push", "develorigin", "--delete", b)
}
}
}
_, err := client.Repository.RepoEdit(repository.NewRepoEditParams().WithOwner(org).WithRepo(giteaPackage(pkg)).WithBody(&models.EditRepoOption{ _, err := client.Repository.RepoEdit(repository.NewRepoEditParams().WithOwner(org).WithRepo(pkg).WithBody(&models.EditRepoOption{
DefaultBranch: "main", DefaultBranch: "main",
DefaultMergeStyle: "fast-forward-only", DefaultMergeStyle: "fast-forward-only",
}), r.DefaultAuthentication) }), r.DefaultAuthentication)
@@ -711,7 +647,7 @@ func syncPackageCollaborators(pkg string, orig_uids []common.PersonRepoMeta) []s
missing := []string{} missing := []string{}
uids := make([]common.PersonRepoMeta, len(orig_uids)) uids := make([]common.PersonRepoMeta, len(orig_uids))
copy(uids, orig_uids) copy(uids, orig_uids)
collab, err := client.Repository.RepoListCollaborators(repository.NewRepoListCollaboratorsParams().WithOwner(org).WithRepo(giteaPackage(pkg)), r.DefaultAuthentication) collab, err := client.Repository.RepoListCollaborators(repository.NewRepoListCollaboratorsParams().WithOwner(org).WithRepo(pkg), r.DefaultAuthentication)
if err != nil { if err != nil {
if errors.Is(err, &repository.RepoListCollaboratorsNotFound{}) { if errors.Is(err, &repository.RepoListCollaboratorsNotFound{}) {
return missing return missing
@@ -732,7 +668,7 @@ func syncPackageCollaborators(pkg string, orig_uids []common.PersonRepoMeta) []s
log.Println("missing collabs for", pkg, ":", uids) log.Println("missing collabs for", pkg, ":", uids)
} }
for _, u := range uids { for _, u := range uids {
_, err := client.Repository.RepoAddCollaborator(repository.NewRepoAddCollaboratorParams().WithOwner(org).WithRepo(giteaPackage(pkg)).WithBody(&models.AddCollaboratorOption{ _, err := client.Repository.RepoAddCollaborator(repository.NewRepoAddCollaboratorParams().WithOwner(org).WithRepo(pkg).WithBody(&models.AddCollaboratorOption{
Permission: "write", Permission: "write",
}).WithCollaborator(u.UserID), r.DefaultAuthentication) }).WithCollaborator(u.UserID), r.DefaultAuthentication)
@@ -764,10 +700,6 @@ func syncMaintainersToGitea(pkgs []string) {
devs := []string{} devs := []string{}
for _, group := range prjMeta.Groups { for _, group := range prjMeta.Groups {
if group.GroupID == "factory-maintainers" {
log.Println("Ignoring factory-maintainers")
continue
}
teamMembers, err := obs.GetGroupMeta(group.GroupID) teamMembers, err := obs.GetGroupMeta(group.GroupID)
if err != nil { if err != nil {
log.Panicln("failed to get group", err) log.Panicln("failed to get group", err)
@@ -863,20 +795,13 @@ func createPrjGit() {
git.GitExecOrPanic(common.DefaultGitPrj, "add", "_config") git.GitExecOrPanic(common.DefaultGitPrj, "add", "_config")
} }
file, err = os.Create(path.Join(git.GetPath(), common.DefaultGitPrj, "staging.config")) file, err = os.Create(path.Join(git.GetPath(), common.DefaultGitPrj, "project.build"))
if err != nil { if err != nil {
log.Panicln(err) log.Panicln(err)
} }
file.WriteString("{\n // Reference build project\n \"ObsProject\": \"" + prj + "\",\n}\n") file.Write([]byte(prj))
file.Close() file.Close()
git.GitExecOrPanic(common.DefaultGitPrj, "add", "staging.config") git.GitExecOrPanic(common.DefaultGitPrj, "add", "project.build")
if file, err = os.Create(path.Join(git.GetPath(), common.DefaultGitPrj, "workflow.config")); err != nil {
log.Panicln(err)
}
file.WriteString("{\n \"Workflows\": [\"direct\", \"pr\"],\n \"Organization\": \"" + org + "\",\n}\n")
file.Close()
git.GitExecOrPanic(common.DefaultGitPrj, "add", "workflow.config")
} }
} }
} }
@@ -887,8 +812,6 @@ var git common.Git
var obs *common.ObsClient var obs *common.ObsClient
var prj, org string var prj, org string
var forceBadPool bool var forceBadPool bool
var forceNonPoolPackages bool
var devel_projects common.DevelProjects
func main() { func main() {
if err := common.RequireGiteaSecretToken(); err != nil { if err := common.RequireGiteaSecretToken(); err != nil {
@@ -905,7 +828,6 @@ func main() {
flags.SetOutput(helpString) flags.SetOutput(helpString)
//workflowConfig := flag.String("config", "", "Repository and workflow definition file") //workflowConfig := flag.String("config", "", "Repository and workflow definition file")
giteaHost := flags.String("gitea", "src.opensuse.org", "Gitea instance") giteaHost := flags.String("gitea", "src.opensuse.org", "Gitea instance")
obsUrl := flags.String("obs-url", "https://api.opensuse.org", "OBS API Url")
//rabbitUrl := flag.String("url", "amqps://rabbit.opensuse.org", "URL for RabbitMQ instance") //rabbitUrl := flag.String("url", "amqps://rabbit.opensuse.org", "URL for RabbitMQ instance")
flags.BoolVar(&DebugMode, "debug", false, "Extra debugging information") flags.BoolVar(&DebugMode, "debug", false, "Extra debugging information")
// revNew := flag.Int("nrevs", 20, "Number of new revisions in factory branch. Indicator of broken history import") // revNew := flag.Int("nrevs", 20, "Number of new revisions in factory branch. Indicator of broken history import")
@@ -914,8 +836,6 @@ func main() {
getMaintainers := flags.Bool("maintainers-only", false, "Get maintainers only and exit") getMaintainers := flags.Bool("maintainers-only", false, "Get maintainers only and exit")
syncMaintainers := flags.Bool("sync-maintainers-only", false, "Sync maintainers to Gitea and exit") syncMaintainers := flags.Bool("sync-maintainers-only", false, "Sync maintainers to Gitea and exit")
flags.BoolVar(&forceBadPool, "bad-pool", false, "Force packages if pool has no branches due to bad import") flags.BoolVar(&forceBadPool, "bad-pool", false, "Force packages if pool has no branches due to bad import")
flags.BoolVar(&forceNonPoolPackages, "non-pool", false, "Allow packages that are not in pool to be created. WARNING: Can't add to factory later!")
specificPackages := flags.String("packages", "", "Process specific package, separated by commas, ignoring the others")
if help := flags.Parse(os.Args[1:]); help == flag.ErrHelp || flags.NArg() != 2 { if help := flags.Parse(os.Args[1:]); help == flag.ErrHelp || flags.NArg() != 2 {
printHelp(helpString.String()) printHelp(helpString.String())
@@ -927,30 +847,25 @@ func main() {
// r.SetDebug(true) // r.SetDebug(true)
client = apiclient.New(r, nil) client = apiclient.New(r, nil)
obs, _ = common.NewObsClient(*obsUrl) obs, _ = common.NewObsClient("api.opensuse.org")
var gh common.GitHandlerGenerator gh := common.GitHandlerGeneratorImpl{}
var err error var err error
git, err = gh.CreateGitHandler("Autogits - Devel Importer", "not.exist", "devel-importer")
devel_projects, err = common.FetchDevelProjects()
if err != nil { if err != nil {
log.Panic("Cannot load devel projects:", err) log.Panicln("Failed to allocate git handler. Err:", err)
} }
log.Println("# devel projects loaded:", len(devel_projects))
if DebugMode { if DebugMode {
if len(*debugGitPath) > 0 { if len(*debugGitPath) > 0 {
gh, err = common.AllocateGitWorkTree(*debugGitPath, "Autogits - Devel Importer", "not.exist") git.Close()
git, err = gh.ReadExistingPath("Autogits - Devel Importer", "not.exist", *debugGitPath)
if err != nil { if err != nil {
log.Panicln(err) log.Panicln(err)
} }
} }
log.Println(" - working directory:" + git.GetPath())
} else { } else {
dir, _ := os.MkdirTemp(os.TempDir(), "devel-importer") defer git.Close()
gh, err = common.AllocateGitWorkTree(dir, "Autogits - Devel Importer", "not.exist")
if err != nil {
log.Panicln("Failed to allocate git handler", err)
}
} }
prj = flags.Arg(0) prj = flags.Arg(0)
@@ -964,13 +879,6 @@ func main() {
} }
} }
git, err = gh.CreateGitHandler(org)
if err != nil {
log.Panicln("Cannot create git", err)
}
defer git.Close()
log.Println(" - working directory:" + git.GetPath())
/* /*
for _, pkg := range packages { for _, pkg := range packages {
if _, err := client.Organization.CreateOrgRepo(organization.NewCreateOrgRepoParams().WithOrg(org).WithBody( if _, err := client.Organization.CreateOrgRepo(organization.NewCreateOrgRepoParams().WithOrg(org).WithBody(
@@ -1012,15 +920,11 @@ func main() {
if *purgeOnly { if *purgeOnly {
log.Println("Purging repositories...") log.Println("Purging repositories...")
for _, pkg := range packages { for _, pkg := range packages {
client.Repository.RepoDelete(repository.NewRepoDeleteParams().WithOwner(org).WithRepo(giteaPackage(pkg)), r.DefaultAuthentication) client.Repository.RepoDelete(repository.NewRepoDeleteParams().WithOwner(org).WithRepo(pkg), r.DefaultAuthentication)
} }
os.Exit(10) os.Exit(10)
} }
if len(*specificPackages) != 0 {
importRepos(common.SplitStringNoEmpty(*specificPackages, ","))
return
}
importRepos(packages) importRepos(packages)
syncMaintainersToGitea(packages) syncMaintainersToGitea(packages)
} }

View File

@@ -1,46 +0,0 @@
package main
import (
"encoding/json"
"fmt"
"io"
"os"
"github.com/tailscale/hujson"
)
type Config struct {
ForgeEndpoint string `json:"forge_url"`
Keys []string `json:"keys"`
}
type contextKey string
const configKey contextKey = "config"
func ReadConfig(reader io.Reader) (*Config, error) {
data, err := io.ReadAll(reader)
if err != nil {
return nil, fmt.Errorf("error reading config data: %w", err)
}
config := Config{}
data, err = hujson.Standardize(data)
if err != nil {
return nil, fmt.Errorf("failed to parse json: %w", err)
}
if err := json.Unmarshal(data, &config); err != nil {
return nil, fmt.Errorf("error parsing json to api keys and target url: %w", err)
}
return &config, nil
}
func ReadConfigFile(filename string) (*Config, error) {
file, err := os.Open(filename)
if err != nil {
return nil, fmt.Errorf("cannot open config file for reading. err: %w", err)
}
defer file.Close()
return ReadConfig(file)
}

View File

@@ -1,15 +0,0 @@
package main
import (
"context"
"net/http"
)
func ConfigMiddleWare(cfg *Config) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), configKey, cfg)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
}

View File

@@ -1,169 +0,0 @@
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io"
"net/http"
"os"
"slices"
"strings"
"src.opensuse.org/autogits/common"
)
type Status struct {
Context string `json:"context"`
State string `json:"state"`
TargetUrl string `json:"target_url"`
}
type StatusInput struct {
State string `json:"state"`
TargetUrl string `json:"target_url"`
}
func main() {
configFile := flag.String("config", "", "status proxy config file")
flag.Parse()
if *configFile == "" {
common.LogError("missing required argument config")
return
}
config, err := ReadConfigFile(*configFile)
if err != nil {
common.LogError("Failed to read config file", err)
return
}
mux := http.NewServeMux()
mux.Handle("/repos/{owner}/{repo}/statuses/{sha}", ConfigMiddleWare(config)(http.HandlerFunc(StatusProxy)))
common.LogInfo("server up and listening on :3000")
err = http.ListenAndServe(":3000", mux)
if err != nil {
common.LogError("Server failed to start up", err)
}
}
func StatusProxy(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
config, ok := r.Context().Value(configKey).(*Config)
if !ok {
common.LogError("Config missing from context")
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
header := r.Header.Get("Authorization")
if header == "" {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
token_arr := strings.Split(header, " ")
if len(token_arr) != 2 {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
if !strings.EqualFold(token_arr[0], "Bearer") {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
token := token_arr[1]
if !slices.Contains(config.Keys, token) {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
owner := r.PathValue("owner")
repo := r.PathValue("repo")
sha := r.PathValue("sha")
if !ok {
common.LogError("Failed to get config from context, is it set?")
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
posturl := fmt.Sprintf("%s/repos/%s/%s/statuses/%s", config.ForgeEndpoint, owner, repo, sha)
decoder := json.NewDecoder(r.Body)
var statusinput StatusInput
err := decoder.Decode(&statusinput)
if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
status := Status{
Context: "Build in obs",
State: statusinput.State,
TargetUrl: statusinput.TargetUrl,
}
status_payload, err := json.Marshal(status)
if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
client := &http.Client{}
req, err := http.NewRequest("POST", posturl, bytes.NewBuffer(status_payload))
if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
ForgeToken := os.Getenv("GITEA_TOKEN")
if ForgeToken == "" {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
common.LogError("GITEA_TOKEN was not set, all requests will fail")
return
}
req.Header.Add("Content-Type", "Content-Type")
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", ForgeToken))
resp, err := client.Do(req)
if err != nil {
common.LogError(fmt.Sprintf("Request to forge endpoint failed: %v", err))
http.Error(w, http.StatusText(http.StatusBadGateway), http.StatusBadGateway)
return
}
defer resp.Body.Close()
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(resp.StatusCode)
/*
the commented out section sets every key
value from the headers, unsure if this
leaks information from gitea
for k, v := range resp.Header {
for _, vv := range v {
w.Header().Add(k, vv)
}
}
*/
_, err = io.Copy(w, resp.Body)
if err != nil {
common.LogError("Error copying response body: %v", err)
}
} else {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
}

5
go.mod
View File

@@ -8,7 +8,6 @@ require (
github.com/go-openapi/strfmt v0.23.0 github.com/go-openapi/strfmt v0.23.0
github.com/go-openapi/swag v0.23.0 github.com/go-openapi/swag v0.23.0
github.com/go-openapi/validate v0.24.0 github.com/go-openapi/validate v0.24.0
github.com/opentracing/opentracing-go v1.2.0
github.com/rabbitmq/amqp091-go v1.10.0 github.com/rabbitmq/amqp091-go v1.10.0
github.com/tailscale/hujson v0.0.0-20250226034555-ec1d1c113d33 github.com/tailscale/hujson v0.0.0-20250226034555-ec1d1c113d33
go.uber.org/mock v0.5.0 go.uber.org/mock v0.5.0
@@ -16,8 +15,6 @@ require (
require ( require (
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.23.0 // indirect github.com/go-openapi/analysis v0.23.0 // indirect
@@ -30,7 +27,7 @@ require (
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect github.com/oklog/ulid v1.3.1 // indirect
github.com/redis/go-redis/v9 v9.11.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect
go.mongodb.org/mongo-driver v1.14.0 // indirect go.mongodb.org/mongo-driver v1.14.0 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect

6
go.sum
View File

@@ -1,12 +1,8 @@
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@@ -54,8 +50,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw= github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
github.com/redis/go-redis/v9 v9.11.0 h1:E3S08Gl/nJNn5vkxd2i78wZxWAPNZgUNTp8WIJUAiIs=
github.com/redis/go-redis/v9 v9.11.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

View File

@@ -2,16 +2,13 @@ package main
import ( import (
"flag" "flag"
"fmt"
"log" "log"
"net/url" "net/url"
"regexp" "regexp"
"runtime/debug"
"slices" "slices"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"unicode"
"src.opensuse.org/autogits/common" "src.opensuse.org/autogits/common"
"src.opensuse.org/autogits/common/gitea-generated/models" "src.opensuse.org/autogits/common/gitea-generated/models"
@@ -22,32 +19,19 @@ var acceptRx *regexp.Regexp
var rejectRx *regexp.Regexp var rejectRx *regexp.Regexp
var groupName string var groupName string
func InitRegex(newGroupName string) { func InitRegex(groupName string) {
groupName = newGroupName acceptRx = regexp.MustCompile("\\s*:\\s*LGTM")
acceptRx = regexp.MustCompile("^:\\s*(LGTM|approved?)") rejectRx = regexp.MustCompile("\\s*:\\s*")
rejectRx = regexp.MustCompile("^:\\s*")
} }
func ParseReviewLine(reviewText string) (bool, string) { func ParseReviewLine(reviewText string) (bool, string) {
line := strings.TrimSpace(reviewText) line := strings.TrimSpace(reviewText)
groupTextName := "@" + groupName glen := len(groupName)
glen := len(groupTextName) if len(line) < glen || line[0:glen] != groupName {
if len(line) < glen || line[0:glen] != groupTextName {
return false, line return false, line
} }
l := line[glen:] return true, line[glen:]
for idx, r := range l {
if unicode.IsSpace(r) {
continue
} else if r == ':' {
return true, l[idx:]
} else {
return false, line
}
}
return false, line
} }
func ReviewAccepted(reviewText string) bool { func ReviewAccepted(reviewText string) bool {
@@ -70,214 +54,92 @@ func ReviewRejected(reviewText string) bool {
return false return false
} }
/* comment types - from gitea models/issues/comment.go
var commentStrings = []string{
"comment",
"reopen",
"close",
"issue_ref",
"commit_ref",
"comment_ref",
"pull_ref",
"label",
"milestone",
"assignees",
"change_title",
"delete_branch",
"start_tracking",
"stop_tracking",
"add_time_manual",
"cancel_tracking",
"added_deadline",
"modified_deadline",
"removed_deadline",
"add_dependency",
"remove_dependency",
"code",
"review",
"lock",
"unlock",
"change_target_branch",
"delete_time_manual",
"review_request",
"merge_pull",
"pull_push",
"project",
"project_board", // FIXME: the name should be project_column
"dismiss_review",
"change_issue_ref",
"pull_scheduled_merge",
"pull_cancel_scheduled_merge",
"pin",
"unpin",
"change_time_estimate",
}*/
func FindAcceptableReviewInTimeline(user string, timeline []*models.TimelineComment, reviews []*models.PullReview) *models.TimelineComment {
for _, t := range timeline {
if t.Type == common.TimelineCommentType_Comment && t.User.UserName == user && t.Created == t.Updated {
if ReviewAccepted(t.Body) || ReviewRejected(t.Body) {
return t
}
}
}
return nil
}
func UnrequestReviews(gitea common.Gitea, org, repo string, id int64, users []string) {
if err := gitea.UnrequestReview(org, repo, id, users...); err != nil {
common.LogError("Can't remove reviewrs after a review:", err)
}
}
func ProcessNotifications(notification *models.NotificationThread, gitea common.Gitea) { func ProcessNotifications(notification *models.NotificationThread, gitea common.Gitea) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
common.LogInfo("panic cought --- recovered") log.Println("--- resovered")
common.LogError(string(debug.Stack()))
} }
}() }()
rx := regexp.MustCompile(`^/?api/v\d+/repos/(?<org>[_a-zA-Z0-9-]+)/(?<project>[_a-zA-Z0-9-]+)/(?:issues|pulls)/(?<num>[0-9]+)$`) rx := regexp.MustCompile(`^/?api/v\d+/repos/(?<org>[_a-zA-Z0-9-]+)/(?<project>[_a-zA-Z0-9-]+)/issues/(?<num>[0-9]+)$`)
subject := notification.Subject subject := notification.Subject
u, err := url.Parse(notification.Subject.URL) u, err := url.Parse(notification.Subject.URL)
if err != nil { if err != nil {
common.LogError("Invalid format of notification:", subject.URL, err) log.Panicln("Invalid format of notification: %s", subject.URL)
return
} }
match := rx.FindStringSubmatch(u.Path) match := rx.FindStringSubmatch(u.Path)
if match == nil { if match == nil {
common.LogError("** Unexpected format of notification:", subject.URL) log.Panicf("** Unexpected format of notification: %s", subject.URL)
return
} }
org := match[1] org := match[1]
repo := match[2] repo := match[2]
id, _ := strconv.ParseInt(match[3], 10, 64) id, _ := strconv.ParseInt(match[3], 10, 64)
common.LogInfo("processing:", fmt.Sprintf("%s/%s#%d", org, repo, id)) log.Printf("processing: %s/%s#%d\n", org, repo, id)
pr, err := gitea.GetPullRequest(org, repo, id) pr, err := gitea.GetPullRequest(org, repo, id)
if err != nil { if err != nil {
common.LogError(" ** Cannot fetch PR associated with review:", subject.URL, "Error:", err) log.Println(" ** Cannot fetch PR associated with review:", subject.URL, "Error:", err)
return
}
found := false
for _, reviewer := range pr.RequestedReviewers {
if reviewer != nil && reviewer.UserName == groupName {
found = true
break
}
}
if !found {
common.LogInfo(" review is not requested for", groupName)
if !common.IsDryRun {
gitea.SetNotificationRead(notification.ID)
}
return return
} }
config := configs.GetPrjGitConfig(org, repo, pr.Base.Name) config := configs.GetPrjGitConfig(org, repo, pr.Base.Name)
if config == nil {
common.LogError("Cannot find config for:", fmt.Sprintf("%s/%s#%s", org, repo, pr.Base.Name))
return
}
if pr.State == "closed" { if pr.State == "closed" {
// dismiss the review // dismiss the review
common.LogInfo(" -- closed request, so nothing to review") log.Println(" -- closed request, so nothing to review")
if !common.IsDryRun { gitea.SetNotificationRead(notification.ID)
gitea.SetNotificationRead(notification.ID)
}
return return
} }
reviews, err := gitea.GetPullRequestReviews(org, repo, id) reviews, err := gitea.GetPullRequestReviews(org, repo, id)
if err != nil { if err != nil {
common.LogInfo(" ** No reviews associated with request:", subject.URL, "Error:", err) log.Println(" ** No reviews associated with request:", subject.URL, "Error:", err)
return
}
timeline, err := common.FetchTimelineSinceReviewRequestOrPush(gitea, groupName, pr.Head.Sha, org, repo, id)
if err != nil {
common.LogError(err)
return return
} }
requestReviewers, err := config.GetReviewGroupMembers(groupName) requestReviewers, err := config.GetReviewGroupMembers(groupName)
if err != nil { if err != nil {
common.LogError(err) log.Println(err)
return return
} }
// submitter cannot be reviewer // submitter cannot be reviewer
requestReviewers = slices.DeleteFunc(requestReviewers, func(u string) bool { return u == pr.User.UserName }) requestReviewers = slices.DeleteFunc(requestReviewers, func(u string) bool { return u == pr.User.UserName })
// pr.Head.Sha
for _, reviewer := range requestReviewers { for _, review := range reviews {
if review := FindAcceptableReviewInTimeline(reviewer, timeline, reviews); review != nil { user := review.User.UserName
if ReviewAccepted(review.Body) { if !review.Stale && !review.Dismissed &&
if !common.IsDryRun { slices.Contains(requestReviewers, user) {
gitea.AddReviewComment(pr, common.ReviewStateApproved, "Signed off by: "+reviewer)
UnrequestReviews(gitea, org, repo, id, requestReviewers) if review.State == common.ReviewStateApproved && ReviewAccepted(review.Body) {
if !common.IsDryRun { gitea.AddReviewComment(pr, common.ReviewStateApproved, "Signed off by: "+user)
if err := gitea.SetNotificationRead(notification.ID); err != nil { if err := gitea.SetNotificationRead(notification.ID); err != nil {
common.LogDebug(" Cannot set notification as read", err) log.Println(" Cannot set notification as read", err)
}
}
} }
common.LogInfo(" -> approved by", reviewer) log.Println(" -> approved by", user)
common.LogInfo(" review at", review.Created)
return return
} else if ReviewRejected(review.Body) { } else if review.State == common.ReviewStateRequestChanges && ReviewRejected(review.Body) {
if !common.IsDryRun { gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Request changes. See review by: "+user)
gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Changes requested. See review by: "+reviewer) if err := gitea.SetNotificationRead(notification.ID); err != nil {
UnrequestReviews(gitea, org, repo, id, requestReviewers) log.Println(" Cannot set notification as read", err)
if err := gitea.SetNotificationRead(notification.ID); err != nil {
common.LogDebug(" Cannot set notification as read", err)
}
} }
common.LogInfo(" -> declined by", reviewer) log.Println(" -> declined by", user)
return return
} }
} }
} }
// request group member reviews, if missing // request group member reviews, if missing
common.LogDebug(" Review incomplete...") log.Println(" Requesting reviews for:", requestReviewers)
if len(requestReviewers) > 0 { if _, err := gitea.RequestReviews(pr, requestReviewers...); err != nil {
common.LogDebug(" Requesting reviews for:", requestReviewers) log.Println(" -> err:", err)
if !common.IsDryRun {
if _, err := gitea.RequestReviews(pr, requestReviewers...); err != nil {
common.LogDebug(" -> err:", err)
}
} else {
common.LogDebug(" ^^^ not done")
}
} else {
common.LogDebug(" Not requesting additional reviewers")
}
// add a helpful comment, if not yet added
found_help_comment := false
for _, t := range timeline {
if t.Type == common.TimelineCommentType_Comment && t.User != nil && t.User.UserName == groupName {
found_help_comment = true
break
}
}
if !found_help_comment && !common.IsDryRun {
helpComment := fmt.Sprintln("Review by", groupName, "represents a group of reviewers:", strings.Join(requestReviewers, ", "), ". To review as part of this group, create a comment with contents @"+groupName+": LGTM on a separate line to accept a review. To request changes, write @"+groupName+": followed by reason for rejection. Do not use reviews to review as a group. Editing a comment invalidates that comment.")
gitea.AddComment(pr, helpComment)
} }
} }
func PeriodReviewCheck(gitea common.Gitea) { func PeriodReviewCheck(gitea common.Gitea) {
notifications, err := gitea.GetNotifications(common.GiteaNotificationType_Pull, nil) notifications, err := gitea.GetPullNotifications(nil)
if err != nil { if err != nil {
common.LogError(" Error fetching unread notifications: %w", err) log.Println(" EEE Error fetching unread notifications: %w", err)
return return
} }
@@ -289,11 +151,9 @@ func PeriodReviewCheck(gitea common.Gitea) {
func main() { func main() {
giteaUrl := flag.String("gitea-url", "https://src.opensuse.org", "Gitea instance used for reviews") giteaUrl := flag.String("gitea-url", "https://src.opensuse.org", "Gitea instance used for reviews")
rabbitMqHost := flag.String("rabbit-url", "amqps://rabbit.opensuse.org", "RabbitMQ instance where Gitea webhook notifications are sent") rabbitMqHost := flag.String("rabbit-host", "rabbit.opensuse.org", "RabbitMQ instance where Gitea webhook notifications are sent")
interval := flag.Int64("interval", 5, "Notification polling interval in minutes (min 1 min)") interval := flag.Int64("interval", 5, "Notification polling interval in minutes (min 1 min)")
configFile := flag.String("config", "", "PrjGit listing config file") configFile := flag.String("config", "", "PrjGit listing config file")
logging := flag.String("logging", "info", "Logging level: [none, error, info, debug]")
flag.BoolVar(&common.IsDryRun, "dry", false, "Dry run, no effect. For debugging")
flag.Parse() flag.Parse()
args := flag.Args() args := flag.Args()
@@ -306,43 +166,29 @@ func main() {
} }
groupName = args[0] groupName = args[0]
if *configFile == "" {
common.LogError("Missing config file")
return
}
configData, err := common.ReadConfigFile(*configFile) configData, err := common.ReadConfigFile(*configFile)
if err != nil { if err != nil {
common.LogError("Failed to read config file", err) log.Println("Failed to read config file", err)
return return
} }
if err := common.RequireGiteaSecretToken(); err != nil { if err := common.RequireGiteaSecretToken(); err != nil {
common.LogError(err) log.Panicln(err)
return
} }
if err := common.RequireRabbitSecrets(); err != nil { if err := common.RequireRabbitSecrets(); err != nil {
common.LogError(err) log.Panicln(err)
return
} }
gitea := common.AllocateGiteaTransport(*giteaUrl) gitea := common.AllocateGiteaTransport(*giteaUrl)
configs, err = common.ResolveWorkflowConfigs(gitea, configData) configs, err = common.ResolveWorkflowConfigs(gitea, configData)
if err != nil { if err != nil {
common.LogError("Cannot parse workflow configs:", err) log.Panicln(err)
return
} }
reviewer, err := gitea.GetCurrentUser() reviewer, err := gitea.GetCurrentUser()
if err != nil { if err != nil {
common.LogError("Cannot fetch review user:", err) log.Panicln("Cannot fetch review user: %w", err)
return
}
if err := common.SetLoggingLevelFromString(*logging); err != nil {
common.LogError(err.Error())
return
} }
if *interval < 1 { if *interval < 1 {
@@ -351,66 +197,31 @@ func main() {
InitRegex(groupName) InitRegex(groupName)
common.LogInfo(" ** processing group reviews for group:", groupName) log.Println(" ** processing group reviews for group:", groupName)
common.LogInfo(" ** username in Gitea:", reviewer.UserName) log.Println(" ** username in Gitea:", reviewer.UserName)
common.LogInfo(" ** polling interval:", *interval, "min") log.Println(" ** polling internval:", *interval, "min")
common.LogInfo(" ** connecting to RabbitMQ:", *rabbitMqHost) log.Println(" ** connecting to RabbitMQ:", *rabbitMqHost)
if groupName != reviewer.UserName { if groupName != reviewer.UserName {
common.LogError(" ***** Reviewer does not match group name. Aborting. *****") log.Println(" ***** Reviewer does not match group name. Aborting. *****")
return return
} }
u, err := url.Parse(*rabbitMqHost) u, err := url.Parse("amqps://" + *rabbitMqHost)
if err != nil { if err != nil {
common.LogError("Cannot parse RabbitMQ host:", err) log.Panicln("Cannot parse RabbitMQ host:", err)
return
} }
config_update := ConfigUpdatePush{ configUpdates := &common.ListenDefinitions {
config_modified: make(chan *common.AutogitConfig),
}
configUpdates := &common.ListenDefinitions{
RabbitURL: u, RabbitURL: u,
Orgs: []string{}, Orgs: []string{},
Handlers: map[string]common.RequestProcessor{ Handlers: map[string]common.RequestProcessor {
common.RequestType_Push: &config_update, common.RequestType_Push: &ConfigUpdatePush{},
}, },
} }
for _, c := range configs {
if org, _, _ := c.GetPrjGit(); !slices.Contains(configUpdates.Orgs, org) {
configUpdates.Orgs = append(configUpdates.Orgs, org)
}
}
go configUpdates.ProcessRabbitMQEvents() go configUpdates.ProcessRabbitMQEvents()
for { for {
config_update_loop:
for {
select {
case configTouched, ok := <-config_update.config_modified:
if ok {
for idx, c := range configs {
if c == configTouched {
org, repo, branch := c.GetPrjGit()
prj := fmt.Sprintf("%s/%s#%s", org, repo, branch)
common.LogInfo("Detected config update for", prj)
new_config, err := common.ReadWorkflowConfig(gitea, prj)
if err != nil {
common.LogError("Failed parsing Project config for", prj, err)
} else {
configs[idx] = new_config
}
}
}
}
default:
break config_update_loop
}
}
PeriodReviewCheck(gitea) PeriodReviewCheck(gitea)
time.Sleep(time.Duration(*interval * int64(time.Minute))) time.Sleep(time.Duration(*interval * int64(time.Minute)))
} }

View File

@@ -2,76 +2,6 @@ package main
import "testing" import "testing"
func TestReviewApprovalCheck(t *testing.T) { func TestReviews(t *testing.T) {
tests := []struct {
Name string
GroupName string
InString string
Approved bool
Rejected bool
}{
{
Name: "Empty String",
GroupName: "group",
InString: "",
},
{
Name: "Random Text",
GroupName: "group",
InString: "some things LGTM",
},
{
Name: "Group name with Random Text means disapproval",
GroupName: "group",
InString: "@group: some things LGTM",
Rejected: true,
},
{
Name: "Bad name with Approval",
GroupName: "group2",
InString: "@group: LGTM",
},
{
Name: "Bad name with Approval",
GroupName: "group2",
InString: "@group: LGTM",
},
{
Name: "LGTM approval",
GroupName: "group2",
InString: "@group2: LGTM",
Approved: true,
},
{
Name: "approval",
GroupName: "group2",
InString: "@group2: approved",
Approved: true,
},
{
Name: "approval",
GroupName: "group2",
InString: "@group2: approve",
Approved: true,
},
{
Name: "disapproval",
GroupName: "group2",
InString: "@group2: disapprove",
Rejected: true,
},
}
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
InitRegex(test.GroupName)
if r := ReviewAccepted(test.InString); r != test.Approved {
t.Error("ReviewAccepted() returned", r, "expecting", test.Approved)
}
if r := ReviewRejected(test.InString); r != test.Rejected {
t.Error("ReviewRejected() returned", r, "expecting", test.Rejected)
}
})
}
} }

View File

@@ -7,8 +7,8 @@ import (
"src.opensuse.org/autogits/common" "src.opensuse.org/autogits/common"
) )
type ConfigUpdatePush struct { type ConfigUpdatePush struct{
config_modified chan *common.AutogitConfig
} }
func (s *ConfigUpdatePush) ProcessFunc(req *common.Request) error { func (s *ConfigUpdatePush) ProcessFunc(req *common.Request) error {
@@ -44,13 +44,7 @@ func (s *ConfigUpdatePush) ProcessFunc(req *common.Request) error {
slices.Contains(commit.Removed, common.ProjectConfigFile) slices.Contains(commit.Removed, common.ProjectConfigFile)
} }
if modified_config { s.config_modified <-
for _, config := range configs {
if o, r, _ := config.GetPrjGit(); o == org && r == repo {
s.config_modified <- config
}
}
}
return nil return nil
} }

View File

@@ -1 +0,0 @@
forward-bot

View File

@@ -1,293 +0,0 @@
package main
import (
"flag"
"fmt"
"log"
"net/url"
"os"
"regexp"
"runtime/debug"
"strconv"
"strings"
"time"
"src.opensuse.org/autogits/common"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
var LastDevelProjectUpdate *time.Time
var Git common.GitHandlerGenerator
func DevelProjectForPR(pr *models.PullRequest) (*common.DevelProject, error) {
devels, err := common.FetchDevelProjects()
if err != nil {
common.LogError("Failed to fetch devel projects:", err)
return nil, err
}
org := pr.Head.Repo.Owner.UserName
pkg := pr.Head.Repo.Name
common.LogDebug("Looking for devel package", org, pkg)
for _, devel_project := range devels {
if devel_project.Package == pkg {
common.LogDebug("Fetching prject meta for", devel_project.Project)
meta, err := Obs.GetProjectMeta(devel_project.Project)
if err != nil {
common.LogError("Failed to fetch devel project OBS meta", err)
return nil, err
}
u, err := url.Parse(meta.ScmSync)
if err != nil {
common.LogError("Failed to parse project scm", err)
return nil, err
}
if u.Hostname() != "src.opensuse.org" || strings.TrimSuffix(u.Path[1:], ".git") != org+"/_ObsPrj" {
common.LogError("Invalid ScmSync format for devel project", meta.ScmSync, "Expected:", u.Path, "!=", org+"/_ObsPrj")
return nil, fmt.Errorf("Invalid ScmSync format for devel project %s", meta.ScmSync)
}
g, err := Git.CreateGitHandler(org)
if err != nil {
common.LogError("Failed to alloate git:", err)
return nil, err
}
defer g.Close()
branch := u.Fragment
u.Fragment = ""
_, err = g.GitClone(common.DefaultGitPrj, branch, u.String())
common.PanicOnError(err)
expectedSha, ok := g.GitSubmoduleCommitId(common.DefaultGitPrj, pkg, branch)
if !ok {
common.LogError("Failed to find", pkg, "in projectgit")
return nil, fmt.Errorf("failed to find %s in projectgit", pkg)
}
if expectedSha == pr.Head.Sha {
// found a match back to the devel project
return devel_project, nil
}
return nil, fmt.Errorf("Failed to match submission to devel project")
}
}
return nil, fmt.Errorf("Failed to find PR in a devel project. Ignoring")
}
func ProcessNotification(notification *models.NotificationThread) {
defer func() {
if r := recover(); r != nil {
common.LogInfo("panic cought --- recovered")
common.LogError(string(debug.Stack()))
}
}()
rx := regexp.MustCompile(`^/?api/v\d+/repos/(?<org>[_a-zA-Z0-9-]+)/(?<project>[_a-zA-Z0-9-]+)/(?:issues|pulls)/(?<num>[0-9]+)$`)
subject := notification.Subject
u, err := url.Parse(notification.Subject.URL)
if err != nil {
common.LogError("Invalid format of notification:", subject.URL, err)
return
}
match := rx.FindStringSubmatch(u.Path)
if match == nil {
common.LogError("** Unexpected format of notification:", subject.URL)
return
}
org := match[1]
repo := match[2]
id, _ := strconv.ParseInt(match[3], 10, 64)
common.LogInfo("processing:", fmt.Sprintf("%s/%s#%d", org, repo, id))
pr, err := Gitea.GetPullRequest(org, repo, id)
if err != nil {
common.LogError(" ** Cannot fetch PR associated with review:", subject.URL, "Error:", err)
return
}
repository := notification.Repository
repoorg := repository.Owner.UserName
reponame := repository.Name
if repoorg != org || reponame != repo {
common.LogError(" *** failed to parse org notification. Expected", repoorg, reponame)
return
}
headSha := pr.Head.Sha
timeline, err := common.FetchTimelineSinceLastPush(Gitea, headSha, org, repo, id)
if err != nil {
common.LogError("Failed to fetch comments:", err)
return
}
ObsSrFormat := "OBS SR#%d\n"
ExtractSR := func(body string) int {
rx := regexp.MustCompile("^OBS SR#(\\d+)$")
for _, line := range common.SplitLines(body) {
if m := rx.FindStringSubmatch(line); m != nil && len(m) == 2 {
id, _ := strconv.ParseInt(m[1], 10, 32)
return int(id)
}
}
return 0
}
common.LogDebug("notification", org, repo, id)
superseed := false
for _, timeline := range timeline {
if timeline.Type == common.TimelineCommentType_Comment && timeline.User.UserName == GiteaUser {
// check if SR comment referenced here
if sr := ExtractSR(timeline.Body); sr > 0 {
status, err := Obs.RequestStatus(sr)
if err != nil {
common.LogError("Failed to request OBS request status", err)
return
}
if superseed {
break
}
common.LogInfo("Found status:", status.State.State)
if !common.IsDryRun {
if status.State.State == common.RequestStatus_Accepted {
if _, err := Gitea.AddReviewComment(pr, common.ReviewStateApproved, "SR was accepted in OBS. Approving."); err != nil {
common.LogError("Failed to add review comment to PR:", err)
return
}
} else if status.State.State == common.RequestStatus_Declined || status.State.State == common.RequestStatus_Revoked {
if _, err := Gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "SR was rejected in OBS. Rejecting."); err != nil {
common.LogError("Failed to add review comment to PR:", err)
return
}
} else {
common.LogDebug("Request is in state:", status.State.State, "Waiting.")
return
}
Gitea.SetNotificationRead(notification.ID)
} else {
}
return
}
} else if timeline.Type == common.TimelineCommentType_PushPull {
superseed = true
}
}
// no current SR running, create one
dp, err := DevelProjectForPR(pr)
if err != nil {
common.LogDebug("Failed to process PR:", err)
return
}
if !common.IsDryRun {
meta, err := Obs.CreateSubmitRequest(dp.Project, dp.Package, ObsTarget)
if err != nil {
common.LogError("Failed to create OBS SR: ", dp.Project, dp.Package, "=>", ObsTarget, err)
return
}
for {
// make sure we leave comment here
err = Gitea.AddComment(pr, "Created OBS submit request to "+ObsTarget+"\n\n"+fmt.Sprintf(ObsSrFormat, meta.Id))
if err == nil {
break
}
common.LogError("Failed to create Gitea comment:", err)
common.LogInfo("Waiting 1 minute and retrying to leave comment...")
time.Sleep(time.Minute)
}
} else {
common.LogInfo("Would create a SR from", dp.Project, "/", dp.Package, "=>", ObsTarget)
}
}
func ProcessNotifications() {
// process PRs and issues
notifications, err := Gitea.GetNotifications(common.GiteaNotificationType_Pull, nil)
if err != nil {
common.LogError("Failed to get notifications.", err)
return
}
for _, notification := range notifications {
ProcessNotification(notification)
}
}
var GiteaUser string
var Gitea common.Gitea
var Obs *common.ObsClient
var ObsTarget, GiteaTargetBranch, GiteaOrg string
func main() {
GiteaHost := flag.String("gitea-host", "https://src.opensuse.org", "Gitea host")
ObsHost := flag.String("obs-host", "https://api.opensuse.org", "OBS instance")
flag.StringVar(&ObsTarget, "obs-target", "openSUSE:Factory", "")
flag.StringVar(&GiteaTargetBranch, "gitea-target", "factory", "")
flag.StringVar(&GiteaOrg, "gitea-org", "pool", "")
debug := flag.Bool("debug", false, "Debug logging")
GitRepoPath := flag.String("git-path", "", "Git repo path")
flag.BoolVar(&common.IsDryRun, "dry", false, "no-op operation")
flag.Parse()
if *debug {
common.SetLoggingLevel(common.LogLevelDebug)
}
var err error
if err = common.RequireGiteaSecretToken(); err != nil {
log.Panic(err)
}
if err = common.RequireObsSecretToken(); err != nil {
log.Panic(err)
}
if Obs, err = common.NewObsClient(*ObsHost); err != nil {
log.Panic(err)
}
Gitea = common.AllocateGiteaTransport(*GiteaHost)
if user, err := Gitea.GetCurrentUser(); err != nil {
log.Panic(err)
} else {
GiteaUser = user.UserName
}
common.LogInfo("Current user:", GiteaUser)
if len(*GitRepoPath) == 0 {
*GitRepoPath, err = os.MkdirTemp(os.TempDir(), "forward-bot")
if err != nil {
common.LogError("Failed to create tempdir:", err)
return
}
}
Git, err = common.AllocateGitWorkTree(*GitRepoPath, "bot", "nothing")
if err != nil {
common.LogError("Failed to allocate git tree", err)
return
}
for {
common.LogDebug("--- Starting processing notifications ---")
ProcessNotifications()
common.LogDebug("--- End processing notifications ---")
time.Sleep(time.Minute * 5)
}
}

View File

@@ -33,9 +33,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/opentracing/opentracing-go/log"
"src.opensuse.org/autogits/common" "src.opensuse.org/autogits/common"
"src.opensuse.org/autogits/common/gitea-generated/client/repository"
"src.opensuse.org/autogits/common/gitea-generated/models" "src.opensuse.org/autogits/common/gitea-generated/models"
) )
@@ -107,16 +105,15 @@ const (
) )
func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatusSummary { func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatusSummary {
if _, finished := project.BuildResultSummary(); !finished {
return BuildStatusSummaryBuilding
}
if _, finished := refProject.BuildResultSummary(); !finished { if _, finished := refProject.BuildResultSummary(); !finished {
common.LogDebug("refProject not finished building??") common.LogDebug("refProject not finished building??")
return BuildStatusSummaryUnknown return BuildStatusSummaryUnknown
} }
if _, finished := project.BuildResultSummary(); !finished {
common.LogDebug("Still building...")
return BuildStatusSummaryBuilding
}
// the repositories should be setup equally between the projects. We // the repositories should be setup equally between the projects. We
// need to verify that packages that are building in `refProject` are not // need to verify that packages that are building in `refProject` are not
// failing in the `project` // failing in the `project`
@@ -133,7 +130,6 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
slices.SortFunc(project.Result, BuildResultSorter) slices.SortFunc(project.Result, BuildResultSorter)
if refProject == nil { if refProject == nil {
// just return if buid finished and have some successes, since new package // just return if buid finished and have some successes, since new package
common.LogInfo("New package. Only need some success...")
SomeSuccess := false SomeSuccess := false
for i := 0; i < len(project.Result); i++ { for i := 0; i < len(project.Result); i++ {
repoRes := &project.Result[i] repoRes := &project.Result[i]
@@ -168,7 +164,6 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
slices.SortFunc(refProject.Result, BuildResultSorter) slices.SortFunc(refProject.Result, BuildResultSorter)
common.LogDebug("comparing results", len(project.Result), "vs. ref", len(refProject.Result)) common.LogDebug("comparing results", len(project.Result), "vs. ref", len(refProject.Result))
SomeSuccess := false
for i := 0; i < len(project.Result); i++ { for i := 0; i < len(project.Result); i++ {
common.LogDebug("searching for", project.Result[i].Repository, "/", project.Result[i].Arch) common.LogDebug("searching for", project.Result[i].Repository, "/", project.Result[i].Arch)
j := 0 j := 0
@@ -180,10 +175,9 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
} }
common.LogDebug(" found match for @ idx:", j) common.LogDebug(" found match for @ idx:", j)
res, success := ProcessRepoBuildStatus(project.Result[i].Status, refProject.Result[j].Status) res := ProcessRepoBuildStatus(project.Result[i].Status, refProject.Result[j].Status)
switch res { switch res {
case BuildStatusSummarySuccess: case BuildStatusSummarySuccess:
SomeSuccess = SomeSuccess || success
break found break found
default: default:
return res return res
@@ -197,42 +191,28 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
return BuildStatusSummaryUnknown return BuildStatusSummaryUnknown
} }
} }
return BuildStatusSummarySuccess
if SomeSuccess {
return BuildStatusSummarySuccess
}
return BuildStatusSummaryFailed
} }
func ProcessRepoBuildStatus(results, ref []common.PackageBuildStatus) (status BuildStatusSummary, SomeSuccess bool) { func ProcessRepoBuildStatus(results, ref []common.PackageBuildStatus) BuildStatusSummary {
PackageBuildStatusSorter := func(a, b common.PackageBuildStatus) int { PackageBuildStatusSorter := func(a, b common.PackageBuildStatus) int {
return strings.Compare(a.Package, b.Package) return strings.Compare(a.Package, b.Package)
} }
common.LogDebug("******** REF: ")
data, _ := xml.MarshalIndent(ref, "", " ")
common.LogDebug(string(data))
common.LogDebug("******* RESULTS: ")
data, _ = xml.MarshalIndent(results, "", " ")
common.LogDebug(string(data))
common.LogDebug("*******")
// compare build result // compare build result
slices.SortFunc(results, PackageBuildStatusSorter) slices.SortFunc(results, PackageBuildStatusSorter)
slices.SortFunc(ref, PackageBuildStatusSorter) slices.SortFunc(ref, PackageBuildStatusSorter)
j := 0 j := 0
SomeSuccess = false
for i := 0; i < len(results); i++ { for i := 0; i < len(results); i++ {
res, ok := common.ObsBuildStatusDetails[results[i].Code] res, ok := common.ObsBuildStatusDetails[results[i].Code]
if !ok { if !ok {
common.LogInfo("unknown package result code:", results[i].Code, "for package:", results[i].Package) common.LogInfo("unknown package result code:", results[i].Code, "for package:", results[i].Package)
return BuildStatusSummaryUnknown, SomeSuccess return BuildStatusSummaryUnknown
} }
if !res.Finished { if !res.Finished {
return BuildStatusSummaryBuilding, SomeSuccess return BuildStatusSummaryBuilding
} }
if !res.Success { if !res.Success {
@@ -244,7 +224,7 @@ func ProcessRepoBuildStatus(results, ref []common.PackageBuildStatus) (status Bu
refRes, ok := common.ObsBuildStatusDetails[ref[j].Code] refRes, ok := common.ObsBuildStatusDetails[ref[j].Code]
if !ok { if !ok {
common.LogInfo("unknown ref package result code:", ref[j].Code, "package:", ref[j].Package) common.LogInfo("unknown ref package result code:", ref[j].Code, "package:", ref[j].Package)
return BuildStatusSummaryUnknown, SomeSuccess return BuildStatusSummaryUnknown
} }
if !refRes.Finished { if !refRes.Finished {
@@ -252,18 +232,16 @@ func ProcessRepoBuildStatus(results, ref []common.PackageBuildStatus) (status Bu
} }
if refRes.Success { if refRes.Success {
return BuildStatusSummaryFailed, SomeSuccess return BuildStatusSummaryFailed
} }
} }
} else {
SomeSuccess = true
} }
} }
return BuildStatusSummarySuccess, SomeSuccess return BuildStatusSummarySuccess
} }
func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullRequest, stagingPrj, buildPrj string) (*common.ProjectMeta, error) { func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullRequest, obsClient *common.ObsClient, stagingPrj, buildPrj string) (*common.ProjectMeta, error) {
common.LogDebug("repo content fetching ...") common.LogDebug("repo content fetching ...")
err := FetchPrGit(git, pr) err := FetchPrGit(git, pr)
if err != nil { if err != nil {
@@ -289,7 +267,7 @@ func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullReque
} }
} }
meta, err := ObsClient.GetProjectMeta(buildPrj) meta, err := obsClient.GetProjectMeta(buildPrj)
if err != nil { if err != nil {
common.LogError("error fetching project meta for", buildPrj, ". Err:", err) common.LogError("error fetching project meta for", buildPrj, ". Err:", err)
return nil, err return nil, err
@@ -315,22 +293,19 @@ func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullReque
} }
meta.ScmSync = pr.Head.Repo.CloneURL + "?" + strings.Join(urlPkg, "&") + "#" + pr.Head.Sha meta.ScmSync = pr.Head.Repo.CloneURL + "?" + strings.Join(urlPkg, "&") + "#" + pr.Head.Sha
meta.Title = fmt.Sprintf("PR#%d to %s", pr.Index, pr.Base.Name) meta.Title = fmt.Sprintf("PR#%d to %s", pr.Index, pr.Base.Name)
// QE wants it published ... also we should not hardcode it here, since meta.PublicFlags = common.Flags{Contents: "<disable/>"}
// it is configurable via the :PullRequest project
// meta.PublicFlags = common.Flags{Contents: "<disable/>"}
meta.Groups = nil meta.Groups = nil
meta.Persons = nil meta.Persons = nil
// set paths to parent project // set paths to parent project
for idx, r := range meta.Repositories { for idx, r := range meta.Repositories {
meta.Repositories[idx].ReleaseTargets = nil
localRepository := false localRepository := false
for pidx, path := range r.Paths { for pidx, path := range r.Paths {
// Check for path building against a repo in template project itself // Check for path building against a repo in template project itself
if path.Project == buildPrj { if path.Project == buildPrj {
meta.Repositories[idx].Paths[pidx].Project = meta.Name meta.Repositories[idx].Paths[pidx].Project = meta.Name
localRepository = true localRepository = true
} }
} }
if localRepository != true { if localRepository != true {
@@ -349,9 +324,9 @@ func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullReque
// stagingProject:$buildProject // stagingProject:$buildProject
// ^- stagingProject:$buildProject:$subProjectName (based on templateProject) // ^- stagingProject:$buildProject:$subProjectName (based on templateProject)
func CreateQASubProject(stagingConfig *common.StagingConfig, git common.Git, gitea common.Gitea, pr *models.PullRequest, stagingProject, templateProject, subProjectName string) error { func CreateQASubProject(stagingConfig *common.StagingConfig, git common.Git, gitea common.Gitea, pr *models.PullRequest, obsClient *common.ObsClient, stagingProject, templateProject, subProjectName string) error {
common.LogDebug("Setup QA sub projects") common.LogDebug("Setup QA sub projects")
templateMeta, err := ObsClient.GetProjectMeta(templateProject) templateMeta, err := obsClient.GetProjectMeta(templateProject)
if err != nil { if err != nil {
common.LogError("error fetching template project meta for", templateProject, ":", err) common.LogError("error fetching template project meta for", templateProject, ":", err)
return err return err
@@ -375,7 +350,7 @@ func CreateQASubProject(stagingConfig *common.StagingConfig, git common.Git, git
} }
if !IsDryRun { if !IsDryRun {
err = ObsClient.SetProjectMeta(templateMeta) err = obsClient.SetProjectMeta(templateMeta)
if err != nil { if err != nil {
common.LogError("cannot create project:", templateMeta.Name, err) common.LogError("cannot create project:", templateMeta.Name, err)
return err return err
@@ -387,10 +362,10 @@ func CreateQASubProject(stagingConfig *common.StagingConfig, git common.Git, git
return nil return nil
} }
func StartOrUpdateBuild(config *common.StagingConfig, git common.Git, gitea common.Gitea, pr *models.PullRequest) (RequestModification, error) { func StartOrUpdateBuild(config *common.StagingConfig, git common.Git, gitea common.Gitea, pr *models.PullRequest, obsClient *common.ObsClient) (RequestModification, error) {
common.LogDebug("fetching OBS project Meta") common.LogDebug("fetching OBS project Meta")
obsPrProject := GetObsProjectAssociatedWithPr(config, ObsClient.HomeProject, pr) obsPrProject := GetObsProjectAssociatedWithPr(config, obsClient.HomeProject, pr)
meta, err := ObsClient.GetProjectMeta(obsPrProject) meta, err := obsClient.GetProjectMeta(obsPrProject)
if err != nil { if err != nil {
common.LogError("error fetching project meta for", obsPrProject, ":", err) common.LogError("error fetching project meta for", obsPrProject, ":", err)
return RequestModificationNoChange, err return RequestModificationNoChange, err
@@ -414,7 +389,7 @@ func StartOrUpdateBuild(config *common.StagingConfig, git common.Git, gitea comm
var state RequestModification = RequestModificationSourceChanged var state RequestModification = RequestModificationSourceChanged
if meta == nil { if meta == nil {
// new build // new build
meta, err = GenerateObsPrjMeta(git, gitea, pr, obsPrProject, config.ObsProject) meta, err = GenerateObsPrjMeta(git, gitea, pr, obsClient, obsPrProject, config.ObsProject)
if err != nil { if err != nil {
return RequestModificationNoChange, err return RequestModificationNoChange, err
} }
@@ -426,7 +401,7 @@ func StartOrUpdateBuild(config *common.StagingConfig, git common.Git, gitea comm
common.LogDebug("Creating build project:") common.LogDebug("Creating build project:")
common.LogDebug(" meta:", string(x)) common.LogDebug(" meta:", string(x))
} else { } else {
err = ObsClient.SetProjectMeta(meta) err = obsClient.SetProjectMeta(meta)
if err != nil { if err != nil {
common.LogError("cannot create meta project:", err) common.LogError("cannot create meta project:", err)
return RequestModificationNoChange, err return RequestModificationNoChange, err
@@ -438,7 +413,7 @@ func StartOrUpdateBuild(config *common.StagingConfig, git common.Git, gitea comm
func IsReviewerRequested(pr *models.PullRequest) bool { func IsReviewerRequested(pr *models.PullRequest) bool {
for _, reviewer := range pr.RequestedReviewers { for _, reviewer := range pr.RequestedReviewers {
if reviewer != nil && reviewer.UserName == Username { if reviewer.UserName == Username {
return true return true
} }
} }
@@ -461,7 +436,7 @@ func FetchOurLatestActionableReview(gitea common.Gitea, org, repo string, id int
for idx := len(reviews) - 1; idx >= 0; idx-- { for idx := len(reviews) - 1; idx >= 0; idx-- {
review := reviews[idx] review := reviews[idx]
if review.User == nil || review.User.UserName == Username { if review.User != nil || review.User.UserName == Username {
if IsDryRun { if IsDryRun {
// for purposes of moving forward a no-op check // for purposes of moving forward a no-op check
return review, nil return review, nil
@@ -480,21 +455,6 @@ func FetchOurLatestActionableReview(gitea common.Gitea, org, repo string, id int
return nil, NoReviewsFoundError return nil, NoReviewsFoundError
} }
func ParseNotificationToPR(thread *models.NotificationThread) (org string, repo string, num int64, err error) {
rx := regexp.MustCompile(`^https://src\.(?:open)?suse\.(?:org|de)/api/v\d+/repos/(?<org>[-_a-zA-Z0-9]+)/(?<project>[-_a-zA-Z0-9]+)/issues/(?<num>[0-9]+)$`)
notification := thread.Subject
match := rx.FindStringSubmatch(notification.URL)
if match == nil {
err = fmt.Errorf("Unexpected notification format: %s", notification.URL)
return
}
org = match[1]
repo = match[2]
num, err = strconv.ParseInt(match[3], 10, 64)
return
}
func ProcessPullNotification(gitea common.Gitea, thread *models.NotificationThread) { func ProcessPullNotification(gitea common.Gitea, thread *models.NotificationThread) {
defer func() { defer func() {
err := recover() err := recover()
@@ -504,125 +464,28 @@ func ProcessPullNotification(gitea common.Gitea, thread *models.NotificationThre
} }
}() }()
org, repo, num, err := ParseNotificationToPR(thread) rx := regexp.MustCompile(`^https://src\.(?:open)?suse\.(?:org|de)/api/v\d+/repos/(?<org>[-_a-zA-Z0-9]+)/(?<project>[-_a-zA-Z0-9]+)/issues/(?<num>[0-9]+)$`)
if err != nil { notification := thread.Subject
common.LogError(err.Error()) match := rx.FindStringSubmatch(notification.URL)
if match == nil {
common.LogError("Unexpected format of notification:", notification.URL)
return return
} }
common.LogInfo("processing PR:", org, "/", repo, "#", num)
done, err := ProcessPullRequest(gitea, org, repo, num) common.LogInfo("processing PR:", match[1], "/", match[2], "#", match[3])
if !IsDryRun && err == nil && done { org := match[1]
repo := match[2]
id, _ := strconv.ParseInt(match[3], 10, 64)
err := ProcessPullRequest(gitea, org, repo, id)
if !IsDryRun && err == nil {
gitea.SetNotificationRead(thread.ID) gitea.SetNotificationRead(thread.ID)
} else if err != nil { } else if err != nil {
common.LogError(err) common.LogError(err)
} }
} }
var CleanedUpIssues []int64 = []int64{} func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) error {
func CleanupPullNotification(gitea common.Gitea, thread *models.NotificationThread) (CleanupComplete bool) {
defer func() {
err := recover()
if err != nil {
common.LogError(err)
common.LogError(string(debug.Stack()))
}
}()
cleanUpIdx, cleanedUp := slices.BinarySearch(CleanedUpIssues, thread.ID)
if cleanedUp {
return true
}
common.LogDebug(" processing notification:", thread.Subject.HTMLURL)
org, repo, num, err := ParseNotificationToPR(thread)
if err != nil {
common.LogError(err.Error())
return false
}
pr, err := gitea.GetPullRequest(org, repo, num)
if err != nil {
common.LogError("Cannot fetch PR ", org, "/", repo, "#", num, " error:", err)
return false
}
if pr.State != "closed" {
common.LogInfo(" ignoring pending PR", thread.Subject.HTMLURL, " state:", pr.State)
return false
}
data, _, err := gitea.GetRepositoryFileContent(org, repo, pr.Head.Sha, common.StagingConfigFile)
// TODO: remove this legacy PR cleanup stuff
var config *common.StagingConfig = &common.StagingConfig{}
if err != nil {
if errors.Is(err, &repository.RepoGetContentsNotFound{}) {
data, _, err := gitea.GetRepositoryFileContent(org, repo, pr.Head.Sha, "project.build")
if err == nil {
common.LogDebug(" --> Legacy PR cleanup")
config.ObsProject = string(data)
} else {
common.LogDebug("assuming cleaned up already...", pr.URL)
CleanedUpIssues = slices.Insert(CleanedUpIssues, cleanUpIdx, thread.ID)
return true
}
}
if config.ObsProject == "" {
common.LogDebug("Cannot fetch config file in the PR. Skipping cleanup.")
return false
}
} else {
config, err = common.ParseStagingConfig(data)
if err != nil {
common.LogDebug("Failed to parse config ... so probably nothing to cleanup anyway. Marked as done")
CleanedUpIssues = slices.Insert(CleanedUpIssues, cleanUpIdx, thread.ID)
return true
}
}
if !pr.HasMerged && time.Since(time.Time(pr.Closed)) < time.Duration(config.CleanupDelay)*time.Hour {
common.LogInfo("Cooldown period for cleanup of", thread.URL)
return false
}
stagingProject := GetObsProjectAssociatedWithPr(config, ObsClient.HomeProject, pr)
if prj, err := ObsClient.GetProjectMeta(stagingProject); err != nil {
common.LogError("Failed fetching meta for project:", stagingProject, ". Not cleaning up")
return false
} else if prj == nil && err == nil {
// cleanup already done
CleanedUpIssues = slices.Insert(CleanedUpIssues, cleanUpIdx, thread.ID)
return true
}
common.LogDebug("Cleaning up", stagingProject)
for _, qa := range config.QA {
project := stagingProject + ":" + qa.Name
common.LogDebug("Cleaning up QA staging", project)
if !IsDryRun {
if err := ObsClient.DeleteProject(project); err != nil {
common.LogError("Failed to cleanup QA staging", project, err)
}
}
}
if !IsDryRun {
if err := ObsClient.DeleteProject(stagingProject); err != nil {
common.LogError("Failed to cleanup staging", stagingProject, err)
}
}
CleanedUpIssues = slices.Insert(CleanedUpIssues, cleanUpIdx, thread.ID)
if l := len(CleanedUpIssues); l > 100000 {
common.LogInfo("** Problem? ** Cleaning up massive CleanedUpIssues cache")
CleanedUpIssues = CleanedUpIssues[l-50000:]
}
return false // cleaned up now, but the cleanup was not aleady done
}
func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) (bool, error) {
dir, err := os.MkdirTemp(os.TempDir(), BotName) dir, err := os.MkdirTemp(os.TempDir(), BotName)
common.PanicOnError(err) common.PanicOnError(err)
if IsDryRun { if IsDryRun {
@@ -641,20 +504,29 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) (bool, e
pr, err := gitea.GetPullRequest(org, repo, id) pr, err := gitea.GetPullRequest(org, repo, id)
if err != nil { if err != nil {
common.LogError("No PR associated with review:", org, "/", repo, "#", id, "Error:", err) common.LogError("No PR associated with review:", org, "/", repo, "#", id, "Error:", err)
return true, err return err
} }
common.LogDebug("PR state:", pr.State) common.LogDebug("PR state:", pr.State)
if pr.State == "closed" { if pr.State == "closed" {
// dismiss the review // dismiss the review
common.LogInfo(" -- closed request, so nothing to review") common.LogInfo(" -- closed request, so nothing to review")
return true, nil return nil
}
obsClient, err := common.NewObsClient(ObsApiHost)
if err != nil {
return err
}
if len(BuildRoot) > 0 {
obsClient.HomeProject = BuildRoot
} }
if !IsReviewerRequested(pr) { if !IsReviewerRequested(pr) {
common.LogError("Review not requested in notification. Setting to status 'read'") common.LogError("Review not requested in notification. Setting to status 'read'")
if !IsDryRun { if !IsDryRun {
return true, nil return nil
} else { } else {
common.LogDebug(" -- continueing dry mode") common.LogDebug(" -- continueing dry mode")
} }
@@ -666,19 +538,20 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) (bool, e
err = FetchPrGit(git, pr) err = FetchPrGit(git, pr)
if err != nil { if err != nil {
common.LogError("Cannot fetch PR git:", pr.URL) common.LogError("Cannot fetch PR git:", pr.URL)
return false, err return err
} }
// we want the possibly pending modification here, in case stagings are added, etc. // we want the possibly pending modification here, in case stagings are added, etc.
// jobs of review team to deal with issues // jobs of review team to deal with issues
common.LogDebug("QA configuration fetching ...", common.StagingConfigFile) common.LogDebug("QA configuration fetching ...", common.StagingConfigFile)
QA := []common.QAConfig{}
data, err := git.GitCatFile(pr.Head.Sha, pr.Head.Sha, common.StagingConfigFile) data, err := git.GitCatFile(pr.Head.Sha, pr.Head.Sha, common.StagingConfigFile)
if err != nil { if err != nil {
common.LogError("Staging config", common.StagingConfigFile, "not found in PR to the project. Aborting.") common.LogError("Staging config", common.StagingConfigFile, "not found in PR to the project. Aborting.")
if !IsDryRun { if !IsDryRun {
_, err = gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot find project config in PR: "+common.ProjectConfigFile) _, err = gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot find project config in PR: "+common.ProjectConfigFile)
} }
return true, err return err
} }
stagingConfig, err := common.ParseStagingConfig(data) stagingConfig, err := common.ParseStagingConfig(data)
@@ -690,25 +563,25 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) (bool, e
common.LogError("Cannot find reference project for PR#", pr.Index) common.LogError("Cannot find reference project for PR#", pr.Index)
if !IsDryRun { if !IsDryRun {
_, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot find reference project") _, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot find reference project")
return true, err return err
} }
return true, nil return nil
} }
meta, err := ObsClient.GetProjectMeta(stagingConfig.ObsProject) meta, err := obsClient.GetProjectMeta(stagingConfig.ObsProject)
if err != nil { if err != nil {
common.LogError("Cannot find reference project meta:", stagingConfig.ObsProject, err) common.LogError("Cannot find reference project meta:", stagingConfig.ObsProject)
if !IsDryRun { if !IsDryRun {
_, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot fetch reference project meta") _, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot fetch reference project meta")
return true, err return err
} }
return true, nil return nil
} }
if metaUrl, err := url.Parse(meta.ScmSync); err != nil { if metaUrl, err := url.Parse(meta.ScmSync); err != nil {
return false, err return err
} else if targetPRSyncUrl, err := url.Parse(pr.Base.Repo.CloneURL); err != nil { } else if targetPRSyncUrl, err := url.Parse(pr.Base.Repo.CloneURL); err != nil {
return false, err return err
} else { } else {
metaUrl.RawQuery = "" metaUrl.RawQuery = ""
metaUrl.Fragment = "" metaUrl.Fragment = ""
@@ -720,10 +593,10 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) (bool, e
if metaUrl.String() != targetPRSyncUrl.String() { if metaUrl.String() != targetPRSyncUrl.String() {
common.LogError("SCMSYNC in meta", meta.ScmSync, "!= PR CloneURL from Gitea", pr.Base.Repo.CloneURL, ". Skipping staging") common.LogError("SCMSYNC in meta", meta.ScmSync, "!= PR CloneURL from Gitea", pr.Base.Repo.CloneURL, ". Skipping staging")
if !IsDryRun { if !IsDryRun {
_, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "SCMSYNC of target project is not equal to CloneURL of this PR. Can't review.") _, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "SCMSYNC of target project is equal to CloneURL of this PR. Can't review.")
return true, err return err
} }
return true, nil return nil
} }
} }
@@ -741,9 +614,9 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) (bool, e
common.LogError("staging.config . ObsProject:", stagingConfig.ObsProject, " is not target project name", meta.Name) common.LogError("staging.config . ObsProject:", stagingConfig.ObsProject, " is not target project name", meta.Name)
if !IsDryRun { if !IsDryRun {
_, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "OBS Meta and staging.config are inconsistent") _, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "OBS Meta and staging.config are inconsistent")
return true, err return err
} }
return true, nil return nil
} }
// find modified submodules and new submodules -- build them // find modified submodules and new submodules -- build them
@@ -807,90 +680,70 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) (bool, e
if !IsDryRun { if !IsDryRun {
_, err = gitea.AddReviewComment(pr, common.ReviewStateComment, "No package changes. Not rebuilding project by default") _, err = gitea.AddReviewComment(pr, common.ReviewStateComment, "No package changes. Not rebuilding project by default")
} }
return true, err return err
} }
} }
common.LogDebug("ObsProject:", stagingConfig.ObsProject) common.LogDebug("ObsProject:", stagingConfig.ObsProject)
stagingProject := GetObsProjectAssociatedWithPr(stagingConfig, ObsClient.HomeProject, pr) stagingProject := GetObsProjectAssociatedWithPr(stagingConfig, obsClient.HomeProject, pr)
change, err := StartOrUpdateBuild(stagingConfig, git, gitea, pr) change, err := StartOrUpdateBuild(stagingConfig, git, gitea, pr, obsClient)
status := &models.CommitStatus{ if change != RequestModificationNoChange {
Context: BotName, msg := "Changed source updated for build"
Description: "OBS Staging build", if change == RequestModificationProjectCreated {
Status: common.CommitStatus_Pending, msg = "Build is started in https://" + ObsWebHost + "/project/show/" +
TargetURL: ObsWebHost + "/project/show/" + stagingProject, stagingProject
}
if !IsDryRun {
gitea.AddComment(pr, msg)
}
} }
msg := "Changed source updated for build"
if change == RequestModificationProjectCreated { if change == RequestModificationProjectCreated {
msg = "Build is started in " + ObsWebHost + "/project/show/" + for _, setup := range QA {
stagingProject + " .\n" CreateQASubProject(stagingConfig, git, gitea, pr, obsClient,
if len(stagingConfig.QA) > 0 {
msg = msg + "\nAdditional QA builds: \n"
}
gitea.SetCommitStatus(pr.Base.Repo.Owner.UserName, pr.Base.Repo.Name, pr.Head.Sha, status)
for _, setup := range stagingConfig.QA {
CreateQASubProject(stagingConfig, git, gitea, pr,
stagingProject, stagingProject,
setup.Origin, setup.Origin,
setup.Name) setup.Name)
msg = msg + ObsWebHost + "/project/show/" +
stagingProject + ":" + setup.Name + "\n"
} }
} }
if change != RequestModificationNoChange && !IsDryRun {
gitea.AddComment(pr, msg)
}
baseResult, err := ObsClient.LastBuildResults(stagingConfig.ObsProject, modifiedOrNew...) baseResult, err := obsClient.LastBuildResults(stagingConfig.ObsProject, modifiedOrNew...)
if err != nil { if err != nil {
common.LogError("failed fetching ref project status for", stagingConfig.ObsProject, ":", err) common.LogError("failed fetching ref project status for", stagingConfig.ObsProject, ":", err)
} }
stagingResult, err := ObsClient.BuildStatus(stagingProject) stagingResult, err := obsClient.BuildStatus(stagingProject)
if err != nil { if err != nil {
common.LogError("failed fetching ref project status for", stagingProject, ":", err) common.LogError("failed fetching ref project status for", stagingProject, ":", err)
} }
buildStatus := ProcessBuildStatus(stagingResult, baseResult) buildStatus := ProcessBuildStatus(stagingResult, baseResult)
switch buildStatus { if !IsDryRun {
case BuildStatusSummarySuccess: switch buildStatus {
status.Status = common.CommitStatus_Success case BuildStatusSummarySuccess:
if !IsDryRun {
_, err := gitea.AddReviewComment(pr, common.ReviewStateApproved, "Build successful") _, err := gitea.AddReviewComment(pr, common.ReviewStateApproved, "Build successful")
if err != nil { if err != nil {
common.LogError(err) common.LogError(err)
} else {
return true, nil
} }
} case BuildStatusSummaryFailed:
case BuildStatusSummaryFailed:
status.Status = common.CommitStatus_Fail
if !IsDryRun {
_, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Build failed") _, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Build failed")
if err != nil { if err != nil {
common.LogError(err) common.LogError(err)
} else {
return true, nil
} }
} }
} }
common.LogInfo("Build status:", buildStatus) common.LogInfo("Build status:", buildStatus)
gitea.SetCommitStatus(pr.Base.Repo.Owner.UserName, pr.Base.Repo.Name, pr.Head.Sha, status)
// waiting for build results -- nothing to do // waiting for build results -- nothing to do
} else if err == NonActionableReviewError || err == NoReviewsFoundError { } else if err == NonActionableReviewError || err == NoReviewsFoundError {
return true, nil return nil
} }
return false, nil return nil
} }
func PollWorkNotifications(giteaUrl string) { func PollWorkNotifications(giteaUrl string) {
gitea := common.AllocateGiteaTransport(giteaUrl) gitea := common.AllocateGiteaTransport(giteaUrl)
data, err := gitea.GetNotifications(common.GiteaNotificationType_Pull, nil) data, err := gitea.GetPullNotifications(nil)
if err != nil { if err != nil {
common.LogError(err) common.LogError(err)
@@ -914,56 +767,32 @@ func PollWorkNotifications(giteaUrl string) {
} }
} }
} }
// cleanup old projects
common.LogDebug("Cleaning up old pull requests")
cleanupFinished := false
for page := int64(1); !cleanupFinished; page++ {
cleanupFinished = true
if data, err := gitea.GetDoneNotifications(common.GiteaNotificationType_Pull, page); data != nil {
for _, n := range data {
if n.Unread {
common.LogError("Done notification is unread or pinned?", *n.Subject)
cleanupFinished = false
continue
}
cleanupFinished = CleanupPullNotification(gitea, n) && cleanupFinished
}
} else if err != nil {
common.LogError(err)
}
}
} }
var ListPullNotificationsOnly bool var ListPullNotificationsOnly bool
var BuildRoot string
var GiteaUrl string var GiteaUrl string
var GiteaUseSshClone bool var GiteaUseSshClone bool
var ObsApiHost string
var ObsWebHost string var ObsWebHost string
var IsDryRun bool var IsDryRun bool
var ProcessPROnly string var ProcessPROnly string
var ObsClient *common.ObsClient
func ObsWebHostFromApiHost(apihost string) string { func ObsWebHostFromApiHost(apihost string) string {
u, err := url.Parse(apihost) if len(apihost) > 4 && apihost[0:4] == "api." {
if err != nil { return "build" + apihost[3:]
common.LogError("Cannot parse OBS API URL")
panic(err)
}
if len(u.Host) > 4 && u.Host[0:4] == "api." {
u.Host = "build" + u.Host[3:]
} }
return u.String() return apihost
} }
func main() { func main() {
flag.BoolVar(&ListPullNotificationsOnly, "list-notifications-only", false, "Only lists notifications without acting on them") flag.BoolVar(&ListPullNotificationsOnly, "list-notifications-only", false, "Only lists notifications without acting on them")
ProcessPROnly := flag.String("pr", "", "Process only specific PR and ignore the rest. Use for debugging") ProcessPROnly := flag.String("pr", "", "Process only specific PR and ignore the rest. Use for debugging")
buildRoot := flag.String("build-root", "", "Default build location for staging projects. Default is bot's home project") flag.StringVar(&BuildRoot, "build-root", "", "Default build location for staging projects. Default is bot's home project")
flag.StringVar(&GiteaUrl, "gitea-url", "https://src.opensuse.org", "Gitea instance") flag.StringVar(&GiteaUrl, "gitea-url", "https://src.opensuse.org", "Gitea instance")
flag.BoolVar(&GiteaUseSshClone, "use-ssh-clone", false, "enforce cloning via ssh") flag.BoolVar(&GiteaUseSshClone, "use-ssh-clone", false, "enforce cloning via ssh")
obsApiHost := flag.String("obs", "https://api.opensuse.org", "API for OBS instance") flag.StringVar(&ObsApiHost, "obs", "api.opensuse.org", "API for OBS instance")
flag.StringVar(&ObsWebHost, "obs-web", "", "Web OBS instance, if not derived from the obs config") flag.StringVar(&ObsWebHost, "obs-web", "", "Web OBS instance, if not derived from the obs config")
flag.BoolVar(&IsDryRun, "dry", false, "Dry-run, don't actually create any build projects or review changes") flag.BoolVar(&IsDryRun, "dry", false, "Dry-run, don't actually create any build projects or review changes")
debug := flag.Bool("debug", false, "Turns on debug logging") debug := flag.Bool("debug", false, "Turns on debug logging")
@@ -976,25 +805,12 @@ func main() {
} }
if len(ObsWebHost) == 0 { if len(ObsWebHost) == 0 {
ObsWebHost = ObsWebHostFromApiHost(*obsApiHost) ObsWebHost = ObsWebHostFromApiHost(ObsApiHost)
} }
common.LogDebug("OBS Web Host:", ObsWebHost)
common.LogDebug("OBS API Host:", *obsApiHost)
common.PanicOnErrorWithMsg(common.RequireGiteaSecretToken(), "Cannot find GITEA_TOKEN") common.PanicOnErrorWithMsg(common.RequireGiteaSecretToken(), "Cannot find GITEA_TOKEN")
common.PanicOnErrorWithMsg(common.RequireObsSecretToken(), "Cannot find OBS_USER and OBS_PASSWORD") common.PanicOnErrorWithMsg(common.RequireObsSecretToken(), "Cannot find OBS_USER and OBS_PASSWORD")
var err error
if ObsClient, err = common.NewObsClient(*obsApiHost); err != nil {
log.Error(err)
return
}
if len(*buildRoot) > 0 {
ObsClient.HomeProject = *buildRoot
}
if len(*ProcessPROnly) > 0 { if len(*ProcessPROnly) > 0 {
rx := regexp.MustCompile("^(\\w+)/(\\w+)#(\\d+)$") rx := regexp.MustCompile("^(\\w+)/(\\w+)#(\\d+)$")
m := rx.FindStringSubmatch(*ProcessPROnly) m := rx.FindStringSubmatch(*ProcessPROnly)
@@ -1012,6 +828,9 @@ func main() {
for { for {
PollWorkNotifications(GiteaUrl) PollWorkNotifications(GiteaUrl)
if *debug {
break
}
common.LogInfo("Poll cycle finished") common.LogInfo("Poll cycle finished")
time.Sleep(5 * time.Minute) time.Sleep(5 * time.Minute)
} }

Some files were not shown because too many files have changed in this diff Show More