From 57524e90f163fbcae2d54ec59208e0a6094a9f23 Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Sun, 27 Jul 2025 10:06:07 +0000 Subject: [PATCH] fix: tolerate strings for fail-fast, max-parallel, timeout-minutes, cancel-timeout-minutes (#203) - the model defines them as strings and can parse them either as string or their effective type (boolean, number) - add workflow validation when reading all testdata - add fail-fast, max-parallel, timeout-minutes, cancel-timeout-minutes to test workflows in the jobparser tests Reviewed-on: https://code.forgejo.org/forgejo/act/pulls/203 Reviewed-by: Michael Kriese Co-authored-by: Earl Warren Co-committed-by: Earl Warren --- act/jobparser/testdata/has_with.in.yaml | 2 + act/jobparser/testdata/has_with.out.yaml | 2 + .../testdata/multiple_matrix.in.yaml | 4 +- .../testdata/multiple_matrix.out.yaml | 12 +++++ act/jobparser/testdata_test.go | 11 +++- act/schema/workflow_schema.json | 50 +++++++++++++++++-- 6 files changed, 73 insertions(+), 8 deletions(-) diff --git a/act/jobparser/testdata/has_with.in.yaml b/act/jobparser/testdata/has_with.in.yaml index ee5ebffc..085570df 100644 --- a/act/jobparser/testdata/has_with.in.yaml +++ b/act/jobparser/testdata/has_with.in.yaml @@ -7,6 +7,8 @@ jobs: - uses: .gitea/workflows/build.yml with: package: service + timeout-minutes: 20 + timeout-minutes: 10 job2: name: job2 diff --git a/act/jobparser/testdata/has_with.out.yaml b/act/jobparser/testdata/has_with.out.yaml index 6e66fecb..6be672d5 100644 --- a/act/jobparser/testdata/has_with.out.yaml +++ b/act/jobparser/testdata/has_with.out.yaml @@ -7,6 +7,8 @@ jobs: - uses: .gitea/workflows/build.yml with: package: service + timeout-minutes: "20" + timeout-minutes: "10" --- name: test jobs: diff --git a/act/jobparser/testdata/multiple_matrix.in.yaml b/act/jobparser/testdata/multiple_matrix.in.yaml index 99985f3c..76b5452a 100644 --- a/act/jobparser/testdata/multiple_matrix.in.yaml +++ b/act/jobparser/testdata/multiple_matrix.in.yaml @@ -2,6 +2,8 @@ name: test jobs: job1: strategy: + fail-fast: true + max-parallel: 5 matrix: os: [ubuntu-22.04, ubuntu-20.04] version: [1.17, 1.18, 1.19] @@ -10,4 +12,4 @@ jobs: - uses: actions/setup-go@v3 with: go-version: ${{ matrix.version }} - - run: uname -a && go version \ No newline at end of file + - run: uname -a && go version diff --git a/act/jobparser/testdata/multiple_matrix.out.yaml b/act/jobparser/testdata/multiple_matrix.out.yaml index e277cdd0..5b878407 100644 --- a/act/jobparser/testdata/multiple_matrix.out.yaml +++ b/act/jobparser/testdata/multiple_matrix.out.yaml @@ -9,6 +9,8 @@ jobs: go-version: ${{ matrix.version }} - run: uname -a && go version strategy: + fail-fast: "true" + max-parallel: "5" matrix: os: - ubuntu-20.04 @@ -26,6 +28,8 @@ jobs: go-version: ${{ matrix.version }} - run: uname -a && go version strategy: + fail-fast: "true" + max-parallel: "5" matrix: os: - ubuntu-20.04 @@ -43,6 +47,8 @@ jobs: go-version: ${{ matrix.version }} - run: uname -a && go version strategy: + fail-fast: "true" + max-parallel: "5" matrix: os: - ubuntu-20.04 @@ -60,6 +66,8 @@ jobs: go-version: ${{ matrix.version }} - run: uname -a && go version strategy: + fail-fast: "true" + max-parallel: "5" matrix: os: - ubuntu-22.04 @@ -77,6 +85,8 @@ jobs: go-version: ${{ matrix.version }} - run: uname -a && go version strategy: + fail-fast: "true" + max-parallel: "5" matrix: os: - ubuntu-22.04 @@ -94,6 +104,8 @@ jobs: go-version: ${{ matrix.version }} - run: uname -a && go version strategy: + fail-fast: "true" + max-parallel: "5" matrix: os: - ubuntu-22.04 diff --git a/act/jobparser/testdata_test.go b/act/jobparser/testdata_test.go index fb75a501..5b75a4c9 100644 --- a/act/jobparser/testdata_test.go +++ b/act/jobparser/testdata_test.go @@ -1,10 +1,13 @@ package jobparser import ( + "bytes" "embed" "path/filepath" "testing" + "github.com/nektos/act/pkg/model" + "github.com/stretchr/testify/require" ) @@ -12,7 +15,11 @@ import ( var testdata embed.FS func ReadTestdata(t *testing.T, name string) []byte { - content, err := testdata.ReadFile(filepath.Join("testdata", name)) - require.NoError(t, err) + t.Helper() + filename := filepath.Join("testdata", name) + content, err := testdata.ReadFile(filename) + require.NoError(t, err, filename) + _, err = model.ReadWorkflow(bytes.NewReader(content), true) + require.NoError(t, err, filename) return content } diff --git a/act/schema/workflow_schema.json b/act/schema/workflow_schema.json index dad253d6..a0c9b11b 100644 --- a/act/schema/workflow_schema.json +++ b/act/schema/workflow_schema.json @@ -1440,10 +1440,10 @@ "required": true }, "timeout-minutes": { - "type": "number-strategy-context", + "type": "job-timeout-minutes", "description": "The maximum number of minutes to let a workflow run before GitHub automatically cancels it. Default: 360" }, - "cancel-timeout-minutes": "number-strategy-context", + "cancel-timeout-minutes": "job-timeout-minutes", "continue-on-error": { "type": "boolean-strategy-context", "description": "Prevents a workflow run from failing when a job fails. Set to true to allow a workflow run to pass when this job fails." @@ -1552,17 +1552,53 @@ "mapping": { "properties": { "fail-fast": { - "type": "boolean", + "type": "fail-fast", "description": "Setting `fail-fast` to `false` prevents GitHub from canceling all in-progress jobs if any matrix job fails. Default: `true`" }, "max-parallel": { - "type": "number", + "type": "max-parallel", "description": "The maximum number of jobs that can run simultaneously when using a matrix job strategy. By default, GitHub will maximize the number of jobs run in parallel depending on runner availability." }, "matrix": "matrix" } } }, + "fail-fast": { + "context": [ + "forge", + "github", + "inputs", + "vars", + "needs", + "strategy", + "matrix", + "secrets", + "steps", + "job", + "runner", + "env", + "hashFiles(1,255)" + ], + "one-of": ["boolean", "string"] + }, + "max-parallel": { + "context": [ + "forge", + "github", + "inputs", + "vars", + "needs", + "strategy", + "matrix", + "secrets", + "steps", + "job", + "runner", + "env", + "hashFiles(1,255)" + ], + "one-of": ["number", "string"] + }, "matrix": { "description": "Use `matrix` to define a matrix of different job configurations. Within your matrix, define one or more variables followed by an array of values.", "mapping": { @@ -1895,7 +1931,7 @@ "env", "hashFiles(1,255)" ], - "number": {}, + "one-of": ["number", "string"], "description": "The maximum number of minutes to run the step before killing the process." }, "step-with": { @@ -2033,6 +2069,10 @@ "context": ["forge", "github", "inputs", "vars", "needs", "strategy", "matrix"], "string": {} }, + "job-timeout-minutes": { + "context": ["forge", "github", "inputs", "vars", "needs", "strategy", "matrix"], + "one-of": ["number", "string"] + }, "boolean-steps-context": { "context": [ "forge",