mirror of
https://github.com/go-gitea/gitea.git
synced 2026-07-25 22:48:10 +02:00
Backport #38520 by @darklight147 ## Problem Jobs that call a reusable workflow (`uses:`) whose steps contain a `run: |` block that **starts with blank lines** never start — the child jobs stay `Blocked` forever, the run never finishes, and nothing is shown to the user (the error is only logged at DEBUG). The reusable is valid YAML and worked on 1.26. ## Root cause `jobparser` serializes each expanded job via `SingleWorkflow.SetJob()`, which uses `yaml.NewEncoder(...).SetIndent(2)`, but `SingleWorkflow.Marshal()` used `yaml.Marshal`, whose default indentation is **4**. Re-emitting a multi-line literal block scalar at a different indentation makes the encoder write a wrong explicit indentation indicator (`run: |4`) whose declared indent doesn't match the actual content indent. The stored `workflow_payload` is then unparseable: ``` run: |4 while ... ``` `jobparser.Parse` / `model.ReadWorkflow` (both go.yaml.in/yaml/v4) reject it: `did not find expected key`. This surfaces in `services/actions/job_emitter.go` `resolve()` → `updateConcurrencyEvaluationForJobWithNeeds` → `ParseJob`, where the error is swallowed at `log.Debug` and the job is left `Blocked`. Encoding at indent 4 triggers the bad indicator; indent 2 does not — matching the value already used by `SetJob`. ## Fix Encode `SingleWorkflow.Marshal()` with `SetIndent(2)` so both encoders agree and the serialized single workflow round-trips. Adds a regression test (`Parse → Marshal → Parse` on a `run:` block with leading blank lines) that fails before the change with `did not find expected key`. ## Notes - This is the correctness fix. Related: #37116 added `ValidateWorkflowContent` to *report* such content for top-level workflows, but the reusable-expansion/concurrency-eval path is not covered and strands silently — this fix removes the failure mode entirely. - Consider a follow-up to elevate the swallowed error in `job_emitter.resolve()` from `log.Debug` to a user-visible job failure (there is an existing `// TODO`). Signed-off-by: quasimodo <mohamed.belkamel@intelcia.com> Co-authored-by: Mohamed Belkamel <39389636+darklight147@users.noreply.github.com> Co-authored-by: quasimodo <mohamed.belkamel@intelcia.com> Co-authored-by: Zettat123 <zettat123@gmail.com>