From 681236bbca342faf9ce86b5c4105be7a040e90ae Mon Sep 17 00:00:00 2001 From: Christopher Schleiden Date: Mon, 12 Dec 2022 10:43:39 -0800 Subject: [PATCH 01/30] Correctly report errors in multi-line expression strings --- .../src/validate.expressions.test.ts | 120 +++++++++++++++++- actions-languageservice/src/validate.ts | 2 - 2 files changed, 119 insertions(+), 3 deletions(-) diff --git a/actions-languageservice/src/validate.expressions.test.ts b/actions-languageservice/src/validate.expressions.test.ts index b914ec9..9157a0b 100644 --- a/actions-languageservice/src/validate.expressions.test.ts +++ b/actions-languageservice/src/validate.expressions.test.ts @@ -306,7 +306,7 @@ jobs: }); }); - describe("multi-line strings", () => { + describe("multi-line strings warnings", () => { it("indented |", async () => { const input = `on: push jobs: @@ -428,6 +428,124 @@ jobs: }); }); + describe("multi-line strings errors", () => { + it("indented |", async () => { + const input = `on: push +jobs: + build: + runs-on: ubuntu-latest + steps: + - run: | + first line + test \${{ fromJSON2('') }} + test2`; + const result = await validate(createDocument("wf.yaml", input)); + + expect(result).toEqual([ + { + message: "Unrecognized function: 'fromJSON2'", + range: { + end: { + character: 35, + line: 7 + }, + start: { + character: 15, + line: 7 + } + } + } + ]); + }); + + it("indented |+", async () => { + const input = `on: push +jobs: + build: + runs-on: ubuntu-latest + steps: + - run: |+ + first line + test \${{ fromJSON2('') }} + test2`; + const result = await validate(createDocument("wf.yaml", input)); + + expect(result).toEqual([ + { + message: "Unrecognized function: 'fromJSON2'", + range: { + end: { + character: 35, + line: 7 + }, + start: { + character: 15, + line: 7 + } + } + } + ]); + }); + + it("indented >", async () => { + const input = `on: push +jobs: + build: + runs-on: ubuntu-latest + steps: + - run: > + first line + test \${{ fromJSON2('') }} + test2`; + const result = await validate(createDocument("wf.yaml", input)); + + expect(result).toEqual([ + { + message: "Unrecognized function: 'fromJSON2'", + range: { + end: { + character: 35, + line: 7 + }, + start: { + character: 15, + line: 7 + } + } + } + ]); + }); + + it("indented >+", async () => { + const input = `on: push +jobs: + build: + runs-on: ubuntu-latest + steps: + - run: >+ + first line + test \${{ fromJSON2('') }} + test2`; + const result = await validate(createDocument("wf.yaml", input)); + + expect(result).toEqual([ + { + message: "Unrecognized function: 'fromJSON2'", + range: { + end: { + character: 35, + line: 7 + }, + start: { + character: 15, + line: 7 + } + } + } + ]); + }); + }); + describe("matrix context", () => { it("reference within a matrix job", async () => { const input = ` diff --git a/actions-languageservice/src/validate.ts b/actions-languageservice/src/validate.ts index 8d2938e..d913a26 100644 --- a/actions-languageservice/src/validate.ts +++ b/actions-languageservice/src/validate.ts @@ -209,8 +209,6 @@ async function validateExpression( severity: DiagnosticSeverity.Warning, range: mapRange(expression.range) }); - } else { - throw e; } } } From f059497eb18c8e3eafd0e65b67ed408e4577c285 Mon Sep 17 00:00:00 2001 From: Christopher Schleiden Date: Mon, 12 Dec 2022 12:55:04 -0800 Subject: [PATCH 02/30] Consume parser --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5106819..ccc4223 100644 --- a/package-lock.json +++ b/package-lock.json @@ -698,9 +698,9 @@ "link": true }, "node_modules/@github/actions-workflow-parser": { - "version": "0.0.31", - "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.31/ebc46956b91ed1a8c45efd41a3256ae818722557", - "integrity": "sha512-3k+MBWG7Gn86aHeLdJTiYUTGm53npEelzleCbq/8Ir51xVkRINsyNe4HuGJizXxZ2WoTxAkLeZ6qpO1oCucSIg==", + "version": "0.0.33", + "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.33/9f4c42ae90a9b010676fec9d9f39b4ea555753b4", + "integrity": "sha512-5yzSAMKCdxy4awZMRNHOIo52E/xx3RtSjHX5I70/Gx9NlnoCQBSLEdd64dY3/fguLLQxksnhiUy/mmUWTqJyLg==", "license": "MIT", "dependencies": { "@github/actions-expressions": "*", @@ -13533,9 +13533,9 @@ } }, "@github/actions-workflow-parser": { - "version": "0.0.31", - "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.31/ebc46956b91ed1a8c45efd41a3256ae818722557", - "integrity": "sha512-3k+MBWG7Gn86aHeLdJTiYUTGm53npEelzleCbq/8Ir51xVkRINsyNe4HuGJizXxZ2WoTxAkLeZ6qpO1oCucSIg==", + "version": "0.0.33", + "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.33/9f4c42ae90a9b010676fec9d9f39b4ea555753b4", + "integrity": "sha512-5yzSAMKCdxy4awZMRNHOIo52E/xx3RtSjHX5I70/Gx9NlnoCQBSLEdd64dY3/fguLLQxksnhiUy/mmUWTqJyLg==", "requires": { "@github/actions-expressions": "*", "yaml": "^2.0.0-8" From 7f7c632939c50a5916437e8c0f36ae9a3fd9202a Mon Sep 17 00:00:00 2001 From: Christopher Schleiden Date: Mon, 12 Dec 2022 14:45:02 -0800 Subject: [PATCH 03/30] Update parser --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index ccc4223..bccbc21 100644 --- a/package-lock.json +++ b/package-lock.json @@ -698,9 +698,9 @@ "link": true }, "node_modules/@github/actions-workflow-parser": { - "version": "0.0.33", - "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.33/9f4c42ae90a9b010676fec9d9f39b4ea555753b4", - "integrity": "sha512-5yzSAMKCdxy4awZMRNHOIo52E/xx3RtSjHX5I70/Gx9NlnoCQBSLEdd64dY3/fguLLQxksnhiUy/mmUWTqJyLg==", + "version": "0.0.34", + "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.34/e369bdaca17cde594ad7420cd0df0efcd2804dc0", + "integrity": "sha512-ttjYUoO2bvi5v/SR267QpDhWJ+I4tXQlSMnscjqUp76IDLxS73I7nCD3KP7g4VxzHmT5j8AxSdjEE25UWpl43g==", "license": "MIT", "dependencies": { "@github/actions-expressions": "*", @@ -13533,9 +13533,9 @@ } }, "@github/actions-workflow-parser": { - "version": "0.0.33", - "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.33/9f4c42ae90a9b010676fec9d9f39b4ea555753b4", - "integrity": "sha512-5yzSAMKCdxy4awZMRNHOIo52E/xx3RtSjHX5I70/Gx9NlnoCQBSLEdd64dY3/fguLLQxksnhiUy/mmUWTqJyLg==", + "version": "0.0.34", + "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.34/e369bdaca17cde594ad7420cd0df0efcd2804dc0", + "integrity": "sha512-ttjYUoO2bvi5v/SR267QpDhWJ+I4tXQlSMnscjqUp76IDLxS73I7nCD3KP7g4VxzHmT5j8AxSdjEE25UWpl43g==", "requires": { "@github/actions-expressions": "*", "yaml": "^2.0.0-8" From b43b55fc033f52d2299f043f95ae1b5dc2dbee3d Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 12 Dec 2022 23:02:02 +0000 Subject: [PATCH 04/30] v0.1.49 --- actions-languageserver/package.json | 4 ++-- actions-languageservice/package.json | 2 +- browser-playground/package.json | 4 ++-- lerna.json | 2 +- package-lock.json | 14 +++++++------- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/actions-languageserver/package.json b/actions-languageserver/package.json index 70178cc..93b14b3 100644 --- a/actions-languageserver/package.json +++ b/actions-languageserver/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageserver", - "version": "0.1.48", + "version": "0.1.49", "description": "Language server for GitHub Actions", "license": "MIT", "type": "module", @@ -38,7 +38,7 @@ "prettier-fix": "prettier --write ." }, "dependencies": { - "@github/actions-languageservice": "^0.1.48", + "@github/actions-languageservice": "^0.1.49", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", "vscode-languageserver-textdocument": "^1.0.7" diff --git a/actions-languageservice/package.json b/actions-languageservice/package.json index 1d67ac5..7d3ae7b 100644 --- a/actions-languageservice/package.json +++ b/actions-languageservice/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageservice", - "version": "0.1.48", + "version": "0.1.49", "description": "Language service for GitHub Actions", "license": "MIT", "type": "module", diff --git a/browser-playground/package.json b/browser-playground/package.json index 175a156..55deb75 100644 --- a/browser-playground/package.json +++ b/browser-playground/package.json @@ -1,12 +1,12 @@ { "name": "browser-playground", - "version": "0.1.48", + "version": "0.1.49", "description": "", "private": true, "main": "index.js", "type": "module", "dependencies": { - "@github/actions-languageserver": "^0.1.48", + "@github/actions-languageserver": "^0.1.49", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", diff --git a/lerna.json b/lerna.json index 316b5a0..217279f 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useWorkspaces": true, - "version": "0.1.48" + "version": "0.1.49" } diff --git a/package-lock.json b/package-lock.json index bccbc21..09e052b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,10 +16,10 @@ }, "actions-languageserver": { "name": "@github/actions-languageserver", - "version": "0.1.48", + "version": "0.1.49", "license": "MIT", "dependencies": { - "@github/actions-languageservice": "^0.1.48", + "@github/actions-languageservice": "^0.1.49", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", "vscode-languageserver-textdocument": "^1.0.7" @@ -38,7 +38,7 @@ }, "actions-languageservice": { "name": "@github/actions-languageservice", - "version": "0.1.48", + "version": "0.1.49", "license": "MIT", "dependencies": { "@github/actions-workflow-parser": "*", @@ -59,10 +59,10 @@ } }, "browser-playground": { - "version": "0.1.48", + "version": "0.1.49", "license": "MIT", "dependencies": { - "@github/actions-languageserver": "^0.1.48", + "@github/actions-languageserver": "^0.1.49", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", @@ -13505,7 +13505,7 @@ "@github/actions-languageserver": { "version": "file:actions-languageserver", "requires": { - "@github/actions-languageservice": "^0.1.48", + "@github/actions-languageservice": "^0.1.49", "@octokit/rest": "^19.0.5", "@types/jest": "^29.0.3", "jest": "^29.0.3", @@ -16288,7 +16288,7 @@ "browser-playground": { "version": "file:browser-playground", "requires": { - "@github/actions-languageserver": "^0.1.48", + "@github/actions-languageserver": "^0.1.49", "css-loader": "^6.7.2", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", From d5ef6aefffd3e0d6e13f88c342e60641b0309347 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Mon, 12 Dec 2022 18:31:34 -0500 Subject: [PATCH 05/30] Add a value provider for action inputs --- actions-languageserver/package.json | 6 +- .../src/utils/action-reference.test.ts | 101 +++++++++++++++++ .../src/utils/action-reference.ts | 41 +++++++ actions-languageserver/src/value-providers.ts | 5 + .../src/value-providers/action-inputs.ts | 102 ++++++++++++++++++ package-lock.json | 10 +- 6 files changed, 260 insertions(+), 5 deletions(-) create mode 100644 actions-languageserver/src/utils/action-reference.test.ts create mode 100644 actions-languageserver/src/utils/action-reference.ts create mode 100644 actions-languageserver/src/value-providers/action-inputs.ts diff --git a/actions-languageserver/package.json b/actions-languageserver/package.json index 93b14b3..f9635a8 100644 --- a/actions-languageserver/package.json +++ b/actions-languageserver/package.json @@ -39,9 +39,11 @@ }, "dependencies": { "@github/actions-languageservice": "^0.1.49", + "@github/actions-workflow-parser": "^0.0.33", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", - "vscode-languageserver-textdocument": "^1.0.7" + "vscode-languageserver-textdocument": "^1.0.7", + "yaml": "^2.1.3" }, "engines": { "node": ">= 16" @@ -57,4 +59,4 @@ "ts-jest": "^29.0.3", "typescript": "^4.8.4" } -} +} \ No newline at end of file diff --git a/actions-languageserver/src/utils/action-reference.test.ts b/actions-languageserver/src/utils/action-reference.test.ts new file mode 100644 index 0000000..eff9ef7 --- /dev/null +++ b/actions-languageserver/src/utils/action-reference.test.ts @@ -0,0 +1,101 @@ +import {actionIdentifier, parseActionReference as parse} from "./action-reference"; + +describe("parseActionReference", () => { + it("basic action", () => { + expect(parse("actions/checkout@v2")).toEqual({ + owner: "actions", + name: "checkout", + ref: "v2" + }); + }); + + it("action with reference to branch", () => { + expect(parse("actions/checkout@main")).toEqual({ + owner: "actions", + name: "checkout", + ref: "main" + }); + }); + + it("action with reference to branch with slashes", () => { + expect(parse("actions/checkout@features/a")).toEqual({ + owner: "actions", + name: "checkout", + ref: "features/a" + }); + }); + + it("action with reference to commit sha", () => { + expect(parse("actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b")).toEqual({ + owner: "actions", + name: "checkout", + ref: "755da8c3cf115ac066823e79a1e1788f8940201b" + }); + }); + + it("valid action with path", () => { + expect(parse("actions/checkout/path/to/action@v2")).toEqual({ + owner: "actions", + name: "checkout", + ref: "v2", + path: "path/to/action" + }); + }); + + it("valid action with path and trailing slash", () => { + expect(parse("actions/checkout/path/to/action/@v2")).toEqual({ + owner: "actions", + name: "checkout", + ref: "v2", + path: "path/to/action" + }); + }); + + it("local action", () => { + expect(parse("./")).toBeUndefined(); + }); + + it("local action with path", () => { + expect(parse("./directory/")).toBeUndefined(); + }); + + it("Docker Hub action", () => { + expect(parse("docker://alpine:3.8")).toBeUndefined(); + }); + + it("GitHub Packages Container action", () => { + expect(parse("docker://ghcr.io/OWNER/IMAGE_NAME")).toBeUndefined(); + }); + + it("action with backslashes", () => { + expect(parse("actions\\checkout\\path\\to\\action@v2")).toEqual({ + owner: "actions", + name: "checkout", + ref: "v2", + path: "path/to/action" + }); + }); +}); + +describe("actionIdentifier", () => { + it("basic action", () => { + expect( + actionIdentifier({ + owner: "actions", + name: "checkout", + ref: "v2" + }) + ).toEqual("actions/checkout/v2"); + }); + + it("action with path", () => { + expect( + actionIdentifier({ + owner: "actions", + name: "checkout", + ref: "v2", + path: "path/to/action" + }) + ).toEqual("actions/checkout/v2/path/to/action"); + }); +}); diff --git a/actions-languageserver/src/utils/action-reference.ts b/actions-languageserver/src/utils/action-reference.ts new file mode 100644 index 0000000..408984b --- /dev/null +++ b/actions-languageserver/src/utils/action-reference.ts @@ -0,0 +1,41 @@ +export type ActionReference = { + owner: string; + name: string; + ref: string; + path?: string; +}; + +// https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsuses +export function parseActionReference(uses: string): ActionReference | undefined { + if (!uses || uses.startsWith("docker://") || uses.startsWith("./") || uses.startsWith(".\\")) { + return undefined; + } + + const [action, ref] = uses.split("@"); + const [owner, name, ...pathSegments] = action.split(/[\\/]/).filter(s => s.length > 0); + if (!owner || !name) { + return undefined; + } + + if (pathSegments.length === 0) { + return { + owner, + name, + ref + }; + } + + return { + owner, + name, + ref, + path: pathSegments.join("/") + }; +} + +export function actionIdentifier(ref: ActionReference): string { + if (ref.path) { + return `${ref.owner}/${ref.name}/${ref.ref}/${ref.path}`; + } + return `${ref.owner}/${ref.name}/${ref.ref}`; +} diff --git a/actions-languageserver/src/value-providers.ts b/actions-languageserver/src/value-providers.ts index ff706a5..3ac95d5 100644 --- a/actions-languageserver/src/value-providers.ts +++ b/actions-languageserver/src/value-providers.ts @@ -4,6 +4,7 @@ import {ValueProviderKind} from "@github/actions-languageservice/value-providers import {Octokit} from "@octokit/rest"; import {RepositoryContext} from "./initializationOptions"; import {TTLCache} from "./utils/cache"; +import {getActionInputs} from "./value-providers/action-inputs"; import {getEnvironments} from "./value-providers/job-environment"; import {getRunnerLabels} from "./value-providers/runs-on"; @@ -32,6 +33,10 @@ export function valueProviders( "runs-on": { kind: ValueProviderKind.SuggestedValues, get: (_: WorkflowContext) => getRunnerLabels(octokit, cache, repo.owner, repo.name) + }, + "step-with": { + kind: ValueProviderKind.AllowedValues, + get: (context: WorkflowContext) => getActionInputs(octokit, cache, context) } }; } diff --git a/actions-languageserver/src/value-providers/action-inputs.ts b/actions-languageserver/src/value-providers/action-inputs.ts new file mode 100644 index 0000000..4d0af91 --- /dev/null +++ b/actions-languageserver/src/value-providers/action-inputs.ts @@ -0,0 +1,102 @@ +import {WorkflowContext} from "@github/actions-languageservice/context/workflow-context"; +import {Value} from "@github/actions-languageservice/value-providers/config"; +import {isActionStep} from "@github/actions-workflow-parser/model/type-guards"; +import {Octokit, RestEndpointMethodTypes} from "@octokit/rest"; +import {parse} from "yaml"; +import {actionIdentifier, ActionReference, parseActionReference} from "../utils/action-reference"; +import {TTLCache} from "../utils/cache"; + +export async function getActionInputs(client: Octokit, cache: TTLCache, context: WorkflowContext): Promise { + if (!context.step || !isActionStep(context.step)) { + return []; + } + + const action = parseActionReference(context.step.uses.value); + if (!action) { + return []; + } + + const inputs = await cache.get(`${actionIdentifier(action)}/action-inputs`, undefined, () => + fetchActionInputs(client, action) + ); + + return inputs; +} + +async function fetchActionInputs(client: Octokit, action: ActionReference): Promise { + const metadata = await getActionMetadata(client, action); + if (!metadata) { + return []; + } + + return parseActionMetadata(metadata); +} + +async function getActionMetadata(client: Octokit, action: ActionReference): Promise { + let resp: RestEndpointMethodTypes["repos"]["getContent"]["response"]; + try { + resp = await client.repos.getContent({ + owner: action.owner, + repo: action.name, + ref: action.ref, + path: action.path ? `${action.path}/action.yml` : "action.yml" + }); + } catch (e: any) { + // If action.yml doesn't exist, try action.yaml + if (e.status === 404) { + resp = await client.repos.getContent({ + owner: action.owner, + repo: action.name, + ref: action.ref, + path: action.path ? `${action.path}/action.yaml` : "action.yaml" + }); + } else { + throw e; + } + } + + // https://docs.github.com/en/rest/repos/contents?apiVersion=2022-11-28 + // Ignore directories (array of files) and non-file content + if (resp.data === undefined || Array.isArray(resp.data) || resp.data.type !== "file") { + return undefined; + } + + if (resp.data.content === undefined) { + return undefined; + } + + const text = Buffer.from(resp.data.content, "base64").toString("utf8"); + // Remove any null bytes + return text.replace(/\0/g, ""); +} + +type ActionMetadata = { + inputs?: Record; +}; + +// https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#inputs +type ActionInput = { + description: string; + required?: boolean; + default?: string; + deprecationMessage?: string; +}; + +// https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions +async function parseActionMetadata(content: string): Promise { + const inputs = new Array(); + + const metadata: ActionMetadata = parse(content); + if (metadata.inputs === undefined) { + return inputs; + } + + for (const [name, input] of Object.entries(metadata.inputs)) { + inputs.push({ + label: name, + description: input.description + }); + } + + return inputs; +} diff --git a/package-lock.json b/package-lock.json index 09e052b..42b3ff8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,9 +20,11 @@ "license": "MIT", "dependencies": { "@github/actions-languageservice": "^0.1.49", + "@github/actions-workflow-parser": "^0.0.33", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", - "vscode-languageserver-textdocument": "^1.0.7" + "vscode-languageserver-textdocument": "^1.0.7", + "yaml": "^2.1.3" }, "devDependencies": { "@types/jest": "^29.0.3", @@ -13506,6 +13508,7 @@ "version": "file:actions-languageserver", "requires": { "@github/actions-languageservice": "^0.1.49", + "@github/actions-workflow-parser": "0.0.33", "@octokit/rest": "^19.0.5", "@types/jest": "^29.0.3", "jest": "^29.0.3", @@ -13514,7 +13517,8 @@ "ts-jest": "^29.0.3", "typescript": "^4.8.4", "vscode-languageserver": "^8.0.2", - "vscode-languageserver-textdocument": "^1.0.7" + "vscode-languageserver-textdocument": "^1.0.7", + "yaml": "^2.1.3" } }, "@github/actions-languageservice": { @@ -23078,4 +23082,4 @@ "dev": true } } -} +} \ No newline at end of file From 037cf7eb3f37fc124721c16ea539324c79a06941 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Mon, 12 Dec 2022 19:03:35 -0500 Subject: [PATCH 06/30] Update package-lock --- package-lock.json | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 42b3ff8..980be28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,6 +38,19 @@ "node": ">= 16" } }, + "actions-languageserver/node_modules/@github/actions-workflow-parser": { + "version": "0.0.33", + "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.33/9f4c42ae90a9b010676fec9d9f39b4ea555753b4", + "integrity": "sha512-5yzSAMKCdxy4awZMRNHOIo52E/xx3RtSjHX5I70/Gx9NlnoCQBSLEdd64dY3/fguLLQxksnhiUy/mmUWTqJyLg==", + "license": "MIT", + "dependencies": { + "@github/actions-expressions": "*", + "yaml": "^2.0.0-8" + }, + "engines": { + "node": ">= 16" + } + }, "actions-languageservice": { "name": "@github/actions-languageservice", "version": "0.1.49", @@ -13508,7 +13521,7 @@ "version": "file:actions-languageserver", "requires": { "@github/actions-languageservice": "^0.1.49", - "@github/actions-workflow-parser": "0.0.33", + "@github/actions-workflow-parser": "^0.0.33", "@octokit/rest": "^19.0.5", "@types/jest": "^29.0.3", "jest": "^29.0.3", @@ -13519,6 +13532,17 @@ "vscode-languageserver": "^8.0.2", "vscode-languageserver-textdocument": "^1.0.7", "yaml": "^2.1.3" + }, + "dependencies": { + "@github/actions-workflow-parser": { + "version": "0.0.33", + "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.33/9f4c42ae90a9b010676fec9d9f39b4ea555753b4", + "integrity": "sha512-5yzSAMKCdxy4awZMRNHOIo52E/xx3RtSjHX5I70/Gx9NlnoCQBSLEdd64dY3/fguLLQxksnhiUy/mmUWTqJyLg==", + "requires": { + "@github/actions-expressions": "*", + "yaml": "^2.0.0-8" + } + } } }, "@github/actions-languageservice": { @@ -23082,4 +23106,4 @@ "dev": true } } -} \ No newline at end of file +} From db22088ab2ebc98b7d895ca1b9ec4ba9ebd9d9c9 Mon Sep 17 00:00:00 2001 From: Beth Brennan Date: Mon, 12 Dec 2022 19:06:08 -0500 Subject: [PATCH 07/30] Add basic github context provider --- .../src/complete.expressions.test.ts | 19 +++++++- .../src/context-providers/default.ts | 22 +++++---- .../src/context-providers/github.ts | 47 +++++++++++++++++++ 3 files changed, 78 insertions(+), 10 deletions(-) create mode 100644 actions-languageservice/src/context-providers/github.ts diff --git a/actions-languageservice/src/complete.expressions.test.ts b/actions-languageservice/src/complete.expressions.test.ts index a32c9dd..6af1866 100644 --- a/actions-languageservice/src/complete.expressions.test.ts +++ b/actions-languageservice/src/complete.expressions.test.ts @@ -36,7 +36,7 @@ describe("expressions", () => { describe("top-level auto-complete", () => { it("single region", async () => { const input = "run-name: ${{ | }}"; - const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + const result = await complete(...getPositionFromCursor(input), undefined, undefined); expect(result.map(x => x.label)).toEqual([ "github", @@ -320,6 +320,23 @@ jobs: expect(result).toEqual([]); }); + it("github context includes expected keys", async () => { + const input = ` +on: push + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: echo \${{ github.| }} + `; + + const result = await complete(...getPositionFromCursor(input), undefined, undefined); + + expect(result.map(x => x.label)).toContain("actor"); + }); + describe("steps context", () => { it("includes defined step IDs", async () => { const input = ` diff --git a/actions-languageservice/src/context-providers/default.ts b/actions-languageservice/src/context-providers/default.ts index ba83a74..5893c49 100644 --- a/actions-languageservice/src/context-providers/default.ts +++ b/actions-languageservice/src/context-providers/default.ts @@ -2,6 +2,7 @@ import {data} from "@github/actions-expressions"; import {Kind} from "@github/actions-expressions/data/expressiondata"; import {WorkflowContext} from "../context/workflow-context"; import {ContextProviderConfig} from "./config"; +import {getGithubContext} from "./github"; import {getInputsContext} from "./inputs"; import {getMatrixContext} from "./matrix"; import {getNeedsContext} from "./needs"; @@ -44,6 +45,18 @@ export async function getContext( function getDefaultContext(name: string, workflowContext: WorkflowContext, mode: Mode): ContextValue | undefined { switch (name) { + case "github": + return getGithubContext(); + + case "inputs": + return getInputsContext(workflowContext); + + case "matrix": + return getMatrixContext(workflowContext, mode); + + case "needs": + return getNeedsContext(workflowContext); + case "runner": return objectToDictionary({ os: "Linux", @@ -53,12 +66,6 @@ function getDefaultContext(name: string, workflowContext: WorkflowContext, mode: temp: "/home/runner/work/_temp" }); - case "needs": - return getNeedsContext(workflowContext); - - case "inputs": - return getInputsContext(workflowContext); - case "secrets": return objectToDictionary({GITHUB_TOKEN: "***"}); @@ -67,9 +74,6 @@ function getDefaultContext(name: string, workflowContext: WorkflowContext, mode: case "strategy": return getStrategyContext(workflowContext); - - case "matrix": - return getMatrixContext(workflowContext, mode); } return undefined; diff --git a/actions-languageservice/src/context-providers/github.ts b/actions-languageservice/src/context-providers/github.ts new file mode 100644 index 0000000..0422bb9 --- /dev/null +++ b/actions-languageservice/src/context-providers/github.ts @@ -0,0 +1,47 @@ +import {data} from "@github/actions-expressions"; + +export function getGithubContext(): data.Dictionary { + // https://docs.github.com/en/actions/learn-github-actions/contexts#github-context + const keys = [ + "action", + "action_path", + "action_ref", + "action_repository", + "action_status", + "actor", + "api_url", + "base_ref", + "env", + "event", + "event_name", + "event_path", + "graphql_url", + "head_ref", + "job", + "ref", + "ref_name", + "ref_protected", + "ref_type", + "path", + "repository", + "repository_owner", + "repositoryUrl", + "retention_days", + "run_id", + "run_number", + "run_attempt", + "secret_source", + "server_url", + "sha", + "token", + "triggering_actor", + "workflow", + "workspace" + ]; + + return new data.Dictionary( + ...keys.map(key => { + return {key, value: new data.Null()}; + }) + ); +} From d392681394f195aac2c6e62f9dfd6018345b4801 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Mon, 12 Dec 2022 19:23:33 -0500 Subject: [PATCH 08/30] Use `*` for parser package version --- actions-languageserver/package.json | 2 +- package-lock.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/actions-languageserver/package.json b/actions-languageserver/package.json index f9635a8..b2177a1 100644 --- a/actions-languageserver/package.json +++ b/actions-languageserver/package.json @@ -39,7 +39,7 @@ }, "dependencies": { "@github/actions-languageservice": "^0.1.49", - "@github/actions-workflow-parser": "^0.0.33", + "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", "vscode-languageserver-textdocument": "^1.0.7", diff --git a/package-lock.json b/package-lock.json index 980be28..20f92bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "license": "MIT", "dependencies": { "@github/actions-languageservice": "^0.1.49", - "@github/actions-workflow-parser": "^0.0.33", + "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", "vscode-languageserver-textdocument": "^1.0.7", @@ -13521,7 +13521,7 @@ "version": "file:actions-languageserver", "requires": { "@github/actions-languageservice": "^0.1.49", - "@github/actions-workflow-parser": "^0.0.33", + "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "@types/jest": "^29.0.3", "jest": "^29.0.3", From 4ee3a88c117b9392ae6a6da3711611d39e3d5c01 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Mon, 12 Dec 2022 19:35:19 -0500 Subject: [PATCH 09/30] Remove separate parser version --- package-lock.json | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index 20f92bc..7392788 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,19 +38,6 @@ "node": ">= 16" } }, - "actions-languageserver/node_modules/@github/actions-workflow-parser": { - "version": "0.0.33", - "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.33/9f4c42ae90a9b010676fec9d9f39b4ea555753b4", - "integrity": "sha512-5yzSAMKCdxy4awZMRNHOIo52E/xx3RtSjHX5I70/Gx9NlnoCQBSLEdd64dY3/fguLLQxksnhiUy/mmUWTqJyLg==", - "license": "MIT", - "dependencies": { - "@github/actions-expressions": "*", - "yaml": "^2.0.0-8" - }, - "engines": { - "node": ">= 16" - } - }, "actions-languageservice": { "name": "@github/actions-languageservice", "version": "0.1.49", @@ -13532,17 +13519,6 @@ "vscode-languageserver": "^8.0.2", "vscode-languageserver-textdocument": "^1.0.7", "yaml": "^2.1.3" - }, - "dependencies": { - "@github/actions-workflow-parser": { - "version": "0.0.33", - "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.33/9f4c42ae90a9b010676fec9d9f39b4ea555753b4", - "integrity": "sha512-5yzSAMKCdxy4awZMRNHOIo52E/xx3RtSjHX5I70/Gx9NlnoCQBSLEdd64dY3/fguLLQxksnhiUy/mmUWTqJyLg==", - "requires": { - "@github/actions-expressions": "*", - "yaml": "^2.0.0-8" - } - } } }, "@github/actions-languageservice": { From d33bf583efaf011f177e6289d7006358a30da8d0 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 13 Dec 2022 00:37:12 +0000 Subject: [PATCH 10/30] v0.1.50 --- actions-languageserver/package.json | 4 ++-- actions-languageservice/package.json | 2 +- browser-playground/package.json | 4 ++-- lerna.json | 2 +- package-lock.json | 14 +++++++------- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/actions-languageserver/package.json b/actions-languageserver/package.json index 93b14b3..0f5dee8 100644 --- a/actions-languageserver/package.json +++ b/actions-languageserver/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageserver", - "version": "0.1.49", + "version": "0.1.50", "description": "Language server for GitHub Actions", "license": "MIT", "type": "module", @@ -38,7 +38,7 @@ "prettier-fix": "prettier --write ." }, "dependencies": { - "@github/actions-languageservice": "^0.1.49", + "@github/actions-languageservice": "^0.1.50", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", "vscode-languageserver-textdocument": "^1.0.7" diff --git a/actions-languageservice/package.json b/actions-languageservice/package.json index 7d3ae7b..60a5ea5 100644 --- a/actions-languageservice/package.json +++ b/actions-languageservice/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageservice", - "version": "0.1.49", + "version": "0.1.50", "description": "Language service for GitHub Actions", "license": "MIT", "type": "module", diff --git a/browser-playground/package.json b/browser-playground/package.json index 55deb75..b619fa2 100644 --- a/browser-playground/package.json +++ b/browser-playground/package.json @@ -1,12 +1,12 @@ { "name": "browser-playground", - "version": "0.1.49", + "version": "0.1.50", "description": "", "private": true, "main": "index.js", "type": "module", "dependencies": { - "@github/actions-languageserver": "^0.1.49", + "@github/actions-languageserver": "^0.1.50", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", diff --git a/lerna.json b/lerna.json index 217279f..7771b9c 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useWorkspaces": true, - "version": "0.1.49" + "version": "0.1.50" } diff --git a/package-lock.json b/package-lock.json index 09e052b..82f7539 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,10 +16,10 @@ }, "actions-languageserver": { "name": "@github/actions-languageserver", - "version": "0.1.49", + "version": "0.1.50", "license": "MIT", "dependencies": { - "@github/actions-languageservice": "^0.1.49", + "@github/actions-languageservice": "^0.1.50", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", "vscode-languageserver-textdocument": "^1.0.7" @@ -38,7 +38,7 @@ }, "actions-languageservice": { "name": "@github/actions-languageservice", - "version": "0.1.49", + "version": "0.1.50", "license": "MIT", "dependencies": { "@github/actions-workflow-parser": "*", @@ -59,10 +59,10 @@ } }, "browser-playground": { - "version": "0.1.49", + "version": "0.1.50", "license": "MIT", "dependencies": { - "@github/actions-languageserver": "^0.1.49", + "@github/actions-languageserver": "^0.1.50", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", @@ -13505,7 +13505,7 @@ "@github/actions-languageserver": { "version": "file:actions-languageserver", "requires": { - "@github/actions-languageservice": "^0.1.49", + "@github/actions-languageservice": "^0.1.50", "@octokit/rest": "^19.0.5", "@types/jest": "^29.0.3", "jest": "^29.0.3", @@ -16288,7 +16288,7 @@ "browser-playground": { "version": "file:browser-playground", "requires": { - "@github/actions-languageserver": "^0.1.49", + "@github/actions-languageserver": "^0.1.50", "css-loader": "^6.7.2", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", From 3ac171716e4838cfddfdfdb925ee908a24f7ed30 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 13 Dec 2022 00:46:44 +0000 Subject: [PATCH 11/30] v0.1.51 --- actions-languageserver/package.json | 6 +++--- actions-languageservice/package.json | 2 +- browser-playground/package.json | 4 ++-- lerna.json | 2 +- package-lock.json | 16 ++++++++-------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/actions-languageserver/package.json b/actions-languageserver/package.json index f9a726c..1248a90 100644 --- a/actions-languageserver/package.json +++ b/actions-languageserver/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageserver", - "version": "0.1.50", + "version": "0.1.51", "description": "Language server for GitHub Actions", "license": "MIT", "type": "module", @@ -38,7 +38,7 @@ "prettier-fix": "prettier --write ." }, "dependencies": { - "@github/actions-languageservice": "^0.1.50", + "@github/actions-languageservice": "^0.1.51", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", @@ -59,4 +59,4 @@ "ts-jest": "^29.0.3", "typescript": "^4.8.4" } -} \ No newline at end of file +} diff --git a/actions-languageservice/package.json b/actions-languageservice/package.json index 60a5ea5..d253d42 100644 --- a/actions-languageservice/package.json +++ b/actions-languageservice/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageservice", - "version": "0.1.50", + "version": "0.1.51", "description": "Language service for GitHub Actions", "license": "MIT", "type": "module", diff --git a/browser-playground/package.json b/browser-playground/package.json index b619fa2..0011685 100644 --- a/browser-playground/package.json +++ b/browser-playground/package.json @@ -1,12 +1,12 @@ { "name": "browser-playground", - "version": "0.1.50", + "version": "0.1.51", "description": "", "private": true, "main": "index.js", "type": "module", "dependencies": { - "@github/actions-languageserver": "^0.1.50", + "@github/actions-languageserver": "^0.1.51", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", diff --git a/lerna.json b/lerna.json index 7771b9c..88d1460 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useWorkspaces": true, - "version": "0.1.50" + "version": "0.1.51" } diff --git a/package-lock.json b/package-lock.json index 46f3f7e..3454b07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,10 +16,10 @@ }, "actions-languageserver": { "name": "@github/actions-languageserver", - "version": "0.1.50", + "version": "0.1.51", "license": "MIT", "dependencies": { - "@github/actions-languageservice": "^0.1.50", + "@github/actions-languageservice": "^0.1.51", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", @@ -40,7 +40,7 @@ }, "actions-languageservice": { "name": "@github/actions-languageservice", - "version": "0.1.50", + "version": "0.1.51", "license": "MIT", "dependencies": { "@github/actions-workflow-parser": "*", @@ -61,10 +61,10 @@ } }, "browser-playground": { - "version": "0.1.50", + "version": "0.1.51", "license": "MIT", "dependencies": { - "@github/actions-languageserver": "^0.1.50", + "@github/actions-languageserver": "^0.1.51", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", @@ -13507,7 +13507,7 @@ "@github/actions-languageserver": { "version": "file:actions-languageserver", "requires": { - "@github/actions-languageservice": "^0.1.50", + "@github/actions-languageservice": "^0.1.51", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "@types/jest": "^29.0.3", @@ -16292,7 +16292,7 @@ "browser-playground": { "version": "file:browser-playground", "requires": { - "@github/actions-languageserver": "^0.1.50", + "@github/actions-languageserver": "^0.1.51", "css-loader": "^6.7.2", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", @@ -23082,4 +23082,4 @@ "dev": true } } -} \ No newline at end of file +} From caff5ce7b63ddf374d830de869074b4878385772 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Tue, 13 Dec 2022 14:58:14 -0500 Subject: [PATCH 12/30] Validate action inputs --- actions-languageserver/src/connection.ts | 40 ++- actions-languageserver/src/value-providers.ts | 4 +- .../src/value-providers/action-inputs.ts | 63 +++-- .../src/action.test.ts | 2 +- .../src/action.ts | 10 + .../src/validate-action.ts | 82 ++++++ .../src/validate.actions.test.ts | 259 ++++++++++++++++++ actions-languageservice/src/validate.ts | 38 ++- 8 files changed, 441 insertions(+), 57 deletions(-) rename actions-languageserver/src/utils/action-reference.test.ts => actions-languageservice/src/action.test.ts (99%) rename actions-languageserver/src/utils/action-reference.ts => actions-languageservice/src/action.ts (77%) create mode 100644 actions-languageservice/src/validate-action.ts create mode 100644 actions-languageservice/src/validate.actions.test.ts diff --git a/actions-languageserver/src/connection.ts b/actions-languageserver/src/connection.ts index 627cd90..c610947 100644 --- a/actions-languageserver/src/connection.ts +++ b/actions-languageserver/src/connection.ts @@ -1,6 +1,7 @@ -import { hover } from "@github/actions-languageservice/hover"; -import { registerLogger, setLogLevel } from "@github/actions-languageservice/log"; -import { validate } from "@github/actions-languageservice/validate"; +import {hover} from "@github/actions-languageservice/hover"; +import {registerLogger, setLogLevel} from "@github/actions-languageservice/log"; +import {validate, ValidationConfig} from "@github/actions-languageservice/validate"; +import {Octokit} from "@octokit/rest"; import { CompletionItem, Connection, @@ -12,12 +13,13 @@ import { TextDocuments, TextDocumentSyncKind } from "vscode-languageserver"; -import { TextDocument } from "vscode-languageserver-textdocument"; -import { contextProviders } from "./context-providers"; -import { InitializationOptions, RepositoryContext } from "./initializationOptions"; -import { onCompletion } from "./on-completion"; -import { TTLCache } from "./utils/cache"; -import { valueProviders } from "./value-providers"; +import {TextDocument} from "vscode-languageserver-textdocument"; +import {contextProviders} from "./context-providers"; +import {InitializationOptions, RepositoryContext} from "./initializationOptions"; +import {onCompletion} from "./on-completion"; +import {TTLCache} from "./utils/cache"; +import {valueProviders} from "./value-providers"; +import {getActionInputs} from "./value-providers/action-inputs"; export function initConnection(connection: Connection) { const documents: TextDocuments = new TextDocuments(TextDocument); @@ -82,11 +84,21 @@ export function initConnection(connection: Connection) { async function validateTextDocument(textDocument: TextDocument): Promise { const repoContext = repos.find(repo => textDocument.uri.startsWith(repo.workspaceUri)); - const result = await validate( - textDocument, - valueProviders(sessionToken, repoContext, cache), - contextProviders(sessionToken, repoContext, cache) - ); + + const config: ValidationConfig = { + valueProviderConfig: valueProviders(sessionToken, repoContext, cache), + contextProviderConfig: contextProviders(sessionToken, repoContext, cache), + getActionInputs: async action => { + if (sessionToken) { + const octokit = new Octokit({ + auth: sessionToken + }); + return await getActionInputs(octokit, cache, action); + } + return undefined; + } + }; + const result = await validate(textDocument, config); connection.sendDiagnostics({uri: textDocument.uri, diagnostics: result}); } diff --git a/actions-languageserver/src/value-providers.ts b/actions-languageserver/src/value-providers.ts index 3ac95d5..d5e0eba 100644 --- a/actions-languageserver/src/value-providers.ts +++ b/actions-languageserver/src/value-providers.ts @@ -4,7 +4,7 @@ import {ValueProviderKind} from "@github/actions-languageservice/value-providers import {Octokit} from "@octokit/rest"; import {RepositoryContext} from "./initializationOptions"; import {TTLCache} from "./utils/cache"; -import {getActionInputs} from "./value-providers/action-inputs"; +import {getActionInputValues} from "./value-providers/action-inputs"; import {getEnvironments} from "./value-providers/job-environment"; import {getRunnerLabels} from "./value-providers/runs-on"; @@ -36,7 +36,7 @@ export function valueProviders( }, "step-with": { kind: ValueProviderKind.AllowedValues, - get: (context: WorkflowContext) => getActionInputs(octokit, cache, context) + get: (context: WorkflowContext) => getActionInputValues(octokit, cache, context) } }; } diff --git a/actions-languageserver/src/value-providers/action-inputs.ts b/actions-languageserver/src/value-providers/action-inputs.ts index 4d0af91..61ff70a 100644 --- a/actions-languageserver/src/value-providers/action-inputs.ts +++ b/actions-languageserver/src/value-providers/action-inputs.ts @@ -1,12 +1,33 @@ +import { + actionIdentifier, + ActionInputs, + ActionReference, + parseActionReference +} from "@github/actions-languageservice/action"; import {WorkflowContext} from "@github/actions-languageservice/context/workflow-context"; import {Value} from "@github/actions-languageservice/value-providers/config"; import {isActionStep} from "@github/actions-workflow-parser/model/type-guards"; import {Octokit, RestEndpointMethodTypes} from "@octokit/rest"; import {parse} from "yaml"; -import {actionIdentifier, ActionReference, parseActionReference} from "../utils/action-reference"; import {TTLCache} from "../utils/cache"; -export async function getActionInputs(client: Octokit, cache: TTLCache, context: WorkflowContext): Promise { +export async function getActionInputs( + client: Octokit, + cache: TTLCache, + action: ActionReference +): Promise { + const inputs = await cache.get(`${actionIdentifier(action)}/action-inputs`, undefined, () => + fetchActionInputs(client, action) + ); + + return inputs; +} + +export async function getActionInputValues( + client: Octokit, + cache: TTLCache, + context: WorkflowContext +): Promise { if (!context.step || !isActionStep(context.step)) { return []; } @@ -15,18 +36,23 @@ export async function getActionInputs(client: Octokit, cache: TTLCache, context: if (!action) { return []; } + const inputs = await getActionInputs(client, cache, action); + if (!inputs) { + return []; + } - const inputs = await cache.get(`${actionIdentifier(action)}/action-inputs`, undefined, () => - fetchActionInputs(client, action) - ); - - return inputs; + return Object.entries(inputs).map(([inputName, input]) => { + return { + label: inputName, + description: input.description + }; + }); } -async function fetchActionInputs(client: Octokit, action: ActionReference): Promise { +async function fetchActionInputs(client: Octokit, action: ActionReference): Promise { const metadata = await getActionMetadata(client, action); if (!metadata) { - return []; + return undefined; } return parseActionMetadata(metadata); @@ -71,7 +97,7 @@ async function getActionMetadata(client: Octokit, action: ActionReference): Prom } type ActionMetadata = { - inputs?: Record; + inputs?: ActionInputs; }; // https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#inputs @@ -83,20 +109,7 @@ type ActionInput = { }; // https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions -async function parseActionMetadata(content: string): Promise { - const inputs = new Array(); - +async function parseActionMetadata(content: string): Promise { const metadata: ActionMetadata = parse(content); - if (metadata.inputs === undefined) { - return inputs; - } - - for (const [name, input] of Object.entries(metadata.inputs)) { - inputs.push({ - label: name, - description: input.description - }); - } - - return inputs; + return metadata.inputs ?? {}; } diff --git a/actions-languageserver/src/utils/action-reference.test.ts b/actions-languageservice/src/action.test.ts similarity index 99% rename from actions-languageserver/src/utils/action-reference.test.ts rename to actions-languageservice/src/action.test.ts index eff9ef7..f06de9b 100644 --- a/actions-languageserver/src/utils/action-reference.test.ts +++ b/actions-languageservice/src/action.test.ts @@ -1,4 +1,4 @@ -import {actionIdentifier, parseActionReference as parse} from "./action-reference"; +import {actionIdentifier, parseActionReference as parse} from "./action"; describe("parseActionReference", () => { it("basic action", () => { diff --git a/actions-languageserver/src/utils/action-reference.ts b/actions-languageservice/src/action.ts similarity index 77% rename from actions-languageserver/src/utils/action-reference.ts rename to actions-languageservice/src/action.ts index 408984b..2f92b5d 100644 --- a/actions-languageserver/src/utils/action-reference.ts +++ b/actions-languageservice/src/action.ts @@ -1,3 +1,13 @@ +// https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#inputs +export type ActionInput = { + description: string; + required?: boolean; + default?: string; + deprecationMessage?: string; +}; + +export type ActionInputs = Record; + export type ActionReference = { owner: string; name: string; diff --git a/actions-languageservice/src/validate-action.ts b/actions-languageservice/src/validate-action.ts new file mode 100644 index 0000000..dbd404a --- /dev/null +++ b/actions-languageservice/src/validate-action.ts @@ -0,0 +1,82 @@ +import {isMapping} from "@github/actions-workflow-parser"; +import {isActionStep} from "@github/actions-workflow-parser/model/type-guards"; +import {Step} from "@github/actions-workflow-parser/model/workflow-template"; +import {ScalarToken} from "@github/actions-workflow-parser/templates/tokens/scalar-token"; +import {TemplateToken} from "@github/actions-workflow-parser/templates/tokens/template-token"; +import {Diagnostic, DiagnosticSeverity} from "vscode-languageserver-types"; +import {parseActionReference} from "./action"; +import {mapRange} from "./utils/range"; +import {ValidationConfig} from "./validate"; + +export async function validateAction( + diagnostics: Diagnostic[], + stepToken: TemplateToken, + step: Step | undefined, + config: ValidationConfig | undefined +): Promise { + if (!isMapping(stepToken) || !step || !isActionStep(step) || !config?.getActionInputs) { + return; + } + + const action = parseActionReference(step.uses.value); + if (!action) { + return; + } + + const actionInputs = await config.getActionInputs(action); + if (actionInputs === undefined) { + return; + } + + let withKey: ScalarToken | undefined; + let withToken: TemplateToken | undefined; + for (const {key, value} of stepToken) { + if (key.toString() === "with") { + withKey = key; + withToken = value; + break; + } + } + + const stepInputs = new Map(); + if (withToken && isMapping(withToken)) { + for (const {key} of withToken) { + stepInputs.set(key.toString(), key); + } + } + + for (const [input, inputToken] of stepInputs) { + if (!actionInputs[input]) { + diagnostics.push({ + severity: DiagnosticSeverity.Error, + range: mapRange(inputToken.range), + message: `Invalid action input '${input}'` + }); + } + + const deprecationMessage = actionInputs[input]?.deprecationMessage; + if (deprecationMessage) { + diagnostics.push({ + severity: DiagnosticSeverity.Warning, + range: mapRange(inputToken.range), + message: deprecationMessage + }); + } + } + + const missingRequiredInputs = Object.entries(actionInputs).filter( + ([inputName, input]) => input.required && !stepInputs.has(inputName) + ); + + if (missingRequiredInputs.length > 0) { + const message = + missingRequiredInputs.length === 1 + ? `Missing required input \`${missingRequiredInputs[0][0]}\`` + : `Missing required inputs: ${missingRequiredInputs.map(input => `\`${input[0]}\``).join(", ")}`; + diagnostics.push({ + severity: DiagnosticSeverity.Error, + range: mapRange((withKey || stepToken).range), // Highlight the whole step if we don't have a with key + message: message + }); + } +} diff --git a/actions-languageservice/src/validate.actions.test.ts b/actions-languageservice/src/validate.actions.test.ts new file mode 100644 index 0000000..9b499bf --- /dev/null +++ b/actions-languageservice/src/validate.actions.test.ts @@ -0,0 +1,259 @@ +import {Diagnostic, DiagnosticSeverity} from "vscode-languageserver-types"; +import {ActionInput, ActionReference} from "./action"; +import {registerLogger} from "./log"; +import {createDocument} from "./test-utils/document"; +import {TestLogger} from "./test-utils/logger"; +import {validate, ValidationConfig} from "./validate"; +import {ValueProviderKind} from "./value-providers/config"; + +registerLogger(new TestLogger()); + +const validationConfig: ValidationConfig = { + getActionInputs: async (ref: ActionReference) => { + let inputs: Record = {}; + switch (ref.owner + "/" + ref.name + "@" + ref.ref) { + case "actions/checkout@v3": + inputs = { + repository: { + description: "Repository name with owner", + default: "${{ github.repository }}" + } + }; + break; + case "actions/setup-node@v1": + inputs = { + version: { + description: "Deprecated. Use node-version instead. Will not be supported after October 1, 2019", + deprecationMessage: + "The version property will not be supported after October 1, 2019. Use node-version instead" + } + }; + break; + case "actions/cache@v1": + inputs = { + path: { + description: "A directory to store and save the cache", + required: true + }, + key: { + description: "An explicit key for restoring and saving the cache", + required: true + }, + "restore-keys": { + description: "An ordered list of keys to use for restoring the cache if no cache hit occurred for key", + required: false + } + }; + break; + } + return inputs; + } +}; +describe("validate action steps", () => { + it("valid action reference", async () => { + const input = ` +on: push +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 +`; + const result = await validate(createDocument("wf.yaml", input), validationConfig); + + expect(result).toEqual([]); + }); + + it("invalid input", async () => { + const input = ` +on: push +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + notanoption: true +`; + const result = await validate(createDocument("wf.yaml", input), validationConfig); + + expect(result).toEqual([ + { + message: "Invalid action input 'notanoption'", + range: { + end: { + character: 19, + line: 8 + }, + start: { + character: 8, + line: 8 + } + }, + severity: DiagnosticSeverity.Error + } + ]); + }); + + it("deprecated input", async () => { + const input = ` +on: push +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/setup-node@v1 + with: + version: 10 +`; + const result = await validate(createDocument("wf.yaml", input), validationConfig); + + expect(result).toEqual([ + { + message: "The version property will not be supported after October 1, 2019. Use node-version instead", + range: { + end: { + character: 15, + line: 8 + }, + start: { + character: 8, + line: 8 + } + }, + severity: DiagnosticSeverity.Warning + } + ]); + }); + + it("missing required input", async () => { + const input = ` +on: push +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/cache@v1 + with: + key: \${{ runner.os }}-node-\${{ hashFiles('**/package-lock.json') }} +`; + const result = await validate(createDocument("wf.yaml", input), validationConfig); + + expect(result).toEqual([ + { + message: "Missing required input `path`", + range: { + end: { + character: 10, + line: 7 + }, + start: { + character: 6, + line: 7 + } + }, + severity: DiagnosticSeverity.Error + } + ]); + }); + + it("multiple missing required inputs", async () => { + const input = ` +on: push +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/cache@v1 + with: + restore-keys: \${{ runner.os }}-node- +`; + const result = await validate(createDocument("wf.yaml", input), validationConfig); + + expect(result).toEqual([ + { + message: "Missing required inputs: `path`, `key`", + range: { + end: { + character: 10, + line: 7 + }, + start: { + character: 6, + line: 7 + } + }, + severity: DiagnosticSeverity.Error + } + ]); + }); + + it("missing required inputs without a `with` key", async () => { + const input = ` +on: push +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/cache@v1 +`; + const result = await validate(createDocument("wf.yaml", input), validationConfig); + + expect(result).toEqual([ + { + message: "Missing required inputs: `path`, `key`", + range: { + end: { + character: 0, + line: 7 + }, + start: { + character: 6, + line: 6 + } + }, + severity: DiagnosticSeverity.Error + } + ]); + }); + + it("skips extra validation from custom value provider", async () => { + const input = ` +on: push +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + notanoption: true +`; + const config = validationConfig; + config.valueProviderConfig = { + "step-with": { + kind: ValueProviderKind.AllowedValues, + get: async () => { + return [{label: "repository", description: "Repository name with owner."}]; + } + } + }; + const result = await validate(createDocument("wf.yaml", input), config); + + expect(result).toEqual([ + { + message: "Invalid action input 'notanoption'", + range: { + end: { + character: 19, + line: 8 + }, + start: { + character: 8, + line: 8 + } + }, + severity: DiagnosticSeverity.Error + } + ]); + }); +}); diff --git a/actions-languageservice/src/validate.ts b/actions-languageservice/src/validate.ts index d913a26..8d2a0b4 100644 --- a/actions-languageservice/src/validate.ts +++ b/actions-languageservice/src/validate.ts @@ -16,6 +16,7 @@ import {TemplateToken} from "@github/actions-workflow-parser/templates/tokens/te import {File} from "@github/actions-workflow-parser/workflows/file"; import {TextDocument} from "vscode-languageserver-textdocument"; import {Diagnostic, DiagnosticSeverity, URI} from "vscode-languageserver-types"; +import {ActionInputs, ActionReference} from "./action"; import {ContextProviderConfig} from "./context-providers/config"; import {getContext, Mode} from "./context-providers/default"; @@ -26,9 +27,16 @@ import {nullTrace} from "./nulltrace"; import {getAllowedContext} from "./utils/allowed-context"; import {findToken} from "./utils/find-token"; import {mapRange} from "./utils/range"; +import {validateAction} from "./validate-action"; import {ValueProviderConfig, ValueProviderKind} from "./value-providers/config"; import {defaultValueProviders} from "./value-providers/default"; +export type ValidationConfig = { + valueProviderConfig?: ValueProviderConfig; + contextProviderConfig?: ContextProviderConfig; + getActionInputs?(action: ActionReference): Promise; +}; + /** * Validates a workflow file * @@ -37,9 +45,8 @@ import {defaultValueProviders} from "./value-providers/default"; */ export async function validate( textDocument: TextDocument, + config?: ValidationConfig // TODO: Support multiple files, context for API calls - valueProviderConfig?: ValueProviderConfig, - contextProviderConfig?: ContextProviderConfig ): Promise { const file: File = { name: textDocument.uri, @@ -55,14 +62,7 @@ export async function validate( const template = convertWorkflowTemplate(result.context, result.value, ErrorPolicy.TryConversion); // Validate expressions and value providers - await additionalValidations( - diagnostics, - textDocument.uri, - template, - result.value, - valueProviderConfig, - contextProviderConfig - ); + await additionalValidations(diagnostics, textDocument.uri, template, result.value, config); } // For now map parser errors directly to diagnostics @@ -86,8 +86,7 @@ async function additionalValidations( documentUri: URI, template: WorkflowTemplate, root: TemplateToken, - valueProviderConfig: ValueProviderConfig | undefined, - contextProviderConfig: ContextProviderConfig | undefined + config?: ValidationConfig ) { for (const [parent, token, key] of TemplateToken.traverse(root)) { // If the token is a value in a pair, use the key definition for validation @@ -103,18 +102,27 @@ async function additionalValidations( diagnostics, token, allowedContext, - contextProviderConfig, + config?.contextProviderConfig, getProviderContext(documentUri, template, root, token) ); } + if (token.definition?.key === "regular-step") { + const context = getProviderContext(documentUri, template, root, token); + await validateAction(diagnostics, token, context.step, config); + } + // Allowed values coming from the schema have already been validated. Only check if // a value provider is defined for a token and if it is, validate the values match. - if (valueProviderConfig && token.range && validationDefinition) { + if (config?.valueProviderConfig && token.range && validationDefinition) { const defKey = validationDefinition.key; + if (defKey === "step-with") { + // Action inputs should be validated already in validateAction + continue; + } // Try a custom value provider first - let valueProvider = valueProviderConfig[defKey]; + let valueProvider = config.valueProviderConfig[defKey]; if (!valueProvider) { // fall back to default valueProvider = defaultValueProviders[defKey]; From de7e919d884906dfdf2cb95d59cb79d3c40f954e Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Tue, 13 Dec 2022 15:14:57 -0500 Subject: [PATCH 13/30] Fix validation config in tests --- actions-languageservice/src/validate.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/actions-languageservice/src/validate.test.ts b/actions-languageservice/src/validate.test.ts index 44beb3a..eaaa38e 100644 --- a/actions-languageservice/src/validate.test.ts +++ b/actions-languageservice/src/validate.test.ts @@ -70,7 +70,7 @@ jobs: steps: - run: echo` ), - defaultValueProviders + {valueProviderConfig: defaultValueProviders} ); expect(result.length).toBe(1); @@ -103,7 +103,7 @@ jobs: steps: - run: echo` ), - defaultValueProviders + {valueProviderConfig: defaultValueProviders} ); expect(result.length).toBe(1); @@ -139,7 +139,7 @@ jobs: steps: - run: echo` ), - defaultValueProviders + {valueProviderConfig: defaultValueProviders} ); expect(result[0]).toEqual({ @@ -168,7 +168,7 @@ jobs: runs-on: - ubuntu-latest` ), - defaultValueProviders + {valueProviderConfig: defaultValueProviders} ); expect(result.length).toBe(1); From 5c052e96a804ed81cd6dfa7dc9106b2acaba6ae4 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 13 Dec 2022 22:25:19 +0000 Subject: [PATCH 14/30] v0.1.52 --- actions-languageserver/package.json | 4 ++-- actions-languageservice/package.json | 2 +- browser-playground/package.json | 4 ++-- lerna.json | 2 +- package-lock.json | 14 +++++++------- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/actions-languageserver/package.json b/actions-languageserver/package.json index 1248a90..37dff11 100644 --- a/actions-languageserver/package.json +++ b/actions-languageserver/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageserver", - "version": "0.1.51", + "version": "0.1.52", "description": "Language server for GitHub Actions", "license": "MIT", "type": "module", @@ -38,7 +38,7 @@ "prettier-fix": "prettier --write ." }, "dependencies": { - "@github/actions-languageservice": "^0.1.51", + "@github/actions-languageservice": "^0.1.52", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", diff --git a/actions-languageservice/package.json b/actions-languageservice/package.json index d253d42..cf4b16e 100644 --- a/actions-languageservice/package.json +++ b/actions-languageservice/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageservice", - "version": "0.1.51", + "version": "0.1.52", "description": "Language service for GitHub Actions", "license": "MIT", "type": "module", diff --git a/browser-playground/package.json b/browser-playground/package.json index 0011685..d05e605 100644 --- a/browser-playground/package.json +++ b/browser-playground/package.json @@ -1,12 +1,12 @@ { "name": "browser-playground", - "version": "0.1.51", + "version": "0.1.52", "description": "", "private": true, "main": "index.js", "type": "module", "dependencies": { - "@github/actions-languageserver": "^0.1.51", + "@github/actions-languageserver": "^0.1.52", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", diff --git a/lerna.json b/lerna.json index 88d1460..a328842 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useWorkspaces": true, - "version": "0.1.51" + "version": "0.1.52" } diff --git a/package-lock.json b/package-lock.json index 3454b07..46fb9bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,10 +16,10 @@ }, "actions-languageserver": { "name": "@github/actions-languageserver", - "version": "0.1.51", + "version": "0.1.52", "license": "MIT", "dependencies": { - "@github/actions-languageservice": "^0.1.51", + "@github/actions-languageservice": "^0.1.52", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", @@ -40,7 +40,7 @@ }, "actions-languageservice": { "name": "@github/actions-languageservice", - "version": "0.1.51", + "version": "0.1.52", "license": "MIT", "dependencies": { "@github/actions-workflow-parser": "*", @@ -61,10 +61,10 @@ } }, "browser-playground": { - "version": "0.1.51", + "version": "0.1.52", "license": "MIT", "dependencies": { - "@github/actions-languageserver": "^0.1.51", + "@github/actions-languageserver": "^0.1.52", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", @@ -13507,7 +13507,7 @@ "@github/actions-languageserver": { "version": "file:actions-languageserver", "requires": { - "@github/actions-languageservice": "^0.1.51", + "@github/actions-languageservice": "^0.1.52", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "@types/jest": "^29.0.3", @@ -16292,7 +16292,7 @@ "browser-playground": { "version": "file:browser-playground", "requires": { - "@github/actions-languageserver": "^0.1.51", + "@github/actions-languageserver": "^0.1.52", "css-loader": "^6.7.2", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", From 63ebc92dec5ab07e3cebca7d645e0c6dfca2700b Mon Sep 17 00:00:00 2001 From: Laura Yu <60276246+lauraway@users.noreply.github.com> Date: Tue, 13 Dec 2022 14:41:29 -0800 Subject: [PATCH 15/30] Use custom value provider from parent when token key doesn't have one (#49) --- actions-languageservice/src/complete.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/actions-languageservice/src/complete.ts b/actions-languageservice/src/complete.ts index bce981a..16b50dc 100644 --- a/actions-languageservice/src/complete.ts +++ b/actions-languageservice/src/complete.ts @@ -129,21 +129,20 @@ async function getValues( const existingValues = getExistingValues(token, parent); - if (keyToken?.definition?.key) { - const customValues = await valueProviderConfig?.[keyToken.definition.key]?.get(workflowContext); + // Use the value providers from the parent if the current key is null + const valueProviderToken = keyToken || parent; + const customValueProvider = valueProviderToken?.definition?.key && valueProviderConfig?.[valueProviderToken.definition.key] + if (customValueProvider) { + const customValues = await customValueProvider.get(workflowContext); if (customValues) { return filterAndSortCompletionOptions(customValues, existingValues); } } - // Use the value provider from the parent if we don't have a value provider for the current key - const valueProvider = - (keyToken?.definition?.key && defaultValueProviders[keyToken.definition.key]) || - (parent.definition?.key && defaultValueProviders[parent.definition.key]); - - if (valueProvider) { - const values = await valueProvider.get(workflowContext); + const defaultValueProvider = valueProviderToken?.definition?.key && defaultValueProviders[valueProviderToken.definition.key] + if (defaultValueProvider) { + const values = await defaultValueProvider.get(workflowContext); return filterAndSortCompletionOptions(values, existingValues); } From b123488a94f7561c523c8dabc79ac8716cae1cb6 Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 13 Dec 2022 22:42:13 +0000 Subject: [PATCH 16/30] v0.1.53 --- actions-languageserver/package.json | 4 ++-- actions-languageservice/package.json | 2 +- browser-playground/package.json | 4 ++-- lerna.json | 2 +- package-lock.json | 14 +++++++------- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/actions-languageserver/package.json b/actions-languageserver/package.json index 37dff11..b59c7b3 100644 --- a/actions-languageserver/package.json +++ b/actions-languageserver/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageserver", - "version": "0.1.52", + "version": "0.1.53", "description": "Language server for GitHub Actions", "license": "MIT", "type": "module", @@ -38,7 +38,7 @@ "prettier-fix": "prettier --write ." }, "dependencies": { - "@github/actions-languageservice": "^0.1.52", + "@github/actions-languageservice": "^0.1.53", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", diff --git a/actions-languageservice/package.json b/actions-languageservice/package.json index cf4b16e..d75109c 100644 --- a/actions-languageservice/package.json +++ b/actions-languageservice/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageservice", - "version": "0.1.52", + "version": "0.1.53", "description": "Language service for GitHub Actions", "license": "MIT", "type": "module", diff --git a/browser-playground/package.json b/browser-playground/package.json index d05e605..7d58984 100644 --- a/browser-playground/package.json +++ b/browser-playground/package.json @@ -1,12 +1,12 @@ { "name": "browser-playground", - "version": "0.1.52", + "version": "0.1.53", "description": "", "private": true, "main": "index.js", "type": "module", "dependencies": { - "@github/actions-languageserver": "^0.1.52", + "@github/actions-languageserver": "^0.1.53", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", diff --git a/lerna.json b/lerna.json index a328842..66d865d 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useWorkspaces": true, - "version": "0.1.52" + "version": "0.1.53" } diff --git a/package-lock.json b/package-lock.json index 46fb9bc..5d9c592 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,10 +16,10 @@ }, "actions-languageserver": { "name": "@github/actions-languageserver", - "version": "0.1.52", + "version": "0.1.53", "license": "MIT", "dependencies": { - "@github/actions-languageservice": "^0.1.52", + "@github/actions-languageservice": "^0.1.53", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", @@ -40,7 +40,7 @@ }, "actions-languageservice": { "name": "@github/actions-languageservice", - "version": "0.1.52", + "version": "0.1.53", "license": "MIT", "dependencies": { "@github/actions-workflow-parser": "*", @@ -61,10 +61,10 @@ } }, "browser-playground": { - "version": "0.1.52", + "version": "0.1.53", "license": "MIT", "dependencies": { - "@github/actions-languageserver": "^0.1.52", + "@github/actions-languageserver": "^0.1.53", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", @@ -13507,7 +13507,7 @@ "@github/actions-languageserver": { "version": "file:actions-languageserver", "requires": { - "@github/actions-languageservice": "^0.1.52", + "@github/actions-languageservice": "^0.1.53", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "@types/jest": "^29.0.3", @@ -16292,7 +16292,7 @@ "browser-playground": { "version": "file:browser-playground", "requires": { - "@github/actions-languageserver": "^0.1.52", + "@github/actions-languageserver": "^0.1.53", "css-loader": "^6.7.2", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", From e67e72019958672ebe4187f2694b389183dfef82 Mon Sep 17 00:00:00 2001 From: Laura Yu <60276246+lauraway@users.noreply.github.com> Date: Tue, 13 Dec 2022 16:26:04 -0800 Subject: [PATCH 17/30] Add test for custom value providers for sequences (#56) --- actions-languageservice/src/complete.test.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/actions-languageservice/src/complete.test.ts b/actions-languageservice/src/complete.test.ts index ef59c0e..b9c20ca 100644 --- a/actions-languageservice/src/complete.test.ts +++ b/actions-languageservice/src/complete.test.ts @@ -199,6 +199,24 @@ jobs: expect(result[0].label).toEqual("my-custom-label"); }); + it("custom value providers for sequences", async () => { + const input = "on: push\njobs:\n build:\n runs-on: [m|]"; + + const config: ValueProviderConfig = { + "runs-on": { + kind: ValueProviderKind.SuggestedValues, + get: async (_: WorkflowContext) => { + return [{label: "my-custom-label"}]; + } + } + }; + const result = await complete(...getPositionFromCursor(input), config); + + expect(result).not.toBeUndefined(); + expect(result.length).toEqual(1); + expect(result[0].label).toEqual("my-custom-label"); + }); + it("does not show parent mapping sibling keys", async () => { const input = `on: push jobs: From c884c397c11c0a0726d59856a000619ddc39112a Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 14 Dec 2022 00:26:40 +0000 Subject: [PATCH 18/30] v0.1.54 --- actions-languageserver/package.json | 4 ++-- actions-languageservice/package.json | 2 +- browser-playground/package.json | 4 ++-- lerna.json | 2 +- package-lock.json | 14 +++++++------- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/actions-languageserver/package.json b/actions-languageserver/package.json index b59c7b3..f93acdf 100644 --- a/actions-languageserver/package.json +++ b/actions-languageserver/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageserver", - "version": "0.1.53", + "version": "0.1.54", "description": "Language server for GitHub Actions", "license": "MIT", "type": "module", @@ -38,7 +38,7 @@ "prettier-fix": "prettier --write ." }, "dependencies": { - "@github/actions-languageservice": "^0.1.53", + "@github/actions-languageservice": "^0.1.54", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", diff --git a/actions-languageservice/package.json b/actions-languageservice/package.json index d75109c..bac06f1 100644 --- a/actions-languageservice/package.json +++ b/actions-languageservice/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageservice", - "version": "0.1.53", + "version": "0.1.54", "description": "Language service for GitHub Actions", "license": "MIT", "type": "module", diff --git a/browser-playground/package.json b/browser-playground/package.json index 7d58984..2e70cef 100644 --- a/browser-playground/package.json +++ b/browser-playground/package.json @@ -1,12 +1,12 @@ { "name": "browser-playground", - "version": "0.1.53", + "version": "0.1.54", "description": "", "private": true, "main": "index.js", "type": "module", "dependencies": { - "@github/actions-languageserver": "^0.1.53", + "@github/actions-languageserver": "^0.1.54", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", diff --git a/lerna.json b/lerna.json index 66d865d..3875256 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useWorkspaces": true, - "version": "0.1.53" + "version": "0.1.54" } diff --git a/package-lock.json b/package-lock.json index 5d9c592..ded6b64 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,10 +16,10 @@ }, "actions-languageserver": { "name": "@github/actions-languageserver", - "version": "0.1.53", + "version": "0.1.54", "license": "MIT", "dependencies": { - "@github/actions-languageservice": "^0.1.53", + "@github/actions-languageservice": "^0.1.54", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", @@ -40,7 +40,7 @@ }, "actions-languageservice": { "name": "@github/actions-languageservice", - "version": "0.1.53", + "version": "0.1.54", "license": "MIT", "dependencies": { "@github/actions-workflow-parser": "*", @@ -61,10 +61,10 @@ } }, "browser-playground": { - "version": "0.1.53", + "version": "0.1.54", "license": "MIT", "dependencies": { - "@github/actions-languageserver": "^0.1.53", + "@github/actions-languageserver": "^0.1.54", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", @@ -13507,7 +13507,7 @@ "@github/actions-languageserver": { "version": "file:actions-languageserver", "requires": { - "@github/actions-languageservice": "^0.1.53", + "@github/actions-languageservice": "^0.1.54", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "@types/jest": "^29.0.3", @@ -16292,7 +16292,7 @@ "browser-playground": { "version": "file:browser-playground", "requires": { - "@github/actions-languageserver": "^0.1.53", + "@github/actions-languageserver": "^0.1.54", "css-loader": "^6.7.2", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", From 2d7a05c0491f3fda14edea5a66f063e0435b54a6 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Wed, 14 Dec 2022 11:18:38 -0500 Subject: [PATCH 19/30] Use the allowed context from the definition info --- actions-languageservice/src/complete.ts | 3 +-- .../src/utils/allowed-context.ts | 15 --------------- actions-languageservice/src/validate.ts | 5 +---- 3 files changed, 2 insertions(+), 21 deletions(-) delete mode 100644 actions-languageservice/src/utils/allowed-context.ts diff --git a/actions-languageservice/src/complete.ts b/actions-languageservice/src/complete.ts index 16b50dc..1617f70 100644 --- a/actions-languageservice/src/complete.ts +++ b/actions-languageservice/src/complete.ts @@ -14,7 +14,6 @@ import {ContextProviderConfig} from "./context-providers/config"; import {getContext, Mode} from "./context-providers/default"; import {getWorkflowContext, WorkflowContext} from "./context/workflow-context"; import {nullTrace} from "./nulltrace"; -import {getAllowedContext} from "./utils/allowed-context"; import {findToken} from "./utils/find-token"; import {mapRange} from "./utils/range"; import {transform} from "./utils/transform"; @@ -92,7 +91,7 @@ export async function complete( const expressionInput = (getExpressionInput(currentInput, relCharPos) || "").trim(); - const allowedContext = getAllowedContext(token, parent); + const allowedContext = token.definitionInfo?.allowedContext || []; const context = await getContext(allowedContext, contextProviderConfig, workflowContext, Mode.Completion); return completeExpression(expressionInput, context, []); diff --git a/actions-languageservice/src/utils/allowed-context.ts b/actions-languageservice/src/utils/allowed-context.ts deleted file mode 100644 index 36a5d91..0000000 --- a/actions-languageservice/src/utils/allowed-context.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {TemplateToken} from "@github/actions-workflow-parser/templates/tokens/template-token"; - -export function getAllowedContext(token: TemplateToken, parent: TemplateToken | null | undefined): string[] { - // Workaround for https://github.com/github/c2c-actions-experience/issues/6876 - // Context is inherited from the parent - const allowedContext = new Set(); - for (const t of [token, parent]) { - if (t?.definition?.readerContext) { - for (const context of t.definition.readerContext) { - allowedContext.add(context); - } - } - } - return Array.from(allowedContext); -} diff --git a/actions-languageservice/src/validate.ts b/actions-languageservice/src/validate.ts index 8d2a0b4..d5e9884 100644 --- a/actions-languageservice/src/validate.ts +++ b/actions-languageservice/src/validate.ts @@ -24,7 +24,6 @@ import {getWorkflowContext, WorkflowContext} from "./context/workflow-context"; import {AccessError, wrapDictionary} from "./expression-validation/error-dictionary"; import {error} from "./log"; import {nullTrace} from "./nulltrace"; -import {getAllowedContext} from "./utils/allowed-context"; import {findToken} from "./utils/find-token"; import {mapRange} from "./utils/range"; import {validateAction} from "./validate-action"; @@ -94,14 +93,12 @@ async function additionalValidations( const validationToken = key || parent || token; const validationDefinition = validationToken.definition; - const allowedContext = getAllowedContext(validationToken, parent); - // If this is an expression, validate it if (isBasicExpression(token)) { await validateExpression( diagnostics, token, - allowedContext, + validationToken.definitionInfo?.allowedContext || [], config?.contextProviderConfig, getProviderContext(documentUri, template, root, token) ); From 447bbfc0329c6937e1e88237aae5237abab81c27 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Wed, 14 Dec 2022 13:07:26 -0500 Subject: [PATCH 20/30] Show deprecation status when suggesting action inputs --- .../src/value-providers/action-inputs.ts | 11 ++--------- actions-languageservice/src/complete.ts | 19 +++++++++++-------- .../src/value-providers/config.ts | 1 + 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/actions-languageserver/src/value-providers/action-inputs.ts b/actions-languageserver/src/value-providers/action-inputs.ts index 61ff70a..63d3e94 100644 --- a/actions-languageserver/src/value-providers/action-inputs.ts +++ b/actions-languageserver/src/value-providers/action-inputs.ts @@ -44,7 +44,8 @@ export async function getActionInputValues( return Object.entries(inputs).map(([inputName, input]) => { return { label: inputName, - description: input.description + description: input.description, + deprecated: input.deprecationMessage !== undefined }; }); } @@ -100,14 +101,6 @@ type ActionMetadata = { inputs?: ActionInputs; }; -// https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#inputs -type ActionInput = { - description: string; - required?: boolean; - default?: string; - deprecationMessage?: string; -}; - // https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions async function parseActionMetadata(content: string): Promise { const metadata: ActionMetadata = parse(content); diff --git a/actions-languageservice/src/complete.ts b/actions-languageservice/src/complete.ts index 16b50dc..cc714ab 100644 --- a/actions-languageservice/src/complete.ts +++ b/actions-languageservice/src/complete.ts @@ -9,7 +9,7 @@ import {MappingToken} from "@github/actions-workflow-parser/templates/tokens/map import {TokenType} from "@github/actions-workflow-parser/templates/tokens/types"; import {File} from "@github/actions-workflow-parser/workflows/file"; import {Position, TextDocument} from "vscode-languageserver-textdocument"; -import {CompletionItem, Range, TextEdit} from "vscode-languageserver-types"; +import {CompletionItem, CompletionItemTag, Range, TextEdit} from "vscode-languageserver-types"; import {ContextProviderConfig} from "./context-providers/config"; import {getContext, Mode} from "./context-providers/default"; import {getWorkflowContext, WorkflowContext} from "./context/workflow-context"; @@ -106,11 +106,12 @@ export async function complete( } return values.map(value => { - const item = CompletionItem.create(value.label); - item.detail = value.description; - if (replaceRange) { - item.textEdit = TextEdit.replace(replaceRange, value.label); - } + const item: CompletionItem = { + label: value.label, + detail: value.description, + tags: value.deprecated ? [CompletionItemTag.Deprecated] : undefined, + textEdit: replaceRange ? TextEdit.replace(replaceRange, value.label) : undefined + }; return item; }); @@ -132,7 +133,8 @@ async function getValues( // Use the value providers from the parent if the current key is null const valueProviderToken = keyToken || parent; - const customValueProvider = valueProviderToken?.definition?.key && valueProviderConfig?.[valueProviderToken.definition.key] + const customValueProvider = + valueProviderToken?.definition?.key && valueProviderConfig?.[valueProviderToken.definition.key]; if (customValueProvider) { const customValues = await customValueProvider.get(workflowContext); if (customValues) { @@ -140,7 +142,8 @@ async function getValues( } } - const defaultValueProvider = valueProviderToken?.definition?.key && defaultValueProviders[valueProviderToken.definition.key] + const defaultValueProvider = + valueProviderToken?.definition?.key && defaultValueProviders[valueProviderToken.definition.key]; if (defaultValueProvider) { const values = await defaultValueProvider.get(workflowContext); return filterAndSortCompletionOptions(values, existingValues); diff --git a/actions-languageservice/src/value-providers/config.ts b/actions-languageservice/src/value-providers/config.ts index 34b7337..725ad4c 100644 --- a/actions-languageservice/src/value-providers/config.ts +++ b/actions-languageservice/src/value-providers/config.ts @@ -3,6 +3,7 @@ import {WorkflowContext} from "../context/workflow-context"; export interface Value { label: string; description?: string; + deprecated?: boolean; } export enum ValueProviderKind { From 6a19aa0a5eed6dc7e918045da1bfe98bd4182ec5 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Wed, 14 Dec 2022 14:55:19 -0500 Subject: [PATCH 21/30] Bump parser version --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index ded6b64..1337178 100644 --- a/package-lock.json +++ b/package-lock.json @@ -700,9 +700,9 @@ "link": true }, "node_modules/@github/actions-workflow-parser": { - "version": "0.0.34", - "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.34/e369bdaca17cde594ad7420cd0df0efcd2804dc0", - "integrity": "sha512-ttjYUoO2bvi5v/SR267QpDhWJ+I4tXQlSMnscjqUp76IDLxS73I7nCD3KP7g4VxzHmT5j8AxSdjEE25UWpl43g==", + "version": "0.0.35", + "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.35/0e88d541486f7c8772c5640fc13fac630cfaeaa8", + "integrity": "sha512-OuNEuqUH4AOfWd2xb8VRl7KwJrtiZu1ic0b27lmadwvK8qgRhPHxvS+QICEc+JtFbbVWpAA2ymh8I1U35639mA==", "license": "MIT", "dependencies": { "@github/actions-expressions": "*", @@ -13537,9 +13537,9 @@ } }, "@github/actions-workflow-parser": { - "version": "0.0.34", - "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.34/e369bdaca17cde594ad7420cd0df0efcd2804dc0", - "integrity": "sha512-ttjYUoO2bvi5v/SR267QpDhWJ+I4tXQlSMnscjqUp76IDLxS73I7nCD3KP7g4VxzHmT5j8AxSdjEE25UWpl43g==", + "version": "0.0.35", + "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.35/0e88d541486f7c8772c5640fc13fac630cfaeaa8", + "integrity": "sha512-OuNEuqUH4AOfWd2xb8VRl7KwJrtiZu1ic0b27lmadwvK8qgRhPHxvS+QICEc+JtFbbVWpAA2ymh8I1U35639mA==", "requires": { "@github/actions-expressions": "*", "yaml": "^2.0.0-8" From af142acb2209971bdd93c740ebb59febedcc1f5a Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 14 Dec 2022 19:56:38 +0000 Subject: [PATCH 22/30] v0.1.55 --- actions-languageserver/package.json | 4 ++-- actions-languageservice/package.json | 2 +- browser-playground/package.json | 4 ++-- lerna.json | 2 +- package-lock.json | 14 +++++++------- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/actions-languageserver/package.json b/actions-languageserver/package.json index f93acdf..b38e4c5 100644 --- a/actions-languageserver/package.json +++ b/actions-languageserver/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageserver", - "version": "0.1.54", + "version": "0.1.55", "description": "Language server for GitHub Actions", "license": "MIT", "type": "module", @@ -38,7 +38,7 @@ "prettier-fix": "prettier --write ." }, "dependencies": { - "@github/actions-languageservice": "^0.1.54", + "@github/actions-languageservice": "^0.1.55", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", diff --git a/actions-languageservice/package.json b/actions-languageservice/package.json index bac06f1..e441757 100644 --- a/actions-languageservice/package.json +++ b/actions-languageservice/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageservice", - "version": "0.1.54", + "version": "0.1.55", "description": "Language service for GitHub Actions", "license": "MIT", "type": "module", diff --git a/browser-playground/package.json b/browser-playground/package.json index 2e70cef..db7adea 100644 --- a/browser-playground/package.json +++ b/browser-playground/package.json @@ -1,12 +1,12 @@ { "name": "browser-playground", - "version": "0.1.54", + "version": "0.1.55", "description": "", "private": true, "main": "index.js", "type": "module", "dependencies": { - "@github/actions-languageserver": "^0.1.54", + "@github/actions-languageserver": "^0.1.55", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", diff --git a/lerna.json b/lerna.json index 3875256..62b0ac4 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useWorkspaces": true, - "version": "0.1.54" + "version": "0.1.55" } diff --git a/package-lock.json b/package-lock.json index ded6b64..3553df5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,10 +16,10 @@ }, "actions-languageserver": { "name": "@github/actions-languageserver", - "version": "0.1.54", + "version": "0.1.55", "license": "MIT", "dependencies": { - "@github/actions-languageservice": "^0.1.54", + "@github/actions-languageservice": "^0.1.55", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", @@ -40,7 +40,7 @@ }, "actions-languageservice": { "name": "@github/actions-languageservice", - "version": "0.1.54", + "version": "0.1.55", "license": "MIT", "dependencies": { "@github/actions-workflow-parser": "*", @@ -61,10 +61,10 @@ } }, "browser-playground": { - "version": "0.1.54", + "version": "0.1.55", "license": "MIT", "dependencies": { - "@github/actions-languageserver": "^0.1.54", + "@github/actions-languageserver": "^0.1.55", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", @@ -13507,7 +13507,7 @@ "@github/actions-languageserver": { "version": "file:actions-languageserver", "requires": { - "@github/actions-languageservice": "^0.1.54", + "@github/actions-languageservice": "^0.1.55", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "@types/jest": "^29.0.3", @@ -16292,7 +16292,7 @@ "browser-playground": { "version": "file:browser-playground", "requires": { - "@github/actions-languageserver": "^0.1.54", + "@github/actions-languageserver": "^0.1.55", "css-loader": "^6.7.2", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", From eafbcde86a29cba88e731bd46cf81c062ca23560 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Wed, 14 Dec 2022 16:10:31 -0500 Subject: [PATCH 23/30] Improve auto-completion for expression functions --- actions-languageservice/package.json | 3 +- .../src/complete.expressions.test.ts | 34 +++++++++++++++++++ actions-languageservice/src/complete.ts | 10 ++++-- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/actions-languageservice/package.json b/actions-languageservice/package.json index e441757..d7ec8ad 100644 --- a/actions-languageservice/package.json +++ b/actions-languageservice/package.json @@ -39,6 +39,7 @@ }, "dependencies": { "@github/actions-workflow-parser": "*", + "@github/actions-expressions": "*", "vscode-languageserver-textdocument": "^1.0.7", "vscode-languageserver-types": "^3.17.2", "yaml": "^2.1.1" @@ -58,4 +59,4 @@ "ts-jest": "^29.0.3", "typescript": "^4.8.4" } -} +} \ No newline at end of file diff --git a/actions-languageservice/src/complete.expressions.test.ts b/actions-languageservice/src/complete.expressions.test.ts index 6af1866..be97f15 100644 --- a/actions-languageservice/src/complete.expressions.test.ts +++ b/actions-languageservice/src/complete.expressions.test.ts @@ -1,4 +1,5 @@ import {data} from "@github/actions-expressions"; +import {CompletionItemKind} from "vscode-languageserver-types"; import {complete, getExpressionInput} from "./complete"; import {ContextProviderConfig} from "./context-providers/config"; import {registerLogger} from "./log"; @@ -632,4 +633,37 @@ jobs: expect(result.map(x => x.label)).toEqual(["color"]); }); }); + + it("context completion items include kind and insert text", async () => { + const input = ` + on: push + + jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: echo \${{ | }}.txt + `; + + const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + + // Built-in function + const toJSON = result.find(x => x.label === "toJson"); + expect(toJSON).toBeDefined(); + expect(toJSON!.kind).toBe(CompletionItemKind.Function); + expect(toJSON!.insertText).toBe("toJson()"); + + // Function from context + const hashFiles = result.find(x => x.label === "hashFiles"); + expect(hashFiles).toBeDefined(); + expect(hashFiles!.kind).toBe(CompletionItemKind.Function); + expect(hashFiles!.insertText).toBe("hashFiles()"); + + // Not a function + const github = result.find(x => x.label === "github"); + expect(github).toBeDefined(); + expect(github!.kind).toBe(CompletionItemKind.Variable); + expect(github!.insertText).toBeUndefined(); + }); }); diff --git a/actions-languageservice/src/complete.ts b/actions-languageservice/src/complete.ts index cc714ab..b675281 100644 --- a/actions-languageservice/src/complete.ts +++ b/actions-languageservice/src/complete.ts @@ -9,7 +9,7 @@ import {MappingToken} from "@github/actions-workflow-parser/templates/tokens/map import {TokenType} from "@github/actions-workflow-parser/templates/tokens/types"; import {File} from "@github/actions-workflow-parser/workflows/file"; import {Position, TextDocument} from "vscode-languageserver-textdocument"; -import {CompletionItem, CompletionItemTag, Range, TextEdit} from "vscode-languageserver-types"; +import {CompletionItem, CompletionItemKind, CompletionItemTag, Range, TextEdit} from "vscode-languageserver-types"; import {ContextProviderConfig} from "./context-providers/config"; import {getContext, Mode} from "./context-providers/default"; import {getWorkflowContext, WorkflowContext} from "./context/workflow-context"; @@ -95,7 +95,13 @@ export async function complete( const allowedContext = getAllowedContext(token, parent); const context = await getContext(allowedContext, contextProviderConfig, workflowContext, Mode.Completion); - return completeExpression(expressionInput, context, []); + return completeExpression(expressionInput, context, []).map(item => { + return { + label: item.label, + insertText: item.function ? item.label + "()" : undefined, + kind: item.function ? CompletionItemKind.Function : CompletionItemKind.Variable + }; + }); } } From 3cbafc3177f79716fc3864e3ea011c02d9a64d71 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 15 Dec 2022 00:16:40 +0000 Subject: [PATCH 24/30] Update @github/actions-workflow-parser --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3553df5..818e19c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -700,9 +700,9 @@ "link": true }, "node_modules/@github/actions-workflow-parser": { - "version": "0.0.34", - "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.34/e369bdaca17cde594ad7420cd0df0efcd2804dc0", - "integrity": "sha512-ttjYUoO2bvi5v/SR267QpDhWJ+I4tXQlSMnscjqUp76IDLxS73I7nCD3KP7g4VxzHmT5j8AxSdjEE25UWpl43g==", + "version": "0.0.35", + "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.35/0e88d541486f7c8772c5640fc13fac630cfaeaa8", + "integrity": "sha512-OuNEuqUH4AOfWd2xb8VRl7KwJrtiZu1ic0b27lmadwvK8qgRhPHxvS+QICEc+JtFbbVWpAA2ymh8I1U35639mA==", "license": "MIT", "dependencies": { "@github/actions-expressions": "*", @@ -13537,9 +13537,9 @@ } }, "@github/actions-workflow-parser": { - "version": "0.0.34", - "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.34/e369bdaca17cde594ad7420cd0df0efcd2804dc0", - "integrity": "sha512-ttjYUoO2bvi5v/SR267QpDhWJ+I4tXQlSMnscjqUp76IDLxS73I7nCD3KP7g4VxzHmT5j8AxSdjEE25UWpl43g==", + "version": "0.0.35", + "resolved": "https://npm.pkg.github.com/download/@github/actions-workflow-parser/0.0.35/0e88d541486f7c8772c5640fc13fac630cfaeaa8", + "integrity": "sha512-OuNEuqUH4AOfWd2xb8VRl7KwJrtiZu1ic0b27lmadwvK8qgRhPHxvS+QICEc+JtFbbVWpAA2ymh8I1U35639mA==", "requires": { "@github/actions-expressions": "*", "yaml": "^2.0.0-8" From 45764915bc64d7617bb5fbb3e98ebe2b89ba0b45 Mon Sep 17 00:00:00 2001 From: Christopher Schleiden Date: Thu, 15 Dec 2022 15:18:59 +0100 Subject: [PATCH 25/30] Account for cursor and newline during expression auto-completeion --- .../src/complete.expressions.test.ts | 40 +++++++++++++++++++ actions-languageservice/src/complete.ts | 15 ++----- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/actions-languageservice/src/complete.expressions.test.ts b/actions-languageservice/src/complete.expressions.test.ts index 6af1866..fb2df57 100644 --- a/actions-languageservice/src/complete.expressions.test.ts +++ b/actions-languageservice/src/complete.expressions.test.ts @@ -30,6 +30,10 @@ describe("expressions", () => { expect(test("${{ gh |")).toBe(" gh "); expect(test("${{ gh |}}")).toBe(" gh "); + expect(test("${{ vars| == 'test' }}")).toBe(" vars"); + expect(test("${{ fromJso|('test').bar == 'test' }}")).toBe(" fromJso"); + expect(test("${{ github.| == 'test' }}")).toBe(" github."); + expect(test("test ${{ github.| == 'test' }}")).toBe(" github."); expect(test("${{ vars }} ${{ gh |}}")).toBe(" gh "); }); @@ -70,6 +74,42 @@ describe("expressions", () => { ]); }); + it("single region with existing condition", async () => { + const input = "run-name: ${{ g| == 'test' }}"; + const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + + expect(result.map(x => x.label)).toEqual([ + "github", + "inputs", + "vars", + "contains", + "endsWith", + "format", + "fromJson", + "join", + "startsWith", + "toJson" + ]); + }); + + it("multiple regions with partial function", async () => { + const input = "run-name: Run a ${{ inputs.test }} one-line script ${{ from|('test') == inputs.name }}"; + const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + + expect(result.map(x => x.label)).toEqual([ + "github", + "inputs", + "vars", + "contains", + "endsWith", + "format", + "fromJson", + "join", + "startsWith", + "toJson" + ]); + }); + it("multiple regions", async () => { const input = "run-name: test-${{ github }}-${{ | }}"; const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); diff --git a/actions-languageservice/src/complete.ts b/actions-languageservice/src/complete.ts index cc714ab..3074a45 100644 --- a/actions-languageservice/src/complete.ts +++ b/actions-languageservice/src/complete.ts @@ -3,7 +3,7 @@ import {convertWorkflowTemplate, isSequence, isString, parseWorkflow} from "@git import {ErrorPolicy} from "@github/actions-workflow-parser/model/convert"; import {DefinitionType} from "@github/actions-workflow-parser/templates/schema/definition-type"; import {StringDefinition} from "@github/actions-workflow-parser/templates/schema/string-definition"; -import {CLOSE_EXPRESSION, OPEN_EXPRESSION} from "@github/actions-workflow-parser/templates/template-constants"; +import {OPEN_EXPRESSION} from "@github/actions-workflow-parser/templates/template-constants"; import {TemplateToken} from "@github/actions-workflow-parser/templates/tokens/index"; import {MappingToken} from "@github/actions-workflow-parser/templates/tokens/mapping-token"; import {TokenType} from "@github/actions-workflow-parser/templates/tokens/types"; @@ -29,14 +29,7 @@ export function getExpressionInput(input: string, pos: number): string { return input; } - // Find end marker after the cursor position - let endPos = input.indexOf(CLOSE_EXPRESSION, pos); - if (endPos === -1) { - // Assume an unfinished expression like "${{ someinput.|" - endPos = input.length; - } - - return input.substring(startPos + OPEN_EXPRESSION.length, endPos); + return input.substring(startPos + OPEN_EXPRESSION.length, pos); } export async function complete( @@ -85,9 +78,9 @@ export async function complete( if (token.range!.start[0] !== token.range!.end[0]) { const lines = currentInput.split("\n"); const linesBeforeCusor = lines.slice(0, lineDiff); - relCharPos = linesBeforeCusor.join("\n").length + newPos.character; + relCharPos = linesBeforeCusor.join("\n").length + 1 + newPos.character; } else { - relCharPos = newPos.character - token.range!.start[1]; + relCharPos = newPos.character - token.range!.start[1] + 1; } const expressionInput = (getExpressionInput(currentInput, relCharPos) || "").trim(); From 1227a124161905f2332624b4838259cdcfd0756c Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 15 Dec 2022 15:07:54 +0000 Subject: [PATCH 26/30] v0.1.56 --- actions-languageserver/package.json | 4 ++-- actions-languageservice/package.json | 2 +- browser-playground/package.json | 4 ++-- lerna.json | 2 +- package-lock.json | 14 +++++++------- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/actions-languageserver/package.json b/actions-languageserver/package.json index b38e4c5..e1d65a7 100644 --- a/actions-languageserver/package.json +++ b/actions-languageserver/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageserver", - "version": "0.1.55", + "version": "0.1.56", "description": "Language server for GitHub Actions", "license": "MIT", "type": "module", @@ -38,7 +38,7 @@ "prettier-fix": "prettier --write ." }, "dependencies": { - "@github/actions-languageservice": "^0.1.55", + "@github/actions-languageservice": "^0.1.56", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", diff --git a/actions-languageservice/package.json b/actions-languageservice/package.json index e441757..5ab20fe 100644 --- a/actions-languageservice/package.json +++ b/actions-languageservice/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageservice", - "version": "0.1.55", + "version": "0.1.56", "description": "Language service for GitHub Actions", "license": "MIT", "type": "module", diff --git a/browser-playground/package.json b/browser-playground/package.json index db7adea..d4857e6 100644 --- a/browser-playground/package.json +++ b/browser-playground/package.json @@ -1,12 +1,12 @@ { "name": "browser-playground", - "version": "0.1.55", + "version": "0.1.56", "description": "", "private": true, "main": "index.js", "type": "module", "dependencies": { - "@github/actions-languageserver": "^0.1.55", + "@github/actions-languageserver": "^0.1.56", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", diff --git a/lerna.json b/lerna.json index 62b0ac4..dbdf586 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useWorkspaces": true, - "version": "0.1.55" + "version": "0.1.56" } diff --git a/package-lock.json b/package-lock.json index 818e19c..ec6e2dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,10 +16,10 @@ }, "actions-languageserver": { "name": "@github/actions-languageserver", - "version": "0.1.55", + "version": "0.1.56", "license": "MIT", "dependencies": { - "@github/actions-languageservice": "^0.1.55", + "@github/actions-languageservice": "^0.1.56", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", @@ -40,7 +40,7 @@ }, "actions-languageservice": { "name": "@github/actions-languageservice", - "version": "0.1.55", + "version": "0.1.56", "license": "MIT", "dependencies": { "@github/actions-workflow-parser": "*", @@ -61,10 +61,10 @@ } }, "browser-playground": { - "version": "0.1.55", + "version": "0.1.56", "license": "MIT", "dependencies": { - "@github/actions-languageserver": "^0.1.55", + "@github/actions-languageserver": "^0.1.56", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", @@ -13507,7 +13507,7 @@ "@github/actions-languageserver": { "version": "file:actions-languageserver", "requires": { - "@github/actions-languageservice": "^0.1.55", + "@github/actions-languageservice": "^0.1.56", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "@types/jest": "^29.0.3", @@ -16292,7 +16292,7 @@ "browser-playground": { "version": "file:browser-playground", "requires": { - "@github/actions-languageserver": "^0.1.55", + "@github/actions-languageserver": "^0.1.56", "css-loader": "^6.7.2", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", From ce03d6347ea08b06e53878ec6c3a8376d1326b15 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 15 Dec 2022 15:32:09 +0000 Subject: [PATCH 27/30] v0.1.57 --- actions-languageserver/package.json | 4 ++-- actions-languageservice/package.json | 2 +- browser-playground/package.json | 4 ++-- lerna.json | 2 +- package-lock.json | 14 +++++++------- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/actions-languageserver/package.json b/actions-languageserver/package.json index e1d65a7..d6e9bed 100644 --- a/actions-languageserver/package.json +++ b/actions-languageserver/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageserver", - "version": "0.1.56", + "version": "0.1.57", "description": "Language server for GitHub Actions", "license": "MIT", "type": "module", @@ -38,7 +38,7 @@ "prettier-fix": "prettier --write ." }, "dependencies": { - "@github/actions-languageservice": "^0.1.56", + "@github/actions-languageservice": "^0.1.57", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", diff --git a/actions-languageservice/package.json b/actions-languageservice/package.json index 5ab20fe..bba26e8 100644 --- a/actions-languageservice/package.json +++ b/actions-languageservice/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageservice", - "version": "0.1.56", + "version": "0.1.57", "description": "Language service for GitHub Actions", "license": "MIT", "type": "module", diff --git a/browser-playground/package.json b/browser-playground/package.json index d4857e6..57e65b9 100644 --- a/browser-playground/package.json +++ b/browser-playground/package.json @@ -1,12 +1,12 @@ { "name": "browser-playground", - "version": "0.1.56", + "version": "0.1.57", "description": "", "private": true, "main": "index.js", "type": "module", "dependencies": { - "@github/actions-languageserver": "^0.1.56", + "@github/actions-languageserver": "^0.1.57", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", diff --git a/lerna.json b/lerna.json index dbdf586..0a1897d 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useWorkspaces": true, - "version": "0.1.56" + "version": "0.1.57" } diff --git a/package-lock.json b/package-lock.json index ec6e2dd..f48743b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,10 +16,10 @@ }, "actions-languageserver": { "name": "@github/actions-languageserver", - "version": "0.1.56", + "version": "0.1.57", "license": "MIT", "dependencies": { - "@github/actions-languageservice": "^0.1.56", + "@github/actions-languageservice": "^0.1.57", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", @@ -40,7 +40,7 @@ }, "actions-languageservice": { "name": "@github/actions-languageservice", - "version": "0.1.56", + "version": "0.1.57", "license": "MIT", "dependencies": { "@github/actions-workflow-parser": "*", @@ -61,10 +61,10 @@ } }, "browser-playground": { - "version": "0.1.56", + "version": "0.1.57", "license": "MIT", "dependencies": { - "@github/actions-languageserver": "^0.1.56", + "@github/actions-languageserver": "^0.1.57", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", @@ -13507,7 +13507,7 @@ "@github/actions-languageserver": { "version": "file:actions-languageserver", "requires": { - "@github/actions-languageservice": "^0.1.56", + "@github/actions-languageservice": "^0.1.57", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "@types/jest": "^29.0.3", @@ -16292,7 +16292,7 @@ "browser-playground": { "version": "file:browser-playground", "requires": { - "@github/actions-languageserver": "^0.1.56", + "@github/actions-languageserver": "^0.1.57", "css-loader": "^6.7.2", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", From b3c97c4c0ff6277e70417e13164aac836e95320f Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Thu, 15 Dec 2022 10:33:57 -0500 Subject: [PATCH 28/30] Bump expressions package version --- package-lock.json | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3553df5..5afb05d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,6 +43,7 @@ "version": "0.1.55", "license": "MIT", "dependencies": { + "@github/actions-expressions": "*", "@github/actions-workflow-parser": "*", "vscode-languageserver-textdocument": "^1.0.7", "vscode-languageserver-types": "^3.17.2", @@ -683,9 +684,9 @@ "dev": true }, "node_modules/@github/actions-expressions": { - "version": "0.0.7", - "resolved": "https://npm.pkg.github.com/download/@github/actions-expressions/0.0.7/deed2be11b9f74791730303b6e33f9aca701d6a7", - "integrity": "sha512-PG8dQUafOckk/ny5O1wcUcfml5IZM8REoi7WBBY1HfpnRR7mL7gqTczQEmQWNTpoHb9f1VQK47y2hBZTOg9Y7g==", + "version": "0.0.8", + "resolved": "https://npm.pkg.github.com/download/@github/actions-expressions/0.0.8/055f455fcb0ed907f52c349b9385728aeed38f9a", + "integrity": "sha512-SPuGfnjgKAbMzJNCk4sZPAK2bxHlRXDJCk6vrwIi9VJL16Eh1YyiyM4fU9kV5EXEE5AV9aPFlZAPXu6t0mmBNw==", "license": "MIT", "engines": { "node": ">= 16" @@ -13500,9 +13501,9 @@ "dev": true }, "@github/actions-expressions": { - "version": "0.0.7", - "resolved": "https://npm.pkg.github.com/download/@github/actions-expressions/0.0.7/deed2be11b9f74791730303b6e33f9aca701d6a7", - "integrity": "sha512-PG8dQUafOckk/ny5O1wcUcfml5IZM8REoi7WBBY1HfpnRR7mL7gqTczQEmQWNTpoHb9f1VQK47y2hBZTOg9Y7g==" + "version": "0.0.8", + "resolved": "https://npm.pkg.github.com/download/@github/actions-expressions/0.0.8/055f455fcb0ed907f52c349b9385728aeed38f9a", + "integrity": "sha512-SPuGfnjgKAbMzJNCk4sZPAK2bxHlRXDJCk6vrwIi9VJL16Eh1YyiyM4fU9kV5EXEE5AV9aPFlZAPXu6t0mmBNw==" }, "@github/actions-languageserver": { "version": "file:actions-languageserver", @@ -13524,6 +13525,7 @@ "@github/actions-languageservice": { "version": "file:actions-languageservice", "requires": { + "@github/actions-expressions": "*", "@github/actions-workflow-parser": "*", "@types/jest": "^29.0.3", "jest": "^29.0.3", From 9130ef0c6510e8fa68687b446df8019d9d81bb29 Mon Sep 17 00:00:00 2001 From: Josh Gross Date: Thu, 15 Dec 2022 10:48:28 -0500 Subject: [PATCH 29/30] Avoid inserting unnecessary parentheses after functions --- .../src/complete.expressions.test.ts | 16 ++++++++++++ actions-languageservice/src/complete.ts | 25 +++++++++++++------ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/actions-languageservice/src/complete.expressions.test.ts b/actions-languageservice/src/complete.expressions.test.ts index a098a9d..6b5e41b 100644 --- a/actions-languageservice/src/complete.expressions.test.ts +++ b/actions-languageservice/src/complete.expressions.test.ts @@ -706,4 +706,20 @@ jobs: expect(github!.kind).toBe(CompletionItemKind.Variable); expect(github!.insertText).toBeUndefined(); }); + + it("function parentheses are not inserted when parentheses already exist", async () => { + const input = ` + on: push + + jobs: + test: + runs-on: ubuntu-latest + steps: + - run: echo \${{ toJS|(github.event) }} + `; + + const result = await complete(...getPositionFromCursor(input), undefined, contextProviderConfig); + + expect(result.find(x => x.label === "toJson")!.insertText).toBe("toJson"); + }); }); diff --git a/actions-languageservice/src/complete.ts b/actions-languageservice/src/complete.ts index cecfb5b..0477b19 100644 --- a/actions-languageservice/src/complete.ts +++ b/actions-languageservice/src/complete.ts @@ -1,4 +1,5 @@ import {complete as completeExpression} from "@github/actions-expressions"; +import {CompletionItem as ExpressionCompletionItem} from "@github/actions-expressions/completion"; import {convertWorkflowTemplate, isSequence, isString, parseWorkflow} from "@github/actions-workflow-parser"; import {ErrorPolicy} from "@github/actions-workflow-parser/model/convert"; import {DefinitionType} from "@github/actions-workflow-parser/templates/schema/definition-type"; @@ -87,13 +88,9 @@ export async function complete( const allowedContext = token.definitionInfo?.allowedContext || []; const context = await getContext(allowedContext, contextProviderConfig, workflowContext, Mode.Completion); - return completeExpression(expressionInput, context, []).map(item => { - return { - label: item.label, - insertText: item.function ? item.label + "()" : undefined, - kind: item.function ? CompletionItemKind.Function : CompletionItemKind.Variable - }; - }); + return completeExpression(expressionInput, context, []).map(item => + mapExpressionCompletionItem(item, currentInput[relCharPos]) + ); } } @@ -198,3 +195,17 @@ function filterAndSortCompletionOptions(options: Value[], existingValues?: Set a.label.localeCompare(b.label)); return options; } + +function mapExpressionCompletionItem(item: ExpressionCompletionItem, charAfterPos: string): CompletionItem { + let insertText: string | undefined; + // Insert parentheses if the cursor is after a function + // and the function does not have any parantheses already + if (item.function) { + insertText = charAfterPos === "(" ? item.label : item.label + "()"; + } + return { + label: item.label, + insertText: insertText, + kind: item.function ? CompletionItemKind.Function : CompletionItemKind.Variable + }; +} From f2b241a447a61dbe51e756e5f1cc3fef3325402f Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 15 Dec 2022 15:59:35 +0000 Subject: [PATCH 30/30] v0.1.58 --- actions-languageserver/package.json | 4 ++-- actions-languageservice/package.json | 6 +++--- browser-playground/package.json | 4 ++-- lerna.json | 2 +- package-lock.json | 14 +++++++------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/actions-languageserver/package.json b/actions-languageserver/package.json index d6e9bed..91a5361 100644 --- a/actions-languageserver/package.json +++ b/actions-languageserver/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageserver", - "version": "0.1.57", + "version": "0.1.58", "description": "Language server for GitHub Actions", "license": "MIT", "type": "module", @@ -38,7 +38,7 @@ "prettier-fix": "prettier --write ." }, "dependencies": { - "@github/actions-languageservice": "^0.1.57", + "@github/actions-languageservice": "^0.1.58", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", diff --git a/actions-languageservice/package.json b/actions-languageservice/package.json index 586ec76..d562436 100644 --- a/actions-languageservice/package.json +++ b/actions-languageservice/package.json @@ -1,6 +1,6 @@ { "name": "@github/actions-languageservice", - "version": "0.1.57", + "version": "0.1.58", "description": "Language service for GitHub Actions", "license": "MIT", "type": "module", @@ -38,8 +38,8 @@ "prettier-fix": "prettier --write ." }, "dependencies": { - "@github/actions-workflow-parser": "*", "@github/actions-expressions": "*", + "@github/actions-workflow-parser": "*", "vscode-languageserver-textdocument": "^1.0.7", "vscode-languageserver-types": "^3.17.2", "yaml": "^2.1.1" @@ -59,4 +59,4 @@ "ts-jest": "^29.0.3", "typescript": "^4.8.4" } -} \ No newline at end of file +} diff --git a/browser-playground/package.json b/browser-playground/package.json index 57e65b9..f87528e 100644 --- a/browser-playground/package.json +++ b/browser-playground/package.json @@ -1,12 +1,12 @@ { "name": "browser-playground", - "version": "0.1.57", + "version": "0.1.58", "description": "", "private": true, "main": "index.js", "type": "module", "dependencies": { - "@github/actions-languageserver": "^0.1.57", + "@github/actions-languageserver": "^0.1.58", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", diff --git a/lerna.json b/lerna.json index 0a1897d..15cc41f 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useWorkspaces": true, - "version": "0.1.57" + "version": "0.1.58" } diff --git a/package-lock.json b/package-lock.json index 3af4e69..fd48861 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,10 +16,10 @@ }, "actions-languageserver": { "name": "@github/actions-languageserver", - "version": "0.1.57", + "version": "0.1.58", "license": "MIT", "dependencies": { - "@github/actions-languageservice": "^0.1.57", + "@github/actions-languageservice": "^0.1.58", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "vscode-languageserver": "^8.0.2", @@ -40,7 +40,7 @@ }, "actions-languageservice": { "name": "@github/actions-languageservice", - "version": "0.1.57", + "version": "0.1.58", "license": "MIT", "dependencies": { "@github/actions-expressions": "*", @@ -62,10 +62,10 @@ } }, "browser-playground": { - "version": "0.1.57", + "version": "0.1.58", "license": "MIT", "dependencies": { - "@github/actions-languageserver": "^0.1.57", + "@github/actions-languageserver": "^0.1.58", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2", "monaco-languageclient": "^4.0.3", @@ -13508,7 +13508,7 @@ "@github/actions-languageserver": { "version": "file:actions-languageserver", "requires": { - "@github/actions-languageservice": "^0.1.57", + "@github/actions-languageservice": "^0.1.58", "@github/actions-workflow-parser": "*", "@octokit/rest": "^19.0.5", "@types/jest": "^29.0.3", @@ -16294,7 +16294,7 @@ "browser-playground": { "version": "file:browser-playground", "requires": { - "@github/actions-languageserver": "^0.1.57", + "@github/actions-languageserver": "^0.1.58", "css-loader": "^6.7.2", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-editor-workers": "^0.34.2",