@@ -49,11 +49,12 @@ type ViewRequest struct {
49
49
type ViewResponse struct {
50
50
State struct {
51
51
Run struct {
52
- Link string `json:"link"`
53
- Title string `json:"title"`
54
- CanCancel bool `json:"canCancel"`
55
- Done bool `json:"done"`
56
- Jobs []* ViewJob `json:"jobs"`
52
+ Link string `json:"link"`
53
+ Title string `json:"title"`
54
+ CanCancel bool `json:"canCancel"`
55
+ CanApprove bool `json:"canApprove"` // the run needs an approval and the doer has permission to approve
56
+ Done bool `json:"done"`
57
+ Jobs []* ViewJob `json:"jobs"`
57
58
} `json:"run"`
58
59
CurrentJob struct {
59
60
Title string `json:"title"`
@@ -107,6 +108,7 @@ func ViewPost(ctx *context_module.Context) {
107
108
resp .State .Run .Title = run .Title
108
109
resp .State .Run .Link = run .Link ()
109
110
resp .State .Run .CanCancel = ! run .Status .IsDone () && ctx .Repo .CanWrite (unit .TypeActions )
111
+ resp .State .Run .CanApprove = run .NeedApproval && ctx .Repo .CanWrite (unit .TypeActions )
110
112
resp .State .Run .Done = run .Status .IsDone ()
111
113
resp .State .Run .Jobs = make ([]* ViewJob , 0 , len (jobs )) // marshal to '[]' instead fo 'null' in json
112
114
for _ , v := range jobs {
@@ -135,6 +137,9 @@ func ViewPost(ctx *context_module.Context) {
135
137
136
138
resp .State .CurrentJob .Title = current .Name
137
139
resp .State .CurrentJob .Detail = current .Status .LocaleString (ctx .Locale )
140
+ if run .NeedApproval {
141
+ resp .State .CurrentJob .Detail = ctx .Locale .Tr ("actions.need_approval_desc" )
142
+ }
138
143
resp .State .CurrentJob .Steps = make ([]* ViewJobStep , 0 ) // marshal to '[]' instead fo 'null' in json
139
144
resp .Logs .StepsLog = make ([]* ViewStepLog , 0 ) // marshal to '[]' instead fo 'null' in json
140
145
if task != nil {
@@ -261,6 +266,40 @@ func Cancel(ctx *context_module.Context) {
261
266
ctx .JSON (http .StatusOK , struct {}{})
262
267
}
263
268
269
+ func Approve (ctx * context_module.Context ) {
270
+ runIndex := ctx .ParamsInt64 ("run" )
271
+
272
+ current , jobs := getRunJobs (ctx , runIndex , - 1 )
273
+ if ctx .Written () {
274
+ return
275
+ }
276
+ run := current .Run
277
+ doer := ctx .Doer
278
+
279
+ if err := db .WithTx (ctx , func (ctx context.Context ) error {
280
+ run .NeedApproval = false
281
+ run .ApprovedBy = doer .ID
282
+ if err := actions_model .UpdateRun (ctx , run , "need_approval" , "approved_by" ); err != nil {
283
+ return err
284
+ }
285
+ for _ , job := range jobs {
286
+ if len (job .Needs ) == 0 && job .Status .IsBlocked () {
287
+ job .Status = actions_model .StatusWaiting
288
+ _ , err := actions_model .UpdateRunJob (ctx , job , nil , "status" )
289
+ if err != nil {
290
+ return err
291
+ }
292
+ }
293
+ }
294
+ return nil
295
+ }); err != nil {
296
+ ctx .Error (http .StatusInternalServerError , err .Error ())
297
+ return
298
+ }
299
+
300
+ ctx .JSON (http .StatusOK , struct {}{})
301
+ }
302
+
264
303
// getRunJobs gets the jobs of runIndex, and returns jobs[jobIndex], jobs.
265
304
// Any error will be written to the ctx.
266
305
// It never returns a nil job of an empty jobs, if the jobIndex is out of range, it will be treated as 0.
0 commit comments