From bdf477f6ef195bec83aa8ad4e77d471d1f019f69 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 20 Aug 2024 00:25:41 +0800 Subject: [PATCH 1/8] Fix actions notify bug (#31866) Try to fix https://github.com/go-gitea/gitea/issues/31757#issuecomment-2295131062 (cherry picked from commit 4f5c96627b4622d64593db2d436b1f3befa5f3c3) --- services/actions/notifier.go | 2 +- services/actions/notifier_helper.go | 25 ++++++++++++++--------- tests/integration/actions_trigger_test.go | 4 ++-- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/services/actions/notifier.go b/services/actions/notifier.go index 1166bbbfd..e97afad99 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -396,7 +396,7 @@ func (n *actionsNotifier) ForkRepository(ctx context.Context, doer *user_model.U // Add to hook queue for created repo after session commit. if u.IsOrganization() { newNotifyInput(repo, doer, webhook_module.HookEventRepository). - WithRef(oldRepo.DefaultBranch). + WithRef(git.RefNameFromBranch(oldRepo.DefaultBranch).String()). WithPayload(&api.RepositoryPayload{ Action: api.HookRepoCreated, Repository: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeOwner}), diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 86897d5cb..751b89616 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -69,7 +69,7 @@ type notifyInput struct { Event webhook_module.HookEventType // optional - Ref string + Ref git.RefName Payload api.Payloader PullRequest *issues_model.PullRequest } @@ -93,7 +93,7 @@ func (input *notifyInput) WithDoer(doer *user_model.User) *notifyInput { } func (input *notifyInput) WithRef(ref string) *notifyInput { - input.Ref = ref + input.Ref = git.RefName(ref) return input } @@ -105,7 +105,7 @@ func (input *notifyInput) WithPayload(payload api.Payloader) *notifyInput { func (input *notifyInput) WithPullRequest(pr *issues_model.PullRequest) *notifyInput { input.PullRequest = pr if input.Ref == "" { - input.Ref = pr.GetGitRefName() + input.Ref = git.RefName(pr.GetGitRefName()) } return input } @@ -148,20 +148,25 @@ func notify(ctx context.Context, input *notifyInput) error { defer gitRepo.Close() ref := input.Ref - if ref != input.Repo.DefaultBranch && actions_module.IsDefaultBranchWorkflow(input.Event) { + if ref.BranchName() != input.Repo.DefaultBranch && actions_module.IsDefaultBranchWorkflow(input.Event) { if ref != "" { log.Warn("Event %q should only trigger workflows on the default branch, but its ref is %q. Will fall back to the default branch", input.Event, ref) } - ref = input.Repo.DefaultBranch + ref = git.RefNameFromBranch(input.Repo.DefaultBranch) } if ref == "" { log.Warn("Ref of event %q is empty, will fall back to the default branch", input.Event) - ref = input.Repo.DefaultBranch + ref = git.RefNameFromBranch(input.Repo.DefaultBranch) + } + + commitID, err := gitRepo.GetRefCommitID(ref.String()) + if err != nil { + return fmt.Errorf("gitRepo.GetRefCommitID: %w", err) } // Get the commit object for the ref - commit, err := gitRepo.GetCommit(ref) + commit, err := gitRepo.GetCommit(commitID) if err != nil { return fmt.Errorf("gitRepo.GetCommit: %w", err) } @@ -177,7 +182,7 @@ func notify(ctx context.Context, input *notifyInput) error { var detectedWorkflows []*actions_module.DetectedWorkflow actionsConfig := input.Repo.MustGetUnit(ctx, unit_model.TypeActions).ActionsConfig() - shouldDetectSchedules := input.Event == webhook_module.HookEventPush && git.RefName(input.Ref).BranchName() == input.Repo.DefaultBranch + shouldDetectSchedules := input.Event == webhook_module.HookEventPush && input.Ref.BranchName() == input.Repo.DefaultBranch workflows, schedules, err := actions_module.DetectWorkflows(gitRepo, commit, input.Event, input.Payload, @@ -235,12 +240,12 @@ func notify(ctx context.Context, input *notifyInput) error { } if shouldDetectSchedules { - if err := handleSchedules(ctx, schedules, commit, input, ref); err != nil { + if err := handleSchedules(ctx, schedules, commit, input, ref.String()); err != nil { return err } } - return handleWorkflows(ctx, detectedWorkflows, commit, input, ref) + return handleWorkflows(ctx, detectedWorkflows, commit, input, ref.String()) } func SkipPullRequestEvent(ctx context.Context, event webhook_module.HookEventType, repoID int64, commitSHA string) bool { diff --git a/tests/integration/actions_trigger_test.go b/tests/integration/actions_trigger_test.go index 0f27e204c..f89bb4687 100644 --- a/tests/integration/actions_trigger_test.go +++ b/tests/integration/actions_trigger_test.go @@ -375,7 +375,7 @@ func TestCreateDeleteRefEvent(t *testing.T) { Title: "add workflow", RepoID: repo.ID, Event: "delete", - Ref: "main", + Ref: "refs/heads/main", WorkflowID: "createdelete.yml", CommitSHA: branch.CommitID, }) @@ -390,7 +390,7 @@ func TestCreateDeleteRefEvent(t *testing.T) { Title: "add workflow", RepoID: repo.ID, Event: "delete", - Ref: "main", + Ref: "refs/heads/main", WorkflowID: "createdelete.yml", CommitSHA: branch.CommitID, }) From 1b845b2722ef22bf4eb783bee8289c8ee6bdf4e0 Mon Sep 17 00:00:00 2001 From: Rowan Bohde Date: Mon, 19 Aug 2024 12:58:53 -0500 Subject: [PATCH 2/8] add CfTurnstileSitekey context data to all captcha templates (#31874) In the OpenID flows, the "CfTurnstileSitekey" wasn't populated, which caused those flows to fail if using Turnstile as the Captcha implementation. This adds the missing context variables, allowing Turnstile to be used in the OpenID flows. (cherry picked from commit 0d24c9f383255605d68a92cc5f087c3f16a1d735) --- routers/web/auth/linkaccount.go | 3 +++ routers/web/auth/openid.go | 1 + 2 files changed, 4 insertions(+) diff --git a/routers/web/auth/linkaccount.go b/routers/web/auth/linkaccount.go index f744a57a4..9b0141c14 100644 --- a/routers/web/auth/linkaccount.go +++ b/routers/web/auth/linkaccount.go @@ -40,6 +40,7 @@ func LinkAccount(ctx *context.Context) { ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL + ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration ctx.Data["AllowOnlyInternalRegistration"] = setting.Service.AllowOnlyInternalRegistration ctx.Data["ShowRegistrationButton"] = false @@ -128,6 +129,7 @@ func LinkAccountPostSignIn(ctx *context.Context) { ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL + ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration ctx.Data["ShowRegistrationButton"] = false @@ -215,6 +217,7 @@ func LinkAccountPostRegister(ctx *context.Context) { ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL + ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration ctx.Data["ShowRegistrationButton"] = false diff --git a/routers/web/auth/openid.go b/routers/web/auth/openid.go index 2143b8096..83268faac 100644 --- a/routers/web/auth/openid.go +++ b/routers/web/auth/openid.go @@ -307,6 +307,7 @@ func RegisterOpenID(ctx *context.Context) { ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL + ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey ctx.Data["OpenID"] = oid userName, _ := ctx.Session.Get("openid_determined_username").(string) if userName != "" { From dda53569b1b70507469fc296881eec89606ab9c3 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 20 Aug 2024 14:17:21 +0800 Subject: [PATCH 3/8] Fix agit automerge (#31207) (cherry picked from commit 8b92eba21f5c5cca277b8101ada0ea7a1fb32ae0) --- models/fixtures/repository.yml | 2 +- services/automerge/automerge.go | 18 ++- .../user2/repo1.git/hooks/proc-receive | 7 + .../repo1.git/hooks/proc-receive.d/gitea | 2 + tests/integration/pull_merge_test.go | 129 ++++++++++++++++++ 5 files changed, 154 insertions(+), 4 deletions(-) create mode 100755 tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive create mode 100755 tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive.d/gitea diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index 845dae7fc..f783d5818 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -26,7 +26,7 @@ fork_id: 0 is_template: false template_id: 0 - size: 7320 + size: 7597 is_fsck_enabled: true close_issues_via_commit_in_any_branch: false diff --git a/services/automerge/automerge.go b/services/automerge/automerge.go index 972961603..a1ee20488 100644 --- a/services/automerge/automerge.go +++ b/services/automerge/automerge.go @@ -245,9 +245,21 @@ func handlePullRequestAutoMerge(pullID int64, sha string) { defer headGitRepo.Close() } - headBranchExist := headGitRepo.IsBranchExist(pr.HeadBranch) - if pr.HeadRepo == nil || !headBranchExist { - log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch: %s]", pr, pr.HeadRepoID, pr.HeadBranch) + switch pr.Flow { + case issues_model.PullRequestFlowGithub: + headBranchExist := headGitRepo.IsBranchExist(pr.HeadBranch) + if pr.HeadRepo == nil || !headBranchExist { + log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch: %s]", pr, pr.HeadRepoID, pr.HeadBranch) + return + } + case issues_model.PullRequestFlowAGit: + headBranchExist := git.IsReferenceExist(ctx, baseGitRepo.Path, pr.GetGitRefName()) + if !headBranchExist { + log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch(Agit): %s]", pr, pr.HeadRepoID, pr.HeadBranch) + return + } + default: + log.Error("wrong flow type %d", pr.Flow) return } diff --git a/tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive b/tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive new file mode 100755 index 000000000..af2808b03 --- /dev/null +++ b/tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +ORI_DIR=`pwd` +SHELL_FOLDER=$(cd "$(dirname "$0")";pwd) +cd "$ORI_DIR" +for i in `ls "$SHELL_FOLDER/proc-receive.d"`; do + sh "$SHELL_FOLDER/proc-receive.d/$i" +done diff --git a/tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive.d/gitea b/tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive.d/gitea new file mode 100755 index 000000000..97521c621 --- /dev/null +++ b/tests/gitea-repositories-meta/user2/repo1.git/hooks/proc-receive.d/gitea @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +"$GITEA_ROOT/gitea" hook --config="$GITEA_ROOT/$GITEA_CONF" proc-receive diff --git a/tests/integration/pull_merge_test.go b/tests/integration/pull_merge_test.go index b13ae60c4..a6c5a5743 100644 --- a/tests/integration/pull_merge_test.go +++ b/tests/integration/pull_merge_test.go @@ -1020,3 +1020,132 @@ func TestPullAutoMergeAfterCommitStatusSucceedAndApproval(t *testing.T) { unittest.AssertNotExistsBean(t, &pull_model.AutoMerge{PullID: pr.ID}) }) } + +func TestPullAutoMergeAfterCommitStatusSucceedAndApprovalForAgitFlow(t *testing.T) { + onGiteaRun(t, func(t *testing.T, u *url.URL) { + // create a pull request + baseAPITestContext := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) + + dstPath := t.TempDir() + + u.Path = baseAPITestContext.GitPath() + u.User = url.UserPassword("user2", userPassword) + + t.Run("Clone", doGitClone(dstPath, u)) + + err := os.WriteFile(path.Join(dstPath, "test_file"), []byte("## test content"), 0o666) + assert.NoError(t, err) + + err = git.AddChanges(dstPath, true) + assert.NoError(t, err) + + err = git.CommitChanges(dstPath, git.CommitChangesOptions{ + Committer: &git.Signature{ + Email: "user2@example.com", + Name: "user2", + When: time.Now(), + }, + Author: &git.Signature{ + Email: "user2@example.com", + Name: "user2", + When: time.Now(), + }, + Message: "Testing commit 1", + }) + assert.NoError(t, err) + + stderrBuf := &bytes.Buffer{} + + err = git.NewCommand(git.DefaultContext, "push", "origin", "HEAD:refs/for/master", "-o"). + AddDynamicArguments(`topic=test/head2`). + AddArguments("-o"). + AddDynamicArguments(`title="create a test pull request with agit"`). + AddArguments("-o"). + AddDynamicArguments(`description="This PR is a test pull request which created with agit"`). + Run(&git.RunOpts{Dir: dstPath, Stderr: stderrBuf}) + assert.NoError(t, err) + + assert.Contains(t, stderrBuf.String(), setting.AppURL+"user2/repo1/pulls/6") + + baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "repo1"}) + pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ + Flow: issues_model.PullRequestFlowAGit, + BaseRepoID: baseRepo.ID, + BaseBranch: "master", + HeadRepoID: baseRepo.ID, + HeadBranch: "user2/test/head2", + }) + + session := loginUser(t, "user1") + // add protected branch for commit status + csrf := GetCSRF(t, session, "/user2/repo1/settings/branches") + // Change master branch to protected + req := NewRequestWithValues(t, "POST", "/user2/repo1/settings/branches/edit", map[string]string{ + "_csrf": csrf, + "rule_name": "master", + "enable_push": "true", + "enable_status_check": "true", + "status_check_contexts": "gitea/actions", + "required_approvals": "1", + }) + session.MakeRequest(t, req, http.StatusSeeOther) + + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + // first time insert automerge record, return true + scheduled, err := automerge.ScheduleAutoMerge(db.DefaultContext, user1, pr, repo_model.MergeStyleMerge, "auto merge test") + assert.NoError(t, err) + assert.True(t, scheduled) + + // second time insert automerge record, return false because it does exist + scheduled, err = automerge.ScheduleAutoMerge(db.DefaultContext, user1, pr, repo_model.MergeStyleMerge, "auto merge test") + assert.Error(t, err) + assert.False(t, scheduled) + + // reload pr again + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}) + assert.False(t, pr.HasMerged) + assert.Empty(t, pr.MergedCommitID) + + // update commit status to success, then it should be merged automatically + baseGitRepo, err := gitrepo.OpenRepository(db.DefaultContext, baseRepo) + assert.NoError(t, err) + sha, err := baseGitRepo.GetRefCommitID(pr.GetGitRefName()) + assert.NoError(t, err) + masterCommitID, err := baseGitRepo.GetBranchCommitID("master") + assert.NoError(t, err) + baseGitRepo.Close() + defer func() { + testResetRepo(t, baseRepo.RepoPath(), "master", masterCommitID) + }() + + err = commitstatus_service.CreateCommitStatus(db.DefaultContext, baseRepo, user1, sha, &git_model.CommitStatus{ + State: api.CommitStatusSuccess, + TargetURL: "https://gitea.com", + Context: "gitea/actions", + }) + assert.NoError(t, err) + + time.Sleep(2 * time.Second) + + // reload pr again + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}) + assert.False(t, pr.HasMerged) + assert.Empty(t, pr.MergedCommitID) + + // approve the PR from non-author + approveSession := loginUser(t, "user1") + req = NewRequest(t, "GET", fmt.Sprintf("/user2/repo1/pulls/%d", pr.Index)) + resp := approveSession.MakeRequest(t, req, http.StatusOK) + htmlDoc := NewHTMLParser(t, resp.Body) + testSubmitReview(t, approveSession, htmlDoc.GetCSRF(), "user2", "repo1", strconv.Itoa(int(pr.Index)), sha, "approve", http.StatusOK) + + time.Sleep(2 * time.Second) + + // realod pr again + pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}) + assert.True(t, pr.HasMerged) + assert.NotEmpty(t, pr.MergedCommitID) + + unittest.AssertNotExistsBean(t, &pull_model.AutoMerge{PullID: pr.ID}) + }) +} From 3ade4d9b2bfa6ae84a1ded932907a53060565575 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 21 Aug 2024 09:54:55 +0800 Subject: [PATCH 4/8] Don't return 500 if mirror url contains special chars (#31859) Fix #31640 (cherry picked from commit d158472a5a9ead8052095b153821a9f26c294452) --- routers/web/repo/setting/setting.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index 76539b9fa..9a989d0c1 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -480,7 +480,8 @@ func SettingsPost(ctx *context.Context) { } remoteAddress, err := util.SanitizeURL(address) if err != nil { - ctx.ServerError("SanitizeURL", err) + ctx.Data["Err_MirrorAddress"] = true + handleSettingRemoteAddrError(ctx, err, form) return } pullMirror.RemoteAddress = remoteAddress @@ -661,7 +662,8 @@ func SettingsPost(ctx *context.Context) { remoteAddress, err := util.SanitizeURL(address) if err != nil { - ctx.ServerError("SanitizeURL", err) + ctx.Data["Err_PushMirrorAddress"] = true + handleSettingRemoteAddrError(ctx, err, form) return } From 79f6f2f62e6827cf6bc186888f6a78478b765b08 Mon Sep 17 00:00:00 2001 From: william-allspice Date: Wed, 21 Aug 2024 00:40:18 -0500 Subject: [PATCH 5/8] Move lock icon position and add additional tooltips to branch list page (#31839) This Pull Request adds missing tool tips for the protected, copy, and rss icons on the branch list page. It also moved protected icon position after the branch name. (cherry picked from commit 40036b610224338ff730acb6e182aa8a6ebdb009) --- templates/repo/branch/list.tmpl | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/templates/repo/branch/list.tmpl b/templates/repo/branch/list.tmpl index e2c7c6f18..f5bffb097 100644 --- a/templates/repo/branch/list.tmpl +++ b/templates/repo/branch/list.tmpl @@ -20,9 +20,11 @@
- {{if .DefaultBranchBranch.IsProtected}}{{svg "octicon-shield-lock"}}{{end}} {{.DefaultBranchBranch.DBBranch.Name}} - + {{if .DefaultBranchBranch.IsProtected}} + {{svg "octicon-shield-lock"}} + {{end}} + {{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DefaultBranchBranch.DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DefaultBranchBranch.DBBranch.CommitID)}}

{{svg "octicon-git-commit" 16 "tw-mr-1"}}{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}} · {{RenderCommitMessage $.Context .DefaultBranchBranch.DBBranch.CommitMessage (.Repository.ComposeMetas ctx)}} · {{ctx.Locale.Tr "org.repo_updated" (TimeSince .DefaultBranchBranch.DBBranch.CommitTime.AsTime ctx.Locale)}} {{if .DefaultBranchBranch.DBBranch.Pusher}}  {{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}}

@@ -39,7 +41,7 @@ {{end}} {{if .EnableFeed}} - {{svg "octicon-rss"}} + {{svg "octicon-rss"}} {{end}} {{if not $.DisableDownloadSourceArchives}}