From 3a07d231a00c8b974ee4b2534d362d02d3f46627 Mon Sep 17 00:00:00 2001 From: Christopher Homberger Date: Tue, 9 Dec 2025 02:28:56 +0000 Subject: [PATCH] Fix yaml with prefixed newline broken setjob + yaml v4 (#144) * go-yaml v3 **and** v4 workaround * avoid yaml.Marshal broken indention Co-authored-by: Lunny Xiao Reviewed-on: https://gitea.com/gitea/act/pulls/144 Reviewed-by: wxiaoguang Reviewed-by: Zettat123 Co-authored-by: Christopher Homberger Co-committed-by: Christopher Homberger --- cmd/root.go | 2 +- go.mod | 3 ++- go.sum | 2 ++ pkg/jobparser/evaluator.go | 2 +- pkg/jobparser/interpeter.go | 2 +- pkg/jobparser/jobparser.go | 2 +- pkg/jobparser/jobparser_test.go | 7 ++++++- pkg/jobparser/model.go | 16 +++++++++------- pkg/jobparser/model_test.go | 2 +- pkg/jobparser/testdata/prefixed_newline.in.yaml | 14 ++++++++++++++ pkg/jobparser/testdata/prefixed_newline.out.yaml | 15 +++++++++++++++ pkg/model/action.go | 2 +- pkg/model/workflow.go | 2 +- pkg/runner/expression.go | 2 +- pkg/runner/expression_test.go | 2 +- pkg/runner/run_context_test.go | 2 +- pkg/runner/runner_test.go | 2 +- pkg/runner/step_action_local_test.go | 2 +- pkg/runner/step_action_remote_test.go | 2 +- pkg/runner/step_test.go | 2 +- 20 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 pkg/jobparser/testdata/prefixed_newline.in.yaml create mode 100644 pkg/jobparser/testdata/prefixed_newline.out.yaml diff --git a/cmd/root.go b/cmd/root.go index 3eca0406..4cd0ebdb 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -19,7 +19,7 @@ import ( gitignore "github.com/sabhiram/go-gitignore" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v4" "github.com/nektos/act/pkg/artifactcache" "github.com/nektos/act/pkg/artifacts" diff --git a/go.mod b/go.mod index 60f152f3..4aee2fce 100644 --- a/go.mod +++ b/go.mod @@ -33,8 +33,8 @@ require ( github.com/stretchr/testify v1.9.0 github.com/timshannon/bolthold v0.0.0-20210913165410-232392fc8a6a go.etcd.io/bbolt v1.3.9 + go.yaml.in/yaml/v4 v4.0.0-rc.2 golang.org/x/term v0.18.0 - gopkg.in/yaml.v3 v3.0.1 gotest.tools/v3 v3.5.1 ) @@ -88,4 +88,5 @@ require ( golang.org/x/tools v0.13.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index bdd044f5..6ec93d53 100644 --- a/go.sum +++ b/go.sum @@ -191,6 +191,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= +go.yaml.in/yaml/v4 v4.0.0-rc.2 h1:/FrI8D64VSr4HtGIlUtlFMGsm7H7pWTbj6vOLVZcA6s= +go.yaml.in/yaml/v4 v4.0.0-rc.2/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/pkg/jobparser/evaluator.go b/pkg/jobparser/evaluator.go index 80a13973..2a950085 100644 --- a/pkg/jobparser/evaluator.go +++ b/pkg/jobparser/evaluator.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/nektos/act/pkg/exprparser" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v4" ) // ExpressionEvaluator is copied from runner.expressionEvaluator, diff --git a/pkg/jobparser/interpeter.go b/pkg/jobparser/interpeter.go index 3d121ade..e5657813 100644 --- a/pkg/jobparser/interpeter.go +++ b/pkg/jobparser/interpeter.go @@ -3,7 +3,7 @@ package jobparser import ( "github.com/nektos/act/pkg/exprparser" "github.com/nektos/act/pkg/model" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v4" ) // NewInterpeter returns an interpeter used in the server, diff --git a/pkg/jobparser/jobparser.go b/pkg/jobparser/jobparser.go index 9092d856..962a26bc 100644 --- a/pkg/jobparser/jobparser.go +++ b/pkg/jobparser/jobparser.go @@ -6,7 +6,7 @@ import ( "sort" "strings" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v4" "github.com/nektos/act/pkg/exprparser" "github.com/nektos/act/pkg/model" diff --git a/pkg/jobparser/jobparser_test.go b/pkg/jobparser/jobparser_test.go index 800e19a3..ed918760 100644 --- a/pkg/jobparser/jobparser_test.go +++ b/pkg/jobparser/jobparser_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v4" ) func TestParse(t *testing.T) { @@ -52,6 +52,11 @@ func TestParse(t *testing.T) { options: nil, wantErr: false, }, + { + name: "prefixed_newline", + options: nil, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/jobparser/model.go b/pkg/jobparser/model.go index e7ca0dfb..3360a72b 100644 --- a/pkg/jobparser/model.go +++ b/pkg/jobparser/model.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/nektos/act/pkg/model" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v4" ) // SingleWorkflow is a workflow with single job and single matrix @@ -50,16 +50,18 @@ func (w *SingleWorkflow) SetJob(id string, job *Job) error { m := map[string]*Job{ id: job, } - out, err := yaml.Marshal(m) - if err != nil { - return err - } + var buf bytes.Buffer + encoder := yaml.NewEncoder(&buf) + encoder.SetIndent(2) + encoder.Encode(m) + encoder.Close() + node := yaml.Node{} - if err := yaml.Unmarshal(out, &node); err != nil { + if err := yaml.Unmarshal(buf.Bytes(), &node); err != nil { return err } if len(node.Content) != 1 || node.Content[0].Kind != yaml.MappingNode { - return fmt.Errorf("can not set job: %q", out) + return fmt.Errorf("can not set job: %s", buf.String()) } w.RawJobs = *node.Content[0] return nil diff --git a/pkg/jobparser/model_test.go b/pkg/jobparser/model_test.go index 079c32d6..833756be 100644 --- a/pkg/jobparser/model_test.go +++ b/pkg/jobparser/model_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v4" ) func TestParseRawOn(t *testing.T) { diff --git a/pkg/jobparser/testdata/prefixed_newline.in.yaml b/pkg/jobparser/testdata/prefixed_newline.in.yaml new file mode 100644 index 00000000..91f85302 --- /dev/null +++ b/pkg/jobparser/testdata/prefixed_newline.in.yaml @@ -0,0 +1,14 @@ +name: Step with leading new line + +on: + push: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: "\nExtract tag for variant" + id: extract_tag + run: | + + echo Test diff --git a/pkg/jobparser/testdata/prefixed_newline.out.yaml b/pkg/jobparser/testdata/prefixed_newline.out.yaml new file mode 100644 index 00000000..027e9dfa --- /dev/null +++ b/pkg/jobparser/testdata/prefixed_newline.out.yaml @@ -0,0 +1,15 @@ +name: Step with leading new line +"on": + push: +jobs: + test: + name: test + runs-on: ubuntu-latest + steps: + - id: extract_tag + name: |2- + + Extract tag for variant + run: |2 + + echo Test diff --git a/pkg/model/action.go b/pkg/model/action.go index 6031cec2..316d9d7b 100644 --- a/pkg/model/action.go +++ b/pkg/model/action.go @@ -5,7 +5,7 @@ import ( "io" "strings" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v4" ) // ActionRunsUsing is the type of runner for the action diff --git a/pkg/model/workflow.go b/pkg/model/workflow.go index f93623fa..7d5ca25d 100644 --- a/pkg/model/workflow.go +++ b/pkg/model/workflow.go @@ -10,7 +10,7 @@ import ( "strings" log "github.com/sirupsen/logrus" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v4" "github.com/nektos/act/pkg/common" ) diff --git a/pkg/runner/expression.go b/pkg/runner/expression.go index 2e3152b0..894ebbfa 100644 --- a/pkg/runner/expression.go +++ b/pkg/runner/expression.go @@ -16,7 +16,7 @@ import ( "github.com/nektos/act/pkg/container" "github.com/nektos/act/pkg/exprparser" "github.com/nektos/act/pkg/model" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v4" ) // ExpressionEvaluator is the interface for evaluating expressions diff --git a/pkg/runner/expression_test.go b/pkg/runner/expression_test.go index 5cc2f7b2..0bc0bf0d 100644 --- a/pkg/runner/expression_test.go +++ b/pkg/runner/expression_test.go @@ -11,7 +11,7 @@ import ( "github.com/nektos/act/pkg/exprparser" "github.com/nektos/act/pkg/model" assert "github.com/stretchr/testify/assert" - yaml "gopkg.in/yaml.v3" + yaml "go.yaml.in/yaml/v4" ) func createRunContext(t *testing.T) *RunContext { diff --git a/pkg/runner/run_context_test.go b/pkg/runner/run_context_test.go index af0cd4ee..7a7ffbaa 100644 --- a/pkg/runner/run_context_test.go +++ b/pkg/runner/run_context_test.go @@ -15,7 +15,7 @@ import ( log "github.com/sirupsen/logrus" assert "github.com/stretchr/testify/assert" - yaml "gopkg.in/yaml.v3" + yaml "go.yaml.in/yaml/v4" ) func TestRunContext_EvalBool(t *testing.T) { diff --git a/pkg/runner/runner_test.go b/pkg/runner/runner_test.go index 20059323..a73ab5f4 100644 --- a/pkg/runner/runner_test.go +++ b/pkg/runner/runner_test.go @@ -15,7 +15,7 @@ import ( "github.com/joho/godotenv" log "github.com/sirupsen/logrus" assert "github.com/stretchr/testify/assert" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v4" "github.com/nektos/act/pkg/common" "github.com/nektos/act/pkg/model" diff --git a/pkg/runner/step_action_local_test.go b/pkg/runner/step_action_local_test.go index c4b63459..8a80a1c6 100644 --- a/pkg/runner/step_action_local_test.go +++ b/pkg/runner/step_action_local_test.go @@ -12,7 +12,7 @@ import ( "github.com/nektos/act/pkg/model" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v4" ) type stepActionLocalMocks struct { diff --git a/pkg/runner/step_action_remote_test.go b/pkg/runner/step_action_remote_test.go index 9dcc3383..1c3a37bf 100644 --- a/pkg/runner/step_action_remote_test.go +++ b/pkg/runner/step_action_remote_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v4" "github.com/nektos/act/pkg/common" "github.com/nektos/act/pkg/common/git" diff --git a/pkg/runner/step_test.go b/pkg/runner/step_test.go index cdb870e2..e2882529 100644 --- a/pkg/runner/step_test.go +++ b/pkg/runner/step_test.go @@ -9,7 +9,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - yaml "gopkg.in/yaml.v3" + yaml "go.yaml.in/yaml/v4" ) func TestMergeIntoMap(t *testing.T) {