diff --git a/languageservice/src/hover.test.ts b/languageservice/src/hover.test.ts index ef0908d..b0217e7 100644 --- a/languageservice/src/hover.test.ts +++ b/languageservice/src/hover.test.ts @@ -110,8 +110,7 @@ jobs: `; const result = await hover(...getPositionFromCursor(input)); expect(result).not.toBeUndefined(); - // Cron description is now shown via diagnostics, not hover - expect(result?.contents).toEqual(""); + expect(result?.contents).toEqual("Runs at 0 and 30 minutes past the hour, at 00:00 and 12:00"); }); it("on a cron mapping key", async () => { diff --git a/languageservice/src/hover.ts b/languageservice/src/hover.ts index b8b6481..873abea 100644 --- a/languageservice/src/hover.ts +++ b/languageservice/src/hover.ts @@ -2,6 +2,8 @@ import {data, DescriptionDictionary, Parser} from "@actions/expressions"; import {FunctionDefinition, FunctionInfo} from "@actions/expressions/funcs/info"; import {Lexer} from "@actions/expressions/lexer"; import {parseAction} from "@actions/workflow-parser/actions/action-parser"; +import {isString} from "@actions/workflow-parser"; +import {getCronDescription} from "@actions/workflow-parser/model/converter/cron"; import {ErrorPolicy} from "@actions/workflow-parser/model/convert"; import {splitAllowedContext} from "@actions/workflow-parser/templates/allowed-context"; import {TemplateToken} from "@actions/workflow-parser/templates/tokens/template-token"; @@ -134,6 +136,17 @@ export async function hover(document: TextDocument, position: Position, config?: // Non-expression hover: show the schema description for the YAML key or value info(`Calculating hover for token with definition ${hoverToken.definition.key}`); + // Check for cron expression hover + if (isString(hoverToken) && hoverToken.definition.key === "cron-pattern") { + const cronDescription = getCronDescription(hoverToken.value); + if (cronDescription) { + return { + contents: cronDescription, + range: mapRange(hoverToken.range) + }; + } + } + let description: string; if (!isAction && tokenResult.parent && isReusableWorkflowJobInput(tokenResult)) { // Reusable workflow call: fetch the called workflow's input descriptions