Skip to content

Commit 94d17bb

Browse files
committed
Support run-name evaluation in action runs
1 parent d9045e2 commit 94d17bb

File tree

5 files changed

+86
-10
lines changed

5 files changed

+86
-10
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.1
320+
replace github.com/nektos/act => gitea.com/gitea/act v0.261.4
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: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
1616
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
1717
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:cliQ4HHsCo6xi2oWZYKWW4bly/Ory9FuTpFPRxj/mAg=
1818
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs=
19-
gitea.com/badhezi/act v0.0.1 h1:lsJL7/BHco3XJyFqI1GJKc0VTX0TPxg/tvsUwAcRiKU=
20-
gitea.com/badhezi/act v0.0.1/go.mod h1:Pg5C9kQY1CEA3QjthjhlrqOC/QOT5NyWNjOjRHw23Ok=
19+
gitea.com/gitea/act v0.261.4 h1:Tf9eLlvsYFtKcpuxlMvf9yT3g4Hshb2Beqw6C1STuH8=
20+
gitea.com/gitea/act v0.261.4/go.mod h1:Pg5C9kQY1CEA3QjthjhlrqOC/QOT5NyWNjOjRHw23Ok=
2121
gitea.com/gitea/git-lfs-transfer v0.2.0 h1:baHaNoBSRaeq/xKayEXwiDQtlIjps4Ac/Ll4KqLMB40=
2222
gitea.com/gitea/git-lfs-transfer v0.2.0/go.mod h1:UrXUCm3xLQkq15fu7qlXHUMlrhdlXHoi13KH2Dfiits=
2323
gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed h1:EZZBtilMLSZNWtHHcgq2mt6NSGhJSZBuduAlinMEmso=

services/actions/notifier_helper.go

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
notify_service "code.gitea.io/gitea/services/notify"
3131
"gopkg.in/yaml.v3"
3232

33+
"github.com/nektos/act/pkg/exprparser"
3334
"github.com/nektos/act/pkg/jobparser"
3435
"github.com/nektos/act/pkg/model"
3536
)
@@ -300,16 +301,14 @@ func handleWorkflows(
300301
}
301302

302303
for _, dwf := range detectedWorkflows {
303-
var yamlData map[string]any
304-
if err := yaml.Unmarshal([]byte(dwf.Content), &yamlData); err != nil {
305-
log.Fatal(err.Error())
306-
}
307304
run := &actions_model.ActionRun{
308-
Title: yamlData["run-name"].(string),
305+
Title: strings.SplitN(commit.CommitMessage, "\n", 2)[0],
309306
RepoID: input.Repo.ID,
307+
Repo: input.Repo,
310308
OwnerID: input.Repo.OwnerID,
311309
WorkflowID: dwf.EntryName,
312310
TriggerUserID: input.Doer.ID,
311+
TriggerUser: input.Doer,
313312
Ref: ref,
314313
CommitSHA: commit.ID.String(),
315314
IsForkPullRequest: isForkPullRequest,
@@ -319,6 +318,11 @@ func handleWorkflows(
319318
Status: actions_model.StatusWaiting,
320319
}
321320

321+
if err := EvaluateExpressionsForRun(run, dwf); err != nil {
322+
log.Error("EvaluateExpressionsForRun: %v", err)
323+
continue
324+
}
325+
322326
need, err := ifNeedApproval(ctx, run, input.Repo, input.Doer)
323327
if err != nil {
324328
log.Error("check if need approval for repo %d with user %d: %v", input.Repo.ID, input.Doer.ID, err)
@@ -523,6 +527,11 @@ func handleSchedules(
523527
Specs: schedules,
524528
Content: dwf.Content,
525529
}
530+
531+
if runName, err := parseRunNameFromDetectedWorkflow(dwf); err == nil {
532+
run.Title = runName
533+
}
534+
526535
crons = append(crons, run)
527536
}
528537

@@ -561,3 +570,56 @@ func DetectAndHandleSchedules(ctx context.Context, repo *repo_model.Repository)
561570

562571
return handleSchedules(ctx, scheduleWorkflows, commit, notifyInput, repo.DefaultBranch)
563572
}
573+
574+
func newExpressionEvaluatorForRun(r *actions_model.ActionRun) (*jobparser.ExpressionEvaluator, error) {
575+
ghCtx := &model.GithubContext{}
576+
gitCtx := GenerateGiteaContext(r, nil)
577+
578+
gitCtxRaw, err := json.Marshal(gitCtx)
579+
if err != nil {
580+
log.Error("NewInterpolatorForRun: %v", err)
581+
return nil, err
582+
}
583+
584+
err = json.Unmarshal(gitCtxRaw, ghCtx)
585+
if err != nil {
586+
log.Error("NewInterpolatorForRun: %v", err)
587+
return nil, err
588+
}
589+
590+
interp := exprparser.NewInterpeter(&exprparser.EvaluationEnvironment{Github: ghCtx}, exprparser.Config{})
591+
ee := jobparser.NewExpressionEvaluator(interp)
592+
return ee, nil
593+
}
594+
595+
func parseRunNameFromDetectedWorkflow(w *actions_module.DetectedWorkflow) (string, error) {
596+
var data map[string]any
597+
var value string
598+
599+
if err := yaml.Unmarshal([]byte(w.Content), &data); err != nil {
600+
log.Error("parseRunNameFromDetectedWorkflow: %v", err)
601+
return "", err
602+
}
603+
604+
if v, ok := data["run-name"]; !ok {
605+
return "", fmt.Errorf("run-name not found in workflow")
606+
} else {
607+
value = v.(string)
608+
}
609+
610+
return value, nil
611+
}
612+
613+
func EvaluateExpressionsForRun(r *actions_model.ActionRun, w *actions_module.DetectedWorkflow) error {
614+
if runName, err := parseRunNameFromDetectedWorkflow(w); err == nil {
615+
ee, err := newExpressionEvaluatorForRun(r)
616+
if err != nil {
617+
log.Error("newExpressionEvaluatorForRun: %v", err)
618+
return err
619+
}
620+
r.Title = ee.Interpolate(runName)
621+
} else {
622+
log.Error("parseRunNameFromDetectedWorkflow: %v", err)
623+
}
624+
return nil
625+
}

services/actions/workflow.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"code.gitea.io/gitea/models/unit"
1919
user_model "code.gitea.io/gitea/models/user"
2020
"code.gitea.io/gitea/modules/actions"
21+
actions_module "code.gitea.io/gitea/modules/actions"
2122
"code.gitea.io/gitea/modules/git"
2223
"code.gitea.io/gitea/modules/log"
2324
"code.gitea.io/gitea/modules/reqctx"
@@ -192,6 +193,8 @@ func DispatchActionWorkflow(ctx reqctx.RequestContext, doer *user_model.User, re
192193

193194
// find workflow from commit
194195
var workflows []*jobparser.SingleWorkflow
196+
dwf := &actions_module.DetectedWorkflow{}
197+
195198
for _, entry := range entries {
196199
if entry.Name() != workflowID {
197200
continue
@@ -201,10 +204,15 @@ func DispatchActionWorkflow(ctx reqctx.RequestContext, doer *user_model.User, re
201204
if err != nil {
202205
return err
203206
}
207+
204208
workflows, err = jobparser.Parse(content)
205209
if err != nil {
206210
return err
207211
}
212+
213+
dwf.Content = content
214+
dwf.EntryName = entry.Name()
215+
208216
break
209217
}
210218

@@ -244,9 +252,11 @@ func DispatchActionWorkflow(ctx reqctx.RequestContext, doer *user_model.User, re
244252
run := &actions_model.ActionRun{
245253
Title: strings.SplitN(runTargetCommit.CommitMessage, "\n", 2)[0],
246254
RepoID: repo.ID,
255+
Repo: repo,
247256
OwnerID: repo.OwnerID,
248257
WorkflowID: workflowID,
249258
TriggerUserID: doer.ID,
259+
TriggerUser: doer,
250260
Ref: string(refName),
251261
CommitSHA: runTargetCommit.ID.String(),
252262
IsForkPullRequest: false,
@@ -256,6 +266,10 @@ func DispatchActionWorkflow(ctx reqctx.RequestContext, doer *user_model.User, re
256266
Status: actions_model.StatusWaiting,
257267
}
258268

269+
if err := EvaluateExpressionsForRun(run, dwf); err != nil {
270+
log.Error("EvaluateExpressionsForRun: %v", err)
271+
}
272+
259273
// cancel running jobs of the same workflow
260274
if err := CancelPreviousJobs(
261275
ctx,

web_src/js/components/RepoActionView.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,11 +346,11 @@ export default defineComponent({
346346
const isFirstLoad = !this.run.status;
347347
const job = await this.fetchJobData(abortController);
348348
if (this.loadingAbortController !== abortController) return;
349-
349+
console.log(job)
350350
this.artifacts = job.artifacts || [];
351351
this.run = job.state.run;
352352
this.currentJob = job.state.currentJob;
353-
353+
console.log(this.currentJob)
354354
// sync the currentJobStepsStates to store the job step states
355355
for (let i = 0; i < this.currentJob.steps.length; i++) {
356356
const expanded = isFirstLoad && this.optionAlwaysExpandRunning && this.currentJob.steps[i].status === 'running';

0 commit comments

Comments
 (0)