@actions/languageserver 0.3.34 → 0.3.36
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.
- package/README.md +32 -0
- package/dist/cli.bundle.cjs +850 -104
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +9 -1
- package/dist/connection.js.map +1 -1
- package/dist/initializationOptions.d.ts +6 -0
- package/dist/initializationOptions.d.ts.map +1 -1
- package/dist/initializationOptions.js.map +1 -1
- package/package.json +4 -4
package/dist/cli.bundle.cjs
CHANGED
|
@@ -3267,7 +3267,7 @@ var require_main2 = __commonJS({
|
|
|
3267
3267
|
ColorPresentation2.create = create;
|
|
3268
3268
|
function is(value) {
|
|
3269
3269
|
var candidate = value;
|
|
3270
|
-
return Is.objectLiteral(candidate) && Is.string(candidate.label) && (Is.undefined(candidate.textEdit) ||
|
|
3270
|
+
return Is.objectLiteral(candidate) && Is.string(candidate.label) && (Is.undefined(candidate.textEdit) || TextEdit3.is(candidate)) && (Is.undefined(candidate.additionalTextEdits) || Is.typedArray(candidate.additionalTextEdits, TextEdit3.is));
|
|
3271
3271
|
}
|
|
3272
3272
|
ColorPresentation2.is = is;
|
|
3273
3273
|
})(ColorPresentation = exports3.ColorPresentation || (exports3.ColorPresentation = {}));
|
|
@@ -3386,26 +3386,26 @@ var require_main2 = __commonJS({
|
|
|
3386
3386
|
}
|
|
3387
3387
|
Command2.is = is;
|
|
3388
3388
|
})(Command = exports3.Command || (exports3.Command = {}));
|
|
3389
|
-
var
|
|
3390
|
-
(function(
|
|
3389
|
+
var TextEdit3;
|
|
3390
|
+
(function(TextEdit4) {
|
|
3391
3391
|
function replace(range, newText) {
|
|
3392
3392
|
return { range, newText };
|
|
3393
3393
|
}
|
|
3394
|
-
|
|
3394
|
+
TextEdit4.replace = replace;
|
|
3395
3395
|
function insert(position, newText) {
|
|
3396
3396
|
return { range: { start: position, end: position }, newText };
|
|
3397
3397
|
}
|
|
3398
|
-
|
|
3398
|
+
TextEdit4.insert = insert;
|
|
3399
3399
|
function del(range) {
|
|
3400
3400
|
return { range, newText: "" };
|
|
3401
3401
|
}
|
|
3402
|
-
|
|
3402
|
+
TextEdit4.del = del;
|
|
3403
3403
|
function is(value) {
|
|
3404
3404
|
var candidate = value;
|
|
3405
3405
|
return Is.objectLiteral(candidate) && Is.string(candidate.newText) && Range2.is(candidate.range);
|
|
3406
3406
|
}
|
|
3407
|
-
|
|
3408
|
-
})(
|
|
3407
|
+
TextEdit4.is = is;
|
|
3408
|
+
})(TextEdit3 = exports3.TextEdit || (exports3.TextEdit = {}));
|
|
3409
3409
|
var ChangeAnnotation;
|
|
3410
3410
|
(function(ChangeAnnotation2) {
|
|
3411
3411
|
function create(label, needsConfirmation, description) {
|
|
@@ -3449,7 +3449,7 @@ var require_main2 = __commonJS({
|
|
|
3449
3449
|
AnnotatedTextEdit2.del = del;
|
|
3450
3450
|
function is(value) {
|
|
3451
3451
|
var candidate = value;
|
|
3452
|
-
return
|
|
3452
|
+
return TextEdit3.is(candidate) && (ChangeAnnotation.is(candidate.annotationId) || ChangeAnnotationIdentifier.is(candidate.annotationId));
|
|
3453
3453
|
}
|
|
3454
3454
|
AnnotatedTextEdit2.is = is;
|
|
3455
3455
|
})(AnnotatedTextEdit = exports3.AnnotatedTextEdit || (exports3.AnnotatedTextEdit = {}));
|
|
@@ -3557,7 +3557,7 @@ var require_main2 = __commonJS({
|
|
|
3557
3557
|
var edit;
|
|
3558
3558
|
var id;
|
|
3559
3559
|
if (annotation === void 0) {
|
|
3560
|
-
edit =
|
|
3560
|
+
edit = TextEdit3.insert(position, newText);
|
|
3561
3561
|
} else if (ChangeAnnotationIdentifier.is(annotation)) {
|
|
3562
3562
|
id = annotation;
|
|
3563
3563
|
edit = AnnotatedTextEdit.insert(position, newText, annotation);
|
|
@@ -3575,7 +3575,7 @@ var require_main2 = __commonJS({
|
|
|
3575
3575
|
var edit;
|
|
3576
3576
|
var id;
|
|
3577
3577
|
if (annotation === void 0) {
|
|
3578
|
-
edit =
|
|
3578
|
+
edit = TextEdit3.replace(range, newText);
|
|
3579
3579
|
} else if (ChangeAnnotationIdentifier.is(annotation)) {
|
|
3580
3580
|
id = annotation;
|
|
3581
3581
|
edit = AnnotatedTextEdit.replace(range, newText, annotation);
|
|
@@ -3593,7 +3593,7 @@ var require_main2 = __commonJS({
|
|
|
3593
3593
|
var edit;
|
|
3594
3594
|
var id;
|
|
3595
3595
|
if (annotation === void 0) {
|
|
3596
|
-
edit =
|
|
3596
|
+
edit = TextEdit3.del(range);
|
|
3597
3597
|
} else if (ChangeAnnotationIdentifier.is(annotation)) {
|
|
3598
3598
|
id = annotation;
|
|
3599
3599
|
edit = AnnotatedTextEdit.del(range, annotation);
|
|
@@ -3901,39 +3901,39 @@ var require_main2 = __commonJS({
|
|
|
3901
3901
|
}
|
|
3902
3902
|
MarkupContent2.is = is;
|
|
3903
3903
|
})(MarkupContent = exports3.MarkupContent || (exports3.MarkupContent = {}));
|
|
3904
|
-
var
|
|
3905
|
-
(function(
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
})(
|
|
3932
|
-
var
|
|
3933
|
-
(function(
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
})(
|
|
3904
|
+
var CompletionItemKind3;
|
|
3905
|
+
(function(CompletionItemKind4) {
|
|
3906
|
+
CompletionItemKind4.Text = 1;
|
|
3907
|
+
CompletionItemKind4.Method = 2;
|
|
3908
|
+
CompletionItemKind4.Function = 3;
|
|
3909
|
+
CompletionItemKind4.Constructor = 4;
|
|
3910
|
+
CompletionItemKind4.Field = 5;
|
|
3911
|
+
CompletionItemKind4.Variable = 6;
|
|
3912
|
+
CompletionItemKind4.Class = 7;
|
|
3913
|
+
CompletionItemKind4.Interface = 8;
|
|
3914
|
+
CompletionItemKind4.Module = 9;
|
|
3915
|
+
CompletionItemKind4.Property = 10;
|
|
3916
|
+
CompletionItemKind4.Unit = 11;
|
|
3917
|
+
CompletionItemKind4.Value = 12;
|
|
3918
|
+
CompletionItemKind4.Enum = 13;
|
|
3919
|
+
CompletionItemKind4.Keyword = 14;
|
|
3920
|
+
CompletionItemKind4.Snippet = 15;
|
|
3921
|
+
CompletionItemKind4.Color = 16;
|
|
3922
|
+
CompletionItemKind4.File = 17;
|
|
3923
|
+
CompletionItemKind4.Reference = 18;
|
|
3924
|
+
CompletionItemKind4.Folder = 19;
|
|
3925
|
+
CompletionItemKind4.EnumMember = 20;
|
|
3926
|
+
CompletionItemKind4.Constant = 21;
|
|
3927
|
+
CompletionItemKind4.Struct = 22;
|
|
3928
|
+
CompletionItemKind4.Event = 23;
|
|
3929
|
+
CompletionItemKind4.Operator = 24;
|
|
3930
|
+
CompletionItemKind4.TypeParameter = 25;
|
|
3931
|
+
})(CompletionItemKind3 = exports3.CompletionItemKind || (exports3.CompletionItemKind = {}));
|
|
3932
|
+
var InsertTextFormat2;
|
|
3933
|
+
(function(InsertTextFormat3) {
|
|
3934
|
+
InsertTextFormat3.PlainText = 1;
|
|
3935
|
+
InsertTextFormat3.Snippet = 2;
|
|
3936
|
+
})(InsertTextFormat2 = exports3.InsertTextFormat || (exports3.InsertTextFormat = {}));
|
|
3937
3937
|
var CompletionItemTag2;
|
|
3938
3938
|
(function(CompletionItemTag3) {
|
|
3939
3939
|
CompletionItemTag3.Deprecated = 1;
|
|
@@ -4359,7 +4359,7 @@ var require_main2 = __commonJS({
|
|
|
4359
4359
|
InlayHint3.create = create;
|
|
4360
4360
|
function is(value) {
|
|
4361
4361
|
var candidate = value;
|
|
4362
|
-
return Is.objectLiteral(candidate) && Position.is(candidate.position) && (Is.string(candidate.label) || Is.typedArray(candidate.label, InlayHintLabelPart.is)) && (candidate.kind === void 0 || InlayHintKind2.is(candidate.kind)) && candidate.textEdits === void 0 || Is.typedArray(candidate.textEdits,
|
|
4362
|
+
return Is.objectLiteral(candidate) && Position.is(candidate.position) && (Is.string(candidate.label) || Is.typedArray(candidate.label, InlayHintLabelPart.is)) && (candidate.kind === void 0 || InlayHintKind2.is(candidate.kind)) && candidate.textEdits === void 0 || Is.typedArray(candidate.textEdits, TextEdit3.is) && (candidate.tooltip === void 0 || Is.string(candidate.tooltip) || MarkupContent.is(candidate.tooltip)) && (candidate.paddingLeft === void 0 || Is.boolean(candidate.paddingLeft)) && (candidate.paddingRight === void 0 || Is.boolean(candidate.paddingRight));
|
|
4363
4363
|
}
|
|
4364
4364
|
InlayHint3.is = is;
|
|
4365
4365
|
})(InlayHint2 = exports3.InlayHint || (exports3.InlayHint = {}));
|
|
@@ -18091,8 +18091,9 @@ var ErrorType;
|
|
|
18091
18091
|
ErrorType2[ErrorType2["ErrorExceededMaxLength"] = 4] = "ErrorExceededMaxLength";
|
|
18092
18092
|
ErrorType2[ErrorType2["ErrorTooFewParameters"] = 5] = "ErrorTooFewParameters";
|
|
18093
18093
|
ErrorType2[ErrorType2["ErrorTooManyParameters"] = 6] = "ErrorTooManyParameters";
|
|
18094
|
-
ErrorType2[ErrorType2["
|
|
18095
|
-
ErrorType2[ErrorType2["
|
|
18094
|
+
ErrorType2[ErrorType2["ErrorEvenParameters"] = 7] = "ErrorEvenParameters";
|
|
18095
|
+
ErrorType2[ErrorType2["ErrorUnrecognizedContext"] = 8] = "ErrorUnrecognizedContext";
|
|
18096
|
+
ErrorType2[ErrorType2["ErrorUnrecognizedFunction"] = 9] = "ErrorUnrecognizedFunction";
|
|
18096
18097
|
})(ErrorType || (ErrorType = {}));
|
|
18097
18098
|
var ExpressionError = class extends Error {
|
|
18098
18099
|
constructor(typ, tok) {
|
|
@@ -18118,6 +18119,8 @@ function errorDescription(typ) {
|
|
|
18118
18119
|
return "Too few parameters supplied";
|
|
18119
18120
|
case ErrorType.ErrorTooManyParameters:
|
|
18120
18121
|
return "Too many parameters supplied";
|
|
18122
|
+
case ErrorType.ErrorEvenParameters:
|
|
18123
|
+
return "Even number of parameters supplied, requires an odd number of parameters";
|
|
18121
18124
|
case ErrorType.ErrorUnrecognizedContext:
|
|
18122
18125
|
return "Unrecognized named-value";
|
|
18123
18126
|
case ErrorType.ErrorUnrecognizedFunction:
|
|
@@ -18129,6 +18132,26 @@ function errorDescription(typ) {
|
|
|
18129
18132
|
var ExpressionEvaluationError = class extends Error {
|
|
18130
18133
|
};
|
|
18131
18134
|
|
|
18135
|
+
// ../expressions/dist/funcs/case.js
|
|
18136
|
+
var caseFunc = {
|
|
18137
|
+
name: "case",
|
|
18138
|
+
description: "`case( pred1, val1, pred2, val2, ..., default )`\n\nEvaluates predicates in order and returns the value corresponding to the first predicate that evaluates to `true`. If no predicate matches, it returns the last argument as the default value.",
|
|
18139
|
+
minArgs: 3,
|
|
18140
|
+
maxArgs: Number.MAX_SAFE_INTEGER,
|
|
18141
|
+
call: (...args) => {
|
|
18142
|
+
for (let i = 0; i < args.length - 1; i += 2) {
|
|
18143
|
+
const predicate = args[i];
|
|
18144
|
+
if (predicate.kind !== Kind.Boolean) {
|
|
18145
|
+
throw new Error("case predicate must evaluate to a boolean value");
|
|
18146
|
+
}
|
|
18147
|
+
if (predicate.value) {
|
|
18148
|
+
return args[i + 1];
|
|
18149
|
+
}
|
|
18150
|
+
}
|
|
18151
|
+
return args[args.length - 1];
|
|
18152
|
+
}
|
|
18153
|
+
};
|
|
18154
|
+
|
|
18132
18155
|
// ../expressions/dist/result.js
|
|
18133
18156
|
function falsy(d) {
|
|
18134
18157
|
switch (d.kind) {
|
|
@@ -18510,6 +18533,7 @@ var tojson = {
|
|
|
18510
18533
|
|
|
18511
18534
|
// ../expressions/dist/funcs.js
|
|
18512
18535
|
var wellKnownFunctions = {
|
|
18536
|
+
case: caseFunc,
|
|
18513
18537
|
contains,
|
|
18514
18538
|
endswith,
|
|
18515
18539
|
format,
|
|
@@ -18537,6 +18561,9 @@ function validateFunction(context, identifier, argCount) {
|
|
|
18537
18561
|
if (argCount > f.maxArgs) {
|
|
18538
18562
|
throw new ExpressionError(ErrorType.ErrorTooManyParameters, identifier);
|
|
18539
18563
|
}
|
|
18564
|
+
if (name === "case" && argCount % 2 === 0) {
|
|
18565
|
+
throw new ExpressionError(ErrorType.ErrorEvenParameters, identifier);
|
|
18566
|
+
}
|
|
18540
18567
|
}
|
|
18541
18568
|
|
|
18542
18569
|
// ../expressions/dist/idxHelper.js
|
|
@@ -18730,6 +18757,40 @@ function objectAccess(obj, idx) {
|
|
|
18730
18757
|
return new Null();
|
|
18731
18758
|
}
|
|
18732
18759
|
|
|
18760
|
+
// ../expressions/dist/features.js
|
|
18761
|
+
var allFeatureKeys = [
|
|
18762
|
+
"missingInputsQuickfix",
|
|
18763
|
+
"blockScalarChompingWarning",
|
|
18764
|
+
"actionScaffoldingSnippets",
|
|
18765
|
+
"allowCaseFunction"
|
|
18766
|
+
];
|
|
18767
|
+
var FeatureFlags = class {
|
|
18768
|
+
constructor(features) {
|
|
18769
|
+
this.features = features ?? {};
|
|
18770
|
+
}
|
|
18771
|
+
/**
|
|
18772
|
+
* Check if an experimental feature is enabled.
|
|
18773
|
+
*
|
|
18774
|
+
* Resolution order:
|
|
18775
|
+
* 1. Explicit feature flag (if set)
|
|
18776
|
+
* 2. `all` flag (if set)
|
|
18777
|
+
* 3. false (default)
|
|
18778
|
+
*/
|
|
18779
|
+
isEnabled(feature) {
|
|
18780
|
+
const explicit = this.features[feature];
|
|
18781
|
+
if (explicit !== void 0) {
|
|
18782
|
+
return explicit;
|
|
18783
|
+
}
|
|
18784
|
+
return this.features.all ?? false;
|
|
18785
|
+
}
|
|
18786
|
+
/**
|
|
18787
|
+
* Returns list of all enabled experimental features.
|
|
18788
|
+
*/
|
|
18789
|
+
getEnabledFeatures() {
|
|
18790
|
+
return allFeatureKeys.filter((key) => this.isEnabled(key));
|
|
18791
|
+
}
|
|
18792
|
+
};
|
|
18793
|
+
|
|
18733
18794
|
// ../expressions/dist/parser.js
|
|
18734
18795
|
var Parser = class {
|
|
18735
18796
|
/**
|
|
@@ -18991,7 +19052,7 @@ var Parser = class {
|
|
|
18991
19052
|
};
|
|
18992
19053
|
|
|
18993
19054
|
// ../expressions/dist/completion.js
|
|
18994
|
-
function complete(input, context, extensionFunctions, functions) {
|
|
19055
|
+
function complete(input, context, extensionFunctions, functions, featureFlags) {
|
|
18995
19056
|
const lexer = new Lexer(input);
|
|
18996
19057
|
const lexResult = lexer.lex();
|
|
18997
19058
|
const tokenInputVector = trimTokenVector(lexResult.tokens);
|
|
@@ -19008,7 +19069,7 @@ function complete(input, context, extensionFunctions, functions) {
|
|
|
19008
19069
|
}
|
|
19009
19070
|
if (tokenIdx < 0) {
|
|
19010
19071
|
const result2 = contextKeys(context);
|
|
19011
|
-
result2.push(...functionItems(extensionFunctions));
|
|
19072
|
+
result2.push(...functionItems(extensionFunctions, featureFlags));
|
|
19012
19073
|
return result2;
|
|
19013
19074
|
}
|
|
19014
19075
|
const pathTokenVector = tokenInputVector.slice(0, tokenIdx);
|
|
@@ -19019,9 +19080,13 @@ function complete(input, context, extensionFunctions, functions) {
|
|
|
19019
19080
|
const result = ev.evaluate();
|
|
19020
19081
|
return contextKeys(result);
|
|
19021
19082
|
}
|
|
19022
|
-
function functionItems(extensionFunctions) {
|
|
19083
|
+
function functionItems(extensionFunctions, featureFlags) {
|
|
19023
19084
|
const result = [];
|
|
19085
|
+
const flags = featureFlags ?? new FeatureFlags();
|
|
19024
19086
|
for (const fdef of [...Object.values(wellKnownFunctions), ...extensionFunctions]) {
|
|
19087
|
+
if (fdef.name === "case" && !flags.isEnabled("allowCaseFunction")) {
|
|
19088
|
+
continue;
|
|
19089
|
+
}
|
|
19025
19090
|
result.push({
|
|
19026
19091
|
label: fdef.name,
|
|
19027
19092
|
description: fdef.description,
|
|
@@ -19194,6 +19259,20 @@ var TraversalState = class {
|
|
|
19194
19259
|
throw new Error(`Unexpected token type '${this._token.templateTokenType}' when traversing state`);
|
|
19195
19260
|
}
|
|
19196
19261
|
}
|
|
19262
|
+
/**
|
|
19263
|
+
* Returns the ancestor tokens from root to the current token's parent container.
|
|
19264
|
+
*/
|
|
19265
|
+
getAncestors() {
|
|
19266
|
+
const ancestors = [];
|
|
19267
|
+
let state = this.parent;
|
|
19268
|
+
while (state) {
|
|
19269
|
+
if (state.current) {
|
|
19270
|
+
ancestors.unshift(state.current);
|
|
19271
|
+
}
|
|
19272
|
+
state = state.parent;
|
|
19273
|
+
}
|
|
19274
|
+
return ancestors;
|
|
19275
|
+
}
|
|
19197
19276
|
};
|
|
19198
19277
|
|
|
19199
19278
|
// ../workflow-parser/dist/templates/tokens/template-token.js
|
|
@@ -19299,11 +19378,12 @@ var TemplateToken = class {
|
|
|
19299
19378
|
}
|
|
19300
19379
|
/**
|
|
19301
19380
|
* Returns all tokens (depth first)
|
|
19302
|
-
* @param value The object to
|
|
19381
|
+
* @param value The object to traverse
|
|
19303
19382
|
* @param omitKeys Whether to omit mapping keys
|
|
19383
|
+
* @yields A tuple of [parent, token, keyToken, ancestors] for each token in the tree
|
|
19304
19384
|
*/
|
|
19305
19385
|
static *traverse(value, omitKeys) {
|
|
19306
|
-
yield [void 0, value, void 0];
|
|
19386
|
+
yield [void 0, value, void 0, []];
|
|
19307
19387
|
switch (value.templateTokenType) {
|
|
19308
19388
|
case TokenType2.Sequence:
|
|
19309
19389
|
case TokenType2.Mapping: {
|
|
@@ -19312,7 +19392,7 @@ var TemplateToken = class {
|
|
|
19312
19392
|
while (state.parent) {
|
|
19313
19393
|
if (state.moveNext(omitKeys ?? false)) {
|
|
19314
19394
|
value = state.current;
|
|
19315
|
-
yield [state.parent?.current, value, state.currentKey];
|
|
19395
|
+
yield [state.parent?.current, value, state.currentKey, state.getAncestors()];
|
|
19316
19396
|
switch (value.type) {
|
|
19317
19397
|
case TokenType2.Sequence:
|
|
19318
19398
|
case TokenType2.Mapping:
|
|
@@ -19616,13 +19696,14 @@ var LiteralToken = class extends ScalarToken {
|
|
|
19616
19696
|
|
|
19617
19697
|
// ../workflow-parser/dist/templates/tokens/string-token.js
|
|
19618
19698
|
var StringToken = class _StringToken extends LiteralToken {
|
|
19619
|
-
constructor(file, range, value, definitionInfo, source) {
|
|
19699
|
+
constructor(file, range, value, definitionInfo, source, blockScalarHeader) {
|
|
19620
19700
|
super(TokenType2.String, file, range, definitionInfo);
|
|
19621
19701
|
this.value = value;
|
|
19622
19702
|
this.source = source;
|
|
19703
|
+
this.blockScalarHeader = blockScalarHeader;
|
|
19623
19704
|
}
|
|
19624
19705
|
clone(omitSource) {
|
|
19625
|
-
return omitSource ? new _StringToken(void 0, void 0, this.value, this.definitionInfo, this.source) : new _StringToken(this.file, this.range, this.value, this.definitionInfo, this.source);
|
|
19706
|
+
return omitSource ? new _StringToken(void 0, void 0, this.value, this.definitionInfo, this.source, this.blockScalarHeader) : new _StringToken(this.file, this.range, this.value, this.definitionInfo, this.source, this.blockScalarHeader);
|
|
19626
19707
|
}
|
|
19627
19708
|
toString() {
|
|
19628
19709
|
return this.value;
|
|
@@ -19848,20 +19929,28 @@ var ExpressionToken = class extends ScalarToken {
|
|
|
19848
19929
|
// ../workflow-parser/dist/templates/tokens/basic-expression-token.js
|
|
19849
19930
|
var BasicExpressionToken = class _BasicExpressionToken extends ExpressionToken {
|
|
19850
19931
|
/**
|
|
19851
|
-
* @param
|
|
19932
|
+
* @param file The file ID where this token originated
|
|
19933
|
+
* @param range The range of the entire expression including `${{` and `}}`
|
|
19934
|
+
* @param expression The expression string without `${{` and `}}` markers
|
|
19935
|
+
* @param definitionInfo Schema definition info for this token
|
|
19936
|
+
* @param originalExpressions If transformed from individual expressions (e.g., format()), these are the originals
|
|
19937
|
+
* @param source The original source string from the YAML
|
|
19938
|
+
* @param expressionRange The range of just the expression, excluding `${{` and `}}`
|
|
19939
|
+
* @param blockScalarHeader The block scalar header (e.g., "|", "|-") if parsed from a YAML block scalar
|
|
19852
19940
|
*/
|
|
19853
|
-
constructor(file, range, expression, definitionInfo, originalExpressions, source, expressionRange) {
|
|
19941
|
+
constructor(file, range, expression, definitionInfo, originalExpressions, source, expressionRange, blockScalarHeader) {
|
|
19854
19942
|
super(TokenType2.BasicExpression, file, range, void 0, definitionInfo);
|
|
19855
19943
|
this.expr = expression;
|
|
19856
19944
|
this.source = source;
|
|
19857
19945
|
this.originalExpressions = originalExpressions;
|
|
19858
19946
|
this.expressionRange = expressionRange;
|
|
19947
|
+
this.blockScalarHeader = blockScalarHeader;
|
|
19859
19948
|
}
|
|
19860
19949
|
get expression() {
|
|
19861
19950
|
return this.expr;
|
|
19862
19951
|
}
|
|
19863
19952
|
clone(omitSource) {
|
|
19864
|
-
return omitSource ? new _BasicExpressionToken(void 0, void 0, this.expr, this.definitionInfo, this.originalExpressions, this.source, this.expressionRange) : new _BasicExpressionToken(this.file, this.range, this.expr, this.definitionInfo, this.originalExpressions, this.source, this.expressionRange);
|
|
19953
|
+
return omitSource ? new _BasicExpressionToken(void 0, void 0, this.expr, this.definitionInfo, this.originalExpressions, this.source, this.expressionRange, this.blockScalarHeader) : new _BasicExpressionToken(this.file, this.range, this.expr, this.definitionInfo, this.originalExpressions, this.source, this.expressionRange, this.blockScalarHeader);
|
|
19865
19954
|
}
|
|
19866
19955
|
toString() {
|
|
19867
19956
|
return `${OPEN_EXPRESSION} ${this.expr} ${CLOSE_EXPRESSION}`;
|
|
@@ -20270,7 +20359,7 @@ var TemplateReader = class {
|
|
|
20270
20359
|
expressionTokens.push(expression);
|
|
20271
20360
|
}
|
|
20272
20361
|
}
|
|
20273
|
-
return new BasicExpressionToken(this._fileId, token.range, `format('${format2.join("")}'${args.join("")})`, definitionInfo, expressionTokens, raw);
|
|
20362
|
+
return new BasicExpressionToken(this._fileId, token.range, `format('${format2.join("")}'${args.join("")})`, definitionInfo, expressionTokens, raw, void 0, token.blockScalarHeader);
|
|
20274
20363
|
}
|
|
20275
20364
|
parseIntoExpressionToken(tr, rawExpression, allowedContext, token, definitionInfo) {
|
|
20276
20365
|
const parseExpressionResult = this.parseExpression(tr, token, rawExpression, allowedContext, definitionInfo);
|
|
@@ -20317,7 +20406,7 @@ var TemplateReader = class {
|
|
|
20317
20406
|
}
|
|
20318
20407
|
};
|
|
20319
20408
|
return {
|
|
20320
|
-
expression: new BasicExpressionToken(this._fileId, range, trimmed, definitionInfo, void 0, token.source, expressionRange),
|
|
20409
|
+
expression: new BasicExpressionToken(this._fileId, range, trimmed, definitionInfo, void 0, token.source, expressionRange, token.blockScalarHeader),
|
|
20321
20410
|
error: void 0
|
|
20322
20411
|
};
|
|
20323
20412
|
}
|
|
@@ -21493,10 +21582,18 @@ var YamlObjectReader = class _YamlObjectReader {
|
|
|
21493
21582
|
return new BooleanToken(fileId, range, value, void 0);
|
|
21494
21583
|
case "string": {
|
|
21495
21584
|
let source;
|
|
21585
|
+
let blockScalarHeader;
|
|
21496
21586
|
if (token.srcToken && "source" in token.srcToken) {
|
|
21497
21587
|
source = token.srcToken.source;
|
|
21588
|
+
if (token.srcToken.type === "block-scalar" && "props" in token.srcToken) {
|
|
21589
|
+
const props = token.srcToken.props;
|
|
21590
|
+
const headerProp = props.find((p) => p.type === "block-scalar-header");
|
|
21591
|
+
if (headerProp?.source) {
|
|
21592
|
+
blockScalarHeader = headerProp.source;
|
|
21593
|
+
}
|
|
21594
|
+
}
|
|
21498
21595
|
}
|
|
21499
|
-
return new StringToken(fileId, range, value, void 0, source);
|
|
21596
|
+
return new StringToken(fileId, range, value, void 0, source, blockScalarHeader);
|
|
21500
21597
|
}
|
|
21501
21598
|
default:
|
|
21502
21599
|
throw new Error(`Unexpected value type '${typeof value}' when reading object`);
|
|
@@ -23066,7 +23163,7 @@ function getOptionsWithDefaults(options) {
|
|
|
23066
23163
|
}
|
|
23067
23164
|
|
|
23068
23165
|
// ../workflow-parser/dist/action-v1.0.min.json
|
|
23069
|
-
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: { "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: "non-empty-string", 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: "non-empty-string", 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", 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: "non-empty-string", 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: "non-empty-string", 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
|
+
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: { "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: "non-empty-string", 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: "non-empty-string", 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: "non-empty-string", 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: "non-empty-string", 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 } } } };
|
|
23070
23167
|
|
|
23071
23168
|
// ../workflow-parser/dist/actions/action-schema.js
|
|
23072
23169
|
var schema2;
|
|
@@ -23079,7 +23176,328 @@ function getActionSchema() {
|
|
|
23079
23176
|
}
|
|
23080
23177
|
|
|
23081
23178
|
// ../languageservice/dist/complete.js
|
|
23179
|
+
var import_vscode_languageserver_types2 = __toESM(require_main2(), 1);
|
|
23180
|
+
|
|
23181
|
+
// ../languageservice/dist/complete-action.js
|
|
23082
23182
|
var import_vscode_languageserver_types = __toESM(require_main2(), 1);
|
|
23183
|
+
var ACTION_NODE_KEYS = /* @__PURE__ */ new Set(["using", "main", "pre", "post", "pre-if", "post-if"]);
|
|
23184
|
+
var ACTION_COMPOSITE_KEYS = /* @__PURE__ */ new Set(["using", "steps"]);
|
|
23185
|
+
var ACTION_DOCKER_KEYS = /* @__PURE__ */ new Set([
|
|
23186
|
+
"using",
|
|
23187
|
+
"image",
|
|
23188
|
+
"args",
|
|
23189
|
+
"env",
|
|
23190
|
+
"entrypoint",
|
|
23191
|
+
"pre-entrypoint",
|
|
23192
|
+
"pre-if",
|
|
23193
|
+
"post-entrypoint",
|
|
23194
|
+
"post-if"
|
|
23195
|
+
]);
|
|
23196
|
+
var ACTION_SNIPPET_NODEJS_FULL = `name: '\${1:Action Name}'
|
|
23197
|
+
description: '\${2:What this action does}'
|
|
23198
|
+
|
|
23199
|
+
inputs:
|
|
23200
|
+
name:
|
|
23201
|
+
description: 'Name to greet'
|
|
23202
|
+
required: false
|
|
23203
|
+
default: 'World'
|
|
23204
|
+
|
|
23205
|
+
outputs:
|
|
23206
|
+
greeting:
|
|
23207
|
+
description: 'The greeting message'
|
|
23208
|
+
|
|
23209
|
+
runs:
|
|
23210
|
+
# For more on JavaScript actions (including @actions/toolkit), see:
|
|
23211
|
+
# https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-javascript-action
|
|
23212
|
+
using: node24
|
|
23213
|
+
main: index.js
|
|
23214
|
+
# Sample index.js (vanilla JS, no build required):
|
|
23215
|
+
#
|
|
23216
|
+
# const fs = require('fs');
|
|
23217
|
+
# const name = process.env.INPUT_NAME || 'World';
|
|
23218
|
+
# const greeting = \\\`Hello \\\${name}\\\`;
|
|
23219
|
+
# console.log(greeting);
|
|
23220
|
+
# fs.appendFileSync(process.env.GITHUB_OUTPUT, \\\`greeting=\\\${greeting}\\\\n\\\`);
|
|
23221
|
+
#
|
|
23222
|
+
# For JavaScript actions with @actions/toolkit, see:
|
|
23223
|
+
# https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-javascript-action
|
|
23224
|
+
`;
|
|
23225
|
+
var ACTION_SNIPPET_NODEJS_RUNS = `inputs:
|
|
23226
|
+
name:
|
|
23227
|
+
description: 'Name to greet'
|
|
23228
|
+
required: false
|
|
23229
|
+
default: 'World'
|
|
23230
|
+
|
|
23231
|
+
outputs:
|
|
23232
|
+
greeting:
|
|
23233
|
+
description: 'The greeting message'
|
|
23234
|
+
|
|
23235
|
+
runs:
|
|
23236
|
+
# For more on JavaScript actions (including @actions/toolkit), see:
|
|
23237
|
+
# https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-javascript-action
|
|
23238
|
+
using: node24
|
|
23239
|
+
main: index.js
|
|
23240
|
+
# Sample index.js (vanilla JS, no build required):
|
|
23241
|
+
#
|
|
23242
|
+
# const fs = require('fs');
|
|
23243
|
+
# const name = process.env.INPUT_NAME || 'World';
|
|
23244
|
+
# const greeting = \\\`Hello \\\${name}\\\`;
|
|
23245
|
+
# console.log(greeting);
|
|
23246
|
+
# fs.appendFileSync(process.env.GITHUB_OUTPUT, \\\`greeting=\\\${greeting}\\\\n\\\`);
|
|
23247
|
+
`;
|
|
23248
|
+
var ACTION_SNIPPET_NODEJS_USING = `# For more on JavaScript actions (including @actions/toolkit), see:
|
|
23249
|
+
# https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-javascript-action
|
|
23250
|
+
using: node24
|
|
23251
|
+
main: index.js
|
|
23252
|
+
# Sample index.js (vanilla JS, no build required):
|
|
23253
|
+
#
|
|
23254
|
+
# console.log('Hello World');
|
|
23255
|
+
`;
|
|
23256
|
+
var ACTION_SNIPPET_COMPOSITE_FULL = `name: '\${1:Action Name}'
|
|
23257
|
+
description: '\${2:What this action does}'
|
|
23258
|
+
|
|
23259
|
+
inputs:
|
|
23260
|
+
name:
|
|
23261
|
+
description: 'Name to greet'
|
|
23262
|
+
required: false
|
|
23263
|
+
default: 'World'
|
|
23264
|
+
|
|
23265
|
+
outputs:
|
|
23266
|
+
greeting:
|
|
23267
|
+
description: 'The greeting message'
|
|
23268
|
+
value: \\\${{ steps.greet.outputs.greeting }}
|
|
23269
|
+
|
|
23270
|
+
runs:
|
|
23271
|
+
# For more on composite actions, see:
|
|
23272
|
+
# https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-composite-action
|
|
23273
|
+
using: composite
|
|
23274
|
+
steps:
|
|
23275
|
+
- id: greet
|
|
23276
|
+
shell: bash
|
|
23277
|
+
env:
|
|
23278
|
+
INPUT_NAME: \\\${{ inputs.name }}
|
|
23279
|
+
run: |
|
|
23280
|
+
GREETING="Hello $INPUT_NAME"
|
|
23281
|
+
echo "$GREETING"
|
|
23282
|
+
echo "greeting=$GREETING" >> $GITHUB_OUTPUT
|
|
23283
|
+
`;
|
|
23284
|
+
var ACTION_SNIPPET_COMPOSITE_RUNS = `inputs:
|
|
23285
|
+
name:
|
|
23286
|
+
description: 'Name to greet'
|
|
23287
|
+
required: false
|
|
23288
|
+
default: 'World'
|
|
23289
|
+
|
|
23290
|
+
outputs:
|
|
23291
|
+
greeting:
|
|
23292
|
+
description: 'The greeting message'
|
|
23293
|
+
value: \\\${{ steps.greet.outputs.greeting }}
|
|
23294
|
+
|
|
23295
|
+
runs:
|
|
23296
|
+
# For more on composite actions, see:
|
|
23297
|
+
# https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-composite-action
|
|
23298
|
+
using: composite
|
|
23299
|
+
steps:
|
|
23300
|
+
- id: greet
|
|
23301
|
+
shell: bash
|
|
23302
|
+
env:
|
|
23303
|
+
INPUT_NAME: \\\${{ inputs.name }}
|
|
23304
|
+
run: |
|
|
23305
|
+
GREETING="Hello $INPUT_NAME"
|
|
23306
|
+
echo "$GREETING"
|
|
23307
|
+
echo "greeting=$GREETING" >> $GITHUB_OUTPUT
|
|
23308
|
+
`;
|
|
23309
|
+
var ACTION_SNIPPET_COMPOSITE_USING = `# For more on composite actions, see:
|
|
23310
|
+
# https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-composite-action
|
|
23311
|
+
using: composite
|
|
23312
|
+
steps:
|
|
23313
|
+
- shell: bash
|
|
23314
|
+
run: echo "Hello World"
|
|
23315
|
+
`;
|
|
23316
|
+
var ACTION_SNIPPET_DOCKER_FULL = `name: '\${1:Action Name}'
|
|
23317
|
+
description: '\${2:What this action does}'
|
|
23318
|
+
|
|
23319
|
+
inputs:
|
|
23320
|
+
name:
|
|
23321
|
+
description: 'Name to greet'
|
|
23322
|
+
required: false
|
|
23323
|
+
default: 'World'
|
|
23324
|
+
|
|
23325
|
+
outputs:
|
|
23326
|
+
greeting:
|
|
23327
|
+
description: 'The greeting message'
|
|
23328
|
+
|
|
23329
|
+
runs:
|
|
23330
|
+
# For more on Docker actions, see:
|
|
23331
|
+
# https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-docker-container-action
|
|
23332
|
+
using: docker
|
|
23333
|
+
# 'docker://image:tag' uses pre-built image, 'Dockerfile' builds locally
|
|
23334
|
+
image: '\${3:docker://alpine:3.20}'
|
|
23335
|
+
env:
|
|
23336
|
+
INPUT_NAME: \\\${{ inputs.name }}
|
|
23337
|
+
entrypoint: '\${4:sh}'
|
|
23338
|
+
args:
|
|
23339
|
+
- -c
|
|
23340
|
+
- |
|
|
23341
|
+
GREETING="Hello $INPUT_NAME"
|
|
23342
|
+
echo "$GREETING"
|
|
23343
|
+
echo "greeting=$GREETING" >> $GITHUB_OUTPUT
|
|
23344
|
+
`;
|
|
23345
|
+
var ACTION_SNIPPET_DOCKER_RUNS = `inputs:
|
|
23346
|
+
name:
|
|
23347
|
+
description: 'Name to greet'
|
|
23348
|
+
required: false
|
|
23349
|
+
default: 'World'
|
|
23350
|
+
|
|
23351
|
+
outputs:
|
|
23352
|
+
greeting:
|
|
23353
|
+
description: 'The greeting message'
|
|
23354
|
+
|
|
23355
|
+
runs:
|
|
23356
|
+
# For more on Docker actions, see:
|
|
23357
|
+
# https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-docker-container-action
|
|
23358
|
+
using: docker
|
|
23359
|
+
# 'docker://image:tag' uses pre-built image, 'Dockerfile' builds locally
|
|
23360
|
+
image: '\${1:docker://alpine:3.20}'
|
|
23361
|
+
env:
|
|
23362
|
+
INPUT_NAME: \\\${{ inputs.name }}
|
|
23363
|
+
entrypoint: '\${2:sh}'
|
|
23364
|
+
args:
|
|
23365
|
+
- -c
|
|
23366
|
+
- |
|
|
23367
|
+
GREETING="Hello $INPUT_NAME"
|
|
23368
|
+
echo "$GREETING"
|
|
23369
|
+
echo "greeting=$GREETING" >> $GITHUB_OUTPUT
|
|
23370
|
+
`;
|
|
23371
|
+
var ACTION_SNIPPET_DOCKER_USING = `# For more on Docker actions, see:
|
|
23372
|
+
# https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-docker-container-action
|
|
23373
|
+
using: docker
|
|
23374
|
+
# 'docker://image:tag' uses pre-built image, 'Dockerfile' builds locally
|
|
23375
|
+
image: '\${1:docker://alpine:3.20}'
|
|
23376
|
+
entrypoint: '\${2:sh}'
|
|
23377
|
+
args:
|
|
23378
|
+
- -c
|
|
23379
|
+
- echo "Hello World"
|
|
23380
|
+
`;
|
|
23381
|
+
function filterActionRunsCompletions(values, path, root) {
|
|
23382
|
+
let runsMapping;
|
|
23383
|
+
if (root instanceof MappingToken) {
|
|
23384
|
+
for (let i = 0; i < root.count; i++) {
|
|
23385
|
+
const { key, value } = root.get(i);
|
|
23386
|
+
if (key.toString().toLowerCase() === "runs" && value instanceof MappingToken) {
|
|
23387
|
+
runsMapping = value;
|
|
23388
|
+
break;
|
|
23389
|
+
}
|
|
23390
|
+
}
|
|
23391
|
+
}
|
|
23392
|
+
if (!runsMapping) {
|
|
23393
|
+
return values;
|
|
23394
|
+
}
|
|
23395
|
+
const isInsideRuns = path.some((token) => token === runsMapping);
|
|
23396
|
+
if (!isInsideRuns) {
|
|
23397
|
+
return values;
|
|
23398
|
+
}
|
|
23399
|
+
const runsMappingIndex = path.indexOf(runsMapping);
|
|
23400
|
+
if (runsMappingIndex === -1) {
|
|
23401
|
+
return values;
|
|
23402
|
+
}
|
|
23403
|
+
if (runsMappingIndex < path.length - 1) {
|
|
23404
|
+
return values;
|
|
23405
|
+
}
|
|
23406
|
+
let usingValue;
|
|
23407
|
+
for (let i = 0; i < runsMapping.count; i++) {
|
|
23408
|
+
const { key, value } = runsMapping.get(i);
|
|
23409
|
+
if (key.toString().toLowerCase() === "using") {
|
|
23410
|
+
usingValue = value.toString();
|
|
23411
|
+
break;
|
|
23412
|
+
}
|
|
23413
|
+
}
|
|
23414
|
+
let allowedKeys;
|
|
23415
|
+
if (!usingValue) {
|
|
23416
|
+
return values.map((v) => {
|
|
23417
|
+
if (v.label.toLowerCase() === "using") {
|
|
23418
|
+
return { ...v, sortText: "0_using" };
|
|
23419
|
+
}
|
|
23420
|
+
return v;
|
|
23421
|
+
});
|
|
23422
|
+
} else if (usingValue.match(/^node\d+$/i)) {
|
|
23423
|
+
allowedKeys = ACTION_NODE_KEYS;
|
|
23424
|
+
} else if (usingValue.toLowerCase() === "composite") {
|
|
23425
|
+
allowedKeys = ACTION_COMPOSITE_KEYS;
|
|
23426
|
+
} else if (usingValue.toLowerCase() === "docker") {
|
|
23427
|
+
allowedKeys = ACTION_DOCKER_KEYS;
|
|
23428
|
+
} else {
|
|
23429
|
+
return values;
|
|
23430
|
+
}
|
|
23431
|
+
return values.filter((v) => allowedKeys.has(v.label.toLowerCase()));
|
|
23432
|
+
}
|
|
23433
|
+
function getActionScaffoldingSnippets(root, path, position) {
|
|
23434
|
+
let runsMapping;
|
|
23435
|
+
if (root instanceof MappingToken) {
|
|
23436
|
+
for (let i = 0; i < root.count; i++) {
|
|
23437
|
+
const { key, value } = root.get(i);
|
|
23438
|
+
if (key.toString().toLowerCase() === "runs" && value instanceof MappingToken) {
|
|
23439
|
+
runsMapping = value;
|
|
23440
|
+
break;
|
|
23441
|
+
}
|
|
23442
|
+
}
|
|
23443
|
+
}
|
|
23444
|
+
if (runsMapping) {
|
|
23445
|
+
for (let i = 0; i < runsMapping.count; i++) {
|
|
23446
|
+
const { key } = runsMapping.get(i);
|
|
23447
|
+
if (key.toString().toLowerCase() === "using") {
|
|
23448
|
+
return [];
|
|
23449
|
+
}
|
|
23450
|
+
}
|
|
23451
|
+
}
|
|
23452
|
+
const runsMappingIndex = runsMapping ? path.indexOf(runsMapping) : -1;
|
|
23453
|
+
const isDirectlyInsideRuns = runsMappingIndex !== -1 && runsMappingIndex === path.length - 1;
|
|
23454
|
+
if (isDirectlyInsideRuns) {
|
|
23455
|
+
return [
|
|
23456
|
+
createSnippetCompletion("Node.js Action", "Scaffold a Node.js action", ACTION_SNIPPET_NODEJS_USING, position, "1_nodejs"),
|
|
23457
|
+
createSnippetCompletion("Composite Action", "Scaffold a composite action", ACTION_SNIPPET_COMPOSITE_USING, position, "2_composite"),
|
|
23458
|
+
createSnippetCompletion("Docker Action", "Scaffold a Docker action", ACTION_SNIPPET_DOCKER_USING, position, "3_docker")
|
|
23459
|
+
];
|
|
23460
|
+
}
|
|
23461
|
+
const isAtRoot = path.length === 0 || path.length === 1 && path[0] === root;
|
|
23462
|
+
if (!isAtRoot || runsMapping) {
|
|
23463
|
+
return [];
|
|
23464
|
+
}
|
|
23465
|
+
let hasNameOrDescription = false;
|
|
23466
|
+
if (root instanceof MappingToken) {
|
|
23467
|
+
for (let i = 0; i < root.count; i++) {
|
|
23468
|
+
const keyStr = root.get(i).key.toString().toLowerCase();
|
|
23469
|
+
if (keyStr === "name" || keyStr === "description") {
|
|
23470
|
+
hasNameOrDescription = true;
|
|
23471
|
+
break;
|
|
23472
|
+
}
|
|
23473
|
+
}
|
|
23474
|
+
}
|
|
23475
|
+
if (hasNameOrDescription) {
|
|
23476
|
+
return [
|
|
23477
|
+
createSnippetCompletion("Node.js Action", "Scaffold a Node.js action", ACTION_SNIPPET_NODEJS_RUNS, position, "1_nodejs"),
|
|
23478
|
+
createSnippetCompletion("Composite Action", "Scaffold a composite action", ACTION_SNIPPET_COMPOSITE_RUNS, position, "2_composite"),
|
|
23479
|
+
createSnippetCompletion("Docker Action", "Scaffold a Docker action", ACTION_SNIPPET_DOCKER_RUNS, position, "3_docker")
|
|
23480
|
+
];
|
|
23481
|
+
}
|
|
23482
|
+
return [
|
|
23483
|
+
createSnippetCompletion("Node.js Action", "Scaffold a complete Node.js action", ACTION_SNIPPET_NODEJS_FULL, position, "1_nodejs"),
|
|
23484
|
+
createSnippetCompletion("Composite Action", "Scaffold a complete composite action", ACTION_SNIPPET_COMPOSITE_FULL, position, "2_composite"),
|
|
23485
|
+
createSnippetCompletion("Docker Action", "Scaffold a complete Docker action", ACTION_SNIPPET_DOCKER_FULL, position, "3_docker")
|
|
23486
|
+
];
|
|
23487
|
+
}
|
|
23488
|
+
function createSnippetCompletion(label, description, snippetText, position, sortText) {
|
|
23489
|
+
return {
|
|
23490
|
+
label,
|
|
23491
|
+
kind: import_vscode_languageserver_types.CompletionItemKind.Snippet,
|
|
23492
|
+
documentation: {
|
|
23493
|
+
kind: "markdown",
|
|
23494
|
+
value: description
|
|
23495
|
+
},
|
|
23496
|
+
insertTextFormat: import_vscode_languageserver_types.InsertTextFormat.Snippet,
|
|
23497
|
+
sortText,
|
|
23498
|
+
textEdit: import_vscode_languageserver_types.TextEdit.insert(position, snippetText)
|
|
23499
|
+
};
|
|
23500
|
+
}
|
|
23083
23501
|
|
|
23084
23502
|
// ../languageservice/dist/context/action-context.js
|
|
23085
23503
|
function getActionContext(uri, template, tokenPath) {
|
|
@@ -25184,13 +25602,20 @@ async function complete2(textDocument, position, config) {
|
|
|
25184
25602
|
if (token && (isBasicExpression(token) || isPotentiallyExpression(token))) {
|
|
25185
25603
|
const allowedContext = token.definitionInfo?.allowedContext || [];
|
|
25186
25604
|
const context = isAction ? getActionExpressionContext(allowedContext, config?.contextProviderConfig, actionContext, Mode.Completion) : await getWorkflowExpressionContext(allowedContext, config?.contextProviderConfig, workflowContext, Mode.Completion);
|
|
25187
|
-
return getExpressionCompletionItems(token, context, newPos);
|
|
25605
|
+
return getExpressionCompletionItems(token, context, newPos, config?.featureFlags);
|
|
25188
25606
|
}
|
|
25189
25607
|
const indentation = guessIndentation(newDoc, 2, true);
|
|
25190
25608
|
const indentString = " ".repeat(indentation.tabSize);
|
|
25191
|
-
|
|
25609
|
+
let values = await getValues(token, keyToken, parent, config?.valueProviderConfig, workflowContext, indentString, schema3);
|
|
25610
|
+
if (isAction && parsedTemplate.value) {
|
|
25611
|
+
values = filterActionRunsCompletions(values, path, parsedTemplate.value);
|
|
25612
|
+
}
|
|
25192
25613
|
const escapeHatches = getEscapeHatchCompletions(token, keyToken, indentString, newPos, schema3);
|
|
25193
25614
|
values.push(...escapeHatches);
|
|
25615
|
+
let actionSnippets = [];
|
|
25616
|
+
if (isAction && config?.featureFlags?.isEnabled("actionScaffoldingSnippets")) {
|
|
25617
|
+
actionSnippets = getActionScaffoldingSnippets(parsedTemplate.value, path, position);
|
|
25618
|
+
}
|
|
25194
25619
|
let replaceRange;
|
|
25195
25620
|
if (token?.range) {
|
|
25196
25621
|
replaceRange = mapRange(token.range);
|
|
@@ -25202,24 +25627,24 @@ async function complete2(textDocument, position, config) {
|
|
|
25202
25627
|
end: { line: position.line, character: position.character + 1 }
|
|
25203
25628
|
});
|
|
25204
25629
|
if (charAfterPos === ":") {
|
|
25205
|
-
replaceRange =
|
|
25630
|
+
replaceRange = import_vscode_languageserver_types2.Range.create({ line: position.line, character: position.character - val }, { line: position.line, character: position.character + 1 });
|
|
25206
25631
|
} else {
|
|
25207
|
-
replaceRange =
|
|
25632
|
+
replaceRange = import_vscode_languageserver_types2.Range.create({ line: position.line, character: position.character - val }, position);
|
|
25208
25633
|
}
|
|
25209
25634
|
}
|
|
25210
|
-
|
|
25635
|
+
const completionItems = values.map((value) => {
|
|
25211
25636
|
const newText = value.insertText || value.label;
|
|
25212
25637
|
let textEdit;
|
|
25213
25638
|
if (value.textEdit) {
|
|
25214
|
-
textEdit =
|
|
25639
|
+
textEdit = import_vscode_languageserver_types2.TextEdit.replace(value.textEdit.range, value.textEdit.newText);
|
|
25215
25640
|
} else if (replaceRange) {
|
|
25216
|
-
textEdit =
|
|
25641
|
+
textEdit = import_vscode_languageserver_types2.TextEdit.replace(replaceRange, newText);
|
|
25217
25642
|
} else {
|
|
25218
|
-
textEdit =
|
|
25643
|
+
textEdit = import_vscode_languageserver_types2.TextEdit.insert(position, newText);
|
|
25219
25644
|
}
|
|
25220
25645
|
let additionalTextEdits;
|
|
25221
25646
|
if (value.additionalTextEdits) {
|
|
25222
|
-
additionalTextEdits = value.additionalTextEdits.map((edit) =>
|
|
25647
|
+
additionalTextEdits = value.additionalTextEdits.map((edit) => import_vscode_languageserver_types2.TextEdit.replace(edit.range, edit.newText));
|
|
25223
25648
|
}
|
|
25224
25649
|
const item = {
|
|
25225
25650
|
label: value.label,
|
|
@@ -25230,12 +25655,13 @@ async function complete2(textDocument, position, config) {
|
|
|
25230
25655
|
kind: "markdown",
|
|
25231
25656
|
value: value.description
|
|
25232
25657
|
},
|
|
25233
|
-
tags: value.deprecated ? [
|
|
25658
|
+
tags: value.deprecated ? [import_vscode_languageserver_types2.CompletionItemTag.Deprecated] : void 0,
|
|
25234
25659
|
textEdit,
|
|
25235
25660
|
additionalTextEdits
|
|
25236
25661
|
};
|
|
25237
25662
|
return item;
|
|
25238
25663
|
});
|
|
25664
|
+
return [...completionItems, ...actionSnippets];
|
|
25239
25665
|
}
|
|
25240
25666
|
async function getValues(token, keyToken, parent, valueProviderConfig, workflowContext, indentation, schema3) {
|
|
25241
25667
|
if (!parent) {
|
|
@@ -25403,7 +25829,7 @@ function getExistingValues(token, parent) {
|
|
|
25403
25829
|
return mapKeys;
|
|
25404
25830
|
}
|
|
25405
25831
|
}
|
|
25406
|
-
function getExpressionCompletionItems(token, context, pos) {
|
|
25832
|
+
function getExpressionCompletionItems(token, context, pos, featureFlags) {
|
|
25407
25833
|
if (!token.range) {
|
|
25408
25834
|
return [];
|
|
25409
25835
|
}
|
|
@@ -25417,7 +25843,7 @@ function getExpressionCompletionItems(token, context, pos) {
|
|
|
25417
25843
|
const cursorOffset = getOffsetInContent(token.range, currentInput, pos);
|
|
25418
25844
|
const expressionInput = (getExpressionInput(currentInput, cursorOffset) || "").trim();
|
|
25419
25845
|
try {
|
|
25420
|
-
return complete(expressionInput, context, [], validatorFunctions).map((item) => mapExpressionCompletionItem(item, currentInput[cursorOffset]));
|
|
25846
|
+
return complete(expressionInput, context, [], validatorFunctions, featureFlags).map((item) => mapExpressionCompletionItem(item, currentInput[cursorOffset]));
|
|
25421
25847
|
} catch (e) {
|
|
25422
25848
|
error(`Error while completing expression: '${e?.message || "<no details>"}'`);
|
|
25423
25849
|
return [];
|
|
@@ -25440,7 +25866,7 @@ function mapExpressionCompletionItem(item, charAfterPos) {
|
|
|
25440
25866
|
value: item.description
|
|
25441
25867
|
},
|
|
25442
25868
|
insertText,
|
|
25443
|
-
kind: item.function ?
|
|
25869
|
+
kind: item.function ? import_vscode_languageserver_types2.CompletionItemKind.Function : import_vscode_languageserver_types2.CompletionItemKind.Variable
|
|
25444
25870
|
};
|
|
25445
25871
|
}
|
|
25446
25872
|
function getOffsetInContent(tokenRange, currentInput, pos) {
|
|
@@ -26148,6 +26574,15 @@ async function hover(document, position, config) {
|
|
|
26148
26574
|
return null;
|
|
26149
26575
|
}
|
|
26150
26576
|
info(`Calculating hover for token with definition ${hoverToken.definition.key}`);
|
|
26577
|
+
if (isString(hoverToken) && hoverToken.definition.key === "cron-pattern") {
|
|
26578
|
+
const cronDescription = getCronDescription(hoverToken.value);
|
|
26579
|
+
if (cronDescription) {
|
|
26580
|
+
return {
|
|
26581
|
+
contents: cronDescription,
|
|
26582
|
+
range: mapRange(hoverToken.range)
|
|
26583
|
+
};
|
|
26584
|
+
}
|
|
26585
|
+
}
|
|
26151
26586
|
let description;
|
|
26152
26587
|
if (!isAction && tokenResult.parent && isReusableWorkflowJobInput(tokenResult)) {
|
|
26153
26588
|
description = getReusableWorkflowInputDescription(documentContext, tokenResult);
|
|
@@ -26225,7 +26660,7 @@ function expressionHover(exprPos, expressionContext, namedContexts, functions) {
|
|
|
26225
26660
|
}
|
|
26226
26661
|
|
|
26227
26662
|
// ../languageservice/dist/inlay-hints.js
|
|
26228
|
-
var
|
|
26663
|
+
var import_vscode_languageserver_types3 = __toESM(require_main2(), 1);
|
|
26229
26664
|
function getInlayHints(document) {
|
|
26230
26665
|
if (isActionDocument(document.uri)) {
|
|
26231
26666
|
return [];
|
|
@@ -26253,7 +26688,7 @@ function getInlayHints(document) {
|
|
|
26253
26688
|
// Convert from 1-based to 0-based
|
|
26254
26689
|
},
|
|
26255
26690
|
label: `\u2192 ${description}`,
|
|
26256
|
-
kind:
|
|
26691
|
+
kind: import_vscode_languageserver_types3.InlayHintKind.Parameter,
|
|
26257
26692
|
paddingLeft: true
|
|
26258
26693
|
});
|
|
26259
26694
|
}
|
|
@@ -26263,7 +26698,7 @@ function getInlayHints(document) {
|
|
|
26263
26698
|
}
|
|
26264
26699
|
|
|
26265
26700
|
// ../languageservice/dist/validate.js
|
|
26266
|
-
var
|
|
26701
|
+
var import_vscode_languageserver_types6 = __toESM(require_main2(), 1);
|
|
26267
26702
|
|
|
26268
26703
|
// ../languageservice/dist/expression-validation/error-dictionary.js
|
|
26269
26704
|
var AccessError = class extends Error {
|
|
@@ -26342,7 +26777,7 @@ var ValidationEvaluator = class extends Evaluator {
|
|
|
26342
26777
|
};
|
|
26343
26778
|
|
|
26344
26779
|
// ../languageservice/dist/validate-action-reference.js
|
|
26345
|
-
var
|
|
26780
|
+
var import_vscode_languageserver_types4 = __toESM(require_main2(), 1);
|
|
26346
26781
|
async function validateActionReference(diagnostics, stepToken, step, config) {
|
|
26347
26782
|
if (!isMapping(stepToken) || !step || !isActionStep(step) || !config?.actionsMetadataProvider) {
|
|
26348
26783
|
return;
|
|
@@ -26354,7 +26789,7 @@ async function validateActionReference(diagnostics, stepToken, step, config) {
|
|
|
26354
26789
|
const actionMetadata = await config.actionsMetadataProvider.fetchActionMetadata(action);
|
|
26355
26790
|
if (actionMetadata === void 0) {
|
|
26356
26791
|
diagnostics.push({
|
|
26357
|
-
severity:
|
|
26792
|
+
severity: import_vscode_languageserver_types4.DiagnosticSeverity.Error,
|
|
26358
26793
|
range: mapRange(step.uses.range),
|
|
26359
26794
|
message: `Unable to resolve action \`${step.uses.value}\`, repository or version not found`
|
|
26360
26795
|
});
|
|
@@ -26382,7 +26817,7 @@ async function validateActionReference(diagnostics, stepToken, step, config) {
|
|
|
26382
26817
|
for (const [input, inputToken] of stepInputs) {
|
|
26383
26818
|
if (!actionInputs[input]) {
|
|
26384
26819
|
diagnostics.push({
|
|
26385
|
-
severity:
|
|
26820
|
+
severity: import_vscode_languageserver_types4.DiagnosticSeverity.Error,
|
|
26386
26821
|
range: mapRange(inputToken.range),
|
|
26387
26822
|
message: `Invalid action input '${input}'`
|
|
26388
26823
|
});
|
|
@@ -26390,7 +26825,7 @@ async function validateActionReference(diagnostics, stepToken, step, config) {
|
|
|
26390
26825
|
const deprecationMessage = actionInputs[input]?.deprecationMessage;
|
|
26391
26826
|
if (deprecationMessage) {
|
|
26392
26827
|
diagnostics.push({
|
|
26393
|
-
severity:
|
|
26828
|
+
severity: import_vscode_languageserver_types4.DiagnosticSeverity.Warning,
|
|
26394
26829
|
range: mapRange(inputToken.range),
|
|
26395
26830
|
message: deprecationMessage
|
|
26396
26831
|
});
|
|
@@ -26400,7 +26835,7 @@ async function validateActionReference(diagnostics, stepToken, step, config) {
|
|
|
26400
26835
|
if (missingRequiredInputs.length > 0) {
|
|
26401
26836
|
const message = missingRequiredInputs.length === 1 ? `Missing required input \`${missingRequiredInputs[0][0]}\`` : `Missing required inputs: ${missingRequiredInputs.map((input) => `\`${input[0]}\``).join(", ")}`;
|
|
26402
26837
|
diagnostics.push({
|
|
26403
|
-
severity:
|
|
26838
|
+
severity: import_vscode_languageserver_types4.DiagnosticSeverity.Error,
|
|
26404
26839
|
range: mapRange((withKey || stepToken).range),
|
|
26405
26840
|
message
|
|
26406
26841
|
});
|
|
@@ -26408,7 +26843,23 @@ async function validateActionReference(diagnostics, stepToken, step, config) {
|
|
|
26408
26843
|
}
|
|
26409
26844
|
|
|
26410
26845
|
// ../languageservice/dist/validate-action.js
|
|
26411
|
-
var
|
|
26846
|
+
var import_vscode_languageserver_types5 = __toESM(require_main2(), 1);
|
|
26847
|
+
var NODE_KEYS = /* @__PURE__ */ new Set(["using", "main", "pre", "post", "pre-if", "post-if"]);
|
|
26848
|
+
var COMPOSITE_KEYS = /* @__PURE__ */ new Set(["using", "steps"]);
|
|
26849
|
+
var DOCKER_KEYS = /* @__PURE__ */ new Set([
|
|
26850
|
+
"using",
|
|
26851
|
+
"image",
|
|
26852
|
+
"args",
|
|
26853
|
+
"env",
|
|
26854
|
+
"entrypoint",
|
|
26855
|
+
"pre-entrypoint",
|
|
26856
|
+
"pre-if",
|
|
26857
|
+
"post-entrypoint",
|
|
26858
|
+
"post-if"
|
|
26859
|
+
]);
|
|
26860
|
+
var NODE_REQUIRED_KEYS = ["main"];
|
|
26861
|
+
var COMPOSITE_REQUIRED_KEYS = ["steps"];
|
|
26862
|
+
var DOCKER_REQUIRED_KEYS = ["image"];
|
|
26412
26863
|
async function validateAction(textDocument, config) {
|
|
26413
26864
|
const file = {
|
|
26414
26865
|
name: textDocument.uri,
|
|
@@ -26420,11 +26871,15 @@ async function validateAction(textDocument, config) {
|
|
|
26420
26871
|
if (!result) {
|
|
26421
26872
|
return [];
|
|
26422
26873
|
}
|
|
26423
|
-
|
|
26874
|
+
const schemaErrors = result.context.errors.getErrors();
|
|
26875
|
+
if (result.value) {
|
|
26876
|
+
diagnostics.push(...validateRunsKeysAndFilterErrors(result.value, schemaErrors));
|
|
26877
|
+
}
|
|
26878
|
+
for (const err of schemaErrors) {
|
|
26424
26879
|
const range = mapRange(err.range);
|
|
26425
|
-
let severity =
|
|
26880
|
+
let severity = import_vscode_languageserver_types5.DiagnosticSeverity.Error;
|
|
26426
26881
|
if (err.rawMessage.includes("deprecated")) {
|
|
26427
|
-
severity =
|
|
26882
|
+
severity = import_vscode_languageserver_types5.DiagnosticSeverity.Warning;
|
|
26428
26883
|
}
|
|
26429
26884
|
diagnostics.push({
|
|
26430
26885
|
message: err.rawMessage,
|
|
@@ -26463,6 +26918,222 @@ function findStepsSequence(root) {
|
|
|
26463
26918
|
}
|
|
26464
26919
|
return void 0;
|
|
26465
26920
|
}
|
|
26921
|
+
function validateRunsKeysAndFilterErrors(root, schemaErrors) {
|
|
26922
|
+
const diagnostics = [];
|
|
26923
|
+
let runsMapping;
|
|
26924
|
+
if (root instanceof MappingToken) {
|
|
26925
|
+
for (let i = 0; i < root.count; i++) {
|
|
26926
|
+
const { key, value } = root.get(i);
|
|
26927
|
+
if (key.toString().toLowerCase() === "runs" && value instanceof MappingToken) {
|
|
26928
|
+
runsMapping = value;
|
|
26929
|
+
break;
|
|
26930
|
+
}
|
|
26931
|
+
}
|
|
26932
|
+
}
|
|
26933
|
+
if (!runsMapping) {
|
|
26934
|
+
return diagnostics;
|
|
26935
|
+
}
|
|
26936
|
+
let usingValue;
|
|
26937
|
+
for (let i = 0; i < runsMapping.count; i++) {
|
|
26938
|
+
const { key, value } = runsMapping.get(i);
|
|
26939
|
+
if (key.toString().toLowerCase() === "using") {
|
|
26940
|
+
usingValue = value.toString();
|
|
26941
|
+
break;
|
|
26942
|
+
}
|
|
26943
|
+
}
|
|
26944
|
+
if (!usingValue) {
|
|
26945
|
+
return diagnostics;
|
|
26946
|
+
}
|
|
26947
|
+
let allowedKeys;
|
|
26948
|
+
let requiredKeys;
|
|
26949
|
+
let actionType;
|
|
26950
|
+
if (usingValue.match(/^node\d+$/i)) {
|
|
26951
|
+
allowedKeys = NODE_KEYS;
|
|
26952
|
+
requiredKeys = NODE_REQUIRED_KEYS;
|
|
26953
|
+
actionType = "Node.js";
|
|
26954
|
+
} else if (usingValue.toLowerCase() === "composite") {
|
|
26955
|
+
allowedKeys = COMPOSITE_KEYS;
|
|
26956
|
+
requiredKeys = COMPOSITE_REQUIRED_KEYS;
|
|
26957
|
+
actionType = "composite";
|
|
26958
|
+
} else if (usingValue.toLowerCase() === "docker") {
|
|
26959
|
+
allowedKeys = DOCKER_KEYS;
|
|
26960
|
+
requiredKeys = DOCKER_REQUIRED_KEYS;
|
|
26961
|
+
actionType = "Docker";
|
|
26962
|
+
} else {
|
|
26963
|
+
return diagnostics;
|
|
26964
|
+
}
|
|
26965
|
+
const presentKeys = /* @__PURE__ */ new Set();
|
|
26966
|
+
for (let i = 0; i < runsMapping.count; i++) {
|
|
26967
|
+
const { key } = runsMapping.get(i);
|
|
26968
|
+
presentKeys.add(key.toString().toLowerCase());
|
|
26969
|
+
}
|
|
26970
|
+
for (let i = 0; i < runsMapping.count; i++) {
|
|
26971
|
+
const { key } = runsMapping.get(i);
|
|
26972
|
+
const keyStr = key.toString().toLowerCase();
|
|
26973
|
+
if (!allowedKeys.has(keyStr)) {
|
|
26974
|
+
diagnostics.push({
|
|
26975
|
+
severity: import_vscode_languageserver_types5.DiagnosticSeverity.Error,
|
|
26976
|
+
range: mapRange(key.range),
|
|
26977
|
+
message: `'${key.toString()}' is not valid for ${actionType} actions (using: ${usingValue})`
|
|
26978
|
+
});
|
|
26979
|
+
}
|
|
26980
|
+
}
|
|
26981
|
+
for (const requiredKey of requiredKeys) {
|
|
26982
|
+
if (!presentKeys.has(requiredKey)) {
|
|
26983
|
+
let usingKeyRange = runsMapping.range;
|
|
26984
|
+
for (let i = 0; i < runsMapping.count; i++) {
|
|
26985
|
+
const { key } = runsMapping.get(i);
|
|
26986
|
+
if (key.toString().toLowerCase() === "using") {
|
|
26987
|
+
usingKeyRange = key.range;
|
|
26988
|
+
break;
|
|
26989
|
+
}
|
|
26990
|
+
}
|
|
26991
|
+
diagnostics.push({
|
|
26992
|
+
severity: import_vscode_languageserver_types5.DiagnosticSeverity.Error,
|
|
26993
|
+
range: mapRange(usingKeyRange),
|
|
26994
|
+
message: `'${requiredKey}' is required for ${actionType} actions (using: ${usingValue})`
|
|
26995
|
+
});
|
|
26996
|
+
}
|
|
26997
|
+
}
|
|
26998
|
+
for (let i = schemaErrors.length - 1; i >= 0; i--) {
|
|
26999
|
+
const err = schemaErrors[i];
|
|
27000
|
+
if (err.range?.start.line !== runsMapping.range?.start.line || err.range?.start.column !== runsMapping.range?.start.column) {
|
|
27001
|
+
continue;
|
|
27002
|
+
}
|
|
27003
|
+
const isOneOfAmbiguity = err.rawMessage.startsWith("There's not enough info to determine");
|
|
27004
|
+
const isRequiredKey = /^Required property is missing: (main|steps|image)$/.test(err.rawMessage);
|
|
27005
|
+
if (!isOneOfAmbiguity && !isRequiredKey) {
|
|
27006
|
+
continue;
|
|
27007
|
+
}
|
|
27008
|
+
if (diagnostics.length > 0) {
|
|
27009
|
+
schemaErrors.splice(i, 1);
|
|
27010
|
+
}
|
|
27011
|
+
}
|
|
27012
|
+
return diagnostics;
|
|
27013
|
+
}
|
|
27014
|
+
|
|
27015
|
+
// ../languageservice/dist/validate-format-string.js
|
|
27016
|
+
function validateFormatString(formatString) {
|
|
27017
|
+
let maxIndex = -1;
|
|
27018
|
+
let i = 0;
|
|
27019
|
+
while (i < formatString.length) {
|
|
27020
|
+
let lbrace = -1;
|
|
27021
|
+
for (let j = i; j < formatString.length; j++) {
|
|
27022
|
+
if (formatString[j] === "{") {
|
|
27023
|
+
lbrace = j;
|
|
27024
|
+
break;
|
|
27025
|
+
}
|
|
27026
|
+
}
|
|
27027
|
+
let rbrace = -1;
|
|
27028
|
+
for (let j = i; j < formatString.length; j++) {
|
|
27029
|
+
if (formatString[j] === "}") {
|
|
27030
|
+
rbrace = j;
|
|
27031
|
+
break;
|
|
27032
|
+
}
|
|
27033
|
+
}
|
|
27034
|
+
if (lbrace < 0 && rbrace < 0) {
|
|
27035
|
+
break;
|
|
27036
|
+
}
|
|
27037
|
+
if (lbrace >= 0 && (rbrace < 0 || lbrace < rbrace)) {
|
|
27038
|
+
if (lbrace + 1 < formatString.length && formatString[lbrace + 1] === "{") {
|
|
27039
|
+
i = lbrace + 2;
|
|
27040
|
+
continue;
|
|
27041
|
+
}
|
|
27042
|
+
rbrace = -1;
|
|
27043
|
+
for (let j = lbrace + 1; j < formatString.length; j++) {
|
|
27044
|
+
if (formatString[j] === "}") {
|
|
27045
|
+
rbrace = j;
|
|
27046
|
+
break;
|
|
27047
|
+
}
|
|
27048
|
+
}
|
|
27049
|
+
if (rbrace < 0) {
|
|
27050
|
+
return { valid: false, maxArgIndex: -1 };
|
|
27051
|
+
}
|
|
27052
|
+
if (rbrace === lbrace + 1) {
|
|
27053
|
+
return { valid: false, maxArgIndex: -1 };
|
|
27054
|
+
}
|
|
27055
|
+
let index = 0;
|
|
27056
|
+
for (let j = lbrace + 1; j < rbrace; j++) {
|
|
27057
|
+
const c = formatString[j];
|
|
27058
|
+
if (c < "0" || c > "9") {
|
|
27059
|
+
return { valid: false, maxArgIndex: -1 };
|
|
27060
|
+
}
|
|
27061
|
+
index = index * 10 + (c.charCodeAt(0) - "0".charCodeAt(0));
|
|
27062
|
+
}
|
|
27063
|
+
if (index > maxIndex) {
|
|
27064
|
+
maxIndex = index;
|
|
27065
|
+
}
|
|
27066
|
+
i = rbrace + 1;
|
|
27067
|
+
continue;
|
|
27068
|
+
}
|
|
27069
|
+
if (rbrace + 1 < formatString.length && formatString[rbrace + 1] === "}") {
|
|
27070
|
+
i = rbrace + 2;
|
|
27071
|
+
continue;
|
|
27072
|
+
}
|
|
27073
|
+
return { valid: false, maxArgIndex: -1 };
|
|
27074
|
+
}
|
|
27075
|
+
return { valid: true, maxArgIndex: maxIndex };
|
|
27076
|
+
}
|
|
27077
|
+
function validateFormatCalls(expr) {
|
|
27078
|
+
const errors = [];
|
|
27079
|
+
const stack = [expr];
|
|
27080
|
+
while (stack.length > 0) {
|
|
27081
|
+
const node = stack.pop();
|
|
27082
|
+
if (!node) {
|
|
27083
|
+
continue;
|
|
27084
|
+
}
|
|
27085
|
+
if (node instanceof FunctionCall) {
|
|
27086
|
+
if (node.functionName.lexeme.toLowerCase() === "format") {
|
|
27087
|
+
const error2 = validateSingleFormatCall(node);
|
|
27088
|
+
if (error2) {
|
|
27089
|
+
errors.push(error2);
|
|
27090
|
+
}
|
|
27091
|
+
}
|
|
27092
|
+
for (const arg of node.args) {
|
|
27093
|
+
stack.push(arg);
|
|
27094
|
+
}
|
|
27095
|
+
} else if (node instanceof Binary) {
|
|
27096
|
+
stack.push(node.left, node.right);
|
|
27097
|
+
} else if (node instanceof Unary) {
|
|
27098
|
+
stack.push(node.expr);
|
|
27099
|
+
} else if (node instanceof Logical) {
|
|
27100
|
+
for (const arg of node.args) {
|
|
27101
|
+
stack.push(arg);
|
|
27102
|
+
}
|
|
27103
|
+
} else if (node instanceof Grouping) {
|
|
27104
|
+
stack.push(node.group);
|
|
27105
|
+
} else if (node instanceof IndexAccess) {
|
|
27106
|
+
stack.push(node.expr, node.index);
|
|
27107
|
+
}
|
|
27108
|
+
}
|
|
27109
|
+
return errors;
|
|
27110
|
+
}
|
|
27111
|
+
function validateSingleFormatCall(fc) {
|
|
27112
|
+
if (fc.args.length < 1) {
|
|
27113
|
+
return void 0;
|
|
27114
|
+
}
|
|
27115
|
+
const firstArg = fc.args[0];
|
|
27116
|
+
if (!(firstArg instanceof Literal) || firstArg.literal.kind !== Kind.String) {
|
|
27117
|
+
return void 0;
|
|
27118
|
+
}
|
|
27119
|
+
const formatString = firstArg.literal.coerceString();
|
|
27120
|
+
const numArgs = fc.args.length - 1;
|
|
27121
|
+
const { valid, maxArgIndex } = validateFormatString(formatString);
|
|
27122
|
+
if (!valid) {
|
|
27123
|
+
return {
|
|
27124
|
+
type: "invalid-syntax",
|
|
27125
|
+
message: "Format string has invalid syntax (missing closing brace, unescaped braces, or invalid placeholder)"
|
|
27126
|
+
};
|
|
27127
|
+
}
|
|
27128
|
+
if (maxArgIndex >= numArgs) {
|
|
27129
|
+
return {
|
|
27130
|
+
type: "arg-count-mismatch",
|
|
27131
|
+
expected: maxArgIndex + 1,
|
|
27132
|
+
provided: numArgs
|
|
27133
|
+
};
|
|
27134
|
+
}
|
|
27135
|
+
return void 0;
|
|
27136
|
+
}
|
|
26466
27137
|
|
|
26467
27138
|
// ../languageservice/dist/validate.js
|
|
26468
27139
|
var CRON_SCHEDULE_DOCS_URL = "https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions#onschedule";
|
|
@@ -26485,7 +27156,7 @@ async function validateWorkflow(textDocument, config) {
|
|
|
26485
27156
|
fetchReusableWorkflowDepth: config?.fileProvider ? 1 : 0,
|
|
26486
27157
|
errorPolicy: ErrorPolicy.TryConversion
|
|
26487
27158
|
});
|
|
26488
|
-
await additionalValidations(diagnostics, textDocument.uri, template, result.value, config);
|
|
27159
|
+
await additionalValidations(diagnostics, textDocument.uri, template, result.value, config, config?.featureFlags);
|
|
26489
27160
|
}
|
|
26490
27161
|
for (const error2 of result.context.errors.getErrors()) {
|
|
26491
27162
|
const range = mapRange(error2.range);
|
|
@@ -26499,19 +27170,22 @@ async function validateWorkflow(textDocument, config) {
|
|
|
26499
27170
|
}
|
|
26500
27171
|
return diagnostics;
|
|
26501
27172
|
}
|
|
26502
|
-
async function additionalValidations(diagnostics, documentUri, template, root, config) {
|
|
26503
|
-
for (const [parent, token, key] of TemplateToken.traverse(root)) {
|
|
27173
|
+
async function additionalValidations(diagnostics, documentUri, template, root, config, featureFlags) {
|
|
27174
|
+
for (const [parent, token, key, ancestors] of TemplateToken.traverse(root)) {
|
|
26504
27175
|
const validationToken = key || parent || token;
|
|
26505
27176
|
const validationDefinition = validationToken.definition;
|
|
26506
27177
|
if (isBasicExpression(token) && token.range) {
|
|
26507
27178
|
await validateExpression(diagnostics, token, validationToken.definitionInfo?.allowedContext || [], config?.contextProviderConfig, getProviderContext(documentUri, template, root, token.range), key?.definition?.key);
|
|
26508
27179
|
}
|
|
27180
|
+
if (featureFlags?.isEnabled("blockScalarChompingWarning")) {
|
|
27181
|
+
validateBlockScalarChomping(diagnostics, token, parent, key, ancestors);
|
|
27182
|
+
}
|
|
26509
27183
|
const definitionKey = token.definition?.key;
|
|
26510
27184
|
if (isString(token) && token.range && (definitionKey === "job-if" || definitionKey === "step-if" || definitionKey === "snapshot-if")) {
|
|
26511
27185
|
const condition = token.value.trim();
|
|
26512
27186
|
if (condition) {
|
|
26513
27187
|
const finalCondition = ensureStatusFunction(condition, token.definitionInfo);
|
|
26514
|
-
const expressionToken = new BasicExpressionToken(token.file, token.range, finalCondition, token.definitionInfo, void 0, token.source);
|
|
27188
|
+
const expressionToken = new BasicExpressionToken(token.file, token.range, finalCondition, token.definitionInfo, void 0, token.source, void 0, token.blockScalarHeader);
|
|
26515
27189
|
await validateExpression(diagnostics, expressionToken, validationToken.definitionInfo?.allowedContext || [], config?.contextProviderConfig, getProviderContext(documentUri, template, root, token.range));
|
|
26516
27190
|
}
|
|
26517
27191
|
}
|
|
@@ -26559,7 +27233,7 @@ function invalidValue(diagnostics, token, kind) {
|
|
|
26559
27233
|
case ValueProviderKind.AllowedValues:
|
|
26560
27234
|
diagnostics.push({
|
|
26561
27235
|
message: `Value '${token.value}' is not valid`,
|
|
26562
|
-
severity:
|
|
27236
|
+
severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
|
|
26563
27237
|
range: mapRange(token.range)
|
|
26564
27238
|
});
|
|
26565
27239
|
break;
|
|
@@ -26578,7 +27252,7 @@ function validateCronExpression(diagnostics, token) {
|
|
|
26578
27252
|
diagnostics.push({
|
|
26579
27253
|
message: `Actions schedules run at most every 5 minutes. "${cronValue}" (${description.toLowerCase()}) will not run as frequently as specified.`,
|
|
26580
27254
|
range: mapRange(token.range),
|
|
26581
|
-
severity:
|
|
27255
|
+
severity: import_vscode_languageserver_types6.DiagnosticSeverity.Warning,
|
|
26582
27256
|
code: "on-schedule",
|
|
26583
27257
|
codeDescription: {
|
|
26584
27258
|
href: CRON_SCHEDULE_DOCS_URL
|
|
@@ -26592,7 +27266,7 @@ function warnIfShortSha(diagnostics, token, ref) {
|
|
|
26592
27266
|
if (SHORT_SHA_PATTERN.test(ref)) {
|
|
26593
27267
|
diagnostics.push({
|
|
26594
27268
|
message: `The provided ref '${ref}' may be a shortened commit SHA. If so, please use the full 40-character commit SHA instead, as short SHAs are not supported.`,
|
|
26595
|
-
severity:
|
|
27269
|
+
severity: import_vscode_languageserver_types6.DiagnosticSeverity.Warning,
|
|
26596
27270
|
range: mapRange(token.range),
|
|
26597
27271
|
code: "short-sha-ref",
|
|
26598
27272
|
codeDescription: {
|
|
@@ -26608,7 +27282,7 @@ function validateStepUsesFormat(diagnostics, token) {
|
|
|
26608
27282
|
if (!uses) {
|
|
26609
27283
|
diagnostics.push({
|
|
26610
27284
|
message: "`uses' value in action cannot be blank",
|
|
26611
|
-
severity:
|
|
27285
|
+
severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
|
|
26612
27286
|
range: mapRange(token.range),
|
|
26613
27287
|
code: "invalid-uses-format"
|
|
26614
27288
|
});
|
|
@@ -26638,7 +27312,7 @@ function validateStepUsesFormat(diagnostics, token) {
|
|
|
26638
27312
|
if (pathSegments.length >= 4 && pathSegments[2] === ".github" && pathSegments[3] === "workflows") {
|
|
26639
27313
|
diagnostics.push({
|
|
26640
27314
|
message: "Reusable workflows should be referenced at the top-level `jobs.<job_id>.uses` key, not within steps",
|
|
26641
|
-
severity:
|
|
27315
|
+
severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
|
|
26642
27316
|
range: mapRange(token.range),
|
|
26643
27317
|
code: "invalid-uses-format"
|
|
26644
27318
|
});
|
|
@@ -26649,7 +27323,7 @@ function validateStepUsesFormat(diagnostics, token) {
|
|
|
26649
27323
|
function addStepUsesFormatError(diagnostics, token) {
|
|
26650
27324
|
diagnostics.push({
|
|
26651
27325
|
message: `Expected format {owner}/{repo}[/path]@{ref}. Actual '${token.value}'`,
|
|
26652
|
-
severity:
|
|
27326
|
+
severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
|
|
26653
27327
|
range: mapRange(token.range),
|
|
26654
27328
|
code: "invalid-uses-format"
|
|
26655
27329
|
});
|
|
@@ -26738,7 +27412,7 @@ function validateWorkflowUsesFormat(diagnostics, token) {
|
|
|
26738
27412
|
function addWorkflowUsesFormatError(diagnostics, token, reason) {
|
|
26739
27413
|
diagnostics.push({
|
|
26740
27414
|
message: `Invalid workflow reference '${token.value}': ${reason}`,
|
|
26741
|
-
severity:
|
|
27415
|
+
severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
|
|
26742
27416
|
range: mapRange(token.range),
|
|
26743
27417
|
code: "invalid-workflow-uses-format"
|
|
26744
27418
|
});
|
|
@@ -26834,7 +27508,7 @@ async function validateExpression(diagnostics, token, allowedContext, contextPro
|
|
|
26834
27508
|
diagnostics.push({
|
|
26835
27509
|
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 ${{ }}?",
|
|
26836
27510
|
range: mapRange(token.range),
|
|
26837
|
-
severity:
|
|
27511
|
+
severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
|
|
26838
27512
|
code: "expression-literal-text-in-condition"
|
|
26839
27513
|
});
|
|
26840
27514
|
}
|
|
@@ -26851,13 +27525,31 @@ async function validateExpression(diagnostics, token, allowedContext, contextPro
|
|
|
26851
27525
|
} catch {
|
|
26852
27526
|
continue;
|
|
26853
27527
|
}
|
|
27528
|
+
const formatErrors = validateFormatCalls(expr);
|
|
27529
|
+
for (const formatError of formatErrors) {
|
|
27530
|
+
if (formatError.type === "invalid-syntax") {
|
|
27531
|
+
diagnostics.push({
|
|
27532
|
+
message: `Invalid format string: ${formatError.message}`,
|
|
27533
|
+
range: mapRange(expression.range),
|
|
27534
|
+
severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
|
|
27535
|
+
code: "invalid-format-string"
|
|
27536
|
+
});
|
|
27537
|
+
} else if (formatError.type === "arg-count-mismatch") {
|
|
27538
|
+
diagnostics.push({
|
|
27539
|
+
message: `Format string references argument {${formatError.expected - 1}} but only ${formatError.provided} argument(s) provided`,
|
|
27540
|
+
range: mapRange(expression.range),
|
|
27541
|
+
severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error,
|
|
27542
|
+
code: "format-arg-count-mismatch"
|
|
27543
|
+
});
|
|
27544
|
+
}
|
|
27545
|
+
}
|
|
26854
27546
|
const context = await getWorkflowExpressionContext(namedContexts, contextProviderConfig, workflowContext, Mode.Validation);
|
|
26855
27547
|
const e = new ValidationEvaluator(expr, wrapDictionary(context), validatorFunctions);
|
|
26856
27548
|
e.validate();
|
|
26857
27549
|
diagnostics.push(...e.errors.map((e2) => ({
|
|
26858
27550
|
message: e2.message,
|
|
26859
27551
|
range: mapRange(expression.range),
|
|
26860
|
-
severity: e2.severity === "error" ?
|
|
27552
|
+
severity: e2.severity === "error" ? import_vscode_languageserver_types6.DiagnosticSeverity.Error : import_vscode_languageserver_types6.DiagnosticSeverity.Warning
|
|
26861
27553
|
})));
|
|
26862
27554
|
}
|
|
26863
27555
|
}
|
|
@@ -26879,14 +27571,14 @@ function validateConcurrencyDeadlock(diagnostics, template) {
|
|
|
26879
27571
|
diagnostics.push({
|
|
26880
27572
|
message: `Concurrency group '${workflowGroup.value}' is also used by job '${job.id.value}'. This will cause a deadlock.`,
|
|
26881
27573
|
range: mapRange(template.concurrency.range),
|
|
26882
|
-
severity:
|
|
27574
|
+
severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error
|
|
26883
27575
|
});
|
|
26884
27576
|
}
|
|
26885
27577
|
if (job.concurrency.range) {
|
|
26886
27578
|
diagnostics.push({
|
|
26887
27579
|
message: `Concurrency group '${jobGroup.value}' is also defined at the workflow level. This will cause a deadlock.`,
|
|
26888
27580
|
range: mapRange(job.concurrency.range),
|
|
26889
|
-
severity:
|
|
27581
|
+
severity: import_vscode_languageserver_types6.DiagnosticSeverity.Error
|
|
26890
27582
|
});
|
|
26891
27583
|
}
|
|
26892
27584
|
}
|
|
@@ -26908,6 +27600,53 @@ function getStaticConcurrencyGroup(token) {
|
|
|
26908
27600
|
}
|
|
26909
27601
|
return void 0;
|
|
26910
27602
|
}
|
|
27603
|
+
function validateBlockScalarChomping(diagnostics, token, parent, key, ancestors) {
|
|
27604
|
+
if (!isBasicExpression(token) && !isString(token)) {
|
|
27605
|
+
return;
|
|
27606
|
+
}
|
|
27607
|
+
const header = token.blockScalarHeader;
|
|
27608
|
+
if (!header) {
|
|
27609
|
+
return;
|
|
27610
|
+
}
|
|
27611
|
+
if (header.includes("+") || header.includes("-")) {
|
|
27612
|
+
return;
|
|
27613
|
+
}
|
|
27614
|
+
let shouldWarn = false;
|
|
27615
|
+
const parentDefinitionName = parent?.definition?.key;
|
|
27616
|
+
const tokenDefinitionName = token.definition?.key;
|
|
27617
|
+
const keyName = key && isString(key) ? key.value : void 0;
|
|
27618
|
+
if (parentDefinitionName && [
|
|
27619
|
+
"workflow-env",
|
|
27620
|
+
"job-env",
|
|
27621
|
+
"step-env",
|
|
27622
|
+
"container-env",
|
|
27623
|
+
"step-with",
|
|
27624
|
+
"job-outputs",
|
|
27625
|
+
"workflow-job-with",
|
|
27626
|
+
"workflow-job-secrets"
|
|
27627
|
+
].includes(parentDefinitionName)) {
|
|
27628
|
+
shouldWarn = true;
|
|
27629
|
+
} else if (ancestors.some((ancestor) => {
|
|
27630
|
+
const ancestorKey = ancestor.definition?.key;
|
|
27631
|
+
return ancestorKey === "matrix" || ancestorKey === "matrix-filter" || ancestorKey === "matrix-filter-item";
|
|
27632
|
+
})) {
|
|
27633
|
+
shouldWarn = true;
|
|
27634
|
+
} else if (tokenDefinitionName && ["workflow-concurrency", "job-concurrency"].includes(tokenDefinitionName)) {
|
|
27635
|
+
shouldWarn = true;
|
|
27636
|
+
} else if (keyName === "group" && parentDefinitionName === "concurrency-mapping") {
|
|
27637
|
+
shouldWarn = true;
|
|
27638
|
+
}
|
|
27639
|
+
if (!shouldWarn) {
|
|
27640
|
+
return;
|
|
27641
|
+
}
|
|
27642
|
+
const blockIndicator = header.startsWith("|") ? "|" : ">";
|
|
27643
|
+
diagnostics.push({
|
|
27644
|
+
message: `Block scalar '${blockIndicator}' implicitly adds a trailing newline that may be unintentional. Use '${blockIndicator}-' to remove it, or '${blockIndicator}+' to explicitly keep it.`,
|
|
27645
|
+
range: mapRange(token.range),
|
|
27646
|
+
severity: import_vscode_languageserver_types6.DiagnosticSeverity.Warning,
|
|
27647
|
+
code: "block-scalar-chomping"
|
|
27648
|
+
});
|
|
27649
|
+
}
|
|
26911
27650
|
|
|
26912
27651
|
// src/connection.ts
|
|
26913
27652
|
var import_vscode_languageserver = __toESM(require_main7(), 1);
|
|
@@ -31255,6 +31994,7 @@ function initConnection(connection) {
|
|
|
31255
31994
|
let repos = [];
|
|
31256
31995
|
const cache = new TTLCache();
|
|
31257
31996
|
let hasWorkspaceFolderCapability = false;
|
|
31997
|
+
let featureFlags = new FeatureFlags();
|
|
31258
31998
|
registerLogger(connection.console);
|
|
31259
31999
|
connection.onInitialize((params) => {
|
|
31260
32000
|
const capabilities = params.capabilities;
|
|
@@ -31269,6 +32009,7 @@ function initConnection(connection) {
|
|
|
31269
32009
|
if (options.logLevel !== void 0) {
|
|
31270
32010
|
setLogLevel(options.logLevel);
|
|
31271
32011
|
}
|
|
32012
|
+
featureFlags = new FeatureFlags(options.experimentalFeatures);
|
|
31272
32013
|
const result = {
|
|
31273
32014
|
capabilities: {
|
|
31274
32015
|
textDocumentSync: import_vscode_languageserver.TextDocumentSyncKind.Full,
|
|
@@ -31293,6 +32034,10 @@ function initConnection(connection) {
|
|
|
31293
32034
|
return result;
|
|
31294
32035
|
});
|
|
31295
32036
|
connection.onInitialized(() => {
|
|
32037
|
+
const enabledFeatures = featureFlags.getEnabledFeatures();
|
|
32038
|
+
if (enabledFeatures.length > 0) {
|
|
32039
|
+
connection.console.info(`Experimental features enabled: ${enabledFeatures.join(", ")}`);
|
|
32040
|
+
}
|
|
31296
32041
|
if (hasWorkspaceFolderCapability) {
|
|
31297
32042
|
connection.workspace.onDidChangeWorkspaceFolders(() => {
|
|
31298
32043
|
clearCache();
|
|
@@ -31311,7 +32056,8 @@ function initConnection(connection) {
|
|
|
31311
32056
|
actionsMetadataProvider: getActionsMetadataProvider(client, cache),
|
|
31312
32057
|
fileProvider: getFileProvider(client, cache, repoContext?.workspaceUri, async (path) => {
|
|
31313
32058
|
return await connection.sendRequest(Requests.ReadFile, { path });
|
|
31314
|
-
})
|
|
32059
|
+
}),
|
|
32060
|
+
featureFlags
|
|
31315
32061
|
};
|
|
31316
32062
|
const result = await validate(textDocument, config);
|
|
31317
32063
|
await connection.sendDiagnostics({ uri: textDocument.uri, diagnostics: result });
|