@@ -37,7 +37,7 @@ List of checks:
37
37
- [ Permissions] ( #permissions )
38
38
- [ Reusable workflows] ( #check-reusable-workflows )
39
39
- [ ID naming convention] ( #id-naming-convention )
40
- - [ Contexts and special functions availability ] ( #ctx-spfunc-availability )
40
+ - [ Availability of contexts and special functions] ( #ctx-spfunc-availability )
41
41
- [ Deprecated workflow commands] ( #check-deprecated-workflow-commands )
42
42
- [ Conditions always evaluated to true at ` if: ` ] ( #if-cond-always-true )
43
43
- [ Action metadata syntax validation] ( #action-metadata-syntax )
@@ -395,8 +395,6 @@ jobs:
395
395
# Function overloads can be handled properly. contains() has string version and array version
396
396
- run : echo "${{ contains('hello, world', 'lo,') }}"
397
397
- run : echo "${{ contains(github.event.labels.*.name, 'enhancement') }}"
398
- # format() has a special check for formatting string
399
- - run : echo "${{ format('{0}{1}', 1, 2, 3) }}"
400
398
` ` `
401
399
402
400
Output:
@@ -422,13 +420,9 @@ test.yaml:15:51: 2nd argument of function call is not assignable. "object" canno
422
420
|
423
421
15 | - run : echo "${{ startsWith('hello, world', github.event) }}"
424
422
| ^~~~~~~~~~~~~
425
- test.yaml:20:24 : format string "{0}{1}" does not contain placeholder {2}. remove argument which is unused in the format string [expression]
426
- |
427
- 20 | - run : echo "${{ format('{0}{1}', 1, 2, 3) }}"
428
- | ^~~~~~~~~~~~~~~~
429
423
` ` `
430
424
431
- [Playground](https://rhysd.github.io/actionlint/#eNqckMFOwzAQRO/9ilGF5IKciMItP8IROWHBAWe3yq4pUuR/Ry4SAqnNoScf5r3xaIU7HLLGzbv02m0AI7X6AnNmbWqe+8yWmxRqdorU6KA/FNBUsgMNUeBulgWZP1iO/DwIG30ZSnGX0LfRYu5b+iQ2vQBuK6gWZnsaLe5cpJTE4yhzenEeLol3tyhlu+rqGfk6y/9bvdpRLxBG1itG/6p/P2tT6Clpe9dymMjDEcfAA03Etl73KvMUbOeW+7Lsi/PYezx4PJ6k7wAAAP//nfWd6A== )
425
+ [Playground](https://rhysd.github.io/actionlint/#eNqckEFKxjAQhfc9xVCEqKQ5QC/iUpI6mGo6UzoTK5TcXWJB/OFvF11l8b7v5TFMPcxZYvPBQfoGQFG0vgBLJulqnkMmzV3yNfuNRHGWnQLoKtkDDpHBPGwbZPokXul1YFL8VijFHKHvo8YcHH4hqRyAbQVF/aIvo8ZHEzEltrDykt6MBZPYmicopT115Y58zbI3q0876gX8SHJh9J/6/zOXfMAk7tmRn9CCQYqeBpyQdK/7CQAA//9h6o/Y )
432
426
433
427
[Contexts][contexts-doc] and [built-in functions][funcs-doc] are strongly typed. Typos in property access of contexts and
434
428
function names can be checked. And invalid function calls like wrong number of arguments or type mismatch at parameter also
@@ -440,11 +434,58 @@ The semantics checker can properly handle that
440
434
- some parameters are optional (e.g. `join(strings, sep)` and `join(strings)`)
441
435
- some parameters are repeatable (e.g. `hashFiles(file1, file2, ...)`)
442
436
443
- In addition, `format()` function has a special check for placeholders in the first parameter which represents the formatting
444
- string.
445
-
446
437
Note that context names and function names are case-insensitive. For example, `toJSON` and `toJson` are the same function.
447
438
439
+ In addition, actionlint performs special checks on some built-in functions.
440
+
441
+ - `format()` : Checks placeholders in the first parameter which represents the format string.
442
+ - `fromJSON()` : Checks the JSON string is valid and the return value is strongly typed.
443
+
444
+ Example input :
445
+
446
+ ` ` ` yaml
447
+ on: push
448
+
449
+ jobs:
450
+ test:
451
+ # ERROR: Key 'mac' does not exist in the object returned by the fromJSON()
452
+ runs-on: ${{ fromJSON('{"win":"windows-latest","linux":"ubuntul-latest"}')['mac'] }}
453
+ steps:
454
+ # ERROR: {2} is missing in the first argument of format()
455
+ - run: echo "${{ format('{0}{1}', 1, 2, 3) }}"
456
+ # ERROR: Argument for {2} is missing in the arguments of format()
457
+ - run: echo "${{ format('{0}{1}{2}', 1, 2) }}"
458
+ - run: echo This is a special branch!
459
+ # ERROR: Broken JSON string. Special check for fromJSON()
460
+ if: contains(fromJson('["main","release","dev"'), github.ref_name)
461
+ ` ` `
462
+
463
+ Output :
464
+
465
+ ` ` `
466
+ test.yaml:6:18: property "mac" is not defined in object type {linux: string; win: string} [expression]
467
+ |
468
+ 6 | runs-on: ${{ fromJSON('{"win":"windows-latest","linux":"ubuntul-latest"}')['mac'] }}
469
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
470
+ test.yaml:9:24: format string "{0}{1}" does not contain placeholder {2}. remove argument which is unused in the format string [expression]
471
+ |
472
+ 9 | - run: echo "${{ format('{0}{1}', 1, 2, 3) }}"
473
+ | ^~~~~~~~~~~~~~~~
474
+ test.yaml:11:24: format string "{0}{1}{2}" contains placeholder {2} but only 2 arguments are given to format [expression]
475
+ |
476
+ 11 | - run: echo "${{ format('{0}{1}{2}', 1, 2) }}"
477
+ | ^~~~~~~~~~~~~~~~~~~
478
+ test.yaml:14:31: broken JSON string is passed to fromJSON() at offset 23: unexpected end of JSON input [expression]
479
+ |
480
+ 14 | if: contains(fromJson('["main","release","dev"'), github.ref_name)
481
+ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~
482
+ ` ` `
483
+
484
+ [Playground](https://rhysd.github.io/actionlint/#eNqMj0FL9DAQhu/7K95v+CAtZMVdb/kJHvSgt0Uk7aY20k5KJnGFkP8ure5R8DJzmPeZhzewwZJl3O3eQydmByQnad1AzCz7NfC/FAwxzPdPjw+NKnTxTGad53CR/WRXhDRNnvMnGcpd5pSn66Gq9qRm26sX1Lo9luQW+XYA+9Vj4PoxgDZTiLNNjSq3tRyq0jhoHDXuWtRKf4PK8cr9Bj2PXuAFFrK43tsJXbTcj/9+soAfDPrAyXqWZmsvgRt1otl6Jk3RTc6KI01n90Gq1XjzaczdTXTDK9vZtV8BAAD//8ITaRA=)
485
+
486
+ GitHub Actions does not provide the syntax to create an array or object constant. It [is popular](https://github.com/search?q=fromJSON%28%27+lang%3Ayaml&type=code)
487
+ to create such constants via `fromJSON()`.
488
+
448
489
<a id="check-contextual-step-object"></a>
449
490
# # Contextual typing for `steps.<step_id>` objects
450
491
@@ -2578,7 +2619,7 @@ IDs must start with a letter or `_` and contain only alphanumeric characters, `-
2578
2619
convention, and reports invalid IDs as errors.
2579
2620
2580
2621
<a id="ctx-spfunc-availability"></a>
2581
- # # Contexts and special functions availability
2622
+ # # Availability of contexts and special functions
2582
2623
2583
2624
Example input :
2584
2625
0 commit comments