@actions/languageserver 0.3.41 → 0.3.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.bundle.cjs +103 -86
  2. package/package.json +4 -4
@@ -22291,6 +22291,16 @@ function walkTreeToFindStatusFunctionCalls(tree) {
22291
22291
  }
22292
22292
  return false;
22293
22293
  }
22294
+ function validateRunsIfCondition(context, token, condition) {
22295
+ const allowedContext = token.definitionInfo?.allowedContext || [];
22296
+ try {
22297
+ ExpressionToken.validateExpression(condition, allowedContext);
22298
+ } catch (err) {
22299
+ context.error(token, err);
22300
+ return void 0;
22301
+ }
22302
+ return condition;
22303
+ }
22294
22304
 
22295
22305
  // ../workflow-parser/dist/model/converter/container.js
22296
22306
  function convertToJobContainer(context, container) {
@@ -23162,7 +23172,7 @@ function getOptionsWithDefaults(options) {
23162
23172
  }
23163
23173
 
23164
23174
  // ../workflow-parser/dist/action-v1.0.min.json
23165
- var action_v1_0_min_default = { definitions: { "action-root": { description: "Action file", mapping: { properties: { name: "string", description: "string", inputs: "inputs", outputs: "outputs", runs: "runs" }, "loose-key-type": "non-empty-string", "loose-value-type": "any" } }, "action-root-strict": { description: "GitHub Action manifest file (action.yml/action.yaml) that defines an action's metadata, inputs, outputs, and execution configuration.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions)", mapping: { properties: { name: { type: "non-empty-string", required: true, description: "The name of your action. GitHub displays the name in the Actions tab to help visually identify actions in each job.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#name)" }, description: { type: "string", required: true, description: "A short description of the action. GitHub displays this description in the Actions Marketplace.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#description)" }, author: { type: "string", description: "The name of the action's author.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#author)" }, inputs: "inputs-strict", outputs: "outputs", runs: { type: "runs-strict", required: true }, branding: "branding" } } }, inputs: { mapping: { "loose-key-type": "non-empty-string", "loose-value-type": "input" } }, "inputs-strict": { description: "Input parameters allow you to specify data that the action expects to use during runtime. GitHub stores input parameters as environment variables. Inputs ids with uppercase letters are converted to lowercase during runtime.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#inputs)", mapping: { "loose-key-type": "non-empty-string", "loose-value-type": "input-strict" } }, input: { mapping: { properties: { default: "input-default-context" }, "loose-key-type": "non-empty-string", "loose-value-type": "any" } }, "input-strict": { description: "An input parameter for this action.", mapping: { properties: { description: { type: "string", description: "A string description of the input parameter.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#inputsinput_iddescription)" }, required: { type: "boolean", description: "A boolean to indicate whether the action requires the input parameter. Set to true when the parameter is required.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#inputsinput_idrequired)" }, default: { type: "input-default-context", description: "A string representing the default value. The default value is used when an input parameter isn't specified in a workflow file.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#inputsinput_iddefault)" }, deprecationMessage: { type: "string", description: "A string shown to users using the deprecated input, warning them that the input is deprecated and mentioning any alternatives.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#inputsinput_iddeprecationmessage)" } }, "loose-key-type": "non-empty-string", "loose-value-type": "any" } }, "input-default-context": { description: "A string representing the default value. The default value is used when an input parameter isn't specified in a workflow file.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#inputsinput_iddefault)", context: ["github", "strategy", "matrix", "job", "runner", "hashFiles(1,255)"], string: {} }, outputs: { description: "Output parameters allow you to declare data that an action sets. Actions that run later in a workflow can use the output data set in previously run actions.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#outputs-for-composite-actions)", mapping: { "loose-key-type": "non-empty-string", "loose-value-type": "output-definition" } }, "output-definition": { description: "An output parameter for this action.", mapping: { properties: { description: { type: "string", description: "A string description of the output parameter.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#outputsoutput_iddescription)" }, value: { type: "output-value", description: "The value that the output parameter will be mapped to. You can set this to a string or an expression with context.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#outputsoutput_idvalue)" } } } }, "output-value": { description: "The value that the output parameter will be mapped to. You can set this to a string or an expression with context.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#outputsoutput_idvalue)", context: ["github", "strategy", "matrix", "steps", "inputs", "job", "runner", "env"], string: {} }, "runs-if": { description: "Condition to control when this action's pre or post script runs.", context: ["runner", "github", "job", "strategy", "matrix", "env", "inputs", "always(0,0)", "success(0,0)", "failure(0,0)", "cancelled(0,0)"], string: {} }, runs: { "one-of": ["container-runs", "node-runs", "composite-runs", "plugin-runs"] }, "runs-strict": { description: "Specifies whether this is a JavaScript action, a composite action, or a Docker container action and how the action is executed.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runs)", "one-of": ["container-runs-strict", "node-runs-strict", "composite-runs-strict"] }, "plugin-runs": { mapping: { properties: { plugin: "non-empty-string" } } }, "container-runs": { mapping: { properties: { using: "non-empty-string", image: "non-empty-string", entrypoint: "non-empty-string", args: "container-runs-args", env: "container-runs-env", "pre-entrypoint": "non-empty-string", "pre-if": "non-empty-string", "post-entrypoint": "non-empty-string", "post-if": "non-empty-string" } } }, "container-runs-args": { description: "An array of strings that define the inputs for a Docker container. Inputs can include hardcoded strings. GitHub passes the args to the container's ENTRYPOINT when the container starts up.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsargs)", sequence: { "item-type": "container-runs-context" } }, "container-runs-env": { description: "Specifies a key/value map of environment variables to set in the container environment.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsenv)", context: ["inputs"], mapping: { "loose-key-type": "non-empty-string", "loose-value-type": "string" } }, "container-runs-context": { context: ["inputs"], string: {} }, "node-runs": { mapping: { properties: { using: "non-empty-string", main: "non-empty-string", pre: "non-empty-string", "pre-if": "non-empty-string", post: "non-empty-string", "post-if": "non-empty-string" } } }, "composite-runs": { mapping: { properties: { using: "non-empty-string", steps: "composite-steps" } } }, "container-runs-strict": { description: "Configuration for Docker container actions.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runs)", mapping: { properties: { using: { type: "using", required: true, description: "The runtime used to execute the action. Must be docker for Docker container actions.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsusing)" }, image: { type: "non-empty-string", required: true, description: "The Docker image to use as the container to run the action. The value can be the Docker base image name, a local Dockerfile in your repository, or a public image in Docker Hub or another registry.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsimage)" }, entrypoint: { type: "non-empty-string", description: "Overrides the Docker ENTRYPOINT in the Dockerfile, or sets it if one wasn't already specified.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsentrypoint)" }, args: "container-runs-args", env: "container-runs-env", "pre-entrypoint": { type: "non-empty-string", description: "Allows you to run a script before the entrypoint action begins.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspre-entrypoint)" }, "pre-if": { type: "runs-if", description: "Allows you to define conditions for the pre: action execution. The pre: action will only run if the conditions in pre-if are met. If not set, then pre-if defaults to always().\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspre-if)" }, "post-entrypoint": { type: "non-empty-string", description: "Allows you to run a cleanup script once the runs.entrypoint action has completed.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspost-entrypoint)" }, "post-if": { type: "runs-if", description: "Allows you to define conditions for the post: action execution. The post: action will only run if the conditions in post-if are met. If not set, then post-if defaults to always().\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspost-if)" } } } }, "node-runs-strict": { description: "Configuration for JavaScript actions executed with Node.js.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runs)", mapping: { properties: { using: { type: "using", required: true, description: "The runtime used to execute the action. Use node20 or node24 for JavaScript actions.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsusing)" }, main: { type: "non-empty-string", required: true, description: "The file that contains your action code. The runtime specified in using executes this file.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsmain)" }, pre: { type: "non-empty-string", description: "Allows you to run a script at the start of a job, before the main: action begins. You can use pre: to run prerequisite setup scripts.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspre)" }, "pre-if": { type: "runs-if", description: "Allows you to define conditions for the pre: action execution. The pre: action will only run if the conditions in pre-if are met. If not set, then pre-if defaults to always().\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspre-if)" }, post: { type: "non-empty-string", description: "Allows you to run a script at the end of a job, once the main: action has completed. You can use post: to run cleanup scripts.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspost)" }, "post-if": { type: "runs-if", description: "Allows you to define conditions for the post: action execution. The post: action will only run if the conditions in post-if are met. If not set, then post-if defaults to always().\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspost-if)" } } } }, "composite-runs-strict": { description: "Configuration for composite actions that run multiple steps.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runs)", mapping: { properties: { using: { type: "using", required: true, description: "The runtime used to execute the action. Must be composite for composite actions.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsusing)" }, steps: { type: "composite-steps", required: true } } } }, "composite-steps": { description: "The steps that you plan to run in this action. These can be either run steps or uses steps.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runssteps)", sequence: { "item-type": "composite-step" } }, "composite-step": { description: "A step within a composite action.", "one-of": ["run-step", "uses-step"] }, "run-step": { description: "Runs a command-line program using the operating system's shell.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsrun)", mapping: { properties: { name: { type: "string-steps-context", description: "A name for your step to display on GitHub.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsname)" }, id: { type: "non-empty-string", description: "A unique identifier for the step. You can use the id to reference the step in contexts.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsid)" }, if: { type: "step-if", description: "You can use the if conditional to prevent a step from running unless a condition is met. You can use any supported context and expression to create a conditional.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsif)" }, run: { type: "string-steps-context", required: true, description: "The command you want to run. This can be inline or a script in your action repository.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsrun)" }, shell: { type: "string-steps-context", required: true, description: "The shell where you want to run the command. Any shell supported by the runner can be used. Required if run is set.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsshell)" }, env: "step-env", "continue-on-error": { type: "boolean-steps-context", description: "Prevents the action from failing when a step fails. Set to true to allow the action to pass when this step fails.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepscontinue-on-error)" }, "working-directory": { type: "string-steps-context", description: "Specifies the working directory where the command is run.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsworking-directory)" } } } }, "uses-step": { description: "Runs another action as part of a step in your action.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsuses)", mapping: { properties: { name: { type: "string-steps-context", description: "A name for your step to display on GitHub.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsname)" }, id: { type: "non-empty-string", description: "A unique identifier for the step. You can use the id to reference the step in contexts.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsid)" }, if: { type: "step-if", description: "You can use the if conditional to prevent a step from running unless a condition is met. You can use any supported context and expression to create a conditional.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsif)" }, uses: { type: "non-empty-string", required: true, description: "Selects an action to run as part of a step in your action. An action is a reusable unit of code.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsuses)" }, with: "step-with", env: "step-env", "continue-on-error": { type: "boolean-steps-context", description: "Prevents the action from failing when a step fails. Set to true to allow the action to pass when this step fails.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepscontinue-on-error)" } } } }, "string-steps-context": { context: ["github", "inputs", "strategy", "matrix", "steps", "job", "runner", "env", "hashFiles(1,255)"], string: {} }, "boolean-steps-context": { context: ["github", "inputs", "strategy", "matrix", "steps", "job", "runner", "env", "hashFiles(1,255)"], boolean: {} }, "step-env": { description: "Sets variables for steps to use in the runner environment. You can also set variables for the entire action.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsenv)", context: ["github", "inputs", "strategy", "matrix", "steps", "job", "runner", "env", "hashFiles(1,255)"], mapping: { "loose-key-type": "non-empty-string", "loose-value-type": "string" } }, "step-if": { description: "You can use the if conditional to prevent a step from running unless a condition is met. You can use any supported context and expression to create a conditional.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsif)", context: ["github", "inputs", "strategy", "matrix", "steps", "job", "runner", "env", "always(0,0)", "failure(0,0)", "cancelled(0,0)", "success(0,0)", "hashFiles(1,255)"], string: {} }, "step-with": { description: "A map of the input parameters defined by the action. Each input parameter is a key/value pair.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepswith)", context: ["github", "inputs", "strategy", "matrix", "steps", "job", "runner", "env", "hashFiles(1,255)"], mapping: { "loose-key-type": "non-empty-string", "loose-value-type": "string" } }, branding: { description: "You can use a color and Feather icon to create a badge to personalize and distinguish your action in GitHub Marketplace.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#branding)", mapping: { properties: { icon: { type: "branding-icon", description: "The name of the v4.28.0 Feather icon to use.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#brandingicon)" }, color: { type: "branding-color", description: "The background color of the badge.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#brandingcolor)" } } } }, "branding-icon": { description: "The name of the v4.28.0 Feather icon to use. Brand icons are omitted as well as: coffee, columns, divide-circle, divide-square, divide, frown, hexagon, key, meh, mouse-pointer, smile, tool, x-octagon.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#brandingicon)", "allowed-values": ["activity", "airplay", "alert-circle", "alert-octagon", "alert-triangle", "align-center", "align-justify", "align-left", "align-right", "anchor", "aperture", "archive", "arrow-down-circle", "arrow-down-left", "arrow-down-right", "arrow-down", "arrow-left-circle", "arrow-left", "arrow-right-circle", "arrow-right", "arrow-up-circle", "arrow-up-left", "arrow-up-right", "arrow-up", "at-sign", "award", "bar-chart-2", "bar-chart", "battery-charging", "battery", "bell-off", "bell", "bluetooth", "bold", "book-open", "book", "bookmark", "box", "briefcase", "calendar", "camera-off", "camera", "cast", "check-circle", "check-square", "check", "chevron-down", "chevron-left", "chevron-right", "chevron-up", "chevrons-down", "chevrons-left", "chevrons-right", "chevrons-up", "circle", "clipboard", "clock", "cloud-drizzle", "cloud-lightning", "cloud-off", "cloud-rain", "cloud-snow", "cloud", "code", "command", "compass", "copy", "corner-down-left", "corner-down-right", "corner-left-down", "corner-left-up", "corner-right-down", "corner-right-up", "corner-up-left", "corner-up-right", "cpu", "credit-card", "crop", "crosshair", "database", "delete", "disc", "dollar-sign", "download-cloud", "download", "droplet", "edit-2", "edit-3", "edit", "external-link", "eye-off", "eye", "fast-forward", "feather", "file-minus", "file-plus", "file-text", "file", "film", "filter", "flag", "folder-minus", "folder-plus", "folder", "gift", "git-branch", "git-commit", "git-merge", "git-pull-request", "globe", "grid", "hard-drive", "hash", "headphones", "heart", "help-circle", "home", "image", "inbox", "info", "italic", "layers", "layout", "life-buoy", "link-2", "link", "list", "loader", "lock", "log-in", "log-out", "mail", "map-pin", "map", "maximize-2", "maximize", "menu", "message-circle", "message-square", "mic-off", "mic", "minimize-2", "minimize", "minus-circle", "minus-square", "minus", "monitor", "moon", "more-horizontal", "more-vertical", "move", "music", "navigation-2", "navigation", "octagon", "package", "paperclip", "pause-circle", "pause", "percent", "phone-call", "phone-forwarded", "phone-incoming", "phone-missed", "phone-off", "phone-outgoing", "phone", "pie-chart", "play-circle", "play", "plus-circle", "plus-square", "plus", "pocket", "power", "printer", "radio", "refresh-ccw", "refresh-cw", "repeat", "rewind", "rotate-ccw", "rotate-cw", "rss", "save", "scissors", "search", "send", "server", "settings", "share-2", "share", "shield-off", "shield", "shopping-bag", "shopping-cart", "shuffle", "sidebar", "skip-back", "skip-forward", "slash", "sliders", "smartphone", "speaker", "square", "star", "stop-circle", "sun", "sunrise", "sunset", "tablet", "tag", "target", "terminal", "thermometer", "thumbs-down", "thumbs-up", "toggle-left", "toggle-right", "trash-2", "trash", "trending-down", "trending-up", "triangle", "truck", "tv", "type", "umbrella", "underline", "unlock", "upload-cloud", "upload", "user-check", "user-minus", "user-plus", "user-x", "user", "users", "video-off", "video", "voicemail", "volume-1", "volume-2", "volume-x", "volume", "watch", "wifi-off", "wifi", "wind", "x-circle", "x-square", "x", "zap-off", "zap", "zoom-in", "zoom-out"] }, "branding-color": { description: "The background color of the badge.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#brandingcolor)", "allowed-values": ["white", "yellow", "blue", "green", "orange", "red", "purple", "gray-dark"] }, using: { description: "The runtime used to execute the action.", "allowed-values": ["docker", "node12", "node16", "node20", "node24", "composite"] }, "non-empty-string": { string: { "require-non-empty": true } } } };
23175
+ var action_v1_0_min_default = { definitions: { "action-root": { description: "Action file", mapping: { properties: { name: "string", description: "string", inputs: "inputs", outputs: "outputs", runs: "runs" }, "loose-key-type": "non-empty-string", "loose-value-type": "any" } }, "action-root-strict": { description: "GitHub Action manifest file (action.yml/action.yaml) that defines an action's metadata, inputs, outputs, and execution configuration.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions)", mapping: { properties: { name: { type: "non-empty-string", required: true, description: "The name of your action. GitHub displays the name in the Actions tab to help visually identify actions in each job.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#name)" }, description: { type: "string", required: true, description: "A short description of the action. GitHub displays this description in the Actions Marketplace.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#description)" }, author: { type: "string", description: "The name of the action's author.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#author)" }, inputs: "inputs-strict", outputs: "outputs", runs: { type: "runs-strict", required: true }, branding: "branding" } } }, inputs: { mapping: { "loose-key-type": "non-empty-string", "loose-value-type": "input" } }, "inputs-strict": { description: "Input parameters allow you to specify data that the action expects to use during runtime. GitHub stores input parameters as environment variables. Inputs ids with uppercase letters are converted to lowercase during runtime.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#inputs)", mapping: { "loose-key-type": "non-empty-string", "loose-value-type": "input-strict" } }, input: { mapping: { properties: { default: "input-default-context" }, "loose-key-type": "non-empty-string", "loose-value-type": "any" } }, "input-strict": { description: "An input parameter for this action.", mapping: { properties: { description: { type: "string", description: "A string description of the input parameter.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#inputsinput_iddescription)" }, required: { type: "boolean", description: "A boolean to indicate whether the action requires the input parameter. Set to true when the parameter is required.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#inputsinput_idrequired)" }, default: { type: "input-default-context", description: "A string representing the default value. The default value is used when an input parameter isn't specified in a workflow file.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#inputsinput_iddefault)" }, deprecationMessage: { type: "string", description: "A string shown to users using the deprecated input, warning them that the input is deprecated and mentioning any alternatives.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#inputsinput_iddeprecationmessage)" } }, "loose-key-type": "non-empty-string", "loose-value-type": "any" } }, "input-default-context": { description: "A string representing the default value. The default value is used when an input parameter isn't specified in a workflow file.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#inputsinput_iddefault)", context: ["github", "strategy", "matrix", "job", "runner", "hashFiles(1,255)"], string: {} }, outputs: { description: "Output parameters allow you to declare data that an action sets. Actions that run later in a workflow can use the output data set in previously run actions.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#outputs-for-composite-actions)", mapping: { "loose-key-type": "non-empty-string", "loose-value-type": "output-definition" } }, "output-definition": { description: "An output parameter for this action.", mapping: { properties: { description: { type: "string", description: "A string description of the output parameter.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#outputsoutput_iddescription)" }, value: { type: "output-value", description: "The value that the output parameter will be mapped to. You can set this to a string or an expression with context.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#outputsoutput_idvalue)" } } } }, "output-value": { description: "The value that the output parameter will be mapped to. You can set this to a string or an expression with context.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#outputsoutput_idvalue)", context: ["github", "strategy", "matrix", "steps", "inputs", "job", "runner", "env"], string: {} }, "runs-if": { description: "Condition to control when this action's pre or post script runs.", context: ["runner", "github", "job", "strategy", "matrix", "env", "inputs", "always(0,0)", "success(0,0)", "failure(0,0)", "cancelled(0,0)", "hashFiles(1,255)"], string: {} }, runs: { "one-of": ["container-runs", "node-runs", "composite-runs", "plugin-runs"] }, "runs-strict": { description: "Specifies whether this is a JavaScript action, a composite action, or a Docker container action and how the action is executed.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runs)", "one-of": ["container-runs-strict", "node-runs-strict", "composite-runs-strict"] }, "plugin-runs": { mapping: { properties: { plugin: "non-empty-string" } } }, "container-runs": { mapping: { properties: { using: "non-empty-string", image: "non-empty-string", entrypoint: "non-empty-string", args: "container-runs-args", env: "container-runs-env", "pre-entrypoint": "non-empty-string", "pre-if": "non-empty-string", "post-entrypoint": "non-empty-string", "post-if": "non-empty-string" } } }, "container-runs-args": { description: "An array of strings that define the inputs for a Docker container. Inputs can include hardcoded strings. GitHub passes the args to the container's ENTRYPOINT when the container starts up.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsargs)", sequence: { "item-type": "container-runs-context" } }, "container-runs-env": { description: "Specifies a key/value map of environment variables to set in the container environment.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsenv)", context: ["inputs"], mapping: { "loose-key-type": "non-empty-string", "loose-value-type": "string" } }, "container-runs-context": { context: ["inputs"], string: {} }, "node-runs": { mapping: { properties: { using: "non-empty-string", main: "non-empty-string", pre: "non-empty-string", "pre-if": "non-empty-string", post: "non-empty-string", "post-if": "non-empty-string" } } }, "composite-runs": { mapping: { properties: { using: "non-empty-string", steps: "composite-steps" } } }, "container-runs-strict": { description: "Configuration for Docker container actions.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runs)", mapping: { properties: { using: { type: "using", required: true, description: "The runtime used to execute the action. Must be docker for Docker container actions.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsusing)" }, image: { type: "non-empty-string", required: true, description: "The Docker image to use as the container to run the action. The value can be the Docker base image name, a local Dockerfile in your repository, or a public image in Docker Hub or another registry.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsimage)" }, entrypoint: { type: "non-empty-string", description: "Overrides the Docker ENTRYPOINT in the Dockerfile, or sets it if one wasn't already specified.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsentrypoint)" }, args: "container-runs-args", env: "container-runs-env", "pre-entrypoint": { type: "non-empty-string", description: "Allows you to run a script before the entrypoint action begins.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspre-entrypoint)" }, "pre-if": { type: "runs-if", description: "Allows you to define conditions for the pre: action execution. The pre: action will only run if the conditions in pre-if are met. If not set, then pre-if defaults to always().\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspre-if)" }, "post-entrypoint": { type: "non-empty-string", description: "Allows you to run a cleanup script once the runs.entrypoint action has completed.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspost-entrypoint)" }, "post-if": { type: "runs-if", description: "Allows you to define conditions for the post: action execution. The post: action will only run if the conditions in post-if are met. If not set, then post-if defaults to always().\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspost-if)" } } } }, "node-runs-strict": { description: "Configuration for JavaScript actions executed with Node.js.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runs)", mapping: { properties: { using: { type: "using", required: true, description: "The runtime used to execute the action. Use node20 or node24 for JavaScript actions.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsusing)" }, main: { type: "non-empty-string", required: true, description: "The file that contains your action code. The runtime specified in using executes this file.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsmain)" }, pre: { type: "non-empty-string", description: "Allows you to run a script at the start of a job, before the main: action begins. You can use pre: to run prerequisite setup scripts.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspre)" }, "pre-if": { type: "runs-if", description: "Allows you to define conditions for the pre: action execution. The pre: action will only run if the conditions in pre-if are met. If not set, then pre-if defaults to always().\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspre-if)" }, post: { type: "non-empty-string", description: "Allows you to run a script at the end of a job, once the main: action has completed. You can use post: to run cleanup scripts.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspost)" }, "post-if": { type: "runs-if", description: "Allows you to define conditions for the post: action execution. The post: action will only run if the conditions in post-if are met. If not set, then post-if defaults to always().\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runspost-if)" } } } }, "composite-runs-strict": { description: "Configuration for composite actions that run multiple steps.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runs)", mapping: { properties: { using: { type: "using", required: true, description: "The runtime used to execute the action. Must be composite for composite actions.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsusing)" }, steps: { type: "composite-steps", required: true } } } }, "composite-steps": { description: "The steps that you plan to run in this action. These can be either run steps or uses steps.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runssteps)", sequence: { "item-type": "composite-step" } }, "composite-step": { description: "A step within a composite action.", "one-of": ["run-step", "uses-step"] }, "run-step": { description: "Runs a command-line program using the operating system's shell.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsrun)", mapping: { properties: { name: { type: "string-steps-context", description: "A name for your step to display on GitHub.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsname)" }, id: { type: "non-empty-string", description: "A unique identifier for the step. You can use the id to reference the step in contexts.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsid)" }, if: { type: "step-if", description: "You can use the if conditional to prevent a step from running unless a condition is met. You can use any supported context and expression to create a conditional.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsif)" }, run: { type: "string-steps-context", required: true, description: "The command you want to run. This can be inline or a script in your action repository.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsrun)" }, shell: { type: "string-steps-context", required: true, description: "The shell where you want to run the command. Any shell supported by the runner can be used. Required if run is set.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsshell)" }, env: "step-env", "continue-on-error": { type: "boolean-steps-context", description: "Prevents the action from failing when a step fails. Set to true to allow the action to pass when this step fails.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepscontinue-on-error)" }, "working-directory": { type: "string-steps-context", description: "Specifies the working directory where the command is run.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsworking-directory)" } } } }, "uses-step": { description: "Runs another action as part of a step in your action.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsuses)", mapping: { properties: { name: { type: "string-steps-context", description: "A name for your step to display on GitHub.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsname)" }, id: { type: "non-empty-string", description: "A unique identifier for the step. You can use the id to reference the step in contexts.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsid)" }, if: { type: "step-if", description: "You can use the if conditional to prevent a step from running unless a condition is met. You can use any supported context and expression to create a conditional.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsif)" }, uses: { type: "non-empty-string", required: true, description: "Selects an action to run as part of a step in your action. An action is a reusable unit of code.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsuses)" }, with: "step-with", env: "step-env", "continue-on-error": { type: "boolean-steps-context", description: "Prevents the action from failing when a step fails. Set to true to allow the action to pass when this step fails.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepscontinue-on-error)" } } } }, "string-steps-context": { context: ["github", "inputs", "strategy", "matrix", "steps", "job", "runner", "env", "hashFiles(1,255)"], string: {} }, "boolean-steps-context": { context: ["github", "inputs", "strategy", "matrix", "steps", "job", "runner", "env", "hashFiles(1,255)"], boolean: {} }, "step-env": { description: "Sets variables for steps to use in the runner environment. You can also set variables for the entire action.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsenv)", context: ["github", "inputs", "strategy", "matrix", "steps", "job", "runner", "env", "hashFiles(1,255)"], mapping: { "loose-key-type": "non-empty-string", "loose-value-type": "string" } }, "step-if": { description: "You can use the if conditional to prevent a step from running unless a condition is met. You can use any supported context and expression to create a conditional.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepsif)", context: ["github", "inputs", "strategy", "matrix", "steps", "job", "runner", "env", "always(0,0)", "failure(0,0)", "cancelled(0,0)", "success(0,0)", "hashFiles(1,255)"], string: {} }, "step-with": { description: "A map of the input parameters defined by the action. Each input parameter is a key/value pair.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#runsstepswith)", context: ["github", "inputs", "strategy", "matrix", "steps", "job", "runner", "env", "hashFiles(1,255)"], mapping: { "loose-key-type": "non-empty-string", "loose-value-type": "string" } }, branding: { description: "You can use a color and Feather icon to create a badge to personalize and distinguish your action in GitHub Marketplace.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#branding)", mapping: { properties: { icon: { type: "branding-icon", description: "The name of the v4.28.0 Feather icon to use.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#brandingicon)" }, color: { type: "branding-color", description: "The background color of the badge.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#brandingcolor)" } } } }, "branding-icon": { description: "The name of the v4.28.0 Feather icon to use. Brand icons are omitted as well as: coffee, columns, divide-circle, divide-square, divide, frown, hexagon, key, meh, mouse-pointer, smile, tool, x-octagon.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#brandingicon)", "allowed-values": ["activity", "airplay", "alert-circle", "alert-octagon", "alert-triangle", "align-center", "align-justify", "align-left", "align-right", "anchor", "aperture", "archive", "arrow-down-circle", "arrow-down-left", "arrow-down-right", "arrow-down", "arrow-left-circle", "arrow-left", "arrow-right-circle", "arrow-right", "arrow-up-circle", "arrow-up-left", "arrow-up-right", "arrow-up", "at-sign", "award", "bar-chart-2", "bar-chart", "battery-charging", "battery", "bell-off", "bell", "bluetooth", "bold", "book-open", "book", "bookmark", "box", "briefcase", "calendar", "camera-off", "camera", "cast", "check-circle", "check-square", "check", "chevron-down", "chevron-left", "chevron-right", "chevron-up", "chevrons-down", "chevrons-left", "chevrons-right", "chevrons-up", "circle", "clipboard", "clock", "cloud-drizzle", "cloud-lightning", "cloud-off", "cloud-rain", "cloud-snow", "cloud", "code", "command", "compass", "copy", "corner-down-left", "corner-down-right", "corner-left-down", "corner-left-up", "corner-right-down", "corner-right-up", "corner-up-left", "corner-up-right", "cpu", "credit-card", "crop", "crosshair", "database", "delete", "disc", "dollar-sign", "download-cloud", "download", "droplet", "edit-2", "edit-3", "edit", "external-link", "eye-off", "eye", "fast-forward", "feather", "file-minus", "file-plus", "file-text", "file", "film", "filter", "flag", "folder-minus", "folder-plus", "folder", "gift", "git-branch", "git-commit", "git-merge", "git-pull-request", "globe", "grid", "hard-drive", "hash", "headphones", "heart", "help-circle", "home", "image", "inbox", "info", "italic", "layers", "layout", "life-buoy", "link-2", "link", "list", "loader", "lock", "log-in", "log-out", "mail", "map-pin", "map", "maximize-2", "maximize", "menu", "message-circle", "message-square", "mic-off", "mic", "minimize-2", "minimize", "minus-circle", "minus-square", "minus", "monitor", "moon", "more-horizontal", "more-vertical", "move", "music", "navigation-2", "navigation", "octagon", "package", "paperclip", "pause-circle", "pause", "percent", "phone-call", "phone-forwarded", "phone-incoming", "phone-missed", "phone-off", "phone-outgoing", "phone", "pie-chart", "play-circle", "play", "plus-circle", "plus-square", "plus", "pocket", "power", "printer", "radio", "refresh-ccw", "refresh-cw", "repeat", "rewind", "rotate-ccw", "rotate-cw", "rss", "save", "scissors", "search", "send", "server", "settings", "share-2", "share", "shield-off", "shield", "shopping-bag", "shopping-cart", "shuffle", "sidebar", "skip-back", "skip-forward", "slash", "sliders", "smartphone", "speaker", "square", "star", "stop-circle", "sun", "sunrise", "sunset", "tablet", "tag", "target", "terminal", "thermometer", "thumbs-down", "thumbs-up", "toggle-left", "toggle-right", "trash-2", "trash", "trending-down", "trending-up", "triangle", "truck", "tv", "type", "umbrella", "underline", "unlock", "upload-cloud", "upload", "user-check", "user-minus", "user-plus", "user-x", "user", "users", "video-off", "video", "voicemail", "volume-1", "volume-2", "volume-x", "volume", "watch", "wifi-off", "wifi", "wind", "x-circle", "x-square", "x", "zap-off", "zap", "zoom-in", "zoom-out"] }, "branding-color": { description: "The background color of the badge.\n\n[Documentation](https://docs.github.com/actions/creating-actions/metadata-syntax-for-github-actions#brandingcolor)", "allowed-values": ["white", "yellow", "blue", "green", "orange", "red", "purple", "gray-dark"] }, using: { description: "The runtime used to execute the action.", "allowed-values": ["docker", "node12", "node16", "node20", "node24", "composite"] }, "non-empty-string": { string: { "require-non-empty": true } } } };
23166
23176
 
23167
23177
  // ../workflow-parser/dist/actions/action-schema.js
23168
23178
  var schema2;
@@ -24425,11 +24435,20 @@ function isActionDocument(uri) {
24425
24435
  }
24426
24436
 
24427
24437
  // ../languageservice/dist/utils/expression-detection.js
24428
- function isPotentiallyExpression(token) {
24429
- const containsExpression = isString(token) && token.value != null && token.value.indexOf(OPEN_EXPRESSION) >= 0;
24430
- const definitionKey = token.definition?.key;
24431
- const isIfCondition = definitionKey === "job-if" || definitionKey === "step-if" || definitionKey === "snapshot-if";
24432
- return containsExpression || isIfCondition;
24438
+ var WORKFLOW_IF_DEFINITIONS = /* @__PURE__ */ new Set(["job-if", "step-if", "snapshot-if"]);
24439
+ var ACTION_IF_DEFINITIONS = /* @__PURE__ */ new Set(["step-if", "runs-if"]);
24440
+ function isPotentiallyExpression(token, isAction) {
24441
+ if (isString(token) && token.value != null && token.value.indexOf(OPEN_EXPRESSION) >= 0) {
24442
+ return true;
24443
+ }
24444
+ if (!token.definition?.key) {
24445
+ return false;
24446
+ }
24447
+ if (isAction) {
24448
+ return ACTION_IF_DEFINITIONS.has(token.definition.key);
24449
+ } else {
24450
+ return WORKFLOW_IF_DEFINITIONS.has(token.definition.key);
24451
+ }
24433
24452
  }
24434
24453
 
24435
24454
  // ../languageservice/dist/utils/find-token.js
@@ -24983,7 +25002,7 @@ function convertRuns(context, token) {
24983
25002
  break;
24984
25003
  case "pre-if":
24985
25004
  if (isString(item.value)) {
24986
- preIf = item.value.value;
25005
+ preIf = validateRunsIfCondition(context, item.value, item.value.value);
24987
25006
  }
24988
25007
  break;
24989
25008
  case "post":
@@ -24993,7 +25012,7 @@ function convertRuns(context, token) {
24993
25012
  break;
24994
25013
  case "post-if":
24995
25014
  if (isString(item.value)) {
24996
- postIf = item.value.value;
25015
+ postIf = validateRunsIfCondition(context, item.value, item.value.value);
24997
25016
  }
24998
25017
  break;
24999
25018
  case "pre-entrypoint":
@@ -25603,10 +25622,14 @@ async function complete2(textDocument, position, config) {
25603
25622
  }, true);
25604
25623
  workflowContext = workflowTemplate ? getWorkflowContext(textDocument.uri, workflowTemplate, path) : void 0;
25605
25624
  }
25606
- if (token && (isBasicExpression(token) || isPotentiallyExpression(token))) {
25625
+ if (token && (isBasicExpression(token) || isPotentiallyExpression(token, isAction))) {
25607
25626
  const allowedContext = token.definitionInfo?.allowedContext || [];
25608
- const context = isAction ? getActionExpressionContext(allowedContext, config?.contextProviderConfig, actionContext, Mode.Completion) : await getWorkflowExpressionContext(allowedContext, config?.contextProviderConfig, workflowContext, Mode.Completion);
25609
- return getExpressionCompletionItems(token, context, newPos, config?.featureFlags);
25627
+ const { namedContexts, functions: extensionFunctions } = splitAllowedContext(allowedContext);
25628
+ const context = isAction ? getActionExpressionContext(namedContexts, config?.contextProviderConfig, actionContext, Mode.Completion) : await getWorkflowExpressionContext(namedContexts, config?.contextProviderConfig, workflowContext, Mode.Completion);
25629
+ for (const func of extensionFunctions) {
25630
+ func.description = getFunctionDescription(func.name);
25631
+ }
25632
+ return getExpressionCompletionItems(token, context, extensionFunctions, newPos, config?.featureFlags);
25610
25633
  }
25611
25634
  const indentation = guessIndentation(newDoc, 2, true);
25612
25635
  const indentString = " ".repeat(indentation.tabSize);
@@ -25833,7 +25856,7 @@ function getExistingValues(token, parent) {
25833
25856
  return mapKeys;
25834
25857
  }
25835
25858
  }
25836
- function getExpressionCompletionItems(token, context, pos, featureFlags) {
25859
+ function getExpressionCompletionItems(token, context, extensionFunctions, pos, featureFlags) {
25837
25860
  if (!token.range) {
25838
25861
  return [];
25839
25862
  }
@@ -25847,7 +25870,7 @@ function getExpressionCompletionItems(token, context, pos, featureFlags) {
25847
25870
  const cursorOffset = getOffsetInContent(token.range, currentInput, pos);
25848
25871
  const expressionInput = (getExpressionInput(currentInput, cursorOffset) || "").trim();
25849
25872
  try {
25850
- return complete(expressionInput, context, [], validatorFunctions, featureFlags).map((item) => mapExpressionCompletionItem(item, currentInput[cursorOffset]));
25873
+ return complete(expressionInput, context, extensionFunctions, validatorFunctions, featureFlags).map((item) => mapExpressionCompletionItem(item, currentInput[cursorOffset]));
25851
25874
  } catch (e) {
25852
25875
  error(`Error while completing expression: '${e?.message || "<no details>"}'`);
25853
25876
  return [];
@@ -26551,7 +26574,7 @@ async function hover(document, position, config) {
26551
26574
  const { token, keyToken, parent } = tokenResult;
26552
26575
  const tokenDefinitionInfo = (keyToken || parent || token)?.definitionInfo;
26553
26576
  const hoverToken = token || keyToken;
26554
- const isExpressionHover = token && tokenDefinitionInfo && (isBasicExpression(token) || isPotentiallyExpression(token));
26577
+ const isExpressionHover = token && tokenDefinitionInfo && (isBasicExpression(token) || isPotentiallyExpression(token, isAction));
26555
26578
  if (!isExpressionHover && !hoverToken?.definition) {
26556
26579
  return null;
26557
26580
  }
@@ -27117,6 +27140,12 @@ async function validateAction(textDocument, config) {
27117
27140
  if (!result) {
27118
27141
  return [];
27119
27142
  }
27143
+ let template;
27144
+ if (result.value) {
27145
+ template = getOrConvertActionTemplate(result.context, result.value, textDocument.uri, {
27146
+ errorPolicy: ErrorPolicy.TryConversion
27147
+ });
27148
+ }
27120
27149
  const schemaErrors = result.context.errors.getErrors();
27121
27150
  if (result.value) {
27122
27151
  diagnostics.push(...validateRunsKeysAndFilterErrors(result.value, schemaErrors));
@@ -27133,11 +27162,8 @@ async function validateAction(textDocument, config) {
27133
27162
  severity
27134
27163
  });
27135
27164
  }
27136
- if (result.value) {
27137
- const template = getOrConvertActionTemplate(result.context, result.value, textDocument.uri, {
27138
- errorPolicy: ErrorPolicy.TryConversion
27139
- });
27140
- if (template?.runs?.using === "composite") {
27165
+ if (result.value && template) {
27166
+ if (template.runs?.using === "composite") {
27141
27167
  const steps = template.runs.steps ?? [];
27142
27168
  const stepsSequence = findStepsSequence(result.value);
27143
27169
  if (stepsSequence) {
@@ -27148,39 +27174,66 @@ async function validateAction(textDocument, config) {
27148
27174
  await validateActionReference(diagnostics, stepToken, step, config);
27149
27175
  }
27150
27176
  if (isMapping(stepToken)) {
27151
- validateCompositeStepTokens(diagnostics, stepToken);
27177
+ validateStepUsesField(diagnostics, stepToken);
27152
27178
  }
27153
27179
  }
27154
27180
  }
27155
27181
  }
27156
- const runsMapping = findRunsMapping(result.value);
27157
- if (runsMapping) {
27158
- validateRunsIfConditions(diagnostics, runsMapping);
27159
- }
27160
- validateAllExpressions(diagnostics, result.value);
27182
+ validateAllTokens(diagnostics, result.value);
27161
27183
  }
27162
27184
  } catch (e) {
27163
27185
  error(`Unhandled error while validating action file: ${e.message}`);
27164
27186
  }
27165
27187
  return diagnostics;
27166
27188
  }
27167
- function validateCompositeStepTokens(diagnostics, stepToken) {
27189
+ function validateStepUsesField(diagnostics, stepToken) {
27168
27190
  for (let i = 0; i < stepToken.count; i++) {
27169
27191
  const { key, value } = stepToken.get(i);
27170
27192
  const keyStr = isString(key) ? key.value.toLowerCase() : "";
27171
27193
  if (keyStr === "uses" && isString(value)) {
27172
27194
  validateStepUsesFormat(diagnostics, value);
27173
27195
  }
27174
- if (keyStr === "if" && value.range) {
27175
- if (isString(value)) {
27176
- validateIfCondition(diagnostics, value);
27177
- } else if (isBasicExpression(value)) {
27178
- validateIfConditionExpression(diagnostics, value);
27196
+ }
27197
+ }
27198
+ function validateAllTokens(diagnostics, root) {
27199
+ for (const [parent, token] of TemplateToken.traverse(root)) {
27200
+ const definitionKey = token.definition?.key;
27201
+ if (token instanceof BasicExpressionToken && token.range) {
27202
+ if (definitionKey === "step-if") {
27203
+ validateIfLiteralText(diagnostics, token);
27204
+ }
27205
+ for (const expression of token.originalExpressions || [token]) {
27206
+ validateExpressionFormatCalls(diagnostics, expression);
27207
+ }
27208
+ if (definitionKey === "runs-if" && parent instanceof MappingToken) {
27209
+ let keyName;
27210
+ for (let i = 0; i < parent.count; i++) {
27211
+ const { key, value } = parent.get(i);
27212
+ if (value === token) {
27213
+ keyName = key.toString().toLowerCase();
27214
+ break;
27215
+ }
27216
+ }
27217
+ if (keyName) {
27218
+ diagnostics.push({
27219
+ message: `Explicit expression syntax \${{ }} is not supported for '${keyName}'. Remove the \${{ }} markers and use the expression directly.`,
27220
+ range: mapRange(token.range),
27221
+ severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
27222
+ code: "explicit-expression-not-allowed"
27223
+ });
27224
+ }
27225
+ }
27226
+ }
27227
+ if (isString(token) && token.range) {
27228
+ if (definitionKey === "step-if" || definitionKey === "runs-if") {
27229
+ validateImplicitIfCondition(diagnostics, token);
27179
27230
  }
27180
27231
  }
27181
27232
  }
27182
27233
  }
27183
- function validateIfCondition(diagnostics, token) {
27234
+ var LITERAL_TEXT_IN_CONDITION_MESSAGE = "Conditional expression contains literal text outside replacement tokens. This will cause the expression to always evaluate to truthy. Did you mean to put the entire expression inside ${{ }}?";
27235
+ var LITERAL_TEXT_IN_CONDITION_CODE = "expression-literal-text-in-condition";
27236
+ function validateImplicitIfCondition(diagnostics, token) {
27184
27237
  const condition = token.value.trim();
27185
27238
  if (!condition) {
27186
27239
  return;
@@ -27188,25 +27241,24 @@ function validateIfCondition(diagnostics, token) {
27188
27241
  const allowedContext = token.definitionInfo?.allowedContext || [];
27189
27242
  const { namedContexts, functions } = splitAllowedContext(allowedContext);
27190
27243
  const finalCondition = ensureStatusFunction(condition, token.definitionInfo);
27191
- const expressionToken = new BasicExpressionToken(token.file, token.range, finalCondition, token.definitionInfo, void 0, token.source, void 0, token.blockScalarHeader);
27192
27244
  try {
27193
- const l = new Lexer(expressionToken.expression);
27245
+ const l = new Lexer(finalCondition);
27194
27246
  const lr = l.lex();
27195
27247
  const p = new Parser(lr.tokens, namedContexts, functions);
27196
27248
  const expr = p.parse();
27197
27249
  if (hasFormatWithLiteralText(expr)) {
27198
27250
  diagnostics.push({
27199
- message: "Conditional expression contains literal text outside replacement tokens. This will cause the expression to always evaluate to truthy. Did you mean to put the entire expression inside ${{ }}?",
27251
+ message: LITERAL_TEXT_IN_CONDITION_MESSAGE,
27200
27252
  range: mapRange(token.range),
27201
27253
  severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
27202
- code: "expression-literal-text-in-condition"
27254
+ code: LITERAL_TEXT_IN_CONDITION_CODE
27203
27255
  });
27204
27256
  }
27205
27257
  validateFormatCallsAndAddDiagnostics(diagnostics, expr, token.range);
27206
27258
  } catch {
27207
27259
  }
27208
27260
  }
27209
- function validateIfConditionExpression(diagnostics, token) {
27261
+ function validateIfLiteralText(diagnostics, token) {
27210
27262
  const allowedContext = token.definitionInfo?.allowedContext || [];
27211
27263
  const { namedContexts, functions } = splitAllowedContext(allowedContext);
27212
27264
  try {
@@ -27216,15 +27268,27 @@ function validateIfConditionExpression(diagnostics, token) {
27216
27268
  const expr = p.parse();
27217
27269
  if (hasFormatWithLiteralText(expr)) {
27218
27270
  diagnostics.push({
27219
- message: "Conditional expression contains literal text outside replacement tokens. This will cause the expression to always evaluate to truthy. Did you mean to put the entire expression inside ${{ }}?",
27271
+ message: LITERAL_TEXT_IN_CONDITION_MESSAGE,
27220
27272
  range: mapRange(token.range),
27221
27273
  severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
27222
- code: "expression-literal-text-in-condition"
27274
+ code: LITERAL_TEXT_IN_CONDITION_CODE
27223
27275
  });
27224
27276
  }
27225
27277
  } catch {
27226
27278
  }
27227
27279
  }
27280
+ function validateExpressionFormatCalls(diagnostics, token) {
27281
+ const allowedContext = token.definitionInfo?.allowedContext || [];
27282
+ const { namedContexts, functions } = splitAllowedContext(allowedContext);
27283
+ try {
27284
+ const l = new Lexer(token.expression);
27285
+ const lr = l.lex();
27286
+ const p = new Parser(lr.tokens, namedContexts, functions);
27287
+ const expr = p.parse();
27288
+ validateFormatCallsAndAddDiagnostics(diagnostics, expr, token.range);
27289
+ } catch {
27290
+ }
27291
+ }
27228
27292
  function validateFormatCallsAndAddDiagnostics(diagnostics, expr, range) {
27229
27293
  const formatErrors = validateFormatCalls(expr);
27230
27294
  for (const formatError of formatErrors) {
@@ -27253,53 +27317,6 @@ function findStepsSequence(root) {
27253
27317
  }
27254
27318
  return void 0;
27255
27319
  }
27256
- function findRunsMapping(root) {
27257
- if (root instanceof MappingToken) {
27258
- for (let i = 0; i < root.count; i++) {
27259
- const { key, value } = root.get(i);
27260
- if (key.toString().toLowerCase() === "runs" && value instanceof MappingToken) {
27261
- return value;
27262
- }
27263
- }
27264
- }
27265
- return void 0;
27266
- }
27267
- function validateRunsIfConditions(diagnostics, runsMapping) {
27268
- for (let i = 0; i < runsMapping.count; i++) {
27269
- const { key, value } = runsMapping.get(i);
27270
- const keyStr = key.toString().toLowerCase();
27271
- if ((keyStr === "pre-if" || keyStr === "post-if") && value.range) {
27272
- if (isString(value)) {
27273
- validateIfCondition(diagnostics, value);
27274
- } else if (isBasicExpression(value)) {
27275
- diagnostics.push({
27276
- message: `Explicit expression syntax \${{ }} is not supported for '${keyStr}'. Remove the \${{ }} markers and use the expression directly.`,
27277
- range: mapRange(value.range),
27278
- severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
27279
- code: "explicit-expression-not-allowed"
27280
- });
27281
- }
27282
- }
27283
- }
27284
- }
27285
- function validateAllExpressions(diagnostics, root) {
27286
- for (const [, token] of TemplateToken.traverse(root)) {
27287
- if (token instanceof BasicExpressionToken) {
27288
- for (const expression of token.originalExpressions || [token]) {
27289
- const allowedContext = expression.definitionInfo?.allowedContext || [];
27290
- const { namedContexts, functions } = splitAllowedContext(allowedContext);
27291
- try {
27292
- const l = new Lexer(expression.expression);
27293
- const lr = l.lex();
27294
- const p = new Parser(lr.tokens, namedContexts, functions);
27295
- const expr = p.parse();
27296
- validateFormatCallsAndAddDiagnostics(diagnostics, expr, expression.range);
27297
- } catch {
27298
- }
27299
- }
27300
- }
27301
- }
27302
- }
27303
27320
  function validateRunsKeysAndFilterErrors(root, schemaErrors) {
27304
27321
  const diagnostics = [];
27305
27322
  let runsMapping;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actions/languageserver",
3
- "version": "0.3.41",
3
+ "version": "0.3.43",
4
4
  "description": "Language server for GitHub Actions",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -48,8 +48,8 @@
48
48
  "actions-languageserver": "./bin/actions-languageserver"
49
49
  },
50
50
  "dependencies": {
51
- "@actions/languageservice": "^0.3.41",
52
- "@actions/workflow-parser": "^0.3.41",
51
+ "@actions/languageservice": "^0.3.43",
52
+ "@actions/workflow-parser": "^0.3.43",
53
53
  "@octokit/rest": "^21.1.1",
54
54
  "@octokit/types": "^9.0.0",
55
55
  "vscode-languageserver": "^8.0.2",
@@ -78,5 +78,5 @@
78
78
  "ts-jest": "^29.0.3",
79
79
  "typescript": "^4.8.4"
80
80
  },
81
- "gitHead": "bdd72406c3df0de2e1fefa8462894228f3fa113d"
81
+ "gitHead": "448180bd7fb42b32566d50239638e51ad8ee78d2"
82
82
  }