diff --git a/languageservice/src/validate.test.ts b/languageservice/src/validate.test.ts index cac98deb..6571b04a 100644 --- a/languageservice/src/validate.test.ts +++ b/languageservice/src/validate.test.ts @@ -11,7 +11,9 @@ beforeEach(() => { describe("validation", () => { it("valid workflow", async () => { - const result = await validate(createDocument("wf.yaml", "on: push\njobs:\n build:\n runs-on: ubuntu-latest")); + const result = await validate( + createDocument("wf.yaml", "on: push\njobs:\n build:\n runs-on: ubuntu-latest\n steps:\n - run: echo") + ); expect(result.length).toBe(0); }); @@ -144,7 +146,9 @@ jobs: jobs: build: runs-on: - - ubuntu-latest` + - ubuntu-latest + steps: + - run: echo hello` ), {valueProviderConfig: defaultValueProviders} ); @@ -174,7 +178,9 @@ jobs: - cron: '0 0 * *' jobs: build: - runs-on: ubuntu-latest` + runs-on: ubuntu-latest + steps: + - run: echo hello` ), {valueProviderConfig: defaultValueProviders} ); diff --git a/workflow-parser/src/model/convert.test.ts b/workflow-parser/src/model/convert.test.ts index 3d92f4a7..064c89c4 100644 --- a/workflow-parser/src/model/convert.test.ts +++ b/workflow-parser/src/model/convert.test.ts @@ -15,7 +15,8 @@ describe("convertWorkflowTemplate", () => { content: `on: push jobs: build: - runs-on: ubuntu-latest` + runs-on: ubuntu-latest + steps: []` }, nullTrace ); @@ -55,9 +56,11 @@ jobs: build: if: \${{ true }} runs-on: ubuntu-latest + steps: [] deploy: if: true - runs-on: ubuntu-latest` + runs-on: ubuntu-latest + steps: []` }, nullTrace ); @@ -105,7 +108,8 @@ jobs: jobs: build: needs: # comment to preserve whitespace in test - runs-on: ubuntu-latest` + runs-on: ubuntu-latest + steps: []` }, nullTrace ); @@ -150,11 +154,17 @@ jobs: job1: needs: [unknown-job, job3] runs-on: ubuntu-latest + steps: + - run: echo job1 job2: runs-on: ubuntu-latest + steps: + - run: echo job2 job3: needs: job1 - runs-on: ubuntu-latest` + runs-on: ubuntu-latest + steps: + - run: echo job3` }, nullTrace ); @@ -174,7 +184,7 @@ jobs: }, { Message: - "wf.yaml (Line: 9, Col: 12): Job 'job3' depends on job 'job1' which creates a cycle in the dependency graph." + "wf.yaml (Line: 13, Col: 12): Job 'job3' depends on job 'job1' which creates a cycle in the dependency graph." } ], events: { @@ -190,7 +200,16 @@ jobs: name: "job1", needs: ["unknown-job", "job3"], "runs-on": "ubuntu-latest", - steps: [], + steps: [ + { + id: "__run", + if: { + expr: "success()", + type: 3 + }, + run: "echo job1" + } + ], type: "job" }, { @@ -201,7 +220,16 @@ jobs: }, name: "job2", "runs-on": "ubuntu-latest", - steps: [], + steps: [ + { + id: "__run", + if: { + expr: "success()", + type: 3 + }, + run: "echo job2" + } + ], type: "job" }, { @@ -213,7 +241,16 @@ jobs: name: "job3", needs: ["job1"], "runs-on": "ubuntu-latest", - steps: [], + steps: [ + { + id: "__run", + if: { + expr: "success()", + type: 3 + }, + run: "echo job3" + } + ], type: "job" } ] @@ -316,6 +353,49 @@ jobs: }); }); + it("converts workflow with one job without steps", async () => { + const result = parseWorkflow( + { + name: "wf.yaml", + content: `on: push +jobs: + build: + runs-on: ubuntu-latest` + }, + nullTrace + ); + + const template = await convertWorkflowTemplate(result.context, result.value!, undefined, { + errorPolicy: ErrorPolicy.TryConversion + }); + + expect(serializeTemplate(template)).toEqual({ + errors: [ + { + Message: "wf.yaml (Line: 4, Col: 5): Required property is missing: steps" + } + ], + events: { + push: {} + }, + jobs: [ + { + id: "build", + if: { + expr: "success()", + type: 3 + }, + name: "build", + needs: undefined, + outputs: undefined, + "runs-on": "ubuntu-latest", + steps: [], + type: "job" + } + ] + }); + }); + // Extra coverage since workflow_call components are not all covered by x-lang parsers it("converts workflow_call on", async () => { const result = parseWorkflow( @@ -336,7 +416,8 @@ jobs: secret2: jobs: build: - runs-on: ubuntu-latest` + runs-on: ubuntu-latest + steps: []` }, nullTrace ); diff --git a/workflow-parser/src/workflow-v1.0.json b/workflow-parser/src/workflow-v1.0.json index 12a38e70..0a9a6ed3 100644 --- a/workflow-parser/src/workflow-v1.0.json +++ b/workflow-parser/src/workflow-v1.0.json @@ -1779,7 +1779,10 @@ "concurrency": "job-concurrency", "outputs": "job-outputs", "defaults": "job-defaults", - "steps": "steps", + "steps": { + "type": "steps", + "required": true + }, "snapshot": "snapshot" } } diff --git a/workflow-parser/testdata/reader/errors-job-runs-on-and-no-steps.yml b/workflow-parser/testdata/reader/errors-job-runs-on-and-no-steps.yml new file mode 100644 index 00000000..31c11ab6 --- /dev/null +++ b/workflow-parser/testdata/reader/errors-job-runs-on-and-no-steps.yml @@ -0,0 +1,14 @@ +include-source: false # Drop file/line/col from output +--- +on: push +jobs: + build: + runs-on: ubuntu-latest +--- +{ + "errors": [ + { + "Message": ".github/workflows/errors-job-runs-on-and-no-steps.yml (Line: 4, Col: 5): Required property is missing: steps" + } + ] +} diff --git a/workflow-parser/testdata/reader/errors-job-runs-on-and-uses.yml b/workflow-parser/testdata/reader/errors-job-runs-on-and-uses.yml index ecbace95..898e981e 100644 --- a/workflow-parser/testdata/reader/errors-job-runs-on-and-uses.yml +++ b/workflow-parser/testdata/reader/errors-job-runs-on-and-uses.yml @@ -5,6 +5,8 @@ jobs: build: runs-on: ubuntu-latest uses: ./.github/workflows/foo.yml + steps: + - run: echo hello --- { "errors": [