main 98594d0

PORTING.md RawHistoryFolder

Porting notes for package template

The package is a port of the template layer of @actions/workflow-parser 0.3.61 (MIT, GitHub, actions/languageservices): templates/ (tokens, reader, schema) and workflows/yaml-object-reader. The schema schema/workflow-v1.0.min.json is copied unmodified. The reference's own output is the specification: ../workflow/testdata/convert.json holds what it answers for 153 workflow files and workflow.TestConvertAgainstReference replays them (messages, line and column included).

The C# runner (ObjectTemplating) is what runs on github.com. It was not available. Nothing here has been checked against it.

Reference versions and regeneration

The answers in ../workflow/testdata/convert.json and testdata/scalars.json come from the versions pinned in ../gen/package.json and ../gen/package-lock.json: @actions/workflow-parser 0.3.61, @actions/expressions 0.3.61, yaml 2.8.3, cronstrue 2.61.0 (only imported by the parser's cron description helper, which is not used here). Run ../gen/regen.sh: it does an npm ci and rewrites both files; git diff must show nothing. The loader hook ../gen/register.mjs adds the with { type: "json" } import attribute that Node 22+ requires and the parser omits, so the packages run unmodified. The last check, on a clean npm ci, gave identical files.

Differences from the reference

  • YAML parser. The reference uses the JavaScript yaml library (YAML 1.2, core schema); this port uses go.yaml.in/yaml/v3 (a YAML 1.1/1.2 hybrid) and re-resolves plain scalars itself (yaml.go, resolveScalar) with the 1.2 core schema: yes/no/on/off are strings, 0o17 and 0x1F are numbers, .inf and .nan are numbers, 0b11, 1_000 and sexagesimal numbers are strings. Quoted, block and !!str scalars are strings. TestPlainScalarsAgainstReference checks 64 plain scalars (octal 017, 00, 1., .inf, -.nan, 0b11, 1_000, dates...) against the JavaScript library's answers (testdata/scalars.json). Not checked: tags other than !!str, !!binary, merge keys << (kept as an ordinary key).
  • YAML syntax errors have yaml.v3's wording and only a line number, and are reported as file.yml: message at line N. The reference's are file.yml: <message> at line N, column M:\n\n<excerpt>. Only the shape (one error, prefixed by the file name) is tested.
  • Multiple documents are an error, with the reference's message text.
  • Anchors and aliases are expanded like the reference does. Added: a limit of MaxNodes (200 000) nodes after expansion, because the reference lets a few kilobytes of nested aliases allocate gigabytes; a circular alias is an error (the reference silently drops it).
  • Positions of expressions in multi-line scalars. The reference computes a precise range for the expression inside a multi-line string; this port reports the position of the scalar, which is what the reference's error messages use too (checked on multiline_*, expr_multi). BasicExpression.Source is the value of the scalar, not the raw source text (so a block scalar's indentation is not in it).
  • File size. A document over MaxFileBytes (1 MiB) is refused before any parsing, with file.yml: The file is too large: N bytes, the limit is M bytes (our wording; the reference has no limit, GitHub has its own). TODO(verify with recording).
  • Error limit. Context keeps at most MaxErrors (1 000) errors.
  • Limits on evaluation. MaxEvalDepth (100) nested tokens; the result budget of package expr applies per expression.
  • No featureFlags. Background steps (background, wait, wait-all, cancel, parallel) are always disabled, which is the reference's default.
  • Duplicate keys are compared case-insensitively with ASCII/Unicode upper casing (strings.ToUpper), the reference uses toUpperCase.
  • Mapping keys that are collections (? [a] : b) are reported as Unexpected value ''; the reference reads undefined there.

Runner mode (package action)

Context has four options that only package action sets, to read an action.yml as the C# runner's loader does (action/PORTING.md lists what is checked against the runner's own code): MaxDepth (TemplateMemory's maxDepth, counting skipped values too), ErrorLimit (the runner keeps ten), RunnerYAML (anchors and aliases, tags other than !!bool/!!float/!!int/!!null, 32-bit limits of 0x/0o integers, a second document, an empty file and a collection used as a key all end the read with the runner's message; mapping keys are resolved like values, ~ giving an empty key and 0x10 the key 16; 0x/0o integers wrap as int32, 0xFFFFFFFF being -1; duplicate keys compare with .NET's OrdinalIgnoreCase, expr.OrdinalFold; a number read as a string is shown as .NET's G15, DotNetNumberString). Without them nothing changes. Error.Exception marks an error that is a .NET exception the runner reports without a position.

To check against the C# runner / recordings

  • A string with ${{ inside a non-expression place (name: of a reusable workflow...) and the Exactly 0 parameter(s)... wording.
  • Which contexts and functions each key may use: taken from the schema, which is the language service's, not necessarily the server's.
  • EvaluateBool/EvaluateNumber accept the strings "true"/"12". The C# TemplateEvaluator converts scalars the same way (assumed).
  • A mapping key expression that produces a non-scalar.
source
1# Porting notes for package template
2
3The package is a port of the template layer of `@actions/workflow-parser`
40.3.61 (MIT, GitHub, actions/languageservices): `templates/` (tokens, reader,
5schema) and `workflows/yaml-object-reader`. The schema
6`schema/workflow-v1.0.min.json` is copied unmodified. The reference's own
7output is the specification: `../workflow/testdata/convert.json` holds what it
8answers for 153 workflow files and `workflow.TestConvertAgainstReference`
9replays them (messages, line and column included).
10
11The C# runner (`ObjectTemplating`) is what runs on github.com. It was not
12available. Nothing here has been checked against it.
13
14## Reference versions and regeneration
15
16The answers in `../workflow/testdata/convert.json` and `testdata/scalars.json`
17come from the versions pinned in `../gen/package.json` and
18`../gen/package-lock.json`: `@actions/workflow-parser` 0.3.61,
19`@actions/expressions` 0.3.61, `yaml` 2.8.3, `cronstrue` 2.61.0 (only imported
20by the parser's cron description helper, which is not used here). Run
21`../gen/regen.sh`: it does an `npm ci` and rewrites both files; `git diff`
22must show nothing. The loader hook `../gen/register.mjs` adds the
23`with { type: "json" }` import attribute that Node 22+ requires and the
24parser omits, so the packages run unmodified. The last check, on a clean
25`npm ci`, gave identical files.
26
27## Differences from the reference
28
29- **YAML parser.** The reference uses the JavaScript `yaml` library (YAML 1.2,
30  core schema); this port uses `go.yaml.in/yaml/v3` (a YAML 1.1/1.2 hybrid) and
31  re-resolves plain scalars itself (`yaml.go`, `resolveScalar`) with the 1.2
32  core schema: `yes`/`no`/`on`/`off` are strings, `0o17` and `0x1F` are
33  numbers, `.inf` and `.nan` are numbers, `0b11`, `1_000` and sexagesimal
34  numbers are strings. Quoted, block and `!!str` scalars are strings.
35  `TestPlainScalarsAgainstReference` checks 64 plain scalars (octal `017`,
36  `00`, `1.`, `.inf`, `-.nan`, `0b11`, `1_000`, dates...) against the
37  JavaScript library's answers (`testdata/scalars.json`). Not checked: tags
38  other than `!!str`, `!!binary`, merge keys `<<` (kept as an ordinary key).
39- **YAML syntax errors** have yaml.v3's wording and only a line number, and are
40  reported as `file.yml: message at line N`. The reference's are
41  `file.yml: <message> at line N, column M:\n\n<excerpt>`. Only the shape
42  (one error, prefixed by the file name) is tested.
43- **Multiple documents** are an error, with the reference's message text.
44- **Anchors and aliases** are expanded like the reference does. Added: a limit
45  of `MaxNodes` (200 000) nodes after expansion, because the reference lets a
46  few kilobytes of nested aliases allocate gigabytes; a circular alias is an
47  error (the reference silently drops it).
48- **Positions of expressions in multi-line scalars.** The reference computes a
49  precise range for the expression inside a multi-line string; this port
50  reports the position of the scalar, which is what the reference's error
51  messages use too (checked on `multiline_*`, `expr_multi`).
52  `BasicExpression.Source` is the value of the scalar, not the raw source text
53  (so a block scalar's indentation is not in it).
54- **File size.** A document over `MaxFileBytes` (1 MiB) is refused before any
55  parsing, with `file.yml: The file is too large: N bytes, the limit is M
56  bytes` (our wording; the reference has no limit, GitHub has its own).
57  TODO(verify with recording).
58- **Error limit.** `Context` keeps at most `MaxErrors` (1 000) errors.
59- **Limits on evaluation.** `MaxEvalDepth` (100) nested tokens; the result
60  budget of package expr applies per expression.
61- **No `featureFlags`.** Background steps (`background`, `wait`, `wait-all`,
62  `cancel`, `parallel`) are always disabled, which is the reference's default.
63- **Duplicate keys** are compared case-insensitively with ASCII/Unicode upper
64  casing (`strings.ToUpper`), the reference uses `toUpperCase`.
65- Mapping keys that are collections (`? [a] : b`) are reported as
66  `Unexpected value ''`; the reference reads `undefined` there.
67
68## Runner mode (package action)
69
70`Context` has four options that only package action sets, to read an
71`action.yml` as the C# runner's loader does (`action/PORTING.md` lists what is
72checked against the runner's own code): `MaxDepth` (`TemplateMemory`'s
73`maxDepth`, counting skipped values too), `ErrorLimit` (the runner keeps ten),
74`RunnerYAML` (anchors and aliases, tags other than `!!bool/!!float/!!int/!!null`,
7532-bit limits of `0x`/`0o` integers, a second document, an empty file and a
76collection used as a key all end the read with the runner's message; mapping
77keys are resolved like values, `~` giving an empty key and `0x10` the key `16`;
78`0x`/`0o` integers wrap as int32, `0xFFFFFFFF` being -1; duplicate keys compare
79with .NET's OrdinalIgnoreCase, `expr.OrdinalFold`; a number read as a string is
80shown as .NET's `G15`, `DotNetNumberString`). Without them
81nothing changes. `Error.Exception` marks an error that is a .NET exception the
82runner reports without a position.
83
84## To check against the C# runner / recordings
85
86- [ ] A string with `${{` inside a non-expression place (`name:` of a
87      reusable workflow...) and the `Exactly 0 parameter(s)...` wording.
88- [ ] Which contexts and functions each key may use: taken from the schema,
89      which is the language service's, not necessarily the server's.
90- [ ] `EvaluateBool`/`EvaluateNumber` accept the strings `"true"`/`"12"`. The
91      C# `TemplateEvaluator` converts scalars the same way (assumed).
92- [ ] A mapping key expression that produces a non-scalar.

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