main 98594d0

convert_steps.go RawHistoryFolder

1// SPDX-License-Identifier: MIT
2
3package workflow
4
5import (
6	"strings"
7
8	"bnema.dev/ermite-actions/template"
9)
10
11// convertSteps is a port of convertSteps: steps that fail to convert are
12// dropped, ids written in the file are checked, and the others get a
13// generated id.
14func (c *converter) convertSteps(t template.Token) []*Step {
15	seq, ok := t.(*template.Sequence)
16	if !ok {
17		c.ctx.ErrorAt(t, "Invalid format for steps")
18		return nil
19	}
20	ids := newIDBuilder()
21	var result []*Step
22	for _, it := range seq.Items {
23		c.handle(seq, func() {
24			if s := c.convertStep(ids, it); s != nil {
25				result = append(result, s)
26			}
27		})
28	}
29	for _, s := range result {
30		if s.ID != "" {
31			continue
32		}
33		id := ""
34		if s.Uses != nil {
35			id = actionStepID(s.Uses.Value)
36		}
37		if id == "" {
38			id = "run"
39		}
40		ids.appendSegment("__" + id)
41		s.ID = ids.build()
42	}
43	return result
44}
45
46func (c *converter) convertStep(ids *idBuilder, t template.Token) *Step {
47	m := asMap(t, "steps item")
48	s := &Step{Pos: t.Pos()}
49	var uses *template.String
50	var run template.Token
51	for _, p := range m.Pairs {
52		key := asString(p.Key, "steps item key")
53		v := p.Value
54		switch key.Value {
55		case "id":
56			id := asString(v, "steps item id")
57			if msg := ids.tryAddKnownID(id.Value); msg != "" {
58				c.ctx.ErrorAt(id, msg)
59			}
60			s.ID = id.Value
61			s.Explicit = id.Value != ""
62		case "name":
63			s.Name = asScalar(v, "steps item name")
64		case "run":
65			run = asScalar(v, "steps item run")
66		case "uses":
67			uses = asString(v, "steps item uses")
68		case "env":
69			s.Env = asMap(v, "step env")
70		case "if":
71			s.If = c.convertIf(v, "step-if")
72		case "continue-on-error":
73			if !template.IsExpression(v) {
74				asBool(v, "steps item continue-on-error")
75			} else {
76				asScalar(v, "steps item continue-on-error")
77			}
78			s.ContinueOnError = v
79		case "shell":
80			s.Shell = v
81		case "working-directory":
82			s.WorkingDirectory = v
83		case "timeout-minutes":
84			s.TimeoutMinutes = v
85		case "with":
86			if wm, ok := v.(*template.Mapping); ok {
87				s.With = wm
88			}
89		}
90	}
91	switch {
92	case run != nil:
93		s.Run = run
94	case uses != nil:
95		s.Uses = uses
96	default:
97		c.ctx.ErrorAt(t, "Expected one of uses or run to be defined")
98		return nil
99	}
100	if s.If == nil {
101		s.If = c.defaultIf("step-if")
102	}
103	return s
104}
105
106// actionStepID is the id segment generated for a uses step without an id.
107func actionStepID(uses string) string {
108	switch {
109	case strings.HasPrefix(uses, "docker://"):
110		return uses[len("docker://"):]
111	case strings.HasPrefix(uses, "./"), strings.HasPrefix(uses, ".\\"), strings.HasPrefix(uses, "$/"):
112		return "self"
113	}
114	segments := strings.Split(uses, "@")
115	if len(segments) != 2 {
116		return ""
117	}
118	path := strings.FieldsFunc(segments[0], func(r rune) bool { return r == '/' || r == '\\' })
119	if len(path) >= 2 && path[0] != "" && path[1] != "" && segments[1] != "" {
120		return path[0] + "/" + path[1]
121	}
122	return ""
123}

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