forked from adamm/autogits
Compare commits
1 Commits
generate-b
...
fix-pr-lin
Author | SHA256 | Date | |
---|---|---|---|
|
933ca9a3db
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
mock
|
||||
node_modules
|
||||
*.obscpio
|
||||
autogits-tmp.tar.zst
|
||||
|
109
autogits.spec
109
autogits.spec
@@ -23,7 +23,6 @@ Summary: GitWorkflow utilities
|
||||
License: GPL-2.0-or-later
|
||||
URL: https://src.opensuse.org/adamm/autogits
|
||||
Source1: vendor.tar.zst
|
||||
BuildRequires: git
|
||||
BuildRequires: golang-packaging
|
||||
BuildRequires: systemd-rpm-macros
|
||||
BuildRequires: zstd
|
||||
@@ -34,22 +33,6 @@ Git Workflow tooling and utilities enabling automated handing of OBS projects
|
||||
as git repositories
|
||||
|
||||
|
||||
|
||||
|
||||
%package -n devel-importer
|
||||
Summary: Imports devel projects from obs to git
|
||||
|
||||
%description -n devel-importer
|
||||
Command-line tool to import devel projects from obs to git
|
||||
|
||||
|
||||
%package -n doc
|
||||
Summary: Common documentation files
|
||||
|
||||
%description -n doc
|
||||
Common documentation files
|
||||
|
||||
|
||||
%package -n gitea-events-rabbitmq-publisher
|
||||
Summary: Publishes Gitea webhook data via RabbitMQ
|
||||
|
||||
@@ -59,10 +42,18 @@ with a topic
|
||||
<scope>.src.$organization.$webhook_type.[$webhook_action_type]
|
||||
|
||||
|
||||
%package -n gitea-status-proxy
|
||||
Summary: gitea-status-proxy
|
||||
%package -n doc
|
||||
Summary: Common documentation files
|
||||
|
||||
%description -n gitea-status-proxy
|
||||
%description -n doc
|
||||
Common documentation files
|
||||
|
||||
|
||||
%package -n devel-importer
|
||||
Summary: Imports devel projects from obs to git
|
||||
|
||||
%description -n devel-importer
|
||||
Command-line tool to import devel projects from obs to git
|
||||
|
||||
|
||||
%package -n group-review
|
||||
@@ -73,12 +64,6 @@ Is used to handle reviews associated with groups defined in the
|
||||
ProjectGit.
|
||||
|
||||
|
||||
%package -n obs-forward-bot
|
||||
Summary: obs-forward-bot
|
||||
|
||||
%description -n obs-forward-bot
|
||||
|
||||
|
||||
%package -n obs-staging-bot
|
||||
Summary: Build a PR against a ProjectGit, if review is requested
|
||||
|
||||
@@ -113,26 +98,18 @@ cp -r /home/abuild/rpmbuild/SOURCES/* ./
|
||||
tar x --zstd -f %{SOURCE1}
|
||||
|
||||
%build
|
||||
go build \
|
||||
-C devel-importer \
|
||||
-mod=vendor \
|
||||
-buildmode=pie
|
||||
go build \
|
||||
-C gitea-events-rabbitmq-publisher \
|
||||
-mod=vendor \
|
||||
-buildmode=pie
|
||||
go build \
|
||||
-C gitea_status_proxy \
|
||||
-C devel-importer \
|
||||
-mod=vendor \
|
||||
-buildmode=pie
|
||||
go build \
|
||||
-C group-review \
|
||||
-mod=vendor \
|
||||
-buildmode=pie
|
||||
go build \
|
||||
-C obs-forward-bot \
|
||||
-mod=vendor \
|
||||
-buildmode=pie
|
||||
go build \
|
||||
-C obs-staging-bot \
|
||||
-mod=vendor \
|
||||
@@ -141,36 +118,24 @@ go build \
|
||||
-C obs-status-service \
|
||||
-mod=vendor \
|
||||
-buildmode=pie
|
||||
go build \
|
||||
-C workflow-direct \
|
||||
-mod=vendor \
|
||||
-buildmode=pie
|
||||
go build \
|
||||
-C workflow-pr \
|
||||
-mod=vendor \
|
||||
-buildmode=pie
|
||||
|
||||
%check
|
||||
# TODO currently needs the source git history, maybe rewrite to create a git repo in the test?
|
||||
#go test -C common
|
||||
go test -C group-review
|
||||
go test -C obs-staging-bot
|
||||
go test -C obs-status-service
|
||||
go test -C workflow-direct
|
||||
# TODO build fails
|
||||
go test -C workflow-pr
|
||||
#go build \
|
||||
# -C workflow-direct \
|
||||
# -mod=vendor \
|
||||
# -buildmode=pie
|
||||
#go build \
|
||||
# -C workflow-pr \
|
||||
# -mod=vendor \
|
||||
# -buildmode=pie
|
||||
|
||||
%install
|
||||
install -D -m0755 devel-importer/devel-importer %{buildroot}%{_bindir}/devel-importer
|
||||
install -D -m0755 gitea-events-rabbitmq-publisher/gitea-events-rabbitmq-publisher %{buildroot}%{_bindir}/gitea-events-rabbitmq-publisher
|
||||
install -D -m0644 systemd/gitea-events-rabbitmq-publisher.service %{buildroot}%{_unitdir}/gitea-events-rabbitmq-publisher.service
|
||||
install -D -m0755 gitea_status_proxy/gitea_status_proxy %{buildroot}%{_bindir}/gitea_status_proxy
|
||||
install -D -m0755 devel-importer/devel-importer %{buildroot}%{_bindir}/devel-importer
|
||||
install -D -m0755 group-review/group-review %{buildroot}%{_bindir}/group-review
|
||||
install -D -m0755 obs-forward-bot/obs-forward-bot %{buildroot}%{_bindir}/obs-forward-bot
|
||||
install -D -m0755 obs-staging-bot/obs-staging-bot %{buildroot}%{_bindir}/obs-staging-bot
|
||||
install -D -m0755 obs-status-service/obs-status-service %{buildroot}%{_bindir}/obs-status-service
|
||||
install -D -m0755 workflow-direct/workflow-direct %{buildroot}%{_bindir}/workflow-direct
|
||||
install -D -m0755 workflow-pr/workflow-pr %{buildroot}%{_bindir}/workflow-pr
|
||||
#install -D -m0755 workflow-direct/workflow-direct %{buildroot}%{_bindir}/workflow-direct
|
||||
#install -D -m0755 workflow-pr/workflow-pr %{buildroot}%{_bindir}/workflow-pr
|
||||
|
||||
%pre -n gitea-events-rabbitmq-publisher
|
||||
%service_add_pre gitea-events-rabbitmq-publisher.service
|
||||
@@ -184,35 +149,27 @@ install -D -m0755 workflow-pr/workflow-pr
|
||||
%postun -n gitea-events-rabbitmq-publisher
|
||||
%service_del_postun gitea-events-rabbitmq-publisher.service
|
||||
|
||||
%files -n devel-importer
|
||||
%license COPYING
|
||||
%doc devel-importer/README.md
|
||||
%{_bindir}/devel-importer
|
||||
|
||||
%files -n doc
|
||||
%license COPYING
|
||||
%doc doc/README.md
|
||||
%doc doc/workflows.md
|
||||
|
||||
%files -n gitea-events-rabbitmq-publisher
|
||||
%license COPYING
|
||||
%doc gitea-events-rabbitmq-publisher/README.md
|
||||
%{_bindir}/gitea-events-rabbitmq-publisher
|
||||
%{_unitdir}/gitea-events-rabbitmq-publisher.service
|
||||
|
||||
%files -n gitea-status-proxy
|
||||
%files -n doc
|
||||
%license COPYING
|
||||
%{_bindir}/gitea_status_proxy
|
||||
%doc doc/README.md
|
||||
%doc doc/workflows.md
|
||||
|
||||
%files -n devel-importer
|
||||
%license COPYING
|
||||
%doc devel-importer/README.md
|
||||
%{_bindir}/devel-importer
|
||||
|
||||
%files -n group-review
|
||||
%license COPYING
|
||||
%doc group-review/README.md
|
||||
%{_bindir}/group-review
|
||||
|
||||
%files -n obs-forward-bot
|
||||
%license COPYING
|
||||
%{_bindir}/obs-forward-bot
|
||||
|
||||
%files -n obs-staging-bot
|
||||
%license COPYING
|
||||
%doc obs-staging-bot/README.md
|
||||
@@ -226,10 +183,10 @@ install -D -m0755 workflow-pr/workflow-pr
|
||||
%files -n workflow-direct
|
||||
%license COPYING
|
||||
%doc workflow-direct/README.md
|
||||
%{_bindir}/workflow-direct
|
||||
#%{_bindir}/workflow-direct
|
||||
|
||||
%files -n workflow-pr
|
||||
%license COPYING
|
||||
%doc workflow-pr/README.md
|
||||
%{_bindir}/workflow-pr
|
||||
#%{_bindir}/workflow-pr
|
||||
|
||||
|
@@ -11,7 +11,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const PrPattern = "PR: %s/%s#%d"
|
||||
const PrPattern = "PR: %s/%s!%d"
|
||||
|
||||
type BasicPR struct {
|
||||
Org, Repo string
|
||||
@@ -36,10 +36,14 @@ func parsePrLine(line string) (BasicPR, error) {
|
||||
return ret, errors.New("missing / separator")
|
||||
}
|
||||
|
||||
repo := strings.SplitN(org[1], "#", 2)
|
||||
repo := strings.SplitN(org[1], "!", 2)
|
||||
ret.Repo = repo[0]
|
||||
if len(repo) != 2 {
|
||||
return ret, errors.New("Missing # separator")
|
||||
repo := strings.SplitN(org[1], "#", 2)
|
||||
ret.Repo = repo[0]
|
||||
}
|
||||
if len(repo) != 2 {
|
||||
return ret, errors.New("Missing ! or # separator")
|
||||
}
|
||||
|
||||
// Gitea requires that each org and repo be [A-Za-z0-9_-]+
|
||||
|
@@ -43,7 +43,6 @@ type ConfigFile struct {
|
||||
|
||||
type ReviewGroup struct {
|
||||
Name string
|
||||
Silent bool // will not request reviews from group members
|
||||
Reviewers []string
|
||||
}
|
||||
|
||||
@@ -58,7 +57,7 @@ type AutogitConfig struct {
|
||||
GitProjectName string // Organization/GitProjectName.git is PrjGit
|
||||
Branch string // branch name of PkgGit that aligns with PrjGit submodules
|
||||
Reviewers []string // only used by `pr` workflow
|
||||
ReviewGroups []*ReviewGroup
|
||||
ReviewGroups []ReviewGroup
|
||||
Committers []string // group in addition to Reviewers and Maintainers that can order the bot around, mostly as helper for factory-maintainers
|
||||
Subdirs []string // list of directories to sort submodules into. Needed b/c _manifest cannot list non-existent directories
|
||||
|
||||
@@ -195,19 +194,10 @@ func (config *AutogitConfig) GetReviewGroupMembers(reviewer string) ([]string, e
|
||||
return nil, errors.New("User " + reviewer + " not found as group reviewer for " + config.GitProjectName)
|
||||
}
|
||||
|
||||
func (config *AutogitConfig) GetReviewGroup(reviewer string) (*ReviewGroup, error) {
|
||||
for _, g := range config.ReviewGroups {
|
||||
if g.Name == reviewer {
|
||||
return g, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("User " + reviewer + " not found as group reviewer for " + config.GitProjectName)
|
||||
}
|
||||
|
||||
func (config *AutogitConfig) GetPrjGit() (string, string, string) {
|
||||
org := config.Organization
|
||||
repo := DefaultGitPrj
|
||||
branch := ""
|
||||
branch := "master"
|
||||
|
||||
a := strings.Split(config.GitProjectName, "/")
|
||||
if len(a[0]) > 0 {
|
||||
@@ -231,9 +221,6 @@ func (config *AutogitConfig) GetPrjGit() (string, string, string) {
|
||||
}
|
||||
}
|
||||
|
||||
if len(branch) == 0 {
|
||||
panic("branch for project is undefined. Should not happend." + org + "/" + repo)
|
||||
}
|
||||
return org, repo, branch
|
||||
}
|
||||
|
||||
|
@@ -160,10 +160,6 @@ type GiteaCommitStatusGetter interface {
|
||||
GetCommitStatus(org, repo, hash string) ([]*models.CommitStatus, error)
|
||||
}
|
||||
|
||||
type GiteaMerger interface {
|
||||
ManualMergePR(org, repo string, id int64, commitid string, delBranch bool) error
|
||||
}
|
||||
|
||||
type Gitea interface {
|
||||
GiteaComment
|
||||
GiteaRepoFetcher
|
||||
@@ -172,7 +168,6 @@ type Gitea interface {
|
||||
GiteaReviewer
|
||||
GiteaPRFetcher
|
||||
GiteaPRUpdater
|
||||
GiteaMerger
|
||||
GiteaCommitFetcher
|
||||
GiteaReviewFetcher
|
||||
GiteaCommentFetcher
|
||||
@@ -238,11 +233,6 @@ func (gitea *GiteaTransport) GetPullRequest(org, project string, num int64) (*mo
|
||||
gitea.transport.DefaultAuthentication,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
LogError(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return pr.Payload, err
|
||||
}
|
||||
|
||||
@@ -256,36 +246,9 @@ func (gitea *GiteaTransport) UpdatePullRequest(org, repo string, num int64, opti
|
||||
gitea.transport.DefaultAuthentication,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
LogError(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return pr.Payload, err
|
||||
}
|
||||
|
||||
func (gitea *GiteaTransport) ManualMergePR(org, repo string, num int64, commitid string, delBranch bool) error {
|
||||
manual_merge := "manually-merged"
|
||||
_, err := gitea.client.Repository.RepoMergePullRequest(
|
||||
repository.NewRepoMergePullRequestParams().
|
||||
WithOwner(org).
|
||||
WithRepo(repo).
|
||||
WithIndex(num).
|
||||
WithBody(&models.MergePullRequestForm{
|
||||
Do: &manual_merge,
|
||||
DeleteBranchAfterMerge: delBranch,
|
||||
HeadCommitID: commitid,
|
||||
}), gitea.transport.DefaultAuthentication,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
LogError(err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gitea *GiteaTransport) GetPullRequests(org, repo string) ([]*models.PullRequest, error) {
|
||||
var page, limit int64
|
||||
|
||||
@@ -647,11 +610,7 @@ func (gitea *GiteaTransport) CreatePullRequestIfNotExist(repo *models.Repository
|
||||
}
|
||||
|
||||
if pr, err := gitea.client.Repository.RepoGetPullRequestByBaseHead(
|
||||
repository.NewRepoGetPullRequestByBaseHeadParams().
|
||||
WithOwner(repo.Owner.UserName).
|
||||
WithRepo(repo.Name).
|
||||
WithBase(targetId).
|
||||
WithHead(srcId),
|
||||
repository.NewRepoGetPullRequestByBaseHeadParams().WithOwner(repo.Owner.UserName).WithRepo(repo.Name).WithBase(targetId).WithHead(srcId),
|
||||
gitea.transport.DefaultAuthentication,
|
||||
); err == nil {
|
||||
return pr.Payload, nil
|
||||
|
@@ -1,120 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: config.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -source=config.go -destination=mock/config.go -typed
|
||||
//
|
||||
|
||||
// Package mock_common is a generated GoMock package.
|
||||
package mock_common
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
models "src.opensuse.org/autogits/common/gitea-generated/models"
|
||||
)
|
||||
|
||||
// MockGiteaFileContentAndRepoFetcher is a mock of GiteaFileContentAndRepoFetcher interface.
|
||||
type MockGiteaFileContentAndRepoFetcher struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockGiteaFileContentAndRepoFetcherMockRecorder
|
||||
isgomock struct{}
|
||||
}
|
||||
|
||||
// MockGiteaFileContentAndRepoFetcherMockRecorder is the mock recorder for MockGiteaFileContentAndRepoFetcher.
|
||||
type MockGiteaFileContentAndRepoFetcherMockRecorder struct {
|
||||
mock *MockGiteaFileContentAndRepoFetcher
|
||||
}
|
||||
|
||||
// NewMockGiteaFileContentAndRepoFetcher creates a new mock instance.
|
||||
func NewMockGiteaFileContentAndRepoFetcher(ctrl *gomock.Controller) *MockGiteaFileContentAndRepoFetcher {
|
||||
mock := &MockGiteaFileContentAndRepoFetcher{ctrl: ctrl}
|
||||
mock.recorder = &MockGiteaFileContentAndRepoFetcherMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockGiteaFileContentAndRepoFetcher) EXPECT() *MockGiteaFileContentAndRepoFetcherMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// GetRepository mocks base method.
|
||||
func (m *MockGiteaFileContentAndRepoFetcher) GetRepository(org, repo string) (*models.Repository, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetRepository", org, repo)
|
||||
ret0, _ := ret[0].(*models.Repository)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetRepository indicates an expected call of GetRepository.
|
||||
func (mr *MockGiteaFileContentAndRepoFetcherMockRecorder) GetRepository(org, repo any) *MockGiteaFileContentAndRepoFetcherGetRepositoryCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRepository", reflect.TypeOf((*MockGiteaFileContentAndRepoFetcher)(nil).GetRepository), org, repo)
|
||||
return &MockGiteaFileContentAndRepoFetcherGetRepositoryCall{Call: call}
|
||||
}
|
||||
|
||||
// MockGiteaFileContentAndRepoFetcherGetRepositoryCall wrap *gomock.Call
|
||||
type MockGiteaFileContentAndRepoFetcherGetRepositoryCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockGiteaFileContentAndRepoFetcherGetRepositoryCall) Return(arg0 *models.Repository, arg1 error) *MockGiteaFileContentAndRepoFetcherGetRepositoryCall {
|
||||
c.Call = c.Call.Return(arg0, arg1)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockGiteaFileContentAndRepoFetcherGetRepositoryCall) Do(f func(string, string) (*models.Repository, error)) *MockGiteaFileContentAndRepoFetcherGetRepositoryCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockGiteaFileContentAndRepoFetcherGetRepositoryCall) DoAndReturn(f func(string, string) (*models.Repository, error)) *MockGiteaFileContentAndRepoFetcherGetRepositoryCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// GetRepositoryFileContent mocks base method.
|
||||
func (m *MockGiteaFileContentAndRepoFetcher) GetRepositoryFileContent(org, repo, hash, path string) ([]byte, string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetRepositoryFileContent", org, repo, hash, path)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(string)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// GetRepositoryFileContent indicates an expected call of GetRepositoryFileContent.
|
||||
func (mr *MockGiteaFileContentAndRepoFetcherMockRecorder) GetRepositoryFileContent(org, repo, hash, path any) *MockGiteaFileContentAndRepoFetcherGetRepositoryFileContentCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRepositoryFileContent", reflect.TypeOf((*MockGiteaFileContentAndRepoFetcher)(nil).GetRepositoryFileContent), org, repo, hash, path)
|
||||
return &MockGiteaFileContentAndRepoFetcherGetRepositoryFileContentCall{Call: call}
|
||||
}
|
||||
|
||||
// MockGiteaFileContentAndRepoFetcherGetRepositoryFileContentCall wrap *gomock.Call
|
||||
type MockGiteaFileContentAndRepoFetcherGetRepositoryFileContentCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockGiteaFileContentAndRepoFetcherGetRepositoryFileContentCall) Return(arg0 []byte, arg1 string, arg2 error) *MockGiteaFileContentAndRepoFetcherGetRepositoryFileContentCall {
|
||||
c.Call = c.Call.Return(arg0, arg1, arg2)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockGiteaFileContentAndRepoFetcherGetRepositoryFileContentCall) Do(f func(string, string, string, string) ([]byte, string, error)) *MockGiteaFileContentAndRepoFetcherGetRepositoryFileContentCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockGiteaFileContentAndRepoFetcherGetRepositoryFileContentCall) DoAndReturn(f func(string, string, string, string) ([]byte, string, error)) *MockGiteaFileContentAndRepoFetcherGetRepositoryFileContentCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,155 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: maintainership.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -source=maintainership.go -destination=mock/maintainership.go -typed
|
||||
//
|
||||
|
||||
// Package mock_common is a generated GoMock package.
|
||||
package mock_common
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
models "src.opensuse.org/autogits/common/gitea-generated/models"
|
||||
)
|
||||
|
||||
// MockMaintainershipData is a mock of MaintainershipData interface.
|
||||
type MockMaintainershipData struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockMaintainershipDataMockRecorder
|
||||
isgomock struct{}
|
||||
}
|
||||
|
||||
// MockMaintainershipDataMockRecorder is the mock recorder for MockMaintainershipData.
|
||||
type MockMaintainershipDataMockRecorder struct {
|
||||
mock *MockMaintainershipData
|
||||
}
|
||||
|
||||
// NewMockMaintainershipData creates a new mock instance.
|
||||
func NewMockMaintainershipData(ctrl *gomock.Controller) *MockMaintainershipData {
|
||||
mock := &MockMaintainershipData{ctrl: ctrl}
|
||||
mock.recorder = &MockMaintainershipDataMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockMaintainershipData) EXPECT() *MockMaintainershipDataMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// IsApproved mocks base method.
|
||||
func (m *MockMaintainershipData) IsApproved(pkg string, reviews []*models.PullReview, submitter string) bool {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "IsApproved", pkg, reviews, submitter)
|
||||
ret0, _ := ret[0].(bool)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// IsApproved indicates an expected call of IsApproved.
|
||||
func (mr *MockMaintainershipDataMockRecorder) IsApproved(pkg, reviews, submitter any) *MockMaintainershipDataIsApprovedCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsApproved", reflect.TypeOf((*MockMaintainershipData)(nil).IsApproved), pkg, reviews, submitter)
|
||||
return &MockMaintainershipDataIsApprovedCall{Call: call}
|
||||
}
|
||||
|
||||
// MockMaintainershipDataIsApprovedCall wrap *gomock.Call
|
||||
type MockMaintainershipDataIsApprovedCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockMaintainershipDataIsApprovedCall) Return(arg0 bool) *MockMaintainershipDataIsApprovedCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockMaintainershipDataIsApprovedCall) Do(f func(string, []*models.PullReview, string) bool) *MockMaintainershipDataIsApprovedCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockMaintainershipDataIsApprovedCall) DoAndReturn(f func(string, []*models.PullReview, string) bool) *MockMaintainershipDataIsApprovedCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// ListPackageMaintainers mocks base method.
|
||||
func (m *MockMaintainershipData) ListPackageMaintainers(pkg string) []string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ListPackageMaintainers", pkg)
|
||||
ret0, _ := ret[0].([]string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ListPackageMaintainers indicates an expected call of ListPackageMaintainers.
|
||||
func (mr *MockMaintainershipDataMockRecorder) ListPackageMaintainers(pkg any) *MockMaintainershipDataListPackageMaintainersCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListPackageMaintainers", reflect.TypeOf((*MockMaintainershipData)(nil).ListPackageMaintainers), pkg)
|
||||
return &MockMaintainershipDataListPackageMaintainersCall{Call: call}
|
||||
}
|
||||
|
||||
// MockMaintainershipDataListPackageMaintainersCall wrap *gomock.Call
|
||||
type MockMaintainershipDataListPackageMaintainersCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockMaintainershipDataListPackageMaintainersCall) Return(arg0 []string) *MockMaintainershipDataListPackageMaintainersCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockMaintainershipDataListPackageMaintainersCall) Do(f func(string) []string) *MockMaintainershipDataListPackageMaintainersCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockMaintainershipDataListPackageMaintainersCall) DoAndReturn(f func(string) []string) *MockMaintainershipDataListPackageMaintainersCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// ListProjectMaintainers mocks base method.
|
||||
func (m *MockMaintainershipData) ListProjectMaintainers() []string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ListProjectMaintainers")
|
||||
ret0, _ := ret[0].([]string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ListProjectMaintainers indicates an expected call of ListProjectMaintainers.
|
||||
func (mr *MockMaintainershipDataMockRecorder) ListProjectMaintainers() *MockMaintainershipDataListProjectMaintainersCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListProjectMaintainers", reflect.TypeOf((*MockMaintainershipData)(nil).ListProjectMaintainers))
|
||||
return &MockMaintainershipDataListProjectMaintainersCall{Call: call}
|
||||
}
|
||||
|
||||
// MockMaintainershipDataListProjectMaintainersCall wrap *gomock.Call
|
||||
type MockMaintainershipDataListProjectMaintainersCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockMaintainershipDataListProjectMaintainersCall) Return(arg0 []string) *MockMaintainershipDataListProjectMaintainersCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockMaintainershipDataListProjectMaintainersCall) Do(f func() []string) *MockMaintainershipDataListProjectMaintainersCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockMaintainershipDataListProjectMaintainersCall) DoAndReturn(f func() []string) *MockMaintainershipDataListProjectMaintainersCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
@@ -1,85 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: obs_utils.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -source=obs_utils.go -destination=mock/obs_utils.go -typed
|
||||
//
|
||||
|
||||
// Package mock_common is a generated GoMock package.
|
||||
package mock_common
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
common "src.opensuse.org/autogits/common"
|
||||
)
|
||||
|
||||
// MockObsStatusFetcherWithState is a mock of ObsStatusFetcherWithState interface.
|
||||
type MockObsStatusFetcherWithState struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockObsStatusFetcherWithStateMockRecorder
|
||||
isgomock struct{}
|
||||
}
|
||||
|
||||
// MockObsStatusFetcherWithStateMockRecorder is the mock recorder for MockObsStatusFetcherWithState.
|
||||
type MockObsStatusFetcherWithStateMockRecorder struct {
|
||||
mock *MockObsStatusFetcherWithState
|
||||
}
|
||||
|
||||
// NewMockObsStatusFetcherWithState creates a new mock instance.
|
||||
func NewMockObsStatusFetcherWithState(ctrl *gomock.Controller) *MockObsStatusFetcherWithState {
|
||||
mock := &MockObsStatusFetcherWithState{ctrl: ctrl}
|
||||
mock.recorder = &MockObsStatusFetcherWithStateMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockObsStatusFetcherWithState) EXPECT() *MockObsStatusFetcherWithStateMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// BuildStatusWithState mocks base method.
|
||||
func (m *MockObsStatusFetcherWithState) BuildStatusWithState(project string, opts *common.BuildResultOptions, packages ...string) (*common.BuildResultList, error) {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []any{project, opts}
|
||||
for _, a := range packages {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "BuildStatusWithState", varargs...)
|
||||
ret0, _ := ret[0].(*common.BuildResultList)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BuildStatusWithState indicates an expected call of BuildStatusWithState.
|
||||
func (mr *MockObsStatusFetcherWithStateMockRecorder) BuildStatusWithState(project, opts any, packages ...any) *MockObsStatusFetcherWithStateBuildStatusWithStateCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
varargs := append([]any{project, opts}, packages...)
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildStatusWithState", reflect.TypeOf((*MockObsStatusFetcherWithState)(nil).BuildStatusWithState), varargs...)
|
||||
return &MockObsStatusFetcherWithStateBuildStatusWithStateCall{Call: call}
|
||||
}
|
||||
|
||||
// MockObsStatusFetcherWithStateBuildStatusWithStateCall wrap *gomock.Call
|
||||
type MockObsStatusFetcherWithStateBuildStatusWithStateCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockObsStatusFetcherWithStateBuildStatusWithStateCall) Return(arg0 *common.BuildResultList, arg1 error) *MockObsStatusFetcherWithStateBuildStatusWithStateCall {
|
||||
c.Call = c.Call.Return(arg0, arg1)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockObsStatusFetcherWithStateBuildStatusWithStateCall) Do(f func(string, *common.BuildResultOptions, ...string) (*common.BuildResultList, error)) *MockObsStatusFetcherWithStateBuildStatusWithStateCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockObsStatusFetcherWithStateBuildStatusWithStateCall) DoAndReturn(f func(string, *common.BuildResultOptions, ...string) (*common.BuildResultList, error)) *MockObsStatusFetcherWithStateBuildStatusWithStateCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
@@ -273,7 +273,7 @@ func (rs *PRSet) AssignReviewers(gitea GiteaReviewFetcherAndRequester, maintaine
|
||||
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)
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -397,7 +397,7 @@ func (rs *PRSet) Merge(gitea GiteaReviewUnrequester, git Git) error {
|
||||
panic("FIXME")
|
||||
}
|
||||
*/
|
||||
msg := fmt.Sprintf("Merging\n\nPR: %s/%s#%d", prjgit.Base.Repo.Owner.UserName, prjgit.Base.Repo.Name, prjgit.Index)
|
||||
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 {
|
||||
|
@@ -132,7 +132,7 @@ func PRtoString(pr *models.PullRequest) string {
|
||||
return "(null)"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s#%d", pr.Base.Repo.Owner.UserName, pr.Base.Repo.Name, pr.Index)
|
||||
return fmt.Sprintf("%s/%s!%d", pr.Base.Repo.Owner.UserName, pr.Base.Repo.Name, pr.Index)
|
||||
}
|
||||
|
||||
type DevelProject struct {
|
||||
|
@@ -1,8 +0,0 @@
|
||||
all: ../workflow-direct/workflow-direct
|
||||
cp ../workflow-direct/workflow-direct workflow-direct
|
||||
podman build --pull=always -t workflow-direct workflow-direct
|
||||
|
||||
pr:
|
||||
cp ../workflow-pr/workflow-pr workflow-pr
|
||||
podman build --pull=always -t workflow-pr workflow-pr
|
||||
|
1
containers/workflow-direct/.gitignore
vendored
1
containers/workflow-direct/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
workflow-direct
|
@@ -1,14 +0,0 @@
|
||||
FROM registry.suse.com/bci/bci-base
|
||||
RUN zypper install -y openssh-clients git-core
|
||||
RUN mkdir /root/.ssh
|
||||
RUN mkdir /repos
|
||||
RUN ln -s /data/workflow-direct.key /root/.ssh/id_ed25519
|
||||
RUN ln -s /data/workflow-direct.key.pub /root/.ssh/id_ed25519.pub
|
||||
ADD known_hosts /root/.ssh/known_hosts
|
||||
ADD workflow-direct /srv/workflow-direct
|
||||
ENV AMQP_USERNAME=opensuse
|
||||
ENV AMQP_PASSWORD=opensuse
|
||||
VOLUME /data
|
||||
VOLUME /repos
|
||||
ENTRYPOINT /srv/workflow-direct -config /data/config.json -repo-path /repos -debug -check-on-start
|
||||
|
@@ -1,4 +0,0 @@
|
||||
src.opensuse.org,195.135.223.224 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDJ8V51MVIFUkQqQOdHwC3SP9NPqp1ZWYoEbcjvZ7HhSFi2XF8ALo/h1Mk+q8kT2O75/goeTsKFbcU8zrYFeOh0=
|
||||
src.opensuse.org,195.135.223.224 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCkVeXePin0haffC085V2L0jvILfwbB2Mt1fpVe21QAOcWNM+/jOC5RwtWweV/LigHImB39/KvkuPa9yLoDf+eLhdZQckSSauRfDjxtlKeFLPrfJKSA0XeVJT3kJcOvDT/3ANFhYeBbAUBTAeQt5bi2hHC1twMPbaaEdJ2jiMaIBztFf6aE9K58uoS+7Y2tTv87Mv/7lqoBW6BFMoDmjQFWgjik6ZMCvIM/7bj7AgqHk/rjmr5zKS4ag5wtHtYLm1L3LBmHdj7d0VFsOpPQexIOEnnjzKqlwmAxT6eYJ/t3qgBlT8KRfshBFgEuUZ5GJOC7TOne4PfB0bboPMZzIRo3WE9dPGRR8kAIme8XqhFbmjdJ+WsTjg0Lj+415tIbyRQoNkLtawrJxozvevs6wFEFcA/YG6o03Z577tiLT3WxOguCcD5vrALH48SyZb8jDUtcVgTWMW0to/n63S8JGUNyF7Bkw9HQWUx+GO1cv2GNzKpk22KS5dlNUVGE9E/7Ydc=
|
||||
src.opensuse.org,195.135.223.224 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFKNThLRPznU5Io1KrAYHmYpaoLQEMGM9nwpKyYQCkPx
|
||||
|
1
containers/workflow-pr/.gitignore
vendored
1
containers/workflow-pr/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
workflow-pr
|
@@ -1,14 +0,0 @@
|
||||
FROM registry.suse.com/bci/bci-base
|
||||
RUN zypper install -y openssh-clients git-core
|
||||
RUN mkdir /root/.ssh
|
||||
RUN mkdir /repos
|
||||
RUN ln -s /data/workflow-pr.key /root/.ssh/id_ed25519
|
||||
RUN ln -s /data/workflow-pr.key.pub /root/.ssh/id_ed25519.pub
|
||||
ADD known_hosts /root/.ssh/known_hosts
|
||||
ADD workflow-pr /srv/workflow-pr
|
||||
ENV AMQP_USERNAME=opensuse
|
||||
ENV AMQP_PASSWORD=opensuse
|
||||
VOLUME /data
|
||||
VOLUME /repos
|
||||
ENTRYPOINT /srv/workflow-pr -config /data/config.json -repo-path /repos -debug -check-on-start
|
||||
|
@@ -1,4 +0,0 @@
|
||||
src.opensuse.org,195.135.223.224 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDJ8V51MVIFUkQqQOdHwC3SP9NPqp1ZWYoEbcjvZ7HhSFi2XF8ALo/h1Mk+q8kT2O75/goeTsKFbcU8zrYFeOh0=
|
||||
src.opensuse.org,195.135.223.224 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCkVeXePin0haffC085V2L0jvILfwbB2Mt1fpVe21QAOcWNM+/jOC5RwtWweV/LigHImB39/KvkuPa9yLoDf+eLhdZQckSSauRfDjxtlKeFLPrfJKSA0XeVJT3kJcOvDT/3ANFhYeBbAUBTAeQt5bi2hHC1twMPbaaEdJ2jiMaIBztFf6aE9K58uoS+7Y2tTv87Mv/7lqoBW6BFMoDmjQFWgjik6ZMCvIM/7bj7AgqHk/rjmr5zKS4ag5wtHtYLm1L3LBmHdj7d0VFsOpPQexIOEnnjzKqlwmAxT6eYJ/t3qgBlT8KRfshBFgEuUZ5GJOC7TOne4PfB0bboPMZzIRo3WE9dPGRR8kAIme8XqhFbmjdJ+WsTjg0Lj+415tIbyRQoNkLtawrJxozvevs6wFEFcA/YG6o03Z577tiLT3WxOguCcD5vrALH48SyZb8jDUtcVgTWMW0to/n63S8JGUNyF7Bkw9HQWUx+GO1cv2GNzKpk22KS5dlNUVGE9E/7Ydc=
|
||||
src.opensuse.org,195.135.223.224 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFKNThLRPznU5Io1KrAYHmYpaoLQEMGM9nwpKyYQCkPx
|
||||
|
@@ -216,8 +216,8 @@ func findMissingDevelBranch(git common.Git, pkg, project string) {
|
||||
}
|
||||
|
||||
func importFactoryRepoAndCheckHistory(pkg string, meta *common.PackageMeta) (factoryRepo *models.Repository, retErr error) {
|
||||
if repo, err := client.Repository.RepoGet(repository.NewRepoGetParams().WithDefaults().WithOwner("pool").WithRepo(giteaPackage(pkg)), r.DefaultAuthentication); err != nil || repo.Payload.ObjectFormatName != "sha256" {
|
||||
if err != nil && !errors.Is(err, &repository.RepoGetNotFound{}) {
|
||||
if repo, err := client.Repository.RepoGet(repository.NewRepoGetParams().WithDefaults().WithOwner("pool").WithRepo(giteaPackage(pkg)), r.DefaultAuthentication); err != nil {
|
||||
if !errors.Is(err, &repository.RepoGetNotFound{}) {
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
@@ -517,7 +517,6 @@ func ImportSha1Sync(pkg string, url *url.URL) {
|
||||
common.LogError(string(data))
|
||||
common.PanicOnError(err)
|
||||
common.PanicOnError(os.RemoveAll(path.Join(git.GetPath(), p)))
|
||||
git.GitExecOrPanic(pkg, "checkout", branch)
|
||||
}
|
||||
|
||||
func LfsImport(pkg string) {
|
||||
@@ -537,7 +536,7 @@ func CloneScmsync(pkg string, meta *common.PackageMeta) bool {
|
||||
git.GitExecOrPanic(pkg, "remote", "add", "origin", u.String())
|
||||
u.Fragment = branch
|
||||
}
|
||||
if err := git.GitExec(pkg, "fetch", "origin"); err != nil && strings.Contains(err.Error(), "fatal: mismatched algorithms: client sha256; server sha1") {
|
||||
if err := git.GitExec(pkg, "fetch", "origin"); strings.Contains(err.Error(), "fatal: mismatched algorithms: client sha256; server sha1") {
|
||||
ImportSha1Sync(pkg, u)
|
||||
} else if err != nil {
|
||||
panic(err)
|
||||
|
@@ -15,23 +15,6 @@ Target Usage
|
||||
|
||||
Projects where policy reviews are required.
|
||||
|
||||
Configiuration
|
||||
--------------
|
||||
|
||||
Groups are defined in the workflow.config inside the project git. They take following options,
|
||||
|
||||
{
|
||||
...
|
||||
ReviewGroups: [
|
||||
{
|
||||
"Name": "name of the group user",
|
||||
"Reviewers": ["members", "of", "group"],
|
||||
"Silent": (true, false) -- if true, do not explicitly require review requests of group members
|
||||
},
|
||||
],
|
||||
...
|
||||
}
|
||||
|
||||
Requirements
|
||||
------------
|
||||
* Gitea token to:
|
||||
|
@@ -157,7 +157,7 @@ func ProcessNotifications(notification *models.NotificationThread, gitea common.
|
||||
repo := match[2]
|
||||
id, _ := strconv.ParseInt(match[3], 10, 64)
|
||||
|
||||
common.LogInfo("processing:", fmt.Sprintf("%s/%s#%d", org, repo, id))
|
||||
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)
|
||||
@@ -181,7 +181,7 @@ func ProcessNotifications(notification *models.NotificationThread, gitea common.
|
||||
|
||||
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))
|
||||
common.LogError("Cannot find config for:", fmt.Sprintf("%s/%s!%s", org, repo, pr.Base.Name))
|
||||
return
|
||||
}
|
||||
if pr.State == "closed" {
|
||||
@@ -205,14 +205,13 @@ func ProcessNotifications(notification *models.NotificationThread, gitea common.
|
||||
return
|
||||
}
|
||||
|
||||
groupConfig, err := config.GetReviewGroup(groupName)
|
||||
requestReviewers, err := config.GetReviewGroupMembers(groupName)
|
||||
if err != nil {
|
||||
common.LogError(err)
|
||||
return
|
||||
}
|
||||
|
||||
// submitter cannot be reviewer
|
||||
requestReviewers := groupConfig.Reviewers
|
||||
requestReviewers = slices.DeleteFunc(requestReviewers, func(u string) bool { return u == pr.User.UserName })
|
||||
// pr.Head.Sha
|
||||
|
||||
@@ -247,7 +246,7 @@ func ProcessNotifications(notification *models.NotificationThread, gitea common.
|
||||
|
||||
// request group member reviews, if missing
|
||||
common.LogDebug(" Review incomplete...")
|
||||
if !groupConfig.Silent && len(requestReviewers) > 0 {
|
||||
if len(requestReviewers) > 0 {
|
||||
common.LogDebug(" Requesting reviews for:", requestReviewers)
|
||||
if !common.IsDryRun {
|
||||
if _, err := gitea.RequestReviews(pr, requestReviewers...); err != nil {
|
||||
@@ -271,9 +270,6 @@ func ProcessNotifications(notification *models.NotificationThread, gitea common.
|
||||
|
||||
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.")
|
||||
if slices.Contains(groupConfig.Reviewers, pr.User.UserName) {
|
||||
helpComment = helpComment + "\n\n" + fmt.Sprintln("Submitter is member of this review group, hence they are excluded from being one of the reviewers here")
|
||||
}
|
||||
gitea.AddComment(pr, helpComment)
|
||||
}
|
||||
}
|
||||
@@ -375,19 +371,19 @@ func main() {
|
||||
config_modified: make(chan *common.AutogitConfig),
|
||||
}
|
||||
|
||||
configUpdates := &common.RabbitMQGiteaEventsProcessor{
|
||||
Orgs: []string{},
|
||||
configUpdates := &common.ListenDefinitions{
|
||||
RabbitURL: u,
|
||||
Orgs: []string{},
|
||||
Handlers: map[string]common.RequestProcessor{
|
||||
common.RequestType_Push: &config_update,
|
||||
},
|
||||
}
|
||||
configUpdates.Connection().RabbitURL = u
|
||||
for _, c := range configs {
|
||||
if org, _, _ := c.GetPrjGit(); !slices.Contains(configUpdates.Orgs, org) {
|
||||
configUpdates.Orgs = append(configUpdates.Orgs, org)
|
||||
}
|
||||
}
|
||||
go common.ProcessRabbitMQEvents(configUpdates)
|
||||
go configUpdates.ProcessRabbitMQEvents()
|
||||
|
||||
for {
|
||||
config_update_loop:
|
||||
|
@@ -108,7 +108,7 @@ func ProcessNotification(notification *models.NotificationThread) {
|
||||
repo := match[2]
|
||||
id, _ := strconv.ParseInt(match[3], 10, 64)
|
||||
|
||||
common.LogInfo("processing:", fmt.Sprintf("%s/%s#%d", org, repo, id))
|
||||
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)
|
||||
|
@@ -120,7 +120,7 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
|
||||
// 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`
|
||||
BuildResultSorter := func(a, b *common.BuildResult) int {
|
||||
BuildResultSorter := func(a, b common.BuildResult) int {
|
||||
if c := strings.Compare(a.Repository, b.Repository); c != 0 {
|
||||
return c
|
||||
}
|
||||
@@ -136,7 +136,7 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
|
||||
common.LogInfo("New package. Only need some success...")
|
||||
SomeSuccess := false
|
||||
for i := 0; i < len(project.Result); i++ {
|
||||
repoRes := project.Result[i]
|
||||
repoRes := &project.Result[i]
|
||||
repoResStatus, ok := common.ObsRepoStatusDetails[repoRes.Code]
|
||||
if !ok {
|
||||
common.LogDebug("cannot find code:", repoRes.Code)
|
||||
@@ -205,8 +205,8 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
|
||||
return BuildStatusSummaryFailed
|
||||
}
|
||||
|
||||
func ProcessRepoBuildStatus(results, ref []*common.PackageBuildStatus) (status BuildStatusSummary, SomeSuccess bool) {
|
||||
PackageBuildStatusSorter := func(a, b *common.PackageBuildStatus) int {
|
||||
func ProcessRepoBuildStatus(results, ref []common.PackageBuildStatus) (status BuildStatusSummary, SomeSuccess bool) {
|
||||
PackageBuildStatusSorter := func(a, b common.PackageBuildStatus) int {
|
||||
return strings.Compare(a.Package, b.Package)
|
||||
}
|
||||
|
||||
|
@@ -100,7 +100,7 @@ func (svg *SvgWriter) WritePackageStatus(loglink, arch, status, detail string) {
|
||||
svg.out.WriteString(`<text fill="#113" x="5ex" y="` + fmt.Sprint(svg.ypos-.6) + `em">` + arch + `</text>`)
|
||||
svg.out.WriteString(`<g>`)
|
||||
if len(loglink) > 0 {
|
||||
svg.out.WriteString(`<a href="` + loglink + `" target="_blank" rel="noopener">`)
|
||||
svg.out.WriteString(`<a href="` + loglink + `">`)
|
||||
}
|
||||
svg.out.WriteString(`<use href="#` + StatusToSVG(status) + `" x="20ex" y="` + fmt.Sprint(svg.ypos-1.7) + `em"/>`)
|
||||
if len(loglink) > 0 {
|
||||
|
BIN
vendor.tar.zst
(Stored with Git LFS)
BIN
vendor.tar.zst
(Stored with Git LFS)
Binary file not shown.
@@ -7,24 +7,14 @@ Areas of responsibility
|
||||
1. Keep ProjectGit in sync with packages in the organization
|
||||
* on pushes to package, updates the submodule commit id
|
||||
to the default branch HEAD (as configured in Gitea)
|
||||
* on repository adds, creates a new submodule (if non empty)
|
||||
* on repository removal, removes the submodule
|
||||
* on package adds, creates a new submodule
|
||||
* on package removal, removes the submodule
|
||||
|
||||
NOTE: reverts (push HEAD^) are not supported as they would step-on the
|
||||
work of the workflow-pr bot. Manual update of the project git is
|
||||
required in this case.
|
||||
2. Assumes:
|
||||
* config.GitProjectName == project name (default: `_ObsPrj`)
|
||||
* Other repositories == packages (similar to OBS project)
|
||||
* config.Branch == "" => default branch from Gitea
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
Uses `workflow.config` for configuration. Parameters
|
||||
|
||||
* _Workflows_: ["direct"] -- direct entry enables direct workflow. **Mandatory**
|
||||
* _Organization_: organization that holds all the packages. **Mandatory**
|
||||
* _Branch_: branch updated in repo's, or blank for default package branch
|
||||
* _GitProjectName_: package in above org, or `org/package#branch` for PrjGit. By default assumes `_ObsPrj` with default branch and in the `Organization`
|
||||
|
||||
NOTE: `-rm`, `-removed`, `-deleted` are all removed suffixes used to indicate current branch is a placeholder for previously existing package. These branches will be ignored by the bot, and if default, the package will be removed and will not be added to the project.
|
||||
|
||||
Target Usage
|
||||
------------
|
||||
|
@@ -23,18 +23,16 @@ Any project (devel, etc) that accepts PR
|
||||
Config file
|
||||
-----------
|
||||
JSON
|
||||
* _Workflows_: ["pr"] -- pr entry enables pr workflow. **Mandatory**
|
||||
* _Organization_: organization that holds all the packages **Mandatory**
|
||||
* _Branch_: branch updated in repo's **Mandatory**
|
||||
* _GitProjectName_: package in above org, or `org/package#branch` for PrjGit. By default assumes `_ObsPrj` with default branch and in the `Organization`
|
||||
* _Workflows_: "pr" -- pr workflow enabled
|
||||
* _Organization_: organization that holds all the packages
|
||||
* _Branch_: branch updated in repo's
|
||||
* _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. 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
|
||||
* _ReviewRequired_: (true, false) ignores that submitter is a maintainer and require a review from other maintainer IFF available
|
||||
|
||||
NOTE: `-rm`, `-removed`, `-deleted` are all removed suffixes used to indicate current branch is a placeholder for previously existing package. These branches will be ignored by the bot, and if default, the package will be removed and will not be added to the project.
|
||||
example:
|
||||
|
||||
[
|
||||
|
@@ -121,12 +121,6 @@ func main() {
|
||||
req.configuredRepos[c.Organization] = configs
|
||||
|
||||
orgs = append(orgs, c.Organization)
|
||||
|
||||
// add project git organization, if different
|
||||
if prjOrg, _, _ := c.GetPrjGit(); prjOrg != c.Organization {
|
||||
orgs = append(orgs, prjOrg)
|
||||
req.configuredRepos[prjOrg] = configs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,13 +163,13 @@ func main() {
|
||||
go checker.ConsistencyCheckProcess()
|
||||
|
||||
listenDefs := &common.RabbitMQGiteaEventsProcessor{
|
||||
Orgs: orgs,
|
||||
Orgs: orgs,
|
||||
// GitAuthor: GitAuthor,
|
||||
Handlers: map[string]common.RequestProcessor{
|
||||
common.RequestType_PR: req,
|
||||
common.RequestType_PRSync: req,
|
||||
common.RequestType_PRReviewAccepted: req,
|
||||
common.RequestType_PRReviewRejected: req,
|
||||
common.RequestType_IssueComment: req,
|
||||
},
|
||||
}
|
||||
listenDefs.Connection().RabbitURL, _ = url.Parse(*rabbitUrl)
|
||||
|
@@ -1,10 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: pr_processor.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -source=pr_processor.go -destination=mock/pr_processor.go -typed
|
||||
//
|
||||
|
||||
// Package mock_main is a generated GoMock package.
|
||||
package mock_main
|
@@ -1,157 +0,0 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: state_checker.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -source=state_checker.go -destination=../mock/state_checker.go -typed -package mock_main
|
||||
//
|
||||
|
||||
// Package mock_main is a generated GoMock package.
|
||||
package mock_main
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
common "src.opensuse.org/autogits/common"
|
||||
interfaces "src.opensuse.org/autogits/workflow-pr/interfaces"
|
||||
)
|
||||
|
||||
// MockStateChecker is a mock of StateChecker interface.
|
||||
type MockStateChecker struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockStateCheckerMockRecorder
|
||||
isgomock struct{}
|
||||
}
|
||||
|
||||
// MockStateCheckerMockRecorder is the mock recorder for MockStateChecker.
|
||||
type MockStateCheckerMockRecorder struct {
|
||||
mock *MockStateChecker
|
||||
}
|
||||
|
||||
// NewMockStateChecker creates a new mock instance.
|
||||
func NewMockStateChecker(ctrl *gomock.Controller) *MockStateChecker {
|
||||
mock := &MockStateChecker{ctrl: ctrl}
|
||||
mock.recorder = &MockStateCheckerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockStateChecker) EXPECT() *MockStateCheckerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// CheckRepos mocks base method.
|
||||
func (m *MockStateChecker) CheckRepos() error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CheckRepos")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CheckRepos indicates an expected call of CheckRepos.
|
||||
func (mr *MockStateCheckerMockRecorder) CheckRepos() *MockStateCheckerCheckReposCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckRepos", reflect.TypeOf((*MockStateChecker)(nil).CheckRepos))
|
||||
return &MockStateCheckerCheckReposCall{Call: call}
|
||||
}
|
||||
|
||||
// MockStateCheckerCheckReposCall wrap *gomock.Call
|
||||
type MockStateCheckerCheckReposCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockStateCheckerCheckReposCall) Return(arg0 error) *MockStateCheckerCheckReposCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockStateCheckerCheckReposCall) Do(f func() error) *MockStateCheckerCheckReposCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockStateCheckerCheckReposCall) DoAndReturn(f func() error) *MockStateCheckerCheckReposCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// ConsistencyCheckProcess mocks base method.
|
||||
func (m *MockStateChecker) ConsistencyCheckProcess() error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ConsistencyCheckProcess")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// ConsistencyCheckProcess indicates an expected call of ConsistencyCheckProcess.
|
||||
func (mr *MockStateCheckerMockRecorder) ConsistencyCheckProcess() *MockStateCheckerConsistencyCheckProcessCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConsistencyCheckProcess", reflect.TypeOf((*MockStateChecker)(nil).ConsistencyCheckProcess))
|
||||
return &MockStateCheckerConsistencyCheckProcessCall{Call: call}
|
||||
}
|
||||
|
||||
// MockStateCheckerConsistencyCheckProcessCall wrap *gomock.Call
|
||||
type MockStateCheckerConsistencyCheckProcessCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockStateCheckerConsistencyCheckProcessCall) Return(arg0 error) *MockStateCheckerConsistencyCheckProcessCall {
|
||||
c.Call = c.Call.Return(arg0)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockStateCheckerConsistencyCheckProcessCall) Do(f func() error) *MockStateCheckerConsistencyCheckProcessCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockStateCheckerConsistencyCheckProcessCall) DoAndReturn(f func() error) *MockStateCheckerConsistencyCheckProcessCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// VerifyProjectState mocks base method.
|
||||
func (m *MockStateChecker) VerifyProjectState(configs *common.AutogitConfig) ([]*interfaces.PRToProcess, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "VerifyProjectState", configs)
|
||||
ret0, _ := ret[0].([]*interfaces.PRToProcess)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// VerifyProjectState indicates an expected call of VerifyProjectState.
|
||||
func (mr *MockStateCheckerMockRecorder) VerifyProjectState(configs any) *MockStateCheckerVerifyProjectStateCall {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyProjectState", reflect.TypeOf((*MockStateChecker)(nil).VerifyProjectState), configs)
|
||||
return &MockStateCheckerVerifyProjectStateCall{Call: call}
|
||||
}
|
||||
|
||||
// MockStateCheckerVerifyProjectStateCall wrap *gomock.Call
|
||||
type MockStateCheckerVerifyProjectStateCall struct {
|
||||
*gomock.Call
|
||||
}
|
||||
|
||||
// Return rewrite *gomock.Call.Return
|
||||
func (c *MockStateCheckerVerifyProjectStateCall) Return(arg0 []*interfaces.PRToProcess, arg1 error) *MockStateCheckerVerifyProjectStateCall {
|
||||
c.Call = c.Call.Return(arg0, arg1)
|
||||
return c
|
||||
}
|
||||
|
||||
// Do rewrite *gomock.Call.Do
|
||||
func (c *MockStateCheckerVerifyProjectStateCall) Do(f func(*common.AutogitConfig) ([]*interfaces.PRToProcess, error)) *MockStateCheckerVerifyProjectStateCall {
|
||||
c.Call = c.Call.Do(f)
|
||||
return c
|
||||
}
|
||||
|
||||
// DoAndReturn rewrite *gomock.Call.DoAndReturn
|
||||
func (c *MockStateCheckerVerifyProjectStateCall) DoAndReturn(f func(*common.AutogitConfig) ([]*interfaces.PRToProcess, error)) *MockStateCheckerVerifyProjectStateCall {
|
||||
c.Call = c.Call.DoAndReturn(f)
|
||||
return c
|
||||
}
|
@@ -11,11 +11,10 @@ import (
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
func prGitBranchNameForPR(repo string, prNo int64) string {
|
||||
func prGitBranchNameForPR(repo string, prNo int) string {
|
||||
return fmt.Sprintf("PR_%s#%d", repo, prNo)
|
||||
}
|
||||
|
||||
@@ -24,9 +23,6 @@ func PrjGitDescription(prset *common.PRSet) (title string, desc string) {
|
||||
refs := make([]string, 0, len(prset.PRs)-1)
|
||||
|
||||
for _, pr := range prset.PRs {
|
||||
if prset.IsPrjGitPR(pr.PR) {
|
||||
continue
|
||||
}
|
||||
org, repo, idx := pr.PRComponents()
|
||||
|
||||
title_refs = append(title_refs, repo)
|
||||
@@ -35,16 +31,16 @@ func PrjGitDescription(prset *common.PRSet) (title string, desc string) {
|
||||
}
|
||||
|
||||
title = "Forwarded PRs: " + strings.Join(title_refs, ", ")
|
||||
desc = fmt.Sprintf("This is a forwarded pull request by %s\nreferencing the following pull request(s):\n\n", GitAuthor) + strings.Join(refs, "\n") + "\n"
|
||||
desc = fmt.Sprintf("This is a forwarded pull request by %s\nreferencing the following pull request(s):\n\n", GitAuthor) + strings.Join(refs, ",\n")
|
||||
|
||||
if prset.Config.ManualMergeOnly {
|
||||
desc = desc + "\n### ManualMergeOnly enabled. To merge, 'merge ok' is required in either the project PR or every package PR."
|
||||
desc = desc + "\n\nManualMergeOnly enabled. To merge, 'merge ok' is required in either the project PR or every package PR."
|
||||
}
|
||||
if prset.Config.ManualMergeProject {
|
||||
desc = desc + "\n### ManualMergeProject enabled. To merge, 'merge ok' is required by project maintainer in the project PR."
|
||||
desc = desc + "\nManualMergeProject enabled. To merge, 'merge ok' is required by project maintainer in the project PR."
|
||||
}
|
||||
if !prset.Config.ManualMergeOnly && !prset.Config.ManualMergeProject {
|
||||
desc = desc + "\n### Automatic merge enabled. This will merge when all review requirements are satisfied."
|
||||
desc = desc + "\nAutomatic merge enabled. This will merge when all review requirements are satisfied."
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -77,19 +73,19 @@ type PRProcessor struct {
|
||||
git common.Git
|
||||
}
|
||||
|
||||
func AllocatePRProcessor(req *models.PullRequest, configs common.AutogitConfigs) (*PRProcessor, error) {
|
||||
org := req.Base.Repo.Owner.UserName
|
||||
repo := req.Base.Repo.Name
|
||||
id := req.Index
|
||||
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.Base.Ref
|
||||
branch := req.Pull_Request.Base.Ref
|
||||
|
||||
PRstr := fmt.Sprintf("%s/%s#%d", org, repo, id)
|
||||
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.Base.Repo.DefaultBranch == branch {
|
||||
if req.Pull_Request.Base.Repo.Default_Branch == branch {
|
||||
common.LogDebug("Default branch submission...", org, repo)
|
||||
config = configs.GetPrjGitConfig(org, repo, "")
|
||||
}
|
||||
@@ -101,8 +97,8 @@ func AllocatePRProcessor(req *models.PullRequest, configs common.AutogitConfigs)
|
||||
|
||||
common.LogDebug("found config", config)
|
||||
if config == nil {
|
||||
common.LogError("Cannot find config for branch '%s'", req.Base.Ref)
|
||||
return nil, fmt.Errorf("Cannot find config for branch '%s'", req.Base.Ref)
|
||||
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)
|
||||
@@ -209,11 +205,8 @@ func (pr *PRProcessor) CreatePRjGitPR(prjGitPRbranch string, prset *common.PRSet
|
||||
return err
|
||||
}
|
||||
|
||||
if !common.IsDryRun {
|
||||
if headCommit != newHeadCommit {
|
||||
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "push", RemoteName, "+HEAD:"+prjGitPRbranch))
|
||||
}
|
||||
|
||||
if !common.IsDryRun && headCommit != newHeadCommit {
|
||||
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "push", RemoteName, "+HEAD:"+prjGitPRbranch))
|
||||
title, desc := PrjGitDescription(prset)
|
||||
pr, err := Gitea.CreatePullRequestIfNotExist(PrjGit, prjGitPRbranch, PrjGitBranch, title, desc)
|
||||
if err != nil {
|
||||
@@ -293,41 +286,37 @@ func (pr *PRProcessor) UpdatePrjGitPR(prset *common.PRSet) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if !common.IsDryRun {
|
||||
if headCommit != newHeadCommit {
|
||||
params := []string{"push", PrjGitPR.RemoteName, "+HEAD:" + prjGitPRbranch}
|
||||
if forcePush {
|
||||
params = slices.Insert(params, 1, "-f")
|
||||
}
|
||||
common.PanicOnError(git.GitExec(common.DefaultGitPrj, params...))
|
||||
if !common.IsDryRun && headCommit != newHeadCommit {
|
||||
params := []string{"push", PrjGitPR.RemoteName, "+HEAD:" + prjGitPRbranch}
|
||||
if forcePush {
|
||||
params = slices.Insert(params, 1, "-f")
|
||||
}
|
||||
common.PanicOnError(git.GitExec(common.DefaultGitPrj, params...))
|
||||
|
||||
// update PR
|
||||
PrjGitTitle, PrjGitBody := PrjGitDescription(prset)
|
||||
if PrjGitPR.PR.Body != PrjGitBody || PrjGitPR.PR.Title != PrjGitTitle {
|
||||
Gitea.UpdatePullRequest(PrjGit.Owner.UserName, PrjGit.Name, PrjGitPR.PR.Index, &models.EditPullRequestOption{
|
||||
RemoveDeadline: true,
|
||||
Title: PrjGitTitle,
|
||||
Body: PrjGitBody,
|
||||
})
|
||||
}
|
||||
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 *models.PullRequest) error {
|
||||
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.URL)
|
||||
prOrg := req.Base.Repo.Owner.UserName
|
||||
prRepo := req.Base.Repo.Name
|
||||
prNo := req.Index
|
||||
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, prNo, config)
|
||||
prset, err := common.FetchPRSet(CurrentUser.UserName, Gitea, prOrg, prRepo, req.Number, config)
|
||||
if err != nil {
|
||||
common.LogError("Cannot fetch PRSet:", err)
|
||||
return err
|
||||
@@ -347,53 +336,14 @@ func (pr *PRProcessor) Process(req *models.PullRequest) error {
|
||||
prjGitPRbranch = prjGitPR.PR.Head.Name
|
||||
|
||||
if prjGitPR.PR.State != "open" {
|
||||
if prjGitPR.PR.HasMerged {
|
||||
// update branches in project
|
||||
prjGitPR.RemoteName, err = git.GitClone(common.DefaultGitPrj, prjGitPRbranch, prjGitPR.PR.Base.Repo.SSHURL)
|
||||
common.PanicOnError(err)
|
||||
|
||||
old_pkgs, err := git.GitSubmoduleList(common.DefaultGitPrj, prjGitPR.PR.MergeBase)
|
||||
common.PanicOnError(err)
|
||||
new_pkgs, err := git.GitSubmoduleList(common.DefaultGitPrj, prjGitPRbranch)
|
||||
common.PanicOnError(err)
|
||||
|
||||
pkgs := make(map[string]string)
|
||||
for pkg, old_commit := range old_pkgs {
|
||||
if new_commit, found := new_pkgs[pkg]; found {
|
||||
// pkg modified
|
||||
if new_commit != old_commit {
|
||||
pkgs[pkg] = new_commit
|
||||
}
|
||||
} else { // not found, pkg removed
|
||||
pkgs[pkg] = ""
|
||||
}
|
||||
}
|
||||
for pkg, commit := range new_pkgs {
|
||||
if _, found := old_pkgs[pkg]; !found {
|
||||
// pkg added
|
||||
pkgs[pkg] = commit
|
||||
}
|
||||
}
|
||||
|
||||
PrjGitSubmoduleCheck(config, git, common.DefaultGitPrj, pkgs)
|
||||
}
|
||||
|
||||
// manually merge or close entire prset that is still open
|
||||
// close entire prset
|
||||
common.LogInfo("PR State is closed:", prjGitPR.PR.State)
|
||||
for _, pr := range prset.PRs {
|
||||
if pr.PR.State == "open" {
|
||||
org, repo, idx := pr.PRComponents()
|
||||
if prjGitPR.PR.HasMerged {
|
||||
Gitea.AddComment(pr.PR, "This PR is merged via the associated Project PR.")
|
||||
err = Gitea.ManualMergePR(org, repo, idx, pr.PR.Head.Sha, false)
|
||||
if _, ok := err.(*repository.RepoMergePullRequestConflict); !ok {
|
||||
common.PanicOnError(err)
|
||||
}
|
||||
} else {
|
||||
Gitea.AddComment(pr.PR, "Closing here because the associated Project PR has been closed.")
|
||||
Gitea.UpdatePullRequest(org, repo, idx, &models.EditPullRequestOption{
|
||||
State: "closed",
|
||||
})
|
||||
}
|
||||
Gitea.UpdatePullRequest(org, repo, idx, &models.EditPullRequestOption{
|
||||
State: "closed",
|
||||
})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -517,23 +467,7 @@ type RequestProcessor struct {
|
||||
configuredRepos map[string][]*common.AutogitConfig
|
||||
}
|
||||
|
||||
func ProcesPullRequest(pr *models.PullRequest, configs []*common.AutogitConfig) error {
|
||||
if len(configs) < 1 {
|
||||
// ignoring pull request against unconfigured project (could be just regular sources?)
|
||||
return nil
|
||||
}
|
||||
|
||||
PRProcessor, err := AllocatePRProcessor(pr, configs)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
defer PRProcessor.git.Close()
|
||||
|
||||
return PRProcessor.Process(pr)
|
||||
}
|
||||
|
||||
func (w *RequestProcessor) ProcessFunc(request *common.Request) error {
|
||||
func ProcesPullRequest(req *common.PullRequestWebhookEvent, configs []*common.AutogitConfig) error {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
common.LogInfo("panic cought --- recovered")
|
||||
@@ -541,28 +475,36 @@ func (w *RequestProcessor) ProcessFunc(request *common.Request) error {
|
||||
}
|
||||
}()
|
||||
|
||||
var pr *models.PullRequest
|
||||
var err error
|
||||
if req, ok := request.Data.(*common.PullRequestWebhookEvent); ok {
|
||||
pr, err = Gitea.GetPullRequest(req.Pull_Request.Base.Repo.Owner.Username, req.Pull_Request.Base.Repo.Name, req.Pull_Request.Number)
|
||||
if err != nil {
|
||||
common.LogError("Cannot find PR for issue:", req.Pull_Request.Base.Repo.Owner.Username, req.Pull_Request.Base.Repo.Name, req.Pull_Request.Number)
|
||||
return err
|
||||
}
|
||||
} else if req, ok := request.Data.(*common.IssueWebhookEvent); ok {
|
||||
pr, err = Gitea.GetPullRequest(req.Repository.Owner.Username, req.Repository.Name, int64(req.Issue.Number))
|
||||
if err != nil {
|
||||
common.LogError("Cannot find PR for issue:", req.Repository.Owner.Username, req.Repository.Name, int64(req.Issue.Number))
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if len(configs) < 1 {
|
||||
// ignoring pull request against unconfigured project (could be just regular sources?)
|
||||
return nil
|
||||
}
|
||||
|
||||
pr, err := AllocatePRProcessor(req, configs)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
defer pr.git.Close()
|
||||
|
||||
switch req.Action {
|
||||
case "opened", "reopened", "synchronized", "edited", "closed", "reviewed":
|
||||
return pr.Process(req)
|
||||
}
|
||||
|
||||
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.")
|
||||
}
|
||||
|
||||
configs, ok := w.configuredRepos[pr.Base.Repo.Owner.UserName]
|
||||
if !ok {
|
||||
common.LogError("*** Cannot find config for org:", pr.Base.Repo.Owner.UserName)
|
||||
}
|
||||
return ProcesPullRequest(pr, configs)
|
||||
org := req.Repository.Owner.Username
|
||||
configs := w.configuredRepos[org]
|
||||
return ProcesPullRequest(req, configs)
|
||||
|
||||
}
|
||||
|
@@ -55,7 +55,44 @@ func (s *DefaultStateChecker) ProcessPR(pr *models.PullRequest, config *common.A
|
||||
return ProcesPullRequest(&event, common.AutogitConfigs{config})
|
||||
}
|
||||
|
||||
func PrjGitSubmoduleCheck(config *common.AutogitConfig, git common.Git, repo string, submodules map[string]string) (prsToProcess []*interfaces.PRToProcess, err error) {
|
||||
func (s *DefaultStateChecker) VerifyProjectState(config *common.AutogitConfig) ([]*interfaces.PRToProcess, error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
common.LogError("panic caught")
|
||||
if err, ok := r.(error); !ok {
|
||||
common.LogError(err)
|
||||
}
|
||||
common.LogError(string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
|
||||
prsToProcess := []*interfaces.PRToProcess{}
|
||||
|
||||
prjGitOrg, prjGitRepo, prjGitBranch := config.GetPrjGit()
|
||||
common.LogInfo(" checking", prjGitOrg+"/"+prjGitRepo+"#"+prjGitBranch)
|
||||
|
||||
git, err := GitHandler.CreateGitHandler(config.Organization)
|
||||
common.LogDebug("Git Path:", git.GetPath())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Cannot create git handler: %w", err)
|
||||
}
|
||||
defer git.Close()
|
||||
|
||||
repo, err := Gitea.CreateRepositoryIfNotExist(git, prjGitOrg, prjGitRepo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error fetching or creating '%s/%s#%s' -- aborting verifyProjectState(). Err: %w", prjGitBranch, prjGitRepo, prjGitBranch, err)
|
||||
}
|
||||
|
||||
_, err = git.GitClone(prjGitRepo, prjGitBranch, repo.SSHURL)
|
||||
common.PanicOnError(err)
|
||||
|
||||
prsToProcess = append(prsToProcess, &interfaces.PRToProcess{
|
||||
Org: prjGitOrg,
|
||||
Repo: prjGitRepo,
|
||||
Branch: prjGitBranch,
|
||||
})
|
||||
submodules, err := git.GitSubmoduleList(prjGitRepo, "HEAD")
|
||||
|
||||
nextSubmodule:
|
||||
for sub, commitID := range submodules {
|
||||
common.LogDebug(" + checking", sub, commitID)
|
||||
@@ -98,8 +135,8 @@ nextSubmodule:
|
||||
}
|
||||
|
||||
// not found in past, check if we should advance the branch label ... pull the submodule
|
||||
git.GitExecOrPanic(repo, "submodule", "update", "--init", "--filter", "blob:none", "--", sub)
|
||||
subDir := path.Join(repo, sub)
|
||||
git.GitExecOrPanic(prjGitRepo, "submodule", "update", "--init", "--filter", "blob:none", "--", sub)
|
||||
subDir := path.Join(prjGitRepo, sub)
|
||||
newCommits := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(subDir, "rev-list", "^origin/"+branch, commitID), "\n")
|
||||
|
||||
if len(newCommits) >= 1 {
|
||||
@@ -115,49 +152,8 @@ nextSubmodule:
|
||||
}
|
||||
}
|
||||
|
||||
return prsToProcess, nil
|
||||
}
|
||||
|
||||
func (s *DefaultStateChecker) VerifyProjectState(config *common.AutogitConfig) ([]*interfaces.PRToProcess, error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
common.LogError("panic caught")
|
||||
if err, ok := r.(error); !ok {
|
||||
common.LogError(err)
|
||||
}
|
||||
common.LogError(string(debug.Stack()))
|
||||
}
|
||||
}()
|
||||
|
||||
prsToProcess := []*interfaces.PRToProcess{}
|
||||
|
||||
prjGitOrg, prjGitRepo, prjGitBranch := config.GetPrjGit()
|
||||
common.LogInfo(" checking", prjGitOrg+"/"+prjGitRepo+"#"+prjGitBranch)
|
||||
|
||||
git, err := GitHandler.CreateGitHandler(config.Organization)
|
||||
common.LogDebug("Git Path:", git.GetPath())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Cannot create git handler: %w", err)
|
||||
}
|
||||
defer git.Close()
|
||||
|
||||
repo, err := Gitea.CreateRepositoryIfNotExist(git, prjGitOrg, prjGitRepo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error fetching or creating '%s/%s#%s' -- aborting verifyProjectState(). Err: %w", prjGitBranch, prjGitRepo, prjGitBranch, err)
|
||||
}
|
||||
|
||||
_, err = git.GitClone(prjGitRepo, prjGitBranch, repo.SSHURL)
|
||||
common.PanicOnError(err)
|
||||
|
||||
prsToProcess = append(prsToProcess, &interfaces.PRToProcess{
|
||||
Org: prjGitOrg,
|
||||
Repo: prjGitRepo,
|
||||
Branch: prjGitBranch,
|
||||
})
|
||||
submodules, err := git.GitSubmoduleList(prjGitRepo, "HEAD")
|
||||
|
||||
// forward any package-gits referred by the project git, but don't go back
|
||||
return PrjGitSubmoduleCheck(config, git, prjGitRepo, submodules)
|
||||
return prsToProcess, nil
|
||||
}
|
||||
|
||||
func (s *DefaultStateChecker) CheckRepos() error {
|
||||
|
Reference in New Issue
Block a user