@actions/languageserver 0.3.42 → 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 +78 -74
  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) {
@@ -24992,7 +25002,7 @@ function convertRuns(context, token) {
24992
25002
  break;
24993
25003
  case "pre-if":
24994
25004
  if (isString(item.value)) {
24995
- preIf = item.value.value;
25005
+ preIf = validateRunsIfCondition(context, item.value, item.value.value);
24996
25006
  }
24997
25007
  break;
24998
25008
  case "post":
@@ -25002,7 +25012,7 @@ function convertRuns(context, token) {
25002
25012
  break;
25003
25013
  case "post-if":
25004
25014
  if (isString(item.value)) {
25005
- postIf = item.value.value;
25015
+ postIf = validateRunsIfCondition(context, item.value, item.value.value);
25006
25016
  }
25007
25017
  break;
25008
25018
  case "pre-entrypoint":
@@ -27130,6 +27140,12 @@ async function validateAction(textDocument, config) {
27130
27140
  if (!result) {
27131
27141
  return [];
27132
27142
  }
27143
+ let template;
27144
+ if (result.value) {
27145
+ template = getOrConvertActionTemplate(result.context, result.value, textDocument.uri, {
27146
+ errorPolicy: ErrorPolicy.TryConversion
27147
+ });
27148
+ }
27133
27149
  const schemaErrors = result.context.errors.getErrors();
27134
27150
  if (result.value) {
27135
27151
  diagnostics.push(...validateRunsKeysAndFilterErrors(result.value, schemaErrors));
@@ -27146,11 +27162,8 @@ async function validateAction(textDocument, config) {
27146
27162
  severity
27147
27163
  });
27148
27164
  }
27149
- if (result.value) {
27150
- const template = getOrConvertActionTemplate(result.context, result.value, textDocument.uri, {
27151
- errorPolicy: ErrorPolicy.TryConversion
27152
- });
27153
- if (template?.runs?.using === "composite") {
27165
+ if (result.value && template) {
27166
+ if (template.runs?.using === "composite") {
27154
27167
  const steps = template.runs.steps ?? [];
27155
27168
  const stepsSequence = findStepsSequence(result.value);
27156
27169
  if (stepsSequence) {
@@ -27161,39 +27174,66 @@ async function validateAction(textDocument, config) {
27161
27174
  await validateActionReference(diagnostics, stepToken, step, config);
27162
27175
  }
27163
27176
  if (isMapping(stepToken)) {
27164
- validateCompositeStepTokens(diagnostics, stepToken);
27177
+ validateStepUsesField(diagnostics, stepToken);
27165
27178
  }
27166
27179
  }
27167
27180
  }
27168
27181
  }
27169
- const runsMapping = findRunsMapping(result.value);
27170
- if (runsMapping) {
27171
- validateRunsIfConditions(diagnostics, runsMapping);
27172
- }
27173
- validateAllExpressions(diagnostics, result.value);
27182
+ validateAllTokens(diagnostics, result.value);
27174
27183
  }
27175
27184
  } catch (e) {
27176
27185
  error(`Unhandled error while validating action file: ${e.message}`);
27177
27186
  }
27178
27187
  return diagnostics;
27179
27188
  }
27180
- function validateCompositeStepTokens(diagnostics, stepToken) {
27189
+ function validateStepUsesField(diagnostics, stepToken) {
27181
27190
  for (let i = 0; i < stepToken.count; i++) {
27182
27191
  const { key, value } = stepToken.get(i);
27183
27192
  const keyStr = isString(key) ? key.value.toLowerCase() : "";
27184
27193
  if (keyStr === "uses" && isString(value)) {
27185
27194
  validateStepUsesFormat(diagnostics, value);
27186
27195
  }
27187
- if (keyStr === "if" && value.range) {
27188
- if (isString(value)) {
27189
- validateIfCondition(diagnostics, value);
27190
- } else if (isBasicExpression(value)) {
27191
- 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);
27192
27230
  }
27193
27231
  }
27194
27232
  }
27195
27233
  }
27196
- 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) {
27197
27237
  const condition = token.value.trim();
27198
27238
  if (!condition) {
27199
27239
  return;
@@ -27201,25 +27241,24 @@ function validateIfCondition(diagnostics, token) {
27201
27241
  const allowedContext = token.definitionInfo?.allowedContext || [];
27202
27242
  const { namedContexts, functions } = splitAllowedContext(allowedContext);
27203
27243
  const finalCondition = ensureStatusFunction(condition, token.definitionInfo);
27204
- const expressionToken = new BasicExpressionToken(token.file, token.range, finalCondition, token.definitionInfo, void 0, token.source, void 0, token.blockScalarHeader);
27205
27244
  try {
27206
- const l = new Lexer(expressionToken.expression);
27245
+ const l = new Lexer(finalCondition);
27207
27246
  const lr = l.lex();
27208
27247
  const p = new Parser(lr.tokens, namedContexts, functions);
27209
27248
  const expr = p.parse();
27210
27249
  if (hasFormatWithLiteralText(expr)) {
27211
27250
  diagnostics.push({
27212
- 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,
27213
27252
  range: mapRange(token.range),
27214
27253
  severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
27215
- code: "expression-literal-text-in-condition"
27254
+ code: LITERAL_TEXT_IN_CONDITION_CODE
27216
27255
  });
27217
27256
  }
27218
27257
  validateFormatCallsAndAddDiagnostics(diagnostics, expr, token.range);
27219
27258
  } catch {
27220
27259
  }
27221
27260
  }
27222
- function validateIfConditionExpression(diagnostics, token) {
27261
+ function validateIfLiteralText(diagnostics, token) {
27223
27262
  const allowedContext = token.definitionInfo?.allowedContext || [];
27224
27263
  const { namedContexts, functions } = splitAllowedContext(allowedContext);
27225
27264
  try {
@@ -27229,15 +27268,27 @@ function validateIfConditionExpression(diagnostics, token) {
27229
27268
  const expr = p.parse();
27230
27269
  if (hasFormatWithLiteralText(expr)) {
27231
27270
  diagnostics.push({
27232
- 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,
27233
27272
  range: mapRange(token.range),
27234
27273
  severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
27235
- code: "expression-literal-text-in-condition"
27274
+ code: LITERAL_TEXT_IN_CONDITION_CODE
27236
27275
  });
27237
27276
  }
27238
27277
  } catch {
27239
27278
  }
27240
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
+ }
27241
27292
  function validateFormatCallsAndAddDiagnostics(diagnostics, expr, range) {
27242
27293
  const formatErrors = validateFormatCalls(expr);
27243
27294
  for (const formatError of formatErrors) {
@@ -27266,53 +27317,6 @@ function findStepsSequence(root) {
27266
27317
  }
27267
27318
  return void 0;
27268
27319
  }
27269
- function findRunsMapping(root) {
27270
- if (root instanceof MappingToken) {
27271
- for (let i = 0; i < root.count; i++) {
27272
- const { key, value } = root.get(i);
27273
- if (key.toString().toLowerCase() === "runs" && value instanceof MappingToken) {
27274
- return value;
27275
- }
27276
- }
27277
- }
27278
- return void 0;
27279
- }
27280
- function validateRunsIfConditions(diagnostics, runsMapping) {
27281
- for (let i = 0; i < runsMapping.count; i++) {
27282
- const { key, value } = runsMapping.get(i);
27283
- const keyStr = key.toString().toLowerCase();
27284
- if ((keyStr === "pre-if" || keyStr === "post-if") && value.range) {
27285
- if (isString(value)) {
27286
- validateIfCondition(diagnostics, value);
27287
- } else if (isBasicExpression(value)) {
27288
- diagnostics.push({
27289
- message: `Explicit expression syntax \${{ }} is not supported for '${keyStr}'. Remove the \${{ }} markers and use the expression directly.`,
27290
- range: mapRange(value.range),
27291
- severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
27292
- code: "explicit-expression-not-allowed"
27293
- });
27294
- }
27295
- }
27296
- }
27297
- }
27298
- function validateAllExpressions(diagnostics, root) {
27299
- for (const [, token] of TemplateToken.traverse(root)) {
27300
- if (token instanceof BasicExpressionToken) {
27301
- for (const expression of token.originalExpressions || [token]) {
27302
- const allowedContext = expression.definitionInfo?.allowedContext || [];
27303
- const { namedContexts, functions } = splitAllowedContext(allowedContext);
27304
- try {
27305
- const l = new Lexer(expression.expression);
27306
- const lr = l.lex();
27307
- const p = new Parser(lr.tokens, namedContexts, functions);
27308
- const expr = p.parse();
27309
- validateFormatCallsAndAddDiagnostics(diagnostics, expr, expression.range);
27310
- } catch {
27311
- }
27312
- }
27313
- }
27314
- }
27315
- }
27316
27320
  function validateRunsKeysAndFilterErrors(root, schemaErrors) {
27317
27321
  const diagnostics = [];
27318
27322
  let runsMapping;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actions/languageserver",
3
- "version": "0.3.42",
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.42",
52
- "@actions/workflow-parser": "^0.3.42",
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": "46b216a6dce39b5cc60bce9325785545fdbaba00"
81
+ "gitHead": "448180bd7fb42b32566d50239638e51ad8ee78d2"
82
82
  }