diff --git a/actions-languageservice/src/complete.ts b/actions-languageservice/src/complete.ts index 1ba93ad..97c8e84 100644 --- a/actions-languageservice/src/complete.ts +++ b/actions-languageservice/src/complete.ts @@ -1,6 +1,8 @@ import {complete as completeExpression} from "@github/actions-expressions"; 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"; +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 {TemplateToken} from "@github/actions-workflow-parser/templates/tokens/index"; import {MappingToken} from "@github/actions-workflow-parser/templates/tokens/mapping-token"; @@ -72,9 +74,10 @@ export async function complete( if (token) { // We don't have any way of specifying that a token in the workflow schema is alwyas an expression. For now these // are only the job and step level `if` nodes, so check for those here. - const isIfKey = keyToken && isString(keyToken) && keyToken.value === "if"; + const isExpression = + token.definition?.definitionType === DefinitionType.String && (token.definition as StringDefinition).isExpression; const containsExpression = isString(token) && token.value.indexOf(OPEN_EXPRESSION) >= 0; - if (isString(token) && (isIfKey || containsExpression)) { + if (isString(token) && (isExpression || containsExpression)) { const currentInput = token.value; // Transform the overall position into a node relative position diff --git a/actions-languageservice/src/validate.expressions.test.ts b/actions-languageservice/src/validate.expressions.test.ts index c73f8c8..9a78a59 100644 --- a/actions-languageservice/src/validate.expressions.test.ts +++ b/actions-languageservice/src/validate.expressions.test.ts @@ -7,7 +7,13 @@ describe("expression validation", () => { const result = await validate( createDocument( "wf.yaml", - "on: push\nrun-name: name-${{ github.does-not-exist }}\njobs:\n build:\n runs-on: ubuntu-latest\n steps:\n - run: echo" + `on: push +run-name: name-\${{ github.does-not-exist }} +jobs: + build: + runs-on: ubuntu-latest + steps: + - run: echo` ) ); @@ -73,4 +79,38 @@ jobs: expect(result).toEqual([]); }); + + describe("expressions without markers", () => { + it("access invalid context field", async () => { + const result = await validate( + createDocument( + "wf.yaml", + `on: push +jobs: + build: + runs-on: ubuntu-latest + steps: + - run: echo + if: github.does-not-exist` + ) + ); + + expect(result).toEqual([ + { + message: "Context access might be invalid: does-not-exist", + range: { + start: { + character: 12, + line: 6 + }, + end: { + character: 33, + line: 6 + } + }, + severity: DiagnosticSeverity.Warning + } + ]); + }); + }); });