2 Commits

Author SHA256 Message Date
Jan Zerebecki
933ca9a3db Fix PR link
to use ! instead of # . The later is for issues and only works due to
a redirect, which currently fails in gitea if a repo has its issue
tracker disabled.
2025-08-19 16:27:39 +02:00
6cbeaef6f2 import: import SHA1 -> SHA256 repos
Also, always import all files to LFS when exported from scmsync
archives, as more often than not they are forgotten
2025-08-17 19:43:45 +02:00
7 changed files with 103 additions and 35 deletions

View File

@@ -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_-]+

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -243,14 +243,14 @@ func importFactoryRepoAndCheckHistory(pkg string, meta *common.PackageMeta) (fac
}
roots := 0
if _, err := git.GitBranchHead(pkg, "pool/devel"); err == nil {
if _, err := git.GitRemoteHead(pkg, "pool", "devel"); err == nil {
factory_roots := strings.TrimSpace(git.GitExecWithOutputOrPanic(pkg, "rev-list", "pool/factory", "--max-parents=0"))
devel_roots := strings.TrimSpace(git.GitExecWithOutputOrPanic(pkg, "rev-list", "pool/devel", "--max-parents=0"))
roots = len(common.SplitLines(factory_roots))
if devel_roots != factory_roots || len(common.SplitLines(factory_roots)) != 1 {
roots = 10
}
} else if _, err := git.GitBranchHead(pkg, "pool/factory"); err == nil {
} else if _, err := git.GitRemoteHead(pkg, "pool", "factory"); err == nil {
items := strings.TrimSpace(git.GitExecWithOutputOrPanic(pkg, "rev-list", "pool/factory", "--max-parents=0"))
roots = len(common.SplitLines(items))
} else {
@@ -396,41 +396,38 @@ func PushRepository(factoryRepo, develRepo *models.Repository, pkg string) (repo
SetRepoOptions(repo)
git.GitExec(pkg, "push", "develorigin", "--delete", "factory")
git.GitExec(pkg, "push", "develorigin", "--delete", "devel")
git.GitExec(pkg, "push", "develorigin", "--delete", "leap-16.0")
return repo
}
func importDevelRepoAndCheckHistory(pkg string, meta *common.PackageMeta) *models.Repository {
repo := CreateDevelOnlyPackage(pkg)
log.Println("setting main branch for devel package:", pkg)
if meta == nil {
log.Println(" **** pkg meta is nil? ****")
} else if len(meta.ScmSync) > 0 {
if _, err := os.Stat(path.Join(git.GetPath(), pkg)); os.IsNotExist(err) {
u, _ := url.Parse(meta.ScmSync)
if err2 := cloneDevel(git, "", pkg, meta.ScmSync, "origin", true); err2 != nil {
log.Panicln(err2)
}
if len(u.Fragment) == 0 {
u.Fragment = "HEAD"
}
git.GitExecOrPanic(pkg, "checkout", "-B", "main", u.Fragment)
}
common.LogDebug("skip check for scmsync")
return repo
}
if _, err := os.Stat(filepath.Join(git.GetPath(), pkg)); os.IsNotExist(err) {
cloneDevel(git, "", pkg, repo.SSHURL, "develorigin", false) // in case we have imported
}
if CloneScmsync(pkg, meta) {
return repo
}
var p, dp string
factory_branch, fhe := git.GitBranchHead(pkg, "factory")
factory_branch, fhe := git.GitRemoteHead(pkg, "develorigin", "factory")
if fhe == nil {
p = strings.TrimSpace(git.GitExecWithOutputOrPanic(pkg, "rev-list", "--max-parents=0", "--count", factory_branch))
} else {
common.LogError(fhe)
}
devel_branch, dhe := git.GitBranchHead(pkg, "devel")
devel_branch, dhe := git.GitRemoteHead(pkg, "develorigin", "devel")
if dhe != nil {
devel_project, err := devel_projects.GetDevelProject(pkg)
common.LogDebug("Devel project:", devel_project, err)
if err == common.DevelProjectNotFound {
// assume it's this project, maybe removed from factory
devel_project = prj
}
common.LogDebug("finding missing branches in", pkg, devel_project)
findMissingDevelBranch(git, pkg, devel_project)
devel_branch, dhe = git.GitBranchHead(pkg, "devel")
}
if dhe == nil {
dp = strings.TrimSpace(git.GitExecWithOutputOrPanic(pkg, "rev-list", "--max-parents=0", "--count", devel_branch))
} else {
@@ -462,11 +459,19 @@ func importDevelRepoAndCheckHistory(pkg string, meta *common.PackageMeta) *model
return repo
}
func SetMainBranch(pkg string) {
func SetMainBranch(pkg string, meta *common.PackageMeta) {
// scnsync, follow that and don't care
common.LogDebug("Setting main branch...")
remotes := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(pkg, "remote", "show"), "\n")
if slices.Contains(remotes, "origin") {
git.GitExecOrPanic(pkg, "checkout", "-B", "main", "origin/HEAD")
u, err := url.Parse(meta.ScmSync)
common.PanicOnError(err)
if len(u.Fragment) == 0 {
u.Fragment = "HEAD"
}
if err := git.GitExec(pkg, "checkout", "-B", "main", u.Fragment); err != nil {
git.GitExecOrPanic(pkg, "checkout", "-B", "main", "origin/"+u.Fragment)
}
return
}
@@ -490,6 +495,60 @@ func ObsToRepoName(obspkg string) string {
return strings.ReplaceAll(obspkg, "+", "_")
}
func ImportSha1Sync(pkg string, url *url.URL) {
common.LogDebug("Converting SHA1", url.String())
branch := url.Fragment
url.Fragment = ""
p := path.Join(pkg, "sha1stuff")
common.PanicOnError(os.RemoveAll(path.Join(git.GetPath(), p)))
git.GitExecOrPanic(pkg, "clone", "--mirror", url.String(), "sha1stuff")
git.GitExecOrPanic(p, "fetch", "origin", branch)
gitexport := exec.Command("/usr/bin/git", "fast-export", "--signed-tags=strip", "--tag-of-filtered-object=drop", "--all")
gitexport.Dir = path.Join(git.GetPath(), p)
gitexportData, err := gitexport.Output()
common.LogDebug("Got export data size:", len(gitexportData))
common.PanicOnError(err)
gitimport := exec.Command("/usr/bin/git", "fast-import", "--allow-unsafe-features")
gitimport.Dir = path.Join(git.GetPath(), pkg)
gitimport.Stdin = bytes.NewReader(gitexportData)
data, err := gitimport.CombinedOutput()
common.LogError(string(data))
common.PanicOnError(err)
common.PanicOnError(os.RemoveAll(path.Join(git.GetPath(), p)))
}
func LfsImport(pkg string) {
git.GitExecOrPanic(pkg, "lfs", "migrate", "import", "--everything",
"--include=*.7z,*.bsp,*.bz2,*.gem,*.gz,*.jar,*.lz,*.lzma,*.obscpio,*.oxt,*.pdf,*.png,*.rpm,*.tar,*.tbz,*.tbz2,*.tgz,*.ttf,*.txz,*.whl,*.xz,*.zip,*.zst")
}
func CloneScmsync(pkg string, meta *common.PackageMeta) bool {
if len(meta.ScmSync) > 0 {
u, _ := url.Parse(meta.ScmSync)
if remotes := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(pkg, "remote", "show"), "\n"); !slices.Contains(remotes, "origin") {
branch := u.Fragment
if len(branch) == 0 {
branch = "HEAD"
}
u.Fragment = ""
git.GitExecOrPanic(pkg, "remote", "add", "origin", u.String())
u.Fragment = branch
}
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)
}
LfsImport(pkg)
return true
}
return false
}
func importRepo(pkg string) (BrokenFactoryPackage, FailedImport bool) {
BrokenFactoryPackage = false
FailedImport = false
@@ -509,6 +568,9 @@ func importRepo(pkg string) (BrokenFactoryPackage, FailedImport bool) {
if err != nil {
common.PanicOnError(err)
}
if meta == nil {
panic("package meta is nil...")
}
factoryRepo, err = importFactoryRepoAndCheckHistory(pkg, meta)
if factoryRepo != nil && err != nil {
@@ -520,9 +582,11 @@ func importRepo(pkg string) (BrokenFactoryPackage, FailedImport bool) {
if factoryRepo == nil || BrokenFactoryPackage {
develRepo = importDevelRepoAndCheckHistory(pkg, meta)
} else {
CloneScmsync(pkg, meta)
}
SetMainBranch(pkg)
SetMainBranch(pkg, meta)
PushRepository(factoryRepo, develRepo, pkg)
return
}

View File

@@ -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" {

View File

@@ -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)

View File

@@ -80,7 +80,7 @@ func AllocatePRProcessor(req *common.PullRequestWebhookEvent, configs common.Aut
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)