1
1
mirror of https://github.com/go-gitea/gitea synced 2025-12-07 05:18:29 +00:00

Add quick approve button on PR page (#35678)

This PR adds a quick approve button on PR page to allow reviewers to
approve all pending checks. Only users with write permission to the 
Actions unit can approve.

---------

Signed-off-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Zettat123
2025-10-20 04:46:37 -06:00
committed by GitHub
parent 66ee8f3553
commit 897e48dde3
10 changed files with 358 additions and 48 deletions

View File

@@ -606,33 +606,53 @@ func Cancel(ctx *context_module.Context) {
func Approve(ctx *context_module.Context) {
runIndex := getRunIndex(ctx)
current, jobs := getRunJobs(ctx, runIndex, -1)
approveRuns(ctx, []int64{runIndex})
if ctx.Written() {
return
}
run := current.Run
doer := ctx.Doer
var updatedJobs []*actions_model.ActionRunJob
ctx.JSONOK()
}
func approveRuns(ctx *context_module.Context, runIndexes []int64) {
doer := ctx.Doer
repo := ctx.Repo.Repository
updatedJobs := make([]*actions_model.ActionRunJob, 0)
runMap := make(map[int64]*actions_model.ActionRun, len(runIndexes))
runJobs := make(map[int64][]*actions_model.ActionRunJob, len(runIndexes))
err := db.WithTx(ctx, func(ctx context.Context) (err error) {
run.NeedApproval = false
run.ApprovedBy = doer.ID
if err := actions_model.UpdateRun(ctx, run, "need_approval", "approved_by"); err != nil {
return err
}
for _, job := range jobs {
job.Status, err = actions_service.PrepareToStartJobWithConcurrency(ctx, job)
for _, runIndex := range runIndexes {
run, err := actions_model.GetRunByIndex(ctx, repo.ID, runIndex)
if err != nil {
return err
}
if job.Status == actions_model.StatusWaiting {
n, err := actions_model.UpdateRunJob(ctx, job, nil, "status")
runMap[run.ID] = run
run.Repo = repo
run.NeedApproval = false
run.ApprovedBy = doer.ID
if err := actions_model.UpdateRun(ctx, run, "need_approval", "approved_by"); err != nil {
return err
}
jobs, err := actions_model.GetRunJobsByRunID(ctx, run.ID)
if err != nil {
return err
}
runJobs[run.ID] = jobs
for _, job := range jobs {
job.Status, err = actions_service.PrepareToStartJobWithConcurrency(ctx, job)
if err != nil {
return err
}
if n > 0 {
updatedJobs = append(updatedJobs, job)
if job.Status == actions_model.StatusWaiting {
n, err := actions_model.UpdateRunJob(ctx, job, nil, "status")
if err != nil {
return err
}
if n > 0 {
updatedJobs = append(updatedJobs, job)
}
}
}
}
@@ -643,7 +663,9 @@ func Approve(ctx *context_module.Context) {
return
}
actions_service.CreateCommitStatusForRunJobs(ctx, current.Run, jobs...)
for runID, run := range runMap {
actions_service.CreateCommitStatusForRunJobs(ctx, run, runJobs[runID]...)
}
if len(updatedJobs) > 0 {
job := updatedJobs[0]
@@ -654,8 +676,6 @@ func Approve(ctx *context_module.Context) {
_ = job.LoadAttributes(ctx)
notify_service.WorkflowJobStatusUpdate(ctx, job.Run.Repo, job.Run.TriggerUser, job, nil)
}
ctx.JSONOK()
}
func Delete(ctx *context_module.Context) {
@@ -818,6 +838,42 @@ func ArtifactsDownloadView(ctx *context_module.Context) {
}
}
func ApproveAllChecks(ctx *context_module.Context) {
repo := ctx.Repo.Repository
commitID := ctx.FormString("commit_id")
commitStatuses, err := git_model.GetLatestCommitStatus(ctx, repo.ID, commitID, db.ListOptionsAll)
if err != nil {
ctx.ServerError("GetLatestCommitStatus", err)
return
}
runs, err := actions_service.GetRunsFromCommitStatuses(ctx, commitStatuses)
if err != nil {
ctx.ServerError("GetRunsFromCommitStatuses", err)
return
}
runIndexes := make([]int64, 0, len(runs))
for _, run := range runs {
if run.NeedApproval {
runIndexes = append(runIndexes, run.Index)
}
}
if len(runIndexes) == 0 {
ctx.JSONOK()
return
}
approveRuns(ctx, runIndexes)
if ctx.Written() {
return
}
ctx.Flash.Success(ctx.Tr("actions.approve_all_success"))
ctx.JSONOK()
}
func DisableWorkflowFile(ctx *context_module.Context) {
disableOrEnableWorkflowFile(ctx, false)
}