main 98594d0

model.go RawHistoryFolder

1// SPDX-License-Identifier: MIT
2
3package action
4
5import (
6	"bnema.dev/ermite-actions/template"
7	"bnema.dev/ermite-actions/workflow"
8)
9
10// Error is a problem found in an action manifest. See the package comment for
11// the form of its message.
12type Error = template.Error
13
14// Action is a parsed action.yml.
15type Action struct {
16	// File is the name given to Parse.
17	File string
18	// Name, Description and Author are the keys of the same names; "" when
19	// absent, or not a string. The runner does not read Author.
20	Name, Description, Author string
21	// Inputs are the declared inputs in file order.
22	Inputs []Input
23	// Outputs are the declared outputs in file order. Only a composite
24	// action's outputs have a Value that is used.
25	Outputs []Output
26	// Runs says how the action runs. It is never nil in a returned Action.
27	Runs *Runs
28}
29
30// Input returns the input called name, compared like the runner compares
31// input names (OrdinalIgnoreCase), or nil.
32func (a *Action) Input(name string) *Input {
33	for i := range a.Inputs {
34		if ordinalEqual(a.Inputs[i].Name, name) {
35			return &a.Inputs[i]
36		}
37	}
38	return nil
39}
40
41// Input is an entry of "inputs".
42type Input struct {
43	// Name is the key, as written.
44	Name string
45	// Pos is where the key is.
46	Pos template.Pos
47	// Description is the "description" key, or "".
48	Description string
49	// Required is "required: true" (a boolean, or the string "true"). The
50	// runner does not check it.
51	Required bool
52	// Default is the default value: a string, or an expression
53	// (${{ github.ref }}) that the runner evaluates when the step does not
54	// give the input; the context it may use is the one of
55	// "input-default-context" in the schema (github, strategy, matrix, job,
56	// runner and hashFiles). It is never nil: an input without a default has
57	// the empty string, as in the runner. HasDefault tells them apart.
58	Default    template.Token
59	HasDefault bool
60	// DeprecationMessage is "deprecationMessage", or "". The runner warns
61	// "Input '<name>' has been deprecated with message: <message>" when a
62	// step gives the input.
63	DeprecationMessage string
64}
65
66// Deprecated reports whether the input has a deprecation message.
67func (in *Input) Deprecated() bool { return in.DeprecationMessage != "" }
68
69// Output is an entry of "outputs".
70type Output struct {
71	Name        string
72	Pos         template.Pos
73	Description string
74	// Value is the "value" token of a composite action's output: a string or
75	// an expression over github, strategy, matrix, steps, inputs, job, runner
76	// and env. nil when the output has none.
77	Value template.Token
78}
79
80// RunsKind is how an action runs.
81type RunsKind int
82
83// The kinds of action.
84const (
85	// RunsNode is a JavaScript action: using node12, node16, node20 or node24.
86	RunsNode RunsKind = iota + 1
87	// RunsDocker is a container action: using docker.
88	RunsDocker
89	// RunsComposite is a composite action: using composite.
90	RunsComposite
91	// RunsPlugin is "runs: {plugin: name}", an internal runner plugin. The
92	// manifest loads, but only the runner's own plugins can run.
93	RunsPlugin
94)
95
96// Runs is the "runs" key. Which fields are set depends on Kind.
97type Runs struct {
98	Kind RunsKind
99	// Using is the runtime: "node12", "node16", "node20", "node24", "docker",
100	// "composite", or "plugin". The runner compares "using" without regard to
101	// case; Using is lower case.
102	Using string
103	// Pos is where "runs" is.
104	Pos template.Pos
105
106	// Node actions.
107	//
108	// Main is the script to run; Pre and Post are scripts that run before the
109	// job's first step and after its last, or "". PreIf and PostIf are their
110	// conditions: expressions written without ${{ }}, evaluated as they are
111	// (the runner does not add "success() &&"), "always()" when absent.
112	// Docker actions have the same four conditions for their entrypoints.
113	Main, Pre, Post string
114	PreIf, PostIf   string
115
116	// Docker actions.
117	//
118	// Image is a path to a Dockerfile ("Dockerfile", "images/Dockerfile") or
119	// "docker://image[:tag]"; see [ParseImage]. Entrypoint overrides the
120	// image's ENTRYPOINT. Args is a sequence of strings and Env a mapping of
121	// strings, both of which may hold ${{ inputs.x }} expressions (and no other
122	// context); nil when absent. PreEntrypoint and PostEntrypoint are the
123	// entrypoints that run before and after, or "".
124	Image, Entrypoint, PreEntrypoint, PostEntrypoint string
125	Args                                             *template.Sequence
126	Env                                              *template.Mapping
127
128	// Composite actions.
129	//
130	// Steps are the steps in file order. A run step has a shell; the contexts
131	// of each key are those of the schema (github, inputs, strategy, matrix,
132	// steps, job, runner, env), and "if" also takes vars and needs. A step
133	// has no timeout-minutes and no working-directory on a uses step.
134	Steps []*workflow.Step
135
136	// Plugin actions.
137	Plugin string
138}
139
140// HasPre reports whether the action has something to run before the job's
141// steps: a node "pre" or a docker "pre-entrypoint".
142func (r *Runs) HasPre() bool {
143	switch r.Kind {
144	case RunsNode:
145		return r.Pre != ""
146	case RunsDocker:
147		return r.PreEntrypoint != ""
148	}
149	return false
150}
151
152// HasPost reports whether the action has something to run after the job's
153// steps: a node "post" or a docker "post-entrypoint".
154func (r *Runs) HasPost() bool {
155	switch r.Kind {
156	case RunsNode:
157		return r.Post != ""
158	case RunsDocker:
159		return r.PostEntrypoint != ""
160	}
161	return false
162}

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