2
1
forked from adamm/autogits

94 Commits

Author SHA256 Message Date
ec5ac4fca3 Don't fail on project git pull request creation. 2025-07-11 10:53:38 +02:00
d7132727a7 Create Pull Requests to specified branches
instead of always using DefaultBranch. This means that target needs
always gets specified now.
2025-07-11 10:52:00 +02:00
74f40f536a message typo 2025-07-11 09:40:36 +02:00
cde46e85f3 Enable code stream publishing 2025-07-11 09:40:36 +02:00
4378568953 Fix logic in crash protection
We must not access review.User object if it is nil
2025-07-11 09:40:36 +02:00
c286e12b67 Try to use Staging Master Project as default build target if available
This allows us to set custom build configuration or repository sets for
pull request projects.
2025-07-11 09:40:36 +02:00
cc9ad1703d Don't crash when new packages got added
The build result request of the base project is failing in this
situation, since the requested package does not exist.

Therefore we need to have seperate lists for proper handling.
2025-07-11 09:40:36 +02:00
2f8b6b4ade Temporary hack to include also changed directories
Need to be clean'd up via proper subdir handling
2025-07-11 09:40:36 +02:00
c11def6005 handle build results different when request with lastbuild=1
In that case we need to

 * ignore repo state as it is the current one. There is no last state
 * handle "unkown" state as finished as the package was never attempted,
   but we don't know the reason (eg. broken source or unresolvable)
2025-07-11 09:40:36 +02:00
0bee48472d Implementing cleanup of closed requests 2025-07-11 09:40:36 +02:00
f9021d08b9 PR: fix case where submodule cannot be initialized
Sometimes the commit is already cleaned up and Project Git cannot
be initialized. This should not be an error. Only fatal error
is if we can't update the PR to current state.
2025-07-10 18:28:09 +02:00
7a0394e51b PR: use "open" not "opened" as state 2025-07-10 16:54:28 +02:00
518bc15696 PR: close empty prjgit PRs 2025-07-09 20:39:38 +02:00
51873eb048 PR: log prjgit PrjGit creator 2025-07-09 20:06:13 +02:00
4f33ce979c PR: use MergeBase as ref. branch for prjgit
The target branch can be moving target, so not appropriate
2025-07-09 19:42:26 +02:00
7cc4db2283 common: prune removed remote branches
During a repository update, we need to remove branches that
no longer exist on remote from local cache.
2025-07-09 18:28:37 +02:00
4d9e2f8cab PR: update PrjGit PR when package PRs are removed or added 2025-07-09 18:05:05 +02:00
ed4f27a19e PR: refactor 2025-07-09 17:33:44 +02:00
e438b5b064 common: fix parsing of submodule commit id from tree object 2025-06-26 14:25:20 +02:00
885bb7e537 forward: fix logic
* fix approval/request changes string
* use common.DevelProject fetcher code
* fix parsing of Requests meta
2025-06-26 14:24:21 +02:00
977d75f6e9 reviews: only react to comment
also, reviews are reverse sorted.
fixed some bugs
2025-06-25 16:13:08 +02:00
42a9ee48e0 import: update config files 2025-06-24 16:03:33 +02:00
9333e5c3da PR: fix README quoting 2025-06-24 14:33:06 +02:00
5e29c88dc8 PR: fix README quoting 2025-06-24 14:32:23 +02:00
4f0f101620 importer: handle case of devel project in git 2025-06-23 18:48:09 +02:00
253f009da3 common: Add devel project query 2025-06-23 18:47:12 +02:00
5e66a14fa9 forward-bot: finish initial braindump 2025-06-17 23:39:47 +02:00
e79122e494 forward-bot: additional first code 2025-06-17 19:27:00 +02:00
0b4b1a4e21 common: Add basic OBS request APIs 2025-06-17 19:24:13 +02:00
0019546e30 forward-bot: initial skeleton 2025-06-17 00:46:26 +02:00
6438a8625a Replace PrjGit creation logic 2025-06-16 14:22:21 +02:00
3928fa6429 PR: use config project git branch, not default 2025-06-13 00:06:02 +02:00
e92ac4a592 PR: refactor 2025-06-12 23:51:04 +02:00
a1520ebfb0 PR: PRSet consistency check 2025-06-12 18:44:16 +02:00
c8d65a3ae5 PR: refactor
Move AssociatedPR fetching
2025-06-11 16:28:02 +02:00
b849a72f31 PR: request optional reviews
Ignore these reviews in approval, for otherwise they can be used
to fetch optional review information
2025-06-10 18:48:42 +02:00
568a2f3df8 PR: Add ability to parse optional reviewers
Document reviewer syntax in the Readme.md
2025-06-10 17:20:33 +02:00
30c8b2fe57 PR: require PRs to be in opened state
PR's that are not opened (eg. closed, or merged) cannot be part of
a consistent PRset. Either everything is merged, or everything should
be opened.
2025-06-10 16:31:44 +02:00
69b0f9a5ed PR: fix error logging 2025-06-10 15:59:07 +02:00
a283d4f26f PR: no submitter reviews needed 2025-06-07 21:52:47 +02:00
af898a6b8d pr: manual project only merge ok is manual merge ok 2025-06-07 21:42:11 +02:00
b89cdb7664 PR: fix parsing comments from timeline 2025-06-05 19:15:53 +02:00
d37bfaa9d3 common: workaround case when user do not have gitea accounts and cannot get reviews assigned 2025-06-04 14:59:46 +02:00
90cca05b31 common: fix maintainership parsing when no maintienrs explicitly set 2025-06-04 13:56:04 +02:00
7c229500c1 common: debug logging 2025-06-03 23:46:53 +02:00
290424c4a7 common: sort timeline in desc order 2025-06-03 23:42:02 +02:00
703fa101a4 group-review: fix crash in notification handling when no config 2025-06-03 17:48:09 +02:00
66e4982e2d group-review: fix build 2025-06-03 16:59:46 +02:00
09b1c415dd PR: fix deadlock in verification routines via git/org locking 2025-06-03 16:18:00 +02:00
629b941558 PR: use correct path for local repo cache 2025-06-03 14:13:58 +02:00
aa50481c00 PR: add test for unauthorized merge reviews 2025-06-03 10:48:17 +02:00
bc714ee22d PR: fix build 2025-06-03 10:40:49 +02:00
b8cc0357a7 PR: limit manual merge to Projects
Add "ManualMergeProject" to require "merge ok" sign-offs on
project level only
2025-06-03 00:07:34 +02:00
aed0ac3ee9 PR: allow maintainers to approve merges by default 2025-06-02 23:54:05 +02:00
cca3575596 PR: add "merge ok" manual merge option 2025-06-02 16:22:50 +02:00
69dcebcf74 common: use Timeline for reviews
Gitea doesn't keep track of Stale reviews well. We should parse
Timeline of a PR *always* and apply our own logic to this instead
2025-05-30 16:51:30 +02:00
7da9daddd5 direct: fix error formatting element 2025-05-27 12:33:51 +02:00
cd0c3bc759 common: fix tests 2025-05-27 12:11:21 +02:00
af096af507 pr: require manual merge options for repositories 2025-05-26 18:10:25 +02:00
d150c66427 common: update gitea APIs 2025-05-26 16:55:15 +02:00
3bef967023 wip 2025-05-16 17:57:02 +02:00
9c3658b33e pr: remove pending requests
Remove all pending review requests when we merge
2025-05-13 18:34:56 +02:00
6968cbc942 group-review: use URL and not hardcode amqps for rabbit 2025-05-13 16:43:16 +02:00
2cb7a065a9 common: extract timeline fetcher to common code 2025-05-13 15:32:38 +02:00
35058623a7 group-review: logic fixes
* Only look at reviews after last update or review request
* Re-request reviews if they are needed
* Use timeline to filter reviews
* Ignore reviews not associated with the group name

Issue: adamm/autogits#28
2025-05-13 14:53:10 +02:00
24fe165c46 reviews: use timeline and ignore reviews prior to last push 2025-05-12 19:44:10 +02:00
1498438fee pr: fix fetching for merging 2025-05-10 16:48:06 +02:00
4653904ded pr: merge - preliminary fixes 2025-05-09 17:28:35 +02:00
bd87bf8ce3 staging: reviewer can be nil
If a user is requested reviewer, but is then deleted in Gitea,
it is still there but as "nil" user that doesn't resolve.
2025-05-09 16:55:16 +02:00
364c3f4ab7 staging: fix logging and cache stale, cleaned up repos 2025-05-08 15:55:27 +02:00
fd8b7f1bee staging: add cleaned up notification cache 2025-05-08 14:49:46 +02:00
da32adb16b staging: cleanup logic
Add cleanup logic for finished requests

Merged PRs are immediatelly removed along with any QA subprojects
Unmerged closed PRs are removed after a day, default 48 hours
since closing.
2025-05-08 13:56:31 +02:00
1b5a0ad0c8 common: default cleanup delay is 48 for unmerged PRs 2025-05-08 13:56:13 +02:00
e78fdf4a09 common: set cookies when availalbe, not just 200 res code 2025-05-08 13:55:31 +02:00
0564a50fb5 remove debug code in OBS client 2025-05-08 13:24:20 +02:00
4f7db36123 handle build results different when request with lastbuild=1
In that case we need to

 * ignore repo state as it is the current one. There is no last state
 * handle "unkown" state as finished as the package was never attempted,
   but we don't know the reason (eg. broken source or unresolvable)
2025-05-08 10:49:09 +02:00
41d536ea1b common: fix parsing commit messages 2025-05-08 10:42:33 +02:00
91d915cc28 Drop release targets in pull request projects 2025-05-08 10:42:03 +02:00
c7a300119e Fix QA project setup handling 2025-05-08 10:41:30 +02:00
c5c3e1c115 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-08 10:28:38 +02:00
c93788d0ee pr: fixes 2025-05-07 16:10:16 +02:00
1e46f8d0ab common: fix tests 2025-05-07 13:41:59 +02:00
9963ae90ef common: fix tests 2025-05-07 12:45:26 +02:00
a9225bbd76 Merge branch 'refactor' into wip 2025-05-07 12:38:19 +02:00
801fff6e22 common: fix parsing commit messages 2025-05-07 12:31:11 +02:00
b4b0d075be staging: only mark as read when processing is done 2025-05-07 01:08:32 +02:00
16c2eb7090 staging fixes 2025-05-07 00:25:44 +02:00
3264ad1589 staging: status line requires write repo access 2025-05-07 00:05:57 +02:00
cb64635aea pr: use correct prjgit repo name 2025-05-06 23:59:51 +02:00
aeb4c20744 pr: reset submodules if they not agreed 2025-05-06 23:15:27 +02:00
da1df24666 wip 2025-05-06 18:06:04 +02:00
6b3c613f14 wip 2025-05-05 18:57:05 +02:00
eb997e1ae9 common: fix dynamic listening for events 2025-05-05 15:33:20 +02:00
f52d72e04a staging: use status line in PRs 2025-05-05 13:52:46 +02:00
106 changed files with 11325 additions and 1445 deletions

View File

@@ -1,13 +1,15 @@
all: build
api.json:
api.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
podman run --rm -v $$(pwd):/api ghcr.io/go-swagger/go-swagger generate client -f /api/api.json -t /api/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
api: gitea-generated/client/gitea_api_client.go mock_gitea_utils.go
swagger: gitea-generated/client/gitea_api_client.go
api:
go generate
build: api

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,7 @@ type BasicPR struct {
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) {
var ret BasicPR

View File

@@ -58,6 +58,10 @@ type AutogitConfig struct {
Branch string // branch name of PkgGit that aligns with PrjGit submodules
Reviewers []string // only used by `pr` workflow
ReviewGroups []ReviewGroup
Committers []string // group in addition to Reviewers and Maintainers that can order the bot around, mostly as helper for factory-maintainers
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
@@ -95,7 +99,7 @@ type GiteaFileContentAndRepoFetcher interface {
GiteaRepoFetcher
}
func PartiallyParseWorkflowConfig(data []byte) (*AutogitConfig, error) {
func UnmarshalWorkflowConfig(data []byte) (*AutogitConfig, error) {
var config AutogitConfig
data, err := hujson.Standardize(data)
if err != nil {
@@ -130,7 +134,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)
}
config, err := PartiallyParseWorkflowConfig(data)
config, err := UnmarshalWorkflowConfig(data)
if err != nil {
return nil, err
}
@@ -224,8 +228,9 @@ func (config *AutogitConfig) GetRemoteBranch() string {
}
type StagingConfig struct {
ObsProject string
RebuildAll bool
ObsProject string
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
StagingProject string
@@ -238,6 +243,7 @@ func ParseStagingConfig(data []byte) (*StagingConfig, error) {
if err != nil {
return nil, err
}
staging.CleanupDelay = 48
if err := json.Unmarshal(data, &staging); err != nil {
return nil, err
}

View File

@@ -10,6 +10,62 @@ import (
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) {
tests := []struct {
name string
@@ -41,10 +97,14 @@ func TestConfigWorkflowParser(t *testing.T) {
gitea.EXPECT().GetRepositoryFileContent("foo", "bar", "", "workflow.config").Return([]byte(test.config_json), "abc", nil)
gitea.EXPECT().GetRepository("foo", "bar").Return(&test.repo, nil)
_, err := common.ReadWorkflowConfig(gitea, "foo/bar")
config, err := common.ReadWorkflowConfig(gitea, "foo/bar")
if err != nil {
t.Fatal(err)
}
if config.ManualMergeOnly != false {
t.Fatal("This should be false")
}
})
}
}
@@ -82,7 +142,7 @@ func TestProjectGitParser(t *testing.T) {
res: [3]string{"oorg", "foo.bar", "point"},
},
{
name: "whitespace shouldn't matter",
name: "whitespace shouldn't matter",
prjgit: " oorg / \nfoo.bar\t # point ",
res: [3]string{"oorg", "foo.bar", "point"},
},

View File

@@ -33,3 +33,6 @@ const (
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,6 +28,7 @@ import (
"os/exec"
"path"
"path/filepath"
"slices"
"strings"
"sync"
)
@@ -43,6 +44,10 @@ type GitStatusLister interface {
GitStatus(cwd string) ([]GitStatusData, error)
}
type GitDiffLister interface {
GitDiff(cwd, base, head string) (string, error)
}
type Git interface {
// 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
@@ -62,6 +67,8 @@ type Git interface {
GitExecOrPanic(cwd string, params ...string)
GitExec(cwd string, params ...string) error
GitExecWithOutput(cwd string, params ...string) (string, error)
GitDiffLister
}
type GitHandlerImpl struct {
@@ -132,6 +139,7 @@ func (s *gitHandlerGeneratorImpl) CreateGitHandler(org string) (Git, error) {
}
func (s *gitHandlerGeneratorImpl) ReadExistingPath(org string) (Git, error) {
LogDebug("Locking git org:", org)
s.lock_lock.Lock()
defer s.lock_lock.Unlock()
@@ -153,6 +161,7 @@ func (s *gitHandlerGeneratorImpl) ReadExistingPath(org string) (Git, error) {
func (s *gitHandlerGeneratorImpl) ReleaseLock(org string) {
m, ok := s.lock[org]
if ok {
LogDebug("Unlocking git org:", org)
m.Unlock()
}
}
@@ -196,19 +205,26 @@ func (refs *GitReferences) addReference(id, branch string) {
}
func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) (string, error) {
LogDebug("Cloning", remoteUrl, " repo:", repo, " branch:", branch)
remoteUrlComp, err := ParseGitRemoteUrl(remoteUrl)
if err != nil {
return "", fmt.Errorf("Cannot parse remote URL: %w", err)
}
if len(branch) == 0 {
remoteBranch := "HEAD"
if len(branch) == 0 && remoteUrlComp != nil {
branch = remoteUrlComp.Commit
}
if len(branch) == 0 {
branch = "HEAD"
remoteBranch = branch
} else if len(branch) > 0 {
remoteBranch = branch
}
remoteName := remoteUrlComp.RemoteName()
LogDebug("Clone", *remoteUrlComp, " -> ", remoteName)
if remoteUrlComp != nil {
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 err = e.GitExec("", "clone", "--origin", remoteName, remoteUrl, repo); err != nil {
return remoteName, err
@@ -222,9 +238,39 @@ func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) (string, error
e.GitExecOrPanic(repo, "remote", "set-url", remoteName, remoteUrl)
}
e.GitExecOrPanic(repo, "fetch", remoteName, branch)
// check if we have submodule to deinit
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) {
@@ -246,6 +292,7 @@ func (e *GitHandlerImpl) GitRemoteHead(gitDir, remote, branchName string) (strin
}
func (e *GitHandlerImpl) Close() error {
LogDebug("Unlocking git lock")
e.lock.Unlock()
return nil
}
@@ -306,7 +353,7 @@ func (e *GitHandlerImpl) GitExecWithOutput(cwd string, params ...string) (string
cmd.Dir = filepath.Join(e.GitPath, cwd)
cmd.Stdin = nil
LogDebug("git execute:", cmd.Args)
LogDebug("git execute @", cwd, ":", cmd.Args)
out, err := cmd.CombinedOutput()
LogDebug(string(out))
if err != nil {
@@ -446,21 +493,29 @@ func parseGitMsg(data <-chan byte) (GitMsg, error) {
}, nil
}
func parseGitCommitHdr(data <-chan byte) ([2]string, error) {
func parseGitCommitHdr(oldHdr [2]string, data <-chan byte) ([2]string, int, error) {
hdr := make([]byte, 0, 60)
val := make([]byte, 0, 1000)
c := <-data
size := 1
if c != '\n' { // end of header marker
for ; c != ' '; c = <-data {
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 {
val = append(val, c)
size++
}
size++
}
return [2]string{string(hdr), string(val)}, nil
return [2]string{string(hdr), string(val)}, size, nil
}
func parseGitCommitMsg(data <-chan byte, l int) (string, error) {
@@ -470,7 +525,6 @@ func parseGitCommitMsg(data <-chan byte, l int) (string, error) {
msg = append(msg, c)
l--
}
// l--
if l != 0 {
return "", fmt.Errorf("Unexpected data in the git commit msg: l=%d", l)
@@ -490,12 +544,14 @@ func parseGitCommit(data <-chan byte) (GitCommit, error) {
var c GitCommit
l := hdr.size
for {
hdr, err := parseGitCommitHdr(data)
var hdr [2]string
hdr, size, err := parseGitCommitHdr(hdr, data)
if err != nil {
return GitCommit{}, nil
}
l -= size
if len(hdr[0])+len(hdr[1]) == 0 { // hdr end marker
if size == 1 {
break
}
@@ -503,10 +559,7 @@ func parseGitCommit(data <-chan byte) (GitCommit, error) {
case "tree":
c.Tree = hdr[1]
}
l -= len(hdr[0]) + len(hdr[1]) + 2
}
l--
c.Msg, err = parseGitCommitMsg(data, l)
return c, err
@@ -595,7 +648,7 @@ func (e *GitHandlerImpl) GitParseCommits(cwd string, commitIDs []string) (parsed
var done sync.Mutex
done.Lock()
data_in, data_out := ChanIO{make(chan byte, 256)}, ChanIO{make(chan byte, 70)}
data_in, data_out := ChanIO{make(chan byte)}, ChanIO{make(chan byte)}
parsedCommits = make([]GitCommit, 0, len(commitIDs))
go func() {
@@ -629,7 +682,12 @@ func (e *GitHandlerImpl) GitParseCommits(cwd string, commitIDs []string) (parsed
return len(data), nil
})
LogDebug("command run:", cmd.Args)
err = cmd.Run()
if e := cmd.Run(); e != nil {
LogError(e)
close(data_in.ch)
close(data_out.ch)
return nil, e
}
done.Lock()
return
@@ -640,7 +698,7 @@ func (e *GitHandlerImpl) GitCatFile(cwd, commitId, filename string) (data []byte
var done sync.Mutex
done.Lock()
data_in, data_out := ChanIO{make(chan byte, 256)}, ChanIO{make(chan byte, 70)}
data_in, data_out := ChanIO{make(chan byte)}, ChanIO{make(chan byte)}
go func() {
defer done.Unlock()
@@ -694,6 +752,7 @@ func (e *GitHandlerImpl) GitCatFile(cwd, commitId, filename string) (data []byte
})
LogDebug("command run:", cmd.Args)
if e := cmd.Run(); e != nil {
LogError(e)
close(data_in.ch)
close(data_out.ch)
return nil, e
@@ -708,7 +767,7 @@ func (e *GitHandlerImpl) GitSubmoduleList(gitPath, commitId string) (submoduleLi
submoduleList = make(map[string]string)
done.Lock()
data_in, data_out := ChanIO{make(chan byte, 256)}, ChanIO{make(chan byte, 70)}
data_in, data_out := ChanIO{make(chan byte)}, ChanIO{make(chan byte)}
go func() {
defer done.Unlock()
@@ -743,6 +802,7 @@ func (e *GitHandlerImpl) GitSubmoduleList(gitPath, commitId string) (submoduleLi
for _, te := range tree.items {
if te.isTree() {
trees[p+te.name+"/"] = te.hash
submoduleList[p+te.name] = te.hash
} else if te.isSubmodule() {
submoduleList[p+te.name] = te.hash
}
@@ -766,14 +826,19 @@ func (e *GitHandlerImpl) GitSubmoduleList(gitPath, commitId string) (submoduleLi
return len(data), nil
})
LogDebug("command run:", cmd.Args)
err = cmd.Run()
if e := cmd.Run(); e != nil {
LogError(e)
close(data_in.ch)
close(data_out.ch)
return submoduleList, e
}
done.Lock()
return submoduleList, err
}
func (e *GitHandlerImpl) GitSubmoduleCommitId(cwd, packageName, commitId string) (subCommitId string, valid bool) {
data_in, data_out := ChanIO{make(chan byte, 256)}, ChanIO{make(chan byte, 70)}
data_in, data_out := ChanIO{make(chan byte)}, ChanIO{make(chan byte)}
var wg sync.WaitGroup
wg.Add(1)
@@ -782,7 +847,7 @@ func (e *GitHandlerImpl) GitSubmoduleCommitId(cwd, packageName, commitId string)
go func() {
defer func() {
if recover() != nil {
subCommitId = "wrong"
subCommitId = ""
commitId = "ok"
valid = false
}
@@ -829,12 +894,15 @@ func (e *GitHandlerImpl) GitSubmoduleCommitId(cwd, packageName, commitId string)
return len(data), nil
})
LogDebug("command run:", cmd.Args)
if err := cmd.Run(); err != nil {
LogError("Error running command:", cmd.Args, err)
if e := cmd.Run(); e != nil {
LogError(e)
close(data_in.ch)
close(data_out.ch)
return subCommitId, false
}
wg.Wait()
return subCommitId, len(subCommitId) == len(commitId)
return subCommitId, len(subCommitId) > 0
}
const (
@@ -1011,3 +1079,26 @@ func (e *GitHandlerImpl) GitStatus(cwd string) (ret []GitStatusData, err error)
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,6 +54,8 @@ func TestGitClone(t *testing.T) {
},
}
return
execPath, err := os.Getwd()
if err != nil {
t.Fatal(err)
@@ -198,7 +200,7 @@ committer Adam Majer <amajer@suse.com> 1720709149 +0200
})
t.Run("parse multiline headers", func(t *testing.T) {
const commitData = "cae5831ab48470ff060a5aaa12eb6e5a7acaf91e commit 1491\x00" +
const commitData = "cae5831ab48470ff060a5aaa12eb6e5a7acaf91e commit 1492\000" +
`tree 1f9c8fe8099615d6d3921528402ac53f09213b02
parent e08a654fae0ecc91678819e0b62a2e014bad3339
author Yagiz Nizipli <yagiz@nizipli.com> 1720967314 -0400
@@ -230,7 +232,7 @@ Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ulises Gascón <ulisesgascongonzalez@gmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>` + "\x00"
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>` + "\000"
ch := make(chan byte, 5000)
for _, b := range []byte(commitData) {
@@ -251,6 +253,51 @@ Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>` + "\x00"
}
})
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) {
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"

View File

@@ -36,6 +36,12 @@ func (o *IssueEditIssueAttachmentReader) ReadResponse(response runtime.ClientRes
return nil, err
}
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:
result := NewIssueEditIssueAttachmentLocked()
if err := result.readResponse(response, consumer, o.formats); err != nil {
@@ -189,6 +195,78 @@ func (o *IssueEditIssueAttachmentNotFound) readResponse(response runtime.ClientR
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
func NewIssueEditIssueAttachmentLocked() *IssueEditIssueAttachmentLocked {
return &IssueEditIssueAttachmentLocked{}

View File

@@ -36,6 +36,12 @@ func (o *IssueEditIssueCommentAttachmentReader) ReadResponse(response runtime.Cl
return nil, err
}
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:
result := NewIssueEditIssueCommentAttachmentLocked()
if err := result.readResponse(response, consumer, o.formats); err != nil {
@@ -189,6 +195,78 @@ func (o *IssueEditIssueCommentAttachmentNotFound) readResponse(response runtime.
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
func NewIssueEditIssueCommentAttachmentLocked() *IssueEditIssueCommentAttachmentLocked {
return &IssueEditIssueCommentAttachmentLocked{}

View File

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

View File

@@ -30,6 +30,18 @@ func (o *IssueSearchIssuesReader) ReadResponse(response runtime.ClientResponse,
return nil, err
}
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:
return nil, runtime.NewAPIError("[GET /repos/issues/search] issueSearchIssues", response, response.Code())
}
@@ -102,3 +114,147 @@ func (o *IssueSearchIssuesOK) readResponse(response runtime.ClientResponse, cons
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

@@ -0,0 +1,242 @@
// 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

@@ -0,0 +1,464 @@
// 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

@@ -0,0 +1,194 @@
// 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

@@ -0,0 +1,402 @@
// 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

@@ -0,0 +1,196 @@
// 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

@@ -0,0 +1,150 @@
// 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,6 +36,12 @@ func (o *RepoEditReleaseAttachmentReader) ReadResponse(response runtime.ClientRe
return nil, err
}
return nil, result
case 422:
result := NewRepoEditReleaseAttachmentUnprocessableEntity()
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}/releases/{id}/assets/{attachment_id}] repoEditReleaseAttachment", response, response.Code())
}
@@ -166,3 +172,75 @@ func (o *RepoEditReleaseAttachmentNotFound) readResponse(response runtime.Client
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

@@ -0,0 +1,217 @@
// 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

@@ -0,0 +1,324 @@
// 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

@@ -0,0 +1,173 @@
// 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

@@ -0,0 +1,164 @@
// 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 of the file to get
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 string
@@ -75,7 +75,7 @@ type RepoGetRawFileOrLFSParams struct {
/* Ref.
The name of the commit/branch/tag. Default the repositorys default branch (usually master)
The name of the commit/branch/tag. Default the repositorys default branch
*/
Ref *string

View File

@@ -63,7 +63,7 @@ type RepoGetRawFileParams struct {
/* Filepath.
filepath of the file to get
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 string
@@ -75,7 +75,7 @@ type RepoGetRawFileParams struct {
/* Ref.
The name of the commit/branch/tag. Default the repositorys default branch (usually master)
The name of the commit/branch/tag. Default the repositorys default branch
*/
Ref *string

View File

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

View File

@@ -0,0 +1,196 @@
// 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

@@ -0,0 +1,168 @@
// 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.
page size of results
Page size of results
*/
Limit *int64
@@ -84,19 +84,27 @@ type RepoListPullRequestsParams struct {
/* Owner.
owner of the repo
Owner of the repo
*/
Owner string
/* Page.
page number of results to return (1-based)
Page number of results to return (1-based)
Default: 1
*/
Page *int64
/* Poster.
Filter by pull request author
*/
Poster *string
/* Repo.
name of the repo
Name of the repo
*/
Repo string
@@ -108,7 +116,9 @@ type RepoListPullRequestsParams struct {
/* State.
State of pull request: open or closed (optional)
State of pull request
Default: "open"
*/
State *string
@@ -129,7 +139,21 @@ func (o *RepoListPullRequestsParams) WithDefaults() *RepoListPullRequestsParams
//
// All values with no default are reset to their zero value.
func (o *RepoListPullRequestsParams) SetDefaults() {
// no default values defined for this parameter
var (
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
@@ -220,6 +244,17 @@ func (o *RepoListPullRequestsParams) SetPage(page *int64) {
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
func (o *RepoListPullRequestsParams) WithRepo(repo string) *RepoListPullRequestsParams {
o.SetRepo(repo)
@@ -328,6 +363,23 @@ 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
if err := r.SetPathParam("repo", o.Repo); err != nil {
return err

View File

@@ -36,6 +36,12 @@ func (o *RepoListPullRequestsReader) ReadResponse(response runtime.ClientRespons
return nil, err
}
return nil, result
case 500:
result := NewRepoListPullRequestsInternalServerError()
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}/pulls] repoListPullRequests", response, response.Code())
}
@@ -164,3 +170,75 @@ func (o *RepoListPullRequestsNotFound) readResponse(response runtime.ClientRespo
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

@@ -0,0 +1,173 @@
// 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

@@ -0,0 +1,104 @@
// 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

@@ -0,0 +1,194 @@
// 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

@@ -0,0 +1,246 @@
// 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 repos by attribute. Supported values are "alpha", "created", "updated", "size", and "id". Default is "alpha"
sort repos by attribute. Supported values are "alpha", "created", "updated", "size", "git_size", "lfs_size", "stars", "forks" and "id". Default is "alpha"
*/
Sort *string

View File

@@ -0,0 +1,216 @@
// 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

@@ -0,0 +1,194 @@
// 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

@@ -0,0 +1,306 @@
// 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

@@ -0,0 +1,306 @@
// 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,6 +127,8 @@ type ClientService interface {
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)
CreateCurrentUserRepo(params *CreateCurrentUserRepoParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*CreateCurrentUserRepoCreated, error)
@@ -193,6 +195,8 @@ type ClientService interface {
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)
RepoDelete(params *RepoDeleteParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoDeleteNoContent, error)
@@ -227,6 +231,8 @@ type ClientService interface {
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)
RepoDeleteTopic(params *RepoDeleteTopicParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoDeleteTopicNoContent, error)
@@ -253,6 +259,8 @@ type ClientService interface {
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)
RepoGet(params *RepoGetParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetOK, error)
@@ -293,6 +301,8 @@ type ClientService interface {
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)
RepoGetPullRequest(params *RepoGetPullRequestParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetPullRequestOK, error)
@@ -329,6 +339,8 @@ type ClientService interface {
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)
RepoGetWikiPageRevisions(params *RepoGetWikiPageRevisionsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetWikiPageRevisionsOK, error)
@@ -377,6 +389,8 @@ type ClientService interface {
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)
RepoListTeams(params *RepoListTeamsParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoListTeamsOK, error)
@@ -385,6 +399,8 @@ type ClientService interface {
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)
RepoMirrorSync(params *RepoMirrorSyncParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoMirrorSyncOK, error)
@@ -411,6 +427,10 @@ type ClientService interface {
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)
RepoUpdatePullRequest(params *RepoUpdatePullRequestParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoUpdatePullRequestOK, error)
@@ -553,6 +573,45 @@ func (a *Client) GetTree(params *GetTreeParams, authInfo runtime.ClientAuthInfoW
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
*/
@@ -987,7 +1046,7 @@ func (a *Client) RejectRepoTransfer(params *RejectRepoTransferParams, authInfo r
}
/*
RepoAddCollaborator adds a collaborator to a repository
RepoAddCollaborator adds or update a collaborator to a repository
*/
func (a *Client) RepoAddCollaborator(params *RepoAddCollaboratorParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoAddCollaboratorNoContent, error) {
// TODO: Validate the params before sending
@@ -1844,6 +1903,45 @@ func (a *Client) RepoCreateTag(params *RepoCreateTagParams, authInfo runtime.Cli
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
*/
@@ -2507,6 +2605,45 @@ func (a *Client) RepoDeleteTag(params *RepoDeleteTagParams, authInfo runtime.Cli
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
*/
@@ -3014,6 +3151,45 @@ func (a *Client) RepoEditReleaseAttachment(params *RepoEditReleaseAttachmentPara
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
*/
@@ -3366,7 +3542,7 @@ func (a *Client) RepoGetCombinedStatusByRef(params *RepoGetCombinedStatusByRefPa
}
/*
RepoGetCommitPullRequest gets the pull request of the commit
RepoGetCommitPullRequest gets the merged pull request of the commit
*/
func (a *Client) RepoGetCommitPullRequest(params *RepoGetCommitPullRequestParams, authInfo runtime.ClientAuthInfoWriter, opts ...ClientOption) (*RepoGetCommitPullRequestOK, error) {
// TODO: Validate the params before sending
@@ -3794,6 +3970,45 @@ func (a *Client) RepoGetLatestRelease(params *RepoGetLatestReleaseParams, authIn
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
*/
@@ -4119,7 +4334,7 @@ func (a *Client) RepoGetRawFile(params *RepoGetRawFileParams, authInfo runtime.C
Method: "GET",
PathPattern: "/repos/{owner}/{repo}/raw/{filepath}",
ProducesMediaTypes: []string{"application/octet-stream"},
ConsumesMediaTypes: []string{"application/octet-stream"},
ConsumesMediaTypes: []string{"application/json", "text/plain"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &RepoGetRawFileReader{formats: a.formats, writer: writer},
@@ -4390,7 +4605,7 @@ func (a *Client) RepoGetRunnerRegistrationToken(params *RepoGetRunnerRegistratio
op := &runtime.ClientOperation{
ID: "repoGetRunnerRegistrationToken",
Method: "GET",
PathPattern: "/repos/{owner}/{repo}/runners/registration-token",
PathPattern: "/repos/{owner}/{repo}/actions/runners/registration-token",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json", "text/plain"},
Schemes: []string{"http", "https"},
@@ -4496,6 +4711,45 @@ func (a *Client) RepoGetTag(params *RepoGetTagParams, authInfo runtime.ClientAut
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
*/
@@ -5432,6 +5686,45 @@ func (a *Client) RepoListSubscribers(params *RepoListSubscribersParams, authInfo
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
*/
@@ -5588,6 +5881,45 @@ func (a *Client) RepoMergePullRequest(params *RepoMergePullRequestParams, authIn
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
*/
@@ -6095,6 +6427,84 @@ func (a *Client) RepoUpdateAvatar(params *RepoUpdateAvatarParams, authInfo runti
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
*/

View File

@@ -0,0 +1,144 @@
// 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

@@ -0,0 +1,124 @@
// 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,6 +7,7 @@ package models
import (
"context"
"encoding/json"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
@@ -38,7 +39,8 @@ type Activity struct {
// is private
IsPrivate bool `json:"is_private,omitempty"`
// op type
// the type of action
// 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"`
// ref name
@@ -68,6 +70,10 @@ func (m *Activity) Validate(formats strfmt.Registry) error {
res = append(res, err)
}
if err := m.validateOpType(formats); err != nil {
res = append(res, err)
}
if err := m.validateActUser(formats); err != nil {
res = append(res, err)
}
@@ -98,6 +104,123 @@ func (m *Activity) validateCreated(formats strfmt.Registry) error {
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 {
if swag.IsZero(m.ActUser) { // not required
return nil

View File

@@ -7,9 +7,12 @@ package models
import (
"context"
"encoding/json"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// AddCollaboratorOption AddCollaboratorOption options when adding a user as a collaborator of a repository
@@ -18,11 +21,66 @@ import (
type AddCollaboratorOption struct {
// permission
// Enum: ["read","write","admin"]
Permission string `json:"permission,omitempty"`
}
// Validate validates this add collaborator option
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
}

View File

@@ -25,6 +25,9 @@ type BranchProtection struct {
// approvals whitelist usernames
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
// block admin merge override
BlockAdminMergeOverride bool `json:"block_admin_merge_override,omitempty"`
// block on official review requests
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests,omitempty"`
@@ -47,6 +50,12 @@ type BranchProtection struct {
// enable approvals whitelist
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
EnableMergeWhitelist bool `json:"enable_merge_whitelist,omitempty"`
@@ -59,6 +68,15 @@ type BranchProtection struct {
// enable status check
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
IgnoreStaleApprovals bool `json:"ignore_stale_approvals,omitempty"`
@@ -68,6 +86,9 @@ type BranchProtection struct {
// merge whitelist usernames
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
// priority
Priority int64 `json:"priority,omitempty"`
// protected file patterns
ProtectedFilePatterns string `json:"protected_file_patterns,omitempty"`

View File

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

View File

@@ -23,6 +23,9 @@ type CreateBranchProtectionOption struct {
// approvals whitelist usernames
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
// block admin merge override
BlockAdminMergeOverride bool `json:"block_admin_merge_override,omitempty"`
// block on official review requests
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests,omitempty"`
@@ -41,6 +44,12 @@ type CreateBranchProtectionOption struct {
// enable approvals whitelist
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
EnableMergeWhitelist bool `json:"enable_merge_whitelist,omitempty"`
@@ -53,6 +62,15 @@ type CreateBranchProtectionOption struct {
// enable status check
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
IgnoreStaleApprovals bool `json:"ignore_stale_approvals,omitempty"`
@@ -62,6 +80,9 @@ type CreateBranchProtectionOption struct {
// merge whitelist usernames
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
// priority
Priority int64 `json:"priority,omitempty"`
// protected file patterns
ProtectedFilePatterns string `json:"protected_file_patterns,omitempty"`

View File

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

View File

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

View File

@@ -0,0 +1,56 @@
// 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,6 +23,9 @@ type EditBranchProtectionOption struct {
// approvals whitelist usernames
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
// block admin merge override
BlockAdminMergeOverride bool `json:"block_admin_merge_override,omitempty"`
// block on official review requests
BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests,omitempty"`
@@ -38,6 +41,12 @@ type EditBranchProtectionOption struct {
// enable approvals whitelist
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
EnableMergeWhitelist bool `json:"enable_merge_whitelist,omitempty"`
@@ -50,6 +59,15 @@ type EditBranchProtectionOption struct {
// enable status check
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
IgnoreStaleApprovals bool `json:"ignore_stale_approvals,omitempty"`
@@ -59,6 +77,9 @@ type EditBranchProtectionOption struct {
// merge whitelist usernames
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
// priority
Priority int64 `json:"priority,omitempty"`
// protected file patterns
ProtectedFilePatterns string `json:"protected_file_patterns,omitempty"`

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,50 @@
// 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

@@ -0,0 +1,50 @@
// 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,6 +21,12 @@ import (
// swagger:model MigrateRepoOptions
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
AuthPassword string `json:"auth_password,omitempty"`

View File

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

View File

@@ -99,6 +99,9 @@ type PullRequest struct {
// 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)
ReviewComments int64 `json:"review_comments,omitempty"`
@@ -166,6 +169,10 @@ func (m *PullRequest) Validate(formats strfmt.Registry) error {
res = append(res, err)
}
if err := m.validateRequestedReviewersTeams(formats); err != nil {
res = append(res, err)
}
if err := m.validateUpdated(formats); err != nil {
res = append(res, err)
}
@@ -330,6 +337,32 @@ func (m *PullRequest) validateRequestedReviewers(formats strfmt.Registry) error
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 {
if swag.IsZero(m.Updated) { // not required
return nil
@@ -489,6 +522,10 @@ func (m *PullRequest) ContextValidate(ctx context.Context, formats strfmt.Regist
res = append(res, err)
}
if err := m.contextValidateRequestedReviewersTeams(ctx, formats); err != nil {
res = append(res, err)
}
if err := m.contextValidateAssignee(ctx, formats); err != nil {
res = append(res, err)
}
@@ -598,6 +635,31 @@ func (m *PullRequest) contextValidateRequestedReviewers(ctx context.Context, for
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 {
if m.Assignee != nil {

View File

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

View File

@@ -0,0 +1,106 @@
// 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

@@ -0,0 +1,50 @@
// 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

@@ -0,0 +1,71 @@
// 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,7 +29,6 @@ import (
"path"
"path/filepath"
"slices"
"strings"
"time"
transport "github.com/go-openapi/runtime/client"
@@ -67,10 +66,18 @@ const (
ReviewStateUnknown models.ReviewStateType = ""
)
type GiteaTimelineFetcher interface {
GetTimeline(org, repo string, idx int64) ([]*models.TimelineComment, error)
}
type GiteaComment interface {
AddComment(pr *models.PullRequest, comment string) error
}
type GiteaSetRepoOptions interface {
SetRepoOptions(owner, repo string, manual_merge bool) (*models.Repository, error)
}
type GiteaMaintainershipReader interface {
FetchMaintainershipFile(org, prjGit, branch string) ([]byte, string, error)
FetchMaintainershipDirFile(org, prjGit, branch, pkg string) ([]byte, string, error)
@@ -78,7 +85,19 @@ type GiteaMaintainershipReader interface {
type GiteaPRFetcher interface {
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 {
@@ -89,14 +108,19 @@ type GiteaCommentFetcher interface {
GetIssueComments(org, project string, issueNo int64) ([]*models.Comment, error)
}
type GiteaPRChecker interface {
type GiteaReviewTimelineFetcher interface {
GiteaReviewFetcher
GiteaTimelineFetcher
}
type GiteaPRChecker interface {
GiteaReviewTimelineFetcher
GiteaCommentFetcher
GiteaMaintainershipReader
}
type GiteaReviewFetcherAndRequester interface {
GiteaReviewFetcher
GiteaReviewTimelineFetcher
GiteaCommentFetcher
GiteaReviewRequester
}
@@ -105,6 +129,10 @@ type GiteaReviewRequester interface {
RequestReviews(pr *models.PullRequest, reviewer ...string) ([]*models.PullReview, error)
}
type GiteaReviewUnrequester interface {
UnrequestReview(org, repo string, id int64, reviwers ...string) error
}
type GiteaReviewer interface {
AddReviewComment(pr *models.PullRequest, state models.ReviewStateType, comment string) (*models.PullReview, error)
}
@@ -124,41 +152,44 @@ const (
CommitStatus_Error = "error"
)
type CommitStatus struct {
Context string
Description string
CommitStatus string
}
type GiteaCommitStatusSetter interface {
SetCommitStatus(org, repo, hash string, status *CommitStatus) error
SetCommitStatus(org, repo, hash string, status *models.CommitStatus) (*models.CommitStatus, error)
}
type GiteaCommitStatusGetter interface {
GetCommitStatus(org, repo, hash string) ([]*CommitStatus, error)
GetCommitStatus(org, repo, hash string) ([]*models.CommitStatus, error)
}
type Gitea interface {
GiteaComment
GiteaRepoFetcher
GiteaReviewRequester
GiteaReviewUnrequester
GiteaReviewer
GiteaPRFetcher
GiteaPRUpdater
GiteaCommitFetcher
GiteaReviewFetcher
GiteaCommentFetcher
GiteaTimelineFetcher
GiteaMaintainershipReader
GiteaFileContentReader
GiteaCommitStatusGetter
GiteaCommitStatusSetter
GiteaSetRepoOptions
GiteaTimelineFetcher
GetPullNotifications(since *time.Time) ([]*models.NotificationThread, error)
GetNotifications(Type string, since *time.Time) ([]*models.NotificationThread, error)
GetDoneNotifications(Type string, page int64) ([]*models.NotificationThread, error)
SetNotificationRead(notificationId int64) error
GetOrganization(orgName string) (*models.Organization, error)
GetOrganizationRepositories(orgName 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)
GetAssociatedPrjGitPR(prjGitOrg, prjGitRepo, refOrg, refRepo string, Index int64) (*models.PullRequest, error)
GetPullRequestFileContent(pr *models.PullRequest, path string) ([]byte, string, error)
GetRecentPullRequests(org, repo, branch string) ([]*models.PullRequest, error)
GetRecentCommits(org, repo, branch string, commitNo int64) ([]*models.Commit, error)
GetPullRequests(org, project string) ([]*models.PullRequest, error)
GetCurrentUser() (*models.User, error)
}
@@ -205,6 +236,96 @@ func (gitea *GiteaTransport) GetPullRequest(org, project string, num int64) (*mo
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) {
repo, err := gitea.client.Repository.RepoGet(repository.NewRepoGetParams().WithDefaults().WithOwner(org).WithRepo(pkg), gitea.transport.DefaultAuthentication)
if err != nil {
@@ -249,6 +370,25 @@ func (gitea *GiteaTransport) GetPullRequestReviews(org, project string, PRnum in
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) {
// limit := int64(20)
// var page int64
@@ -273,25 +413,73 @@ func (gitea *GiteaTransport) GetIssueComments(org, project string, issueNo int64
}
func (gitea *GiteaTransport) GetPullNotifications(since *time.Time) ([]*models.NotificationThread, error) {
bigLimit := int64(100000)
func (gitea *GiteaTransport) SetRepoOptions(owner, repo string, manual_merge bool) (*models.Repository, error) {
ok, err := gitea.client.Repository.RepoEdit(repository.NewRepoEditParams().WithOwner(owner).WithRepo(repo).WithBody(
&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 {
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
}
@@ -415,14 +603,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) {
prOptions := models.CreatePullRequestOption{
Base: repo.DefaultBranch,
Base: targetId,
Head: srcId,
Title: title,
Body: body,
}
if pr, err := gitea.client.Repository.RepoGetPullRequestByBaseHead(
repository.NewRepoGetPullRequestByBaseHeadParams().WithOwner(repo.Owner.UserName).WithRepo(repo.Name).WithBase(repo.DefaultBranch).WithHead(srcId),
repository.NewRepoGetPullRequestByBaseHeadParams().WithOwner(repo.Owner.UserName).WithRepo(repo.Name).WithBase(targetId).WithHead(srcId),
gitea.transport.DefaultAuthentication,
); err == nil {
return pr.Payload, nil
@@ -445,46 +633,6 @@ func (gitea *GiteaTransport) CreatePullRequestIfNotExist(repo *models.Repository
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) {
reviewOptions := models.PullReviewRequestOptions{
Reviewers: reviewers,
@@ -507,6 +655,14 @@ func (gitea *GiteaTransport) RequestReviews(pr *models.PullRequest, reviewers ..
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) {
c, err := gitea.client.Repository.RepoCreatePullReview(
repository.NewRepoCreatePullReviewParams().
@@ -561,6 +717,41 @@ func (gitea *GiteaTransport) AddComment(pr *models.PullRequest, comment string)
return nil
}
func (gitea *GiteaTransport) GetTimeline(org, repo string, idx int64) ([]*models.TimelineComment, error) {
limit := int64(20)
page := int64(1)
resCount := limit
retData := []*models.TimelineComment{}
for resCount == limit {
res, err := gitea.client.Issue.IssueGetCommentsAndTimeline(
issue.NewIssueGetCommentsAndTimelineParams().
WithOwner(org).
WithRepo(repo).
WithIndex(idx).
WithPage(&page).
WithLimit(&limit),
gitea.transport.DefaultAuthentication,
)
if err != nil {
return nil, err
}
resCount = int64(len(res.Payload))
page++
retData = append(retData, res.Payload...)
}
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) {
params := repository.NewRepoGetContentsParams().WithOwner(org).WithRepo(repo).WithFilepath(path)
if len(hash) > 0 {
@@ -632,7 +823,7 @@ endPrs:
}
// if pr is closed for more than a week, assume that we are done too
if time.Since(time.Time(pr.Updated)) > 7*24*time.Hour {
if pr.State == "closed" && time.Since(time.Time(pr.Updated)) > 7*24*time.Hour {
break endPrs
}

View File

@@ -149,7 +149,7 @@ func (l *ListenDefinitions) processRabbitMQ(msgCh chan<- RabbitMessage) error {
}
// log.Printf("queue: %s:%d", q.Name, q.Consumers)
LogInfo(" -- listening to topics:")
LogDebug(" -- listening to topics:")
l.topicSubChanges = make(chan string)
defer close(l.topicSubChanges)
go l.processTopicChanges(ch, q.Name)
@@ -264,6 +264,13 @@ next_new_topic:
l.topicSubChanges <- "+" + topic
}
}
for j < len(l.topics) {
l.topicSubChanges <- "-" + l.topics[j]
j++
}
l.topics = newTopics
}
func (l *ListenDefinitions) ProcessRabbitMQEvents() error {

View File

@@ -2,6 +2,7 @@ package common
import (
"net/url"
"slices"
"testing"
)
@@ -20,8 +21,29 @@ func TestListenDefinitionsTopicUpdate(t *testing.T) {
{
name: "adding one org",
handlers: []string{"foo"},
orgs2: []string{"newOrg"},
topicDelta: []string{"+suse"},
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.#"},
},
}
@@ -35,13 +57,42 @@ func TestListenDefinitionsTopicUpdate(t *testing.T) {
RabbitURL: u,
}
slices.Sort(test.topicDelta)
for _, r := range test.handlers {
l.Handlers[r] = nil
}
changes := []string{}
l.UpdateTopics()
if len(l.topicSubChanges) != len(test.topicDelta) {
t.Fatal("topicSubChanges", len(l.topicSubChanges), " != topicDelta", len(test.topicDelta))
a:
for {
select {
case c := <-l.topicSubChanges:
changes = append(changes, c)
default:
changes = []string{}
break a
}
}
l.Orgs = test.orgs2
l.UpdateTopics()
changes = []string{}
b:
for {
select {
case c := <-l.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

@@ -36,13 +36,14 @@ func CreateStdoutLogger(stdout, stderr io.Writer) (*log.Logger, *log.Logger) {
func PanicOnError(err error) {
if err != nil {
LogError(err)
panic(err)
}
}
func PanicOnErrorWithMsg(err error, msg string) {
func PanicOnErrorWithMsg(err error, msg ...any) {
if err != nil {
LogError(msg)
LogError(msg...)
panic(err)
}
}
@@ -51,18 +52,38 @@ type LogLevel int
const (
LogLevelNone = 0
LogLevelError = 2
LogLevelInfo = 5
LogLevelDebug = 10
)
var logLevel LogLevel
var logLevel LogLevel = LogLevelInfo
func SetLoggingLevel(ll LogLevel) {
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) {
log.Println(append([]any{"[E]"}, params...)...)
if logLevel >= LogLevelError {
log.Println(append([]any{"[E]"}, params...)...)
}
}
func LogDebug(params ...any) {

View File

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

View File

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

View File

@@ -25,7 +25,6 @@ import (
"errors"
"fmt"
"io"
"log"
"net/http"
"net/url"
"os/exec"
@@ -59,7 +58,7 @@ type ObsClient struct {
}
func NewObsClient(host string) (*ObsClient, error) {
baseUrl, err := url.Parse("https://" + host)
baseUrl, err := url.Parse(host)
if err != nil {
return nil, err
}
@@ -157,6 +156,34 @@ type GroupMeta struct {
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) {
var meta ProjectMeta
err := xml.Unmarshal(data, &meta)
@@ -167,8 +194,83 @@ func parseProjectMeta(data []byte) (*ProjectMeta, error) {
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) {
res, err := c.ObsRequest("GET", c.baseUrl.JoinPath("group", gid).String(), nil)
res, err := c.ObsRequest("GET", []string{"group", gid}, nil)
if err != nil {
return nil, err
}
@@ -186,6 +288,7 @@ func (c *ObsClient) GetGroupMeta(gid string) (*GroupMeta, error) {
if err != nil {
return nil, err
}
defer res.Body.Close()
var meta GroupMeta
err = xml.Unmarshal(data, &meta)
@@ -197,7 +300,7 @@ func (c *ObsClient) GetGroupMeta(gid string) (*GroupMeta, error) {
}
func (c *ObsClient) GetUserMeta(uid string) (*UserMeta, error) {
res, err := c.ObsRequest("GET", c.baseUrl.JoinPath("person", uid).String(), nil)
res, err := c.ObsRequest("GET", []string{"person", uid}, nil)
if err != nil {
return nil, err
}
@@ -215,6 +318,7 @@ func (c *ObsClient) GetUserMeta(uid string) (*UserMeta, error) {
if err != nil {
return nil, err
}
defer res.Body.Close()
var meta UserMeta
err = xml.Unmarshal(data, &meta)
@@ -225,7 +329,11 @@ func (c *ObsClient) GetUserMeta(uid string) (*UserMeta, error) {
return &meta, nil
}
func (c *ObsClient) ObsRequest(method string, url string, body io.Reader) (*http.Response, error) {
func (c *ObsClient) ObsRequest(method string, url_path []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)
if err != nil {
@@ -238,6 +346,12 @@ func (c *ObsClient) ObsRequest(method string, url string, body io.Reader) (*http
req.Header.Add("cookie", c.cookie)
}
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 {
auth_cookie := res.Header.Get("set-cookie")
if auth_cookie != "" {
@@ -248,6 +362,7 @@ func (c *ObsClient) ObsRequest(method string, url string, body io.Reader) (*http
if res.StatusCode == 401 {
if c.sshkey == "" {
LogDebug("setting basic auth")
req.SetBasicAuth(c.user, c.password)
} else {
www := res.Header.Get("www-authenticate")
@@ -290,28 +405,32 @@ func (c *ObsClient) ObsRequest(method string, url string, body io.Reader) (*http
// log.Printf("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
}
}
// Another time with authentification header
// log.Printf("Trying again with authorization: %s", req.Header.Get("Authorization"))
res, err = c.client.Do(req)
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
if err == nil {
// Store the cookie for next call
auth_cookie := res.Header.Get("set-cookie")
if auth_cookie != "" {
c.cookie = auth_cookie
}
}
return res, err
}
func (c *ObsClient) GetProjectMeta(project string) (*ProjectMeta, error) {
res, err := c.ObsRequest("GET", c.baseUrl.JoinPath("source", project, "_meta").String(), nil)
req := []string{"source", project, "_meta"}
res, err := c.ObsRequest("GET", req, nil)
if err != nil {
return nil, err
@@ -323,7 +442,7 @@ func (c *ObsClient) GetProjectMeta(project string) (*ProjectMeta, error) {
case 404:
return nil, nil
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)
@@ -331,11 +450,12 @@ func (c *ObsClient) GetProjectMeta(project string) (*ProjectMeta, error) {
return nil, err
}
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)
res, err := c.ObsRequest("GET", []string{"source", project, pkg, "_meta"}, nil)
if err != nil {
return nil, err
@@ -354,6 +474,7 @@ func (c *ObsClient) GetPackageMeta(project, pkg string) (*PackageMeta, error) {
if err != nil {
return nil, err
}
defer res.Body.Close()
var meta PackageMeta
err = xml.Unmarshal(data, &meta)
@@ -408,10 +529,11 @@ func (c *ObsClient) SetProjectMeta(meta *ProjectMeta) error {
return err
}
res, err := c.ObsRequest("PUT", c.baseUrl.JoinPath("source", meta.Name, "_meta").String(), io.NopCloser(bytes.NewReader(xml)))
res, err := c.ObsRequest("PUT", []string{"source", meta.Name, "_meta"}, io.NopCloser(bytes.NewReader(xml)))
if err != nil {
return err
}
defer res.Body.Close()
switch res.StatusCode {
case 200:
@@ -424,10 +546,15 @@ func (c *ObsClient) SetProjectMeta(meta *ProjectMeta) error {
}
func (c *ObsClient) DeleteProject(project string) error {
res, err := c.ObsRequest("DELETE", c.baseUrl.JoinPath("source", project).String(), nil)
url := c.baseUrl.JoinPath("source", project)
query := url.Query()
query.Add("force", "1")
url.RawQuery = query.Encode()
res, err := c.ObsRequestRaw("DELETE", url.String(), nil)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != 200 {
return fmt.Errorf("Unexpected return code: %d", res.StatusCode)
@@ -470,6 +597,8 @@ type BuildResultList struct {
XMLName xml.Name `xml:"resultlist"`
State string `xml:"state,attr"`
Result []BuildResult `xml:"result"`
isLastBuild bool
}
func (r *BuildResultList) GetPackageList() []string {
@@ -494,7 +623,7 @@ func (r *BuildResultList) GetPackageList() []string {
func (r *BuildResultList) BuildResultSummary() (success, finished bool) {
if r == nil {
return true, true
return false, false
}
finished = len(r.Result) > 0 && len(r.Result[0].Status) > 0
@@ -507,7 +636,7 @@ func (r *BuildResultList) BuildResultSummary() (success, finished bool) {
panic("Unknown repo result code: " + resultSet.Code)
}
finished = repoDetail.Finished
finished = r.isLastBuild || repoDetail.Finished
if !finished || resultSet.Dirty {
return
}
@@ -518,6 +647,11 @@ func (r *BuildResultList) BuildResultSummary() (success, finished bool) {
if !ok {
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
success = success && detail.Success
@@ -613,7 +747,7 @@ var ObsBuildStatusDetails map[string]ObsBuildStatusDetail = map[string]ObsBuildS
},
"unknown": ObsBuildStatusDetail{
Code: "unknown",
Description: "The scheduler has not yet evaluated this package. Should be a short intermediate state for new packages.",
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",
Finished: false,
},
@@ -690,14 +824,13 @@ func (obs ObsProjectNotFound) Error() string {
}
func (c *ObsClient) ProjectConfig(project string) (string, error) {
u := c.baseUrl.JoinPath("source", project, "_config")
res, err := c.ObsRequest("GET", u.String(), nil)
res, err := c.ObsRequest("GET", []string{"source", project, "_config"}, nil)
if err != nil {
return "", err
}
if data, err := io.ReadAll(res.Body); err == nil {
defer res.Body.Close()
return string(data), nil
} else {
return "", err
@@ -732,7 +865,7 @@ func (c *ObsClient) BuildStatusWithState(project string, opts *BuildResultOption
}
}
u.RawQuery = query.Encode()
res, err := c.ObsRequest("GET", u.String(), nil)
res, err := c.ObsRequestRaw("GET", u.String(), nil)
if err != nil {
return nil, err
}
@@ -750,5 +883,10 @@ func (c *ObsClient) BuildStatusWithState(project string, opts *BuildResultOption
if err != nil {
return nil, err
}
return parseBuildResults(data)
defer res.Body.Close()
ret, err := parseBuildResults(data)
if ret != nil {
ret.isLastBuild = opts.LastBuild
}
return ret, err
}

View File

@@ -55,6 +55,52 @@ 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 = `
<project name="home:adamm">
<title>Adam's Home Projects</title>

View File

@@ -13,25 +13,29 @@ import (
)
type PRInfo struct {
PR *models.PullRequest
Reviews *PRReviews
PR *models.PullRequest
Reviews *PRReviews
RemoteName string
}
type PRSet struct {
PRs []PRInfo
PRs []*PRInfo
Config *AutogitConfig
BotUser string
}
func readPRData(gitea GiteaPRFetcher, pr *models.PullRequest, currentSet []PRInfo, config *AutogitConfig) ([]PRInfo, error) {
func readPRData(gitea GiteaPRFetcher, pr *models.PullRequest, currentSet []*PRInfo, config *AutogitConfig) ([]*PRInfo, error) {
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 {
return nil, nil
}
}
retSet := []PRInfo{PRInfo{PR: pr}}
retSet := []*PRInfo{&PRInfo{PR: pr}}
// only need to extact there on PrjGit PR
if pr.Base.Repo.Name == config.GitProjectName && pr.Base.Repo.Owner.UserName == config.Organization {
org, repo, _ := config.GetPrjGit()
if pr.Base.Repo.Name == repo && pr.Base.Repo.Owner.UserName == org {
_, refPRs := ExtractDescriptionAndPRs(bufio.NewScanner(strings.NewReader(pr.Body)))
for _, prdata := range refPRs {
pr, err := gitea.GetPullRequest(prdata.Org, prdata.Repo, prdata.Num)
@@ -49,13 +53,52 @@ func readPRData(gitea GiteaPRFetcher, pr *models.PullRequest, currentSet []PRInf
return retSet, nil
}
func FetchPRSet(gitea GiteaPRFetcher, org, repo string, num int64, config *AutogitConfig) (*PRSet, error) {
var Timeline_RefIssueNotFound error = errors.New("RefIssue not found on the timeline")
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 err error
prjGitOrg, prjGitRepo, _ := config.GetPrjGit()
if prjGitOrg != org || prjGitRepo != config.GitProjectName {
if pr, err = gitea.GetAssociatedPrjGitPR(prjGitOrg, prjGitRepo, org, repo, num); err != nil {
if prjGitOrg == org && prjGitRepo == repo {
if pr, err = gitea.GetPullRequest(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
}
@@ -64,10 +107,6 @@ func FetchPRSet(gitea GiteaPRFetcher, org, repo string, num int64, config *Autog
return nil, err
}
}
} else {
if pr, err = gitea.GetPullRequest(org, repo, num); err != nil {
return nil, err
}
}
prs, err := readPRData(gitea, pr, nil, config)
@@ -75,22 +114,53 @@ func FetchPRSet(gitea GiteaPRFetcher, org, repo string, num int64, config *Autog
return nil, err
}
return &PRSet{PRs: prs, Config: config}, nil
return &PRSet{
PRs: prs,
Config: config,
BotUser: user,
}, nil
}
func (rs *PRSet) Contains(pr *models.PullRequest) 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 true
}
}
return false
}
func (rs *PRSet) AddPR(pr *models.PullRequest) error {
if rs.Contains(pr) {
return nil
}
rs.PRs = append(rs.PRs, &PRInfo{
PR: pr,
})
return nil
}
func (rs *PRSet) IsPrjGitPR(pr *models.PullRequest) bool {
return pr.Base.Repo.Name == rs.Config.GitProjectName && pr.Base.Repo.Owner.UserName == rs.Config.Organization
org, repo, branch := rs.Config.GetPrjGit()
return pr.Base.Name == branch && pr.Base.Repo.Name == repo && pr.Base.Repo.Owner.UserName == org
}
func (rs *PRSet) GetPrjGitPR() (*models.PullRequest, error) {
var ret *models.PullRequest
var PRSet_PrjGitMissing error = errors.New("No PrjGit PR found")
var PRSet_MultiplePrjGit error = errors.New("Multiple PrjGit PRs in one review set")
func (rs *PRSet) GetPrjGitPR() (*PRInfo, error) {
var ret *PRInfo
for _, prinfo := range rs.PRs {
if rs.IsPrjGitPR(prinfo.PR) {
if ret == nil {
ret = prinfo.PR
ret = prinfo
} else {
return nil, errors.New("Multiple PrjGit PRs in one review set")
return nil, PRSet_MultiplePrjGit
}
}
}
@@ -99,21 +169,28 @@ func (rs *PRSet) GetPrjGitPR() (*models.PullRequest, error) {
return ret, nil
}
return nil, errors.New("No PrjGit PR found")
return nil, PRSet_PrjGitMissing
}
func (rs *PRSet) IsConsistent() bool {
prjpr, err := rs.GetPrjGitPR()
prjpr_info, err := rs.GetPrjGitPR()
if err != nil {
return false
}
prjpr := prjpr_info.PR
_, prjpr_set := ExtractDescriptionAndPRs(bufio.NewScanner(strings.NewReader(prjpr.Body)))
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
}
next_rs:
for _, prinfo := range rs.PRs {
if prinfo.PR.State != "open" {
return false
}
if prjpr == prinfo.PR {
continue
}
@@ -133,24 +210,33 @@ func (rs *PRSet) AssignReviewers(gitea GiteaReviewFetcherAndRequester, maintaine
for _, pr := range rs.PRs {
reviewers := []string{}
if rs.IsPrjGitPR(pr.PR) {
reviewers = configReviewers.Prj
reviewers = slices.Concat(configReviewers.Prj, configReviewers.PrjOptional)
LogDebug("PrjGit submitter:", pr.PR.User.UserName)
if len(rs.PRs) == 1 {
reviewers = slices.Concat(reviewers, maintainers.ListProjectMaintainers())
}
} else {
pkg := pr.PR.Base.Repo.Name
reviewers = slices.Concat(configReviewers.Pkg, maintainers.ListProjectMaintainers(), maintainers.ListPackageMaintainers(pkg))
reviewers = slices.Concat(configReviewers.Pkg, maintainers.ListProjectMaintainers(), maintainers.ListPackageMaintainers(pkg), configReviewers.PkgOptional)
}
slices.Sort(reviewers)
reviewers = slices.Compact(reviewers)
// submitters do not need to review their own work
if idx := slices.Index(reviewers, pr.PR.User.UserName); 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
reviews, err := FetchGiteaReviews(gitea, reviewers, pr.PR.Base.Repo.Owner.UserName, pr.PR.Base.Repo.Name, pr.PR.Index)
if err != nil {
LogError("Error fetching reviews:", err)
return err
}
@@ -158,6 +244,7 @@ func (rs *PRSet) AssignReviewers(gitea GiteaReviewFetcherAndRequester, maintaine
user := reviewers[idx]
if reviews.HasPendingReviewBy(user) || reviews.IsReviewedBy(user) {
reviewers = slices.Delete(reviewers, idx, idx+1)
LogDebug("removing reviewer:", user)
} else {
idx++
}
@@ -165,8 +252,13 @@ func (rs *PRSet) AssignReviewers(gitea GiteaReviewFetcherAndRequester, maintaine
// get maintainers associated with the PR too
if len(reviewers) > 0 {
if _, err := gitea.RequestReviews(pr.PR, reviewers...); err != nil {
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)
LogDebug("Requesting reviews from:", reviewers)
if !IsDryRun {
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)
}
}
}
}
}
@@ -176,7 +268,54 @@ func (rs *PRSet) AssignReviewers(gitea GiteaReviewFetcherAndRequester, maintaine
func (rs *PRSet) IsApproved(gitea GiteaPRChecker, maintainers MaintainershipData) bool {
configReviewers := ParseReviewers(rs.Config.Reviewers)
is_reviewed := false
is_manually_reviewed_ok := 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")
return false
}
}
is_manually_reviewed_ok = true
}
if !is_manually_reviewed_ok {
LogInfo("manual merge not ok")
return false
}
}
for _, pr := range rs.PRs {
var reviewers []string
var pkg string
@@ -188,48 +327,60 @@ func (rs *PRSet) IsApproved(gitea GiteaPRChecker, maintainers MaintainershipData
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)
if err != nil {
return false
}
is_reviewed = r.IsApproved()
if !is_reviewed {
LogError("Cannot fetch gita reaviews for PR:", err)
return false
}
if is_reviewed = maintainers.IsApproved(pkg, r.reviews); !is_reviewed {
is_manually_reviewed_ok = r.IsApproved()
LogDebug(pr.PR.Base.Repo.Name, is_manually_reviewed_ok)
if !is_manually_reviewed_ok {
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_reviewed
return is_manually_reviewed_ok
}
func (rs *PRSet) Merge(gh GitHandlerGenerator) error {
prjgit, err := rs.GetPrjGitPR()
func (rs *PRSet) Merge(gitea GiteaReviewUnrequester, git Git) error {
prjgit_info, err := rs.GetPrjGitPR()
if err != nil {
return err
}
prjgit := prjgit_info.PR
git, err := gh.CreateGitHandler(rs.Config.Organization)
defer git.Close()
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)
remote, err := git.GitClone(DefaultGitPrj, rs.Config.Branch, prjgit.Base.Repo.SSHURL)
PanicOnError(err)
git.GitExecOrPanic(DefaultGitPrj, "fetch", remote, prjgit.Head.Sha)
// if other changes merged, check if we have conflicts
rev := strings.TrimSpace(git.GitExecWithOutputOrPanic(DefaultGitPrj, "merge-base", "HEAD", prjgit.Base.Sha, prjgit.Head.Sha))
if rev != prjgit.Base.Sha {
return fmt.Errorf("Base.Sha (%s) not yet merged into project-git. Aborting merge.", prjgit.Base.Sha)
}
/*
rev := strings.TrimSpace(git.GitExecWithOutputOrPanic(DefaultGitPrj, "merge-base", "HEAD", prjgit.Base.Sha, prjgit.Head.Sha))
if rev != 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")
if rev != prjgit.Base.Sha {
panic("FIXME")
}
*/
msg := "merging"
msg := fmt.Sprintf("Merging\n\nPR: %s/%s#%d", prjgit.Base.Repo.Owner.UserName, prjgit.Base.Repo.Name, prjgit.Index)
err = git.GitExec(DefaultGitPrj, "merge", "--no-ff", "-m", msg, prjgit.Head.Sha)
if err != nil {
@@ -303,31 +454,58 @@ func (rs *PRSet) Merge(gh GitHandlerGenerator) error {
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, "-c", "core.editor=true", "merge", "--continue")
}
}
}
// FF all non-prj git
// FF all non-prj git and unrequest reviews.
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) {
continue
}
git.GitExecOrPanic("", "clone", prinfo.PR.Base.Repo.SSHURL, prinfo.PR.Base.Name)
git.GitExecOrPanic(prinfo.PR.Base.Name, "fetch", "origin", prinfo.PR.Head.Sha)
git.GitExecOrPanic(prinfo.PR.Base.Name, "merge", "--ff", prinfo.PR.Head.Sha)
prinfo.RemoteName, err = git.GitClone(repo.Name, rs.Config.Branch, repo.SSHURL)
PanicOnError(err)
git.GitExecOrPanic(repo.Name, "fetch", prinfo.RemoteName, head.Sha)
git.GitExecOrPanic(repo.Name, "merge", "--ff", head.Sha)
}
// push changes
git.GitExecOrPanic(DefaultGitPrj, "push", "origin")
if !IsDryRun {
git.GitExecOrPanic(DefaultGitPrj, "push", remote)
} else {
LogInfo("*** WOULD push", DefaultGitPrj, "changes to", remote)
}
for _, prinfo := range rs.PRs {
if rs.IsPrjGitPR(prinfo.PR) {
continue
}
git.GitExecOrPanic(prinfo.PR.Base.Name, "push", "origin")
repo := prinfo.PR.Base.Repo
if !IsDryRun {
git.GitExecOrPanic(repo.Name, "push", prinfo.RemoteName)
} else {
LogInfo("*** WOULD push", repo.Name, "to", prinfo.RemoteName)
}
}
return nil

View File

@@ -6,6 +6,7 @@ import (
"os"
"os/exec"
"path"
"slices"
"strings"
"testing"
@@ -15,6 +16,21 @@ import (
mock_common "src.opensuse.org/autogits/common/mock"
)
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) {
baseConfig := common.AutogitConfig{
Reviewers: []string{"+super1", "*super2", "m1", "-m2"},
@@ -27,6 +43,7 @@ func TestPR(t *testing.T) {
pr *models.PullRequest
pr_err error
reviews []*models.PullReview
timeline []*models.TimelineComment
review_error error
}
@@ -40,26 +57,26 @@ func TestPR(t *testing.T) {
consistentSet bool
prjGitPRIndex int
reviewSetFetcher func(*mock_common.MockGiteaPRFetcher) (*common.PRSet, error)
reviewSetFetcher func(*mock_common.MockGiteaPRTimelineFetcher) (*common.PRSet, error)
}{
{
name: "Error fetching PullRequest",
data: []prdata{
{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")},
{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")},
},
prjGitPRIndex: -1,
},
{
name: "Error fetching PullRequest in PrjGit",
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"}}}}, 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"}}}}},
{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: "", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, State: "opened"}},
},
},
{
name: "Error fetching prjgit",
data: []prdata{
{pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}}},
{pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo", Owner: &models.User{UserName: "test"}}}, State: "opened"}},
},
resLen: 1,
prjGitPRIndex: -1,
@@ -67,8 +84,8 @@ func TestPR(t *testing.T) {
{
name: "Review set is consistent",
data: []prdata{
{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"}}}}},
{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: "PR: test/repo#42", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, State: "opened"}},
},
resLen: 2,
prjGitPRIndex: 1,
@@ -78,8 +95,8 @@ func TestPR(t *testing.T) {
{
name: "Review set is consistent: 1pkg",
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"}}}}},
{pr: &models.PullRequest{Body: "PR: test/repo#42", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}}},
{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: test/repo#42", Index: 22, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}, State: "opened"}},
},
resLen: 2,
prjGitPRIndex: 1,
@@ -88,9 +105,9 @@ func TestPR(t *testing.T) {
{
name: "Review set is consistent: 2pkg",
data: []prdata{
{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"}}}}},
{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"}}}}},
{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: "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: "some other desc\nPR: foo/fer#33", Index: 41, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo2", Owner: &models.User{UserName: "test"}}}, State: "opened"}},
},
resLen: 3,
prjGitPRIndex: 1,
@@ -100,7 +117,7 @@ func TestPR(t *testing.T) {
name: "Review set of prjgit PR is consistent",
data: []prdata{
{
pr: &models.PullRequest{Body: "", Index: 42, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "barPrj", Owner: &models.User{UserName: "foo"}}}},
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},
@@ -112,38 +129,385 @@ func TestPR(t *testing.T) {
prjGitPRIndex: 0,
consistentSet: true,
reviewed: true,
reviewSetFetcher: func(mock *mock_common.MockGiteaPRFetcher) (*common.PRSet, error) {
return common.FetchPRSet(mock, "foo", "barPrj", 42, &baseConfig)
reviewSetFetcher: func(mock *mock_common.MockGiteaPRTimelineFetcher) (*common.PRSet, error) {
return common.FetchPRSet("test", mock, "foo", "barPrj", 42, &baseConfig)
},
},
{
name: "Review set is consistent: 2pkg",
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"}}}}},
{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"}}}}},
{pr: &models.PullRequest{Body: "PR: foo/barPrj#20", Index: 41, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo2", Owner: &models.User{UserName: "test"}}}}},
{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: 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/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: foo/barPrj#20", Index: 41, Base: &models.PRBranchInfo{Repo: &models.Repository{Name: "repo2", Owner: &models.User{UserName: "test"}}}, State: "opened"}},
},
resLen: 3,
prjGitPRIndex: 2,
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 {
t.Run(test.name, func(t *testing.T) {
ctl := gomock.NewController(t)
pr_mock := mock_common.NewMockGiteaPRFetcher(ctl)
pr_mock := mock_common.NewMockGiteaPRTimelineFetcher(ctl)
review_mock := mock_common.NewMockGiteaPRChecker(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.prjGitPRIndex >= 0 {
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).
pr_mock.EXPECT().GetPullRequest(baseConfig.Organization, baseConfig.GitProjectName, test.prjGitPRIndex).
Return(test.data[test.prjGitPRIndex].pr, test.data[test.prjGitPRIndex].pr_err)
} else if test.prjGitPRIndex < 0 {
// no prjgit PR
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).
pr_mock.EXPECT().GetPullRequest(baseConfig.Organization, baseConfig.GitProjectName, gomock.Any()).
Return(nil, nil)
}
}
@@ -155,6 +519,10 @@ func TestPR(t *testing.T) {
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()
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
@@ -163,7 +531,7 @@ func TestPR(t *testing.T) {
if test.reviewSetFetcher != nil {
res, err = test.reviewSetFetcher(pr_mock)
} else {
res, err = common.FetchPRSet(pr_mock, "test", "repo", 42, &baseConfig)
res, err = common.FetchPRSet("test", pr_mock, "test", "repo", 42, &baseConfig)
}
if err == nil {
@@ -198,7 +566,7 @@ func TestPR(t *testing.T) {
pr_found := false
if test.prjGitPRIndex >= 0 {
for i := range test.data {
if PrjGitPR == test.data[i].pr && i == test.prjGitPRIndex {
if PrjGitPR.PR == test.data[i].pr && i == test.prjGitPRIndex {
t.Log("found at index", i)
pr_found = true
}
@@ -222,7 +590,9 @@ func TestPR(t *testing.T) {
*/
maintainers := mock_common.NewMockMaintainershipData(ctl)
maintainers.EXPECT().IsApproved(gomock.Any(), gomock.Any()).Return(true).AnyTimes()
maintainers.EXPECT().ListPackageMaintainers(gomock.Any()).Return([]string{}).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 {
t.Error("expected reviewed to be NOT", isApproved)
@@ -242,8 +612,10 @@ func TestPRAssignReviewers(t *testing.T) {
reviewer string
}
pkgReviews []*models.PullReview
prjReviews []*models.PullReview
pkgReviews []*models.PullReview
pkgTimeline []*models.TimelineComment
prjReviews []*models.PullReview
prjTimeline []*models.TimelineComment
expectedReviewerCall [2][]string
}{
@@ -331,8 +703,8 @@ func TestPRAssignReviewers(t *testing.T) {
},
pkgReviews: []*models.PullReview{
{
State: common.ReviewStateApproved,
User: &models.User{UserName: "user2"},
State: common.ReviewStateApproved,
User: &models.User{UserName: "user2"},
},
{
State: common.ReviewStatePending,
@@ -353,15 +725,59 @@ func TestPRAssignReviewers(t *testing.T) {
},
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 {
t.Run(test.name, func(t *testing.T) {
ctl := gomock.NewController(t)
pr_mock := mock_common.NewMockGiteaPRFetcher(ctl)
pr_mock := mock_common.NewMockGiteaPRTimelineFetcher(ctl)
review_mock := mock_common.NewMockGiteaReviewFetcherAndRequester(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{
Body: "Some description is here",
User: &models.User{UserName: "submitter"},
@@ -371,7 +787,8 @@ func TestPRAssignReviewers(t *testing.T) {
Index: 1,
}, nil)
review_mock.EXPECT().GetPullRequestReviews("other", "pkgrepo", int64(1)).Return(test.pkgReviews, nil)
pr_mock.EXPECT().GetAssociatedPrjGitPR("org", "repo", "other", "pkgrepo", int64(1)).Return(&models.PullRequest{
review_mock.EXPECT().GetTimeline("other", "pkgrepo", int64(1)).Return(test.pkgTimeline, nil)
pr_mock.EXPECT().GetPullRequest("org", "repo", int64(1)).Return(&models.PullRequest{
Body: fmt.Sprintf(common.PrPattern, "other", "pkgrepo", 1),
User: &models.User{UserName: "bot1"},
RequestedReviewers: []*models.User{{UserName: "main_reviewer"}},
@@ -380,11 +797,12 @@ func TestPRAssignReviewers(t *testing.T) {
Index: 42,
}, 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().ListPackageMaintainers("pkgrepo").Return([]string{"pkgmaintainer"}).AnyTimes()
prs, _ := common.FetchPRSet(pr_mock, "other", "pkgrepo", int64(1), &test.config)
prs, _ := common.FetchPRSet("test", pr_mock, "other", "pkgrepo", int64(1), &test.config)
if len(prs.PRs) != 2 {
t.Fatal("PRs not fetched")
}
@@ -393,8 +811,9 @@ func TestPRAssignReviewers(t *testing.T) {
if !prs.IsPrjGitPR(pr.PR) {
r = test.expectedReviewerCall[1]
}
if len(r) > 0 {
review_mock.EXPECT().RequestReviews(pr.PR, r).Return(nil, nil)
slices.Sort(r)
for _, reviewer := range r {
review_mock.EXPECT().RequestReviews(pr.PR, reviewer).Return(nil, nil)
}
}
prs.AssignReviewers(review_mock, maintainership_mock)
@@ -428,7 +847,7 @@ func TestPRAssignReviewers(t *testing.T) {
for _, test := range prjgit_tests {
t.Run(test.name, func(t *testing.T) {
ctl := gomock.NewController(t)
pr_mock := mock_common.NewMockGiteaPRFetcher(ctl)
pr_mock := mock_common.NewMockGiteaPRTimelineFetcher(ctl)
review_mock := mock_common.NewMockGiteaReviewFetcherAndRequester(ctl)
maintainership_mock := mock_common.NewMockMaintainershipData(ctl)
@@ -441,10 +860,11 @@ func TestPRAssignReviewers(t *testing.T) {
Index: 1,
}, 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()
prs, _ := common.FetchPRSet(pr_mock, "org", "repo", int64(1), &test.config)
prs, _ := common.FetchPRSet("test", pr_mock, "org", "repo", int64(1), &test.config)
if len(prs.PRs) != 1 {
t.Fatal("PRs not fetched")
}
@@ -453,8 +873,8 @@ func TestPRAssignReviewers(t *testing.T) {
if !prs.IsPrjGitPR(pr.PR) {
t.Fatal("only prjgit pr here")
}
if len(r) > 0 {
review_mock.EXPECT().RequestReviews(pr.PR, r).Return(nil, nil)
for _, reviewer := range r {
review_mock.EXPECT().RequestReviews(pr.PR, reviewer).Return(nil, nil)
}
}
prs.AssignReviewers(review_mock, maintainership_mock)
@@ -463,9 +883,11 @@ func TestPRAssignReviewers(t *testing.T) {
}
func TestPRMerge(t *testing.T) {
repoDir := t.TempDir()
cwd, _ := os.Getwd()
cmd := exec.Command("/usr/bin/bash", path.Join(cwd, "test_repo_setup.sh"))
cmd.Dir = t.TempDir()
cmd := exec.Command(path.Join(cwd, "test_repo_setup.sh"))
cmd.Dir = repoDir
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatal(string(out))
}
@@ -504,7 +926,7 @@ func TestPRMerge(t *testing.T) {
Owner: &models.User{
UserName: "org",
},
SSHURL: path.Join(cmd.Dir, "prjgit"),
SSHURL: "file://" + path.Join(repoDir, "prjgit"),
},
},
Head: &models.PRBranchInfo{
@@ -514,7 +936,7 @@ func TestPRMerge(t *testing.T) {
mergeError: "Aborting merge",
},
{
name: "Merge conflict in modules",
name: "Merge conflict in modules, auto-resolved",
pr: &models.PullRequest{
Base: &models.PRBranchInfo{
@@ -524,7 +946,7 @@ func TestPRMerge(t *testing.T) {
Owner: &models.User{
UserName: "org",
},
SSHURL: path.Join(cmd.Dir, "prjgit"),
SSHURL: "file://" + path.Join(cmd.Dir, "prjgit"),
},
},
Head: &models.PRBranchInfo{
@@ -537,19 +959,79 @@ func TestPRMerge(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctl := gomock.NewController(t)
mock := mock_common.NewMockGiteaPRFetcher(ctl)
mock := mock_common.NewMockGiteaPRTimelineFetcher(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)
set, err := common.FetchPRSet(mock, "org", "prj", 1, config)
set, err := common.FetchPRSet("test", mock, "org", "prj", 1, config)
if err != nil {
t.Fatal(err)
}
gh, _ := common.AllocateGitWorkTree("", "", "")
if err = set.Merge(gh); err != nil && (test.mergeError == "" || (len(test.mergeError) > 0 && !strings.Contains(err.Error(), test.mergeError))) {
gh, _ := common.AllocateGitWorkTree(testDir, "", "")
git, err := gh.CreateGitHandler("org")
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)
}
})
}
}
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

@@ -7,21 +7,33 @@ import (
type Reviewers struct {
Prj []string
Pkg []string
PrjOptional []string
PkgOptional []string
}
func ParseReviewers(input []string) *Reviewers {
r := &Reviewers{}
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] {
case '*':
r.Prj = append(r.Prj, reviewer[1:])
r.Pkg = append(r.Pkg, reviewer[1:])
*prj = append(*prj, reviewer[1:])
*pkg = append(*pkg, reviewer[1:])
case '-':
r.Prj = append(r.Prj, reviewer[1:])
*prj = append(*prj, reviewer[1:])
case '+':
r.Pkg = append(r.Pkg, reviewer[1:])
*pkg = append(*pkg, reviewer[1:])
default:
r.Pkg = append(r.Pkg, reviewer)
*pkg = append(*pkg, reviewer)
}
}

View File

@@ -12,8 +12,10 @@ func TestReviewers(t *testing.T) {
name string
input []string
prj []string
pkg []string
prj []string
pkg []string
pkg_optional []string
prj_optional []string
}{
{
name: "project and package reviewers",
@@ -22,6 +24,15 @@ func TestReviewers(t *testing.T) {
prj: []string{"5", "7", common.Bot_BuildReview},
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 {
@@ -31,7 +42,13 @@ func TestReviewers(t *testing.T) {
t.Error("unexpected return of ForProject():", reviewers.Prj)
}
if !slices.Equal(reviewers.Pkg, test.pkg) {
t.Error("unexpected return of ForProject():", reviewers.Pkg)
t.Error("unexpected return of ForPackage():", 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,7 +1,9 @@
package common
import (
"regexp"
"slices"
"strings"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
@@ -9,27 +11,96 @@ import (
type PRReviews struct {
reviews []*models.PullReview
reviewers []string
comments []*models.TimelineComment
}
func FetchGiteaReviews(rf GiteaReviewFetcher, reviewers []string, org, repo string, no int64) (*PRReviews, error) {
reviews, err := rf.GetPullRequestReviews(org, repo, no)
func FetchGiteaReviews(rf GiteaReviewTimelineFetcher, reviewers []string, org, repo string, no int64) (*PRReviews, error) {
timeline, err := rf.GetTimeline(org, repo, no)
if err != nil {
return nil, err
}
rawReviews, err := rf.GetPullRequestReviews(org, repo, no)
if err != nil {
return nil, err
}
reviews := make([]*models.PullReview, 0, 10)
var comments []*models.TimelineComment
for idx, item := range timeline {
if item.Type == TimelineCommentType_Review {
for _, r := range rawReviews {
if r.ID == item.ReviewID {
reviews = append(reviews, r)
break
}
}
} else if item.Type == TimelineCommentType_Comment {
comments = append(comments, item)
} else if item.Type == TimelineCommentType_PushPull {
timeline = timeline[0:idx]
break
} else {
LogDebug("Unhandled timeline type:", item.Type)
}
}
return &PRReviews{
reviews: reviews,
reviewers: reviewers,
comments: comments,
}, 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
}
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 {
goodReview := false
goodReview := true
for _, reviewer := range r.reviewers {
goodReview = false
for _, review := range r.reviews {
if review.User.UserName == reviewer && review.State == ReviewStateApproved && !review.Stale && !review.Dismissed {
LogDebug(" -- found review: ", review.User.UserName)
goodReview = true
break
}

View File

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

63
common/timeline.go Normal file
View File

@@ -0,0 +1,63 @@
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,11 +19,16 @@ package common
*/
import (
"bufio"
"errors"
"fmt"
"net/http"
"net/url"
"regexp"
"slices"
"strings"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
func SplitLines(str string) []string {
@@ -84,6 +89,11 @@ var valid_schemas []string = []string{"https", "ssh", "http", "file"}
func ParseGitRemoteUrl(urlString string) (*GitUrl, error) {
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) {
u, err := TranslateSshNativeToUrl(urlString)
if err != nil {
@@ -98,10 +108,7 @@ func ParseGitRemoteUrl(urlString string) (*GitUrl, error) {
}
org := e[0]
repo := e[1]
if len(repo) > 4 && repo[len(repo)-4:] == ".git" {
repo = repo[0 : len(repo)-4]
}
repo := strings.TrimSuffix(e[1], ".git")
u := GitUrl{
Org: org,
@@ -119,3 +126,51 @@ func (giturl *GitUrl) RemoteName() string {
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

@@ -168,13 +168,14 @@ func gitImporter(prj, pkg string) error {
func cloneDevel(git common.Git, gitDir, outName, urlString string) error {
url, err := url.Parse(urlString)
branch := url.Fragment
// branch := url.Fragment
url.Fragment = ""
params := []string{"clone"}
if len(branch) > 0 {
params = append(params, "-b", branch)
}
/* if len(branch) > 0 {
params = append(params, "-b", branch)
}
*/
params = append(params, url.String(), outName)
if err != nil {
@@ -206,6 +207,15 @@ func importRepos(packages []string) {
}
}
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))
for _, repo := range factoryRepos {
@@ -241,15 +251,11 @@ func importRepos(packages []string) {
}
// scmsync?
devel_project, err := runObsCommand("develproject", "openSUSE:Factory", pkg.Name)
if err != nil || len(devel_project) != 1 {
log.Panicln("devel project len:", len(devel_project), "for", pkg.Name, "err:", err)
devel_project, err := devel_projects.GetDevelProject(pkg.Name)
if err != nil {
log.Panicln("devel project not found for", pkg.Name, "err:", err)
}
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])
meta, _ := obs.GetPackageMeta(devel_project, pkg.Name)
if len(meta.ScmSync) > 0 {
if err2 := cloneDevel(git, "", pkg.Name, meta.ScmSync); err != nil {
log.Panicln(err2)
@@ -329,7 +335,7 @@ func importRepos(packages []string) {
break
} else {
log.Panicln(" *** factory has no branches", branches)
}
}
}
pool_branch := "factory"
@@ -700,6 +706,10 @@ func syncMaintainersToGitea(pkgs []string) {
devs := []string{}
for _, group := range prjMeta.Groups {
if group.GroupID == "factory-maintainers" {
log.Println("Ignoring factory-maintainers")
continue
}
teamMembers, err := obs.GetGroupMeta(group.GroupID)
if err != nil {
log.Panicln("failed to get group", err)
@@ -795,13 +805,20 @@ func createPrjGit() {
git.GitExecOrPanic(common.DefaultGitPrj, "add", "_config")
}
file, err = os.Create(path.Join(git.GetPath(), common.DefaultGitPrj, "project.build"))
file, err = os.Create(path.Join(git.GetPath(), common.DefaultGitPrj, "staging.config"))
if err != nil {
log.Panicln(err)
}
file.Write([]byte(prj))
file.WriteString("{\n // Reference build project\n \"ObsProject\": \""+prj+"\",\n}\n")
file.Close()
git.GitExecOrPanic(common.DefaultGitPrj, "add", "project.build")
git.GitExecOrPanic(common.DefaultGitPrj, "add", "staging.config")
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")
}
}
}
@@ -812,6 +829,8 @@ var git common.Git
var obs *common.ObsClient
var prj, org string
var forceBadPool bool
var forceNonPoolPackages bool
var devel_projects common.DevelProjects
func main() {
if err := common.RequireGiteaSecretToken(); err != nil {
@@ -828,6 +847,7 @@ func main() {
flags.SetOutput(helpString)
//workflowConfig := flag.String("config", "", "Repository and workflow definition file")
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")
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")
@@ -836,6 +856,7 @@ func main() {
getMaintainers := flags.Bool("maintainers-only", false, "Get maintainers only 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(&forceNonPoolPackages, "non-pool", false, "Allow packages that are not in pool to be created. WARNING: Can't add to factory later!")
if help := flags.Parse(os.Args[1:]); help == flag.ErrHelp || flags.NArg() != 2 {
printHelp(helpString.String())
@@ -847,25 +868,30 @@ func main() {
// r.SetDebug(true)
client = apiclient.New(r, nil)
obs, _ = common.NewObsClient("api.opensuse.org")
obs, _ = common.NewObsClient(*obsUrl)
gh := common.GitHandlerGeneratorImpl{}
var gh common.GitHandlerGenerator
var err error
git, err = gh.CreateGitHandler("Autogits - Devel Importer", "not.exist", "devel-importer")
devel_projects, err = common.FetchDevelProjects()
if err != nil {
log.Panicln("Failed to allocate git handler. Err:", err)
log.Panic("Cannot load devel projects:", err)
}
log.Println("# devel projects loaded:", len(devel_projects))
if DebugMode {
if len(*debugGitPath) > 0 {
git.Close()
git, err = gh.ReadExistingPath("Autogits - Devel Importer", "not.exist", *debugGitPath)
gh, err = common.AllocateGitWorkTree(*debugGitPath, "Autogits - Devel Importer", "not.exist")
if err != nil {
log.Panicln(err)
}
}
log.Println(" - working directory:" + git.GetPath())
} else {
defer git.Close()
dir, _ := os.MkdirTemp(os.TempDir(), "devel-importer")
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)
@@ -879,6 +905,13 @@ 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 {
if _, err := client.Organization.CreateOrgRepo(organization.NewCreateOrgRepoParams().WithOrg(org).WithBody(

2
go.mod
View File

@@ -8,6 +8,7 @@ require (
github.com/go-openapi/strfmt v0.23.0
github.com/go-openapi/swag v0.23.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/tailscale/hujson v0.0.0-20250226034555-ec1d1c113d33
go.uber.org/mock v0.5.0
@@ -27,7 +28,6 @@ require (
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
go.mongodb.org/mongo-driver v1.14.0 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect

View File

@@ -2,9 +2,11 @@ package main
import (
"flag"
"fmt"
"log"
"net/url"
"regexp"
"runtime/debug"
"slices"
"strconv"
"strings"
@@ -26,8 +28,9 @@ func InitRegex(groupName string) {
func ParseReviewLine(reviewText string) (bool, string) {
line := strings.TrimSpace(reviewText)
glen := len(groupName)
if len(line) < glen || line[0:glen] != groupName {
groupTextName := "@" + groupName
glen := len(groupTextName)
if len(line) < glen || line[0:glen] != groupTextName {
return false, line
}
@@ -54,92 +57,214 @@ func ReviewRejected(reviewText string) bool {
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) {
defer func() {
if r := recover(); r != nil {
log.Println("--- resovered")
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/(?<num>[0-9]+)$`)
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 {
log.Panicln("Invalid format of notification: %s", subject.URL)
common.LogError("Invalid format of notification:", subject.URL, err)
return
}
match := rx.FindStringSubmatch(u.Path)
if match == nil {
log.Panicf("** Unexpected format of notification: %s", subject.URL)
common.LogError("** Unexpected format of notification:", subject.URL)
return
}
org := match[1]
repo := match[2]
id, _ := strconv.ParseInt(match[3], 10, 64)
log.Printf("processing: %s/%s#%d\n", org, repo, id)
common.LogInfo("processing:", fmt.Sprintf("%s/%s#%d", org, repo, id))
pr, err := gitea.GetPullRequest(org, repo, id)
if err != nil {
log.Println(" ** Cannot fetch PR associated with review:", subject.URL, "Error:", err)
common.LogError(" ** 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
}
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" {
// dismiss the review
log.Println(" -- closed request, so nothing to review")
gitea.SetNotificationRead(notification.ID)
common.LogInfo(" -- closed request, so nothing to review")
if !common.IsDryRun {
gitea.SetNotificationRead(notification.ID)
}
return
}
reviews, err := gitea.GetPullRequestReviews(org, repo, id)
if err != nil {
log.Println(" ** No reviews associated with request:", subject.URL, "Error:", err)
common.LogInfo(" ** 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
}
requestReviewers, err := config.GetReviewGroupMembers(groupName)
if err != nil {
log.Println(err)
common.LogError(err)
return
}
// submitter cannot be reviewer
requestReviewers = slices.DeleteFunc(requestReviewers, func(u string) bool { return u == pr.User.UserName })
// pr.Head.Sha
for _, review := range reviews {
user := review.User.UserName
if !review.Stale && !review.Dismissed &&
slices.Contains(requestReviewers, user) {
if review.State == common.ReviewStateApproved && ReviewAccepted(review.Body) {
gitea.AddReviewComment(pr, common.ReviewStateApproved, "Signed off by: "+user)
if err := gitea.SetNotificationRead(notification.ID); err != nil {
log.Println(" Cannot set notification as read", err)
for _, reviewer := range requestReviewers {
if review := FindAcceptableReviewInTimeline(reviewer, timeline, reviews); review != nil {
if ReviewAccepted(review.Body) {
if !common.IsDryRun {
gitea.AddReviewComment(pr, common.ReviewStateApproved, "Signed off by: "+reviewer)
UnrequestReviews(gitea, org, repo, id, requestReviewers)
if !common.IsDryRun {
if err := gitea.SetNotificationRead(notification.ID); err != nil {
common.LogDebug(" Cannot set notification as read", err)
}
}
}
log.Println(" -> approved by", user)
common.LogInfo(" -> approved by", reviewer)
common.LogInfo(" review at", review.Created)
return
} else if review.State == common.ReviewStateRequestChanges && ReviewRejected(review.Body) {
gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Request changes. See review by: "+user)
if err := gitea.SetNotificationRead(notification.ID); err != nil {
log.Println(" Cannot set notification as read", err)
} else if ReviewRejected(review.Body) {
if !common.IsDryRun {
gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Changes requested. See review by: "+reviewer)
UnrequestReviews(gitea, org, repo, id, requestReviewers)
if err := gitea.SetNotificationRead(notification.ID); err != nil {
common.LogDebug(" Cannot set notification as read", err)
}
}
log.Println(" -> declined by", user)
common.LogInfo(" -> declined by", reviewer)
return
}
}
}
// request group member reviews, if missing
log.Println(" Requesting reviews for:", requestReviewers)
if _, err := gitea.RequestReviews(pr, requestReviewers...); err != nil {
log.Println(" -> err:", err)
common.LogDebug(" Review incomplete...")
if len(requestReviewers) > 0 {
common.LogDebug(" Requesting reviews for:", requestReviewers)
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) {
notifications, err := gitea.GetPullNotifications(nil)
notifications, err := gitea.GetNotifications(common.GiteaNotificationType_Pull, nil)
if err != nil {
log.Println(" EEE Error fetching unread notifications: %w", err)
common.LogError(" Error fetching unread notifications: %w", err)
return
}
@@ -151,9 +276,11 @@ func PeriodReviewCheck(gitea common.Gitea) {
func main() {
giteaUrl := flag.String("gitea-url", "https://src.opensuse.org", "Gitea instance used for reviews")
rabbitMqHost := flag.String("rabbit-host", "rabbit.opensuse.org", "RabbitMQ instance where Gitea webhook notifications are sent")
rabbitMqHost := flag.String("rabbit-url", "amqps://rabbit.opensuse.org", "RabbitMQ instance where Gitea webhook notifications are sent")
interval := flag.Int64("interval", 5, "Notification polling interval in minutes (min 1 min)")
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()
args := flag.Args()
@@ -166,29 +293,43 @@ func main() {
}
groupName = args[0]
if *configFile == "" {
common.LogError("Missing config file")
return
}
configData, err := common.ReadConfigFile(*configFile)
if err != nil {
log.Println("Failed to read config file", err)
common.LogError("Failed to read config file", err)
return
}
if err := common.RequireGiteaSecretToken(); err != nil {
log.Panicln(err)
common.LogError(err)
return
}
if err := common.RequireRabbitSecrets(); err != nil {
log.Panicln(err)
common.LogError(err)
return
}
gitea := common.AllocateGiteaTransport(*giteaUrl)
configs, err = common.ResolveWorkflowConfigs(gitea, configData)
if err != nil {
log.Panicln(err)
common.LogError("Cannot parse workflow configs:", err)
return
}
reviewer, err := gitea.GetCurrentUser()
if err != nil {
log.Panicln("Cannot fetch review user: %w", err)
common.LogError("Cannot fetch review user:", err)
return
}
if err := common.SetLoggingLevelFromString(*logging); err != nil {
common.LogError(err.Error())
return
}
if *interval < 1 {
@@ -197,31 +338,66 @@ func main() {
InitRegex(groupName)
log.Println(" ** processing group reviews for group:", groupName)
log.Println(" ** username in Gitea:", reviewer.UserName)
log.Println(" ** polling internval:", *interval, "min")
log.Println(" ** connecting to RabbitMQ:", *rabbitMqHost)
common.LogInfo(" ** processing group reviews for group:", groupName)
common.LogInfo(" ** username in Gitea:", reviewer.UserName)
common.LogInfo(" ** polling interval:", *interval, "min")
common.LogInfo(" ** connecting to RabbitMQ:", *rabbitMqHost)
if groupName != reviewer.UserName {
log.Println(" ***** Reviewer does not match group name. Aborting. *****")
common.LogError(" ***** Reviewer does not match group name. Aborting. *****")
return
}
u, err := url.Parse("amqps://" + *rabbitMqHost)
u, err := url.Parse(*rabbitMqHost)
if err != nil {
log.Panicln("Cannot parse RabbitMQ host:", err)
common.LogError("Cannot parse RabbitMQ host:", err)
return
}
configUpdates := &common.ListenDefinitions {
config_update := ConfigUpdatePush{
config_modified: make(chan *common.AutogitConfig),
}
configUpdates := &common.ListenDefinitions{
RabbitURL: u,
Orgs: []string{},
Handlers: map[string]common.RequestProcessor {
common.RequestType_Push: &ConfigUpdatePush{},
Orgs: []string{},
Handlers: map[string]common.RequestProcessor{
common.RequestType_Push: &config_update,
},
}
for _, c := range configs {
if org, _, _ := c.GetPrjGit(); !slices.Contains(configUpdates.Orgs, org) {
configUpdates.Orgs = append(configUpdates.Orgs, org)
}
}
go configUpdates.ProcessRabbitMQEvents()
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)
time.Sleep(time.Duration(*interval * int64(time.Minute)))
}

View File

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

1
obs-forward-bot/.gitignore vendored Normal file
View File

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

293
obs-forward-bot/main.go Normal file
View File

@@ -0,0 +1,293 @@
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,7 +33,9 @@ import (
"strings"
"time"
"github.com/opentracing/opentracing-go/log"
"src.opensuse.org/autogits/common"
"src.opensuse.org/autogits/common/gitea-generated/client/repository"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
@@ -105,15 +107,16 @@ const (
)
func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatusSummary {
if _, finished := project.BuildResultSummary(); !finished {
return BuildStatusSummaryBuilding
}
if _, finished := refProject.BuildResultSummary(); !finished {
common.LogDebug("refProject not finished building??")
return BuildStatusSummaryUnknown
}
if _, finished := project.BuildResultSummary(); !finished {
common.LogDebug("Still building...")
return BuildStatusSummaryBuilding
}
// the repositories should be setup equally between the projects. We
// need to verify that packages that are building in `refProject` are not
// failing in the `project`
@@ -130,6 +133,7 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
slices.SortFunc(project.Result, BuildResultSorter)
if refProject == nil {
// just return if buid finished and have some successes, since new package
common.LogInfo("New package. Only need some success...")
SomeSuccess := false
for i := 0; i < len(project.Result); i++ {
repoRes := &project.Result[i]
@@ -164,6 +168,7 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
slices.SortFunc(refProject.Result, BuildResultSorter)
common.LogDebug("comparing results", len(project.Result), "vs. ref", len(refProject.Result))
SomeSuccess := false
for i := 0; i < len(project.Result); i++ {
common.LogDebug("searching for", project.Result[i].Repository, "/", project.Result[i].Arch)
j := 0
@@ -175,9 +180,10 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
}
common.LogDebug(" found match for @ idx:", j)
res := ProcessRepoBuildStatus(project.Result[i].Status, refProject.Result[j].Status)
res, success := ProcessRepoBuildStatus(project.Result[i].Status, refProject.Result[j].Status)
switch res {
case BuildStatusSummarySuccess:
SomeSuccess = SomeSuccess || success
break found
default:
return res
@@ -191,28 +197,42 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
return BuildStatusSummaryUnknown
}
}
return BuildStatusSummarySuccess
if SomeSuccess {
return BuildStatusSummarySuccess
}
return BuildStatusSummaryFailed
}
func ProcessRepoBuildStatus(results, ref []common.PackageBuildStatus) BuildStatusSummary {
func ProcessRepoBuildStatus(results, ref []common.PackageBuildStatus) (status BuildStatusSummary, SomeSuccess bool) {
PackageBuildStatusSorter := func(a, b common.PackageBuildStatus) int {
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
slices.SortFunc(results, PackageBuildStatusSorter)
slices.SortFunc(ref, PackageBuildStatusSorter)
j := 0
SomeSuccess = false
for i := 0; i < len(results); i++ {
res, ok := common.ObsBuildStatusDetails[results[i].Code]
if !ok {
common.LogInfo("unknown package result code:", results[i].Code, "for package:", results[i].Package)
return BuildStatusSummaryUnknown
return BuildStatusSummaryUnknown, SomeSuccess
}
if !res.Finished {
return BuildStatusSummaryBuilding
return BuildStatusSummaryBuilding, SomeSuccess
}
if !res.Success {
@@ -224,7 +244,7 @@ func ProcessRepoBuildStatus(results, ref []common.PackageBuildStatus) BuildStatu
refRes, ok := common.ObsBuildStatusDetails[ref[j].Code]
if !ok {
common.LogInfo("unknown ref package result code:", ref[j].Code, "package:", ref[j].Package)
return BuildStatusSummaryUnknown
return BuildStatusSummaryUnknown, SomeSuccess
}
if !refRes.Finished {
@@ -232,16 +252,18 @@ func ProcessRepoBuildStatus(results, ref []common.PackageBuildStatus) BuildStatu
}
if refRes.Success {
return BuildStatusSummaryFailed
return BuildStatusSummaryFailed, SomeSuccess
}
}
} else {
SomeSuccess = true
}
}
return BuildStatusSummarySuccess
return BuildStatusSummarySuccess, SomeSuccess
}
func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullRequest, obsClient *common.ObsClient, stagingPrj, buildPrj string) (*common.ProjectMeta, error) {
func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullRequest, stagingPrj, buildPrj string, stagingMasterPrj string) (*common.ProjectMeta, error) {
common.LogDebug("repo content fetching ...")
err := FetchPrGit(git, pr)
if err != nil {
@@ -267,7 +289,15 @@ func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullReque
}
}
meta, err := obsClient.GetProjectMeta(buildPrj)
common.LogDebug("Trying first staging master project: ", stagingMasterPrj)
meta, err := ObsClient.GetProjectMeta(stagingMasterPrj)
if err == nil {
// success, so we use that staging master project as our build project
buildPrj = stagingMasterPrj
} else {
common.LogInfo("error fetching project meta for ", stagingMasterPrj, ". Fall Back to ", buildPrj)
meta, err = ObsClient.GetProjectMeta(buildPrj)
}
if err != nil {
common.LogError("error fetching project meta for", buildPrj, ". Err:", err)
return nil, err
@@ -293,17 +323,30 @@ func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullReque
}
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.PublicFlags = common.Flags{Contents: "<disable/>"}
// QE wants it published ... also we should not hardcode it here, since
// it is configurable via the :PullRequest project
// meta.PublicFlags = common.Flags{Contents: "<disable/>"}
meta.Groups = nil
meta.Persons = nil
// set paths to parent project
for idx, r := range meta.Repositories {
meta.Repositories[idx].Paths = []common.RepositoryPathMeta{{
Project: buildPrj,
Repository: r.Name,
}}
meta.Repositories[idx].ReleaseTargets = nil
localRepository := false
for pidx, path := range r.Paths {
// Check for path building against a repo in template project itself
if path.Project == buildPrj {
meta.Repositories[idx].Paths[pidx].Project = meta.Name
localRepository = true
}
}
if localRepository != true {
meta.Repositories[idx].Paths = []common.RepositoryPathMeta{{
Project: buildPrj,
Repository: r.Name,
}}
}
}
return meta, nil
}
@@ -314,9 +357,9 @@ func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullReque
// stagingProject:$buildProject
// ^- stagingProject:$buildProject:$subProjectName (based on templateProject)
func CreateQASubProject(stagingConfig *common.StagingConfig, git common.Git, gitea common.Gitea, pr *models.PullRequest, obsClient *common.ObsClient, stagingProject, templateProject, subProjectName string) error {
func CreateQASubProject(stagingConfig *common.StagingConfig, git common.Git, gitea common.Gitea, pr *models.PullRequest, stagingProject, templateProject, subProjectName string) error {
common.LogDebug("Setup QA sub projects")
templateMeta, err := obsClient.GetProjectMeta(templateProject)
templateMeta, err := ObsClient.GetProjectMeta(templateProject)
if err != nil {
common.LogError("error fetching template project meta for", templateProject, ":", err)
return err
@@ -340,7 +383,7 @@ func CreateQASubProject(stagingConfig *common.StagingConfig, git common.Git, git
}
if !IsDryRun {
err = obsClient.SetProjectMeta(templateMeta)
err = ObsClient.SetProjectMeta(templateMeta)
if err != nil {
common.LogError("cannot create project:", templateMeta.Name, err)
return err
@@ -352,10 +395,10 @@ func CreateQASubProject(stagingConfig *common.StagingConfig, git common.Git, git
return nil
}
func StartOrUpdateBuild(config *common.StagingConfig, git common.Git, gitea common.Gitea, pr *models.PullRequest, obsClient *common.ObsClient) (RequestModification, error) {
func StartOrUpdateBuild(config *common.StagingConfig, git common.Git, gitea common.Gitea, pr *models.PullRequest) (RequestModification, error) {
common.LogDebug("fetching OBS project Meta")
obsPrProject := GetObsProjectAssociatedWithPr(config, obsClient.HomeProject, pr)
meta, err := obsClient.GetProjectMeta(obsPrProject)
obsPrProject := GetObsProjectAssociatedWithPr(config, ObsClient.HomeProject, pr)
meta, err := ObsClient.GetProjectMeta(obsPrProject)
if err != nil {
common.LogError("error fetching project meta for", obsPrProject, ":", err)
return RequestModificationNoChange, err
@@ -379,7 +422,8 @@ func StartOrUpdateBuild(config *common.StagingConfig, git common.Git, gitea comm
var state RequestModification = RequestModificationSourceChanged
if meta == nil {
// new build
meta, err = GenerateObsPrjMeta(git, gitea, pr, obsClient, obsPrProject, config.ObsProject)
common.LogDebug(" Staging master:", config.StagingProject)
meta, err = GenerateObsPrjMeta(git, gitea, pr, obsPrProject, config.ObsProject, config.StagingProject)
if err != nil {
return RequestModificationNoChange, err
}
@@ -391,8 +435,10 @@ func StartOrUpdateBuild(config *common.StagingConfig, git common.Git, gitea comm
common.LogDebug("Creating build project:")
common.LogDebug(" meta:", string(x))
} else {
err = obsClient.SetProjectMeta(meta)
err = ObsClient.SetProjectMeta(meta)
if err != nil {
x, _ := xml.MarshalIndent(meta, "", " ")
common.LogDebug(" meta:", string(x))
common.LogError("cannot create meta project:", err)
return RequestModificationNoChange, err
}
@@ -403,7 +449,7 @@ func StartOrUpdateBuild(config *common.StagingConfig, git common.Git, gitea comm
func IsReviewerRequested(pr *models.PullRequest) bool {
for _, reviewer := range pr.RequestedReviewers {
if reviewer.UserName == Username {
if reviewer != nil && reviewer.UserName == Username {
return true
}
}
@@ -426,7 +472,7 @@ func FetchOurLatestActionableReview(gitea common.Gitea, org, repo string, id int
for idx := len(reviews) - 1; idx >= 0; idx-- {
review := reviews[idx]
if review.User != nil || review.User.UserName == Username {
if review.User == nil || review.User.UserName == Username {
if IsDryRun {
// for purposes of moving forward a no-op check
return review, nil
@@ -445,6 +491,21 @@ func FetchOurLatestActionableReview(gitea common.Gitea, org, repo string, id int
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) {
defer func() {
err := recover()
@@ -454,28 +515,125 @@ func ProcessPullNotification(gitea common.Gitea, thread *models.NotificationThre
}
}()
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 {
common.LogError("Unexpected format of notification:", notification.URL)
org, repo, num, err := ParseNotificationToPR(thread)
if err != nil {
common.LogError(err.Error())
return
}
common.LogInfo("processing PR:", org, "/", repo, "#", num)
common.LogInfo("processing PR:", match[1], "/", match[2], "#", match[3])
org := match[1]
repo := match[2]
id, _ := strconv.ParseInt(match[3], 10, 64)
err := ProcessPullRequest(gitea, org, repo, id)
if !IsDryRun && err == nil {
done, err := ProcessPullRequest(gitea, org, repo, num)
if !IsDryRun && err == nil && done {
gitea.SetNotificationRead(thread.ID)
} else if err != nil {
common.LogError(err)
}
}
func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) error {
var CleanedUpIssues []int64 = []int64{}
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)
common.PanicOnError(err)
if IsDryRun {
@@ -494,84 +652,101 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) error {
pr, err := gitea.GetPullRequest(org, repo, id)
if err != nil {
common.LogError("No PR associated with review:", org, "/", repo, "#", id, "Error:", err)
return err
return true, err
}
common.LogDebug("PR state:", pr.State)
if pr.State == "closed" {
// dismiss the review
common.LogInfo(" -- closed request, so nothing to review")
return nil
}
obsClient, err := common.NewObsClient(ObsApiHost)
if err != nil {
return err
}
if len(BuildRoot) > 0 {
obsClient.HomeProject = BuildRoot
return true, nil
}
if !IsReviewerRequested(pr) {
common.LogError("Review not requested in notification. Setting to status 'read'")
if !IsDryRun {
return nil
return true, nil
} else {
common.LogDebug(" -- continueing dry mode")
}
}
if review, err := FetchOurLatestActionableReview(gitea, org, repo, id); err == nil {
// Fetching data
review, review_error := FetchOurLatestActionableReview(gitea, org, repo, id)
if pr.State != "closed" && review_error != nil {
// Nothing to do
return true, nil
}
err = FetchPrGit(git, pr)
if err != nil {
common.LogError("Cannot fetch PR git:", pr.URL)
return false, err
}
// we want the possibly pending modification here, in case stagings are added, etc.
// jobs of review team to deal with issues
common.LogDebug("QA configuration fetching ...", common.StagingConfigFile)
data, err := git.GitCatFile(pr.Head.Sha, pr.Head.Sha, common.StagingConfigFile)
if err != nil {
common.LogError("Staging config", common.StagingConfigFile, "not found in PR to the project. Aborting.")
if !IsDryRun {
_, err = gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot find project config in PR: "+common.ProjectConfigFile)
}
return true, err
}
stagingConfig, err := common.ParseStagingConfig(data)
if err != nil {
common.LogError("Error parsing config file", common.StagingConfigFile, err)
}
if stagingConfig.ObsProject == "" {
common.LogError("Cannot find reference project for PR#", pr.Index)
if !IsDryRun && review_error == nil {
_, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot find reference project")
return true, err
}
return true, nil
}
common.LogDebug("ObsProject:", stagingConfig.ObsProject)
stagingProject := GetObsProjectAssociatedWithPr(stagingConfig, ObsClient.HomeProject, pr)
// Cleanup projects
if pr.State == "closed" {
// review is done, cleanup
common.LogInfo(" -- closed request, cleanup staging projects")
for _, setup := range stagingConfig.QA {
if !IsDryRun {
ObsClient.DeleteProject(stagingProject + ":" + setup.Name)
}
}
if stagingProject != "" {
if !IsDryRun {
ObsClient.DeleteProject(stagingProject)
}
}
return true, nil
}
// Process review aka setup projects
if review_error == nil {
common.LogInfo("processing review", review.HTMLURL, "state", review.State)
err = FetchPrGit(git, pr)
meta, err := ObsClient.GetProjectMeta(stagingConfig.ObsProject)
if err != nil {
common.LogError("Cannot fetch PR git:", pr.URL)
return err
}
// we want the possibly pending modification here, in case stagings are added, etc.
// jobs of review team to deal with issues
common.LogDebug("QA configuration fetching ...", common.StagingConfigFile)
QA := []common.QAConfig{}
data, err := git.GitCatFile(pr.Head.Sha, pr.Head.Sha, common.StagingConfigFile)
if err != nil {
common.LogError("Staging config", common.StagingConfigFile, "not found in PR to the project. Aborting.")
if !IsDryRun {
_, err = gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot find project config in PR: "+common.ProjectConfigFile)
}
return err
}
stagingConfig, err := common.ParseStagingConfig(data)
if err != nil {
common.LogError("Error parsing config file", common.StagingConfigFile, err)
}
if stagingConfig.ObsProject == "" {
common.LogError("Cannot find reference project for PR#", pr.Index)
if !IsDryRun {
_, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot find reference project")
return err
}
return nil
}
meta, err := obsClient.GetProjectMeta(stagingConfig.ObsProject)
if err != nil {
common.LogError("Cannot find reference project meta:", stagingConfig.ObsProject)
common.LogError("Cannot find reference project meta:", stagingConfig.ObsProject, err)
if !IsDryRun {
_, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot fetch reference project meta")
return err
return true, err
}
return nil
return true, nil
}
if metaUrl, err := url.Parse(meta.ScmSync); err != nil {
return err
return false, err
} else if targetPRSyncUrl, err := url.Parse(pr.Base.Repo.CloneURL); err != nil {
return err
return false, err
} else {
metaUrl.RawQuery = ""
metaUrl.Fragment = ""
@@ -583,20 +758,10 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) error {
if metaUrl.String() != targetPRSyncUrl.String() {
common.LogError("SCMSYNC in meta", meta.ScmSync, "!= PR CloneURL from Gitea", pr.Base.Repo.CloneURL, ". Skipping staging")
if !IsDryRun {
_, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "SCMSYNC of target project is equal to CloneURL of this PR. Can't review.")
return err
_, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "SCMSYNC of target project is not equal to CloneURL of this PR. Can't review.")
return true, err
}
return nil
}
}
if stagingConfig.StagingProject != "" {
// staging project must either be nothing or be *under* the target project.
// other setups are currently not supported
// NOTE: this is user input, so we need some limits here
l := len(stagingConfig.ObsProject)
if l >= len(stagingConfig.StagingProject) || stagingConfig.ObsProject != stagingConfig.StagingProject[0:l] {
common.LogError("StagingProject (", stagingConfig.StagingProject, ") is not child of target project", stagingConfig.ObsProject)
return true, nil
}
}
@@ -604,9 +769,9 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) error {
common.LogError("staging.config . ObsProject:", stagingConfig.ObsProject, " is not target project name", meta.Name)
if !IsDryRun {
_, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "OBS Meta and staging.config are inconsistent")
return err
return true, err
}
return nil
return true, nil
}
// find modified submodules and new submodules -- build them
@@ -620,17 +785,22 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) error {
common.LogDebug(" # head submodules:", len(headSubmodules))
common.LogDebug(" # base submodules:", len(baseSubmodules))
modifiedOrNew := make([]string, 0, 16)
modifiedPackages := make([]string, 0, 16)
newPackages := make([]string, 0, 16)
if !stagingConfig.RebuildAll {
for pkg, headOid := range headSubmodules {
if baseOid, exists := baseSubmodules[pkg]; !exists || baseOid != headOid {
modifiedOrNew = append(modifiedOrNew, pkg)
if len(baseOid) > 0 {
modifiedPackages = append(modifiedPackages, pkg)
} else {
newPackages = append(newPackages, pkg)
}
common.LogDebug(pkg, ":", baseOid, "->", headOid)
}
}
}
if len(modifiedOrNew) == 0 {
if len(modifiedPackages) == 0 && len(newPackages) == 0 {
rebuild_all := false || stagingConfig.RebuildAll
reviews, err := gitea.GetPullRequestReviews(pr.Base.Repo.Owner.UserName, pr.Base.Repo.Name, pr.Index)
@@ -670,70 +840,90 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) error {
if !IsDryRun {
_, err = gitea.AddReviewComment(pr, common.ReviewStateComment, "No package changes. Not rebuilding project by default")
}
return err
return true, err
}
}
common.LogDebug("ObsProject:", stagingConfig.ObsProject)
stagingProject := GetObsProjectAssociatedWithPr(stagingConfig, obsClient.HomeProject, pr)
change, err := StartOrUpdateBuild(stagingConfig, git, gitea, pr, obsClient)
if change != RequestModificationNoChange {
msg := "Changed source updated for build"
if change == RequestModificationProjectCreated {
msg = "Build is started in https://" + ObsWebHost + "/project/show/" +
stagingProject
}
if !IsDryRun {
gitea.AddComment(pr, msg)
}
stagingProject := GetObsProjectAssociatedWithPr(stagingConfig, ObsClient.HomeProject, pr)
change, err := StartOrUpdateBuild(stagingConfig, git, gitea, pr)
status := &models.CommitStatus{
Context: BotName,
Description: "OBS Staging build",
Status: common.CommitStatus_Pending,
TargetURL: ObsWebHost + "/project/show/" + stagingProject,
}
msg := "Changed source updated for build"
if change == RequestModificationProjectCreated {
for _, setup := range QA {
CreateQASubProject(stagingConfig, git, gitea, pr, obsClient,
msg = "Build is started in " + ObsWebHost + "/project/show/" +
stagingProject + " .\n"
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,
setup.Origin,
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, modifiedPackages...)
if err != nil {
common.LogError("failed fetching ref project status for", stagingConfig.ObsProject, ":", err)
}
stagingResult, err := obsClient.BuildStatus(stagingProject)
stagingResult, err := ObsClient.BuildStatus(stagingProject)
if err != nil {
common.LogError("failed fetching ref project status for", stagingProject, ":", err)
common.LogError("failed fetching stage project status for", stagingProject, ":", err)
}
buildStatus := ProcessBuildStatus(stagingResult, baseResult)
if !IsDryRun {
switch buildStatus {
case BuildStatusSummarySuccess:
switch buildStatus {
case BuildStatusSummarySuccess:
status.Status = common.CommitStatus_Success
if !IsDryRun {
_, err := gitea.AddReviewComment(pr, common.ReviewStateApproved, "Build successful")
if err != nil {
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")
if err != nil {
common.LogError(err)
} else {
return true, nil
}
}
}
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
} else if err == NonActionableReviewError || err == NoReviewsFoundError {
return nil
return true, nil
}
return nil
return false, nil
}
func PollWorkNotifications(giteaUrl string) {
gitea := common.AllocateGiteaTransport(giteaUrl)
data, err := gitea.GetPullNotifications(nil)
data, err := gitea.GetNotifications(common.GiteaNotificationType_Pull, nil)
if err != nil {
common.LogError(err)
@@ -757,32 +947,56 @@ 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 BuildRoot string
var GiteaUrl string
var GiteaUseSshClone bool
var ObsApiHost string
var ObsWebHost string
var IsDryRun bool
var ProcessPROnly string
var ObsClient *common.ObsClient
func ObsWebHostFromApiHost(apihost string) string {
if len(apihost) > 4 && apihost[0:4] == "api." {
return "build" + apihost[3:]
u, err := url.Parse(apihost)
if err != nil {
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 apihost
return u.String()
}
func main() {
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")
flag.StringVar(&BuildRoot, "build-root", "", "Default build location for staging projects. Default is bot's home project")
buildRoot := flag.String("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.BoolVar(&GiteaUseSshClone, "use-ssh-clone", false, "enforce cloning via ssh")
flag.StringVar(&ObsApiHost, "obs", "api.opensuse.org", "API for OBS instance")
obsApiHost := flag.String("obs", "https://api.opensuse.org", "API for OBS instance")
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")
debug := flag.Bool("debug", false, "Turns on debug logging")
@@ -795,12 +1009,25 @@ func main() {
}
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.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 {
rx := regexp.MustCompile("^(\\w+)/(\\w+)#(\\d+)$")
m := rx.FindStringSubmatch(*ProcessPROnly)
@@ -818,9 +1045,6 @@ func main() {
for {
PollWorkNotifications(GiteaUrl)
if *debug {
break
}
common.LogInfo("Poll cycle finished")
time.Sleep(5 * time.Minute)
}

View File

@@ -17,23 +17,33 @@ func TestObsAPIHostFromWebHost(t *testing.T) {
}{
{
name: "api host",
api: "api.suse.de",
web: "build.suse.de",
api: "https://api.suse.de",
web: "https://build.suse.de",
},
{
name: "api host",
api: "api.opensuse.org",
web: "build.opensuse.org",
api: "https://api.opensuse.org",
web: "https://build.opensuse.org",
},
{
name: "other host",
api: "someapi.suse.de",
web: "someapi.suse.de",
api: "https://someapi.suse.de",
web: "https://someapi.suse.de",
},
{
name: "short host",
api: "s",
web: "s",
api: "https://s",
web: "https://s",
},
{
name: "other schema works",
api: "s://stuffhere",
web: "s://stuffhere",
},
{
name: "other schema works",
api: "s://api.stuffhere/foo",
web: "s://build.stuffhere/foo",
},
}
@@ -101,3 +111,6 @@ func TestPRtoObsProjectMapping(t *testing.T) {
})
}
}
func TestStatusCodeResults(t *testing.T) {
}

View File

@@ -103,7 +103,7 @@ func processConfiguredRepositoryAction(action *common.RepositoryWebhookEvent, co
prjGitRepo, err := gitea.CreateRepositoryIfNotExist(git, gitOrg, gitPrj)
if err != nil {
return fmt.Errorf("Error accessing/creating prjgit: %s/%s#%d err: %w", gitOrg, gitPrj, gitBranch, err)
return fmt.Errorf("Error accessing/creating prjgit: %s/%s#%s err: %w", gitOrg, gitPrj, gitBranch, err)
}
remoteName, err := git.GitClone(gitPrj, gitBranch, prjGitRepo.SSHURL)
@@ -513,7 +513,7 @@ func main() {
giteaUrl := flag.String("gitea-url", "https://src.opensuse.org", "Gitea instance")
rabbitUrl := flag.String("url", "amqps://rabbit.opensuse.org", "URL for RabbitMQ instance")
flag.BoolVar(&DebugMode, "debug", false, "Extra debugging information")
flag.BoolVar(&noop, "no-op", false, "No-op mode. Do not push changes to remote repo.")
flag.BoolVar(&noop, "dry", false, "Dry mode. Do not push changes to remote repo.")
flag.BoolVar(&checkOnStart, "check-on-start", false, "Check all repositories for consistency on start, without delays")
checkIntervalHours := flag.Float64("check-interval", 5, "Check interval (+-random delay) for repositories for consitency, in hours")
basePath := flag.String("repo-path", "", "Repository path. Default is temporary directory")

View File

@@ -29,7 +29,9 @@ JSON
* _GitProjectName_: package in above org, or `org/package` for PrjGit
* _Reviewers_: accounts associated with mandatory reviews for PrjGit. Can trigger additional
review requests for PrjGit or associated PkgGit repos. Only when all reviews are
satisfied, will the PrjGit PR be merged.
satisfied, will the PrjGit PR be merged. See Reviewers below.
* _ManualMergeOnly_: (true, false) only merge if "merge ok" comment/review by package or project maintainers or reviewers
* _ManualMergeProject_: (true, false) only merge if "merge ok" by project maintainers or reviewers
example:
@@ -44,6 +46,29 @@ example:
...
]
Reviewers
---------
Reviews is a list of accounts that need to review package and/or project. They have specific syntax
[~][*|-|+]username
General prefix of ~ indicates advisory reviewer. They will be requested, but ignored otherwise.
Other prefixes indicate project or package association of the reviewer:
* `*` indicates project *and* package
* `-` indicates project-only reviewer
* `+` indicates package-only reviewer
`+` is implied. For example
`[foo, -bar, ~*moo]`
results in
* foo -> package reviews
* bar -> project reviews
* moo -> package and project reviews, but ignored
Maintainership
--------------

View File

@@ -0,0 +1,18 @@
package interfaces
import "src.opensuse.org/autogits/common"
//go:generate mockgen -source=state_checker.go -destination=../mock/state_checker.go -typed -package mock_main
type StateChecker interface {
VerifyProjectState(configs *common.AutogitConfig) ([]*PRToProcess, error)
CheckRepos() error
ConsistencyCheckProcess() error
}
type PRToProcess struct {
Org, Repo, Branch string
}

View File

@@ -22,7 +22,9 @@ import (
"flag"
"net/url"
"os"
"regexp"
"slices"
"strconv"
"time"
"src.opensuse.org/autogits/common"
@@ -30,17 +32,22 @@ import (
)
const (
AppName = "workflow-pr"
GitAuthor = "AutoGits - pr-review"
GitEmail = "adam+autogits-pr@zombino.com"
AppName = "workflow-pr"
)
var GitAuthor string
var GitEmail string
var ListPROnly bool
var PRID int64
var CurrentUser *models.User
var GitHandler common.GitHandlerGenerator
var Gitea common.Gitea
func main() {
flag.StringVar(&GitAuthor, "git-author", "AutoGits PR Review Bot", "Git commit author")
flag.StringVar(&GitEmail, "git-email", "amajer+devel-git@suse.de", "Git commit email")
workflowConfig := flag.String("config", "", "Repository and workflow definition file")
giteaUrl := flag.String("gitea-url", "https://src.opensuse.org", "Gitea instance")
rabbitUrl := flag.String("url", "amqps://rabbit.opensuse.org", "URL for RabbitMQ instance")
@@ -50,6 +57,8 @@ func main() {
flag.BoolVar(&ListPROnly, "list-prs-only", false, "Only lists PRs without acting on them")
flag.Int64Var(&PRID, "id", -1, "Process only the specific ID and ignore the rest. Use for debugging")
basePath := flag.String("repo-path", "", "Repository path. Default is temporary directory")
pr := flag.String("only-pr", "", "Only specific PR to process. For debugging")
flag.BoolVar(&common.IsDryRun, "dry", false, "Dry mode. Do not push changes to remote repo.")
flag.Parse()
common.SetLoggingLevel(common.LogLevelInfo)
@@ -72,19 +81,23 @@ func main() {
return
}
gitea := common.AllocateGiteaTransport(*giteaUrl)
Gitea = common.AllocateGiteaTransport(*giteaUrl)
config, err := common.ReadConfigFile(*workflowConfig)
if err != nil {
common.LogError("Cannot read config files:", err)
return
}
configs, err := common.ResolveWorkflowConfigs(gitea, config)
configs, err := common.ResolveWorkflowConfigs(Gitea, config)
if err != nil {
common.LogError("Cannot resolve config files:", err)
return
}
for _, c := range configs {
common.LogDebug(*c)
}
req := new(RequestProcessor)
req.configuredRepos = make(map[string][]*common.AutogitConfig)
@@ -111,26 +124,42 @@ func main() {
}
}
if CurrentUser, err = gitea.GetCurrentUser(); err != nil {
if CurrentUser, err = Gitea.GetCurrentUser(); err != nil {
common.LogError("Failed to fetch current gitea user:", err)
return
}
common.LogInfo("Running with token from", CurrentUser.UserName)
req.Synced = &PullRequestSynced{
gitea: gitea,
}
req.Opened = &PullRequestOpened{
gitea: gitea,
}
req.Closed = &PullRequestClosed{
gitea: gitea,
}
req.Review = &PullRequestReviewed{
gitea: gitea,
if *pr != "" {
rx := regexp.MustCompile("^([a-zA-Z0-9_\\.-]+)/([a-zA-Z0-9_\\.-]+)#([0-9]+)$")
if data := rx.FindStringSubmatch(*pr); data == nil {
common.LogError("Cannot parse PR line to process", *pr)
} else {
org := data[1]
repo := data[2]
num, err := strconv.ParseInt(data[3], 10, 64)
common.LogInfo("Processing:", org, "/", repo, "#", num)
common.PanicOnError(err)
pr, err := Gitea.GetPullRequest(org, repo, num)
if err != nil {
common.LogError("Cannot fetch PR", err)
return
}
p := common.PullRequestWebhookEvent{
Action: "opened",
Number: num,
Pull_Request: common.PullRequestFromModel(pr),
}
if err = ProcesPullRequest(&p, configs); err != nil {
common.LogError("processor returned error", err)
}
}
return
}
checker := CreateDefaultStateChecker(*checkOnStart, req, gitea, time.Duration(*checkIntervalHours)*time.Hour)
checker := CreateDefaultStateChecker(*checkOnStart, req, Gitea, time.Duration(*checkIntervalHours)*time.Hour)
go checker.ConsistencyCheckProcess()
listenDefs := common.ListenDefinitions{

View File

@@ -16,32 +16,12 @@ import (
)
func TestProjectBranchName(t *testing.T) {
req := common.PullRequestWebhookEvent{
Repository: &common.Repository{
Name: "testingRepo",
},
Pull_Request: &common.PullRequest{
Number: 10,
},
}
branchName := prGitBranchNameForPR(&req)
branchName := prGitBranchNameForPR("testingRepo", 10)
if branchName != "PR_testingRepo#10" {
t.Error("Unexpected branch name:", branchName)
}
}
func TestProjctGitSync(t *testing.T) {
req := common.PullRequestWebhookEvent{
Action: "pull",
Number: 0,
}
if err := processPrjGitPullRequestSync(&req); err != nil {
t.Error(err)
}
}
const LocalCMD = "---"
func gitExecs(t *testing.T, git *common.GitHandlerImpl, cmds [][]string) {
@@ -133,7 +113,6 @@ func TestUpdatePrBranch(t *testing.T) {
}
git := &common.GitHandlerImpl{
DebugLogger: true,
GitCommiter: "TestCommiter",
GitEmail: "test@testing",
GitPath: t.TempDir(),
@@ -146,7 +125,7 @@ func TestUpdatePrBranch(t *testing.T) {
req.Pull_Request.Base.Sha = strings.TrimSpace(revs[1])
req.Pull_Request.Head.Sha = strings.TrimSpace(revs[0])
updateSubmoduleInPR(req, git)
updateSubmoduleInPR("mainRepo", revs[0], git)
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "commit", "-a", "-m", "created commit"))
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "push", "origin", "+HEAD:+testing"))
git.GitExecOrPanic("prj", "reset", "--hard", "testing")
@@ -171,7 +150,6 @@ func TestCreatePrBranch(t *testing.T) {
}
git := &common.GitHandlerImpl{
DebugLogger: true,
GitCommiter: "TestCommiter",
GitEmail: "test@testing",
GitPath: t.TempDir(),
@@ -184,7 +162,7 @@ func TestCreatePrBranch(t *testing.T) {
req.Pull_Request.Base.Sha = strings.TrimSpace(revs[1])
req.Pull_Request.Head.Sha = strings.TrimSpace(revs[0])
updateSubmoduleInPR(req, git)
updateSubmoduleInPR("testRepo", revs[0], git)
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "commit", "-a", "-m", "created commit"))
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "push", "origin", "+HEAD:testingCreated"))
@@ -194,7 +172,7 @@ func TestCreatePrBranch(t *testing.T) {
t.Error(buf.String())
}
os.CopyFS("/tmp/test", os.DirFS(git.GitPath))
os.CopyFS("/tmp/test", os.DirFS(git.GitPath))
git.GitExecOrPanic("prj", "reset", "--hard", "testingCreated")
rev = strings.TrimSpace(git.GitExecWithOutputOrPanic("prj", "submodule", "status", "testRepo"))[1 : len(req.Pull_Request.Head.Sha)+1]
if rev != req.Pull_Request.Head.Sha {

View File

@@ -4,64 +4,447 @@ package main
import (
"fmt"
"path"
"runtime/debug"
"strings"
"github.com/opentracing/opentracing-go/log"
"src.opensuse.org/autogits/common"
"src.opensuse.org/autogits/common/gitea-generated/models"
)
type PullRequestProcessor interface {
Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error
func prGitBranchNameForPR(repo string, prNo int) string {
return fmt.Sprintf("PR_%s#%d", repo, prNo)
}
func verifyRepositoryConfiguration(repo *models.Repository) error {
if repo.AutodetectManualMerge && repo.AllowManualMerge {
return nil
}
// modify repo to allow above
common.LogDebug("Adjusting repo to accept manual merges:", repo.Owner.UserName+"/"+repo.Name)
_, err := Gitea.SetRepoOptions(repo.Owner.UserName, repo.Name, true)
if err != nil {
common.LogError("Failed to set repo to manual merges:", err)
}
return err
}
func updateSubmoduleInPR(submodule, headSha string, git common.Git) {
common.LogDebug("updating submodule", submodule, "to HEAD", headSha)
// NOTE: this can fail if current PrjGit is pointing to outdated, GC'ed commit
// as long as we can update to newer one later, we are still OK
git.GitExec(common.DefaultGitPrj, "submodule", "update", "--init", "--checkout", "--depth", "1", submodule)
common.PanicOnError(git.GitExec(path.Join(common.DefaultGitPrj, submodule), "fetch", "--depth", "1", "origin", headSha))
common.PanicOnError(git.GitExec(path.Join(common.DefaultGitPrj, submodule), "checkout", headSha))
}
type PRProcessor struct {
config *common.AutogitConfig
git common.Git
}
func AllocatePRProcessor(req *common.PullRequestWebhookEvent, configs common.AutogitConfigs) (*PRProcessor, error) {
org := req.Pull_Request.Base.Repo.Owner.Username
repo := req.Pull_Request.Base.Repo.Name
id := req.Pull_Request.Number
branch := req.Pull_Request.Base.Ref
PRstr := fmt.Sprintf("%s/%s#%d", org, repo, id)
common.LogInfo("*** Starting processing PR:", PRstr, "branch:", branch)
config := configs.GetPrjGitConfig(org, repo, branch)
if config == nil {
if req.Pull_Request.Base.Repo.Default_Branch == branch {
common.LogDebug("Default branch submission...", org, repo)
config = configs.GetPrjGitConfig(org, repo, "")
}
}
if config == nil {
common.LogError("Cannot find config for PR.")
return nil, fmt.Errorf("Cannot find config for PR")
}
common.LogDebug("found config", config)
if config == nil {
common.LogError("Cannot find config for branch '%s'", req.Pull_Request.Base.Ref)
return nil, fmt.Errorf("Cannot find config for branch '%s'", req.Pull_Request.Base.Ref)
}
git, err := GitHandler.CreateGitHandler(config.Organization)
if err != nil {
common.LogError("Cannot allocate GitHandler:", err)
return nil, fmt.Errorf("Error allocating GitHandler. Err: %w", err)
}
common.LogDebug("git path:", git.GetPath())
return &PRProcessor{
config: config,
git: git,
}, nil
}
func (pr *PRProcessor) SetSubmodulesToMatchPRSet(prset *common.PRSet) ([]string, []string, error) {
git := pr.git
subList, err := git.GitSubmoduleList(common.DefaultGitPrj, "HEAD")
if err != nil {
common.LogError("Error fetching submodule list for PrjGit", err)
return nil, nil, err
}
refs := make([]string, 0, len(prset.PRs))
title_refs := make([]string, 0, len(prset.PRs))
for _, pr := range prset.PRs {
if prset.IsPrjGitPR(pr.PR) {
continue
}
org := pr.PR.Base.Repo.Owner.UserName
repo := pr.PR.Base.Repo.Name
idx := pr.PR.Index
prHead := pr.PR.Head.Sha
revert := false
if pr.PR.State != "open" {
prjGitPR, err := prset.GetPrjGitPR()
if prjGitPR != nil {
// remove PR from PrjGit
var valid bool
if prHead, valid = git.GitSubmoduleCommitId(common.DefaultGitPrj, repo, prjGitPR.PR.MergeBase); !valid {
common.LogError("Failed fetching original submodule commit id for repo")
return nil, nil, err
}
}
revert = true
}
// find 'repo' in the submodule list
submodule_found := false
for submodulePath, id := range subList {
if path.Base(submodulePath) == repo {
submodule_found = true
if id != prHead {
ref := fmt.Sprintf(common.PrPattern, org, repo, idx)
commitMsg := fmt.Sprintln("auto-created for", repo, "\n\nThis commit was autocreated by", GitAuthor, "referencing\n", ref)
if revert {
commitMsg = fmt.Sprintln("auto-created for", repo, "\n\nThis commit was autocreated by", GitAuthor, "removing\n", ref)
} else {
refs = append(refs, ref)
title_refs = append(title_refs, repo)
}
updateSubmoduleInPR(submodulePath, prHead, git)
status, err := git.GitStatus(common.DefaultGitPrj)
common.LogDebug("status:", status)
common.LogDebug("submodule", repo, " hash:", id, " -> ", prHead)
common.PanicOnError(err)
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "commit", "-a", "-m", commitMsg))
}
submodule_found = true
break
}
}
if !submodule_found {
common.LogError("Failed to find expected repo:", repo)
}
}
return title_refs, refs, nil
}
func (pr *PRProcessor) CreatePRjGitPR(prjGitPRbranch string, prset *common.PRSet) error {
git := pr.git
PrjGitOrg, PrjGitRepo, PrjGitBranch := prset.Config.GetPrjGit()
PrjGit, err := Gitea.GetRepository(PrjGitOrg, PrjGitRepo)
if err != nil {
common.LogError("Failed to fetch PrjGit repository data.", PrjGitOrg, PrjGitRepo, err)
return err
}
remoteName, err := git.GitClone(common.DefaultGitPrj, PrjGitBranch, PrjGit.SSHURL)
common.PanicOnError(err)
git.GitExecOrPanic(common.DefaultGitPrj, "checkout", "-B", prjGitPRbranch, remoteName+"/"+PrjGitBranch)
headCommit, err := git.GitBranchHead(common.DefaultGitPrj, prjGitPRbranch)
if err != nil {
common.LogError("Failed to fetch PrjGit branch", prjGitPRbranch, err)
return err
}
title_refs, refs, err := pr.SetSubmodulesToMatchPRSet(prset)
if err != nil {
return err
}
newHeadCommit, err := git.GitBranchHead(common.DefaultGitPrj, prjGitPRbranch)
if err != nil {
common.LogError("Failed to fetch updated PrjGit branch", prjGitPRbranch, err)
return err
}
if !common.IsDryRun && headCommit != newHeadCommit {
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "push", remoteName, "+HEAD:"+prjGitPRbranch))
pr, err := Gitea.CreatePullRequestIfNotExist(PrjGit, prjGitPRbranch, PrjGitBranch,
"Forwarded PRs: "+strings.Join(title_refs, ", "),
fmt.Sprintf("This is a forwarded pull request by %s\nreferencing the following pull request(s):\n\n", GitAuthor)+strings.Join(refs, ", "),
)
if err != nil {
common.LogError("Error creating PrjGit PR:", err)
return err
}
Gitea.UpdatePullRequest(PrjGit.Owner.UserName, PrjGit.Name, pr.Index, &models.EditPullRequestOption{
RemoveDeadline: true,
})
prset.AddPR(pr)
}
return nil
}
func (pr *PRProcessor) UpdatePrjGitPR(prset *common.PRSet) error {
PrjGitPR, err := prset.GetPrjGitPR()
if err != nil {
common.LogError("Updating PrjGitPR but not found?", err)
return err
}
git := pr.git
PrjGit := PrjGitPR.PR.Base.Repo
prjGitPRbranch := PrjGitPR.PR.Head.Name
remoteName, err := git.GitClone(common.DefaultGitPrj, prjGitPRbranch, PrjGit.SSHURL)
common.PanicOnError(err)
headCommit, err := git.GitBranchHead(common.DefaultGitPrj, prjGitPRbranch)
if err != nil {
common.LogError("Failed to fetch PrjGit branch", prjGitPRbranch, err)
return err
}
title_refs, refs, err := pr.SetSubmodulesToMatchPRSet(prset)
if err != nil {
return err
}
newHeadCommit, err := git.GitBranchHead(common.DefaultGitPrj, prjGitPRbranch)
if err != nil {
common.LogError("Failed to fetch updated PrjGit branch", prjGitPRbranch, err)
return err
}
if !common.IsDryRun && headCommit != newHeadCommit {
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "push", remoteName, "+HEAD:"+prjGitPRbranch))
// update PR
PrjGitTitle := "Forwarded PRs: " + strings.Join(title_refs, ", ")
PrjGitBody := fmt.Sprintf("This is a forwarded pull request by %s\nreferencing the following pull request(s):\n\n", GitAuthor) + strings.Join(refs, ", ")
Gitea.UpdatePullRequest(PrjGit.Owner.UserName, PrjGit.Name, PrjGitPR.PR.Index, &models.EditPullRequestOption{
RemoveDeadline: true,
Title: PrjGitTitle,
Body: PrjGitBody,
})
}
return nil
}
func (pr *PRProcessor) Process(req *common.PullRequestWebhookEvent) error {
config := pr.config
git := pr.git
// requests against project are not handled here
common.LogInfo("processing opened PR:", req.Pull_Request.Url)
prOrg := req.Pull_Request.Base.Repo.Owner.Username
prRepo := req.Pull_Request.Base.Repo.Name
prNo := int(req.Pull_Request.Number)
common.LogError(req)
prset, err := common.FetchPRSet(CurrentUser.UserName, Gitea, prOrg, prRepo, req.Number, config)
if err != nil {
common.LogError("Cannot fetch PRSet:", err)
return err
}
common.LogInfo("fetched PRSet of size:", len(prset.PRs))
prjGitPRbranch := prGitBranchNameForPR(prRepo, prNo)
prjGitPR, err := prset.GetPrjGitPR()
if err == common.PRSet_PrjGitMissing {
common.LogDebug("Missing PrjGit. Need to create one...")
if err = pr.CreatePRjGitPR(prjGitPRbranch, prset); err != nil {
return err
}
} else if err == nil {
common.LogDebug("Found PrjGit PR:", common.PRtoString(prjGitPR.PR))
prjGitPRbranch = prjGitPR.PR.Head.Name
if prjGitPR.PR.State != "open" {
// close entire prset
common.LogInfo("PR State is closed:", prjGitPR.PR.State)
for _, pr := range prset.PRs {
if pr.PR.State == "open" {
org := pr.PR.Base.Repo.Owner.UserName
repo := pr.PR.Base.Repo.Name
idx := pr.PR.Index
Gitea.UpdatePullRequest(org, repo, idx, &models.EditPullRequestOption{
State: "closed",
})
}
}
return nil
}
if err = pr.UpdatePrjGitPR(prset); err != nil {
return err
}
}
if prjGitPR == nil {
prjGitPR, err = prset.GetPrjGitPR()
if err != nil {
common.LogError("Error fetching PrjGitPR:", err)
return nil
}
}
common.LogDebug("Updated PR")
// make sure that prjgit is consistent and only submodules that are to be *updated*
// reset anything that changed that is not part of the prset
// package removals/additions are *not* counted here
if pr, err := prset.GetPrjGitPR(); err == nil {
remote, err := git.GitClone(common.DefaultGitPrj, prjGitPRbranch, pr.PR.Base.Repo.CloneURL)
common.PanicOnError(err)
git.GitExecOrPanic(common.DefaultGitPrj, "fetch", remote, pr.PR.MergeBase, pr.PR.Head.Ref)
common.LogDebug("Fetch done")
orig_subs, err := git.GitSubmoduleList(common.DefaultGitPrj, pr.PR.MergeBase)
common.PanicOnError(err)
new_subs, err := git.GitSubmoduleList(common.DefaultGitPrj, pr.PR.Head.Sha)
common.PanicOnError(err)
common.LogDebug("Submodule parse done")
reset_submodule := func(submodule, sha string) {
updateSubmoduleInPR(submodule, sha, git)
}
for path, commit := range new_subs {
if old, ok := orig_subs[path]; ok && old != commit {
found := false
for _, pr := range prset.PRs {
if pr.PR.Base.Repo.Name == path && commit == pr.PR.Head.Sha {
found = true
break
}
}
if !found {
reset_submodule(path, old)
}
}
}
stats, err := git.GitStatus(common.DefaultGitPrj)
common.PanicOnError(err)
if len(stats) > 0 {
git.GitExecOrPanic(common.DefaultGitPrj, "commit", "-a", "-m", "Sync submodule updates with PR-set")
git.GitExecOrPanic(common.DefaultGitPrj, "submodule", "deinit", "--all", "--force")
if !common.IsDryRun {
git.GitExecOrPanic(common.DefaultGitPrj, "push")
}
}
}
common.LogDebug(" num of reviewers:", len(prjGitPR.PR.RequestedReviewers))
org, repo, branch := config.GetPrjGit()
maintainers, err := common.FetchProjectMaintainershipData(Gitea, org, repo, branch)
if err != nil {
return err
}
// handle case where PrjGit PR is only one left and there are no changes, then we can just close the PR
if len(prset.PRs) == 1 && prset.PRs[0] == prjGitPR && prjGitPR.PR.User.UserName == prset.BotUser {
common.LogDebug(" --> checking if superflous PR")
diff, err := git.GitDiff(common.DefaultGitPrj, prjGitPR.PR.MergeBase, prjGitPR.PR.Head.Sha)
if err != nil {
return err
}
if len(diff) == 0 {
common.LogInfo("PR is no-op and can be closed. Closing.")
if !common.IsDryRun {
Gitea.AddComment(prjGitPR.PR, "Pull request no longer contains any changes. Closing.")
_, err = Gitea.UpdatePullRequest(prjGitPR.PR.Base.Repo.Owner.UserName, prjGitPR.PR.Base.Repo.Name, prjGitPR.PR.Index, &models.EditPullRequestOption{
State: "closed",
})
if err != nil {
return err
}
}
return nil
}
common.LogDebug(" --> NOT superflous PR")
}
prset.AssignReviewers(Gitea, maintainers)
for _, pr := range prset.PRs {
if err := verifyRepositoryConfiguration(pr.PR.Base.Repo); err != nil {
common.LogError("Cannot set manual merge... aborting processing")
return err
}
}
common.LogInfo("Consistent PRSet:", prset.IsConsistent())
common.LogInfo("Reviewed?", prset.IsApproved(Gitea, maintainers))
if prset.IsConsistent() && prset.IsApproved(Gitea, maintainers) {
common.LogInfo("Merging...")
if err = prset.Merge(Gitea, git); err != nil {
common.LogError("merge error:", err)
}
}
return err
}
type RequestProcessor struct {
Opened, Synced, Closed, Review PullRequestProcessor
configuredRepos map[string][]*common.AutogitConfig
}
func (w *RequestProcessor) ProcessFunc(request *common.Request) error {
req, ok := request.Data.(*common.PullRequestWebhookEvent)
if !ok {
return fmt.Errorf("*** Invalid data format for PR processing.")
}
func ProcesPullRequest(req *common.PullRequestWebhookEvent, configs []*common.AutogitConfig) error {
defer func() {
if r := recover(); r != nil {
common.LogInfo("panic cought --- recovered")
common.LogError(string(debug.Stack()))
}
}()
configs := w.configuredRepos[req.Repository.Owner.Username]
if len(configs) < 1 {
// ignoring pull request against unconfigured project (could be just regular sources?)
return nil
}
var config *common.AutogitConfig
for _, c := range configs {
if c.GitProjectName == req.Pull_Request.Base.Repo.Name ||
c.Branch == req.Pull_Request.Base.Ref {
config = c
break
}
}
if config == nil {
return fmt.Errorf("Cannot find config for branch '%s'", req.Pull_Request.Base.Ref)
}
git, err := GitHandler.CreateGitHandler(config.Organization)
pr, err := AllocatePRProcessor(req, configs)
if err != nil {
return fmt.Errorf("Error allocating GitHandler. Err: %w", err)
log.Error(err)
return err
}
defer git.Close()
defer pr.git.Close()
switch req.Action {
case "opened", "reopened":
return w.Opened.Process(req, git, config)
case "synchronized":
return w.Synced.Process(req, git, config)
case "edited":
// not need to be handled??
return nil
case "closed":
return w.Closed.Process(req, git, config)
case "reviewed":
return w.Review.Process(req, git, config)
case "opened", "reopened", "synchronized", "edited", "closed", "reviewed":
return pr.Process(req)
}
return fmt.Errorf("Unhandled pull request action: %s", req.Action)
common.LogError("Unhandled pull request action:", req.Action)
return nil
}
func (w *RequestProcessor) ProcessFunc(request *common.Request) error {
req, ok := request.Data.(*common.PullRequestWebhookEvent)
if !ok {
common.LogError("*** Invalid data format for PR processing.")
return fmt.Errorf("*** Invalid data format for PR processing.")
}
org := req.Repository.Owner.Username
configs := w.configuredRepos[org]
return ProcesPullRequest(req, configs)
}

View File

@@ -1,34 +0,0 @@
package main
import (
"src.opensuse.org/autogits/common"
)
type PullRequestClosed struct {
gitea common.Gitea
}
func (*PullRequestClosed) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error {
if req.Repository.Name != config.GitProjectName {
return nil
}
common.LogInfo(req.Pull_Request.Url, "is", req.Pull_Request.State)
return nil
/*
req := h.Data.(*common.PullRequestAction)
if req.Repository.Name != common.DefaultGitPrj {
// we only handle project git PR updates here
return nil
}
if err := fetchPrGit(h, req.Pull_Request); err != nil {
return err
}
headSubmodules := h.GitSubmoduleList(dir, pr.Head.Sha)
baseSubmodules := h.GitSubmoduleList(dir, pr.Base.Sha)
return nil
*/
}

View File

@@ -1,84 +0,0 @@
package main
import (
"testing"
"go.uber.org/mock/gomock"
"src.opensuse.org/autogits/common"
mock_common "src.opensuse.org/autogits/common/mock"
)
func TestClosePR(t *testing.T) {
pr := PullRequestClosed{}
config := &common.AutogitConfig{
Reviewers: []string{"reviewer1", "reviewer2"},
Branch: "branch",
Organization: "test",
GitProjectName: "prj",
}
event := &common.PullRequestWebhookEvent{
Action: "closed",
Number: 1,
Pull_Request: &common.PullRequest{
Id: 1,
Base: common.Head{
Ref: "branch",
Sha: "testing",
Repo: &common.Repository{
Name: "testRepo",
Default_Branch: "main1",
},
},
Head: common.Head{
Ref: "branch",
Sha: "testing",
Repo: &common.Repository{
Name: "testRepo",
Default_Branch: "main1",
},
},
},
Repository: &common.Repository{
Owner: &common.Organization{
Username: "test",
},
},
}
git := &common.GitHandlerImpl{
GitCommiter: "tester",
GitEmail: "test@suse.com",
}
t.Run("PR git closed request against PrjGit == no action", func(t *testing.T) {
ctl := gomock.NewController(t)
pr.gitea = mock_common.NewMockGitea(ctl)
git.GitPath = t.TempDir()
config.GitProjectName = "testRepo"
event.Repository.Name = "testRepo"
if err := pr.Process(event, git, config); err != nil {
t.Error("Error PrjGit closed request. Should be no error.", err)
}
})
t.Run("PR git closed", func(t *testing.T) {
ctl := gomock.NewController(t)
pr.gitea = mock_common.NewMockGitea(ctl)
git.GitPath = t.TempDir()
config.GitProjectName = "prjGit"
event.Repository.Name = "tester"
if err := pr.Process(event, git, config); err != nil {
t.Error("Error PrjGit closed request. Should be no error.", err)
}
})
}

View File

@@ -1,83 +0,0 @@
package main
import (
"fmt"
"src.opensuse.org/autogits/common"
)
type PullRequestOpened struct {
gitea common.Gitea
}
func (o *PullRequestOpened) CreateOrUpdatePrjGitPR(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error {
// create PrjGit branch for buidling the pull request
branchName := prGitBranchNameForPR(req)
// TODO: fix this for config.Organization
org, prj, _ := config.GetPrjGit()
prjGit, err := o.gitea.CreateRepositoryIfNotExist(git, org, prj)
common.PanicOnErrorWithMsg(err, "Error creating a prjgitrepo: "+err.Error())
remoteName, err := git.GitClone(common.DefaultGitPrj, config.Branch, prjGit.SSHURL)
common.PanicOnError(err)
commitMsg := fmt.Sprintf(`auto-created for %s
This commit was autocreated by %s
referencing
`+common.PrPattern,
req.Repository.Owner.Username,
req.Repository.Name,
GitAuthor,
req.Repository.Name,
req.Pull_Request.Number,
)
subList, err := git.GitSubmoduleList(common.DefaultGitPrj, "HEAD")
common.PanicOnError(err)
if id := subList[req.Repository.Name]; id != req.Pull_Request.Head.Sha {
updateSubmoduleInPR(req, git)
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "commit", "-a", "-m", commitMsg))
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "push", remoteName, "+HEAD:"+branchName))
}
_, err = o.gitea.CreatePullRequestIfNotExist(prjGit, branchName, prjGit.DefaultBranch,
fmt.Sprintf("Forwarded PR: %s", req.Repository.Name),
fmt.Sprintf(`This is a forwarded pull request by %s
referencing the following pull request:
`+common.PrPattern,
GitAuthor, req.Repository.Owner.Username, req.Repository.Name, req.Pull_Request.Number),
)
return err
}
func (o *PullRequestOpened) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error {
// requests against project are not handled here
common.LogInfo("processing opened PR:", req.Pull_Request.Url)
if org, repo, _ := config.GetPrjGit(); req.Repository.Owner.Username != org || req.Repository.Name != repo {
if err := o.CreateOrUpdatePrjGitPR(req, git, config); err != nil {
return err
}
}
prset, err := common.FetchPRSet(o.gitea, req.Repository.Owner.Username, req.Repository.Name, req.Number, config)
if err != nil {
return err
}
// request build review
PR, err := prset.GetPrjGitPR()
if err != nil {
return nil
}
common.LogDebug(" num of reviewers:", len(PR.RequestedReviewers))
maintainers, err := common.FetchProjectMaintainershipData(o.gitea, config.Organization, config.GitProjectName, config.Branch)
if err != nil {
return err
}
return prset.AssignReviewers(o.gitea, maintainers)
}

View File

@@ -12,13 +12,13 @@ import (
)
func TestOpenPR(t *testing.T) {
pr := PullRequestOpened{}
config := &common.AutogitConfig{
Reviewers: []string{"reviewer1", "reviewer2"},
Branch: "branch",
Organization: "test",
GitProjectName: "prj",
pr := PRProcessor{
config: &common.AutogitConfig{
Reviewers: []string{"reviewer1", "reviewer2"},
Branch: "branch",
Organization: "test",
GitProjectName: "prj",
},
}
event := &common.PullRequestWebhookEvent{
@@ -60,14 +60,14 @@ func TestOpenPR(t *testing.T) {
t.Run("PR git opened request against PrjGit == no action", func(t *testing.T) {
ctl := gomock.NewController(t)
pr.gitea = mock_common.NewMockGitea(ctl)
Gitea = mock_common.NewMockGitea(ctl)
git.GitPath = t.TempDir()
config.GitProjectName = "testRepo"
pr.config.GitProjectName = "testRepo"
event.Repository.Name = "testRepo"
if err := pr.Process(event, git, config); err != nil {
if err := pr.Process(event); err != nil {
t.Error("Error PrjGit opened request. Should be no error.", err)
}
})
@@ -76,10 +76,10 @@ func TestOpenPR(t *testing.T) {
ctl := gomock.NewController(t)
gitea := mock_common.NewMockGitea(ctl)
pr.gitea = gitea
Gitea = gitea
event.Repository.Name = "testRepo"
config.GitProjectName = "prjcopy"
pr.config.GitProjectName = "prjcopy"
git.GitPath = t.TempDir()
setupGitForTests(t, git)
@@ -101,7 +101,7 @@ func TestOpenPR(t *testing.T) {
UserName: "test",
},
}
gitea.EXPECT().GetAssociatedPrjGitPR("test", "prjcopy", "test", "testRepo", int64(1)).Return(nil, nil)
// gitea.EXPECT().GetAssociatedPrjGitPR("test", "prjcopy", "test", "testRepo", int64(1)).Return(nil, nil)
gitea.EXPECT().CreateRepositoryIfNotExist(git, "test", "prjcopy").Return(prjgit, nil)
gitea.EXPECT().CreatePullRequestIfNotExist(prjgit, gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(giteaPR, nil)
gitea.EXPECT().GetPullRequest("test", "testRepo", int64(1)).Return(giteaPR, nil)
@@ -111,7 +111,7 @@ func TestOpenPR(t *testing.T) {
gitea.EXPECT().FetchMaintainershipDirFile("test", "prjcopy", "branch", "_project").Return(nil, "", repository.NewRepoGetRawFileNotFound())
gitea.EXPECT().FetchMaintainershipFile("test", "prjcopy", "branch").Return(nil, "", repository.NewRepoGetRawFileNotFound())
err := pr.Process(event, git, config)
err := pr.Process(event)
if err != nil {
t.Error("error:", err)
}
@@ -121,17 +121,17 @@ func TestOpenPR(t *testing.T) {
ctl := gomock.NewController(t)
gitea := mock_common.NewMockGitea(ctl)
pr.gitea = gitea
Gitea = gitea
event.Repository.Name = "testRepo"
config.GitProjectName = "prjcopy"
pr.config.GitProjectName = "prjcopy"
git.GitPath = t.TempDir()
setupGitForTests(t, git)
failedErr := errors.New("Returned error here")
gitea.EXPECT().CreateRepositoryIfNotExist(git, "test", "prjcopy").Return(nil, failedErr)
err := pr.Process(event, git, config)
err := pr.Process(event)
if err != failedErr {
t.Error("error:", err)
}
@@ -140,10 +140,10 @@ func TestOpenPR(t *testing.T) {
ctl := gomock.NewController(t)
gitea := mock_common.NewMockGitea(ctl)
pr.gitea = gitea
Gitea = gitea
event.Repository.Name = "testRepo"
config.GitProjectName = "prjcopy"
pr.config.GitProjectName = "prjcopy"
git.GitPath = t.TempDir()
setupGitForTests(t, git)
@@ -155,7 +155,7 @@ func TestOpenPR(t *testing.T) {
gitea.EXPECT().CreateRepositoryIfNotExist(git, "test", "prjcopy").Return(prjgit, nil)
gitea.EXPECT().CreatePullRequestIfNotExist(prjgit, gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, failedErr)
err := pr.Process(event, git, config)
err := pr.Process(event)
if err != failedErr {
t.Error("error:", err)
}
@@ -164,10 +164,10 @@ func TestOpenPR(t *testing.T) {
ctl := gomock.NewController(t)
gitea := mock_common.NewMockGitea(ctl)
pr.gitea = gitea
Gitea = gitea
event.Repository.Name = "testRepo"
config.GitProjectName = "prjcopy"
pr.config.GitProjectName = "prjcopy"
git.GitPath = t.TempDir()
setupGitForTests(t, git)
@@ -189,7 +189,7 @@ func TestOpenPR(t *testing.T) {
},
}
failedErr := errors.New("Returned error here")
gitea.EXPECT().GetAssociatedPrjGitPR("test", "prjcopy", "test", "testRepo", int64(1)).Return(nil, nil)
// gitea.EXPECT().GetAssociatedPrjGitPR("test", "prjcopy", "test", "testRepo", int64(1)).Return(nil, nil)
gitea.EXPECT().CreateRepositoryIfNotExist(git, "test", "prjcopy").Return(prjgit, nil)
gitea.EXPECT().GetPullRequest("test", "testRepo", int64(1)).Return(giteaPR, nil)
gitea.EXPECT().GetPullRequestReviews("org", "SomeRepo", int64(13)).Return([]*models.PullReview{}, nil)
@@ -199,7 +199,7 @@ func TestOpenPR(t *testing.T) {
gitea.EXPECT().FetchMaintainershipDirFile("test", "prjcopy", "branch", "_project").Return(nil, "", repository.NewRepoGetRawFileNotFound())
gitea.EXPECT().FetchMaintainershipFile("test", "prjcopy", "branch").Return(nil, "", repository.NewRepoGetRawFileNotFound())
err := pr.Process(event, git, config)
err := pr.Process(event)
if errors.Unwrap(err) != failedErr {
t.Error("error:", err)
}

View File

@@ -1,25 +0,0 @@
package main
import "src.opensuse.org/autogits/common"
type PullRequestReviewed struct {
gitea common.Gitea
}
func (o *PullRequestReviewed) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error {
prset, err := common.FetchPRSet(o.gitea, req.Repository.Owner.Username, req.Repository.Name, req.Number, config)
if err != nil {
return err
}
maintainers, err := common.FetchProjectMaintainershipData(o.gitea, prset.Config.Organization, prset.Config.GitProjectName, prset.Config.Branch)
if err != nil {
return err
}
if prset.IsApproved(o.gitea, maintainers) {
return prset.Merge(GitHandler)
}
return nil
}

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