This commit is contained in:
2025-05-05 18:57:05 +02:00
parent eb997e1ae9
commit da1df24666
20 changed files with 274 additions and 119 deletions

View File

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

View File

@@ -95,7 +95,7 @@ type GiteaFileContentAndRepoFetcher interface {
GiteaRepoFetcher GiteaRepoFetcher
} }
func PartiallyParseWorkflowConfig(data []byte) (*AutogitConfig, error) { func UnmarshalWorkflowConfig(data []byte) (*AutogitConfig, error) {
var config AutogitConfig var config AutogitConfig
data, err := hujson.Standardize(data) data, err := hujson.Standardize(data)
if err != nil { if err != nil {
@@ -130,7 +130,7 @@ func ReadWorkflowConfig(gitea GiteaFileContentAndRepoFetcher, git_project string
return nil, fmt.Errorf("Error fetching 'workflow.config' for %s/%s#%s: %w", a[0], prjGitRepo, branch, err) return nil, fmt.Errorf("Error fetching 'workflow.config' for %s/%s#%s: %w", a[0], prjGitRepo, branch, err)
} }
config, err := PartiallyParseWorkflowConfig(data) config, err := UnmarshalWorkflowConfig(data)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -196,19 +196,26 @@ func (refs *GitReferences) addReference(id, branch string) {
} }
func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) (string, error) { func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) (string, error) {
LogDebug("Cloning", remoteUrl, " repo:", repo, " branch:", branch)
remoteUrlComp, err := ParseGitRemoteUrl(remoteUrl) remoteUrlComp, err := ParseGitRemoteUrl(remoteUrl)
if err != nil { if err != nil {
return "", fmt.Errorf("Cannot parse remote URL: %w", err) return "", fmt.Errorf("Cannot parse remote URL: %w", err)
} }
if len(branch) == 0 { remoteBranch := "HEAD"
if len(branch) == 0 && remoteUrlComp != nil {
branch = remoteUrlComp.Commit branch = remoteUrlComp.Commit
} remoteBranch = branch
if len(branch) == 0 { } else if len(branch) > 0 {
branch = "HEAD" remoteBranch = branch
} }
remoteName := remoteUrlComp.RemoteName() remoteName := remoteUrlComp.RemoteName()
if remoteUrlComp != nil {
LogDebug("Clone", *remoteUrlComp, " -> ", remoteName) LogDebug("Clone", *remoteUrlComp, " -> ", remoteName)
} else {
LogDebug("Clone", "[default] -> ", remoteName)
}
remoteRef := remoteName + "/" + remoteBranch
if fi, err := os.Stat(path.Join(e.GitPath, repo)); os.IsNotExist(err) { if fi, err := os.Stat(path.Join(e.GitPath, repo)); os.IsNotExist(err) {
if err = e.GitExec("", "clone", "--origin", remoteName, remoteUrl, repo); err != nil { if err = e.GitExec("", "clone", "--origin", remoteName, remoteUrl, repo); err != nil {
return remoteName, err return remoteName, err
@@ -222,9 +229,34 @@ func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) (string, error
e.GitExecOrPanic(repo, "remote", "set-url", remoteName, remoteUrl) e.GitExecOrPanic(repo, "remote", "set-url", remoteName, remoteUrl)
} }
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")
} }
return remoteName, e.GitExec(repo, "checkout", "-B", branch, "refs/remotes/"+remoteName+"/"+branch)
e.GitExecOrPanic(repo, "fetch", remoteName, remoteBranch)
}
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)
}
return remoteName, e.GitExec(repo, "checkout", "--track", "-B", branch, remoteRef)
} }
func (e *GitHandlerImpl) GitBranchHead(gitDir, branchName string) (string, error) { func (e *GitHandlerImpl) GitBranchHead(gitDir, branchName string) (string, error) {
@@ -306,7 +338,7 @@ func (e *GitHandlerImpl) GitExecWithOutput(cwd string, params ...string) (string
cmd.Dir = filepath.Join(e.GitPath, cwd) cmd.Dir = filepath.Join(e.GitPath, cwd)
cmd.Stdin = nil cmd.Stdin = nil
LogDebug("git execute:", cmd.Args) LogDebug("git execute @", cwd, ":", cmd.Args)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
LogDebug(string(out)) LogDebug(string(out))
if err != nil { if err != nil {

View File

@@ -54,6 +54,8 @@ func TestGitClone(t *testing.T) {
}, },
} }
return
execPath, err := os.Getwd() execPath, err := os.Getwd()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@@ -239,6 +239,9 @@ func (gitea *GiteaTransport) SetCommitStatus(org, repo, hash string, status *mod
}), }),
gitea.transport.DefaultAuthentication, gitea.transport.DefaultAuthentication,
) )
if err != nil {
return nil, err
}
return res.Payload, err return res.Payload, err
} }
@@ -485,6 +488,9 @@ func (gitea *GiteaTransport) CreatePullRequestIfNotExist(repo *models.Repository
func (gitea *GiteaTransport) GetAssociatedPrjGitPR(prjGitOrg, prjGitRepo, refOrg, refRepo string, Index int64) (*models.PullRequest, error) { func (gitea *GiteaTransport) GetAssociatedPrjGitPR(prjGitOrg, prjGitRepo, refOrg, refRepo string, Index int64) (*models.PullRequest, error) {
var page int64 var page int64
state := "open" state := "open"
prLine := fmt.Sprintf(PrPattern, refOrg, refRepo, Index)
LogDebug("Finding PrjGitPR for", prLine, " Looking in", prjGitOrg, "/", prjGitRepo)
for { for {
page++ page++
prs, err := gitea.client.Repository.RepoListPullRequests( prs, err := gitea.client.Repository.RepoListPullRequests(
@@ -501,14 +507,13 @@ func (gitea *GiteaTransport) GetAssociatedPrjGitPR(prjGitOrg, prjGitRepo, refOrg
return nil, fmt.Errorf("cannot fetch PR list for %s / %s : %w", prjGitOrg, prjGitRepo, err) return nil, fmt.Errorf("cannot fetch PR list for %s / %s : %w", prjGitOrg, prjGitRepo, err)
} }
prLine := fmt.Sprintf(PrPattern, refOrg, refRepo, Index)
// payload_processing: // payload_processing:
for _, pr := range prs.Payload { for _, pr := range prs.Payload {
lines := strings.Split(pr.Body, "\n") lines := strings.Split(pr.Body, "\n")
for _, line := range lines { for _, line := range lines {
if strings.TrimSpace(line) == prLine { if strings.TrimSpace(line) == prLine {
LogDebug("Found PR:", pr.Index)
return pr, nil return pr, nil
} }
} }
@@ -669,7 +674,7 @@ endPrs:
} }
// if pr is closed for more than a week, assume that we are done too // if pr is closed for more than a week, assume that we are done too
if 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 break endPrs
} }

View File

@@ -40,9 +40,9 @@ func PanicOnError(err error) {
} }
} }
func PanicOnErrorWithMsg(err error, msg string) { func PanicOnErrorWithMsg(err error, msg ...any) {
if err != nil { if err != nil {
LogError(msg) LogError(msg...)
panic(err) panic(err)
} }
} }

View File

@@ -44,12 +44,13 @@ func FetchProjectMaintainershipData(gitea GiteaMaintainershipReader, org, prjGit
dir := true dir := true
if err != nil || data == nil { if err != nil || data == nil {
dir = false dir = false
if _, notFound := err.(*repository.RepoGetRawFileNotFound); !notFound { if _, notFound := err.(*repository.RepoGetContentsNotFound); !notFound {
return nil, err return nil, err
} }
LogDebug("Falling back to maintainership file")
data, _, err = gitea.FetchMaintainershipFile(org, prjGit, branch) data, _, err = gitea.FetchMaintainershipFile(org, prjGit, branch)
if err != nil || data == nil { if err != nil || data == nil {
if _, notFound := err.(*repository.RepoGetRawFileNotFound); !notFound { if _, notFound := err.(*repository.RepoGetContentsNotFound); !notFound {
return nil, err return nil, err
} }

View File

@@ -59,7 +59,7 @@ type ObsClient struct {
} }
func NewObsClient(host string) (*ObsClient, error) { func NewObsClient(host string) (*ObsClient, error) {
baseUrl, err := url.Parse("https://" + host) baseUrl, err := url.Parse(host)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -186,6 +186,7 @@ func (c *ObsClient) GetGroupMeta(gid string) (*GroupMeta, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer res.Body.Close()
var meta GroupMeta var meta GroupMeta
err = xml.Unmarshal(data, &meta) err = xml.Unmarshal(data, &meta)
@@ -215,6 +216,7 @@ func (c *ObsClient) GetUserMeta(uid string) (*UserMeta, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer res.Body.Close()
var meta UserMeta var meta UserMeta
err = xml.Unmarshal(data, &meta) err = xml.Unmarshal(data, &meta)
@@ -238,6 +240,11 @@ func (c *ObsClient) ObsRequest(method string, url string, body io.Reader) (*http
req.Header.Add("cookie", c.cookie) req.Header.Add("cookie", c.cookie)
} }
res, err := c.client.Do(req) res, err := c.client.Do(req)
if err != nil && res == nil {
LogDebug(err)
return res, err
}
if err == nil && res.StatusCode == 200 { if err == nil && res.StatusCode == 200 {
auth_cookie := res.Header.Get("set-cookie") auth_cookie := res.Header.Get("set-cookie")
if auth_cookie != "" { if auth_cookie != "" {
@@ -331,6 +338,7 @@ func (c *ObsClient) GetProjectMeta(project string) (*ProjectMeta, error) {
return nil, err return nil, err
} }
defer res.Body.Close()
return parseProjectMeta(data) return parseProjectMeta(data)
} }
@@ -354,6 +362,7 @@ func (c *ObsClient) GetPackageMeta(project, pkg string) (*PackageMeta, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer res.Body.Close()
var meta PackageMeta var meta PackageMeta
err = xml.Unmarshal(data, &meta) err = xml.Unmarshal(data, &meta)
@@ -412,6 +421,7 @@ func (c *ObsClient) SetProjectMeta(meta *ProjectMeta) error {
if err != nil { if err != nil {
return err return err
} }
defer res.Body.Close()
switch res.StatusCode { switch res.StatusCode {
case 200: case 200:
@@ -428,6 +438,7 @@ func (c *ObsClient) DeleteProject(project string) error {
if err != nil { if err != nil {
return err return err
} }
defer res.Body.Close()
if res.StatusCode != 200 { if res.StatusCode != 200 {
return fmt.Errorf("Unexpected return code: %d", res.StatusCode) return fmt.Errorf("Unexpected return code: %d", res.StatusCode)
@@ -494,7 +505,7 @@ func (r *BuildResultList) GetPackageList() []string {
func (r *BuildResultList) BuildResultSummary() (success, finished bool) { func (r *BuildResultList) BuildResultSummary() (success, finished bool) {
if r == nil { if r == nil {
return true, true return false, false
} }
finished = len(r.Result) > 0 && len(r.Result[0].Status) > 0 finished = len(r.Result) > 0 && len(r.Result[0].Status) > 0
@@ -698,6 +709,7 @@ func (c *ObsClient) ProjectConfig(project string) (string, error) {
} }
if data, err := io.ReadAll(res.Body); err == nil { if data, err := io.ReadAll(res.Body); err == nil {
defer res.Body.Close()
return string(data), nil return string(data), nil
} else { } else {
return "", err return "", err
@@ -750,5 +762,6 @@ func (c *ObsClient) BuildStatusWithState(project string, opts *BuildResultOption
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer res.Body.Close()
return parseBuildResults(data) return parseBuildResults(data)
} }

View File

@@ -15,6 +15,7 @@ import (
type PRInfo struct { type PRInfo struct {
PR *models.PullRequest PR *models.PullRequest
Reviews *PRReviews Reviews *PRReviews
RemoteName string
} }
type PRSet struct { type PRSet struct {
@@ -31,7 +32,8 @@ func readPRData(gitea GiteaPRFetcher, pr *models.PullRequest, currentSet []PRInf
retSet := []PRInfo{PRInfo{PR: pr}} retSet := []PRInfo{PRInfo{PR: pr}}
// only need to extact there on PrjGit PR // only need to extact there on PrjGit PR
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))) _, refPRs := ExtractDescriptionAndPRs(bufio.NewScanner(strings.NewReader(pr.Body)))
for _, prdata := range refPRs { for _, prdata := range refPRs {
pr, err := gitea.GetPullRequest(prdata.Org, prdata.Repo, prdata.Num) pr, err := gitea.GetPullRequest(prdata.Org, prdata.Repo, prdata.Num)
@@ -54,7 +56,11 @@ func FetchPRSet(gitea GiteaPRFetcher, org, repo string, num int64, config *Autog
var err error var err error
prjGitOrg, prjGitRepo, _ := config.GetPrjGit() prjGitOrg, prjGitRepo, _ := config.GetPrjGit()
if prjGitOrg != org || prjGitRepo != config.GitProjectName { if prjGitOrg == org && prjGitRepo == repo {
if pr, err = gitea.GetPullRequest(org, repo, num); err != nil {
return nil, err
}
} else {
if pr, err = gitea.GetAssociatedPrjGitPR(prjGitOrg, prjGitRepo, org, repo, num); err != nil { if pr, err = gitea.GetAssociatedPrjGitPR(prjGitOrg, prjGitRepo, org, repo, num); err != nil {
return nil, err return nil, err
} }
@@ -64,10 +70,6 @@ func FetchPRSet(gitea GiteaPRFetcher, org, repo string, num int64, config *Autog
return nil, err return nil, err
} }
} }
} else {
if pr, err = gitea.GetPullRequest(org, repo, num); err != nil {
return nil, err
}
} }
prs, err := readPRData(gitea, pr, nil, config) prs, err := readPRData(gitea, pr, nil, config)
@@ -79,7 +81,8 @@ func FetchPRSet(gitea GiteaPRFetcher, org, repo string, num int64, config *Autog
} }
func (rs *PRSet) IsPrjGitPR(pr *models.PullRequest) bool { 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, _ := rs.Config.GetPrjGit()
return pr.Base.Repo.Name == repo && pr.Base.Repo.Owner.UserName == org
} }
func (rs *PRSet) GetPrjGitPR() (*models.PullRequest, error) { func (rs *PRSet) GetPrjGitPR() (*models.PullRequest, error) {
@@ -215,8 +218,9 @@ func (rs *PRSet) Merge(gh GitHandlerGenerator) error {
if err != nil { if err != nil {
return err return err
} }
git.GitExecOrPanic("", "clone", "--depth", "1", prjgit.Base.Repo.SSHURL, DefaultGitPrj) remote, err := git.GitClone(DefaultGitPrj, rs.Config.Branch, prjgit.Base.Repo.SSHURL)
git.GitExecOrPanic(DefaultGitPrj, "fetch", "origin", prjgit.Base.Sha, prjgit.Head.Sha) PanicOnError(err)
git.GitExecOrPanic(DefaultGitPrj, "fetch", remote, prjgit.Base.Sha, prjgit.Head.Sha)
// if other changes merged, check if we have conflicts // if other changes merged, check if we have conflicts
rev := strings.TrimSpace(git.GitExecWithOutputOrPanic(DefaultGitPrj, "merge-base", "HEAD", prjgit.Base.Sha, prjgit.Head.Sha)) rev := strings.TrimSpace(git.GitExecWithOutputOrPanic(DefaultGitPrj, "merge-base", "HEAD", prjgit.Base.Sha, prjgit.Head.Sha))
@@ -303,8 +307,6 @@ func (rs *PRSet) Merge(gh GitHandlerGenerator) error {
return fmt.Errorf("Can't close .gitmodules: %w", err) return fmt.Errorf("Can't close .gitmodules: %w", err)
} }
os.CopyFS("/tmp/test", os.DirFS(git.GetPath()))
git.GitExecOrPanic(DefaultGitPrj, "add", ".gitmodules") git.GitExecOrPanic(DefaultGitPrj, "add", ".gitmodules")
git.GitExecOrPanic(DefaultGitPrj, "-c", "core.editor=true", "merge", "--continue") git.GitExecOrPanic(DefaultGitPrj, "-c", "core.editor=true", "merge", "--continue")
} }
@@ -316,18 +318,19 @@ func (rs *PRSet) Merge(gh GitHandlerGenerator) error {
if rs.IsPrjGitPR(prinfo.PR) { if rs.IsPrjGitPR(prinfo.PR) {
continue continue
} }
git.GitExecOrPanic("", "clone", prinfo.PR.Base.Repo.SSHURL, prinfo.PR.Base.Name) prinfo.RemoteName, err = git.GitClone(prinfo.PR.Base.Name, rs.Config.Branch, prinfo.PR.Base.Repo.SSHURL)
git.GitExecOrPanic(prinfo.PR.Base.Name, "fetch", "origin", prinfo.PR.Head.Sha) PanicOnError(err)
git.GitExecOrPanic(prinfo.PR.Base.Name, "fetch", prinfo.RemoteName, prinfo.PR.Head.Sha)
git.GitExecOrPanic(prinfo.PR.Base.Name, "merge", "--ff", prinfo.PR.Head.Sha) git.GitExecOrPanic(prinfo.PR.Base.Name, "merge", "--ff", prinfo.PR.Head.Sha)
} }
// push changes // push changes
git.GitExecOrPanic(DefaultGitPrj, "push", "origin") git.GitExecOrPanic(DefaultGitPrj, "push", remote)
for _, prinfo := range rs.PRs { for _, prinfo := range rs.PRs {
if rs.IsPrjGitPR(prinfo.PR) { if rs.IsPrjGitPR(prinfo.PR) {
continue continue
} }
git.GitExecOrPanic(prinfo.PR.Base.Name, "push", "origin") git.GitExecOrPanic(prinfo.PR.Base.Name, "push", prinfo.RemoteName)
} }
return nil return nil

View File

@@ -463,13 +463,17 @@ func TestPRAssignReviewers(t *testing.T) {
} }
func TestPRMerge(t *testing.T) { func TestPRMerge(t *testing.T) {
repoDir := t.TempDir()
cwd, _ := os.Getwd() cwd, _ := os.Getwd()
cmd := exec.Command("/usr/bin/bash", path.Join(cwd, "test_repo_setup.sh")) cmd := exec.Command(path.Join(cwd, "test_repo_setup.sh"))
cmd.Dir = t.TempDir() cmd.Dir = repoDir
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Fatal(string(out)) t.Fatal(string(out))
} }
common.SetLoggingLevel(common.LogLevelDebug)
common.ExtraGitParams = []string{ common.ExtraGitParams = []string{
"GIT_CONFIG_COUNT=1", "GIT_CONFIG_COUNT=1",
"GIT_CONFIG_KEY_0=protocol.file.allow", "GIT_CONFIG_KEY_0=protocol.file.allow",
@@ -504,7 +508,7 @@ func TestPRMerge(t *testing.T) {
Owner: &models.User{ Owner: &models.User{
UserName: "org", UserName: "org",
}, },
SSHURL: path.Join(cmd.Dir, "prjgit"), SSHURL: "file://" + path.Join(repoDir, "prjgit"),
}, },
}, },
Head: &models.PRBranchInfo{ Head: &models.PRBranchInfo{
@@ -524,7 +528,7 @@ func TestPRMerge(t *testing.T) {
Owner: &models.User{ Owner: &models.User{
UserName: "org", UserName: "org",
}, },
SSHURL: path.Join(cmd.Dir, "prjgit"), SSHURL: "file://" + path.Join(cmd.Dir, "prjgit"),
}, },
}, },
Head: &models.PRBranchInfo{ Head: &models.PRBranchInfo{
@@ -539,6 +543,8 @@ func TestPRMerge(t *testing.T) {
ctl := gomock.NewController(t) ctl := gomock.NewController(t)
mock := mock_common.NewMockGiteaPRFetcher(ctl) mock := mock_common.NewMockGiteaPRFetcher(ctl)
testDir := t.TempDir()
t.Log("dir:", testDir)
mock.EXPECT().GetPullRequest("org", "prj", int64(1)).Return(test.pr, nil) mock.EXPECT().GetPullRequest("org", "prj", int64(1)).Return(test.pr, nil)
set, err := common.FetchPRSet(mock, "org", "prj", 1, config) set, err := common.FetchPRSet(mock, "org", "prj", 1, config)
@@ -546,8 +552,12 @@ func TestPRMerge(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
gh, _ := common.AllocateGitWorkTree("", "", "") gh, _ := common.AllocateGitWorkTree(testDir, "", "")
if err = set.Merge(gh); err != nil && (test.mergeError == "" || (len(test.mergeError) > 0 && !strings.Contains(err.Error(), test.mergeError))) { err = set.Merge(gh)
if err != nil && (test.mergeError == "" || (len(test.mergeError) > 0 && !strings.Contains(err.Error(), test.mergeError))) {
os.CopyFS("/tmp/upstream", os.DirFS(repoDir))
os.CopyFS("/tmp/out", os.DirFS(testDir))
t.Fatal(err) t.Fatal(err)
} }
}) })

View File

@@ -84,6 +84,11 @@ var valid_schemas []string = []string{"https", "ssh", "http", "file"}
func ParseGitRemoteUrl(urlString string) (*GitUrl, error) { func ParseGitRemoteUrl(urlString string) (*GitUrl, error) {
url, err := url.Parse(urlString) url, err := url.Parse(urlString)
if url != nil && url.Scheme == "file" && err == nil {
return nil, nil
}
if err != nil || !slices.Contains(valid_schemas, url.Scheme) { if err != nil || !slices.Contains(valid_schemas, url.Scheme) {
u, err := TranslateSshNativeToUrl(urlString) u, err := TranslateSshNativeToUrl(urlString)
if err != nil { if err != nil {

View File

@@ -105,15 +105,16 @@ const (
) )
func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatusSummary { func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatusSummary {
if _, finished := project.BuildResultSummary(); !finished {
return BuildStatusSummaryBuilding
}
if _, finished := refProject.BuildResultSummary(); !finished { if _, finished := refProject.BuildResultSummary(); !finished {
common.LogDebug("refProject not finished building??") common.LogDebug("refProject not finished building??")
return BuildStatusSummaryUnknown return BuildStatusSummaryUnknown
} }
if _, finished := project.BuildResultSummary(); !finished {
common.LogDebug("Still building...")
return BuildStatusSummaryBuilding
}
// the repositories should be setup equally between the projects. We // the repositories should be setup equally between the projects. We
// need to verify that packages that are building in `refProject` are not // need to verify that packages that are building in `refProject` are not
// failing in the `project` // failing in the `project`
@@ -684,7 +685,7 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) error {
TargetURL: ObsWebHost + "/project/show/" + stagingProject, TargetURL: ObsWebHost + "/project/show/" + stagingProject,
} }
if change != RequestModificationNoChange { if change != RequestModificationNoChange {
gitea.SetCommitStatus(pr.Base.Repo.Owner.UserName, pr.Base.Repo.Name, pr.Head.Sha, status) common.LogDebug(gitea.SetCommitStatus(pr.Base.Repo.Owner.UserName, pr.Base.Repo.Name, pr.Head.Sha, status))
} }
if change == RequestModificationProjectCreated { if change == RequestModificationProjectCreated {
@@ -808,6 +809,9 @@ func main() {
ObsWebHost = ObsWebHostFromApiHost(ObsApiHost) ObsWebHost = ObsWebHostFromApiHost(ObsApiHost)
} }
common.LogDebug("OBS Web Host:", ObsWebHost)
common.LogDebug("OBS API Host:", ObsApiHost)
common.PanicOnErrorWithMsg(common.RequireGiteaSecretToken(), "Cannot find GITEA_TOKEN") common.PanicOnErrorWithMsg(common.RequireGiteaSecretToken(), "Cannot find GITEA_TOKEN")
common.PanicOnErrorWithMsg(common.RequireObsSecretToken(), "Cannot find OBS_USER and OBS_PASSWORD") common.PanicOnErrorWithMsg(common.RequireObsSecretToken(), "Cannot find OBS_USER and OBS_PASSWORD")
@@ -828,9 +832,6 @@ func main() {
for { for {
PollWorkNotifications(GiteaUrl) PollWorkNotifications(GiteaUrl)
if *debug {
break
}
common.LogInfo("Poll cycle finished") common.LogInfo("Poll cycle finished")
time.Sleep(5 * time.Minute) time.Sleep(5 * time.Minute)
} }

View File

@@ -513,7 +513,7 @@ func main() {
giteaUrl := flag.String("gitea-url", "https://src.opensuse.org", "Gitea instance") giteaUrl := flag.String("gitea-url", "https://src.opensuse.org", "Gitea instance")
rabbitUrl := flag.String("url", "amqps://rabbit.opensuse.org", "URL for RabbitMQ instance") rabbitUrl := flag.String("url", "amqps://rabbit.opensuse.org", "URL for RabbitMQ instance")
flag.BoolVar(&DebugMode, "debug", false, "Extra debugging information") 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") 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") 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") basePath := flag.String("repo-path", "", "Repository path. Default is temporary directory")

View File

@@ -22,7 +22,9 @@ import (
"flag" "flag"
"net/url" "net/url"
"os" "os"
"regexp"
"slices" "slices"
"strconv"
"time" "time"
"src.opensuse.org/autogits/common" "src.opensuse.org/autogits/common"
@@ -39,6 +41,7 @@ var ListPROnly bool
var PRID int64 var PRID int64
var CurrentUser *models.User var CurrentUser *models.User
var GitHandler common.GitHandlerGenerator var GitHandler common.GitHandlerGenerator
var Gitea common.Gitea
func main() { func main() {
workflowConfig := flag.String("config", "", "Repository and workflow definition file") workflowConfig := flag.String("config", "", "Repository and workflow definition file")
@@ -50,6 +53,7 @@ func main() {
flag.BoolVar(&ListPROnly, "list-prs-only", false, "Only lists PRs without acting on them") 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") 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") basePath := flag.String("repo-path", "", "Repository path. Default is temporary directory")
pr := flag.String("only-pr", "", "Only specific PR to process. For debugging")
flag.Parse() flag.Parse()
common.SetLoggingLevel(common.LogLevelInfo) common.SetLoggingLevel(common.LogLevelInfo)
@@ -72,19 +76,23 @@ func main() {
return return
} }
gitea := common.AllocateGiteaTransport(*giteaUrl) Gitea = common.AllocateGiteaTransport(*giteaUrl)
config, err := common.ReadConfigFile(*workflowConfig) config, err := common.ReadConfigFile(*workflowConfig)
if err != nil { if err != nil {
common.LogError("Cannot read config files:", err) common.LogError("Cannot read config files:", err)
return return
} }
configs, err := common.ResolveWorkflowConfigs(gitea, config) configs, err := common.ResolveWorkflowConfigs(Gitea, config)
if err != nil { if err != nil {
common.LogError("Cannot resolve config files:", err) common.LogError("Cannot resolve config files:", err)
return return
} }
for _, c := range configs {
common.LogDebug(*c)
}
req := new(RequestProcessor) req := new(RequestProcessor)
req.configuredRepos = make(map[string][]*common.AutogitConfig) req.configuredRepos = make(map[string][]*common.AutogitConfig)
@@ -111,26 +119,67 @@ 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) common.LogError("Failed to fetch current gitea user:", err)
return return
} }
common.LogInfo("Running with token from", CurrentUser.UserName) common.LogInfo("Running with token from", CurrentUser.UserName)
req.Synced = &PullRequestSynced{ req.Synced = &PullRequestSynced{}
gitea: gitea, req.Opened = &PullRequestOpened{}
} req.Closed = &PullRequestClosed{}
req.Opened = &PullRequestOpened{ req.Review = &PullRequestReviewed{}
gitea: gitea,
} if *pr != "" {
req.Closed = &PullRequestClosed{ rx := regexp.MustCompile("^([a-zA-Z0-9_\\.-]+)/([a-zA-Z0-9_\\.-]+)#([0-9]+)$")
gitea: gitea, if data := rx.FindStringSubmatch(*pr); data == nil {
} common.LogError("Cannot parse PR line to process", *pr)
req.Review = &PullRequestReviewed{ } else {
gitea: gitea, 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
} }
checker := CreateDefaultStateChecker(*checkOnStart, req, gitea, time.Duration(*checkIntervalHours)*time.Hour) if pr.State != "open" {
common.LogError("Can only deal with open PRs. This one is", pr.State)
return
}
c := configs.GetPrjGitConfig(org, repo, pr.Base.Ref)
if c == nil {
if pr.Base.Repo.DefaultBranch == pr.Base.Ref {
c = configs.GetPrjGitConfig(org, repo, "")
}
}
if c == nil {
common.LogError("Cannot find config for PR.")
return
}
git, err := GitHandler.CreateGitHandler(org)
common.PanicOnError(err)
defer git.Close()
p := common.PullRequestWebhookEvent{
Action: "opened",
Number: num,
Pull_Request: common.PullRequestFromModel(pr),
}
if err = req.Opened.Process(&p, git, c); err != nil {
common.LogError("processor returned error", err)
}
}
return
}
checker := CreateDefaultStateChecker(*checkOnStart, req, Gitea, time.Duration(*checkIntervalHours)*time.Hour)
go checker.ConsistencyCheckProcess() go checker.ConsistencyCheckProcess()
listenDefs := common.ListenDefinitions{ listenDefs := common.ListenDefinitions{

View File

@@ -30,14 +30,26 @@ func (w *RequestProcessor) ProcessFunc(request *common.Request) error {
return nil return nil
} }
org := req.Pull_Request.Base.Repo.Owner.Username
pkg := req.Pull_Request.Base.Repo.Name
branch := req.Pull_Request.Base.Ref
assumed_git_project_name := org + "/" + pkg + "#" + branch
var config *common.AutogitConfig var config *common.AutogitConfig
for _, c := range configs { for _, c := range configs {
if c.GitProjectName == req.Pull_Request.Base.Repo.Name || if c.GitProjectName == assumed_git_project_name {
c.Branch == req.Pull_Request.Base.Ref {
config = c config = c
break break
} }
if c.Organization == org {
// default branch *or* match branch
if (c.Branch == "" && branch == req.Pull_Request.Base.Repo.Default_Branch) ||
(c.Branch != "" && c.Branch == branch) {
config = c
break
}
}
} }
if config == nil { if config == nil {
return fmt.Errorf("Cannot find config for branch '%s'", req.Pull_Request.Base.Ref) return fmt.Errorf("Cannot find config for branch '%s'", req.Pull_Request.Base.Ref)

View File

@@ -4,9 +4,7 @@ import (
"src.opensuse.org/autogits/common" "src.opensuse.org/autogits/common"
) )
type PullRequestClosed struct { type PullRequestClosed struct{}
gitea common.Gitea
}
func (*PullRequestClosed) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error { func (*PullRequestClosed) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error {
if req.Repository.Name != config.GitProjectName { if req.Repository.Name != config.GitProjectName {

View File

@@ -5,50 +5,61 @@ import (
"src.opensuse.org/autogits/common" "src.opensuse.org/autogits/common"
) )
type PullRequestOpened struct { type PullRequestOpened struct{}
gitea common.Gitea
}
func (o *PullRequestOpened) CreateOrUpdatePrjGitPR(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error { func (o *PullRequestOpened) CreateOrUpdatePrjGitPR(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error {
// create PrjGit branch for buidling the pull request // create PrjGit branch for buidling the pull request
branchName := prGitBranchNameForPR(req) branchName := prGitBranchNameForPR(req)
// TODO: fix this for config.Organization // TODO: fix this for config.Organization
org, prj, _ := config.GetPrjGit() org, prj, _ := config.GetPrjGit()
prjGit, err := o.gitea.CreateRepositoryIfNotExist(git, org, prj) prjGit, err := Gitea.CreateRepositoryIfNotExist(git, org, prj)
common.PanicOnErrorWithMsg(err, "Error creating a prjgitrepo: "+err.Error()) common.PanicOnErrorWithMsg(err, "Error creating a prjgitrepo:", err)
remoteName, err := git.GitClone(common.DefaultGitPrj, config.Branch, prjGit.SSHURL) remoteName, err := git.GitClone(common.DefaultGitPrj, config.Branch, prjGit.SSHURL)
common.PanicOnError(err) common.PanicOnError(err)
// check if branch already there, and check that out if available
if err := git.GitExec(common.DefaultGitPrj, "fetch", remoteName, branchName); err == nil {
git.GitExecOrPanic(common.DefaultGitPrj, "checkout", "-B", branchName, remoteName+"/"+branchName)
}
prOrg := req.Pull_Request.Base.Repo.Owner.Username
prRepo := req.Pull_Request.Base.Repo.Name
commitMsg := fmt.Sprintf(`auto-created for %s commitMsg := fmt.Sprintf(`auto-created for %s
This commit was autocreated by %s This commit was autocreated by %s
referencing referencing
`+common.PrPattern, `+common.PrPattern,
req.Repository.Owner.Username, prOrg,
req.Repository.Name, prRepo,
GitAuthor, GitAuthor,
req.Repository.Name, prRepo,
req.Pull_Request.Number, req.Pull_Request.Number,
) )
subList, err := git.GitSubmoduleList(common.DefaultGitPrj, "HEAD") subList, err := git.GitSubmoduleList(common.DefaultGitPrj, "HEAD")
common.PanicOnError(err) common.PanicOnError(err)
if id := subList[req.Repository.Name]; id != req.Pull_Request.Head.Sha { if id := subList[prRepo]; id != req.Pull_Request.Head.Sha {
updateSubmoduleInPR(req, git) updateSubmoduleInPR(req, git)
status, err := git.GitStatus(common.DefaultGitPrj)
common.LogDebug("status:", status)
common.LogDebug("submodule", prRepo, " hash:", id, " -> ", req.Pull_Request.Head.Sha)
common.PanicOnError(err)
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "commit", "-a", "-m", commitMsg)) common.PanicOnError(git.GitExec(common.DefaultGitPrj, "commit", "-a", "-m", commitMsg))
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "push", remoteName, "+HEAD:"+branchName)) common.PanicOnError(git.GitExec(common.DefaultGitPrj, "push", remoteName, "+HEAD:"+branchName))
} }
_, err = o.gitea.CreatePullRequestIfNotExist(prjGit, branchName, prjGit.DefaultBranch, _, err = Gitea.CreatePullRequestIfNotExist(prjGit, branchName, prjGit.DefaultBranch,
fmt.Sprintf("Forwarded PR: %s", req.Repository.Name), fmt.Sprintf("Forwarded PR: %s", prRepo),
fmt.Sprintf(`This is a forwarded pull request by %s fmt.Sprintf(`This is a forwarded pull request by %s
referencing the following pull request: referencing the following pull request:
`+common.PrPattern, `+common.PrPattern,
GitAuthor, req.Repository.Owner.Username, req.Repository.Name, req.Pull_Request.Number), GitAuthor, prOrg, prRepo, req.Pull_Request.Number),
) )
return err return err
@@ -57,27 +68,33 @@ referencing the following pull request:
func (o *PullRequestOpened) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error { func (o *PullRequestOpened) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error {
// requests against project are not handled here // requests against project are not handled here
common.LogInfo("processing opened PR:", req.Pull_Request.Url) common.LogInfo("processing opened PR:", req.Pull_Request.Url)
if org, repo, _ := config.GetPrjGit(); req.Repository.Owner.Username != org || req.Repository.Name != repo { prOrg := req.Pull_Request.Base.Repo.Owner.Username
prRepo := req.Pull_Request.Base.Repo.Name
if prjGitOrg, prjGitRepo, _ := config.GetPrjGit(); prOrg != prjGitOrg || prRepo != prjGitRepo {
if err := o.CreateOrUpdatePrjGitPR(req, git, config); err != nil { if err := o.CreateOrUpdatePrjGitPR(req, git, config); err != nil {
return err return err
} }
} }
prset, err := common.FetchPRSet(o.gitea, req.Repository.Owner.Username, req.Repository.Name, req.Number, config) prset, err := common.FetchPRSet(Gitea, prOrg, prRepo, req.Number, config)
if err != nil { if err != nil {
common.LogError("Cannot fetch PRSet:", err)
return err return err
} }
common.LogInfo("fetched PRSet of size:", len(prset.PRs))
// request build review // request build review
PR, err := prset.GetPrjGitPR() PR, err := prset.GetPrjGitPR()
if err != nil { if err != nil {
common.LogError("Error fetching PrjGitPR:", err)
return nil return nil
} }
common.LogDebug(" num of reviewers:", len(PR.RequestedReviewers)) common.LogDebug(" num of reviewers:", len(PR.RequestedReviewers))
maintainers, err := common.FetchProjectMaintainershipData(o.gitea, config.Organization, config.GitProjectName, config.Branch) org, repo, branch := config.GetPrjGit()
maintainers, err := common.FetchProjectMaintainershipData(Gitea, org, repo, branch)
if err != nil { if err != nil {
return err return err
} }
return prset.AssignReviewers(o.gitea, maintainers) return prset.AssignReviewers(Gitea, maintainers)
} }

View File

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

View File

@@ -10,7 +10,7 @@ import (
) )
func prGitBranchNameForPR(req *common.PullRequestWebhookEvent) string { func prGitBranchNameForPR(req *common.PullRequestWebhookEvent) string {
return fmt.Sprintf("PR_%s#%d", req.Repository.Name, req.Pull_Request.Number) return fmt.Sprintf("PR_%s#%d", req.Pull_Request.Base.Repo.Name, req.Pull_Request.Number)
} }
func updateSubmoduleInPR(req *common.PullRequestWebhookEvent, git common.Git) { func updateSubmoduleInPR(req *common.PullRequestWebhookEvent, git common.Git) {
@@ -25,18 +25,17 @@ func processPrjGitPullRequestSync(req *common.PullRequestWebhookEvent) error {
return nil return nil
} }
type PullRequestSynced struct { type PullRequestSynced struct{}
gitea common.Gitea
}
func (o *PullRequestSynced) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error { func (o *PullRequestSynced) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error {
if req.Repository.Name == config.GitProjectName { prjGitOrg, prjGitRepo, _ := config.GetPrjGit()
if req.Repository.Owner.Username == prjGitOrg && req.Repository.Name == prjGitRepo {
return processPrjGitPullRequestSync(req) return processPrjGitPullRequestSync(req)
} }
// need to verify that submodule in the PR for prjgit // need to verify that submodule in the PR for prjgit
// is still pointing to the HEAD of the PR // is still pointing to the HEAD of the PR
pr, err := o.gitea.GetPullRequest(req.Repository.Owner.Username, req.Repository.Name, req.Number) pr, err := Gitea.GetPullRequest(req.Repository.Owner.Username, req.Repository.Name, req.Number)
if err != nil { if err != nil {
return fmt.Errorf("Cannot fetch PR data from gitea: %w", err) return fmt.Errorf("Cannot fetch PR data from gitea: %w", err)
} }
@@ -46,13 +45,15 @@ func (o *PullRequestSynced) Process(req *common.PullRequestWebhookEvent, git com
return fmt.Errorf("Package update associated with invalid number of projects. Expected 1. Got %d", len(prs)) return fmt.Errorf("Package update associated with invalid number of projects. Expected 1. Got %d", len(prs))
} }
prjPr, err := o.gitea.GetPullRequest(prs[0].Org, prs[0].Repo, prs[0].Num) prjPr, err := Gitea.GetPullRequest(prs[0].Org, prs[0].Repo, prs[0].Num)
if err != nil { if err != nil {
return fmt.Errorf("Cannot get PrjGit PR in processPullRequestSync. Err: %w", err) return fmt.Errorf("Cannot get PrjGit PR in processPullRequestSync. Err: %w", err)
} }
common.PanicOnError(git.GitExec("", "clone", "--branch", prjPr.Head.Name, "--depth", "1", prjPr.Head.Repo.SSHURL, common.DefaultGitPrj)) branchName := prGitBranchNameForPR(req)
remote, err := git.GitClone(common.DefaultGitPrj, branchName, prjPr.Head.Repo.SSHURL)
common.PanicOnError(err)
commitId, ok := git.GitSubmoduleCommitId(common.DefaultGitPrj, req.Repository.Name, prjPr.Head.Sha) commitId, ok := git.GitSubmoduleCommitId(common.DefaultGitPrj, req.Repository.Name, prjPr.Head.Sha)
if !ok { if !ok {
@@ -74,9 +75,8 @@ Update to %s`, req.Pull_Request.Head.Sha)
common.LogDebug("Creating new commit msg:", commitMsg) common.LogDebug("Creating new commit msg:", commitMsg)
// we need to update prjgit PR with the new head hash // we need to update prjgit PR with the new head hash
branchName := prGitBranchNameForPR(req)
updateSubmoduleInPR(req, git) updateSubmoduleInPR(req, git)
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "commit", "-a", "-m", commitMsg)) common.PanicOnError(git.GitExec(common.DefaultGitPrj, "commit", "-a", "-m", commitMsg))
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "push", "origin", "+HEAD:"+branchName)) common.PanicOnError(git.GitExec(common.DefaultGitPrj, "push", remote))
return nil return nil
} }

View File

@@ -26,14 +26,12 @@ type DefaultStateChecker struct {
checkOnStart bool checkOnStart bool
checkInterval time.Duration checkInterval time.Duration
gitea common.Gitea
processor *RequestProcessor processor *RequestProcessor
i StateChecker i StateChecker
} }
func CreateDefaultStateChecker(checkOnStart bool, processor *RequestProcessor, gitea common.Gitea, interval time.Duration) *DefaultStateChecker { func CreateDefaultStateChecker(checkOnStart bool, processor *RequestProcessor, gitea common.Gitea, interval time.Duration) *DefaultStateChecker {
var s = &DefaultStateChecker{ var s = &DefaultStateChecker{
gitea: gitea,
checkInterval: interval, checkInterval: interval,
checkOnStart: checkOnStart, checkOnStart: checkOnStart,
processor: processor, processor: processor,
@@ -62,8 +60,10 @@ func (s *DefaultStateChecker) ProcessPR(git common.Git, pr *models.PullRequest,
return fmt.Errorf("Unhandled pull request state: '%s'. %s/%s/%d", pr.State, config.Organization, "", pr.Index) return fmt.Errorf("Unhandled pull request state: '%s'. %s/%s/%d", pr.State, config.Organization, "", pr.Index)
} }
if err != nil {
common.LogError(" * processor error returned:", err) common.LogError(" * processor error returned:", err)
return nil }
return err
} }
func (s *DefaultStateChecker) VerifyProjectState(config *common.AutogitConfig) error { func (s *DefaultStateChecker) VerifyProjectState(config *common.AutogitConfig) error {
@@ -80,20 +80,20 @@ func (s *DefaultStateChecker) VerifyProjectState(config *common.AutogitConfig) e
prjGitOrg, prjGitRepo, prjGitBranch := config.GetPrjGit() prjGitOrg, prjGitRepo, prjGitBranch := config.GetPrjGit()
common.LogInfo(" checking", prjGitOrg+"/"+prjGitRepo+"#"+prjGitBranch) common.LogInfo(" checking", prjGitOrg+"/"+prjGitRepo+"#"+prjGitBranch)
git, err := GitHandler.CreateGitHandler(prjGitOrg) git, err := GitHandler.CreateGitHandler(config.Organization)
if err != nil { if err != nil {
return fmt.Errorf("Cannot create git handler: %w", err) return fmt.Errorf("Cannot create git handler: %w", err)
} }
defer git.Close() defer git.Close()
repo, err := s.gitea.CreateRepositoryIfNotExist(git, prjGitOrg, prjGitRepo) repo, err := Gitea.CreateRepositoryIfNotExist(git, prjGitOrg, prjGitRepo)
if err != nil { if err != nil {
return fmt.Errorf("Error fetching or creating '%s/%s#%s' -- aborting verifyProjectState(). Err: %w", prjGitBranch, prjGitRepo, prjGitBranch, err) return fmt.Errorf("Error fetching or creating '%s/%s#%s' -- aborting verifyProjectState(). Err: %w", prjGitBranch, prjGitRepo, prjGitBranch, err)
} }
_, err = git.GitClone(config.GitProjectName, prjGitBranch, repo.SSHURL) _, err = git.GitClone(config.GitProjectName, prjGitBranch, repo.SSHURL)
common.PanicOnError(err) common.PanicOnError(err)
prs, err := s.gitea.GetRecentPullRequests(prjGitOrg, prjGitRepo, prjGitBranch) prs, err := Gitea.GetRecentPullRequests(prjGitOrg, prjGitRepo, prjGitBranch)
if err != nil { if err != nil {
return fmt.Errorf("Error fetching PrjGit Prs for %s/%s#%s: %w", prjGitOrg, prjGitRepo, prjGitBranch, err) return fmt.Errorf("Error fetching PrjGit Prs for %s/%s#%s: %w", prjGitOrg, prjGitRepo, prjGitBranch, err)
} }
@@ -114,9 +114,18 @@ nextSubmodule:
} }
// check if open PR have PR against project // check if open PR have PR against project
prs, err := s.gitea.GetRecentPullRequests(config.Organization, submoduleName, config.Branch) branch := config.Branch
if branch == "" {
repo, err := Gitea.GetRepository(config.Organization, submoduleName)
if err != nil || repo == nil {
common.LogError("Cannot fetch repository:", config.Organization, "/", submoduleName, "... submodule skipped.")
continue
}
branch = repo.DefaultBranch
}
prs, err := Gitea.GetRecentPullRequests(config.Organization, submoduleName, branch)
if err != nil { if err != nil {
return fmt.Errorf("Error fetching pull requests for %s/%s#%s. Err: %w", config.Organization, submoduleName, config.Branch, err) return fmt.Errorf("Error fetching pull requests for %s/%s#%s. Err: %w", config.Organization, submoduleName, branch, err)
} }
common.LogDebug(" - # of PRs to check:", len(prs)) common.LogDebug(" - # of PRs to check:", len(prs))
@@ -125,7 +134,7 @@ nextSubmodule:
} }
// check if the commited changes are syned with branches // check if the commited changes are syned with branches
commits, err := s.gitea.GetRecentCommits(config.Organization, submoduleName, config.Branch, 10) commits, err := Gitea.GetRecentCommits(config.Organization, submoduleName, branch, 10)
if err != nil { if err != nil {
return fmt.Errorf("Error fetching recent commits for %s/%s. Err: %w", config.Organization, submoduleName, err) return fmt.Errorf("Error fetching recent commits for %s/%s. Err: %w", config.Organization, submoduleName, err)
} }
@@ -143,18 +152,18 @@ nextSubmodule:
// not found in past, check if we should advance the branch label ... pull the submodule // not found in past, check if we should advance the branch label ... pull the submodule
git.GitExecOrPanic(config.GitProjectName, "submodule", "update", "--init", "--filter", "blob:none", "--", sub) git.GitExecOrPanic(config.GitProjectName, "submodule", "update", "--init", "--filter", "blob:none", "--", sub)
subDir := path.Join(config.GitProjectName, sub) subDir := path.Join(config.GitProjectName, sub)
newCommits := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(subDir, "rev-list", "^origin/"+config.Branch, commitID), "\n") newCommits := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(subDir, "rev-list", "^origin/"+branch, commitID), "\n")
if len(newCommits) >= 1 { if len(newCommits) >= 1 {
common.LogDebug(" - updating branch", config.Branch, "to new head", commitID, " - len:", len(newCommits)) common.LogDebug(" - updating branch", branch, "to new head", commitID, " - len:", len(newCommits))
git.GitExecOrPanic(subDir, "checkout", "-B", config.Branch, commitID) git.GitExecOrPanic(subDir, "checkout", "-B", branch, commitID)
url := git.GitExecWithOutputOrPanic(subDir, "remote", "get-url", "origin", "--push") url := git.GitExecWithOutputOrPanic(subDir, "remote", "get-url", "origin", "--push")
sshUrl, err := common.TranslateHttpsToSshUrl(strings.TrimSpace(url)) sshUrl, err := common.TranslateHttpsToSshUrl(strings.TrimSpace(url))
if err != nil { if err != nil {
return fmt.Errorf("Cannot traslate HTTPS git URL to SSH_URL. %w", err) return fmt.Errorf("Cannot traslate HTTPS git URL to SSH_URL. %w", err)
} }
git.GitExecOrPanic(subDir, "remote", "set-url", "origin", "--push", sshUrl) git.GitExecOrPanic(subDir, "remote", "set-url", "origin", "--push", sshUrl)
git.GitExecOrPanic(subDir, "push", "origin", config.Branch) git.GitExecOrPanic(subDir, "push", "origin", branch)
} }
} }