diff --git a/actions-languageservice/src/context-providers/needs.test.ts b/actions-languageservice/src/context-providers/needs.test.ts index 6058798..729646c 100644 --- a/actions-languageservice/src/context-providers/needs.test.ts +++ b/actions-languageservice/src/context-providers/needs.test.ts @@ -72,4 +72,57 @@ jobs: const context = getNeedsContext(workflowContext); expect(context.pairs().map(x => x.key)).toEqual(["test"]); }); + + describe("outputs", () => { + it("regular job with outputs", async () => { + const workflowContext = await testGetWorkflowContext(` +on: push +jobs: + a: + outputs: + build_id: my-build-id + runs-on: ubuntu-latest + steps: + - run: echo + b: + uses: ./.github/workflows/some-reusable-wor|kflow.yml + needs: [a] +`); + + const context = getNeedsContext(workflowContext); + + const needs = context.get("a") as DescriptionDictionary; + expect(needs).toBeDefined(); + + const outputs = needs.get("outputs") as DescriptionDictionary; + expect(outputs).toBeDefined(); + + expect(outputs.pairs().map(x => x.key)).toEqual(["build_id"]); + }); + + it("reusable job with outputs", async () => { + const workflowContext = await testGetWorkflowContext(` +on: push +jobs: + a: + uses: ./reusable-workflow-with-outputs.yaml + + b: + needs: [a] + runs-on: ubuntu-latest + steps: + - run: ec|ho +`); + + const context = getNeedsContext(workflowContext); + + const needs = context.get("a") as DescriptionDictionary; + expect(needs).toBeDefined(); + + const outputs = needs.get("outputs") as DescriptionDictionary; + expect(outputs).toBeDefined(); + + expect(outputs.pairs().map(x => x.key)).toEqual(["build_id"]); + }); + }); }); diff --git a/actions-languageservice/src/context-providers/needs.ts b/actions-languageservice/src/context-providers/needs.ts index 23d9aa8..3196e9f 100644 --- a/actions-languageservice/src/context-providers/needs.ts +++ b/actions-languageservice/src/context-providers/needs.ts @@ -1,7 +1,6 @@ import {data, DescriptionDictionary} from "@github/actions-expressions"; import {isScalar, isString} from "@github/actions-workflow-parser"; -import {isJob} from "@github/actions-workflow-parser/model/type-guards"; -import {Job, WorkflowJob} from "@github/actions-workflow-parser/model/workflow-template"; +import {WorkflowJob} from "@github/actions-workflow-parser/model/workflow-template"; import {WorkflowContext} from "../context/workflow-context"; export function getNeedsContext(workflowContext: WorkflowContext): DescriptionDictionary { @@ -25,7 +24,7 @@ function needsJobContext(job?: WorkflowJob): DescriptionDictionary { // https://docs.github.com/en/actions/learn-github-actions/contexts#needs-context const d = new DescriptionDictionary(); - if (job && isJob(job)) { + if (job) { d.add("outputs", jobOutputs(job)); } @@ -34,7 +33,7 @@ function needsJobContext(job?: WorkflowJob): DescriptionDictionary { return d; } -function jobOutputs(job?: Job): DescriptionDictionary { +function jobOutputs(job?: WorkflowJob): DescriptionDictionary { const d = new DescriptionDictionary(); if (!job?.outputs) { return d; diff --git a/actions-languageservice/src/test-utils/test-file-provider.ts b/actions-languageservice/src/test-utils/test-file-provider.ts index 8e45679..c527755 100644 --- a/actions-languageservice/src/test-utils/test-file-provider.ts +++ b/actions-languageservice/src/test-utils/test-file-provider.ts @@ -68,6 +68,25 @@ jobs: ` }; + case "./reusable-workflow-with-outputs.yaml": + return { + name: "reusable-workflow-with-outputs.yaml", + content: ` +on: + workflow_call: + outputs: + build_id: + description: 'The resulting build ID' + value: 123 + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 +` + }; + default: throw new Error("File not found"); } diff --git a/actions-languageservice/src/test-utils/test-workflow-context.ts b/actions-languageservice/src/test-utils/test-workflow-context.ts index c5a1a7b..e671ba2 100644 --- a/actions-languageservice/src/test-utils/test-workflow-context.ts +++ b/actions-languageservice/src/test-utils/test-workflow-context.ts @@ -3,6 +3,7 @@ import {getWorkflowContext, WorkflowContext} from "../context/workflow-context"; import {nullTrace} from "../nulltrace"; import {findToken} from "../utils/find-token"; import {getPositionFromCursor} from "./cursor-position"; +import {testFileProvider} from "./test-file-provider"; export async function testGetWorkflowContext(input: string): Promise { const [textDocument, pos] = getPositionFromCursor(input); @@ -17,7 +18,9 @@ export async function testGetWorkflowContext(input: string): Promise