Skip to content

Commit 11e23c2

Browse files
committed
Move interpolation logic to jobparser, add helper ToGitHubContext, reorder DispatchActionWorkflow to support run-name parsing
1 parent ba6c9fb commit 11e23c2

File tree

6 files changed

+240
-72
lines changed

6 files changed

+240
-72
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1
317317

318318
replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0
319319

320-
replace github.com/nektos/act => gitea.com/badhezi/act v0.0.0-20250429095415-d27028e1df50
320+
replace github.com/nektos/act => gitea.com/badhezi/act v0.0.0-20250501202946-5f2de4d09b1f
321321

322322
// TODO: the only difference is in `PutObject`: the fork doesn't use `NewVerifyingReader(r, sha256.New(), oid, expectedSize)`, need to figure out why
323323
replace github.com/charmbracelet/git-lfs-transfer => gitea.com/gitea/git-lfs-transfer v0.2.0

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
1616
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
1717
gitea.com/badhezi/act v0.0.0-20250429095415-d27028e1df50 h1:46UPmv+pLMBd2TR/N/hKpWY3SloOlVusmZg6SmpcfbE=
1818
gitea.com/badhezi/act v0.0.0-20250429095415-d27028e1df50/go.mod h1:Pg5C9kQY1CEA3QjthjhlrqOC/QOT5NyWNjOjRHw23Ok=
19+
gitea.com/badhezi/act v0.0.0-20250501200956-eaed3ad12395 h1:LWYeTtkf2cBhRNPqXrIPxMOlH3EmvU6EyKyqzf66hM0=
20+
gitea.com/badhezi/act v0.0.0-20250501200956-eaed3ad12395/go.mod h1:Pg5C9kQY1CEA3QjthjhlrqOC/QOT5NyWNjOjRHw23Ok=
21+
gitea.com/badhezi/act v0.0.0-20250501202946-5f2de4d09b1f h1:aPHa4bpjOgUGJoMkQZ5PvpASmrjHLx55sIu+RtGWzvE=
22+
gitea.com/badhezi/act v0.0.0-20250501202946-5f2de4d09b1f/go.mod h1:Pg5C9kQY1CEA3QjthjhlrqOC/QOT5NyWNjOjRHw23Ok=
1923
gitea.com/gitea/git-lfs-transfer v0.2.0 h1:baHaNoBSRaeq/xKayEXwiDQtlIjps4Ac/Ll4KqLMB40=
2024
gitea.com/gitea/git-lfs-transfer v0.2.0/go.mod h1:UrXUCm3xLQkq15fu7qlXHUMlrhdlXHoi13KH2Dfiits=
2125
gitea.com/gitea/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:BAFmdZpRW7zMQZQDClaCWobRj9uL1MR3MzpCVJvc5s4=

services/actions/context.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@ import (
1414
"code.gitea.io/gitea/modules/container"
1515
"code.gitea.io/gitea/modules/git"
1616
"code.gitea.io/gitea/modules/json"
17+
"code.gitea.io/gitea/modules/log"
1718
"code.gitea.io/gitea/modules/setting"
19+
20+
"github.com/nektos/act/pkg/model"
1821
)
1922

23+
type GiteaContext map[string]any
24+
2025
// GenerateGiteaContext generate the gitea context without token and gitea_runtime_token
2126
// job can be nil when generating a context for parsing workflow-level expressions
22-
func GenerateGiteaContext(run *actions_model.ActionRun, job *actions_model.ActionRunJob) map[string]any {
27+
func GenerateGiteaContext(run *actions_model.ActionRun, job *actions_model.ActionRunJob) GiteaContext {
2328
event := map[string]any{}
2429
_ = json.Unmarshal([]byte(run.EventPayload), &event)
2530

@@ -42,7 +47,7 @@ func GenerateGiteaContext(run *actions_model.ActionRun, job *actions_model.Actio
4247

4348
refName := git.RefName(ref)
4449

45-
gitContext := map[string]any{
50+
gitContext := GiteaContext{
4651
// standard contexts, see https://docs.github.com/en/actions/learn-github-actions/contexts#github-context
4752
"action": "", // string, The name of the action currently running, or the id of a step. GitHub removes special characters, and uses the name __run when the current step runs a script without an id. If you use the same action more than once in the same job, the name will include a suffix with the sequence number with underscore before it. For example, the first script you run will have the name __run, and the second script will be named __run_2. Similarly, the second invocation of actions/checkout will be actionscheckout2.
4853
"action_path": "", // string, The path where an action is located. This property is only supported in composite actions. You can use this path to access files located in the same repository as the action.
@@ -160,3 +165,19 @@ func mergeTwoOutputs(o1, o2 map[string]string) map[string]string {
160165
}
161166
return ret
162167
}
168+
169+
func (g *GiteaContext) ToGitHubContext() *model.GithubContext {
170+
ghCtx := &model.GithubContext{}
171+
172+
gitCtxRaw, err := json.Marshal(g)
173+
if err != nil {
174+
log.Error("ToGitHubContext.json.Marshal: %v", err)
175+
}
176+
177+
err = json.Unmarshal(gitCtxRaw, ghCtx)
178+
if err != nil {
179+
log.Error("ToGitHubContext.json.Unmarshal: %v", err)
180+
}
181+
182+
return ghCtx
183+
}

services/actions/notifier_helper.go

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -316,10 +316,6 @@ func handleWorkflows(
316316
Status: actions_model.StatusWaiting,
317317
}
318318

319-
if runName, err := parseRunName(run, dwf); err == nil {
320-
run.Title = runName
321-
}
322-
323319
need, err := ifNeedApproval(ctx, run, input.Repo, input.Doer)
324320
if err != nil {
325321
log.Error("check if need approval for repo %d with user %d: %v", input.Repo.ID, input.Doer.ID, err)
@@ -339,12 +335,18 @@ func handleWorkflows(
339335
continue
340336
}
341337

342-
jobs, err := jobparser.Parse(dwf.Content, jobparser.WithVars(vars))
338+
giteaCtx := GenerateGiteaContext(run, nil)
339+
340+
jobs, err := jobparser.Parse(dwf.Content, jobparser.WithVars(vars), jobparser.WithGitContext(giteaCtx.ToGitHubContext()))
343341
if err != nil {
344342
log.Error("jobparser.Parse: %v", err)
345343
continue
346344
}
347345

346+
if len(jobs) > 0 && jobs[0].RunName != "" {
347+
run.Title = jobs[0].RunName
348+
}
349+
348350
// cancel running jobs if the event is push or pull_request_sync
349351
if run.Event == webhook_module.HookEventPush ||
350352
run.Event == webhook_module.HookEventPullRequestSync {
@@ -527,8 +529,22 @@ func handleSchedules(
527529
Content: dwf.Content,
528530
}
529531

530-
if runName, err := parseRunName(run.ToActionRun(), dwf); err == nil {
531-
run.Title = runName
532+
vars, err := actions_model.GetVariablesOfRun(ctx, run.ToActionRun())
533+
if err != nil {
534+
log.Error("GetVariablesOfRun: %v", err)
535+
continue
536+
}
537+
538+
giteaCtx := GenerateGiteaContext(run.ToActionRun(), nil)
539+
540+
jobs, err := jobparser.Parse(dwf.Content, jobparser.WithVars(vars), jobparser.WithGitContext(giteaCtx.ToGitHubContext()))
541+
if err != nil {
542+
log.Error("jobparser.Parse: %v", err)
543+
continue
544+
}
545+
546+
if len(jobs) > 0 && jobs[0].RunName != "" {
547+
run.Title = jobs[0].RunName
532548
}
533549

534550
crons = append(crons, run)
@@ -569,28 +585,3 @@ func DetectAndHandleSchedules(ctx context.Context, repo *repo_model.Repository)
569585

570586
return handleSchedules(ctx, scheduleWorkflows, commit, notifyInput, repo.DefaultBranch)
571587
}
572-
573-
func parseRunName(r *actions_model.ActionRun, w *actions_module.DetectedWorkflow) (string, error) {
574-
ghCtx := &model.GithubContext{}
575-
gitCtx := GenerateGiteaContext(r, nil)
576-
577-
gitCtxRaw, err := json.Marshal(gitCtx)
578-
if err != nil {
579-
log.Error("NewInterpolatorForRun: %v", err)
580-
return "", err
581-
}
582-
583-
err = json.Unmarshal(gitCtxRaw, ghCtx)
584-
if err != nil {
585-
log.Error("NewInterpolatorForRun: %v", err)
586-
return "", err
587-
}
588-
589-
title, err := jobparser.ParseRunName(w.Content, jobparser.WithGitContext(ghCtx))
590-
if err != nil {
591-
// stay silent, run-name was not provided.
592-
return "", err
593-
}
594-
595-
return title, nil
596-
}

services/actions/workflow.go

Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -192,27 +192,46 @@ func DispatchActionWorkflow(ctx reqctx.RequestContext, doer *user_model.User, re
192192

193193
// find workflow from commit
194194
var workflows []*jobparser.SingleWorkflow
195-
dwf := &actions.DetectedWorkflow{}
195+
var entry *git.TreeEntry
196196

197-
for _, entry := range entries {
198-
if entry.Name() != workflowID {
197+
for _, e := range entries {
198+
if e.Name() != workflowID {
199199
continue
200200
}
201+
entry = e
202+
break
203+
}
201204

202-
content, err := actions.GetContentFromEntry(entry)
203-
if err != nil {
204-
return err
205-
}
205+
content, err := actions.GetContentFromEntry(entry)
206+
if err != nil {
207+
return err
208+
}
206209

207-
workflows, err = jobparser.Parse(content)
208-
if err != nil {
209-
return err
210-
}
210+
run := &actions_model.ActionRun{
211+
Title: strings.SplitN(runTargetCommit.CommitMessage, "\n", 2)[0],
212+
RepoID: repo.ID,
213+
Repo: repo,
214+
OwnerID: repo.OwnerID,
215+
WorkflowID: workflowID,
216+
TriggerUserID: doer.ID,
217+
TriggerUser: doer,
218+
Ref: string(refName),
219+
CommitSHA: runTargetCommit.ID.String(),
220+
IsForkPullRequest: false,
221+
Event: "workflow_dispatch",
222+
TriggerEvent: "workflow_dispatch",
223+
Status: actions_model.StatusWaiting,
224+
}
211225

212-
dwf.Content = content
213-
dwf.EntryName = entry.Name()
226+
giteaCtx := GenerateGiteaContext(run, nil)
214227

215-
break
228+
workflows, err = jobparser.Parse(content, jobparser.WithGitContext(giteaCtx.ToGitHubContext()))
229+
if err != nil {
230+
return err
231+
}
232+
233+
if len(workflows) > 0 && workflows[0].RunName != "" {
234+
run.Title = workflows[0].RunName
216235
}
217236

218237
if len(workflows) == 0 {
@@ -243,33 +262,12 @@ func DispatchActionWorkflow(ctx reqctx.RequestContext, doer *user_model.User, re
243262
Inputs: inputsWithDefaults,
244263
Sender: convert.ToUserWithAccessMode(ctx, doer, perm.AccessModeNone),
245264
}
265+
246266
var eventPayload []byte
247267
if eventPayload, err = workflowDispatchPayload.JSONPayload(); err != nil {
248268
return fmt.Errorf("JSONPayload: %w", err)
249269
}
250-
251-
run := &actions_model.ActionRun{
252-
Title: strings.SplitN(runTargetCommit.CommitMessage, "\n", 2)[0],
253-
RepoID: repo.ID,
254-
Repo: repo,
255-
OwnerID: repo.OwnerID,
256-
WorkflowID: workflowID,
257-
TriggerUserID: doer.ID,
258-
TriggerUser: doer,
259-
Ref: string(refName),
260-
CommitSHA: runTargetCommit.ID.String(),
261-
IsForkPullRequest: false,
262-
Event: "workflow_dispatch",
263-
TriggerEvent: "workflow_dispatch",
264-
EventPayload: string(eventPayload),
265-
Status: actions_model.StatusWaiting,
266-
}
267-
268-
if runName, err := parseRunName(run, dwf); err == nil {
269-
run.Title = runName
270-
} else {
271-
log.Error("ParseRunName: %v", err)
272-
}
270+
run.EventPayload = string(eventPayload)
273271

274272
// cancel running jobs of the same workflow
275273
if err := CancelPreviousJobs(

0 commit comments

Comments
 (0)