detached 110f7f5

fix(action): keys resolve like values, int32 wraparound, OrdinalIgnoreCase folding

Found by review, each checked against the runner's own loader (39 new cases):

- GO-001: in runner mode a mapping key is resolved like a value, as the
  runner's YAML reader does: ~ is null, 0x10 is 16, 1.0 is 1, TRUE is true.
- GO-002: 0x and 0o integers (plain or !!int) are read as int32 with
  wraparound: 0xFFFFFFFF is -1, 0x80000000 is -2147483648. !!float refuses them.
- GO-003: step ids, input names and mapping keys compare with .NET's
  OrdinalIgnoreCase (expr.OrdinalFold): e and E fold, s and the long s do not.
  asciiEqualFold stays for ASCII literals only.
- GO-004: HasPost no longer says plugin.

Lint cannot follow the reference on non-string keys (it crashes on them) nor on
the sharp s duplicate; those files are excused with their reason.
commit
110f7f52c8339324d413d41e8ce44a795ff66929
author
brice · · 2026-10-13 14:05 UTC
committer
brice · · 2026-10-18 14:59 UTC
parent
73aa774
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
49 files · +1490 -50
M action/PORTING.md +1 -1
@@ -120,7 +120,7 @@ All verified by `TestAgainstRunner`.
120120 ...`) instead of being recorded and skipped; an unknown key in a step is
121121 `Error while reading 'steps item key'. Unexpected value 'k'`; the id check
122122 (`ReferenceNameBuilder`) accepts ids that start with `__`, lets an id of 100
123- characters or more through, compares ids ASCII case-insensitively, and words its
123+ characters or more through, compares ids with OrdinalIgnoreCase, and words its
124124 message `... IDs must start with a letter or '_' and must be less than 100
125125 characters.` (the language service has `and and`); generated ids are
126126 `__run`, `__owner_repo`, `__<image>`, `__self`, `__selfRepository`, made unique
@@ -120,7 +120,7 @@ All verified by `TestAgainstRunner`.
120 ...`) instead of being recorded and skipped; an unknown key in a step is120 ...`) instead of being recorded and skipped; an unknown key in a step is
121 `Error while reading 'steps item key'. Unexpected value 'k'`; the id check121 `Error while reading 'steps item key'. Unexpected value 'k'`; the id check
122 (`ReferenceNameBuilder`) accepts ids that start with `__`, lets an id of 100122 (`ReferenceNameBuilder`) accepts ids that start with `__`, lets an id of 100
123- characters or more through, compares ids ASCII case-insensitively, and words its123+ characters or more through, compares ids with OrdinalIgnoreCase, and words its
124 message `... IDs must start with a letter or '_' and must be less than 100124 message `... IDs must start with a letter or '_' and must be less than 100
125 characters.` (the language service has `and and`); generated ids are125 characters.` (the language service has `and and`); generated ids are
126 `__run`, `__owner_repo`, `__<image>`, `__self`, `__selfRepository`, made unique126 `__run`, `__owner_repo`, `__<image>`, `__self`, `__selfRepository`, made unique
M action/lint_test.go +16 -0
@@ -53,8 +53,24 @@ var (
5353 // reproduced, with the reason.
5454 var knownLintDifferences = map[string]string{
5555 "yaml_key_collection.yml": "a mapping key that is a collection: the reference reads it as undefined (\"Unexpected value 'undefined'\"), package template reports \"Unexpected value ''\" (twice); see template/PORTING.md",
56+ "fold_inputs_sharp.yml": "duplicate keys: the reference compares with JavaScript's toUpperCase (\u00df is SS), template with strings.ToUpper; Lint is not the runner's OrdinalIgnoreCase, Parse is",
57+ "int32_key.yml": jsKey,
58+ "key_bool_dup.yml": jsKey,
59+ "key_float_dup.yml": jsKey,
60+ "key_hex_dup.yml": jsKey,
61+ "key_hex_input.yml": jsKey,
62+ "key_null_env.yml": jsKey,
63+ "key_null_inputs.yml": jsKey,
64+ "key_null_top.yml": jsKey,
65+ "key_number_runs.yml": jsKey,
5666 }
5767
68+// jsKey: the reference resolves a plain key to a number, boolean or null (and
69+// then crashes on it, "raw.indexOf is not a function", or words it
70+// differently); template keeps keys of the workflow-style readers as strings.
71+// The runner's reader resolves keys like values, which Parse reproduces.
72+const jsKey = "the reference resolves non-string keys and fails on them with its own wording; Lint keeps keys as strings"
73+
5874 func TestLintAgainstReference(t *testing.T) {
5975 data, err := os.ReadFile("testdata/strict.json")
6076 if err != nil {
@@ -53,8 +53,24 @@ var (
53 // reproduced, with the reason.53 // reproduced, with the reason.
54 var knownLintDifferences = map[string]string{54 var knownLintDifferences = map[string]string{
55 "yaml_key_collection.yml": "a mapping key that is a collection: the reference reads it as undefined (\"Unexpected value 'undefined'\"), package template reports \"Unexpected value ''\" (twice); see template/PORTING.md",55 "yaml_key_collection.yml": "a mapping key that is a collection: the reference reads it as undefined (\"Unexpected value 'undefined'\"), package template reports \"Unexpected value ''\" (twice); see template/PORTING.md",
56+ "fold_inputs_sharp.yml": "duplicate keys: the reference compares with JavaScript's toUpperCase (\u00df is SS), template with strings.ToUpper; Lint is not the runner's OrdinalIgnoreCase, Parse is",
57+ "int32_key.yml": jsKey,
58+ "key_bool_dup.yml": jsKey,
59+ "key_float_dup.yml": jsKey,
60+ "key_hex_dup.yml": jsKey,
61+ "key_hex_input.yml": jsKey,
62+ "key_null_env.yml": jsKey,
63+ "key_null_inputs.yml": jsKey,
64+ "key_null_top.yml": jsKey,
65+ "key_number_runs.yml": jsKey,
56 }66 }
57 67
68+// jsKey: the reference resolves a plain key to a number, boolean or null (and
69+// then crashes on it, "raw.indexOf is not a function", or words it
70+// differently); template keeps keys of the workflow-style readers as strings.
71+// The runner's reader resolves keys like values, which Parse reproduces.
72+const jsKey = "the reference resolves non-string keys and fails on them with its own wording; Lint keeps keys as strings"
73+
58 func TestLintAgainstReference(t *testing.T) {74 func TestLintAgainstReference(t *testing.T) {
59 data, err := os.ReadFile("testdata/strict.json")75 data, err := os.ReadFile("testdata/strict.json")
60 if err != nil {76 if err != nil {
M action/model.go +3 -3
@@ -28,10 +28,10 @@ type Action struct {
2828 }
2929
3030 // Input returns the input called name, compared like the runner compares
31-// input names (ASCII case-insensitively), or nil.
31+// input names (OrdinalIgnoreCase), or nil.
3232 func (a *Action) Input(name string) *Input {
3333 for i := range a.Inputs {
34- if asciiEqualFold(a.Inputs[i].Name, name) {
34+ if ordinalEqual(a.Inputs[i].Name, name) {
3535 return &a.Inputs[i]
3636 }
3737 }
@@ -150,7 +150,7 @@ func (r *Runs) HasPre() bool {
150150 }
151151
152152 // HasPost reports whether the action has something to run after the job's
153-// steps: a node "post", a docker "post-entrypoint" or a plugin.
153+// steps: a node "post" or a docker "post-entrypoint".
154154 func (r *Runs) HasPost() bool {
155155 switch r.Kind {
156156 case RunsNode:
@@ -28,10 +28,10 @@ type Action struct {
28 }28 }
29 29
30 // Input returns the input called name, compared like the runner compares30 // Input returns the input called name, compared like the runner compares
31-// input names (ASCII case-insensitively), or nil.31+// input names (OrdinalIgnoreCase), or nil.
32 func (a *Action) Input(name string) *Input {32 func (a *Action) Input(name string) *Input {
33 for i := range a.Inputs {33 for i := range a.Inputs {
34- if asciiEqualFold(a.Inputs[i].Name, name) {34+ if ordinalEqual(a.Inputs[i].Name, name) {
35 return &a.Inputs[i]35 return &a.Inputs[i]
36 }36 }
37 }37 }
@@ -150,7 +150,7 @@ func (r *Runs) HasPre() bool {
150 }150 }
151 151
152 // HasPost reports whether the action has something to run after the job's152 // HasPost reports whether the action has something to run after the job's
153-// steps: a node "post", a docker "post-entrypoint" or a plugin.153+// steps: a node "post" or a docker "post-entrypoint".
154 func (r *Runs) HasPost() bool {154 func (r *Runs) HasPost() bool {
155 switch r.Kind {155 switch r.Kind {
156 case RunsNode:156 case RunsNode:
M action/refnames.go +6 -15
@@ -5,6 +5,8 @@ package action
55 import (
66 "fmt"
77 "unicode/utf16"
8+
9+ "bnema.dev/ermite-actions/expr"
810 )
911
1012 // refNames is a port of the runner's ReferenceNameBuilder
@@ -16,29 +18,18 @@ import (
1618 // doubled "and".
1719 type refNames struct {
1820 name []uint16
19- distinct map[string]bool // upper-cased with ASCII rules
21+ distinct map[string]bool // OrdinalIgnoreCase folds
2022 }
2123
2224 const maxNodeNameLength = 100
2325
2426 func newRefNames() *refNames { return &refNames{distinct: map[string]bool{}} }
2527
26-func asciiUpper(s string) string {
27- b := []byte(s)
28- for i, c := range b {
29- if c >= 'a' && c <= 'z' {
30- b[i] = c - 'a' + 'A'
31- }
32- }
33- return string(b)
34-}
35-
3628 // add records name and reports whether it was new (HashSet.Add with
37-// OrdinalIgnoreCase; a name that is not ASCII is one that validName refused,
38-// or one of 100 characters or more, which are compared by their ASCII upper
39-// case here).
29+// OrdinalIgnoreCase). A name with non-ASCII characters can get here when it has
30+// 100 characters or more, and "é...é" then collides with "É...É".
4031 func (b *refNames) add(name string) bool {
41- k := asciiUpper(name)
32+ k := expr.OrdinalFold(name)
4233 if b.distinct[k] {
4334 return false
4435 }
@@ -5,6 +5,8 @@ package action
5 import (5 import (
6 "fmt"6 "fmt"
7 "unicode/utf16"7 "unicode/utf16"
8+
9+ "bnema.dev/ermite-actions/expr"
8 )10 )
9 11
10 // refNames is a port of the runner's ReferenceNameBuilder12 // refNames is a port of the runner's ReferenceNameBuilder
@@ -16,29 +18,18 @@ import (
16 // doubled "and".18 // doubled "and".
17 type refNames struct {19 type refNames struct {
18 name []uint1620 name []uint16
19- distinct map[string]bool // upper-cased with ASCII rules21+ distinct map[string]bool // OrdinalIgnoreCase folds
20 }22 }
21 23
22 const maxNodeNameLength = 10024 const maxNodeNameLength = 100
23 25
24 func newRefNames() *refNames { return &refNames{distinct: map[string]bool{}} }26 func newRefNames() *refNames { return &refNames{distinct: map[string]bool{}} }
25 27
26-func asciiUpper(s string) string {
27- b := []byte(s)
28- for i, c := range b {
29- if c >= 'a' && c <= 'z' {
30- b[i] = c - 'a' + 'A'
31- }
32- }
33- return string(b)
34-}
35-
36 // add records name and reports whether it was new (HashSet.Add with28 // add records name and reports whether it was new (HashSet.Add with
37-// OrdinalIgnoreCase; a name that is not ASCII is one that validName refused,29+// OrdinalIgnoreCase). A name with non-ASCII characters can get here when it has
38-// or one of 100 characters or more, which are compared by their ASCII upper30+// 100 characters or more, and "é...é" then collides with "É...É".
39-// case here).
40 func (b *refNames) add(name string) bool {31 func (b *refNames) add(name string) bool {
41- k := asciiUpper(name)32+ k := expr.OrdinalFold(name)
42 if b.distinct[k] {33 if b.distinct[k] {
43 return false34 return false
44 }35 }
A action/testdata/cases/fold_inputs_accent.yml +10 -0
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ é:
5+ default: x
6+ É:
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ é:
5+ default: x
6+ É:
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
A action/testdata/cases/fold_inputs_dotless.yml +12 -0
@@ -0,0 +1,12 @@
1+name: A
2+description: D
3+inputs:
4+ ı:
5+ default: x
6+ I:
7+ default: y
8+ i:
9+ default: z
10+runs:
11+ using: node20
12+ main: m.js
@@ -0,0 +1,12 @@
1+name: A
2+description: D
3+inputs:
4+ ı:
5+ default: x
6+ I:
7+ default: y
8+ i:
9+ default: z
10+runs:
11+ using: node20
12+ main: m.js
A action/testdata/cases/fold_inputs_greek.yml +12 -0
@@ -0,0 +1,12 @@
1+name: A
2+description: D
3+inputs:
4+ σ:
5+ default: x
6+ ς:
7+ default: y
8+ Σ:
9+ default: z
10+runs:
11+ using: node20
12+ main: m.js
@@ -0,0 +1,12 @@
1+name: A
2+description: D
3+inputs:
4+ σ:
5+ default: x
6+ ς:
7+ default: y
8+ Σ:
9+ default: z
10+runs:
11+ using: node20
12+ main: m.js
A action/testdata/cases/fold_inputs_kelvin.yml +10 -0
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ k:
5+ default: x
6+ K:
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ k:
5+ default: x
6+ K:
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
A action/testdata/cases/fold_inputs_s.yml +10 -0
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ s:
5+ default: x
6+ ſ:
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ s:
5+ default: x
6+ ſ:
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
A action/testdata/cases/fold_inputs_sharp.yml +10 -0
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ ß:
5+ default: x
6+ SS:
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ ß:
5+ default: x
6+ SS:
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
A action/testdata/cases/fold_runs_keys.yml +7 -0
@@ -0,0 +1,7 @@
1+name: A
2+description: D
3+runs:
4+ using: node20
5+ main: m.js
6+ é: 1
7+ É: 2
@@ -0,0 +1,7 @@
1+name: A
2+description: D
3+runs:
4+ using: node20
5+ main: m.js
6+ é: 1
7+ É: 2
A action/testdata/cases/fold_step_ids_ascii_dup.yml +11 -0
@@ -0,0 +1,11 @@
1+name: A
2+description: D
3+runs:
4+ using: composite
5+ steps:
6+ - run: x
7+ shell: sh
8+ id: abc
9+ - run: x
10+ shell: sh
11+ id: ABC
@@ -0,0 +1,11 @@
1+name: A
2+description: D
3+runs:
4+ using: composite
5+ steps:
6+ - run: x
7+ shell: sh
8+ id: abc
9+ - run: x
10+ shell: sh
11+ id: ABC
A action/testdata/cases/fold_step_ids_long.yml +11 -0
@@ -0,0 +1,11 @@
1+name: A
2+description: D
3+runs:
4+ using: composite
5+ steps:
6+ - run: x
7+ shell: sh
8+ id: éééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééé
9+ - run: x
10+ shell: sh
11+ id: ÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉ
@@ -0,0 +1,11 @@
1+name: A
2+description: D
3+runs:
4+ using: composite
5+ steps:
6+ - run: x
7+ shell: sh
8+ id: éééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééé
9+ - run: x
10+ shell: sh
11+ id: ÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉ
A action/testdata/cases/fold_step_ids_long_s.yml +11 -0
@@ -0,0 +1,11 @@
1+name: A
2+description: D
3+runs:
4+ using: composite
5+ steps:
6+ - run: x
7+ shell: sh
8+ id: ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
9+ - run: x
10+ shell: sh
11+ id: ſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſ
@@ -0,0 +1,11 @@
1+name: A
2+description: D
3+runs:
4+ using: composite
5+ steps:
6+ - run: x
7+ shell: sh
8+ id: ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
9+ - run: x
10+ shell: sh
11+ id: ſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſ
A action/testdata/cases/fold_top_keys.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+NAME: B
3+é: 1
4+É: 2
5+description: D
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+NAME: B
3+é: 1
4+É: 2
5+description: D
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/fold_using_dotless.yml +5 -0
@@ -0,0 +1,5 @@
1+name: A
2+description: D
3+runs:
4+ using: DOCKER
5+ image: Dockerfile
@@ -0,0 +1,5 @@
1+name: A
2+description: D
3+runs:
4+ using: DOCKER
5+ image: Dockerfile
A action/testdata/cases/fold_using_kelvin.yml +5 -0
@@ -0,0 +1,5 @@
1+name: A
2+description: D
3+runs:
4+ using: Komposite
5+ steps: []
@@ -0,0 +1,5 @@
1+name: A
2+description: D
3+runs:
4+ using: Komposite
5+ steps: []
A action/testdata/cases/int32_00.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0x7FFFFFFF
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0x7FFFFFFF
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_01.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0x80000000
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0x80000000
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_02.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0xFFFFFFFF
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0xFFFFFFFF
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_03.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0x100000000
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0x100000000
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_04.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0o17777777777
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0o17777777777
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_05.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0o20000000000
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0o20000000000
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_06.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0o37777777777
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0o37777777777
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_07.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0o40000000000
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0o40000000000
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_08.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: !!int 0xFFFFFFFF
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: !!int 0xFFFFFFFF
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_09.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: !!int 0x80000000
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: !!int 0x80000000
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_10.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: !!int 0x100000000
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: !!int 0x100000000
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_11.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: !!int 0o20000000000
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: !!int 0o20000000000
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_12.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: !!int 0o40000000000
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: !!int 0o40000000000
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_13.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: !!int 12
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: !!int 12
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_14.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: !!float 0x10
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: !!float 0x10
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_15.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0x0
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0x0
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_16.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0xDEADBEEF
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ a:
5+ default: 0xDEADBEEF
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/int32_key.yml +10 -0
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ 0xFFFFFFFF:
5+ default: x
6+ 0x80000000:
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ 0xFFFFFFFF:
5+ default: x
6+ 0x80000000:
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
A action/testdata/cases/key_bool_dup.yml +10 -0
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ TRUE:
5+ default: x
6+ true:
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ TRUE:
5+ default: x
6+ true:
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
A action/testdata/cases/key_float_dup.yml +10 -0
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ 1.0:
5+ default: x
6+ '1':
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ 1.0:
5+ default: x
6+ '1':
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
A action/testdata/cases/key_hex_dup.yml +10 -0
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ 0x10:
5+ default: x
6+ 16:
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
@@ -0,0 +1,10 @@
1+name: A
2+description: D
3+inputs:
4+ 0x10:
5+ default: x
6+ 16:
7+ default: y
8+runs:
9+ using: node20
10+ main: m.js
A action/testdata/cases/key_hex_input.yml +12 -0
@@ -0,0 +1,12 @@
1+name: A
2+description: D
3+inputs:
4+ 0x10:
5+ default: x
6+ 1.0:
7+ default: y
8+ TRUE:
9+ default: z
10+runs:
11+ using: node20
12+ main: m.js
@@ -0,0 +1,12 @@
1+name: A
2+description: D
3+inputs:
4+ 0x10:
5+ default: x
6+ 1.0:
7+ default: y
8+ TRUE:
9+ default: z
10+runs:
11+ using: node20
12+ main: m.js
A action/testdata/cases/key_null_env.yml +7 -0
@@ -0,0 +1,7 @@
1+name: A
2+description: D
3+runs:
4+ using: docker
5+ image: Dockerfile
6+ env:
7+ ~: v
@@ -0,0 +1,7 @@
1+name: A
2+description: D
3+runs:
4+ using: docker
5+ image: Dockerfile
6+ env:
7+ ~: v
A action/testdata/cases/key_null_inputs.yml +8 -0
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ ~:
5+ default: x
6+runs:
7+ using: node20
8+ main: m.js
@@ -0,0 +1,8 @@
1+name: A
2+description: D
3+inputs:
4+ ~:
5+ default: x
6+runs:
7+ using: node20
8+ main: m.js
A action/testdata/cases/key_null_top.yml +6 -0
@@ -0,0 +1,6 @@
1+~: 1
2+name: A
3+description: D
4+runs:
5+ using: node20
6+ main: m.js
@@ -0,0 +1,6 @@
1+~: 1
2+name: A
3+description: D
4+runs:
5+ using: node20
6+ main: m.js
A action/testdata/cases/key_number_runs.yml +6 -0
@@ -0,0 +1,6 @@
1+name: A
2+description: D
3+runs:
4+ using: node20
5+ main: m.js
6+ 1e3: x
@@ -0,0 +1,6 @@
1+name: A
2+description: D
3+runs:
4+ using: node20
5+ main: m.js
6+ 1e3: x
M action/testdata/runner.json +556 -0
@@ -1261,6 +1261,193 @@
12611261 ],
12621262 "failed": "Failed to load empty_file.yml"
12631263 },
1264+ "fold_inputs_accent.yml": {
1265+ "name": "A",
1266+ "description": "D",
1267+ "errors": [
1268+ "fold_inputs_accent.yml (Line: 6, Col: 3): 'É' is already defined"
1269+ ],
1270+ "failed": "Failed to load fold_inputs_accent.yml"
1271+ },
1272+ "fold_inputs_dotless.yml": {
1273+ "name": "A",
1274+ "description": "D",
1275+ "errors": [
1276+ "fold_inputs_dotless.yml (Line: 8, Col: 3): 'i' is already defined"
1277+ ],
1278+ "failed": "Failed to load fold_inputs_dotless.yml"
1279+ },
1280+ "fold_inputs_greek.yml": {
1281+ "name": "A",
1282+ "description": "D",
1283+ "errors": [
1284+ "fold_inputs_greek.yml (Line: 6, Col: 3): 'ς' is already defined",
1285+ "fold_inputs_greek.yml (Line: 8, Col: 3): 'Σ' is already defined"
1286+ ],
1287+ "failed": "Failed to load fold_inputs_greek.yml"
1288+ },
1289+ "fold_inputs_kelvin.yml": {
1290+ "name": "A",
1291+ "description": "D",
1292+ "inputs": [
1293+ {
1294+ "name": "k",
1295+ "default": "x"
1296+ },
1297+ {
1298+ "name": "K",
1299+ "default": "y"
1300+ }
1301+ ],
1302+ "execution": {
1303+ "type": "node",
1304+ "using": "node20",
1305+ "main": "m.js",
1306+ "pre": null,
1307+ "preIf": "always()",
1308+ "post": null,
1309+ "postIf": "always()"
1310+ }
1311+ },
1312+ "fold_inputs_s.yml": {
1313+ "name": "A",
1314+ "description": "D",
1315+ "inputs": [
1316+ {
1317+ "name": "s",
1318+ "default": "x"
1319+ },
1320+ {
1321+ "name": "ſ",
1322+ "default": "y"
1323+ }
1324+ ],
1325+ "execution": {
1326+ "type": "node",
1327+ "using": "node20",
1328+ "main": "m.js",
1329+ "pre": null,
1330+ "preIf": "always()",
1331+ "post": null,
1332+ "postIf": "always()"
1333+ }
1334+ },
1335+ "fold_inputs_sharp.yml": {
1336+ "name": "A",
1337+ "description": "D",
1338+ "inputs": [
1339+ {
1340+ "name": "ß",
1341+ "default": "x"
1342+ },
1343+ {
1344+ "name": "SS",
1345+ "default": "y"
1346+ }
1347+ ],
1348+ "execution": {
1349+ "type": "node",
1350+ "using": "node20",
1351+ "main": "m.js",
1352+ "pre": null,
1353+ "preIf": "always()",
1354+ "post": null,
1355+ "postIf": "always()"
1356+ }
1357+ },
1358+ "fold_runs_keys.yml": {
1359+ "name": "A",
1360+ "description": "D",
1361+ "errors": [
1362+ "fold_runs_keys.yml (Line: 6, Col: 3): Unexpected value 'é'",
1363+ "fold_runs_keys.yml (Line: 7, Col: 3): 'É' is already defined"
1364+ ],
1365+ "failed": "Failed to load fold_runs_keys.yml"
1366+ },
1367+ "fold_step_ids_ascii_dup.yml": {
1368+ "name": "A",
1369+ "description": "D",
1370+ "errors": [
1371+ "fold_step_ids_ascii_dup.yml (Line: 11, Col: 11): The identifier 'ABC' may not be used more than once within the same scope.",
1372+ "GitHub.DistributedTask.ObjectTemplating.TemplateValidationException: The template is not valid. fold_step_ids_ascii_dup.yml (Line: 11, Col: 11): The identifier 'ABC' may not be used more than once within the same scope."
1373+ ],
1374+ "failed": "Failed to load fold_step_ids_ascii_dup.yml"
1375+ },
1376+ "fold_step_ids_long.yml": {
1377+ "name": "A",
1378+ "description": "D",
1379+ "errors": [
1380+ "fold_step_ids_long.yml (Line: 11, Col: 11): The identifier 'ÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉ' may not be used more than once within the same scope.",
1381+ "GitHub.DistributedTask.ObjectTemplating.TemplateValidationException: The template is not valid. fold_step_ids_long.yml (Line: 11, Col: 11): The identifier 'ÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉ' may not be used more than once within the same scope."
1382+ ],
1383+ "failed": "Failed to load fold_step_ids_long.yml"
1384+ },
1385+ "fold_step_ids_long_s.yml": {
1386+ "name": "A",
1387+ "description": "D",
1388+ "inputs": [],
1389+ "execution": {
1390+ "type": "composite",
1391+ "using": "composite",
1392+ "steps": [
1393+ {
1394+ "id": "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss",
1395+ "if": "success()",
1396+ "name": null,
1397+ "continueOnError": null,
1398+ "timeout": null,
1399+ "kind": "run",
1400+ "script": "x",
1401+ "shell": "sh"
1402+ },
1403+ {
1404+ "id": "ſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſ",
1405+ "if": "success()",
1406+ "name": null,
1407+ "continueOnError": null,
1408+ "timeout": null,
1409+ "kind": "run",
1410+ "script": "x",
1411+ "shell": "sh"
1412+ }
1413+ ],
1414+ "outputs": null
1415+ }
1416+ },
1417+ "fold_top_keys.yml": {
1418+ "name": "A",
1419+ "description": "D",
1420+ "errors": [
1421+ "fold_top_keys.yml (Line: 2, Col: 1): 'NAME' is already defined",
1422+ "fold_top_keys.yml (Line: 4, Col: 1): 'É' is already defined"
1423+ ],
1424+ "failed": "Failed to load fold_top_keys.yml"
1425+ },
1426+ "fold_using_dotless.yml": {
1427+ "name": "A",
1428+ "description": "D",
1429+ "inputs": [],
1430+ "execution": {
1431+ "type": "docker",
1432+ "using": "DOCKER",
1433+ "image": "Dockerfile",
1434+ "args": null,
1435+ "entrypoint": null,
1436+ "env": null,
1437+ "pre": null,
1438+ "preIf": "always()",
1439+ "post": null,
1440+ "postIf": "always()"
1441+ }
1442+ },
1443+ "fold_using_kelvin.yml": {
1444+ "name": "A",
1445+ "description": "D",
1446+ "errors": [
1447+ "System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. (Parameter ''using: Komposite' is not supported, use 'docker', 'node12', 'node16', 'node20' or 'node24' instead.')"
1448+ ],
1449+ "failed": "Failed to load fold_using_kelvin.yml"
1450+ },
12641451 "inputs_default_bad_context.yml": {
12651452 "name": "A",
12661453 "description": "D",
@@ -1429,6 +1616,375 @@
14291616 "postIf": "always()"
14301617 }
14311618 },
1619+ "int32_00.yml": {
1620+ "name": "A",
1621+ "description": "D",
1622+ "inputs": [
1623+ {
1624+ "name": "a",
1625+ "default": "2147483647"
1626+ }
1627+ ],
1628+ "execution": {
1629+ "type": "node",
1630+ "using": "node20",
1631+ "main": "m.js",
1632+ "pre": null,
1633+ "preIf": "always()",
1634+ "post": null,
1635+ "postIf": "always()"
1636+ }
1637+ },
1638+ "int32_01.yml": {
1639+ "name": "A",
1640+ "description": "D",
1641+ "inputs": [
1642+ {
1643+ "name": "a",
1644+ "default": "-2147483648"
1645+ }
1646+ ],
1647+ "execution": {
1648+ "type": "node",
1649+ "using": "node20",
1650+ "main": "m.js",
1651+ "pre": null,
1652+ "preIf": "always()",
1653+ "post": null,
1654+ "postIf": "always()"
1655+ }
1656+ },
1657+ "int32_02.yml": {
1658+ "name": "A",
1659+ "description": "D",
1660+ "inputs": [
1661+ {
1662+ "name": "a",
1663+ "default": "-1"
1664+ }
1665+ ],
1666+ "execution": {
1667+ "type": "node",
1668+ "using": "node20",
1669+ "main": "m.js",
1670+ "pre": null,
1671+ "preIf": "always()",
1672+ "post": null,
1673+ "postIf": "always()"
1674+ }
1675+ },
1676+ "int32_03.yml": {
1677+ "errors": [
1678+ "int32_03.yml: The value '0x100000000' on line 5 and column 14 is invalid for the type ''",
1679+ "System.ArgumentException: Unexpected type '' encountered while reading 'action manifest root'. The type 'MappingToken' was expected."
1680+ ],
1681+ "failed": "Failed to load int32_03.yml"
1682+ },
1683+ "int32_04.yml": {
1684+ "name": "A",
1685+ "description": "D",
1686+ "inputs": [
1687+ {
1688+ "name": "a",
1689+ "default": "2147483647"
1690+ }
1691+ ],
1692+ "execution": {
1693+ "type": "node",
1694+ "using": "node20",
1695+ "main": "m.js",
1696+ "pre": null,
1697+ "preIf": "always()",
1698+ "post": null,
1699+ "postIf": "always()"
1700+ }
1701+ },
1702+ "int32_05.yml": {
1703+ "name": "A",
1704+ "description": "D",
1705+ "inputs": [
1706+ {
1707+ "name": "a",
1708+ "default": "-2147483648"
1709+ }
1710+ ],
1711+ "execution": {
1712+ "type": "node",
1713+ "using": "node20",
1714+ "main": "m.js",
1715+ "pre": null,
1716+ "preIf": "always()",
1717+ "post": null,
1718+ "postIf": "always()"
1719+ }
1720+ },
1721+ "int32_06.yml": {
1722+ "name": "A",
1723+ "description": "D",
1724+ "inputs": [
1725+ {
1726+ "name": "a",
1727+ "default": "-1"
1728+ }
1729+ ],
1730+ "execution": {
1731+ "type": "node",
1732+ "using": "node20",
1733+ "main": "m.js",
1734+ "pre": null,
1735+ "preIf": "always()",
1736+ "post": null,
1737+ "postIf": "always()"
1738+ }
1739+ },
1740+ "int32_07.yml": {
1741+ "errors": [
1742+ "int32_07.yml: The value '0o40000000000' on line 5 and column 14 is invalid for the type ''",
1743+ "System.ArgumentException: Unexpected type '' encountered while reading 'action manifest root'. The type 'MappingToken' was expected."
1744+ ],
1745+ "failed": "Failed to load int32_07.yml"
1746+ },
1747+ "int32_08.yml": {
1748+ "name": "A",
1749+ "description": "D",
1750+ "inputs": [
1751+ {
1752+ "name": "a",
1753+ "default": "-1"
1754+ }
1755+ ],
1756+ "execution": {
1757+ "type": "node",
1758+ "using": "node20",
1759+ "main": "m.js",
1760+ "pre": null,
1761+ "preIf": "always()",
1762+ "post": null,
1763+ "postIf": "always()"
1764+ }
1765+ },
1766+ "int32_09.yml": {
1767+ "name": "A",
1768+ "description": "D",
1769+ "inputs": [
1770+ {
1771+ "name": "a",
1772+ "default": "-2147483648"
1773+ }
1774+ ],
1775+ "execution": {
1776+ "type": "node",
1777+ "using": "node20",
1778+ "main": "m.js",
1779+ "pre": null,
1780+ "preIf": "always()",
1781+ "post": null,
1782+ "postIf": "always()"
1783+ }
1784+ },
1785+ "int32_10.yml": {
1786+ "errors": [
1787+ "int32_10.yml: The value '0x100000000' on line 5 and column 14 is invalid for the type 'tag:yaml.org,2002:int'",
1788+ "System.ArgumentException: Unexpected type '' encountered while reading 'action manifest root'. The type 'MappingToken' was expected."
1789+ ],
1790+ "failed": "Failed to load int32_10.yml"
1791+ },
1792+ "int32_11.yml": {
1793+ "name": "A",
1794+ "description": "D",
1795+ "inputs": [
1796+ {
1797+ "name": "a",
1798+ "default": "-2147483648"
1799+ }
1800+ ],
1801+ "execution": {
1802+ "type": "node",
1803+ "using": "node20",
1804+ "main": "m.js",
1805+ "pre": null,
1806+ "preIf": "always()",
1807+ "post": null,
1808+ "postIf": "always()"
1809+ }
1810+ },
1811+ "int32_12.yml": {
1812+ "errors": [
1813+ "int32_12.yml: The value '0o40000000000' on line 5 and column 14 is invalid for the type 'tag:yaml.org,2002:int'",
1814+ "System.ArgumentException: Unexpected type '' encountered while reading 'action manifest root'. The type 'MappingToken' was expected."
1815+ ],
1816+ "failed": "Failed to load int32_12.yml"
1817+ },
1818+ "int32_13.yml": {
1819+ "name": "A",
1820+ "description": "D",
1821+ "inputs": [
1822+ {
1823+ "name": "a",
1824+ "default": "12"
1825+ }
1826+ ],
1827+ "execution": {
1828+ "type": "node",
1829+ "using": "node20",
1830+ "main": "m.js",
1831+ "pre": null,
1832+ "preIf": "always()",
1833+ "post": null,
1834+ "postIf": "always()"
1835+ }
1836+ },
1837+ "int32_14.yml": {
1838+ "errors": [
1839+ "int32_14.yml: The value '0x10' on line 5 and column 14 is invalid for the type 'tag:yaml.org,2002:float'",
1840+ "System.ArgumentException: Unexpected type '' encountered while reading 'action manifest root'. The type 'MappingToken' was expected."
1841+ ],
1842+ "failed": "Failed to load int32_14.yml"
1843+ },
1844+ "int32_15.yml": {
1845+ "name": "A",
1846+ "description": "D",
1847+ "inputs": [
1848+ {
1849+ "name": "a",
1850+ "default": "0"
1851+ }
1852+ ],
1853+ "execution": {
1854+ "type": "node",
1855+ "using": "node20",
1856+ "main": "m.js",
1857+ "pre": null,
1858+ "preIf": "always()",
1859+ "post": null,
1860+ "postIf": "always()"
1861+ }
1862+ },
1863+ "int32_16.yml": {
1864+ "name": "A",
1865+ "description": "D",
1866+ "inputs": [
1867+ {
1868+ "name": "a",
1869+ "default": "-559038737"
1870+ }
1871+ ],
1872+ "execution": {
1873+ "type": "node",
1874+ "using": "node20",
1875+ "main": "m.js",
1876+ "pre": null,
1877+ "preIf": "always()",
1878+ "post": null,
1879+ "postIf": "always()"
1880+ }
1881+ },
1882+ "int32_key.yml": {
1883+ "name": "A",
1884+ "description": "D",
1885+ "inputs": [
1886+ {
1887+ "name": "-1",
1888+ "default": "x"
1889+ },
1890+ {
1891+ "name": "-2147483648",
1892+ "default": "y"
1893+ }
1894+ ],
1895+ "execution": {
1896+ "type": "node",
1897+ "using": "node20",
1898+ "main": "m.js",
1899+ "pre": null,
1900+ "preIf": "always()",
1901+ "post": null,
1902+ "postIf": "always()"
1903+ }
1904+ },
1905+ "key_bool_dup.yml": {
1906+ "name": "A",
1907+ "description": "D",
1908+ "errors": [
1909+ "key_bool_dup.yml (Line: 6, Col: 3): 'true' is already defined"
1910+ ],
1911+ "failed": "Failed to load key_bool_dup.yml"
1912+ },
1913+ "key_float_dup.yml": {
1914+ "name": "A",
1915+ "description": "D",
1916+ "errors": [
1917+ "key_float_dup.yml (Line: 6, Col: 3): '1' is already defined"
1918+ ],
1919+ "failed": "Failed to load key_float_dup.yml"
1920+ },
1921+ "key_hex_dup.yml": {
1922+ "name": "A",
1923+ "description": "D",
1924+ "errors": [
1925+ "key_hex_dup.yml (Line: 6, Col: 3): '16' is already defined"
1926+ ],
1927+ "failed": "Failed to load key_hex_dup.yml"
1928+ },
1929+ "key_hex_input.yml": {
1930+ "name": "A",
1931+ "description": "D",
1932+ "inputs": [
1933+ {
1934+ "name": "16",
1935+ "default": "x"
1936+ },
1937+ {
1938+ "name": "1",
1939+ "default": "y"
1940+ },
1941+ {
1942+ "name": "true",
1943+ "default": "z"
1944+ }
1945+ ],
1946+ "execution": {
1947+ "type": "node",
1948+ "using": "node20",
1949+ "main": "m.js",
1950+ "pre": null,
1951+ "preIf": "always()",
1952+ "post": null,
1953+ "postIf": "always()"
1954+ }
1955+ },
1956+ "key_null_env.yml": {
1957+ "name": "A",
1958+ "description": "D",
1959+ "errors": [
1960+ "key_null_env.yml (Line: 7, Col: 5): Unexpected value ''"
1961+ ],
1962+ "failed": "Failed to load key_null_env.yml"
1963+ },
1964+ "key_null_inputs.yml": {
1965+ "name": "A",
1966+ "description": "D",
1967+ "errors": [
1968+ "key_null_inputs.yml (Line: 4, Col: 3): Unexpected value ''"
1969+ ],
1970+ "failed": "Failed to load key_null_inputs.yml"
1971+ },
1972+ "key_null_top.yml": {
1973+ "name": "A",
1974+ "description": "D",
1975+ "errors": [
1976+ "key_null_top.yml (Line: 1, Col: 1): Unexpected value ''"
1977+ ],
1978+ "failed": "Failed to load key_null_top.yml"
1979+ },
1980+ "key_number_runs.yml": {
1981+ "name": "A",
1982+ "description": "D",
1983+ "errors": [
1984+ "key_number_runs.yml (Line: 6, Col: 3): Unexpected value '1000'"
1985+ ],
1986+ "failed": "Failed to load key_number_runs.yml"
1987+ },
14321988 "ls_parser_accepts_valid_context_in_pre_if.yml": {
14331989 "name": "Node Action",
14341990 "description": "A node action",
@@ -1261,6 +1261,193 @@
1261 ],1261 ],
1262 "failed": "Failed to load empty_file.yml"1262 "failed": "Failed to load empty_file.yml"
1263 },1263 },
1264+ "fold_inputs_accent.yml": {
1265+ "name": "A",
1266+ "description": "D",
1267+ "errors": [
1268+ "fold_inputs_accent.yml (Line: 6, Col: 3): 'É' is already defined"
1269+ ],
1270+ "failed": "Failed to load fold_inputs_accent.yml"
1271+ },
1272+ "fold_inputs_dotless.yml": {
1273+ "name": "A",
1274+ "description": "D",
1275+ "errors": [
1276+ "fold_inputs_dotless.yml (Line: 8, Col: 3): 'i' is already defined"
1277+ ],
1278+ "failed": "Failed to load fold_inputs_dotless.yml"
1279+ },
1280+ "fold_inputs_greek.yml": {
1281+ "name": "A",
1282+ "description": "D",
1283+ "errors": [
1284+ "fold_inputs_greek.yml (Line: 6, Col: 3): 'ς' is already defined",
1285+ "fold_inputs_greek.yml (Line: 8, Col: 3): 'Σ' is already defined"
1286+ ],
1287+ "failed": "Failed to load fold_inputs_greek.yml"
1288+ },
1289+ "fold_inputs_kelvin.yml": {
1290+ "name": "A",
1291+ "description": "D",
1292+ "inputs": [
1293+ {
1294+ "name": "k",
1295+ "default": "x"
1296+ },
1297+ {
1298+ "name": "K",
1299+ "default": "y"
1300+ }
1301+ ],
1302+ "execution": {
1303+ "type": "node",
1304+ "using": "node20",
1305+ "main": "m.js",
1306+ "pre": null,
1307+ "preIf": "always()",
1308+ "post": null,
1309+ "postIf": "always()"
1310+ }
1311+ },
1312+ "fold_inputs_s.yml": {
1313+ "name": "A",
1314+ "description": "D",
1315+ "inputs": [
1316+ {
1317+ "name": "s",
1318+ "default": "x"
1319+ },
1320+ {
1321+ "name": "ſ",
1322+ "default": "y"
1323+ }
1324+ ],
1325+ "execution": {
1326+ "type": "node",
1327+ "using": "node20",
1328+ "main": "m.js",
1329+ "pre": null,
1330+ "preIf": "always()",
1331+ "post": null,
1332+ "postIf": "always()"
1333+ }
1334+ },
1335+ "fold_inputs_sharp.yml": {
1336+ "name": "A",
1337+ "description": "D",
1338+ "inputs": [
1339+ {
1340+ "name": "ß",
1341+ "default": "x"
1342+ },
1343+ {
1344+ "name": "SS",
1345+ "default": "y"
1346+ }
1347+ ],
1348+ "execution": {
1349+ "type": "node",
1350+ "using": "node20",
1351+ "main": "m.js",
1352+ "pre": null,
1353+ "preIf": "always()",
1354+ "post": null,
1355+ "postIf": "always()"
1356+ }
1357+ },
1358+ "fold_runs_keys.yml": {
1359+ "name": "A",
1360+ "description": "D",
1361+ "errors": [
1362+ "fold_runs_keys.yml (Line: 6, Col: 3): Unexpected value 'é'",
1363+ "fold_runs_keys.yml (Line: 7, Col: 3): 'É' is already defined"
1364+ ],
1365+ "failed": "Failed to load fold_runs_keys.yml"
1366+ },
1367+ "fold_step_ids_ascii_dup.yml": {
1368+ "name": "A",
1369+ "description": "D",
1370+ "errors": [
1371+ "fold_step_ids_ascii_dup.yml (Line: 11, Col: 11): The identifier 'ABC' may not be used more than once within the same scope.",
1372+ "GitHub.DistributedTask.ObjectTemplating.TemplateValidationException: The template is not valid. fold_step_ids_ascii_dup.yml (Line: 11, Col: 11): The identifier 'ABC' may not be used more than once within the same scope."
1373+ ],
1374+ "failed": "Failed to load fold_step_ids_ascii_dup.yml"
1375+ },
1376+ "fold_step_ids_long.yml": {
1377+ "name": "A",
1378+ "description": "D",
1379+ "errors": [
1380+ "fold_step_ids_long.yml (Line: 11, Col: 11): The identifier 'ÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉ' may not be used more than once within the same scope.",
1381+ "GitHub.DistributedTask.ObjectTemplating.TemplateValidationException: The template is not valid. fold_step_ids_long.yml (Line: 11, Col: 11): The identifier 'ÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉ' may not be used more than once within the same scope."
1382+ ],
1383+ "failed": "Failed to load fold_step_ids_long.yml"
1384+ },
1385+ "fold_step_ids_long_s.yml": {
1386+ "name": "A",
1387+ "description": "D",
1388+ "inputs": [],
1389+ "execution": {
1390+ "type": "composite",
1391+ "using": "composite",
1392+ "steps": [
1393+ {
1394+ "id": "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss",
1395+ "if": "success()",
1396+ "name": null,
1397+ "continueOnError": null,
1398+ "timeout": null,
1399+ "kind": "run",
1400+ "script": "x",
1401+ "shell": "sh"
1402+ },
1403+ {
1404+ "id": "ſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſſ",
1405+ "if": "success()",
1406+ "name": null,
1407+ "continueOnError": null,
1408+ "timeout": null,
1409+ "kind": "run",
1410+ "script": "x",
1411+ "shell": "sh"
1412+ }
1413+ ],
1414+ "outputs": null
1415+ }
1416+ },
1417+ "fold_top_keys.yml": {
1418+ "name": "A",
1419+ "description": "D",
1420+ "errors": [
1421+ "fold_top_keys.yml (Line: 2, Col: 1): 'NAME' is already defined",
1422+ "fold_top_keys.yml (Line: 4, Col: 1): 'É' is already defined"
1423+ ],
1424+ "failed": "Failed to load fold_top_keys.yml"
1425+ },
1426+ "fold_using_dotless.yml": {
1427+ "name": "A",
1428+ "description": "D",
1429+ "inputs": [],
1430+ "execution": {
1431+ "type": "docker",
1432+ "using": "DOCKER",
1433+ "image": "Dockerfile",
1434+ "args": null,
1435+ "entrypoint": null,
1436+ "env": null,
1437+ "pre": null,
1438+ "preIf": "always()",
1439+ "post": null,
1440+ "postIf": "always()"
1441+ }
1442+ },
1443+ "fold_using_kelvin.yml": {
1444+ "name": "A",
1445+ "description": "D",
1446+ "errors": [
1447+ "System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. (Parameter ''using: Komposite' is not supported, use 'docker', 'node12', 'node16', 'node20' or 'node24' instead.')"
1448+ ],
1449+ "failed": "Failed to load fold_using_kelvin.yml"
1450+ },
1264 "inputs_default_bad_context.yml": {1451 "inputs_default_bad_context.yml": {
1265 "name": "A",1452 "name": "A",
1266 "description": "D",1453 "description": "D",
@@ -1429,6 +1616,375 @@
1429 "postIf": "always()"1616 "postIf": "always()"
1430 }1617 }
1431 },1618 },
1619+ "int32_00.yml": {
1620+ "name": "A",
1621+ "description": "D",
1622+ "inputs": [
1623+ {
1624+ "name": "a",
1625+ "default": "2147483647"
1626+ }
1627+ ],
1628+ "execution": {
1629+ "type": "node",
1630+ "using": "node20",
1631+ "main": "m.js",
1632+ "pre": null,
1633+ "preIf": "always()",
1634+ "post": null,
1635+ "postIf": "always()"
1636+ }
1637+ },
1638+ "int32_01.yml": {
1639+ "name": "A",
1640+ "description": "D",
1641+ "inputs": [
1642+ {
1643+ "name": "a",
1644+ "default": "-2147483648"
1645+ }
1646+ ],
1647+ "execution": {
1648+ "type": "node",
1649+ "using": "node20",
1650+ "main": "m.js",
1651+ "pre": null,
1652+ "preIf": "always()",
1653+ "post": null,
1654+ "postIf": "always()"
1655+ }
1656+ },
1657+ "int32_02.yml": {
1658+ "name": "A",
1659+ "description": "D",
1660+ "inputs": [
1661+ {
1662+ "name": "a",
1663+ "default": "-1"
1664+ }
1665+ ],
1666+ "execution": {
1667+ "type": "node",
1668+ "using": "node20",
1669+ "main": "m.js",
1670+ "pre": null,
1671+ "preIf": "always()",
1672+ "post": null,
1673+ "postIf": "always()"
1674+ }
1675+ },
1676+ "int32_03.yml": {
1677+ "errors": [
1678+ "int32_03.yml: The value '0x100000000' on line 5 and column 14 is invalid for the type ''",
1679+ "System.ArgumentException: Unexpected type '' encountered while reading 'action manifest root'. The type 'MappingToken' was expected."
1680+ ],
1681+ "failed": "Failed to load int32_03.yml"
1682+ },
1683+ "int32_04.yml": {
1684+ "name": "A",
1685+ "description": "D",
1686+ "inputs": [
1687+ {
1688+ "name": "a",
1689+ "default": "2147483647"
1690+ }
1691+ ],
1692+ "execution": {
1693+ "type": "node",
1694+ "using": "node20",
1695+ "main": "m.js",
1696+ "pre": null,
1697+ "preIf": "always()",
1698+ "post": null,
1699+ "postIf": "always()"
1700+ }
1701+ },
1702+ "int32_05.yml": {
1703+ "name": "A",
1704+ "description": "D",
1705+ "inputs": [
1706+ {
1707+ "name": "a",
1708+ "default": "-2147483648"
1709+ }
1710+ ],
1711+ "execution": {
1712+ "type": "node",
1713+ "using": "node20",
1714+ "main": "m.js",
1715+ "pre": null,
1716+ "preIf": "always()",
1717+ "post": null,
1718+ "postIf": "always()"
1719+ }
1720+ },
1721+ "int32_06.yml": {
1722+ "name": "A",
1723+ "description": "D",
1724+ "inputs": [
1725+ {
1726+ "name": "a",
1727+ "default": "-1"
1728+ }
1729+ ],
1730+ "execution": {
1731+ "type": "node",
1732+ "using": "node20",
1733+ "main": "m.js",
1734+ "pre": null,
1735+ "preIf": "always()",
1736+ "post": null,
1737+ "postIf": "always()"
1738+ }
1739+ },
1740+ "int32_07.yml": {
1741+ "errors": [
1742+ "int32_07.yml: The value '0o40000000000' on line 5 and column 14 is invalid for the type ''",
1743+ "System.ArgumentException: Unexpected type '' encountered while reading 'action manifest root'. The type 'MappingToken' was expected."
1744+ ],
1745+ "failed": "Failed to load int32_07.yml"
1746+ },
1747+ "int32_08.yml": {
1748+ "name": "A",
1749+ "description": "D",
1750+ "inputs": [
1751+ {
1752+ "name": "a",
1753+ "default": "-1"
1754+ }
1755+ ],
1756+ "execution": {
1757+ "type": "node",
1758+ "using": "node20",
1759+ "main": "m.js",
1760+ "pre": null,
1761+ "preIf": "always()",
1762+ "post": null,
1763+ "postIf": "always()"
1764+ }
1765+ },
1766+ "int32_09.yml": {
1767+ "name": "A",
1768+ "description": "D",
1769+ "inputs": [
1770+ {
1771+ "name": "a",
1772+ "default": "-2147483648"
1773+ }
1774+ ],
1775+ "execution": {
1776+ "type": "node",
1777+ "using": "node20",
1778+ "main": "m.js",
1779+ "pre": null,
1780+ "preIf": "always()",
1781+ "post": null,
1782+ "postIf": "always()"
1783+ }
1784+ },
1785+ "int32_10.yml": {
1786+ "errors": [
1787+ "int32_10.yml: The value '0x100000000' on line 5 and column 14 is invalid for the type 'tag:yaml.org,2002:int'",
1788+ "System.ArgumentException: Unexpected type '' encountered while reading 'action manifest root'. The type 'MappingToken' was expected."
1789+ ],
1790+ "failed": "Failed to load int32_10.yml"
1791+ },
1792+ "int32_11.yml": {
1793+ "name": "A",
1794+ "description": "D",
1795+ "inputs": [
1796+ {
1797+ "name": "a",
1798+ "default": "-2147483648"
1799+ }
1800+ ],
1801+ "execution": {
1802+ "type": "node",
1803+ "using": "node20",
1804+ "main": "m.js",
1805+ "pre": null,
1806+ "preIf": "always()",
1807+ "post": null,
1808+ "postIf": "always()"
1809+ }
1810+ },
1811+ "int32_12.yml": {
1812+ "errors": [
1813+ "int32_12.yml: The value '0o40000000000' on line 5 and column 14 is invalid for the type 'tag:yaml.org,2002:int'",
1814+ "System.ArgumentException: Unexpected type '' encountered while reading 'action manifest root'. The type 'MappingToken' was expected."
1815+ ],
1816+ "failed": "Failed to load int32_12.yml"
1817+ },
1818+ "int32_13.yml": {
1819+ "name": "A",
1820+ "description": "D",
1821+ "inputs": [
1822+ {
1823+ "name": "a",
1824+ "default": "12"
1825+ }
1826+ ],
1827+ "execution": {
1828+ "type": "node",
1829+ "using": "node20",
1830+ "main": "m.js",
1831+ "pre": null,
1832+ "preIf": "always()",
1833+ "post": null,
1834+ "postIf": "always()"
1835+ }
1836+ },
1837+ "int32_14.yml": {
1838+ "errors": [
1839+ "int32_14.yml: The value '0x10' on line 5 and column 14 is invalid for the type 'tag:yaml.org,2002:float'",
1840+ "System.ArgumentException: Unexpected type '' encountered while reading 'action manifest root'. The type 'MappingToken' was expected."
1841+ ],
1842+ "failed": "Failed to load int32_14.yml"
1843+ },
1844+ "int32_15.yml": {
1845+ "name": "A",
1846+ "description": "D",
1847+ "inputs": [
1848+ {
1849+ "name": "a",
1850+ "default": "0"
1851+ }
1852+ ],
1853+ "execution": {
1854+ "type": "node",
1855+ "using": "node20",
1856+ "main": "m.js",
1857+ "pre": null,
1858+ "preIf": "always()",
1859+ "post": null,
1860+ "postIf": "always()"
1861+ }
1862+ },
1863+ "int32_16.yml": {
1864+ "name": "A",
1865+ "description": "D",
1866+ "inputs": [
1867+ {
1868+ "name": "a",
1869+ "default": "-559038737"
1870+ }
1871+ ],
1872+ "execution": {
1873+ "type": "node",
1874+ "using": "node20",
1875+ "main": "m.js",
1876+ "pre": null,
1877+ "preIf": "always()",
1878+ "post": null,
1879+ "postIf": "always()"
1880+ }
1881+ },
1882+ "int32_key.yml": {
1883+ "name": "A",
1884+ "description": "D",
1885+ "inputs": [
1886+ {
1887+ "name": "-1",
1888+ "default": "x"
1889+ },
1890+ {
1891+ "name": "-2147483648",
1892+ "default": "y"
1893+ }
1894+ ],
1895+ "execution": {
1896+ "type": "node",
1897+ "using": "node20",
1898+ "main": "m.js",
1899+ "pre": null,
1900+ "preIf": "always()",
1901+ "post": null,
1902+ "postIf": "always()"
1903+ }
1904+ },
1905+ "key_bool_dup.yml": {
1906+ "name": "A",
1907+ "description": "D",
1908+ "errors": [
1909+ "key_bool_dup.yml (Line: 6, Col: 3): 'true' is already defined"
1910+ ],
1911+ "failed": "Failed to load key_bool_dup.yml"
1912+ },
1913+ "key_float_dup.yml": {
1914+ "name": "A",
1915+ "description": "D",
1916+ "errors": [
1917+ "key_float_dup.yml (Line: 6, Col: 3): '1' is already defined"
1918+ ],
1919+ "failed": "Failed to load key_float_dup.yml"
1920+ },
1921+ "key_hex_dup.yml": {
1922+ "name": "A",
1923+ "description": "D",
1924+ "errors": [
1925+ "key_hex_dup.yml (Line: 6, Col: 3): '16' is already defined"
1926+ ],
1927+ "failed": "Failed to load key_hex_dup.yml"
1928+ },
1929+ "key_hex_input.yml": {
1930+ "name": "A",
1931+ "description": "D",
1932+ "inputs": [
1933+ {
1934+ "name": "16",
1935+ "default": "x"
1936+ },
1937+ {
1938+ "name": "1",
1939+ "default": "y"
1940+ },
1941+ {
1942+ "name": "true",
1943+ "default": "z"
1944+ }
1945+ ],
1946+ "execution": {
1947+ "type": "node",
1948+ "using": "node20",
1949+ "main": "m.js",
1950+ "pre": null,
1951+ "preIf": "always()",
1952+ "post": null,
1953+ "postIf": "always()"
1954+ }
1955+ },
1956+ "key_null_env.yml": {
1957+ "name": "A",
1958+ "description": "D",
1959+ "errors": [
1960+ "key_null_env.yml (Line: 7, Col: 5): Unexpected value ''"
1961+ ],
1962+ "failed": "Failed to load key_null_env.yml"
1963+ },
1964+ "key_null_inputs.yml": {
1965+ "name": "A",
1966+ "description": "D",
1967+ "errors": [
1968+ "key_null_inputs.yml (Line: 4, Col: 3): Unexpected value ''"
1969+ ],
1970+ "failed": "Failed to load key_null_inputs.yml"
1971+ },
1972+ "key_null_top.yml": {
1973+ "name": "A",
1974+ "description": "D",
1975+ "errors": [
1976+ "key_null_top.yml (Line: 1, Col: 1): Unexpected value ''"
1977+ ],
1978+ "failed": "Failed to load key_null_top.yml"
1979+ },
1980+ "key_number_runs.yml": {
1981+ "name": "A",
1982+ "description": "D",
1983+ "errors": [
1984+ "key_number_runs.yml (Line: 6, Col: 3): Unexpected value '1000'"
1985+ ],
1986+ "failed": "Failed to load key_number_runs.yml"
1987+ },
1432 "ls_parser_accepts_valid_context_in_pre_if.yml": {1988 "ls_parser_accepts_valid_context_in_pre_if.yml": {
1433 "name": "Node Action",1989 "name": "Node Action",
1434 "description": "A node action",1990 "description": "A node action",
M action/testdata/strict.json +498 -0
@@ -863,6 +863,155 @@
863863 "empty_file.yml: Expected a scalar value, a sequence, or a mapping"
864864 ]
865865 },
866+ "fold_inputs_accent.yml": {
867+ "errors": [
868+ "fold_inputs_accent.yml (Line: 6, Col: 3): 'É' is already defined"
869+ ],
870+ "inputs": [],
871+ "outputs": [],
872+ "runs": {
873+ "steps": 0
874+ }
875+ },
876+ "fold_inputs_dotless.yml": {
877+ "errors": [
878+ "fold_inputs_dotless.yml (Line: 6, Col: 3): 'I' is already defined",
879+ "fold_inputs_dotless.yml (Line: 8, Col: 3): 'i' is already defined"
880+ ],
881+ "inputs": [],
882+ "outputs": [],
883+ "runs": {
884+ "steps": 0
885+ }
886+ },
887+ "fold_inputs_greek.yml": {
888+ "errors": [
889+ "fold_inputs_greek.yml (Line: 6, Col: 3): 'ς' is already defined",
890+ "fold_inputs_greek.yml (Line: 8, Col: 3): 'Σ' is already defined"
891+ ],
892+ "inputs": [],
893+ "outputs": [],
894+ "runs": {
895+ "steps": 0
896+ }
897+ },
898+ "fold_inputs_kelvin.yml": {
899+ "errors": [],
900+ "name": "A",
901+ "description": "D",
902+ "inputs": [
903+ {
904+ "id": "k",
905+ "default": "x"
906+ },
907+ {
908+ "id": "K",
909+ "default": "y"
910+ }
911+ ],
912+ "outputs": [],
913+ "runs": {
914+ "using": "node20",
915+ "main": "m.js",
916+ "steps": 0
917+ }
918+ },
919+ "fold_inputs_s.yml": {
920+ "errors": [
921+ "fold_inputs_s.yml (Line: 6, Col: 3): 'ſ' is already defined"
922+ ],
923+ "inputs": [],
924+ "outputs": [],
925+ "runs": {
926+ "steps": 0
927+ }
928+ },
929+ "fold_inputs_sharp.yml": {
930+ "errors": [
931+ "fold_inputs_sharp.yml (Line: 6, Col: 3): 'SS' is already defined"
932+ ],
933+ "inputs": [],
934+ "outputs": [],
935+ "runs": {
936+ "steps": 0
937+ }
938+ },
939+ "fold_runs_keys.yml": {
940+ "errors": [
941+ "fold_runs_keys.yml (Line: 6, Col: 3): Unexpected value 'é'",
942+ "fold_runs_keys.yml (Line: 7, Col: 3): 'É' is already defined"
943+ ],
944+ "inputs": [],
945+ "outputs": [],
946+ "runs": {
947+ "steps": 0
948+ }
949+ },
950+ "fold_step_ids_ascii_dup.yml": {
951+ "errors": [],
952+ "name": "A",
953+ "description": "D",
954+ "inputs": [],
955+ "outputs": [],
956+ "runs": {
957+ "using": "composite",
958+ "steps": 2
959+ }
960+ },
961+ "fold_step_ids_long.yml": {
962+ "errors": [],
963+ "name": "A",
964+ "description": "D",
965+ "inputs": [],
966+ "outputs": [],
967+ "runs": {
968+ "using": "composite",
969+ "steps": 2
970+ }
971+ },
972+ "fold_step_ids_long_s.yml": {
973+ "errors": [],
974+ "name": "A",
975+ "description": "D",
976+ "inputs": [],
977+ "outputs": [],
978+ "runs": {
979+ "using": "composite",
980+ "steps": 2
981+ }
982+ },
983+ "fold_top_keys.yml": {
984+ "errors": [
985+ "fold_top_keys.yml (Line: 2, Col: 1): 'NAME' is already defined",
986+ "fold_top_keys.yml (Line: 3, Col: 1): Unexpected value 'é'",
987+ "fold_top_keys.yml (Line: 4, Col: 1): 'É' is already defined"
988+ ],
989+ "inputs": [],
990+ "outputs": [],
991+ "runs": {
992+ "steps": 0
993+ }
994+ },
995+ "fold_using_dotless.yml": {
996+ "errors": [
997+ "fold_using_dotless.yml (Line: 4, Col: 10): Unexpected value 'DOCKER'"
998+ ],
999+ "inputs": [],
1000+ "outputs": [],
1001+ "runs": {
1002+ "steps": 0
1003+ }
1004+ },
1005+ "fold_using_kelvin.yml": {
1006+ "errors": [
1007+ "fold_using_kelvin.yml (Line: 4, Col: 10): Unexpected value 'Komposite'"
1008+ ],
1009+ "inputs": [],
1010+ "outputs": [],
1011+ "runs": {
1012+ "steps": 0
1013+ }
1014+ },
8661015 "inputs_default_bad_context.yml": {
8671016 "errors": [
8681017 "inputs_default_bad_context.yml (Line: 5, Col: 14): Unrecognized named-value: 'inputs'"
@@ -991,6 +1140,355 @@
9911140 "steps": 0
9921141 }
9931142 },
1143+ "int32_00.yml": {
1144+ "errors": [],
1145+ "name": "A",
1146+ "description": "D",
1147+ "inputs": [
1148+ {
1149+ "id": "a",
1150+ "default": "2147483647"
1151+ }
1152+ ],
1153+ "outputs": [],
1154+ "runs": {
1155+ "using": "node20",
1156+ "main": "m.js",
1157+ "steps": 0
1158+ }
1159+ },
1160+ "int32_01.yml": {
1161+ "errors": [],
1162+ "name": "A",
1163+ "description": "D",
1164+ "inputs": [
1165+ {
1166+ "id": "a",
1167+ "default": "2147483648"
1168+ }
1169+ ],
1170+ "outputs": [],
1171+ "runs": {
1172+ "using": "node20",
1173+ "main": "m.js",
1174+ "steps": 0
1175+ }
1176+ },
1177+ "int32_02.yml": {
1178+ "errors": [],
1179+ "name": "A",
1180+ "description": "D",
1181+ "inputs": [
1182+ {
1183+ "id": "a",
1184+ "default": "4294967295"
1185+ }
1186+ ],
1187+ "outputs": [],
1188+ "runs": {
1189+ "using": "node20",
1190+ "main": "m.js",
1191+ "steps": 0
1192+ }
1193+ },
1194+ "int32_03.yml": {
1195+ "errors": [],
1196+ "name": "A",
1197+ "description": "D",
1198+ "inputs": [
1199+ {
1200+ "id": "a",
1201+ "default": "4294967296"
1202+ }
1203+ ],
1204+ "outputs": [],
1205+ "runs": {
1206+ "using": "node20",
1207+ "main": "m.js",
1208+ "steps": 0
1209+ }
1210+ },
1211+ "int32_04.yml": {
1212+ "errors": [],
1213+ "name": "A",
1214+ "description": "D",
1215+ "inputs": [
1216+ {
1217+ "id": "a",
1218+ "default": "2147483647"
1219+ }
1220+ ],
1221+ "outputs": [],
1222+ "runs": {
1223+ "using": "node20",
1224+ "main": "m.js",
1225+ "steps": 0
1226+ }
1227+ },
1228+ "int32_05.yml": {
1229+ "errors": [],
1230+ "name": "A",
1231+ "description": "D",
1232+ "inputs": [
1233+ {
1234+ "id": "a",
1235+ "default": "2147483648"
1236+ }
1237+ ],
1238+ "outputs": [],
1239+ "runs": {
1240+ "using": "node20",
1241+ "main": "m.js",
1242+ "steps": 0
1243+ }
1244+ },
1245+ "int32_06.yml": {
1246+ "errors": [],
1247+ "name": "A",
1248+ "description": "D",
1249+ "inputs": [
1250+ {
1251+ "id": "a",
1252+ "default": "4294967295"
1253+ }
1254+ ],
1255+ "outputs": [],
1256+ "runs": {
1257+ "using": "node20",
1258+ "main": "m.js",
1259+ "steps": 0
1260+ }
1261+ },
1262+ "int32_07.yml": {
1263+ "errors": [],
1264+ "name": "A",
1265+ "description": "D",
1266+ "inputs": [
1267+ {
1268+ "id": "a",
1269+ "default": "4294967296"
1270+ }
1271+ ],
1272+ "outputs": [],
1273+ "runs": {
1274+ "using": "node20",
1275+ "main": "m.js",
1276+ "steps": 0
1277+ }
1278+ },
1279+ "int32_08.yml": {
1280+ "errors": [],
1281+ "name": "A",
1282+ "description": "D",
1283+ "inputs": [
1284+ {
1285+ "id": "a",
1286+ "default": "4294967295"
1287+ }
1288+ ],
1289+ "outputs": [],
1290+ "runs": {
1291+ "using": "node20",
1292+ "main": "m.js",
1293+ "steps": 0
1294+ }
1295+ },
1296+ "int32_09.yml": {
1297+ "errors": [],
1298+ "name": "A",
1299+ "description": "D",
1300+ "inputs": [
1301+ {
1302+ "id": "a",
1303+ "default": "2147483648"
1304+ }
1305+ ],
1306+ "outputs": [],
1307+ "runs": {
1308+ "using": "node20",
1309+ "main": "m.js",
1310+ "steps": 0
1311+ }
1312+ },
1313+ "int32_10.yml": {
1314+ "errors": [],
1315+ "name": "A",
1316+ "description": "D",
1317+ "inputs": [
1318+ {
1319+ "id": "a",
1320+ "default": "4294967296"
1321+ }
1322+ ],
1323+ "outputs": [],
1324+ "runs": {
1325+ "using": "node20",
1326+ "main": "m.js",
1327+ "steps": 0
1328+ }
1329+ },
1330+ "int32_11.yml": {
1331+ "errors": [],
1332+ "name": "A",
1333+ "description": "D",
1334+ "inputs": [
1335+ {
1336+ "id": "a",
1337+ "default": "2147483648"
1338+ }
1339+ ],
1340+ "outputs": [],
1341+ "runs": {
1342+ "using": "node20",
1343+ "main": "m.js",
1344+ "steps": 0
1345+ }
1346+ },
1347+ "int32_12.yml": {
1348+ "errors": [],
1349+ "name": "A",
1350+ "description": "D",
1351+ "inputs": [
1352+ {
1353+ "id": "a",
1354+ "default": "4294967296"
1355+ }
1356+ ],
1357+ "outputs": [],
1358+ "runs": {
1359+ "using": "node20",
1360+ "main": "m.js",
1361+ "steps": 0
1362+ }
1363+ },
1364+ "int32_13.yml": {
1365+ "errors": [],
1366+ "name": "A",
1367+ "description": "D",
1368+ "inputs": [
1369+ {
1370+ "id": "a",
1371+ "default": "12"
1372+ }
1373+ ],
1374+ "outputs": [],
1375+ "runs": {
1376+ "using": "node20",
1377+ "main": "m.js",
1378+ "steps": 0
1379+ }
1380+ },
1381+ "int32_14.yml": {
1382+ "errors": [],
1383+ "name": "A",
1384+ "description": "D",
1385+ "inputs": [
1386+ {
1387+ "id": "a",
1388+ "default": "0x10"
1389+ }
1390+ ],
1391+ "outputs": [],
1392+ "runs": {
1393+ "using": "node20",
1394+ "main": "m.js",
1395+ "steps": 0
1396+ }
1397+ },
1398+ "int32_15.yml": {
1399+ "errors": [],
1400+ "name": "A",
1401+ "description": "D",
1402+ "inputs": [
1403+ {
1404+ "id": "a",
1405+ "default": "0"
1406+ }
1407+ ],
1408+ "outputs": [],
1409+ "runs": {
1410+ "using": "node20",
1411+ "main": "m.js",
1412+ "steps": 0
1413+ }
1414+ },
1415+ "int32_16.yml": {
1416+ "errors": [],
1417+ "name": "A",
1418+ "description": "D",
1419+ "inputs": [
1420+ {
1421+ "id": "a",
1422+ "default": "3735928559"
1423+ }
1424+ ],
1425+ "outputs": [],
1426+ "runs": {
1427+ "using": "node20",
1428+ "main": "m.js",
1429+ "steps": 0
1430+ }
1431+ },
1432+ "int32_key.yml": {
1433+ "errors": [
1434+ "int32_key.yml: raw.indexOf is not a function"
1435+ ]
1436+ },
1437+ "key_bool_dup.yml": {
1438+ "errors": [
1439+ "key_bool_dup.yml: raw.indexOf is not a function"
1440+ ]
1441+ },
1442+ "key_float_dup.yml": {
1443+ "errors": [
1444+ "key_float_dup.yml: raw.indexOf is not a function"
1445+ ]
1446+ },
1447+ "key_hex_dup.yml": {
1448+ "errors": [
1449+ "key_hex_dup.yml: raw.indexOf is not a function"
1450+ ]
1451+ },
1452+ "key_hex_input.yml": {
1453+ "errors": [
1454+ "key_hex_input.yml: raw.indexOf is not a function"
1455+ ]
1456+ },
1457+ "key_null_env.yml": {
1458+ "errors": [
1459+ "key_null_env.yml (Line: 7, Col: 5): Unexpected value 'null'"
1460+ ],
1461+ "inputs": [],
1462+ "outputs": [],
1463+ "runs": {
1464+ "steps": 0
1465+ }
1466+ },
1467+ "key_null_inputs.yml": {
1468+ "errors": [
1469+ "key_null_inputs.yml (Line: 4, Col: 3): Unexpected value 'null'"
1470+ ],
1471+ "inputs": [],
1472+ "outputs": [],
1473+ "runs": {
1474+ "steps": 0
1475+ }
1476+ },
1477+ "key_null_top.yml": {
1478+ "errors": [
1479+ "key_null_top.yml (Line: 1, Col: 1): Unexpected value 'null'"
1480+ ],
1481+ "inputs": [],
1482+ "outputs": [],
1483+ "runs": {
1484+ "steps": 0
1485+ }
1486+ },
1487+ "key_number_runs.yml": {
1488+ "errors": [
1489+ "key_number_runs.yml: raw.indexOf is not a function"
1490+ ]
1491+ },
9941492 "ls_parser_accepts_valid_context_in_pre_if.yml": {
9951493 "errors": [],
9961494 "name": "Node Action",
@@ -863,6 +863,155 @@
863 "empty_file.yml: Expected a scalar value, a sequence, or a mapping"863 "empty_file.yml: Expected a scalar value, a sequence, or a mapping"
864 ]864 ]
865 },865 },
866+ "fold_inputs_accent.yml": {
867+ "errors": [
868+ "fold_inputs_accent.yml (Line: 6, Col: 3): 'É' is already defined"
869+ ],
870+ "inputs": [],
871+ "outputs": [],
872+ "runs": {
873+ "steps": 0
874+ }
875+ },
876+ "fold_inputs_dotless.yml": {
877+ "errors": [
878+ "fold_inputs_dotless.yml (Line: 6, Col: 3): 'I' is already defined",
879+ "fold_inputs_dotless.yml (Line: 8, Col: 3): 'i' is already defined"
880+ ],
881+ "inputs": [],
882+ "outputs": [],
883+ "runs": {
884+ "steps": 0
885+ }
886+ },
887+ "fold_inputs_greek.yml": {
888+ "errors": [
889+ "fold_inputs_greek.yml (Line: 6, Col: 3): 'ς' is already defined",
890+ "fold_inputs_greek.yml (Line: 8, Col: 3): 'Σ' is already defined"
891+ ],
892+ "inputs": [],
893+ "outputs": [],
894+ "runs": {
895+ "steps": 0
896+ }
897+ },
898+ "fold_inputs_kelvin.yml": {
899+ "errors": [],
900+ "name": "A",
901+ "description": "D",
902+ "inputs": [
903+ {
904+ "id": "k",
905+ "default": "x"
906+ },
907+ {
908+ "id": "K",
909+ "default": "y"
910+ }
911+ ],
912+ "outputs": [],
913+ "runs": {
914+ "using": "node20",
915+ "main": "m.js",
916+ "steps": 0
917+ }
918+ },
919+ "fold_inputs_s.yml": {
920+ "errors": [
921+ "fold_inputs_s.yml (Line: 6, Col: 3): 'ſ' is already defined"
922+ ],
923+ "inputs": [],
924+ "outputs": [],
925+ "runs": {
926+ "steps": 0
927+ }
928+ },
929+ "fold_inputs_sharp.yml": {
930+ "errors": [
931+ "fold_inputs_sharp.yml (Line: 6, Col: 3): 'SS' is already defined"
932+ ],
933+ "inputs": [],
934+ "outputs": [],
935+ "runs": {
936+ "steps": 0
937+ }
938+ },
939+ "fold_runs_keys.yml": {
940+ "errors": [
941+ "fold_runs_keys.yml (Line: 6, Col: 3): Unexpected value 'é'",
942+ "fold_runs_keys.yml (Line: 7, Col: 3): 'É' is already defined"
943+ ],
944+ "inputs": [],
945+ "outputs": [],
946+ "runs": {
947+ "steps": 0
948+ }
949+ },
950+ "fold_step_ids_ascii_dup.yml": {
951+ "errors": [],
952+ "name": "A",
953+ "description": "D",
954+ "inputs": [],
955+ "outputs": [],
956+ "runs": {
957+ "using": "composite",
958+ "steps": 2
959+ }
960+ },
961+ "fold_step_ids_long.yml": {
962+ "errors": [],
963+ "name": "A",
964+ "description": "D",
965+ "inputs": [],
966+ "outputs": [],
967+ "runs": {
968+ "using": "composite",
969+ "steps": 2
970+ }
971+ },
972+ "fold_step_ids_long_s.yml": {
973+ "errors": [],
974+ "name": "A",
975+ "description": "D",
976+ "inputs": [],
977+ "outputs": [],
978+ "runs": {
979+ "using": "composite",
980+ "steps": 2
981+ }
982+ },
983+ "fold_top_keys.yml": {
984+ "errors": [
985+ "fold_top_keys.yml (Line: 2, Col: 1): 'NAME' is already defined",
986+ "fold_top_keys.yml (Line: 3, Col: 1): Unexpected value 'é'",
987+ "fold_top_keys.yml (Line: 4, Col: 1): 'É' is already defined"
988+ ],
989+ "inputs": [],
990+ "outputs": [],
991+ "runs": {
992+ "steps": 0
993+ }
994+ },
995+ "fold_using_dotless.yml": {
996+ "errors": [
997+ "fold_using_dotless.yml (Line: 4, Col: 10): Unexpected value 'DOCKER'"
998+ ],
999+ "inputs": [],
1000+ "outputs": [],
1001+ "runs": {
1002+ "steps": 0
1003+ }
1004+ },
1005+ "fold_using_kelvin.yml": {
1006+ "errors": [
1007+ "fold_using_kelvin.yml (Line: 4, Col: 10): Unexpected value 'Komposite'"
1008+ ],
1009+ "inputs": [],
1010+ "outputs": [],
1011+ "runs": {
1012+ "steps": 0
1013+ }
1014+ },
866 "inputs_default_bad_context.yml": {1015 "inputs_default_bad_context.yml": {
867 "errors": [1016 "errors": [
868 "inputs_default_bad_context.yml (Line: 5, Col: 14): Unrecognized named-value: 'inputs'"1017 "inputs_default_bad_context.yml (Line: 5, Col: 14): Unrecognized named-value: 'inputs'"
@@ -991,6 +1140,355 @@
991 "steps": 01140 "steps": 0
992 }1141 }
993 },1142 },
1143+ "int32_00.yml": {
1144+ "errors": [],
1145+ "name": "A",
1146+ "description": "D",
1147+ "inputs": [
1148+ {
1149+ "id": "a",
1150+ "default": "2147483647"
1151+ }
1152+ ],
1153+ "outputs": [],
1154+ "runs": {
1155+ "using": "node20",
1156+ "main": "m.js",
1157+ "steps": 0
1158+ }
1159+ },
1160+ "int32_01.yml": {
1161+ "errors": [],
1162+ "name": "A",
1163+ "description": "D",
1164+ "inputs": [
1165+ {
1166+ "id": "a",
1167+ "default": "2147483648"
1168+ }
1169+ ],
1170+ "outputs": [],
1171+ "runs": {
1172+ "using": "node20",
1173+ "main": "m.js",
1174+ "steps": 0
1175+ }
1176+ },
1177+ "int32_02.yml": {
1178+ "errors": [],
1179+ "name": "A",
1180+ "description": "D",
1181+ "inputs": [
1182+ {
1183+ "id": "a",
1184+ "default": "4294967295"
1185+ }
1186+ ],
1187+ "outputs": [],
1188+ "runs": {
1189+ "using": "node20",
1190+ "main": "m.js",
1191+ "steps": 0
1192+ }
1193+ },
1194+ "int32_03.yml": {
1195+ "errors": [],
1196+ "name": "A",
1197+ "description": "D",
1198+ "inputs": [
1199+ {
1200+ "id": "a",
1201+ "default": "4294967296"
1202+ }
1203+ ],
1204+ "outputs": [],
1205+ "runs": {
1206+ "using": "node20",
1207+ "main": "m.js",
1208+ "steps": 0
1209+ }
1210+ },
1211+ "int32_04.yml": {
1212+ "errors": [],
1213+ "name": "A",
1214+ "description": "D",
1215+ "inputs": [
1216+ {
1217+ "id": "a",
1218+ "default": "2147483647"
1219+ }
1220+ ],
1221+ "outputs": [],
1222+ "runs": {
1223+ "using": "node20",
1224+ "main": "m.js",
1225+ "steps": 0
1226+ }
1227+ },
1228+ "int32_05.yml": {
1229+ "errors": [],
1230+ "name": "A",
1231+ "description": "D",
1232+ "inputs": [
1233+ {
1234+ "id": "a",
1235+ "default": "2147483648"
1236+ }
1237+ ],
1238+ "outputs": [],
1239+ "runs": {
1240+ "using": "node20",
1241+ "main": "m.js",
1242+ "steps": 0
1243+ }
1244+ },
1245+ "int32_06.yml": {
1246+ "errors": [],
1247+ "name": "A",
1248+ "description": "D",
1249+ "inputs": [
1250+ {
1251+ "id": "a",
1252+ "default": "4294967295"
1253+ }
1254+ ],
1255+ "outputs": [],
1256+ "runs": {
1257+ "using": "node20",
1258+ "main": "m.js",
1259+ "steps": 0
1260+ }
1261+ },
1262+ "int32_07.yml": {
1263+ "errors": [],
1264+ "name": "A",
1265+ "description": "D",
1266+ "inputs": [
1267+ {
1268+ "id": "a",
1269+ "default": "4294967296"
1270+ }
1271+ ],
1272+ "outputs": [],
1273+ "runs": {
1274+ "using": "node20",
1275+ "main": "m.js",
1276+ "steps": 0
1277+ }
1278+ },
1279+ "int32_08.yml": {
1280+ "errors": [],
1281+ "name": "A",
1282+ "description": "D",
1283+ "inputs": [
1284+ {
1285+ "id": "a",
1286+ "default": "4294967295"
1287+ }
1288+ ],
1289+ "outputs": [],
1290+ "runs": {
1291+ "using": "node20",
1292+ "main": "m.js",
1293+ "steps": 0
1294+ }
1295+ },
1296+ "int32_09.yml": {
1297+ "errors": [],
1298+ "name": "A",
1299+ "description": "D",
1300+ "inputs": [
1301+ {
1302+ "id": "a",
1303+ "default": "2147483648"
1304+ }
1305+ ],
1306+ "outputs": [],
1307+ "runs": {
1308+ "using": "node20",
1309+ "main": "m.js",
1310+ "steps": 0
1311+ }
1312+ },
1313+ "int32_10.yml": {
1314+ "errors": [],
1315+ "name": "A",
1316+ "description": "D",
1317+ "inputs": [
1318+ {
1319+ "id": "a",
1320+ "default": "4294967296"
1321+ }
1322+ ],
1323+ "outputs": [],
1324+ "runs": {
1325+ "using": "node20",
1326+ "main": "m.js",
1327+ "steps": 0
1328+ }
1329+ },
1330+ "int32_11.yml": {
1331+ "errors": [],
1332+ "name": "A",
1333+ "description": "D",
1334+ "inputs": [
1335+ {
1336+ "id": "a",
1337+ "default": "2147483648"
1338+ }
1339+ ],
1340+ "outputs": [],
1341+ "runs": {
1342+ "using": "node20",
1343+ "main": "m.js",
1344+ "steps": 0
1345+ }
1346+ },
1347+ "int32_12.yml": {
1348+ "errors": [],
1349+ "name": "A",
1350+ "description": "D",
1351+ "inputs": [
1352+ {
1353+ "id": "a",
1354+ "default": "4294967296"
1355+ }
1356+ ],
1357+ "outputs": [],
1358+ "runs": {
1359+ "using": "node20",
1360+ "main": "m.js",
1361+ "steps": 0
1362+ }
1363+ },
1364+ "int32_13.yml": {
1365+ "errors": [],
1366+ "name": "A",
1367+ "description": "D",
1368+ "inputs": [
1369+ {
1370+ "id": "a",
1371+ "default": "12"
1372+ }
1373+ ],
1374+ "outputs": [],
1375+ "runs": {
1376+ "using": "node20",
1377+ "main": "m.js",
1378+ "steps": 0
1379+ }
1380+ },
1381+ "int32_14.yml": {
1382+ "errors": [],
1383+ "name": "A",
1384+ "description": "D",
1385+ "inputs": [
1386+ {
1387+ "id": "a",
1388+ "default": "0x10"
1389+ }
1390+ ],
1391+ "outputs": [],
1392+ "runs": {
1393+ "using": "node20",
1394+ "main": "m.js",
1395+ "steps": 0
1396+ }
1397+ },
1398+ "int32_15.yml": {
1399+ "errors": [],
1400+ "name": "A",
1401+ "description": "D",
1402+ "inputs": [
1403+ {
1404+ "id": "a",
1405+ "default": "0"
1406+ }
1407+ ],
1408+ "outputs": [],
1409+ "runs": {
1410+ "using": "node20",
1411+ "main": "m.js",
1412+ "steps": 0
1413+ }
1414+ },
1415+ "int32_16.yml": {
1416+ "errors": [],
1417+ "name": "A",
1418+ "description": "D",
1419+ "inputs": [
1420+ {
1421+ "id": "a",
1422+ "default": "3735928559"
1423+ }
1424+ ],
1425+ "outputs": [],
1426+ "runs": {
1427+ "using": "node20",
1428+ "main": "m.js",
1429+ "steps": 0
1430+ }
1431+ },
1432+ "int32_key.yml": {
1433+ "errors": [
1434+ "int32_key.yml: raw.indexOf is not a function"
1435+ ]
1436+ },
1437+ "key_bool_dup.yml": {
1438+ "errors": [
1439+ "key_bool_dup.yml: raw.indexOf is not a function"
1440+ ]
1441+ },
1442+ "key_float_dup.yml": {
1443+ "errors": [
1444+ "key_float_dup.yml: raw.indexOf is not a function"
1445+ ]
1446+ },
1447+ "key_hex_dup.yml": {
1448+ "errors": [
1449+ "key_hex_dup.yml: raw.indexOf is not a function"
1450+ ]
1451+ },
1452+ "key_hex_input.yml": {
1453+ "errors": [
1454+ "key_hex_input.yml: raw.indexOf is not a function"
1455+ ]
1456+ },
1457+ "key_null_env.yml": {
1458+ "errors": [
1459+ "key_null_env.yml (Line: 7, Col: 5): Unexpected value 'null'"
1460+ ],
1461+ "inputs": [],
1462+ "outputs": [],
1463+ "runs": {
1464+ "steps": 0
1465+ }
1466+ },
1467+ "key_null_inputs.yml": {
1468+ "errors": [
1469+ "key_null_inputs.yml (Line: 4, Col: 3): Unexpected value 'null'"
1470+ ],
1471+ "inputs": [],
1472+ "outputs": [],
1473+ "runs": {
1474+ "steps": 0
1475+ }
1476+ },
1477+ "key_null_top.yml": {
1478+ "errors": [
1479+ "key_null_top.yml (Line: 1, Col: 1): Unexpected value 'null'"
1480+ ],
1481+ "inputs": [],
1482+ "outputs": [],
1483+ "runs": {
1484+ "steps": 0
1485+ }
1486+ },
1487+ "key_number_runs.yml": {
1488+ "errors": [
1489+ "key_number_runs.yml: raw.indexOf is not a function"
1490+ ]
1491+ },
994 "ls_parser_accepts_valid_context_in_pre_if.yml": {1492 "ls_parser_accepts_valid_context_in_pre_if.yml": {
995 "errors": [],1493 "errors": [],
996 "name": "Node Action",1494 "name": "Node Action",
M action/util.go +9 -3
@@ -7,12 +7,15 @@ import (
77 "strings"
88 "unicode"
99
10+ "bnema.dev/ermite-actions/expr"
1011 "bnema.dev/ermite-actions/template"
1112 )
1213
13-// asciiEqualFold is String.Equals(a, b, OrdinalIgnoreCase) for the strings the
14-// manifest compares: .NET's simple case mapping folds no non-ASCII character
15-// into ASCII, so only A-Z and a-z fold.
14+// asciiEqualFold is String.Equals(a, b, OrdinalIgnoreCase) when b is an ASCII
15+// literal ("docker", "default"): .NET's simple case mapping folds no non-ASCII
16+// character into an ASCII one, so only A-Z and a-z can match. It is wrong for
17+// two arbitrary strings ("é" and "É" are equal under OrdinalIgnoreCase); use
18+// ordinalEqual for those.
1619 func asciiEqualFold(a, b string) bool {
1720 if len(a) != len(b) {
1821 return false
@@ -125,3 +128,6 @@ func assertScalar(t template.Token, desc string) template.Token {
125128 func trimSpaceJS(s string) string {
126129 return strings.TrimFunc(s, func(r rune) bool { return unicode.IsSpace(r) || r == '\ufeff' })
127130 }
131+
132+// ordinalEqual is String.Equals(a, b, StringComparison.OrdinalIgnoreCase).
133+func ordinalEqual(a, b string) bool { return expr.OrdinalFold(a) == expr.OrdinalFold(b) }
@@ -7,12 +7,15 @@ import (
7 "strings"7 "strings"
8 "unicode"8 "unicode"
9 9
10+ "bnema.dev/ermite-actions/expr"
10 "bnema.dev/ermite-actions/template"11 "bnema.dev/ermite-actions/template"
11 )12 )
12 13
13-// asciiEqualFold is String.Equals(a, b, OrdinalIgnoreCase) for the strings the14+// asciiEqualFold is String.Equals(a, b, OrdinalIgnoreCase) when b is an ASCII
14-// manifest compares: .NET's simple case mapping folds no non-ASCII character15+// literal ("docker", "default"): .NET's simple case mapping folds no non-ASCII
15-// into ASCII, so only A-Z and a-z fold.16+// character into an ASCII one, so only A-Z and a-z can match. It is wrong for
17+// two arbitrary strings ("é" and "É" are equal under OrdinalIgnoreCase); use
18+// ordinalEqual for those.
16 func asciiEqualFold(a, b string) bool {19 func asciiEqualFold(a, b string) bool {
17 if len(a) != len(b) {20 if len(a) != len(b) {
18 return false21 return false
@@ -125,3 +128,6 @@ func assertScalar(t template.Token, desc string) template.Token {
125 func trimSpaceJS(s string) string {128 func trimSpaceJS(s string) string {
126 return strings.TrimFunc(s, func(r rune) bool { return unicode.IsSpace(r) || r == '\ufeff' })129 return strings.TrimFunc(s, func(r rune) bool { return unicode.IsSpace(r) || r == '\ufeff' })
127 }130 }
131+
132+// ordinalEqual is String.Equals(a, b, StringComparison.OrdinalIgnoreCase).
133+func ordinalEqual(a, b string) bool { return expr.OrdinalFold(a) == expr.OrdinalFold(b) }
M expr/ordinal.go +8 -0
@@ -62,6 +62,14 @@ func ordinalFold(s string) string {
6262 return b.String()
6363 }
6464
65+// OrdinalFold returns s folded the way .NET's OrdinalIgnoreCase compares
66+// strings (the runner's HashSet and Dictionary keys): every code point is
67+// replaced by its simple upper-case form from a table generated from the
68+// runner's own behaviour. Non-ASCII characters never fold into ASCII ones
69+// ("ſ" and the Kelvin sign stay themselves), unlike JavaScript's toUpperCase.
70+// Two strings are equal under OrdinalIgnoreCase iff their folds are equal.
71+func OrdinalFold(s string) string { return ordinalFold(s) }
72+
6573 // ordinalEqual is String.Equals(a, b, OrdinalIgnoreCase).
6674 func ordinalEqual(a, b string) bool { return ordinalFold(a) == ordinalFold(b) }
6775
@@ -62,6 +62,14 @@ func ordinalFold(s string) string {
62 return b.String()62 return b.String()
63 }63 }
64 64
65+// OrdinalFold returns s folded the way .NET's OrdinalIgnoreCase compares
66+// strings (the runner's HashSet and Dictionary keys): every code point is
67+// replaced by its simple upper-case form from a table generated from the
68+// runner's own behaviour. Non-ASCII characters never fold into ASCII ones
69+// ("ſ" and the Kelvin sign stay themselves), unlike JavaScript's toUpperCase.
70+// Two strings are equal under OrdinalIgnoreCase iff their folds are equal.
71+func OrdinalFold(s string) string { return ordinalFold(s) }
72+
65 // ordinalEqual is String.Equals(a, b, OrdinalIgnoreCase).73 // ordinalEqual is String.Equals(a, b, OrdinalIgnoreCase).
66 func ordinalEqual(a, b string) bool { return ordinalFold(a) == ordinalFold(b) }74 func ordinalEqual(a, b string) bool { return ordinalFold(a) == ordinalFold(b) }
67 75
M template/reader.go +15 -3
@@ -6,6 +6,8 @@ import (
66 "fmt"
77 "sort"
88 "strings"
9+
10+ "bnema.dev/ermite-actions/expr"
911 )
1012
1113 // ReadYAML parses a YAML document and reads it as a template of the schema
@@ -89,6 +91,16 @@ func (r *reader) text(t Token) string {
8991 return t.String()
9092 }
9193
94+// foldKey is the form of a key under which duplicates are detected: the
95+// reference upper-cases like JavaScript, the runner compares keys with
96+// .NET's OrdinalIgnoreCase.
97+func (r *reader) foldKey(s string) string {
98+ if r.ctx.RunnerYAML {
99+ return expr.OrdinalFold(s)
100+ }
101+ return strings.ToUpper(s)
102+}
103+
92104 func (r *reader) leave() {
93105 if r.ctx.MaxDepth > 0 {
94106 r.depth--
@@ -223,7 +235,7 @@ func (r *reader) mappingWithProperties(n *rnode, m *Mapping, def *DefinitionInfo
223235 nextKey = &String{tokenBase: *keyScalar.base(), Value: r.text(keyScalar)}
224236 }
225237 if nextKey.Value != "" {
226- up := strings.ToUpper(nextKey.Value)
238+ up := r.foldKey(nextKey.Value)
227239 if upperKeys[up] {
228240 r.ctx.Errorf(nextKey, "'%s' is already defined", nextKey.Value)
229241 r.skip(val)
@@ -278,7 +290,7 @@ func (r *reader) mappingWithProperties(n *rnode, m *Mapping, def *DefinitionInfo
278290 r.ctx.Errorf(m, "There's not enough info to determine what you meant. Add one of these properties: %s", strings.Join(props, ", "))
279291 case len(defs) == 1 && !hasExpressionKey:
280292 for _, name := range defs[0].PropertyNames {
281- if defs[0].Properties[name].Required && !upperKeys[strings.ToUpper(name)] {
293+ if defs[0].Properties[name].Required && !upperKeys[r.foldKey(name)] {
282294 r.ctx.Errorf(m, "Required property is missing: %s", name)
283295 }
284296 }
@@ -310,7 +322,7 @@ func (r *reader) mappingAllLoose(n *rnode, m *Mapping, def, keyDef, valDef *Defi
310322 nextKey = &String{tokenBase: *keyScalar.base(), Value: r.text(keyScalar)}
311323 }
312324 if nextKey.Value != "" {
313- up := strings.ToUpper(nextKey.Value)
325+ up := r.foldKey(nextKey.Value)
314326 if upperKeys[up] {
315327 r.ctx.Errorf(nextKey, "'%s' is already defined", nextKey.Value)
316328 r.skip(val)
@@ -6,6 +6,8 @@ import (
6 "fmt"6 "fmt"
7 "sort"7 "sort"
8 "strings"8 "strings"
9+
10+ "bnema.dev/ermite-actions/expr"
9 )11 )
10 12
11 // ReadYAML parses a YAML document and reads it as a template of the schema13 // ReadYAML parses a YAML document and reads it as a template of the schema
@@ -89,6 +91,16 @@ func (r *reader) text(t Token) string {
89 return t.String()91 return t.String()
90 }92 }
91 93
94+// foldKey is the form of a key under which duplicates are detected: the
95+// reference upper-cases like JavaScript, the runner compares keys with
96+// .NET's OrdinalIgnoreCase.
97+func (r *reader) foldKey(s string) string {
98+ if r.ctx.RunnerYAML {
99+ return expr.OrdinalFold(s)
100+ }
101+ return strings.ToUpper(s)
102+}
103+
92 func (r *reader) leave() {104 func (r *reader) leave() {
93 if r.ctx.MaxDepth > 0 {105 if r.ctx.MaxDepth > 0 {
94 r.depth--106 r.depth--
@@ -223,7 +235,7 @@ func (r *reader) mappingWithProperties(n *rnode, m *Mapping, def *DefinitionInfo
223 nextKey = &String{tokenBase: *keyScalar.base(), Value: r.text(keyScalar)}235 nextKey = &String{tokenBase: *keyScalar.base(), Value: r.text(keyScalar)}
224 }236 }
225 if nextKey.Value != "" {237 if nextKey.Value != "" {
226- up := strings.ToUpper(nextKey.Value)238+ up := r.foldKey(nextKey.Value)
227 if upperKeys[up] {239 if upperKeys[up] {
228 r.ctx.Errorf(nextKey, "'%s' is already defined", nextKey.Value)240 r.ctx.Errorf(nextKey, "'%s' is already defined", nextKey.Value)
229 r.skip(val)241 r.skip(val)
@@ -278,7 +290,7 @@ func (r *reader) mappingWithProperties(n *rnode, m *Mapping, def *DefinitionInfo
278 r.ctx.Errorf(m, "There's not enough info to determine what you meant. Add one of these properties: %s", strings.Join(props, ", "))290 r.ctx.Errorf(m, "There's not enough info to determine what you meant. Add one of these properties: %s", strings.Join(props, ", "))
279 case len(defs) == 1 && !hasExpressionKey:291 case len(defs) == 1 && !hasExpressionKey:
280 for _, name := range defs[0].PropertyNames {292 for _, name := range defs[0].PropertyNames {
281- if defs[0].Properties[name].Required && !upperKeys[strings.ToUpper(name)] {293+ if defs[0].Properties[name].Required && !upperKeys[r.foldKey(name)] {
282 r.ctx.Errorf(m, "Required property is missing: %s", name)294 r.ctx.Errorf(m, "Required property is missing: %s", name)
283 }295 }
284 }296 }
@@ -310,7 +322,7 @@ func (r *reader) mappingAllLoose(n *rnode, m *Mapping, def, keyDef, valDef *Defi
310 nextKey = &String{tokenBase: *keyScalar.base(), Value: r.text(keyScalar)}322 nextKey = &String{tokenBase: *keyScalar.base(), Value: r.text(keyScalar)}
311 }323 }
312 if nextKey.Value != "" {324 if nextKey.Value != "" {
313- up := strings.ToUpper(nextKey.Value)325+ up := r.foldKey(nextKey.Value)
314 if upperKeys[up] {326 if upperKeys[up] {
315 r.ctx.Errorf(nextKey, "'%s' is already defined", nextKey.Value)327 r.ctx.Errorf(nextKey, "'%s' is already defined", nextKey.Value)
316 r.skip(val)328 r.skip(val)
M template/yaml.go +41 -25
@@ -204,11 +204,13 @@ func (b *yamlBuilder) build1(n *yaml.Node, asKey bool) *rnode {
204204 return r
205205 case yaml.ScalarNode:
206206 r := &rnode{kind: rLiteral, pos: pos}
207- if asKey {
207+ if asKey && !b.runnerYAML {
208208 // Keys are always strings, whatever they look like.
209209 r.lit = NewString(o, n.Value)
210210 } else {
211- r.lit = resolveScalar(o, n)
211+ // The runner's YAML reader resolves a key like a value: "~" is
212+ // null, "0x10" is 16, "TRUE" is true.
213+ r.lit = resolveScalar(o, n, b.runnerYAML)
212214 }
213215 r.quoted = n.Style&(yaml.DoubleQuotedStyle|yaml.SingleQuotedStyle) != 0
214216 r.block = n.Style&(yaml.LiteralStyle|yaml.FoldedStyle) != 0
@@ -225,8 +227,8 @@ func runnerYAMLError(n *yaml.Node) string {
225227 return fmt.Sprintf("Anchors are not currently supported. Remove the anchor '%s'", n.Anchor)
226228 }
227229 if n.Kind == yaml.ScalarNode && n.Style&(yaml.TaggedStyle|yaml.DoubleQuotedStyle|yaml.SingleQuotedStyle|yaml.LiteralStyle|yaml.FoldedStyle) == 0 {
228- if msg := runnerIntegerError(n); msg != "" {
229- return msg
230+ if !fitsInt32(n.Value) {
231+ return fmt.Sprintf("The value '%s' on line %d and column %d is invalid for the type ''", n.Value, n.Line, n.Column)
230232 }
231233 }
232234 if n.Kind != yaml.ScalarNode || n.Style&yaml.TaggedStyle == 0 {
@@ -257,7 +259,7 @@ func runnerYAMLError(n *yaml.Node) string {
257259 default:
258260 return fmt.Sprintf("Unexpected tag '%s'", tag)
259261 }
260- t := resolvePlain(Origin{}, n.Value)
262+ t := resolvePlain(Origin{}, n.Value, true)
261263 ok := false
262264 switch tag {
263265 case yamlTag + "bool":
@@ -265,9 +267,10 @@ func runnerYAMLError(n *yaml.Node) string {
265267 case yamlTag + "null":
266268 ok = t.Kind() == KindNull
267269 case yamlTag + "float":
268- ok = t.Kind() == KindNumber
270+ // MatchFloat knows no 0x or 0o form.
271+ ok = t.Kind() == KindNumber && !reHex.MatchString(n.Value) && !reOct.MatchString(n.Value)
269272 case yamlTag + "int":
270- ok = t.Kind() == KindNumber && (reInt.MatchString(n.Value) || reOct.MatchString(n.Value) || reHex.MatchString(n.Value))
273+ ok = t.Kind() == KindNumber && (reInt.MatchString(n.Value) || reOct.MatchString(n.Value) || reHex.MatchString(n.Value)) && fitsInt32(n.Value)
271274 }
272275 if !ok {
273276 return fmt.Sprintf("The value '%s' on line %d and column %d is invalid for the type '%s'", n.Value, n.Line, n.Column, tag)
@@ -275,46 +278,50 @@ func runnerYAMLError(n *yaml.Node) string {
275278 return ""
276279 }
277280
278-// runnerIntegerError is the runner's refusal of a plain 0x or 0o integer that
279-// does not fit 32 bits (Int32.TryParse with AllowHexSpecifier, which accepts up
280-// to FFFFFFFF as a negative number, and Convert.ToInt32(s, 8)). The tag is
281-// empty in the message, as the plain scalar has none.
282-func runnerIntegerError(n *yaml.Node) string {
283- v := n.Value
284- var limit uint64 = 1<<32 - 1
285- var base int
281+// fitsInt32 reports whether a plain 0x or 0o integer is accepted by the
282+// runner's reader: Int32.TryParse with AllowHexSpecifier (up to FFFFFFFF, read
283+// as a negative number above 7FFFFFFF) and Convert.ToInt32(s, 8) (up to
284+// 37777777777). Other values always fit.
285+func fitsInt32(v string) bool {
286+ var base uint64
286287 switch {
287288 case reHex.MatchString(v):
288289 base = 16
289290 case reOct.MatchString(v):
290291 base = 8
291292 default:
292- return ""
293+ return true
293294 }
295+ _, ok := parseUint32(v[2:], base)
296+ return ok
297+}
298+
299+// parseUint32 reads digits in base 8 or 16, reporting false past 32 bits.
300+func parseUint32(digits string, base uint64) (uint32, bool) {
294301 var acc uint64
295- for _, c := range strings.ToLower(v[2:]) {
302+ for _, c := range strings.ToLower(digits) {
296303 d := uint64(c - '0')
297304 if c >= 'a' {
298305 d = uint64(c-'a') + 10
299306 }
300- acc = acc*uint64(base) + d
301- if acc > limit {
302- return fmt.Sprintf("The value '%s' on line %d and column %d is invalid for the type ''", v, n.Line, n.Column)
307+ acc = acc*base + d
308+ if acc > 1<<32-1 {
309+ return 0, false
303310 }
304311 }
305- return ""
312+ return uint32(acc), true
306313 }
307314
308315 // resolveScalar gives a scalar its type the way the YAML 1.2 core schema of
309316 // the JavaScript yaml library does: only plain scalars are resolved, and an
310317 // explicit !!tag overrides the guess.
311-func resolveScalar(o Origin, n *yaml.Node) Token {
318+func resolveScalar(o Origin, n *yaml.Node, runner bool) Token {
312319 if n.Style&yaml.TaggedStyle != 0 {
313320 switch n.ShortTag() {
314321 case "!!str":
315322 return NewString(o, n.Value)
316323 case "!!null", "!!bool", "!!int", "!!float":
317- if t := resolvePlain(o, n.Value); t.Kind() != KindString {
324+ if t := resolvePlain(o, n.Value, runner); t.Kind() != KindString {
318325 return t
319326 }
320327 if n.ShortTag() == "!!null" && n.Value == "" {
@@ -326,7 +333,7 @@ func resolveScalar(o Origin, n *yaml.Node) Token {
326333 if n.Style&(yaml.DoubleQuotedStyle|yaml.SingleQuotedStyle|yaml.LiteralStyle|yaml.FoldedStyle) != 0 {
327334 return NewString(o, n.Value)
328335 }
329- return resolvePlain(o, n.Value)
336+ return resolvePlain(o, n.Value, runner)
330337 }
331338
332339 var (
@@ -338,7 +345,10 @@ var (
338345 reNaN = regexp.MustCompile(`^\.(?:nan|NaN|NAN)$`)
339346 )
340347
341-func resolvePlain(o Origin, s string) Token {
348+// resolvePlain gives a plain scalar its type. In runner mode a 0x or 0o
349+// integer is the 32-bit two's complement value the runner reads: 0xFFFFFFFF
350+// is -1 and 0x80000000 is -2147483648.
351+func resolvePlain(o Origin, s string, runner bool) Token {
342352 switch s {
343353 case "", "~", "null", "Null", "NULL":
344354 return NewNull(o)
@@ -352,8 +362,14 @@ func resolvePlain(o Origin, s string) Token {
352362 f, _ := strconv.ParseFloat(s, 64)
353363 return NewNumber(o, f)
354364 case reOct.MatchString(s):
365+ if u, ok := parseUint32(s[2:], 8); runner && ok {
366+ return NewNumber(o, float64(int32(u)))
367+ }
355368 return NewNumber(o, parseBase(s[2:], 8))
356369 case reHex.MatchString(s):
370+ if u, ok := parseUint32(s[2:], 16); runner && ok {
371+ return NewNumber(o, float64(int32(u)))
372+ }
357373 return NewNumber(o, parseBase(s[2:], 16))
358374 case reFloat.MatchString(s):
359375 f, _ := strconv.ParseFloat(s, 64)
@@ -204,11 +204,13 @@ func (b *yamlBuilder) build1(n *yaml.Node, asKey bool) *rnode {
204 return r204 return r
205 case yaml.ScalarNode:205 case yaml.ScalarNode:
206 r := &rnode{kind: rLiteral, pos: pos}206 r := &rnode{kind: rLiteral, pos: pos}
207- if asKey {207+ if asKey && !b.runnerYAML {
208 // Keys are always strings, whatever they look like.208 // Keys are always strings, whatever they look like.
209 r.lit = NewString(o, n.Value)209 r.lit = NewString(o, n.Value)
210 } else {210 } else {
211- r.lit = resolveScalar(o, n)211+ // The runner's YAML reader resolves a key like a value: "~" is
212+ // null, "0x10" is 16, "TRUE" is true.
213+ r.lit = resolveScalar(o, n, b.runnerYAML)
212 }214 }
213 r.quoted = n.Style&(yaml.DoubleQuotedStyle|yaml.SingleQuotedStyle) != 0215 r.quoted = n.Style&(yaml.DoubleQuotedStyle|yaml.SingleQuotedStyle) != 0
214 r.block = n.Style&(yaml.LiteralStyle|yaml.FoldedStyle) != 0216 r.block = n.Style&(yaml.LiteralStyle|yaml.FoldedStyle) != 0
@@ -225,8 +227,8 @@ func runnerYAMLError(n *yaml.Node) string {
225 return fmt.Sprintf("Anchors are not currently supported. Remove the anchor '%s'", n.Anchor)227 return fmt.Sprintf("Anchors are not currently supported. Remove the anchor '%s'", n.Anchor)
226 }228 }
227 if n.Kind == yaml.ScalarNode && n.Style&(yaml.TaggedStyle|yaml.DoubleQuotedStyle|yaml.SingleQuotedStyle|yaml.LiteralStyle|yaml.FoldedStyle) == 0 {229 if n.Kind == yaml.ScalarNode && n.Style&(yaml.TaggedStyle|yaml.DoubleQuotedStyle|yaml.SingleQuotedStyle|yaml.LiteralStyle|yaml.FoldedStyle) == 0 {
228- if msg := runnerIntegerError(n); msg != "" {230+ if !fitsInt32(n.Value) {
229- return msg231+ return fmt.Sprintf("The value '%s' on line %d and column %d is invalid for the type ''", n.Value, n.Line, n.Column)
230 }232 }
231 }233 }
232 if n.Kind != yaml.ScalarNode || n.Style&yaml.TaggedStyle == 0 {234 if n.Kind != yaml.ScalarNode || n.Style&yaml.TaggedStyle == 0 {
@@ -257,7 +259,7 @@ func runnerYAMLError(n *yaml.Node) string {
257 default:259 default:
258 return fmt.Sprintf("Unexpected tag '%s'", tag)260 return fmt.Sprintf("Unexpected tag '%s'", tag)
259 }261 }
260- t := resolvePlain(Origin{}, n.Value)262+ t := resolvePlain(Origin{}, n.Value, true)
261 ok := false263 ok := false
262 switch tag {264 switch tag {
263 case yamlTag + "bool":265 case yamlTag + "bool":
@@ -265,9 +267,10 @@ func runnerYAMLError(n *yaml.Node) string {
265 case yamlTag + "null":267 case yamlTag + "null":
266 ok = t.Kind() == KindNull268 ok = t.Kind() == KindNull
267 case yamlTag + "float":269 case yamlTag + "float":
268- ok = t.Kind() == KindNumber270+ // MatchFloat knows no 0x or 0o form.
271+ ok = t.Kind() == KindNumber && !reHex.MatchString(n.Value) && !reOct.MatchString(n.Value)
269 case yamlTag + "int":272 case yamlTag + "int":
270- ok = t.Kind() == KindNumber && (reInt.MatchString(n.Value) || reOct.MatchString(n.Value) || reHex.MatchString(n.Value))273+ ok = t.Kind() == KindNumber && (reInt.MatchString(n.Value) || reOct.MatchString(n.Value) || reHex.MatchString(n.Value)) && fitsInt32(n.Value)
271 }274 }
272 if !ok {275 if !ok {
273 return fmt.Sprintf("The value '%s' on line %d and column %d is invalid for the type '%s'", n.Value, n.Line, n.Column, tag)276 return fmt.Sprintf("The value '%s' on line %d and column %d is invalid for the type '%s'", n.Value, n.Line, n.Column, tag)
@@ -275,46 +278,50 @@ func runnerYAMLError(n *yaml.Node) string {
275 return ""278 return ""
276 }279 }
277 280
278-// runnerIntegerError is the runner's refusal of a plain 0x or 0o integer that281+// fitsInt32 reports whether a plain 0x or 0o integer is accepted by the
279-// does not fit 32 bits (Int32.TryParse with AllowHexSpecifier, which accepts up282+// runner's reader: Int32.TryParse with AllowHexSpecifier (up to FFFFFFFF, read
280-// to FFFFFFFF as a negative number, and Convert.ToInt32(s, 8)). The tag is283+// as a negative number above 7FFFFFFF) and Convert.ToInt32(s, 8) (up to
281-// empty in the message, as the plain scalar has none.284+// 37777777777). Other values always fit.
282-func runnerIntegerError(n *yaml.Node) string {285+func fitsInt32(v string) bool {
283- v := n.Value286+ var base uint64
284- var limit uint64 = 1<<32 - 1
285- var base int
286 switch {287 switch {
287 case reHex.MatchString(v):288 case reHex.MatchString(v):
288 base = 16289 base = 16
289 case reOct.MatchString(v):290 case reOct.MatchString(v):
290 base = 8291 base = 8
291 default:292 default:
292- return ""293+ return true
293 }294 }
295+ _, ok := parseUint32(v[2:], base)
296+ return ok
297+}
298+
299+// parseUint32 reads digits in base 8 or 16, reporting false past 32 bits.
300+func parseUint32(digits string, base uint64) (uint32, bool) {
294 var acc uint64301 var acc uint64
295- for _, c := range strings.ToLower(v[2:]) {302+ for _, c := range strings.ToLower(digits) {
296 d := uint64(c - '0')303 d := uint64(c - '0')
297 if c >= 'a' {304 if c >= 'a' {
298 d = uint64(c-'a') + 10305 d = uint64(c-'a') + 10
299 }306 }
300- acc = acc*uint64(base) + d307+ acc = acc*base + d
301- if acc > limit {308+ if acc > 1<<32-1 {
302- return fmt.Sprintf("The value '%s' on line %d and column %d is invalid for the type ''", v, n.Line, n.Column)309+ return 0, false
303 }310 }
304 }311 }
305- return ""312+ return uint32(acc), true
306 }313 }
307 314
308 // resolveScalar gives a scalar its type the way the YAML 1.2 core schema of315 // resolveScalar gives a scalar its type the way the YAML 1.2 core schema of
309 // the JavaScript yaml library does: only plain scalars are resolved, and an316 // the JavaScript yaml library does: only plain scalars are resolved, and an
310 // explicit !!tag overrides the guess.317 // explicit !!tag overrides the guess.
311-func resolveScalar(o Origin, n *yaml.Node) Token {318+func resolveScalar(o Origin, n *yaml.Node, runner bool) Token {
312 if n.Style&yaml.TaggedStyle != 0 {319 if n.Style&yaml.TaggedStyle != 0 {
313 switch n.ShortTag() {320 switch n.ShortTag() {
314 case "!!str":321 case "!!str":
315 return NewString(o, n.Value)322 return NewString(o, n.Value)
316 case "!!null", "!!bool", "!!int", "!!float":323 case "!!null", "!!bool", "!!int", "!!float":
317- if t := resolvePlain(o, n.Value); t.Kind() != KindString {324+ if t := resolvePlain(o, n.Value, runner); t.Kind() != KindString {
318 return t325 return t
319 }326 }
320 if n.ShortTag() == "!!null" && n.Value == "" {327 if n.ShortTag() == "!!null" && n.Value == "" {
@@ -326,7 +333,7 @@ func resolveScalar(o Origin, n *yaml.Node) Token {
326 if n.Style&(yaml.DoubleQuotedStyle|yaml.SingleQuotedStyle|yaml.LiteralStyle|yaml.FoldedStyle) != 0 {333 if n.Style&(yaml.DoubleQuotedStyle|yaml.SingleQuotedStyle|yaml.LiteralStyle|yaml.FoldedStyle) != 0 {
327 return NewString(o, n.Value)334 return NewString(o, n.Value)
328 }335 }
329- return resolvePlain(o, n.Value)336+ return resolvePlain(o, n.Value, runner)
330 }337 }
331 338
332 var (339 var (
@@ -338,7 +345,10 @@ var (
338 reNaN = regexp.MustCompile(`^\.(?:nan|NaN|NAN)$`)345 reNaN = regexp.MustCompile(`^\.(?:nan|NaN|NAN)$`)
339 )346 )
340 347
341-func resolvePlain(o Origin, s string) Token {348+// resolvePlain gives a plain scalar its type. In runner mode a 0x or 0o
349+// integer is the 32-bit two's complement value the runner reads: 0xFFFFFFFF
350+// is -1 and 0x80000000 is -2147483648.
351+func resolvePlain(o Origin, s string, runner bool) Token {
342 switch s {352 switch s {
343 case "", "~", "null", "Null", "NULL":353 case "", "~", "null", "Null", "NULL":
344 return NewNull(o)354 return NewNull(o)
@@ -352,8 +362,14 @@ func resolvePlain(o Origin, s string) Token {
352 f, _ := strconv.ParseFloat(s, 64)362 f, _ := strconv.ParseFloat(s, 64)
353 return NewNumber(o, f)363 return NewNumber(o, f)
354 case reOct.MatchString(s):364 case reOct.MatchString(s):
365+ if u, ok := parseUint32(s[2:], 8); runner && ok {
366+ return NewNumber(o, float64(int32(u)))
367+ }
355 return NewNumber(o, parseBase(s[2:], 8))368 return NewNumber(o, parseBase(s[2:], 8))
356 case reHex.MatchString(s):369 case reHex.MatchString(s):
370+ if u, ok := parseUint32(s[2:], 16); runner && ok {
371+ return NewNumber(o, float64(int32(u)))
372+ }
357 return NewNumber(o, parseBase(s[2:], 16))373 return NewNumber(o, parseBase(s[2:], 16))
358 case reFloat.MatchString(s):374 case reFloat.MatchString(s):
359 f, _ := strconv.ParseFloat(s, 64)375 f, _ := strconv.ParseFloat(s, 64)

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 3

↑↓ moveenter openesc close