diff --git a/go.mod b/go.mod index 8a7c8b6faa..3afb624188 100644 --- a/go.mod +++ b/go.mod @@ -244,7 +244,7 @@ require ( replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1 -replace github.com/nektos/act => code.forgejo.org/forgejo/act v1.29.0 +replace github.com/nektos/act => code.forgejo.org/forgejo/act v1.32.0 replace github.com/mholt/archiver/v3 => code.forgejo.org/forgejo/archiver/v3 v3.5.1 diff --git a/go.sum b/go.sum index a291e6c4b7..35d1d09dde 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ code.forgejo.org/f3/gof3/v3 v3.11.0 h1:f/xToKwqTgxG6PYxvewywjDQyCcyHEEJ6sZqUitFs code.forgejo.org/f3/gof3/v3 v3.11.0/go.mod h1:4FaRUNSQGBiD1M0DuB0yNv+Z2wMtlOeckgygHSSq4KQ= code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251 h1:HTZl3CBk3ABNYtFI6TPLvJgGKFIhKT5CBk0sbOtkDKU= code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:PphB88CPbx601QrWPMZATeorACeVmQlyv3u+uUMbSaM= -code.forgejo.org/forgejo/act v1.29.0 h1:CPiI0LRPU0f6gUdQj1ZVax0ySc8CfegY4hiRsymdZU0= -code.forgejo.org/forgejo/act v1.29.0/go.mod h1:RPqtuaI2FkC1SVOaYCRODo5jIfoMTBVgEOOP3Sdiuh4= +code.forgejo.org/forgejo/act v1.32.0 h1:hns2WvrJs6qWCmvzoSllNGNzSvcDMcSvJvVtQj3FaQc= +code.forgejo.org/forgejo/act v1.32.0/go.mod h1:WkmxVBteC4zoyQGYp8ZFZY7Xb+jat+b7ChvqW6TxqF8= code.forgejo.org/forgejo/archiver/v3 v3.5.1 h1:UmmbA7D5550uf71SQjarmrn6yKwOGxtEjb3jaYYtmSE= code.forgejo.org/forgejo/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= code.forgejo.org/forgejo/go-rpmutils v1.0.0 h1:RZGGeKt70p/WaIEL97pyT6uiiEIoN8/aLmS5Z6WmX0M= diff --git a/models/actions/task.go b/models/actions/task.go index 93369db7e8..7c85ffc232 100644 --- a/models/actions/task.go +++ b/models/actions/task.go @@ -275,7 +275,7 @@ func CreateTaskForRunner(ctx context.Context, runner *ActionRunner) (*ActionTask } var workflowJob *jobparser.Job - if gots, err := jobparser.Parse(job.WorkflowPayload); err != nil { + if gots, err := jobparser.Parse(job.WorkflowPayload, false); err != nil { return nil, false, fmt.Errorf("parse workflow of job %d: %w", job.ID, err) } else if len(gots) != 1 { return nil, false, fmt.Errorf("workflow of job %d: not single workflow", job.ID) diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 7ae4557ed6..b04f97df0f 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -86,7 +86,7 @@ func GetContentFromEntry(entry *git.TreeEntry) ([]byte, error) { } func GetEventsFromContent(content []byte) ([]*jobparser.Event, error) { - workflow, err := model.ReadWorkflow(bytes.NewReader(content)) + workflow, err := model.ReadWorkflow(bytes.NewReader(content), false) if err != nil { return nil, err } diff --git a/release-notes/8502.md b/release-notes/8502.md new file mode 100644 index 0000000000..b7fa0fd892 --- /dev/null +++ b/release-notes/8502.md @@ -0,0 +1 @@ +Forgejo Actions workflows are verified with a YAML schema and common errors such as using an incorrect context (e.g. `${{ badcontext.FORGEJO_REPOSITORY }}`) or a typo in a required keyword (e.g. `ruins-on:` instead of `runs-on:`) will be reported in the action page and the web page that displays the file in the repository. It is recommended to verify existing workflows are successfully verified prior to upgrading, [as explained in the Forgejo runner release notes](https://code.forgejo.org/forgejo/runner/src/branch/main/RELEASE-NOTES.md#8-0-0). diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index 7aa52ddd4c..6f1f19b107 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -111,7 +111,7 @@ func List(ctx *context.Context) { ctx.ServerError("GetContentFromEntry", err) return } - wf, err := model.ReadWorkflow(bytes.NewReader(content)) + wf, err := model.ReadWorkflow(bytes.NewReader(content), true) if err != nil { workflow.ErrMsg = ctx.Locale.TrString("actions.runs.invalid_workflow_helper", err.Error()) workflows = append(workflows, workflow) diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index e61059da64..8e1028968e 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -434,7 +434,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) { if err != nil { log.Error("actions.GetContentFromEntry: %v", err) } - _, workFlowErr := model.ReadWorkflow(bytes.NewReader(content)) + _, workFlowErr := model.ReadWorkflow(bytes.NewReader(content), true) if workFlowErr != nil { ctx.Data["FileError"] = ctx.Locale.Tr("actions.runs.invalid_workflow_helper", workFlowErr.Error()) } diff --git a/services/actions/commit_status.go b/services/actions/commit_status.go index 755fa648dc..b054f2036c 100644 --- a/services/actions/commit_status.go +++ b/services/actions/commit_status.go @@ -80,7 +80,7 @@ func createCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er repo := run.Repo // TODO: store workflow name as a field in ActionRun to avoid parsing runName := path.Base(run.WorkflowID) - if wfs, err := jobparser.Parse(job.WorkflowPayload); err == nil && len(wfs) > 0 { + if wfs, err := jobparser.Parse(job.WorkflowPayload, false); err == nil && len(wfs) > 0 { runName = wfs[0].Name } ctxname := fmt.Sprintf("%s / %s (%s)", runName, job.Name, event) diff --git a/services/actions/job_emitter.go b/services/actions/job_emitter.go index 942c698e73..8178d210ce 100644 --- a/services/actions/job_emitter.go +++ b/services/actions/job_emitter.go @@ -142,7 +142,7 @@ func (r *jobStatusResolver) resolve() map[int64]actions_model.Status { } else { // Check if the job has an "if" condition hasIf := false - if wfJobs, _ := jobparser.Parse(r.jobMap[id].WorkflowPayload); len(wfJobs) == 1 { + if wfJobs, _ := jobparser.Parse(r.jobMap[id].WorkflowPayload, false); len(wfJobs) == 1 { _, wfJob := wfJobs[0].Job() hasIf = len(wfJob.If.Value) > 0 } diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index e240c996b5..e31817a5e2 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -345,7 +345,7 @@ func handleWorkflows( Status: actions_model.StatusWaiting, } - if workflow, err := model.ReadWorkflow(bytes.NewReader(dwf.Content)); err == nil { + if workflow, err := model.ReadWorkflow(bytes.NewReader(dwf.Content), false); err == nil { notifications, err := workflow.Notifications() if err != nil { log.Error("Notifications: %w", err) @@ -372,7 +372,7 @@ func handleWorkflows( continue } - jobs, err := jobparser.Parse(dwf.Content, jobparser.WithVars(vars)) + jobs, err := jobparser.Parse(dwf.Content, false, jobparser.WithVars(vars)) if err != nil { run.Status = actions_model.StatusFailure log.Info("jobparser.Parse: invalid workflow, setting job status to failed: %v", err) @@ -537,7 +537,7 @@ func handleSchedules( crons := make([]*actions_model.ActionSchedule, 0, len(detectedWorkflows)) for _, dwf := range detectedWorkflows { // Check cron job condition. Only working in default branch - workflow, err := model.ReadWorkflow(bytes.NewReader(dwf.Content)) + workflow, err := model.ReadWorkflow(bytes.NewReader(dwf.Content), false) if err != nil { log.Error("ReadWorkflow: %v", err) continue diff --git a/services/actions/schedule_tasks.go b/services/actions/schedule_tasks.go index cf8b29ead7..d275837cbb 100644 --- a/services/actions/schedule_tasks.go +++ b/services/actions/schedule_tasks.go @@ -142,7 +142,7 @@ func CreateScheduleTask(ctx context.Context, cron *actions_model.ActionSchedule) return err } - workflow, err := act_model.ReadWorkflow(bytes.NewReader(cron.Content)) + workflow, err := act_model.ReadWorkflow(bytes.NewReader(cron.Content), false) if err != nil { return err } @@ -153,7 +153,7 @@ func CreateScheduleTask(ctx context.Context, cron *actions_model.ActionSchedule) run.NotifyEmail = notifications // Parse the workflow specification from the cron schedule - workflows, err := jobparser.Parse(cron.Content, jobparser.WithVars(vars)) + workflows, err := jobparser.Parse(cron.Content, false, jobparser.WithVars(vars)) if err != nil { return err } diff --git a/services/actions/workflows.go b/services/actions/workflows.go index fbba3fd667..22417d4e32 100644 --- a/services/actions/workflows.go +++ b/services/actions/workflows.go @@ -56,7 +56,7 @@ func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGette return nil, nil, err } - wf, err := act_model.ReadWorkflow(bytes.NewReader(content)) + wf, err := act_model.ReadWorkflow(bytes.NewReader(content), false) if err != nil { return nil, nil, err } @@ -138,7 +138,7 @@ func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGette return nil, nil, err } - jobs, err := jobparser.Parse(content, jobparser.WithVars(vars)) + jobs, err := jobparser.Parse(content, false, jobparser.WithVars(vars)) if err != nil { return nil, nil, err }