@@ -32,8 +32,9 @@ import (
3232)
3333
3434const  (
35- 	tplListActions  templates.TplName  =  "repo/actions/list" 
36- 	tplViewActions  templates.TplName  =  "repo/actions/view" 
35+ 	tplListActions            templates.TplName  =  "repo/actions/list" 
36+ 	tplDispatchInputsActions  templates.TplName  =  "repo/actions/workflow_dispatch_inputs" 
37+ 	tplViewActions            templates.TplName  =  "repo/actions/view" 
3738)
3839
3940type  Workflow  struct  {
@@ -64,107 +65,143 @@ func MustEnableActions(ctx *context.Context) {
6465func  List (ctx  * context.Context ) {
6566	ctx .Data ["Title" ] =  ctx .Tr ("actions.actions" )
6667	ctx .Data ["PageIsActions" ] =  true 
68+ 
69+ 	commit , err  :=  ctx .Repo .GitRepo .GetBranchCommit (ctx .Repo .Repository .DefaultBranch )
70+ 	if  err  !=  nil  {
71+ 		ctx .ServerError ("GetBranchCommit" , err )
72+ 		return 
73+ 	}
74+ 
75+ 	workflows  :=  prepareWorkflowDispatchTemplate (ctx , commit )
76+ 	if  ctx .Written () {
77+ 		return 
78+ 	}
79+ 
80+ 	prepareWorkflowList (ctx , workflows )
81+ 	if  ctx .Written () {
82+ 		return 
83+ 	}
84+ 
85+ 	ctx .HTML (http .StatusOK , tplListActions )
86+ }
87+ 
88+ func  WorkflowDispatchInputs (ctx  * context.Context ) {
89+ 	ref  :=  ctx .FormString ("ref" )
90+ 	if  ref  ==  ""  {
91+ 		ctx .NotFound ("WorkflowDispatchInputs: no ref" , nil )
92+ 		return 
93+ 	}
94+ 	// get target commit of run from specified ref 
95+ 	refName  :=  git .RefName (ref )
96+ 	var  commit  * git.Commit 
97+ 	var  err  error 
98+ 	if  refName .IsTag () {
99+ 		commit , err  =  ctx .Repo .GitRepo .GetTagCommit (refName .TagName ())
100+ 	} else  if  refName .IsBranch () {
101+ 		commit , err  =  ctx .Repo .GitRepo .GetBranchCommit (refName .BranchName ())
102+ 	} else  {
103+ 		ctx .ServerError ("UnsupportedRefType" , nil )
104+ 		return 
105+ 	}
106+ 	if  err  !=  nil  {
107+ 		ctx .ServerError ("GetTagCommit/GetBranchCommit" , err )
108+ 		return 
109+ 	}
110+ 	prepareWorkflowDispatchTemplate (ctx , commit )
111+ 	if  ctx .Written () {
112+ 		return 
113+ 	}
114+ 	ctx .HTML (http .StatusOK , tplDispatchInputsActions )
115+ }
116+ 
117+ func  prepareWorkflowDispatchTemplate (ctx  * context.Context , commit  * git.Commit ) (workflows  []Workflow ) {
67118	workflowID  :=  ctx .FormString ("workflow" )
68- 	actorID  :=  ctx .FormInt64 ("actor" )
69- 	status  :=  ctx .FormInt ("status" )
70119	ctx .Data ["CurWorkflow" ] =  workflowID 
120+ 	ctx .Data ["CurWorkflowExists" ] =  false 
71121
72- 	var  workflows  []Workflow 
73122	var  curWorkflow  * model.Workflow 
74- 	if  empty , err  :=  ctx .Repo .GitRepo .IsEmpty (); err  !=  nil  {
75- 		ctx .ServerError ("IsEmpty" , err )
76- 		return 
77- 	} else  if  ! empty  {
78- 		commit , err  :=  ctx .Repo .GitRepo .GetBranchCommit (ctx .Repo .Repository .DefaultBranch )
79- 		if  err  !=  nil  {
80- 			ctx .ServerError ("GetBranchCommit" , err )
81- 			return 
82- 		}
83- 		entries , err  :=  actions .ListWorkflows (commit )
84- 		if  err  !=  nil  {
85- 			ctx .ServerError ("ListWorkflows" , err )
86- 			return 
87- 		}
88123
89- 		// Get all runner labels 
90- 		runners , err  :=  db .Find [actions_model.ActionRunner ](ctx , actions_model.FindRunnerOptions {
91- 			RepoID :        ctx .Repo .Repository .ID ,
92- 			IsOnline :      optional .Some (true ),
93- 			WithAvailable : true ,
94- 		})
124+ 	entries , err  :=  actions .ListWorkflows (commit )
125+ 	if  err  !=  nil  {
126+ 		ctx .ServerError ("ListWorkflows" , err )
127+ 		return  nil 
128+ 	}
129+ 
130+ 	// Get all runner labels 
131+ 	runners , err  :=  db .Find [actions_model.ActionRunner ](ctx , actions_model.FindRunnerOptions {
132+ 		RepoID :        ctx .Repo .Repository .ID ,
133+ 		IsOnline :      optional .Some (true ),
134+ 		WithAvailable : true ,
135+ 	})
136+ 	if  err  !=  nil  {
137+ 		ctx .ServerError ("FindRunners" , err )
138+ 		return  nil 
139+ 	}
140+ 	allRunnerLabels  :=  make (container.Set [string ])
141+ 	for  _ , r  :=  range  runners  {
142+ 		allRunnerLabels .AddMultiple (r .AgentLabels ... )
143+ 	}
144+ 
145+ 	workflows  =  make ([]Workflow , 0 , len (entries ))
146+ 	for  _ , entry  :=  range  entries  {
147+ 		workflow  :=  Workflow {Entry : * entry }
148+ 		content , err  :=  actions .GetContentFromEntry (entry )
95149		if  err  !=  nil  {
96- 			ctx .ServerError ("FindRunners " , err )
97- 			return 
150+ 			ctx .ServerError ("GetContentFromEntry " , err )
151+ 			return   nil 
98152		}
99- 		allRunnerLabels  :=  make (container.Set [string ])
100- 		for  _ , r  :=  range  runners  {
101- 			allRunnerLabels .AddMultiple (r .AgentLabels ... )
153+ 		wf , err  :=  model .ReadWorkflow (bytes .NewReader (content ))
154+ 		if  err  !=  nil  {
155+ 			workflow .ErrMsg  =  ctx .Locale .TrString ("actions.runs.invalid_workflow_helper" , err .Error ())
156+ 			workflows  =  append (workflows , workflow )
157+ 			continue 
102158		}
103- 
104- 		workflows  =  make ([]Workflow , 0 , len (entries ))
105- 		for  _ , entry  :=  range  entries  {
106- 			workflow  :=  Workflow {Entry : * entry }
107- 			content , err  :=  actions .GetContentFromEntry (entry )
108- 			if  err  !=  nil  {
109- 				ctx .ServerError ("GetContentFromEntry" , err )
110- 				return 
111- 			}
112- 			wf , err  :=  model .ReadWorkflow (bytes .NewReader (content ))
113- 			if  err  !=  nil  {
114- 				workflow .ErrMsg  =  ctx .Locale .TrString ("actions.runs.invalid_workflow_helper" , err .Error ())
115- 				workflows  =  append (workflows , workflow )
159+ 		// The workflow must contain at least one job without "needs". Otherwise, a deadlock will occur and no jobs will be able to run. 
160+ 		hasJobWithoutNeeds  :=  false 
161+ 		// Check whether you have matching runner and a job without "needs" 
162+ 		emptyJobsNumber  :=  0 
163+ 		for  _ , j  :=  range  wf .Jobs  {
164+ 			if  j  ==  nil  {
165+ 				emptyJobsNumber ++ 
116166				continue 
117167			}
118- 			// The workflow must contain at least one job without "needs". Otherwise, a deadlock will occur and no jobs will be able to run. 
119- 			hasJobWithoutNeeds  :=  false 
120- 			// Check whether have matching runner and a job without "needs" 
121- 			emptyJobsNumber  :=  0 
122- 			for  _ , j  :=  range  wf .Jobs  {
123- 				if  j  ==  nil  {
124- 					emptyJobsNumber ++ 
168+ 			if  ! hasJobWithoutNeeds  &&  len (j .Needs ()) ==  0  {
169+ 				hasJobWithoutNeeds  =  true 
170+ 			}
171+ 			runsOnList  :=  j .RunsOn ()
172+ 			for  _ , ro  :=  range  runsOnList  {
173+ 				if  strings .Contains (ro , "${{" ) {
174+ 					// Skip if it contains expressions. 
175+ 					// The expressions could be very complex and could not be evaluated here, 
176+ 					// so just skip it, it's OK since it's just a tooltip message. 
125177					continue 
126178				}
127- 				if  ! hasJobWithoutNeeds  &&  len (j .Needs ()) ==  0  {
128- 					hasJobWithoutNeeds  =  true 
129- 				}
130- 				runsOnList  :=  j .RunsOn ()
131- 				for  _ , ro  :=  range  runsOnList  {
132- 					if  strings .Contains (ro , "${{" ) {
133- 						// Skip if it contains expressions. 
134- 						// The expressions could be very complex and could not be evaluated here, 
135- 						// so just skip it, it's OK since it's just a tooltip message. 
136- 						continue 
137- 					}
138- 					if  ! allRunnerLabels .Contains (ro ) {
139- 						workflow .ErrMsg  =  ctx .Locale .TrString ("actions.runs.no_matching_online_runner_helper" , ro )
140- 						break 
141- 					}
142- 				}
143- 				if  workflow .ErrMsg  !=  ""  {
179+ 				if  ! allRunnerLabels .Contains (ro ) {
180+ 					workflow .ErrMsg  =  ctx .Locale .TrString ("actions.runs.no_matching_online_runner_helper" , ro )
144181					break 
145182				}
146183			}
147- 			if  ! hasJobWithoutNeeds  {
148- 				workflow .ErrMsg  =  ctx .Locale .TrString ("actions.runs.no_job_without_needs" )
149- 			}
150- 			if  emptyJobsNumber  ==  len (wf .Jobs ) {
151- 				workflow .ErrMsg  =  ctx .Locale .TrString ("actions.runs.no_job" )
184+ 			if  workflow .ErrMsg  !=  ""  {
185+ 				break 
152186			}
153- 			workflows  =  append (workflows , workflow )
187+ 		}
188+ 		if  ! hasJobWithoutNeeds  {
189+ 			workflow .ErrMsg  =  ctx .Locale .TrString ("actions.runs.no_job_without_needs" )
190+ 		}
191+ 		if  emptyJobsNumber  ==  len (wf .Jobs ) {
192+ 			workflow .ErrMsg  =  ctx .Locale .TrString ("actions.runs.no_job" )
193+ 		}
194+ 		workflows  =  append (workflows , workflow )
154195
155- 			 if  workflow .Entry .Name () ==  workflowID  {
156- 				 curWorkflow  =  wf 
157- 			} 
196+ 		if  workflow .Entry .Name () ==  workflowID  {
197+ 			curWorkflow  =  wf 
198+ 			ctx . Data [ "CurWorkflowExists" ]  =   true 
158199		}
159200	}
201+ 
160202	ctx .Data ["workflows" ] =  workflows 
161203	ctx .Data ["RepoLink" ] =  ctx .Repo .Repository .Link ()
162204
163- 	page  :=  ctx .FormInt ("page" )
164- 	if  page  <=  0  {
165- 		page  =  1 
166- 	}
167- 
168205	actionsConfig  :=  ctx .Repo .Repository .MustGetUnit (ctx , unit .TypeActions ).ActionsConfig ()
169206	ctx .Data ["ActionsConfig" ] =  actionsConfig 
170207
@@ -188,7 +225,7 @@ func List(ctx *context.Context) {
188225				branches , err  :=  git_model .FindBranchNames (ctx , branchOpts )
189226				if  err  !=  nil  {
190227					ctx .ServerError ("FindBranchNames" , err )
191- 					return 
228+ 					return   nil 
192229				}
193230				// always put default branch on the top if it exists 
194231				if  slices .Contains (branches , ctx .Repo .Repository .DefaultBranch ) {
@@ -200,12 +237,23 @@ func List(ctx *context.Context) {
200237				tags , err  :=  repo_model .GetTagNamesByRepoID (ctx , ctx .Repo .Repository .ID )
201238				if  err  !=  nil  {
202239					ctx .ServerError ("GetTagNamesByRepoID" , err )
203- 					return 
240+ 					return   nil 
204241				}
205242				ctx .Data ["Tags" ] =  tags 
206243			}
207244		}
208245	}
246+ 	return  workflows 
247+ }
248+ 
249+ func  prepareWorkflowList (ctx  * context.Context , workflows  []Workflow ) {
250+ 	actorID  :=  ctx .FormInt64 ("actor" )
251+ 	status  :=  ctx .FormInt ("status" )
252+ 	workflowID  :=  ctx .FormString ("workflow" )
253+ 	page  :=  ctx .FormInt ("page" )
254+ 	if  page  <=  0  {
255+ 		page  =  1 
256+ 	}
209257
210258	// if status or actor query param is not given to frontend href, (href="/<repoLink>/actions") 
211259	// they will be 0 by default, which indicates get all status or actors 
@@ -264,8 +312,6 @@ func List(ctx *context.Context) {
264312	pager .AddParamFromRequest (ctx .Req )
265313	ctx .Data ["Page" ] =  pager 
266314	ctx .Data ["HasWorkflowsOrRuns" ] =  len (workflows ) >  0  ||  len (runs ) >  0 
267- 
268- 	ctx .HTML (http .StatusOK , tplListActions )
269315}
270316
271317// loadIsRefDeleted loads the IsRefDeleted field for each run in the list. 
0 commit comments