From 096e9270f87d252229464a38afb9820b070c4b3b Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Thu, 1 Dec 2022 14:46:48 -0500 Subject: [PATCH] Include job outputs in `needs` context completion --- .../src/complete.expressions.test.ts | 2 +- .../src/context-providers/needs.ts | 27 ++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/actions-languageservice/src/complete.expressions.test.ts b/actions-languageservice/src/complete.expressions.test.ts index 4c5b32d..cfd1ab4 100644 --- a/actions-languageservice/src/complete.expressions.test.ts +++ b/actions-languageservice/src/complete.expressions.test.ts @@ -192,7 +192,7 @@ jobs: expect(result.map(x => x.label)).toEqual(["outputs", "result"]); }); - it.failing("needs..outputs includes outputs", async () => { + it("needs..outputs includes outputs", async () => { const input = ` on: push jobs: diff --git a/actions-languageservice/src/context-providers/needs.ts b/actions-languageservice/src/context-providers/needs.ts index 9f5d889..ec7f5e4 100644 --- a/actions-languageservice/src/context-providers/needs.ts +++ b/actions-languageservice/src/context-providers/needs.ts @@ -1,4 +1,6 @@ import {data} from "@github/actions-expressions"; +import {isString} from "@github/actions-workflow-parser/."; +import {Job} from "@github/actions-workflow-parser/model/workflow-template"; import {WorkflowContext} from "../context/workflow-context"; export function getNeedsContext(workflowContext: WorkflowContext): data.Dictionary { @@ -7,21 +9,38 @@ export function getNeedsContext(workflowContext: WorkflowContext): data.Dictiona return d; } - for (const job of workflowContext.job.needs) { - d.add(job, defaultNeedsValues()); + for (const jobID of workflowContext.job.needs) { + const job = workflowContext.template?.jobs.find(job => job.id.value === jobID); + d.add(jobID, needsJobContext(job)); } return d; } -function defaultNeedsValues(): data.Dictionary { +function needsJobContext(job?: Job): data.Dictionary { // https://docs.github.com/en/actions/learn-github-actions/contexts#needs-context const d = new data.Dictionary(); // Once job config contains outputs, this can be populated - d.add("outputs", new data.Null()); + d.add("outputs", jobOutputs(job)); // Can be "success", "failure", "cancelled", or "skipped" d.add("result", new data.Null()); return d; } + +function jobOutputs(job?: Job): data.Dictionary { + const d = new data.Dictionary(); + if (!job?.outputs) { + return d; + } + + for (let i = 0; i < job.outputs.count; ++i) { + const output = job.outputs.get(i); + if (!isString(output.key)) { + continue; + } + d.add(output.key.value, new data.Null()); + } + return d; +}