bab29a83fa
Sweep all .go imports + go.mod, plus module-path refs in .golangci.yml, Dockerfile, swagger templates, locale example, and repo/wiki URLs (MokoGitea-Fork -> MokoGIT). Part of the MokoGIT rebrand. Claude-Session: https://claude.ai/code/session_01Bqe7fAuHQeiLueYfeHFrHw
104 lines
3.3 KiB
Go
104 lines
3.3 KiB
Go
// Copyright 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package cascade
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
issues_model "code.mokoconsulting.tech/MokoConsulting/MokoGIT/models/issues"
|
|
repo_model "code.mokoconsulting.tech/MokoConsulting/MokoGIT/models/repo"
|
|
user_model "code.mokoconsulting.tech/MokoConsulting/MokoGIT/models/user"
|
|
"code.mokoconsulting.tech/MokoConsulting/MokoGIT/modules/log"
|
|
notify_service "code.mokoconsulting.tech/MokoConsulting/MokoGIT/services/notify"
|
|
pull_service "code.mokoconsulting.tech/MokoConsulting/MokoGIT/services/pull"
|
|
)
|
|
|
|
func Init() {
|
|
notify_service.RegisterNotifier(&cascadeNotifier{})
|
|
}
|
|
|
|
type cascadeNotifier struct {
|
|
notify_service.NullNotifier
|
|
}
|
|
|
|
func (n *cascadeNotifier) MergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
|
|
handleCascade(ctx, doer, pr)
|
|
}
|
|
|
|
func (n *cascadeNotifier) AutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
|
|
handleCascade(ctx, doer, pr)
|
|
}
|
|
|
|
func handleCascade(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) {
|
|
if err := pr.LoadBaseRepo(ctx); err != nil {
|
|
log.Error("cascade: LoadBaseRepo for PR #%d: %v", pr.Index, err)
|
|
return
|
|
}
|
|
|
|
rules, err := repo_model.GetCascadeRulesForBranch(ctx, pr.BaseRepo.ID, pr.BaseBranch)
|
|
if err != nil {
|
|
log.Error("cascade: GetCascadeRulesForBranch repo=%d branch=%s: %v", pr.BaseRepo.ID, pr.BaseBranch, err)
|
|
return
|
|
}
|
|
|
|
for _, rule := range rules {
|
|
if err := createCascadePR(ctx, doer, pr, rule); err != nil {
|
|
log.Error("cascade: failed to create PR %s→%s in repo %d: %v", rule.SourceBranch, rule.TargetBranch, rule.RepoID, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func createCascadePR(ctx context.Context, doer *user_model.User, mergedPR *issues_model.PullRequest, rule *repo_model.CascadeMergeRule) error {
|
|
repo := mergedPR.BaseRepo
|
|
|
|
existingPRs, err := issues_model.GetUnmergedPullRequestsByBaseInfo(ctx, repo.ID, rule.TargetBranch)
|
|
if err != nil {
|
|
return fmt.Errorf("check existing PRs: %w", err)
|
|
}
|
|
for _, existing := range existingPRs {
|
|
if existing.HeadBranch == rule.SourceBranch && existing.HeadRepoID == repo.ID {
|
|
log.Info("cascade: PR already exists %s→%s in %s/%s (#%d), skipping",
|
|
rule.SourceBranch, rule.TargetBranch, repo.OwnerName, repo.Name, existing.Index)
|
|
return nil
|
|
}
|
|
}
|
|
|
|
title := fmt.Sprintf("cascade: merge %s into %s", rule.SourceBranch, rule.TargetBranch)
|
|
body := fmt.Sprintf("Auto-created by cascade merge rule after PR #%d was merged.\n\nSource: `%s` → Target: `%s`",
|
|
mergedPR.Index, rule.SourceBranch, rule.TargetBranch)
|
|
|
|
issue := &issues_model.Issue{
|
|
RepoID: repo.ID,
|
|
Repo: repo,
|
|
Title: title,
|
|
Content: body,
|
|
PosterID: doer.ID,
|
|
Poster: doer,
|
|
IsPull: true,
|
|
}
|
|
|
|
pullRequest := &issues_model.PullRequest{
|
|
HeadRepoID: repo.ID,
|
|
BaseRepoID: repo.ID,
|
|
HeadBranch: rule.SourceBranch,
|
|
BaseBranch: rule.TargetBranch,
|
|
HeadRepo: repo,
|
|
BaseRepo: repo,
|
|
Type: issues_model.PullRequestGitea,
|
|
}
|
|
|
|
if err := pull_service.NewPullRequest(ctx, &pull_service.NewPullRequestOptions{
|
|
Repo: repo,
|
|
Issue: issue,
|
|
PullRequest: pullRequest,
|
|
}); err != nil {
|
|
return fmt.Errorf("NewPullRequest: %w", err)
|
|
}
|
|
|
|
log.Info("cascade: created PR #%d (%s→%s) in %s/%s",
|
|
issue.Index, rule.SourceBranch, rule.TargetBranch, repo.OwnerName, repo.Name)
|
|
return nil
|
|
}
|